370 lines
8.4 KiB
C
370 lines
8.4 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.
|
||
|
****************************************************************************/
|
||
|
/* 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();
|
||
|
}
|
||
|
|