/*** * @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__