Files
kunlun/dtest/kl1_fdma_mst_test/fdma_mst_test.c

310 lines
9.2 KiB
C
Raw Permalink Normal View History

2024-09-28 14:24:04 +08:00
/****************************************************************************
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.
****************************************************************************/
#include "os_types.h"
#include "encoding.h"
#include "platform.h"
#include "gpio_hw.h"
#include "gpio_mtx.h"
#include "clk.h"
#include "apb.h"
#include "uart.h"
#include "dbg_io.h"
#include "gp_timer.h"
#include "iot_irq.h"
#include "iot_clock.h"
#include "os_mem.h"
#include "iot_system.h"
#include "iot_gpio_api.h"
#include "os_mem_api.h"
#include "iot_io_api.h"
#include "iot_errno_api.h"
#include "iot_utils_api.h"
#include "fdma_mst_protocol.h"
#define FDMA_MST_CMD_UART 0
#define FDMA_MST_CMD_HELP 0x3F //"?"
#define FDMA_MST_CMD_HEADER 0xAA
#define FDMA_MST_CMD_TAIL 0x55
#define FDMA_MST_CMD_BUF_LEN 64
#define FDMA_MST_SWAP_BUF_LEN 64 //64 * 4 bytes
typedef enum {
FDMA_MST_UART_FSM_IDLE = 0,
FDMA_MST_UART_FSM_GET_HEADER,
FDMA_MST_UART_FSM_GET_CMD_DATA,
FDMA_MST_UART_FSM_WAITING_TAIL,
FDMA_MST_UART_FSM_COMPLETE,
} fdma_mst_uart_fsm_t;
typedef enum {
FDMA_MST_CMD_READ = 0,
FDMA_MST_CMD_WRITE,
FDMA_MST_CMD_MAX,
} fdma_mst_cmd_type_t;
typedef struct _fdma_mst_cmd_read_t {
uint32_t addr;
uint32_t len;
} fdma_mst_cmd_read_t;
typedef struct _fdma_mst_cmd_write_t {
uint32_t addr;
uint32_t len;
uint32_t data[0];
} fdma_mst_cmd_write_t;
typedef struct _fdma_mst_uart_cmd_t {
uint8_t fsm;
uint8_t cmd_type;
uint8_t buf_idx;
uint8_t padding;
uint8_t buf[FDMA_MST_CMD_BUF_LEN]; //ensure that is a four byte pair
} fdma_mst_uart_cmd_t;
typedef struct _fdma_mst_globle_t {
fdma_mst_uart_cmd_t cmd;
uint32_t swap_buf[FDMA_MST_SWAP_BUF_LEN];
} fdma_mst_globle_t;
fdma_mst_globle_t g_fm = {0};
void dtest_fdma_mst_print_usage()
{
iot_printf("----------------HELP----------------\n");
iot_printf("| spi_read\n");
iot_printf("| spi_write\n");
iot_printf("| spi_debug\n");
iot_printf("| spi_reset_cpu\n");
iot_printf("| spi_release_cpu\n");
iot_printf("| spi_ping\n");
iot_printf("| spi_nop\n");
iot_printf("------------------------------------\n");
}
uint32_t dtest_fdma_mst_get_cmd()
{
char get_char = 0;
fdma_mst_cmd_write_t *cmd_write;
while(1) {
if (uart_e_ctrl.rx_fifo_cnt(FDMA_MST_CMD_UART) == 0) {
continue;
}
get_char = uart_e_ctrl.getc(FDMA_MST_CMD_UART);
switch (g_fm.cmd.fsm) {
case FDMA_MST_UART_FSM_IDLE:
if (get_char == FDMA_MST_CMD_HEADER) {
g_fm.cmd.fsm = FDMA_MST_UART_FSM_GET_HEADER;
} else if (get_char == FDMA_MST_CMD_HELP) {
dtest_fdma_mst_print_usage();
}
break;
case FDMA_MST_UART_FSM_GET_HEADER:
if (g_fm.cmd.cmd_type >= FDMA_MST_CMD_MAX) {
if (get_char >= FDMA_MST_CMD_MAX) {
iot_printf("get invalid cmd type:0x%x\n", get_char);
g_fm.cmd.fsm = FDMA_MST_UART_FSM_IDLE;
} else {
g_fm.cmd.cmd_type = get_char;
g_fm.cmd.fsm = FDMA_MST_UART_FSM_GET_CMD_DATA;
}
}
break;
case FDMA_MST_UART_FSM_GET_CMD_DATA:
switch(g_fm.cmd.cmd_type) {
case FDMA_MST_CMD_READ:
g_fm.cmd.buf[g_fm.cmd.buf_idx] = get_char;
g_fm.cmd.buf_idx++;
if (g_fm.cmd.buf_idx >= sizeof(fdma_mst_cmd_read_t)) {
g_fm.cmd.fsm = FDMA_MST_UART_FSM_WAITING_TAIL;
}
break;
case FDMA_MST_CMD_WRITE:
g_fm.cmd.buf[g_fm.cmd.buf_idx] = get_char;
g_fm.cmd.buf_idx++;
cmd_write = (fdma_mst_cmd_write_t *)g_fm.cmd.buf;
if (g_fm.cmd.buf_idx >= sizeof(fdma_mst_cmd_write_t) +
NTOHL(cmd_write->len) * 4) {
g_fm.cmd.fsm = FDMA_MST_UART_FSM_WAITING_TAIL;
}
break;
}
break;
case FDMA_MST_UART_FSM_WAITING_TAIL:
if (get_char == FDMA_MST_CMD_TAIL) {
g_fm.cmd.fsm = FDMA_MST_UART_FSM_COMPLETE;
return ERR_OK;
} else {
iot_printf("get error tail byte:0x%x\n", get_char);
g_fm.cmd.fsm = FDMA_MST_UART_FSM_IDLE;
g_fm.cmd.cmd_type = FDMA_MST_CMD_MAX;
g_fm.cmd.buf_idx = 0;
}
break;
}
}
}
static void dtest_fdma_mst_main()
{
fdma_mst_cmd_read_t *cmd_read;
fdma_mst_cmd_write_t *cmd_write;
uint32_t i, addr, len;
iot_printf("fdma master test\n");
dtest_fdma_mst_print_usage();
gp_timer_init();
gp_timer_set(0, 0xffffffff, 0);
gp_timer_start(0);
g_fm.cmd.cmd_type = FDMA_MST_CMD_MAX;
while(1) {
if (dtest_fdma_mst_get_cmd() != ERR_OK) {
iot_printf("entry ? get usage\n");
continue;
}
switch (g_fm.cmd.cmd_type) {
case FDMA_MST_CMD_READ:
cmd_read = (fdma_mst_cmd_read_t *)g_fm.cmd.buf;
addr = NTOHL(cmd_read->addr);
len = NTOHL(cmd_read->len);
iot_printf("get read cmd, addr:0x%08x, len:0x%08x\n", addr, len);
//call read api
iot_spi_fdma_master_read(addr, len, g_fm.swap_buf);
iot_printf("read data:");
for (i = 0; i < len; i++) {
iot_printf("0x%08x ", g_fm.swap_buf[i]);
}
iot_printf("\n");
break;
case FDMA_MST_CMD_WRITE:
cmd_write = (fdma_mst_cmd_write_t *)g_fm.cmd.buf;
addr = NTOHL(cmd_write->addr);
len = NTOHL(cmd_write->len);
iot_printf("get write cmd, addr:0x%08x, len:0x%08x, data:", addr, len);
for (i = 0; i < len; i++) {
iot_printf("0x%08x ", cmd_write->data[i]);
}
iot_printf("\n");
iot_spi_fdma_master_write(addr, len, cmd_write->data);
break;
}
g_fm.cmd.fsm = FDMA_MST_UART_FSM_IDLE;
g_fm.cmd.cmd_type = FDMA_MST_CMD_MAX;
g_fm.cmd.buf_idx = 0;
}
return;
}
void dtest_fdma_exception_handler(uintptr_t mcause)
{
uint32_t mbadaddr = 0;
//disble global interrupt;
__asm volatile ( "csrc mstatus,8" );
__asm volatile ( "csrr %0, mbadaddr" : "=r"(mbadaddr));
switch(mcause) {
case 0x0:
iot_printf("mcause: 0x%02x[Instruction address misaligned]\n",
mcause);
break;
case 0x1:
iot_printf("mcause: 0x%02x[Instruction access fault]\n",
mcause);
break;
case 0x2:
iot_printf("mcause: 0x%02x[Illegal instruction]\n", mcause);
break;
case 0x3:
iot_printf("mcause: 0x%02x[Breakpoint]\n", mcause);
break;
case 0x4:
iot_printf("mcause: 0x%02x[Load address misaligned]\n",
mcause);
break;
case 0x5:
iot_printf("mcause: 0x%02x[Load access fault]\n", mcause);
break;
case 0x6:
iot_printf("mcause: 0x%02x[Store address misaligned]\n",
mcause);
break;
case 0x7:
iot_printf("mcase: 0x%02x[Store access fault]\n", mcause);
break;
default:
iot_printf("mcause: 0x%02x\n", mcause);
break;
}
}
uintptr_t dtest_fdma_handle_trap(uintptr_t mcause,
uintptr_t epc, saved_registers *reg)
{
if ((mcause & MCAUSE_CAUSE) == IRQ_M_EXT) {
// intc_handler(cpu_get_mhartid());
} else {
dtest_fdma_exception_handler(mcause);
// void dtest_fdma_mst_main(void);
// void (*pgm_start)(void) = (void*)dtest_fdma_mst_main;
// pgm_start();
dtest_fdma_mst_main();
}
return epc;
}
extern unsigned int _heap_end, _heap_start;
extern void dtest_fdma_trap_entry();
int main(void)
{
write_csr(mtvec, &dtest_fdma_trap_entry);
clk_core_freq_set(CPU_FREQ_150M);
dbg_uart_init();
os_mem_init(&_heap_start,
(unsigned char *)&_heap_end - (unsigned char*)&_heap_start);
apb_enable(APB_GPIO);
apb_enable(APB_PIN);
gpio_pin_select(GPIO_S_CLK, 0);
gpio_pin_select(GPIO_S_CS, 0);
gpio_pin_select(GPIO_S_MS, 0);
iot_gpio_open_as_output(GPIO_S_CLK);
iot_gpio_open_as_output(GPIO_S_CS);
iot_gpio_open_as_output(GPIO_S_MS);
gpio_pin_wpd(GPIO_S_MS, 1);
gpio_pin_wpu(GPIO_S_MS, 0);
iot_gpio_set_opendrain_mode(GPIO_S_MS, GPIO_DRAIN_ONLY_0);
dtest_fdma_mst_main();
return 0;
}