From 67a44c4636e73410b6418dba66fed649b0e8e470 Mon Sep 17 00:00:00 2001 From: jflyper Date: Mon, 21 Aug 2017 11:23:09 +0900 Subject: [PATCH 1/3] Clock divisor for SPI2 and SPI3 must be halved --- src/main/drivers/bus_spi.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/main/drivers/bus_spi.c b/src/main/drivers/bus_spi.c index 61f441ac75..4ff35aeb66 100644 --- a/src/main/drivers/bus_spi.c +++ b/src/main/drivers/bus_spi.c @@ -249,6 +249,8 @@ bool spiTransfer(SPI_TypeDef *instance, const uint8_t *txData, uint8_t *rxData, return true; } +#include "build/debug.h" + bool spiBusTransfer(const busDevice_t *bus, const uint8_t *txData, uint8_t *rxData, int length) { IOLo(bus->busdev_u.spi.csnPin); @@ -259,10 +261,17 @@ bool spiBusTransfer(const busDevice_t *bus, const uint8_t *txData, uint8_t *rxDa void spiSetDivisor(SPI_TypeDef *instance, uint16_t divisor) { -#define BR_CLEAR_MASK 0xFFC7 +#define BR_BITS ((BIT(5) | BIT(4) | BIT(3))) + + // SPI2 and SPI3 are always on APB1/AHB1 which PCLK is half that of APB2/AHB2. + + if (instance == SPI2 || instance == SPI3) { + divisor /= 2; // Safe for divisor == 0 or 1 + } + SPI_Cmd(instance, DISABLE); - const uint16_t tempRegister = (instance->CR1 & BR_CLEAR_MASK); + const uint16_t tempRegister = (instance->CR1 & ~BR_BITS); instance->CR1 = (tempRegister | ((ffs(divisor | 0x100) - 2) << 3)); SPI_Cmd(instance, ENABLE); From 6936601415559288e836df7e6382bd4d2ae101c7 Mon Sep 17 00:00:00 2001 From: jflyper Date: Mon, 21 Aug 2017 16:19:40 +0900 Subject: [PATCH 2/3] Undefine BR_BITS for safety --- src/main/drivers/bus_spi.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/drivers/bus_spi.c b/src/main/drivers/bus_spi.c index 4ff35aeb66..9def6956e2 100644 --- a/src/main/drivers/bus_spi.c +++ b/src/main/drivers/bus_spi.c @@ -275,6 +275,8 @@ void spiSetDivisor(SPI_TypeDef *instance, uint16_t divisor) instance->CR1 = (tempRegister | ((ffs(divisor | 0x100) - 2) << 3)); SPI_Cmd(instance, ENABLE); + +#undef BR_BITS } uint16_t spiGetErrorCounter(SPI_TypeDef *instance) From ee329328feba56be6a763a9b5b732581a6893d45 Mon Sep 17 00:00:00 2001 From: jflyper Date: Tue, 22 Aug 2017 00:44:06 +0900 Subject: [PATCH 3/3] Handle LL case --- src/main/drivers/bus_spi_ll.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/main/drivers/bus_spi_ll.c b/src/main/drivers/bus_spi_ll.c index d7caf0911f..24abef5a91 100644 --- a/src/main/drivers/bus_spi_ll.c +++ b/src/main/drivers/bus_spi_ll.c @@ -302,13 +302,14 @@ bool spiBusTransfer(const busDevice_t *bus, const uint8_t *txData, uint8_t *rxDa void spiSetDivisor(SPI_TypeDef *instance, uint16_t divisor) { + // SPI2 and SPI3 are always on APB1/AHB1 which PCLK is half that of APB2/AHB2. + + if (instance == SPI2 || instance == SPI3) { + divisor /= 2; // Safe for divisor == 0 or 1 + } + LL_SPI_Disable(instance); -#define BR_CLEAR_MASK 0xFFC7 - - const uint16_t tempRegister = (instance->CR1 & BR_CLEAR_MASK); - instance->CR1 = (tempRegister | ((ffs(divisor | 0x100) - 2) << 3)); - - //LL_SPI_SetBaudRatePrescaler(instance, baudRatePrescaler); + LL_SPI_SetBaudRatePrescaler(instance, (ffs(divisor | 0x100) - 2) << SPI_CR1_BR_Pos); LL_SPI_Enable(instance); }