RadioHead
Public Member Functions | Protected Member Functions | List of all members
RH_STM32WLx Class Reference

Driver to send and receive unaddressed, unreliable datagrams via a SX1261 LoRa capable radio transceiver embedded in a ST Microelectronics STM32WLE5xx and STM32WLE4xx processors. More...

#include <RH_STM32WLx.h>

Inheritance diagram for RH_STM32WLx:
RH_SX126x RHSPIDriver RHGenericDriver

Public Member Functions

virtual bool init ()
 
- Public Member Functions inherited from RH_SX126x
 RH_SX126x (uint8_t slaveSelectPin=SS, uint8_t interruptPin=2, uint8_t busyPin=RH_INVALID_PIN, uint8_t resetPin=RH_INVALID_PIN, RHGenericSPI &spi=hardware_spi, RadioPinConfig *radioPinConfig=nullptr)
 
virtual bool init ()
 
bool printRegisters (uint16_t address, uint8_t count)
 
bool setModemRegisters (const ModemConfig *config)
 
bool setModemConfig (ModemConfigChoice index)
 
virtual bool available ()
 
virtual bool recv (uint8_t *buf, uint8_t *len)
 
virtual bool send (const uint8_t *data, uint8_t len)
 
void setPreambleLength (uint16_t bytes)
 
virtual uint8_t maxMessageLength ()
 
bool setFrequency (float centre, bool calibrate=true)
 
void setModeIdle ()
 
void setModeRx ()
 
void setModeTx ()
 
virtual bool setTxPower (int8_t power)
 
virtual bool sleep ()
 
virtual bool isChannelActive ()
 
int lastSNR ()
 
void setRadioPinConfig (RadioPinConfig *config)
 
bool setTxContinuous ()
 
uint8_t getStatus ()
 Read and return the radio status byte.
 
- Public Member Functions inherited from RHSPIDriver
 RHSPIDriver (uint8_t slaveSelectPin=SS, RHGenericSPI &spi=hardware_spi)
 
bool init ()
 
uint8_t spiRead (uint8_t reg)
 
uint8_t spiWrite (uint8_t reg, uint8_t val)
 
uint8_t spiBurstRead (uint8_t reg, uint8_t *dest, uint8_t len)
 
uint8_t spiBurstWrite (uint8_t reg, const uint8_t *src, uint8_t len)
 
void setSlaveSelectPin (uint8_t slaveSelectPin)
 
void spiUsingInterrupt (uint8_t interruptNumber)
 
- Public Member Functions inherited from RHGenericDriver
 RHGenericDriver ()
 Constructor.
 
virtual ~RHGenericDriver ()
 Generic destructor to prevent warnings when objects are dynamically allocated.
 
virtual bool init ()
 
virtual bool available ()=0
 
virtual bool recv (uint8_t *buf, uint8_t *len)=0
 
virtual bool send (const uint8_t *data, uint8_t len)=0
 
virtual uint8_t maxMessageLength ()=0
 
virtual void waitAvailable (uint16_t polldelay=0)
 
virtual bool waitPacketSent ()
 
virtual bool waitPacketSent (uint16_t timeout)
 
virtual bool waitAvailableTimeout (uint16_t timeout, uint16_t polldelay=0)
 
virtual bool waitCAD ()
 
void setCADTimeout (unsigned long cad_timeout)
 
virtual bool isChannelActive ()
 
virtual void setThisAddress (uint8_t thisAddress)
 
virtual void setHeaderTo (uint8_t to)
 
virtual void setHeaderFrom (uint8_t from)
 
virtual void setHeaderId (uint8_t id)
 
virtual void setHeaderFlags (uint8_t set, uint8_t clear=RH_FLAGS_APPLICATION_SPECIFIC)
 
virtual void setPromiscuous (bool promiscuous)
 
virtual uint8_t headerTo ()
 
virtual uint8_t headerFrom ()
 
virtual uint8_t headerId ()
 
virtual uint8_t headerFlags ()
 
virtual int16_t lastRssi ()
 
virtual RHMode mode ()
 
virtual void setMode (RHMode mode)
 Sets the operating mode of the transport. More...
 
virtual bool sleep ()
 
virtual uint16_t rxBad ()
 
virtual uint16_t rxGood ()
 
virtual uint16_t txGood ()
 

Protected Member Functions

