Skip to content

Commit 3152208

Browse files
committed
TARGET_STM: L0 CUBE SPI async mode send next byte after previous one read
In STM32 Cube HAL, in interrupt mode (async), 2 bytes can be prepared in hardware registers without any read (1 in regular register, the other in shift register), but Only 1 RX byte can stored in hardware register, specially when there is no hardware FIFO. If interrupt handling is fast enough, each read is made in parralele of the write. But if interrupt handling is too long or is interrupted for too long, it can happen that one read byte is lost (overrun). For STM32F4, Tickless has been deactivated to avoid such issue. For STM32L0, we don't want to deactivate tickless, because those chips are specially design for lowpower. So instead of removing SPI async mode, we propose to change the HAL behavior specially for L0: each byte is send only when previous read is performed. Thus only 1 RX byte at a time which is saved in hardware register. This prevent overrun, but it introduceS some latency between each byte send, this is why it is not applied to all STM32 families.
1 parent 443802a commit 3152208

File tree

1 file changed

+14
-1
lines changed

1 file changed

+14
-1
lines changed

targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_spi.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1239,7 +1239,7 @@ HAL_StatusTypeDef HAL_SPI_TransmitReceive_IT(SPI_HandleTypeDef *hspi, uint8_t *p
12391239
}
12401240

12411241
/* Enable TXE, RXNE and ERR interrupt */
1242-
__HAL_SPI_ENABLE_IT(hspi, (SPI_IT_TXE | SPI_IT_RXNE | SPI_IT_ERR));
1242+
__HAL_SPI_ENABLE_IT(hspi, (SPI_IT_RXNE | SPI_IT_ERR)); // MBED patch: Send next byte in hardware register only after previous one is read
12431243

12441244
/* Process Unlocked */
12451245
__HAL_UNLOCK(hspi);
@@ -1251,6 +1251,11 @@ HAL_StatusTypeDef HAL_SPI_TransmitReceive_IT(SPI_HandleTypeDef *hspi, uint8_t *p
12511251
__HAL_SPI_ENABLE(hspi);
12521252
}
12531253

1254+
/* MBED patch: Send next byte in hardware register only after previous one is read
1255+
Start 1st byte transmission (function is the same than for ISR), further transmissions will be trigger by RX interrupt */
1256+
hspi->TxISR(hspi);
1257+
1258+
12541259
return HAL_OK;
12551260
}
12561261
else
@@ -1650,6 +1655,14 @@ void HAL_SPI_IRQHandler(SPI_HandleTypeDef *hspi)
16501655
if((__HAL_SPI_GET_IT_SOURCE(hspi, SPI_IT_RXNE) != RESET) && (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE) != RESET) && (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_OVR) == RESET))
16511656
{
16521657
hspi->RxISR(hspi);
1658+
/* MBED patch Send next byte in hardware register only after previous one is read to avoid overrun */
1659+
if ((hspi->Init.Mode == SPI_MODE_MASTER) && (hspi->Init.Direction == SPI_DIRECTION_2LINES)) {
1660+
if ((__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE) != RESET) && (hspi->TxXferCount != 0U))
1661+
{
1662+
hspi->TxISR(hspi);
1663+
}
1664+
}
1665+
16531666
return;
16541667
}
16551668

0 commit comments

Comments
 (0)