本例程演示RVB2601的录音与回放,因为音频数据需要大量的内存空间来存放,所以本例程不使用AOS,直接使用裸机。本例程在SDK中ch2601_helloworld中修改,
打开ch2601_helloworld例程,找到C-Sky\CDK\CSKY\PACK\aos\v7.4.3\src\main.c 修改如下
/*
* Copyright (C) 2019-2020 Alibaba Group Holding Limited
*/
/******************************************************************************
* @file main.c
* @brief CSI Source File for main
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#include <yoc/sysinfo.h>
#include <yoc/yoc.h>
#ifdef CONFIG_OS_TRACE
#include <trcTrig.h>
#include <trcKernelPort.h>
#endif
#ifndef CONFIG_INIT_TASK_STACK_SIZE
#define INIT_TASK_STACK_SIZE 8192
#else
#define INIT_TASK_STACK_SIZE CONFIG_INIT_TASK_STACK_SIZE
#endif
static aos_task_t app_task_handle;
extern int main(void);
static void application_task_entry(void *arg)
{
main();
aos_task_exit(0);
}
void base_init()
{
}
#include "board_config.h"
#include "drv/gpio_pin.h"
#include <drv/pin.h>
#include <drv/pwm.h>
#include <drv/uart.h>
#include <drv/iic.h>
#include <drv/i2s.h>
#include <es8156.h>
#include <es7210.h>
#include <drv/codec.h>
int pre_main(void)
{
/* kernel init */
// aos_init();
//#ifdef CONFIG_OS_TRACE
// trace_init_data();
//#endif
//
// /* init task */
// aos_task_new_ext(&app_task_handle, "app_task", application_task_entry,
// NULL, INIT_TASK_STACK_SIZE, AOS_DEFAULT_APP_PRI);
//
// /* kernel start */
// aos_start();
void my_main(void);
my_main();
return 0;
}
#if 1
uint8_t data_pcm[1024*172];
static csi_gpio_pin_t key1;
static csi_gpio_pin_t r;
static csi_gpio_pin_t g;
static csi_gpio_pin_t b;
void key_led_init(void)
{
csi_pin_set_mux(PA7, PIN_FUNC_GPIO);
csi_pin_set_mux(PA25, PIN_FUNC_GPIO);
csi_pin_set_mux(PA4, PIN_FUNC_GPIO);
csi_gpio_pin_init(&r, PA7);
csi_gpio_pin_dir(&r, GPIO_DIRECTION_OUTPUT);
csi_gpio_pin_init(&g, PA25);
csi_gpio_pin_dir(&g, GPIO_DIRECTION_OUTPUT);
csi_gpio_pin_init(&b, PA4);
csi_gpio_pin_dir(&b, GPIO_DIRECTION_OUTPUT);
csi_pin_set_mux(PA11, PIN_FUNC_GPIO);
csi_gpio_pin_init(&key1, PA11);
csi_gpio_pin_dir(&key1, GPIO_DIRECTION_INPUT);
}
static csi_uart_t g_uart;
void uart_init(void)
{
char send_buf[] = "uart_init \r\n";
csi_pin_set_mux(PA23, PA23_UART0_TX);
csi_pin_set_mux(PA24, PA24_UART0_RX);
csi_uart_init(&g_uart, 0);
csi_uart_baud(&g_uart, 115200);
csi_uart_format(&g_uart, UART_DATA_BITS_8, UART_PARITY_NONE, UART_STOP_BITS_1);
//csi_uart_send(&g_uart, send_buf, sizeof(send_buf), 50);
//csi_uart_send(&g_uart, "uart_init\r\n", strlen("uart_init\r\n"), 50);
}
static csi_iic_t g_iic;
void iic_init(void)
{
csi_pin_set_mux(PA9, PA9_IIC0_SDA);
csi_pin_set_mux(PA8, PA8_IIC0_SCL);
csi_iic_init(&g_iic, 0);
csi_iic_mode(&g_iic, IIC_MODE_MASTER);
csi_iic_addr_mode(&g_iic, IIC_ADDRESS_7BIT);
csi_iic_speed(&g_iic, IIC_BUS_SPEED_STANDARD);
}
int32_t iic_write(uint8_t addr, uint8_t *data, uint32_t data_len)
{
return csi_iic_master_send(&g_iic, addr, data, data_len, 1000);
}
int32_t iic_read(uint8_t addr, uint8_t *data, uint32_t data_len)
{
return csi_iic_master_receive(&g_iic, addr, data, data_len, 1000);
}
static csi_i2s_t g_i2s1;
void i2s1_init(void)
{
csi_i2s_format_t i2s_format;
csi_pin_set_mux(PA26, PA26_I2S1_MCLK);
csi_pin_set_mux(PA2, PA2_I2S1_SCLK);
csi_pin_set_mux(PA5, PA5_I2S1_SDA);
csi_pin_set_mux(PA3, PA3_I2S1_WSCLK);
csi_i2s_init(&g_i2s1, 1);
i2s_format.mode = I2S_MODE_MASTER; ///< 设置I2S 为主机
i2s_format.protocol = I2S_PROTOCOL_I2S; ///< 设置I2S协议为I2S
i2s_format.width = I2S_SAMPLE_WIDTH_16BIT; ///< 设置采样宽度为16bit
i2s_format.rate = I2S_SAMPLE_RATE_8000; ///< 设置采样率为16K
i2s_format.polarity = I2S_LEFT_POLARITY_LOW; ///< WSCLK的高低极性电平对应的声道
i2s_format.sclk_nfs = I2S_SCLK_16FS; ///< 设置SCLK为FS的32倍
i2s_format.mclk_nfs = I2S_MCLK_256FS; ///< 设置MCLK为FS的256倍
csi_i2s_format(&g_i2s1, &i2s_format);
csi_i2s_enable(&g_i2s1, true);
// extern const unsigned char simple_pcm[];
// extern unsigned int simple_pcm_len;
// csi_i2s_send(&g_i2s1, simple_pcm, simple_pcm_len);
}
static csi_i2s_t g_i2s4;
void i2s4_init(void)
{
csi_i2s_format_t i2s_format;
if(CSI_OK != csi_i2s_init(&g_i2s4, 4))
{
csi_uart_send(&g_uart, "i2s4 init failed\r\n", strlen("i2s4 init failed\r\n"), 50);
}
i2s_format.mode = I2S_MODE_MASTER;
i2s_format.protocol = I2S_PROTOCOL_I2S;
i2s_format.width = I2S_SAMPLE_WIDTH_16BIT;
i2s_format.rate = I2S_SAMPLE_RATE_8000;
i2s_format.polarity = I2S_LEFT_POLARITY_LOW;
i2s_format.sclk_nfs = I2S_SCLK_16FS;
i2s_format.mclk_nfs = I2S_MCLK_256FS;
csi_i2s_format(&g_i2s4, &i2s_format);
csi_i2s_rx_select_sound_channel(&g_i2s4, I2S_LEFT_RIGHT_CHANNEL);
csi_i2s_enable(&g_i2s4, true);
}
void i2s0_init(void)
{
static csi_i2s_t i2s_mclk;
csi_i2s_format_t i2s_format;
/* adc i2s0 pinmux init */
csi_pin_set_mux(PA10, PA10_I2S0_MCLK);
csi_i2s_init(&i2s_mclk, 0); ///< init input i2s
i2s_format.mode = I2S_MODE_MASTER;
i2s_format.protocol = I2S_PROTOCOL_I2S;
i2s_format.width = I2S_SAMPLE_WIDTH_16BIT;
i2s_format.rate = I2S_SAMPLE_RATE_8000;
i2s_format.polarity = I2S_LEFT_POLARITY_LOW;
i2s_format.sclk_nfs = I2S_SCLK_16FS;
i2s_format.mclk_nfs = I2S_MCLK_256FS;
csi_i2s_format(&i2s_mclk, &i2s_format);
csi_i2s_enable(&i2s_mclk,true);
}
es8156_dev_t es8156_dev;
es8156_config_t es8156_config;
es7210_dev_t es7210_dev;
es7210_config_t es7210_config;
void my_main(void)
{
csi_gpio_pin_state_t key1_state_last, key1_state_this;
uint8_t* pcm_data_p;
uint32_t pcm_data_len;
key_led_init();
uart_init();
iic_init();
es8156_dev.es8156_addr = 0x09;
es8156_dev.es8156_iic_read = iic_read;
es8156_dev.es8156_iic_write = iic_write;
es8156_config.data_len = ES8156_16BIT_LENGTH;
es8156_config.i2s_mode = ES8156_I2S_MODE_SLAVE;
es8156_config.i2s_protocol = ES8156_NORMAL_I2S;
es8156_config.i2s_rate = ES8156_I2S_SAMPLE_RATE_8000;
es8156_config.i2s_sclk_freq = ES8156_I2S_SCLK_16FS;
es8156_config.mclk_freq = ES8156_MCLK_256FS;
es8156_init(&es8156_dev, &es8156_config);
es8156_all_data_right_channel(&es8156_dev);
es8156_set_volume(&es8156_dev, 200);
es7210_dev.es7210_addr = 0x40;
es7210_dev.es7210_iic_read = iic_read;
es7210_dev.es7210_iic_write = iic_write;
es7210_config.data_len = ES7210_16BIT_LENGTH;
es7210_config.i2s_mode = ES7210_I2S_MODE_SLAVE;
es7210_config.i2s_protocol = ES7210_NORMAL_I2S;
es7210_config.i2s_rate = ES7210_I2S_SAMPLE_RATE_8000;
es7210_config.i2s_sclk_freq = ES7210_I2S_SCLK_16FS;
es7210_config.mclk_freq = ES7210_MCLK_256FS;
es7210_init(&es7210_dev, &es7210_config);
// es7210_mic1_set_gain(&es7210_dev,255);
// es7210_mic2_set_gain(&es7210_dev,255);
// es7210_mic3_set_gain(&es7210_dev,255);
// es7210_mic4_set_gain(&es7210_dev,255);
// es7210_adc1_set_gain(&es7210_dev, 255);
// es7210_adc2_set_gain(&es7210_dev, 255);
// es7210_adc3_set_gain(&es7210_dev, 255);
// es7210_adc4_set_gain(&es7210_dev, 255);
i2s0_init();
i2s1_init();
i2s4_init();
csi_gpio_pin_write(&r, GPIO_PIN_HIGH);
csi_gpio_pin_write(&g, GPIO_PIN_HIGH);
csi_gpio_pin_write(&b, GPIO_PIN_HIGH);
while (1)
{
key1_state_last = key1_state_this;
key1_state_this = csi_gpio_pin_read(&key1);
if((GPIO_PIN_LOW == key1_state_this)&&(GPIO_PIN_HIGH == key1_state_last))
{
csi_gpio_pin_write(&r, GPIO_PIN_HIGH);
csi_gpio_pin_write(&g, GPIO_PIN_LOW);
pcm_data_p = data_pcm;
pcm_data_len = 0;
while(1)
{
if(((pcm_data_len+1024)>sizeof(data_pcm))||(GPIO_PIN_HIGH == csi_gpio_pin_read(&key1)))
{
break;
}
csi_i2s_receive(&g_i2s4, pcm_data_p, 1024);
pcm_data_p += 1024;
pcm_data_len += 1024;
}
csi_gpio_pin_write(&g, GPIO_PIN_HIGH);
csi_gpio_pin_write(&r, GPIO_PIN_LOW);
csi_i2s_send(&g_i2s1, data_pcm, pcm_data_len);
csi_gpio_pin_write(&r, GPIO_PIN_LOW);
csi_gpio_pin_write(&g, GPIO_PIN_LOW);
}
}
}
#endif
编译,下载,运行,按住RVB2601开发板上key1按键开始录音,松开按键就开始回放录音了。
演示视频链接不得不说平头哥的CSI驱动写的还是非常不错的。
附件下载
这效果不错啊!