aboutsummaryrefslogtreecommitdiffstats
path: root/src/stm32/spi.c
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2019-08-31 19:51:51 -0400
committerKevin O'Connor <kevin@koconnor.net>2019-08-31 19:55:30 -0400
commit7031202e7c2c7f96eb351399f629d718e7733388 (patch)
treee7dda78c16419645393d641a73c58615eb912c8b /src/stm32/spi.c
parent04db5f95d207749a370d5f4e0e3e9bdef2026ee3 (diff)
downloadkutter-7031202e7c2c7f96eb351399f629d718e7733388.tar.gz
kutter-7031202e7c2c7f96eb351399f629d718e7733388.tar.xz
kutter-7031202e7c2c7f96eb351399f629d718e7733388.zip
stm32: Add support for SPI1 and SPI3 busses
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Diffstat (limited to 'src/stm32/spi.c')
-rw-r--r--src/stm32/spi.c46
1 files changed, 34 insertions, 12 deletions
diff --git a/src/stm32/spi.c b/src/stm32/spi.c
index 77072958..c5e36022 100644
--- a/src/stm32/spi.c
+++ b/src/stm32/spi.c
@@ -9,49 +9,71 @@
#include "internal.h" // gpio_peripheral
#include "sched.h" // sched_shutdown
+struct spi_info {
+ void *spi;
+ uint8_t miso_pin, mosi_pin, sck_pin, function;
+};
+
DECL_ENUMERATION("spi_bus", "spi2", 0);
DECL_CONSTANT_STR("BUS_PINS_spi2", "PB14,PB15,PB13");
+DECL_ENUMERATION("spi_bus", "spi1", 1);
+DECL_CONSTANT_STR("BUS_PINS_spi1", "PA6,PA7,PA5");
+#ifdef SPI3
+DECL_ENUMERATION("spi_bus", "spi3", 2);
+DECL_CONSTANT_STR("BUS_PINS_spi3", "PB4,PB5,PB3");
+#endif
+
+static const struct spi_info spi_bus[] = {
+ { SPI2, GPIO('B', 14), GPIO('B', 15), GPIO('B', 13), GPIO_FUNCTION(5) },
+ { SPI1, GPIO('A', 6), GPIO('A', 7), GPIO('A', 5), GPIO_FUNCTION(5) },
+#ifdef SPI3
+ { SPI3, GPIO('B', 4), GPIO('B', 5), GPIO('B', 3), GPIO_FUNCTION(6) },
+#endif
+};
struct spi_config
spi_setup(uint32_t bus, uint8_t mode, uint32_t rate)
{
- if (bus)
+ if (bus >= ARRAY_SIZE(spi_bus))
shutdown("Invalid spi bus");
// Enable SPI
- if (!is_enabled_pclock(SPI2_BASE)) {
- enable_pclock(SPI2_BASE);
- gpio_peripheral(GPIO('B', 14), GPIO_FUNCTION(5), 1);
- gpio_peripheral(GPIO('B', 15), GPIO_FUNCTION(5), 0);
- gpio_peripheral(GPIO('B', 13), GPIO_FUNCTION(5), 0);
+ SPI_TypeDef *spi = spi_bus[bus].spi;
+ if (!is_enabled_pclock((uint32_t)spi)) {
+ enable_pclock((uint32_t)spi);
+ gpio_peripheral(spi_bus[bus].miso_pin, spi_bus[bus].function, 1);
+ gpio_peripheral(spi_bus[bus].mosi_pin, spi_bus[bus].function, 0);
+ gpio_peripheral(spi_bus[bus].sck_pin, spi_bus[bus].function, 0);
}
// Calculate CR1 register
- uint32_t pclk = get_pclock_frequency(SPI2_BASE);
+ uint32_t pclk = get_pclock_frequency((uint32_t)spi);
uint32_t div = 0;
while ((pclk >> (div + 1)) > rate && div < 7)
div++;
uint32_t cr1 = ((mode << SPI_CR1_CPHA_Pos) | (div << SPI_CR1_BR_Pos)
| SPI_CR1_SPE | SPI_CR1_MSTR | SPI_CR1_SSM | SPI_CR1_SSI);
- return (struct spi_config){ .spi_cr1 = cr1 };
+ return (struct spi_config){ .spi = spi, .spi_cr1 = cr1 };
}
void
spi_prepare(struct spi_config config)
{
- SPI2->CR1 = config.spi_cr1;
+ SPI_TypeDef *spi = config.spi;
+ spi->CR1 = config.spi_cr1;
}
void
spi_transfer(struct spi_config config, uint8_t receive_data,
uint8_t len, uint8_t *data)
{
+ SPI_TypeDef *spi = config.spi;
while (len--) {
- SPI2->DR = *data;
- while (!(SPI2->SR & SPI_SR_RXNE))
+ spi->DR = *data;
+ while (!(spi->SR & SPI_SR_RXNE))
;
- uint8_t rdata = SPI2->DR;
+ uint8_t rdata = spi->DR;
if (receive_data)
*data = rdata;
data++;