i2c.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. /****************************************************************************//**
  2. * @file i2c.c
  3. * @version V0.10
  4. * $Revision: 13 $
  5. * $Date: 14/09/30 1:10p $
  6. * @brief NUC472/NUC442 I2C driver source file
  7. *
  8. * @note
  9. * Copyright (C) 2014 Nuvoton Technology Corp. All rights reserved.
  10. *****************************************************************************/
  11. #include "NUC472_442.h"
  12. /** @addtogroup NUC472_442_Device_Driver NUC472/NUC442 Device Driver
  13. @{
  14. */
  15. /** @addtogroup NUC472_442_I2C_Driver I2C Driver
  16. @{
  17. */
  18. /** @addtogroup NUC472_442_I2C_EXPORTED_FUNCTIONS I2C Exported Functions
  19. @{
  20. */
  21. /**
  22. * @brief This function make I2C module be ready and set the wanted bus clock.
  23. * @param[in] i2c is the base address of I2C module.
  24. * @param[in] u32BusClock is the target bus speed of I2C module.
  25. * @return Actual I2C bus clock frequency.
  26. */
  27. uint32_t I2C_Open(I2C_T *i2c, uint32_t u32BusClock)
  28. {
  29. uint32_t u32Div;
  30. uint32_t u32Pclk = CLK_GetPCLKFreq();
  31. u32Div = (uint32_t) ((( u32Pclk * 10)/(u32BusClock * 4) + 5) / 10 - 1); /* Compute proper divider for I2C clock */
  32. i2c->CLKDIV = u32Div;
  33. /* Enable I2C */
  34. i2c->CTL |= I2C_CTL_I2CEN_Msk;
  35. return ( u32Pclk / ((u32Div+1)<<2) );
  36. }
  37. /**
  38. * @brief This function closes the I2C module.
  39. * @param[in] i2c is the base address of I2C module.
  40. * @return none
  41. */
  42. void I2C_Close(I2C_T *i2c)
  43. {
  44. /* Reset SPI */
  45. if((uint32_t)i2c == I2C0_BASE) {
  46. SYS->IPRST1 |= SYS_IPRST1_I2C0RST_Msk;
  47. SYS->IPRST1 &= ~SYS_IPRST1_I2C0RST_Msk;
  48. } else if((uint32_t)i2c == I2C1_BASE) {
  49. SYS->IPRST1 |= SYS_IPRST1_I2C1RST_Msk;
  50. SYS->IPRST1 &= ~SYS_IPRST1_I2C1RST_Msk;
  51. } else if((uint32_t)i2c == I2C2_BASE) {
  52. SYS->IPRST1 |= SYS_IPRST1_I2C2RST_Msk;
  53. SYS->IPRST1 &= ~SYS_IPRST1_I2C2RST_Msk;
  54. } else {
  55. SYS->IPRST1 |= SYS_IPRST1_I2C3RST_Msk;
  56. SYS->IPRST1 &= ~SYS_IPRST1_I2C3RST_Msk;
  57. }
  58. /* Disable I2C */
  59. i2c->CTL &= ~I2C_CTL_I2CEN_Msk;
  60. }
  61. /**
  62. * @brief This function clears the time-out flag.
  63. * @param[in] i2c is the base address of I2C module.
  64. * @return none
  65. */
  66. void I2C_ClearTimeoutFlag(I2C_T *i2c)
  67. {
  68. i2c->TOCTL |= I2C_TOCTL_TOIF_Msk;
  69. }
  70. /**
  71. * @brief This function sets the control bit of the I2C module.
  72. * @param[in] i2c is the base address of I2C module.
  73. * @param[in] u8Start sets START bit to I2C module.
  74. * @param[in] u8Stop sets STOP bit to I2C module.
  75. * @param[in] u8Si sets SI bit to I2C module.
  76. * @param[in] u8Ack sets ACK bit to I2C module.
  77. * @return none
  78. */
  79. void I2C_Trigger(I2C_T *i2c, uint8_t u8Start, uint8_t u8Stop, uint8_t u8Si, uint8_t u8Ack)
  80. {
  81. uint32_t u32Reg = 0;
  82. uint32_t u32Val = i2c->CTL & ~(I2C_STA | I2C_STO | I2C_AA);
  83. if (u8Start)
  84. u32Reg |= I2C_STA;
  85. if (u8Stop)
  86. u32Reg |= I2C_STO;
  87. if (u8Si)
  88. u32Reg |= I2C_SI;
  89. if (u8Ack)
  90. u32Reg |= I2C_AA;
  91. i2c->CTL = u32Val | u32Reg;
  92. }
  93. /**
  94. * @brief This function disables the interrupt of I2C module.
  95. * @param[in] i2c is the base address of I2C module.
  96. * @return none
  97. */
  98. void I2C_DisableInt(I2C_T *i2c)
  99. {
  100. i2c->CTL &= ~I2C_CTL_INTEN_Msk;
  101. }
  102. /**
  103. * @brief This function enables the interrupt (EI bit) of I2C module.
  104. * @param[in] i2c is the base address of I2C module.
  105. * @return none
  106. */
  107. void I2C_EnableInt(I2C_T *i2c)
  108. {
  109. i2c->CTL |= I2C_CTL_INTEN_Msk;
  110. }
  111. /**
  112. * @brief This function returns the real bus clock of I2C module.
  113. * @param[in] i2c is the base address of I2C module.
  114. * @return Actual I2C bus clock frequency.
  115. */
  116. uint32_t I2C_GetBusClockFreq(I2C_T *i2c)
  117. {
  118. uint32_t u32Divider = i2c->CLKDIV;
  119. return ( CLK_GetPCLKFreq() / ((u32Divider+1)<<2) );
  120. }
  121. /**
  122. * @brief This function sets bus frequency of I2C module.
  123. * @param[in] i2c is the base address of I2C module.
  124. * @param[in] u32BusClock is the target bus speed of I2C module.
  125. * @return Actual I2C bus clock frequency.
  126. */
  127. uint32_t I2C_SetBusClockFreq(I2C_T *i2c, uint32_t u32BusClock)
  128. {
  129. uint32_t u32Div;
  130. uint32_t u32Pclk = CLK_GetPCLKFreq();
  131. u32Div = (uint32_t) (((u32Pclk * 10)/(u32BusClock * 4) + 5) / 10 - 1); /* Compute proper divider for I2C clock */
  132. i2c->CLKDIV = u32Div;
  133. return ( u32Pclk / ((u32Div+1)<<2) );
  134. }
  135. /**
  136. * @brief This function gets the interrupt flag of I2C module.
  137. * @param[in] i2c is the base address of I2C module.
  138. * @return Interrupt flag.
  139. * @retval 0 Flag is not set.
  140. * @retval 1 Flag is set.
  141. */
  142. uint32_t I2C_GetIntFlag(I2C_T *i2c)
  143. {
  144. return ( (i2c->CTL & I2C_CTL_SI_Msk) == I2C_CTL_SI_Msk ? 1:0 );
  145. }
  146. /**
  147. * @brief This function returns the status of I2C module.
  148. * @param[in] i2c is the base address of I2C module.
  149. * @return I2C status
  150. */
  151. uint32_t I2C_GetStatus(I2C_T *i2c)
  152. {
  153. return ( i2c->STATUS );
  154. }
  155. /**
  156. * @brief This function returns the data stored in data register of I2C module.
  157. * @param[in] i2c is the base address of I2C module.
  158. * @return I2C data.
  159. */
  160. uint32_t I2C_GetData(I2C_T *i2c)
  161. {
  162. return ( i2c->DAT );
  163. }
  164. /**
  165. * @brief This function writes the data to data register of I2C module.
  166. * @param[in] i2c is the base address of I2C module.
  167. * @param[in] u8Data is the data which will be write to data register of I2C module.
  168. * @return none
  169. */
  170. void I2C_SetData(I2C_T *i2c, uint8_t u8Data)
  171. {
  172. i2c->DAT = u8Data;
  173. }
  174. /**
  175. * @brief Configure slave address and enable GC mode.
  176. * @param[in] i2c is the base address of I2C module.
  177. * @param[in] u8SlaveNo is the set number of salve address.
  178. * @param[in] u8SlaveAddr is the slave address.
  179. * @param[in] u8GCMode GC mode enable or not. Valid values are:
  180. * - \ref I2C_GCMODE_ENABLE
  181. * - \ref I2C_GCMODE_DISABLE
  182. * @return none
  183. */
  184. void I2C_SetSlaveAddr(I2C_T *i2c, uint8_t u8SlaveNo, uint8_t u8SlaveAddr, uint8_t u8GCMode)
  185. {
  186. switch (u8SlaveNo) {
  187. case 0:
  188. i2c->ADDR0 = (u8SlaveAddr << 1) | u8GCMode;
  189. break;
  190. case 1:
  191. i2c->ADDR1 = (u8SlaveAddr << 1) | u8GCMode;
  192. break;
  193. case 2:
  194. i2c->ADDR2 = (u8SlaveAddr << 1) | u8GCMode;
  195. break;
  196. case 3:
  197. i2c->ADDR3 = (u8SlaveAddr << 1) | u8GCMode;
  198. break;
  199. default:
  200. i2c->ADDR0 = (u8SlaveAddr << 1) | u8GCMode;
  201. }
  202. }
  203. /**
  204. * @brief Configure the mask of slave address. The corresponding address bit is "Don't Care".
  205. * @param[in] i2c is the base address of I2C module.
  206. * @param[in] u8SlaveNo is the set number of salve address.
  207. * @param[in] u8SlaveAddrMask is the slave address mask.
  208. * @return none
  209. */
  210. void I2C_SetSlaveAddrMask(I2C_T *i2c, uint8_t u8SlaveNo, uint8_t u8SlaveAddrMask)
  211. {
  212. switch (u8SlaveNo) {
  213. case 0:
  214. i2c->ADDRMSK0 = u8SlaveAddrMask << 1;
  215. break;
  216. case 1:
  217. i2c->ADDRMSK1 = u8SlaveAddrMask << 1;
  218. break;
  219. case 2:
  220. i2c->ADDRMSK2 = u8SlaveAddrMask << 1;
  221. break;
  222. case 3:
  223. i2c->ADDRMSK3 = u8SlaveAddrMask << 1;
  224. break;
  225. default:
  226. i2c->ADDRMSK0 = u8SlaveAddrMask << 1;
  227. }
  228. }
  229. /**
  230. * @brief This function enables timeout function and configures DIV4 function to support long timeout.
  231. * @param[in] i2c is the base address of I2C module.
  232. * @param[in] u8LongTimeout Enable timeout counter input clock is divide by 4.
  233. * @return none
  234. */
  235. void I2C_EnableTimeout(I2C_T *i2c, uint8_t u8LongTimeout)
  236. {
  237. if(u8LongTimeout)
  238. i2c->TOCTL |= I2C_TOCTL_TOCDIV4_Msk;
  239. else
  240. i2c->TOCTL &= ~I2C_TOCTL_TOCDIV4_Msk;
  241. i2c->TOCTL |= I2C_TOCTL_TOCEN_Msk;
  242. }
  243. /**
  244. * @brief This function disables time-out function.
  245. * @param[in] i2c is the base address of I2C module.
  246. * @return none
  247. */
  248. void I2C_DisableTimeout(I2C_T *i2c)
  249. {
  250. i2c->TOCTL &= ~I2C_TOCTL_TOCEN_Msk;
  251. }
  252. /**
  253. * @brief This function enables the wakeup function of I2C module.
  254. * @param[in] i2c is the base address of I2C module.
  255. * @return none
  256. */
  257. void I2C_EnableWakeup(I2C_T *i2c)
  258. {
  259. i2c->WKCTL |= I2C_WKCTL_WKEN_Msk;
  260. }
  261. /**
  262. * @brief This function disables the wakeup function of I2C module.
  263. * @param[in] i2c is the base address of I2C module.
  264. * @return none
  265. */
  266. void I2C_DisableWakeup(I2C_T *i2c)
  267. {
  268. i2c->WKCTL &= ~I2C_WKCTL_WKEN_Msk;
  269. }
  270. /*@}*/ /* end of group NUC472_442_I2C_EXPORTED_FUNCTIONS */
  271. /*@}*/ /* end of group NUC472_442_I2C_Driver */
  272. /*@}*/ /* end of group NUC472_442_Device_Driver */
  273. /*** (C) COPYRIGHT 2014 Nuvoton Technology Corp. ***/