• 大小: 20KB
    文件类型: .cpp
    金币: 1
    下载: 0 次
    发布日期: 2021-06-07
  • 语言: C/C++
  • 标签: CRC  

资源简介

16位 CRC 校验代码 直接可用

资源截图

代码片段和文件信息

/*
 * 8136S freeRTOS spi slave 驱动
 * 除了CLK CS MISO MOSI 4根线外,又增加了SPI NOTIFY 和 SPI READY 2根 GPIO,用于slave端通知master
 * SPI NOTIFY GPIO 上升沿用于slave端通知master端有数据要发送,下降沿用于通知master端发送数据已就绪,master可以启动SPI读取数据
 * SPI READY  上升沿用于slave端通知master端 可以接收数据,
 * 数据包格式:应用数据长度(4个字节) + 应用数据(n个字节) ,应用数据大小不能超过SPI_S_MAX_APP_SIZE
 * master -> slave : master 判断 spi ready 是否有效 (用信号量记录)有效则发送4个字节长度信息,无效则等待有效;然后等spi ready 信号量有效,再发送n个字节应用数据
 *  slave 收到 4个字节数据长度信息后,配置接收DMA,然后通过spi ready给master一个中断,DMA传输结束后配置接收DMA接收4个字节长度信息,然后通过spi ready再给master一个中断。
 *
 *  slave -> master : slave 通过 SPI NOTIFY 管脚给master一个下降沿中断通知master端有数据发送,master端收到通知后给slave发送一个长度为0的4个字节长度信息,
 * slave收到长度为0的4个字节长度信息后知道master已准备好接收数据,slave配置发送DMA,就绪后通过 SPI NOTIFY 管脚给master一个上升沿中断通知master端可以读取数据,
 * master收到SPI READY 上升沿中断后先读取4个字节长度信息,然后读取该长度的应用数据,slave dma传输结束后 配置接收DMA 接收4个字节长度信息,下一次传输就绪,然后通过
 * SPI READY GPIO给master一个中断。
 *
 * 该方式的SPI 工作在半双工模式,也就是在同一时间,要么是master发送数据,要么是master接收数据,master通过数据长度信息发起读写操作。
 * */
#include 
#include 
#include 
#include 
#include 
#include 
#include “lib_board.h“
#include “lib_ssp.h“
#include “lib_gpio.h“
#include “platform_io.h“
#include “io.h“
#include “lib_pmu.h“
#include “lib_dma.h“
#include “lib_mm.h“
#include “spi_slave.h“


#define SPI_CRC16       1


#define SSP_DMA_TX_CH         AHB_DMA_Ch3
#define SSP_DMA_RX_CH         AHB_DMA_Ch7
#define SSP_base(x)           (0x91300000 + 0x100000 * x)

static xQueueHandle tx_requst;
static xQueueHandle tx_done;
static xQueueHandle rx_done;

static xQueueHandle dma_rx;

static u32 *spi_tx_rx_buf;
static u32 spi_dma_rx_status;



#define _GPIO_ID_(group pin)   ((32 * group) + pin)
#define SPI_NOTIFY _GPIO_ID_(1 20)
#define SPI_READY        _GPIO_ID_(1 19)

//demo
//#define SPI_NOTIFY _GPIO_ID_(1 22)
//#define SPI_READY        _GPIO_ID_(1 21)


#define SPI_DMA_RX_STATUS_LEN       0
#define SPI_DMA_RX_STATUS_DATA      1
#define SPI_DMA_RX_STATUS_NULL      2





//SPI数据包格式: 4个字节长度信息 + n个字节应用数据
struct spi_package_t
{
u32 len;
u32 len_crc;
u32 data[0];
};

#define SPI_PACK_HEAD_SIZE   sizeof(struct spi_package_t)

static int spi_dma_rx(void *data u32 len);

#if SPI_CRC16
static unsigned int crc_cal_by_byte(unsigned char* ptr int len);
#endif

inline void spi_slave_ready_rx()
{
u32 i;
gm_gpio_direction_output(SPI_READY 1);
for (i = 0; i < 100; i++)
asm(“nop“);
gm_gpio_direction_output(SPI_READY 0);
}

inline void spi_slave_request_tx()
{
gm_gpio_direction_output(SPI_NOTIFY 1);
}

inline void spi_slave_ready_tx()
{
gm_gpio_direction_output(SPI_NOTIFY 0);
}

static void ssp_tx_isr_cb(void *data)
{
   gm_dma_clear_channel_int_status(SSP_DMA_TX_CH);
}

static void ssp_rx_isr_cb(void *data)
{
//struct spi_package_t *pack;
u32 i;
//pack = (struct spi_package_t *)spi_tx_rx_buf;
gm_dma_clear_channel_int_status(SSP_DMA_RX_CH);
if(xQueueSendToBackFromISR(dma_rx &i NULL) != pdPASS)
printf(“dma rx is full!!!\n“);
// printf(“ssp_rx_isr_cb!!!\n

评论

共有 条评论