/** * @file spi_driver.h * @brief SPI driver interface */ #ifndef SPI_DRIVER_H #define SPI_DRIVER_H #include #include #include "kernel.h" /* SPI Configuration Constants */ #define SPI_MAX_INSTANCES 4 #define SPI_MAX_BUFFER_SIZE 4096 #define SPI_MAX_TRANSFER_SIZE 65535 /* SPI Modes */ typedef enum { SPI_MODE_0 = 0, /* CPOL=0, CPHA=0 */ SPI_MODE_1 = 1, /* CPOL=0, CPHA=1 */ SPI_MODE_2 = 2, /* CPOL=1, CPHA=0 */ SPI_MODE_3 = 3 /* CPOL=1, CPHA=1 */ } SpiMode_t; /* SPI Clock Speeds */ typedef enum { SPI_CLOCK_1MHZ = 1000000, SPI_CLOCK_2MHZ = 2000000, SPI_CLOCK_4MHZ = 4000000, SPI_CLOCK_8MHZ = 8000000, SPI_CLOCK_16MHZ = 16000000, SPI_CLOCK_32MHZ = 32000000 } SpiClockSpeed_t; /* SPI Data Order */ typedef enum { SPI_DATA_ORDER_MSB_FIRST = 0, SPI_DATA_ORDER_LSB_FIRST = 1 } SpiDataOrder_t; /* SPI Chip Select */ typedef enum { SPI_CS_ACTIVE_LOW = 0, SPI_CS_ACTIVE_HIGH = 1 } SpiChipSelectPolarity_t; /* SPI Transfer Status */ typedef enum { SPI_TRANSFER_COMPLETE = 0, SPI_TRANSFER_ERROR = 1, SPI_TRANSFER_TIMEOUT = 2, SPI_TRANSFER_DMA_COMPLETE = 3 } SpiTransferStatus_t; /* SPI Callbacks */ typedef void (*SpiTransferCompleteCallback_t)(SpiTransferStatus_t status, void* user_data); /* SPI Configuration */ typedef struct { SpiMode_t mode; SpiClockSpeed_t clock_speed; SpiDataOrder_t data_order; uint8_t data_size; /* 8 or 16 bits */ bool use_dma; bool enable_hardware_cs; SpiChipSelectPolarity_t cs_polarity; uint8_t cs_port; uint8_t cs_pin; SpiTransferCompleteCallback_t transfer_complete_callback; } SpiConfig_t; /* SPI Statistics */ typedef struct { uint32_t transfers_completed; uint32_t transfers_failed; uint32_t bytes_transferred; uint32_t dma_transfers; uint32_t overrun_errors; uint32_t underrun_errors; uint32_t timeout_errors; } SpiStatistics_t; /* SPI Transaction */ typedef struct { const uint8_t* tx_data; uint8_t* rx_data; uint16_t length; bool keep_cs_active; void* user_data; } SpiTransaction_t; /* SPI Driver Interface */ KernelStatus_t spi_init(uint8_t instance, SpiConfig_t* config); KernelStatus_t spi_deinit(uint8_t instance); KernelStatus_t spi_transfer(uint8_t instance, const SpiTransaction_t* transaction, uint32_t timeout_ms); KernelStatus_t spi_transfer_async(uint8_t instance, const SpiTransaction_t* transaction); KernelStatus_t spi_read(uint8_t instance, uint8_t* data, uint16_t length, uint32_t timeout_ms); KernelStatus_t spi_write(uint8_t instance, const uint8_t* data, uint16_t length, uint32_t timeout_ms); KernelStatus_t spi_read_write(uint8_t instance, const uint8_t* tx_data, uint8_t* rx_data, uint16_t length, uint32_t timeout_ms); KernelStatus_t spi_get_statistics(uint8_t instance, SpiStatistics_t* stats); void spi_set_chip_select(uint8_t instance, bool active); void spi_process_interrupt(uint8_t instance); #endif /* SPI_DRIVER_H */