1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-01-17 05:12:57 +01:00

cpu/stm32/periph_spi: Fix /CS handling

Previously, the /CS signal was performed by enabling / disabling the
SPI peripheral. This had the disadvantage that clock polarity settings
where not applied starting with `spi_acquire()`, as assumed by e.g.
the SPI SD card driver, but only just before transmitting data.

Now the SPI peripheral is enabled on `spi_acquire()` and only disabled
when calling `spi_release()`, and the `SPI_CR2_SSOE` bit in the `CR2`
register is used for hardware /CS handling (as supposed to).
This commit is contained in:
Marian Buschsieweke 2023-11-13 16:13:02 +01:00
parent 7057aa674d
commit 63a2a50b5f
No known key found for this signature in database
GPG Key ID: 77AA882EC78084E6

View File

@ -29,7 +29,6 @@
#include <assert.h>
#include "bitarithm.h"
#include "cpu.h"
#include "mutex.h"
#include "periph/gpio.h"
#include "periph/spi.h"
@ -246,19 +245,19 @@ void spi_acquire(spi_t bus, spi_cs_t cs, spi_mode_t mode, spi_clk_t clk)
periph_apb_clk(spi_config[bus].apbbus)/(1 << (br + 1)),
br);
uint16_t cr1_settings = ((br << BR_SHIFT) | mode | SPI_CR1_MSTR);
uint16_t cr1 = ((br << BR_SHIFT) | mode | SPI_CR1_MSTR | SPI_CR1_SPE);
/* Settings to add to CR2 in addition to SPI_CR2_SETTINGS */
uint16_t cr2_extra_settings = 0;
uint16_t cr2 = SPI_CR2_SETTINGS;
if (cs != SPI_HWCS_MASK) {
cr1_settings |= (SPI_CR1_SSM | SPI_CR1_SSI);
cr1 |= (SPI_CR1_SSM | SPI_CR1_SSI);
}
else {
cr2_extra_settings = (SPI_CR2_SSOE);
cr2 = (SPI_CR2_SSOE);
}
#ifdef MODULE_PERIPH_DMA
if (_use_dma(&spi_config[bus])) {
cr2_extra_settings |= SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN;
cr2 |= SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN;
dma_acquire(spi_config[bus].tx_dma);
dma_setup(spi_config[bus].tx_dma,
@ -277,8 +276,8 @@ void spi_acquire(spi_t bus, spi_cs_t cs, spi_mode_t mode, spi_clk_t clk)
0);
}
#endif
dev(bus)->CR1 = cr1_settings;
dev(bus)->CR2 = (SPI_CR2_SETTINGS | cr2_extra_settings);
dev(bus)->CR1 = cr1;
dev(bus)->CR2 = cr2;
}
void spi_release(spi_t bus)
@ -393,10 +392,12 @@ void spi_transfer_bytes(spi_t bus, spi_cs_t cs, bool cont,
assert(out || in);
/* active the given chip select line */
dev(bus)->CR1 |= (SPI_CR1_SPE); /* this pulls the HW CS line low */
if ((cs != SPI_HWCS_MASK) && gpio_is_valid(cs)) {
gpio_clear((gpio_t)cs);
}
else {
dev(bus)->CR2 |= SPI_CR2_SSOE;
}
#ifdef MODULE_PERIPH_DMA
if (_use_dma(&spi_config[bus])) {
@ -411,9 +412,11 @@ void spi_transfer_bytes(spi_t bus, spi_cs_t cs, bool cont,
/* release the chip select if not specified differently */
if ((!cont) && gpio_is_valid(cs)) {
dev(bus)->CR1 &= ~(SPI_CR1_SPE); /* pull HW CS line high */
if (cs != SPI_HWCS_MASK) {
gpio_set((gpio_t)cs);
}
else {
dev(bus)->CR2 &= ~(SPI_CR2_SSOE);
}
}
}