From 6aacaa36d691cf588710b1c65ed5396b7411fded Mon Sep 17 00:00:00 2001 From: Hansem Ro Date: Thu, 22 Dec 2022 12:15:49 -0800 Subject: [PATCH] HT32: SPI: avoid write collisions when SPI FIFO is disabled This fixes possible write collisions experienced when SPI FIFO is disabled due to not checking whether the SPI shift register is empty before writing. This is done by checking TXE flag instead of TXBE flag when the FIFO is not used. --- os/common/ext/CMSIS/HT32/HT32F165x/ht32f165x_reg.h | 1 + os/common/ext/CMSIS/HT32/HT32F523xx/ht32f523x2_reg.h | 1 + os/hal/ports/HT32/LLD/SPIv1/hal_spi_lld.c | 12 +++++++++--- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/os/common/ext/CMSIS/HT32/HT32F165x/ht32f165x_reg.h b/os/common/ext/CMSIS/HT32/HT32F165x/ht32f165x_reg.h index 7d7c7938b1..b93b660149 100644 --- a/os/common/ext/CMSIS/HT32/HT32F165x/ht32f165x_reg.h +++ b/os/common/ext/CMSIS/HT32/HT32F165x/ht32f165x_reg.h @@ -495,6 +495,7 @@ typedef struct { #define SPI_CR1_FORMAT_MODE2 (0x6U << 8) #define SPI_CR1_FORMAT_MODE3 (0x5U << 8) #define SPI_IER_RXBNEIEN (1U << 2) +#define SPI_IER_TXEIEN (1U << 1) #define SPI_IER_TXBEIEN (1U << 0) #define SPI_SR_RXBNE (1U << 2) #define SPI_SR_TXE (1U << 1) diff --git a/os/common/ext/CMSIS/HT32/HT32F523xx/ht32f523x2_reg.h b/os/common/ext/CMSIS/HT32/HT32F523xx/ht32f523x2_reg.h index 40eb8e8305..43f57927e4 100644 --- a/os/common/ext/CMSIS/HT32/HT32F523xx/ht32f523x2_reg.h +++ b/os/common/ext/CMSIS/HT32/HT32F523xx/ht32f523x2_reg.h @@ -477,6 +477,7 @@ typedef struct { #define SPI_CR1_FORMAT_MODE2 (0x6U << 8) #define SPI_CR1_FORMAT_MODE3 (0x5U << 8) #define SPI_IER_RXBNEIEN (1U << 2) +#define SPI_IER_TXEIEN (1U << 1) #define SPI_IER_TXBEIEN (1U << 0) #define SPI_SR_RXBNE (1U << 2) #define SPI_SR_TXE (1U << 1) diff --git a/os/hal/ports/HT32/LLD/SPIv1/hal_spi_lld.c b/os/hal/ports/HT32/LLD/SPIv1/hal_spi_lld.c index f3ff0b00f0..d77773fa7a 100644 --- a/os/hal/ports/HT32/LLD/SPIv1/hal_spi_lld.c +++ b/os/hal/ports/HT32/LLD/SPIv1/hal_spi_lld.c @@ -76,8 +76,14 @@ static void spi_lld_tx(SPIDriver * const spip) { while (spip->txcnt) { sr = spip->SPI->SR; - if ((sr & SPI_SR_TXBE) == 0) - return; + // avoid write collision + if (spip->SPI->FCR & SPI_FCR_FIFOEN) { + if ((sr & SPI_SR_TXBE) == 0) + return; + } else { + if ((sr & SPI_SR_TXE) == 0) + return; + } if (spip->txptr) { fd = *spip->txptr++; } else { @@ -260,7 +266,7 @@ void spi_lld_exchange(SPIDriver *spip, size_t n, spip->txptr = txbuf; spip->rxptr = rxbuf; spip->rxcnt = spip->txcnt = n; - spip->SPI->IER = SPI_IER_RXBNEIEN | SPI_IER_TXBEIEN; + spip->SPI->IER = SPI_IER_RXBNEIEN | SPI_IER_TXBEIEN | SPI_IER_TXEIEN; } /**