mirror of https://github.com/Desuuuu/klipper.git
stm32: Add support for SPI1 and SPI3 busses
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
parent
04db5f95d2
commit
7031202e7c
|
@ -31,7 +31,7 @@ uint16_t gpio_adc_read(struct gpio_adc g);
|
|||
void gpio_adc_cancel_sample(struct gpio_adc g);
|
||||
|
||||
struct spi_config {
|
||||
void *spidev;
|
||||
void *spi;
|
||||
uint32_t spi_cr1;
|
||||
};
|
||||
struct spi_config spi_setup(uint32_t bus, uint8_t mode, uint32_t rate);
|
||||
|
|
|
@ -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++;
|
||||
|
|
Loading…
Reference in New Issue