This repository has been archived on 2025-01-02. You can view files and clone it, but cannot push or open issues or pull requests.
torsion/User/system/bsp/spis.h

121 lines
3.8 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_spi(_spi); // LCD模拟IO比较慢
_spi->spix = 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 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_spi)(spi_t *handle, SPI_TypeDef *spix); // 硬件SPI
} 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接口
BOOL simulate_gpio; // 是否模拟GPIO,默认使用IO模拟SPI
SPI_TypeDef *spix; // SPI外设
};
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__