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:
parent
7057aa674d
commit
63a2a50b5f
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user