1000 lines
23 KiB
C
Executable File
1000 lines
23 KiB
C
Executable File
// 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
|
||
|
||
X4:adc 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("X4:adc 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
|
||
|
||
X4:adc 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);
|
||
}
|
||
|