(F4) Hardware SPI not driving SSEL pin correctly since v2.7.0 (affects STM32F4xx and others) #2834
-
| Since release 2.7.0, the SPI library no longer properly drives the SSEL (NSS) pin when using hardware SPI. This affects at least the STM32F4xx variants, and possibly others. When defining a new SPIClass instance with AF MOSI/MISO/SCLK/SSEL pins, or when calling SPI.setSSEL(AF_PIN), the SPI peripheral does not drive the SSEL pin as expected. This forces users to manually control the SSEL pin in software, which breaks compatibility with many libraries that rely on hardware-controlled chip select. This issue persists up to v2.11.0. My setup consists on using SPI2 with alternate function pins: 1- Use SPI2 (or other SPI peripheral) with alternate function pin mapping such as: const PinMap PinMap_SPI_MOSI[] = {
  {PB_15, SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)},
  {NC, NP, 0}
};
const PinMap PinMap_SPI_MISO[] = {
  {PB_14, SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)},
  {NC, NP, 0}
};
const PinMap PinMap_SPI_SCLK[] = {
  {PB_13, SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLDOWN, GPIO_AF5_SPI2)},
  {NC, NP, 0}
};
const PinMap PinMap_SPI_SSEL[] = {
  {PB_12, SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)},
  {NC, NP, 0}
};2- Instantiate SPI with these pins: SPIClass SPI_2(PB_15, PB_14, PB_13, PB_12);
SPI_2.begin();Attempt to communicate with a peripheral (e.g. MPU6500) using hardware-controlled SSEL. SPI_2.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE3));
SPI_2.transfer(data);
SPI_2.endTransaction();Observe that the SSEL pin is not driven by hardware, causing SPI communication to fail unless SSEL is handled manually via GPIO. Root Cause Analysis The issue was introduced in 2.7.0, where SPIClass::beginTransaction() stopped calling spi_init() unconditionally. Proposed Fix Always call spi_init() on beginTransaction(). void SPIClass::beginTransaction(SPISettings settings)
{
  if (_spiSettings != settings) {
    _spiSettings = settings;
+++ }
  spi_init(&_spi, _spiSettings.clockFreq,
           _spiSettings.dataMode,
           _spiSettings.bitOrder);
--- }
}This restores pre-2.7.0 behavior and fixes SSEL handling for all transactions. | 
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
| Hi @danieltr3s   And well described also here: About pre-2.7.0, in fact as the SPI always init, then the SPI was disabled, init then enabled producinf change on the SSEL pin. I've modified the Arduino SD library to be able to use the hardware NSS and tested with card info example and it works, using Hardware SS or not. I saw the signal is kept LOW but is is not an issue.   | 
Beta Was this translation helpful? Give feedback.

Hi @danieltr3s
In fact there is no issue.
If you read the Reference manual.
Example STM32F429ZI:
And well described also here:
https://community.st.com/t5/stm32-mcus-products/chip-select-of-spi-in-nucleo-f401re-stuck-low/m-p/721624/highlight/true#M261205
About pre-2.7.0, in fact as the SPI always init, then the SPI was disabled, init then enabled producinf change on the SSEL pin.
I've modified the Arduino SD library to be able to use the hardware NSS and tested with card info example and it works, using Hardware SS or not. I saw the signal is kept LOW but is is not an issue.
Software NSS
Hardware NSS