at32f415_i2c.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632
  1. /**
  2. **************************************************************************
  3. * @file at32f415_i2c.c
  4. * @version v2.0.5
  5. * @date 2022-05-20
  6. * @brief contains all the functions for the i2c firmware library
  7. **************************************************************************
  8. * Copyright notice & Disclaimer
  9. *
  10. * The software Board Support Package (BSP) that is made available to
  11. * download from Artery official website is the copyrighted work of Artery.
  12. * Artery authorizes customers to use, copy, and distribute the BSP
  13. * software and its related documentation for the purpose of design and
  14. * development in conjunction with Artery microcontrollers. Use of the
  15. * software is governed by this copyright notice and the following disclaimer.
  16. *
  17. * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
  18. * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
  19. * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
  20. * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
  21. * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
  22. * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
  23. *
  24. **************************************************************************
  25. */
  26. #include "at32f415_conf.h"
  27. /** @addtogroup AT32F415_periph_driver
  28. * @{
  29. */
  30. /** @defgroup I2C
  31. * @brief I2C driver modules
  32. * @{
  33. */
  34. #ifdef I2C_MODULE_ENABLED
  35. /** @defgroup I2C_private_functions
  36. * @{
  37. */
  38. /**
  39. * @brief reset the i2c register
  40. * @param i2c_x: to select the i2c peripheral.
  41. * this parameter can be one of the following values:
  42. * I2C1, I2C2.
  43. * @retval none
  44. */
  45. void i2c_reset(i2c_type *i2c_x)
  46. {
  47. if(i2c_x == I2C1)
  48. {
  49. crm_periph_reset(CRM_I2C1_PERIPH_RESET, TRUE);
  50. crm_periph_reset(CRM_I2C1_PERIPH_RESET, FALSE);
  51. }
  52. else if(i2c_x == I2C2)
  53. {
  54. crm_periph_reset(CRM_I2C2_PERIPH_RESET, TRUE);
  55. crm_periph_reset(CRM_I2C2_PERIPH_RESET, FALSE);
  56. }
  57. }
  58. /**
  59. * @brief software reset.
  60. * @param i2c_x: to select the i2c peripheral.
  61. * this parameter can be one of the following values:
  62. * I2C1, I2C2.
  63. * @param new_state (TRUE or FALSE)
  64. * @retval none
  65. */
  66. void i2c_software_reset(i2c_type *i2c_x, confirm_state new_state)
  67. {
  68. i2c_x->ctrl1_bit.reset = new_state;
  69. }
  70. /**
  71. * @brief init i2c speed and duty cycle.
  72. * @param i2c_x: to select the i2c peripheral.
  73. * this parameter can be one of the following values:
  74. * I2C1, I2C2.
  75. * @param duty
  76. * this parameter can be one of the following values:
  77. * - I2C_FSMODE_DUTY_2_1: duty cycle 2:1
  78. * - I2C_FSMODE_DUTY_16_9: duty cycle 16:9
  79. * @param speed: i2c scl clock speed, such as 100000
  80. * @retval none
  81. */
  82. void i2c_init(i2c_type *i2c_x, i2c_fsmode_duty_cycle_type duty, uint32_t speed)
  83. {
  84. uint32_t apb_freq = 0;
  85. uint16_t freq_mhz = 0, temp = 0;
  86. crm_clocks_freq_type clocks;
  87. /* disable i2c peripherals */
  88. i2c_x->ctrl1_bit.i2cen = FALSE;
  89. /* get system clock */
  90. crm_clocks_freq_get(&clocks);
  91. if((i2c_x == I2C1) || (i2c_x == I2C2))
  92. {
  93. apb_freq = clocks.apb1_freq;
  94. }
  95. freq_mhz = (apb_freq / 1000000);
  96. /* set i2c input clock frequency */
  97. i2c_x->ctrl2_bit.clkfreq = freq_mhz;
  98. /* standard mode */
  99. if(speed <= 100000)
  100. {
  101. temp = (uint16_t)(apb_freq / (speed << 1));
  102. if (temp < 0x04)
  103. {
  104. temp = 0x04;
  105. }
  106. /* set scl clock */
  107. i2c_x->clkctrl_bit.speed = temp;
  108. /* disable fast mode */
  109. i2c_x->clkctrl_bit.speedmode = FALSE;
  110. /* set the maximum rise time */
  111. if((freq_mhz + 1) > 0x3F)
  112. {
  113. i2c_x->tmrise_bit.risetime = 0x3F;
  114. }
  115. else
  116. {
  117. i2c_x->tmrise_bit.risetime = (freq_mhz + 1);
  118. }
  119. }
  120. /* fast mode */
  121. else
  122. {
  123. if (duty == I2C_FSMODE_DUTY_2_1)
  124. {
  125. temp = (uint16_t)(apb_freq / (speed * 3));
  126. /* the ratio of high level to low level is 1:2 */
  127. i2c_x->clkctrl_bit.dutymode = I2C_FSMODE_DUTY_2_1;
  128. }
  129. else
  130. {
  131. temp = (uint16_t)(apb_freq / (speed * 25));
  132. /* the ratio of high level to low level is 9:16 */
  133. i2c_x->clkctrl_bit.dutymode = I2C_FSMODE_DUTY_16_9;
  134. }
  135. if (temp == 0)
  136. {
  137. temp = 0x0001;
  138. }
  139. /* set scl clock*/
  140. i2c_x->clkctrl_bit.speed = temp;
  141. /* set the mode to fast mode */
  142. i2c_x->clkctrl_bit.speedmode = TRUE;
  143. /* set the maximum rise time */
  144. i2c_x->tmrise_bit.risetime = (uint16_t)(((freq_mhz * (uint16_t)300) / (uint16_t)1000) + (uint16_t)1);
  145. }
  146. }
  147. /**
  148. * @brief config own address1.
  149. * @param i2c_x: to select the i2c peripheral.
  150. * this parameter can be one of the following values:
  151. * I2C1, I2C2.
  152. * @param mode
  153. * this parameter can be one of the following values:
  154. * - I2C_ADDRESS_MODE_7BIT: 7bit address.
  155. * - I2C_ADDRESS_MODE_10BIT: 10bit address.
  156. * @param address: own address1, such as 0xb0.
  157. * @retval none
  158. */
  159. void i2c_own_address1_set(i2c_type *i2c_x, i2c_address_mode_type mode, uint16_t address)
  160. {
  161. /* set address mode */
  162. i2c_x->oaddr1_bit.addr1mode = mode;
  163. /* set own address1 */
  164. i2c_x->oaddr1_bit.addr1 = address;
  165. }
  166. /**
  167. * @brief config own address2.
  168. * @param i2c_x: to select the i2c peripheral.
  169. * this parameter can be one of the following values:
  170. * I2C1, I2C2.
  171. * @param address: specifies the 7bit i2c own address2, such as 0xa0.
  172. * @retval none.
  173. */
  174. void i2c_own_address2_set(i2c_type *i2c_x, uint8_t address)
  175. {
  176. i2c_x->oaddr2_bit.addr2 = (address >> 1);
  177. }
  178. /**
  179. * @brief enable or disable own address2.
  180. * @param i2c_x: to select the i2c peripheral.
  181. * this parameter can be one of the following values:
  182. * I2C1, I2C2.
  183. * @param new_state (TRUE or FALSE)
  184. * @retval none
  185. */
  186. void i2c_own_address2_enable(i2c_type *i2c_x, confirm_state new_state)
  187. {
  188. i2c_x->oaddr2_bit.addr2en = new_state;
  189. }
  190. /**
  191. * @brief enable or disable the smbus mode
  192. * @param i2c_x: to select the i2c peripheral.
  193. * this parameter can be one of the following values:
  194. * I2C1, I2C2.
  195. * @param new_state (TRUE or FALSE)
  196. * @retval none
  197. */
  198. void i2c_smbus_enable(i2c_type *i2c_x, confirm_state new_state)
  199. {
  200. i2c_x->ctrl1_bit.permode = new_state;
  201. }
  202. /**
  203. * @brief enable or disable i2c periph
  204. * @param i2c_x: to select the i2c peripheral.
  205. * this parameter can be one of the following values:
  206. * I2C1, I2C2.
  207. * @param new_state (TRUE or FALSE)
  208. * @retval none
  209. */
  210. void i2c_enable(i2c_type *i2c_x, confirm_state new_state)
  211. {
  212. i2c_x->ctrl1_bit.i2cen = new_state;
  213. }
  214. /**
  215. * @brief config fast mode duty cycle
  216. * @param i2c_x: to select the i2c peripheral.
  217. * this parameter can be one of the following values:
  218. * I2C1, I2C2.
  219. * @param duty
  220. * this parameter can be one of the following values:
  221. * - I2C_FSMODE_DUTY_2_1: duty cycle 2:1
  222. * - I2C_FSMODE_DUTY_16_9: duty cycle 16:9
  223. * @retval none
  224. */
  225. void i2c_fast_mode_duty_set(i2c_type *i2c_x, i2c_fsmode_duty_cycle_type duty)
  226. {
  227. i2c_x->clkctrl_bit.dutymode = duty;
  228. }
  229. /**
  230. * @brief enable or disable clock stretch.
  231. * @param i2c_x: to select the i2c peripheral.
  232. * this parameter can be one of the following values:
  233. * I2C1, I2C2.
  234. * @param new_state (TRUE or FALSE)
  235. * @retval none
  236. */
  237. void i2c_clock_stretch_enable(i2c_type *i2c_x, confirm_state new_state)
  238. {
  239. i2c_x->ctrl1_bit.stretch = !new_state;
  240. }
  241. /**
  242. * @brief enable or disable acknowledge.
  243. * @param i2c_x: to select the i2c peripheral.
  244. * this parameter can be one of the following values:
  245. * I2C1, I2C2.
  246. * @param new_state (TRUE or FALSE)
  247. * @retval none.
  248. */
  249. void i2c_ack_enable(i2c_type *i2c_x, confirm_state new_state)
  250. {
  251. i2c_x->ctrl1_bit.acken = new_state;
  252. }
  253. /**
  254. * @brief master receiving mode acknowledge control.
  255. * @param i2c_x: to select the i2c peripheral.
  256. * this parameter can be one of the following values:
  257. * I2C1, I2C2.
  258. * @param pos
  259. * this parameter can be one of the following values:
  260. * - I2C_MASTER_ACK_CURRENT: acken bit acts on the current byte
  261. * - I2C_MASTER_ACK_NEXT: acken bit acts on the next byte
  262. * @retval none
  263. */
  264. void i2c_master_receive_ack_set(i2c_type *i2c_x, i2c_master_ack_type pos)
  265. {
  266. i2c_x->ctrl1_bit.mackctrl = pos;
  267. }
  268. /**
  269. * @brief pec position set.
  270. * @param i2c_x: to select the i2c peripheral.
  271. * this parameter can be one of the following values:
  272. * I2C1, I2C2.
  273. * @param pos
  274. * this parameter can be one of the following values:
  275. * - I2C_PEC_POSITION_CURRENT: the current byte is pec
  276. * - I2C_PEC_POSITION_NEXT: the next byte is pec
  277. * @retval none
  278. */
  279. void i2c_pec_position_set(i2c_type *i2c_x, i2c_pec_position_type pos)
  280. {
  281. i2c_x->ctrl1_bit.mackctrl = pos;
  282. }
  283. /**
  284. * @brief enable or disable general call.
  285. * @param i2c_x: to select the i2c peripheral.
  286. * this parameter can be one of the following values:
  287. * I2C1, I2C2.
  288. * @param new_state (TRUE or FALSE)
  289. * @retval none
  290. */
  291. void i2c_general_call_enable(i2c_type *i2c_x, confirm_state new_state)
  292. {
  293. i2c_x->ctrl1_bit.gcaen = new_state;
  294. }
  295. /**
  296. * @brief enable or disable arp mode.
  297. * @param i2c_x: to select the i2c peripheral.
  298. * this parameter can be one of the following values:
  299. * I2C1, I2C2.
  300. * @param new_state (TRUE or FALSE)
  301. * @retval none
  302. */
  303. void i2c_arp_mode_enable(i2c_type *i2c_x, confirm_state new_state)
  304. {
  305. i2c_x->ctrl1_bit.arpen = new_state;
  306. }
  307. /**
  308. * @brief config smbus host or device.
  309. * @param i2c_x: to select the i2c peripheral.
  310. * this parameter can be one of the following values:
  311. * I2C1, I2C2.
  312. * @param level
  313. * this parameter can be one of the following values:
  314. * - I2C_SMBUS_MODE_DEVICE: smbus device.
  315. * - I2C_SMBUS_MODE_HOST: smbus host.
  316. * @retval none
  317. */
  318. void i2c_smbus_mode_set(i2c_type *i2c_x, i2c_smbus_mode_set_type mode)
  319. {
  320. i2c_x->ctrl1_bit.smbmode = mode;
  321. }
  322. /**
  323. * @brief drive the smbus alert pin high or low.
  324. * @param i2c_x: to select the i2c peripheral.
  325. * this parameter can be one of the following values:
  326. * I2C1, I2C2.
  327. * @param level
  328. * this parameter can be one of the following values:
  329. * - I2C_SMBUS_ALERT_LOW: smbus alert pin set low.
  330. * - I2C_SMBUS_ALERT_HIGH: smbus alert pin set high.
  331. * @retval none
  332. */
  333. void i2c_smbus_alert_set(i2c_type *i2c_x, i2c_smbus_alert_set_type level)
  334. {
  335. i2c_x->ctrl1_bit.smbalert = level;
  336. }
  337. /**
  338. * @brief enable or disable pec transfer.
  339. * @param i2c_x: to select the i2c peripheral.
  340. * this parameter can be one of the following values:
  341. * I2C1, I2C2.
  342. * @param new_state (TRUE or FALSE)
  343. * @retval none
  344. */
  345. void i2c_pec_transmit_enable(i2c_type *i2c_x, confirm_state new_state)
  346. {
  347. i2c_x->ctrl1_bit.pecten = new_state;
  348. }
  349. /**
  350. * @brief enable or disable pec calcultetion.
  351. * @param i2c_x: to select the i2c peripheral.
  352. * this parameter can be one of the following values:
  353. * I2C1, I2C2.
  354. * @param new_state (TRUE or FALSE)
  355. * @retval none
  356. */
  357. void i2c_pec_calculate_enable(i2c_type *i2c_x, confirm_state new_state)
  358. {
  359. i2c_x->ctrl1_bit.pecen = new_state;
  360. }
  361. /**
  362. * @brief get pec value.
  363. * @param i2c_x: to select the i2c peripheral.
  364. * this parameter can be one of the following values:
  365. * I2C1, I2C2.
  366. * @retval uint8_t: pec value.
  367. */
  368. uint8_t i2c_pec_value_get(i2c_type *i2c_x)
  369. {
  370. return i2c_x->sts2_bit.pecval;
  371. }
  372. /**
  373. * @brief enable or disable if the next dma transfer will be the last one.
  374. * @param i2c_x: to select the i2c peripheral.
  375. * this parameter can be one of the following values:
  376. * I2C1, I2C2.
  377. * @param new_state (TRUE or FALSE)
  378. * @retval none
  379. */
  380. void i2c_dma_end_transfer_set(i2c_type *i2c_x, confirm_state new_state)
  381. {
  382. i2c_x->ctrl2_bit.dmaend = new_state;
  383. }
  384. /**
  385. * @brief enable or disable dma requests.
  386. * @param i2c_x: to select the i2c peripheral.
  387. * this parameter can be one of the following values:
  388. * I2C1, I2C2.
  389. * @param new_state (TRUE or FALSE)
  390. * @retval none
  391. */
  392. void i2c_dma_enable(i2c_type *i2c_x, confirm_state new_state)
  393. {
  394. i2c_x->ctrl2_bit.dmaen = new_state;
  395. }
  396. /**
  397. * @brief enable or disable interrupt
  398. * @param i2c_x: to select the i2c peripheral.
  399. * this parameter can be one of the following values:
  400. * I2C1, I2C2.
  401. * @param source
  402. * this parameter can be one of the following values:
  403. * - I2C_DATA_INT: data interrupt.
  404. * - I2C_EV_INT: event interrupt.
  405. * - I2C_ERR_INT: error interrupt.
  406. * @param new_state (TRUE or FALSE)
  407. * @retval none
  408. */
  409. void i2c_interrupt_enable(i2c_type *i2c_x, uint16_t source, confirm_state new_state)
  410. {
  411. if (new_state != FALSE)
  412. {
  413. i2c_x->ctrl2 |= source;
  414. }
  415. else
  416. {
  417. i2c_x->ctrl2 &= (uint16_t)~source;
  418. }
  419. }
  420. /**
  421. * @brief generate start condition.
  422. * @param i2c_x: to select the i2c peripheral.
  423. * this parameter can be one of the following values:
  424. * I2C1, I2C2.
  425. * @retval none.
  426. */
  427. void i2c_start_generate(i2c_type *i2c_x)
  428. {
  429. i2c_x->ctrl1_bit.genstart = TRUE;
  430. }
  431. /**
  432. * @brief generate stop condition.
  433. * @param i2c_x: to select the i2c peripheral.
  434. * this parameter can be one of the following values:
  435. * I2C1, I2C2.
  436. * @retval none.
  437. */
  438. void i2c_stop_generate(i2c_type *i2c_x)
  439. {
  440. i2c_x->ctrl1_bit.genstop = TRUE;
  441. }
  442. /**
  443. * @brief transmit the slave address.
  444. * @param i2c_x: to select the i2c peripheral.
  445. * this parameter can be one of the following values:
  446. * I2C1, I2C2.
  447. * @param address: specifies the slave address which will be transmitted
  448. * @param direction
  449. * this parameter can be one of the following values:
  450. * - I2C_DIRECTION_TRANSMIT: transmit mode.
  451. * - I2C_DIRECTION_RECEIVE: receive mode.
  452. * @retval none.
  453. */
  454. void i2c_7bit_address_send(i2c_type *i2c_x, uint8_t address, i2c_direction_type direction)
  455. {
  456. if(direction == I2C_DIRECTION_TRANSMIT)
  457. {
  458. i2c_x->dt = address & 0xFE;
  459. }
  460. else
  461. {
  462. i2c_x->dt = address | 0x01;
  463. }
  464. }
  465. /**
  466. * @brief send a byte through the i2c periph.
  467. * @param i2c_x: to select the i2c peripheral.
  468. * this parameter can be one of the following values:
  469. * I2C1, I2C2.
  470. * @param data: byte to be transmitted.
  471. * @retval none
  472. */
  473. void i2c_data_send(i2c_type *i2c_x, uint8_t data)
  474. {
  475. i2c_x->dt = data;
  476. }
  477. /**
  478. * @brief receive a byte through the i2c periph.
  479. * @param i2c_x: to select the i2c peripheral.
  480. * this parameter can be one of the following values:
  481. * I2C1, I2C2.
  482. * @retval uint8_t: received byte
  483. */
  484. uint8_t i2c_data_receive(i2c_type *i2c_x)
  485. {
  486. return (uint8_t)i2c_x->dt;
  487. }
  488. /**
  489. * @brief get flag status
  490. * @param i2c_x: to select the i2c peripheral.
  491. * this parameter can be one of the following values:
  492. * I2C1, I2C2.
  493. * @param flag
  494. * this parameter can be one of the following values:
  495. * - I2C_STARTF_FLAG: start condition generation complete flag.
  496. * - I2C_ADDR7F_FLAG: 0~7 bit address match flag.
  497. * - I2C_TDC_FLAG: transmit data complete flag.
  498. * - I2C_ADDRHF_FLAG: master 9~8 bit address header match flag.
  499. * - I2C_STOPF_FLAG: stop condition generation complete flag.
  500. * - I2C_RDBF_FLAG: receive data buffer full flag.
  501. * - I2C_TDBE_FLAG: transmit data buffer empty flag.
  502. * - I2C_BUSERR_FLAG: bus error flag.
  503. * - I2C_ARLOST_FLAG: arbitration lost flag.
  504. * - I2C_ACKFAIL_FLAG: acknowledge failure flag.
  505. * - I2C_OUF_FLAG: overflow or underflow flag.
  506. * - I2C_PECERR_FLAG: pec receive error flag.
  507. * - I2C_TMOUT_FLAG: smbus timeout flag.
  508. * - I2C_ALERTF_FLAG: smbus alert flag.
  509. * - I2C_TRMODE_FLAG: transmission mode.
  510. * - I2C_BUSYF_FLAG: bus busy flag transmission mode.
  511. * - I2C_DIRF_FLAG: transmission direction flag.
  512. * - I2C_GCADDRF_FLAG: general call address received flag.
  513. * - I2C_DEVADDRF_FLAG: smbus device address received flag.
  514. * - I2C_HOSTADDRF_FLAG: smbus host address received flag.
  515. * - I2C_ADDR2_FLAG: own address 2 received flag.
  516. * @retval flag_status (SET or RESET)
  517. */
  518. flag_status i2c_flag_get(i2c_type *i2c_x, uint32_t flag)
  519. {
  520. __IO uint32_t reg = 0, value = 0;
  521. reg = flag >> 28;
  522. flag &= (uint32_t)0x00FFFFFF;
  523. if(reg == 0)
  524. {
  525. value = i2c_x->sts1;
  526. }
  527. else
  528. {
  529. flag = (uint32_t)(flag >> 16);
  530. value = i2c_x->sts2;
  531. }
  532. if((value & flag) != (uint32_t)RESET)
  533. {
  534. return SET;
  535. }
  536. else
  537. {
  538. return RESET;
  539. }
  540. }
  541. /**
  542. * @brief clear flag status
  543. * @param i2c_x: to select the i2c peripheral.
  544. * this parameter can be one of the following values:
  545. * I2C1, I2C2.
  546. * @param flag
  547. * this parameter can be any combination of the following values:
  548. * - I2C_BUSERR_FLAG: bus error flag.
  549. * - I2C_ARLOST_FLAG: arbitration lost flag.
  550. * - I2C_ACKFAIL_FLAG: acknowledge failure flag.
  551. * - I2C_OUF_FLAG: overflow or underflow flag.
  552. * - I2C_PECERR_FLAG: pec receive error flag.
  553. * - I2C_TMOUT_FLAG: smbus timeout flag.
  554. * - I2C_ALERTF_FLAG: smbus alert flag.
  555. * @retval none
  556. */
  557. void i2c_flag_clear(i2c_type *i2c_x, uint32_t flag)
  558. {
  559. i2c_x->sts1 = (uint16_t)~(flag & (uint32_t)0x00FFFFFF);
  560. }
  561. /**
  562. * @}
  563. */
  564. #endif
  565. /**
  566. * @}
  567. */
  568. /**
  569. * @}
  570. */