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;
 | 
						|
}
 |