diff options
-rw-r--r-- | 02-usart/include/arch/arm/arch.h | 3 | ||||
-rw-r--r-- | 02-usart/include/arch/x86_64/arch.h | 3 | ||||
-rw-r--r-- | 02-usart/include/core/spi.h | 102 | ||||
-rw-r--r-- | 02-usart/test_harness/fake_env.c | 4 | ||||
-rw-r--r-- | 02-usart/test_harness/fake_env.h | 2 | ||||
-rw-r--r-- | 02-usart/tests/test_spi.c | 11 |
6 files changed, 125 insertions, 0 deletions
diff --git a/02-usart/include/arch/arm/arch.h b/02-usart/include/arch/arm/arch.h index f140c97..42b33bb 100644 --- a/02-usart/include/arch/arm/arch.h +++ b/02-usart/include/arch/arm/arch.h @@ -28,6 +28,9 @@ #define NVIC_BASE (0xE000E004) #define RCC_BASE (0x40021000) +#define SPI1_BASE (0x40013000) +#define SPI3_BASE (0x40003C00) + #include <stdint.h> #ifndef DRY_RUN _Static_assert(sizeof(void*) == sizeof(uint32_t), "Pointers must be 32 bits"); diff --git a/02-usart/include/arch/x86_64/arch.h b/02-usart/include/arch/x86_64/arch.h index e87559b..5e1217c 100644 --- a/02-usart/include/arch/x86_64/arch.h +++ b/02-usart/include/arch/x86_64/arch.h @@ -24,6 +24,9 @@ #define SYSTEM_CONFIG_BLOCK_BASE (load_fake_scb__()) #define NVIC_BASE (load_fake_nvic__()) +#define SPI1_BASE (load_fake_spi1__()) +#define SPI3_BASE (load_fake_spi3__()) + // Pretend there's a data segement at the start of SRAM1 for more accurate // testing. #define GHOST_DATA_SEGMENT_SIZE 1234 diff --git a/02-usart/include/core/spi.h b/02-usart/include/core/spi.h new file mode 100644 index 0000000..77cd61e --- /dev/null +++ b/02-usart/include/core/spi.h @@ -0,0 +1,102 @@ +#ifndef CORE_SPI_H_ +#define CORE_SPI_H_ + +#include "common.h" +#include "arch.h" + +#define SPI1 (*((spi_t*)(SPI1_BASE))) +#define SPI3 (*((spi_t*)(SPI3_BASE))) + +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_rate_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 __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. */ + __IO uint32_t d_r; + + /* 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_t; + +static_assert(offsetof(spi_t, txcrc_r) == 0x18, "Offset check failed."); + +#endif /* CORE_SPI_H_ */ diff --git a/02-usart/test_harness/fake_env.c b/02-usart/test_harness/fake_env.c index 43a6caa..3175317 100644 --- a/02-usart/test_harness/fake_env.c +++ b/02-usart/test_harness/fake_env.c @@ -35,3 +35,7 @@ DEFINE_MEMORY_SEGMENT(nvic, 0xE000E004, 0xE000E4F0) /* SRAM */ DEFINE_MEMORY_SEGMENT(sram1, 0x20000000, 0x2000C000) DEFINE_MEMORY_SEGMENT(sram2, 0x2000C000, 0x20018000) + +/* Serial Peripheral Interface */ +DEFINE_MEMORY_SEGMENT(spi1, 0x40013000, 0x400133FF) +DEFINE_MEMORY_SEGMENT(spi3, 0x40003C00, 0x40003FFF) diff --git a/02-usart/test_harness/fake_env.h b/02-usart/test_harness/fake_env.h index 787abf5..73323cf 100644 --- a/02-usart/test_harness/fake_env.h +++ b/02-usart/test_harness/fake_env.h @@ -12,5 +12,7 @@ void* load_fake_sram2__(); void* load_fake_scb__(); void* load_fake_nvic__(); void* load_fake_rcc__(); +void* load_fake_spi1__(); +void* load_fake_spi3__(); #endif /* FAKE_ENV_H_ */ diff --git a/02-usart/tests/test_spi.c b/02-usart/tests/test_spi.c new file mode 100644 index 0000000..d6cc24e --- /dev/null +++ b/02-usart/tests/test_spi.c @@ -0,0 +1,11 @@ +#include "test_harness.h" + +#include "core/spi.h" + +TEST(spi, smoke) +{ + __IO spi_t* spi = &SPI1; + spi->s_r = 1; + + return 0; +} |