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

528 lines
14 KiB
C

/****************************************************************************
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.
****************************************************************************/
/* FreeRTOS includes */
#include "FreeRTOS.h"
#include "task.h"
/* os shim includes */
#include "os_types.h"
#include "os_event.h"
#include "os_task.h"
#include "os_utils.h"
/* common includes */
#include "iot_module.h"
/* common includes */
#include "iot_io.h"
#include "iot_bitops.h"
#include "iot_pkt_api.h"
#include "iot_ipc.h"
#include "iot_plc_lib.h"
#include "iot_dbglog_api.h"
#include "iot_config.h"
/* driver includes */
#include "iot_clock.h"
#include "iot_uart.h"
#include "iot_led.h"
/* cli includes */
#include "iot_cli.h"
/* debug includes*/
#include "dbg_io.h"
#include "iot_crc.h"
#include "iot_checksum.h"
#include "apb_dma.h"
#include "dma_sw.h"
#include "dma_reg.h"
#include "apb.h"
#include "mac_sys_reg.h"
#define DTEST_DMA_DEV DMA_DEV_SW0 //DMA_DEV_SW1
#ifndef DMA_DEBUG_LEVEL
#define DMA_DEBUG_LEVEL 0
#endif
#define DTEST_DMA_CHK_CRC_EN 1
#define DTEST_DMA_CRC32_EN 0
#define DTEST_DMA_CRC24_EN 1
#define DTEST_DMA_CRC16_EN 0
#define DTEST_DMA_CRC8_EN 0
typedef volatile unsigned char reg8;
#define IN_BUF_MASK (1 << 0)
#define OUT_BUF_MASK (1 << 1)
extern int platform_init();
extern void dbg_uart_stage1_init();
os_task_h test_init_handle;
#define IN_BUF_CNT (5)
#define OUT_BUF_CNT (5)
#define IN_BUF_SIZE (128)
#define OUT_BUF_SIZE (32)
reg8 in_buf[IN_BUF_CNT][IN_BUF_SIZE];
reg8 out_buf[OUT_BUF_CNT][OUT_BUF_SIZE];
desc_t in_descls[IN_BUF_CNT];
desc_t out_descls[OUT_BUF_CNT];
void dma_test_handler(int vector, int status)
{
(void)vector;
if (status & DMA_OUT_TOTAL_EOF_INT_ST_MASK)
{
//dma_pop_all_desc_list(DTEST_DMA_DEV, &desc1, &desc2);
}
}
void dma_buffer_reset(uint8_t buf_mask)
{
uint32_t i;
if (buf_mask & IN_BUF_MASK)
{
os_mem_set((uint8_t *)in_buf, 0, sizeof(in_buf));
}
if (buf_mask & OUT_BUF_MASK)
{
for (i = 0; i < sizeof(out_buf); i++)
{
*((uint8_t *)out_buf + i) = (uint8_t)i;
}
}
os_mem_set((uint8_t *)in_descls, 0, sizeof(in_descls));
os_mem_set((uint8_t *)out_descls, 0, sizeof(out_descls));
}
/**
* out_len: 0 ~ OUT_BUF_SIZE (32byte)
* out_cnt: 0 ~ OUT_BUF_CNT
* in_len: 0 ~ IN_BUF_SIZE (128byte)
* in_cnt: 0 ~ OUT_BUF_CNT
* out_offset: 0 ~ 3
* in_offset: 0 ~ 3
*/
int32_t dma_test_case(uint32_t out_len, uint32_t out_size, uint32_t out_cnt, \
uint32_t in_len, uint32_t in_size, uint32_t in_cnt, \
uint8_t out_offset, uint8_t in_offset)
{
uint32_t crc_src = 0, crc_dma = 0;
uint32_t cksum_src = 0, cksum_dma = 0;
uint32_t out_len_total, in_len_total;
uint32_t i, j, tmp;
uint8_t *data = NULL, *src_data = NULL;
int32_t ret = 0;
dma_buffer_reset(IN_BUF_MASK | OUT_BUF_MASK);
src_data = os_mem_malloc(0, out_len*out_cnt);
if (NULL == src_data)
{
return -1;
}
os_mem_set(src_data, 0, out_len*out_cnt);
out_len_total = 0;
for (i = 0; i < out_cnt; i++)
{
data = (uint8_t *)&out_buf[i][out_offset];
DMA_MAKE_DESC(&out_descls[i], data, out_size, out_len, \
0, 0, (out_cnt - i) > 1 ? 0 : 1, DESC_OWNER_DMA);
//make out desc list
out_descls[i].n_ptr = NULL;
if (i)
{
out_descls[i].l_ptr = &out_descls[i-1];
out_descls[i - 1].n_ptr = &out_descls[i];
}
else
{
out_descls[i].l_ptr = NULL;
}
os_mem_cpy(src_data + i * out_len, data, out_len);
out_len_total += out_len;
}
for (i = 0; i < in_cnt; i++)
{
data = (uint8_t *)&in_buf[i][in_offset];
DMA_MAKE_DESC(&in_descls[i], data, in_size, in_len, \
0, 0, 0, DESC_OWNER_DMA);
//make in desc list
in_descls[i].n_ptr = NULL;
if (i)
{
in_descls[i].l_ptr = &in_descls[i-1];
in_descls[i - 1].n_ptr = &in_descls[i];
}
else
{
in_descls[i].l_ptr = NULL;
}
}
dma_sw_start_recieve(DTEST_DMA_DEV, in_descls);
dma_sw_start_send(DTEST_DMA_DEV, out_descls);
os_delay(1000);
#if (DTEST_DMA_CRC32_EN)
crc_src = iot_getcrc32(src_data, out_len*out_cnt);
#elif (DTEST_DMA_CRC24_EN)
crc_src = iot_getcrc24(src_data, out_len*out_cnt);
#elif (DTEST_DMA_CRC16_EN)
crc_src = iot_getcrc32_h16(src_data, out_len*out_cnt);
#elif (DTEST_DMA_CRC8_EN)
crc_src = iot_getcrc8(src_data, out_len*out_cnt);
#else //default CRC32
crc_src = iot_getcrc32(src_data, out_len*out_cnt);
#endif
cksum_src = iot_getcksum(src_data, out_len*out_cnt);
crc_dma = dma_sw_verify_value_get(DTEST_DMA_DEV);
cksum_dma = dma_sw_verify_value_get(DTEST_DMA_DEV);
/* check desc length */
in_len_total = 0;
for (i = 0; i < in_cnt; i++)
{
in_len_total += in_descls[i].length;
}
if (in_len_total != out_len_total)
{
iot_printf("warning:length not match,out_len=0x%X,in_len=0x%X\r\n", \
out_len_total, in_len_total);
}
else /* check src data & dst data*/
{
iot_printf("DMA copy length match\r\n");
tmp = 0;
for (i = 0; i < in_cnt; i++)
{
ret = os_mem_cmp((uint8_t *)(src_data + tmp), \
(uint8_t *)in_descls[i].buf, in_descls[i].length);
if (ret)
{
iot_printf("warning:data no match,desc = %d\r\n", i);
break;
}
tmp += in_descls[i].length;
}
if (i >= in_cnt)
{
iot_printf("DMA data cmp success\r\n");
}
}
#if (DTEST_DMA_CHK_CRC_EN)
/* check crc */
if (crc_src != crc_dma)
{
ret = -1;
iot_printf("warning:crc err, src = 0x%08X,dma = 0x%08X\r\n", \
crc_src, crc_dma);
}
else
{
iot_printf("DMA crc success\r\n");
}
(void)cksum_src;
(void)cksum_dma;
#else
/* check checksum */
if (cksum_src != cksum_dma)
{
ret = -1;
iot_printf("warning:cksum err, src = 0x%04X,dma = 0x%04X\r\n", \
cksum_src, cksum_dma);
}
else
{
iot_printf("DMA checksum success\r\n");
}
(void)crc_src;
(void)crc_dma;
#endif /* DTEST_DMA_CHK_CRC_EN */
#if (defined(DMA_DEBUG_LEVEL) && (DMA_DEBUG_LEVEL > 1))
iot_printf("src data:\r\n");
for (i = 0; i < out_cnt; i++)
{
for(j = 0; j < out_len; j++)
{
iot_printf("0x%02X ", out_buf[i][j + out_offset]);
}
}
iot_printf("\r\n");
iot_printf("des data:\r\n");
for (i = 0; i < in_cnt; i++)
{
for(j = 0; j < in_len; j++)
{
iot_printf("0x%02X ", in_buf[i][j + in_offset]);
}
}
iot_printf("\r\n");
#endif
os_mem_free(src_data);
(void)i;
(void)j;
return ret;
}
void dma_task_1(void *arg)
{
uint32_t task_cnt = 0;
uint32_t i, j;
dma_verify cfg;
iot_printf("task_1 entry\r\n");
#if defined(DTEST_DMA_CHK_CRC_EN) /* CRC case */
#if (DTEST_DMA_CRC32_EN)
cfg.ver_mode = DMA_CRC32;
cfg.crc_polynomial = DMA_CRC32_POLY;
#elif (DTEST_DMA_CRC24_EN)
cfg.ver_mode = DMA_CRC24;
cfg.crc_polynomial = DMA_CRC24_POLY;
#elif (DTEST_DMA_CRC16_EN)
cfg.ver_mode = DMA_CRC16;
cfg.crc_polynomial = DMA_CRC16_POLY;
#elif (DTEST_DMA_CRC8_EN)
cfg.ver_mode = DMA_CRC8;
cfg.crc_polynomial = DMA_CRC8_POLY;
#else /* default CRC32 */
cfg.ver_mode = DMA_CRC32;
cfg.crc_polynomial = DMA_CRC32_POLY;
#endif /* DTEST_DMA_CRC32_EN */
cfg.crc_mode = DMA_CRC_INV;
cfg.crc_init_a0 = 0;
#else /* checksum case */
cfg.ver_mode = DMA_CHKSUM;
#endif /* DTEST_DMA_CHK_CRC_EN */
dma_sw_open(DTEST_DMA_DEV, (dma_int_handler)dma_test_handler, &cfg);
for(;;) {
iot_printf("\r\nTask1 running count:%d\r\n", task_cnt++);
#if 1
/* 1 buffer(32byte) -> 1 buffer(128 byte) */
iot_printf("case1: 1 buf len %d -> 1 buf len %d\r\n", \
OUT_BUF_SIZE, IN_BUF_SIZE);
dma_test_case(OUT_BUF_SIZE, OUT_BUF_SIZE, 1, \
IN_BUF_SIZE, IN_BUF_SIZE, 1, 0, 0);
os_delay(100);
#endif
#if 1
/* 1 buffer(32byte) -> 1 buffer(32 byte) */
iot_printf("case2: 1 buf len %d -> 1 buf len %d\r\n", \
OUT_BUF_SIZE, OUT_BUF_SIZE);
dma_test_case(OUT_BUF_SIZE, OUT_BUF_SIZE, 1, \
OUT_BUF_SIZE, OUT_BUF_SIZE, 1, 0, 0);
os_delay(100);
#endif
/* n buf(32byte * n) -> 1 buffer(128 byte) */
//for (i = 1; i < (IN_BUF_SIZE/OUT_BUF_SIZE + 1); i++)
{
iot_printf("case3:%d buf->1 buf,out size %d, in size %d\r\n", \
3, OUT_BUF_SIZE, IN_BUF_SIZE);
dma_test_case(OUT_BUF_SIZE, OUT_BUF_SIZE, 3, \
IN_BUF_SIZE, IN_BUF_SIZE, 1, 0, 0);
}
os_delay(100);
#if 1
/* n buf(32byte * n) -> 1 buffer(128 byte) */
for (i = 1; i < (IN_BUF_SIZE/OUT_BUF_SIZE + 1); i++)
{
iot_printf("case3:%d buf->1 buf,out size %d, in size %d\r\n", \
i, OUT_BUF_SIZE, IN_BUF_SIZE);
dma_test_case(OUT_BUF_SIZE, OUT_BUF_SIZE, i, \
IN_BUF_SIZE, IN_BUF_SIZE, 1, 0, 0);
}
os_delay(100);
#endif
#if 1
/* 1 buf(32byte) -> 2 buffer(16byte * 2) */
iot_printf("case4: 1 buf -> 2 buf\r\n");
dma_test_case(OUT_BUF_SIZE, OUT_BUF_SIZE, 1, \
OUT_BUF_SIZE/2, OUT_BUF_SIZE/2, 2, 0, 0);
//dma_test_case(16, 1,16, 1, 0, 0);
os_delay(100);
#endif
#if 1
/* 1 buf(32 - head offset) -> 1 buffer(128byte) */
/* data len 4 Byte alignment, out tail addr none 4 byte alignment */
for (i = 0; i < 4; i++)
{
iot_printf("case5:1 buf offset %d ->1 buf,data_len=%d\r\n", \
i, OUT_BUF_SIZE - 4);
dma_test_case(OUT_BUF_SIZE - 4, OUT_BUF_SIZE, 1, \
IN_BUF_SIZE, IN_BUF_SIZE, 1, i, 0);
}
os_delay(100);
#endif
#if 1
/* 1 buf(32 - head offset) -> 1 buffer(128byte) */
/* data len not 4 Byte alignment, out tail addr 4 byte alignment */
for (i = 0; i < 4; i++)
{
iot_printf("case6:1 buf-> 1 buf offset %d, data_len=%d\r\n", \
i, OUT_BUF_SIZE);
dma_test_case(OUT_BUF_SIZE, OUT_BUF_SIZE, 1, \
IN_BUF_SIZE - 8, IN_BUF_SIZE - 4, 1, 0, i);
}
os_delay(100);
#endif
#if 1
/* 1 buf(32 - head offset) -> 1 buffer(128byte) */
/* data len not 4 Byte alignment, out tail addr 4 byte alignment */
for (i = 0; i < 4; i++)
{
iot_printf("case7:1 buf tail offset %d -> 1 buf,data_len=%d\r\n", \
i, OUT_BUF_SIZE - i);
dma_test_case(OUT_BUF_SIZE - i, OUT_BUF_SIZE, 1, \
IN_BUF_SIZE, IN_BUF_SIZE, 1, 0, 0);
}
os_delay(100);
#endif
#if 1
/* 1 buf(32 - head offset) -> 1 buffer(128byte) */
/* data len not 4 Byte alignment, out tail addr 4 byte alignment */
for (i = 0; i < 4; i++)
{
iot_printf("case8:1 buf->1 buf tail offset %d,data_len=%d\r\n", \
i, OUT_BUF_SIZE);
dma_test_case(OUT_BUF_SIZE, OUT_BUF_SIZE, 1, \
OUT_BUF_SIZE + i, OUT_BUF_SIZE + i, 1, 0, 0);
}
os_delay(100);
#endif
#if 1
/* 1 buf(32 - head offset) -> 1 buffer(128byte - head offset) */
for (i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++)
{
iot_printf("case8: buf offset %d -> buf offset %d:", i, j);
dma_test_case(OUT_BUF_SIZE - i, OUT_BUF_SIZE, 1, \
IN_BUF_SIZE, IN_BUF_SIZE, 1, i, j);
}
}
os_delay(100);
#endif
#if 1
/* 2 buf(32 - out_offset) -> 1 buffer(128byte - in_offset) */
for (i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++)
{
iot_printf("case9: buf tail offset %d -> buf tail offset %d:", \
i, j);
dma_test_case(OUT_BUF_SIZE - i, OUT_BUF_SIZE - i, 1, \
IN_BUF_SIZE - j, IN_BUF_SIZE - j, 1, 0, 0);
}
}
os_delay(100);
#endif
(void)i;
(void)j;
}
}
int32_t dma_task_init()
{
/* start plc lib task */
test_init_handle = os_create_task(dma_task_1, NULL, 9);
//create the tasks;
if(test_init_handle != NULL) {
iot_printf("task 1 init successfully...\n");
}
return 0;
}
int32_t dma_task_start()
{
//start the tasks;
os_start_kernel();
return 0;
}
int32_t dma_platform_init()
{
/*platform intialization*/
platform_init();
//resource initializations;
system_clock_init();
system_uart_init();
dbg_uart_init();
dbg_uart_stage1_init();
iot_led_init();
return 0;
}
int main(void)
{
//platform intialization;
dma_platform_init();
//create all the tasks;
dma_task_init();
dma_task_start();
return 0;
}