528 lines
14 KiB
C
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;
|
|
}
|
|
|