AnsweredAssumed Answered

SPI Slave missing interrupts (NUCLEO-F401RE)

Question asked by F. Pabst on Jun 12, 2018


im trying to implement a basic SPI full-duplex slave using HAL (the reason to use HAL here is that i have to switch to another STM MCU later).


The biggest problem is that the slave sometimes doesn't seem to react to interrupts in time / at all.


As Master i use a NUCLEO-F429ZI and as Slave a NUCLEO-F401RE.


The slave setup is being done by CubeMX (file attached).


I had a SPI full-duplex implemtation with several commands up and running already - but sadly it just works in ~95%  of time. I broke down the entire implementation I had before to:


void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi)
    HAL_GPIO_TogglePin(ERROR_GPIO_Port, ERROR_Pin);
    uint8_t txData = 0x01;
    uint8_t rxData = 0x00;
    HAL_SPI_TransmitReceive_IT(&hspi2, &txData, &rxData, 1);
    HAL_GPIO_TogglePin(ERROR_GPIO_Port, ERROR_Pin);


void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)

  // only CS pin is connected - all other EXTIs are tied low

  // so this function should mirror the CS pin - CS is just a DUMMY implentation as we use HW CS atm
  HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);


void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
  if (htim->Instance == TIM3)
    sensor_read_request = 1; // is unused atm


with HAL_SPI_TransmitReceive_IT(&hspi2, &txData, &rxData, 1) being called once in the beinning before main loop.


Master is continuously sending 1 byte, reading 1 bytes on the SPI bus using some µs delay inbetween for the slave being able to respond / TX.


uint8_t cmd = 0x02;

uint8_t data = 0x00;

uint8_t length = 1;


void SpiBusRead(uint8_t cmd, uint8_t* data, uint16_t length) {
    HAL_SPI_Transmit(&hspi4, &cmd, 1, HAL_MAX_DELAY);
    for (int ii = 0; ii < length; ii++) {
        HAL_SPI_Receive(&hspi4, &data[ii], 1, HAL_MAX_DELAY);


So in my Logic capture the slave should toggle LD2_Pin ech time the CS line is pulled. The ERROR_Pin should be toggled each time an SPI byte is received.


On the Master side I also have an ERROR_pin wich toggles when I detect something didn't work (further explanation coming later)


I tried both the HW CS and the SW CS for the slave - same problems on both [SW CS was implemented by using EXTI on CS PIN and use SET/CLEAR_BIT(hspi->Instance->CR1, SPI_CR1_SSI) ]


1. Worst case: EXTI  + SPI interrupt is missing:

2. Here we can see how often this error occurs - when doing the 2 byte thing continusouly

.3 In a more complex scenario sometimes just the SPI interrupt is missing:

Since this was a 2 byte read request - the answer in being send 1 byte too late and leads to corrupted data (0x0001 indead of 0x0101)


4. This also might happen in between:


5. Or just the EXTIs are skipped andd SPI is totaly fine:


All in all it seems to me something is blocking interrupts - or the HAL might have some hickups.


Any help appreciated.