i2s_ll.h 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847
  1. /*
  2. * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. // The LL layer for I2S register operations
  7. /*******************************************************************************
  8. * NOTICE
  9. * The hal is not public api, don't use in application code.
  10. * See readme.md in hal/include/hal/readme.md
  11. ******************************************************************************/
  12. #pragma once
  13. #include <stdbool.h>
  14. #include "hal/misc.h"
  15. #include "soc/i2s_periph.h"
  16. #include "soc/i2s_struct.h"
  17. #include "hal/i2s_types.h"
  18. #ifdef __cplusplus
  19. extern "C" {
  20. #endif
  21. #define I2S_LL_GET_HW(num) (&I2S0)
  22. #define I2S_LL_TDM_CH_MASK (0xffff)
  23. #define I2S_LL_PDM_BCK_FACTOR (64)
  24. #define I2S_LL_BASE_CLK (2*APB_CLK_FREQ)
  25. #define I2S_LL_MCLK_DIVIDER_BIT_WIDTH (9)
  26. #define I2S_LL_MCLK_DIVIDER_MAX ((1 << I2S_LL_MCLK_DIVIDER_BIT_WIDTH) - 1)
  27. /* I2S clock configuration structure */
  28. typedef struct {
  29. uint16_t mclk_div; // I2S module clock devider, Fmclk = Fsclk /(mclk_div+b/a)
  30. uint16_t a;
  31. uint16_t b; // The decimal part of module clock devider, the decimal is: b/a
  32. } i2s_ll_mclk_div_t;
  33. /**
  34. * @brief I2S module general init, enable I2S clock.
  35. *
  36. * @param hw Peripheral I2S hardware instance address.
  37. */
  38. static inline void i2s_ll_enable_clock(i2s_dev_t *hw)
  39. {
  40. hw->tx_clkm_conf.clk_en = 1;
  41. }
  42. /**
  43. * @brief I2S module disable I2S clock.
  44. *
  45. * @param hw Peripheral I2S hardware instance address.
  46. */
  47. static inline void i2s_ll_disable_clock(i2s_dev_t *hw)
  48. {
  49. hw->tx_clkm_conf.clk_en = 0;
  50. }
  51. /**
  52. * @brief Enable I2S tx module clock
  53. *
  54. * @param hw Peripheral I2S hardware instance address.
  55. */
  56. static inline void i2s_ll_tx_enable_clock(i2s_dev_t *hw)
  57. {
  58. hw->tx_clkm_conf.tx_clk_active = 1;
  59. }
  60. /**
  61. * @brief Enable I2S rx module clock
  62. *
  63. * @param hw Peripheral I2S hardware instance address.
  64. */
  65. static inline void i2s_ll_rx_enable_clock(i2s_dev_t *hw)
  66. {
  67. hw->rx_clkm_conf.rx_clk_active = 1;
  68. }
  69. /**
  70. * @brief Disable I2S tx module clock
  71. *
  72. * @param hw Peripheral I2S hardware instance address.
  73. */
  74. static inline void i2s_ll_tx_disable_clock(i2s_dev_t *hw)
  75. {
  76. hw->tx_clkm_conf.tx_clk_active = 0;
  77. }
  78. /**
  79. * @brief Disable I2S rx module clock
  80. *
  81. * @param hw Peripheral I2S hardware instance address.
  82. */
  83. static inline void i2s_ll_rx_disable_clock(i2s_dev_t *hw)
  84. {
  85. hw->rx_clkm_conf.rx_clk_active = 0;
  86. }
  87. /**
  88. * @brief I2S mclk use tx module clock
  89. *
  90. * @param hw Peripheral I2S hardware instance address.
  91. */
  92. static inline void i2s_ll_mclk_use_tx_clk(i2s_dev_t *hw)
  93. {
  94. hw->rx_clkm_conf.mclk_sel = 0;
  95. }
  96. /**
  97. * @brief I2S mclk use rx module clock
  98. *
  99. * @param hw Peripheral I2S hardware instance address.
  100. */
  101. static inline void i2s_ll_mclk_use_rx_clk(i2s_dev_t *hw)
  102. {
  103. hw->rx_clkm_conf.mclk_sel = 1;
  104. }
  105. /**
  106. * @brief Enable I2S TX slave mode
  107. *
  108. * @param hw Peripheral I2S hardware instance address.
  109. * @param slave_en Set true to enable slave mode
  110. */
  111. static inline void i2s_ll_tx_set_slave_mod(i2s_dev_t *hw, bool slave_en)
  112. {
  113. hw->tx_conf.tx_slave_mod = slave_en;
  114. }
  115. /**
  116. * @brief Enable I2S RX slave mode
  117. *
  118. * @param hw Peripheral I2S hardware instance address.
  119. * @param slave_en Set true to enable slave mode
  120. */
  121. static inline void i2s_ll_rx_set_slave_mod(i2s_dev_t *hw, bool slave_en)
  122. {
  123. hw->rx_conf.rx_slave_mod = slave_en;
  124. }
  125. /**
  126. * @brief Reset I2S TX module
  127. *
  128. * @param hw Peripheral I2S hardware instance address.
  129. */
  130. static inline void i2s_ll_tx_reset(i2s_dev_t *hw)
  131. {
  132. hw->tx_conf.tx_reset = 1;
  133. hw->tx_conf.tx_reset = 0;
  134. }
  135. /**
  136. * @brief Reset I2S RX module
  137. *
  138. * @param hw Peripheral I2S hardware instance address.
  139. */
  140. static inline void i2s_ll_rx_reset(i2s_dev_t *hw)
  141. {
  142. hw->rx_conf.rx_reset = 1;
  143. hw->rx_conf.rx_reset = 0;
  144. }
  145. /**
  146. * @brief Reset I2S TX FIFO
  147. *
  148. * @param hw Peripheral I2S hardware instance address.
  149. */
  150. static inline void i2s_ll_tx_reset_fifo(i2s_dev_t *hw)
  151. {
  152. hw->tx_conf.tx_fifo_reset = 1;
  153. hw->tx_conf.tx_fifo_reset = 0;
  154. }
  155. /**
  156. * @brief Reset I2S RX FIFO
  157. *
  158. * @param hw Peripheral I2S hardware instance address.
  159. */
  160. static inline void i2s_ll_rx_reset_fifo(i2s_dev_t *hw)
  161. {
  162. hw->rx_conf.rx_fifo_reset = 1;
  163. hw->rx_conf.rx_fifo_reset = 0;
  164. }
  165. /**
  166. * @brief Set TX source clock
  167. *
  168. * @param hw Peripheral I2S hardware instance address.
  169. * @param src I2S source clock.
  170. */
  171. static inline void i2s_ll_tx_clk_set_src(i2s_dev_t *hw, i2s_clock_src_t src)
  172. {
  173. hw->tx_clkm_conf.tx_clk_sel = 2;
  174. }
  175. /**
  176. * @brief Set RX source clock
  177. *
  178. * @param hw Peripheral I2S hardware instance address.
  179. * @param src I2S source clock, ESP32-C3 only support `I2S_CLK_D2CLK`
  180. */
  181. static inline void i2s_ll_rx_clk_set_src(i2s_dev_t *hw, i2s_clock_src_t src)
  182. {
  183. hw->rx_clkm_conf.rx_clk_sel = 2;
  184. }
  185. /**
  186. * @brief Set I2S tx bck div num
  187. *
  188. * @param hw Peripheral I2S hardware instance address.
  189. * @param val value to set tx bck div num
  190. */
  191. static inline void i2s_ll_tx_set_bck_div_num(i2s_dev_t *hw, uint32_t val)
  192. {
  193. hw->tx_conf1.tx_bck_div_num = val - 1;
  194. }
  195. /**
  196. * @brief Configure I2S TX clock devider
  197. *
  198. * @param hw Peripheral I2S hardware instance address.
  199. * @param set Pointer to I2S clock devider configuration paramater
  200. */
  201. static inline void i2s_ll_tx_set_clk(i2s_dev_t *hw, i2s_ll_mclk_div_t *set)
  202. {
  203. if (set->a == 0 || set->b == 0) {
  204. hw->tx_clkm_div_conf.tx_clkm_div_x = 0;
  205. hw->tx_clkm_div_conf.tx_clkm_div_y = 0;
  206. hw->tx_clkm_div_conf.tx_clkm_div_z = 0;
  207. } else {
  208. if (set->b > set->a / 2) {
  209. hw->tx_clkm_div_conf.tx_clkm_div_x = set->a / (set->a - set->b) - 1;
  210. hw->tx_clkm_div_conf.tx_clkm_div_y = set->a % (set->a - set->b);
  211. hw->tx_clkm_div_conf.tx_clkm_div_z = set->a - set->b;
  212. hw->tx_clkm_div_conf.tx_clkm_div_yn1 = 1;
  213. } else {
  214. hw->tx_clkm_div_conf.tx_clkm_div_x = set->a / set->b - 1;
  215. hw->tx_clkm_div_conf.tx_clkm_div_y = set->a % set->b + 1;
  216. hw->tx_clkm_div_conf.tx_clkm_div_z = set->b;
  217. hw->tx_clkm_div_conf.tx_clkm_div_yn1 = 0;
  218. }
  219. }
  220. HAL_FORCE_MODIFY_U32_REG_FIELD(hw->tx_clkm_conf, tx_clkm_div_num, set->mclk_div);
  221. }
  222. /**
  223. * @brief Set I2S rx bck div num
  224. *
  225. * @param hw Peripheral I2S hardware instance address.
  226. * @param val value to set rx bck div num
  227. */
  228. static inline void i2s_ll_rx_set_bck_div_num(i2s_dev_t *hw, uint32_t val)
  229. {
  230. hw->rx_conf1.rx_bck_div_num = val - 1;
  231. }
  232. /**
  233. * @brief Configure I2S RX clock devider
  234. *
  235. * @param hw Peripheral I2S hardware instance address.
  236. * @param set Pointer to I2S clock devider configuration paramater
  237. */
  238. static inline void i2s_ll_rx_set_clk(i2s_dev_t *hw, i2s_ll_mclk_div_t *set)
  239. {
  240. if (set->a == 0 || set->b == 0) {
  241. hw->rx_clkm_div_conf.rx_clkm_div_x = 0;
  242. hw->rx_clkm_div_conf.rx_clkm_div_y = 0;
  243. hw->rx_clkm_div_conf.rx_clkm_div_z = 0;
  244. } else {
  245. if (set->b > set->a / 2) {
  246. hw->rx_clkm_div_conf.rx_clkm_div_x = set->a / (set->a - set->b) - 1;
  247. hw->rx_clkm_div_conf.rx_clkm_div_y = set->a % (set->a - set->b);
  248. hw->rx_clkm_div_conf.rx_clkm_div_z = set->a - set->b;
  249. hw->rx_clkm_div_conf.rx_clkm_div_yn1 = 1;
  250. } else {
  251. hw->rx_clkm_div_conf.rx_clkm_div_x = set->a / set->b - 1;
  252. hw->rx_clkm_div_conf.rx_clkm_div_y = set->a % set->b + 1;
  253. hw->rx_clkm_div_conf.rx_clkm_div_z = set->b;
  254. hw->rx_clkm_div_conf.rx_clkm_div_yn1 = 0;
  255. }
  256. }
  257. HAL_FORCE_MODIFY_U32_REG_FIELD(hw->rx_clkm_conf, rx_clkm_div_num, set->mclk_div);
  258. }
  259. /**
  260. * @brief Start I2S TX
  261. *
  262. * @param hw Peripheral I2S hardware instance address.
  263. */
  264. static inline void i2s_ll_tx_start(i2s_dev_t *hw)
  265. {
  266. hw->tx_conf.tx_update = 0;
  267. hw->tx_conf.tx_update = 1;
  268. hw->tx_conf.tx_start = 1;
  269. }
  270. /**
  271. * @brief Start I2S RX
  272. *
  273. * @param hw Peripheral I2S hardware instance address.
  274. */
  275. static inline void i2s_ll_rx_start(i2s_dev_t *hw)
  276. {
  277. hw->rx_conf.rx_update = 0;
  278. hw->rx_conf.rx_update = 1;
  279. hw->rx_conf.rx_start = 1;
  280. }
  281. /**
  282. * @brief Stop I2S TX
  283. *
  284. * @param hw Peripheral I2S hardware instance address.
  285. */
  286. static inline void i2s_ll_tx_stop(i2s_dev_t *hw)
  287. {
  288. hw->tx_conf.tx_start = 0;
  289. }
  290. /**
  291. * @brief Stop I2S RX
  292. *
  293. * @param hw Peripheral I2S hardware instance address.
  294. */
  295. static inline void i2s_ll_rx_stop(i2s_dev_t *hw)
  296. {
  297. hw->rx_conf.rx_start = 0;
  298. }
  299. /**
  300. * @brief Configure TX WS signal width
  301. *
  302. * @param hw Peripheral I2S hardware instance address.
  303. * @param width WS width in BCK cycle
  304. */
  305. static inline void i2s_ll_tx_set_ws_width(i2s_dev_t *hw, int width)
  306. {
  307. hw->tx_conf1.tx_tdm_ws_width = width - 1;
  308. }
  309. /**
  310. * @brief Configure RX WS signal width
  311. *
  312. * @param hw Peripheral I2S hardware instance address.
  313. * @param width WS width in BCK cycle
  314. */
  315. static inline void i2s_ll_rx_set_ws_width(i2s_dev_t *hw, int width)
  316. {
  317. hw->rx_conf1.rx_tdm_ws_width = width - 1;
  318. }
  319. /**
  320. * @brief Configure the received length to trigger in_suc_eof interrupt
  321. *
  322. * @param hw Peripheral I2S hardware instance address.
  323. * @param eof_num the byte length to trigger in_suc_eof interrupt
  324. */
  325. static inline void i2s_ll_rx_set_eof_num(i2s_dev_t *hw, int eof_num)
  326. {
  327. hw->rx_eof_num.rx_eof_num = eof_num;
  328. }
  329. /**
  330. * @brief Congfigure TX chan bit and audio data bit
  331. *
  332. * @param hw Peripheral I2S hardware instance address.
  333. * @param chan_bit The chan bit width
  334. * @param data_bit The audio data bit width
  335. */
  336. static inline void i2s_ll_tx_set_sample_bit(i2s_dev_t *hw, uint8_t chan_bit, int data_bit)
  337. {
  338. hw->tx_conf1.tx_bits_mod = data_bit - 1;
  339. hw->tx_conf1.tx_tdm_chan_bits = chan_bit - 1;
  340. }
  341. /**
  342. * @brief Congfigure RX chan bit and audio data bit
  343. *
  344. * @param hw Peripheral I2S hardware instance address.
  345. * @param chan_bit The chan bit width
  346. * @param data_bit The audio data bit width
  347. */
  348. static inline void i2s_ll_rx_set_sample_bit(i2s_dev_t *hw, uint8_t chan_bit, int data_bit)
  349. {
  350. hw->rx_conf1.rx_bits_mod = data_bit - 1;
  351. hw->rx_conf1.rx_tdm_chan_bits = chan_bit - 1;
  352. }
  353. /**
  354. * @brief Configure RX half_sample_bit
  355. *
  356. * @param hw Peripheral I2S hardware instance address.
  357. * @param half_sample_bits half sample bit width
  358. */
  359. static inline void i2s_ll_tx_set_half_sample_bit(i2s_dev_t *hw, int half_sample_bits)
  360. {
  361. hw->tx_conf1.tx_half_sample_bits = half_sample_bits - 1;
  362. }
  363. /**
  364. * @brief Configure RX half_sample_bit
  365. *
  366. * @param hw Peripheral I2S hardware instance address.
  367. * @param half_sample_bits half sample bit width
  368. */
  369. static inline void i2s_ll_rx_set_half_sample_bit(i2s_dev_t *hw, int half_sample_bits)
  370. {
  371. hw->rx_conf1.rx_half_sample_bits = half_sample_bits - 1;
  372. }
  373. /**
  374. * @brief Enable TX MSB shift, the data will be launch at the first BCK clock
  375. *
  376. * @param hw Peripheral I2S hardware instance address.
  377. * @param msb_shift_enable Set true to enable MSB shift
  378. */
  379. static inline void i2s_ll_tx_enable_msb_shift(i2s_dev_t *hw, bool msb_shift_enable)
  380. {
  381. hw->tx_conf1.tx_msb_shift = msb_shift_enable;
  382. }
  383. /**
  384. * @brief Enable RX MSB shift, the data will be launch at the first BCK clock
  385. *
  386. * @param hw Peripheral I2S hardware instance address.
  387. * @param msb_shift_enable Set true to enable MSB shift
  388. */
  389. static inline void i2s_ll_rx_enable_msb_shift(i2s_dev_t *hw, bool msb_shift_enable)
  390. {
  391. hw->rx_conf1.rx_msb_shift = msb_shift_enable;
  392. }
  393. /**
  394. * @brief Configure TX total chan number
  395. *
  396. * @param hw Peripheral I2S hardware instance address.
  397. * @param total_num Total chan number
  398. */
  399. static inline void i2s_ll_tx_set_chan_num(i2s_dev_t *hw, int total_num)
  400. {
  401. hw->tx_tdm_ctrl.tx_tdm_tot_chan_num = total_num - 1;
  402. }
  403. /**
  404. * @brief Configure RX total chan number
  405. *
  406. * @param hw Peripheral I2S hardware instance address.
  407. * @param total_num Total chan number
  408. */
  409. static inline void i2s_ll_rx_set_chan_num(i2s_dev_t *hw, int total_num)
  410. {
  411. hw->rx_tdm_ctrl.rx_tdm_tot_chan_num = total_num - 1;
  412. }
  413. /**
  414. * @brief Set the bimap of the active TX chan, only the active chan can launch audio data.
  415. *
  416. * @param hw Peripheral I2S hardware instance address.
  417. * @param chan_mask mask of tx active chan
  418. */
  419. static inline void i2s_ll_tx_set_active_chan_mask(i2s_dev_t *hw, uint32_t chan_mask)
  420. {
  421. typeof(hw->tx_tdm_ctrl) tdm_ctrl_reg = hw->tx_tdm_ctrl;
  422. tdm_ctrl_reg.val &= ~I2S_LL_TDM_CH_MASK;
  423. tdm_ctrl_reg.val |= chan_mask & I2S_LL_TDM_CH_MASK;
  424. hw->tx_tdm_ctrl.val = tdm_ctrl_reg.val;
  425. }
  426. /**
  427. * @brief Set the bimap of the active RX chan, only the active chan can receive audio data.
  428. *
  429. * @param hw Peripheral I2S hardware instance address.
  430. * @param chan_mask mask of rx active chan
  431. */
  432. static inline void i2s_ll_rx_set_active_chan_mask(i2s_dev_t *hw, uint32_t chan_mask)
  433. {
  434. typeof(hw->rx_tdm_ctrl) tdm_ctrl_reg = hw->rx_tdm_ctrl;
  435. tdm_ctrl_reg.val &= ~I2S_LL_TDM_CH_MASK;
  436. tdm_ctrl_reg.val |= chan_mask & I2S_LL_TDM_CH_MASK;
  437. hw->rx_tdm_ctrl.val = tdm_ctrl_reg.val;
  438. }
  439. /**
  440. * @brief Set TX WS signal pol level
  441. *
  442. * @param hw Peripheral I2S hardware instance address.
  443. * @param ws_pol_level pin level of WS(output) when receiving left channel data
  444. */
  445. static inline void i2s_ll_tx_set_ws_idle_pol(i2s_dev_t *hw, bool ws_pol_level)
  446. {
  447. hw->tx_conf.tx_ws_idle_pol = ws_pol_level;
  448. }
  449. /**
  450. * @brief Set RX WS signal pol level
  451. *
  452. * @param hw Peripheral I2S hardware instance address.
  453. * @param ws_pol_level pin level of WS(input) when receiving left channel data
  454. */
  455. static inline void i2s_ll_rx_set_ws_idle_pol(i2s_dev_t *hw, bool ws_pol_level)
  456. {
  457. hw->rx_conf.rx_ws_idle_pol = ws_pol_level;
  458. }
  459. /**
  460. * @brief Enable TX PDM mode.
  461. *
  462. * @param hw Peripheral I2S hardware instance address.
  463. * @param pdm_enable Set true to TX enable PDM mode
  464. */
  465. static inline void i2s_ll_tx_enable_pdm(i2s_dev_t *hw, bool pdm_enable)
  466. {
  467. hw->tx_conf.tx_pdm_en = pdm_enable;
  468. hw->tx_conf.tx_tdm_en = !pdm_enable;
  469. hw->tx_pcm2pdm_conf.pcm2pdm_conv_en = pdm_enable;
  470. }
  471. /**
  472. * @brief Set I2S TX PDM prescale
  473. *
  474. * @param hw Peripheral I2S hardware instance address.
  475. * @param prescale I2S TX PDM prescale
  476. */
  477. static inline void i2s_ll_tx_set_pdm_prescale(i2s_dev_t *hw, bool prescale)
  478. {
  479. HAL_FORCE_MODIFY_U32_REG_FIELD(hw->tx_pcm2pdm_conf, tx_pdm_prescale, prescale);
  480. }
  481. /**
  482. * @brief Set I2S TX PDM high pass filter scaling
  483. *
  484. * @param hw Peripheral I2S hardware instance address.
  485. * @param sig_scale I2S TX PDM signal scaling before transmit to the filter
  486. */
  487. static inline void i2s_ll_tx_set_pdm_hp_scale(i2s_dev_t *hw, i2s_pdm_sig_scale_t sig_scale)
  488. {
  489. hw->tx_pcm2pdm_conf.tx_pdm_hp_in_shift = sig_scale;
  490. }
  491. /**
  492. * @brief Set I2S TX PDM low pass filter scaling
  493. *
  494. * @param hw Peripheral I2S hardware instance address.
  495. * @param sig_scale I2S TX PDM signal scaling before transmit to the filter
  496. */
  497. static inline void i2s_ll_tx_set_pdm_lp_scale(i2s_dev_t *hw, i2s_pdm_sig_scale_t sig_scale)
  498. {
  499. hw->tx_pcm2pdm_conf.tx_pdm_lp_in_shift = sig_scale;
  500. }
  501. /**
  502. * @brief Set I2S TX PDM sinc filter scaling
  503. *
  504. * @param hw Peripheral I2S hardware instance address.
  505. * @param sig_scale I2S TX PDM signal scaling before transmit to the filter
  506. */
  507. static inline void i2s_ll_tx_set_pdm_sinc_scale(i2s_dev_t *hw, i2s_pdm_sig_scale_t sig_scale)
  508. {
  509. hw->tx_pcm2pdm_conf.tx_pdm_sinc_in_shift = sig_scale;
  510. }
  511. /**
  512. * @brief Set I2S TX PDM sigma-delta filter scaling
  513. *
  514. * @param hw Peripheral I2S hardware instance address.
  515. * @param sig_scale I2S TX PDM signal scaling before transmit to the filter
  516. */
  517. static inline void i2s_ll_tx_set_pdm_sd_scale(i2s_dev_t *hw, i2s_pdm_sig_scale_t sig_scale)
  518. {
  519. hw->tx_pcm2pdm_conf.tx_pdm_sigmadelta_in_shift = sig_scale;
  520. }
  521. /**
  522. * @brief Set I2S TX PDM high pass filter param0
  523. *
  524. * @param hw Peripheral I2S hardware instance address.
  525. * @param param The fourth parameter of PDM TX IIR_HP filter stage 1 is (504 + I2S_TX_IIR_HP_MULT12_0[2:0])
  526. */
  527. static inline void i2s_ll_tx_set_pdm_hp_filter_param0(i2s_dev_t *hw, uint32_t param)
  528. {
  529. hw->tx_pcm2pdm_conf1.tx_iir_hp_mult12_0 = param;
  530. }
  531. /**
  532. * @brief Set I2S TX PDM high pass filter param5
  533. *
  534. * @param hw Peripheral I2S hardware instance address.
  535. * @param param The fourth parameter of PDM TX IIR_HP filter stage 2 is (504 + I2S_TX_IIR_HP_MULT12_5[2:0])
  536. */
  537. static inline void i2s_ll_tx_set_pdm_hp_filter_param5(i2s_dev_t *hw, uint32_t param)
  538. {
  539. hw->tx_pcm2pdm_conf1.tx_iir_hp_mult12_5 = param;
  540. }
  541. /**
  542. * @brief Enable I2S TX PDM high pass filter
  543. *
  544. * @param hw Peripheral I2S hardware instance address.
  545. * @param enable Set true to enable I2S TX PDM high pass filter, set false to bypass it
  546. */
  547. static inline void i2s_ll_tx_enable_pdm_hp_filter(i2s_dev_t *hw, bool enable)
  548. {
  549. hw->tx_pcm2pdm_conf.tx_pdm_hp_bypass = !enable;
  550. }
  551. /**
  552. * @brief Enable I2S TX PDM sigma-delta codec
  553. *
  554. * @param hw Peripheral I2S hardware instance address.
  555. * @param dither I2S TX PDM sigmadelta dither value
  556. */
  557. static inline void i2s_ll_tx_enable_pdm_sd_codec(i2s_dev_t *hw, bool enable)
  558. {
  559. hw->tx_pcm2pdm_conf.tx_pdm_dac_2out_en = enable;
  560. hw->tx_pcm2pdm_conf.tx_pdm_dac_mode_en = enable;
  561. }
  562. /**
  563. * @brief Set I2S TX PDM sigma-delta codec dither
  564. *
  565. * @param hw Peripheral I2S hardware instance address.
  566. * @param dither I2S TX PDM sigmadelta dither value
  567. */
  568. static inline void i2s_ll_tx_set_pdm_sd_dither(i2s_dev_t *hw, uint32_t dither)
  569. {
  570. hw->tx_pcm2pdm_conf.tx_pdm_sigmadelta_dither = dither;
  571. }
  572. /**
  573. * @brief Set I2S TX PDM sigma-delta codec dither
  574. *
  575. * @param hw Peripheral I2S hardware instance address.
  576. * @param dither2 I2S TX PDM sigmadelta dither2 value
  577. */
  578. static inline void i2s_ll_tx_set_pdm_sd_dither2(i2s_dev_t *hw, uint32_t dither2)
  579. {
  580. hw->tx_pcm2pdm_conf.tx_pdm_sigmadelta_dither2 = dither2;
  581. }
  582. /**
  583. * @brief Configure I2S TX PDM sample rate
  584. * Fpdm = 64*Fpcm*fp/fs
  585. *
  586. * @param hw Peripheral I2S hardware instance address.
  587. * @param fp The fp value of TX PDM filter module group0.
  588. * @param fs The fs value of TX PDM filter module group0.
  589. */
  590. static inline void i2s_ll_tx_set_pdm_fpfs(i2s_dev_t *hw, uint32_t fp, uint32_t fs)
  591. {
  592. hw->tx_pcm2pdm_conf1.tx_pdm_fp = fp;
  593. hw->tx_pcm2pdm_conf1.tx_pdm_fs = fs;
  594. hw->tx_pcm2pdm_conf.tx_pdm_sinc_osr2 = fp / fs;
  595. }
  596. /**
  597. * @brief Get I2S TX PDM fp configuration paramater
  598. *
  599. * @param hw Peripheral I2S hardware instance address.
  600. * @return
  601. * - fp configuration paramater
  602. */
  603. static inline uint32_t i2s_ll_tx_get_pdm_fp(i2s_dev_t *hw)
  604. {
  605. return hw->tx_pcm2pdm_conf1.tx_pdm_fp;
  606. }
  607. /**
  608. * @brief Get I2S TX PDM fs configuration paramater
  609. *
  610. * @param hw Peripheral I2S hardware instance address.
  611. * @return
  612. * - fs configuration paramater
  613. */
  614. static inline uint32_t i2s_ll_tx_get_pdm_fs(i2s_dev_t *hw)
  615. {
  616. return hw->tx_pcm2pdm_conf1.tx_pdm_fs;
  617. }
  618. /**
  619. * @brief Enable RX PDM mode.
  620. * @note ESP32-C3 doesn't support pdm in rx mode, disable anyway
  621. *
  622. * @param hw Peripheral I2S hardware instance address.
  623. * @param pdm_enable Set true to RX enable PDM mode (ignored)
  624. */
  625. static inline void i2s_ll_rx_enable_pdm(i2s_dev_t *hw, bool pdm_enable)
  626. {
  627. hw->rx_conf.rx_pdm_en = 0;
  628. hw->rx_conf.rx_tdm_en = 1;
  629. }
  630. /**
  631. * @brief Configura TX a/u-law decompress or compress
  632. *
  633. * @param hw Peripheral I2S hardware instance address.
  634. * @param pcm_cfg PCM configuration paramater
  635. */
  636. static inline void i2s_ll_tx_set_pcm_type(i2s_dev_t *hw, i2s_pcm_compress_t pcm_cfg)
  637. {
  638. hw->tx_conf.tx_pcm_conf = pcm_cfg;
  639. hw->tx_conf.tx_pcm_bypass = !pcm_cfg;
  640. }
  641. /**
  642. * @brief Configure RX a/u-law decompress or compress
  643. *
  644. * @param hw Peripheral I2S hardware instance address.
  645. * @param pcm_cfg PCM configuration paramater
  646. */
  647. static inline void i2s_ll_rx_set_pcm_type(i2s_dev_t *hw, i2s_pcm_compress_t pcm_cfg)
  648. {
  649. hw->rx_conf.rx_pcm_conf = pcm_cfg;
  650. hw->rx_conf.rx_pcm_bypass = !pcm_cfg;
  651. }
  652. /**
  653. * @brief Enable TX audio data left alignment
  654. *
  655. * @param hw Peripheral I2S hardware instance address.
  656. * @param ena Set true to enable left alignment
  657. */
  658. static inline void i2s_ll_tx_enable_left_align(i2s_dev_t *hw, bool ena)
  659. {
  660. hw->tx_conf.tx_left_align = ena;
  661. }
  662. /**
  663. * @brief Enable RX audio data left alignment
  664. *
  665. * @param hw Peripheral I2S hardware instance address.
  666. * @param ena Set true to enable left alignment
  667. */
  668. static inline void i2s_ll_rx_enable_left_align(i2s_dev_t *hw, bool ena)
  669. {
  670. hw->rx_conf.rx_left_align = ena;
  671. }
  672. /**
  673. * @brief Enable TX big endian mode
  674. *
  675. * @param hw Peripheral I2S hardware instance address.
  676. * @param ena Set true to enable big endian mode
  677. */
  678. static inline void i2s_ll_rx_enable_big_endian(i2s_dev_t *hw, bool ena)
  679. {
  680. hw->rx_conf.rx_big_endian = ena;
  681. }
  682. /**
  683. * @brief Enable RX big endian mode
  684. *
  685. * @param hw Peripheral I2S hardware instance address.
  686. * @param ena Set true to enable big endian mode
  687. */
  688. static inline void i2s_ll_tx_enable_big_endian(i2s_dev_t *hw, bool ena)
  689. {
  690. hw->tx_conf.tx_big_endian = ena;
  691. }
  692. /**
  693. * @brief Configure TX bit order
  694. *
  695. * @param hw Peripheral I2S hardware instance address.
  696. * @param lsb_order_ena Set true to enable LSB bit order
  697. */
  698. static inline void i2s_ll_tx_set_bit_order(i2s_dev_t *hw, bool lsb_order_ena)
  699. {
  700. hw->tx_conf.tx_bit_order = lsb_order_ena;
  701. }
  702. /**
  703. * @brief Configure RX bit order
  704. *
  705. * @param hw Peripheral I2S hardware instance address.
  706. * @param lsb_order_ena Set true to enable LSB bit order
  707. */
  708. static inline void i2s_ll_rx_set_bit_order(i2s_dev_t *hw, bool lsb_order_ena)
  709. {
  710. hw->rx_conf.rx_bit_order = lsb_order_ena;
  711. }
  712. /**
  713. * @brief Configure TX skip mask enable
  714. *
  715. * @param hw Peripheral I2S hardware instance address.
  716. * @param skip_mask_ena Set true to skip inactive channels.
  717. */
  718. static inline void i2s_ll_tx_set_skip_mask(i2s_dev_t *hw, bool skip_mask_ena)
  719. {
  720. hw->tx_tdm_ctrl.tx_tdm_skip_msk_en = skip_mask_ena;
  721. }
  722. /**
  723. * @brief Configure single data
  724. *
  725. * @param hw Peripheral I2S hardware instance address.
  726. * @param data Single data to be set
  727. */
  728. static inline void i2s_ll_set_single_data(i2s_dev_t *hw, uint32_t data)
  729. {
  730. hw->conf_single_data = data;
  731. }
  732. /**
  733. * @brief Enable TX mono mode
  734. * @note MONO in hardware means only one channel got data, but another doesn't
  735. * MONO in software means two channel share same data
  736. * This function aims to use MONO in software meaning
  737. * so 'tx_mono' and 'tx_chan_equal' should be enabled at the same time
  738. *
  739. * @param hw Peripheral I2S hardware instance address.
  740. * @param mono_ena Set true to enable mono mde.
  741. */
  742. static inline void i2s_ll_tx_enable_mono_mode(i2s_dev_t *hw, bool mono_ena)
  743. {
  744. hw->tx_conf.tx_mono = mono_ena;
  745. hw->tx_conf.tx_chan_equal = mono_ena;
  746. }
  747. /**
  748. * @brief Enable RX mono mode
  749. *
  750. * @param hw Peripheral I2S hardware instance address.
  751. * @param mono_ena Set true to enable mono mde.
  752. */
  753. static inline void i2s_ll_rx_enable_mono_mode(i2s_dev_t *hw, bool mono_ena)
  754. {
  755. hw->rx_conf.rx_mono = mono_ena;
  756. hw->rx_conf.rx_mono_fst_vld = mono_ena;
  757. }
  758. /**
  759. * @brief Enable loopback mode
  760. *
  761. * @param hw Peripheral I2S hardware instance address.
  762. * @param ena Set true to share BCK and WS signal for tx module and rx module.
  763. */
  764. static inline void i2s_ll_share_bck_ws(i2s_dev_t *hw, bool ena)
  765. {
  766. hw->tx_conf.sig_loopback = ena;
  767. }
  768. #ifdef __cplusplus
  769. }
  770. #endif