diff options
Diffstat (limited to 'include/kern/spi/spi_manager.h')
-rw-r--r-- | include/kern/spi/spi_manager.h | 179 |
1 files changed, 179 insertions, 0 deletions
diff --git a/include/kern/spi/spi_manager.h b/include/kern/spi/spi_manager.h new file mode 100644 index 0000000..53e4c2a --- /dev/null +++ b/include/kern/spi/spi_manager.h @@ -0,0 +1,179 @@ +#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_ */ |