310 lines
9.2 KiB
C
310 lines
9.2 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.
|
|
|
|
****************************************************************************/
|
|
#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;
|
|
}
|