#ifndef CORE_SPI_H_ #define CORE_SPI_H_ #include "kern/common.h" #include "arch.h" #define SPI1 (*((spi_regs_t*)(SPI1_BASE))) #define SPI3 (*((spi_regs_t*)(SPI3_BASE))) typedef enum { SPI_BAUD_RATE_FPCLK_DIV_2 = 0, SPI_BAUD_RATE_FPCLK_DIV_4 = 1, SPI_BAUD_RATE_FPCLK_DIV_8 = 2, SPI_BAUD_RATE_FPCLK_DIV_16 = 3, SPI_BAUD_RATE_FPCLK_DIV_32 = 4, SPI_BAUD_RATE_FPCLK_DIV_64 = 5, SPI_BAUD_RATE_FPCLK_DIV_128 = 6, SPI_BAUD_RATE_FPCLK_DIV_256 = 7, } spi_baud_rate_t; typedef enum { SPI_REG_DATA_SIZE_NOT_USED_0 = 0, SPI_REG_DATA_SIZE_NOT_USED_1 = 1, SPI_REG_DATA_SIZE_NOT_USED_2 = 2, SPI_REG_DATA_SIZE_4_BITS = 3, SPI_REG_DATA_SIZE_5_BITS = 4, SPI_REG_DATA_SIZE_6_BITS = 5, SPI_REG_DATA_SIZE_7_BITS = 6, SPI_REG_DATA_SIZE_8_BITS = 7, SPI_REG_DATA_SIZE_9_BITS = 8, SPI_REG_DATA_SIZE_10_BITS = 9, SPI_REG_DATA_SIZE_11_BITS = 10, SPI_REG_DATA_SIZE_12_BITS = 11, SPI_REG_DATA_SIZE_13_BITS = 12, SPI_REG_DATA_SIZE_14_BITS = 13, SPI_REG_DATA_SIZE_15_BITS = 14, SPI_REG_DATA_SIZE_16_BITS = 15, } spi_reg_data_size_t; typedef enum { SPI_FIFO_STATUS_EMPTY = 0, SPI_FIFO_STATUS_QUARTER = 1, SPI_FIFO_STATUS_HALF = 2, SPI_FIFO_STATUS_FULL = 3, } spi_fifo_status_t; typedef __IO struct { /* spi control register. */ #define spi_bidimode (1 << 15) /* Bidirectional data mode enable. */ #define spi_bidioe (1 << 14) /* Output enable in bidirectional mode */ #define spi_crcen (1 << 13) /* Hardware CRC calculation enable */ #define spi_crcnext (1 << 12) /* Transmit CRC next */ #define spi_crcl (1 << 11) /* CRC length */ #define spi_rxonly (1 << 10) /* Receive only mode enabled. */ #define spi_ssm (1 << 9) /* Software slave management */ #define spi_ssi (1 << 8) /* Internal slave select */ #define spi_lsbfirst (1 << 7) /* Frame format */ #define spi_spe (1 << 6) /* SPI enable */ #define spi_br (7 << 3) /* SPI enable */ #define spi_mstr (1 << 2) /* Master selection */ #define spi_cpol (1 << 1) /* Clock polarity */ #define spi_cpha (1 << 0) /* Clock phase */ uint32_t c_r1; /* spi control register #2 */ #define spi_ldma_tx (1 << 14) /* Last DMA transfer for transmission */ #define spi_ldma_rx (1 << 13) /* Last DMA transfer for reception */ #define spi_frxth (1 << 12) /* FIFO reception threshold */ #define spi_ds (0xF << 8) /* Data size */ #define spi_txeie (1 << 7) /* Tx buffer empty interrupt enable */ #define spi_rxneie (1 << 6) /* RX buffer not empty interrupt enable */ #define spi_errie (1 << 5) /* Error interrupt enable */ #define spi_frf (1 << 4) /* Frame format */ #define spi_nssp (1 << 3) /*: NSS pulse management */ #define spi_ssoe (1 << 2) /* SS output enable */ #define spi_txdmaen (1 << 1) /* Tx buffer DMA enable */ #define spi_rxdmaen (1 << 0) /* Rx buffer DMA enable */ uint32_t c_r2; /* spi status register. */ #define spi_ftlvl (3 << 11) /* Transmisison level */ #define spi_frlvl (3 << 9) /* Reception level */ #define spi_fre (1 << 8) /* Frame format error */ #define spi_bsy (1 << 7) /* Busy flag */ #define spi_ovr (1 << 6) /* Overrun flag */ #define spi_modf (1 << 5) /* Mode fault */ #define spi_crcerr (1 << 4) /* CRC error flag */ #define spi_txe (1 << 1) /* Transmit buffer empty */ #define spi_rxne (1 << 0) /* Receive buffer not empty */ uint32_t s_r; /* spi data register. Really only the least-significant 16 bits are used. * reading from this register reads from the Rx FIFO while writing to it * writes to the Tx FIFO. */ union { /* The lower 8 its of the spi data register. */ __IO uint8_t dl_r; /* The data register. */ __IO uint16_t d_r; }; __IO uint16_t unused; /* spi CRC polynomial register. */ uint32_t crcp_r; /* spi rx CRC register. */ uint32_t rxcrc_r; /* spi tx CRC register. */ uint32_t txcrc_r; } spi_regs_t; static_assert(offsetof(spi_regs_t, txcrc_r) == 0x18, "Offset check failed."); #endif /* CORE_SPI_H_ */