i2s_hal.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. /*
  2. * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. // The HAL layer for I2S (common part)
  7. #include "soc/soc.h"
  8. #include "hal/i2s_hal.h"
  9. #if SOC_I2S_HW_VERSION_2 && (SOC_I2S_SUPPORTS_PDM_TX || SOC_I2S_SUPPORTS_PDM_RX_HP_FILTER)
  10. /* PDM tx high pass filter cut-off frequency and coefficients list
  11. * [0]: cut-off frequency * 10; [1]: param0; [2]: param5
  12. * NOTE: the cut-off frequency was timed 10 to use integer type */
  13. static const uint32_t cut_off_coef[21][3] = {
  14. {1850, 0, 0}, {1720, 0, 1}, {1600, 1, 1},
  15. {1500, 1, 2}, {1370, 2, 2}, {1260, 2, 3},
  16. {1200, 0, 3}, {1150, 3, 3}, {1060, 1, 7},
  17. {1040, 2, 4}, {920, 4, 4}, {915, 2, 7},
  18. {810, 4, 5}, {772, 3, 7}, {690, 5, 5},
  19. {630, 4, 7}, {580, 5, 6}, {490, 5, 7},
  20. {460, 6, 6}, {355, 6, 7}, {233, 7, 7}
  21. };
  22. static void s_i2s_hal_get_cut_off_coef(uint32_t freq, uint32_t *param0, uint32_t *param5)
  23. {
  24. uint8_t cnt = 0;
  25. uint32_t min = 10000;
  26. /* Find the closest cut-off frequency and its coefficients */
  27. for (int i = 0; i < 21; i++) {
  28. uint32_t tmp = cut_off_coef[i][0] < freq ? freq - cut_off_coef[i][0] : cut_off_coef[i][0] - freq;
  29. if (tmp < min) {
  30. min = tmp;
  31. cnt = i;
  32. }
  33. }
  34. *param0 = (uint32_t)cut_off_coef[cnt][1];
  35. *param5 = (uint32_t)cut_off_coef[cnt][2];
  36. }
  37. #endif
  38. /**
  39. * @brief Calculate the precise mclk division by sclk and mclk
  40. *
  41. * @param sclk system clock
  42. * @param mclk module clock
  43. * @param mclk_div output the mclk division coefficients
  44. */
  45. void i2s_hal_calc_mclk_precise_division(uint32_t sclk, uint32_t mclk, hal_utils_clk_div_t *mclk_div)
  46. {
  47. hal_utils_clk_info_t i2s_clk_info = {
  48. .src_freq_hz = sclk,
  49. .exp_freq_hz = mclk,
  50. .max_integ = I2S_LL_CLK_FRAC_DIV_N_MAX,
  51. .min_integ = 1,
  52. .max_fract = I2S_LL_CLK_FRAC_DIV_AB_MAX,
  53. };
  54. hal_utils_calc_clk_div_frac_accurate(&i2s_clk_info, mclk_div);
  55. }
  56. void i2s_hal_init(i2s_hal_context_t *hal, int port_id)
  57. {
  58. /* Get hardware instance */
  59. hal->dev = I2S_LL_GET_HW(port_id);
  60. }
  61. void _i2s_hal_set_tx_clock(i2s_hal_context_t *hal, const i2s_hal_clock_info_t *clk_info, i2s_clock_src_t clk_src)
  62. {
  63. if (clk_info) {
  64. hal_utils_clk_div_t mclk_div = {};
  65. #if SOC_I2S_HW_VERSION_2
  66. i2s_ll_tx_enable_clock(hal->dev);
  67. i2s_ll_mclk_bind_to_tx_clk(hal->dev);
  68. #endif
  69. i2s_ll_tx_clk_set_src(hal->dev, clk_src);
  70. i2s_hal_calc_mclk_precise_division(clk_info->sclk, clk_info->mclk, &mclk_div);
  71. i2s_ll_tx_set_mclk(hal->dev, &mclk_div);
  72. i2s_ll_tx_set_bck_div_num(hal->dev, clk_info->bclk_div);
  73. } else {
  74. i2s_ll_tx_clk_set_src(hal->dev, clk_src);
  75. }
  76. }
  77. void _i2s_hal_set_rx_clock(i2s_hal_context_t *hal, const i2s_hal_clock_info_t *clk_info, i2s_clock_src_t clk_src)
  78. {
  79. if (clk_info) {
  80. hal_utils_clk_div_t mclk_div = {};
  81. #if SOC_I2S_HW_VERSION_2
  82. i2s_ll_rx_enable_clock(hal->dev);
  83. i2s_ll_mclk_bind_to_rx_clk(hal->dev);
  84. #endif
  85. i2s_ll_rx_clk_set_src(hal->dev, clk_src);
  86. i2s_hal_calc_mclk_precise_division(clk_info->sclk, clk_info->mclk, &mclk_div);
  87. i2s_ll_rx_set_mclk(hal->dev, &mclk_div);
  88. i2s_ll_rx_set_bck_div_num(hal->dev, clk_info->bclk_div);
  89. } else {
  90. i2s_ll_rx_clk_set_src(hal->dev, clk_src);
  91. }
  92. }
  93. /*-------------------------------------------------------------------------
  94. | STD Specific Slot Configurations |
  95. -------------------------------------------------------------------------*/
  96. void i2s_hal_std_set_tx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_hal_slot_config_t *slot_cfg)
  97. {
  98. uint32_t slot_bit_width = (int)slot_cfg->slot_bit_width < (int)slot_cfg->data_bit_width ?
  99. slot_cfg->data_bit_width : slot_cfg->slot_bit_width;
  100. i2s_ll_tx_reset(hal->dev);
  101. i2s_ll_tx_set_slave_mod(hal->dev, is_slave); //TX Slave
  102. i2s_ll_tx_set_sample_bit(hal->dev, slot_bit_width, slot_cfg->data_bit_width);
  103. i2s_ll_tx_enable_msb_shift(hal->dev, slot_cfg->std.bit_shift);
  104. i2s_ll_tx_set_ws_width(hal->dev, slot_cfg->std.ws_width);
  105. #if SOC_I2S_HW_VERSION_1
  106. i2s_ll_tx_enable_mono_mode(hal->dev, slot_cfg->slot_mode == I2S_SLOT_MODE_MONO);
  107. i2s_ll_tx_select_std_slot(hal->dev, slot_cfg->std.slot_mask, slot_cfg->slot_mode == I2S_SLOT_MODE_MONO);
  108. // According to the test, the behavior of tx_msb_right is opposite with TRM, TRM is wrong?
  109. i2s_ll_tx_enable_msb_right(hal->dev, slot_cfg->std.msb_right);
  110. i2s_ll_tx_enable_right_first(hal->dev, slot_cfg->std.ws_pol);
  111. /* Should always enable fifo */
  112. i2s_ll_tx_force_enable_fifo_mod(hal->dev, true);
  113. #elif SOC_I2S_HW_VERSION_2
  114. bool is_copy_mono = slot_cfg->slot_mode == I2S_SLOT_MODE_MONO && slot_cfg->std.slot_mask == I2S_STD_SLOT_BOTH;
  115. i2s_ll_tx_enable_mono_mode(hal->dev, is_copy_mono);
  116. i2s_ll_tx_select_std_slot(hal->dev, is_copy_mono ? I2S_STD_SLOT_LEFT : slot_cfg->std.slot_mask);
  117. i2s_ll_tx_set_skip_mask(hal->dev, (slot_cfg->std.slot_mask != I2S_STD_SLOT_BOTH) &&
  118. (slot_cfg->slot_mode == I2S_SLOT_MODE_STEREO));
  119. i2s_ll_tx_set_half_sample_bit(hal->dev, slot_bit_width);
  120. i2s_ll_tx_set_ws_idle_pol(hal->dev, slot_cfg->std.ws_pol);
  121. i2s_ll_tx_set_bit_order(hal->dev, slot_cfg->std.bit_order_lsb);
  122. i2s_ll_tx_enable_left_align(hal->dev, slot_cfg->std.left_align);
  123. i2s_ll_tx_enable_big_endian(hal->dev, slot_cfg->std.big_endian);
  124. #endif
  125. }
  126. void i2s_hal_std_set_rx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_hal_slot_config_t *slot_cfg)
  127. {
  128. uint32_t slot_bit_width = (int)slot_cfg->slot_bit_width < (int)slot_cfg->data_bit_width ?
  129. slot_cfg->data_bit_width : slot_cfg->slot_bit_width;
  130. i2s_ll_rx_reset(hal->dev);
  131. i2s_ll_rx_set_slave_mod(hal->dev, is_slave); //RX Slave
  132. i2s_ll_rx_set_sample_bit(hal->dev, slot_bit_width, slot_cfg->data_bit_width);
  133. i2s_ll_rx_enable_mono_mode(hal->dev, slot_cfg->slot_mode == I2S_SLOT_MODE_MONO);
  134. i2s_ll_rx_enable_msb_shift(hal->dev, slot_cfg->std.bit_shift);
  135. i2s_ll_rx_set_ws_width(hal->dev, slot_cfg->std.ws_width);
  136. #if SOC_I2S_HW_VERSION_1
  137. i2s_ll_rx_select_std_slot(hal->dev, slot_cfg->std.slot_mask, slot_cfg->std.msb_right);
  138. i2s_ll_rx_enable_msb_right(hal->dev, slot_cfg->std.msb_right);
  139. i2s_ll_rx_enable_right_first(hal->dev, slot_cfg->std.ws_pol);
  140. /* Should always enable fifo */
  141. i2s_ll_rx_force_enable_fifo_mod(hal->dev, true);
  142. #elif SOC_I2S_HW_VERSION_2
  143. i2s_ll_rx_select_std_slot(hal->dev, slot_cfg->std.slot_mask);
  144. i2s_ll_rx_set_half_sample_bit(hal->dev, slot_bit_width);
  145. i2s_ll_rx_set_ws_idle_pol(hal->dev, slot_cfg->std.ws_pol);
  146. i2s_ll_rx_set_bit_order(hal->dev, slot_cfg->std.bit_order_lsb);
  147. i2s_ll_rx_enable_left_align(hal->dev, slot_cfg->std.left_align);
  148. i2s_ll_rx_enable_big_endian(hal->dev, slot_cfg->std.big_endian);
  149. #endif
  150. }
  151. void i2s_hal_std_enable_tx_channel(i2s_hal_context_t *hal)
  152. {
  153. i2s_ll_tx_enable_std(hal->dev);
  154. }
  155. void i2s_hal_std_enable_rx_channel(i2s_hal_context_t *hal)
  156. {
  157. i2s_ll_rx_enable_std(hal->dev);
  158. }
  159. /*-------------------------------------------------------------------------
  160. | PDM Specific Slot Configurations |
  161. -------------------------------------------------------------------------*/
  162. #if SOC_I2S_SUPPORTS_PDM_TX
  163. void i2s_hal_pdm_set_tx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_hal_slot_config_t *slot_cfg)
  164. {
  165. bool is_mono = slot_cfg->slot_mode == I2S_SLOT_MODE_MONO;
  166. i2s_ll_tx_reset(hal->dev);
  167. i2s_ll_tx_set_slave_mod(hal->dev, is_slave); //TX Slave
  168. i2s_ll_tx_enable_msb_shift(hal->dev, false);
  169. i2s_ll_tx_set_pdm_prescale(hal->dev, slot_cfg->pdm_tx.sd_prescale);
  170. i2s_ll_tx_set_pdm_hp_scale(hal->dev, slot_cfg->pdm_tx.hp_scale);
  171. i2s_ll_tx_set_pdm_lp_scale(hal->dev, slot_cfg->pdm_tx.lp_scale);
  172. i2s_ll_tx_set_pdm_sinc_scale(hal->dev, slot_cfg->pdm_tx.sinc_scale);
  173. i2s_ll_tx_set_pdm_sd_scale(hal->dev, slot_cfg->pdm_tx.sd_scale);
  174. #if SOC_I2S_HW_VERSION_1
  175. uint32_t slot_bit_width = (int)slot_cfg->slot_bit_width < (int)slot_cfg->data_bit_width ?
  176. slot_cfg->data_bit_width : slot_cfg->slot_bit_width;
  177. i2s_ll_tx_force_enable_fifo_mod(hal->dev, true);
  178. i2s_ll_tx_set_sample_bit(hal->dev, slot_bit_width, slot_cfg->data_bit_width);
  179. i2s_ll_tx_enable_mono_mode(hal->dev, is_mono);
  180. i2s_ll_tx_select_pdm_slot(hal->dev, slot_cfg->pdm_tx.slot_mask & I2S_STD_SLOT_BOTH, is_mono);
  181. i2s_ll_tx_enable_msb_right(hal->dev, false);
  182. i2s_ll_tx_enable_right_first(hal->dev, false);
  183. #elif SOC_I2S_HW_VERSION_2
  184. /* PDM TX line mode */
  185. i2s_ll_tx_pdm_line_mode(hal->dev, slot_cfg->pdm_tx.line_mode);
  186. /* Force use 32 bit in PDM TX stereo mode to satisfy the frequency */
  187. uint32_t slot_bit_width = is_mono ? 16 : 32;
  188. i2s_ll_tx_set_sample_bit(hal->dev, slot_bit_width, slot_bit_width);
  189. i2s_ll_tx_set_half_sample_bit(hal->dev, 16); // Fixed to 16 in PDM mode
  190. /* By default, taking the DMA data at the first half period of WS */
  191. i2s_ll_tx_pdm_dma_take_mode(hal->dev, is_mono, true);
  192. i2s_ll_tx_set_ws_idle_pol(hal->dev, false);
  193. /* Slot mode seems not take effect according to the test, leave it default here */
  194. i2s_ll_tx_pdm_slot_mode(hal->dev, is_mono, false, I2S_PDM_SLOT_BOTH);
  195. uint32_t param0;
  196. uint32_t param5;
  197. s_i2s_hal_get_cut_off_coef(slot_cfg->pdm_tx.hp_cut_off_freq_hzx10, &param0, &param5);
  198. i2s_ll_tx_enable_pdm_hp_filter(hal->dev, slot_cfg->pdm_tx.hp_en);
  199. i2s_ll_tx_set_pdm_hp_filter_param0(hal->dev, param0);
  200. i2s_ll_tx_set_pdm_hp_filter_param5(hal->dev, param5);
  201. i2s_ll_tx_set_pdm_sd_dither(hal->dev, slot_cfg->pdm_tx.sd_dither);
  202. i2s_ll_tx_set_pdm_sd_dither2(hal->dev, slot_cfg->pdm_tx.sd_dither2);
  203. #endif
  204. }
  205. void i2s_hal_pdm_enable_tx_channel(i2s_hal_context_t *hal)
  206. {
  207. i2s_ll_tx_enable_pdm(hal->dev);
  208. }
  209. #endif
  210. #if SOC_I2S_SUPPORTS_PDM_RX
  211. void i2s_hal_pdm_set_rx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_hal_slot_config_t *slot_cfg)
  212. {
  213. uint32_t slot_bit_width = (int)slot_cfg->slot_bit_width < (int)slot_cfg->data_bit_width ?
  214. slot_cfg->data_bit_width : slot_cfg->slot_bit_width;
  215. i2s_ll_rx_reset(hal->dev);
  216. i2s_ll_rx_set_slave_mod(hal->dev, is_slave); //RX Slave
  217. i2s_ll_rx_set_sample_bit(hal->dev, slot_bit_width, slot_cfg->data_bit_width);
  218. #if SOC_I2S_HW_VERSION_1
  219. i2s_ll_rx_enable_mono_mode(hal->dev, slot_cfg->slot_mode == I2S_SLOT_MODE_MONO);
  220. i2s_ll_rx_select_pdm_slot(hal->dev, slot_cfg->pdm_rx.slot_mask);
  221. i2s_ll_rx_force_enable_fifo_mod(hal->dev, true);
  222. i2s_ll_rx_enable_msb_right(hal->dev, false);
  223. i2s_ll_rx_enable_right_first(hal->dev, false);
  224. #elif SOC_I2S_HW_VERSION_2
  225. i2s_ll_rx_set_half_sample_bit(hal->dev, 16);
  226. i2s_ll_rx_enable_mono_mode(hal->dev, false);
  227. #if SOC_I2S_PDM_MAX_RX_LINES > 1
  228. uint32_t slot_mask = (slot_cfg->slot_mode == I2S_SLOT_MODE_STEREO && slot_cfg->pdm_rx.slot_mask <= I2S_PDM_SLOT_BOTH) ?
  229. I2S_PDM_SLOT_BOTH : slot_cfg->pdm_rx.slot_mask;
  230. #else
  231. /* Set the channel mask to enable corresponding slots, always enable two slots for stereo mode */
  232. uint32_t slot_mask = slot_cfg->slot_mode == I2S_SLOT_MODE_STEREO ? I2S_PDM_SLOT_BOTH : slot_cfg->pdm_rx.slot_mask;
  233. #endif // SOC_I2S_SUPPORTS_PDM_RX > 1
  234. i2s_ll_rx_set_active_chan_mask(hal->dev, slot_mask);
  235. #endif // SOC_I2S_HW_VERSION_1
  236. #if SOC_I2S_SUPPORTS_PDM_RX_HP_FILTER
  237. uint32_t param0;
  238. uint32_t param5;
  239. s_i2s_hal_get_cut_off_coef(slot_cfg->pdm_rx.hp_cut_off_freq_hzx10, &param0, &param5);
  240. i2s_ll_rx_enable_pdm_hp_filter(hal->dev, slot_cfg->pdm_rx.hp_en);
  241. i2s_ll_rx_set_pdm_hp_filter_param0(hal->dev, param0);
  242. i2s_ll_rx_set_pdm_hp_filter_param5(hal->dev, param5);
  243. /* Set the amplification number, the default and the minimum value is 1. 0 will mute the channel */
  244. i2s_ll_rx_set_pdm_amplify_num(hal->dev, slot_cfg->pdm_rx.amplify_num ? slot_cfg->pdm_rx.amplify_num : 1);
  245. #endif // SOC_I2S_SUPPORTS_PDM_RX_HP_FILTER
  246. }
  247. void i2s_hal_pdm_enable_rx_channel(i2s_hal_context_t *hal)
  248. {
  249. i2s_ll_rx_enable_pdm(hal->dev);
  250. }
  251. #endif
  252. /*-------------------------------------------------------------------------
  253. | TDM Specific Slot Configurations |
  254. -------------------------------------------------------------------------*/
  255. #if SOC_I2S_SUPPORTS_TDM
  256. void i2s_hal_tdm_set_tx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_hal_slot_config_t *slot_cfg)
  257. {
  258. uint32_t slot_bit_width = (int)slot_cfg->slot_bit_width < (int)slot_cfg->data_bit_width ?
  259. slot_cfg->data_bit_width : slot_cfg->slot_bit_width;
  260. uint32_t cnt;
  261. uint32_t msk = slot_cfg->tdm.slot_mask;
  262. /* Get the maximum slot number */
  263. cnt = 32 - __builtin_clz(msk);
  264. /* There should be at least 2 slots in total even for mono mode */
  265. cnt = cnt < 2 ? 2 : cnt;
  266. uint32_t total_slot = slot_cfg->tdm.total_slot > cnt ? slot_cfg->tdm.total_slot : cnt;
  267. i2s_ll_tx_reset(hal->dev);
  268. i2s_ll_tx_set_slave_mod(hal->dev, is_slave); //TX Slave
  269. i2s_ll_tx_set_sample_bit(hal->dev, slot_bit_width, slot_cfg->data_bit_width);
  270. i2s_ll_tx_enable_mono_mode(hal->dev, slot_cfg->slot_mode == I2S_SLOT_MODE_MONO);
  271. i2s_ll_tx_enable_msb_shift(hal->dev, slot_cfg->tdm.bit_shift);
  272. if (slot_cfg->tdm.ws_width == 0) { // 0: I2S_TDM_AUTO_WS_WIDTH
  273. i2s_ll_tx_set_ws_width(hal->dev, (total_slot * slot_bit_width) / 2);
  274. } else {
  275. i2s_ll_tx_set_ws_width(hal->dev, slot_cfg->tdm.ws_width);
  276. }
  277. i2s_ll_tx_set_ws_idle_pol(hal->dev, slot_cfg->tdm.ws_pol);
  278. i2s_ll_tx_set_chan_num(hal->dev, total_slot);
  279. /* In mono mode, there only should be one slot enabled, other inactive slots will transmit same data as enabled slot */
  280. i2s_ll_tx_set_active_chan_mask(hal->dev, (slot_cfg->slot_mode == I2S_SLOT_MODE_MONO) ?
  281. I2S_TDM_SLOT0 : (uint32_t)slot_cfg->tdm.slot_mask);
  282. i2s_ll_tx_set_skip_mask(hal->dev, slot_cfg->tdm.skip_mask);
  283. i2s_ll_tx_set_half_sample_bit(hal->dev, total_slot * slot_bit_width / 2);
  284. i2s_ll_tx_set_bit_order(hal->dev, slot_cfg->tdm.bit_order_lsb);
  285. i2s_ll_tx_enable_left_align(hal->dev, slot_cfg->tdm.left_align);
  286. i2s_ll_tx_enable_big_endian(hal->dev, slot_cfg->tdm.big_endian);
  287. }
  288. void i2s_hal_tdm_set_rx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_hal_slot_config_t *slot_cfg)
  289. {
  290. uint32_t slot_bit_width = (int)slot_cfg->slot_bit_width < (int)slot_cfg->data_bit_width ?
  291. slot_cfg->data_bit_width : slot_cfg->slot_bit_width;
  292. uint32_t cnt;
  293. uint32_t msk = slot_cfg->tdm.slot_mask;
  294. /* Get the maximum slot number */
  295. cnt = 32 - __builtin_clz(msk);
  296. /* There should be at least 2 slots in total even for mono mode */
  297. cnt = cnt < 2 ? 2 : cnt;
  298. uint32_t total_slot = slot_cfg->tdm.total_slot > cnt ? slot_cfg->tdm.total_slot : cnt;
  299. i2s_ll_rx_reset(hal->dev);
  300. i2s_ll_rx_set_slave_mod(hal->dev, is_slave); //RX Slave
  301. i2s_ll_rx_set_sample_bit(hal->dev, slot_bit_width, slot_cfg->data_bit_width);
  302. i2s_ll_rx_enable_mono_mode(hal->dev, slot_cfg->slot_mode == I2S_SLOT_MODE_MONO);
  303. i2s_ll_rx_enable_msb_shift(hal->dev, slot_cfg->tdm.bit_shift);
  304. if (slot_cfg->tdm.ws_width == 0) { // 0: I2S_TDM_AUTO_WS_WIDTH
  305. i2s_ll_rx_set_ws_width(hal->dev, (total_slot * slot_bit_width) / 2);
  306. } else {
  307. i2s_ll_rx_set_ws_width(hal->dev, slot_cfg->tdm.ws_width);
  308. }
  309. i2s_ll_rx_set_ws_idle_pol(hal->dev, slot_cfg->tdm.ws_pol);
  310. i2s_ll_rx_set_chan_num(hal->dev, total_slot);
  311. /* In mono mode, there only should be one slot enabled, other inactive slots will transmit same data as enabled slot */
  312. i2s_ll_rx_set_active_chan_mask(hal->dev, (slot_cfg->slot_mode == I2S_SLOT_MODE_MONO) ?
  313. I2S_TDM_SLOT0 : (uint32_t)slot_cfg->tdm.slot_mask);
  314. i2s_ll_rx_set_half_sample_bit(hal->dev, total_slot * slot_bit_width / 2);
  315. i2s_ll_rx_set_bit_order(hal->dev, slot_cfg->tdm.bit_order_lsb);
  316. i2s_ll_rx_enable_left_align(hal->dev, slot_cfg->tdm.left_align);
  317. i2s_ll_rx_enable_big_endian(hal->dev, slot_cfg->tdm.big_endian);
  318. }
  319. void i2s_hal_tdm_enable_tx_channel(i2s_hal_context_t *hal)
  320. {
  321. i2s_ll_tx_enable_tdm(hal->dev);
  322. }
  323. void i2s_hal_tdm_enable_rx_channel(i2s_hal_context_t *hal)
  324. {
  325. i2s_ll_rx_enable_tdm(hal->dev);
  326. }
  327. #endif