modify spi slave driver
This commit is contained in:
parent
a8f5ea747e
commit
a454a6e4d2
|
@ -157,18 +157,47 @@ typedef enum _spi_chip_select
|
|||
SPI_CHIP_SELECT_MAX,
|
||||
} spi_chip_select_t;
|
||||
|
||||
typedef enum _spi_slave_event
|
||||
{
|
||||
SPI_EV_TRANS,
|
||||
SPI_EV_RECV,
|
||||
} spi_slave_event_t;
|
||||
typedef enum {
|
||||
WRITE_CONFIG,
|
||||
READ_CONFIG,
|
||||
WRITE_DATA_BYTE,
|
||||
READ_DATA_BYTE,
|
||||
WRITE_DATA_BLOCK,
|
||||
READ_DATA_BLOCK,
|
||||
} spi_slave_command_e;
|
||||
|
||||
typedef struct _spi_slave_handler
|
||||
typedef struct
|
||||
{
|
||||
void (*on_receive)(uint32_t data);
|
||||
uint32_t (*on_transmit)(uint32_t data);
|
||||
spi_slave_event_t (*on_event)(uint32_t data);
|
||||
} spi_slave_handler_t;
|
||||
uint8_t cmd;
|
||||
uint8_t err;
|
||||
uint32_t addr;
|
||||
uint32_t len;
|
||||
} spi_slave_command_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
IDLE,
|
||||
COMMAND,
|
||||
TRANSFER,
|
||||
} spi_slave_status_e;
|
||||
|
||||
typedef int (*spi_slave_receive_callback_t)(void *ctx);
|
||||
|
||||
typedef struct _spi_slave_instance
|
||||
{
|
||||
uint8_t int_pin;
|
||||
uint8_t ready_pin;
|
||||
dmac_channel_number_t dmac_channel;
|
||||
uint8_t dfs;
|
||||
uint8_t slv_oe;
|
||||
uint8_t work_mode;
|
||||
size_t data_bit_length;
|
||||
volatile spi_slave_status_e status;
|
||||
volatile spi_slave_command_t command;
|
||||
volatile uint8_t *config_ptr;
|
||||
uint32_t config_len;
|
||||
spi_slave_receive_callback_t callback;
|
||||
} spi_slave_instance_t;
|
||||
|
||||
extern volatile spi_t *const spi[4];
|
||||
|
||||
|
@ -186,16 +215,6 @@ extern volatile spi_t *const spi[4];
|
|||
void spi_init(spi_device_num_t spi_num, spi_work_mode_t work_mode, spi_frame_format_t frame_format,
|
||||
size_t data_bit_length, uint32_t endian);
|
||||
|
||||
/**
|
||||
* @brief Set spi slave configuration
|
||||
*
|
||||
* @param[in] data_bit_length Spi data bit length
|
||||
* @param[in] handler Handle of spi slave interrupt function.
|
||||
*
|
||||
* @return Void
|
||||
*/
|
||||
void spi_slave_config(size_t data_bit_length, const spi_slave_handler_t *handler);
|
||||
|
||||
/**
|
||||
* @brief Set multiline configuration
|
||||
*
|
||||
|
@ -419,6 +438,21 @@ void spi_dup_send_receive_data_dma(dmac_channel_number_t dma_send_channel_num,
|
|||
spi_device_num_t spi_num, spi_chip_select_t chip_select,
|
||||
const uint8_t *tx_buf, size_t tx_len, uint8_t *rx_buf, size_t rx_len);
|
||||
|
||||
/**
|
||||
* @brief Set spi slave configuration
|
||||
*
|
||||
* @param[in] int_pin SPI master starts sending data interrupt.
|
||||
* @param[in] ready_pin SPI slave ready.
|
||||
* @param[in] dmac_channel Dmac channel number for block.
|
||||
* @param[in] data_bit_length Spi data bit length
|
||||
* @param[in] data SPI slave device data buffer.
|
||||
* @param[in] len The length of SPI slave device data buffer.
|
||||
* @param[in] callback Callback of spi slave.
|
||||
*
|
||||
* @return Void
|
||||
*/
|
||||
void spi_slave_config(uint8_t int_pin, uint8_t ready_pin, dmac_channel_number_t dmac_channel, size_t data_bit_length, uint8_t *data, uint32_t len, spi_slave_receive_callback_t callback);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -16,16 +16,10 @@
|
|||
#include "spi.h"
|
||||
#include "fpioa.h"
|
||||
#include "utils.h"
|
||||
#include "gpiohs.h"
|
||||
#include "sysctl.h"
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
typedef struct _spi_slave_context
|
||||
{
|
||||
size_t data_bit_length;
|
||||
const spi_slave_handler_t *handler;
|
||||
} spi_slave_context_t;
|
||||
|
||||
static spi_slave_context_t spi_slave_context;
|
||||
|
||||
volatile spi_t *const spi[4] =
|
||||
{
|
||||
|
@ -35,6 +29,8 @@ volatile spi_t *const spi[4] =
|
|||
(volatile spi_t *)SPI3_BASE_ADDR
|
||||
};
|
||||
|
||||
static spi_slave_instance_t g_instance;
|
||||
|
||||
static spi_frame_format_t spi_get_frame_format(spi_device_num_t spi_num)
|
||||
{
|
||||
uint8_t frf_offset;
|
||||
|
@ -150,66 +146,6 @@ void spi_init(spi_device_num_t spi_num, spi_work_mode_t work_mode, spi_frame_for
|
|||
spi_adapter->endian = endian;
|
||||
}
|
||||
|
||||
int spi_slave_irq(void *userdata)
|
||||
{
|
||||
spi_slave_context_t *context = (spi_slave_context_t *)userdata;
|
||||
volatile spi_t *spi_adapter = spi[2];
|
||||
uint8_t isr = spi_adapter->isr;
|
||||
uint32_t data;
|
||||
uint32_t transmit_data;
|
||||
uint8_t dfs_offset = 16, slv_oe = 10, work_mode_offset = 6;
|
||||
if (isr & 0x10)
|
||||
{
|
||||
data = spi_adapter->dr[0];
|
||||
if(context->handler->on_event(data) == SPI_EV_RECV)
|
||||
{
|
||||
context->handler->on_receive(data);
|
||||
}
|
||||
if(context->handler->on_event(data) == SPI_EV_TRANS)
|
||||
{
|
||||
transmit_data = context->handler->on_transmit(data);
|
||||
spi_adapter->ssienr = 0x00;
|
||||
spi_adapter->ctrlr0 = (0x0 << work_mode_offset) | (0x0 << slv_oe) | ((context->data_bit_length - 1) << dfs_offset);
|
||||
spi_set_tmod(2, SPI_TMOD_TRANS);
|
||||
spi_adapter->ssienr = 0x01;
|
||||
spi_adapter->dr[0] = transmit_data;
|
||||
spi_adapter->dr[0] = transmit_data;
|
||||
spi_adapter->imr = 0x00000001;
|
||||
}
|
||||
}
|
||||
if (isr & 0x01)
|
||||
{
|
||||
spi_adapter->ssienr = 0x00;
|
||||
spi_adapter->ctrlr0 = (0x0 << work_mode_offset) | (0x1 << slv_oe) | ((context->data_bit_length - 1) << dfs_offset);
|
||||
spi_set_tmod(2, SPI_TMOD_RECV);
|
||||
spi_adapter->imr = 0x00000010;
|
||||
spi_adapter->ssienr = 0x01;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void spi_slave_config(size_t data_bit_length, const spi_slave_handler_t *handler)
|
||||
{
|
||||
sysctl_reset(SYSCTL_RESET_SPI2);
|
||||
sysctl_clock_enable(SYSCTL_CLOCK_SPI2);
|
||||
sysctl_clock_set_threshold(SYSCTL_THRESHOLD_SPI2, 0);
|
||||
|
||||
spi_slave_context.data_bit_length = data_bit_length;
|
||||
spi_slave_context.handler = handler;
|
||||
uint8_t dfs_offset = 16, slv_oe = 10, work_mode_offset = 6;
|
||||
|
||||
volatile spi_t *spi_adapter = spi[2];
|
||||
spi_adapter->ssienr = 0x00;
|
||||
spi_adapter->ctrlr0 = (0x0 << work_mode_offset) | (0x1 << slv_oe) | ((data_bit_length - 1) << dfs_offset);
|
||||
spi_adapter->txftlr = 0x00000000;
|
||||
spi_adapter->rxftlr = 0x00000000;
|
||||
spi_adapter->imr = 0x00000010;
|
||||
spi_adapter->ssienr = 0x01;
|
||||
plic_set_priority(IRQN_SPI_SLAVE_INTERRUPT, 1);
|
||||
plic_irq_enable(IRQN_SPI_SLAVE_INTERRUPT);
|
||||
plic_irq_register(IRQN_SPI_SLAVE_INTERRUPT, spi_slave_irq, &spi_slave_context);
|
||||
}
|
||||
|
||||
void spi_init_non_standard(spi_device_num_t spi_num, uint32_t instruction_length, uint32_t address_length,
|
||||
uint32_t wait_cycles, spi_instruction_address_trans_mode_t instruction_address_trans_mode)
|
||||
{
|
||||
|
@ -1036,3 +972,327 @@ void spi_fill_data_dma(dmac_channel_number_t channel_num, spi_device_num_t spi_n
|
|||
spi_handle->ssienr = 0x00;
|
||||
}
|
||||
|
||||
static int spi_slave_irq(void *ctx)
|
||||
{
|
||||
volatile spi_t *spi_handle = spi[2];
|
||||
|
||||
spi_handle->imr = 0x00;
|
||||
*(volatile uint32_t *)(spi_handle->icr);
|
||||
if (g_instance.status == IDLE)
|
||||
g_instance.status = COMMAND;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void spi_slave_idle_mode(void)
|
||||
{
|
||||
volatile spi_t *spi_handle = spi[2];
|
||||
uint32_t data_width = g_instance.data_bit_length / 8;
|
||||
g_instance.status = IDLE;
|
||||
spi_handle->ssienr = 0x00;
|
||||
spi_handle->ctrlr0 = (0x0 << g_instance.work_mode) | (0x1 << g_instance.slv_oe) | ((g_instance.data_bit_length - 1) << g_instance.dfs);
|
||||
spi_handle->rxftlr = 0x08 / data_width - 1;
|
||||
|
||||
spi_handle->dmacr = 0x00;
|
||||
spi_handle->imr = 0x10;
|
||||
spi_handle->ssienr = 0x01;
|
||||
gpiohs_set_pin(g_instance.ready_pin, GPIO_PV_HIGH);
|
||||
}
|
||||
|
||||
static void spi_slave_command_mode(void)
|
||||
{
|
||||
volatile spi_t *spi_handle = spi[2];
|
||||
uint8_t cmd_data[8], sum = 0;
|
||||
|
||||
spi_transfer_width_t frame_width = spi_get_frame_size(g_instance.data_bit_length - 1);
|
||||
uint32_t data_width = g_instance.data_bit_length / 8;
|
||||
spi_device_num_t spi_num = SPI_DEVICE_2;
|
||||
switch(frame_width)
|
||||
{
|
||||
case SPI_TRANS_INT:
|
||||
for (uint32_t i = 0; i < 8 / 4; i++)
|
||||
((uint32_t *)cmd_data)[i] = spi_handle->dr[0];
|
||||
break;
|
||||
case SPI_TRANS_SHORT:
|
||||
for (uint32_t i = 0; i < 8 / 2; i++)
|
||||
((uint16_t *)cmd_data)[i] = spi_handle->dr[0];
|
||||
break;
|
||||
default:
|
||||
for (uint32_t i = 0; i < 8; i++)
|
||||
cmd_data[i] = spi_handle->dr[0];
|
||||
break;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < 7; i++)
|
||||
{
|
||||
sum += cmd_data[i];
|
||||
}
|
||||
if (cmd_data[7] != sum)
|
||||
{
|
||||
spi_slave_idle_mode();
|
||||
return;
|
||||
}
|
||||
g_instance.command.cmd = cmd_data[0];
|
||||
g_instance.command.addr = cmd_data[1] | (cmd_data[2] << 8) | (cmd_data[3] << 16) | (cmd_data[4] << 24);
|
||||
g_instance.command.len = cmd_data[5] | (cmd_data[6] << 8);
|
||||
if (g_instance.command.len == 0)
|
||||
g_instance.command.len = 65536;
|
||||
if ((g_instance.command.cmd < WRITE_DATA_BLOCK) && (g_instance.command.len > 8))
|
||||
{
|
||||
spi_slave_idle_mode();
|
||||
return;
|
||||
}
|
||||
g_instance.status = TRANSFER;
|
||||
spi_handle->ssienr = 0x00;
|
||||
if (g_instance.command.cmd == WRITE_CONFIG)
|
||||
{
|
||||
spi_handle->ctrlr0 = (0x0 << g_instance.work_mode) | (0x1 << g_instance.slv_oe) | ((g_instance.data_bit_length - 1) << g_instance.dfs);
|
||||
spi[2]->rxftlr = g_instance.command.len / data_width - 1;
|
||||
spi_handle->imr = 0x00;
|
||||
spi_handle->ssienr = 0x01;
|
||||
}
|
||||
else if (g_instance.command.cmd == READ_CONFIG)
|
||||
{
|
||||
spi_handle->ctrlr0 = (0x0 << g_instance.work_mode) | (0x0 << g_instance.slv_oe) | ((g_instance.data_bit_length - 1) << g_instance.dfs);
|
||||
spi_set_tmod(2, SPI_TMOD_TRANS);
|
||||
spi_handle->txftlr = 0x00;
|
||||
spi_handle->imr = 0x00;
|
||||
spi_handle->ssienr = 0x01;
|
||||
switch(frame_width)
|
||||
{
|
||||
case SPI_TRANS_INT:
|
||||
for (uint32_t i = 0; i < g_instance.command.len / 4; i++)
|
||||
{
|
||||
spi_handle->dr[0] = ((uint32_t *)&g_instance.config_ptr[g_instance.command.addr])[i];
|
||||
}
|
||||
break;
|
||||
case SPI_TRANS_SHORT:
|
||||
for (uint32_t i = 0; i < g_instance.command.len / 2; i++)
|
||||
{
|
||||
spi_handle->dr[0] = ((uint16_t *)&g_instance.config_ptr[g_instance.command.addr])[i];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
for (uint32_t i = 0; i < g_instance.command.len; i++)
|
||||
{
|
||||
spi_handle->dr[0] = ((uint8_t *)&g_instance.config_ptr[g_instance.command.addr])[i];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (g_instance.command.cmd == WRITE_DATA_BYTE)
|
||||
{
|
||||
spi_handle->ctrlr0 = (0x0 << g_instance.work_mode) | (0x1 << g_instance.slv_oe) | ((g_instance.data_bit_length - 1) << g_instance.dfs);
|
||||
spi[2]->rxftlr = g_instance.command.len / data_width - 1;
|
||||
spi_handle->imr = 0x00;
|
||||
spi_handle->ssienr = 0x01;
|
||||
}
|
||||
else if (g_instance.command.cmd == READ_DATA_BYTE)
|
||||
{
|
||||
spi_handle->ctrlr0 = (0x0 << g_instance.work_mode) | (0x0 << g_instance.slv_oe) | ((g_instance.data_bit_length - 1) << g_instance.dfs);
|
||||
spi_set_tmod(2, SPI_TMOD_TRANS);
|
||||
spi_handle->txftlr = 0x00;
|
||||
spi_handle->imr = 0x00;
|
||||
spi_handle->ssienr = 0x01;
|
||||
switch(frame_width)
|
||||
{
|
||||
case SPI_TRANS_INT:
|
||||
for (uint32_t i = 0; i < g_instance.command.len / 4; i++)
|
||||
{
|
||||
spi_handle->dr[0] = ((uint32_t *)g_instance.command.addr)[i];
|
||||
}
|
||||
break;
|
||||
case SPI_TRANS_SHORT:
|
||||
for (uint32_t i = 0; i < g_instance.command.len / 2; i++)
|
||||
{
|
||||
spi_handle->dr[0] = ((uint16_t *)g_instance.command.addr)[i];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
for (uint32_t i = 0; i < g_instance.command.len; i++)
|
||||
{
|
||||
spi_handle->dr[0] = ((uint8_t *)g_instance.command.addr)[i];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (g_instance.command.cmd == WRITE_DATA_BLOCK)
|
||||
{
|
||||
spi_handle->ctrlr0 = (0x0 << g_instance.work_mode) | (0x1 << g_instance.slv_oe) | ((32 - 1) << g_instance.dfs);
|
||||
|
||||
spi_handle->dmacr = 0x01;
|
||||
spi_handle->imr = 0x00;
|
||||
spi_handle->ssienr = 0x01;
|
||||
|
||||
sysctl_dma_select(g_instance.dmac_channel, SYSCTL_DMA_SELECT_SSI0_RX_REQ + spi_num * 2);
|
||||
|
||||
dmac_set_single_mode(g_instance.dmac_channel, (void *)(&spi_handle->dr[0]), (void *)(g_instance.command.addr & 0xFFFFFFF0), DMAC_ADDR_NOCHANGE, DMAC_ADDR_INCREMENT,
|
||||
DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, g_instance.command.len * 4);
|
||||
}
|
||||
else if (g_instance.command.cmd == READ_DATA_BLOCK)
|
||||
{
|
||||
spi_handle->ctrlr0 = (0x0 << g_instance.work_mode) | (0x0 << g_instance.slv_oe) | ((32 - 1) << g_instance.dfs);
|
||||
spi_set_tmod(2, SPI_TMOD_TRANS);
|
||||
spi_handle->dmacr = 0x02;
|
||||
spi_handle->imr = 0x00;
|
||||
spi_handle->ssienr = 0x01;
|
||||
|
||||
sysctl_dma_select(g_instance.dmac_channel, SYSCTL_DMA_SELECT_SSI0_TX_REQ + spi_num * 2);
|
||||
dmac_set_single_mode(g_instance.dmac_channel, (void *)(g_instance.command.addr & 0xFFFFFFF0), (void *)(&spi_handle->dr[0]), DMAC_ADDR_INCREMENT, DMAC_ADDR_NOCHANGE,
|
||||
DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, g_instance.command.len * 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
spi_slave_idle_mode();
|
||||
return;
|
||||
}
|
||||
gpiohs_set_pin(g_instance.ready_pin, GPIO_PV_LOW);
|
||||
}
|
||||
|
||||
static void spi_slave_transfer_mode(void)
|
||||
{
|
||||
spi_transfer_width_t frame_width = spi_get_frame_size(g_instance.data_bit_length - 1);
|
||||
uint32_t command_len = 0;
|
||||
|
||||
switch(frame_width)
|
||||
{
|
||||
case SPI_TRANS_INT:
|
||||
command_len = g_instance.command.len / 4;
|
||||
break;
|
||||
case SPI_TRANS_SHORT:
|
||||
command_len = g_instance.command.len / 2;
|
||||
break;
|
||||
default:
|
||||
command_len = g_instance.command.len;
|
||||
break;
|
||||
}
|
||||
volatile spi_t *spi_handle = spi[2];
|
||||
g_instance.command.err = 0;
|
||||
if (g_instance.command.cmd == WRITE_CONFIG || g_instance.command.cmd == WRITE_DATA_BYTE)
|
||||
{
|
||||
if (spi_handle->rxflr < command_len - 1)
|
||||
g_instance.command.err = 1;
|
||||
}
|
||||
else if (g_instance.command.cmd == READ_CONFIG || g_instance.command.cmd == READ_DATA_BYTE)
|
||||
{
|
||||
if (spi_handle->txflr != 0)
|
||||
g_instance.command.err = 2;
|
||||
} else if (g_instance.command.cmd == WRITE_DATA_BLOCK || g_instance.command.cmd == READ_DATA_BLOCK)
|
||||
{
|
||||
if (dmac->channel[g_instance.dmac_channel].intstatus != 0x02)
|
||||
g_instance.command.err = 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
spi_slave_idle_mode();
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_instance.command.err == 0)
|
||||
{
|
||||
if (g_instance.command.cmd == WRITE_CONFIG)
|
||||
{
|
||||
switch(frame_width)
|
||||
{
|
||||
case SPI_TRANS_INT:
|
||||
for (uint32_t i = 0; i < command_len; i++)
|
||||
{
|
||||
((uint32_t *)&g_instance.config_ptr[g_instance.command.addr])[i] = spi_handle->dr[0];
|
||||
}
|
||||
break;
|
||||
case SPI_TRANS_SHORT:
|
||||
for (uint32_t i = 0; i < command_len; i++)
|
||||
{
|
||||
((uint16_t *)&g_instance.config_ptr[g_instance.command.addr])[i] = spi_handle->dr[0];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
for (uint32_t i = 0; i < command_len; i++)
|
||||
{
|
||||
((uint8_t *)&g_instance.config_ptr[g_instance.command.addr])[i] = spi_handle->dr[0];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (g_instance.command.cmd == WRITE_DATA_BYTE)
|
||||
{
|
||||
switch(frame_width)
|
||||
{
|
||||
case SPI_TRANS_INT:
|
||||
for (uint32_t i = 0; i < command_len; i++)
|
||||
{
|
||||
((uint32_t *)g_instance.command.addr)[i] = spi_handle->dr[0];
|
||||
}
|
||||
break;
|
||||
case SPI_TRANS_SHORT:
|
||||
for (uint32_t i = 0; i < command_len; i++)
|
||||
{
|
||||
((uint16_t *)g_instance.command.addr)[i] = spi_handle->dr[0];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
for (uint32_t i = 0; i < command_len; i++)
|
||||
{
|
||||
((uint8_t *)g_instance.command.addr)[i] = spi_handle->dr[0];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(g_instance.callback != NULL)
|
||||
{
|
||||
g_instance.callback((void *)&g_instance.command);
|
||||
}
|
||||
spi_slave_idle_mode();
|
||||
}
|
||||
|
||||
static void spi_slave_cs_irq(void)
|
||||
{
|
||||
if (g_instance.status == IDLE)
|
||||
spi_slave_idle_mode();
|
||||
else if (g_instance.status == COMMAND)
|
||||
spi_slave_command_mode();
|
||||
else if (g_instance.status == TRANSFER)
|
||||
spi_slave_transfer_mode();
|
||||
}
|
||||
|
||||
void spi_slave_config(uint8_t int_pin, uint8_t ready_pin, dmac_channel_number_t dmac_channel, size_t data_bit_length, uint8_t *data, uint32_t len, spi_slave_receive_callback_t callback)
|
||||
{
|
||||
g_instance.status = IDLE;
|
||||
g_instance.config_ptr = data;
|
||||
g_instance.config_len = len;
|
||||
g_instance.work_mode = 6;
|
||||
g_instance.slv_oe = 10;
|
||||
g_instance.dfs = 16;
|
||||
g_instance.data_bit_length = data_bit_length;
|
||||
g_instance.ready_pin = ready_pin;
|
||||
g_instance.int_pin = int_pin;
|
||||
g_instance.callback = callback;
|
||||
g_instance.dmac_channel = dmac_channel;
|
||||
sysctl_reset(SYSCTL_RESET_SPI2);
|
||||
sysctl_clock_enable(SYSCTL_CLOCK_SPI2);
|
||||
sysctl_clock_set_threshold(SYSCTL_THRESHOLD_SPI2, 9);
|
||||
|
||||
uint32_t data_width = data_bit_length / 8;
|
||||
volatile spi_t *spi_handle = spi[2];
|
||||
spi_handle->ssienr = 0x00;
|
||||
spi_handle->ctrlr0 = (0x0 << g_instance.work_mode) | (0x1 << g_instance.slv_oe) | ((data_bit_length - 1) << g_instance.dfs);
|
||||
spi_handle->dmatdlr = 0x04;
|
||||
spi_handle->dmardlr = 0x03;
|
||||
spi_handle->dmacr = 0x00;
|
||||
spi_handle->txftlr = 0x00;
|
||||
spi_handle->rxftlr = 0x08 / data_width - 1;
|
||||
spi_handle->imr = 0x10;
|
||||
spi_handle->ssienr = 0x01;
|
||||
|
||||
gpiohs_set_drive_mode(g_instance.ready_pin, GPIO_DM_OUTPUT);
|
||||
gpiohs_set_pin(g_instance.ready_pin, GPIO_PV_HIGH);
|
||||
|
||||
gpiohs_set_drive_mode(g_instance.int_pin, GPIO_DM_INPUT_PULL_UP);
|
||||
gpiohs_set_pin_edge(g_instance.int_pin, GPIO_PE_RISING);
|
||||
gpiohs_set_irq(g_instance.int_pin, 3, spi_slave_cs_irq);
|
||||
|
||||
plic_set_priority(IRQN_SPI_SLAVE_INTERRUPT, 4);
|
||||
plic_irq_enable(IRQN_SPI_SLAVE_INTERRUPT);
|
||||
plic_irq_register(IRQN_SPI_SLAVE_INTERRUPT, spi_slave_irq, NULL);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue