i2c.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656
  1. /******************************************************************************
  2. *
  3. * @brief providing APIs for configuring I2C module (I2C).
  4. *
  5. *******************************************************************************
  6. *
  7. * provide APIs for configuring I2C module (I2C).
  8. ******************************************************************************/
  9. #include "common.h"
  10. #include "i2c.h"
  11. /******************************************************************************
  12. * Global variables
  13. ******************************************************************************/
  14. /******************************************************************************
  15. * Constants and macros
  16. ******************************************************************************/
  17. /******************************************************************************
  18. * Local types
  19. ******************************************************************************/
  20. /******************************************************************************
  21. * Local function prototypes
  22. ******************************************************************************/
  23. /******************************************************************************
  24. * Local variables
  25. ******************************************************************************/
  26. static I2C_CallbackType I2C_Callback[2] = {(I2C_CallbackType)NULL};
  27. /******************************************************************************
  28. * Local functions
  29. ******************************************************************************/
  30. void I2C0_Isr( void );
  31. /******************************************************************************
  32. * Global functions
  33. ******************************************************************************/
  34. /******************************************************************************
  35. * define I2C APIs
  36. *
  37. *//*! @addtogroup i2c_api_list
  38. * @{
  39. *******************************************************************************/
  40. /*****************************************************************************//*!
  41. *
  42. * @brief Initialize I2C module.
  43. *
  44. * @param[in] pI2Cx point to I2C module type.
  45. * @param[in] pI2CConfig point to I2C configure structure.
  46. *
  47. * @return none
  48. *
  49. * @ Pass/ Fail criteria: none
  50. *****************************************************************************/
  51. void I2C_Init(I2C_Type *pI2Cx,I2C_ConfigPtr pI2CConfig)
  52. {
  53. uint8_t u8Temp;
  54. #if defined(CPU_NV32)
  55. SIM->SCGC |= SIM_SCGC_IIC_MASK;
  56. #elif defined(CPU_NV32M3)
  57. SIM->SCGC |= SIM_SCGC_IIC_MASK;
  58. #elif defined(CPU_NV32M4)
  59. if(pI2Cx == I2C0)
  60. {
  61. SIM->SCGC |= SIM_SCGC_I2C0_MASK;
  62. }
  63. else
  64. {
  65. SIM->SCGC |= SIM_SCGC_I2C1_MASK;
  66. }
  67. #endif
  68. I2C_SetBaudRate(pI2Cx,pI2CConfig->u16F);
  69. I2C_SetSlaveAddress(pI2Cx,pI2CConfig->u16OwnA1);
  70. pI2Cx->FLT = (uint8_t)pI2CConfig->u16Filt;
  71. pI2Cx->RA = (uint8_t)pI2CConfig->u16RangeA & 0xfe;
  72. I2C_SetSCLLowETMeout(pI2Cx,pI2CConfig->u16Slt);
  73. /* configure C2 control register */
  74. u8Temp = 0;
  75. if( pI2CConfig->sSetting.bGCAEn )
  76. {
  77. u8Temp |= I2C_C2_GCAEN_MASK;
  78. }
  79. if( pI2CConfig->sSetting.bAddressExt )
  80. {
  81. u8Temp |= I2C_C2_ADEXT_MASK;
  82. }
  83. if( pI2CConfig->sSetting.bRangeAddEn )
  84. {
  85. u8Temp |= I2C_C2_RMEN_MASK;
  86. }
  87. pI2Cx->C2 |= u8Temp;
  88. /* configure SMB rehister */
  89. u8Temp = 0;
  90. if( pI2CConfig->sSetting.bFackEn )
  91. {
  92. u8Temp |= I2C_SMB_FACK_MASK;
  93. }
  94. if( pI2CConfig->sSetting.bSMB_AlertEn )
  95. {
  96. u8Temp |= I2C_SMB_ALERTEN_MASK;
  97. }
  98. if( pI2CConfig->sSetting.bSecondAddressEn )
  99. {
  100. u8Temp |= I2C_SMB_SIICAEN_MASK;
  101. }
  102. if( pI2CConfig->sSetting.bSHTF2IntEn )
  103. {
  104. u8Temp |= I2C_SMB_SHTF2IE_MASK;
  105. }
  106. pI2Cx->SMB = u8Temp;
  107. /* configure C1 rehister */
  108. u8Temp = 0;
  109. if( pI2CConfig->sSetting.bIntEn )
  110. {
  111. u8Temp |= I2C_C1_IICIE_MASK;
  112. if(pI2Cx == I2C0)
  113. {
  114. NVIC_EnableIRQ(I2C0_IRQn);
  115. }
  116. #if defined(CPU_NV32M4)
  117. else if(pI2Cx == I2C1)
  118. {
  119. NVIC_EnableIRQ(I2C1_IRQn);
  120. }
  121. #endif
  122. else
  123. {
  124. //
  125. }
  126. }
  127. if( pI2CConfig->sSetting.bWakeUpEn )
  128. {
  129. u8Temp |= I2C_C1_WUEN_MASK;
  130. }
  131. if( pI2CConfig->sSetting.bI2CEn )
  132. {
  133. u8Temp |= I2C_C1_IICEN_MASK;
  134. }
  135. pI2Cx->C1 = u8Temp;
  136. }
  137. /*****************************************************************************//*!
  138. *
  139. * @brief send out start signals.
  140. *
  141. * @param[in] pI2Cx point to I2C module type.
  142. *
  143. * @return error status
  144. *
  145. * @ Pass/ Fail criteria: none
  146. *****************************************************************************/
  147. uint8_t I2C_Start(I2C_Type *pI2Cx)
  148. {
  149. uint32_t u32ETMeout;
  150. uint8_t u8ErrorStatus;
  151. u32ETMeout = 0;
  152. u8ErrorStatus = 0x00;
  153. I2C_TxEnable(pI2Cx);
  154. pI2Cx->C1 |= I2C_C1_MST_MASK;
  155. while( (!I2C_IsBusy(pI2Cx)) && ( u32ETMeout < I2C_WAIT_STATUS_ETMEOUT))
  156. {
  157. u32ETMeout ++;
  158. }
  159. if( u32ETMeout == I2C_WAIT_STATUS_ETMEOUT )
  160. {
  161. u8ErrorStatus |= I2C_ERROR_START_NO_BUSY_FLAG;
  162. }
  163. return u8ErrorStatus;
  164. }
  165. /*****************************************************************************//*!
  166. *
  167. * @brief send out stop signals.
  168. *
  169. * @param[in] pI2Cx point to I2C module type.
  170. *
  171. * @return error status
  172. *
  173. * @ Pass/ Fail criteria: none
  174. *****************************************************************************/
  175. uint8_t I2C_Stop(I2C_Type *pI2Cx)
  176. {
  177. uint32_t u32ETMeout;
  178. uint8_t u8ErrorStatus;
  179. u32ETMeout = 0;
  180. u8ErrorStatus = 0x00;
  181. pI2Cx->C1 &= ~I2C_C1_MST_MASK;
  182. while( (I2C_IsBusy(pI2Cx) ) && ( u32ETMeout < I2C_WAIT_STATUS_ETMEOUT))
  183. {
  184. u32ETMeout ++;
  185. }
  186. if( u32ETMeout == I2C_WAIT_STATUS_ETMEOUT )
  187. {
  188. u8ErrorStatus |= I2C_ERROR_STOP_BUSY_FLAG;
  189. }
  190. return u8ErrorStatus;
  191. }
  192. /*****************************************************************************//*!
  193. *
  194. * @brief send out repeat start signals.
  195. *
  196. * @param[in] pI2Cx point to I2C module type.
  197. *
  198. * @return error status.
  199. *
  200. * @ Pass/ Fail criteria: none
  201. *****************************************************************************/
  202. uint8_t I2C_RepeatStart(I2C_Type *pI2Cx)
  203. {
  204. uint32_t u32ETMeout;
  205. uint8_t u8ErrorStatus;
  206. u32ETMeout = 0;
  207. u8ErrorStatus = 0x00;
  208. pI2Cx->C1 |= I2C_C1_RSTA_MASK;
  209. while( (!I2C_IsBusy(I2C0) ) && ( u32ETMeout < I2C_WAIT_STATUS_ETMEOUT))
  210. {
  211. u32ETMeout ++;
  212. }
  213. if( u32ETMeout == I2C_WAIT_STATUS_ETMEOUT )
  214. {
  215. u8ErrorStatus |= I2C_ERROR_START_NO_BUSY_FLAG;
  216. }
  217. return u8ErrorStatus;
  218. }
  219. /*****************************************************************************//*!
  220. *
  221. * @brief set slave address.
  222. *
  223. * @param[in] pI2Cx point to I2C module type.
  224. *
  225. * @return none
  226. *
  227. * @ Pass/ Fail criteria: none
  228. *****************************************************************************/
  229. void I2C_SetSlaveAddress(I2C_Type *pI2Cx,uint16_t u16SlaveAddress)
  230. {
  231. /* write low 8bit address */
  232. pI2Cx->A1 = (uint8_t)u16SlaveAddress;
  233. /* write high 3bit address if it support 10bit slave address */
  234. pI2Cx->C2 &= ~I2C_C2_AD_MASK;
  235. pI2Cx->C2 |= (uint8_t)(u16SlaveAddress>>8)&0x03;
  236. }
  237. /*****************************************************************************//*!
  238. *
  239. * @brief disable IICIF interrupt.
  240. *
  241. * @param[in] pI2Cx point to I2C module type.
  242. *
  243. * @return none.
  244. *
  245. * @ Pass/ Fail criteria: none
  246. *****************************************************************************/
  247. void I2C_IntDisable(I2C_Type *pI2Cx)
  248. {
  249. pI2Cx->C1 &= ~I2C_C1_IICIE_MASK;
  250. if(pI2Cx == I2C0)
  251. {
  252. NVIC_DisableIRQ(I2C0_IRQn);
  253. }
  254. #if defined(CPU_NV32M4)
  255. else if(pI2Cx == I2C1)
  256. {
  257. NVIC_DisableIRQ(I2C1_IRQn);
  258. }
  259. #endif
  260. else
  261. {
  262. }
  263. }
  264. /*****************************************************************************//*!
  265. *
  266. * @brief enable IICIF interrupt.
  267. *
  268. * @param[in] pI2Cx point to I2C module type.
  269. *
  270. * @return none.
  271. *
  272. * @ Pass/ Fail criteria: none.
  273. *****************************************************************************/
  274. void I2C_IntEnable(I2C_Type *pI2Cx)
  275. {
  276. pI2Cx->C1 |= I2C_C1_IICIE_MASK;
  277. if(pI2Cx == I2C0)
  278. {
  279. NVIC_EnableIRQ(I2C0_IRQn);
  280. }
  281. #if defined(CPU_NV32M4)
  282. else if(pI2Cx == I2C1)
  283. {
  284. NVIC_EnableIRQ(I2C1_IRQn);
  285. }
  286. #endif
  287. else
  288. {
  289. }
  290. }
  291. /*****************************************************************************//*!
  292. *
  293. * @brief SCL low ETMeout value that determines the ETMeout period of SCL low.
  294. *
  295. * @param[in] pI2Cx point to I2C module type.
  296. *
  297. * @return none.
  298. *
  299. * @ Pass/ Fail criteria: none.
  300. *****************************************************************************/
  301. void I2C_SetSCLLowETMeout(I2C_Type *pI2Cx, uint16_t u16ETMeout)
  302. {
  303. pI2Cx->SLTL = (uint8_t)u16ETMeout;
  304. pI2Cx->SLTH = (uint8_t)(u16ETMeout>>8);
  305. }
  306. /*****************************************************************************//*!
  307. *
  308. * @brief deinit I2C module.
  309. *
  310. * @param[in] pI2Cx point to I2C module type.
  311. *
  312. * @return none
  313. *
  314. * @ Pass/ Fail criteria: none
  315. *****************************************************************************/
  316. void I2C_Deinit(I2C_Type *pI2Cx)
  317. {
  318. pI2Cx->C1 &= ~I2C_C1_IICEN_MASK;
  319. #if defined(CPU_NV32)
  320. SIM->SCGC &= ~SIM_SCGC_IIC_MASK;
  321. #elif defined(CPU_NV32M3)
  322. SIM->SCGC &= ~SIM_SCGC_IIC_MASK;
  323. #elif defined(CPU_NV32M4)
  324. if(pI2Cx == I2C0)
  325. {
  326. SIM->SCGC &= ~SIM_SCGC_I2C0_MASK;
  327. }
  328. else
  329. {
  330. SIM->SCGC &= ~SIM_SCGC_I2C1_MASK;
  331. }
  332. #endif
  333. }
  334. /*****************************************************************************//*!
  335. *
  336. * @brief write a byte to I2C module.
  337. *
  338. * @param[in] pI2Cx point to I2C module type.
  339. * @param[in] u8WrBuff data buffer for writing.
  340. *
  341. * @return error status
  342. *
  343. * @ Pass/ Fail criteria: none
  344. *****************************************************************************/
  345. uint8_t I2C_WriteOneByte(I2C_Type *pI2Cx, uint8_t u8WrBuff)
  346. {
  347. uint32_t u32ETMeout;
  348. uint8_t u8ErrorStatus;
  349. u32ETMeout = 0;
  350. u8ErrorStatus = 0x00;
  351. while (((I2C_GetStatus(pI2Cx)&I2C_S_TCF_MASK) != I2C_S_TCF_MASK)
  352. && (u32ETMeout<I2C_WAIT_STATUS_ETMEOUT))
  353. {
  354. u32ETMeout ++;
  355. }
  356. if (u32ETMeout >= I2C_WAIT_STATUS_ETMEOUT)
  357. {
  358. u8ErrorStatus |= I2C_ERROR_NO_WAIT_TCF_FLAG;
  359. return u8ErrorStatus;
  360. }
  361. I2C_TxEnable(pI2Cx);
  362. I2C_WriteDataReg(pI2Cx,u8WrBuff);
  363. u32ETMeout = 0;
  364. while (((I2C_GetStatus(pI2Cx)&I2C_S_IICIF_MASK) != I2C_S_IICIF_MASK)
  365. && (u32ETMeout<I2C_WAIT_STATUS_ETMEOUT))
  366. {
  367. u32ETMeout ++;
  368. }
  369. if (u32ETMeout >= I2C_WAIT_STATUS_ETMEOUT)
  370. {
  371. u8ErrorStatus |= I2C_ERROR_NO_WAIT_IICIF_FLAG;
  372. return u8ErrorStatus;
  373. }
  374. /* clear IICIF flag */
  375. I2C_ClearStatus(pI2Cx,I2C_S_IICIF_MASK);
  376. if (I2C_GetStatus(pI2Cx) & I2C_S_RXAK_MASK)
  377. {
  378. u8ErrorStatus |= I2C_ERROR_NO_GET_ACK;
  379. }
  380. return u8ErrorStatus;
  381. }
  382. /*****************************************************************************//*!
  383. *
  384. * @brief read a byte from slave I2C.
  385. *
  386. * @param[in] pI2Cx point to I2C module type.
  387. * @param[out] pRdBuff point to the data read from slave I2C.
  388. * @param[out] u8Ack send out ack or nack.
  389. *
  390. * @return error status
  391. *
  392. * @ Pass/ Fail criteria: none
  393. *****************************************************************************/
  394. uint8_t I2C_ReadOneByte(I2C_Type *pI2Cx, uint8_t *pRdBuff, uint8_t u8Ack)
  395. {
  396. uint32_t u32ETMeout;
  397. uint8_t u8ErrorStatus;
  398. u32ETMeout = 0;
  399. u8ErrorStatus = 0x00;
  400. while (((I2C_GetStatus(pI2Cx)&I2C_S_TCF_MASK) != I2C_S_TCF_MASK)
  401. && (u32ETMeout<I2C_WAIT_STATUS_ETMEOUT))
  402. {
  403. u32ETMeout ++;
  404. }
  405. if (u32ETMeout >= I2C_WAIT_STATUS_ETMEOUT)
  406. {
  407. u8ErrorStatus |= I2C_ERROR_NO_WAIT_TCF_FLAG;
  408. return u8ErrorStatus;
  409. }
  410. I2C_RxEnable(pI2Cx);
  411. if( u8Ack )
  412. {
  413. /* send out nack */
  414. I2C_SendNack(pI2Cx);
  415. }
  416. else
  417. {
  418. /* send out ack */
  419. I2C_SendAck(pI2Cx);
  420. }
  421. *pRdBuff = I2C_ReadDataReg(pI2Cx);
  422. u32ETMeout = 0;
  423. while (((I2C_GetStatus(pI2Cx)&I2C_S_IICIF_MASK) != I2C_S_IICIF_MASK)
  424. && (u32ETMeout<I2C_WAIT_STATUS_ETMEOUT))
  425. {
  426. u32ETMeout ++;
  427. }
  428. if (u32ETMeout >= I2C_WAIT_STATUS_ETMEOUT)
  429. {
  430. u8ErrorStatus |= I2C_ERROR_NO_WAIT_IICIF_FLAG;
  431. return u8ErrorStatus;
  432. }
  433. /* clear IICIF flag */
  434. I2C_ClearStatus(pI2Cx,I2C_S_IICIF_MASK);
  435. return u8ErrorStatus;
  436. }
  437. /*****************************************************************************//*!
  438. *
  439. * @brief send data to I2C, and wait to complete transfering.
  440. *
  441. * @param[in] pI2Cx point to I2C module type.
  442. * @param[in] u16SlaveAddress slave address.
  443. * @param[in] pWrBuff point the first address of transfering data buffer.
  444. * @param[in] the length of transfering data.
  445. *
  446. * @return error status
  447. *
  448. * @ Pass/ Fail criteria: none
  449. *****************************************************************************/
  450. uint8_t I2C_MasterSendWait(I2C_Type *pI2Cx,uint16_t u16SlaveAddress,uint8_t *pWrBuff,uint32_t u32Length)
  451. {
  452. uint32_t i;
  453. uint8_t u8ErrorStatus;
  454. /* send start signals to bus */
  455. u8ErrorStatus = I2C_Start(pI2Cx);
  456. /* send device address to slave */
  457. u8ErrorStatus = I2C_WriteOneByte(pI2Cx,((uint8_t)u16SlaveAddress<<1) | I2C_WRITE);
  458. /* if no error occur, received the correct ack from slave
  459. continue to send data to slave
  460. */
  461. if( u8ErrorStatus == I2C_ERROR_NULL )
  462. {
  463. for(i=0;i<u32Length;i++)
  464. {
  465. u8ErrorStatus = I2C_WriteOneByte(pI2Cx,pWrBuff[i]);
  466. if( u8ErrorStatus != I2C_ERROR_NULL )
  467. {
  468. return u8ErrorStatus;
  469. }
  470. }
  471. }
  472. /* send stop signals to bus */
  473. u8ErrorStatus = I2C_Stop(pI2Cx);
  474. return u8ErrorStatus;
  475. }
  476. /*****************************************************************************//*!
  477. *
  478. * @brief read data from I2C,and wait to complete transferring.
  479. *
  480. * @param[in] pI2Cx point to I2C module type.
  481. * @param[in] u16SlaveAddress slave address.
  482. * @param[in] pRdBuff point the first address of reading data buffer.
  483. * @param[in] the length of transfering data.
  484. *
  485. * @return error status
  486. *
  487. * @ Pass/ Fail criteria: none
  488. *****************************************************************************/
  489. uint8_t I2C_MasterReadWait(I2C_Type *pI2Cx,uint16_t u16SlaveAddress,uint8_t *pRdBuff,uint32_t u32Length)
  490. {
  491. uint32_t i;
  492. uint8_t u8ErrorStatus;
  493. /* send start signals to bus */
  494. u8ErrorStatus = I2C_Start(pI2Cx);
  495. /* send device address to slave */
  496. u8ErrorStatus = I2C_WriteOneByte(pI2Cx,((uint8_t)u16SlaveAddress<<1) | I2C_READ);
  497. /* if no error occur, received the correct ack from slave
  498. continue to send data to slave
  499. */
  500. /* dummy read one byte to switch to Rx mode */
  501. I2C_ReadOneByte(pI2Cx,&pRdBuff[0],I2C_SEND_ACK);
  502. if( u8ErrorStatus == I2C_ERROR_NULL )
  503. {
  504. for(i=0;i<u32Length-1;i++)
  505. {
  506. u8ErrorStatus = I2C_ReadOneByte(pI2Cx,&pRdBuff[i],I2C_SEND_ACK);
  507. if( u8ErrorStatus != I2C_ERROR_NULL )
  508. {
  509. return u8ErrorStatus;
  510. }
  511. }
  512. u8ErrorStatus = I2C_ReadOneByte(pI2Cx,&pRdBuff[i],I2C_SEND_NACK);
  513. }
  514. /* send stop signals to bus */
  515. u8ErrorStatus = I2C_Stop(pI2Cx);
  516. return u8ErrorStatus;
  517. }
  518. /*****************************************************************************//*!
  519. *
  520. * @brief set call back function for I2C1 module.
  521. *
  522. * @param[in] pCallBack point to address of I2C1 call back function.
  523. *
  524. * @return none.
  525. *
  526. * @ Pass/ Fail criteria: none.
  527. *****************************************************************************/
  528. void I2C1_SetCallBack( I2C_CallbackType pCallBack )
  529. {
  530. I2C_Callback[1] = pCallBack;
  531. }
  532. /*****************************************************************************//*!
  533. *
  534. * @brief set call back function for I2C0 module.
  535. *
  536. * @param[in] pCallBack point to address of I2C0 call back function.
  537. *
  538. * @return none.
  539. *
  540. * @ Pass/ Fail criteria: none.
  541. *****************************************************************************/
  542. void I2C0_SetCallBack( I2C_CallbackType pCallBack )
  543. {
  544. I2C_Callback[0] = pCallBack;
  545. }
  546. /*! @} End of i2c_api_list */
  547. /*****************************************************************************//*!
  548. *
  549. * @brief I2C0 interrupt service routine.
  550. *
  551. * @param
  552. *
  553. * @return none
  554. *
  555. * @ Pass/ Fail criteria: none
  556. *****************************************************************************/
  557. void I2C0_Isr( void )
  558. {
  559. if( I2C_Callback[0] )
  560. {
  561. I2C_Callback[0]();
  562. }
  563. }
  564. /*****************************************************************************//*!
  565. *
  566. * @brief I2C1 interrupt service routine.
  567. *
  568. * @param
  569. *
  570. * @return none
  571. *
  572. * @ Pass/ Fail criteria: none
  573. *****************************************************************************/
  574. void I2C1_Isr( void )
  575. {
  576. if( I2C_Callback[1] )
  577. {
  578. I2C_Callback[1]();
  579. }
  580. }