hpm_i2c_drv.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469
  1. /*
  2. * Copyright (c) 2021 hpmicro
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. *
  6. */
  7. #ifndef HPM_I2C_DRV_H
  8. #define HPM_I2C_DRV_H
  9. #include "hpm_common.h"
  10. #include "hpm_i2c_regs.h"
  11. #include "hpm_soc_feature.h"
  12. /**
  13. * @brief I2C driver APIs
  14. * @defgroup i2c_interface I2C driver APIs
  15. * @ingroup io_interfaces
  16. * @{
  17. */
  18. /**
  19. * @brief I2C status
  20. */
  21. enum {
  22. status_i2c_no_ack = MAKE_STATUS(status_group_i2c, 1),
  23. status_i2c_invalid_data = MAKE_STATUS(status_group_i2c, 2),
  24. status_i2c_no_addr_hit = MAKE_STATUS(status_group_i2c, 3),
  25. status_i2c_transmit_not_completed = MAKE_STATUS(status_group_i2c, 4),
  26. status_i2c_not_supported = MAKE_STATUS(status_group_i2c, 9),
  27. };
  28. /**
  29. * @brief I2C CMD
  30. */
  31. #define I2C_CMD_NO_ACTION (I2C_CMD_CMD_SET(0))
  32. #define I2C_CMD_ISSUE_DATA_TRANSMISSION (I2C_CMD_CMD_SET(1))
  33. #define I2C_CMD_ACK (I2C_CMD_CMD_SET(2))
  34. #define I2C_CMD_NACK (I2C_CMD_CMD_SET(3))
  35. #define I2C_CMD_CLEAR_FIFO (I2C_CMD_CMD_SET(4))
  36. #define I2C_CMD_RESET (I2C_CMD_CMD_SET(5))
  37. /**
  38. * @brief I2C data direction
  39. */
  40. #define I2C_DIR_MASTER_WRITE (0U)
  41. #define I2C_DIR_MASTER_READ (1U)
  42. #define I2C_DIR_SLAVE_READ (0U)
  43. #define I2C_DIR_SLAVE_WRITE (1U)
  44. /**
  45. * @brief I2C events for interrupt enable and status check
  46. */
  47. #define I2C_EVENT_TRANSACTION_COMPLETE I2C_INTEN_CMPL_MASK
  48. #define I2C_EVENT_BYTE_RECEIVED I2C_INTEN_BYTERECV_MASK
  49. #define I2C_EVENT_BYTE_TRANSMIT I2C_INTEN_BYTETRANS_MASK
  50. #define I2C_EVENT_START_CONDITION I2C_INTEN_START_MASK
  51. #define I2C_EVENT_STOP_CONDITION I2C_INTEN_STOP_MASK
  52. #define I2C_EVENT_LOSS_ARBITRATION I2C_INTEN_ARBLOSE_MASK
  53. #define I2C_EVENT_ADDRESS_HIT I2C_INTEN_ADDRHIT_MASK
  54. #define I2C_EVENT_FIFO_HALF I2C_INTEN_FIFOHALF_MASK
  55. #define I2C_EVENT_FIFO_FULL I2C_INTEN_FIFOFULL_MASK
  56. #define I2C_EVENT_FIFO_EMPTY I2C_INTEN_FIFOEMPTY_MASK
  57. #define I2C_EVENT_ALL_MASK (I2C_INTEN_CMPL_MASK \
  58. | I2C_INTEN_BYTERECV_MASK \
  59. | I2C_INTEN_BYTETRANS_MASK \
  60. | I2C_INTEN_START_MASK \
  61. | I2C_INTEN_STOP_MASK \
  62. | I2C_INTEN_ARBLOSE_MASK \
  63. | I2C_INTEN_ADDRHIT_MASK \
  64. | I2C_INTEN_FIFOHALF_MASK \
  65. | I2C_INTEN_FIFOFULL_MASK \
  66. | I2C_INTEN_FIFOEMPTY_MASK)
  67. /**
  68. * @brief I2C status for status check only
  69. */
  70. #define I2C_STATUS_LINE_SDA I2C_STATUS_LINESDA_MASK
  71. #define I2C_STATUS_LINE_SCL I2C_STATUS_LINESCL_MASK
  72. #define I2C_STATUS_GENERAL_CALL I2C_STATUS_GENCALL_MASK
  73. #define I2C_STATUS_BUS_BUSY I2C_STATUS_BUSBUSY_MASK
  74. #define I2C_STATUS_ACK I2C_STATUS_ACK_MASK
  75. /**
  76. * @brief I2C config
  77. */
  78. typedef struct {
  79. bool is_10bit_addressing;
  80. uint8_t i2c_mode;
  81. } i2c_config_t;
  82. /**
  83. * @brief I2C mode
  84. */
  85. typedef enum i2c_mode {
  86. i2c_mode_normal,
  87. i2c_mode_fast,
  88. i2c_mode_fast_plus,
  89. } i2c_mode_t;
  90. #ifdef __cplusplus
  91. extern "C" {
  92. #endif
  93. /**
  94. * @brief respond NACK
  95. *
  96. * @param [in] ptr I2C base address
  97. */
  98. static inline void i2c_respond_Nack(I2C_Type *ptr)
  99. {
  100. ptr->CMD = I2C_CMD_NACK;
  101. }
  102. /**
  103. * @brief respond ACK
  104. *
  105. * @param [in] ptr I2C base address
  106. */
  107. static inline void i2c_respond_ack(I2C_Type *ptr)
  108. {
  109. ptr->CMD = I2C_CMD_ACK;
  110. }
  111. /**
  112. * @brief clear I2C fifo
  113. *
  114. * @param [in] ptr I2C base address
  115. */
  116. static inline void i2c_clear_fifo(I2C_Type *ptr)
  117. {
  118. ptr->CMD = I2C_CMD_CLEAR_FIFO;
  119. }
  120. /**
  121. * @brief check data count
  122. *
  123. * @details It indicates number of bytes to transfer
  124. *
  125. * @param [in] ptr I2C base address
  126. * @retval data count value in byte
  127. */
  128. static inline uint8_t i2c_get_data_count(I2C_Type *ptr)
  129. {
  130. return I2C_CTRL_DATACNT_GET(ptr->CTRL);
  131. }
  132. /**
  133. * @brief check if I2C FIFO is full
  134. *
  135. * @param [in] ptr I2C base address
  136. * @retval true if FIFO is full
  137. */
  138. static inline bool i2c_fifo_is_full(I2C_Type *ptr)
  139. {
  140. return ptr->STATUS & I2C_STATUS_FIFOFULL_MASK;
  141. }
  142. /**
  143. * @brief check if I2C FIFO is half
  144. *
  145. * @note When I2C is transmitting data, it indicates if fifo is half-empty;
  146. * @note When I2C is receiving data, it indicates if fifo is half full.
  147. *
  148. * @param [in] ptr I2C base address
  149. * @retval true if FIFO is half empty or full
  150. */
  151. static inline bool i2c_fifo_is_half(I2C_Type *ptr)
  152. {
  153. return ptr->STATUS & I2C_STATUS_FIFOHALF_MASK;
  154. }
  155. /**
  156. * @brief check if I2C FIFO is empty
  157. *
  158. * @param [in] ptr I2C base address
  159. * @retval true if FIFO is empty
  160. */
  161. static inline bool i2c_fifo_is_empty(I2C_Type *ptr)
  162. {
  163. return ptr->STATUS & I2C_STATUS_FIFOEMPTY_MASK;
  164. }
  165. /**
  166. * @brief check if I2C is writing
  167. *
  168. * @param [in] ptr I2C base address
  169. * @retval bool value
  170. * @arg true: receive data if master mode, send data in slave mode
  171. * @arg false: send data if master mode, reveive data in slave mode
  172. *
  173. */
  174. static inline bool i2c_is_writing(I2C_Type *ptr)
  175. {
  176. return (ptr->CTRL & I2C_CTRL_DIR_MASK);
  177. }
  178. /**
  179. * @brief check if I2C is reading
  180. *
  181. * @param [in] ptr I2C base address
  182. * @retval bool value
  183. * @arg true: send data if master mode, receive data in slave mode
  184. * @arg false: receive data if master mode, send data in slave mode
  185. *
  186. */
  187. static inline bool i2c_is_reading(I2C_Type *ptr)
  188. {
  189. return !i2c_is_writing(ptr);
  190. }
  191. /**
  192. * @brief clear status
  193. *
  194. * @details Clear status based on mask
  195. *
  196. * @param [in] ptr I2C base address
  197. * @param [in] mask mask to clear status
  198. */
  199. static inline void i2c_clear_status(I2C_Type *ptr, uint32_t mask)
  200. {
  201. ptr->STATUS |= (mask & I2C_EVENT_ALL_MASK);
  202. }
  203. /**
  204. * @brief get status
  205. *
  206. * @details Get current I2C status bits
  207. *
  208. * @param [in] ptr I2C base address
  209. * @retval current I2C status
  210. */
  211. static inline uint32_t i2c_get_status(I2C_Type *ptr)
  212. {
  213. return ptr->STATUS;
  214. }
  215. /**
  216. * @brief disable interrupts
  217. *
  218. * @details Disable interrupts based on given mask
  219. *
  220. * @param [in] ptr I2C base address
  221. * @param [in] mask interrupt mask to be disabled
  222. */
  223. static inline void i2c_disable_irq(I2C_Type *ptr, uint32_t mask)
  224. {
  225. ptr->INTEN &= ~mask;
  226. }
  227. /**
  228. * @brief enable interrupts
  229. *
  230. * @details Enable interrupts based on given mask
  231. *
  232. * @param [in] ptr I2C base address
  233. * @param [in] mask interrupt mask to be enabled
  234. */
  235. static inline void i2c_enable_irq(I2C_Type *ptr, uint32_t mask)
  236. {
  237. ptr->INTEN |= mask;
  238. }
  239. /**
  240. * @brief enable 10 bit address mode
  241. *
  242. * @details enable 10 bit address mode, if not, address is 7 bit mode
  243. *
  244. * @param [in] ptr I2C base address
  245. * @param [in] enable
  246. * @arg true: enable 10 bit address mode
  247. * @arg false: enable 7 bit address mode
  248. */
  249. static inline void i2c_enable_10bit_address_mode(I2C_Type *ptr, bool enable)
  250. {
  251. ptr->SETUP |= I2C_SETUP_ADDRESSING_SET(enable);
  252. }
  253. /**
  254. * @brief I2C master initialization
  255. *
  256. * @details Initialized I2C controller working at master mode
  257. *
  258. * @param [in] ptr I2C base address
  259. * @param [in] src_clk_in_hz I2C controller source clock source frequency in Hz
  260. * @param [in] config i2c_config_t
  261. * @retval hpm_stat_t: status_success if initialization is completed without any error
  262. */
  263. hpm_stat_t i2c_init_master(I2C_Type *ptr,
  264. uint32_t src_clk_in_hz,
  265. i2c_config_t *config);
  266. /**
  267. * @brief I2C master write data to specific address of certain slave device
  268. *
  269. * @details Write to certain I2C device at specific address within that device
  270. *
  271. * @param [in] ptr I2C base address
  272. * @param [in] device_address I2C slave address
  273. * @param [in] addr address in that I2C device
  274. * @param [in] addr_size_in_byte I2C address in byte
  275. * @param [in] buf pointer of the data to be sent
  276. * @param [in] size_in_byte size of data to be sent in bytes
  277. * @retval hpm_stat_t: status_success if writing is completed without any error
  278. */
  279. hpm_stat_t i2c_master_address_write(I2C_Type *ptr,
  280. const uint16_t device_address,
  281. uint8_t *addr,
  282. uint8_t addr_size_in_byte,
  283. uint8_t *buf,
  284. const uint32_t size_in_byte);
  285. /**
  286. * @brief I2C master read data from specific address of certain slave device
  287. *
  288. * @details Read fram certain I2C device at specific address within that device
  289. *
  290. * @param [in] ptr I2C base address
  291. * @param [in] device_address I2C slave address
  292. * @param [in] addr address in that I2C device
  293. * @param [in] addr_size_in_byte I2C address in byte
  294. * @param [out] buf pointer of the buffer to receive data read from the device
  295. * @param [in] size size of data to be read in bytes
  296. * @retval hpm_stat_t: status_success if reading is completed without any error
  297. */
  298. hpm_stat_t i2c_master_address_read(I2C_Type *ptr,
  299. const uint16_t device_address,
  300. uint8_t *addr,
  301. uint8_t addr_size_in_byte,
  302. uint8_t *buf,
  303. const uint32_t size);
  304. /**
  305. * @brief I2C master write data to certain slave device
  306. *
  307. * @details Write data to I2C device
  308. *
  309. * @param [in] ptr I2C base address
  310. * @param [in] device_address I2C slave address
  311. * @param [in] buf pointer of the data to be sent
  312. * @param [in] size size of data to be sent in bytes
  313. * @retval hpm_stat_t: status_success if writing is completed without any error
  314. */
  315. hpm_stat_t i2c_master_write(I2C_Type *ptr,
  316. const uint16_t device_address,
  317. uint8_t *buf,
  318. const uint32_t size);
  319. /**
  320. * @brief I2C master start write data by DMA
  321. *
  322. * @details Write data to I2C device by DMA
  323. *
  324. * @param [in] i2c_ptr I2C base address
  325. * @param [in] device_address I2C slave address
  326. * @param [in] size size of data to be sent in bytes
  327. */
  328. void i2c_master_start_dma_write(I2C_Type *i2c_ptr, const uint16_t device_address, uint32_t size);
  329. /**
  330. * @brief I2C master start read data by DMA
  331. *
  332. * @details Read data to I2C device by DMA
  333. *
  334. * @param [in] i2c_ptr I2C base address
  335. * @param [in] device_address I2C slave address
  336. * @param [in] size size of data to be read in bytes
  337. */
  338. void i2c_master_start_dma_read(I2C_Type *i2c_ptr, const uint16_t device_address, uint32_t size);
  339. /**
  340. * @brief I2C master read data from certain slave device
  341. *
  342. * @details Read data from I2C device
  343. *
  344. * @param [in] ptr I2C base address
  345. * @param [in] device_address I2C slave address
  346. * @param [out] buf pointer of the buffer to store data read from device
  347. * @param [in] size size of data to be read in bytes
  348. * @retval hpm_stat_t: status_success if reading is completed without any error
  349. */
  350. hpm_stat_t i2c_master_read(I2C_Type *ptr,
  351. const uint16_t device_address,
  352. uint8_t *buf,
  353. const uint32_t size);
  354. /**
  355. * @brief I2C slave initialization
  356. *
  357. * @details Initialize I2C controller working at slave mode
  358. *
  359. * @param [in] ptr I2C base address
  360. * @param [in] src_clk_in_hz I2C controller source clock source frequency in Hz
  361. * @param [in] config I2C configuration structure
  362. * @param [in] slave_address I2C address to be used at slave mode
  363. * @retval hpm_stat_t: status_success if initialization is completed without any error
  364. */
  365. hpm_stat_t i2c_init_slave(I2C_Type *ptr, uint32_t src_clk_in_hz,
  366. i2c_config_t *config, const uint16_t slave_address);
  367. /**
  368. * @brief I2C slave read data
  369. *
  370. * @details Read data at slave mode
  371. *
  372. * @param [in] ptr I2C base address
  373. * @param [in] buf pointer of the buffer to store data read from device
  374. * @param [in] size size of data to be read in bytes
  375. * @retval hpm_stat_t: status_success if reading is completed without any error
  376. */
  377. hpm_stat_t i2c_slave_read(I2C_Type *ptr, uint8_t *buf, const uint32_t size);
  378. /**
  379. * @brief I2C slave write data
  380. *
  381. * @details Write data at slave mode.
  382. *
  383. * @param [in] ptr I2C base address
  384. * @param [in] buf pointer of the buffer to store data sent from device
  385. * @param [in] size size of data to be sent in bytes
  386. * @retval hpm_stat_t status_success if writing is completed without any error
  387. */
  388. hpm_stat_t i2c_slave_write(I2C_Type *ptr, uint8_t *buf, const uint32_t size);
  389. /**
  390. * @brief reset I2C
  391. *
  392. * @param [in] ptr I2C base address
  393. */
  394. void i2c_reset(I2C_Type *ptr);
  395. /**
  396. * @brief Enable i2c DMA
  397. *
  398. * @param [in] ptr I2C base address
  399. */
  400. static inline void i2c_dma_enable(I2C_Type *ptr)
  401. {
  402. ptr->SETUP |= I2C_SETUP_DMAEN_MASK;
  403. }
  404. /**
  405. * @brief Disable i2c DMA
  406. *
  407. * @param [in] ptr I2C base address
  408. */
  409. static inline void i2c_dma_disable(I2C_Type *ptr)
  410. {
  411. ptr->SETUP &= ~I2C_SETUP_DMAEN_MASK;
  412. }
  413. /**
  414. * @brief I2C slave dma transfer data
  415. *
  416. * @note The direction of data transmission depends on Master setting
  417. *
  418. * @param [in] ptr I2C base address
  419. * @param [in] size size of data in bytes
  420. */
  421. void i2c_slave_dma_transfer(I2C_Type *ptr, const uint32_t size);
  422. /**
  423. * @}
  424. */
  425. #ifdef __cplusplus
  426. }
  427. #endif
  428. #endif /* HPM_I2C_DRV_H */