134 lines
4.5 KiB
C
134 lines
4.5 KiB
C
/***
|
|
* @Author: xxx
|
|
* @Date: 2023-08-01 15:15:53
|
|
* @LastEditors: xxx
|
|
* @LastEditTime: 2023-08-10 10:37:54
|
|
* @Description: SPI驱动, 用于SPI设备的读写操作
|
|
* @email:
|
|
* @Copyright (c) 2023 by xxx, All Rights Reserved.
|
|
*/
|
|
|
|
/**
|
|
使用教程:
|
|
1. 初始化
|
|
spi_t *_spi = NULL;
|
|
spi_gpio_group_t gpios;
|
|
gpios.cs = gpio_create(EEPROM_M95_CS_PORT, EEPROM_M95_CS_PIN);
|
|
gpios.mosi = gpio_create(SPI_MOSI_GPIO_Port, SPI_MOSI_Pin);
|
|
gpios.sck = gpio_create(SPI_CLK_GPIO_Port, SPI_CLK_Pin);
|
|
gpios.miso = gpio_create(SPI_MISO_GPIO_Port, SPI_MISO_Pin);
|
|
gpios.rst = gpio_create(NULL, 0);
|
|
gpios.rdy = gpio_create(NULL, 0);
|
|
_spi = spi_create(SPI_TYPE_NORMAL, gpios, 0);
|
|
2. 使用
|
|
_spi->gpios.cs->reset(*_spi->gpios.cs);
|
|
_spi->interface.u.normal.spi_send(_spi, M95_CMD_READ);
|
|
_spi->interface.u.normal.spi_send(_spi, read_addr >> 8);
|
|
_spi->interface.u.normal.spi_send(_spi, read_addr & 0xff);
|
|
for (uint16_t i = 0; i < length; i++)
|
|
{
|
|
data[i] = _spi->interface.u.normal.spi_send(_spi, M95_DUMMY_BYTE);
|
|
}
|
|
_spi->gpios.cs->set(*_spi->gpios.cs);
|
|
3. 使用LCD
|
|
spi_t *_spi = NULL;
|
|
spi_gpio_group_t gpios;
|
|
gpios.cs = gpio_create(LCD_CS_GPIO_Port, LCD_CS_Pin);
|
|
gpios.mosi = gpio_create(SPI_MOSI_GPIO_Port, SPI_MOSI_Pin);
|
|
gpios.sck = gpio_create(SPI_CLK_GPIO_Port, SPI_CLK_Pin);
|
|
gpios.rst = gpio_create(LCD_RST_GPIO_Port, LCD_RST_Pin);
|
|
gpios.rdy = gpio_create(LCD_RS_GPIO_Port, LCD_RS_Pin);
|
|
gpios.miso = gpio_create(NULL, 0);
|
|
_spi = spi_create(SPI_TYPE_LCD, gpios, 0);
|
|
_spi->interface.hardware_enable(_spi); // LCD模拟IO比较慢
|
|
_spi->spi = SPI1;
|
|
lcd = lcd_create(_spi);
|
|
lcd->driver.init(lcd);
|
|
|
|
*/
|
|
#ifndef __SPIS_H__
|
|
#define __SPIS_H__
|
|
#include "lib.h"
|
|
#include "gpios.h"
|
|
|
|
#define SPI_ENABLE(SPIX) LL_SPI_Enable(SPIX)
|
|
|
|
typedef struct SPIS spi_t;
|
|
typedef void spis_dma_callback(spi_t *handle);
|
|
typedef enum
|
|
{
|
|
SPI_TYPE_NORMAL = 0, // SPI1:NORMAL
|
|
SPI_TYPE_LCD, // SPI2:LCD
|
|
SPI_TYPE_MAX,
|
|
} spi_type_e;
|
|
|
|
typedef struct
|
|
{
|
|
// NORMAL:通过SPI写单个寄存器
|
|
uint8_t (*write_reg)(spi_t *handle, uint8_t reg, uint8_t data);
|
|
// NORMAL:通过SPI读取单个寄存器值
|
|
uint8_t (*read_reg)(spi_t *handle, uint8_t reg);
|
|
|
|
uint8_t (*read_drdy)(spi_t *handle); // 获取SPI DRDY引脚的值
|
|
uint8_t (*write_regs)(spi_t *handle, uint8_t reg, uint8_t *data, uint8_t len); // 通过SPI写多个寄存器
|
|
uint8_t (*read_regs)(spi_t *handle, uint8_t reg, uint8_t *data, uint8_t len); // 通过SPI读多个寄存器
|
|
|
|
uint8_t (*spi_send)(spi_t *handle, uint8_t data); // 通过SPI发送数据
|
|
} spi_normal_interface_t;
|
|
|
|
typedef struct
|
|
{
|
|
// LCD:通过SPI写命令
|
|
uint8_t (*write_cmd)(spi_t *handle, uint8_t cmd);
|
|
// LCD:通过SPI写数据
|
|
uint8_t (*write_data)(spi_t *handle, uint8_t *data, uint16_t len);
|
|
} spi_lcd_interface_t;
|
|
|
|
typedef struct
|
|
{
|
|
union
|
|
{
|
|
spi_normal_interface_t normal;
|
|
spi_lcd_interface_t lcd;
|
|
} u;
|
|
void (*hardware_enable)(spi_t *handle, SPI_TypeDef *spi); // 硬件SPI
|
|
void (*dma_enable)(spi_t *handle, DMA_TypeDef *dma, uint32_t dma_rx_channel, spis_dma_callback *dma_rx_cb,
|
|
uint32_t dma_tx_channel, spis_dma_callback *dma_tx_cb); // DMA SPI
|
|
void (*spi_dma_callback)(spi_t *spi); // DMA发送完成回调
|
|
void (*spi_dma_send)(spi_t *handle, uint8_t *data, uint16_t length); // DMA发送
|
|
} spi_interface_t;
|
|
|
|
typedef struct
|
|
{
|
|
gpio_t *mosi; // MOSI
|
|
gpio_t *miso; // MISO
|
|
gpio_t *sck; // SCK
|
|
gpio_t *cs; // CS
|
|
gpio_t *rst; // RST
|
|
gpio_t *rdy; // DRDY
|
|
} spi_gpio_group_t;
|
|
|
|
struct SPIS
|
|
{
|
|
spi_type_e spi_type; // SPI类型
|
|
uint16_t delay_ticks; // 延时多少个NOP
|
|
spi_gpio_group_t gpios; // SPI引脚
|
|
spi_interface_t interface; // SPI接口
|
|
SPI_TypeDef *spi; // SPI外设
|
|
BOOL simualte_gpio; // 是否模拟GPIO
|
|
|
|
// DMA
|
|
DMA_TypeDef *dma; // 外部设置
|
|
uint32_t dma_rx_channel; // 外部设置
|
|
uint32_t dma_tx_channel; // 外部设置
|
|
__IO BOOL rx_dma_ok;
|
|
__IO BOOL tx_dma_ok;
|
|
spis_dma_callback *dma_rx_cb; // DMA接收回调函数
|
|
spis_dma_callback *dma_tx_cb; // DMA发送回调函数
|
|
};
|
|
|
|
extern spi_t *spi_create(spi_type_e spi_type, spi_gpio_group_t gpios, uint16_t delay_ticks); // 创建SPI
|
|
extern void spi_free(spi_t *spi); // 释放SPI
|
|
|
|
#endif // __SPIS_H__
|