From 8e8feb0c58c1ac17008c5dd082226d746232a4ea Mon Sep 17 00:00:00 2001 From: Frederic Pillon Date: Thu, 23 Nov 2023 15:28:26 +0100 Subject: [PATCH 1/8] Revert "chore(SPI): align with ArduinoCoreAPI" This reverts commit 392469a1dc66448dea543119b7258128b5596a03. --- libraries/SPI/src/SPI.cpp | 95 +++++++++--------- libraries/SPI/src/SPI.h | 144 ++++++++-------------------- libraries/SPI/src/utility/spi_com.c | 6 +- libraries/SPI/src/utility/spi_com.h | 13 ++- 4 files changed, 94 insertions(+), 164 deletions(-) diff --git a/libraries/SPI/src/SPI.cpp b/libraries/SPI/src/SPI.cpp index b3266d348a..b8f282ffe5 100644 --- a/libraries/SPI/src/SPI.cpp +++ b/libraries/SPI/src/SPI.cpp @@ -57,10 +57,9 @@ SPIClass::SPIClass(uint32_t mosi, uint32_t miso, uint32_t sclk, uint32_t ssel) void SPIClass::begin(void) { _spi.handle.State = HAL_SPI_STATE_RESET; - _spiSettings = DEFAULT_SPI_SETTINGS; - spi_init(&_spi, _spiSettings.getClockFreq(), - _spiSettings.getDataMode(), - _spiSettings.getBitOrder()); + spi_init(&_spi, _spiSettings.clk, + _spiSettings.dMode, + _spiSettings.bOrder); } /** @@ -70,12 +69,14 @@ void SPIClass::begin(void) */ void SPIClass::beginTransaction(SPISettings settings) { - if (_spiSettings != settings) { - _spiSettings = settings; - spi_init(&_spi, _spiSettings.getClockFreq(), - _spiSettings.getDataMode(), - _spiSettings.getBitOrder()); - } + _spiSettings.clk = settings.clk; + _spiSettings.dMode = settings.dMode; + _spiSettings.bOrder = settings.bOrder; + _spiSettings.noReceive = settings.noReceive; + + spi_init(&_spi, _spiSettings.clk, + _spiSettings.dMode, + _spiSettings.bOrder); } /** @@ -101,17 +102,17 @@ void SPIClass::end() */ void SPIClass::setBitOrder(BitOrder bitOrder) { - _spiSettings.setBitOrder(bitOrder); + _spiSettings.bOrder = bitOrder; - spi_init(&_spi, _spiSettings.getClockFreq(), - _spiSettings.getDataMode(), - _spiSettings.getBitOrder()); + spi_init(&_spi, _spiSettings.clk, + _spiSettings.dMode, + _spiSettings.bOrder); } /** * @brief Deprecated function. * Configure the data mode (clock polarity and clock phase) - * @param mode: SPI_MODE0, SPI_MODE1, SPI_MODE2 or SPI_MODE3 + * @param _mode: SPI_MODE0, SPI_MODE1, SPI_MODE2 or SPI_MODE3 * @note * Mode Clock Polarity (CPOL) Clock Phase (CPHA) * SPI_MODE0 0 0 @@ -119,19 +120,21 @@ void SPIClass::setBitOrder(BitOrder bitOrder) * SPI_MODE2 1 0 * SPI_MODE3 1 1 */ - -void SPIClass::setDataMode(uint8_t mode) +void SPIClass::setDataMode(uint8_t _mode) { - setDataMode((SPIMode)mode); -} - -void SPIClass::setDataMode(SPIMode mode) -{ - _spiSettings.setDataMode(mode); + if (SPI_MODE0 == _mode) { + _spiSettings.dMode = SPI_MODE_0; + } else if (SPI_MODE1 == _mode) { + _spiSettings.dMode = SPI_MODE_1; + } else if (SPI_MODE2 == _mode) { + _spiSettings.dMode = SPI_MODE_2; + } else if (SPI_MODE3 == _mode) { + _spiSettings.dMode = SPI_MODE_3; + } - spi_init(&_spi, _spiSettings.getClockFreq(), - _spiSettings.getDataMode(), - _spiSettings.getBitOrder()); + spi_init(&_spi, _spiSettings.clk, + _spiSettings.dMode, + _spiSettings.bOrder); } /** @@ -143,15 +146,15 @@ void SPIClass::setDataMode(SPIMode mode) void SPIClass::setClockDivider(uint8_t _divider) { if (_divider == 0) { - _spiSettings.setClockFreq(SPI_SPEED_CLOCK_DEFAULT); + _spiSettings.clk = SPI_SPEED_CLOCK_DEFAULT; } else { - /* Get clock freq of the SPI instance and compute it */ - _spiSettings.setClockFreq(spi_getClkFreq(&_spi) / _divider); + /* Get clk freq of the SPI instance and compute it */ + _spiSettings.clk = spi_getClkFreq(&_spi) / _divider; } - spi_init(&_spi, _spiSettings.getClockFreq(), - _spiSettings.getDataMode(), - _spiSettings.getBitOrder()); + spi_init(&_spi, _spiSettings.clk, + _spiSettings.dMode, + _spiSettings.bOrder); } /** @@ -160,9 +163,9 @@ void SPIClass::setClockDivider(uint8_t _divider) * @param data: byte to send. * @return byte received from the slave. */ -uint8_t SPIClass::transfer(uint8_t data) +byte SPIClass::transfer(uint8_t data) { - spi_transfer(&_spi, &data, sizeof(uint8_t), SPI_TRANSFER_TIMEOUT, _spiSettings.getSkipRecv()); + spi_transfer(&_spi, &data, sizeof(uint8_t), SPI_TRANSFER_TIMEOUT, _spiSettings.noReceive); return data; } @@ -176,14 +179,14 @@ uint16_t SPIClass::transfer16(uint16_t data) { uint16_t tmp; - if (_spiSettings.getBitOrder()) { + if (_spiSettings.bOrder) { tmp = ((data & 0xff00) >> 8) | ((data & 0xff) << 8); data = tmp; } spi_transfer(&_spi, (uint8_t *)&data, sizeof(uint16_t), - SPI_TRANSFER_TIMEOUT, _spiSettings.getSkipRecv()); + SPI_TRANSFER_TIMEOUT, _spiSettings.noReceive); - if (_spiSettings.getBitOrder()) { + if (_spiSettings.bOrder) { tmp = ((data & 0xff00) >> 8) | ((data & 0xff) << 8); data = tmp; } @@ -194,30 +197,22 @@ uint16_t SPIClass::transfer16(uint16_t data) /** * @brief Transfer several bytes. Only one buffer used to send and receive data. * begin() or beginTransaction() must be called at least once before. - * @param buf: pointer to the bytes to send. The bytes received are copy in + * @param _buf: pointer to the bytes to send. The bytes received are copy in * this buffer. - * @param count: number of bytes to send/receive. + * @param _count: number of bytes to send/receive. */ -void SPIClass::transfer(void *buf, size_t count) +void SPIClass::transfer(void *_buf, size_t _count) { if ((count != 0) && (buf != NULL)) { spi_transfer(&_spi, ((uint8_t *)buf), count, - SPI_TRANSFER_TIMEOUT, _spiSettings.getSkipRecv()); + SPI_TRANSFER_TIMEOUT, _spiSettings.noReceive); } } /** * @brief Not implemented. */ -void SPIClass::usingInterrupt(int interruptNumber) -{ - UNUSED(interruptNumber); -} - -/** - * @brief Not implemented. - */ -void SPIClass::notUsingInterrupt(int interruptNumber) +void SPIClass::usingInterrupt(uint8_t interruptNumber) { UNUSED(interruptNumber); } diff --git a/libraries/SPI/src/SPI.h b/libraries/SPI/src/SPI.h index 9509c871eb..f8e41bea5c 100644 --- a/libraries/SPI/src/SPI.h +++ b/libraries/SPI/src/SPI.h @@ -38,6 +38,12 @@ extern "C" { #define SPI_CLOCK_DIV64 64 #define SPI_CLOCK_DIV128 128 +// SPI mode parameters for SPISettings +#define SPI_MODE0 0x00 +#define SPI_MODE1 0x01 +#define SPI_MODE2 0x02 +#define SPI_MODE3 0x03 + #define SPI_TRANSMITRECEIVE 0x0 #define SPI_TRANSMITONLY 0x1 @@ -48,105 +54,37 @@ extern "C" { class SPISettings { public: - SPISettings(uint32_t clock, BitOrder bitOrder, SPIMode dataMode, bool skipRecv = SPI_TRANSMITRECEIVE) - { - if (__builtin_constant_p(clock)) { - init_AlwaysInline(clock, bitOrder, dataMode, skipRecv); - } else { - init_MightInline(clock, bitOrder, dataMode, skipRecv); - } - } - - SPISettings(uint32_t clock, BitOrder bitOrder, int dataMode, bool skipRecv = SPI_TRANSMITRECEIVE) - { - if (__builtin_constant_p(clock)) { - init_AlwaysInline(clock, bitOrder, (SPIMode)dataMode, skipRecv); - } else { - init_MightInline(clock, bitOrder, (SPIMode)dataMode, skipRecv); - } - } - - // Default speed set to 4MHz, SPI mode set to MODE 0 and Bit order set to MSB first. - SPISettings() - { - init_AlwaysInline(SPI_SPEED_CLOCK_DEFAULT, MSBFIRST, SPI_MODE0, SPI_TRANSMITRECEIVE); - } - - bool operator==(const SPISettings &rhs) const - { - if ((this->clockFreq == rhs.clockFreq) && - (this->bitOrder == rhs.bitOrder) && - (this->dataMode == rhs.dataMode) && - (this->skipRecv == rhs.skipRecv)) { - return true; - } - return false; - } - - bool operator!=(const SPISettings &rhs) const - { - return !(*this == rhs); - } - - uint32_t getClockFreq() const - { - return clockFreq; - } - SPIMode getDataMode() const - { - return dataMode; - } - BitOrder getBitOrder() const - { - return (bitOrder); - } - bool getSkipRecv() const - { - return skipRecv; - } - - void setClockFreq(uint32_t clkFreq) - { - clockFreq = clkFreq; - } - void setDataMode(SPIMode mode) - { - dataMode = mode; - } - void setBitOrder(BitOrder order) - { - bitOrder = order; - } - void setSkipRecv(bool skip) - { - skipRecv = skip; - } - + constexpr SPISettings(uint32_t clock, BitOrder bitOrder, uint8_t dataMode, bool noRecv = SPI_TRANSMITRECEIVE) + : clk(clock), + bOrder(bitOrder), + dMode((spi_mode_e)( + (SPI_MODE0 == dataMode) ? SPI_MODE_0 : + (SPI_MODE1 == dataMode) ? SPI_MODE_1 : + (SPI_MODE2 == dataMode) ? SPI_MODE_2 : + (SPI_MODE3 == dataMode) ? SPI_MODE_3 : + SPI_MODE0 + )), + noReceive(noRecv) + { } + constexpr SPISettings() + : clk(SPI_SPEED_CLOCK_DEFAULT), + bOrder(MSBFIRST), + dMode(SPI_MODE_0), + noReceive(SPI_TRANSMITRECEIVE) + { } private: - void init_MightInline(uint32_t clock, BitOrder bitOrder, SPIMode dataMode, bool skipRecv) - { - init_AlwaysInline(clock, bitOrder, dataMode, skipRecv); - } - - // Core developer MUST use an helper function in beginTransaction() to use this data - void init_AlwaysInline(uint32_t clock, BitOrder bitOrder, SPIMode dataMode, bool skipRecv) __attribute__((__always_inline__)) - { - this->clockFreq = clock; - this->dataMode = dataMode; - this->bitOrder = bitOrder; - this->skipRecv = skipRecv; - } - - uint32_t clockFreq; - SPIMode dataMode; - BitOrder bitOrder; - bool skipRecv; - - friend class HardwareSPI; + uint32_t clk; //specifies the spi bus maximum clock speed + BitOrder bOrder; //bit order (MSBFirst or LSBFirst) + spi_mode_e dMode; //one of the data mode + //Mode Clock Polarity (CPOL) Clock Phase (CPHA) + //SPI_MODE0 0 0 + //SPI_MODE1 0 1 + //SPI_MODE2 1 0 + //SPI_MODE3 1 1 + friend class SPIClass; + bool noReceive; }; -const SPISettings DEFAULT_SPI_SETTINGS = SPISettings(); - class SPIClass { public: SPIClass(); @@ -187,7 +125,7 @@ class SPIClass { _spi.pin_ssel = (ssel); }; - virtual void begin(void); + virtual void begin(); void end(void); /* This function should be used to configure the SPI instance in case you @@ -199,21 +137,19 @@ class SPIClass { /* Transfer functions: must be called after initialization of the SPI * instance with begin() or beginTransaction(). */ - virtual uint8_t transfer(uint8_t _data); + virtual byte transfer(uint8_t _data); virtual uint16_t transfer16(uint16_t _data); - virtual void transfer(void *buf, size_t count); + virtual void transfer(void *_buf, size_t _count); /* These methods are deprecated and kept for compatibility. * Use SPISettings with SPI.beginTransaction() to configure SPI parameters. */ void setBitOrder(BitOrder); void setDataMode(uint8_t); - void setDataMode(SPIMode); void setClockDivider(uint8_t); - // Not implemented functions. Kept for compatibility. - void usingInterrupt(int interruptNumber); - void notUsingInterrupt(int interruptNumber); + // Not implemented functions. Kept for backward compatibility. + void usingInterrupt(uint8_t interruptNumber); void attachInterrupt(void); void detachInterrupt(void); @@ -229,7 +165,7 @@ class SPIClass { private: /* Current SPISettings */ - SPISettings _spiSettings = DEFAULT_SPI_SETTINGS; + SPISettings _spiSettings = SPISettings(); }; extern SPIClass SPI; diff --git a/libraries/SPI/src/utility/spi_com.c b/libraries/SPI/src/utility/spi_com.c index bd582681bd..cfc2c2cc45 100644 --- a/libraries/SPI/src/utility/spi_com.c +++ b/libraries/SPI/src/utility/spi_com.c @@ -227,7 +227,7 @@ static uint32_t compute_disable_delay(spi_t *obj) * @param msb : set to 1 in msb first * @retval None */ -void spi_init(spi_t *obj, uint32_t speed, SPIMode mode, uint8_t msb) +void spi_init(spi_t *obj, uint32_t speed, spi_mode_e mode, uint8_t msb) { if (obj == NULL) { return; @@ -313,13 +313,13 @@ void spi_init(spi_t *obj, uint32_t speed, SPIMode mode, uint8_t msb) handle->Init.Direction = SPI_DIRECTION_2LINES; - if ((mode == SPI_MODE0) || (mode == SPI_MODE2)) { + if ((mode == SPI_MODE_0) || (mode == SPI_MODE_2)) { handle->Init.CLKPhase = SPI_PHASE_1EDGE; } else { handle->Init.CLKPhase = SPI_PHASE_2EDGE; } - if ((mode == SPI_MODE0) || (mode == SPI_MODE1)) { + if ((mode == SPI_MODE_0) || (mode == SPI_MODE_1)) { handle->Init.CLKPolarity = SPI_POLARITY_LOW; } else { handle->Init.CLKPolarity = SPI_POLARITY_HIGH; diff --git a/libraries/SPI/src/utility/spi_com.h b/libraries/SPI/src/utility/spi_com.h index 7562c08118..ee322e6982 100644 --- a/libraries/SPI/src/utility/spi_com.h +++ b/libraries/SPI/src/utility/spi_com.h @@ -85,13 +85,12 @@ typedef struct spi_s spi_t; //SPI_MODE2 1 0 //SPI_MODE3 1 1 //enum definitions coming from SPI.h of SAM -// SPI mode parameters for SPISettings typedef enum { - SPI_MODE0 = 0, - SPI_MODE1 = 1, - SPI_MODE2 = 2, - SPI_MODE3 = 3, -} SPIMode; + SPI_MODE_0 = 0x00, + SPI_MODE_1 = 0x01, + SPI_MODE_2 = 0x02, + SPI_MODE_3 = 0x03 +} spi_mode_e; ///@brief SPI errors typedef enum { @@ -101,7 +100,7 @@ typedef enum { } spi_status_e; /* Exported functions ------------------------------------------------------- */ -void spi_init(spi_t *obj, uint32_t speed, SPIMode mode, uint8_t msb); +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_transfer(spi_t *obj, uint8_t *buffer, uint16_t len, uint32_t Timeout, bool skipReceive); From c9a89f1b611df1c1bdb5694c2069071201860991 Mon Sep 17 00:00:00 2001 From: Frederic Pillon Date: Thu, 23 Nov 2023 16:14:31 +0100 Subject: [PATCH 2/8] Revert "fix(SubGhz): SPISettings not properly defined" This reverts commit d61ad831a72241657fcd2dfd1d3e6d704dd601e6. --- libraries/SubGhz/src/SubGhz.cpp | 2 ++ libraries/SubGhz/src/SubGhz.h | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/libraries/SubGhz/src/SubGhz.cpp b/libraries/SubGhz/src/SubGhz.cpp index a175c0c551..b5394fd55f 100644 --- a/libraries/SubGhz/src/SubGhz.cpp +++ b/libraries/SubGhz/src/SubGhz.cpp @@ -21,6 +21,8 @@ extern "C" void SUBGHZ_Radio_IRQHandler(void) SubGhz.handleIrq(); } +constexpr SPISettings SubGhzClass::spi_settings; + void SubGhzClass::handleIrq() { if (callback) { diff --git a/libraries/SubGhz/src/SubGhz.h b/libraries/SubGhz/src/SubGhz.h index dd8683f279..60bb621fad 100644 --- a/libraries/SubGhz/src/SubGhz.h +++ b/libraries/SubGhz/src/SubGhz.h @@ -101,7 +101,7 @@ class SubGhzClass { // supported by the radio, which should always work (no chance of // bad wiring that requires reducing the speed). // This value should be passed to `SubGhz.SPI.beginTransaction()`. - const SPISettings spi_settings = {16000000, MSBFIRST, SPI_MODE0}; + static constexpr SPISettings spi_settings = {16000000, MSBFIRST, SPI_MODE0}; protected: // To access handleIrq() From ea70e88cfa393c2f2683a75de6c2d9d06b0d4ed0 Mon Sep 17 00:00:00 2001 From: Frederic Pillon Date: Thu, 23 Nov 2023 16:13:57 +0100 Subject: [PATCH 3/8] chore(spi): partially align with ArduinoCoreAPI Keep constexpr constructor to ensures that constructing an SPISettings object can be done at compiletime. Fixes #2201. Signed-off-by: Frederic Pillon --- libraries/SPI/src/SPI.cpp | 95 +++++++++++++++-------------- libraries/SPI/src/SPI.h | 71 ++++++++++----------- libraries/SPI/src/utility/spi_com.c | 6 +- libraries/SPI/src/utility/spi_com.h | 13 ++-- 4 files changed, 96 insertions(+), 89 deletions(-) diff --git a/libraries/SPI/src/SPI.cpp b/libraries/SPI/src/SPI.cpp index b8f282ffe5..15dbb79f18 100644 --- a/libraries/SPI/src/SPI.cpp +++ b/libraries/SPI/src/SPI.cpp @@ -57,9 +57,10 @@ SPIClass::SPIClass(uint32_t mosi, uint32_t miso, uint32_t sclk, uint32_t ssel) void SPIClass::begin(void) { _spi.handle.State = HAL_SPI_STATE_RESET; - spi_init(&_spi, _spiSettings.clk, - _spiSettings.dMode, - _spiSettings.bOrder); + _spiSettings = SPISettings(); + spi_init(&_spi, _spiSettings.clockFreq, + _spiSettings.dataMode, + _spiSettings.bitOrder); } /** @@ -69,14 +70,12 @@ void SPIClass::begin(void) */ void SPIClass::beginTransaction(SPISettings settings) { - _spiSettings.clk = settings.clk; - _spiSettings.dMode = settings.dMode; - _spiSettings.bOrder = settings.bOrder; - _spiSettings.noReceive = settings.noReceive; - - spi_init(&_spi, _spiSettings.clk, - _spiSettings.dMode, - _spiSettings.bOrder); + if (_spiSettings != settings) { + _spiSettings = settings; + spi_init(&_spi, _spiSettings.clockFreq, + _spiSettings.dataMode, + _spiSettings.bitOrder); + } } /** @@ -90,7 +89,7 @@ void SPIClass::endTransaction(void) /** * @brief Deinitialize the SPI instance and stop it. */ -void SPIClass::end() +void SPIClass::end(void) { spi_deinit(&_spi); } @@ -98,21 +97,21 @@ void SPIClass::end() /** * @brief Deprecated function. * Configure the bit order: MSB first or LSB first. - * @param _bitOrder: MSBFIRST or LSBFIRST + * @param bitOrder: MSBFIRST or LSBFIRST */ void SPIClass::setBitOrder(BitOrder bitOrder) { - _spiSettings.bOrder = bitOrder; + _spiSettings.bitOrder = bitOrder; - spi_init(&_spi, _spiSettings.clk, - _spiSettings.dMode, - _spiSettings.bOrder); + spi_init(&_spi, _spiSettings.clockFreq, + _spiSettings.dataMode, + _spiSettings.bitOrder); } /** * @brief Deprecated function. * Configure the data mode (clock polarity and clock phase) - * @param _mode: SPI_MODE0, SPI_MODE1, SPI_MODE2 or SPI_MODE3 + * @param mode: SPI_MODE0, SPI_MODE1, SPI_MODE2 or SPI_MODE3 * @note * Mode Clock Polarity (CPOL) Clock Phase (CPHA) * SPI_MODE0 0 0 @@ -120,41 +119,37 @@ void SPIClass::setBitOrder(BitOrder bitOrder) * SPI_MODE2 1 0 * SPI_MODE3 1 1 */ -void SPIClass::setDataMode(uint8_t _mode) +void SPIClass::setDataMode(uint8_t mode) { - if (SPI_MODE0 == _mode) { - _spiSettings.dMode = SPI_MODE_0; - } else if (SPI_MODE1 == _mode) { - _spiSettings.dMode = SPI_MODE_1; - } else if (SPI_MODE2 == _mode) { - _spiSettings.dMode = SPI_MODE_2; - } else if (SPI_MODE3 == _mode) { - _spiSettings.dMode = SPI_MODE_3; - } + setDataMode((SPIMode)mode); +} - spi_init(&_spi, _spiSettings.clk, - _spiSettings.dMode, - _spiSettings.bOrder); +void SPIClass::setDataMode(SPIMode mode) +{ + _spiSettings.dataMode = mode; + spi_init(&_spi, _spiSettings.clockFreq, + _spiSettings.dataMode, + _spiSettings.bitOrder); } /** * @brief Deprecated function. * Configure the clock speed - * @param _divider: the SPI clock can be divided by values from 1 to 255. + * @param divider: the SPI clock can be divided by values from 1 to 255. * If 0, default SPI speed is used. */ -void SPIClass::setClockDivider(uint8_t _divider) +void SPIClass::setClockDivider(uint8_t divider) { - if (_divider == 0) { - _spiSettings.clk = SPI_SPEED_CLOCK_DEFAULT; + if (divider == 0) { + _spiSettings.clockFreq = SPI_SPEED_CLOCK_DEFAULT; } else { /* Get clk freq of the SPI instance and compute it */ - _spiSettings.clk = spi_getClkFreq(&_spi) / _divider; + _spiSettings.clockFreq = spi_getClkFreq(&_spi) / divider; } - spi_init(&_spi, _spiSettings.clk, - _spiSettings.dMode, - _spiSettings.bOrder); + spi_init(&_spi, _spiSettings.clockFreq, + _spiSettings.dataMode, + _spiSettings.bitOrder); } /** @@ -163,7 +158,7 @@ void SPIClass::setClockDivider(uint8_t _divider) * @param data: byte to send. * @return byte received from the slave. */ -byte SPIClass::transfer(uint8_t data) +uint8_t SPIClass::transfer(uint8_t data) { spi_transfer(&_spi, &data, sizeof(uint8_t), SPI_TRANSFER_TIMEOUT, _spiSettings.noReceive); return data; @@ -179,14 +174,14 @@ uint16_t SPIClass::transfer16(uint16_t data) { uint16_t tmp; - if (_spiSettings.bOrder) { + if (_spiSettings.bitOrder) { tmp = ((data & 0xff00) >> 8) | ((data & 0xff) << 8); data = tmp; } spi_transfer(&_spi, (uint8_t *)&data, sizeof(uint16_t), SPI_TRANSFER_TIMEOUT, _spiSettings.noReceive); - if (_spiSettings.bOrder) { + if (_spiSettings.bitOrder) { tmp = ((data & 0xff00) >> 8) | ((data & 0xff) << 8); data = tmp; } @@ -197,11 +192,11 @@ uint16_t SPIClass::transfer16(uint16_t data) /** * @brief Transfer several bytes. Only one buffer used to send and receive data. * begin() or beginTransaction() must be called at least once before. - * @param _buf: pointer to the bytes to send. The bytes received are copy in + * @param buf: pointer to the bytes to send. The bytes received are copy in * this buffer. - * @param _count: number of bytes to send/receive. + * @param count: number of bytes to send/receive. */ -void SPIClass::transfer(void *_buf, size_t _count) +void SPIClass::transfer(void *buf, size_t count) { if ((count != 0) && (buf != NULL)) { spi_transfer(&_spi, ((uint8_t *)buf), count, @@ -212,7 +207,15 @@ void SPIClass::transfer(void *_buf, size_t _count) /** * @brief Not implemented. */ -void SPIClass::usingInterrupt(uint8_t interruptNumber) +void SPIClass::usingInterrupt(int interruptNumber) +{ + UNUSED(interruptNumber); +} + +/** + * @brief Not implemented. + */ +void SPIClass::notUsingInterrupt(int interruptNumber) { UNUSED(interruptNumber); } diff --git a/libraries/SPI/src/SPI.h b/libraries/SPI/src/SPI.h index f8e41bea5c..af19d4e38e 100644 --- a/libraries/SPI/src/SPI.h +++ b/libraries/SPI/src/SPI.h @@ -38,12 +38,6 @@ extern "C" { #define SPI_CLOCK_DIV64 64 #define SPI_CLOCK_DIV128 128 -// SPI mode parameters for SPISettings -#define SPI_MODE0 0x00 -#define SPI_MODE1 0x01 -#define SPI_MODE2 0x02 -#define SPI_MODE3 0x03 - #define SPI_TRANSMITRECEIVE 0x0 #define SPI_TRANSMITONLY 0x1 @@ -54,35 +48,42 @@ extern "C" { class SPISettings { public: - constexpr SPISettings(uint32_t clock, BitOrder bitOrder, uint8_t dataMode, bool noRecv = SPI_TRANSMITRECEIVE) - : clk(clock), - bOrder(bitOrder), - dMode((spi_mode_e)( - (SPI_MODE0 == dataMode) ? SPI_MODE_0 : - (SPI_MODE1 == dataMode) ? SPI_MODE_1 : - (SPI_MODE2 == dataMode) ? SPI_MODE_2 : - (SPI_MODE3 == dataMode) ? SPI_MODE_3 : - SPI_MODE0 - )), + constexpr SPISettings(uint32_t clock, BitOrder bitOrder, SPIMode dataMode, bool noRecv = SPI_TRANSMITRECEIVE) + : clockFreq(clock), + bitOrder(bitOrder), + dataMode(dataMode), noReceive(noRecv) { } constexpr SPISettings() - : clk(SPI_SPEED_CLOCK_DEFAULT), - bOrder(MSBFIRST), - dMode(SPI_MODE_0), + : clockFreq(SPI_SPEED_CLOCK_DEFAULT), + bitOrder(MSBFIRST), + dataMode(SPI_MODE0), noReceive(SPI_TRANSMITRECEIVE) { } + + bool operator==(const SPISettings &rhs) const + { + if ((this->clockFreq == rhs.clockFreq) && + (this->bitOrder == rhs.bitOrder) && + (this->dataMode == rhs.dataMode) && + (this->noReceive == rhs.noReceive)) { + return true; + } + return false; + } + + bool operator!=(const SPISettings &rhs) const + { + return !(*this == rhs); + } + private: - uint32_t clk; //specifies the spi bus maximum clock speed - BitOrder bOrder; //bit order (MSBFirst or LSBFirst) - spi_mode_e dMode; //one of the data mode - //Mode Clock Polarity (CPOL) Clock Phase (CPHA) - //SPI_MODE0 0 0 - //SPI_MODE1 0 1 - //SPI_MODE2 1 0 - //SPI_MODE3 1 1 - friend class SPIClass; + uint32_t clockFreq; //specifies the spi bus maximum clock speed + BitOrder bitOrder; //bit order (MSBFirst or LSBFirst) + SPIMode dataMode; //one of the data mode bool noReceive; + + friend class SPIClass; }; class SPIClass { @@ -125,7 +126,7 @@ class SPIClass { _spi.pin_ssel = (ssel); }; - virtual void begin(); + virtual void begin(void); void end(void); /* This function should be used to configure the SPI instance in case you @@ -137,19 +138,21 @@ class SPIClass { /* Transfer functions: must be called after initialization of the SPI * instance with begin() or beginTransaction(). */ - virtual byte transfer(uint8_t _data); - virtual uint16_t transfer16(uint16_t _data); - virtual void transfer(void *_buf, size_t _count); + virtual uint8_t transfer(uint8_t data); + virtual uint16_t transfer16(uint16_t data); + virtual void transfer(void *buf, size_t count); /* These methods are deprecated and kept for compatibility. * Use SPISettings with SPI.beginTransaction() to configure SPI parameters. */ void setBitOrder(BitOrder); void setDataMode(uint8_t); + void setDataMode(SPIMode); void setClockDivider(uint8_t); - // Not implemented functions. Kept for backward compatibility. - void usingInterrupt(uint8_t interruptNumber); + // Not implemented functions. Kept for compatibility. + void usingInterrupt(int interruptNumber); + void notUsingInterrupt(int interruptNumber); void attachInterrupt(void); void detachInterrupt(void); diff --git a/libraries/SPI/src/utility/spi_com.c b/libraries/SPI/src/utility/spi_com.c index cfc2c2cc45..bd582681bd 100644 --- a/libraries/SPI/src/utility/spi_com.c +++ b/libraries/SPI/src/utility/spi_com.c @@ -227,7 +227,7 @@ static uint32_t compute_disable_delay(spi_t *obj) * @param msb : set to 1 in msb first * @retval None */ -void spi_init(spi_t *obj, uint32_t speed, spi_mode_e mode, uint8_t msb) +void spi_init(spi_t *obj, uint32_t speed, SPIMode mode, uint8_t msb) { if (obj == NULL) { return; @@ -313,13 +313,13 @@ void spi_init(spi_t *obj, uint32_t speed, spi_mode_e mode, uint8_t msb) handle->Init.Direction = SPI_DIRECTION_2LINES; - if ((mode == SPI_MODE_0) || (mode == SPI_MODE_2)) { + if ((mode == SPI_MODE0) || (mode == SPI_MODE2)) { handle->Init.CLKPhase = SPI_PHASE_1EDGE; } else { handle->Init.CLKPhase = SPI_PHASE_2EDGE; } - if ((mode == SPI_MODE_0) || (mode == SPI_MODE_1)) { + if ((mode == SPI_MODE0) || (mode == SPI_MODE1)) { handle->Init.CLKPolarity = SPI_POLARITY_LOW; } else { handle->Init.CLKPolarity = SPI_POLARITY_HIGH; diff --git a/libraries/SPI/src/utility/spi_com.h b/libraries/SPI/src/utility/spi_com.h index ee322e6982..7562c08118 100644 --- a/libraries/SPI/src/utility/spi_com.h +++ b/libraries/SPI/src/utility/spi_com.h @@ -85,12 +85,13 @@ typedef struct spi_s spi_t; //SPI_MODE2 1 0 //SPI_MODE3 1 1 //enum definitions coming from SPI.h of SAM +// SPI mode parameters for SPISettings typedef enum { - SPI_MODE_0 = 0x00, - SPI_MODE_1 = 0x01, - SPI_MODE_2 = 0x02, - SPI_MODE_3 = 0x03 -} spi_mode_e; + SPI_MODE0 = 0, + SPI_MODE1 = 1, + SPI_MODE2 = 2, + SPI_MODE3 = 3, +} SPIMode; ///@brief SPI errors typedef enum { @@ -100,7 +101,7 @@ typedef enum { } spi_status_e; /* Exported functions ------------------------------------------------------- */ -void spi_init(spi_t *obj, uint32_t speed, spi_mode_e mode, uint8_t msb); +void spi_init(spi_t *obj, uint32_t speed, SPIMode mode, uint8_t msb); void spi_deinit(spi_t *obj); spi_status_e spi_transfer(spi_t *obj, uint8_t *buffer, uint16_t len, uint32_t Timeout, bool skipReceive); From c1b1d61ac158f3c571ad4044f8a97fd59c3bbaf8 Mon Sep 17 00:00:00 2001 From: Frederic Pillon Date: Mon, 20 Nov 2023 17:02:50 +0100 Subject: [PATCH 4/8] feat(spi): remove skip receive from SPISettings This parameter should not be part of SPISettings. Signed-off-by: Frederic Pillon --- libraries/SPI/README.md | 4 ---- libraries/SPI/src/SPI.cpp | 6 +++--- libraries/SPI/src/SPI.h | 15 ++++----------- 3 files changed, 7 insertions(+), 18 deletions(-) diff --git a/libraries/SPI/README.md b/libraries/SPI/README.md index 5bf0889c59..2849c787ac 100644 --- a/libraries/SPI/README.md +++ b/libraries/SPI/README.md @@ -7,10 +7,6 @@ User have 2 possibilities about the management of the CS pin: * the CS pin is managed directly by the user code before to transfer the data (like the Arduino SPI library) * the user uses a hardware CS pin linked to the SPI peripheral -### New SPISetting parameter - -* `noReceive`: value can be `SPI_TRANSMITRECEIVE` or `SPI_TRANSMITONLY`. It allows to skip receive data after transmitting. Default `SPI_TRANSMITRECEIVE`. - ### New API functions * `SPIClass::SPIClass(uint8_t mosi, uint8_t miso, uint8_t sclk, uint8_t ssel)`: alternative class constructor diff --git a/libraries/SPI/src/SPI.cpp b/libraries/SPI/src/SPI.cpp index 15dbb79f18..01d74b2852 100644 --- a/libraries/SPI/src/SPI.cpp +++ b/libraries/SPI/src/SPI.cpp @@ -160,7 +160,7 @@ void SPIClass::setClockDivider(uint8_t divider) */ uint8_t SPIClass::transfer(uint8_t data) { - spi_transfer(&_spi, &data, sizeof(uint8_t), SPI_TRANSFER_TIMEOUT, _spiSettings.noReceive); + spi_transfer(&_spi, &data, sizeof(uint8_t), SPI_TRANSFER_TIMEOUT, false); return data; } @@ -179,7 +179,7 @@ uint16_t SPIClass::transfer16(uint16_t data) data = tmp; } spi_transfer(&_spi, (uint8_t *)&data, sizeof(uint16_t), - SPI_TRANSFER_TIMEOUT, _spiSettings.noReceive); + SPI_TRANSFER_TIMEOUT, false); if (_spiSettings.bitOrder) { tmp = ((data & 0xff00) >> 8) | ((data & 0xff) << 8); @@ -200,7 +200,7 @@ void SPIClass::transfer(void *buf, size_t count) { if ((count != 0) && (buf != NULL)) { spi_transfer(&_spi, ((uint8_t *)buf), count, - SPI_TRANSFER_TIMEOUT, _spiSettings.noReceive); + SPI_TRANSFER_TIMEOUT, false); } } diff --git a/libraries/SPI/src/SPI.h b/libraries/SPI/src/SPI.h index af19d4e38e..fc673ca882 100644 --- a/libraries/SPI/src/SPI.h +++ b/libraries/SPI/src/SPI.h @@ -38,9 +38,6 @@ extern "C" { #define SPI_CLOCK_DIV64 64 #define SPI_CLOCK_DIV128 128 -#define SPI_TRANSMITRECEIVE 0x0 -#define SPI_TRANSMITONLY 0x1 - // Defines a default timeout delay in milliseconds for the SPI transfer #ifndef SPI_TRANSFER_TIMEOUT #define SPI_TRANSFER_TIMEOUT 1000 @@ -48,25 +45,22 @@ extern "C" { class SPISettings { public: - constexpr SPISettings(uint32_t clock, BitOrder bitOrder, SPIMode dataMode, bool noRecv = SPI_TRANSMITRECEIVE) + constexpr SPISettings(uint32_t clock, BitOrder bitOrder, SPIMode dataMode) : clockFreq(clock), bitOrder(bitOrder), - dataMode(dataMode), - noReceive(noRecv) + dataMode(dataMode) { } constexpr SPISettings() : clockFreq(SPI_SPEED_CLOCK_DEFAULT), bitOrder(MSBFIRST), - dataMode(SPI_MODE0), - noReceive(SPI_TRANSMITRECEIVE) + dataMode(SPI_MODE0) { } bool operator==(const SPISettings &rhs) const { if ((this->clockFreq == rhs.clockFreq) && (this->bitOrder == rhs.bitOrder) && - (this->dataMode == rhs.dataMode) && - (this->noReceive == rhs.noReceive)) { + (this->dataMode == rhs.dataMode)) { return true; } return false; @@ -81,7 +75,6 @@ class SPISettings { uint32_t clockFreq; //specifies the spi bus maximum clock speed BitOrder bitOrder; //bit order (MSBFirst or LSBFirst) SPIMode dataMode; //one of the data mode - bool noReceive; friend class SPIClass; }; From 98fca7dc081def1ac072196cf91ffbf82833af89 Mon Sep 17 00:00:00 2001 From: Frederic Pillon Date: Wed, 22 Nov 2023 14:30:24 +0100 Subject: [PATCH 5/8] chore(subghzspi): clean up useless declaration Since internal CS pin removed. Signed-off-by: Frederic Pillon --- libraries/SPI/src/SPI.cpp | 29 ----------------------------- libraries/SPI/src/SPI.h | 9 --------- 2 files changed, 38 deletions(-) diff --git a/libraries/SPI/src/SPI.cpp b/libraries/SPI/src/SPI.cpp index 01d74b2852..4bd483a5da 100644 --- a/libraries/SPI/src/SPI.cpp +++ b/libraries/SPI/src/SPI.cpp @@ -237,35 +237,6 @@ void SPIClass::detachInterrupt(void) } #if defined(SUBGHZSPI_BASE) -void SUBGHZSPIClass::begin() -{ - SPIClass::begin(); -} - -void SUBGHZSPIClass::beginTransaction(SPISettings settings) -{ - SPIClass::beginTransaction(settings); -} - -byte SUBGHZSPIClass::transfer(uint8_t _data) -{ - byte res; - res = SPIClass::transfer(_data); - return res; -} - -uint16_t SUBGHZSPIClass::transfer16(uint16_t _data) -{ - uint16_t rx_buffer = 0; - rx_buffer = SPIClass::transfer16(_data); - return rx_buffer; -} - -void SUBGHZSPIClass::transfer(void *_buf, size_t _count) -{ - SPIClass::transfer(_buf, _count); -} - void SUBGHZSPIClass::enableDebugPins(uint32_t mosi, uint32_t miso, uint32_t sclk, uint32_t ssel) { /* Configure SPI GPIO pins */ diff --git a/libraries/SPI/src/SPI.h b/libraries/SPI/src/SPI.h index fc673ca882..49dcdbcd6e 100644 --- a/libraries/SPI/src/SPI.h +++ b/libraries/SPI/src/SPI.h @@ -174,16 +174,7 @@ class SUBGHZSPIClass : public SPIClass { _spi.spi = SUBGHZSPI; } - void begin(); - void beginTransaction(SPISettings settings); - byte transfer(uint8_t _data); - uint16_t transfer16(uint16_t _data); - void transfer(void *_buf, size_t _count); void enableDebugPins(uint32_t mosi = DEBUG_SUBGHZSPI_MOSI, uint32_t miso = DEBUG_SUBGHZSPI_MISO, uint32_t sclk = DEBUG_SUBGHZSPI_SCLK, uint32_t ssel = DEBUG_SUBGHZSPI_SS); - - using SPIClass::beginTransaction; - using SPIClass::transfer; - using SPIClass::transfer16; }; #endif From aa5abaad419792c61dbab5101d78fe8496da0539 Mon Sep 17 00:00:00 2001 From: Frederic Pillon Date: Tue, 21 Nov 2023 10:04:26 +0100 Subject: [PATCH 6/8] feat(spi): allow to skip receive during transfer Linked to #912. Signed-off-by: Frederic Pillon --- libraries/SPI/README.md | 4 ++++ libraries/SPI/src/SPI.cpp | 21 +++++++++++++++------ libraries/SPI/src/SPI.h | 9 ++++++--- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/libraries/SPI/README.md b/libraries/SPI/README.md index 2849c787ac..a74b2fc272 100644 --- a/libraries/SPI/README.md +++ b/libraries/SPI/README.md @@ -35,6 +35,10 @@ void setup() { } ``` +### Extended API + +* All `transfer()` API's have a new bool argument `skipReceive`. It allows to skip receive data after transmitting. Value can be `SPI_TRANSMITRECEIVE` or `SPI_TRANSMITONLY`. Default `SPI_TRANSMITRECEIVE`. + #### Change default `SPI` instance pins It is also possible to change the default pins used by the `SPI` instance using above API: diff --git a/libraries/SPI/src/SPI.cpp b/libraries/SPI/src/SPI.cpp index 4bd483a5da..f42f2e88d7 100644 --- a/libraries/SPI/src/SPI.cpp +++ b/libraries/SPI/src/SPI.cpp @@ -156,11 +156,14 @@ void SPIClass::setClockDivider(uint8_t divider) * @brief Transfer one byte on the SPI bus. * begin() or beginTransaction() must be called at least once before. * @param data: byte to send. + * @param skipReceive: skip receiving data after transmit or not. + * SPI_TRANSMITRECEIVE or SPI_TRANSMITONLY. + * Optional, default: SPI_TRANSMITRECEIVE. * @return byte received from the slave. */ -uint8_t SPIClass::transfer(uint8_t data) +uint8_t SPIClass::transfer(uint8_t data, bool skipReceive) { - spi_transfer(&_spi, &data, sizeof(uint8_t), SPI_TRANSFER_TIMEOUT, false); + spi_transfer(&_spi, &data, sizeof(uint8_t), SPI_TRANSFER_TIMEOUT, skipReceive); return data; } @@ -168,9 +171,12 @@ uint8_t SPIClass::transfer(uint8_t data) * @brief Transfer two bytes on the SPI bus in 16 bits format. * begin() or beginTransaction() must be called at least once before. * @param data: bytes to send. + * @param skipReceive: skip receiving data after transmit or not. + * SPI_TRANSMITRECEIVE or SPI_TRANSMITONLY. + * Optional, default: SPI_TRANSMITRECEIVE. * @return bytes received from the slave in 16 bits format. */ -uint16_t SPIClass::transfer16(uint16_t data) +uint16_t SPIClass::transfer16(uint16_t data, bool skipReceive) { uint16_t tmp; @@ -179,7 +185,7 @@ uint16_t SPIClass::transfer16(uint16_t data) data = tmp; } spi_transfer(&_spi, (uint8_t *)&data, sizeof(uint16_t), - SPI_TRANSFER_TIMEOUT, false); + SPI_TRANSFER_TIMEOUT, skipReceive); if (_spiSettings.bitOrder) { tmp = ((data & 0xff00) >> 8) | ((data & 0xff) << 8); @@ -195,12 +201,15 @@ uint16_t SPIClass::transfer16(uint16_t data) * @param buf: pointer to the bytes to send. The bytes received are copy in * this buffer. * @param count: number of bytes to send/receive. + * @param skipReceive: skip receiving data after transmit or not. + * SPI_TRANSMITRECEIVE or SPI_TRANSMITONLY. + * Optional, default: SPI_TRANSMITRECEIVE. */ -void SPIClass::transfer(void *buf, size_t count) +void SPIClass::transfer(void *buf, size_t count, bool skipReceive) { if ((count != 0) && (buf != NULL)) { spi_transfer(&_spi, ((uint8_t *)buf), count, - SPI_TRANSFER_TIMEOUT, false); + SPI_TRANSFER_TIMEOUT, skipReceive); } } diff --git a/libraries/SPI/src/SPI.h b/libraries/SPI/src/SPI.h index 49dcdbcd6e..d293d3ac46 100644 --- a/libraries/SPI/src/SPI.h +++ b/libraries/SPI/src/SPI.h @@ -38,6 +38,9 @@ extern "C" { #define SPI_CLOCK_DIV64 64 #define SPI_CLOCK_DIV128 128 +#define SPI_TRANSMITRECEIVE false +#define SPI_TRANSMITONLY true + // Defines a default timeout delay in milliseconds for the SPI transfer #ifndef SPI_TRANSFER_TIMEOUT #define SPI_TRANSFER_TIMEOUT 1000 @@ -131,9 +134,9 @@ class SPIClass { /* Transfer functions: must be called after initialization of the SPI * instance with begin() or beginTransaction(). */ - virtual uint8_t transfer(uint8_t data); - virtual uint16_t transfer16(uint16_t data); - virtual void transfer(void *buf, size_t count); + virtual uint8_t transfer(uint8_t data, bool skipReceive = SPI_TRANSMITRECEIVE); + virtual uint16_t transfer16(uint16_t data, bool skipReceive = SPI_TRANSMITRECEIVE); + virtual void transfer(void *buf, size_t count, bool skipReceive = SPI_TRANSMITRECEIVE); /* These methods are deprecated and kept for compatibility. * Use SPISettings with SPI.beginTransaction() to configure SPI parameters. From 8a01b92bb15db6ec5a056d8cdad034a8134051a0 Mon Sep 17 00:00:00 2001 From: Frederic Pillon Date: Tue, 21 Nov 2023 09:48:56 +0100 Subject: [PATCH 7/8] doc(spi): update README.md Signed-off-by: Frederic Pillon --- libraries/SPI/README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libraries/SPI/README.md b/libraries/SPI/README.md index a74b2fc272..59564fd7e5 100644 --- a/libraries/SPI/README.md +++ b/libraries/SPI/README.md @@ -42,7 +42,8 @@ void setup() { #### Change default `SPI` instance pins It is also possible to change the default pins used by the `SPI` instance using above API: -[[/img/Warning-icon.png|alt="Warning"]] **Have to be called before `begin()`.** +> [!WARNING] +> **Have to be called before `begin()`.** * `void setMISO(uint32_t miso)` * `void setMOSI(uint32_t mosi)` @@ -53,7 +54,8 @@ It is also possible to change the default pins used by the `SPI` instance using * `void setSCLK(PinName sclk)` * `void setSSEL(PinName ssel)` -**_Note 1_** Using `setSSEL()` allows to enable hardware CS pin management linked to the SPI peripheral. +> [!NOTE] +> Using `setSSEL()` allows to enable hardware CS pin management linked to the SPI peripheral. ##### Example: ```C++ From e781dc78a81b3f3fe92d4c49a86e9d59c375a850 Mon Sep 17 00:00:00 2001 From: Frederic Pillon Date: Thu, 23 Nov 2023 17:14:04 +0100 Subject: [PATCH 8/8] feat(spi): add SPISettings constructor with uint8_t for backward compatibility. Example with Adafruit GFX Library library. Signed-off-by: Frederic Pillon --- libraries/SPI/src/SPI.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libraries/SPI/src/SPI.h b/libraries/SPI/src/SPI.h index d293d3ac46..1c8bbc11cd 100644 --- a/libraries/SPI/src/SPI.h +++ b/libraries/SPI/src/SPI.h @@ -48,6 +48,11 @@ extern "C" { class SPISettings { public: + constexpr SPISettings(uint32_t clock, BitOrder bitOrder, uint8_t dataMode) + : clockFreq(clock), + bitOrder(bitOrder), + dataMode((SPIMode)dataMode) + { } constexpr SPISettings(uint32_t clock, BitOrder bitOrder, SPIMode dataMode) : clockFreq(clock), bitOrder(bitOrder), 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