kendryte-sdk-source/lib/drivers/include/i2s.h

784 lines
23 KiB
C

/* Copyright 2018 Canaan Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _DRIVER_I2S_H
#define _DRIVER_I2S_H
#include <stdint.h>
#include <stddef.h>
#include "platform.h"
#include "io.h"
#include "dmac.h"
#include "bsp.h"
#ifdef __cplusplus
extern "C" {
#endif
#define I2S0_IN_D0 90
#define I2S0_SCLK 88
#define I2S0_WS 89
typedef enum _i2s_device_number
{
I2S_DEVICE_0 = 0,
I2S_DEVICE_1 = 1,
I2S_DEVICE_2 = 2,
I2S_DEVICE_MAX
} i2s_device_number_t;
typedef enum _i2s_channel_num
{
I2S_CHANNEL_0 = 0,
I2S_CHANNEL_1 = 1,
I2S_CHANNEL_2 = 2,
I2S_CHANNEL_3 = 3
} i2s_channel_num_t;
typedef enum _i2s_transmit
{
I2S_TRANSMITTER = 0,
I2S_RECEIVER = 1
} i2s_transmit_t;
typedef enum _i2s_work_mode
{
STANDARD_MODE = 1,
RIGHT_JUSTIFYING_MODE = 2,
LEFT_JUSTIFYING_MODE = 4
} i2s_work_mode_t;
typedef enum _sclk_gating_cycles
{
/* Clock gating is diable */
NO_CLOCK_GATING = 0x0,
/* Gating after 12 sclk cycles */
CLOCK_CYCLES_12 = 0x1,
/* Gating after 16 sclk cycles */
CLOCK_CYCLES_16 = 0x2,
/* Gating after 20 sclk cycles */
CLOCK_CYCLES_20 = 0x3,
/* Gating after 24 sclk cycles */
CLOCK_CYCLES_24 = 0x4
} i2s_sclk_gating_cycles_t;
typedef enum _word_select_cycles
{
/* 16 sclk cycles */
SCLK_CYCLES_16 = 0x0,
/* 24 sclk cycles */
SCLK_CYCLES_24 = 0x1,
/* 32 sclk cycles */
SCLK_CYCLES_32 = 0x2
} i2s_word_select_cycles_t;
typedef enum _word_length
{
/* Ignore the word length */
IGNORE_WORD_LENGTH = 0x0,
/* 12-bit data resolution of the receiver */
RESOLUTION_12_BIT = 0x1,
/* 16-bit data resolution of the receiver */
RESOLUTION_16_BIT = 0x2,
/* 20-bit data resolution of the receiver */
RESOLUTION_20_BIT = 0x3,
/* 24-bit data resolution of the receiver */
RESOLUTION_24_BIT = 0x4,
/* 32-bit data resolution of the receiver */
RESOLUTION_32_BIT = 0x5
} i2s_word_length_t;
typedef enum _fifo_threshold
{
/* Interrupt trigger when FIFO level is 1 */
TRIGGER_LEVEL_1 = 0x0,
/* Interrupt trigger when FIFO level is 2 */
TRIGGER_LEVEL_2 = 0x1,
/* Interrupt trigger when FIFO level is 3 */
TRIGGER_LEVEL_3 = 0x2,
/* Interrupt trigger when FIFO level is 4 */
TRIGGER_LEVEL_4 = 0x3,
/* Interrupt trigger when FIFO level is 5 */
TRIGGER_LEVEL_5 = 0x4,
/* Interrupt trigger when FIFO level is 6 */
TRIGGER_LEVEL_6 = 0x5,
/* Interrupt trigger when FIFO level is 7 */
TRIGGER_LEVEL_7 = 0x6,
/* Interrupt trigger when FIFO level is 8 */
TRIGGER_LEVEL_8 = 0x7,
/* Interrupt trigger when FIFO level is 9 */
TRIGGER_LEVEL_9 = 0x8,
/* Interrupt trigger when FIFO level is 10 */
TRIGGER_LEVEL_10 = 0x9,
/* Interrupt trigger when FIFO level is 11 */
TRIGGER_LEVEL_11 = 0xa,
/* Interrupt trigger when FIFO level is 12 */
TRIGGER_LEVEL_12 = 0xb,
/* Interrupt trigger when FIFO level is 13 */
TRIGGER_LEVEL_13 = 0xc,
/* Interrupt trigger when FIFO level is 14 */
TRIGGER_LEVEL_14 = 0xd,
/* Interrupt trigger when FIFO level is 15 */
TRIGGER_LEVEL_15 = 0xe,
/* Interrupt trigger when FIFO level is 16 */
TRIGGER_LEVEL_16 = 0xf
} i2s_fifo_threshold_t;
typedef struct _i2s_ier
{
/* Bit 0 is ien, 0 for disable i2s and 1 for enable i2s */
uint32_t ien : 1;
/* Bits [31:1] is reserved */
uint32_t resv : 31;
} __attribute__((packed, aligned(4))) i2s_ier_t;
typedef union _ier_u
{
i2s_ier_t ier;
uint32_t reg_data;
} ier_t;
typedef struct _i2s_irer
{
/* Bit 0 is receiver block enable,
* 0 for receiver disable
* 1 for receiver enable
*/
uint32_t rxen : 1;
/* Bits [31:1] is reserved */
uint32_t resv : 31;
} __attribute__((packed, aligned(4))) i2s_irer_t;
typedef union _irer_u
{
i2s_irer_t irer;
uint32_t reg_data;
} irer_t;
typedef struct _i2s_iter
{
uint32_t txen : 1;
/* Bit 0 is transmitter block enable,
* 0 for transmitter disable
* 1 for transmitter enable
*/
uint32_t resv : 31;
/* Bits [31:1] is reserved */
} __attribute__((packed, aligned(4))) i2s_iter_t;
typedef union _iter_u
{
i2s_iter_t iter;
uint32_t reg_data;
} iter_t;
typedef struct _i2s_cer
{
uint32_t clken : 1;
/* Bit 0 is clock generation enable/disable,
* 0 for clock generation disable,
* 1 for clock generation enable
*/
uint32_t resv : 31;
/* Bits [31:1] is reserved */
} __attribute__((packed, aligned(4))) i2s_cer_t;
typedef union _cer_u
{
i2s_cer_t cer;
uint32_t reg_data;
} cer_t;
typedef struct _i2s_ccr
{
/* Bits [2:0] is used to program the gating of sclk,
* 0x0 for clock gating is diable,
* 0x1 for gating after 12 sclk cycles
* 0x2 for gating after 16 sclk cycles
* 0x3 for gating after 20 sclk cycles
* 0x4 for gating after 24 sclk cycles
*/
uint32_t clk_gate : 3;
/* Bits [4:3] used program the number of sclk cycles for which the
* word select line stayd in the left aligned or right aligned mode.
* 0x0 for 16sclk cycles, 0x1 for 24 sclk cycles 0x2 for 32 sclk
* cycles
*/
uint32_t clk_word_size : 2;
/* Bit[5:7] is alignment mode setting.
* 0x1 for standard i2s format
* 0x2 for right aligned format
* 0x4 for left aligned format
*/
uint32_t align_mode : 3;
/* Bit[8] is DMA transmit enable control */
uint32_t dma_tx_en : 1;
/* Bit[9] is DMA receive enable control */
uint32_t dma_rx_en : 1;
uint32_t dma_divide_16 : 1;
/* Bit[10] split 32bit data to two 16 bit data and filled in left
* and right channel. Used with dma_tx_en or dma_rx_en
*/
uint32_t sign_expand_en : 1;
uint32_t resv : 20;
/* Bits [31:11] is reseved */
} __attribute__((packed, aligned(4))) i2s_ccr_t;
typedef union _ccr_u
{
i2s_ccr_t ccr;
uint32_t reg_data;
} ccr_t;
typedef struct _i2s_rxffr
{
uint32_t rxffr : 1;
/* Bit 0 is receiver FIFO reset,
* 0 for does not flush RX FIFO, 1 for flush RX FIFO
*/
uint32_t resv : 31;
/* Bits [31:1] is reserved */
} __attribute__((packed, aligned(4))) i2s_rxffr_t;
typedef union _rxffr_u
{
i2s_rxffr_t rxffr;
uint32_t reg_data;
} rxffr_t;
typedef struct _i2s_lrbrthr
{
uint32_t fifo : 16;
/* Bits [15:0] if used data receive or transmit */
uint32_t resv : 16;
} i2s_lrbrthr_t;
typedef union _lrbthr_u
{
i2s_lrbrthr_t buffer;
uint32_t reg_data;
} lrbthr_t;
typedef struct _i2s_rthr
{
/* Bits [15:0] is right stereo data transmitted serially
* from transmit channel input
*/
uint32_t rthrx : 16;
/* Bits [31:16] is reserved */
uint32_t resv : 16;
} __attribute__((packed, aligned(4))) i2s_rthr_t;
typedef union _rthr_u
{
i2s_rthr_t rthr;
uint32_t reg_data;
} rthr_t;
typedef struct _i2s_rer
{
/* Bit 0 is receive channel enable/disable, 0 for receive channel disable,
*1 for receive channel enable
*/
uint32_t rxchenx : 1;
/* Bits [31:1] is reseved */
uint32_t resv : 31;
} __attribute__((packed, aligned(4))) i2s_rer_t;
typedef union _rer_u
{
i2s_rer_t rer;
uint32_t reg_data;
} rer_t;
typedef struct _i2s_ter
{
/* Bit 0 is transmit channel enable/disable, 0 for transmit channel disable,
* 1 for transmit channel enable
*/
uint32_t txchenx : 1;
/* Bits [31:1] is reseved */
uint32_t resv : 31;
} __attribute__((packed, aligned(4))) i2s_ter_t;
typedef union _ter_u
{
i2s_ter_t ter;
uint32_t reg_data;
} ter_t;
typedef struct _i2s_rcr_tcr
{
/* Bits [2:0] is used to program desired data resolution of
* receiver/transmitter,
* 0x0 for ignore the word length
* 0x1 for 12-bit data resolution of the receiver/transmitter,
* 0x2 for 16-bit data resolution of the receiver/transmitter,
* 0x3 for 20-bit data resolution of the receiver/transmitter,
* 0x4 for 24-bit data resolution of the receiver/transmitter,
* 0x5 for 32-bit data resolution of the receiver/transmitter
*/
uint32_t wlen : 3;
/* Bits [31:3] is reseved */
uint32_t resv : 29;
} __attribute__((packed, aligned(4))) i2s_rcr_tcr_t;
typedef union _rcr_tcr_u {
i2s_rcr_tcr_t rcr_tcr;
uint32_t reg_data;
} rcr_tcr_t;
typedef struct _i2s_isr
{
/* Bit 0 is status of receiver data avaliable interrupt
* 0x0 for RX FIFO trigger level not reached
* 0x1 for RX FIFO trigger level is reached
*/
uint32_t rxda : 1;
/* Bit 1 is status of data overrun interrupt for rx channel
* 0x0 for RX FIFO write valid
* 0x1 for RX FIFO write overrun
*/
uint32_t rxfo : 1;
/* Bits [3:2] is reserved */
uint32_t resv1 : 2;
/* Bit 4 is status of transmit empty triger interrupt
* 0x0 for TX FIFO triiger level is reach
* 0x1 for TX FIFO trigger level is not reached
*/
uint32_t txfe : 1;
/* BIt 5 is status of data overrun interrupt for the TX channel
* 0x0 for TX FIFO write valid
* 0x1 for TX FIFO write overrun
*/
uint32_t txfo : 1;
/* BIts [31:6] is reserved */
uint32_t resv2 : 26;
} __attribute__((packed, aligned(4))) i2s_isr_t;
typedef union _isr_u
{
i2s_isr_t isr;
uint32_t reg_data;
} isr_t;
typedef struct _i2s_imr
{
/* Bit 0 is mask RX FIFO data available interrupt
* 0x0 for unmask RX FIFO data available interrupt
* 0x1 for mask RX FIFO data available interrupt
*/
uint32_t rxdam : 1;
/* Bit 1 is mask RX FIFO overrun interrupt
* 0x0 for unmask RX FIFO overrun interrupt
* 0x1 for mask RX FIFO overrun interrupt
*/
uint32_t rxfom : 1;
/* Bits [3:2] is reserved */
uint32_t resv1 : 2;
/* Bit 4 is mask TX FIFO empty interrupt,
* 0x0 for unmask TX FIFO empty interrupt,
* 0x1 for mask TX FIFO empty interrupt
*/
uint32_t txfem : 1;
/* BIt 5 is mask TX FIFO overrun interrupt
* 0x0 for mask TX FIFO overrun interrupt
* 0x1 for unmash TX FIFO overrun interrupt
*/
uint32_t txfom : 1;
/* Bits [31:6] is reserved */
uint32_t resv2 : 26;
} __attribute__((packed, aligned(4))) i2s_imr_t;
typedef union _imr_u
{
i2s_imr_t imr;
uint32_t reg_data;
} imr_t;
typedef struct _i2s_ror
{
/* Bit 0 is read this bit to clear RX FIFO data overrun interrupt
* 0x0 for RX FIFO write valid,
*0x1 for RX FIFO write overrun
*/
uint32_t rxcho : 1;
/* Bits [31:1] is reserved */
uint32_t resv : 31;
} __attribute__((packed, aligned(4))) i2s_ror_t;
typedef union _ror_u
{
i2s_ror_t ror;
uint32_t reg_data;
} ror_t;
typedef struct _i2s_tor
{
/* Bit 0 is read this bit to clear TX FIFO data overrun interrupt
* 0x0 for TX FIFO write valid,
*0x1 for TX FIFO write overrun
*/
uint32_t txcho : 1;
/* Bits [31:1] is reserved */
uint32_t resv : 31;
} __attribute__((packed, aligned(4))) i2s_tor_t;
typedef union _tor_u
{
i2s_tor_t tor;
uint32_t reg_data;
} tor_t;
typedef struct _i2s_rfcr
{
/* Bits [3:0] is used program the trigger level in the RX FIFO at
* which the receiver data available interrupt generate,
* 0x0 for interrupt trigger when FIFO level is 1,
* 0x2 for interrupt trigger when FIFO level is 2,
* 0x3 for interrupt trigger when FIFO level is 4,
* 0x4 for interrupt trigger when FIFO level is 5,
* 0x5 for interrupt trigger when FIFO level is 6,
* 0x6 for interrupt trigger when FIFO level is 7,
* 0x7 for interrupt trigger when FIFO level is 8,
* 0x8 for interrupt trigger when FIFO level is 9,
* 0x9 for interrupt trigger when FIFO level is 10,
* 0xa for interrupt trigger when FIFO level is 11,
* 0xb for interrupt trigger when FIFO level is 12,
* 0xc for interrupt trigger when FIFO level is 13,
* 0xd for interrupt trigger when FIFO level is 14,
* 0xe for interrupt trigger when FIFO level is 15,
* 0xf for interrupt trigger when FIFO level is 16
*/
uint32_t rxchdt : 4;
/* Bits [31:4] is reserved */
uint32_t rsvd_rfcrx : 28;
} __attribute__((packed, aligned(4))) i2s_rfcr_t;
typedef union _rfcr_u
{
i2s_rfcr_t rfcr;
uint32_t reg_data;
} rfcr_t;
typedef struct _i2s_tfcr
{
/* Bits [3:0] is used program the trigger level in the TX FIFO at
* which the receiver data available interrupt generate,
* 0x0 for interrupt trigger when FIFO level is 1,
* 0x2 for interrupt trigger when FIFO level is 2,
* 0x3 for interrupt trigger when FIFO level is 4,
* 0x4 for interrupt trigger when FIFO level is 5,
* 0x5 for interrupt trigger when FIFO level is 6,
* 0x6 for interrupt trigger when FIFO level is 7,
* 0x7 for interrupt trigger when FIFO level is 8,
* 0x8 for interrupt trigger when FIFO level is 9,
* 0x9 for interrupt trigger when FIFO level is 10,
* 0xa for interrupt trigger when FIFO level is 11,
* 0xb for interrupt trigger when FIFO level is 12,
* 0xc for interrupt trigger when FIFO level is 13,
* 0xd for interrupt trigger when FIFO level is 14,
* 0xe for interrupt trigger when FIFO level is 15,
* 0xf for interrupt trigger when FIFO level is 16
*/
uint32_t txchet : 4;
/* Bits [31:4] is reserved */
uint32_t rsvd_tfcrx : 28;
} __attribute__((packed, aligned(4))) i2s_tfcr_t;
typedef union _tfcr_u
{
i2s_tfcr_t tfcr;
uint32_t reg_data;
} tfcr_t;
typedef struct _i2s_rff
{
/* Bit 0 is receiver channel FIFO reset,
* 0x0 for does not flush an individual RX FIFO,
* 0x1 for flush an indiviadual RX FIFO
*/
uint32_t rxchfr : 1;
/*< Bits [31:1] is reserved ,write only */
uint32_t rsvd_rffx : 31;
} __attribute__((packed, aligned(4))) i2s_rff_t;
typedef union _rff_u
{
i2s_rff_t rff;
uint32_t reg_data;
} rff_t;
typedef struct _i2s_tff
{
/* Bit 0 is transmit channel FIFO reset,
* 0x0 for does not flush an individual TX FIFO,
* 0x1 for flush an indiviadual TX FIFO
*/
uint32_t rtxchfr : 1;
/*< Bits [31:1] is reserved ,write only */
uint32_t rsvd_rffx : 31;
} __attribute__((packed, aligned(4))) i2s_tff_t;
typedef union tff_u
{
i2s_tff_t tff;
uint32_t reg_data;
} tff_t;
typedef struct _i2s_channel
{
/* Left Receive or Left Transmit Register (0x20) */
volatile uint32_t left_rxtx;
/* Right Receive or Right Transmit Register (0x24) */
volatile uint32_t right_rxtx;
/* Receive Enable Register (0x28) */
volatile uint32_t rer;
/* Transmit Enable Register (0x2c) */
volatile uint32_t ter;
/* Receive Configuration Register (0x30) */
volatile uint32_t rcr;
/* Transmit Configuration Register (0x34) */
volatile uint32_t tcr;
/* Interrupt Status Register (0x38) */
volatile uint32_t isr;
/* Interrupt Mask Register (0x3c) */
volatile uint32_t imr;
/* Receive Overrun Register (0x40) */
volatile uint32_t ror;
/* Transmit Overrun Register (0x44) */
volatile uint32_t tor;
/* Receive FIFO Configuration Register (0x48) */
volatile uint32_t rfcr;
/* Transmit FIFO Configuration Register (0x4c) */
volatile uint32_t tfcr;
/* Receive FIFO Flush Register (0x50) */
volatile uint32_t rff;
/* Transmit FIFO Flush Register (0x54) */
volatile uint32_t tff;
/* reserved (0x58-0x5c) */
volatile uint32_t reserved1[2];
} __attribute__((packed, aligned(4))) i2s_channel_t;
/****is* i2s.api/dw_i2s_portmap
* NAME
* i2s_t
* DESCRIPTION
* This is the structure used for accessing the i2s register
* portmap.
* EXAMPLE
* struct i2s_t *portmap;
* portmap = (struct dw_i2s_portmap *) DW_APB_I2S_BASE;
* SOURCE
*/
typedef struct _i2s
{
/* I2S Enable Register (0x00) */
volatile uint32_t ier;
/* I2S Receiver Block Enable Register (0x04) */
volatile uint32_t irer;
/* I2S Transmitter Block Enable Register (0x08) */
volatile uint32_t iter;
/* Clock Enable Register (0x0c) */
volatile uint32_t cer;
/* Clock Configuration Register (0x10) */
volatile uint32_t ccr;
/* Receiver Block FIFO Reset Register (0x04) */
volatile uint32_t rxffr;
/* Transmitter Block FIFO Reset Register (0x18) */
volatile uint32_t txffr;
/* reserved (0x1c) */
volatile uint32_t reserved1;
volatile i2s_channel_t channel[4];
/* reserved (0x118-0x1bc) */
volatile uint32_t reserved2[40];
/* Receiver Block DMA Register (0x1c0) */
volatile uint32_t rxdma;
/* Reset Receiver Block DMA Register (0x1c4) */
volatile uint32_t rrxdma;
/* Transmitter Block DMA Register (0x1c8) */
volatile uint32_t txdma;
/* Reset Transmitter Block DMA Register (0x1cc) */
volatile uint32_t rtxdma;
/* reserved (0x1d0-0x1ec) */
volatile uint32_t reserved3[8];
/* Component Parameter Register 2 (0x1f0) */
volatile uint32_t i2s_comp_param_2;
/* Component Parameter Register 1 (0x1f4) */
volatile uint32_t i2s_comp_param_1;
/* I2S Component Version Register (0x1f8) */
volatile uint32_t i2s_comp_version_1;
/* I2S Component Type Register (0x1fc) */
volatile uint32_t i2s_comp_type;
} __attribute__((packed, aligned(4))) i2s_t;
typedef enum _i2s_transfer_mode
{
I2S_SEND,
I2S_RECEIVE,
} i2s_transfer_mode_t;
typedef struct _i2s_data_t
{
dmac_channel_number_t tx_channel;
dmac_channel_number_t rx_channel;
uint32_t *tx_buf;
size_t tx_len;
uint32_t *rx_buf;
size_t rx_len;
i2s_transfer_mode_t transfer_mode;
bool nowait_dma_idle;
bool wait_dma_done;
} i2s_data_t;
/**
* @brief I2S object instance
*/
extern volatile i2s_t *const i2s[3];
/**
* @brief I2s init
*
* @param[in] device_num The device number
* @param[in] rxtx_mode I2s work mode
* @param[in] channel_mask Channel mask to which channel work
*
*/
void i2s_init(i2s_device_number_t device_num, i2s_transmit_t rxtx_mode, uint32_t channel_mask);
/**
* @brief Read pcm data from dma
*
* @param[in] device_num which of device
* @param[in] buf save read data
* @param[in] buf_len the length to read form i2s
* @param[in] channel_num The dma channel number
*
* @return result
* - 0 Success
* - Other Fail
*/
void i2s_receive_data_dma(i2s_device_number_t device_num, uint32_t *buf, size_t buf_len,
dmac_channel_number_t channel_num);
/**
* @brief Write pcm data to channel_num channel by dma, first wait dmac done
*
* @param[in] device_num which of device
* @param[in] pcm Send data
* @param[in] buf_len Send data length
* @param[in] channel_num dmac channel
*
*/
void i2s_send_data_dma(i2s_device_number_t device_num, const void *buf, size_t buf_len, dmac_channel_number_t channel_num);
/**
* @brief I2S receive channel configure
*
* @param[in] device_num The device number
* @param[in] channel_num The channel number
* @param[in] word_length The word length
* @param[in] word_select_size The word select size
* @param[in] trigger_level The trigger level
*/
void i2s_rx_channel_config(i2s_device_number_t device_num,
i2s_channel_num_t channel_num,
i2s_word_length_t word_length,
i2s_word_select_cycles_t word_select_size,
i2s_fifo_threshold_t trigger_level,
i2s_work_mode_t word_mode);
/**
* @brief I2S transmit channel enable
*
* @param[in] device_num The device number
* @param[in] channel_num The channel number
* @param[in] word_length The word length
* @param[in] word_select_size The word select size
* @param[in] trigger_level The trigger level
*/
void i2s_tx_channel_config(i2s_device_number_t device_num,
i2s_channel_num_t channel_num,
i2s_word_length_t word_length,
i2s_word_select_cycles_t word_select_size,
i2s_fifo_threshold_t trigger_level,
i2s_work_mode_t word_mode);
/**
* @brief Play PCM format audio
*
* @param[in] device_num The device number
* @param[in] channel_num The channel number
* @param[in] buf PCM data
* @param[in] buf_len PCM data length
* @param[in] frame Transmit amount once
* @param[in] bits_per_sample Sample bit length
* @param[in] track_num Track amount
*/
void i2s_play(i2s_device_number_t device_num, dmac_channel_number_t channel_num,
const uint8_t *buf, size_t buf_len, size_t frame, size_t bits_per_sample, uint8_t track_num);
/**
* @brief Play PCM format audio
*
* @param[in] device_num The device number
* @param[in] sample_rate The Sample rate
*
*
* @return The real sample rate
*/
uint32_t i2s_set_sample_rate(i2s_device_number_t device_num, uint32_t sample_rate);
/**
* @brief Set dma_divide_16 split 32bit data to two 16 bit data and filled in left
* and right channel. Used with dma_tx_en or dma_rx_en
*
* @param[in] device_num The device number
* @param[in] enable The value of dma_divide_16 0:disable 1:enable
*
* @return result
* - 0 Success
* - Other Fail
*/
int i2s_set_dma_divide_16(i2s_device_number_t device_num, uint32_t enable);
/**
* @brief Get dma_divide_16.
*
* @param[in] device_num The device number
*
* @return result
* - <0 Fail
* - other value of dma_divide_16
*/
int i2s_get_dma_divide_16(i2s_device_number_t device_num);
/**
* @brief I2s handle transfer data operations
*
* @param[in] device_num I2s device number
* @param[in] data I2s data information
* @param[in] cb I2s dma callback
*
*/
void i2s_handle_data_dma(i2s_device_number_t device_num, i2s_data_t data, plic_interrupt_t *cb);
#ifdef __cplusplus
}
#endif
#endif