gd32f30x_i2c.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683
  1. /*!
  2. \file gd32f30x_i2c.c
  3. \brief I2C driver
  4. */
  5. /*
  6. Copyright (C) 2017 GigaDevice
  7. 2017-02-10, V1.0.1, firmware for GD32F30x
  8. */
  9. #include "gd32f30x_i2c.h"
  10. #define I2CCLK_MAX 0x7fU /*!< i2cclk max value */
  11. #define I2C_FLAG_MASK 0x0000FFFFU /*!< i2c flag mask */
  12. /*!
  13. \brief reset I2C
  14. \param[in] i2c_periph: I2Cx(x=0,1)
  15. \param[out] none
  16. \retval none
  17. */
  18. void i2c_deinit(uint32_t i2c_periph)
  19. {
  20. switch(i2c_periph){
  21. case I2C0:
  22. /* reset I2C0 */
  23. rcu_periph_reset_enable(RCU_I2C0RST);
  24. rcu_periph_reset_disable(RCU_I2C0RST);
  25. break;
  26. case I2C1:
  27. /* reset I2C1 */
  28. rcu_periph_reset_enable(RCU_I2C1RST);
  29. rcu_periph_reset_disable(RCU_I2C1RST);
  30. break;
  31. default:
  32. break;
  33. }
  34. }
  35. /*!
  36. \brief configure I2C clock
  37. \param[in] i2c_periph: I2Cx(x=0,1)
  38. \param[in] clkspeed: I2C clock speed, supports standard mode (up to 100 kHz), fast mode (up to 400 kHz)
  39. and fast mode plus (up to 1MHz)
  40. \param[in] dutycyc: duty cycle in fast mode or fast mode plus
  41. \arg I2C_DTCY_2: T_low/T_high=2
  42. \arg I2C_DTCY_16_9: T_low/T_high=16/9
  43. \param[out] none
  44. \retval none
  45. */
  46. void i2c_clock_config(uint32_t i2c_periph, uint32_t clkspeed, uint32_t dutycyc)
  47. {
  48. uint32_t pclk1,clkc,freq,risetime;
  49. uint32_t temp;
  50. pclk1 = rcu_clock_freq_get(CK_APB1);
  51. /* I2C peripheral clock frequency */
  52. freq = (uint32_t)(pclk1/1000000U);
  53. if(freq >= I2CCLK_MAX){
  54. freq = I2CCLK_MAX;
  55. }
  56. temp = I2C_CTL1(i2c_periph);
  57. temp &= ~I2C_CTL1_I2CCLK;
  58. temp |= freq;
  59. I2C_CTL1(i2c_periph) = temp;
  60. if(100000U >= clkspeed){
  61. /* the maximum SCL rise time is 1000ns in standard mode */
  62. risetime = (uint32_t)((pclk1/1000000U)+1U);
  63. if(risetime >= I2CCLK_MAX){
  64. I2C_RT(i2c_periph) = I2CCLK_MAX;
  65. }else{
  66. I2C_RT(i2c_periph) = risetime;
  67. }
  68. clkc = (uint32_t)(pclk1/(clkspeed*2U));
  69. if(clkc < 0x04U){
  70. /* the CLKC in standard mode minmum value is 4 */
  71. clkc = 0x04U;
  72. }
  73. I2C_CKCFG(i2c_periph) |= (I2C_CKCFG_CLKC & clkc);
  74. }else if(400000U >= clkspeed){
  75. /* the maximum SCL rise time is 300ns in fast mode */
  76. I2C_RT(i2c_periph) = (uint32_t)(((freq*(uint32_t)300U)/(uint32_t)1000U)+(uint32_t)1U);
  77. if(I2C_DTCY_2 == dutycyc){
  78. /* I2C duty cycle is 2 */
  79. clkc = (uint32_t)(pclk1/(clkspeed*3U));
  80. I2C_CKCFG(i2c_periph) &= ~I2C_CKCFG_DTCY;
  81. }else{
  82. /* I2C duty cycle is 16/9 */
  83. clkc = (uint32_t)(pclk1/(clkspeed*25U));
  84. I2C_CKCFG(i2c_periph) |= I2C_CKCFG_DTCY;
  85. }
  86. if(0U == (clkc & I2C_CKCFG_CLKC)){
  87. /* the CLKC in fast mode minmum value is 1 */
  88. clkc |= 0x0001U;
  89. }
  90. I2C_CKCFG(i2c_periph) |= I2C_CKCFG_FAST;
  91. I2C_CKCFG(i2c_periph) |= clkc;
  92. }else{
  93. /* fast mode plus, the maximum SCL rise time is 120ns */
  94. I2C_RT(i2c_periph) = (uint32_t)(((freq*(uint32_t)120U)/(uint32_t)1000U)+(uint32_t)1U);
  95. if(I2C_DTCY_2 == dutycyc){
  96. /* I2C duty cycle is 2 */
  97. clkc = (uint32_t)(pclk1/(clkspeed*3U));
  98. I2C_CKCFG(i2c_periph) &= ~I2C_CKCFG_DTCY;
  99. }else{
  100. /* I2C duty cycle is 16/9 */
  101. clkc = (uint32_t)(pclk1/(clkspeed*25U));
  102. I2C_CKCFG(i2c_periph) |= I2C_CKCFG_DTCY;
  103. }
  104. /* enable fast mode */
  105. I2C_CKCFG(i2c_periph) |= I2C_CKCFG_FAST;
  106. I2C_CKCFG(i2c_periph) |= clkc;
  107. /* enable I2C fast mode plus */
  108. I2C_FMPCFG(i2c_periph) = I2C_FMPCFG_FMPEN;
  109. }
  110. }
  111. /*!
  112. \brief configure I2C address
  113. \param[in] i2c_periph: I2Cx(x=0,1)
  114. \param[in] mode:
  115. \arg I2C_I2CMODE_ENABLE: I2C mode
  116. \arg I2C_SMBUSMODE_ENABLE: SMBus mode
  117. \param[in] addformat: 7bits or 10bits
  118. \arg I2C_ADDFORMAT_7BITS: 7bits
  119. \arg I2C_ADDFORMAT_10BITS: 10bits
  120. \param[in] addr: I2C address
  121. \param[out] none
  122. \retval none
  123. */
  124. void i2c_mode_addr_config(uint32_t i2c_periph, uint32_t mode, uint32_t addformat, uint32_t addr)
  125. {
  126. /* SMBus/I2C mode selected */
  127. uint32_t ctl = 0U;
  128. ctl = I2C_CTL0(i2c_periph);
  129. ctl &= ~(I2C_CTL0_SMBEN);
  130. ctl |= mode;
  131. I2C_CTL0(i2c_periph) = ctl;
  132. /* configure address */
  133. I2C_SADDR0(i2c_periph) = (addformat | addr);
  134. }
  135. /*!
  136. \brief SMBus type selection
  137. \param[in] i2c_periph: I2Cx(x=0,1)
  138. \param[in] ack:
  139. \arg I2C_SMBUS_DEVICE: device
  140. \arg I2C_SMBUS_HOST: host
  141. \param[out] none
  142. \retval none
  143. */
  144. void i2c_smbus_type_config(uint32_t i2c_periph, uint32_t type)
  145. {
  146. if(I2C_SMBUS_HOST == type){
  147. I2C_CTL0(i2c_periph) |= I2C_CTL0_SMBSEL;
  148. }else{
  149. I2C_CTL0(i2c_periph) &= ~(I2C_CTL0_SMBSEL);
  150. }
  151. }
  152. /*!
  153. \brief whether or not to send an ACK
  154. \param[in] i2c_periph: I2Cx(x=0,1)
  155. \param[in] ack:
  156. \arg I2C_ACK_ENABLE: ACK will be sent
  157. \arg I2C_ACK_DISABLE: ACK will not be sent
  158. \param[out] none
  159. \retval none
  160. */
  161. void i2c_ack_config(uint32_t i2c_periph, uint32_t ack)
  162. {
  163. if(I2C_ACK_ENABLE == ack){
  164. I2C_CTL0(i2c_periph) |= I2C_CTL0_ACKEN;
  165. }else{
  166. I2C_CTL0(i2c_periph) &= ~(I2C_CTL0_ACKEN);
  167. }
  168. }
  169. /*!
  170. \brief I2C POAP position configure
  171. \param[in] i2c_periph: I2Cx(x=0,1)
  172. \param[in] pos:
  173. \arg I2C_ACKPOS_CURRENT: whether to send ACK or not for the current
  174. \arg I2C_ACKPOS_NEXT: whether to send ACK or not for the next byte
  175. \param[out] none
  176. \retval none
  177. */
  178. void i2c_ackpos_config(uint32_t i2c_periph, uint32_t pos)
  179. {
  180. /* configure I2C POAP position */
  181. if(I2C_ACKPOS_NEXT == pos){
  182. I2C_CTL0(i2c_periph) |= I2C_CTL0_POAP;
  183. }else{
  184. I2C_CTL0(i2c_periph) &= ~(I2C_CTL0_POAP);
  185. }
  186. }
  187. /*!
  188. \brief master send slave address
  189. \param[in] i2c_periph: I2Cx(x=0,1)
  190. \param[in] addr: slave address
  191. \param[in] trandirection: transmitter or receiver
  192. \arg I2C_TRANSMITTER: transmitter
  193. \arg I2C_RECEIVER: receiver
  194. \param[out] none
  195. \retval none
  196. */
  197. void i2c_master_addressing(uint32_t i2c_periph, uint32_t addr, uint32_t trandirection)
  198. {
  199. if(I2C_TRANSMITTER == trandirection){
  200. addr = addr & I2C_TRANSMITTER;
  201. }else{
  202. addr = addr | I2C_RECEIVER;
  203. }
  204. I2C_DATA(i2c_periph) = addr;
  205. }
  206. /*!
  207. \brief dual-address mode switch
  208. \param[in] i2c_periph: I2Cx(x=0,1)
  209. \param[in] dualaddr:
  210. \arg I2C_DUADEN_DISABLE: disable dual-address mode
  211. \arg I2C_DUADEN_ENABLE: enable dual-address mode
  212. \param[out] none
  213. \retval none
  214. */
  215. void i2c_dualaddr_enable(uint32_t i2c_periph, uint32_t dualaddr)
  216. {
  217. if(I2C_DUADEN_ENABLE == dualaddr){
  218. I2C_SADDR1(i2c_periph) |= I2C_SADDR1_DUADEN;
  219. }else{
  220. I2C_SADDR1(i2c_periph) &= ~(I2C_SADDR1_DUADEN);
  221. }
  222. }
  223. /*!
  224. \brief enable I2C
  225. \param[in] i2c_periph: I2Cx(x=0,1)
  226. \param[out] none
  227. \retval none
  228. */
  229. void i2c_enable(uint32_t i2c_periph)
  230. {
  231. I2C_CTL0(i2c_periph) |= I2C_CTL0_I2CEN;
  232. }
  233. /*!
  234. \brief disable I2C
  235. \param[in] i2c_periph: I2Cx(x=0,1)
  236. \param[out] none
  237. \retval none
  238. */
  239. void i2c_disable(uint32_t i2c_periph)
  240. {
  241. I2C_CTL0(i2c_periph) &= ~(I2C_CTL0_I2CEN);
  242. }
  243. /*!
  244. \brief generate a START condition on I2C bus
  245. \param[in] i2c_periph: I2Cx(x=0,1)
  246. \param[out] none
  247. \retval none
  248. */
  249. void i2c_start_on_bus(uint32_t i2c_periph)
  250. {
  251. I2C_CTL0(i2c_periph) |= I2C_CTL0_START;
  252. }
  253. /*!
  254. \brief generate a STOP condition on I2C bus
  255. \param[in] i2c_periph: I2Cx(x=0,1)
  256. \param[out] none
  257. \retval none
  258. */
  259. void i2c_stop_on_bus(uint32_t i2c_periph)
  260. {
  261. I2C_CTL0(i2c_periph) |= I2C_CTL0_STOP;
  262. }
  263. /*!
  264. \brief I2C transmit data function
  265. \param[in] i2c_periph: I2Cx(x=0,1)
  266. \param[in] data: data of transmission
  267. \param[out] none
  268. \retval none
  269. */
  270. void i2c_data_transmit(uint32_t i2c_periph, uint8_t data)
  271. {
  272. I2C_DATA(i2c_periph) = DATA_TRANS(data);
  273. }
  274. /*!
  275. \brief I2C receive data function
  276. \param[in] i2c_periph: I2Cx(x=0,1)
  277. \param[out] none
  278. \retval data of received
  279. */
  280. uint8_t i2c_data_receive(uint32_t i2c_periph)
  281. {
  282. return (uint8_t)DATA_RECV(I2C_DATA(i2c_periph));
  283. }
  284. /*!
  285. \brief enable I2C DMA mode
  286. \param[in] i2c_periph: I2Cx(x=0,1)
  287. \param[in] dmastate:
  288. \arg I2C_DMA_ON: DMA mode enable
  289. \arg I2C_DMA_OFF: DMA mode disable
  290. \param[out] none
  291. \retval none
  292. */
  293. void i2c_dma_enable(uint32_t i2c_periph, uint32_t dmastate)
  294. {
  295. /* configure I2C DMA function */
  296. uint32_t ctl = 0U;
  297. ctl = I2C_CTL1(i2c_periph);
  298. ctl &= ~(I2C_CTL1_DMAON);
  299. ctl |= dmastate;
  300. I2C_CTL1(i2c_periph) = ctl;
  301. }
  302. /*!
  303. \brief flag indicating DMA last transfer
  304. \param[in] i2c_periph: I2Cx(x=0,1)
  305. \param[in] dmalast:
  306. \arg I2C_DMALST_ON: next DMA EOT is the last transfer
  307. \arg I2C_DMALST_OFF: next DMA EOT is not the last transfer
  308. \param[out] none
  309. \retval none
  310. */
  311. void i2c_dma_last_transfer_enable(uint32_t i2c_periph, uint32_t dmalast)
  312. {
  313. /* configure DMA last transfer */
  314. uint32_t ctl = 0U;
  315. ctl = I2C_CTL1(i2c_periph);
  316. ctl &= ~(I2C_CTL1_DMALST);
  317. ctl |= dmalast;
  318. I2C_CTL1(i2c_periph) = ctl;
  319. }
  320. /*!
  321. \brief whether to stretch SCL low when data is not ready in slave mode
  322. \param[in] i2c_periph: I2Cx(x=0,1)
  323. \param[in] stretchpara:
  324. \arg I2C_SCLSTRETCH_ENABLE: SCL stretching is enabled
  325. \arg I2C_SCLSTRETCH_DISABLE: SCL stretching is disabled
  326. \param[out] none
  327. \retval none
  328. */
  329. void i2c_stretch_scl_low_config(uint32_t i2c_periph, uint32_t stretchpara)
  330. {
  331. /* configure I2C SCL strerching enable or disable */
  332. uint32_t ctl = 0U;
  333. ctl = I2C_CTL0(i2c_periph);
  334. ctl &= ~(I2C_CTL0_DISSTRC);
  335. ctl |= stretchpara;
  336. I2C_CTL0(i2c_periph) = ctl;
  337. }
  338. /*!
  339. \brief whether or not to response to a general call
  340. \param[in] i2c_periph: I2Cx(x=0,1)
  341. \param[in] gcallpara:
  342. \arg I2C_GCEN_ENABLE: slave will response to a general call
  343. \arg I2C_GCEN_DISABLE: slave will not response to a general call
  344. \param[out] none
  345. \retval none
  346. */
  347. void i2c_slave_response_to_gcall_config(uint32_t i2c_periph, uint32_t gcallpara)
  348. {
  349. /* configure slave response to a general call enable or disable */
  350. uint32_t ctl = 0U;
  351. ctl = I2C_CTL0(i2c_periph);
  352. ctl &= ~(I2C_CTL0_GCEN);
  353. ctl |= gcallpara;
  354. I2C_CTL0(i2c_periph) = ctl;
  355. }
  356. /*!
  357. \brief software reset I2C
  358. \param[in] i2c_periph: I2Cx(x=0,1)
  359. \param[in] sreset:
  360. \arg I2C_SRESET_SET: I2C is under reset
  361. \arg I2C_SRESET_RESET: I2C is not under reset
  362. \param[out] none
  363. \retval none
  364. */
  365. void i2c_software_reset_config(uint32_t i2c_periph, uint32_t sreset)
  366. {
  367. /* modify CTL0 and configure software reset I2C state */
  368. uint32_t ctl = 0U;
  369. ctl = I2C_CTL0(i2c_periph);
  370. ctl &= ~(I2C_CTL0_SRESET);
  371. ctl |= sreset;
  372. I2C_CTL0(i2c_periph) = ctl;
  373. }
  374. /*!
  375. \brief check I2C flag is set or not
  376. \param[in] i2c_periph: I2Cx(x=0,1)
  377. \param[in] flag:
  378. \arg I2C_FLAG_SBSEND: start condition send out
  379. \arg I2C_FLAG_ADDSEND: address is sent in master mode or received and matches in slave mode
  380. \arg I2C_FLAG_BTC: byte transmission finishes
  381. \arg I2C_FLAG_ADD10SEND: header of 10-bit address is sent in master mode
  382. \arg I2C_FLAG_STPDET: stop condition detected in slave mode
  383. \arg I2C_FLAG_RBNE: I2C_DATA is not Empty during receiving
  384. \arg I2C_FLAG_TBE: I2C_DATA is empty during transmitting
  385. \arg I2C_FLAG_BERR: a bus error occurs indication a unexpected start or stop condition on I2C bus
  386. \arg I2C_FLAG_LOSTARB: arbitration lost in master mode
  387. \arg I2C_FLAG_AERR: acknowledge error
  388. \arg I2C_FLAG_OUERR: overrun or underrun situation occurs in slave mode
  389. \arg I2C_FLAG_PECERR: PEC error when receiving data
  390. \arg I2C_FLAG_SMBTO: timeout signal in SMBus mode
  391. \arg I2C_FLAG_SMBALT: SMBus alert status
  392. \arg I2C_FLAG_MASTER: a flag indicating whether I2C block is in master or slave mode
  393. \arg I2C_FLAG_I2CBSY: busy flag
  394. \arg I2C_FLAG_TRS: whether the I2C is a transmitter or a receiver
  395. \arg I2C_FLAG_RXGC: general call address (00h) received
  396. \arg I2C_FLAG_DEFSMB: default address of SMBus device
  397. \arg I2C_FLAG_HSTSMB: SMBus host header detected in slave mode
  398. \arg I2C_FLAG_DUMOD: dual flag in slave mode indicating which address is matched in dual-address mode
  399. \param[out] none
  400. \retval FlagStatus: SET or RESET
  401. */
  402. FlagStatus i2c_flag_get(uint32_t i2c_periph, uint32_t flag)
  403. {
  404. uint32_t reg = 0U;
  405. FlagStatus reval = RESET;
  406. /* get the flag in which register */
  407. reg = (BIT(31) & flag);
  408. if((BIT(31) == reg)){
  409. if((I2C_STAT1(i2c_periph)&(flag & I2C_FLAG_MASK))){
  410. reval = SET;
  411. }else{
  412. reval = RESET;
  413. }
  414. }else{
  415. if((I2C_STAT0(i2c_periph)&(flag & I2C_FLAG_MASK))){
  416. reval = SET;
  417. }else{
  418. reval = RESET;
  419. }
  420. }
  421. /* return the flag status */
  422. return reval;
  423. }
  424. /*!
  425. \brief clear I2C flag
  426. \param[in] i2c_periph: I2Cx(x=0,1)
  427. \param[in] flag: flag type
  428. \arg I2C_FLAG_SMBALT: SMBus Alert status
  429. \arg I2C_FLAG_SMBTO: timeout signal in SMBus mode
  430. \arg I2C_FLAG_PECERR: PEC error when receiving data
  431. \arg I2C_FLAG_OUERR: over-run or under-run situation occurs in slave mode
  432. \arg I2C_FLAG_AERR: acknowledge error
  433. \arg I2C_FLAG_LOSTARB: arbitration lost in master mode
  434. \arg I2C_FLAG_BERR: a bus error
  435. \arg I2C_FLAG_ADDSEND: cleared by reading I2C_STAT0 and reading I2C_STAT1
  436. \param[out] none
  437. \retval none
  438. */
  439. void i2c_flag_clear(uint32_t i2c_periph, uint32_t flag)
  440. {
  441. if(I2C_FLAG_ADDSEND == flag){
  442. /* read I2C_STAT0 and then read I2C_STAT1 to clear ADDSEND */
  443. I2C_STAT0(i2c_periph);
  444. I2C_STAT1(i2c_periph);
  445. }else{
  446. I2C_STAT0(i2c_periph) &= ~(flag);
  447. }
  448. }
  449. /*!
  450. \brief enable I2C interrupt
  451. \param[in] i2c_periph: I2Cx(x=0,1)
  452. \param[in] inttype: interrupt type
  453. \arg I2C_INT_ERR: error interrupt enable
  454. \arg I2C_INT_EV: event interrupt enable
  455. \arg I2C_INT_BUF: buffer interrupt enable
  456. \param[out] none
  457. \retval none
  458. */
  459. void i2c_interrupt_enable(uint32_t i2c_periph, uint32_t inttype)
  460. {
  461. I2C_CTL1(i2c_periph) |= (inttype);
  462. }
  463. /*!
  464. \brief disable I2C interrupt
  465. \param[in] i2c_periph: I2Cx(x=0,1)
  466. \param[in] inttype: interrupt type
  467. \arg I2C_INT_ERR: error interrupt enable
  468. \arg I2C_INT_EV: event interrupt enable
  469. \arg I2C_INT_BUF: buffer interrupt enable
  470. \param[out] none
  471. \retval none
  472. */
  473. void i2c_interrupt_disable(uint32_t i2c_periph, uint32_t inttype)
  474. {
  475. I2C_CTL1(i2c_periph) &= ~(inttype);
  476. }
  477. /*!
  478. \brief check I2C interrupt flag
  479. \param[in] i2c_periph: I2Cx(x=0,1)
  480. \param[in] int_flag: interrupt flag
  481. \arg I2C_INT_FLAG_SBSEND: start condition sent out in master mode interrupt flag
  482. \arg I2C_INT_FLAG_ADDSEND: address is sent in master mode or received and matches in slave mode interrupt flag
  483. \arg I2C_INT_FLAG_BTC: byte transmission finishes
  484. \arg I2C_INT_FLAG_ADD10SEND: header of 10-bit address is sent in master mode interrupt flag
  485. \arg I2C_INT_FLAG_STPDET: etop condition detected in slave mode interrupt flag
  486. \arg I2C_INT_FLAG_RBNE: I2C_DATA is not Empty during receiving interrupt flag
  487. \arg I2C_INT_FLAG_TBE: I2C_DATA is empty during transmitting interrupt flag
  488. \arg I2C_INT_FLAG_BERR: a bus error occurs indication a unexpected start or stop condition on I2C bus interrupt flag
  489. \arg I2C_INT_FLAG_LOSTARB: arbitration lost in master mode interrupt flag
  490. \arg I2C_INT_FLAG_AERR: acknowledge error interrupt flag
  491. \arg I2C_INT_FLAG_OUERR: over-run or under-run situation occurs in slave mode interrupt flag
  492. \arg I2C_INT_FLAG_PECERR: PEC error when receiving data interrupt flag
  493. \arg I2C_INT_FLAG_SMBTO: timeout signal in SMBus mode interrupt flag
  494. \arg I2C_INT_FLAG_SMBALT: SMBus Alert status interrupt flag
  495. \param[out] none
  496. \retval none
  497. */
  498. FlagStatus i2c_interrupt_flag_get(uint32_t i2c_periph, uint32_t intflag)
  499. {
  500. uint32_t evie, errie, bufie;
  501. evie = I2C_CTL1(i2c_periph)&I2C_CTL1_EVIE;
  502. errie = I2C_CTL1(i2c_periph)&I2C_CTL1_ERRIE;
  503. /* check I2C event interrupt enable bit */
  504. if((intflag&0x00ffU) && evie){
  505. if(intflag&0x001fU){
  506. /* check I2C event flags except TBE and RBNE */
  507. if(intflag & I2C_STAT0(i2c_periph)){
  508. return SET;
  509. }else{
  510. return RESET;
  511. }
  512. }else{
  513. /* check I2C event flags TBE and RBNE */
  514. bufie = I2C_CTL1(i2c_periph)&I2C_CTL1_BUFIE;
  515. if(bufie){
  516. if(intflag & I2C_STAT0(i2c_periph)){
  517. return SET;
  518. }else{
  519. return RESET;
  520. }
  521. }else{
  522. return RESET;
  523. }
  524. }
  525. /* check I2C error interrupt enable bit */
  526. }else if((intflag&0xff00U) && errie){
  527. /* check I2C error flags */
  528. if(intflag & I2C_STAT0(i2c_periph)){
  529. return SET;
  530. }else{
  531. return RESET;
  532. }
  533. }else{
  534. return RESET;
  535. }
  536. }
  537. /*!
  538. \brief clear I2C interrupt flag
  539. \param[in] i2c_periph: I2Cx(x=0,1)
  540. \param[in] intflag: interrupt flag
  541. \arg I2C_INT_FLAG_ADDSEND: address is sent in master mode or received and matches in slave mode interrupt flag
  542. \arg I2C_INT_FLAG_BERR: a bus error occurs indication a unexpected start or stop condition on I2C bus interrupt flag
  543. \arg I2C_INT_FLAG_LOSTARB: arbitration lost in master mode interrupt flag
  544. \arg I2C_INT_FLAG_AERR: acknowledge error interrupt flag
  545. \arg I2C_INT_FLAG_OUERR: over-run or under-run situation occurs in slave mode interrupt flag
  546. \arg I2C_INT_FLAG_PECERR: PEC error when receiving data interrupt flag
  547. \arg I2C_INT_FLAG_SMBTO: timeout signal in SMBus mode interrupt flag
  548. \arg I2C_INT_FLAG_SMBALT: SMBus Alert status interrupt flag
  549. \param[out] none
  550. \retval none
  551. */
  552. void i2c_interrupt_flag_clear(uint32_t i2c_periph, uint32_t intflag)
  553. {
  554. if(I2C_INT_FLAG_ADDSEND == intflag){
  555. /* read I2C_STAT0 and then read I2C_STAT1 to clear ADDSEND */
  556. I2C_STAT0(i2c_periph);
  557. I2C_STAT1(i2c_periph);
  558. }else{
  559. I2C_STAT0(i2c_periph) &= ~(intflag);
  560. }
  561. }
  562. /*!
  563. \brief I2C PEC calculation on or off
  564. \param[in] i2c_periph: I2Cx(x=0,1)
  565. \param[in] pecpara:
  566. \arg I2C_PEC_ENABLE: PEC calculation on
  567. \arg I2C_PEC_DISABLE: PEC calculation off
  568. \param[out] none
  569. \retval none
  570. */
  571. void i2c_pec_enable(uint32_t i2c_periph, uint32_t pecstate)
  572. {
  573. /* on/off PEC calculation */
  574. uint32_t ctl = 0U;
  575. ctl = I2C_CTL0(i2c_periph);
  576. ctl &= ~(I2C_CTL0_PECEN);
  577. ctl |= pecstate;
  578. I2C_CTL0(i2c_periph) = ctl;
  579. }
  580. /*!
  581. \brief I2C whether to transfer PEC value
  582. \param[in] i2c_periph: I2Cx(x=0,1)
  583. \param[in] pecpara:
  584. \arg I2C_PECTRANS_ENABLE: transfer PEC
  585. \arg I2C_PECTRANS_DISABLE: not transfer PEC
  586. \param[out] none
  587. \retval none
  588. */
  589. void i2c_pec_transfer_enable(uint32_t i2c_periph, uint32_t pecpara)
  590. {
  591. /* whether to transfer PEC */
  592. uint32_t ctl = 0U;
  593. ctl = I2C_CTL0(i2c_periph);
  594. ctl &= ~(I2C_CTL0_PECTRANS);
  595. ctl |= pecpara;
  596. I2C_CTL0(i2c_periph) = ctl;
  597. }
  598. /*!
  599. \brief get packet error checking value
  600. \param[in] i2c_periph: I2Cx(x=0,1)
  601. \param[out] none
  602. \retval PEC value
  603. */
  604. uint8_t i2c_pec_value_get(uint32_t i2c_periph)
  605. {
  606. return (uint8_t)((I2C_STAT1(i2c_periph) & I2C_STAT1_ECV)>>8);
  607. }
  608. /*!
  609. \brief I2C issue alert through SMBA pin
  610. \param[in] i2c_periph: I2Cx(x=0,1)
  611. \param[in] smbuspara:
  612. \arg I2C_SALTSEND_ENABLE: issue alert through SMBA pin
  613. \arg I2C_SALTSEND_DISABLE: not issue alert through SMBA pin
  614. \param[out] none
  615. \retval none
  616. */
  617. void i2c_smbus_issue_alert(uint32_t i2c_periph, uint32_t smbuspara)
  618. {
  619. /* issue alert through SMBA pin configure*/
  620. uint32_t ctl = 0U;
  621. ctl = I2C_CTL0(i2c_periph);
  622. ctl &= ~(I2C_CTL0_SALT);
  623. ctl |= smbuspara;
  624. I2C_CTL0(i2c_periph) = ctl;
  625. }
  626. /*!
  627. \brief enable or disable I2C ARP protocol in SMBus switch
  628. \param[in] i2c_periph: I2Cx(x=0,1)
  629. \param[in] smbuspara:
  630. \arg I2C_ARP_ENABLE: enable ARP
  631. \arg I2C_ARP_DISABLE: disable ARP
  632. \param[out] none
  633. \retval none
  634. */
  635. void i2c_smbus_arp_enable(uint32_t i2c_periph, uint32_t arpstate)
  636. {
  637. /* enable or disable I2C ARP protocol*/
  638. uint32_t ctl = 0U;
  639. ctl = I2C_CTL0(i2c_periph);
  640. ctl &= ~(I2C_CTL0_ARPEN);
  641. ctl |= arpstate;
  642. I2C_CTL0(i2c_periph) = ctl;
  643. }