virtual bool waitUntilNotBusy ()
 
bool setupInterruptHandler ()
 
- Protected Member Functions inherited from RH_SX126x
virtual bool waitUntilNotBusy ()
 
bool sendCommand (uint8_t command, uint8_t data[], uint8_t len)
 Send a command with multi-byte data to the radio.
 
bool sendCommand (uint8_t command, uint8_t value)
 Send a command with a single data byte to the radio.
 
bool sendCommand (uint8_t command)
 Send a command without any data to the radio.
 
bool getCommand (uint8_t command, uint8_t data[], uint8_t len)
 Send a command to the radio and get a multi-byte respose.
 
bool readRegisters (uint16_t address, uint8_t data[], uint8_t len)
 Read multiple registers from the radio.
 
uint8_t readRegister (uint16_t address)
 Read and return a single register byte from the radio.
 
bool writeRegisters (uint16_t address, uint8_t data[], uint8_t len)
 Write multibyte data to the given register and sunbsequent registers.
 
bool writeRegister (uint16_t address, uint8_t data)
 Write a single byte to the given register.
 
bool writeBuffer (uint8_t offset, const uint8_t data[], uint8_t len)
 Write multibyte data to the radio IO buffer at the current buffer address.
 
bool writeBuffer (uint8_t offset, const char *text)
 Write a single byte to the radio IO bufferat the current buffer address.
 
bool readBuffer (uint8_t offset, uint8_t data[], uint8_t len)
 Read multibyte data from the radio IO buffer at the current buffer address.
 
bool setPaConfig (uint8_t paDutyCycle, uint8_t hpMax, uint8_t deviceSel, uint8_t paLut)
 Set the radio Power Amplifier configuration.
 
bool setTxParams (uint8_t power, uint8_t rampTime)
 Set the radio power output. CAUTION: for internal use only. Users should use setTxPower()
 
bool clearDeviceErrors ()
 Clear the radio error byte.
 
bool setDIO2AsRfSwitchCtrl (bool value)
 
bool setRxFallbackMode (uint8_t mode)
 Sets the mode that the radio will change to after a transmit or receive is complete.
 
bool setModulationParameters (uint8_t p1, uint8_t p2, uint8_t p3, uint8_t p4, uint8_t p5, uint8_t p6, uint8_t p7, uint8_t p8)
 Set the low-level registers for any desired modulation scheme.
 
bool setModulationParametersLoRa (uint8_t sf, float bw, uint8_t cr, bool ldro)
 Set the low-level registers for the desired LoRA modulation scheme.
 
bool setModulationParametersGFSK (uint32_t br, uint8_t sh, uint8_t rxBw, uint32_t freqDev)
 Set the low-level registers for the desired GFSK modulation scheme.
 
bool calibrate (uint8_t calib_param)
 Cause the radio to calibrate all its sections at the currently selected frequency.
 
bool calibrateImage (uint8_t f1, uint8_t f2)
 Allows the user to calibrate the image rejection of the device for the device operating frequency band.
 
bool setLoRaSyncWord (uint16_t sync)
 Set the 16 bit LoRa sync word.
 
bool setOCPConfiguration (uint8_t setting)
 Set the radio power amplifier over-current protection.
 
bool setDIO3AsTcxoCtrl (uint8_t voltage, uint32_t delay)
 
bool setTCXO (float voltage, uint32_t delay)
 Set the voltage to use for the TCXO oven.
 
bool setPacketParams (uint8_t p1, uint8_t p2, uint8_t p3, uint8_t p4, uint8_t p5, uint8_t p6, uint8_t p7, uint8_t p8, uint8_t p9)
 Low level function to set the radio packet confiuration.
 
bool setPacketParametersLoRa (uint8_t payload_length)
 Set the necessary radio packet parameters for a forthcoming transmission of payload_length bytes.
 
bool setBufferBaseAddress (uint8_t txbase, uint8_t rxbase)
 Low level function to set the address wherge the next radBuffer or writeBuffer will occur.
 
bool setSleep (uint8_t config)
 Set the radio to sleep mode. Automatically configures the radio control pins to the configuration RadioPinConfigMode_IDLE.
 
bool setStandby (uint8_t config)
 Set the radio to sleep mode. Automatically configures the radio control pins to the configuration RadioPinConfigMode_IDLE.
 
