hpm_i2s_drv.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510
  1. /*
  2. * Copyright (c) 2021 hpmicro
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. *
  6. */
  7. #ifndef HPM_I2S_DRV_H
  8. #define HPM_I2S_DRV_H
  9. #include "hpm_common.h"
  10. #include "hpm_soc_feature.h"
  11. #include "hpm_i2s_regs.h"
  12. #include "hpm_i2s_common.h"
  13. /**
  14. * @brief I2S driver APIs
  15. * @defgroup i2s_interface I2S driver APIs
  16. * @ingroup io_interfaces
  17. * @{
  18. */
  19. /**
  20. * @brief I2S IRQ mask
  21. */
  22. #define I2S_IRQ_TX_FIFO_EMPTY I2S_CTRL_TXDNIE_MASK
  23. #define I2S_IRQ_RX_FIFO_DATA_AVAILABLE I2S_CTRL_RXDAIE_MASK
  24. #define I2S_IRQ_ERROR I2S_CTRL_ERRIE_MASK
  25. /**
  26. * @brief I2S data line
  27. */
  28. #define I2S_DATA_LINE_0 (0U)
  29. #define I2S_DATA_LINE_1 (1U)
  30. #define I2S_DATA_LINE_2 (2U)
  31. #define I2S_DATA_LINE_3 (3U)
  32. #define I2S_DATA_LINE_MAX I2S_DATA_LINE_3
  33. /* i2s channel slot mask */
  34. #define I2S_CHANNEL_SLOT_MASK(x) ((1U << (x)) & I2S_RXDSLOT_EN_MASK)
  35. /**
  36. * @brief I2S config
  37. */
  38. typedef struct i2s_config {
  39. bool invert_mclk_out;
  40. bool invert_mclk_in;
  41. bool use_external_mclk;
  42. bool invert_bclk_out;
  43. bool invert_bclk_in;
  44. bool use_external_bclk;
  45. bool invert_fclk_out;
  46. bool invert_fclk_in;
  47. bool use_external_fclk;
  48. bool enable_mclk_out;
  49. bool frame_start_at_rising_edge;
  50. uint16_t fifo_threshold;
  51. } i2s_config_t;
  52. /**
  53. * @brief I2S transfer config
  54. */
  55. typedef struct i2x_transfer_config {
  56. uint32_t sample_rate;
  57. bool enable_tdm_mode;
  58. uint8_t channel_num_per_frame;
  59. uint8_t channel_length; /* 16-bit or 32-bit */
  60. uint8_t audio_depth; /* 8-bit, 24-bit, 32-bit */
  61. bool master_mode;
  62. uint8_t protocol;
  63. uint8_t data_line;
  64. uint32_t channel_slot_mask;
  65. } i2s_transfer_config_t;
  66. #ifdef __cplusplus
  67. extern "C" {
  68. #endif
  69. /**
  70. * @brief enable TDM
  71. *
  72. * @param [in] ptr I2S base address
  73. */
  74. static inline void i2s_enable_tdm(I2S_Type *ptr)
  75. {
  76. ptr->CFGR |= I2S_CFGR_TDM_EN_MASK;
  77. }
  78. /**
  79. * @brief disable TDM
  80. *
  81. * @param [in] ptr I2S base address
  82. */
  83. static inline void i2s_disable_tdm(I2S_Type *ptr)
  84. {
  85. ptr->CFGR &= ~I2S_CFGR_TDM_EN_MASK;
  86. }
  87. /**
  88. * @brief update rx fifo threshold
  89. *
  90. * @param [in] ptr I2S base address
  91. * @param [in] threshold fifo threshold value
  92. */
  93. static inline void i2s_update_rx_fifo_threshold(I2S_Type *ptr, uint8_t threshold)
  94. {
  95. ptr->FIFO_THRESH = (ptr->FIFO_THRESH & ~I2S_FIFO_THRESH_RX_MASK)
  96. | I2S_FIFO_THRESH_RX_SET(threshold);
  97. }
  98. /**
  99. * @brief update tx fifo threshold
  100. *
  101. * @param [in] ptr I2S base address
  102. * @param [in] threshold fifo threshold value
  103. */
  104. static inline void i2s_update_tx_fifo_threshold(I2S_Type *ptr, uint8_t threshold)
  105. {
  106. ptr->FIFO_THRESH = (ptr->FIFO_THRESH & ~I2S_FIFO_THRESH_TX_MASK)
  107. | I2S_FIFO_THRESH_TX_SET(threshold);
  108. }
  109. /**
  110. * @brief open BCLK
  111. *
  112. * @param [in] ptr I2S base address
  113. */
  114. static inline void i2s_ungate_bclk(I2S_Type *ptr)
  115. {
  116. ptr->CFGR &= ~I2S_CFGR_BCLK_GATEOFF_MASK;
  117. }
  118. /**
  119. * @brief gete off BCLK
  120. *
  121. * @param [in] ptr I2S base address
  122. */
  123. static inline void i2s_gate_bclk(I2S_Type *ptr)
  124. {
  125. ptr->CFGR |= I2S_CFGR_BCLK_GATEOFF_MASK;
  126. }
  127. /**
  128. * @brief open MCLK
  129. *
  130. * @param [in] ptr I2S base address
  131. */
  132. static inline void i2s_ungate_mclk(I2S_Type *ptr)
  133. {
  134. ptr->MISC_CFGR &= ~I2S_MISC_CFGR_MCLK_GATEOFF_MASK;
  135. }
  136. /**
  137. * @brief gate off MCLK
  138. *
  139. * @param [in] ptr I2S base address
  140. */
  141. static inline void i2s_gate_mclk(I2S_Type *ptr)
  142. {
  143. ptr->MISC_CFGR |= I2S_MISC_CFGR_MCLK_GATEOFF_MASK;
  144. }
  145. /**
  146. * @brief enable TX dma request
  147. *
  148. * @param [in] ptr I2S base address
  149. */
  150. static inline void i2s_enable_tx_dma_request(I2S_Type *ptr)
  151. {
  152. ptr->CTRL |=I2S_CTRL_TX_DMA_EN_MASK;
  153. }
  154. /**
  155. * @brief disable TX dma request
  156. *
  157. * @param [in] ptr I2S base address
  158. */
  159. static inline void i2s_disable_tx_dma_request(I2S_Type *ptr)
  160. {
  161. ptr->CTRL &= ~I2S_CTRL_TX_DMA_EN_MASK;
  162. }
  163. /**
  164. * @brief enable RX dma request
  165. *
  166. * @param [in] ptr I2S base address
  167. */
  168. static inline void i2s_enable_rx_dma_request(I2S_Type *ptr)
  169. {
  170. ptr->CTRL |=I2S_CTRL_RX_DMA_EN_MASK;
  171. }
  172. /**
  173. * @brief disable RX dma request
  174. *
  175. * @param [in] ptr I2S base address
  176. */
  177. static inline void i2s_disable_rx_dma_request(I2S_Type *ptr)
  178. {
  179. ptr->CTRL &= ~I2S_CTRL_RX_DMA_EN_MASK;
  180. }
  181. /**
  182. * @brief enable IRQ
  183. *
  184. * @param [in] ptr I2S base address
  185. * @param [in] mask irq bit mask
  186. */
  187. static inline void i2s_enable_irq(I2S_Type *ptr, uint32_t mask)
  188. {
  189. ptr->CTRL |= mask;
  190. }
  191. /**
  192. * @brief disable IRQ
  193. *
  194. * @param [in] ptr I2S base address
  195. * @param [in] mask irq bit mask
  196. */
  197. static inline void i2s_disable_irq(I2S_Type *ptr, uint32_t mask)
  198. {
  199. ptr->CTRL &= ~mask;
  200. }
  201. /**
  202. * @brief I2S enable
  203. *
  204. * @param [in] ptr I2S base address
  205. */
  206. static inline void i2s_enable(I2S_Type *ptr)
  207. {
  208. ptr->CTRL |= ~I2S_CTRL_I2S_EN_MASK;
  209. }
  210. /**
  211. * @brief I2S disable
  212. *
  213. * @param [in] ptr I2S base address
  214. */
  215. static inline void i2s_disable(I2S_Type *ptr)
  216. {
  217. ptr->CTRL &= ~I2S_CTRL_I2S_EN_MASK;
  218. }
  219. /**
  220. * @brief I2S enable rx function
  221. *
  222. * @param [in] ptr I2S base address
  223. * @param [in] rx_mask rx data line mask
  224. */
  225. static inline void i2s_enable_rx(I2S_Type *ptr, uint8_t rx_mask)
  226. {
  227. ptr->CTRL |= I2S_CTRL_RX_EN_SET(rx_mask);
  228. }
  229. /**
  230. * @brief I2S disable rx function
  231. *
  232. * @param [in] ptr I2S base address
  233. * @param [in] rx_mask rx data line mask
  234. */
  235. static inline void i2s_disable_rx(I2S_Type *ptr, uint8_t rx_mask)
  236. {
  237. ptr->CTRL &= ~I2S_CTRL_RX_EN_SET(rx_mask);
  238. }
  239. /**
  240. * @brief I2S enable tx function
  241. *
  242. * @param [in] ptr I2S base address
  243. * @param [in] tx_mask tx data line mask
  244. */
  245. static inline void i2s_enable_tx(I2S_Type *ptr, uint8_t tx_mask)
  246. {
  247. ptr->CTRL |= I2S_CTRL_TX_EN_SET(tx_mask);
  248. }
  249. /**
  250. * @brief I2S disbale tx function
  251. *
  252. * @param [in] ptr I2S base address
  253. * @param [in] tx_mask tx data line mask
  254. */
  255. static inline void i2s_disable_tx(I2S_Type *ptr, uint8_t tx_mask)
  256. {
  257. ptr->CTRL &= ~I2S_CTRL_TX_EN_SET(tx_mask);
  258. }
  259. /**
  260. * @brief I2S clear tx fifo
  261. *
  262. * @param [in] ptr I2S base address
  263. */
  264. static inline void i2s_clear_tx_fifo(I2S_Type *ptr)
  265. {
  266. ptr->CTRL |= I2S_CTRL_TXFIFOCLR_MASK;
  267. while (ptr->CTRL & I2S_CTRL_TXFIFOCLR_MASK) {}
  268. }
  269. /**
  270. * @brief I2S clear rx fifo
  271. *
  272. * @param [in] ptr I2S base address
  273. */
  274. static inline void i2s_clear_rx_fifo(I2S_Type *ptr)
  275. {
  276. ptr->CTRL |= I2S_CTRL_RXFIFOCLR_MASK;
  277. while (ptr->CTRL & I2S_CTRL_RXFIFOCLR_MASK) {}
  278. }
  279. /**
  280. * @brief I2S reset clock generator
  281. *
  282. * @param [in] ptr I2S base address
  283. */
  284. static inline void i2s_reset_clock_gen(I2S_Type *ptr)
  285. {
  286. ptr->CTRL |= I2S_CTRL_SFTRST_CLKGEN_MASK;
  287. ptr->CTRL &= ~I2S_CTRL_SFTRST_CLKGEN_MASK;
  288. }
  289. /**
  290. * @brief I2S reset tx function
  291. *
  292. * @param [in] ptr I2S base address
  293. */
  294. static inline void i2s_reset_tx(I2S_Type *ptr)
  295. {
  296. ptr->CTRL |= I2S_CTRL_SFTRST_TX_MASK;
  297. ptr->CTRL &= ~I2S_CTRL_SFTRST_TX_MASK;
  298. }
  299. /**
  300. * @brief I2S reset rx function
  301. *
  302. * @param [in] ptr I2S base address
  303. */
  304. static inline void i2s_reset_rx(I2S_Type *ptr)
  305. {
  306. ptr->CTRL |= I2S_CTRL_SFTRST_RX_MASK;
  307. ptr->CTRL &= ~I2S_CTRL_SFTRST_RX_MASK;
  308. }
  309. /**
  310. * @brief I2S get tx fifo level
  311. *
  312. * @param [in] ptr I2S base address
  313. *
  314. * @retval I2S tx fifo level
  315. */
  316. static inline uint32_t i2s_get_tx_fifo_level(I2S_Type *ptr)
  317. {
  318. return ptr->TFIFO_FILLINGS;
  319. }
  320. /**
  321. * @brief I2S get data line tx fifo level
  322. *
  323. * @param [in] ptr I2S base address
  324. * @param [in] line I2S data line
  325. *
  326. * @retval I2S data line tx fifo level
  327. */
  328. static inline uint32_t i2s_get_tx_line_fifo_level(I2S_Type *ptr, uint8_t line)
  329. {
  330. return i2s_get_tx_fifo_level(ptr) & (0xFF << (line << 3));
  331. }
  332. /**
  333. * @brief I2S get rx fifo level
  334. *
  335. * @param [in] ptr I2S base address
  336. *
  337. * @retval I2S rx fifo level
  338. */
  339. static inline uint32_t i2s_get_rx_fifo_level(I2S_Type *ptr)
  340. {
  341. return ptr->RFIFO_FILLINGS;
  342. }
  343. /**
  344. * @brief I2S get data line rx fifo level
  345. *
  346. * @param [in] ptr I2S base address
  347. * @param [in] line I2S data line
  348. *
  349. * @retval I2S data line rx fifo level
  350. */
  351. static inline uint32_t i2s_get_rx_line_fifo_level(I2S_Type *ptr, uint8_t line)
  352. {
  353. return i2s_get_rx_fifo_level(ptr) & (0xFF << (line << 3));
  354. }
  355. /**
  356. * @brief I2S get IRQ status
  357. *
  358. * @param [in] ptr I2S base address
  359. *
  360. * @retval I2S STA register value
  361. */
  362. static inline uint32_t i2s_get_irq_status(I2S_Type *ptr)
  363. {
  364. return ptr->STA;
  365. }
  366. /**
  367. * @brief I2S stop transfer
  368. *
  369. * @param [in] ptr I2S base address
  370. */
  371. static inline void i2s_stop_transfer(I2S_Type *ptr)
  372. {
  373. i2s_disable(ptr);
  374. }
  375. /**
  376. * @brief I2S config tx
  377. *
  378. * @param [in] ptr I2S base address
  379. * @param [in] mclk_in_hz mclk frequency in Hz
  380. * @param [in] config i2s_transfer_config_t
  381. * @retval hpm_stat_t status_invalid_argument or status_success
  382. */
  383. hpm_stat_t i2s_config_tx(I2S_Type *ptr, uint32_t mclk_in_hz, i2s_transfer_config_t *config);
  384. /**
  385. * @brief I2S config rx
  386. *
  387. * @param [in] ptr I2S base address
  388. * @param [in] mclk_in_hz mclk frequency in Hz
  389. * @param [in] config i2s_transfer_config_t
  390. * @retval hpm_stat_t status_invalid_argument or status_success
  391. */
  392. hpm_stat_t i2s_config_rx(I2S_Type *ptr, uint32_t mclk_in_hz, i2s_transfer_config_t *config);
  393. /**
  394. * @brief I2S config transfer
  395. *
  396. * @param [in] ptr I2S base address
  397. * @param [in] mclk_in_hz mclk frequency in Hz
  398. * @param [in] config i2s_transfer_config_t
  399. * @retval hpm_stat_t status_invalid_argument or status_success
  400. */
  401. hpm_stat_t i2s_config_transfer(I2S_Type *ptr, uint32_t mclk_in_hz, i2s_transfer_config_t *config);
  402. /**
  403. * @brief I2S send data
  404. *
  405. * @param [in] ptr I2S base address
  406. * @param [in] tx_line_index data line
  407. * @param [in] src source data buff
  408. * @param [in] size data size
  409. */
  410. uint32_t i2s_send_data(I2S_Type *ptr, uint8_t tx_line_index, uint32_t *src, uint32_t size);
  411. /**
  412. * @brief I2S receive data
  413. *
  414. * @param [in] ptr I2S base address
  415. * @param [in] rx_line_index data line
  416. * @param [out] dst target data buff
  417. * @param [in] size data size
  418. */
  419. uint32_t i2s_receive_data(I2S_Type *ptr, uint8_t rx_line_index, uint32_t *dst, uint32_t size);
  420. /**
  421. * @brief I2S get default config
  422. *
  423. * @param [in] ptr I2S base address
  424. * @param [out] config i2s_config_t
  425. */
  426. void i2s_get_default_config(I2S_Type *ptr, i2s_config_t *config);
  427. /**
  428. * @brief I2S initialization
  429. *
  430. * @param [in] ptr I2S base address
  431. * @param [in] config i2s_config_t
  432. */
  433. void i2s_init(I2S_Type *ptr, i2s_config_t *config);
  434. /**
  435. * @brief I2S get default transfer config for pdm
  436. *
  437. * @param [out] transfer i2s_transfer_config_t
  438. */
  439. void i2s_get_default_transfer_config_for_pdm(i2s_transfer_config_t *transfer);
  440. /**
  441. * @brief I2S get default transfer config for dao
  442. *
  443. * @param [out] transfer i2s_transfer_config_t
  444. */
  445. void i2s_get_default_transfer_config_for_dao(i2s_transfer_config_t *transfer);
  446. /**
  447. * @brief I2S get default transfer config
  448. *
  449. * @param [out] transfer i2s_transfer_config_t
  450. */
  451. void i2s_get_default_transfer_config(i2s_transfer_config_t *transfer);
  452. /**
  453. * @}
  454. */
  455. #ifdef __cplusplus
  456. }
  457. #endif
  458. #endif /* HPM_I2S_DRV_H */