Files
kunlun/dtest/kl1_fdma_mst_test/fdma_mst_protocol.c

370 lines
8.4 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.
****************************************************************************/
/* Copied on iot_gpio_simu_spi.c and slightly modified */
#include "os_types.h"
#include "gpio_hw.h"
#include "clk.h"
#include "uart.h"
#include "iot_gpio.h"
#include "iot_clock.h"
#include "iot_errno.h"
#include "iot_io_api.h"
#include "iot_gpio_api.h"
#include "fdma_mst_protocol.h"
#define IRQ_DISABLE()
#define IRQ_ENABLE()
#define USE_HAL_API 1
#if !USE_HAL_API
static volatile int clk_val = 0;
#endif
static void cs_high(void)
{
#if USE_HAL_API
iot_gpio_value_set(GPIO_S_CS, 1);
#else
hw_gpio_api_table.set_value(GPIO_S_CS, 1);
#endif
}
static void cs_low(void)
{
#if USE_HAL_API
iot_gpio_value_set(GPIO_S_CS, 0);
#else
hw_gpio_api_table.set_value(GPIO_S_CS, 0);
#endif
}
static void clk_overturn(void)
{
#if USE_HAL_API
int val = 0;
iot_gpio_output_value_get(GPIO_S_CLK, &val);
iot_gpio_value_set(GPIO_S_CLK, val^1);
#else
for (volatile uint32_t i = 0; i < 10; i++);
hw_gpio_api_table.set_value(GPIO_S_CLK, !clk_val);
clk_val = !clk_val;
#endif
}
static void spi_write_byte(unsigned char d)
{
int i;
for (i = 15; i >= 0; i--) {
// From high 7 to low 0 written sequentially.
#if USE_HAL_API
iot_gpio_value_set(GPIO_S_MS, d & (1 << i / 2));
#else
hw_gpio_api_table.set_value(GPIO_S_MS, d & (1 << i / 2));
#endif
clk_overturn();
}
}
static int iot_s_spi_write_data(int dev, char* buf, int wt_size)
{
int i;
for (i = 0; i < wt_size; i++) {
spi_write_byte(buf[i]);
}
return 0;
}
static uint8_t spi_read_byte(void)
{
int i;
uint8_t r = 0;
for (i = 0; i <= 15; i++) {
// From high 7 to low 0 serial readout
clk_overturn();
#if USE_HAL_API
r = r | ((uint8_t)iot_gpio_value_get(GPIO_S_MS) << (7 - i / 2));
#else
r = r | ((uint8_t)hw_gpio_api_table.get_value(GPIO_S_MS) << (7 - i / 2));
#endif
}
return r;
}
static uint32_t iot_s_spi_read_data(int dev, int rd_size)
{
int i;
uint32_t data = 0;
#if USE_HAL_API
iot_gpio_close(GPIO_S_MS);
iot_gpio_open_as_input(GPIO_S_MS);
#else
hw_gpio_api_table.set_value(GPIO_S_MS, 0);
hw_gpio_api_table.set_gpio_mode(GPIO_S_MS, GPIO_INPUT);
#endif
// Read in teh data.
for (i = 0; i < rd_size; i++) {
data = data | ((uint32_t)spi_read_byte() << (8 * (rd_size - 1 - i)));
}
#if USE_HAL_API
iot_gpio_close(GPIO_S_MS);
iot_gpio_open_as_output(GPIO_S_MS);
iot_gpio_value_set(GPIO_S_CLK, 0);
iot_gpio_value_set(GPIO_S_MS, 1);
#else
hw_gpio_api_table.set_gpio_mode(GPIO_S_MS, GPIO_OUTPUT);
hw_gpio_api_table.set_value(GPIO_S_CLK, 1);
clk_val = 1;
hw_gpio_api_table.set_value(GPIO_S_MS, 1);
#endif
return data;
}
// purpose:Shake hands with slave
static void spi_start(void)
{
uint16_t i;
#if USE_HAL_API
iot_gpio_value_set(GPIO_S_CLK, 1);
#else
hw_gpio_api_table.set_value(GPIO_S_CLK, 0);
clk_val = 0;
#endif
iot_delay_us(100);
// iot_delay_us_cpu_cycle(100);
for (i = 0; i < 15; i++) {
#if USE_HAL_API
iot_gpio_value_set(GPIO_S_MS, 1);
#else
hw_gpio_api_table.set_value(GPIO_S_MS, 1);
#endif
clk_overturn();
}
cs_low();
}
// purpose:goodbye with slave
static void spi_end(void)
{
uint16_t i;
for (i = 0; i < 14; i++) {
#if USE_HAL_API
iot_gpio_value_set(GPIO_S_MS, 1);
#else
hw_gpio_api_table.set_value(GPIO_S_MS, 1);
#endif
clk_overturn();
}
#if USE_HAL_API
iot_gpio_value_set(GPIO_S_CLK, 1);
iot_gpio_value_set(GPIO_S_MS, 1);
#else
hw_gpio_api_table.set_value(GPIO_S_CLK, 1);
clk_val = 1;
hw_gpio_api_table.set_value(GPIO_S_MS, 1);
#endif
cs_high();
}
void iot_spi_fdma_master_write(uint32_t addr, uint32_t w_lenth,
uint32_t* w_data)
{
uint32_t fifo[2];
uint16_t i;
uint32_t data_temp;
fifo[0] = NTOHL(FMST_SET_CMD(FMST_CMD_WRITE, w_lenth));
fifo[1] = NTOHL(addr);
IRQ_DISABLE();
spi_start();
iot_s_spi_write_data(INVALID_DRIVER, (char*)fifo, sizeof(fifo));
for (i = 0; i < w_lenth; i++) {
data_temp = NTOHL(w_data[i]);
iot_s_spi_write_data(INVALID_DRIVER, (char*)&data_temp,
sizeof(uint32_t));
}
spi_end();
IRQ_ENABLE();
}
uint16_t iot_spi_fdma_master_read(uint32_t addr, uint32_t r_lenth,
uint32_t* rx_buff)
{
uint32_t fifo[2];
uint32_t fifo2[1];
uint16_t i;
if (!r_lenth) {
return ERR_FAIL;
}
fifo[0] = NTOHL(FMST_SET_CMD(FMST_CMD_READ_ALLOCATE, r_lenth));
fifo[1] = NTOHL(addr);
IRQ_DISABLE();
spi_start();
iot_s_spi_write_data(INVALID_DRIVER, (char*)fifo, sizeof(fifo));
spi_end();
fifo2[0] = NTOHL(FMST_SET_CMD(FMST_CMD_READ_FETCH, r_lenth));
spi_start();
iot_s_spi_write_data(INVALID_DRIVER, (char*)fifo2, sizeof(fifo2));
for (i = 0; i < r_lenth;) {
rx_buff[i] = iot_s_spi_read_data(INVALID_DRIVER, sizeof(uint32_t));
i++;
}
#if USE_HAL_API
iot_gpio_value_set(GPIO_S_CLK, 1);
iot_gpio_value_set(GPIO_S_MS, 1);
#else
hw_gpio_api_table.set_value(GPIO_S_CLK, 1);
clk_val = 1;
hw_gpio_api_table.set_value(GPIO_S_MS, 1);
#endif
cs_high();
IRQ_ENABLE();
return ERR_OK;
}
uint16_t iot_spi_fdma_master_get_debuginfo(uint32_t id, uint32_t* rx_buff)
{
uint32_t cmd;
uint16_t i;
cmd = NTOHL(FMST_SET_CMD(FMST_CMD_MODULE_STS, id));
IRQ_DISABLE();
spi_start();
iot_s_spi_write_data(INVALID_DRIVER, (char*)&cmd, sizeof(cmd));
for (i = 0; i < 8; i++) {
rx_buff[i] = iot_s_spi_read_data(INVALID_DRIVER, sizeof(uint32_t));
}
#if USE_HAL_API
iot_gpio_value_set(GPIO_S_CLK, 1);
iot_gpio_value_set(GPIO_S_MS, 1);
#else
hw_gpio_api_table.set_value(GPIO_S_CLK, 1);
clk_val = 1;
hw_gpio_api_table.set_value(GPIO_S_MS, 1);
#endif
cs_high();
IRQ_ENABLE();
return ERR_OK;
}
void iot_spi_fdma_master_reset_cpu(void)
{
uint32_t cmd;
cmd = NTOHL(FMST_SET_CMD(FMST_CMD_CPU_RESET, 0));
IRQ_DISABLE();
spi_start();
iot_s_spi_write_data(INVALID_DRIVER, (char*)&cmd, sizeof(cmd));
spi_end();
IRQ_ENABLE();
}
void iot_spi_fdma_master_reset_release_cpu(void)
{
uint32_t cmd;
cmd = NTOHL(FMST_SET_CMD(FMST_CMD_CPU_RESET_RELEASE, 0));
IRQ_DISABLE();
spi_start();
iot_s_spi_write_data(INVALID_DRIVER, (char*)&cmd, sizeof(cmd));
spi_end();
IRQ_ENABLE();
}
uint16_t iot_spi_fdma_master_ping(uint32_t* rx_buff)
{
uint32_t cmd;
uint16_t i;
cmd = NTOHL(FMST_SET_CMD(FMST_CMD_PING, 0));
IRQ_DISABLE();
spi_start();
iot_s_spi_write_data(INVALID_DRIVER, (char*)&cmd, sizeof(cmd));
for (i = 0; i < 4; i++) {
rx_buff[i] = iot_s_spi_read_data(INVALID_DRIVER, sizeof(uint32_t));
}
#if USE_HAL_API
iot_gpio_value_set(GPIO_S_CLK, 1);
iot_gpio_value_set(GPIO_S_MS, 1);
#else
hw_gpio_api_table.set_value(GPIO_S_CLK, 1);
clk_val = 1;
hw_gpio_api_table.set_value(GPIO_S_MS, 1);
#endif
cs_high();
IRQ_ENABLE();
return ERR_OK;
}
void iot_spi_fdma_master_nop(void)
{
uint32_t cmd;
cmd = NTOHL(FMST_SET_CMD(FMST_CMD_NOP, 0));
IRQ_DISABLE();
spi_start();
iot_s_spi_write_data(INVALID_DRIVER, (char*)&cmd, sizeof(cmd));
spi_end();
IRQ_ENABLE();
}