1000 lines
23 KiB
C
Raw Normal View History

2025-10-10 16:07:00 +08:00
// Copyright 2020-2021 Beken
//
// 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.
#include "cli.h"
#include <os/os.h>
#include <os/mem.h>
#include <os/str.h>
#include <driver/dma.h>
#include "sys_driver.h"
#include <driver/aud_dac_types.h>
#include <driver/aud_dac.h>
#include <driver/aud_adc_types.h>
#include <driver/aud_adc.h>
#include <driver/i2s.h>
#include <driver/i2s_types.h>
#include <driver/uart.h>
#include "gpio_driver.h"
//#define UART_DUMP_DEBUG
#define ADC_FRAME_SIZE (1280*4)
static dma_id_t adc_dma_id = 0;
static dma_id_t dac_dma_id = 0;
static uint8_t *adc_ringbuff_addr = NULL;
static uint8_t *dac_ringbuff_addr = NULL;
static RingBufferContext adc_rb;
static RingBufferContext dac_rb;
static uint16_t *adc_temp = NULL;
/*
aud_ate_test X1 X2 X3 X4
X1: test control
00: stop test
01: start test
X2: test mode
00: loop
01: adc (IIS OUT,master)
02: dac (IIS IN,master)
03: dac & adc (IIS IN,master)
X3:sample rate setting
1-9: 8K-48K
X4adc and dac mode
00: differential
01: single-ended
*/
static void cli_aud_ate_help(void)
{
os_printf("aud_ate_test {X1 X2 X3 X4} \r\n");
os_printf("X1: test control \n\r00: stop test\n\r01: start test \r\n");
os_printf("X2: test mode \n\r00: loop\n\r01: adc (IIS OUT,master)\n\r02: dac (IIS IN,master)\n\r03: dac & adc (IIS IN,master)\r\n");
os_printf("X3:sample rate setting \n\r1-9: 8K-48K \r\n");
os_printf("X4adc and dac mode \n\r00: differential\n\r01: single-ended \r\n");
}
/**
* @brief audio loop test
*
* @param mic_id test mic number
*
* @return none
*/
void audio_loop_test(uint32_t state)
{
aud_adc_config_t adc_config = DEFAULT_AUD_ADC_CONFIG();
aud_dac_config_t dac_config = DEFAULT_AUD_DAC_CONFIG();
if (state == 1) {
adc_config.adc_chl = AUD_ADC_CHL_LR;
adc_config.samp_rate = 16000;
adc_config.clk_src = AUD_CLK_XTAL;
dac_config.dac_chl = AUD_DAC_CHL_LR;
dac_config.samp_rate = 16000;
dac_config.clk_src = AUD_CLK_XTAL;
bk_aud_adc_init(&adc_config);
bk_aud_dac_init(&dac_config);
/* audio process test */
sys_drv_aud_dacg_set(0);
sys_drv_aud_mic1_gain_set(0);
sys_drv_aud_mic2_gain_set(0);
//disable audio interrupt when loop test
sys_drv_aud_int_en(0);
bk_aud_adc_disable_int();
//start adc
bk_aud_adc_start();
//start adc
bk_aud_dac_start();
//enable adc to dac loop test
bk_aud_adc_start_loop_test();
}else {
//disable adc and dac
bk_aud_adc_stop();
bk_aud_dac_stop();
//stop loop test
bk_aud_adc_stop_loop_test();
bk_aud_adc_deinit();
bk_aud_dac_deinit();
}
}
#ifdef UART_DUMP_DEBUG
static void uart_dump_mic_data(uart_id_t id, uint32_t baud_rate)
{
uart_config_t config = {0};
os_memset(&config, 0, sizeof(uart_config_t));
if (id == 0) {
gpio_dev_unmap(GPIO_10);
gpio_dev_map(GPIO_10, GPIO_DEV_UART1_RXD);
gpio_dev_unmap(GPIO_11);
gpio_dev_map(GPIO_11, GPIO_DEV_UART1_TXD);
} else if (id == 2) {
gpio_dev_unmap(GPIO_40);
gpio_dev_map(GPIO_40, GPIO_DEV_UART3_RXD);
gpio_dev_unmap(GPIO_41);
gpio_dev_map(GPIO_41, GPIO_DEV_UART3_TXD);
} else {
gpio_dev_unmap(GPIO_0);
gpio_dev_map(GPIO_0, GPIO_DEV_UART2_TXD);
gpio_dev_unmap(GPIO_1);
gpio_dev_map(GPIO_1, GPIO_DEV_UART2_RXD);
}
config.baud_rate = baud_rate;
config.data_bits = UART_DATA_8_BITS;
config.parity = UART_PARITY_NONE;
config.stop_bits = UART_STOP_BITS_1;
config.flow_ctrl = UART_FLOWCTRL_DISABLE;
config.src_clk = UART_SCLK_XTAL_26M;
if (bk_uart_init(id, &config) != BK_OK) {
os_printf("init uart fail \r\n");
} else {
os_printf("init uart ok \r\n");
}
}
#endif
/* 搬运audio adc 采集到的一帧mic和ref信号后触发中断通知AEC处理数据 */
static void audio_adc_dma_finish_isr(void)
{
// GPIO_UP(2);
/* read adc data from adc ringbuffer */
//os_printf("adc_rb fill size, size:%d \r\n", ring_buffer_get_fill_size(&adc_rb));
uint32_t size = ring_buffer_read(&adc_rb, (uint8_t*)adc_temp, ADC_FRAME_SIZE);
if (size != ADC_FRAME_SIZE) {
os_printf("read mic_ring_buff fail, size: %d, need: %d \r\n", size, ADC_FRAME_SIZE);
//return BK_FAIL;
} else {
//os_printf("read ok size: %d, need: %d \r\n", size, ADC_FRAME_SIZE);
}
/* select r channel data */
for (uint32_t i = 0; i < ADC_FRAME_SIZE/2; i++) {
adc_temp[i] = adc_temp[2*i+1];
}
#ifdef UART_DUMP_DEBUG
bk_uart_write_bytes(UART_ID_1, adc_temp, ADC_FRAME_SIZE/2);
#endif
size = ring_buffer_get_free_size(&dac_rb);
if (size >= ADC_FRAME_SIZE/2) {
ring_buffer_write(&dac_rb, (uint8_t *)adc_temp, ADC_FRAME_SIZE/2);
} else {
os_printf("dac_rb free size, size:%d \r\n", size);
}
// GPIO_DOWN(2);
}
void audio_adc_mic2_to_dac_test_start(void)
{
aud_adc_config_t adc_config = DEFAULT_AUD_ADC_CONFIG();
adc_config.adc_chl = AUD_ADC_CHL_LR;
adc_config.clk_src = AUD_CLK_XTAL;
adc_config.adc_gain = 0x15;
aud_dac_config_t dac_config = DEFAULT_AUD_DAC_CONFIG();
dac_config.clk_src = AUD_CLK_XTAL;
dac_config.dac_gain = 0x3f;
dma_config_t dma_config = {0};
dma_config_t dac_dma_config = {0};
uint32_t aud_adc_data_addr;
uint32_t aud_dac_data_addr;
bk_err_t ret = BK_OK;
#ifdef UART_DUMP_DEBUG
uart_dump_mic_data(1, 2000000);
#endif
bk_aud_adc_init(&adc_config);
//disable audio interrupt when loop test
sys_drv_aud_int_en(0);
bk_aud_adc_disable_int();
//start adc
// bk_aud_adc_start();
/* init dma driver */
ret = bk_dma_driver_init();
if (ret != BK_OK) {
os_printf("[%s]bk_dma_driver_init fail, line: %d \n", __func__, __LINE__);
return;
}
/* allocate free DMA channel */
adc_dma_id = bk_dma_alloc(DMA_DEV_AUDIO);
if ((adc_dma_id < DMA_ID_0) || (adc_dma_id >= DMA_ID_MAX)) {
os_printf("[%s]bk_dma_alloc fail, line: %d \n", __func__, __LINE__);
return;
}
dma_config.mode = DMA_WORK_MODE_REPEAT;
dma_config.chan_prio = 1;
dma_config.src.width = DMA_DATA_WIDTH_32BITS;
dma_config.dst.width = DMA_DATA_WIDTH_32BITS;
dma_config.src.addr_inc_en = DMA_ADDR_INC_ENABLE;
dma_config.src.addr_loop_en = DMA_ADDR_LOOP_ENABLE;
dma_config.dst.addr_inc_en = DMA_ADDR_INC_ENABLE;
dma_config.dst.addr_loop_en = DMA_ADDR_LOOP_ENABLE;
dma_config.trans_type = DMA_TRANS_DEFAULT;
/* get audio adc and dac fifo address */
bk_aud_adc_get_fifo_addr(&aud_adc_data_addr);
/* init ringbuff */
adc_ringbuff_addr = (uint8_t *)os_malloc(ADC_FRAME_SIZE*2);
ring_buffer_init(&adc_rb, adc_ringbuff_addr, ADC_FRAME_SIZE*2, adc_dma_id, RB_DMA_TYPE_WRITE);
adc_temp = (uint16_t *)os_malloc(ADC_FRAME_SIZE);
/* audio adc to dtcm by dma */
dma_config.src.dev = DMA_DEV_AUDIO_RX;
dma_config.dst.dev = DMA_DEV_DTCM;
dma_config.dst.start_addr = (uint32_t)adc_ringbuff_addr;
dma_config.dst.end_addr = (uint32_t)adc_ringbuff_addr + ADC_FRAME_SIZE*2;
dma_config.src.start_addr = aud_adc_data_addr;
dma_config.src.end_addr = aud_adc_data_addr + 4;
/* init dma channel */
ret = bk_dma_init(adc_dma_id, &dma_config);
if (ret != BK_OK) {
os_printf("[%s]bk_dma_init fail, line: %d \n", __func__, __LINE__);
return;
}
/* set dma transfer length */
bk_dma_set_transfer_len(adc_dma_id, ADC_FRAME_SIZE);
os_printf("adc ring_buff size: %d, dma transfer len: %d \n", ADC_FRAME_SIZE*2, ADC_FRAME_SIZE);
#if (CONFIG_SPE)
bk_dma_set_dest_sec_attr(adc_dma_id, DMA_ATTR_SEC);
bk_dma_set_src_sec_attr(adc_dma_id, DMA_ATTR_SEC);
#endif
//register isr
bk_dma_register_isr(adc_dma_id, NULL, (void *)audio_adc_dma_finish_isr);
bk_dma_enable_finish_interrupt(adc_dma_id);
/* dac config */
bk_aud_dac_init(&dac_config);
//disable audio interrupt when loop test
// bk_aud_dac_disable_int();
//start dac
// bk_aud_dac_start();
/* allocate free DMA channel */
dac_dma_id = bk_dma_alloc(DMA_DEV_AUDIO);
if ((dac_dma_id < DMA_ID_0) || (dac_dma_id >= DMA_ID_MAX)) {
os_printf("[%s]bk_dma_alloc fail, line: %d \n", __func__, __LINE__);
return;
}
dac_dma_config.mode = DMA_WORK_MODE_REPEAT;
dac_dma_config.chan_prio = 1;
dac_dma_config.src.width = DMA_DATA_WIDTH_32BITS;
dac_dma_config.dst.width = DMA_DATA_WIDTH_16BITS;
dac_dma_config.src.addr_inc_en = DMA_ADDR_INC_ENABLE;
dac_dma_config.src.addr_loop_en = DMA_ADDR_LOOP_ENABLE;
dac_dma_config.dst.addr_inc_en = DMA_ADDR_INC_ENABLE;
dac_dma_config.dst.addr_loop_en = DMA_ADDR_LOOP_ENABLE;
dac_dma_config.trans_type = DMA_TRANS_DEFAULT;
/* get audio adc and dac fifo address */
bk_aud_dac_get_fifo_addr(&aud_dac_data_addr);
/* init ringbuff */
dac_ringbuff_addr = (uint8_t *)os_malloc(ADC_FRAME_SIZE);
ring_buffer_init(&dac_rb, dac_ringbuff_addr, ADC_FRAME_SIZE, dac_dma_id, RB_DMA_TYPE_READ);
/* audio adc to dtcm by dma */
dac_dma_config.src.dev = DMA_DEV_DTCM;
dac_dma_config.dst.dev = DMA_DEV_AUDIO;
dac_dma_config.dst.start_addr = aud_dac_data_addr;
dac_dma_config.dst.end_addr = aud_dac_data_addr + 2;
dac_dma_config.src.start_addr = (uint32_t)dac_ringbuff_addr;
dac_dma_config.src.end_addr = (uint32_t)dac_ringbuff_addr + ADC_FRAME_SIZE;
/* init dma channel */
ret = bk_dma_init(dac_dma_id, &dac_dma_config);
if (ret != BK_OK) {
os_printf("[%s]bk_dma_init fail, line: %d \n", __func__, __LINE__);
return;
}
/* set dma transfer length */
bk_dma_set_transfer_len(dac_dma_id, ADC_FRAME_SIZE/2);
os_memset(adc_temp, 0, ADC_FRAME_SIZE/2);
ring_buffer_write(&dac_rb, (uint8_t *)adc_temp, ADC_FRAME_SIZE/2);
os_printf("dac ring_buff size: %d, dma transfer len: %d \n", ADC_FRAME_SIZE, ADC_FRAME_SIZE/2);
#if (CONFIG_SPE)
bk_dma_set_dest_sec_attr(dac_dma_id, DMA_ATTR_SEC);
bk_dma_set_src_sec_attr(dac_dma_id, DMA_ATTR_SEC);
#endif
/* start dac and adc */
bk_aud_dac_start();
bk_aud_dac_start();
bk_aud_adc_start();
/* start dma */
bk_dma_start(dac_dma_id);
bk_dma_start(adc_dma_id);
}
void audio_adc_mic2_to_dac_test_stop(void)
{
for (uint8_t i = 0; i < DMA_ID_MAX; i++) {
if (bk_dma_user(i) == DMA_DEV_AUDIO) {
bk_dma_stop(i);
bk_dma_deinit(i);
bk_dma_free(DMA_DEV_AUDIO, i);
}
}
bk_dma_driver_deinit();
if (adc_ringbuff_addr) {
ring_buffer_clear(&adc_rb);
os_free(adc_ringbuff_addr);
adc_ringbuff_addr = NULL;
}
if (dac_ringbuff_addr) {
ring_buffer_clear(&dac_rb);
os_free(dac_ringbuff_addr);
dac_ringbuff_addr = NULL;
}
if (adc_temp) {
os_free(adc_temp);
adc_temp =NULL;
}
bk_aud_adc_stop();
bk_aud_adc_deinit();
bk_aud_dac_stop();
bk_aud_dac_deinit();
}
/* audio auto test */
static void audio_auto_loop_test(uint32_t state, uint32_t sample_rate, uint32_t dac_mode)
{
aud_adc_config_t adc_config = DEFAULT_AUD_ADC_CONFIG();
aud_dac_config_t dac_config = DEFAULT_AUD_DAC_CONFIG();
if (state == 1) {
adc_config.adc_chl = AUD_ADC_CHL_LR;
adc_config.clk_src = AUD_CLK_XTAL;
dac_config.dac_chl = AUD_DAC_CHL_LR;
dac_config.clk_src = AUD_CLK_XTAL;
switch (sample_rate) {
case 1:
adc_config.samp_rate = 8000;
dac_config.samp_rate = 8000;
break;
case 2:
adc_config.samp_rate = 11025;
dac_config.samp_rate = 11025;
break;
case 3:
adc_config.samp_rate = 12000;
dac_config.samp_rate = 12000;
break;
case 4:
adc_config.samp_rate = 16000;
dac_config.samp_rate = 16000;
break;
case 5:
adc_config.samp_rate = 22050;
dac_config.samp_rate = 22050;
break;
case 6:
adc_config.samp_rate = 24000;
dac_config.samp_rate = 24000;
break;
case 7:
adc_config.samp_rate = 32000;
dac_config.samp_rate = 32000;
break;
case 8:
adc_config.samp_rate = 44100;
dac_config.samp_rate = 44100;
break;
case 9:
adc_config.samp_rate = 48000;
dac_config.samp_rate = 48000;
break;
default:
break;
}
if (dac_mode == 0) {
dac_config.work_mode = AUD_DAC_WORK_MODE_DIFFEN;
} else if (dac_mode == 1) {
dac_config.work_mode = AUD_DAC_WORK_MODE_SIGNAL_END;
} else {
dac_config.work_mode = AUD_DAC_WORK_MODE_DIFFEN;
}
/* audio process test */
sys_drv_aud_dacg_set(0);
sys_drv_aud_mic1_gain_set(0);
sys_drv_aud_mic2_gain_set(0);
bk_aud_adc_init(&adc_config);
bk_aud_dac_init(&dac_config);
//disable audio interrupt when loop test
sys_drv_aud_int_en(0);
bk_aud_adc_disable_int();
//start adc
bk_aud_adc_start();
//start adc
bk_aud_dac_start();
//enable adc to dac loop test
bk_aud_adc_start_loop_test();
}else {
//disable adc and dac
bk_aud_adc_stop();
bk_aud_dac_stop();
//stop loop test
bk_aud_adc_stop_loop_test();
bk_aud_adc_deinit();
bk_aud_dac_deinit();
}
}
static void audio_adc_config(uint32_t sample_rate, uint32_t adc_mode)
{
aud_adc_config_t adc_config = DEFAULT_AUD_ADC_CONFIG();
adc_config.adc_chl = AUD_ADC_CHL_LR;
adc_config.clk_src = AUD_CLK_XTAL;
adc_config.adc_mode = adc_mode;
switch (sample_rate) {
case 1:
adc_config.samp_rate = 8000;
break;
case 2:
adc_config.samp_rate = 11025;
break;
case 3:
adc_config.samp_rate = 12000;
break;
case 4:
adc_config.samp_rate = 16000;
break;
case 5:
adc_config.samp_rate = 22050;
break;
case 6:
adc_config.samp_rate = 24000;
break;
case 7:
adc_config.samp_rate = 32000;
break;
case 8:
adc_config.samp_rate = 44100;
break;
case 9:
adc_config.samp_rate = 48000;
break;
default:
break;
}
/* audio process test */
sys_drv_aud_mic1_gain_set(0);
sys_drv_aud_mic2_gain_set(0);
bk_aud_adc_init(&adc_config);
//disable audio interrupt when loop test
// sys_drv_aud_int_en(0);
// bk_aud_adc_disable_int();
//start adc
bk_aud_adc_start();
}
static void audio_adc_deconfig(void)
{
//disable adc
bk_aud_adc_stop();
bk_aud_adc_deinit();
//bk_aud_driver_deinit();
}
static void audio_dac_config(uint32_t sample_rate, uint32_t dac_mode)
{
aud_dac_config_t dac_config = DEFAULT_AUD_DAC_CONFIG();
dac_config.dac_chl = AUD_DAC_CHL_LR;
dac_config.clk_src = AUD_CLK_XTAL;
dac_config.work_mode = dac_mode;
switch (sample_rate) {
case 1:
dac_config.samp_rate = 8000;
break;
case 2:
dac_config.samp_rate = 11025;
break;
case 3:
dac_config.samp_rate = 12000;
break;
case 4:
dac_config.samp_rate = 16000;
break;
case 5:
dac_config.samp_rate = 22050;
break;
case 6:
dac_config.samp_rate = 24000;
break;
case 7:
dac_config.samp_rate = 32000;
break;
case 8:
dac_config.samp_rate = 44100;
break;
case 9:
dac_config.samp_rate = 48000;
break;
default:
break;
}
/* audio process test */
sys_drv_aud_dacg_set(0);
bk_aud_dac_init(&dac_config);
//disable audio interrupt when loop test
sys_drv_aud_int_en(0);
bk_aud_adc_disable_int();
//start adc
bk_aud_dac_start();
}
static void audio_dac_deconfig(void)
{
//disable dac
bk_aud_dac_stop();
bk_aud_dac_deinit();
//bk_aud_driver_deinit();
}
static void i2s_config(uint32_t sample_rate)
{
i2s_config_t i2s_config = DEFAULT_I2S_CONFIG();
i2s_samp_rate_t samp_rate = I2S_SAMP_RATE_8000;
switch (sample_rate) {
case 1: //8k
samp_rate = I2S_SAMP_RATE_8000;
break;
case 2: //11.025k
samp_rate = I2S_SAMP_RATE_11025;
break;
case 3: //12k
samp_rate = I2S_SAMP_RATE_12000;
break;
case 4: //16k
samp_rate = I2S_SAMP_RATE_16000;
break;
case 5: //22.05k
samp_rate = I2S_SAMP_RATE_22050;
break;
case 6: //24k
samp_rate = I2S_SAMP_RATE_24000;
break;
case 7: //32k
samp_rate = I2S_SAMP_RATE_32000;
break;
case 8: //44.1k
samp_rate = I2S_SAMP_RATE_44100;
break;
case 9: //48k
samp_rate = I2S_SAMP_RATE_48000;
break;
default:
break;
}
i2s_config.samp_rate = I2S_SAMP_RATE_8000;
i2s_config.samp_rate = samp_rate;
i2s_config.store_mode = I2S_LRCOM_STORE_16R16L;
/* init i2s */
bk_i2s_driver_init();
/* config i2s */
#if CONFIG_SOC_BK7256XX
bk_i2s_init(I2S_GPIO_GROUP_0, &i2s_config);
#endif
#if (CONFIG_SOC_BK7236XX) || (CONFIG_SOC_BK7239XX) || (CONFIG_SOC_BK7286XX)
bk_i2s_init(I2S_GPIO_GROUP_2, &i2s_config);
#endif
bk_i2s_enable(I2S_ENABLE);
}
static void i2s_deconfig(void)
{
bk_i2s_enable(I2S_DISABLE);
bk_i2s_deinit();
bk_i2s_driver_deinit();
}
static dma_id_t aud_i2s_dma_config(uint32_t state)
{
bk_err_t ret = BK_OK;
dma_config_t dma_config;
uint32_t i2s_data_addr;
uint32_t aud_adc_data_addr;
uint32_t aud_dac_data_addr;
/* init dma driver */
ret = bk_dma_driver_init();
if (ret != BK_OK) {
return DMA_ID_MAX;
}
/* allocate free DMA channel */
dma_id_t dma_id = bk_dma_alloc(DMA_DEV_AUDIO);
if ((dma_id < DMA_ID_0) || (dma_id >= DMA_ID_MAX)) {
return DMA_ID_MAX;
}
dma_config.mode = DMA_WORK_MODE_REPEAT;
dma_config.chan_prio = 1;
dma_config.src.width = DMA_DATA_WIDTH_32BITS;
dma_config.dst.width = DMA_DATA_WIDTH_32BITS;
dma_config.src.addr_inc_en = DMA_ADDR_INC_ENABLE;
dma_config.src.addr_loop_en = DMA_ADDR_LOOP_ENABLE;
dma_config.dst.addr_inc_en = DMA_ADDR_INC_ENABLE;
dma_config.dst.addr_loop_en = DMA_ADDR_LOOP_ENABLE;
/* get audio adc and dac fifo address */
bk_aud_adc_get_fifo_addr(&aud_adc_data_addr);
bk_aud_dac_get_fifo_addr(&aud_dac_data_addr);
/* get i2s address */
bk_i2s_get_data_addr(I2S_CHANNEL_1, &i2s_data_addr);
if (state) {
/* audio adc to i2s by dma */
#if (CONFIG_SOC_BK7236XX) || (CONFIG_SOC_BK7239XX) || (CONFIG_SOC_BK7286XX)
dma_config.src.dev = DMA_DEV_AUDIO_RX;
#else
dma_config.src.dev = DMA_DEV_AUDIO;
#endif
#if CONFIG_SOC_BK7256XX
dma_config.dst.dev = DMA_DEV_I2S;
#endif
#if (CONFIG_SOC_BK7236XX) || (CONFIG_SOC_BK7239XX) || (CONFIG_SOC_BK7286XX)
dma_config.dst.dev = DMA_DEV_I2S2;
#endif
dma_config.dst.start_addr = i2s_data_addr;
dma_config.dst.end_addr = i2s_data_addr + 4;
dma_config.src.start_addr = aud_adc_data_addr;
dma_config.src.end_addr = aud_adc_data_addr + 4;
} else {
/* audio i2s to dac by dma */
#if CONFIG_SOC_BK7256XX
dma_config.src.dev = DMA_DEV_I2S_RX;
#endif
#if (CONFIG_SOC_BK7236XX) || (CONFIG_SOC_BK7239XX) || (CONFIG_SOC_BK7286XX)
dma_config.src.dev = DMA_DEV_I2S2_RX;
#endif
dma_config.dst.dev = DMA_DEV_AUDIO;
dma_config.src.start_addr = i2s_data_addr;
dma_config.src.end_addr = i2s_data_addr + 4;
dma_config.dst.start_addr = aud_dac_data_addr;
dma_config.dst.end_addr = aud_dac_data_addr + 4;
}
/* init dma channel */
ret = bk_dma_init(dma_id, &dma_config);
if (ret != BK_OK) {
return DMA_ID_MAX;
}
/* set dma transfer length */
bk_dma_set_transfer_len(dma_id, 4);
#if (CONFIG_SPE)
bk_dma_set_dest_sec_attr(dma_id, DMA_ATTR_SEC);
bk_dma_set_src_sec_attr(dma_id, DMA_ATTR_SEC);
#endif
return dma_id;
}
static void aud_i2s_dma_deconfig(void)
{
for (uint8_t i = 0; i < DMA_ID_MAX; i++) {
if (bk_dma_user(i) == DMA_DEV_AUDIO) {
bk_dma_stop(i);
bk_dma_deinit(i);
bk_dma_free(DMA_DEV_AUDIO, i);
}
}
bk_dma_driver_deinit();
}
static void aud_i2s_dma_ctrl(uint32_t state, dma_id_t adc_dma_id, dma_id_t dac_dma_id)
{
uint32_t temp_data = 0xF0F0F0F0;
if (state) {
/* start dma */
if (adc_dma_id != DMA_ID_MAX) {
bk_dma_start(adc_dma_id);
}
if (dac_dma_id != DMA_ID_MAX) {
bk_dma_start(dac_dma_id);
}
// bk_i2s_write_data(0, &temp_data, 1);
bk_i2s_write_data(1, &temp_data, 1);
bk_i2s_write_data(2, &temp_data, 1);
} else {
/* stop dma */
if (adc_dma_id != DMA_ID_MAX) {
bk_dma_stop(adc_dma_id);
}
if (dac_dma_id != DMA_ID_MAX) {
bk_dma_stop(dac_dma_id);
}
}
}
/*
01 e0 fc 05 37 X1 X2 X3 X4 (hex)
X1: test control
00: stop test
01: start test
X2: test mode
00: loop
01: adc (IIS OUT,master)
02: dac (IIS IN,master)
03: dac & adc (IIS IN,master)
X3:sample rate setting
1-9: 8K-48K
X4adc and dac mode
00: differential
01: single-ended
*/
//extern void dma_struct_dump(dma_id_t id);
void audio_ap_test_for_ate(UINT8 enable, UINT8 test_mode, UINT8 sample_rate, UINT8 adc_dac_mode)
{
dma_id_t adc_dma_id = DMA_ID_MAX;
dma_id_t dac_dma_id = DMA_ID_MAX;
UINT8 ret = 0;
/* parameter check */
if ((enable < 0 || enable > 1) ||
(test_mode < 0 || test_mode > 4) ||
(sample_rate < 1 || sample_rate > 9) ||
(adc_dac_mode < 0 || adc_dac_mode > 1))
{
ret = 1;
goto audio_exit;
}
if (enable == 1) {
/* start test */
switch (test_mode)
{
/* loop mode */
case 0:
audio_auto_loop_test(1, sample_rate, adc_dac_mode);
break;
/* audio adc */
case 1:
audio_adc_config(sample_rate, adc_dac_mode);
i2s_config(sample_rate);
adc_dma_id = aud_i2s_dma_config(1);
//dma_struct_dump(adc_dma_id);
aud_i2s_dma_ctrl(1, adc_dma_id, dac_dma_id);
//dma_struct_dump(adc_dma_id);
break;
/* audio dac */
case 2:
audio_dac_config(sample_rate, adc_dac_mode);
i2s_config(sample_rate);
dac_dma_id = aud_i2s_dma_config(0);
aud_i2s_dma_ctrl(1, adc_dma_id, dac_dma_id);
break;
/* audio adc and dac */
case 3:
audio_adc_config(sample_rate, adc_dac_mode);
audio_dac_config(sample_rate, adc_dac_mode);
i2s_config(sample_rate);
dac_dma_id = aud_i2s_dma_config(0);
adc_dma_id = aud_i2s_dma_config(1);
aud_i2s_dma_ctrl(1, adc_dma_id, dac_dma_id);
break;
/* mic2 to dacl */
case 4:
audio_adc_mic2_to_dac_test_start();
break;
default:
break;
}
} else if (enable == 0) {
/* stop test */
switch (test_mode)
{
/* loop mode */
case 0:
audio_auto_loop_test(0, sample_rate, adc_dac_mode);
break;
/* audio adc */
case 1:
aud_i2s_dma_ctrl(0, adc_dma_id, dac_dma_id);
audio_adc_deconfig();
bk_aud_driver_deinit();
i2s_deconfig();
aud_i2s_dma_deconfig();
break;
/* audio dac */
case 2:
aud_i2s_dma_ctrl(0, adc_dma_id, dac_dma_id);
audio_dac_deconfig();
bk_aud_driver_deinit();
i2s_deconfig();
aud_i2s_dma_deconfig();
break;
/* audio dac */
case 3:
aud_i2s_dma_ctrl(0, adc_dma_id, dac_dma_id);
audio_adc_deconfig();
audio_dac_deconfig();
bk_aud_driver_deinit();
i2s_deconfig();
aud_i2s_dma_deconfig();
break;
/* mic2 to dacl */
case 4:
audio_adc_mic2_to_dac_test_stop();
break;
default:
ret = 2;
goto audio_exit;
break;
}
} else {
ret = 3;
goto audio_exit;
}
audio_exit:
//uart_send_bytes_for_ate((UINT8 *)&ret, 1);
os_printf("ret: %d \n", ret);
}
static void cli_aud_ate_test_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
{
if (argc != 5) {
cli_aud_ate_help();
return;
}
audio_ap_test_for_ate(strtoul(argv[1], NULL, 10), strtoul(argv[2], NULL, 10), strtoul(argv[3], NULL, 10), strtoul(argv[4], NULL, 10));
}
#define AUD_ATE_CMD_CNT (sizeof(s_aud_ate_commands) / sizeof(struct cli_command))
static const struct cli_command s_aud_ate_commands[] = {
{"aud_ate_test", "aud_ate_test {X1 X2 X3 X4}", cli_aud_ate_test_cmd},
};
int cli_aud_ate_init(void)
{
return cli_register_commands(s_aud_ate_commands, AUD_ATE_CMD_CNT);
}