diff --git a/libraries/SPI/README.md b/libraries/SPI/README.md index 5bf0889c59..59564fd7e5 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 @@ -39,10 +35,15 @@ 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: -[[/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++ diff --git a/libraries/SPI/src/SPI.cpp b/libraries/SPI/src/SPI.cpp index b3266d348a..f42f2e88d7 100644 --- a/libraries/SPI/src/SPI.cpp +++ b/libraries/SPI/src/SPI.cpp @@ -57,10 +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; - _spiSettings = DEFAULT_SPI_SETTINGS; - spi_init(&_spi, _spiSettings.getClockFreq(), - _spiSettings.getDataMode(), - _spiSettings.getBitOrder()); + _spiSettings = SPISettings(); + spi_init(&_spi, _spiSettings.clockFreq, + _spiSettings.dataMode, + _spiSettings.bitOrder); } /** @@ -72,9 +72,9 @@ void SPIClass::beginTransaction(SPISettings settings) { if (_spiSettings != settings) { _spiSettings = settings; - spi_init(&_spi, _spiSettings.getClockFreq(), - _spiSettings.getDataMode(), - _spiSettings.getBitOrder()); + spi_init(&_spi, _spiSettings.clockFreq, + _spiSettings.dataMode, + _spiSettings.bitOrder); } } @@ -89,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); } @@ -97,15 +97,15 @@ 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.setBitOrder(bitOrder); + _spiSettings.bitOrder = bitOrder; - spi_init(&_spi, _spiSettings.getClockFreq(), - _spiSettings.getDataMode(), - _spiSettings.getBitOrder()); + spi_init(&_spi, _spiSettings.clockFreq, + _spiSettings.dataMode, + _spiSettings.bitOrder); } /** @@ -119,7 +119,6 @@ void SPIClass::setBitOrder(BitOrder bitOrder) * SPI_MODE2 1 0 * SPI_MODE3 1 1 */ - void SPIClass::setDataMode(uint8_t mode) { setDataMode((SPIMode)mode); @@ -127,42 +126,44 @@ void SPIClass::setDataMode(uint8_t mode) void SPIClass::setDataMode(SPIMode mode) { - _spiSettings.setDataMode(mode); - - spi_init(&_spi, _spiSettings.getClockFreq(), - _spiSettings.getDataMode(), - _spiSettings.getBitOrder()); + _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.setClockFreq(SPI_SPEED_CLOCK_DEFAULT); + if (divider == 0) { + _spiSettings.clockFreq = 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.clockFreq = spi_getClkFreq(&_spi) / divider; } - spi_init(&_spi, _spiSettings.getClockFreq(), - _spiSettings.getDataMode(), - _spiSettings.getBitOrder()); + spi_init(&_spi, _spiSettings.clockFreq, + _spiSettings.dataMode, + _spiSettings.bitOrder); } /** * @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, _spiSettings.getSkipRecv()); + spi_transfer(&_spi, &data, sizeof(uint8_t), SPI_TRANSFER_TIMEOUT, skipReceive); return data; } @@ -170,20 +171,23 @@ 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; - if (_spiSettings.getBitOrder()) { + 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.getSkipRecv()); + SPI_TRANSFER_TIMEOUT, skipReceive); - if (_spiSettings.getBitOrder()) { + if (_spiSettings.bitOrder) { tmp = ((data & 0xff00) >> 8) | ((data & 0xff) << 8); data = tmp; } @@ -197,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, _spiSettings.getSkipRecv()); + SPI_TRANSFER_TIMEOUT, skipReceive); } } @@ -239,35 +246,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 9509c871eb..1c8bbc11cd 100644 --- a/libraries/SPI/src/SPI.h +++ b/libraries/SPI/src/SPI.h @@ -38,8 +38,8 @@ extern "C" { #define SPI_CLOCK_DIV64 64 #define SPI_CLOCK_DIV128 128 -#define SPI_TRANSMITRECEIVE 0x0 -#define SPI_TRANSMITONLY 0x1 +#define SPI_TRANSMITRECEIVE false +#define SPI_TRANSMITONLY true // Defines a default timeout delay in milliseconds for the SPI transfer #ifndef SPI_TRANSFER_TIMEOUT @@ -48,36 +48,27 @@ 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); - } + 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), + dataMode(dataMode) + { } + constexpr SPISettings() + : clockFreq(SPI_SPEED_CLOCK_DEFAULT), + bitOrder(MSBFIRST), + dataMode(SPI_MODE0) + { } bool operator==(const SPISettings &rhs) const { if ((this->clockFreq == rhs.clockFreq) && (this->bitOrder == rhs.bitOrder) && - (this->dataMode == rhs.dataMode) && - (this->skipRecv == rhs.skipRecv)) { + (this->dataMode == rhs.dataMode)) { return true; } return false; @@ -88,65 +79,14 @@ class SPISettings { 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; - } - 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; //specifies the spi bus maximum clock speed + BitOrder bitOrder; //bit order (MSBFirst or LSBFirst) + SPIMode dataMode; //one of the data mode - uint32_t clockFreq; - SPIMode dataMode; - BitOrder bitOrder; - bool skipRecv; - - friend class HardwareSPI; + friend class SPIClass; }; -const SPISettings DEFAULT_SPI_SETTINGS = SPISettings(); - class SPIClass { public: SPIClass(); @@ -199,9 +139,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. @@ -229,7 +169,7 @@ class SPIClass { private: /* Current SPISettings */ - SPISettings _spiSettings = DEFAULT_SPI_SETTINGS; + SPISettings _spiSettings = SPISettings(); }; extern SPIClass SPI; @@ -242,16 +182,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 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()
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: