From 9c83128e50967fe82693338fd76b9a2402f46171 Mon Sep 17 00:00:00 2001 From: Alexey Golyshin Date: Mon, 3 Feb 2020 18:52:59 +0300 Subject: [PATCH 1/4] SPI: improvements for SPI library - optimize spi_transfer routine to use LL instead of HAL - add SPISettings field for transmit only operations - replace spi_send with call to spi_transfer with SPI_TRANSMITONLY flag - allow SPI_TRANSFER_TIMEOUT redefinition Signed-off-by: Alexey Golyshin --- libraries/SPI/src/SPI.cpp | 21 +++++----- libraries/SPI/src/SPI.h | 11 +++++- libraries/SPI/src/utility/spi_com.c | 61 ++++++++++++++++------------- libraries/SPI/src/utility/spi_com.h | 2 +- 4 files changed, 55 insertions(+), 40 deletions(-) diff --git a/libraries/SPI/src/SPI.cpp b/libraries/SPI/src/SPI.cpp index e162338e99..cab53b92c1 100644 --- a/libraries/SPI/src/SPI.cpp +++ b/libraries/SPI/src/SPI.cpp @@ -115,6 +115,7 @@ void SPIClass::beginTransaction(uint8_t _pin, SPISettings settings) spiSettings[idx].clk = settings.clk; spiSettings[idx].dMode = settings.dMode; spiSettings[idx].bOrder = settings.bOrder; + spiSettings[idx].noReceive = settings.noReceive; if ((_pin != CS_PIN_CONTROLLED_BY_USER) && (_spi.pin_ssel == NC)) { pinMode(_pin, OUTPUT); @@ -262,9 +263,8 @@ byte SPIClass::transfer(uint8_t _pin, uint8_t data, SPITransferMode _mode) if (_pin > NUM_DIGITAL_PINS) { return rx_buffer; } - + uint8_t idx = pinIdx(_pin, GET_IDX); if (_pin != _CSPinConfig) { - uint8_t idx = pinIdx(_pin, GET_IDX); if (idx >= NB_SPI_SETTINGS) { return rx_buffer; } @@ -278,7 +278,7 @@ byte SPIClass::transfer(uint8_t _pin, uint8_t data, SPITransferMode _mode) digitalWrite(_pin, LOW); } - spi_transfer(&_spi, &data, &rx_buffer, sizeof(uint8_t), SPI_TRANSFER_TIMEOUT); + spi_transfer(&_spi, &data, &rx_buffer, sizeof(uint8_t), SPI_TRANSFER_TIMEOUT, spiSettings[idx].noReceive); if ((_pin != CS_PIN_CONTROLLED_BY_USER) && (_mode == SPI_LAST) && (_spi.pin_ssel == NC)) { digitalWrite(_pin, HIGH); @@ -330,7 +330,8 @@ uint16_t SPIClass::transfer16(uint8_t _pin, uint16_t data, SPITransferMode _mode digitalWrite(_pin, LOW); } - spi_transfer(&_spi, (uint8_t *)&data, (uint8_t *)&rx_buffer, sizeof(uint16_t), SPI_TRANSFER_TIMEOUT); + spi_transfer(&_spi, (uint8_t *)&data, (uint8_t *)&rx_buffer, sizeof(uint16_t), + SPI_TRANSFER_TIMEOUT, spiSettings[idx].noReceive); if ((_pin != CS_PIN_CONTROLLED_BY_USER) && (_mode == SPI_LAST) && (_spi.pin_ssel == NC)) { digitalWrite(_pin, HIGH); @@ -363,9 +364,8 @@ void SPIClass::transfer(uint8_t _pin, void *_buf, size_t _count, SPITransferMode if ((_count == 0) || (_buf == NULL) || (_pin > NUM_DIGITAL_PINS)) { return; } - + uint8_t idx = pinIdx(_pin, GET_IDX); if (_pin != _CSPinConfig) { - uint8_t idx = pinIdx(_pin, GET_IDX); if (idx >= NB_SPI_SETTINGS) { return; } @@ -379,7 +379,8 @@ void SPIClass::transfer(uint8_t _pin, void *_buf, size_t _count, SPITransferMode digitalWrite(_pin, LOW); } - spi_transfer(&_spi, ((uint8_t *)_buf), ((uint8_t *)_buf), _count, SPI_TRANSFER_TIMEOUT); + spi_transfer(&_spi, ((uint8_t *)_buf), ((uint8_t *)_buf), _count, + SPI_TRANSFER_TIMEOUT, spiSettings[idx].noReceive); if ((_pin != CS_PIN_CONTROLLED_BY_USER) && (_mode == SPI_LAST) && (_spi.pin_ssel == NC)) { digitalWrite(_pin, HIGH); @@ -406,9 +407,8 @@ void SPIClass::transfer(byte _pin, void *_bufout, void *_bufin, size_t _count, S if ((_count == 0) || (_bufout == NULL) || (_bufin == NULL) || (_pin > NUM_DIGITAL_PINS)) { return; } - + uint8_t idx = pinIdx(_pin, GET_IDX); if (_pin != _CSPinConfig) { - uint8_t idx = pinIdx(_pin, GET_IDX); if (idx >= NB_SPI_SETTINGS) { return; } @@ -422,7 +422,8 @@ void SPIClass::transfer(byte _pin, void *_bufout, void *_bufin, size_t _count, S digitalWrite(_pin, LOW); } - spi_transfer(&_spi, ((uint8_t *)_bufout), ((uint8_t *)_bufin), _count, SPI_TRANSFER_TIMEOUT); + spi_transfer(&_spi, ((uint8_t *)_bufout), ((uint8_t *)_bufin), _count, + SPI_TRANSFER_TIMEOUT, spiSettings[idx].noReceive); if ((_pin != CS_PIN_CONTROLLED_BY_USER) && (_mode == SPI_LAST) && (_spi.pin_ssel == NC)) { digitalWrite(_pin, HIGH); diff --git a/libraries/SPI/src/SPI.h b/libraries/SPI/src/SPI.h index 8ce8e5b24a..7ea60cfdad 100644 --- a/libraries/SPI/src/SPI.h +++ b/libraries/SPI/src/SPI.h @@ -44,6 +44,9 @@ extern "C" { #define SPI_MODE2 0x02 #define SPI_MODE3 0x03 +#define SPI_TRANSMITRECEIVE 0x0 +#define SPI_TRANSMITONLY 0x1 + // Transfer mode enum SPITransferMode { SPI_CONTINUE, /* Transfer not finished: CS pin kept active */ @@ -57,7 +60,9 @@ enum SPITransferMode { #define NO_CONFIG ((int16_t)(-1)) // Defines a default timeout delay in milliseconds for the SPI transfer -#define SPI_TRANSFER_TIMEOUT 1000 +#ifndef SPI_TRANSFER_TIMEOUT +#define SPI_TRANSFER_TIMEOUT 1000 +#endif /* * Defines the number of settings saved per SPI instance. Must be in range 1 to 254. @@ -69,10 +74,11 @@ enum SPITransferMode { class SPISettings { public: - SPISettings(uint32_t clock, BitOrder bitOrder, uint8_t dataMode) + SPISettings(uint32_t clock, BitOrder bitOrder, uint8_t dataMode, bool noRecv = SPI_TRANSMITRECEIVE) { clk = clock; bOrder = bitOrder; + noReceive = noRecv; if (SPI_MODE0 == dataMode) { dMode = SPI_MODE_0; @@ -102,6 +108,7 @@ class SPISettings { //SPI_MODE2 1 0 //SPI_MODE3 1 1 friend class SPIClass; + bool noReceive; }; class SPIClass { diff --git a/libraries/SPI/src/utility/spi_com.c b/libraries/SPI/src/utility/spi_com.c index b324ebebe1..1ce808d86f 100644 --- a/libraries/SPI/src/utility/spi_com.c +++ b/libraries/SPI/src/utility/spi_com.c @@ -40,6 +40,7 @@ #include "utility/spi_com.h" #include "PinAF_STM32F1.h" #include "pinconfig.h" +#include "stm32yyxx_ll_spi.h" #ifdef __cplusplus extern "C" { @@ -381,22 +382,7 @@ void spi_deinit(spi_t *obj) */ spi_status_e spi_send(spi_t *obj, uint8_t *Data, uint16_t len, uint32_t Timeout) { - spi_status_e ret = SPI_OK; - HAL_StatusTypeDef hal_status; - - if ((obj == NULL) || (len == 0)) { - return SPI_ERROR; - } - - hal_status = HAL_SPI_Transmit(&(obj->handle), Data, len, Timeout); - - if (hal_status == HAL_TIMEOUT) { - ret = SPI_TIMEOUT; - } else if (hal_status != HAL_OK) { - ret = SPI_ERROR; - } - - return ret; + return spi_transfer(obj, Data, Data, len, Timeout, 1 /* SPI_TRANSMITONLY */); } /** @@ -407,26 +393,47 @@ spi_status_e spi_send(spi_t *obj, uint8_t *Data, uint16_t len, uint32_t Timeout) * @param rx_buffer : data to receive * @param len : length in byte of the data to send and receive * @param Timeout: Timeout duration in tick + * @param skipRecieve: skip recieving data after transmit or not * @retval status of the send operation (0) in case of error */ -spi_status_e spi_transfer(spi_t *obj, uint8_t *tx_buffer, - uint8_t *rx_buffer, uint16_t len, uint32_t Timeout) +spi_status_e spi_transfer(spi_t *obj, uint8_t *tx_buffer, uint8_t *rx_buffer, + uint16_t len, uint32_t Timeout, bool skipReceive) { spi_status_e ret = SPI_OK; - HAL_StatusTypeDef hal_status; + uint32_t tickstart, size = len; + SPI_TypeDef *_SPI = obj->handle.Instance; - if ((obj == NULL) || (len == 0)) { - return SPI_ERROR; + if ((obj == NULL) || (len == 0) || (Timeout == 0U)) { + return Timeout > 0U ? SPI_ERROR : SPI_TIMEOUT; } + tickstart = HAL_GetTick(); + if (skipReceive) { + while (size--) { + while (!LL_SPI_IsActiveFlag_TXE(_SPI)) + ; + LL_SPI_TransmitData8(_SPI, *tx_buffer++); + + if ((Timeout != HAL_MAX_DELAY) && (HAL_GetTick() - tickstart >= Timeout)) { + ret = SPI_TIMEOUT; + break; + } + } + } else { + while (size--) { + while (!LL_SPI_IsActiveFlag_TXE(_SPI)) + ; + LL_SPI_TransmitData8(_SPI, *tx_buffer++); - hal_status = HAL_SPI_TransmitReceive(&(obj->handle), tx_buffer, rx_buffer, len, Timeout); + while (!LL_SPI_IsActiveFlag_RXNE(_SPI)) + ; + *rx_buffer++ = LL_SPI_ReceiveData8(_SPI); - if (hal_status == HAL_TIMEOUT) { - ret = SPI_TIMEOUT; - } else if (hal_status != HAL_OK) { - ret = SPI_ERROR; + if ((Timeout != HAL_MAX_DELAY) && (HAL_GetTick() - tickstart >= Timeout)) { + ret = SPI_TIMEOUT; + break; + } + } } - return ret; } diff --git a/libraries/SPI/src/utility/spi_com.h b/libraries/SPI/src/utility/spi_com.h index 0b15e011c0..abf611cba7 100644 --- a/libraries/SPI/src/utility/spi_com.h +++ b/libraries/SPI/src/utility/spi_com.h @@ -99,7 +99,7 @@ void spi_init(spi_t *obj, uint32_t speed, spi_mode_e mode, uint8_t msb); void spi_deinit(spi_t *obj); spi_status_e spi_send(spi_t *obj, uint8_t *Data, uint16_t len, uint32_t Timeout); spi_status_e spi_transfer(spi_t *obj, uint8_t *tx_buffer, - uint8_t *rx_buffer, uint16_t len, uint32_t Timeout); + uint8_t *rx_buffer, uint16_t len, uint32_t Timeout, bool skipReceive); uint32_t spi_getClkFreq(spi_t *obj); #ifdef __cplusplus From d55eb703823cccf8c4f98e85d517a332b0922c84 Mon Sep 17 00:00:00 2001 From: Alexandre Bourdiol Date: Thu, 6 Feb 2020 11:53:42 +0100 Subject: [PATCH 2/4] spi_tranfer: factorize common code to simplify maintenance --- libraries/SPI/src/utility/spi_com.c | 31 ++++++++++------------------- 1 file changed, 10 insertions(+), 21 deletions(-) diff --git a/libraries/SPI/src/utility/spi_com.c b/libraries/SPI/src/utility/spi_com.c index 1ce808d86f..fdca96bad0 100644 --- a/libraries/SPI/src/utility/spi_com.c +++ b/libraries/SPI/src/utility/spi_com.c @@ -407,33 +407,22 @@ spi_status_e spi_transfer(spi_t *obj, uint8_t *tx_buffer, uint8_t *rx_buffer, return Timeout > 0U ? SPI_ERROR : SPI_TIMEOUT; } tickstart = HAL_GetTick(); - if (skipReceive) { - while (size--) { - while (!LL_SPI_IsActiveFlag_TXE(_SPI)) - ; - LL_SPI_TransmitData8(_SPI, *tx_buffer++); - - if ((Timeout != HAL_MAX_DELAY) && (HAL_GetTick() - tickstart >= Timeout)) { - ret = SPI_TIMEOUT; - break; - } - } - } else { - while (size--) { - while (!LL_SPI_IsActiveFlag_TXE(_SPI)) - ; - LL_SPI_TransmitData8(_SPI, *tx_buffer++); + while (size--) { + while (!LL_SPI_IsActiveFlag_TXE(_SPI)) + ; + LL_SPI_TransmitData8(_SPI, *tx_buffer++); + if (!skipReceive) { while (!LL_SPI_IsActiveFlag_RXNE(_SPI)) ; *rx_buffer++ = LL_SPI_ReceiveData8(_SPI); - - if ((Timeout != HAL_MAX_DELAY) && (HAL_GetTick() - tickstart >= Timeout)) { - ret = SPI_TIMEOUT; - break; - } + } + if ((Timeout != HAL_MAX_DELAY) && (HAL_GetTick() - tickstart >= Timeout)) { + ret = SPI_TIMEOUT; + break; } } + return ret; } From 4e8df33f1585d446d0fded0eba7c3ea2d4d7ced2 Mon Sep 17 00:00:00 2001 From: Alexey Golyshin Date: Mon, 10 Feb 2020 19:38:24 +0300 Subject: [PATCH 3/4] SPI: H7 and MP1 fix Signed-off-by: Alexey Golyshin --- libraries/SPI/src/utility/spi_com.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/libraries/SPI/src/utility/spi_com.c b/libraries/SPI/src/utility/spi_com.c index fdca96bad0..383eb9c926 100644 --- a/libraries/SPI/src/utility/spi_com.c +++ b/libraries/SPI/src/utility/spi_com.c @@ -393,7 +393,7 @@ spi_status_e spi_send(spi_t *obj, uint8_t *Data, uint16_t len, uint32_t Timeout) * @param rx_buffer : data to receive * @param len : length in byte of the data to send and receive * @param Timeout: Timeout duration in tick - * @param skipRecieve: skip recieving data after transmit or not + * @param skipReceive: skip receiving data after transmit or not * @retval status of the send operation (0) in case of error */ spi_status_e spi_transfer(spi_t *obj, uint8_t *tx_buffer, uint8_t *rx_buffer, @@ -407,14 +407,25 @@ spi_status_e spi_transfer(spi_t *obj, uint8_t *tx_buffer, uint8_t *rx_buffer, return Timeout > 0U ? SPI_ERROR : SPI_TIMEOUT; } tickstart = HAL_GetTick(); + +#if defined(STM32H7xx) || defined(STM32MP1xx) + LL_SPI_StartMasterTransfer(_SPI); // start master transfer +#endif + while (size--) { - while (!LL_SPI_IsActiveFlag_TXE(_SPI)) - ; +#if defined(STM32H7xx) || defined(STM32MP1xx) + while (!LL_SPI_IsActiveFlag_TXP(_SPI)); +#else + while (!LL_SPI_IsActiveFlag_TXE(_SPI)); +#endif LL_SPI_TransmitData8(_SPI, *tx_buffer++); if (!skipReceive) { - while (!LL_SPI_IsActiveFlag_RXNE(_SPI)) - ; +#if defined(STM32H7xx) || defined(STM32MP1xx) + while (!LL_SPI_IsActiveFlag_RXP(_SPI)); +#else + while (!LL_SPI_IsActiveFlag_RXNE(_SPI)); +#endif *rx_buffer++ = LL_SPI_ReceiveData8(_SPI); } if ((Timeout != HAL_MAX_DELAY) && (HAL_GetTick() - tickstart >= Timeout)) { From 63d541bccee5d97b8ea27964952cda70c597a7f4 Mon Sep 17 00:00:00 2001 From: Alexandre Bourdiol Date: Tue, 11 Feb 2020 18:47:03 +0100 Subject: [PATCH 4/4] SPI: Dedicated start/stop transfer for STM32H7 and STM32MP1 --- libraries/SPI/src/utility/spi_com.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/libraries/SPI/src/utility/spi_com.c b/libraries/SPI/src/utility/spi_com.c index 383eb9c926..ee607ee028 100644 --- a/libraries/SPI/src/utility/spi_com.c +++ b/libraries/SPI/src/utility/spi_com.c @@ -409,7 +409,10 @@ spi_status_e spi_transfer(spi_t *obj, uint8_t *tx_buffer, uint8_t *rx_buffer, tickstart = HAL_GetTick(); #if defined(STM32H7xx) || defined(STM32MP1xx) - LL_SPI_StartMasterTransfer(_SPI); // start master transfer + /* Start transfer */ + LL_SPI_SetTransferSize(_SPI, size); + LL_SPI_Enable(_SPI); + LL_SPI_StartMasterTransfer(_SPI); #endif while (size--) { @@ -434,6 +437,15 @@ spi_status_e spi_transfer(spi_t *obj, uint8_t *tx_buffer, uint8_t *rx_buffer, } } +#if defined(STM32H7xx) || defined(STM32MP1xx) + /* Close transfer */ + /* Clear flags */ + LL_SPI_ClearFlag_EOT(_SPI); + LL_SPI_ClearFlag_TXTF(_SPI); + /* Disable SPI peripheral */ + LL_SPI_Disable(_SPI); +#endif + return ret; }