#ifndef KERN_SPI_SPI_MANAGER_H_ #define KERN_SPI_SPI_MANAGER_H_ #include "kern/common.h" #define SPI_ERROR_ALREADY_IN_USE 1 #define SPI_ERROR_SELECTION_NOT_VALID 2 typedef enum { SPI_CRCL_8_BITS, SPI_CRCL_16_BITS } spi_crcl_t; typedef enum { SPI_DATA_SIZE_NOT_USED_0 = 0, SPI_DATA_SIZE_NOT_USED_1 = 1, SPI_DATA_SIZE_NOT_USED_2 = 2, SPI_DATA_SIZE_4_BITS = 3, SPI_DATA_SIZE_5_BITS = 4, SPI_DATA_SIZE_6_BITS = 5, SPI_DATA_SIZE_7_BITS = 6, SPI_DATA_SIZE_8_BITS = 7, SPI_DATA_SIZE_9_BITS = 8, SPI_DATA_SIZE_10_BITS = 9, SPI_DATA_SIZE_11_BITS = 10, SPI_DATA_SIZE_12_BITS = 11, SPI_DATA_SIZE_13_BITS = 12, SPI_DATA_SIZE_14_BITS = 13, SPI_DATA_SIZE_15_BITS = 14, SPI_DATA_SIZE_16_BITS = 15, } spi_data_size_t; typedef enum { SPI_BAUD_FPCLK_DIV_2 = 0, SPI_BAUD_FPCLK_DIV_4 = 1, SPI_BAUD_FPCLK_DIV_8 = 2, SPI_BAUD_FPCLK_DIV_16 = 3, SPI_BAUD_FPCLK_DIV_32 = 4, SPI_BAUD_FPCLK_DIV_64 = 5, SPI_BAUD_FPCLK_DIV_128 = 6, SPI_BAUD_FPCLK_DIV_256 = 7, } spi_baud_t; typedef enum { SPI_MODE_MASTER, SPI_MODE_SLAVE } spi_mode_t; typedef enum { SPI_POLARITY_0, SPI_POLARITY_1 } spi_polarity_t; typedef enum { /* The first clock transition is the first data capture edge. */ SPI_CLOCK_PHASE_FIRST, /* The second clock transition is the first data capture edge. */ SPI_CLOCK_PHASE_SECOND, } spi_clock_phase_t; typedef enum { SPI_DMA_PARITY_EVEN, SPI_DMA_PARITY_ODD, } spi_dma_parity_t; typedef enum { SPI_FIFO_THRESHOLD_HALF, SPI_FIFO_THRESHOLD_QUARTER, } spi_fifo_threshold_t; typedef enum { SPI_FRAME_FORMAT_MOTOROLA, SPI_FRAME_FORMAT_TI, } spi_frame_format_t; typedef struct { bool enable_bidirectional_data_mode; /* Enable hardware crc checking. */ bool enable_crc; /* CRC length. */ spi_crcl_t crc_length; bool receieve_only; bool enable_software_slave_management; bool internal_slave_select; endianness_t endianness; spi_baud_t baud; spi_mode_t spi_mode; spi_polarity_t polarity; spi_clock_phase_t clock_phase; spi_dma_parity_t number_of_data_parity_tx; spi_dma_parity_t number_of_data_parity_rx; spi_fifo_threshold_t rx_interrupt_fifo_threshold; spi_data_size_t data_size; bool enable_tx_buffer_empty_interrupt; bool enable_rx_buffer_not_empty_interrupt; bool enable_error_interrupt; spi_frame_format_t frame_format; bool enable_nss_pulse; bool enable_ss_output; bool enable_tx_dma; bool enable_rx_dma; union { struct { bool output_enable; } bidir_opts_t; }; } spi_opts_t; #define DEFAULT_SPI_OPTS { \ .enable_bidirectional_data_mode = 0,\ .enable_crc = 0,\ .crc_length = SPI_CRCL_8_BITS,\ .receieve_only = 0,\ .enable_software_slave_management = 1,\ .internal_slave_select = 1,\ .endianness = ENDIANNESS_LITTLE,\ .baud = SPI_BAUD_FPCLK_DIV_32,\ .spi_mode = SPI_MODE_MASTER,\ .polarity = SPI_POLARITY_0,\ .clock_phase = SPI_CLOCK_PHASE_FIRST,\ .number_of_data_parity_tx = SPI_DMA_PARITY_EVEN,\ .number_of_data_parity_rx = SPI_DMA_PARITY_EVEN,\ .rx_interrupt_fifo_threshold = SPI_FIFO_THRESHOLD_HALF,\ .data_size = SPI_DATA_SIZE_8_BITS,\ .enable_tx_buffer_empty_interrupt = 0,\ .enable_rx_buffer_not_empty_interrupt = 0,\ .enable_error_interrupt = 0,\ .frame_format = SPI_FRAME_FORMAT_MOTOROLA,\ .enable_nss_pulse = 0,\ .enable_ss_output = 0,\ .enable_tx_dma = 0 ,\ .enable_rx_dma = 0,\ } typedef struct spi spi_t; typedef enum { #define SPI(sp, u) SPI_SELECT_##sp, #include "arch/stm32l4xxx/peripherals/tables/stm32l432xx/spi/buses.inc" #undef SPI N_SPI_SELECT } spi_select_t; /* Reserve a spi bus. If an error occurs, NULL is returned * and *ec is set to the appropriate value. */ spi_t* reserve_spi(spi_select_t spi_select, spi_opts_t* opts, int* ec); /* Sets the SPI to enable. */ void spi_start(spi_t* spi); /* Release the spi bus. */; void release_spi(spi_t* spi); void spi_set_crc_next(spi_t* spi); void spi_write_8_sync(spi_t* spi, uint8_t data); void spi_write_16_sync(spi_t* spi, uint16_t data); uint8_t spi_read_8_sync(spi_t* spi); uint16_t spi_read_16_sync(spi_t* spi); #endif /* KERN_SPI_SPI_MANAGER_H_ */