1 /*
2 * Copyright (c) 2021-2023 HPMicro
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8 #ifndef HPM_I2S_DRV_H
9 #define HPM_I2S_DRV_H
10 #include "hpm_common.h"
11 #include "hpm_soc_feature.h"
12 #include "hpm_i2s_regs.h"
13 #include "hpm_i2s_common.h"
14
15 /**
16 * @brief I2S driver APIs
17 * @defgroup i2s_interface I2S driver APIs
18 * @ingroup io_interfaces
19 * @{
20 */
21
22 /**
23 * @brief I2S data line
24 */
25 #define I2S_DATA_LINE_0 (0U)
26 #define I2S_DATA_LINE_1 (1U)
27 #define I2S_DATA_LINE_2 (2U)
28 #define I2S_DATA_LINE_3 (3U)
29 #define I2S_DATA_LINE_MAX I2S_DATA_LINE_3
30
31 /**
32 * @brief I2S config
33 */
34 typedef struct i2s_config {
35 bool invert_mclk_out;
36 bool invert_mclk_in;
37 bool use_external_mclk;
38 bool invert_bclk_out;
39 bool invert_bclk_in;
40 bool use_external_bclk;
41 bool invert_fclk_out;
42 bool invert_fclk_in;
43 bool use_external_fclk;
44 bool enable_mclk_out;
45 bool frame_start_at_rising_edge;
46 uint16_t fifo_threshold;
47 } i2s_config_t;
48
49 /**
50 * @brief I2S transfer config
51 */
52 typedef struct i2x_transfer_config {
53 uint32_t sample_rate;
54 bool enable_tdm_mode;
55 uint8_t channel_num_per_frame;
56 uint8_t channel_length; /* 16-bit or 32-bit */
57 uint8_t audio_depth; /* 16-bit, 24-bit, 32-bit */
58 bool master_mode;
59 uint8_t protocol;
60 uint8_t data_line;
61 uint32_t channel_slot_mask;
62 } i2s_transfer_config_t;
63
64 typedef enum {
65 i2s_tx_fifo_threshold_irq_mask = I2S_CTRL_TXDNIE_MASK,
66 i2s_rx_fifo_threshold_irq_mask = I2S_CTRL_RXDAIE_MASK,
67 i2s_fifo_error_irq_mask = I2S_CTRL_ERRIE_MASK, /*<! rx fifo overrun, tx fifo underrun */
68 } i2s_irq_mask_t;
69
70 typedef enum {
71 i2s_data_line_rx_fifo_avail = 1U, /*<! data avail */
72 i2s_data_line_tx_fifo_avail = 2U, /*<! fifo empty avail */
73 i2s_data_line_rx_fifo_overrun = 4U,
74 i2s_data_line_tx_fifo_underrun = 8U,
75 } i2s_data_line_stat_t;
76
77 #ifdef __cplusplus
78 extern "C" {
79 #endif
80
81 /**
82 * @brief enable TDM
83 *
84 * @param [in] ptr I2S base address
85 */
i2s_enable_tdm(I2S_Type * ptr)86 static inline void i2s_enable_tdm(I2S_Type *ptr)
87 {
88 ptr->CFGR |= I2S_CFGR_TDM_EN_MASK;
89 }
90
91 /**
92 * @brief disable TDM
93 *
94 * @param [in] ptr I2S base address
95 */
i2s_disable_tdm(I2S_Type * ptr)96 static inline void i2s_disable_tdm(I2S_Type *ptr)
97 {
98 ptr->CFGR &= ~I2S_CFGR_TDM_EN_MASK;
99 }
100
101 /**
102 * @brief update rx fifo threshold
103 *
104 * @param [in] ptr I2S base address
105 * @param [in] threshold fifo threshold value
106 */
i2s_update_rx_fifo_threshold(I2S_Type * ptr,uint8_t threshold)107 static inline void i2s_update_rx_fifo_threshold(I2S_Type *ptr, uint8_t threshold)
108 {
109 ptr->FIFO_THRESH = (ptr->FIFO_THRESH & ~I2S_FIFO_THRESH_RX_MASK)
110 | I2S_FIFO_THRESH_RX_SET(threshold);
111 }
112
113 /**
114 * @brief update tx fifo threshold
115 *
116 * @param [in] ptr I2S base address
117 * @param [in] threshold fifo threshold value
118 */
i2s_update_tx_fifo_threshold(I2S_Type * ptr,uint8_t threshold)119 static inline void i2s_update_tx_fifo_threshold(I2S_Type *ptr, uint8_t threshold)
120 {
121 ptr->FIFO_THRESH = (ptr->FIFO_THRESH & ~I2S_FIFO_THRESH_TX_MASK)
122 | I2S_FIFO_THRESH_TX_SET(threshold);
123 }
124
125 /**
126 * @brief open BCLK
127 *
128 * @param [in] ptr I2S base address
129 */
i2s_ungate_bclk(I2S_Type * ptr)130 static inline void i2s_ungate_bclk(I2S_Type *ptr)
131 {
132 ptr->CFGR &= ~I2S_CFGR_BCLK_GATEOFF_MASK;
133 }
134
135 /**
136 * @brief gete off BCLK
137 *
138 * @param [in] ptr I2S base address
139 */
i2s_gate_bclk(I2S_Type * ptr)140 static inline void i2s_gate_bclk(I2S_Type *ptr)
141 {
142 ptr->CFGR |= I2S_CFGR_BCLK_GATEOFF_MASK;
143 }
144
145 /**
146 * @brief open MCLK
147 *
148 * @param [in] ptr I2S base address
149 */
i2s_ungate_mclk(I2S_Type * ptr)150 static inline void i2s_ungate_mclk(I2S_Type *ptr)
151 {
152 ptr->MISC_CFGR &= ~I2S_MISC_CFGR_MCLK_GATEOFF_MASK;
153 }
154
155 /**
156 * @brief gate off MCLK
157 *
158 * @param [in] ptr I2S base address
159 */
i2s_gate_mclk(I2S_Type * ptr)160 static inline void i2s_gate_mclk(I2S_Type *ptr)
161 {
162 ptr->MISC_CFGR |= I2S_MISC_CFGR_MCLK_GATEOFF_MASK;
163 }
164
165 /**
166 * @brief enable TX dma request
167 *
168 * @param [in] ptr I2S base address
169 */
i2s_enable_tx_dma_request(I2S_Type * ptr)170 static inline void i2s_enable_tx_dma_request(I2S_Type *ptr)
171 {
172 ptr->CTRL |= I2S_CTRL_TX_DMA_EN_MASK;
173 }
174
175 /**
176 * @brief disable TX dma request
177 *
178 * @param [in] ptr I2S base address
179 */
i2s_disable_tx_dma_request(I2S_Type * ptr)180 static inline void i2s_disable_tx_dma_request(I2S_Type *ptr)
181 {
182 ptr->CTRL &= ~I2S_CTRL_TX_DMA_EN_MASK;
183 }
184
185 /**
186 * @brief enable RX dma request
187 *
188 * @param [in] ptr I2S base address
189 */
i2s_enable_rx_dma_request(I2S_Type * ptr)190 static inline void i2s_enable_rx_dma_request(I2S_Type *ptr)
191 {
192 ptr->CTRL |= I2S_CTRL_RX_DMA_EN_MASK;
193 }
194
195 /**
196 * @brief disable RX dma request
197 *
198 * @param [in] ptr I2S base address
199 */
i2s_disable_rx_dma_request(I2S_Type * ptr)200 static inline void i2s_disable_rx_dma_request(I2S_Type *ptr)
201 {
202 ptr->CTRL &= ~I2S_CTRL_RX_DMA_EN_MASK;
203 }
204
205 /**
206 * @brief enable IRQ
207 *
208 * @param [in] ptr I2S base address
209 * @param [in] mask irq bit mask
210 */
i2s_enable_irq(I2S_Type * ptr,uint32_t mask)211 static inline void i2s_enable_irq(I2S_Type *ptr, uint32_t mask)
212 {
213 ptr->CTRL |= mask;
214 }
215
216 /**
217 * @brief disable IRQ
218 *
219 * @param [in] ptr I2S base address
220 * @param [in] mask irq bit mask
221 */
i2s_disable_irq(I2S_Type * ptr,uint32_t mask)222 static inline void i2s_disable_irq(I2S_Type *ptr, uint32_t mask)
223 {
224 ptr->CTRL &= ~mask;
225 }
226
227 /**
228 * @brief I2S enable
229 *
230 * @note dropped API, please use i2s_start
231 *
232 * @param [in] ptr I2S base address
233 */
i2s_enable(I2S_Type * ptr)234 static inline void i2s_enable(I2S_Type *ptr)
235 {
236 ptr->CTRL |= I2S_CTRL_I2S_EN_MASK;
237 }
238
239 /**
240 * @brief I2S disable
241 *
242 * @note dropped API, please use i2s_stop
243 *
244 * @param [in] ptr I2S base address
245 */
i2s_disable(I2S_Type * ptr)246 static inline void i2s_disable(I2S_Type *ptr)
247 {
248 ptr->CTRL &= ~I2S_CTRL_I2S_EN_MASK;
249 }
250
251 /**
252 * @brief I2S start
253 *
254 * @param [in] ptr I2S base address
255 */
i2s_start(I2S_Type * ptr)256 static inline void i2s_start(I2S_Type *ptr)
257 {
258 ptr->CTRL |= I2S_CTRL_I2S_EN_MASK;
259 }
260
261 /**
262 * @brief I2S stop
263 *
264 * @param [in] ptr I2S base address
265 */
i2s_stop(I2S_Type * ptr)266 static inline void i2s_stop(I2S_Type *ptr)
267 {
268 ptr->CTRL &= ~I2S_CTRL_I2S_EN_MASK;
269 }
270
271 /**
272 * @brief I2S enable rx function
273 *
274 * @param [in] ptr I2S base address
275 * @param [in] rx_mask rx data line mask
276 */
i2s_enable_rx(I2S_Type * ptr,uint8_t rx_mask)277 static inline void i2s_enable_rx(I2S_Type *ptr, uint8_t rx_mask)
278 {
279 ptr->CTRL |= I2S_CTRL_RX_EN_SET(rx_mask);
280 }
281
282 /**
283 * @brief I2S disable rx function
284 *
285 * @param [in] ptr I2S base address
286 * @param [in] rx_mask rx data line mask
287 */
i2s_disable_rx(I2S_Type * ptr,uint8_t rx_mask)288 static inline void i2s_disable_rx(I2S_Type *ptr, uint8_t rx_mask)
289 {
290 ptr->CTRL &= ~I2S_CTRL_RX_EN_SET(rx_mask);
291 }
292
293 /**
294 * @brief I2S enable tx function
295 *
296 * @param [in] ptr I2S base address
297 * @param [in] tx_mask tx data line mask
298 */
i2s_enable_tx(I2S_Type * ptr,uint8_t tx_mask)299 static inline void i2s_enable_tx(I2S_Type *ptr, uint8_t tx_mask)
300 {
301 ptr->CTRL |= I2S_CTRL_TX_EN_SET(tx_mask);
302 }
303
304 /**
305 * @brief I2S disbale tx function
306 *
307 * @param [in] ptr I2S base address
308 * @param [in] tx_mask tx data line mask
309 */
i2s_disable_tx(I2S_Type * ptr,uint8_t tx_mask)310 static inline void i2s_disable_tx(I2S_Type *ptr, uint8_t tx_mask)
311 {
312 ptr->CTRL &= ~I2S_CTRL_TX_EN_SET(tx_mask);
313 }
314
315 /**
316 * @brief I2S reset clock generator
317 *
318 * @param [in] ptr I2S base address
319 */
i2s_reset_clock_gen(I2S_Type * ptr)320 static inline void i2s_reset_clock_gen(I2S_Type *ptr)
321 {
322 ptr->CTRL |= I2S_CTRL_SFTRST_CLKGEN_MASK;
323 ptr->CTRL &= ~I2S_CTRL_SFTRST_CLKGEN_MASK;
324 }
325
326 /**
327 * @brief I2S reset tx function
328 *
329 * @note This API will disable I2S, reset tx function
330 *
331 * @param [in] ptr I2S base address
332 */
i2s_reset_tx(I2S_Type * ptr)333 static inline void i2s_reset_tx(I2S_Type *ptr)
334 {
335 /* disable I2S */
336 ptr->CTRL &= ~I2S_CTRL_I2S_EN_MASK;
337
338 /* reset tx and clear fifo */
339 ptr->CTRL |= (I2S_CTRL_TXFIFOCLR_MASK | I2S_CTRL_SFTRST_TX_MASK);
340 ptr->CTRL &= ~(I2S_CTRL_TXFIFOCLR_MASK | I2S_CTRL_SFTRST_TX_MASK);
341 }
342
343 /**
344 * @brief I2S reset rx function
345 *
346 * @note This API will disable I2S, reset rx function
347 *
348 * @param [in] ptr I2S base address
349 */
i2s_reset_rx(I2S_Type * ptr)350 static inline void i2s_reset_rx(I2S_Type *ptr)
351 {
352 /* disable I2S */
353 ptr->CTRL &= ~I2S_CTRL_I2S_EN_MASK;
354
355 /* reset rx and clear fifo */
356 ptr->CTRL |= (I2S_CTRL_RXFIFOCLR_MASK | I2S_CTRL_SFTRST_RX_MASK);
357 ptr->CTRL &= ~(I2S_CTRL_RXFIFOCLR_MASK | I2S_CTRL_SFTRST_RX_MASK);
358 }
359
360 /**
361 * @brief I2S reset tx and rx function
362 *
363 * @note This API will disable I2S, reset tx/rx function
364 *
365 * @param [in] ptr I2S base address
366 */
i2s_reset_tx_rx(I2S_Type * ptr)367 static inline void i2s_reset_tx_rx(I2S_Type *ptr)
368 {
369 /* disable I2S */
370 ptr->CTRL &= ~I2S_CTRL_I2S_EN_MASK;
371
372 /* reset tx/rx and clear fifo */
373 ptr->CTRL |= (I2S_CTRL_TXFIFOCLR_MASK | I2S_CTRL_RXFIFOCLR_MASK | I2S_CTRL_SFTRST_TX_MASK | I2S_CTRL_SFTRST_RX_MASK);
374 ptr->CTRL &= ~(I2S_CTRL_TXFIFOCLR_MASK | I2S_CTRL_RXFIFOCLR_MASK | I2S_CTRL_SFTRST_TX_MASK | I2S_CTRL_SFTRST_RX_MASK);
375 }
376
377 /**
378 * @brief I2S get tx fifo level
379 *
380 * @param [in] ptr I2S base address
381 *
382 * @retval I2S tx fifo level
383 */
i2s_get_tx_fifo_level(I2S_Type * ptr)384 static inline uint32_t i2s_get_tx_fifo_level(I2S_Type *ptr)
385 {
386 return ptr->TFIFO_FILLINGS;
387 }
388
389 /**
390 * @brief I2S get data line tx fifo level
391 *
392 * @param [in] ptr I2S base address
393 * @param [in] line I2S data line
394 *
395 * @retval I2S data line tx fifo level
396 */
i2s_get_tx_line_fifo_level(I2S_Type * ptr,uint8_t line)397 static inline uint32_t i2s_get_tx_line_fifo_level(I2S_Type *ptr, uint8_t line)
398 {
399 return (i2s_get_tx_fifo_level(ptr) & (0xFF << (line << 3))) >> (line << 3);
400 }
401
402 /**
403 * @brief I2S get rx fifo level
404 *
405 * @param [in] ptr I2S base address
406 *
407 * @retval I2S rx fifo level
408 */
i2s_get_rx_fifo_level(I2S_Type * ptr)409 static inline uint32_t i2s_get_rx_fifo_level(I2S_Type *ptr)
410 {
411 return ptr->RFIFO_FILLINGS;
412 }
413
414 /**
415 * @brief I2S get data line rx fifo level
416 *
417 * @param [in] ptr I2S base address
418 * @param [in] line I2S data line
419 *
420 * @retval I2S data line rx fifo level
421 */
i2s_get_rx_line_fifo_level(I2S_Type * ptr,uint8_t line)422 static inline uint32_t i2s_get_rx_line_fifo_level(I2S_Type *ptr, uint8_t line)
423 {
424 return (i2s_get_rx_fifo_level(ptr) & (0xFF << (line << 3))) >> (line << 3);
425 }
426
427 /**
428 * @brief Check I2S data line status
429 *
430 * @param[in] ptr I2S base address
431 * @param[in] line I2S data line
432 *
433 * @retval i2s_data_line_rx_fifo_avail data in rx fifo >= threshold
434 * @retval i2s_data_line_tx_fifo_avail data in tx fifo <= threshold
435 * @retval i2s_data_line_rx_fifo_overrun rx fifo overrun occured
436 * @retval i2s_data_line_tx_fifo_underrun tx fifo underrun occured
437 */
i2s_check_data_line_status(I2S_Type * ptr,uint8_t line)438 static inline uint32_t i2s_check_data_line_status(I2S_Type *ptr, uint8_t line)
439 {
440 volatile uint32_t reg_val = ptr->STA;
441 uint32_t bit_mask;
442 uint32_t stat = 0;
443
444 bit_mask = 1 << (I2S_STA_RX_DA_SHIFT + line);
445 if ((bit_mask & reg_val) != 0) {
446 stat |= i2s_data_line_rx_fifo_avail;
447 }
448
449 bit_mask = 1 << (I2S_STA_TX_DN_SHIFT + line);
450 if ((bit_mask & reg_val) != 0) {
451 stat |= i2s_data_line_tx_fifo_avail;
452 }
453
454 bit_mask = 1 << (I2S_STA_RX_OV_SHIFT + line);
455 if ((bit_mask & reg_val) != 0) {
456 stat |= i2s_data_line_rx_fifo_overrun;
457 ptr->STA = bit_mask; /* clear flag: W1C*/
458 }
459
460 bit_mask = 1 << (I2S_STA_TX_UD_SHIFT + line);
461 if ((bit_mask & reg_val) != 0) {
462 stat |= i2s_data_line_tx_fifo_underrun;
463 ptr->STA = bit_mask; /* clear flag: W1C*/
464 }
465
466 return stat;
467 }
468
469 /**
470 * @brief I2S get IRQ status
471 *
472 * @param [in] ptr I2S base address
473 *
474 * @retval I2S STA register value
475 */
i2s_get_irq_status(I2S_Type * ptr)476 static inline uint32_t i2s_get_irq_status(I2S_Type *ptr)
477 {
478 return ptr->STA;
479 }
480
481 /**
482 * @brief I2S stop transfer
483 *
484 * @param [in] ptr I2S base address
485 */
i2s_stop_transfer(I2S_Type * ptr)486 static inline void i2s_stop_transfer(I2S_Type *ptr)
487 {
488 i2s_disable(ptr);
489 }
490
491 /**
492 * @brief I2S config tx
493 *
494 * @note This API will disable I2S and configure parameters, could call i2s_enable() to enable I2S
495 *
496 * @param [in] ptr I2S base address
497 * @param [in] mclk_in_hz mclk frequency in Hz
498 * @param [in] config i2s_transfer_config_t
499 * @retval hpm_stat_t status_invalid_argument or status_success
500 */
501 hpm_stat_t i2s_config_tx(I2S_Type *ptr, uint32_t mclk_in_hz, i2s_transfer_config_t *config);
502
503 /**
504 * @brief I2S config tx for slave
505 *
506 * @note This API will disable I2S and configure parameters, could call i2s_enable() to enable I2S
507 *
508 * @param [in] ptr I2S base address
509 * @param [in] config i2s_transfer_config_t
510 */
511 hpm_stat_t i2s_config_tx_slave(I2S_Type *ptr, i2s_transfer_config_t *config);
512
513 /**
514 * @brief I2S config rx
515 *
516 * @note This API will disable I2S and configure parameters, could call i2s_enable() to enable I2S
517 *
518 * @param [in] ptr I2S base address
519 * @param [in] mclk_in_hz mclk frequency in Hz
520 * @param [in] config i2s_transfer_config_t
521 * @retval hpm_stat_t status_invalid_argument or status_success
522 */
523 hpm_stat_t i2s_config_rx(I2S_Type *ptr, uint32_t mclk_in_hz, i2s_transfer_config_t *config);
524
525 /**
526 * @brief I2S config rx for slave
527 *
528 * @note This API will disable I2S and configure parameters, could call i2s_enable() to enable I2S
529 *
530 * @param [in] ptr I2S base address
531 * @param [in] config i2s_transfer_config_t
532 * @retval hpm_stat_t status_invalid_argument or status_success
533 */
534 hpm_stat_t i2s_config_rx_slave(I2S_Type *ptr, i2s_transfer_config_t *config);
535
536 /**
537 * @brief I2S config transfer
538 *
539 * @note This API will disable I2S and configure parameters, could call i2s_enable() to enable I2S
540 *
541 * @param [in] ptr I2S base address
542 * @param [in] mclk_in_hz mclk frequency in Hz
543 * @param [in] config i2s_transfer_config_t
544 * @retval hpm_stat_t status_invalid_argument or status_success
545 */
546 hpm_stat_t i2s_config_transfer(I2S_Type *ptr, uint32_t mclk_in_hz, i2s_transfer_config_t *config);
547
548 /**
549 * @brief I2S config transfer for slave
550 *
551 * @note This API will disable I2S and configure parameters, could call i2s_enable() to enable I2S
552 *
553 * @param [in] ptr I2S base address
554 * @param [in] config i2s_transfer_config_t
555 * @retval hpm_stat_t status_invalid_argument or status_success
556 */
557 hpm_stat_t i2s_config_transfer_slave(I2S_Type *ptr, i2s_transfer_config_t *config);
558
559 /**
560 * @brief I2S send data
561 *
562 * @param [in] ptr I2S base address
563 * @param [in] tx_line_index data line
564 * @param [in] data data to be written
565 */
i2s_send_data(I2S_Type * ptr,uint8_t tx_line_index,uint32_t data)566 static inline void i2s_send_data(I2S_Type *ptr, uint8_t tx_line_index, uint32_t data)
567 {
568 ptr->TXD[tx_line_index] = data;
569 }
570
571 /**
572 * @brief I2S receive data
573 *
574 * @param [in] ptr I2S base address
575 * @param [in] rx_line_index data line
576 * @param [out] data point to store data address
577 */
i2s_receive_data(I2S_Type * ptr,uint8_t rx_line_index,uint32_t * data)578 static inline void i2s_receive_data(I2S_Type *ptr, uint8_t rx_line_index, uint32_t *data)
579 {
580 *data = ptr->RXD[rx_line_index];
581 }
582
583 /**
584 * @brief I2S send data in buff
585 *
586 * @param [in] ptr I2S base address
587 * @param [in] tx_line_index data line
588 * @param [in] samplebits audio data width
589 * @param [in] src source data buff
590 * @param [in] size data size
591 *
592 * @retval I2S sent data size in byte
593 */
594 uint32_t i2s_send_buff(I2S_Type *ptr, uint8_t tx_line_index, uint8_t samplebits, uint8_t *src, uint32_t size);
595
596 /**
597 * @brief I2S receive data in buff
598 *
599 * @param [in] ptr I2S base address
600 * @param [in] rx_line_index data line
601 * @param [in] samplebits audio data width
602 * @param [out] dst target data buff
603 * @param [in] size data size
604 *
605 * @retval I2S sent data size in byte
606 */
607 uint32_t i2s_receive_buff(I2S_Type *ptr, uint8_t rx_line_index, uint8_t samplebits, uint8_t *dst, uint32_t size);
608
609 /**
610 * @brief I2S get default config
611 *
612 * @param [in] ptr I2S base address
613 * @param [out] config i2s_config_t
614 */
615 void i2s_get_default_config(I2S_Type *ptr, i2s_config_t *config);
616
617 /**
618 * @brief I2S initialization
619 *
620 * @param [in] ptr I2S base address
621 * @param [in] config i2s_config_t
622 */
623 void i2s_init(I2S_Type *ptr, i2s_config_t *config);
624
625 /**
626 * @brief I2S get default transfer config for pdm
627 *
628 * @param [out] transfer i2s_transfer_config_t
629 */
630 void i2s_get_default_transfer_config_for_pdm(i2s_transfer_config_t *transfer);
631
632 /**
633 * @brief I2S get default transfer config for dao
634 *
635 * @param [out] transfer i2s_transfer_config_t
636 */
637 void i2s_get_default_transfer_config_for_dao(i2s_transfer_config_t *transfer);
638
639 /**
640 * @brief I2S get default transfer config
641 *
642 * @param [out] transfer i2s_transfer_config_t
643 */
644 void i2s_get_default_transfer_config(i2s_transfer_config_t *transfer);
645
646 /**
647 * @brief I2S fill dummy data into TX fifo
648 *
649 * @note workaround: fill dummy data into TX fifo to avoid TX underflow during tx start
650 *
651 * @param [in] ptr I2S base address
652 * @param [in] data_line data line
653 * @param [in] data_count dummy data count, This value should be the same as the number of audio channels
654 *
655 * @retval status_success if no error occurred
656 */
657 hpm_stat_t i2s_fill_tx_dummy_data(I2S_Type *ptr, uint8_t data_line, uint8_t data_count);
658
659 /**
660 * @}
661 */
662
663 #ifdef __cplusplus
664 }
665 #endif
666
667 #endif /* HPM_I2S_DRV_H */
668