mirror of
https://github.com/Dev-KATECH/ADM.git
synced 2026-05-17 18:03:59 +09:00
2985 lines
106 KiB
C
2985 lines
106 KiB
C
/*==================================================================================================
|
|
* Project : RTD AUTOSAR 4.4
|
|
* Platform : CORTEXM
|
|
* Peripheral : LPI2C
|
|
* Dependencies : none
|
|
*
|
|
* Autosar Version : 4.4.0
|
|
* Autosar Revision : ASR_REL_4_4_REV_0000
|
|
* Autosar Conf.Variant :
|
|
* SW Version : 0.9.0
|
|
* Build Version : S32K3_RTD_0_9_0__ASR_REL_4_4_REV_0000_20210326
|
|
*
|
|
* (c) Copyright 2020 - 2021 NXP Semiconductors
|
|
* All Rights Reserved.
|
|
*
|
|
* NXP Confidential. This software is owned or controlled by NXP and may only be
|
|
* used strictly in accordance with the applicable license terms. By expressly
|
|
* accepting such terms or by downloading, installing, activating and/or otherwise
|
|
* using the software, you are agreeing that you have read, and that you agree to
|
|
* comply with and are bound by, such license terms. If you do not agree to be
|
|
* bound by the applicable license terms, then you may not retain, install,
|
|
* activate or otherwise use the software.
|
|
==================================================================================================*/
|
|
|
|
/**
|
|
* @file
|
|
*
|
|
* @addtogroup LPI2C_DRIVER Lpi2c Driver
|
|
* @{
|
|
*/
|
|
|
|
#ifdef __cplusplus
|
|
extern "C"{
|
|
#endif
|
|
|
|
/*==================================================================================================
|
|
* INCLUDE FILES
|
|
* 1) system and project includes
|
|
* 2) needed interfaces from external units
|
|
* 3) internal and external interfaces from this unit
|
|
==================================================================================================*/
|
|
#include "Lpi2c_Ip_HwAccess.h"
|
|
#include "Lpi2c_Ip_Features.h"
|
|
#include "Osif.h"
|
|
#include "Lpi2c_Ip.h"
|
|
|
|
#if (STD_ON == LPI2C_IP_DMA_FEATURE_AVAILABLE)
|
|
#include "Dma_Ip.h"
|
|
#endif /* (STD_ON == LPI2C_IP_DMA_FEATURE_AVAILABLE) */
|
|
|
|
#if (STD_ON == LPI2C_IP_DEV_ERROR_DETECT)
|
|
#include "Devassert.h"
|
|
#endif /* (STD_ON == LPI2C_IP_DEV_ERROR_DETECT) */
|
|
|
|
/*==================================================================================================
|
|
* SOURCE FILE VERSION INFORMATION
|
|
==================================================================================================*/
|
|
#define LPI2C_IP_VENDOR_ID_C 43
|
|
#define LPI2C_IP_AR_RELEASE_MAJOR_VERSION_C 4
|
|
#define LPI2C_IP_AR_RELEASE_MINOR_VERSION_C 4
|
|
#define LPI2C_IP_AR_RELEASE_REVISION_VERSION_C 0
|
|
#define LPI2C_IP_SW_MAJOR_VERSION_C 0
|
|
#define LPI2C_IP_SW_MINOR_VERSION_C 9
|
|
#define LPI2C_IP_SW_PATCH_VERSION_C 0
|
|
|
|
/*==================================================================================================
|
|
* FILE VERSION CHECKS
|
|
==================================================================================================*/
|
|
/* Checks against Lpi2c_Ip.h */
|
|
#if (LPI2C_IP_VENDOR_ID_C != LPI2C_IP_VENDOR_ID)
|
|
#error "Lpi2c_Ip.c and Lpi2c_Ip.h have different vendor ids"
|
|
#endif
|
|
#if (( LPI2C_IP_AR_RELEASE_MAJOR_VERSION_C != LPI2C_IP_AR_RELEASE_MAJOR_VERSION) || \
|
|
( LPI2C_IP_AR_RELEASE_MINOR_VERSION_C != LPI2C_IP_AR_RELEASE_MINOR_VERSION) || \
|
|
( LPI2C_IP_AR_RELEASE_REVISION_VERSION_C != LPI2C_IP_AR_RELEASE_REVISION_VERSION))
|
|
#error "AUTOSAR Version Numbers of Lpi2c_Ip.c and Lpi2c_Ip.h are different"
|
|
#endif
|
|
#if (( LPI2C_IP_SW_MAJOR_VERSION_C != LPI2C_IP_SW_MAJOR_VERSION) || \
|
|
( LPI2C_IP_SW_MINOR_VERSION_C != LPI2C_IP_SW_MINOR_VERSION) || \
|
|
( LPI2C_IP_SW_PATCH_VERSION_C != LPI2C_IP_SW_PATCH_VERSION))
|
|
#error "Software Version Numbers of Lpi2c_Ip.c and Lpi2c_Ip.h are different"
|
|
#endif
|
|
|
|
/* Checks against Lpi2c_Ip_HwAccess.h */
|
|
#if (LPI2C_IP_VENDOR_ID_C != LPI2C_IP_HWACCESS_VENDOR_ID)
|
|
#error "Lpi2c_Ip.c and Lpi2c_Ip_HwAccess.h have different vendor ids"
|
|
#endif
|
|
#if (( LPI2C_IP_AR_RELEASE_MAJOR_VERSION_C != LPI2C_IP_HWACCESS_AR_RELEASE_MAJOR_VERSION) || \
|
|
( LPI2C_IP_AR_RELEASE_MINOR_VERSION_C != LPI2C_IP_HWACCESS_AR_RELEASE_MINOR_VERSION) || \
|
|
( LPI2C_IP_AR_RELEASE_REVISION_VERSION_C != LPI2C_IP_HWACCESS_AR_RELEASE_REVISION_VERSION))
|
|
#error "AUTOSAR Version Numbers of Lpi2c_Ip.c and Lpi2c_Ip_HwAccess.h are different"
|
|
#endif
|
|
#if (( LPI2C_IP_SW_MAJOR_VERSION_C != LPI2C_IP_HWACCESS_SW_MAJOR_VERSION) || \
|
|
( LPI2C_IP_SW_MINOR_VERSION_C != LPI2C_IP_HWACCESS_SW_MINOR_VERSION) || \
|
|
( LPI2C_IP_SW_PATCH_VERSION_C != LPI2C_IP_HWACCESS_SW_PATCH_VERSION))
|
|
#error "Software Version Numbers of LPI2C_Ip.c and Lpi2c_Ip_HwAccess.h are different"
|
|
#endif
|
|
|
|
/* Checks against Lpi2c_Ip_Features.h */
|
|
#if (LPI2C_IP_VENDOR_ID_C != LPI2C_IP_FEATURES_VENDOR_ID)
|
|
#error "Lpi2c_Ip.c and Lpi2c_Ip_Features.h have different vendor ids"
|
|
#endif
|
|
#if (( LPI2C_IP_AR_RELEASE_MAJOR_VERSION_C != LPI2C_IP_FEATURES_AR_RELEASE_MAJOR_VERSION) || \
|
|
( LPI2C_IP_AR_RELEASE_MINOR_VERSION_C != LPI2C_IP_FEATURES_AR_RELEASE_MINOR_VERSION) || \
|
|
( LPI2C_IP_AR_RELEASE_REVISION_VERSION_C != LPI2C_IP_FEATURES_AR_RELEASE_REVISION_VERSION))
|
|
#error "AUTOSAR Version Numbers of Lpi2c_Ip.c and Lpi2c_Ip_Features.h are different"
|
|
#endif
|
|
#if (( LPI2C_IP_SW_MAJOR_VERSION_C != LPI2C_IP_FEATURES_SW_MAJOR_VERSION) || \
|
|
( LPI2C_IP_SW_MINOR_VERSION_C != LPI2C_IP_FEATURES_SW_MINOR_VERSION) || \
|
|
( LPI2C_IP_SW_PATCH_VERSION_C != LPI2C_IP_FEATURES_SW_PATCH_VERSION))
|
|
#error "Software Version Numbers of LPI2C_Ip.c and Lpi2c_Ip_Features.h are different"
|
|
#endif
|
|
|
|
#ifndef DISABLE_MCAL_INTERMODULE_ASR_CHECK
|
|
/* Checks against Mcal.h */
|
|
#if ((LPI2C_IP_AR_RELEASE_MAJOR_VERSION_C != MCAL_AR_RELEASE_MAJOR_VERSION) || \
|
|
(LPI2C_IP_AR_RELEASE_MINOR_VERSION_C != MCAL_AR_RELEASE_MINOR_VERSION))
|
|
#error "AUTOSAR Version Numbers of Lpi2c_Ip.h and Mcal.h are different"
|
|
#endif
|
|
#endif
|
|
|
|
/*******************************************************************************
|
|
* Variables
|
|
******************************************************************************/
|
|
|
|
/** @cond DRIVER_INTERNAL_USE_ONLY */
|
|
|
|
/* Constraints used for baud rate computation */
|
|
#define CLKHI_MIN_VALUE 1U
|
|
#define CLKLO_MIN_VALUE 3U
|
|
#define CLKHI_MAX_VALUE ((1U << LPI2C_MCCR0_CLKHI_WIDTH) - 1U)
|
|
#define CLKLO_MAX_VALUE CLKHI_MAX_VALUE
|
|
#define DATAVD_MIN_VALUE 1U
|
|
#define SETHOLD_MIN_VALUE 2U
|
|
|
|
/* DMA definitions */
|
|
#define I2C_DMA_CHANNEL_CONFIG_LIST_SIZE_MASTER (10U)
|
|
#define I2C_DMA_CHANNEL_CONFIG_LIST_SIZE_SLAVE (9U)
|
|
|
|
#define I2C_START_SEC_CONST_UNSPECIFIED
|
|
#include "I2c_MemMap.h"
|
|
|
|
/* Table of base addresses for LPI2C instances. */
|
|
static LPI2C_Type * const g_lpi2cBase[LPI2C_INSTANCE_COUNT] = LPI2C_BASE_PTRS;
|
|
|
|
#define I2C_STOP_SEC_CONST_UNSPECIFIED
|
|
#include "I2c_MemMap.h"
|
|
|
|
#if(LPI2C_IP_NUMBER_OF_MASTER_INSTANCES != 0U)
|
|
|
|
#define I2C_START_SEC_VAR_NO_INIT_UNSPECIFIED
|
|
#include "I2c_MemMap.h"
|
|
|
|
Lpi2c_Ip_MasterStateType Lpi2c_Ip_MasterState[LPI2C_IP_NUMBER_OF_MASTER_INSTANCES];
|
|
|
|
#define I2C_STOP_SEC_VAR_NO_INIT_UNSPECIFIED
|
|
#include "I2c_MemMap.h"
|
|
|
|
#endif
|
|
|
|
#if(LPI2C_IP_NUMBER_OF_SLAVE_INSTANCES != 0U)
|
|
|
|
#define I2C_START_SEC_VAR_NO_INIT_UNSPECIFIED
|
|
#include "I2c_MemMap.h"
|
|
|
|
Lpi2c_Ip_SlaveStateType Lpi2c_Ip_SlaveState[LPI2C_IP_NUMBER_OF_SLAVE_INSTANCES];
|
|
|
|
#define I2C_STOP_SEC_VAR_NO_INIT_UNSPECIFIED
|
|
#include "I2c_MemMap.h"
|
|
|
|
#endif
|
|
|
|
#define I2C_START_SEC_VAR_INIT_UNSPECIFIED
|
|
#include "I2c_MemMap.h"
|
|
|
|
/* Pointer to runtime state structure.*/
|
|
static Lpi2c_Ip_MasterStateType* g_lpi2cMasterStatePtr[LPI2C_INSTANCE_COUNT] = {NULL_PTR,NULL_PTR};
|
|
static Lpi2c_Ip_SlaveStateType* g_lpi2cSlaveStatePtr[LPI2C_INSTANCE_COUNT] = {NULL_PTR,NULL_PTR};
|
|
|
|
#define I2C_STOP_SEC_VAR_INIT_UNSPECIFIED
|
|
#include "I2c_MemMap.h"
|
|
|
|
#define I2C_START_SEC_VAR_NO_INIT_UNSPECIFIED
|
|
#include "I2c_MemMap.h"
|
|
|
|
#if (STD_ON == LPI2C_IP_DMA_FEATURE_AVAILABLE)
|
|
/* Structures for configuration the master DMA channel */
|
|
static Dma_Ip_LogicChannelTransferListType dmaChannelTransferListReceive[I2C_DMA_CHANNEL_CONFIG_LIST_SIZE_MASTER];
|
|
static Dma_Ip_LogicChannelTransferListType dmaChannelTransferListSend[I2C_DMA_CHANNEL_CONFIG_LIST_SIZE_MASTER];
|
|
|
|
/* Structures for configuration the master DMA channel */
|
|
static Dma_Ip_LogicChannelTransferListType dmaSlaveChTransferListReceive[I2C_DMA_CHANNEL_CONFIG_LIST_SIZE_SLAVE];
|
|
static Dma_Ip_LogicChannelTransferListType dmaSlaveChTransferListSend[I2C_DMA_CHANNEL_CONFIG_LIST_SIZE_SLAVE];
|
|
#endif /* LPI2C_IP_DMA_FEATURE_AVAILABLE */
|
|
|
|
#define I2C_STOP_SEC_VAR_NO_INIT_UNSPECIFIED
|
|
#include "I2c_MemMap.h"
|
|
|
|
#if(STD_ON == LPI2C_IP_DMA_FEATURE_AVAILABLE)
|
|
/* Callback for master DMA transfer done.*/
|
|
static void Lpi2c_Ip_MasterCompleteDMATransfer(uint32 u32Instance);
|
|
#endif
|
|
|
|
/** @brief Direction of a LPI2C transfer - transmit or receive. */
|
|
typedef enum
|
|
{
|
|
LPI2C_TX_REQ = 0, /**< The driver will perform an I2C transmit transfer */
|
|
LPI2C_RX_REQ = 1, /**< The driver will perform an I2C receive transfer */
|
|
} Lpi2c_Ip_TransferDirectionType;
|
|
|
|
#define I2C_START_SEC_CODE
|
|
#include "I2c_MemMap.h"
|
|
/*******************************************************************************
|
|
* API
|
|
******************************************************************************/
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_MasterCmdQueueEmpty
|
|
* Description : checks if there are any commands in the master software queue
|
|
*
|
|
*END**************************************************************************/
|
|
static inline boolean Lpi2c_Ip_MasterCmdQueueEmpty(const Lpi2c_Ip_MasterStateType * master)
|
|
{
|
|
#if (STD_ON == LPI2C_IP_DEV_ERROR_DETECT)
|
|
DevAssert(master != NULL_PTR);
|
|
#endif
|
|
return (master->cmdQueue.writeIdx == master->cmdQueue.readIdx);
|
|
}
|
|
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_MasterResetQueue
|
|
* Description : resets the master software queue
|
|
*
|
|
*END**************************************************************************/
|
|
static inline void Lpi2c_Ip_MasterResetQueue(Lpi2c_Ip_MasterStateType * master)
|
|
{
|
|
#if (STD_ON == LPI2C_IP_DEV_ERROR_DETECT)
|
|
DevAssert(master != NULL_PTR);
|
|
#endif
|
|
master->cmdQueue.readIdx = 0U;
|
|
master->cmdQueue.writeIdx = 0U;
|
|
}
|
|
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_MasterQueueCmd
|
|
* Description : queues a command in the hardware FIFO or in the master software queue
|
|
*
|
|
*END**************************************************************************/
|
|
static inline void Lpi2c_Ip_MasterQueueCmd(LPI2C_Type *baseAddr,
|
|
Lpi2c_Ip_MasterStateType * master,
|
|
Lpi2c_Ip_MasterCommandType cmd,
|
|
uint8 data)
|
|
{
|
|
uint16 txFIFOCount;
|
|
uint16 txFIFOSize;
|
|
|
|
#if (STD_ON == LPI2C_IP_DEV_ERROR_DETECT)
|
|
DevAssert(master != NULL_PTR);
|
|
DevAssert(baseAddr != NULL_PTR);
|
|
#endif
|
|
|
|
txFIFOCount = LPI2C_Get_MasterTxFIFOCount(baseAddr);
|
|
txFIFOSize = LPI2C_Get_MasterTxFIFOSize(baseAddr);
|
|
|
|
/* Check if there is room in the hardware FIFO */
|
|
if (txFIFOCount < txFIFOSize)
|
|
{
|
|
LPI2C_Cmd_MasterTransmit(baseAddr, cmd, data);
|
|
}
|
|
else
|
|
{
|
|
#if (STD_ON == LPI2C_IP_DEV_ERROR_DETECT)
|
|
/* Hardware FIFO full, use software FIFO */
|
|
DevAssert(master->cmdQueue.writeIdx < LPI2C_MASTER_CMD_QUEUE_SIZE);
|
|
#endif
|
|
master->cmdQueue.cmd[master->cmdQueue.writeIdx] = cmd;
|
|
master->cmdQueue.data[master->cmdQueue.writeIdx] = data;
|
|
master->cmdQueue.writeIdx++;
|
|
}
|
|
}
|
|
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_MasterSendQueuedCmd
|
|
* Description : transfers commands from the master software queue to the hardware FIFO
|
|
*
|
|
*END**************************************************************************/
|
|
static inline void Lpi2c_Ip_MasterSendQueuedCmd(LPI2C_Type *baseAddr, Lpi2c_Ip_MasterStateType * master)
|
|
{
|
|
#if (STD_ON == LPI2C_IP_DEV_ERROR_DETECT)
|
|
DevAssert(master != NULL_PTR);
|
|
DevAssert(baseAddr != NULL_PTR);
|
|
#endif
|
|
uint16 txFIFOCount = LPI2C_Get_MasterTxFIFOCount(baseAddr);
|
|
uint16 txFifoSize = LPI2C_Get_MasterTxFIFOSize(baseAddr);
|
|
|
|
while ((!Lpi2c_Ip_MasterCmdQueueEmpty(master)) && (txFIFOCount < txFifoSize))
|
|
{
|
|
LPI2C_Cmd_MasterTransmit(baseAddr,
|
|
master->cmdQueue.cmd[master->cmdQueue.readIdx],
|
|
master->cmdQueue.data[master->cmdQueue.readIdx]);
|
|
master->cmdQueue.readIdx++;
|
|
|
|
txFIFOCount = LPI2C_Get_MasterTxFIFOCount(baseAddr);
|
|
}
|
|
|
|
if (Lpi2c_Ip_MasterCmdQueueEmpty(master))
|
|
{
|
|
/* Reset queue */
|
|
Lpi2c_Ip_MasterResetQueue(master);
|
|
}
|
|
}
|
|
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_MasterSendAddress
|
|
* Description : send start event and slave address
|
|
* parameter receive specifies the direction of the transfer
|
|
*
|
|
*END**************************************************************************/
|
|
static void Lpi2c_Ip_MasterSendAddress(LPI2C_Type *baseAddr,
|
|
Lpi2c_Ip_MasterStateType * master,
|
|
boolean receive)
|
|
{
|
|
uint8 addrByte;
|
|
Lpi2c_Ip_MasterCommandType startCommand;
|
|
#if (STD_ON == LPI2C_IP_DEV_ERROR_DETECT)
|
|
DevAssert(master != NULL_PTR);
|
|
DevAssert(baseAddr != NULL_PTR);
|
|
#endif
|
|
|
|
if ((master->operatingMode == LPI2C_HIGHSPEED_MODE) && (master->highSpeedInProgress == FALSE))
|
|
{
|
|
/* Initiating High-speed mode - send master code first */
|
|
Lpi2c_Ip_MasterQueueCmd(baseAddr, master, LPI2C_MASTER_COMMAND_START_NACK, master->masterCode);
|
|
master->highSpeedInProgress = TRUE;
|
|
}
|
|
|
|
if (master->highSpeedInProgress == TRUE)
|
|
{
|
|
/* Use high-speed settings after start event in High Speed mode */
|
|
startCommand = LPI2C_MASTER_COMMAND_START_HS;
|
|
}
|
|
else
|
|
{
|
|
/* Normal START command */
|
|
startCommand = LPI2C_MASTER_COMMAND_START;
|
|
}
|
|
|
|
if (master->is10bitAddr)
|
|
{
|
|
/* 10-bit addressing */
|
|
/* First address byte: 1111 0XXD, where XX are bits 10 and 9 of address, and D = 0(transmit) */
|
|
addrByte = (uint8)(0xF0U + ((master->slaveAddress >> 7U) & 0x6U) + (uint8)0U);
|
|
Lpi2c_Ip_MasterQueueCmd(baseAddr, master, startCommand, addrByte);
|
|
/* Second address byte: Remaining 8 bits of address */
|
|
addrByte = (uint8)(master->slaveAddress & 0xFFU);
|
|
Lpi2c_Ip_MasterQueueCmd(baseAddr, master, LPI2C_MASTER_COMMAND_TRANSMIT, addrByte);
|
|
if (receive == TRUE)
|
|
{
|
|
/* Receiving from 10-bit slave - must send repeated start and resend first address byte */
|
|
/* First address byte: 1111 0XXD, where XX are bits 10 and 9 of address, and D = 1 (receive) */
|
|
addrByte = (uint8)(0xF0U + ((master->slaveAddress >> 7U) & 0x6U) + (uint8)1U);
|
|
Lpi2c_Ip_MasterQueueCmd(baseAddr, master, startCommand, addrByte);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* 7-bit addressing */
|
|
/* Address byte: slave 7-bit address + D = 0(transmit) or 1 (receive) */
|
|
addrByte = (uint8)((master->slaveAddress << 1U) + (uint8)receive);
|
|
Lpi2c_Ip_MasterQueueCmd(baseAddr, master, startCommand, addrByte);
|
|
}
|
|
}
|
|
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_MasterQueueData
|
|
* Description : queues transmit data in the LPI2C tx fifo until it is full
|
|
*
|
|
*END**************************************************************************/
|
|
static void Lpi2c_Ip_MasterQueueData(LPI2C_Type *baseAddr,
|
|
Lpi2c_Ip_MasterStateType * master)
|
|
{
|
|
|
|
#if (STD_ON == LPI2C_IP_DEV_ERROR_DETECT)
|
|
DevAssert(master != NULL_PTR);
|
|
DevAssert(baseAddr != NULL_PTR);
|
|
#endif
|
|
|
|
uint16 txFIFOCount = LPI2C_Get_MasterTxFIFOCount(baseAddr);
|
|
uint16 txFifoSize = LPI2C_Get_MasterTxFIFOSize(baseAddr);
|
|
|
|
/* Don't queue any data if there are commands in the software queue */
|
|
if (Lpi2c_Ip_MasterCmdQueueEmpty(master))
|
|
{
|
|
while ((master->bufferSize > 0U) && (txFIFOCount < txFifoSize))
|
|
{
|
|
LPI2C_Cmd_MasterTransmit(baseAddr, LPI2C_MASTER_COMMAND_TRANSMIT, master->dataBuffer[0U]);
|
|
master->dataBuffer++;
|
|
master->bufferSize--;
|
|
|
|
txFIFOCount = LPI2C_Get_MasterTxFIFOCount(baseAddr);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_MasterEndTransfer
|
|
* Description : ends current transmission or reception
|
|
*
|
|
*END**************************************************************************/
|
|
static void Lpi2c_Ip_MasterEndTransfer(LPI2C_Type *baseAddr,
|
|
Lpi2c_Ip_MasterStateType * master,
|
|
boolean sendStop,
|
|
boolean resetFIFO)
|
|
{
|
|
#if(STD_ON == LPI2C_IP_DEV_ERROR_DETECT)
|
|
DevAssert(master != NULL_PTR);
|
|
DevAssert(baseAddr != NULL_PTR);
|
|
#endif
|
|
|
|
/* Disable all events */
|
|
LPI2C_Set_MasterInt(baseAddr, LPI2C_MASTER_FIFO_ERROR_INT |
|
|
LPI2C_MASTER_ARBITRATION_LOST_INT |
|
|
LPI2C_MASTER_NACK_DETECT_INT |
|
|
LPI2C_MASTER_TRANSMIT_DATA_INT |
|
|
LPI2C_MASTER_PIN_LOW_TIMEOUT_INT |
|
|
LPI2C_MASTER_RECEIVE_DATA_INT,
|
|
FALSE);
|
|
|
|
#if(STD_ON == LPI2C_IP_DMA_FEATURE_AVAILABLE)
|
|
if (master->transferType == LPI2C_USING_DMA)
|
|
{
|
|
/* Disable LPI2C DMA request. */
|
|
if (LPI2C_IP_RECEIVE == master->direction)
|
|
{
|
|
(void)LPI2C_Set_MasterRxDMA(baseAddr, FALSE);
|
|
}
|
|
else
|
|
{
|
|
(void)LPI2C_Set_MasterTxDMA(baseAddr, FALSE);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
if (resetFIFO == TRUE)
|
|
{
|
|
/* Reset FIFOs if requested */
|
|
LPI2C_Reset_MasterTxFIFOCmd(baseAddr);
|
|
LPI2C_Reset_MasterRxFIFOCmd(baseAddr);
|
|
}
|
|
|
|
/* Queue STOP command if requested */
|
|
if (sendStop == TRUE)
|
|
{
|
|
LPI2C_Cmd_MasterTransmit(baseAddr, LPI2C_MASTER_COMMAND_STOP, 0U);
|
|
|
|
master->highSpeedInProgress = FALSE; /* High-speed transfers end at STOP condition */
|
|
|
|
}
|
|
|
|
master->dataBuffer = NULL_PTR;
|
|
master->bufferSize = 0U;
|
|
master->i2cIdle = TRUE;
|
|
}
|
|
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_MasterSetOperatingMode
|
|
* Description : sets the operating mode of the I2C master
|
|
*
|
|
*END**************************************************************************/
|
|
static void Lpi2c_Ip_MasterSetOperatingMode(uint32 instance, Lpi2c_Ip_ModeType operatingMode)
|
|
{
|
|
LPI2C_Type *baseAddr;
|
|
Lpi2c_Ip_MasterStateType * master;
|
|
|
|
baseAddr = g_lpi2cBase[instance];
|
|
master = g_lpi2cMasterStatePtr[instance];
|
|
#if (STD_ON == LPI2C_IP_DEV_ERROR_DETECT)
|
|
DevAssert(master != NULL_PTR);
|
|
#endif
|
|
|
|
#if(LPI2C_HAS_ULTRA_FAST_MODE)
|
|
if (operatingMode == LPI2C_ULTRAFAST_MODE)
|
|
{
|
|
LPI2C_Set_MasterPinConfig(baseAddr, LPI2C_CFG_2PIN_OUTPUT_ONLY);
|
|
LPI2C_Set_MasterNACKConfig(baseAddr, LPI2C_NACK_IGNORE);
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
LPI2C_Set_MasterPinConfig(baseAddr, LPI2C_CFG_2PIN_OPEN_DRAIN);
|
|
LPI2C_Set_MasterNACKConfig(baseAddr, LPI2C_NACK_RECEIVE);
|
|
}
|
|
|
|
master->operatingMode = operatingMode;
|
|
}
|
|
|
|
#if(LPI2C_HAS_ULTRA_FAST_MODE)
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_SlaveConfigureUltraFastMode
|
|
* Description : configures slave in ultra fast mode
|
|
*
|
|
*END**************************************************************************/
|
|
static void Lpi2c_Ip_SlaveConfigureUltraFastMode(LPI2C_Type *baseAddr)
|
|
{
|
|
/* ignore NACK received */
|
|
LPI2C_Set_SlaveIgnoreNACK(baseAddr, LPI2C_SLAVE_NACK_CONTINUE_TRANSFER);
|
|
/* Transmit NACK */
|
|
LPI2C_Set_SlaveTransmitNACK(baseAddr, LPI2C_SLAVE_TRANSMIT_NACK);
|
|
/* Disable all clock stretching in ultra-fast mode */
|
|
LPI2C_Set_SlaveACKStall(baseAddr, FALSE);
|
|
LPI2C_Set_SlaveTXDStall(baseAddr, FALSE);
|
|
LPI2C_Set_SlaveRXStall(baseAddr, FALSE);
|
|
LPI2C_Set_SlaveAddrStall(baseAddr, FALSE);
|
|
}
|
|
#endif
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_SlaveConfigureNormalMode
|
|
* Description : configures slave for normal operations
|
|
*
|
|
*END**************************************************************************/
|
|
static void Lpi2c_Ip_SlaveConfigureNormalMode(LPI2C_Type *baseAddr)
|
|
{
|
|
/* End transfer when NACK is received */
|
|
LPI2C_Set_SlaveIgnoreNACK(baseAddr, LPI2C_SLAVE_NACK_END_TRANSFER);
|
|
/* Transmit ACK */
|
|
LPI2C_Set_SlaveTransmitNACK(baseAddr, LPI2C_SLAVE_TRANSMIT_ACK);
|
|
/* Enable clock stretching except ACKSTALL (we don't need to send ACK/NACK manually) */
|
|
LPI2C_Set_SlaveACKStall(baseAddr, FALSE);
|
|
LPI2C_Set_SlaveTXDStall(baseAddr, TRUE);
|
|
LPI2C_Set_SlaveRXStall(baseAddr, TRUE);
|
|
LPI2C_Set_SlaveAddrStall(baseAddr, TRUE);
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_SlaveSetOperatingMode
|
|
* Description : sets the operating mode of the I2C slave
|
|
*
|
|
*END**************************************************************************/
|
|
static void Lpi2c_Ip_SlaveSetOperatingMode(uint32 instance, Lpi2c_Ip_ModeType operatingMode)
|
|
{
|
|
LPI2C_Type *baseAddr;
|
|
Lpi2c_Ip_SlaveStateType * slave;
|
|
boolean bHighSpeedMode = FALSE;
|
|
baseAddr = g_lpi2cBase[instance];
|
|
slave = g_lpi2cSlaveStatePtr[instance];
|
|
#if (STD_ON == LPI2C_IP_DEV_ERROR_DETECT)
|
|
DevAssert(slave != NULL_PTR);
|
|
#endif
|
|
|
|
#if(LPI2C_HAS_ULTRA_FAST_MODE)
|
|
if (operatingMode == LPI2C_ULTRAFAST_MODE)
|
|
{
|
|
Lpi2c_Ip_SlaveConfigureUltraFastMode(baseAddr);
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
Lpi2c_Ip_SlaveConfigureNormalMode(baseAddr);
|
|
}
|
|
|
|
if (operatingMode == LPI2C_HIGHSPEED_MODE)
|
|
{
|
|
/* Enable detection of high speed mode */
|
|
bHighSpeedMode = TRUE;
|
|
}
|
|
|
|
/* Enable/disable detection of the High-speed Mode master code */
|
|
LPI2C_Set_SlaveHighSpeedModeDetect(baseAddr, bHighSpeedMode);
|
|
|
|
slave->operatingMode = operatingMode;
|
|
}
|
|
|
|
#if(STD_ON == LPI2C_IP_DMA_FEATURE_AVAILABLE)
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_MasterCompleteDMATransfer
|
|
* Description : Finish up a transfer DMA for master. The main purpose of
|
|
* this function is to create a function compatible with DMA
|
|
* callback type
|
|
*
|
|
*END**************************************************************************/
|
|
static void Lpi2c_Ip_MasterCompleteDMATransfer(uint32 u32Instance)
|
|
{
|
|
LPI2C_Type *baseAddr;
|
|
Lpi2c_Ip_MasterStateType *master;
|
|
|
|
baseAddr = g_lpi2cBase[u32Instance];
|
|
master = g_lpi2cMasterStatePtr[u32Instance];
|
|
|
|
|
|
if((master->bufferSize > 0U) && (LPI2C_IP_SEND == master->direction))
|
|
{
|
|
master->bufferSize = 0U;
|
|
|
|
LPI2C_Set_MasterTxFIFOWatermark(baseAddr, 0U);
|
|
|
|
/* Disable transmit data DMA requests */
|
|
(void)LPI2C_Set_MasterTxDMA(baseAddr, FALSE);
|
|
|
|
/* Activate transmit data events */
|
|
LPI2C_Set_MasterInt(baseAddr, (uint32)LPI2C_MASTER_TRANSMIT_DATA_INT, TRUE);
|
|
}
|
|
else
|
|
{
|
|
/* Signal transfer end for blocking transfers */
|
|
Lpi2c_Ip_MasterEndTransfer(baseAddr, master, master->sendStop, FALSE);
|
|
|
|
master->status = STATUS_LPI2C_IP_SUCCESS;
|
|
|
|
if (master->masterCallback != NULL_PTR)
|
|
{
|
|
master->masterCallback(I2C_MASTER_EVENT_END_TRANSFER, master->callbackParam);
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#if(STD_ON == LPI2C_IP_DMA_FEATURE_AVAILABLE)
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_MasterConfigureTxDmaChannel
|
|
* Description : configures the Tx dma channel
|
|
*
|
|
*END**************************************************************************/
|
|
static void Lpi2c_Ip_MasterConfigureTxDmaChannel(uint32 instance)
|
|
{
|
|
LPI2C_Type *baseAddr = g_lpi2cBase[instance];
|
|
const Lpi2c_Ip_MasterStateType *master = g_lpi2cMasterStatePtr[instance];
|
|
|
|
/* Configure watermarks for transmit DMA for master */
|
|
uint32 txBytes = LPI2C_Get_MasterTxFIFOSize(baseAddr);
|
|
|
|
if (txBytes > master->bufferSize)
|
|
{
|
|
txBytes = master->bufferSize;
|
|
}
|
|
LPI2C_Set_MasterTxFIFOWatermark(baseAddr, (uint16)(txBytes - 1U));
|
|
|
|
/* Set source address and major loop transfer size */
|
|
dmaChannelTransferListSend[0u].Value = (uint32)(&(master->dataBuffer[0]));
|
|
dmaChannelTransferListSend[3u].Value = (uint32)(&(baseAddr->MTDR));
|
|
dmaChannelTransferListSend[7u].Value = master->bufferSize;
|
|
|
|
(void)Dma_Ip_SetLogicChannelTransferList(master->dmaTxChannel, dmaChannelTransferListSend, I2C_DMA_CHANNEL_CONFIG_LIST_SIZE_MASTER);
|
|
/* Start DMA channel */
|
|
(void)Dma_Ip_SetLogicChannelCommand(master->dmaTxChannel, DMA_IP_CH_SET_HARDWARE_REQUEST);
|
|
}
|
|
#endif
|
|
|
|
#if(STD_ON == LPI2C_IP_DMA_FEATURE_AVAILABLE)
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_MasterConfigureRxDmaChannel
|
|
* Description : configures the Rx dma channel
|
|
*
|
|
*END**************************************************************************/
|
|
static void Lpi2c_Ip_MasterConfigureRxDmaChannel(uint32 instance)
|
|
{
|
|
LPI2C_Type *baseAddr = g_lpi2cBase[instance];
|
|
const Lpi2c_Ip_MasterStateType *master = g_lpi2cMasterStatePtr[instance];
|
|
|
|
/* Configure watermarks for receive DMA for master */
|
|
LPI2C_Set_MasterRxFIFOWatermark(baseAddr, 0U);
|
|
|
|
/* Set destination address and major loop transfer size */
|
|
dmaChannelTransferListReceive[0u].Value = (uint32) (&(baseAddr->MRDR));
|
|
dmaChannelTransferListReceive[3u].Value = (uint32)(&(master->dataBuffer[0]));
|
|
dmaChannelTransferListReceive[7u].Value = master->bufferSize;
|
|
|
|
(void)Dma_Ip_SetLogicChannelTransferList(master->dmaRxChannel, dmaChannelTransferListReceive, I2C_DMA_CHANNEL_CONFIG_LIST_SIZE_MASTER);
|
|
/* Start DMA channel */
|
|
(void)Dma_Ip_SetLogicChannelCommand(master->dmaRxChannel, DMA_IP_CH_SET_HARDWARE_REQUEST);
|
|
}
|
|
#endif
|
|
|
|
#if(STD_ON == LPI2C_IP_DMA_FEATURE_AVAILABLE)
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_MasterStartDmaTransfer
|
|
* Description : starts the DMA transfer for master
|
|
*
|
|
*END**************************************************************************/
|
|
static void Lpi2c_Ip_MasterStartDmaTransfer(uint32 instance)
|
|
{
|
|
LPI2C_Type *baseAddr = g_lpi2cBase[instance];
|
|
Lpi2c_Ip_MasterStateType *master = g_lpi2cMasterStatePtr[instance];
|
|
boolean receive = FALSE;
|
|
|
|
if (LPI2C_IP_SEND == master->direction)
|
|
{
|
|
/* Configure dma TX channel */
|
|
Lpi2c_Ip_MasterConfigureTxDmaChannel(instance);
|
|
}
|
|
else
|
|
{
|
|
receive = TRUE;
|
|
|
|
/* Configure dma RX channel */
|
|
Lpi2c_Ip_MasterConfigureRxDmaChannel(instance);
|
|
}
|
|
|
|
/* Send address */
|
|
Lpi2c_Ip_MasterSendAddress(baseAddr, master, receive);
|
|
|
|
/* Enable transmit/receive DMA requests */
|
|
if (LPI2C_IP_SEND == master->direction)
|
|
{
|
|
(void)LPI2C_Set_MasterTxDMA(baseAddr, TRUE);
|
|
}
|
|
else
|
|
{
|
|
Lpi2c_Ip_MasterQueueCmd(baseAddr, master, LPI2C_MASTER_COMMAND_RECEIVE, (uint8)(master->bufferSize - 1U));
|
|
(void)LPI2C_Set_MasterRxDMA(baseAddr, TRUE);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#if(STD_ON == LPI2C_IP_DMA_FEATURE_AVAILABLE)
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_SlaveStartDmaTransfer
|
|
* Description : starts the DMA transfer for slave
|
|
*
|
|
*END**************************************************************************/
|
|
static void Lpi2c_Ip_SlaveStartDmaTransfer(uint32 instance)
|
|
{
|
|
LPI2C_Type *baseAddr = g_lpi2cBase[instance];
|
|
const Lpi2c_Ip_SlaveStateType *slave = g_lpi2cSlaveStatePtr[instance];
|
|
|
|
if(LPI2C_IP_SEND == slave->direction)
|
|
{
|
|
/* Set source address and major loop transfer size */
|
|
dmaSlaveChTransferListSend[0u].Value = (uint32)(&(slave->dataBuffer[0]));
|
|
dmaSlaveChTransferListSend[3u].Value = (uint32)(&(baseAddr->STDR));
|
|
dmaSlaveChTransferListSend[7u].Value = slave->bufferSize;
|
|
dmaSlaveChTransferListSend[8u].Value = slave->bufferSize;
|
|
|
|
(void)Dma_Ip_SetLogicChannelTransferList(slave->dmaTxChannel, dmaSlaveChTransferListSend, I2C_DMA_CHANNEL_CONFIG_LIST_SIZE_SLAVE);
|
|
/* Start DMA channel */
|
|
(void)Dma_Ip_SetLogicChannelCommand(slave->dmaTxChannel, DMA_IP_CH_SET_HARDWARE_REQUEST);
|
|
}
|
|
else
|
|
{
|
|
/* Set destination address and major loop transfer size */
|
|
dmaSlaveChTransferListReceive[0u].Value = (uint32) (&(baseAddr->SRDR));
|
|
dmaSlaveChTransferListReceive[3u].Value = (uint32)(&(slave->dataBuffer[0]));
|
|
dmaSlaveChTransferListReceive[7u].Value = slave->bufferSize;
|
|
dmaSlaveChTransferListReceive[8u].Value = 0U;
|
|
|
|
(void)Dma_Ip_SetLogicChannelTransferList(slave->dmaRxChannel, dmaSlaveChTransferListReceive, I2C_DMA_CHANNEL_CONFIG_LIST_SIZE_SLAVE);
|
|
/* Start DMA channel */
|
|
(void)Dma_Ip_SetLogicChannelCommand(slave->dmaRxChannel, DMA_IP_CH_SET_HARDWARE_REQUEST);
|
|
}
|
|
|
|
/* Enable transmit/receive DMA requests */
|
|
if(LPI2C_IP_SEND == slave->direction)
|
|
{
|
|
(void)LPI2C_Set_SlaveTxDMA(baseAddr, TRUE);
|
|
}
|
|
else
|
|
{
|
|
(void)LPI2C_Set_SlaveRxDMA(baseAddr, TRUE);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_MasterHandleTransmitDataRequest
|
|
* Description : handle a transmit request for master
|
|
*
|
|
*END**************************************************************************/
|
|
static void Lpi2c_Ip_MasterHandleTransmitDataRequest(LPI2C_Type *baseAddr, Lpi2c_Ip_MasterStateType *master)
|
|
{
|
|
/* More data needed for transmission */
|
|
if (!Lpi2c_Ip_MasterCmdQueueEmpty(master))
|
|
{
|
|
/* If there are queued commands, send them */
|
|
Lpi2c_Ip_MasterSendQueuedCmd(baseAddr, master);
|
|
}
|
|
else if ((master->dataBuffer != NULL_PTR) && (master->direction == LPI2C_IP_SEND))
|
|
{
|
|
/* A transmission is in progress */
|
|
if (master->bufferSize == 0U)
|
|
{
|
|
/* There is no more data in buffer, the transmission is over */
|
|
Lpi2c_Ip_MasterEndTransfer(baseAddr, master, master->sendStop, FALSE);
|
|
|
|
master->status = STATUS_LPI2C_IP_SUCCESS;
|
|
|
|
if (master->masterCallback != NULL_PTR)
|
|
{
|
|
master->masterCallback(I2C_MASTER_EVENT_END_TRANSFER, master->callbackParam);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* Queue data bytes to fill tx fifo */
|
|
Lpi2c_Ip_MasterQueueData(baseAddr, master);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* No more commands and no transmission in progress - disable tx event */
|
|
LPI2C_Set_MasterInt(baseAddr, (uint32)LPI2C_MASTER_TRANSMIT_DATA_INT, FALSE);
|
|
}
|
|
}
|
|
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_MasterHandleReceiveDataRequest
|
|
* Description : handle a receive request for master
|
|
*
|
|
*END**************************************************************************/
|
|
static void Lpi2c_Ip_MasterHandleReceiveDataReadyEvent(LPI2C_Type *baseAddr, Lpi2c_Ip_MasterStateType *master)
|
|
{
|
|
/* Received data ready */
|
|
#if(STD_ON == LPI2C_IP_DEV_ERROR_DETECT)
|
|
DevAssert(master->dataBuffer != NULL_PTR);
|
|
#endif
|
|
|
|
/* Transfer received data to user buffer */
|
|
while ((LPI2C_Get_MasterRxFIFOCount(baseAddr) > 0U) && (master->bufferSize > 0U))
|
|
{
|
|
master->dataBuffer[0U] = LPI2C_Get_MasterRxData(baseAddr);
|
|
master->dataBuffer++;
|
|
master->bufferSize--;
|
|
}
|
|
|
|
if (master->bufferSize == 0U)
|
|
{
|
|
/* Done receiving */
|
|
Lpi2c_Ip_MasterEndTransfer(baseAddr, master, master->sendStop, FALSE);
|
|
|
|
master->status = STATUS_LPI2C_IP_SUCCESS;
|
|
|
|
if (master->masterCallback != NULL_PTR)
|
|
{
|
|
master->masterCallback(I2C_MASTER_EVENT_END_TRANSFER, master->callbackParam);
|
|
}
|
|
}
|
|
else if (master->bufferSize <= LPI2C_Get_MasterRxFIFOWatermark(baseAddr))
|
|
{
|
|
/* Reduce rx watermark to receive the last few bytes */
|
|
LPI2C_Set_MasterRxFIFOWatermark(baseAddr, (uint16)(master->bufferSize - 1U));
|
|
}
|
|
else
|
|
{
|
|
/* Continue reception */
|
|
}
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_SlaveHandleAddressValidEvent
|
|
* Description : handle an address valid event for slave
|
|
*
|
|
*END**************************************************************************/
|
|
static void Lpi2c_Ip_SlaveHandleAddressValidEvent(uint32 instance, const LPI2C_Type *baseAddr, Lpi2c_Ip_SlaveStateType *slave)
|
|
{
|
|
uint16 receivedAddr;
|
|
|
|
receivedAddr = LPI2C_Get_SlaveReceivedAddr(baseAddr);
|
|
if ((receivedAddr & 1U) != (uint16)0U)
|
|
{
|
|
/* Request from master to transmit data */
|
|
slave->direction = LPI2C_IP_SEND;
|
|
|
|
if (slave->slaveCallback != NULL_PTR)
|
|
{
|
|
slave->slaveCallback(I2C_SLAVE_EVENT_TX_REQ, slave->callbackParam);
|
|
}
|
|
|
|
#if defined(ERRATA_E10792)
|
|
if (slave->transferType == LPI2C_USING_INTERRUPTS) {
|
|
/* Enable interrupt for transmitting data */
|
|
LPI2C_Set_SlaveInt(g_lpi2cBase[instance], (uint32)LPI2C_SLAVE_TRANSMIT_DATA_INT, TRUE);
|
|
}
|
|
#endif
|
|
|
|
slave->txUnderrunWarning = FALSE;
|
|
|
|
#if(STD_ON == LPI2C_IP_DMA_FEATURE_AVAILABLE)
|
|
if (slave->transferType == LPI2C_USING_DMA)
|
|
{
|
|
(void)Lpi2c_Ip_SlaveStartDmaTransfer(instance);
|
|
}
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
/* Request from master to receive data */
|
|
slave->direction = LPI2C_IP_RECEIVE;
|
|
|
|
if (slave->slaveCallback != NULL_PTR)
|
|
{
|
|
slave->slaveCallback(I2C_SLAVE_EVENT_RX_REQ, slave->callbackParam);
|
|
}
|
|
#if(STD_ON == LPI2C_IP_DMA_FEATURE_AVAILABLE)
|
|
if (slave->transferType == LPI2C_USING_DMA)
|
|
{
|
|
(void)Lpi2c_Ip_SlaveStartDmaTransfer(instance);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
(void) instance;
|
|
slave->status = STATUS_LPI2C_IP_BUSY;
|
|
}
|
|
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_SlaveHandleTransmitDataEvent
|
|
* Description : handle a transmit data event for slave
|
|
*
|
|
*END**************************************************************************/
|
|
static void Lpi2c_Ip_SlaveHandleTransmitDataEvent(LPI2C_Type *baseAddr, Lpi2c_Ip_SlaveStateType *slave)
|
|
{
|
|
if (slave->txUnderrunWarning == TRUE)
|
|
{
|
|
/* Another Tx event after underflow warning means the dummy char was sent */
|
|
slave->status = STATUS_LPI2C_IP_TX_UNDERRUN;
|
|
|
|
#if (STD_ON == LPI2C_IP_EVENT_ERROR_DETECT)
|
|
if (slave->slaveCallback != NULL_PTR)
|
|
{
|
|
slave->slaveCallback(I2C_SLAVE_EVENT_UNDERRUN, slave->callbackParam);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
if(slave->bufferSize == 0U)
|
|
{
|
|
/* Out of data, call callback to allow user to provide a new buffer */
|
|
if (slave->slaveCallback != NULL_PTR)
|
|
{
|
|
slave->slaveCallback(I2C_SLAVE_EVENT_TX_EMPTY, slave->callbackParam);
|
|
}
|
|
}
|
|
|
|
if (slave->bufferSize == 0U)
|
|
{
|
|
/*
|
|
* Still no data, record tx underflow event and send dummy char.
|
|
* Special case after the last tx byte: the device will ask for more data
|
|
* but the dummy char will not be sent if NACK and then STOP condition are
|
|
* received from master. So only record a "warning" for now.
|
|
*/
|
|
slave->txUnderrunWarning = TRUE;
|
|
LPI2C_Transmit_SlaveData(baseAddr, (uint8)0xFFU);
|
|
}
|
|
else
|
|
{
|
|
LPI2C_Transmit_SlaveData(baseAddr, slave->dataBuffer[0U]);
|
|
slave->dataBuffer++;
|
|
slave->bufferSize--;
|
|
}
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_SlaveHandleReceiveDataEvent
|
|
* Description : handle a receive data event for slave
|
|
*
|
|
*END**************************************************************************/
|
|
static void Lpi2c_Ip_SlaveHandleReceiveDataEvent(const LPI2C_Type *baseAddr, Lpi2c_Ip_SlaveStateType *slave)
|
|
{
|
|
if (slave->bufferSize == 0U)
|
|
{
|
|
/* No more room for data, call callback to allow user to provide a new buffer */
|
|
if (slave->slaveCallback != NULL_PTR)
|
|
{
|
|
slave->slaveCallback(I2C_SLAVE_EVENT_RX_FULL, slave->callbackParam);
|
|
}
|
|
}
|
|
|
|
if (slave->bufferSize == 0U)
|
|
{
|
|
/* Still no room for data, record rx overrun event and dummy read data */
|
|
slave->status = STATUS_LPI2C_IP_RX_OVERRUN;
|
|
(void)LPI2C_Get_SlaveData(baseAddr);
|
|
|
|
#if (STD_ON == LPI2C_IP_EVENT_ERROR_DETECT)
|
|
if (slave->slaveCallback != NULL_PTR)
|
|
{
|
|
slave->slaveCallback(I2C_SLAVE_EVENT_OVERRUN, slave->callbackParam);
|
|
}
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
slave->dataBuffer[0U] = LPI2C_Get_SlaveData(baseAddr);
|
|
slave->dataBuffer++;
|
|
slave->bufferSize--;
|
|
}
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : LPI2C_Get_MasterFIFOErrorEventHandler
|
|
* Description : handles master fifo error
|
|
*
|
|
*END**************************************************************************/
|
|
static void LPI2C_Get_MasterFIFOErrorEventHandler(LPI2C_Type *baseAddr, Lpi2c_Ip_MasterStateType * master)
|
|
{
|
|
/* FIFO error */
|
|
LPI2C_Clear_MasterFIFOErrorEvent(baseAddr);
|
|
|
|
if(master->operatingMode == LPI2C_HIGHSPEED_MODE)
|
|
{
|
|
/* High-speed transfers end at STOP condition */
|
|
master->highSpeedInProgress = FALSE;
|
|
}
|
|
|
|
master->status = STATUS_LPI2C_IP_ERROR;
|
|
|
|
/* End transfer: no stop generation (the module will handle that by itself
|
|
if needed), reset FIFOs */
|
|
Lpi2c_Ip_MasterEndTransfer(baseAddr, master, FALSE, TRUE);
|
|
|
|
if (master->masterCallback != NULL_PTR)
|
|
{
|
|
#if (STD_ON == LPI2C_IP_EVENT_ERROR_DETECT)
|
|
master->masterCallback(I2C_MASTER_EVENT_ERROR_FIFO, master->callbackParam);
|
|
#else
|
|
master->masterCallback(I2C_MASTER_EVENT_END_TRANSFER, master->callbackParam);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : LPI2C_Get_MasterNACKDetectEventHandler
|
|
* Description : handles master NACK detection event
|
|
*
|
|
*END**************************************************************************/
|
|
static void LPI2C_Get_MasterNACKDetectEventHandler(LPI2C_Type *baseAddr, Lpi2c_Ip_MasterStateType * master)
|
|
{
|
|
|
|
#if(LPI2C_HAS_ULTRA_FAST_MODE)
|
|
/* Ignore NACK in Ultra Fast mode */
|
|
if (master->operatingMode != LPI2C_ULTRAFAST_MODE)
|
|
{
|
|
#endif
|
|
|
|
/* High-speed transfers end at STOP condition */
|
|
master->highSpeedInProgress = FALSE;
|
|
|
|
master->status = STATUS_LPI2C_IP_RECEIVED_NACK;
|
|
|
|
/* End transfer: no stop generation (the module will handle that by itself
|
|
if needed), reset FIFOs */
|
|
Lpi2c_Ip_MasterEndTransfer(baseAddr, master, FALSE, TRUE);
|
|
|
|
if (master->masterCallback != NULL_PTR)
|
|
{
|
|
#if (STD_ON == LPI2C_IP_EVENT_ERROR_DETECT)
|
|
master->masterCallback(I2C_MASTER_EVENT_NACK, master->callbackParam);
|
|
#else
|
|
master->masterCallback(I2C_MASTER_EVENT_END_TRANSFER, master->callbackParam);
|
|
#endif
|
|
}
|
|
|
|
/* Clear NACK flag */
|
|
LPI2C_Clear_MasterNACKDetectEvent(baseAddr);
|
|
#if(LPI2C_HAS_ULTRA_FAST_MODE)
|
|
}
|
|
#endif
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : LPI2C_Get_MasterArbitrationLostEventHandler
|
|
* Description : handles master arbitration lost event
|
|
*
|
|
*END**************************************************************************/
|
|
static void LPI2C_Get_MasterArbitrationLostEventHandler(LPI2C_Type *baseAddr, Lpi2c_Ip_MasterStateType * master)
|
|
{
|
|
/* Arbitration lost */
|
|
LPI2C_Clear_MasterArbitrationLostEvent(baseAddr);
|
|
|
|
/* End transfer: no stop generation (the module will handle that by itself
|
|
if needed), reset FIFOs */
|
|
Lpi2c_Ip_MasterEndTransfer(baseAddr, master, FALSE, TRUE);
|
|
|
|
master->status = STATUS_LPI2C_IP_ARBITRATION_LOST;
|
|
|
|
if (master->masterCallback != NULL_PTR)
|
|
{
|
|
#if (STD_ON == LPI2C_IP_EVENT_ERROR_DETECT)
|
|
master->masterCallback(I2C_MASTER_EVENT_ARBITRATION_LOST, master->callbackParam);
|
|
#else
|
|
master->masterCallback(I2C_MASTER_EVENT_END_TRANSFER, master->callbackParam);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_MasterCheckErrorEvents
|
|
* Description : checks error events for master module
|
|
*
|
|
*END**************************************************************************/
|
|
static void Lpi2c_Ip_MasterCheckErrorEvents(LPI2C_Type *baseAddr, Lpi2c_Ip_MasterStateType * master)
|
|
{
|
|
if (LPI2C_Get_MasterFIFOErrorEvent(baseAddr))
|
|
{
|
|
/* Handle FIFO error event */
|
|
LPI2C_Get_MasterFIFOErrorEventHandler(baseAddr, master);
|
|
}
|
|
|
|
if (LPI2C_Get_MasterArbitrationLostEvent(baseAddr))
|
|
{
|
|
/* Handle arbitration lost event */
|
|
LPI2C_Get_MasterArbitrationLostEventHandler(baseAddr, master);
|
|
}
|
|
|
|
if (LPI2C_Get_MasterNACKDetectEvent(baseAddr))
|
|
{
|
|
/* Handle Received NACK */
|
|
LPI2C_Get_MasterNACKDetectEventHandler(baseAddr, master);
|
|
}
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_MasterSend
|
|
* Description : sync send transfer handler
|
|
*
|
|
*END**************************************************************************/
|
|
static void Lpi2c_Ip_MasterSend(uint32 instance)
|
|
{
|
|
LPI2C_Type *baseAddr;
|
|
Lpi2c_Ip_MasterStateType * master;
|
|
boolean masterCmdQueueEmpty = FALSE;
|
|
|
|
#if (STD_ON == LPI2C_IP_DEV_ERROR_DETECT)
|
|
DevAssert(instance < LPI2C_INSTANCE_COUNT);
|
|
#endif
|
|
baseAddr = g_lpi2cBase[instance];
|
|
master = g_lpi2cMasterStatePtr[instance];
|
|
#if (STD_ON == LPI2C_IP_DEV_ERROR_DETECT)
|
|
DevAssert(master != NULL_PTR);
|
|
#endif
|
|
/* Check which event caused the interrupt */
|
|
if (LPI2C_Get_MasterTransmitDataRequestEvent(baseAddr))
|
|
{
|
|
/* More data needed for transmission */
|
|
if (!Lpi2c_Ip_MasterCmdQueueEmpty(master))
|
|
{
|
|
/* If there are queued commands, send them */
|
|
Lpi2c_Ip_MasterSendQueuedCmd(baseAddr, master);
|
|
}
|
|
else
|
|
{
|
|
masterCmdQueueEmpty = TRUE;
|
|
}
|
|
}
|
|
|
|
if(masterCmdQueueEmpty)
|
|
{
|
|
if (master->dataBuffer != NULL_PTR)
|
|
{
|
|
/* A transmission is in progress */
|
|
if (master->bufferSize == 0U)
|
|
{
|
|
/* There is no more data in buffer, the transmission is over */
|
|
Lpi2c_Ip_MasterEndTransfer(baseAddr, master, master->sendStop, FALSE);
|
|
|
|
master->status = STATUS_LPI2C_IP_SUCCESS;
|
|
|
|
if (master->masterCallback != NULL_PTR)
|
|
{
|
|
master->masterCallback(I2C_MASTER_EVENT_END_TRANSFER, master->callbackParam);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* Queue data bytes to fill tx fifo */
|
|
Lpi2c_Ip_MasterQueueData(baseAddr, master);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* else case */
|
|
}
|
|
}
|
|
|
|
/* Check error event */
|
|
Lpi2c_Ip_MasterCheckErrorEvents(baseAddr, master);
|
|
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_MasterGetReceivedData
|
|
* Description : read data receive from RX FIFO
|
|
*
|
|
*END**************************************************************************/
|
|
static void Lpi2c_Ip_MasterGetReceivedData(const LPI2C_Type *baseAddr, Lpi2c_Ip_MasterStateType * master)
|
|
{
|
|
/* Read data from RX FIFO */
|
|
while ((LPI2C_Get_MasterRxFIFOCount(baseAddr) > 0U) && (master->bufferSize > 0U))
|
|
{
|
|
master->dataBuffer[0U] = LPI2C_Get_MasterRxData(baseAddr);
|
|
master->dataBuffer++;
|
|
master->bufferSize--;
|
|
}
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_MasterReceive
|
|
* Description : sync receive transfer handler
|
|
*
|
|
*END**************************************************************************/
|
|
static void Lpi2c_Ip_MasterReceive(uint32 instance)
|
|
{
|
|
LPI2C_Type *baseAddr;
|
|
Lpi2c_Ip_MasterStateType * master;
|
|
#if (STD_ON == LPI2C_IP_DEV_ERROR_DETECT)
|
|
DevAssert(instance < LPI2C_INSTANCE_COUNT);
|
|
#endif
|
|
baseAddr = g_lpi2cBase[instance];
|
|
master = g_lpi2cMasterStatePtr[instance];
|
|
#if (STD_ON == LPI2C_IP_DEV_ERROR_DETECT)
|
|
DevAssert(master != NULL_PTR);
|
|
#endif
|
|
if ((LPI2C_Get_MasterReceiveDataReadyEvent(baseAddr)))
|
|
{
|
|
/* Read data from RX FIFO */
|
|
Lpi2c_Ip_MasterGetReceivedData(baseAddr, master);
|
|
|
|
if (master->bufferSize == 0U)
|
|
{
|
|
/* Done receiving */
|
|
Lpi2c_Ip_MasterEndTransfer(baseAddr, master, master->sendStop, FALSE);
|
|
|
|
master->status = STATUS_LPI2C_IP_SUCCESS;
|
|
|
|
if (master->masterCallback != NULL_PTR)
|
|
{
|
|
master->masterCallback(I2C_MASTER_EVENT_END_TRANSFER, master->callbackParam);
|
|
}
|
|
}
|
|
else if (master->bufferSize <= LPI2C_Get_MasterRxFIFOWatermark(baseAddr))
|
|
{
|
|
LPI2C_Set_MasterRxFIFOWatermark(baseAddr, (uint16)(master->bufferSize - 1U));
|
|
}
|
|
else
|
|
{
|
|
/* Continue reception */
|
|
}
|
|
}
|
|
|
|
/* Check error event */
|
|
Lpi2c_Ip_MasterCheckErrorEvents(baseAddr, master);
|
|
|
|
}
|
|
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_BaudRateConfig
|
|
* Description : configures MCCR0 register
|
|
*
|
|
*END**************************************************************************/
|
|
static void Lpi2c_Ip_BaudRateConfig(LPI2C_Type *baseAddr, const Lpi2c_Ip_BaudRateType * baudRate)
|
|
{
|
|
/* Set prescaler */
|
|
LPI2C_Set_MasterPrescaler(baseAddr, baudRate->prescaler);
|
|
/* Set hold delay */
|
|
LPI2C_Set_MasterSetupHoldDelay(baseAddr, (uint8)baudRate->setHold);
|
|
/* Set data valid delay */
|
|
LPI2C_Set_MasterDataValidDelay(baseAddr, (uint8)baudRate->dataValid);
|
|
/* Set clock HIGH period */
|
|
LPI2C_Set_MasterClockHighPeriod(baseAddr, (uint8)baudRate->clkHI);
|
|
/* Set clock low period */
|
|
LPI2C_Set_MasterClockLowPeriod(baseAddr, (uint8)baudRate->clkLO);
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_HSBaudRateConfig
|
|
* Description : configures MCCR1 register
|
|
*
|
|
*END**************************************************************************/
|
|
static void Lpi2c_Ip_HSBaudRateConfig(LPI2C_Type *baseAddr, const Lpi2c_Ip_BaudRateType * baudRate)
|
|
{
|
|
/* Set data valid delay */
|
|
LPI2C_Set_MasterDataValidDelayHS(baseAddr, (uint8)baudRate->setHoldHS);
|
|
/* Set hold delay */
|
|
LPI2C_Set_MasterSetupHoldDelayHS(baseAddr, (uint8)baudRate->dataValidHS);
|
|
/* Set clock HIGH period */
|
|
LPI2C_Set_MasterClockHighPeriodHS(baseAddr, (uint8)baudRate->clkHIHS);
|
|
/* Set clock low period */
|
|
LPI2C_Set_MasterClockLowPeriodHS(baseAddr, (uint8)baudRate->clkLOHS);
|
|
}
|
|
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_MasterSetBaudRate
|
|
* Description : set the baud rate for any subsequent I2C communication
|
|
*
|
|
* Implements : Lpi2c_Ip_MasterSetBaudRate_Activity
|
|
*END**************************************************************************/
|
|
Lpi2c_Ip_StatusType Lpi2c_Ip_MasterSetBaudRate(uint32 instance,
|
|
Lpi2c_Ip_ModeType operatingMode,
|
|
uint32 baudrate,
|
|
uint32 inputClock)
|
|
{
|
|
LPI2C_Type *baseAddr;
|
|
const Lpi2c_Ip_MasterStateType * master;
|
|
Lpi2c_Ip_BaudRateType baudRateParams;
|
|
uint32 minPrescaler = 0U;
|
|
uint32 prescaler;
|
|
uint32 clkTotal;
|
|
uint32 clkLo;
|
|
uint32 clkHi;
|
|
uint32 setHold;
|
|
uint32 dataVd;
|
|
Lpi2c_Ip_StatusType retStatus = STATUS_LPI2C_IP_BUSY;
|
|
|
|
#if (STD_ON == LPI2C_IP_DEV_ERROR_DETECT)
|
|
DevAssert(instance < LPI2C_INSTANCE_COUNT);
|
|
#endif
|
|
|
|
baseAddr = g_lpi2cBase[instance];
|
|
master = g_lpi2cMasterStatePtr[instance];
|
|
#if (STD_ON == LPI2C_IP_DEV_ERROR_DETECT)
|
|
DevAssert(master != NULL_PTR);
|
|
#endif
|
|
|
|
/* Check if driver is busy */
|
|
if(master->i2cIdle)
|
|
{
|
|
/* Disable master */
|
|
LPI2C_Set_MasterEnable(baseAddr, FALSE);
|
|
|
|
/* Ignoring the glitch filter, the baud rate formula is:
|
|
SCL_freq = Input_freq / (2^PRESCALER * (CLKLO + CLKHI + 2))
|
|
Assume CLKLO = CLKHI, SETHOLD = CLKHI, DATAVD = CLKHI/2
|
|
*/
|
|
if (baudrate != 0U)
|
|
{
|
|
/* Compute minimum prescaler for which CLKLO and CLKHI values are in valid range. Always round up. */
|
|
minPrescaler = ((inputClock - 1U) / ((baudrate) * (CLKHI_MAX_VALUE + CLKLO_MAX_VALUE + 2U))) + (uint32)1U;
|
|
for (prescaler = 0U; prescaler < 7U; prescaler++)
|
|
{
|
|
if (((uint32)1U << prescaler) >= minPrescaler)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
/* Compute CLKLO and CLKHI values for this prescaler. Round to nearest integer. */
|
|
clkTotal = (inputClock + ((baudrate << prescaler) >> 1U)) / (baudrate << prescaler);
|
|
}
|
|
else
|
|
{
|
|
prescaler = 7U;
|
|
clkTotal = (CLKHI_MAX_VALUE + CLKLO_MAX_VALUE + 2U);
|
|
}
|
|
|
|
if (clkTotal > (CLKHI_MAX_VALUE + CLKLO_MAX_VALUE + 2U))
|
|
{
|
|
clkTotal = (CLKHI_MAX_VALUE + CLKLO_MAX_VALUE + 2U);
|
|
}
|
|
|
|
/*
|
|
* If we try to compute clk high and low values using clkTotal equal with 0
|
|
* (this is the case when the baudrate is 0), we will get negative values for
|
|
* them, so we set them to 0 for this case.
|
|
*/
|
|
if (clkTotal <= 1U)
|
|
{
|
|
clkHi = 0U;
|
|
clkLo = 0U;
|
|
}
|
|
else
|
|
{
|
|
clkHi = (clkTotal - 2U) / 2U;
|
|
clkLo = clkTotal - 2U - clkHi;
|
|
}
|
|
|
|
if (clkHi < CLKHI_MIN_VALUE)
|
|
{
|
|
clkHi = CLKHI_MIN_VALUE;
|
|
}
|
|
if (clkLo < CLKLO_MIN_VALUE)
|
|
{
|
|
clkLo = CLKLO_MIN_VALUE;
|
|
}
|
|
|
|
/* Compute DATAVD and SETHOLD */
|
|
setHold = clkHi;
|
|
dataVd = clkHi >> 1U;
|
|
if (setHold < SETHOLD_MIN_VALUE)
|
|
{
|
|
setHold = SETHOLD_MIN_VALUE;
|
|
}
|
|
if (dataVd < DATAVD_MIN_VALUE)
|
|
{
|
|
dataVd = DATAVD_MIN_VALUE;
|
|
}
|
|
|
|
/* Init baud rate params */
|
|
baudRateParams.prescaler = (Lpi2c_Ip_MasterPrescalerType) prescaler;
|
|
baudRateParams.dataValid = dataVd;
|
|
baudRateParams.setHold = setHold;
|
|
baudRateParams.clkHI = clkHi;
|
|
baudRateParams.clkLO = clkLo;
|
|
|
|
/* Apply settings */
|
|
Lpi2c_Ip_BaudRateConfig(baseAddr, &baudRateParams);
|
|
|
|
/* Perform other settings related to the chosen operating mode */
|
|
Lpi2c_Ip_MasterSetOperatingMode(instance, operatingMode);
|
|
|
|
/* Re-enable master */
|
|
LPI2C_Set_MasterEnable(baseAddr, TRUE);
|
|
retStatus = STATUS_LPI2C_IP_SUCCESS;
|
|
}
|
|
(void) minPrescaler;
|
|
(void)master;
|
|
|
|
return retStatus;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_MasterSetBaudRateInit
|
|
* Description : set the baud rate for any subsequent I2C communication
|
|
*
|
|
* Implements : Lpi2c_Ip_MasterSetBaudRateInit_Activity
|
|
*END**************************************************************************/
|
|
static Lpi2c_Ip_StatusType Lpi2c_Ip_MasterSetBaudRateInit(uint32 instance,
|
|
const Lpi2c_Ip_ModeType operatingMode,
|
|
const Lpi2c_Ip_BaudRateType * baudRate)
|
|
{
|
|
|
|
LPI2C_Type *baseAddr;
|
|
const Lpi2c_Ip_MasterStateType *master;
|
|
Lpi2c_Ip_StatusType retStatus = STATUS_LPI2C_IP_BUSY;
|
|
#if (STD_ON == LPI2C_IP_DEV_ERROR_DETECT)
|
|
DevAssert(instance < LPI2C_INSTANCE_COUNT);
|
|
#endif
|
|
master = g_lpi2cMasterStatePtr[instance];
|
|
baseAddr = g_lpi2cBase[instance];
|
|
|
|
/* Check if driver is busy */
|
|
if(master->i2cIdle)
|
|
{
|
|
/* Disable master */
|
|
LPI2C_Set_MasterEnable(baseAddr, FALSE);
|
|
|
|
/* Apply settings */
|
|
Lpi2c_Ip_BaudRateConfig(baseAddr, baudRate);
|
|
|
|
/* Apply High-speed settings */
|
|
Lpi2c_Ip_HSBaudRateConfig(baseAddr, baudRate);
|
|
|
|
/* Perform other settings related to the chosen operating mode */
|
|
Lpi2c_Ip_MasterSetOperatingMode(instance, operatingMode);
|
|
|
|
/* Re-enable master */
|
|
LPI2C_Set_MasterEnable(baseAddr, TRUE);
|
|
retStatus = STATUS_LPI2C_IP_SUCCESS;
|
|
}
|
|
|
|
return retStatus;
|
|
}
|
|
|
|
#if (STD_ON == LPI2C_IP_DMA_FEATURE_AVAILABLE)
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : I2c_Ip_SlaveCmdDmaTcdInit
|
|
* Description : This function configures the TCD for I2C DMA transfers
|
|
*
|
|
*END**************************************************************************/
|
|
static void Lpi2c_Ip_SlaveCmdDmaTcdInit(void)
|
|
{
|
|
/* Configure DMA channel for send transfers */
|
|
/* Source configuration parameters */
|
|
dmaSlaveChTransferListSend[0u].Param = DMA_IP_CH_SET_SOURCE_ADDRESS;
|
|
dmaSlaveChTransferListSend[1u].Param = DMA_IP_CH_SET_SOURCE_SIGNED_OFFSET;
|
|
dmaSlaveChTransferListSend[2u].Param = DMA_IP_CH_SET_SOURCE_TRANSFER_SIZE;
|
|
/* Destination configuration parameters */
|
|
dmaSlaveChTransferListSend[3u].Param = DMA_IP_CH_SET_DESTINATION_ADDRESS;
|
|
dmaSlaveChTransferListSend[4u].Param = DMA_IP_CH_SET_DESTINATION_SIGNED_OFFSET;
|
|
dmaSlaveChTransferListSend[5u].Param = DMA_IP_CH_SET_DESTINATION_TRANSFER_SIZE;
|
|
/* Minor/Major Loop parameters */
|
|
dmaSlaveChTransferListSend[6u].Param = DMA_IP_CH_SET_MINORLOOP_SIZE;
|
|
dmaSlaveChTransferListSend[7u].Param = DMA_IP_CH_SET_MAJORLOOP_COUNT;
|
|
/* Adjustment added to source address at the beginning of TX buffer */
|
|
dmaSlaveChTransferListSend[8u].Param = DMA_IP_CH_SET_SOURCE_SIGNED_LAST_ADDR_ADJ;
|
|
|
|
/* Source configuration values */
|
|
dmaSlaveChTransferListSend[1u].Value = 1U;
|
|
dmaSlaveChTransferListSend[2u].Value = DMA_IP_TRANSFER_SIZE_1_BYTE;
|
|
/* Destination configuration values */
|
|
dmaSlaveChTransferListSend[4u].Value = 0U;
|
|
dmaSlaveChTransferListSend[5u].Value = DMA_IP_TRANSFER_SIZE_1_BYTE;
|
|
/* Minor/Major Loop values */
|
|
dmaSlaveChTransferListSend[6u].Value = 1U;
|
|
|
|
/* Configure DMA channel for receive transfers*/
|
|
/* Source configuration parameters */
|
|
dmaSlaveChTransferListReceive[0u].Param = DMA_IP_CH_SET_SOURCE_ADDRESS;
|
|
dmaSlaveChTransferListReceive[1u].Param = DMA_IP_CH_SET_SOURCE_SIGNED_OFFSET;
|
|
dmaSlaveChTransferListReceive[2u].Param = DMA_IP_CH_SET_SOURCE_TRANSFER_SIZE;
|
|
/* Destination configuration parameters */
|
|
dmaSlaveChTransferListReceive[3u].Param = DMA_IP_CH_SET_DESTINATION_ADDRESS;
|
|
dmaSlaveChTransferListReceive[4u].Param = DMA_IP_CH_SET_DESTINATION_SIGNED_OFFSET;
|
|
dmaSlaveChTransferListReceive[5u].Param = DMA_IP_CH_SET_DESTINATION_TRANSFER_SIZE;
|
|
/* Minor/Major Loop parameters */
|
|
dmaSlaveChTransferListReceive[6u].Param = DMA_IP_CH_SET_MINORLOOP_SIZE;
|
|
dmaSlaveChTransferListReceive[7u].Param = DMA_IP_CH_SET_MAJORLOOP_COUNT;
|
|
/* Adjustment added to source address at the beginning of TX buffer */
|
|
dmaSlaveChTransferListReceive[8u].Param = DMA_IP_CH_SET_SOURCE_SIGNED_LAST_ADDR_ADJ;
|
|
|
|
/* Source configuration values */
|
|
dmaSlaveChTransferListReceive[1u].Value = 0U;
|
|
dmaSlaveChTransferListReceive[2u].Value = DMA_IP_TRANSFER_SIZE_1_BYTE;
|
|
/* Destination configuration values */
|
|
dmaSlaveChTransferListReceive[4u].Value = 1U;
|
|
dmaSlaveChTransferListReceive[5u].Value = DMA_IP_TRANSFER_SIZE_1_BYTE;
|
|
/* Minor/Major Loop values */
|
|
dmaSlaveChTransferListReceive[6u].Value = 1U;
|
|
}
|
|
#endif /* STD_ON == LPI2C_IP_DMA_FEATURE_AVAILABLE */
|
|
|
|
|
|
#if (STD_ON == LPI2C_IP_DMA_FEATURE_AVAILABLE)
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : I2c_Ip_CmdDmaTcdInit
|
|
* Description : This function configures the TCD for I2C DMA transfers
|
|
*
|
|
*END**************************************************************************/
|
|
static void Lpi2c_Ip_MasterCmdDmaTcdInit(void)
|
|
{
|
|
/* Configure DMA channel for send transfers */
|
|
/* Source configuration parameters */
|
|
dmaChannelTransferListSend[0u].Param = DMA_IP_CH_SET_SOURCE_ADDRESS;
|
|
dmaChannelTransferListSend[1u].Param = DMA_IP_CH_SET_SOURCE_SIGNED_OFFSET;
|
|
dmaChannelTransferListSend[2u].Param = DMA_IP_CH_SET_SOURCE_TRANSFER_SIZE;
|
|
/* Destination configuration parameters */
|
|
dmaChannelTransferListSend[3u].Param = DMA_IP_CH_SET_DESTINATION_ADDRESS;
|
|
dmaChannelTransferListSend[4u].Param = DMA_IP_CH_SET_DESTINATION_SIGNED_OFFSET;
|
|
dmaChannelTransferListSend[5u].Param = DMA_IP_CH_SET_DESTINATION_TRANSFER_SIZE;
|
|
/* Minor/Major Loop parameters */
|
|
dmaChannelTransferListSend[6u].Param = DMA_IP_CH_SET_MINORLOOP_SIZE;
|
|
dmaChannelTransferListSend[7u].Param = DMA_IP_CH_SET_MAJORLOOP_COUNT;
|
|
/* Disable Hw auto request and enable interrupts */
|
|
dmaChannelTransferListSend[8u].Param = DMA_IP_CH_SET_CONTROL_DIS_AUTO_REQUEST;
|
|
dmaChannelTransferListSend[9u].Param = DMA_IP_CH_SET_CONTROL_EN_MAJOR_INTERRUPT;
|
|
|
|
/* Source configuration values */
|
|
dmaChannelTransferListSend[1u].Value = 1U;
|
|
dmaChannelTransferListSend[2u].Value = DMA_IP_TRANSFER_SIZE_1_BYTE;
|
|
/* Destination configuration values */
|
|
dmaChannelTransferListSend[4u].Value = 0U;
|
|
dmaChannelTransferListSend[5u].Value = DMA_IP_TRANSFER_SIZE_1_BYTE;
|
|
/* Minor/Major Loop values */
|
|
dmaChannelTransferListSend[6u].Value = 1U;
|
|
/* Disable Hw auto request and enable interrupts */
|
|
dmaChannelTransferListSend[8u].Value = 1U;
|
|
dmaChannelTransferListSend[9u].Value = 1U;
|
|
|
|
/* Configure DMA channel for receive transfers*/
|
|
/* Source configuration parameters */
|
|
dmaChannelTransferListReceive[0u].Param = DMA_IP_CH_SET_SOURCE_ADDRESS;
|
|
dmaChannelTransferListReceive[1u].Param = DMA_IP_CH_SET_SOURCE_SIGNED_OFFSET;
|
|
dmaChannelTransferListReceive[2u].Param = DMA_IP_CH_SET_SOURCE_TRANSFER_SIZE;
|
|
/* Destination configuration parameters */
|
|
dmaChannelTransferListReceive[3u].Param = DMA_IP_CH_SET_DESTINATION_ADDRESS;
|
|
dmaChannelTransferListReceive[4u].Param = DMA_IP_CH_SET_DESTINATION_SIGNED_OFFSET;
|
|
dmaChannelTransferListReceive[5u].Param = DMA_IP_CH_SET_DESTINATION_TRANSFER_SIZE;
|
|
/* Minor/Major Loop parameters */
|
|
dmaChannelTransferListReceive[6u].Param = DMA_IP_CH_SET_MINORLOOP_SIZE;
|
|
dmaChannelTransferListReceive[7u].Param = DMA_IP_CH_SET_MAJORLOOP_COUNT;
|
|
/* Disable Hw auto request and enable interrupts */
|
|
dmaChannelTransferListReceive[8u].Param = DMA_IP_CH_SET_CONTROL_DIS_AUTO_REQUEST;
|
|
dmaChannelTransferListReceive[9u].Param = DMA_IP_CH_SET_CONTROL_EN_MAJOR_INTERRUPT;
|
|
|
|
/* Source configuration values */
|
|
dmaChannelTransferListReceive[1u].Value = 0U;
|
|
dmaChannelTransferListReceive[2u].Value = DMA_IP_TRANSFER_SIZE_1_BYTE;
|
|
/* Destination configuration values */
|
|
dmaChannelTransferListReceive[4u].Value = 1U;
|
|
dmaChannelTransferListReceive[5u].Value = DMA_IP_TRANSFER_SIZE_1_BYTE;
|
|
/* Minor/Major Loop values */
|
|
dmaChannelTransferListReceive[6u].Value = 1U;
|
|
/* Disable Hw auto request and enable interrupts */
|
|
dmaChannelTransferListReceive[8u].Value = 1U;
|
|
dmaChannelTransferListReceive[9u].Value = 1U;
|
|
}
|
|
#endif /* STD_ON == LPI2C_IP_DMA_FEATURE_AVAILABLE */
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_MasterInitModule
|
|
* Description : resets software queue and resets master FIFOs
|
|
*END**************************************************************************/
|
|
static void Lpi2c_Ip_MasterInitModule(LPI2C_Type *baseAddr, Lpi2c_Ip_MasterStateType * master)
|
|
{
|
|
/* Reset software queue */
|
|
Lpi2c_Ip_MasterResetQueue(master);
|
|
|
|
/* Initialize module */
|
|
LPI2C_Init(baseAddr);
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_MasterConfigFeatures
|
|
* Description : configures glitch filter for SDA and SCL, bus idle and pin low timeout
|
|
*END**************************************************************************/
|
|
static void Lpi2c_Ip_MasterConfigFeatures(LPI2C_Type *baseAddr, const Lpi2c_Ip_MasterConfigType * userConfigPtr)
|
|
{
|
|
/* Set glitch filters for SDA and SCL */
|
|
LPI2C_Set_MasterGlitchFilterSDA(baseAddr, userConfigPtr->u32GlitchFilterSDA);
|
|
LPI2C_Set_MasterGlitchFilterSCL(baseAddr, userConfigPtr->u32GlitchFilterSCL);
|
|
|
|
/* Set bus idle timeout */
|
|
LPI2C_Set_MasterBusIdleTimeout(baseAddr, userConfigPtr->u32BusIdleTimeout);
|
|
|
|
/* Configure pin low timeout for both SDA and SCL */
|
|
LPI2C_Set_MasterPinLowTimeoutConfiguration(baseAddr, TRUE);
|
|
|
|
/* Configure Pin Low Timeout */
|
|
LPI2C_Set_MasterPinLowTimeout(baseAddr, userConfigPtr->u32PinLowTimeout);
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_MasterInit
|
|
* Description : initialize the I2C master mode driver
|
|
*
|
|
* Implements : Lpi2c_Ip_MasterInit_Activity
|
|
*END**************************************************************************/
|
|
Lpi2c_Ip_StatusType Lpi2c_Ip_MasterInit(uint32 instance,
|
|
const Lpi2c_Ip_MasterConfigType * userConfigPtr)
|
|
{
|
|
LPI2C_Type *baseAddr;
|
|
#if (STD_ON == LPI2C_IP_DEV_ERROR_DETECT)
|
|
DevAssert(userConfigPtr != NULL_PTR);
|
|
DevAssert(instance < LPI2C_INSTANCE_COUNT);
|
|
/* Check to see if the LPI2C master instance is already initialized */
|
|
DevAssert(g_lpi2cMasterStatePtr[instance] == NULL_PTR);
|
|
#endif
|
|
|
|
baseAddr = g_lpi2cBase[instance];
|
|
g_lpi2cMasterStatePtr[instance] = userConfigPtr->masterState;
|
|
Lpi2c_Ip_MasterStateType * master = g_lpi2cMasterStatePtr[instance];
|
|
|
|
/* Initialize driver status structure */
|
|
master->direction = LPI2C_IP_SEND;
|
|
master->dataBuffer = NULL_PTR;
|
|
master->bufferSize = 0U;
|
|
master->status = STATUS_LPI2C_IP_SUCCESS;
|
|
master->i2cIdle = TRUE;
|
|
master->slaveAddress = userConfigPtr->slaveAddress;
|
|
master->is10bitAddr = userConfigPtr->is10bitAddr;
|
|
master->transferType = userConfigPtr->transferType;
|
|
/* Store DMA channel number used in transfer */
|
|
master->dmaTxChannel = userConfigPtr->dmaTxChannel;
|
|
master->dmaRxChannel = userConfigPtr->dmaRxChannel;
|
|
master->masterCallback = userConfigPtr->masterCallback;
|
|
master->callbackParam = userConfigPtr->callbackParam;
|
|
master->masterCode = userConfigPtr->masterCode;
|
|
master->highSpeedInProgress = FALSE;
|
|
|
|
master->baudrateParams = userConfigPtr->baudrateParams;
|
|
|
|
/* Init/enable master module */
|
|
Lpi2c_Ip_MasterInitModule(baseAddr, master);
|
|
|
|
#if (STD_ON == LPI2C_IP_DMA_FEATURE_AVAILABLE)
|
|
if(master->transferType == LPI2C_USING_DMA)
|
|
{
|
|
Lpi2c_Ip_MasterCmdDmaTcdInit();
|
|
}
|
|
#endif /* STD_ON == LPI2C_IP_DMA_FEATURE_AVAILABLE */
|
|
|
|
/* Configure glitch filter, bus idle and pin low timeout */
|
|
Lpi2c_Ip_MasterConfigFeatures(baseAddr, userConfigPtr);
|
|
|
|
/* Set baud rate */
|
|
(void)Lpi2c_Ip_MasterSetBaudRateInit(instance, userConfigPtr->operatingMode, master->baudrateParams);
|
|
|
|
/* Set slave address */
|
|
Lpi2c_Ip_MasterSetSlaveAddr(instance, userConfigPtr->slaveAddress, userConfigPtr->is10bitAddr);
|
|
|
|
|
|
/* Enable LPI2C master */
|
|
LPI2C_Set_MasterEnable(baseAddr, TRUE);
|
|
|
|
return STATUS_LPI2C_IP_SUCCESS;
|
|
}
|
|
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_MasterDeinit
|
|
* Description : deinitialize the I2C master mode driver
|
|
*
|
|
* Implements : Lpi2c_Ip_MasterDeinit_Activity
|
|
*END**************************************************************************/
|
|
Lpi2c_Ip_StatusType Lpi2c_Ip_MasterDeinit(uint32 instance)
|
|
{
|
|
LPI2C_Type *baseAddr;
|
|
const Lpi2c_Ip_MasterStateType *master;
|
|
#if (STD_ON == LPI2C_IP_DEV_ERROR_DETECT)
|
|
DevAssert(instance < LPI2C_INSTANCE_COUNT);
|
|
#endif
|
|
baseAddr = g_lpi2cBase[instance];
|
|
master = g_lpi2cMasterStatePtr[instance];
|
|
#if (STD_ON == LPI2C_IP_DEV_ERROR_DETECT)
|
|
DevAssert(master != NULL_PTR);
|
|
#endif
|
|
|
|
g_lpi2cMasterStatePtr[instance] = NULL_PTR;
|
|
|
|
/* Disable master */
|
|
LPI2C_Set_MasterEnable(baseAddr, FALSE);
|
|
|
|
(void) master;
|
|
return STATUS_LPI2C_IP_SUCCESS;
|
|
}
|
|
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_MasterGetBaudRate
|
|
* Description : returns the currently configured baud rate
|
|
*
|
|
* Implements : Lpi2c_Ip_MasterGetBaudRate_Activity
|
|
*END**************************************************************************/
|
|
void Lpi2c_Ip_MasterGetBaudRate(uint32 instance, uint32 inputClock, uint32 *baudRate)
|
|
{
|
|
const LPI2C_Type *baseAddr;
|
|
const Lpi2c_Ip_MasterStateType *master;
|
|
uint32 prescaler;
|
|
uint32 clkLo;
|
|
uint32 clkHi;
|
|
#if (STD_ON == LPI2C_IP_DEV_ERROR_DETECT)
|
|
DevAssert(instance < LPI2C_INSTANCE_COUNT);
|
|
#endif
|
|
baseAddr = g_lpi2cBase[instance];
|
|
master = g_lpi2cMasterStatePtr[instance];
|
|
|
|
/* Ignoring the glitch filter, the baud rate formula is:
|
|
SCL_freq = Input_freq / (2^PRESCALER * (CLKLO + CLKHI + 2))
|
|
*/
|
|
prescaler = (uint32)LPI2C_Get_MasterPrescaler(baseAddr);
|
|
clkHi = (uint32)LPI2C_Get_MasterClockHighPeriod(baseAddr);
|
|
clkLo = (uint32)LPI2C_Get_MasterClockLowPeriod(baseAddr);
|
|
|
|
*baudRate = inputClock / (((uint32)1U << prescaler) * (clkLo + clkHi + (uint32)2U));
|
|
|
|
if (master->operatingMode == LPI2C_HIGHSPEED_MODE)
|
|
{
|
|
clkHi = LPI2C_Get_MasterClockHighPeriodHS(baseAddr);
|
|
clkLo = LPI2C_Get_MasterClockLowPeriodHS(baseAddr);
|
|
|
|
*baudRate = inputClock / (((uint32)1U << prescaler) * (clkLo + clkHi + (uint32)2U));
|
|
}
|
|
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_MasterSetSlaveAddr
|
|
* Description : set the slave address for any subsequent I2C communication
|
|
*
|
|
* Implements : Lpi2c_Ip_MasterSetSlaveAddr_Activity
|
|
*END**************************************************************************/
|
|
void Lpi2c_Ip_MasterSetSlaveAddr(uint32 instance, const uint16 address, const boolean is10bitAddr)
|
|
{
|
|
Lpi2c_Ip_MasterStateType * master;
|
|
#if (STD_ON == LPI2C_IP_DEV_ERROR_DETECT)
|
|
DevAssert(instance < LPI2C_INSTANCE_COUNT);
|
|
#endif
|
|
master = g_lpi2cMasterStatePtr[instance];
|
|
#if (STD_ON == LPI2C_IP_DEV_ERROR_DETECT)
|
|
DevAssert(master != NULL_PTR);
|
|
#endif
|
|
|
|
master->slaveAddress = address;
|
|
master->is10bitAddr = is10bitAddr;
|
|
}
|
|
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_MasterSendData
|
|
* Description : perform a non-blocking send transaction on the I2C bus
|
|
*
|
|
* Implements : Lpi2c_Ip_MasterSendData_Activity
|
|
*END**************************************************************************/
|
|
Lpi2c_Ip_StatusType Lpi2c_Ip_MasterSendData(uint32 instance,
|
|
uint8 * txBuff,
|
|
uint32 txSize,
|
|
boolean sendStop)
|
|
{
|
|
LPI2C_Type *baseAddr;
|
|
Lpi2c_Ip_MasterStateType *master;
|
|
Lpi2c_Ip_StatusType retStatus = STATUS_LPI2C_IP_BUSY;
|
|
#if (STD_ON == LPI2C_IP_DEV_ERROR_DETECT)
|
|
DevAssert(instance < LPI2C_INSTANCE_COUNT);
|
|
DevAssert(txBuff != NULL_PTR);
|
|
DevAssert(txSize > 0U);
|
|
#endif
|
|
|
|
baseAddr = g_lpi2cBase[instance];
|
|
master = g_lpi2cMasterStatePtr[instance];
|
|
#if (STD_ON == LPI2C_IP_DEV_ERROR_DETECT)
|
|
DevAssert(master != NULL_PTR);
|
|
#endif
|
|
/* Check if driver is busy */
|
|
if(master->i2cIdle)
|
|
{
|
|
/* Copy parameters to driver state structure */
|
|
master->bufferSize = txSize;
|
|
master->dataBuffer = txBuff;
|
|
master->direction = LPI2C_IP_SEND;
|
|
master->sendStop = sendStop;
|
|
master->i2cIdle = FALSE;
|
|
master->status = STATUS_LPI2C_IP_BUSY;
|
|
|
|
#if(STD_ON == LPI2C_IP_DMA_FEATURE_AVAILABLE)
|
|
if (master->transferType == LPI2C_USING_DMA)
|
|
{
|
|
LPI2C_Set_MasterInt(baseAddr, LPI2C_MASTER_FIFO_ERROR_INT |
|
|
LPI2C_MASTER_ARBITRATION_LOST_INT |
|
|
LPI2C_MASTER_NACK_DETECT_INT,
|
|
TRUE);
|
|
|
|
Lpi2c_Ip_MasterStartDmaTransfer(instance);
|
|
}
|
|
else
|
|
{
|
|
#endif
|
|
/* Initiate communication */
|
|
Lpi2c_Ip_MasterSendAddress(baseAddr, master, FALSE);
|
|
|
|
/* Queue data bytes to fill tx fifo */
|
|
Lpi2c_Ip_MasterQueueData(baseAddr, master);
|
|
|
|
/* Set tx FIFO watermark */
|
|
LPI2C_Set_MasterTxFIFOWatermark(baseAddr, 0U);
|
|
|
|
/* Enable relevant events */
|
|
#if(LPI2C_HAS_ULTRA_FAST_MODE)
|
|
if (master->operatingMode == LPI2C_ULTRA_FAST_MODE)
|
|
{
|
|
/* Do not enable NACK event reporting in ultra-fast mode */
|
|
LPI2C_Set_MasterInt(baseAddr, LPI2C_MASTER_FIFO_ERROR_INT |
|
|
LPI2C_MASTER_ARBITRATION_LOST_INT |
|
|
LPI2C_MASTER_TRANSMIT_DATA_INT,
|
|
TRUE);
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
LPI2C_Set_MasterInt(baseAddr, LPI2C_MASTER_FIFO_ERROR_INT |
|
|
LPI2C_MASTER_ARBITRATION_LOST_INT |
|
|
LPI2C_MASTER_NACK_DETECT_INT |
|
|
LPI2C_MASTER_PIN_LOW_TIMEOUT_INT |
|
|
LPI2C_MASTER_TRANSMIT_DATA_INT,
|
|
TRUE);
|
|
}
|
|
#if(STD_ON == LPI2C_IP_DMA_FEATURE_AVAILABLE)
|
|
}
|
|
#endif
|
|
retStatus = STATUS_LPI2C_IP_SUCCESS;
|
|
}
|
|
|
|
return retStatus;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_MasterInitSendTransfer
|
|
* Description : initializes send transfer
|
|
|
|
*END**************************************************************************/
|
|
static void Lpi2c_Ip_MasterInitSendTransfer(LPI2C_Type *baseAddr, Lpi2c_Ip_MasterStateType *master)
|
|
{
|
|
/* Initiate communication */
|
|
Lpi2c_Ip_MasterSendAddress(baseAddr, master, FALSE);
|
|
|
|
/* Queue data bytes to fill tx fifo */
|
|
Lpi2c_Ip_MasterQueueData(baseAddr, master);
|
|
|
|
/* Set tx FIFO watermark */
|
|
LPI2C_Set_MasterTxFIFOWatermark(baseAddr, 0U);
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_MasterSendDataBlocking
|
|
* Description : perform a blocking send transaction on the I2C bus
|
|
*
|
|
* Implements : Lpi2c_Ip_MasterSendDataBlocking_Activity
|
|
*END**************************************************************************/
|
|
Lpi2c_Ip_StatusType Lpi2c_Ip_MasterSendDataBlocking(uint32 instance,
|
|
uint8 * txBuff,
|
|
uint32 txSize,
|
|
boolean sendStop,
|
|
uint32 timeout)
|
|
{
|
|
uint32 CurrentTicks = 0u;
|
|
uint32 ElapsedTicks = 0u;
|
|
uint32 TimeoutTicks = OsIf_MicrosToTicks(timeout, I2C_TIMEOUT_TYPE);
|
|
Lpi2c_Ip_StatusType retStatus = STATUS_LPI2C_IP_BUSY;
|
|
|
|
#if (STD_ON == LPI2C_IP_DEV_ERROR_DETECT)
|
|
DevAssert(instance < LPI2C_INSTANCE_COUNT);
|
|
DevAssert(txBuff != NULL_PTR);
|
|
DevAssert(txSize > 0U);
|
|
#endif
|
|
LPI2C_Type *baseAddr;
|
|
baseAddr = g_lpi2cBase[instance];
|
|
|
|
Lpi2c_Ip_MasterStateType *master = g_lpi2cMasterStatePtr[instance];
|
|
#if (STD_ON == LPI2C_IP_DEV_ERROR_DETECT)
|
|
DevAssert(master != NULL_PTR);
|
|
#endif
|
|
/* Check if driver is busy */
|
|
if(master->i2cIdle)
|
|
{
|
|
master->bufferSize = txSize;
|
|
master->dataBuffer = txBuff;
|
|
master->direction = LPI2C_IP_SEND;
|
|
master->sendStop = sendStop;
|
|
master->i2cIdle = FALSE;
|
|
master->status = STATUS_LPI2C_IP_BUSY;
|
|
|
|
/* Initiate send transfer */
|
|
Lpi2c_Ip_MasterInitSendTransfer(baseAddr, master);
|
|
|
|
/* Get current ticks */
|
|
CurrentTicks = OsIf_GetCounter(I2C_TIMEOUT_TYPE);
|
|
|
|
do
|
|
{
|
|
/* Master send data */
|
|
Lpi2c_Ip_MasterSend(instance);
|
|
ElapsedTicks += OsIf_GetElapsed(&CurrentTicks, I2C_TIMEOUT_TYPE);
|
|
|
|
}while((Lpi2c_Ip_MasterGetTransferStatus(instance, NULL_PTR) == STATUS_LPI2C_IP_BUSY) && (ElapsedTicks < TimeoutTicks));
|
|
|
|
/* Check timeout */
|
|
if(ElapsedTicks >= TimeoutTicks)
|
|
{
|
|
master->status = STATUS_LPI2C_IP_TIMEOUT;
|
|
}
|
|
retStatus = master->status;
|
|
}
|
|
|
|
return retStatus;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_MasterInterruptReceiveInit
|
|
* Description : configures interrupt receive transfer
|
|
*END**************************************************************************/
|
|
static void Lpi2c_Ip_MasterInterruptReceiveInit(uint32 instance, uint32 rxSize)
|
|
{
|
|
LPI2C_Type *baseAddr = g_lpi2cBase[instance];
|
|
Lpi2c_Ip_MasterStateType *master = g_lpi2cMasterStatePtr[instance];
|
|
uint16 rxBytes;
|
|
|
|
/* Send Address */
|
|
Lpi2c_Ip_MasterSendAddress(baseAddr, master, TRUE);
|
|
|
|
/* Queue receive command for rxSize bytes */
|
|
Lpi2c_Ip_MasterQueueCmd(baseAddr, master, LPI2C_MASTER_COMMAND_RECEIVE, (uint8)(rxSize - 1U));
|
|
|
|
/* Set rx FIFO watermark */
|
|
rxBytes = LPI2C_Get_MasterRxFIFOSize(baseAddr);
|
|
if (rxBytes > rxSize)
|
|
{
|
|
rxBytes = (uint8)rxSize;
|
|
}
|
|
|
|
/* Set RX watermark */
|
|
LPI2C_Set_MasterRxFIFOWatermark(baseAddr, (uint16)(rxBytes - 1U));
|
|
}
|
|
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_MasterReceiveData
|
|
* Description : perform a non-blocking receive transaction on the I2C bus
|
|
*
|
|
* Implements : Lpi2c_Ip_MasterReceiveData_Activity
|
|
*END**************************************************************************/
|
|
Lpi2c_Ip_StatusType Lpi2c_Ip_MasterReceiveData(uint32 instance,
|
|
uint8 * rxBuff,
|
|
uint32 rxSize,
|
|
boolean sendStop)
|
|
{
|
|
LPI2C_Type *baseAddr;
|
|
Lpi2c_Ip_MasterStateType * master;
|
|
Lpi2c_Ip_StatusType retStatus = STATUS_LPI2C_IP_BUSY;
|
|
|
|
#if (STD_ON == LPI2C_IP_DEV_ERROR_DETECT)
|
|
DevAssert(instance < LPI2C_INSTANCE_COUNT);
|
|
DevAssert(rxBuff != NULL_PTR);
|
|
DevAssert(rxSize > 0U);
|
|
DevAssert(rxSize <= 256U);
|
|
#endif
|
|
|
|
baseAddr = g_lpi2cBase[instance];
|
|
master = g_lpi2cMasterStatePtr[instance];
|
|
#if (STD_ON == LPI2C_IP_DEV_ERROR_DETECT)
|
|
DevAssert(master != NULL_PTR);
|
|
#endif
|
|
/* Check if driver is busy */
|
|
if(!master->i2cIdle)
|
|
{
|
|
retStatus = STATUS_LPI2C_IP_BUSY;
|
|
}
|
|
else
|
|
{
|
|
#if(LPI2C_HAS_ULTRA_FAST_MODE)
|
|
if (master->operatingMode == LPI2C_ULTRAFAST_MODE)
|
|
{
|
|
/* No reception possible in ultra-fast mode */
|
|
retStatus = STATUS_LPI2C_IP_ERROR;
|
|
}
|
|
else
|
|
{
|
|
#endif
|
|
retStatus = STATUS_LPI2C_IP_SUCCESS;
|
|
/* Copy parameters to driver state structure */
|
|
master->bufferSize = rxSize;
|
|
master->i2cIdle = FALSE;
|
|
master->sendStop = sendStop;
|
|
master->dataBuffer = rxBuff;
|
|
master->direction = LPI2C_IP_RECEIVE;
|
|
master->status = STATUS_LPI2C_IP_BUSY;
|
|
|
|
#if(STD_ON == LPI2C_IP_DMA_FEATURE_AVAILABLE)
|
|
if (master->transferType == LPI2C_USING_DMA)
|
|
{
|
|
LPI2C_Set_MasterInt(baseAddr, LPI2C_MASTER_FIFO_ERROR_INT |
|
|
LPI2C_MASTER_ARBITRATION_LOST_INT |
|
|
LPI2C_MASTER_NACK_DETECT_INT,
|
|
TRUE);
|
|
|
|
Lpi2c_Ip_MasterStartDmaTransfer(instance);
|
|
}
|
|
else
|
|
{
|
|
#endif
|
|
|
|
/* Init interrupt receive transfer */
|
|
Lpi2c_Ip_MasterInterruptReceiveInit(instance, rxSize);
|
|
|
|
/* Enable relevant events */
|
|
if (!Lpi2c_Ip_MasterCmdQueueEmpty(master))
|
|
{
|
|
/* Enable tx event too if there are commands in the software FIFO */
|
|
LPI2C_Set_MasterInt(baseAddr, LPI2C_MASTER_FIFO_ERROR_INT |
|
|
LPI2C_MASTER_ARBITRATION_LOST_INT |
|
|
LPI2C_MASTER_NACK_DETECT_INT |
|
|
LPI2C_MASTER_TRANSMIT_DATA_INT |
|
|
LPI2C_MASTER_RECEIVE_DATA_INT,
|
|
TRUE);
|
|
}
|
|
else
|
|
{
|
|
LPI2C_Set_MasterInt(baseAddr, LPI2C_MASTER_FIFO_ERROR_INT |
|
|
LPI2C_MASTER_ARBITRATION_LOST_INT |
|
|
LPI2C_MASTER_NACK_DETECT_INT |
|
|
LPI2C_MASTER_RECEIVE_DATA_INT,
|
|
TRUE);
|
|
}
|
|
#if(STD_ON == LPI2C_IP_DMA_FEATURE_AVAILABLE)
|
|
}
|
|
#endif
|
|
#if(LPI2C_HAS_ULTRA_FAST_MODE)
|
|
}
|
|
#endif
|
|
}
|
|
|
|
return retStatus;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_MasterReceiveDataBlocking
|
|
* Description : perform a blocking receive transaction on the I2C bus
|
|
*
|
|
* Implements : Lpi2c_Ip_MasterReceiveDataBlocking_Activity
|
|
*END**************************************************************************/
|
|
Lpi2c_Ip_StatusType Lpi2c_Ip_MasterReceiveDataBlocking(uint32 instance,
|
|
uint8 * rxBuff,
|
|
uint32 rxSize,
|
|
boolean sendStop,
|
|
uint32 timeout)
|
|
{
|
|
Lpi2c_Ip_MasterStateType * master;
|
|
|
|
uint32 CurrentTicks = 0u;
|
|
uint32 ElapsedTicks = 0u;
|
|
uint32 TimeoutTicks = OsIf_MicrosToTicks(timeout, I2C_TIMEOUT_TYPE);
|
|
Lpi2c_Ip_StatusType retStatus = STATUS_LPI2C_IP_BUSY;
|
|
|
|
#if (STD_ON == LPI2C_IP_DEV_ERROR_DETECT)
|
|
DevAssert(instance < LPI2C_INSTANCE_COUNT);
|
|
DevAssert(rxBuff != NULL_PTR);
|
|
DevAssert(rxSize > 0U);
|
|
DevAssert(rxSize <= 256U);
|
|
#endif
|
|
master = g_lpi2cMasterStatePtr[instance];
|
|
#if (STD_ON == LPI2C_IP_DEV_ERROR_DETECT)
|
|
DevAssert(master != NULL_PTR);
|
|
#endif
|
|
|
|
/* Check if driver is busy */
|
|
if(master->i2cIdle)
|
|
{
|
|
master->bufferSize = rxSize;
|
|
master->dataBuffer = rxBuff;
|
|
master->direction = LPI2C_IP_RECEIVE;
|
|
master->sendStop = sendStop;
|
|
master->i2cIdle = FALSE;
|
|
master->status = STATUS_LPI2C_IP_BUSY;
|
|
|
|
/* Initiate communication */
|
|
Lpi2c_Ip_MasterInterruptReceiveInit(instance, rxSize);
|
|
|
|
CurrentTicks = OsIf_GetCounter(I2C_TIMEOUT_TYPE);
|
|
|
|
do
|
|
{
|
|
/* Master send data */
|
|
Lpi2c_Ip_MasterReceive(instance);
|
|
ElapsedTicks += OsIf_GetElapsed(&CurrentTicks, I2C_TIMEOUT_TYPE);
|
|
|
|
}while((Lpi2c_Ip_MasterGetTransferStatus(instance, NULL_PTR) == STATUS_LPI2C_IP_BUSY) && (ElapsedTicks < TimeoutTicks));
|
|
|
|
if(ElapsedTicks >= TimeoutTicks)
|
|
{
|
|
master->status = STATUS_LPI2C_IP_TIMEOUT;
|
|
}
|
|
retStatus = master->status;
|
|
}
|
|
|
|
return retStatus;
|
|
}
|
|
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_MasterGetTransferStatus
|
|
* Description : return the current status of the I2C master transfer
|
|
*
|
|
* When performing an a-sync (non-blocking) transfer, the user can call this function
|
|
* to ascertain the state of the current transfer. In addition, if the transfer is still
|
|
* in progress, the user can get the number of words that should be receive.
|
|
*
|
|
* Implements : Lpi2c_Ip_MasterGetTransferStatus_Activity
|
|
*END**************************************************************************/
|
|
Lpi2c_Ip_StatusType Lpi2c_Ip_MasterGetTransferStatus(uint32 instance,
|
|
uint32 *bytesRemaining)
|
|
{
|
|
const Lpi2c_Ip_MasterStateType * master;
|
|
#if (STD_ON == LPI2C_IP_DEV_ERROR_DETECT)
|
|
DevAssert(instance < LPI2C_INSTANCE_COUNT);
|
|
#endif
|
|
master = g_lpi2cMasterStatePtr[instance];
|
|
#if (STD_ON == LPI2C_IP_DEV_ERROR_DETECT)
|
|
DevAssert(master != NULL_PTR);
|
|
#endif
|
|
if ((bytesRemaining != NULL_PTR) && (master->transferType == LPI2C_USING_INTERRUPTS))
|
|
{
|
|
*bytesRemaining = master->bufferSize;
|
|
}
|
|
|
|
return master->status;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_MasterCheckDataTxRxEvent
|
|
* Description : checks if data send or data receive event occurred
|
|
*
|
|
*END**************************************************************************/
|
|
static void Lpi2c_Ip_MasterCheckDataTxRxEvent(LPI2C_Type *baseAddr, Lpi2c_Ip_MasterStateType * master)
|
|
{
|
|
|
|
if (LPI2C_Get_MasterTransmitDataRequestEvent(baseAddr))
|
|
{ /* Send data event */
|
|
Lpi2c_Ip_MasterHandleTransmitDataRequest(baseAddr, master);
|
|
}
|
|
|
|
if ((LPI2C_Get_MasterReceiveDataReadyEvent(baseAddr)))
|
|
{
|
|
/* Receive data event */
|
|
Lpi2c_Ip_MasterHandleReceiveDataReadyEvent(baseAddr, master);
|
|
}
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_MasterIRQHandler
|
|
* Description : handle non-blocking master operation when I2C interrupt occurs
|
|
*
|
|
*END**************************************************************************/
|
|
void Lpi2c_Ip_MasterIRQHandler(uint32 instance)
|
|
{
|
|
LPI2C_Type *baseAddr;
|
|
Lpi2c_Ip_MasterStateType * master;
|
|
#if (STD_ON == LPI2C_IP_DEV_ERROR_DETECT)
|
|
DevAssert(instance < LPI2C_INSTANCE_COUNT);
|
|
#endif
|
|
baseAddr = g_lpi2cBase[instance];
|
|
master = g_lpi2cMasterStatePtr[instance];
|
|
#if (STD_ON == LPI2C_IP_DEV_ERROR_DETECT)
|
|
DevAssert(master != NULL_PTR);
|
|
#endif
|
|
/* Check which event caused the interrupt */
|
|
Lpi2c_Ip_MasterCheckDataTxRxEvent(baseAddr, master);
|
|
|
|
/* Master check error events */
|
|
Lpi2c_Ip_MasterCheckErrorEvents(baseAddr, master);
|
|
|
|
/* Check Pin Timeout Flag */
|
|
if(LPI2C_Get_MasterPinLowTimeoutEvent(baseAddr))
|
|
{
|
|
if (master->masterCallback != NULL_PTR)
|
|
{
|
|
master->masterCallback(I2C_MASTER_EVENT_PIN_LOW_TIMEOUT, master->callbackParam);
|
|
}
|
|
|
|
/* Clear pin low timeout flag */
|
|
LPI2C_Clear_MasterPinLowTimeoutEvent(baseAddr);
|
|
}
|
|
}
|
|
|
|
static void Lpi2c_Ip_SlaveActivateEvents(uint32 instance)
|
|
{
|
|
LPI2C_Type *baseAddr;
|
|
baseAddr = g_lpi2cBase[instance];
|
|
const Lpi2c_Ip_SlaveStateType *slave = g_lpi2cSlaveStatePtr[instance];
|
|
|
|
if (slave->transferType == LPI2C_USING_DMA)
|
|
{
|
|
/* Activate events */
|
|
LPI2C_Set_SlaveInt(baseAddr, LPI2C_SLAVE_BIT_ERROR_INT |
|
|
LPI2C_SLAVE_FIFO_ERROR_INT |
|
|
LPI2C_SLAVE_STOP_DETECT_INT |
|
|
LPI2C_SLAVE_REPEATED_START_INT |
|
|
LPI2C_SLAVE_ADDRESS_VALID_INT,
|
|
TRUE);
|
|
}
|
|
|
|
if (slave->transferType == LPI2C_USING_INTERRUPTS)
|
|
{
|
|
/* Activate events */
|
|
#if defined(ERRATA_E10792)
|
|
LPI2C_Set_SlaveInt(baseAddr, LPI2C_SLAVE_BIT_ERROR_INT |
|
|
LPI2C_SLAVE_FIFO_ERROR_INT |
|
|
LPI2C_SLAVE_STOP_DETECT_INT |
|
|
LPI2C_SLAVE_REPEATED_START_INT |
|
|
LPI2C_SLAVE_ADDRESS_VALID_INT |
|
|
LPI2C_SLAVE_RECEIVE_DATA_INT,
|
|
TRUE);
|
|
|
|
#else
|
|
LPI2C_Set_SlaveInt(baseAddr, LPI2C_SLAVE_BIT_ERROR_INT |
|
|
LPI2C_SLAVE_FIFO_ERROR_INT |
|
|
LPI2C_SLAVE_STOP_DETECT_INT |
|
|
LPI2C_SLAVE_REPEATED_START_INT |
|
|
LPI2C_SLAVE_ADDRESS_VALID_INT |
|
|
LPI2C_SLAVE_RECEIVE_DATA_INT |
|
|
LPI2C_SLAVE_TRANSMIT_DATA_INT,
|
|
TRUE);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
/* Enable LPI2C slave */
|
|
LPI2C_Set_SlaveEnable(baseAddr, TRUE);
|
|
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_SlaveConigureAddress
|
|
* Description : configures slave address
|
|
*END**************************************************************************/
|
|
static void Lpi2c_Ip_SlaveConigureAddress(LPI2C_Type *baseAddr, uint16 slaveAddr, boolean is10bitAddr)
|
|
{
|
|
LPI2C_Set_SlaveAddr0(baseAddr, slaveAddr);
|
|
|
|
if (is10bitAddr)
|
|
{
|
|
LPI2C_Set_SlaveAddrConfig(baseAddr, LPI2C_SLAVE_ADDR_MATCH_0_10BIT);
|
|
}
|
|
else
|
|
{
|
|
LPI2C_Set_SlaveAddrConfig(baseAddr, LPI2C_SLAVE_ADDR_MATCH_0_7BIT);
|
|
}
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_SlaveConfigureGlitchFilter
|
|
* Description : configures slave glitch filter
|
|
*END**************************************************************************/
|
|
static void Lpi2c_Ip_SlaveConfigureGlitchFilter(LPI2C_Type *baseAddr, uint32 u32GlitchFilterSDA, uint32 u32GlitchFilterSCL)
|
|
{
|
|
/* Set SDA glitch filter */
|
|
LPI2C_Set_SlaveGlitchFilterSDA(baseAddr, u32GlitchFilterSDA);
|
|
/* Set SCL glitch filter */
|
|
LPI2C_Set_SlaveGlitchFilterSCL(baseAddr, u32GlitchFilterSCL);
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_SlaveInit
|
|
* Description : initialize the I2C slave mode driver
|
|
*
|
|
* Implements : Lpi2c_Ip_SlaveInit_Activity
|
|
*END**************************************************************************/
|
|
Lpi2c_Ip_StatusType Lpi2c_Ip_SlaveInit(uint32 instance,
|
|
const Lpi2c_Ip_SlaveConfigType * userConfigPtr)
|
|
{
|
|
LPI2C_Type *baseAddr;
|
|
|
|
#if (STD_ON == LPI2C_IP_DEV_ERROR_DETECT)
|
|
DevAssert(userConfigPtr != NULL_PTR);
|
|
DevAssert(instance < LPI2C_INSTANCE_COUNT);
|
|
DevAssert(g_lpi2cSlaveStatePtr[instance] == NULL_PTR);
|
|
#endif
|
|
|
|
baseAddr = g_lpi2cBase[instance];
|
|
g_lpi2cSlaveStatePtr[instance] = userConfigPtr->slaveState;
|
|
Lpi2c_Ip_SlaveStateType * slave = g_lpi2cSlaveStatePtr[instance];
|
|
|
|
/* Initialize driver status structure */
|
|
slave->status = STATUS_LPI2C_IP_SUCCESS;
|
|
slave->slaveCallback = userConfigPtr->slaveCallback;
|
|
slave->callbackParam = userConfigPtr->callbackParam;
|
|
slave->dataBuffer = NULL_PTR;
|
|
slave->bufferSize = 0U;
|
|
slave->direction = LPI2C_IP_SEND;
|
|
slave->transferType = userConfigPtr->transferType;
|
|
/* Store DMA channel number used in transfer */
|
|
slave->dmaTxChannel = userConfigPtr->dmaTxChannel;
|
|
slave->dmaRxChannel = userConfigPtr->dmaRxChannel;
|
|
slave->isTransferInProgress = FALSE;
|
|
slave->is10bitAddress = userConfigPtr->is10bitAddr;
|
|
slave->repeatedStarts = 0U;
|
|
slave->slaveListening = userConfigPtr->slaveListening;
|
|
|
|
/* Initialize module */
|
|
LPI2C_Init(baseAddr);
|
|
|
|
#if (STD_ON == LPI2C_IP_DMA_FEATURE_AVAILABLE)
|
|
if(slave->transferType == LPI2C_USING_DMA)
|
|
{
|
|
Lpi2c_Ip_SlaveCmdDmaTcdInit();
|
|
}
|
|
#endif
|
|
|
|
/* Configure slave address */
|
|
Lpi2c_Ip_SlaveConigureAddress(baseAddr, userConfigPtr->slaveAddress, userConfigPtr->is10bitAddr);
|
|
|
|
/* Configure operating mode */
|
|
Lpi2c_Ip_SlaveSetOperatingMode(instance, userConfigPtr->operatingMode);
|
|
|
|
/* Set glitch filters for SDA and SCL */
|
|
Lpi2c_Ip_SlaveConfigureGlitchFilter(baseAddr, userConfigPtr->u32GlitchFilterSDA, userConfigPtr->u32GlitchFilterSCL);
|
|
|
|
if(slave->slaveListening)
|
|
{
|
|
Lpi2c_Ip_SlaveActivateEvents(instance);
|
|
}
|
|
|
|
return STATUS_LPI2C_IP_SUCCESS;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_StartListening
|
|
* Description : Makes a slave channel available for processing request in case
|
|
* slave is in not listening mode
|
|
* Implements : I2c_Ip_StartListening_Activity
|
|
*
|
|
*END**************************************************************************/
|
|
void Lpi2c_Ip_StartListening(uint32 u32Instance)
|
|
{
|
|
const Lpi2c_Ip_SlaveStateType * slave;
|
|
slave = g_lpi2cSlaveStatePtr[u32Instance];
|
|
|
|
#if (STD_ON == LPI2C_IP_DEV_ERROR_DETECT)
|
|
DevAssert(slave != NULL_PTR);
|
|
DevAssert(!slave->slaveListening);
|
|
#endif
|
|
|
|
Lpi2c_Ip_SlaveActivateEvents(u32Instance);
|
|
(void) slave;
|
|
}
|
|
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_SlaveDeinit
|
|
* Description : de-initialize the I2C slave mode driver
|
|
*
|
|
* Implements : Lpi2c_Ip_SlaveDeinit_Activity
|
|
*END**************************************************************************/
|
|
Lpi2c_Ip_StatusType Lpi2c_Ip_SlaveDeinit(uint32 instance)
|
|
{
|
|
LPI2C_Type *baseAddr;
|
|
#if (STD_ON == LPI2C_IP_DEV_ERROR_DETECT)
|
|
DevAssert(instance < LPI2C_INSTANCE_COUNT);
|
|
#endif
|
|
baseAddr = g_lpi2cBase[instance];
|
|
const Lpi2c_Ip_SlaveStateType *slave = g_lpi2cSlaveStatePtr[instance];
|
|
#if (STD_ON == LPI2C_IP_DEV_ERROR_DETECT)
|
|
DevAssert(slave != NULL_PTR);
|
|
#endif
|
|
if ((slave->transferType == LPI2C_USING_DMA) && (TRUE == slave->slaveListening))
|
|
{
|
|
/* Disable LPI2C DMA requests. */
|
|
(void)LPI2C_Set_SlaveRxDMA(baseAddr, FALSE);
|
|
(void)LPI2C_Set_SlaveTxDMA(baseAddr, FALSE);
|
|
}
|
|
|
|
g_lpi2cSlaveStatePtr[instance] = NULL_PTR;
|
|
|
|
/* Disable LPI2C slave */
|
|
LPI2C_Set_SlaveEnable(baseAddr, FALSE);
|
|
|
|
return STATUS_LPI2C_IP_SUCCESS;
|
|
}
|
|
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_SlaveSetTxBuffer
|
|
* Description : Provide a buffer for transmitting data.
|
|
*
|
|
* Implements : Lpi2c_Ip_SlaveSetTxBuffer_Activity
|
|
*END**************************************************************************/
|
|
Lpi2c_Ip_StatusType Lpi2c_Ip_SlaveSetBuffer(uint32 instance,
|
|
uint8 * dataBuff,
|
|
uint32 dataSize)
|
|
{
|
|
Lpi2c_Ip_SlaveStateType * slave;
|
|
#if (STD_ON == LPI2C_IP_DEV_ERROR_DETECT)
|
|
DevAssert(instance < LPI2C_INSTANCE_COUNT);
|
|
DevAssert(dataBuff != NULL_PTR);
|
|
DevAssert(dataSize > 0U);
|
|
#endif
|
|
slave = g_lpi2cSlaveStatePtr[instance];
|
|
#if (STD_ON == LPI2C_IP_DEV_ERROR_DETECT)
|
|
DevAssert(slave != NULL_PTR);
|
|
#endif
|
|
slave->dataBuffer = dataBuff;
|
|
slave->bufferSize = dataSize;
|
|
|
|
return STATUS_LPI2C_IP_SUCCESS;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_SlaveGetTransferStatus
|
|
* Description : return the current status of the I2C slave transfer
|
|
*
|
|
* When performing an a-sync (non-blocking) transfer, the user can call this function
|
|
* to ascertain the state of the current transfer. In addition, if the transfer is still
|
|
* in progress, the user can get the number of words that should be receive.
|
|
*
|
|
* Implements : Lpi2c_Ip_SlaveGetTransferStatus_Activity
|
|
*END**************************************************************************/
|
|
Lpi2c_Ip_StatusType Lpi2c_Ip_SlaveGetTransferStatus(uint32 instance,
|
|
uint32 *bytesRemaining)
|
|
{
|
|
const Lpi2c_Ip_SlaveStateType *slave;
|
|
#if (STD_ON == LPI2C_IP_DEV_ERROR_DETECT)
|
|
DevAssert(instance < LPI2C_INSTANCE_COUNT);
|
|
#endif
|
|
slave = g_lpi2cSlaveStatePtr[instance];
|
|
#if (STD_ON == LPI2C_IP_DEV_ERROR_DETECT)
|
|
DevAssert(slave != NULL_PTR);
|
|
#endif
|
|
if ((bytesRemaining != NULL_PTR) && (slave->transferType == LPI2C_USING_INTERRUPTS))
|
|
{
|
|
*bytesRemaining = slave->bufferSize;
|
|
}
|
|
|
|
return slave->status;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : LPI2C_DRV_SlaveEndTransfer
|
|
* Description : ends current transmission or reception
|
|
*
|
|
*END**************************************************************************/
|
|
static void Lpi2c_Ip_SlaveEndTransfer(LPI2C_Type *baseAddr)
|
|
{
|
|
/* Deactivate events */
|
|
|
|
LPI2C_Set_SlaveInt(baseAddr, LPI2C_SLAVE_BIT_ERROR_INT |
|
|
LPI2C_SLAVE_FIFO_ERROR_INT |
|
|
LPI2C_SLAVE_STOP_DETECT_INT |
|
|
LPI2C_SLAVE_REPEATED_START_INT |
|
|
LPI2C_SLAVE_ADDRESS_VALID_INT |
|
|
LPI2C_SLAVE_RECEIVE_DATA_INT |
|
|
LPI2C_SLAVE_TRANSMIT_DATA_INT,
|
|
FALSE);
|
|
|
|
/* Disable LPI2C slave */
|
|
LPI2C_Set_SlaveEnable(baseAddr, FALSE);
|
|
|
|
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_SlaveEndTransferHandler
|
|
* Description : handle slave end transfer operations
|
|
*
|
|
*END**************************************************************************/
|
|
static void Lpi2c_Ip_SlaveEndTransferHandler(const Lpi2c_Ip_SlaveStateType *slave, LPI2C_Type *baseAddr)
|
|
{
|
|
/* Check slave state */
|
|
#if (STD_ON == LPI2C_IP_DEV_ERROR_DETECT)
|
|
DevAssert(slave != NULL_PTR);
|
|
#endif
|
|
|
|
#if(STD_ON == LPI2C_IP_DMA_FEATURE_AVAILABLE)
|
|
/* Stop DMA channel if slave is transferring data in DMA mode */
|
|
if (slave->transferType == LPI2C_USING_DMA)
|
|
{
|
|
if(slave->direction == LPI2C_IP_SEND)
|
|
{
|
|
/* Stop TX DMA channel */
|
|
(void)Dma_Ip_SetLogicChannelCommand(slave->dmaTxChannel, DMA_IP_CH_CLEAR_HARDWARE_REQUEST);
|
|
}
|
|
else
|
|
{
|
|
/* Stop RX DMA channel */
|
|
(void)Dma_Ip_SetLogicChannelCommand(slave->dmaRxChannel, DMA_IP_CH_CLEAR_HARDWARE_REQUEST);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
if (!slave->slaveListening)
|
|
{
|
|
Lpi2c_Ip_SlaveEndTransfer(baseAddr);
|
|
}
|
|
|
|
if(slave->slaveCallback != NULL_PTR)
|
|
{
|
|
slave->slaveCallback(I2C_SLAVE_EVENT_STOP, slave->callbackParam);
|
|
}
|
|
|
|
(void) baseAddr;
|
|
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_SlaveCheckDataEvent
|
|
* Description : check slave adress valid and tx/rx event
|
|
*
|
|
*END**************************************************************************/
|
|
static void Lpi2c_Ip_SlaveCheckDataEvent(uint32 instance, LPI2C_Type *baseAddr, Lpi2c_Ip_SlaveStateType * slave)
|
|
{
|
|
boolean slaveInterrupt = FALSE;
|
|
|
|
/* Check which event caused the interrupt */
|
|
if (LPI2C_Get_SlaveAddressValidEvent(baseAddr))
|
|
{
|
|
Lpi2c_Ip_SlaveHandleAddressValidEvent(instance, baseAddr, slave);
|
|
}
|
|
|
|
/* Check transmit event */
|
|
if (LPI2C_Get_SlaveTransmitDataEvent(baseAddr))
|
|
{
|
|
slaveInterrupt = LPI2C_Get_SlaveInt(baseAddr, (uint32)LPI2C_SLAVE_TRANSMIT_DATA_INT);
|
|
if (slaveInterrupt)
|
|
{
|
|
/* Handle transmit event */
|
|
Lpi2c_Ip_SlaveHandleTransmitDataEvent(baseAddr, slave);
|
|
}
|
|
}
|
|
|
|
/* Check receive event */
|
|
if (LPI2C_Get_SlaveReceiveDataEvent(baseAddr))
|
|
{
|
|
slaveInterrupt = LPI2C_Get_SlaveInt(baseAddr, (uint32)LPI2C_SLAVE_RECEIVE_DATA_INT);
|
|
if (slaveInterrupt)
|
|
{
|
|
/* Handle receive event */
|
|
Lpi2c_Ip_SlaveHandleReceiveDataEvent(baseAddr, slave);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_SlaveStopDetectHandler
|
|
* Description : handles stop/repeated start event
|
|
*
|
|
*END**************************************************************************/
|
|
static void Lpi2c_Ip_SlaveStopDetectHandler(LPI2C_Type *baseAddr, Lpi2c_Ip_SlaveStateType * slave)
|
|
{
|
|
/* Either STOP or repeated START have the same meaning here: the current transfer is over */
|
|
LPI2C_Clear_SlaveSTOPDetectEvent(baseAddr);
|
|
LPI2C_Clear_SlaveRepeatedStartEvent(baseAddr);
|
|
|
|
#if defined(ERRATA_E10792)
|
|
/* Deactivate interrupts for transmitting data */
|
|
LPI2C_Set_SlaveInt(baseAddr, (uint32)LPI2C_SLAVE_TRANSMIT_DATA_INT, FALSE);
|
|
#endif
|
|
|
|
if (slave->status == STATUS_LPI2C_IP_BUSY)
|
|
{
|
|
/* Report success if no error was recorded */
|
|
slave->status = STATUS_LPI2C_IP_SUCCESS;
|
|
}
|
|
|
|
Lpi2c_Ip_SlaveEndTransferHandler(slave, baseAddr);
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_SlaveBitErrorEventHandler
|
|
* Description : handles slave bit error event
|
|
*
|
|
*END**************************************************************************/
|
|
static void Lpi2c_Ip_SlaveBitErrorEventHandler(LPI2C_Type *baseAddr, Lpi2c_Ip_SlaveStateType * slave)
|
|
{
|
|
slave->status = STATUS_LPI2C_IP_ERROR;
|
|
|
|
LPI2C_Clear_SlaveBitErrorEvent(baseAddr);
|
|
|
|
#if (STD_ON == LPI2C_IP_EVENT_ERROR_DETECT)
|
|
if (slave->slaveCallback != NULL_PTR)
|
|
{
|
|
slave->slaveCallback(I2C_SLAVE_EVENT_ERROR_BIT, slave->callbackParam);
|
|
}
|
|
#endif
|
|
|
|
#if defined(ERRATA_E10792)
|
|
/* Deactivate interrupts for transmitting data */
|
|
LPI2C_Set_SlaveInt(baseAddr, (uint32)LPI2C_SLAVE_TRANSMIT_DATA_INT, FALSE);
|
|
#endif
|
|
|
|
/* Slave end transfer */
|
|
Lpi2c_Ip_SlaveEndTransferHandler(slave, baseAddr);
|
|
}
|
|
|
|
#if(LPI2C_HAS_ULTRA_FAST_MODE)
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_SlaveFIFOErrorEventHandler
|
|
* Description : handles slave FIFO error event
|
|
*
|
|
*END**************************************************************************/
|
|
static void Lpi2c_Ip_SlaveFIFOErrorEventHandler(LPI2C_Type *baseAddr, Lpi2c_Ip_SlaveStateType * slave)
|
|
{
|
|
/* In Ultra-Fast mode clock stretching is disabled, so it is possible to get
|
|
this event if the slave can't keep up */
|
|
slave->status = STATUS_LPI2C_IP_RX_OVERRUN;
|
|
LPI2C_Clear_SlaveFIFOErrorEvent(baseAddr);
|
|
|
|
#if defined(ERRATA_E10792)
|
|
/* Deactivate interrupts for transmitting data */
|
|
LPI2C_Set_SlaveInt(baseAddr, LPI2C_SLAVE_TRANSMIT_DATA_INT, FALSE);
|
|
#endif
|
|
|
|
Lpi2c_Ip_SlaveEndTransferHandler(slave, baseAddr);
|
|
}
|
|
#endif
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_SlaveCheckErrorEvent
|
|
* Description : checks for slave errors
|
|
*
|
|
*END**************************************************************************/
|
|
static void Lpi2c_Ip_SlaveCheckErrorEvent(LPI2C_Type *baseAddr, Lpi2c_Ip_SlaveStateType * slave)
|
|
{
|
|
if (LPI2C_Get_SlaveBitErrorEvent(baseAddr))
|
|
{
|
|
/* Handle slave bit error event */
|
|
Lpi2c_Ip_SlaveBitErrorEventHandler(baseAddr, slave);
|
|
}
|
|
|
|
#if(LPI2C_HAS_ULTRA_FAST_MODE)
|
|
if (LPI2C_Get_SlaveFIFOErrorEvent(baseAddr))
|
|
{
|
|
/* Handle slave FIFO error event */
|
|
Lpi2c_Ip_SlaveFIFOErrorEventHandler(baseAddr, slave);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_SlaveIRQHandler
|
|
* Description : handle non-blocking slave operation when I2C interrupt occurs
|
|
*
|
|
*END**************************************************************************/
|
|
void Lpi2c_Ip_SlaveIRQHandler(uint32 instance)
|
|
{
|
|
LPI2C_Type *baseAddr;
|
|
Lpi2c_Ip_SlaveStateType * slave;
|
|
boolean stopDetect = FALSE, repeatStartDetect = FALSE;
|
|
#if (STD_ON == LPI2C_IP_DEV_ERROR_DETECT)
|
|
DevAssert(instance < LPI2C_INSTANCE_COUNT);
|
|
#endif
|
|
baseAddr = g_lpi2cBase[instance];
|
|
slave = g_lpi2cSlaveStatePtr[instance];
|
|
#if (STD_ON == LPI2C_IP_DEV_ERROR_DETECT)
|
|
DevAssert(slave != NULL_PTR);
|
|
#endif
|
|
|
|
/* Check address valid and tx/rx event */
|
|
Lpi2c_Ip_SlaveCheckDataEvent(instance, baseAddr, slave);
|
|
|
|
stopDetect = LPI2C_Get_SlaveSTOPDetectEvent(baseAddr);
|
|
repeatStartDetect = LPI2C_Get_SlaveRepeatedStartEvent(baseAddr);
|
|
|
|
if (repeatStartDetect)
|
|
{
|
|
slave->repeatedStarts++;
|
|
|
|
if ((slave->repeatedStarts == 1U) && (slave->is10bitAddress))
|
|
{
|
|
repeatStartDetect = FALSE;
|
|
LPI2C_Clear_SlaveRepeatedStartEvent(baseAddr);
|
|
}
|
|
}
|
|
|
|
if ((stopDetect == TRUE) || (repeatStartDetect == TRUE))
|
|
{
|
|
/* Stop/repeated start detected */
|
|
Lpi2c_Ip_SlaveStopDetectHandler(baseAddr, slave);
|
|
|
|
if (stopDetect == TRUE)
|
|
{
|
|
/* reset repetead starts for a new transfer */
|
|
slave->repeatedStarts = 0U;
|
|
}
|
|
}
|
|
|
|
/* Check for slave errors */
|
|
Lpi2c_Ip_SlaveCheckErrorEvent(baseAddr, slave);
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_ModuleIRQHandler
|
|
* Description : handle events for lpi2c module
|
|
*
|
|
*END**************************************************************************/
|
|
void Lpi2c_Ip_ModuleIRQHandler(uint32 instance)
|
|
{
|
|
LPI2C_Type *baseAddr;
|
|
uint32 u32MasterIsrEnable = 0u;
|
|
uint32 u32MasterIsrStatus = 0u;
|
|
uint32 u32SlaveIsrEnable = 0u;
|
|
uint32 u32SlaveIsrStatus = 0u;
|
|
|
|
#if (STD_ON == LPI2C_IP_DEV_ERROR_DETECT)
|
|
DevAssert(instance < LPI2C_INSTANCE_COUNT);
|
|
#endif
|
|
|
|
baseAddr = g_lpi2cBase[instance];
|
|
|
|
/* Check spurious interrupt */
|
|
if ((NULL_PTR != g_lpi2cSlaveStatePtr[instance]) || (NULL_PTR != g_lpi2cMasterStatePtr[instance]))
|
|
{
|
|
/* the driver has been initialized */
|
|
/* Check i2c interrupts */
|
|
u32MasterIsrEnable = baseAddr->MIER & (LPI2C_MIER_DMIE_MASK | LPI2C_MIER_PLTIE_MASK | LPI2C_MIER_FEIE_MASK | LPI2C_MIER_ALIE_MASK | LPI2C_MIER_NDIE_MASK |
|
|
LPI2C_MIER_SDIE_MASK | LPI2C_MIER_EPIE_MASK | LPI2C_MIER_RDIE_MASK | LPI2C_MIER_TDIE_MASK);
|
|
|
|
u32MasterIsrStatus = baseAddr->MSR & ( LPI2C_MSR_DMF_MASK | LPI2C_MSR_PLTF_MASK | LPI2C_MSR_FEF_MASK | LPI2C_MSR_ALF_MASK | LPI2C_MSR_NDF_MASK |
|
|
LPI2C_MSR_SDF_MASK | LPI2C_MSR_EPF_MASK | LPI2C_MSR_RDF_MASK | LPI2C_MSR_TDF_MASK);
|
|
|
|
u32SlaveIsrEnable = baseAddr->SIER & (LPI2C_SIER_SARIE_MASK | LPI2C_SIER_GCIE_MASK | LPI2C_SIER_AM0IE_MASK | LPI2C_SIER_FEIE_MASK |
|
|
LPI2C_SIER_BEIE_MASK | LPI2C_SIER_SDIE_MASK | LPI2C_SIER_RSIE_MASK | LPI2C_SIER_TAIE_MASK |
|
|
LPI2C_SIER_AVIE_MASK | LPI2C_SIER_RDIE_MASK | LPI2C_SIER_TDIE_MASK | LPI2C_SIER_AM1IE_MASK);
|
|
|
|
u32SlaveIsrStatus = baseAddr->SSR & (LPI2C_SSR_SARF_MASK | LPI2C_SSR_GCF_MASK | LPI2C_SSR_AM1F_MASK | LPI2C_SSR_AM0F_MASK | LPI2C_SSR_FEF_MASK |
|
|
LPI2C_SSR_BEF_MASK | LPI2C_SSR_SDF_MASK | LPI2C_SSR_RSF_MASK | LPI2C_SSR_TAF_MASK | LPI2C_SSR_AVF_MASK |
|
|
LPI2C_SSR_RDF_MASK | LPI2C_SSR_TDF_MASK);
|
|
|
|
if (((0u != u32MasterIsrEnable) && (0u != u32MasterIsrStatus)) || ((0u != u32SlaveIsrEnable) && (0u != u32SlaveIsrStatus)))
|
|
{
|
|
/* Check if module is master or slave */
|
|
if (g_lpi2cSlaveStatePtr[instance] == NULL_PTR)
|
|
{
|
|
Lpi2c_Ip_MasterIRQHandler(instance);
|
|
}
|
|
else
|
|
{
|
|
Lpi2c_Ip_SlaveIRQHandler(instance);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* Clear all flags */
|
|
baseAddr->MSR &= (uint32)0xFFFFFFFFU;
|
|
baseAddr->SSR &= (uint32)0xFFFFFFFFU;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* Clear all flags */
|
|
baseAddr->MSR &= (uint32)0xFFFFFFFFU;
|
|
baseAddr->SSR &= (uint32)0xFFFFFFFFU;
|
|
}
|
|
|
|
/* Cast to void to avoid compiler warnings */
|
|
(void) u32MasterIsrEnable;
|
|
(void) u32MasterIsrStatus;
|
|
(void) u32SlaveIsrEnable;
|
|
(void) u32SlaveIsrStatus;
|
|
}
|
|
|
|
#if(STD_ON == LPI2C_IP_DMA_FEATURE_AVAILABLE)
|
|
|
|
#if (LPI2C_INSTANCE_COUNT >= 1U)
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : I2C0_DmaCompleteNotification
|
|
* Description : Dma complete notification for instance 0
|
|
*
|
|
*END**************************************************************************/
|
|
void LPI2C0_DmaCompleteNotification(void)
|
|
{
|
|
#ifdef LPI2C_ENABLE_USER_MODE_SUPPORT
|
|
#if (STD_ON == LPI2C_ENABLE_USER_MODE_SUPPORT)
|
|
OsIf_Trusted_Call1param(Lpi2c_Ip_MasterCompleteDMATransfer,(0U));
|
|
#else
|
|
Lpi2c_Ip_MasterCompleteDMATransfer(0U);
|
|
#endif
|
|
#endif
|
|
}
|
|
#endif /* LPI2C_INSTANCE_COUNT >= 1U */
|
|
|
|
#if (LPI2C_INSTANCE_COUNT >= 2U)
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : I2C1_DmaCompleteNotification
|
|
* Description : Dma complete notification for instance 1
|
|
*
|
|
*END**************************************************************************/
|
|
void LPI2C1_DmaCompleteNotification(void)
|
|
{
|
|
#ifdef LPI2C_ENABLE_USER_MODE_SUPPORT
|
|
#if (STD_ON == LPI2C_ENABLE_USER_MODE_SUPPORT)
|
|
OsIf_Trusted_Call1param(Lpi2c_Ip_MasterCompleteDMATransfer,(1U));
|
|
#else
|
|
Lpi2c_Ip_MasterCompleteDMATransfer(1U);
|
|
#endif
|
|
#endif
|
|
}
|
|
#endif /* LPI2C_INSTANCE_COUNT >= 2U */
|
|
|
|
#endif /* STD_ON == LPI2C_IP_DMA_FEATURE_AVAILABLE */
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_SetMasterCallback
|
|
* Description : Sets the master callback
|
|
*
|
|
*END**************************************************************************/
|
|
void Lpi2c_Ip_SetMasterCallback(uint32 u32Instance, Lpi2c_Ip_MasterCallbackType masterCallback)
|
|
{
|
|
Lpi2c_Ip_MasterStateType * master;
|
|
#if (STD_ON == LPI2C_IP_DEV_ERROR_DETECT)
|
|
DevAssert(u32Instance < LPI2C_INSTANCE_COUNT);
|
|
#endif
|
|
master = g_lpi2cMasterStatePtr[u32Instance];
|
|
#if (STD_ON == LPI2C_IP_DEV_ERROR_DETECT)
|
|
DevAssert(master != NULL_PTR);
|
|
#endif
|
|
|
|
master->masterCallback = masterCallback;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_SetSlaveCallback
|
|
* Description : Sets the slave callback
|
|
*
|
|
*END**************************************************************************/
|
|
void Lpi2c_Ip_SetSlaveCallback(uint32 u32Instance, Lpi2c_Ip_SlaveCallbackType slaveCallback)
|
|
{
|
|
Lpi2c_Ip_SlaveStateType * slave;
|
|
#if (STD_ON == LPI2C_IP_DEV_ERROR_DETECT)
|
|
DevAssert(u32Instance < LPI2C_INSTANCE_COUNT);
|
|
#endif
|
|
slave = g_lpi2cSlaveStatePtr[u32Instance];
|
|
#if (STD_ON == LPI2C_IP_DEV_ERROR_DETECT)
|
|
DevAssert(slave != NULL_PTR);
|
|
#endif
|
|
|
|
slave->slaveCallback = slaveCallback;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpi2c_Ip_SetMasterHighSpeedMode
|
|
* Description : Sets high speed mode for master
|
|
*
|
|
*END**************************************************************************/
|
|
void Lpi2c_Ip_SetMasterHighSpeedMode(uint32 u32Instance, boolean bHighSpeedEnabled)
|
|
{
|
|
Lpi2c_Ip_MasterStateType * master;
|
|
#if (STD_ON == LPI2C_IP_DEV_ERROR_DETECT)
|
|
DevAssert(u32Instance < LPI2C_INSTANCE_COUNT);
|
|
#endif
|
|
master = g_lpi2cMasterStatePtr[u32Instance];
|
|
#if (STD_ON == LPI2C_IP_DEV_ERROR_DETECT)
|
|
DevAssert(master != NULL_PTR);
|
|
#endif
|
|
|
|
if (TRUE == bHighSpeedEnabled)
|
|
{
|
|
/* Set high speed operating mode */
|
|
master->operatingMode = LPI2C_HIGHSPEED_MODE;
|
|
}
|
|
else
|
|
{
|
|
/* High speed mode is not selected */
|
|
master->operatingMode = LPI2C_STANDARD_MODE;
|
|
}
|
|
}
|
|
|
|
#define I2C_STOP_SEC_CODE
|
|
#include "I2c_MemMap.h"
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
/** @} */
|
|
|
|
/*******************************************************************************
|
|
* EOF
|
|
******************************************************************************/
|