/** * @file spis.h * @brief SPI驱动, 用于SPI设备的读写操作 * * This file contains the SPI driver used for reading and writing operations on SPI devices. * * @date 2023-08-01 * @version 1.0 * * @note This file is part of the STM32 controller-v2 project. * */ #ifndef __SPIS_H__ #define __SPIS_H__ #include "lib.h" #include "gpios.h" #define SPI_ENABLE(SPIX) LL_SPI_Enable(SPIX) typedef struct GPIO gpio_t; typedef struct SPIS spi_t; typedef void spis_dma_callback(spi_t *handle); /** * @brief SPI type enumeration */ typedef enum { SPI_TYPE_NORMAL = 0, ///< SPI1:NORMAL SPI_TYPE_LCD, ///< SPI2:LCD SPI_TYPE_MAX, } spi_type_e; /** * @brief SPI GPIO group structure */ 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; /** * @brief SPI normal interface structure */ typedef struct { uint8_t (*write_reg)(spi_t *handle, uint8_t reg, uint8_t data); ///< Write a single register via SPI uint8_t (*read_reg)(spi_t *handle, uint8_t reg); ///< Read the value of a single register via SPI uint8_t (*read_drdy)(spi_t *handle); ///< Get the value of the SPI DRDY pin uint8_t (*write_regs)(spi_t *handle, uint8_t reg, uint8_t *data, uint8_t len); ///< Write multiple registers via SPI uint8_t (*read_regs)(spi_t *handle, uint8_t reg, uint8_t *data, uint8_t len); ///< Read multiple registers via SPI uint8_t (*spi_send)(spi_t *handle, uint8_t data); ///< Send data via SPI void (*spi_reset)(spi_t *handle); ///< Reset SPI BOOL(*spi_write) (spi_t *handle, uint32_t write_addr, uint8_t *data, uint16_t length); ///< Write data via SPI BOOL(*spi_read) (spi_t *handle, uint32_t read_addr, uint8_t *data, uint16_t length); ///< Read data via SPI void (*spi_write_reg)(spi_t *handle, uint8_t reg, uint8_t data); ///< Write a single register via SPI uint8_t (*spi_read_reg)(spi_t *handle, uint8_t reg); ///< Read a single register via SPI } spi_normal_interface_t; /** * @brief SPI LCD interface structure */ typedef struct { uint8_t (*write_cmd)(spi_t *handle, uint8_t cmd); ///< Write a command via SPI uint8_t (*write_data)(spi_t *handle, uint8_t *data, uint16_t len); ///< Write data via SPI } spi_lcd_interface_t; /** * @brief SPI interface structure */ typedef struct { union { spi_normal_interface_t normal; spi_lcd_interface_t lcd; } u; void (*hardware_enable)(spi_t *handle, SPI_TypeDef *spi); ///< Enable hardware 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); ///< Enable DMA SPI void (*spi_dma_callback)(spi_t *spi); ///< DMA send completion callback BOOL(*spi_dma_send) (spi_t *handle, uint8_t *data, uint16_t length); ///< DMA send } spi_interface_t; /** * @brief SPI structure */ typedef struct SPIS spi_t; /** * @brief SPI DMA callback function */ typedef void spis_dma_callback(spi_t *handle); typedef struct { // CMD uint8_t cmd_rdsr; ///< Read Status Register instruction uint8_t cmd_wrsr; ///< Write Status Register instruction uint8_t cmd_wren; ///< Write enable instruction uint8_t cmd_wrdi; ///< Write disable instruction uint8_t cmd_read; ///< Read from Memory instruction uint8_t cmd_write; ///< Write to Memory instruction uint8_t dummy_byte; ///< Dummy byte uint8_t address_bytes; uint32_t page_size; uint32_t total_size; uint8_t ticks; ///< Delay in NOP ticks BOOL continuous_write; ///< Continuous write } spi_normal_config_t; struct SPIS { spi_type_e spi_type; ///< SPI type uint16_t delay_ticks; ///< Delay in NOP ticks spi_gpio_group_t gpios; ///< SPI GPIOs spi_interface_t interface; ///< SPI interface SPI_TypeDef *spi; ///< SPI peripheral BOOL simualte_gpio; ///< Simulate GPIO spi_normal_config_t cfg; ///< Normal SPI configuration ///< DMA DMA_TypeDef *dma; ///< External setting uint32_t dma_rx_channel; ///< External setting uint32_t dma_tx_channel; ///< External setting __IO BOOL rx_dma_ok; __IO BOOL tx_dma_ok; spis_dma_callback *dma_rx_cb; ///< DMA receive callback function spis_dma_callback *dma_tx_cb; ///< DMA send callback function void *params; ///< 扩展参数 }; /** * @brief Create a new SPI instance * * @param spi_type The type of SPI * @param gpios The SPI GPIO group * @param delay_ticks The delay in NOP ticks * @return spi_t* The created SPI instance */ extern spi_t *spi_create(spi_type_e spi_type, spi_gpio_group_t gpios, uint16_t delay_ticks); /** * @brief Free the SPI instance * * @param spi The SPI instance to free */ extern void spi_free(spi_t *spi); #endif ///< __SPIS_H__