bool setTx (uint32_t timeout)
 
bool setCad ()
 Starts the radio in Clear Air Detect (CAD) mode. CAUTION: NOT YET WORKING, always retuns false.
 
bool setRx (uint32_t timeout)
 Set the radio to receive mode. Automatically configures the radio control pins to the configuration RadioPinConfigMode_RX.
 
bool setRxBoostMode (bool boost, bool retain)
 Sets whether radios receiver gain boost should be enabled instead of the default power saving mode.
 
bool setRegulatorMode (uint8_t mode)
 
bool setDioIrqParams (uint16_t irqmask, uint16_t dio1mask, uint16_t dio2mask, uint16_t dio3mask)
 Configures the conditions under which the radio will enable an interrupt, and for which DIO pins.
 
bool clearIrqStatus (uint16_t mask)
 Clear the radio IRQ state.
 
uint16_t getIrqStatus ()
 Return the radio IRQ state.
 
uint8_t getPacketType ()
 return the current packet type
 
void setInvertIQ (bool invertIQ)
 
bool fixPAClamping (bool enable)
 Per SX1262_datasheet.pdf Rev 1.2 section 15.2, this fixes an error in the radio Power Amplifier clamping.
 
virtual bool setupInterruptHandler ()
 Do whatever is necesary to establish the interrupt handler. Subclasses may have different needs. More...
 
void handleInterrupt ()
 
void validateRxBuf ()
 Examine the revceive buffer to determine whether the message is for this node.
 
void clearRxBuf ()
 Clear our local receive buffer.
 
virtual bool modeWillChange (RHMode)
 
virtual bool setRadioPinsForMode (RadioPinConfigMode mode)
 
virtual RadioPinConfigEntryfindRadioPinConfigEntry (RadioPinConfigMode mode)
 Find the pin configuration entry for a desired radio mode.
 
- Protected Member Functions inherited from RHSPIDriver
virtual void beginTransaction ()
 
virtual void endTransaction ()
 
virtual void selectSlave ()
 
virtual void deselectSlave ()
 

Additional Inherited Members

- Public Types inherited from RH_SX126x
enum  PacketType { PacketTypeLoRa = 0 , PacketTypeGFSK }
 Packet types the modem can be configured for. More...
 
enum  ModemConfigChoice {
  LoRa_Bw125Cr45Sf128 = 0 , LoRa_Bw500Cr45Sf128 , LoRa_Bw31_25Cr48Sf512 , LoRa_Bw125Cr48Sf4096 ,
  LoRa_Bw125Cr45Sf2048
}
 
enum  RadioPinConfigMode {
  RadioPinConfigMode_EOT = 0 , RadioPinConfigMode_IDLE , RadioPinConfigMode_RX , RadioPinConfigMode_TX_LOW_POWER ,
  RadioPinConfigMode_TX_HIGH_POWER
}
 
- Public Types inherited from RHGenericDriver
enum  RHMode {
  RHModeInitialising = 0 , RHModeSleep , RHModeIdle , RHModeTx ,
  RHModeRx , RHModeCad
}
 Defines different operating modes for the transport hardware. More...
 
- Static Public Member Functions inherited from RHGenericDriver
static void printBuffer (const char *prompt, const uint8_t *buf, uint8_t len)
 
- Protected Attributes inherited from RHSPIDriver
RHGenericSPI_spi
 Reference to the RHGenericSPI instance to use to transfer data with the SPI device.
 
uint8_t _slaveSelectPin
 The pin number of the Slave Select pin that is used to select the desired device.
 
- Protected Attributes inherited from RHGenericDriver
volatile RHMode _mode
 The current transport operating mode.
 
uint8_t _thisAddress
 This node id.
 
bool _promiscuous
 Whether the transport is in promiscuous mode.
 
volatile uint8_t _rxHeaderTo
 TO header in the last received mesasge.
 
volatile uint8_t _rxHeaderFrom
 FROM header in the last received mesasge.
 
volatile uint8_t _rxHeaderId
 ID header in the last received mesasge.
 
volatile uint8_t _rxHeaderFlags
 FLAGS header in the last received mesasge.
 
uint8_t _txHeaderTo
 TO header to send in all messages.
 
uint8_t _txHeaderFrom
 FROM header to send in all messages.
 
uint8_t _txHeaderId
 ID header to send in all messages.
 
