Files
kunlun/dtest/bee_i2s_test/bee_i2s_test.c
2024-09-28 14:24:04 +08:00

406 lines
10 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/****************************************************************************
*
* Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
*
* This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
* be copied by any method or incorporated into another program without
* the express written consent of Aerospace C.Power. This Information or any portion
* thereof remains the property of Aerospace C.Power. The Information contained herein
* is believed to be accurate and Aerospace C.Power assumes no responsibility or
* liability for its use in any way and conveys no license or title under
* any patent or copyright and makes no representation or warranty that this
* Information is free from patent or copyright infringement.
*
* ****************************************************************************/
/* os shim includes */
#include "os_types.h"
#include "os_task.h"
#include "os_utils.h"
/* common includes */
#include "iot_io.h"
#include "iot_bitops.h"
#include "iot_pkt.h"
#include "iot_ipc.h"
#include "iot_plc_lib.h"
#include "iot_dbglog_api.h"
#include "iot_config.h"
#include "iot_errno_api.h"
/* driver includes */
#include "iot_clock.h"
#include "iot_uart.h"
#include "iot_led.h"
#include "iot_gpio_api.h"
/* cli includes */
#include "iot_cli.h"
#include "iot_uart_h.h"
/* debug includes*/
#include "dbg_io.h"
#include "gpio.h"
#include "hw_reg_api.h"
#include "gpio_mtx_reg.h"
#include "pin_rf.h"
#include "apb.h"
#include "gpio_mtx.h"
//#include "gpio_reg.h"
#include "i2s_reg.h"
#include "apb_dma.h"
#include "dma_hw.h"
#include "i2s.h"
#include "dma_i2s.h"
#include "iot_share_task.h"
#include "wav.h"
#include "d16.h"
#include "s16.h"
#define USE_SINE_TONE 0
char pcm_data[2]={0};
extern int platform_init();
#if USE_SINE_TONE
static short sine_table[48] = {
0x0000, 0x10b4, 0x2120, 0x30fb, 0x3fff, 0x4dea, 0x5a81, 0x658b,
0x6ed8, 0x763f, 0x7ba1, 0x7ee5, 0x7ffd, 0x7ee5, 0x7ba1, 0x76ef,
0x6ed8, 0x658b, 0x5a81, 0x4dea, 0x3fff, 0x30fb, 0x2120, 0x10b4,
0x0000, 0xef4c, 0xdee0, 0xcf06, 0xc002, 0xb216, 0xa57f, 0x9a75,
0x9128, 0x89c1, 0x845f, 0x811b, 0x8002, 0x811b, 0x845f, 0x89c1,
0x9128, 0x9a76, 0xa57f, 0xb216, 0xc002, 0xcf06, 0xdee0, 0xef4c
};
static void sine_tone_fill( unsigned char *buf, int len)
{
static int i = 0;
short *p;
IOT_ASSERT( len > 0);
IOT_ASSERT( ( len & 3) == 0);
p = ( short *)buf;
while( len > 0)
{
p[0] = p[1] = sine_table[i];
p += 2;
i = ( i + 1) % 48;
len -= 4;
}
}
#endif
#define BUF_SIZE 640
os_task_h test_init_handle;
#define MAX_BUF_LEN 3840
#define SAMPLE_RATE 600000
unsigned char buf[2][BUF_SIZE];
desc_t descLs[2];
desc_t *pdesc_pool;
void i2s_test_i2s_func();
void i2s_dma__handler(int vector, int status)
{
desc_t *pdesc1, *pdesc2;
// Recycle out descroptors
if(status&DMA_INT_OUT_DONE)
{
pdesc1 = NULL;
//i2s_tx_stop();
if(pdesc1)
{
if(pdesc_pool)
{
pdesc2 = pdesc_pool;
while(pdesc2->n_ptr)
{
pdesc2 = pdesc2->n_ptr;
}
pdesc2->n_ptr = pdesc1;
}
else
{
pdesc_pool = pdesc1;
}
}
}
// Send bytes that we recieved, and add Recycled descriptors on the list tail
if(status&DMA_INT_IN_DONE)
{
buf[1][0x12] = 0xaa;
DMA_MAKE_DESC(&descLs[1], buf[1], BUF_SIZE, 0, 0, 0, 0, DESC_OWNER_DMA);
dma_hw_start_recieve(DMA_DEV_I2S, &descLs[1]);
/*
pdesc1 = NULL;
if(pdesc1)
{
pdesc2 = pdesc1;
while(pdesc2)
{
DMA_MAKE_DESC(pdesc2, 0, BUF_SIZE, pdesc2->length, 0, 0, 0, DESC_OWNER_DMA);
pdesc2 = pdesc2->n_ptr;
}
dma_hw_start_send(DMA_DEV_I2S, pdesc1);
}
if(pdesc_pool)
{
pdesc1 = pdesc_pool;
while(pdesc1)
{
DMA_MAKE_DESC(pdesc1, 0, BUF_SIZE, 0, 0, 0, 0, DESC_OWNER_DMA);
pdesc1 = pdesc1->n_ptr;
}
dma_hw_start_recieve(DMA_DEV_I2S, pdesc1);
pdesc_pool = NULL;
}
*/
}
if(status&DMA_INT_ERROR_DEFAULT)
{
// TODO: Error handle.
}
return ;
}
void i2s_dma_config(void)
{
int cnt=0;
dma_hw_open(DMA_DEV_I2S, (dma_int_handler)i2s_dma__handler, NULL);
for(cnt=0; cnt<BUF_SIZE; )
{
buf[0][cnt++] = 0xaa;
buf[0][cnt++] = 0x55;
buf[0][cnt++] = 0x80;
buf[0][cnt++] = 0x00;
}
#ifndef I2S_PDM_MODE_TEST
DMA_MAKE_DESC(&descLs[0], &pcm_data[0], BUF_SIZE, BUF_SIZE, 0, 0, 0, DESC_OWNER_DMA);
#else
DMA_MAKE_DESC(&descLs[0], &pcm_data[0], BUF_SIZE, BUF_SIZE, 0, 0, 0, DESC_OWNER_DMA);
#endif
buf[1][0x12] = 0xaa;
DMA_MAKE_DESC(&descLs[1], buf[1], BUF_SIZE, 0, 0, 0, 0, DESC_OWNER_DMA);
dma_hw_start_recieve(DMA_DEV_I2S, &descLs[1]);
//dma_hw_start_send(DMA_DEV_I2S, &descLs[0]);
}
uint16_t test_data[MAX_BUF_LEN/2] = {0};
uint32_t g_recv_cnt = 0;
uint32_t g_send_cnt = 0;
uint32_t g_recv_total_cnt = 0;
uint32_t iot_dtest_dma_recv(unsigned char port, uint8_t *buf, uint32_t len)
{
static uint32_t cnt=0;
if((cnt++ % 1000) == 999)
{
int i;
for (i=0;i<500;i++)
iot_printf("%02x",buf[i]);
}
if(os_mem_cmp(&test_data[0], buf, len))
{
}else{
g_recv_cnt++;
}
os_mem_set((uint8_t *)buf, 0, len);
g_recv_total_cnt++;
return 0;
}
uint32_t iot_dtest_dma_send(unsigned char port, uint8_t *buf, uint32_t len, uint8_t seq)
{
static uint32_t cnt=0;
if ((cnt++ % 1000) == 0)
{
g_recv_total_cnt=g_recv_cnt=0;
}
if(seq!=0)
{
iot_printf("iis dma hw process too FASTWILL NOT SYNC!!!!!!!!! seq=%x \r\n",seq);
}
g_send_cnt++;
return 0;
}
int rx_start=0;
#define BYTES_PER_SEC ( SAMPLE_RATE * 4) // dual 16bit by default
void i2s_test_i2s_func()
{
unsigned int t0, t;
uint32_t tx_bytes;
uint8_t ret;
i2s_config_t i2s_cfg = {0};
i2s_cfg.clk = SAMPLE_RATE; //in FPGA 16M i2s module clk, > 126K ws clk is valid
i2s_cfg.type = I2S_TYPE_MSTR_TX;//I2S_TYPE_MSTR_TX;
i2s_cfg.bit_mode = I2S_BITS_16BIT;
i2s_cfg.msb_right = I2S_MSB_RIGHT_BIT0;//1
i2s_cfg.port = I2S_0;
i2s_cfg.tx_cfg.data_fmt = I2S_DATA_FMT_DUAL_BIT16;
i2s_cfg.tx_cfg.chl_sel = I2S_CHL_SEL_DUAL;
i2s_cfg.tx_cfg.msb_shift = I2S_SHIFT_PHILIPS_DIS;
i2s_cfg.tx_cfg.tx_desc_num = 20;
i2s_cfg.tx_cfg.send = iot_dtest_dma_send;
i2s_config_t i2s_cfg_rx = {0};
i2s_cfg_rx.clk = SAMPLE_RATE; //in FPGA 16M i2s module clk, > 126K ws clk is valid
i2s_cfg_rx.type = I2S_TYPE_SLAV_RX; //I2S_TYPE_SLAV_RX;
i2s_cfg_rx.bit_mode = I2S_BITS_16BIT;
i2s_cfg_rx.msb_right = I2S_MSB_RIGHT_BIT0;//1
i2s_cfg_rx.port = I2S_1;
i2s_cfg_rx.rx_cfg.data_fmt = I2S_DATA_FMT_DUAL_BIT16;
i2s_cfg_rx.rx_cfg.chl_sel = I2S_CHL_SEL_DUAL;
i2s_cfg_rx.rx_cfg.msb_shift = I2S_SHIFT_PHILIPS_DIS;
i2s_cfg_rx.rx_cfg.rx_eof_len = 0xffffffff;
i2s_cfg_rx.rx_cfg.recv = iot_dtest_dma_recv;
i2s_cfg_rx.rx_cfg.rx_desc_num=10;
#if 0 // MASTER TX SLAVE RX
i2s_cfg.type = I2S_TYPE_MSTR_TX;
i2s_cfg_rx.type = I2S_TYPE_SLAV_RX;
i2s_pin_sel_t pin_master = {11, 13, 15}; //LOOP BACK TEST: keep ws/bck/data line apart!! Or the signal will influent each other!
i2s_pin_sel_t pin_slave = {12, 14, 16};
i2s_cfg.pin_master = &pin_master;
i2s_cfg_rx.pin_slave = &pin_slave;
#else //SLAVE TX MASTER RX
i2s_cfg.type = I2S_TYPE_SLAV_TX;
i2s_cfg_rx.type = I2S_TYPE_MSTR_RX;
i2s_pin_sel_t pin_slave = {11, 13, 15};
i2s_pin_sel_t pin_master = {12, 14, 16};
i2s_cfg.pin_slave = &pin_slave;
i2s_cfg_rx.pin_master = &pin_master;
#endif
iot_set_tx_sync_en(1);
iot_i2s_module_init(&i2s_cfg);
for(uint32_t i = 0; i < (MAX_BUF_LEN/2); i++) {
test_data[i] = 0x5aa5;
i++;
test_data[i] = 0xa55a;
}
#if USE_SINE_TONE
sine_tone_fill( (unsigned char *)test_data, MAX_BUF_LEN);
#endif
tx_bytes = 0;
t0 = os_boot_time32();
while(1)
{
ret = iot_i2s_push_pool(I2S_0, (char *)test_data, MAX_BUF_LEN);
if (rx_start==0) // this code just do loop back
{
iot_i2s_module_init(&i2s_cfg_rx);
volatile uint32_t *reg = (volatile uint32_t *) 0x020000c0;
*reg |= 0x3;
rx_start=1;
}
if(ret == 0)
{
#if USE_SINE_TONE
sine_tone_fill( (unsigned char *)test_data, MAX_BUF_LEN);
#endif
tx_bytes += MAX_BUF_LEN;
if ( tx_bytes >= BYTES_PER_SEC)
{
t = os_boot_time32();
iot_printf("\r\n %u, cnt: %d, rx_ok: %d, rx_tol: %d \n", ( unsigned int)( tx_bytes * 1000) / ( unsigned int)( t - t0), g_send_cnt, g_recv_cnt, g_recv_total_cnt);
t0 = t;
tx_bytes = 0;
}
}
else{
os_delay(2);
}
}
}
void i2s_test_task()
{
dma_hw_init(NULL);
i2s_test_i2s_func();
}
void i2s_test_task_init()
{
os_task_h handle;
handle = os_create_task(i2s_test_task, NULL, 6);
if(handle != NULL) {
iot_printf("task create successfully...\n");
}
}
int32_t iot_task_init()
{
test_init_handle = os_create_task(i2s_test_task, NULL, 9);
if(test_init_handle != NULL) {
iot_printf("i2s_test_task created successfully .. \r\n");
}
return 0;
}
int32_t iot_task_start()
{
os_start_kernel();
return 0;
}
static int32_t iot_platform_init()
{
platform_init();
dbg_uart_init();
iot_share_task_init();
return 0;
}
int32_t iot_module_init(void)
{
iot_platform_init();
iot_task_init();
return 0;
}
int32_t iot_module_start(void)
{
int32_t res = 0;
res = iot_task_start();
return res;
}
int main(void)
{
iot_module_init();
iot_module_start();
return 0;
}