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; } pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy