From 8b9cc62359057a686929cc713ffe2931e2203946 Mon Sep 17 00:00:00 2001 From: Kevin O'Connor Date: Sun, 28 Jul 2019 23:15:54 -0400 Subject: stm32: Rename stm32f4/ directory to stm32/ Now that the code in stm32f4/ can handle both stm32f1 and stm32f4 chips, rename the directory to just "stm32". Signed-off-by: Kevin O'Connor --- src/stm32/spi.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 src/stm32/spi.c (limited to 'src/stm32/spi.c') diff --git a/src/stm32/spi.c b/src/stm32/spi.c new file mode 100644 index 00000000..77072958 --- /dev/null +++ b/src/stm32/spi.c @@ -0,0 +1,59 @@ +// SPI functions on STM32 +// +// Copyright (C) 2019 Kevin O'Connor +// +// This file may be distributed under the terms of the GNU GPLv3 license. + +#include "command.h" // shutdown +#include "gpio.h" // spi_setup +#include "internal.h" // gpio_peripheral +#include "sched.h" // sched_shutdown + +DECL_ENUMERATION("spi_bus", "spi2", 0); +DECL_CONSTANT_STR("BUS_PINS_spi2", "PB14,PB15,PB13"); + +struct spi_config +spi_setup(uint32_t bus, uint8_t mode, uint32_t rate) +{ + if (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); + } + + // Calculate CR1 register + uint32_t pclk = get_pclock_frequency(SPI2_BASE); + 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 }; +} + +void +spi_prepare(struct spi_config config) +{ + SPI2->CR1 = config.spi_cr1; +} + +void +spi_transfer(struct spi_config config, uint8_t receive_data, + uint8_t len, uint8_t *data) +{ + while (len--) { + SPI2->DR = *data; + while (!(SPI2->SR & SPI_SR_RXNE)) + ; + uint8_t rdata = SPI2->DR; + if (receive_data) + *data = rdata; + data++; + } +} -- cgit v1.2.3-70-g09d2