| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656 |
- /******************************************************************************
- *
- * @brief providing APIs for configuring I2C module (I2C).
- *
- *******************************************************************************
- *
- * provide APIs for configuring I2C module (I2C).
- ******************************************************************************/
- #include "common.h"
- #include "i2c.h"
- /******************************************************************************
- * Global variables
- ******************************************************************************/
- /******************************************************************************
- * Constants and macros
- ******************************************************************************/
- /******************************************************************************
- * Local types
- ******************************************************************************/
- /******************************************************************************
- * Local function prototypes
- ******************************************************************************/
- /******************************************************************************
- * Local variables
- ******************************************************************************/
- static I2C_CallbackType I2C_Callback[2] = {(I2C_CallbackType)NULL};
- /******************************************************************************
- * Local functions
- ******************************************************************************/
- void I2C0_Isr( void );
- /******************************************************************************
- * Global functions
- ******************************************************************************/
- /******************************************************************************
- * define I2C APIs
- *
- *//*! @addtogroup i2c_api_list
- * @{
- *******************************************************************************/
- /*****************************************************************************//*!
- *
- * @brief Initialize I2C module.
- *
- * @param[in] pI2Cx point to I2C module type.
- * @param[in] pI2CConfig point to I2C configure structure.
- *
- * @return none
- *
- * @ Pass/ Fail criteria: none
- *****************************************************************************/
- void I2C_Init(I2C_Type *pI2Cx,I2C_ConfigPtr pI2CConfig)
- {
- uint8_t u8Temp;
- #if defined(CPU_NV32)
- SIM->SCGC |= SIM_SCGC_IIC_MASK;
- #elif defined(CPU_NV32M3)
- SIM->SCGC |= SIM_SCGC_IIC_MASK;
- #elif defined(CPU_NV32M4)
- if(pI2Cx == I2C0)
- {
- SIM->SCGC |= SIM_SCGC_I2C0_MASK;
- }
- else
- {
- SIM->SCGC |= SIM_SCGC_I2C1_MASK;
- }
- #endif
- I2C_SetBaudRate(pI2Cx,pI2CConfig->u16F);
- I2C_SetSlaveAddress(pI2Cx,pI2CConfig->u16OwnA1);
- pI2Cx->FLT = (uint8_t)pI2CConfig->u16Filt;
- pI2Cx->RA = (uint8_t)pI2CConfig->u16RangeA & 0xfe;
- I2C_SetSCLLowETMeout(pI2Cx,pI2CConfig->u16Slt);
- /* configure C2 control register */
- u8Temp = 0;
- if( pI2CConfig->sSetting.bGCAEn )
- {
- u8Temp |= I2C_C2_GCAEN_MASK;
- }
- if( pI2CConfig->sSetting.bAddressExt )
- {
- u8Temp |= I2C_C2_ADEXT_MASK;
- }
- if( pI2CConfig->sSetting.bRangeAddEn )
- {
- u8Temp |= I2C_C2_RMEN_MASK;
- }
- pI2Cx->C2 |= u8Temp;
- /* configure SMB rehister */
- u8Temp = 0;
- if( pI2CConfig->sSetting.bFackEn )
- {
- u8Temp |= I2C_SMB_FACK_MASK;
- }
- if( pI2CConfig->sSetting.bSMB_AlertEn )
- {
- u8Temp |= I2C_SMB_ALERTEN_MASK;
- }
- if( pI2CConfig->sSetting.bSecondAddressEn )
- {
- u8Temp |= I2C_SMB_SIICAEN_MASK;
- }
- if( pI2CConfig->sSetting.bSHTF2IntEn )
- {
- u8Temp |= I2C_SMB_SHTF2IE_MASK;
- }
- pI2Cx->SMB = u8Temp;
-
- /* configure C1 rehister */
- u8Temp = 0;
- if( pI2CConfig->sSetting.bIntEn )
- {
- u8Temp |= I2C_C1_IICIE_MASK;
- if(pI2Cx == I2C0)
- {
- NVIC_EnableIRQ(I2C0_IRQn);
- }
- #if defined(CPU_NV32M4)
- else if(pI2Cx == I2C1)
- {
- NVIC_EnableIRQ(I2C1_IRQn);
- }
- #endif
- else
- {
- //
- }
- }
- if( pI2CConfig->sSetting.bWakeUpEn )
- {
- u8Temp |= I2C_C1_WUEN_MASK;
- }
- if( pI2CConfig->sSetting.bI2CEn )
- {
- u8Temp |= I2C_C1_IICEN_MASK;
- }
- pI2Cx->C1 = u8Temp;
- }
- /*****************************************************************************//*!
- *
- * @brief send out start signals.
- *
- * @param[in] pI2Cx point to I2C module type.
- *
- * @return error status
- *
- * @ Pass/ Fail criteria: none
- *****************************************************************************/
- uint8_t I2C_Start(I2C_Type *pI2Cx)
- {
- uint32_t u32ETMeout;
- uint8_t u8ErrorStatus;
-
- u32ETMeout = 0;
- u8ErrorStatus = 0x00;
- I2C_TxEnable(pI2Cx);
- pI2Cx->C1 |= I2C_C1_MST_MASK;
- while( (!I2C_IsBusy(pI2Cx)) && ( u32ETMeout < I2C_WAIT_STATUS_ETMEOUT))
- {
- u32ETMeout ++;
- }
- if( u32ETMeout == I2C_WAIT_STATUS_ETMEOUT )
- {
- u8ErrorStatus |= I2C_ERROR_START_NO_BUSY_FLAG;
- }
- return u8ErrorStatus;
- }
- /*****************************************************************************//*!
- *
- * @brief send out stop signals.
- *
- * @param[in] pI2Cx point to I2C module type.
- *
- * @return error status
- *
- * @ Pass/ Fail criteria: none
- *****************************************************************************/
- uint8_t I2C_Stop(I2C_Type *pI2Cx)
- {
- uint32_t u32ETMeout;
- uint8_t u8ErrorStatus;
-
- u32ETMeout = 0;
- u8ErrorStatus = 0x00;
-
- pI2Cx->C1 &= ~I2C_C1_MST_MASK;
- while( (I2C_IsBusy(pI2Cx) ) && ( u32ETMeout < I2C_WAIT_STATUS_ETMEOUT))
- {
- u32ETMeout ++;
- }
- if( u32ETMeout == I2C_WAIT_STATUS_ETMEOUT )
- {
- u8ErrorStatus |= I2C_ERROR_STOP_BUSY_FLAG;
- }
- return u8ErrorStatus;
- }
- /*****************************************************************************//*!
- *
- * @brief send out repeat start signals.
- *
- * @param[in] pI2Cx point to I2C module type.
- *
- * @return error status.
- *
- * @ Pass/ Fail criteria: none
- *****************************************************************************/
- uint8_t I2C_RepeatStart(I2C_Type *pI2Cx)
- {
- uint32_t u32ETMeout;
- uint8_t u8ErrorStatus;
-
- u32ETMeout = 0;
- u8ErrorStatus = 0x00;
-
- pI2Cx->C1 |= I2C_C1_RSTA_MASK;
- while( (!I2C_IsBusy(I2C0) ) && ( u32ETMeout < I2C_WAIT_STATUS_ETMEOUT))
- {
- u32ETMeout ++;
- }
- if( u32ETMeout == I2C_WAIT_STATUS_ETMEOUT )
- {
- u8ErrorStatus |= I2C_ERROR_START_NO_BUSY_FLAG;
- }
- return u8ErrorStatus;
- }
- /*****************************************************************************//*!
- *
- * @brief set slave address.
- *
- * @param[in] pI2Cx point to I2C module type.
- *
- * @return none
- *
- * @ Pass/ Fail criteria: none
- *****************************************************************************/
- void I2C_SetSlaveAddress(I2C_Type *pI2Cx,uint16_t u16SlaveAddress)
- {
- /* write low 8bit address */
- pI2Cx->A1 = (uint8_t)u16SlaveAddress;
- /* write high 3bit address if it support 10bit slave address */
- pI2Cx->C2 &= ~I2C_C2_AD_MASK;
- pI2Cx->C2 |= (uint8_t)(u16SlaveAddress>>8)&0x03;
- }
- /*****************************************************************************//*!
- *
- * @brief disable IICIF interrupt.
- *
- * @param[in] pI2Cx point to I2C module type.
- *
- * @return none.
- *
- * @ Pass/ Fail criteria: none
- *****************************************************************************/
- void I2C_IntDisable(I2C_Type *pI2Cx)
- {
- pI2Cx->C1 &= ~I2C_C1_IICIE_MASK;
- if(pI2Cx == I2C0)
- {
- NVIC_DisableIRQ(I2C0_IRQn);
- }
- #if defined(CPU_NV32M4)
- else if(pI2Cx == I2C1)
- {
- NVIC_DisableIRQ(I2C1_IRQn);
- }
- #endif
- else
- {
-
- }
- }
- /*****************************************************************************//*!
- *
- * @brief enable IICIF interrupt.
- *
- * @param[in] pI2Cx point to I2C module type.
- *
- * @return none.
- *
- * @ Pass/ Fail criteria: none.
- *****************************************************************************/
- void I2C_IntEnable(I2C_Type *pI2Cx)
- {
- pI2Cx->C1 |= I2C_C1_IICIE_MASK;
- if(pI2Cx == I2C0)
- {
- NVIC_EnableIRQ(I2C0_IRQn);
- }
- #if defined(CPU_NV32M4)
- else if(pI2Cx == I2C1)
- {
- NVIC_EnableIRQ(I2C1_IRQn);
- }
- #endif
- else
- {
-
- }
- }
- /*****************************************************************************//*!
- *
- * @brief SCL low ETMeout value that determines the ETMeout period of SCL low.
- *
- * @param[in] pI2Cx point to I2C module type.
- *
- * @return none.
- *
- * @ Pass/ Fail criteria: none.
- *****************************************************************************/
- void I2C_SetSCLLowETMeout(I2C_Type *pI2Cx, uint16_t u16ETMeout)
- {
- pI2Cx->SLTL = (uint8_t)u16ETMeout;
- pI2Cx->SLTH = (uint8_t)(u16ETMeout>>8);
- }
- /*****************************************************************************//*!
- *
- * @brief deinit I2C module.
- *
- * @param[in] pI2Cx point to I2C module type.
- *
- * @return none
- *
- * @ Pass/ Fail criteria: none
- *****************************************************************************/
- void I2C_Deinit(I2C_Type *pI2Cx)
- {
- pI2Cx->C1 &= ~I2C_C1_IICEN_MASK;
- #if defined(CPU_NV32)
- SIM->SCGC &= ~SIM_SCGC_IIC_MASK;
- #elif defined(CPU_NV32M3)
- SIM->SCGC &= ~SIM_SCGC_IIC_MASK;
- #elif defined(CPU_NV32M4)
- if(pI2Cx == I2C0)
- {
- SIM->SCGC &= ~SIM_SCGC_I2C0_MASK;
- }
- else
- {
- SIM->SCGC &= ~SIM_SCGC_I2C1_MASK;
- }
- #endif
- }
- /*****************************************************************************//*!
- *
- * @brief write a byte to I2C module.
- *
- * @param[in] pI2Cx point to I2C module type.
- * @param[in] u8WrBuff data buffer for writing.
- *
- * @return error status
- *
- * @ Pass/ Fail criteria: none
- *****************************************************************************/
- uint8_t I2C_WriteOneByte(I2C_Type *pI2Cx, uint8_t u8WrBuff)
- {
- uint32_t u32ETMeout;
- uint8_t u8ErrorStatus;
-
- u32ETMeout = 0;
- u8ErrorStatus = 0x00;
- while (((I2C_GetStatus(pI2Cx)&I2C_S_TCF_MASK) != I2C_S_TCF_MASK)
- && (u32ETMeout<I2C_WAIT_STATUS_ETMEOUT))
- {
- u32ETMeout ++;
- }
- if (u32ETMeout >= I2C_WAIT_STATUS_ETMEOUT)
- {
- u8ErrorStatus |= I2C_ERROR_NO_WAIT_TCF_FLAG;
- return u8ErrorStatus;
- }
-
- I2C_TxEnable(pI2Cx);
- I2C_WriteDataReg(pI2Cx,u8WrBuff);
- u32ETMeout = 0;
- while (((I2C_GetStatus(pI2Cx)&I2C_S_IICIF_MASK) != I2C_S_IICIF_MASK)
- && (u32ETMeout<I2C_WAIT_STATUS_ETMEOUT))
- {
- u32ETMeout ++;
- }
- if (u32ETMeout >= I2C_WAIT_STATUS_ETMEOUT)
- {
- u8ErrorStatus |= I2C_ERROR_NO_WAIT_IICIF_FLAG;
- return u8ErrorStatus;
- }
- /* clear IICIF flag */
- I2C_ClearStatus(pI2Cx,I2C_S_IICIF_MASK);
- if (I2C_GetStatus(pI2Cx) & I2C_S_RXAK_MASK)
- {
- u8ErrorStatus |= I2C_ERROR_NO_GET_ACK;
- }
- return u8ErrorStatus;
- }
- /*****************************************************************************//*!
- *
- * @brief read a byte from slave I2C.
- *
- * @param[in] pI2Cx point to I2C module type.
- * @param[out] pRdBuff point to the data read from slave I2C.
- * @param[out] u8Ack send out ack or nack.
- *
- * @return error status
- *
- * @ Pass/ Fail criteria: none
- *****************************************************************************/
- uint8_t I2C_ReadOneByte(I2C_Type *pI2Cx, uint8_t *pRdBuff, uint8_t u8Ack)
- {
- uint32_t u32ETMeout;
- uint8_t u8ErrorStatus;
-
- u32ETMeout = 0;
- u8ErrorStatus = 0x00;
- while (((I2C_GetStatus(pI2Cx)&I2C_S_TCF_MASK) != I2C_S_TCF_MASK)
- && (u32ETMeout<I2C_WAIT_STATUS_ETMEOUT))
- {
- u32ETMeout ++;
- }
- if (u32ETMeout >= I2C_WAIT_STATUS_ETMEOUT)
- {
- u8ErrorStatus |= I2C_ERROR_NO_WAIT_TCF_FLAG;
- return u8ErrorStatus;
- }
-
- I2C_RxEnable(pI2Cx);
- if( u8Ack )
- {
- /* send out nack */
- I2C_SendNack(pI2Cx);
-
- }
- else
- {
- /* send out ack */
- I2C_SendAck(pI2Cx);
- }
- *pRdBuff = I2C_ReadDataReg(pI2Cx);
- u32ETMeout = 0;
- while (((I2C_GetStatus(pI2Cx)&I2C_S_IICIF_MASK) != I2C_S_IICIF_MASK)
- && (u32ETMeout<I2C_WAIT_STATUS_ETMEOUT))
- {
- u32ETMeout ++;
- }
- if (u32ETMeout >= I2C_WAIT_STATUS_ETMEOUT)
- {
- u8ErrorStatus |= I2C_ERROR_NO_WAIT_IICIF_FLAG;
- return u8ErrorStatus;
- }
- /* clear IICIF flag */
- I2C_ClearStatus(pI2Cx,I2C_S_IICIF_MASK);
- return u8ErrorStatus;
- }
- /*****************************************************************************//*!
- *
- * @brief send data to I2C, and wait to complete transfering.
- *
- * @param[in] pI2Cx point to I2C module type.
- * @param[in] u16SlaveAddress slave address.
- * @param[in] pWrBuff point the first address of transfering data buffer.
- * @param[in] the length of transfering data.
- *
- * @return error status
- *
- * @ Pass/ Fail criteria: none
- *****************************************************************************/
- uint8_t I2C_MasterSendWait(I2C_Type *pI2Cx,uint16_t u16SlaveAddress,uint8_t *pWrBuff,uint32_t u32Length)
- {
- uint32_t i;
- uint8_t u8ErrorStatus;
- /* send start signals to bus */
- u8ErrorStatus = I2C_Start(pI2Cx);
- /* send device address to slave */
- u8ErrorStatus = I2C_WriteOneByte(pI2Cx,((uint8_t)u16SlaveAddress<<1) | I2C_WRITE);
- /* if no error occur, received the correct ack from slave
- continue to send data to slave
- */
- if( u8ErrorStatus == I2C_ERROR_NULL )
- {
- for(i=0;i<u32Length;i++)
- {
- u8ErrorStatus = I2C_WriteOneByte(pI2Cx,pWrBuff[i]);
- if( u8ErrorStatus != I2C_ERROR_NULL )
- {
- return u8ErrorStatus;
- }
- }
- }
- /* send stop signals to bus */
- u8ErrorStatus = I2C_Stop(pI2Cx);
- return u8ErrorStatus;
-
- }
- /*****************************************************************************//*!
- *
- * @brief read data from I2C,and wait to complete transferring.
- *
- * @param[in] pI2Cx point to I2C module type.
- * @param[in] u16SlaveAddress slave address.
- * @param[in] pRdBuff point the first address of reading data buffer.
- * @param[in] the length of transfering data.
- *
- * @return error status
- *
- * @ Pass/ Fail criteria: none
- *****************************************************************************/
- uint8_t I2C_MasterReadWait(I2C_Type *pI2Cx,uint16_t u16SlaveAddress,uint8_t *pRdBuff,uint32_t u32Length)
- {
- uint32_t i;
- uint8_t u8ErrorStatus;
- /* send start signals to bus */
- u8ErrorStatus = I2C_Start(pI2Cx);
- /* send device address to slave */
- u8ErrorStatus = I2C_WriteOneByte(pI2Cx,((uint8_t)u16SlaveAddress<<1) | I2C_READ);
- /* if no error occur, received the correct ack from slave
- continue to send data to slave
- */
- /* dummy read one byte to switch to Rx mode */
- I2C_ReadOneByte(pI2Cx,&pRdBuff[0],I2C_SEND_ACK);
-
- if( u8ErrorStatus == I2C_ERROR_NULL )
- {
- for(i=0;i<u32Length-1;i++)
- {
- u8ErrorStatus = I2C_ReadOneByte(pI2Cx,&pRdBuff[i],I2C_SEND_ACK);
- if( u8ErrorStatus != I2C_ERROR_NULL )
- {
- return u8ErrorStatus;
- }
- }
- u8ErrorStatus = I2C_ReadOneByte(pI2Cx,&pRdBuff[i],I2C_SEND_NACK);
- }
- /* send stop signals to bus */
- u8ErrorStatus = I2C_Stop(pI2Cx);
-
- return u8ErrorStatus;
-
- }
- /*****************************************************************************//*!
- *
- * @brief set call back function for I2C1 module.
- *
- * @param[in] pCallBack point to address of I2C1 call back function.
- *
- * @return none.
- *
- * @ Pass/ Fail criteria: none.
- *****************************************************************************/
- void I2C1_SetCallBack( I2C_CallbackType pCallBack )
- {
- I2C_Callback[1] = pCallBack;
- }
- /*****************************************************************************//*!
- *
- * @brief set call back function for I2C0 module.
- *
- * @param[in] pCallBack point to address of I2C0 call back function.
- *
- * @return none.
- *
- * @ Pass/ Fail criteria: none.
- *****************************************************************************/
- void I2C0_SetCallBack( I2C_CallbackType pCallBack )
- {
- I2C_Callback[0] = pCallBack;
- }
- /*! @} End of i2c_api_list */
- /*****************************************************************************//*!
- *
- * @brief I2C0 interrupt service routine.
- *
- * @param
- *
- * @return none
- *
- * @ Pass/ Fail criteria: none
- *****************************************************************************/
- void I2C0_Isr( void )
- {
- if( I2C_Callback[0] )
- {
- I2C_Callback[0]();
- }
- }
- /*****************************************************************************//*!
- *
- * @brief I2C1 interrupt service routine.
- *
- * @param
- *
- * @return none
- *
- * @ Pass/ Fail criteria: none
- *****************************************************************************/
- void I2C1_Isr( void )
- {
- if( I2C_Callback[1] )
- {
- I2C_Callback[1]();
- }
- }
|