uint8_t _txHeaderFlags
 FLAGS header to send in all messages.
 
volatile int16_t _lastRssi
 The value of the last received RSSI value, in some transport specific units.
 
volatile uint16_t _rxBad
 Count of the number of bad messages (eg bad checksum etc) received.
 
volatile uint16_t _rxGood
 Count of the number of successfully transmitted messaged.
 
volatile uint16_t _txGood
 Count of the number of bad messages (correct checksum etc) received.
 
volatile bool _cad
 Channel activity detected.
 
unsigned int _cad_timeout
 Channel activity timeout in ms.
 

Detailed Description

Driver to send and receive unaddressed, unreliable datagrams via a SX1261 LoRa capable radio transceiver embedded in a ST Microelectronics STM32WLE5xx and STM32WLE4xx processors.

Overview

The ST Microelectronics STM32WLE5xx and STM32WLE4xx Arm Cortex processors contain a SX1261 radio with 2 power amplifiers (PAs), a bit like a combination of a SX1261 and SX1262. There is a dedicated SPI interface (called the SubGhzSPI that is used only to communicate with the radio.

The Seeed LoRa-E5-HF and LoRa-E5-LF modules encapsulate a STM32WLE5JC processor, along with an antenna switch, Temperature Controlled Crystal Oscillator (TCXO) and some support components. The Seeed Wio-E5 mini developement board (described below) has a LoRa-E5-HF along with voltage regulator, USB interface, antenna connector etc.

This class is a subclass of RH_SX126x. See the documentation for that class for more details about configuring and using this class.

The stmx32wl_* examples provided should compile out of the box on Arduino 2.1 or later and run with either modules equipped with LoRa-E4 or on the NUCLEO_WL55JC1. Make sure you select the appropriate board in Arduino.

The Seeed Wio-E5 mini

One example of a development board that includes a STM32WLE5xx and SX1261 radio is the Wio-E5 mini.

The Wio-E5 mini is powered by the ST Microelectronics STM32WLE5JC, which contains an ARM Cortex-M4 core and Semtech SX126X LoRa capable radio. The core and radio are enclosed in a sealed Seeed LoRa-E5-HF module, and which includes an antenna switch.

https://wiki.seeedstudio.com/LoRa_E5_mini/ https://files.seeedstudio.com/products/317990687/res/LoRa-E5+module+datasheet_V1.0.pdf

It comes with a 868 to 915MHz compatible antenna and USB-C cable.

As shipped, the Wio-E5 mini contains firmware that provides a serial AT command set that allows the device to connect to join a LoRaWAN network (via a LoRaWAN gateway) using LoRA radio modulation. https://files.seeedstudio.com/products/317990687/res/LoRa-E5+AT+Command+Specification_V1.0+.pdf

You can plug the WiO E5 into a USB port, and use a serial port program (gtkterm, putty, Hyperterm or whatever) to communicate (using AT commands) with the Wio-E5, configure it and then use it to send LoRaWAN messages to a LoRaWAN server.

However, what we want to do is to upload RadioHead based firmware into the Wio-E5 and use the built in SX126X radio to communicate via LoRa radio modulation with other similar LoRA radio nodes.

Note: LoRa is NOT the same thing as LoRaWAN. LoRaWAN is a complete networking system that uses LoRa radio modulation as the transport layer. If you want to work with a LoRaWAN network, you should be using LoRaWAN software and libraries, not RadioHead. LoRa is a much simpler and lower level transport layer that can he used to send short messages over significant distances withglow power.

So, we want to upload RadioHead based software (containing the RadioHead SX126X driver) to the STM32WLE5JC on the Wio-E5. Before we can do that we have to disable the firmware write protection on the STM32WLE5JC.

The Wio-E5 (as shipped) AT command firmware is protected by the ARM processor's Read Out Protection (RDP) byte, meaning you cant read out the AT command set firmware, nor can you upload new firmware, The RDP byte has to be reset first.

But CAUTION: resetting the RDP byte will permanently ERASE the as-shipped AT command firmware, and THERE IS NO WAY TO GET IT BACK. So make sure thats what you want to do.

In order to be able to upload our own firmware we must reset the RDP byte from the as-shipped value of 0xBB (Level 1 read protection) to 0xAA (Level 0, no protection). In order to do this you will need:

  1. Install STM32CubeProgrammer
  2. Wire the STLink/V2 to the Wio-E5 pins with the jumper wires provided. This will provide both power and communications with the STM32WLE5JC: Wio-E5 STLink/V2 (writing on the end shows the pinout)
    3.3V 3.3V
    GND GND
    DIO SWDIO
    CLK SWCLK
  3. Plug the STLink/V2 into a USB port. Red light should appear on the STLink/V2.
  4. Run STM32CubeProgrammer (appears in Ubuntu Applications menu if installed on Linux with wine)
  5. At the top right you should see ST-LINK selected, and below that, in the ST-LINK Configuration box, the Serial number of your STLink/V2. 6a. If this is the first time you have used the STLink/V2, you will need to upgrade its firmware. Click on 'Firmware upgrade' in the ST-LINK Configuration box, get the Upgrade dialog. 6b. Click on 'Open in update mode'. If it complains the STlink is not in DFU mode, unplug and replug the STlink, click on 'Refresh device list', then 'Open in update mode' 6c Click on Upgrade. Wait 20 seconds. See success. 6d Close the dialog. 7a Press RST reset pin on the Wio-E5 and then immediately: 7b Click on 'Connect' top right of STM32CubeProgrammer. You should see some blue progress lines in the Log, maybe finally a red 'Data read failed'. Thats OK, because the RDP byte is still set.
  6. Click on the 'OB' icon, 3rd from the top in the far left margin.
  7. Select Read Out Protection item, see RDP value set to 'BB'. Change to 'AA', click Apply. See pop-up 'Option Bytes successfully programmed'.

Good! The STM32WLE5JC firmware can now be written and read as we need (note that the factory supplied LoRaWan firmware has now been erased), by either STM32CubeProgrammer or Arduino IDE (2.1.1 or later) via the STLink/V2, so leave it connected

In order to use the Arduino IDE to program the Wio-E5, you must install the stm32duino package using these instructions: https://community.st.com/t5/stm32-mcus/stm32-arduino-stm32duino-tutorial/ta-p/49649

Leave STLink/V2 connected but close STM32CubeProgrammer In Arduino IDE: select the following menu options: Tools -> Board -> STM32 MCU based boards -> LoRa boards Tools -> Board part number -> LoRa-E5 mini Tools -> U(S)ART support -> Enabled (generic Serial) You will then be able to edit and upload directly from Arduino IDE through the STLink/V2 You can connect the Wio-E5 USB-C to your hosts USB port and use Arduino IDE to monitor the serial output to Serial (Note: programming does not occur over the USB connection).

There are other options for programming the STM32WLE5JC, including STM32CubeIDE from ST. We did not test them.

https://www.rfsolutions.co.uk/downloads/1537522406DS_SX1261-2_V1.1_SEMTECH.pdf

Lora-net software: https://github.com/Lora-net/SWL2001/releases/tag/v3.3.0

Interrupts

This driver uses the SubGhzClass class (part of the Arduino stm32duino board support) to interface with the internal SX1261/2 radio. That class implements the dedicated radio SPI interface. The radio also has a dedicated internal pin for the radio interrupt and the SPI device select pin and the radio reset pin. The SubGhzClass class includes methods for using all those pins.

Nevertheless it should be possible to use this processor with the normal external SPI interfaces to also interface with another SPI based RadioHEad supported radio, in oprder to make a radio gateway etc.

Member Function Documentation

◆ init()

virtual bool RH_STM32WLx::init ( )
virtual

Initialise the Driver transport hardware and software. Leaves the radio in idle mode, with default configuration of: 915.0MHz, 13dBm, Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on

Returns
true if initialisation succeeded.

Reimplemented from RH_SX126x.

◆ setupInterruptHandler()

bool RH_STM32WLx::setupInterruptHandler ( )
protectedvirtual

Do whatever is necesary to establish the interrupt handler. This device has special requirements for setting up the interupt handler through the SUBGHZSPI interface so we override

Reimplemented from RH_SX126x.

◆ waitUntilNotBusy()

virtual bool RH_STM32WLx::waitUntilNotBusy ( )
inlineprotectedvirtual

Wait until the busy pin (if speecified in the contructor) is no longer low On timeout, prints an error to eSerial and returns false. Else returns true.

Reimplemented from RH_SX126x.


The documentation for this class was generated from the following file: