Docker-Build mit gcc-arm-none-eabi 4.9-2014q4 (statt Homebrew-Cask) verwendet, Dockerfile/tools/docker.sh dafür aus Task 13 vorgezogen. cmake/sdk.cmake schont gcc 4.9 (kennt -fcommon/-Wno-error=... nicht). Zwei zusätzliche SDK-Stubs (EarlyInit, pre_gpio_config) in src/sys/sdk_stubs.c ergänzt, siehe sdk/PATCHES.md.
585 lines
15 KiB
C
585 lines
15 KiB
C
/**************************************************************************//**
|
|
* @file wm_i2s.c
|
|
* @author
|
|
* @version
|
|
* @date
|
|
* @brief
|
|
*
|
|
* Copyright (c) 2014 Winner Microelectronics Co., Ltd. All rights reserved.
|
|
*****************************************************************************/
|
|
|
|
#define TLS_CONFIG_I2S 1
|
|
|
|
#if TLS_CONFIG_I2S
|
|
|
|
#include "wm_i2s.h"
|
|
#include "string.h"
|
|
#include "wm_debug.h"
|
|
#include "wm_irq.h"
|
|
#include "wm_config.h"
|
|
#include "wm_mem.h"
|
|
|
|
#define I2S_CLK (160000000)
|
|
|
|
#define WM_I2S_FIFO_LEN (8)
|
|
static tls_i2s_port_t tls_i2s_port;
|
|
|
|
static void tls_i2s_fill_txfifo(void);
|
|
|
|
/**
|
|
* @brief This function is used to initial i2s port.
|
|
* @param[in] opts the i2s setting options,if this param is NULL,this function will use the default options.
|
|
* @retval
|
|
* - \ref WM_SUCCESS
|
|
* - \ref WM_FAILED
|
|
*
|
|
*/
|
|
int tls_i2s_port_init(tls_i2s_options_t *opts)
|
|
{
|
|
tls_i2s_options_t opt;
|
|
|
|
tls_i2s_port.regs = I2S;
|
|
|
|
if(NULL == opts)
|
|
{
|
|
memset(&opt, 0, sizeof(tls_i2s_options_t));
|
|
opt.data_width = I2S_CTRL_DATABIT_16;
|
|
opt.format = I2S_CTRL_FORMAT_I2S;
|
|
opt.stereo_mono = I2S_CTRL_STERO;
|
|
opt.sample_rate = 8000;
|
|
opt.tx_en = 1;
|
|
tls_i2s_config(&opt);
|
|
}
|
|
else
|
|
{
|
|
tls_i2s_config(opts);
|
|
}
|
|
/* enable i2s interrupt */
|
|
NVIC_ClearPendingIRQ(I2S_IRQn);
|
|
tls_irq_enable(I2S_INT);
|
|
|
|
return WM_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
* @brief This function is used to initial i2s port.
|
|
* @param[in] opts the i2s setting options,if this param is NULL,this function will use the default options.
|
|
*
|
|
* @retval
|
|
*
|
|
* @note
|
|
*/
|
|
void tls_i2s_config(tls_i2s_options_t *opts)
|
|
{
|
|
tls_i2s_port.regs->CTRL &= ~(I2S_CTRL_FORMAT_MASK | \
|
|
I2S_CTRL_DATABIT_MASK | \
|
|
I2S_CTRL_STEREO_MONO_MASK);
|
|
tls_i2s_port.regs->CTRL = opts->data_width | opts->format | opts->stereo_mono;
|
|
if (opts->rx_en)
|
|
{
|
|
TLS_I2S_RX_ENABLE();
|
|
TLS_I2S_RX_FIFO_CLEAR();
|
|
}
|
|
if (opts->tx_en)
|
|
{
|
|
TLS_I2S_TX_ENABLE();
|
|
TLS_I2S_TX_FIFO_CLEAR();
|
|
}
|
|
tls_i2s_set_freq(opts->sample_rate);
|
|
}
|
|
|
|
/**
|
|
* @brief
|
|
* set the frequency of the i2s port.
|
|
*
|
|
* @param[in] freq
|
|
* the required frequency of the i2s module
|
|
*
|
|
* @retval
|
|
*
|
|
*/
|
|
void tls_i2s_set_freq(uint32_t freq)
|
|
{
|
|
uint32_t div;
|
|
uint32_t reg;
|
|
uint8_t width, stereo;
|
|
|
|
reg = I2S->CTRL;
|
|
width = (((reg>>4)&0x03)+1)<<3;
|
|
stereo = tls_bitband_read(HR_I2S_CTRL, I2S_CTRL_STEREO_MONO_Pos) ? 1:2;
|
|
div = (I2S_CLK + freq * width * stereo)/(freq * width * stereo) - 1;
|
|
|
|
*(volatile uint32_t *)HR_CLK_I2S_CTL &= ~0xFF00;
|
|
*(volatile uint32_t *)HR_CLK_I2S_CTL |= (uint32_t)div<<8;
|
|
}
|
|
|
|
/**
|
|
* @brief
|
|
* set the frequency of the i2s port.
|
|
*
|
|
* @param[in] freq
|
|
* the required frequency of the i2s module
|
|
* @param[in] exclk
|
|
* the frequency of the ext clock
|
|
*
|
|
* @retval
|
|
*
|
|
* @note
|
|
* this function will be called after tls_i2s_port_init function
|
|
*/
|
|
void wm_i2s_set_freq_exclk(uint32_t freq, uint32_t exclk)
|
|
{
|
|
uint32_t div;
|
|
uint32_t temp;
|
|
uint8_t wdwidth, stereo;
|
|
temp = I2S->CTRL;
|
|
wdwidth = (((temp>>4)&0x03)+1)<<3;
|
|
stereo = tls_bitband_read(HR_I2S_CTRL, 22) ? 1:2;
|
|
div = (exclk * 2 + freq * wdwidth * stereo)/(2* freq * wdwidth * stereo) - 1;
|
|
*(volatile uint32_t *)0x40000718 &= ~0x3FF00;
|
|
*(volatile uint32_t *)0x40000718 |= (uint32_t)div<<8;
|
|
*(volatile uint32_t *)0x40000718 |= 0x01;
|
|
}
|
|
void I2S_IRQHandler(void)
|
|
{
|
|
uint8_t rx_fifocnt;
|
|
|
|
/** LZC */
|
|
if (tls_bitband_read(HR_I2S_INT_SRC, I2S_FLAG_LZC_Pos) && !tls_bitband_read(HR_I2S_INT_MASK, I2S_FLAG_LZC_Pos))
|
|
{
|
|
tls_reg_write32(HR_I2S_INT_SRC, I2S_FLAG_LZC);
|
|
}
|
|
/** RZC */
|
|
if (tls_bitband_read(HR_I2S_INT_SRC, I2S_FLAG_RZC_Pos) && !tls_bitband_read(HR_I2S_INT_MASK, I2S_FLAG_RZC_Pos))
|
|
{
|
|
tls_reg_write32(HR_I2S_INT_SRC, I2S_FLAG_RZC);
|
|
}
|
|
/** Tx Done*/
|
|
if (tls_bitband_read(HR_I2S_INT_SRC, I2S_FLAG_TXDONE_Pos) && !tls_bitband_read(HR_I2S_INT_MASK, I2S_FLAG_TXDONE_Pos))
|
|
{
|
|
tls_reg_write32(HR_I2S_INT_SRC, I2S_FLAG_TXDONE);
|
|
}
|
|
/** TxTH*/
|
|
if (tls_bitband_read(HR_I2S_INT_SRC, I2S_FLAG_TXTH_Pos)&& !tls_bitband_read(HR_I2S_INT_MASK, I2S_FLAG_TXTH_Pos))
|
|
{
|
|
tls_reg_write32(HR_I2S_INT_SRC, I2S_FLAG_TXTH);
|
|
tls_i2s_fill_txfifo();
|
|
}
|
|
/** TXOV*/
|
|
if (tls_bitband_read(HR_I2S_INT_SRC, I2S_FLAG_TXOV_Pos) && !tls_bitband_read(HR_I2S_INT_MASK, I2S_FLAG_TXOV_Pos))
|
|
{
|
|
tls_reg_write32(HR_I2S_INT_SRC, I2S_FLAG_TXOV);
|
|
}
|
|
/** TXUD*/
|
|
if (tls_bitband_read(HR_I2S_INT_SRC, I2S_FLAG_TXUD_Pos) && !tls_bitband_read(HR_I2S_INT_MASK, I2S_FLAG_TXUD_Pos))
|
|
{
|
|
tls_reg_write32(HR_I2S_INT_SRC, I2S_FLAG_TXUD);
|
|
}
|
|
/** Rx Done*/
|
|
if (tls_bitband_read(HR_I2S_INT_SRC, I2S_FLAG_RXDONE_Pos) && !tls_bitband_read(HR_I2S_INT_MASK, I2S_FLAG_RXDONE_Pos))
|
|
{
|
|
tls_reg_write32(HR_I2S_INT_SRC, I2S_FLAG_RXDONE);
|
|
}
|
|
/** RxTH */
|
|
if (tls_bitband_read(HR_I2S_INT_SRC, I2S_FLAG_RXTH_Pos)&& !tls_bitband_read(HR_I2S_INT_MASK, I2S_FLAG_RXTH_Pos))
|
|
{
|
|
tls_reg_write32(HR_I2S_INT_SRC, I2S_FLAG_RXTH);
|
|
rx_fifocnt = tls_i2s_port.regs->INT_STATUS & I2S_RX_FIFO_CNT_MASK;
|
|
if (tls_i2s_port.rx_buf.buf != NULL)
|
|
{
|
|
while(rx_fifocnt-- > 0)
|
|
{
|
|
tls_i2s_port.rx_buf.buf[tls_i2s_port.rx_buf.index] = tls_i2s_port.regs->RX;
|
|
tls_i2s_port.rx_buf.index++;
|
|
}
|
|
if (tls_i2s_port.rx_buf.index >= (tls_i2s_port.rx_buf.len))
|
|
{
|
|
tls_i2s_port.rx_buf.buf = NULL;
|
|
tls_i2s_int_config(I2S_INT_MASK_RXTH, 0);
|
|
if (tls_i2s_port.rx_callback != NULL)
|
|
{
|
|
tls_i2s_port.rx_callback(tls_i2s_port.rx_buf.len);
|
|
}
|
|
tls_i2s_port.rx_buf.index = 0;
|
|
}
|
|
}
|
|
|
|
}
|
|
/** RXOV*/
|
|
if (tls_bitband_read(HR_I2S_INT_SRC, I2S_FLAG_RXOV_Pos) && !tls_bitband_read(HR_I2S_INT_MASK, I2S_FLAG_RXOV_Pos))
|
|
{
|
|
tls_reg_write32(HR_I2S_INT_SRC, I2S_FLAG_RXOV);
|
|
}
|
|
/** RXUD*/
|
|
if (tls_bitband_read(HR_I2S_INT_SRC, I2S_FLAG_RXUD_Pos) && !tls_bitband_read(HR_I2S_INT_MASK, I2S_FLAG_RXUD_Pos))
|
|
{
|
|
tls_reg_write32(HR_I2S_INT_SRC, I2S_FLAG_RXUD);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief
|
|
* This function is used to register i2s rx interrupt.
|
|
*
|
|
* @param[in] rx_callback
|
|
* is the i2s interrupt call back function.
|
|
*
|
|
* @retval
|
|
*
|
|
*/
|
|
|
|
void tls_i2s_rx_register( void (*rx_callback)(u16 len))
|
|
{
|
|
tls_i2s_port.rx_callback = rx_callback;
|
|
}
|
|
|
|
/**
|
|
* @brief
|
|
* This function is used to register i2s tx interrupt.
|
|
*
|
|
* @param[in] tx_callback
|
|
* is the i2s interrupt call back function.
|
|
*
|
|
* @retval
|
|
*
|
|
*/
|
|
void tls_i2s_tx_register(void (* tx_callback)(u16 len))
|
|
{
|
|
tls_i2s_port.tx_callback = tx_callback;
|
|
}
|
|
|
|
static void tls_i2s_fill_txfifo()
|
|
{
|
|
s8 fifo_left = 0;
|
|
|
|
if (tls_i2s_port.tx_buf.index < tls_i2s_port.tx_buf.len)
|
|
{
|
|
fifo_left = I2S_MAX_RXTXFIFO_LEVEL - ((tls_i2s_port.regs->INT_STATUS & I2S_TX_FIFO_CNT_MASK)>>4);
|
|
while (fifo_left--)
|
|
{
|
|
tls_i2s_port.regs->TX = *(uint32_t *)(tls_i2s_port.tx_buf.buf + tls_i2s_port.tx_buf.index);
|
|
tls_i2s_port.tx_buf.index ++;
|
|
}
|
|
if(tls_i2s_port.tx_buf.index >= tls_i2s_port.tx_buf.len)
|
|
{
|
|
while((tls_i2s_port.regs->INT_STATUS & I2S_TX_FIFO_CNT_MASK)>>4);
|
|
if(tls_i2s_port.tx_sem)
|
|
{
|
|
memset(&tls_i2s_port.tx_buf, 0, sizeof(tls_i2s_buf));
|
|
tls_os_sem_release(tls_i2s_port.tx_sem);
|
|
return;
|
|
}
|
|
if (tls_i2s_port.tx_callback)
|
|
{
|
|
tls_i2s_port.tx_callback(tls_i2s_port.tx_buf.len);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief
|
|
* This function is used to transfer data in blocking mode.
|
|
*
|
|
* @param[in] buf
|
|
* pointer to the transfering data.
|
|
*
|
|
* @param[in] len
|
|
* is the data length.
|
|
*
|
|
* @retval
|
|
*
|
|
*/
|
|
int tls_i2s_tx_block(uint32_t *buf, uint16_t len)
|
|
{
|
|
uint8_t err;
|
|
|
|
|
|
err = tls_os_sem_create(&tls_i2s_port.tx_sem, 0);
|
|
if (err != TLS_OS_SUCCESS)
|
|
{
|
|
TLS_DBGPRT_ERR("\ni2s tx sem create fail\n");
|
|
return WM_FAILED;
|
|
}
|
|
TLS_I2S_TX_FIFO_CLEAR();
|
|
tls_reg_write32(HR_I2S_INT_SRC, 0x1FF);
|
|
NVIC_ClearPendingIRQ(I2S_IRQn);
|
|
|
|
tls_i2s_port.tx_buf.buf = buf;
|
|
tls_i2s_port.tx_buf.len = len;
|
|
tls_i2s_port.tx_buf.index = 0;
|
|
|
|
tls_i2s_set_txth(5);
|
|
tls_i2s_int_config(I2S_INT_MASK_TXTH, 1);
|
|
TLS_I2S_TX_ENABLE();
|
|
TLS_I2S_ENABLE();
|
|
|
|
tls_os_sem_acquire(tls_i2s_port.tx_sem, 0);
|
|
tls_os_sem_delete(tls_i2s_port.tx_sem);
|
|
tls_i2s_port.tx_sem = NULL;
|
|
TLS_I2S_TX_DISABLE();
|
|
|
|
return WM_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
* @brief
|
|
* This function is used to transfer data in non blocking mode.
|
|
*
|
|
* @param[in] buf
|
|
* is a buf for user data.
|
|
*
|
|
* @param[in] len
|
|
* is the data length.
|
|
*
|
|
* @param[in] tx_callback
|
|
* a function pointer,which will be called when the designated data sent
|
|
*
|
|
* @retval
|
|
*
|
|
* @note the \ref len in words
|
|
*/
|
|
int tls_i2s_tx_nonblock(uint32_t *buf, uint16_t len, void (*tx_callback)(u16 len))
|
|
{
|
|
tls_i2s_port.tx_buf.buf = (uint32_t *)buf;
|
|
tls_i2s_port.tx_buf.len = len;
|
|
tls_i2s_port.tx_buf.index = 0;
|
|
|
|
tls_i2s_set_txth(5);
|
|
tls_i2s_int_config(I2S_INT_MASK_TXTH, 1);
|
|
tls_i2s_tx_register( tx_callback);
|
|
|
|
TLS_I2S_TX_FIFO_CLEAR();
|
|
TLS_I2S_TX_ENABLE();
|
|
TLS_I2S_ENABLE();
|
|
return WM_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
* @brief
|
|
* This function is used to receiver data in non blocking mode.
|
|
*
|
|
* @param[in] buf
|
|
* the buffer for storing the received data.
|
|
*
|
|
* @param[in] len
|
|
* the length of the data will be receiving
|
|
*
|
|
* @param[in] rx_callback
|
|
* a function pointer,which will be called when the demanded data have been received
|
|
*
|
|
* @retval
|
|
*
|
|
*/
|
|
int tls_i2s_rx_nonblock(uint32_t *buf, uint16_t len, void (*rx_callback)(u16 len))
|
|
{
|
|
tls_i2s_port.rx_buf.buf = buf;
|
|
tls_i2s_port.rx_buf.len = len;
|
|
tls_i2s_port.rx_buf.index = 0;
|
|
|
|
tls_i2s_set_rxth(5);
|
|
tls_i2s_int_config(I2S_INT_MASK_RXTH, 1);
|
|
tls_i2s_rx_register( rx_callback);
|
|
|
|
TLS_I2S_RX_FIFO_CLEAR();
|
|
NVIC_ClearPendingIRQ(I2S_IRQn);
|
|
TLS_I2S_RX_ENABLE();
|
|
TLS_I2S_ENABLE();
|
|
|
|
return WM_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
* @brief
|
|
* This function is used to the tx DMA configuration of the I2S module.
|
|
*
|
|
* @param[in] dma_channel
|
|
* the free dma channel number which returned by calling function tls_dma_request()
|
|
*
|
|
* @param[in] addr
|
|
* point to the data buffer will be sent
|
|
*
|
|
* @param[in] len
|
|
* length of the data to be transfered in bytes
|
|
*
|
|
* @retval
|
|
*/
|
|
void tls_i2s_tx_dma_config(uint8_t dma_channel, uint32_t * addr, uint16_t len)
|
|
{
|
|
|
|
struct tls_dma_descriptor DmaDesc;
|
|
|
|
TLS_I2S_TX_DISABLE();
|
|
TLS_I2S_TX_FIFO_CLEAR();
|
|
/** Mask i2s txth interrupt*/
|
|
tls_i2s_set_txth(4);
|
|
tls_i2s_int_config(I2S_INT_MASK_TXTH, 0);
|
|
DmaDesc.src_addr = (unsigned int) addr;
|
|
DmaDesc.dest_addr = (unsigned int)HR_I2S_TX;
|
|
|
|
DmaDesc.dma_ctrl = TLS_DMA_DESC_CTRL_SRC_ADD_INC | TLS_DMA_DESC_CTRL_DATA_SIZE_WORD |
|
|
(len << 7);
|
|
DmaDesc.valid = TLS_DMA_DESC_VALID;
|
|
DmaDesc.next = NULL;
|
|
tls_dma_start(dma_channel, &DmaDesc, 0);
|
|
|
|
}
|
|
|
|
/**
|
|
* @brief
|
|
* datas transmit throuth DMA
|
|
*
|
|
* @param[in] addr
|
|
* point to the data buffer will be sent
|
|
* @param[in] len
|
|
* length of the data to be transfered in bytes
|
|
* @param[in] callback
|
|
* the callback function when datas transfer finished
|
|
*
|
|
* @retval
|
|
*
|
|
* @note the \ref len in bytes
|
|
*/
|
|
int tls_i2s_tx_dma(uint32_t * addr, uint16_t len, tls_i2s_callback callback)
|
|
{
|
|
uint8_t tx_channel;
|
|
|
|
TLS_I2S_TX_FIFO_CLEAR();
|
|
tls_reg_write32(HR_I2S_INT_SRC, 0x1FF);
|
|
NVIC_ClearPendingIRQ(I2S_IRQn);
|
|
|
|
TLS_I2S_TX_FIFO_CLEAR();
|
|
|
|
tx_channel = tls_dma_request(WM_I2S_TX_DMA_CHANNEL, TLS_DMA_FLAGS_CHANNEL_SEL(TLS_DMA_SEL_I2S_TX) | TLS_DMA_FLAGS_HARD_MODE);
|
|
if (tx_channel == 0)
|
|
{
|
|
return WM_FAILED;
|
|
}
|
|
if (tls_dma_stop(tx_channel))
|
|
{
|
|
return WM_FAILED;
|
|
}
|
|
tls_i2s_tx_dma_config(tx_channel, addr, len);
|
|
tls_dma_irq_register(tx_channel, callback, NULL, TLS_DMA_IRQ_TRANSFER_DONE);
|
|
TLS_I2S_TXDMA_ENABLE();
|
|
TLS_I2S_TX_ENABLE();
|
|
TLS_I2S_ENABLE();
|
|
|
|
return WM_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
* @brief
|
|
* This function is used to the rx DMA configuration of the I2S module.
|
|
*
|
|
* @param[in] addr
|
|
* point to the storge buffer of the received data
|
|
*
|
|
* @param[in] len
|
|
* the storge buffer length in bytes
|
|
*
|
|
* @retval
|
|
*/
|
|
void tls_i2s_rx_dma_config(uint8_t dma_channel, uint32_t * addr, uint16_t len)
|
|
{
|
|
|
|
struct tls_dma_descriptor DmaDesc;
|
|
|
|
tls_i2s_int_config(I2S_INT_MASK_RXTH, 0);
|
|
TLS_I2S_RX_DISABLE();
|
|
TLS_I2S_RXDMA_DISABLE();
|
|
TLS_I2S_RX_FIFO_CLEAR();
|
|
/** Mask i2s rxth interrupt*/
|
|
tls_i2s_set_rxth(4);
|
|
|
|
tls_i2s_int_config(I2S_INT_MASK_RXTH, 0);
|
|
DmaDesc.src_addr = (int)HR_I2S_RX;
|
|
DmaDesc.dest_addr = (int)addr;
|
|
|
|
DmaDesc.dma_ctrl = TLS_DMA_DESC_CTRL_DEST_ADD_INC | TLS_DMA_DESC_CTRL_DATA_SIZE_WORD |
|
|
(len << 7);
|
|
DmaDesc.valid = TLS_DMA_DESC_VALID;
|
|
DmaDesc.next = NULL;
|
|
tls_dma_start(dma_channel, &DmaDesc, 0);
|
|
}
|
|
|
|
int tls_i2s_rx_dma(uint32_t * addr, uint16_t len, tls_i2s_callback callback)
|
|
{
|
|
uint8_t rx_channel;
|
|
|
|
rx_channel = tls_dma_request(WM_I2S_RX_DMA_CHANNEL, TLS_DMA_FLAGS_CHANNEL_SEL(TLS_DMA_SEL_I2S_RX) | TLS_DMA_FLAGS_HARD_MODE);
|
|
if (rx_channel == 0)
|
|
{
|
|
return WM_FAILED;
|
|
}
|
|
if (tls_dma_stop(rx_channel))
|
|
{
|
|
return WM_FAILED;
|
|
}
|
|
tls_i2s_rx_dma_config(rx_channel, addr, len);
|
|
tls_dma_irq_register(rx_channel, callback, NULL, TLS_DMA_IRQ_TRANSFER_DONE);
|
|
TLS_I2S_RXDMA_ENABLE();
|
|
NVIC_ClearPendingIRQ(I2S_IRQn);
|
|
TLS_I2S_RX_ENABLE();
|
|
TLS_I2S_ENABLE();
|
|
|
|
return WM_SUCCESS;
|
|
}
|
|
#if 1
|
|
uint8_t tst_flag = 0;
|
|
|
|
void tls_i2s_tx_dma_callback()
|
|
{
|
|
I2S->TX = 0x00;
|
|
while(!tls_bitband_read(HR_I2S_INT_SRC, 7));
|
|
TLS_I2S_TX_DISABLE();
|
|
DMA_CHNLCTRL_REG(WM_I2S_TX_DMA_CHANNEL) |= DMA_CHNL_CTRL_CHNL_OFF;
|
|
tls_dma_free(WM_I2S_TX_DMA_CHANNEL);
|
|
tst_flag = 1;
|
|
}
|
|
void tls_i2s_rx_dma_callback()
|
|
{
|
|
TLS_I2S_RX_DISABLE();
|
|
DMA_CHNLCTRL_REG(WM_I2S_RX_DMA_CHANNEL) |= DMA_CHNL_CTRL_CHNL_OFF;
|
|
tls_dma_free(WM_I2S_RX_DMA_CHANNEL);
|
|
tst_flag = 1;
|
|
}
|
|
void tls_i2s_rx_callback()
|
|
{
|
|
TLS_I2S_RX_DISABLE();
|
|
tst_flag = 1;
|
|
}
|
|
void tls_i2s_test()
|
|
{
|
|
uint32_t *ptr = NULL;
|
|
uint32_t len;
|
|
uint32_t * i2s_tx_test = tls_mem_alloc(1024);
|
|
tls_i2s_port.opts.data_width = I2S_CTRL_DATABIT_16;
|
|
tls_i2s_port.opts.format = I2S_CTRL_FORMAT_I2S;
|
|
tls_i2s_port.opts.tx_en = 1;
|
|
tls_i2s_port.opts.sample_rate = 8000;
|
|
tls_i2s_port.opts.stereo_mono = I2S_CTRL_STERO;
|
|
tls_i2s_port_init(&tls_i2s_port.opts);
|
|
if (i2s_tx_test == NULL)
|
|
{
|
|
return;
|
|
}
|
|
ptr = i2s_tx_test;
|
|
for (len = 0; len < 256; len++)
|
|
{
|
|
*ptr++ = 0xABCD0200 + len;
|
|
}
|
|
i2s_tx_test[255] = 0xABCD02FA;
|
|
tls_i2s_tx_dma(i2s_tx_test, 1024,tls_i2s_tx_dma_callback);
|
|
while(!tst_flag);
|
|
tst_flag = 0;
|
|
tls_i2s_tx_dma(i2s_tx_test, 1024,tls_i2s_tx_dma_callback);
|
|
while(!tst_flag);
|
|
tst_flag = 0;
|
|
}
|
|
#endif
|
|
#endif /** TLS_CONFIG_I2S */
|
|
|
|
|
|
/*** (C) COPYRIGHT 2014 Winner Microelectronics Co., Ltd. ***/
|