Update RadioLib

This commit is contained in:
lewisxhe 2026-04-17 10:15:48 +08:00
commit 811f6064d7
183 changed files with 19613 additions and 10628 deletions

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,847 @@
#if !defined(RADIOLIB_LR2021_H)
#define RADIOLIB_LR2021_H
#include "../../TypeDef.h"
#if !RADIOLIB_EXCLUDE_LR2021
#include "../../Module.h"
#include "../../protocols/PhysicalLayer/PhysicalLayer.h"
#include "../LR11x0/LR_common.h"
#include "LR2021_commands.h"
#include "LR2021_types.h"
// LR2021 physical layer properties
#define RADIOLIB_LR2021_FREQUENCY_STEP_SIZE 1.0
#define RADIOLIB_LR2021_MAX_PACKET_LENGTH 255
#define RADIOLIB_LR2021_CRYSTAL_FREQ 32.0
#define RADIOLIB_LR2021_DIV_EXPONENT 25
/*!
\class LR2021
\brief
*/
class LR2021: public LRxxxx {
public:
// introduce PhysicalLayer overloads
using PhysicalLayer::transmit;
using PhysicalLayer::receive;
using PhysicalLayer::startTransmit;
using PhysicalLayer::startReceive;
using PhysicalLayer::readData;
/*!
\brief Default constructor.
\param mod Instance of Module that will be used to communicate with the radio.
*/
LR2021(Module* mod); // cppcheck-suppress noExplicitConstructor
/*!
\brief Which DIO pin is to be used as the interrupt pin.
*/
uint32_t irqDioNum = 5;
/*!
\brief Custom operation modes for LR2021.
Needed because LR2021 has several modems (sub-GHz, 2.4 GHz etc.) in one package
*/
enum OpMode_t {
/*! End of table marker, use \ref END_OF_MODE_TABLE constant instead */
MODE_END_OF_TABLE = Module::MODE_END_OF_TABLE,
/*! Standby/idle mode */
MODE_STBY = Module::MODE_IDLE,
/*! Receive mode */
MODE_RX = Module::MODE_RX,
/*! Transmission mode */
MODE_TX = Module::MODE_TX,
/*! High frequency receive mode */
MODE_RX_HF,
/*! High frequency transmission mode */
MODE_TX_HF,
};
// basic methods
/*!
\brief Initialization method for LoRa modem.
\param freq Carrier frequency in MHz. Defaults to 434.0 MHz.
\param bw LoRa bandwidth in kHz. Defaults to 125.0 kHz.
\param sf LoRa spreading factor. Defaults to 9.
\param cr LoRa coding rate denominator. Defaults to 7 (coding rate 4/7). Allowed values range from 4 to 8. Note that a value of 4 means no coding,
is undocumented and not recommended without your own FEC.
\param syncWord 1-byte LoRa sync word. Defaults to RADIOLIB_LR2021_LORA_SYNC_WORD_PRIVATE (0x12).
\param power Output power in dBm. Defaults to 10 dBm.
\param preambleLength LoRa preamble length in symbols. Defaults to 8 symbols.
\param tcxoVoltage TCXO reference voltage to be set. Defaults to 1.6 V.
If you are seeing -706/-707 error codes, it likely means you are using non-0 value for module with XTAL.
To use XTAL, either set this value to 0, or set LR2021::XTAL to true.
\returns \ref status_codes
*/
int16_t begin(float freq = 434.0, float bw = 125.0, uint8_t sf = 9, uint8_t cr = 7, uint8_t syncWord = RADIOLIB_LR2021_LORA_SYNC_WORD_PRIVATE, int8_t power = 10, uint16_t preambleLength = 8, float tcxoVoltage = 1.6);
/*!
\brief Initialization method for FSK modem.
\param freq Carrier frequency in MHz. Defaults to 434.0 MHz.
\param br FSK bit rate in kbps. Defaults to 4.8 kbps.
\param freqDev Frequency deviation from carrier frequency in kHz. Defaults to 5.0 kHz.
\param rxBw Receiver bandwidth in kHz. Defaults to 153.8 kHz.
\param power Output power in dBm. Defaults to 10 dBm.
\param preambleLength FSK preamble length in bits. Defaults to 16 bits.
\param tcxoVoltage TCXO reference voltage to be set. Defaults to 1.6 V.
If you are seeing -706/-707 error codes, it likely means you are using non-0 value for module with XTAL.
To use XTAL, either set this value to 0, or set LR2021::XTAL to true.
\returns \ref status_codes
*/
int16_t beginGFSK(float freq = 434.0, float br = 4.8, float freqDev = 5.0, float rxBw = 153.8, int8_t power = 10, uint16_t preambleLength = 16, float tcxoVoltage = 1.6);
/*!
\brief Initialization method for OOK modem.
\param freq Carrier frequency in MHz. Defaults to 434.0 MHz.
\param br OOK bit rate in kbps. Defaults to 4.8 kbps.
\param rxBw Receiver bandwidth in kHz. Defaults to 153.8 kHz.
\param power Output power in dBm. Defaults to 10 dBm.
\param preambleLength OOK preamble length in bits. Defaults to 16 bits.
\param tcxoVoltage TCXO reference voltage to be set. Defaults to 1.6 V.
If you are seeing -706/-707 error codes, it likely means you are using non-0 value for module with XTAL.
To use XTAL, either set this value to 0, or set LR2021::XTAL to true.
\returns \ref status_codes
*/
int16_t beginOOK(float freq = 434.0, float br = 4.8, float rxBw = 153.8, int8_t power = 10, uint16_t preambleLength = 16, float tcxoVoltage = 1.6);
/*!
\brief Initialization method for LR-FHSS modem.
\param freq Carrier frequency in MHz. Defaults to 434.0 MHz.
\param bw LR-FHSS bandwidth, one of RADIOLIB_LRXXXX_LR_FHSS_BW_* values. Defaults to 722.66 kHz.
\param cr LR-FHSS coding rate, one of RADIOLIB_LRXXXX_LR_FHSS_CR_* values. Defaults to 2/3 coding rate.
\param narrowGrid Whether to use narrow (3.9 kHz) or wide (25.39 kHz) grid spacing. Defaults to true (narrow/non-FCC) grid.
\param power Output power in dBm. Defaults to 10 dBm.
\param tcxoVoltage TCXO reference voltage to be set. Defaults to 1.6 V.
If you are seeing -706/-707 error codes, it likely means you are using non-0 value for module with XTAL.
To use XTAL, either set this value to 0, or set LR2021::XTAL to true.
\returns \ref status_codes
*/
int16_t beginLRFHSS(float freq = 434.0, uint8_t bw = RADIOLIB_LRXXXX_LR_FHSS_BW_722_66, uint8_t cr = RADIOLIB_LRXXXX_LR_FHSS_CR_2_3, bool narrowGrid = true, int8_t power = 10, float tcxoVoltage = 1.6);
/*!
\brief Initialization method for FLRC modem.
\param freq Carrier frequency in MHz. Defaults to 434.0 MHz.
\param br FLRC bit rate in kbps. Defaults to 650 kbps.
\param cr FLRC coding rate. Defaults to RADIOLIB_LR2021_FLRC_CR_2_3 (coding rate 2/3).
\param pwr Output power in dBm. Defaults to 10 dBm.
\param preambleLength FLRC preamble length in bits. Defaults to 16 bits.
\param dataShaping Time-bandwidth product of the Gaussian filter to be used for shaping. Defaults to 0.5.
\returns \ref status_codes
*/
int16_t beginFLRC(float freq = 434.0, uint16_t br = 650, uint8_t cr = RADIOLIB_LR2021_FLRC_CR_2_3, int8_t pwr = 10, uint16_t preambleLength = 16, uint8_t dataShaping = RADIOLIB_SHAPING_0_5, float tcxoVoltage = 1.6);
/*!
\brief Blocking binary transmit method.
Overloads for string-based transmissions are implemented in PhysicalLayer.
\param data Binary data to be sent.
\param len Number of bytes to send.
\param addr Address to send the data to. Will only be added if address filtering was enabled.
\returns \ref status_codes
*/
int16_t transmit(const uint8_t* data, size_t len, uint8_t addr = 0) override;
/*!
\brief Blocking binary receive method.
Overloads for string-based transmissions are implemented in PhysicalLayer.
\param data Pointer to array to save the received binary data.
\param len Number of bytes that will be received. Must be known in advance for binary transmissions.
\param timeout Reception timeout in milliseconds. If set to 0,
timeout period will be calculated automatically based on the radio configuration.
\returns \ref status_codes
*/
int16_t receive(uint8_t* data, size_t len, RadioLibTime_t timeout = 0) override;
/*!
\brief Starts direct mode transmission.
\param frf Raw RF frequency value. Defaults to 0, required for quick frequency shifts in RTTY.
\returns \ref status_codes
*/
int16_t transmitDirect(uint32_t frf = 0) override;
/*!
\brief Starts direct mode reception. Only implemented for PhysicalLayer compatibility, as LR2021 does not support direct mode reception.
Will always return RADIOLIB_ERR_UNKNOWN.
\returns \ref status_codes
*/
int16_t receiveDirect() override;
/*!
\brief Performs scan for LoRa transmission in the current channel. Detects both preamble and payload.
\returns \ref status_codes
*/
int16_t scanChannel() override;
/*!
\brief Performs scan for LoRa transmission in the current channel. Detects both preamble and payload.
\param config CAD configuration structure.
\returns \ref status_codes
*/
int16_t scanChannel(const ChannelScanConfig_t &config) override;
/*!
\brief Sets the module to standby mode (overload for PhysicalLayer compatibility, uses 13 MHz RC oscillator).
\returns \ref status_codes
*/
int16_t standby() override;
/*!
\brief Sets the module to standby mode.
\param mode Oscillator to be used in standby mode. Can be set to RADIOLIB_LR2021_STANDBY_RC (13 MHz RC oscillator)
or RADIOLIB_LR2021_STANDBY_XOSC (32 MHz external crystal oscillator).
\returns \ref status_codes
*/
int16_t standby(uint8_t mode) override;
/*!
\brief Sets the module to standby mode.
\param mode Oscillator to be used in standby mode. Can be set to RADIOLIB_LR2021_STANDBY_RC (13 MHz RC oscillator)
or RADIOLIB_LR2021_STANDBY_XOSC (32 MHz external crystal oscillator).
\param wakeup Whether to force the module to wake up. Setting to true will immediately attempt to wake up the module.
\returns \ref status_codes
*/
int16_t standby(uint8_t mode, bool wakeup);
/*!
\brief Sets the module to sleep mode. To wake the device up, call standby().
Overload with warm start enabled for PhysicalLayer compatibility.
\returns \ref status_codes
*/
int16_t sleep() override;
/*!
\brief Sets the module to sleep mode. To wake the device up, call standby().
\param retainConfig Set to true to retain configuration of the currently active modem ("warm start")
or to false to discard current configuration ("cold start"). Defaults to true.
\param sleepTime Sleep duration (enables automatic wakeup), in multiples of 30.52 us. Ignored if set to 0.
\returns \ref status_codes
*/
int16_t sleep(bool retainConfig, uint32_t sleepTime);
/*!
\brief Query modem for the packet length of received payload.
\param update Update received packet length. Will return cached value when set to false.
\returns Length of last received packet in bytes.
*/
size_t getPacketLength(bool update = true) override;
// interrupt methods
/*!
\brief Clean up after transmission is done.
\returns \ref status_codes
*/
int16_t finishTransmit() override;
/*!
\brief Interrupt-driven receive method with default parameters.
Implemented for compatibility with PhysicalLayer.
\returns \ref status_codes
*/
int16_t startReceive() override;
/*!
\brief Reads data received after calling startReceive method. When the packet length is not known in advance,
getPacketLength method must be called BEFORE calling readData!
\param data Pointer to array to save the received binary data.
\param len Number of bytes that will be read. When set to 0, the packet length will be retrieved automatically.
When more bytes than received are requested, only the number of bytes requested will be returned.
\returns \ref status_codes
*/
int16_t readData(uint8_t* data, size_t len) override;
/*!
\brief Clean up after reception is done.
\returns \ref status_codes
*/
int16_t finishReceive() override;
/*!
\brief Interrupt-driven channel activity detection method. IRQ1 will be activated
when LoRa preamble is detected, or upon timeout. Defaults to CAD parameter values recommended by AN1200.48.
\returns \ref status_codes
*/
int16_t startChannelScan() override;
/*!
\brief Interrupt-driven channel activity detection method. IRQ pin will be activated
when LoRa preamble is detected, or upon timeout.
\param config CAD configuration structure.
\returns \ref status_codes
*/
int16_t startChannelScan(const ChannelScanConfig_t &config) override;
/*!
\brief Read the channel scan result
\returns \ref status_codes
*/
int16_t getChannelScanResult() override;
/*!
\brief Read currently active IRQ flags.
\returns IRQ flags.
*/
uint32_t getIrqFlags() override;
/*!
\brief Set interrupt on DIO1 to be sent on a specific IRQ bit (e.g. RxTimeout, CadDone).
\param irq Module-specific IRQ flags.
\returns \ref status_codes
*/
int16_t setIrqFlags(uint32_t irq) override;
/*!
\brief Clear interrupt on a specific IRQ bit (e.g. RxTimeout, CadDone).
\param irq Module-specific IRQ flags.
\returns \ref status_codes
*/
int16_t clearIrqFlags(uint32_t irq) override;
/*!
\brief Set modem for the radio to use. Will perform full reset and reconfigure the radio
using its default parameters.
\param modem Modem type to set - FSK, LoRa or LR-FHSS.
\returns \ref status_codes
*/
int16_t setModem(ModemType_t modem) override;
// configuration methods
/*!
\brief Sets carrier frequency. Allowed values are in range from 150.0 to 960.0 MHz,
1900 - 2200 MHz and 2400 - 2500 MHz.
Will automatically perform image calibration if the frequency changes by
more than RADIOLIB_LR2021_CAL_IMG_FREQ_TRIG MHz.
NOTE: When switching between sub-GHz and high-frequency bands, after changing the frequency,
setOutputPower() must be called in order to set the correct power amplifier!
\param freq Carrier frequency to be set in MHz.
\returns \ref status_codes
*/
int16_t setFrequency(float freq) override;
/*!
\brief Sets carrier frequency. Allowed values are in range from 150.0 to 960.0 MHz,
1900 - 2200 MHz and 2400 - 2500 MHz.
Will automatically perform image calibration if the frequency changes by
more than RADIOLIB_LR2021_CAL_IMG_FREQ_TRIG MHz.
NOTE: When switching between sub-GHz and high-frequency bands, after changing the frequency,
setOutputPower() must be called in order to set the correct power amplifier!
\param freq Carrier frequency to be set in MHz.
\param skipCalibration Skip automated image calibration.
\returns \ref status_codes
*/
int16_t setFrequency(float freq, bool skipCalibration);
/*!
\brief Sets output power. Allowed values are in range from -9 to 22 dBm (sub-GHz PA) or -19 to 12 dBm (high-frequency PA).
\param power Output power to be set in dBm.
\returns \ref status_codes
*/
int16_t setOutputPower(int8_t power) override;
/*!
\brief Sets output power. Allowed values are in range from -9 to 22 dBm (sub-GHz PA) or -19 to 12 dBm (high-frequency PA).
\param power Output power to be set in dBm.
\param rampTimeUs PA power ramping time in microseconds. Provided value is rounded up to the
nearest discrete ramp time supported by the PA.
\returns \ref status_codes
*/
int16_t setOutputPower(int8_t power, uint32_t rampTimeUs);
/*!
\brief Check if output power is configurable.
This method is needed for compatibility with PhysicalLayer::checkOutputPower.
\param power Output power in dBm, PA will be determined automatically.
\param clipped Clipped output power value to what is possible within the module's range.
\returns \ref status_codes
*/
int16_t checkOutputPower(int8_t power, int8_t* clipped) override;
/*! \copydoc Module::setRfSwitchTable */
void setRfSwitchTable(const uint32_t (&pins)[Module::RFSWITCH_MAX_PINS], const Module::RfSwitchMode_t table[]);
/*!
\brief Sets LoRa bandwidth. Allowed values are 31.25, 41.67, 62.5, 83.34, 125.0,
101.56, 203.13, 250.0, 406.25, 500.0 kHz, 812.5 kHz and 1000.0 kHz.
\param bw LoRa bandwidth to be set in kHz.
\returns \ref status_codes
*/
int16_t setBandwidth(float bw);
/*!
\brief Sets LoRa spreading factor. Allowed values range from 5 to 12.
\param sf LoRa spreading factor to be set.
\param legacy Enable legacy mode for SF6 - this allows to communicate with SX127x at SF6.
\returns \ref status_codes
*/
int16_t setSpreadingFactor(uint8_t sf, bool legacy = false);
/*!
\brief Sets LoRa coding rate denominator. Allowed values range from 4 to 8. Note that a value of 4 means no coding,
is undocumented and not recommended without your own FEC.
\param cr LoRa coding rate denominator to be set.
\param longInterleave Enable long interleaver when set to true.
Note that with long interleaver enabled, CR 4/7 is not possible, there are packet length restrictions,
and it is not compatible with SX127x radios!
\returns \ref status_codes
*/
int16_t setCodingRate(uint8_t cr, bool longInterleave = false);
/*!
\brief Sets LoRa sync word.
\param syncWord LoRa sync word to be set.
\returns \ref status_codes
*/
int16_t setSyncWord(uint8_t syncWord);
/*!
\brief Sets preamble length for LoRa or GFSK modem. Allowed values range from 1 to 65535.
\param preambleLength Preamble length to be set in symbols (LoRa) or bits (GFSK).
\returns \ref status_codes
*/
int16_t setPreambleLength(size_t preambleLength) override;
/*!
\brief Sets TCXO (Temperature Compensated Crystal Oscillator) configuration.
\param voltage TCXO reference voltage in volts. Allowed values are 1.6, 1.7, 1.8, 2.2. 2.4, 2.7, 3.0 and 3.3 V.
Set to 0 to disable TCXO.
NOTE: After setting this parameter to 0, the module will be reset (since there's no other way to disable TCXO).
\param delay TCXO timeout in us. Defaults to 1000000 (1 second), because especially on the first startup,
this delay may be measured very inaccurately.
\returns \ref status_codes
*/
int16_t setTCXO(float voltage, uint32_t delay = 1000000);
/*!
\brief Sets CRC configuration.
\param len CRC length in bytes, Allowed values are 1 or 2, set to 0 to disable CRC.
\param initial Initial CRC value. GFSK only. Defaults to 0x1D0F (CCITT CRC).
\param polynomial Polynomial for CRC calculation. GFSK only. Defaults to 0x1021 (CCITT CRC).
\param inverted Invert CRC bytes. GFSK only. Defaults to true (CCITT CRC).
\returns \ref status_codes
*/
int16_t setCRC(uint8_t len, uint32_t initial = 0x00001D0FUL, uint32_t polynomial = 0x00001021UL, bool inverted = true);
/*!
\brief Enable/disable inversion of the I and Q signals
\param enable IQ inversion enabled (true) or disabled (false);
\returns \ref status_codes
*/
int16_t invertIQ(bool enable) override;
/*!
\brief Sets GFSK bit rate. Allowed values range from 0.5 to 2000.0 kbps.
\param br FSK bit rate to be set in kbps.
\returns \ref status_codes
*/
int16_t setBitRate(float br) override;
/*!
\brief Sets GFSK frequency deviation. Allowed values range from 0.6 to 500.0 kHz.
\param freqDev GFSK frequency deviation to be set in kHz.
\returns \ref status_codes
*/
int16_t setFrequencyDeviation(float freqDev) override;
/*!
\brief Sets GFSK receiver bandwidth. Allowed values are 4.8, 5.8, 7.3, 9.7, 11.7, 14.6, 19.5,
23.4, 29.3, 39.0, 46.9, 58.6, 78.2, 93.8, 117.3, 156.2, 187.2, 234.3, 312.0, 373.6 and 467.0 kHz.
\param rxBw GFSK receiver bandwidth to be set in kHz.
\returns \ref status_codes
*/
int16_t setRxBandwidth(float rxBw);
/*!
\brief Sets GFSK sync word in the form of array of up to 8 bytes.
\param syncWord GFSK sync word to be set.
\param len GFSK sync word length in bytes.
\returns \ref status_codes
*/
int16_t setSyncWord(uint8_t* syncWord, size_t len) override;
/*!
\brief Sets node address. Calling this method will also enable address filtering for node address only.
\param nodeAddr Node address to be set.
\returns \ref status_codes
*/
int16_t setNodeAddress(uint8_t nodeAddr);
/*!
\brief Sets broadcast address. Calling this method will also enable address
filtering for node and broadcast address.
\param broadAddr Node address to be set.
\returns \ref status_codes
*/
int16_t setBroadcastAddress(uint8_t broadAddr);
/*!
\brief Disables address filtering. Calling this method will also erase previously set addresses.
\returns \ref status_codes
*/
int16_t disableAddressFiltering();
/*!
\brief Sets time-bandwidth product of Gaussian filter applied for shaping.
Allowed values are RADIOLIB_SHAPING_0_3, RADIOLIB_SHAPING_0_5, RADIOLIB_SHAPING_0_7 or RADIOLIB_SHAPING_1_0.
Set to RADIOLIB_SHAPING_NONE to disable data shaping.
\param sh Time-bandwidth product of Gaussian filter to be set.
\returns \ref status_codes
*/
int16_t setDataShaping(uint8_t sh) override;
/*!
\brief Sets transmission encoding. Available in GFSK mode only. Serves only as alias for PhysicalLayer compatibility.
\param encoding Encoding to be used. Set to 0 for NRZ, and 2 for whitening.
\returns \ref status_codes
*/
int16_t setEncoding(uint8_t encoding) override;
/*!
\brief Set modem in fixed packet length mode. Available in GFSK mode only.
\param len Packet length.
\returns \ref status_codes
*/
int16_t fixedPacketLengthMode(uint8_t len = RADIOLIB_LR2021_MAX_PACKET_LENGTH);
/*!
\brief Set modem in variable packet length mode. Available in GFSK mode only.
\param maxLen Maximum packet length.
\returns \ref status_codes
*/
int16_t variablePacketLengthMode(uint8_t maxLen = RADIOLIB_LR2021_MAX_PACKET_LENGTH);
/*!
\brief Sets GFSK whitening parameters.
\param enabled True = Whitening enabled
\param initial Initial value used for the whitening LFSR in GFSK mode.
By default set to 0x01FF for compatibility with SX127x and LoRaWAN.
\returns \ref status_codes
*/
int16_t setWhitening(bool enabled, uint16_t initial = 0x01FF);
/*!
\brief Set data rate.
\param dr Data rate struct.
\param modem The modem corresponding to the requested datarate (FSK, LoRa or LR-FHSS).
Defaults to currently active modem if not supplied.
\returns \ref status_codes
*/
int16_t setDataRate(DataRate_t dr, ModemType_t modem = RADIOLIB_MODEM_NONE) override;
/*!
\brief Check the data rate can be configured by this module.
\param dr Data rate struct.
\param modem The modem corresponding to the requested datarate (FSK, LoRa or LR-FHSS).
Defaults to currently active modem if not supplied.
\returns \ref status_codes
*/
int16_t checkDataRate(DataRate_t dr, ModemType_t modem = RADIOLIB_MODEM_NONE) override;
/*!
\brief Sets LR-FHSS configuration.
\param bw LR-FHSS bandwidth, one of RADIOLIB_LRXXXX_LR_FHSS_BW_* values.
\param cr LR-FHSS coding rate, one of RADIOLIB_LRXXXX_LR_FHSS_CR_* values.
\param hdrCount Header packet count, 1 - 4. Defaults to 3.
\param hopSeed 9-bit seed number for PRNG generation of the hopping sequence. Defaults to 0x13A.
\returns \ref status_codes
*/
int16_t setLrFhssConfig(uint8_t bw, uint8_t cr, uint8_t hdrCount = 3, uint16_t hopSeed = 0x13A);
/*!
\brief Enables or disables Rx Boosted Gain mode (additional Rx gain for increased power consumption).
\param level Rx gain boost level. 0 (disabled) to 7 (maximum boost).
\returns \ref status_codes
*/
int16_t setRxBoostedGainMode(uint8_t level);
/*!
\brief Get expected time-on-air for a given size of payload
\param len Payload length in bytes.
\returns Expected time-on-air in microseconds.
*/
RadioLibTime_t getTimeOnAir(size_t len) override;
/*!
\brief Get modem currently in use by the radio.
\param modem Pointer to a variable to save the retrieved configuration into.
\returns \ref status_codes
*/
int16_t getModem(ModemType_t* modem) override;
/*! \copydoc PhysicalLayer::stageMode */
int16_t stageMode(RadioModeType_t mode, RadioModeConfig_t* cfg) override;
/*! \copydoc PhysicalLayer::launchMode */
int16_t launchMode() override;
/*!
\brief Read the supply voltage on the Vbat pin.
\param bits Measurement resolution in bits, 8 to 13.
\returns \ref Supply voltage in volts.
*/
float getVoltage(uint8_t bits = 13);
/*!
\brief Read the temperature.
\param source Measurement source, one of RADIOLIB_LR2021_TEMP_SOURCE_* macros.
\param bits Measurement resolution in bits, 8 to 13.
\returns \ref Temperature in degrees Celsius.
*/
float getTemperature(uint8_t source, uint8_t bits = 13);
/*!
\brief Gets recorded signal strength indicator.
Overload with packet mode enabled for PhysicalLayer compatibility.
\returns RSSI value in dBm.
*/
float getRSSI() override;
/*!
\brief Gets RSSI (Recorded Signal Strength Indicator).
\param packet Whether to read last packet RSSI, or the current value.
\param skipReceive Set to true to skip putting radio in receive mode for the RSSI measurement in FSK/OOK mode.
\returns RSSI value in dBm.
*/
float getRSSI(bool packet, bool skipReceive = false);
/*!
\brief Gets SNR (Signal to Noise Ratio) of the last received packet. Only available for LoRa modem.
\returns SNR of the last received packet in dB.
*/
float getSNR() override;
/*!
\brief Get one truly random byte from RSSI noise.
\returns TRNG byte.
*/
uint8_t randomByte() override;
/*!
\brief Set implicit header mode for future reception/transmission.
\param len Payload length in bytes.
\returns \ref status_codes
*/
int16_t implicitHeader(size_t len);
/*!
\brief Set explicit header mode for future reception/transmission.
\returns \ref status_codes
*/
int16_t explicitHeader();
/*!
\brief Set OOK detector properties. The default values are set to allow ADS-B reception.
\param pattern Preamble pattern, should end with 01 or 10 (binary).
\param len Preamble pattern length in bits.
\param repeats Number of preamble repeats, maximum of 31.
\param syncRaw Whether the sync word is send raw (unencoded) or encoded. Set to false for encoded sync word.
\param rising Whether the start of frame delimiter edge is rising (true) or falling (false).
\param sofLen Start-of-frame length in bits.
\returns \ref status_codes
*/
int16_t ookDetector(uint16_t pattern = 0x0285, uint8_t len = 16, uint8_t repeats = 0, bool syncRaw = false, bool rising = false, uint8_t sofLen = 0);
/*!
\brief Set OOK detection threshold.
\param level Threshold level in dB
\returns \ref status_codes
*/
int16_t setOokDetectionThreshold(int16_t level);
/*!
\brief Configure LoRa side detector, which enables to detect mutiple spreading factors and receive one of them.
The following limitations apply:
* In Rx mode, all side-detector spreading factors must be higher than the primary one (configured via begin or setSpreadingFactor)
* For CAD mode, the above condition is inverted - all side-detector spreading factors must be smaller
* All packets to be detected must have the same header type (implicit or explicit)
* If bandwidth is higher than 500 kHz, at most 2 side detectors are allowed.
* If the primary spreading factor is 10, 11 or 12, at most 2 side detectors are allowed.
* All spreading factors must be different.
* The difference between maximum and minimum spreading factor used must be less than or equal to 4.
\param cfg Pointer to an array of side detector configuration structures. Set to null to disable all side detectors.
\param numDetectors Number of side detectors to configure. Maximum of 3, set to 0 to to disable all side detectors.
\returns \ref status_codes
*/
int16_t setSideDetector(const LR2021LoRaSideDetector_t* cfg, size_t numDetectors);
/*!
\brief Sets gain of receiver LNA (low-noise amplifier). Can be set to any integer in range 1 to 13,
where 13 is the highest gain. Set to 0 to enable automatic gain control (recommended).
\param gain Gain of receiver LNA (low-noise amplifier) to be set.
\returns \ref status_codes
*/
int16_t setGain(uint8_t gain);
#if !RADIOLIB_GODMODE && !RADIOLIB_LOW_LEVEL
protected:
#endif
Module* getMod() override;
#if !RADIOLIB_GODMODE
protected:
#endif
#if !RADIOLIB_GODMODE
private:
#endif
// flag to determine whether we are in the sub-GHz or 2.4 GHz range
// this is needed to automatically detect which PA to use
bool highFreq = false;
uint8_t gainModeLf = RADIOLIB_LR2021_RX_BOOST_LF;
uint8_t gainModeHf = RADIOLIB_LR2021_RX_BOOST_HF;
// cached FLRC parameters
uint16_t bitRateFlrc = 0;
uint8_t codingRateFlrc = 0;
int16_t modSetup(float freq, float tcxoVoltage, uint8_t modem);
bool findChip(void);
int16_t config(uint8_t modem);
int16_t setPacketMode(uint8_t mode, uint8_t len);
int16_t startCad(uint8_t symbolNum, uint8_t detPeak, uint8_t detMin, uint8_t exitMode, RadioLibTime_t timeout);
// chip control commands
int16_t readRadioRxFifo(uint8_t* data, size_t len);
int16_t writeRadioTxFifo(const uint8_t* data, size_t len);
int16_t writeRegMem32(uint32_t addr, const uint32_t* data, size_t len);
int16_t writeRegMemMask32(uint32_t addr, uint32_t mask, uint32_t data);
int16_t readRegMem32(uint32_t addr, uint32_t* data, size_t len);
int16_t setFs(void);
int16_t setAdditionalRegToRetain(uint8_t slot, uint32_t addr);
int16_t setRx(uint32_t timeout);
int16_t setTx(uint32_t timeout);
int16_t setRxTxFallbackMode(uint8_t mode);
int16_t setRxDutyCycle(uint32_t rxMaxTime, uint32_t cycleTime, uint8_t cfg);
int16_t autoTxRx(uint32_t delay, uint8_t mode, uint32_t timeout);
int16_t getRxPktLength(uint16_t* len);
int16_t resetRxStats(void);
int16_t setDefaultRxTxTimeout(uint32_t rxTimeout, uint32_t txTimeout);
int16_t setRegMode(uint8_t simoUsage, const uint8_t rampTimes[4]);
int16_t calibrate(uint8_t blocks);
int16_t calibrateFrontEnd(const uint16_t freq[3]);
int16_t getVbat(uint8_t resolution, uint16_t* vbat);
int16_t getTemp(uint8_t source, uint8_t resolution, float* temp);
int16_t setEolConfig(bool enable, uint8_t trim);
int16_t getRandomNumber(uint32_t* rnd);
int16_t getVersion(uint8_t* major, uint8_t* minor);
int16_t clearErrors(void);
int16_t getErrors(uint16_t* err);
int16_t setDioFunction(uint8_t dio, uint8_t func, uint8_t pullDrive);
int16_t setDioRfSwitchConfig(uint8_t dio, uint8_t func);
int16_t setDioIrqConfig(uint8_t dio, uint32_t irq);
int16_t clearIrqState(uint32_t irq);
int16_t getAndClearIrqStatus(uint32_t* irq);
int16_t configFifoIrq(uint8_t rxFifoIrq, uint8_t txFifoIrq, uint8_t rxHighThreshold, uint8_t txHighThreshold);
int16_t getFifoIrqFlags(uint8_t* rxFifoFlags, uint8_t* txFifoFlags);
int16_t clearFifoIrqFlags(uint8_t rxFifoFlags, uint8_t txFifoFlags);
int16_t getAndClearFifoIrqFlags(uint8_t* rxFifoFlags, uint8_t* txFifoFlags);
int16_t getRxFifoLevel(uint16_t* level);
int16_t getTxFifoLevel(uint16_t* level);
int16_t clearRxFifo(void);
int16_t clearTxFifo(void);
int16_t configLfClock(uint8_t cfg);
int16_t configClkOutputs(uint8_t scaling);
int16_t setTcxoMode(uint8_t tune, uint32_t startTime);
int16_t setXoscCpTrim(uint8_t xta, uint8_t xtb, uint8_t startTime);
// radio frequency front end commands
int16_t setRfFrequency(uint32_t rfFreq);
int16_t setRxPath(uint8_t rxPath, uint8_t rxBoost);
int16_t getRssiInst(float* rssi);
int16_t setRssiCalibration(uint8_t rxPath, const uint16_t gain[RADIOLIB_LR2021_GAIN_TABLE_LENGTH], const uint8_t noiseFloor[RADIOLIB_LR2021_GAIN_TABLE_LENGTH]);
int16_t setTimestampSource(uint8_t index, uint8_t source);
int16_t getTimestampValue(uint8_t index, uint32_t* timestamp);
int16_t setCca(uint32_t duration, uint8_t gain);
int16_t getCcaResult(float* rssiMin, float* rssiMax, float* rssiAvg);
int16_t setCadParams(uint32_t cadTimeout, uint8_t threshold, uint8_t exitMode, uint32_t trxTimeout);
int16_t setCad(void);
int16_t selPa(uint8_t pa);
int16_t setPaConfig(uint8_t pa, uint8_t paLfMode, uint8_t paLfDutyCycle, uint8_t paLfSlices, uint8_t paHfDutyCycle);
int16_t setTxParams(int8_t txPower, uint8_t rampTime);
// modem configuration commands
int16_t setPacketType(uint8_t packetType);
int16_t getPacketType(uint8_t* packetType);
// LoRa commands
int16_t setLoRaModulationParams(uint8_t sf, uint8_t bw, uint8_t cr, uint8_t ldro);
int16_t setLoRaPacketParams(uint16_t preambleLen, uint8_t hdrType, uint8_t payloadLen, uint8_t crcType, uint8_t invertIQ);
int16_t setLoRaSynchTimeout(uint8_t numSymbols, bool format);
int16_t setLoRaSyncword(uint8_t syncword);
int16_t setLoRaSideDetConfig(uint8_t* configs, size_t numSideDets);
int16_t setLoRaSideDetSyncword(uint8_t* syncwords, size_t numSideDets);
int16_t setLoRaCadParams(uint8_t numSymbols, bool preambleOnly, uint8_t pnrDelta, uint8_t cadExitMode, uint32_t timeout, uint8_t detPeak);
int16_t setLoRaCad(void);
int16_t getLoRaRxStats(uint16_t* pktRxTotal, uint16_t* pktCrcError, uint16_t* headerCrcError, uint16_t* falseSynch);
int16_t getLoRaPacketStatus(uint8_t* crc, uint8_t* cr, uint8_t* packetLen, float* snrPacket, float* rssiPacket, float* rssiSignalPacket);
int16_t setLoRaAddress(uint8_t addrLen, uint8_t addrPos, const uint8_t* addr);
int16_t setLoRaHopping(uint8_t hopCtrl, uint16_t hopPeriod, const uint32_t* freqHops, size_t numFreqHops);
int16_t setLoRaTxSync(uint8_t function, uint8_t dioNum);
int16_t setLoRaSideDetCad(const uint8_t* pnrDelta, const uint8_t* detPeak, size_t numSideDets);
int16_t setLoRaHeaderType(uint8_t hdrType, size_t len = RADIOLIB_LR2021_MAX_PACKET_LENGTH);
// ranging commands
int16_t setRangingAddr(uint32_t addr, uint8_t checkLen);
int16_t setRangingReqAddr(uint32_t addr);
int16_t getRangingResult(uint8_t type, uint32_t* rng1, uint8_t* rssi1, uint32_t* rng2);
int16_t getRangingStats(uint16_t* exchangeValid, uint16_t* requestValid, uint16_t* responseDone, uint16_t* timeout, uint16_t* requestDiscarded);
int16_t setRangingTxRxDelay(uint32_t delay);
int16_t setRangingParams(bool spyMode, uint8_t nbSymbols);
// GFSK commands
int16_t setGfskModulationParams(uint32_t bitRate, uint8_t pulseShape, uint8_t rxBw, uint32_t freqDev);
int16_t setGfskPacketParams(uint16_t preambleLen, uint8_t preambleDetect, bool longPreamble, bool pldLenBits, uint8_t addrComp, uint8_t packetFormat, uint16_t payloadLen, uint8_t crc, uint8_t dcFree);
int16_t setGfskWhiteningParams(uint8_t whitenType, uint16_t init);
int16_t setGfskCrcParams(uint32_t poly, uint32_t init);
int16_t setGfskSyncword(const uint8_t* syncWord, size_t syncWordLen, bool msbFirst);
int16_t setGfskAddress(uint8_t addrNode, uint8_t addrBroadcast);
int16_t getGfskRxStats(uint16_t* packetRx, uint16_t* packetCrcError, uint16_t* lenError, uint16_t* preambleDet, uint16_t* syncOk, uint16_t* syncFail, uint16_t* timeout);
int16_t getGfskPacketStatus(uint16_t* packetLen, float* rssiAvg, float* rssiSync, bool* addrMatchNode, bool* addrMatchBroadcast, float* lqi);
// OQPSK commands
int16_t setOqpskParams(uint8_t mode, uint8_t rxBw, uint8_t payloadLen, uint16_t preambleLen, bool addrFilt, bool fcsManual);
int16_t getOqpskRxStats(uint16_t* packetRx, uint16_t* crcError, uint16_t* lenError);
int16_t getOqpskPacketStatus(uint8_t* rxHeader, uint16_t* payloadLen, float* rssiAvg, float* rssiSync, float* lqi);
int16_t setOqpskPacketLen(uint8_t len);
int16_t setOqpskAddress(const uint8_t longDestAddr[8], uint16_t shortDestAddr, uint16_t panId, uint8_t transId);
// BPSK commands
int16_t setBpskModulationParams(uint32_t bitRate, uint8_t pulseShape, bool diff, uint8_t diffInit);
int16_t setBpskPacketParams(uint8_t payloadLen, uint8_t mode, bool sigFoxControlMsg, uint8_t sigFoxRank);
// FLRC commands
int16_t setFlrcModulationParams(uint8_t brBw, uint8_t cr, uint8_t pulseShape);
int16_t setFlrcPacketParams(uint8_t agcPreambleLen, uint8_t syncWordLen, uint8_t syncWordTx, uint8_t syncMatch, bool fixedLength, uint8_t crc, uint16_t payloadLen);
int16_t getFlrcRxStats(uint16_t* packetRx, uint16_t* packetCrcError, uint16_t* lenError);
int16_t getFlrcPacketStatus(uint16_t* packetLen, float* rssiAvg, float* rssiSync, uint8_t* syncWordNum);
int16_t setFlrcSyncWord(uint8_t syncWordNum, uint32_t syncWord);
// LR-FHSS commands
int16_t lrFhssSetSyncword(uint32_t syncWord);
//! \TODO: [LR2021] Implement reading/writing LR-FHSS hopping table
//int16_t readLrFhssHoppingTable(LR2021LrFhssHopTableEntry_t* hopTable[40], size_t* hopTableLen);
//int16_t writeLrFhssHoppingTable(LR2021LrFhssHopTableEntry_t* hopTable[40], size_t hopTableLen);
// OOK commands
int16_t setOokModulationParams(uint32_t bitRate, uint8_t pulseShape, uint8_t rxBw, uint8_t depth);
int16_t setOokPacketParams(uint16_t preambleLen, uint8_t addrComp, uint8_t packetFormat, uint16_t payloadLen, uint8_t crc, uint8_t manchester);
int16_t setOokCrcParams(uint32_t poly, uint32_t init);
int16_t setOokSyncword(const uint8_t* syncWord, size_t syncWordLen, bool msbFirst);
int16_t setOokAddress(uint8_t addrNode, uint8_t addrBroadcast);
int16_t getOokRxStats(uint16_t* packetRx, uint16_t* crcError, uint16_t* lenError);
int16_t getOokPacketStatus(uint16_t* packetLen, float* rssiAvg, float* rssiSync, bool* addrMatchNode, bool* addrMatchBroadcast, float* lqi);
int16_t setOokDetector(uint16_t preamblePattern, uint8_t patternLen, uint8_t patternNumRepeaters, bool syncWordRaw, bool sofDelimiterRising, uint8_t sofDelimiterLen);
int16_t setOokWhiteningParams(uint8_t bitIdx, uint16_t poly, uint16_t init);
// test commands
int16_t setTxTestMode(uint8_t mode);
};
#endif
#endif

View file

@ -0,0 +1,311 @@
#include "LR2021.h"
#include "../LR11x0/LR_common.h"
#include <string.h>
#include <math.h>
#if !RADIOLIB_EXCLUDE_LR2021
int16_t LR2021::readRadioRxFifo(uint8_t* data, size_t len) {
// FIFO read is just a single transaction sent without the status code
this->mod->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_STATUS] = Module::BITS_0;
int16_t state = this->mod->SPIreadStream(RADIOLIB_LR2021_CMD_READ_RX_FIFO, data, len, true, false);
this->mod->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_STATUS] = Module::BITS_16;
return(state);
}
int16_t LR2021::writeRadioTxFifo(const uint8_t* data, size_t len) {
return(this->SPIcommand(RADIOLIB_LR2021_CMD_WRITE_TX_FIFO, true, const_cast<uint8_t*>(data), len, NULL, 0));
}
int16_t LR2021::writeRegMem32(uint32_t addr, const uint32_t* data, size_t len) {
// check maximum size
if(len > (RADIOLIB_LRXXXX_SPI_MAX_READ_WRITE_LEN/sizeof(uint32_t))) {
return(RADIOLIB_ERR_SPI_CMD_INVALID);
}
return(this->writeCommon(RADIOLIB_LR2021_CMD_WRITE_REG_MEM_32, addr, data, len, false));
}
int16_t LR2021::writeRegMemMask32(uint32_t addr, uint32_t mask, uint32_t data) {
uint8_t buff[11] = {
(uint8_t)((addr >> 16) & 0xFF), (uint8_t)((addr >> 8) & 0xFF), (uint8_t)(addr & 0xFF),
(uint8_t)((mask >> 24) & 0xFF), (uint8_t)((mask >> 16) & 0xFF), (uint8_t)((mask >> 8) & 0xFF), (uint8_t)(mask & 0xFF),
(uint8_t)((data >> 24) & 0xFF), (uint8_t)((data >> 16) & 0xFF), (uint8_t)((data >> 8) & 0xFF), (uint8_t)(data & 0xFF),
};
return(this->SPIcommand(RADIOLIB_LR2021_CMD_WRITE_REG_MEM_MASK_32, true, buff, sizeof(buff)));
}
int16_t LR2021::readRegMem32(uint32_t addr, uint32_t* data, size_t len) {
// check maximum size
if(len > (RADIOLIB_LRXXXX_SPI_MAX_READ_WRITE_LEN/sizeof(uint32_t))) {
return(RADIOLIB_ERR_SPI_CMD_INVALID);
}
// the request contains the address and length
uint8_t reqBuff[4] = {
(uint8_t)((addr >> 16) & 0xFF), (uint8_t)((addr >> 8) & 0xFF),
(uint8_t)(addr & 0xFF), (uint8_t)len,
};
// build buffers - later we need to ensure endians are correct,
// so there is probably no way to do this without copying buffers and iterating
#if RADIOLIB_STATIC_ONLY
uint8_t rplBuff[RADIOLIB_LRXXXX_SPI_MAX_READ_WRITE_LEN];
#else
uint8_t* rplBuff = new uint8_t[len*sizeof(uint32_t)];
#endif
int16_t state = this->SPIcommand(RADIOLIB_LR2021_CMD_READ_REG_MEM_32, false, rplBuff, len*sizeof(uint32_t), reqBuff, sizeof(reqBuff));
// convert endians
if(data && (state == RADIOLIB_ERR_NONE)) {
for(size_t i = 0; i < len; i++) {
data[i] = ((uint32_t)rplBuff[2 + i*sizeof(uint32_t)] << 24) | ((uint32_t)rplBuff[3 + i*sizeof(uint32_t)] << 16) | ((uint32_t)rplBuff[4 + i*sizeof(uint32_t)] << 8) | (uint32_t)rplBuff[5 + i*sizeof(uint32_t)];
}
}
#if !RADIOLIB_STATIC_ONLY
delete[] rplBuff;
#endif
return(state);
}
int16_t LR2021::setFs(void) {
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_FS, true, NULL, 0));
}
int16_t LR2021::setAdditionalRegToRetain(uint8_t slot, uint32_t addr) {
uint8_t buff[] = {
slot, (uint8_t)((addr >> 16) & 0xFF),
(uint8_t)((addr >> 8) & 0xFF), (uint8_t)(addr & 0xFF),
};
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_ADDITIONAL_REG_TO_RETAIN, true, buff, sizeof(buff)));
}
int16_t LR2021::setRx(uint32_t timeout) {
uint8_t buff[] = {
(uint8_t)((timeout >> 16) & 0xFF), (uint8_t)((timeout >> 8) & 0xFF), (uint8_t)(timeout & 0xFF),
};
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_RX, true, buff, sizeof(buff)));
}
int16_t LR2021::setTx(uint32_t timeout) {
uint8_t buff[] = {
(uint8_t)((timeout >> 16) & 0xFF), (uint8_t)((timeout >> 8) & 0xFF), (uint8_t)(timeout & 0xFF),
};
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_TX, true, buff, sizeof(buff)));
}
int16_t LR2021::setRxTxFallbackMode(uint8_t mode) {
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_RX_TX_FALLBACK_MODE, true, &mode, sizeof(mode)));
}
int16_t LR2021::setRxDutyCycle(uint32_t rxMaxTime, uint32_t cycleTime, uint8_t cfg) {
uint8_t buff[] = {
(uint8_t)((rxMaxTime >> 16) & 0xFF), (uint8_t)((rxMaxTime >> 8) & 0xFF), (uint8_t)(rxMaxTime & 0xFF),
(uint8_t)((cycleTime >> 16) & 0xFF), (uint8_t)((cycleTime >> 8) & 0xFF), (uint8_t)(cycleTime & 0xFF),
cfg
};
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_RX_DUTY_CYCLE, true, buff, sizeof(buff)));
}
int16_t LR2021::autoTxRx(uint32_t delay, uint8_t mode, uint32_t timeout) {
uint8_t buff[] = {
(uint8_t)((delay >> 16) & 0xFF), (uint8_t)((delay >> 8) & 0xFF), (uint8_t)(delay & 0xFF), mode,
(uint8_t)((timeout >> 16) & 0xFF), (uint8_t)((timeout >> 8) & 0xFF), (uint8_t)(timeout & 0xFF),
};
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_AUTO_RX_TX, true, buff, sizeof(buff)));
}
int16_t LR2021::getRxPktLength(uint16_t* len) {
uint8_t buff[2] = { 0 };
int16_t state = this->SPIcommand(RADIOLIB_LR2021_CMD_GET_RX_PKT_LENGTH, false, buff, sizeof(buff));
if(len) { *len = ((uint16_t)(buff[0]) << 8) | (uint16_t)buff[1]; }
return(state);
}
int16_t LR2021::resetRxStats(void) {
return(this->SPIcommand(RADIOLIB_LR2021_CMD_RESET_RX_STATS, true, NULL, 0));
}
int16_t LR2021::setDefaultRxTxTimeout(uint32_t rxTimeout, uint32_t txTimeout) {
uint8_t buff[] = {
(uint8_t)((rxTimeout >> 16) & 0xFF), (uint8_t)((rxTimeout >> 8) & 0xFF), (uint8_t)(rxTimeout & 0xFF),
(uint8_t)((txTimeout >> 16) & 0xFF), (uint8_t)((txTimeout >> 8) & 0xFF), (uint8_t)(txTimeout & 0xFF),
};
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_DEFAULT_RX_TX_TIMEOUT, true, buff, sizeof(buff)));
}
int16_t LR2021::setRegMode(uint8_t simoUsage, const uint8_t rampTimes[4]) {
uint8_t buff[] = { simoUsage,
rampTimes[RADIOLIB_LR2021_REG_MODE_RAMP_INDEX_RC2RU], rampTimes[RADIOLIB_LR2021_REG_MODE_RAMP_INDEX_TX2RU],
rampTimes[RADIOLIB_LR2021_REG_MODE_RAMP_INDEX_RU2RC], rampTimes[RADIOLIB_LR2021_REG_MODE_RAMP_INDEX_RAMP_DOWN],
};
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_REG_MODE, true, buff, sizeof(buff)));
}
int16_t LR2021::calibrate(uint8_t blocks) {
return(this->SPIcommand(RADIOLIB_LR2021_CMD_CALIBRATE, true, &blocks, sizeof(blocks)));
}
int16_t LR2021::calibrateFrontEnd(const uint16_t freq[3]) {
uint8_t buff[] = {
(uint8_t)((freq[0] >> 8) & 0xFF), (uint8_t)(freq[0] & 0xFF),
(uint8_t)((freq[1] >> 8) & 0xFF), (uint8_t)(freq[1] & 0xFF),
(uint8_t)((freq[2] >> 8) & 0xFF), (uint8_t)(freq[2] & 0xFF),
};
return(this->SPIcommand(RADIOLIB_LR2021_CMD_CALIB_FRONT_END, true, buff, sizeof(buff)));
}
int16_t LR2021::getVbat(uint8_t resolution, uint16_t* vbat) {
uint8_t reqBuff[] = { (uint8_t)(RADIOLIB_LR2021_VBAT_FORMAT_MV | ((RADIOLIB_LR2021_MEAS_RESOLUTION_OFFSET + resolution) & 0x07)) };
uint8_t rplBuff[2] = { 0 };
int16_t state = this->SPIcommand(RADIOLIB_LR2021_CMD_GET_V_BAT, false, rplBuff, sizeof(rplBuff), reqBuff, sizeof(reqBuff));
if(vbat) { *vbat = ((uint16_t)(rplBuff[0]) << 8) | (uint16_t)rplBuff[1]; }
return(state);
}
int16_t LR2021::getTemp(uint8_t source, uint8_t resolution, float* temp) {
uint8_t reqBuff[] = { (uint8_t)((source & 0x30) | RADIOLIB_LR2021_TEMP_FORMAT_DEG_C | ((RADIOLIB_LR2021_MEAS_RESOLUTION_OFFSET + resolution) & 0x07)) };
uint8_t rplBuff[2] = { 0 };
int16_t state = this->SPIcommand(RADIOLIB_LR2021_CMD_GET_TEMP, false, rplBuff, sizeof(rplBuff), reqBuff, sizeof(reqBuff));
if(temp) {
uint16_t raw = ((uint16_t)(rplBuff[0]) << 8) | (uint16_t)rplBuff[1];
*temp = (float)raw/320.0f;
}
return(state);
}
int16_t LR2021::setEolConfig(bool enable, uint8_t trim) {
uint8_t buff[] = { (uint8_t)((trim & 0x06) | (uint8_t)enable) };
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_EOL_CONFIG, true, buff, sizeof(buff)));
}
int16_t LR2021::getRandomNumber(uint32_t* rnd) {
uint8_t buff[4] = { 0 };
int16_t state = this->SPIcommand(RADIOLIB_LR2021_CMD_GET_RANDOM_NUMBER, false, buff, sizeof(buff));
if(rnd) { *rnd = ((uint32_t)(buff[0]) << 24) | ((uint32_t)(buff[1]) << 16) | ((uint32_t)(buff[2]) << 8) | (uint32_t)buff[3]; }
return(state);
}
int16_t LR2021::getVersion(uint8_t* major, uint8_t* minor) {
uint8_t buff[2] = { 0 };
int16_t state = this->SPIcommand(RADIOLIB_LR2021_CMD_GET_VERSION, false, buff, sizeof(buff));
if(major) { *major = buff[0]; }
if(minor) { *minor = buff[1]; }
return(state);
}
int16_t LR2021::clearErrors(void) {
return(this->SPIcommand(RADIOLIB_LR2021_CMD_CLEAR_ERRORS, true, NULL, 0));
}
int16_t LR2021::getErrors(uint16_t* err) {
uint8_t buff[2] = { 0 };
int16_t state = this->SPIcommand(RADIOLIB_LR2021_CMD_GET_ERRORS, false, buff, sizeof(buff));
if(err) { *err = ((uint16_t)(buff[0]) << 8) | (uint16_t)buff[1]; }
return(state);
}
int16_t LR2021::setDioFunction(uint8_t dio, uint8_t func, uint8_t pullDrive) {
uint8_t buff[] = { dio, (uint8_t)((func & 0xF0) | (pullDrive & 0x0F)) };
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_DIO_FUNCTION, true, buff, sizeof(buff)));
}
int16_t LR2021::setDioRfSwitchConfig(uint8_t dio, uint8_t func) {
uint8_t buff[] = { dio, func };
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_DIO_RF_SWITCH_CONFIG, true, buff, sizeof(buff)));
}
int16_t LR2021::setDioIrqConfig(uint8_t dio, uint32_t irq) {
uint8_t buff[] = { dio,
(uint8_t)((irq >> 24) & 0xFF), (uint8_t)((irq >> 16) & 0xFF),
(uint8_t)((irq >> 8) & 0xFF), (uint8_t)(irq & 0xFF),
};
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_DIO_IRQ_CONFIG, true, buff, sizeof(buff)));
}
int16_t LR2021::clearIrqState(uint32_t irq) {
return(this->setU32(RADIOLIB_LR2021_CMD_CLEAR_IRQ, irq));
}
int16_t LR2021::getAndClearIrqStatus(uint32_t* irq) {
uint8_t buff[4] = { 0 };
int16_t state = this->SPIcommand(RADIOLIB_LR2021_CMD_GET_AND_CLEAR_IRQ_STATUS, false, buff, sizeof(buff));
if(irq) { *irq = ((uint32_t)(buff[0]) << 24) | ((uint32_t)(buff[1]) << 16) | ((uint32_t)(buff[2]) << 8) |(uint32_t)buff[3]; }
return(state);
}
int16_t LR2021::configFifoIrq(uint8_t rxFifoIrq, uint8_t txFifoIrq, uint8_t rxHighThreshold, uint8_t txHighThreshold) {
uint8_t buff[] = { rxFifoIrq, txFifoIrq, rxHighThreshold, txHighThreshold };
return(this->SPIcommand(RADIOLIB_LR2021_CMD_CONFIG_FIFO_IRQ, true, buff, sizeof(buff)));
}
int16_t LR2021::getFifoIrqFlags(uint8_t* rxFifoFlags, uint8_t* txFifoFlags) {
uint8_t buff[2] = { 0 };
int16_t state = this->SPIcommand(RADIOLIB_LR2021_CMD_GET_FIFO_IRQ_FLAGS, false, buff, sizeof(buff));
if(rxFifoFlags) { *rxFifoFlags = buff[0]; }
if(txFifoFlags) { *txFifoFlags = buff[1]; }
return(state);
}
int16_t LR2021::clearFifoIrqFlags(uint8_t rxFifoFlags, uint8_t txFifoFlags) {
uint8_t buff[] = { rxFifoFlags, txFifoFlags };
return(this->SPIcommand(RADIOLIB_LR2021_CMD_CLEAR_FIFO_IRQ_FLAGS, true, buff, sizeof(buff)));
}
int16_t LR2021::getAndClearFifoIrqFlags(uint8_t* rxFifoFlags, uint8_t* txFifoFlags) {
uint8_t buff[2] = { 0 };
int16_t state = this->SPIcommand(RADIOLIB_LR2021_CMD_GET_AND_CLEAR_FIFO_IRQ_FLAGS, false, buff, sizeof(buff));
if(rxFifoFlags) { *rxFifoFlags = buff[0]; }
if(txFifoFlags) { *txFifoFlags = buff[1]; }
return(state);
}
int16_t LR2021::getRxFifoLevel(uint16_t* level) {
uint8_t buff[2] = { 0 };
int16_t state = this->SPIcommand(RADIOLIB_LR2021_CMD_GET_RX_FIFO_LEVEL, false, buff, sizeof(buff));
if(level) { *level = ((uint16_t)(buff[0]) << 8) | (uint16_t)buff[1]; }
return(state);
}
int16_t LR2021::getTxFifoLevel(uint16_t* level) {
uint8_t buff[2] = { 0 };
int16_t state = this->SPIcommand(RADIOLIB_LR2021_CMD_GET_TX_FIFO_LEVEL, false, buff, sizeof(buff));
if(level) { *level = ((uint16_t)(buff[0]) << 8) | (uint16_t)buff[1]; }
return(state);
}
int16_t LR2021::clearRxFifo(void) {
return(this->SPIcommand(RADIOLIB_LR2021_CMD_CLEAR_RX_FIFO, true, NULL, 0));
}
int16_t LR2021::clearTxFifo(void) {
return(this->SPIcommand(RADIOLIB_LR2021_CMD_CLEAR_TX_FIFO, true, NULL, 0));
}
int16_t LR2021::configLfClock(uint8_t cfg) {
return(this->SPIcommand(RADIOLIB_LR2021_CMD_CONFIG_LF_CLOCK, true, &cfg, sizeof(cfg)));
}
int16_t LR2021::configClkOutputs(uint8_t scaling) {
return(this->SPIcommand(RADIOLIB_LR2021_CMD_CONFIG_CLK_OUTPUTS, true, &scaling, sizeof(scaling)));
}
int16_t LR2021::setTcxoMode(uint8_t tune, uint32_t startTime) {
uint8_t buff[] = { (uint8_t)(tune & 0x07),
(uint8_t)((startTime >> 24) & 0xFF), (uint8_t)((startTime >> 16) & 0xFF),
(uint8_t)((startTime >> 8) & 0xFF), (uint8_t)(startTime & 0xFF),
};
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_TCXO_MODE, true, buff, sizeof(buff)));
}
int16_t LR2021::setXoscCpTrim(uint8_t xta, uint8_t xtb, uint8_t startTime) {
uint8_t buff[] = { (uint8_t)(xta & 0x3F), (uint8_t)(xtb & 0x3F), startTime };
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_XOSC_CP_TRIM, true, buff, sizeof(buff)));
}
#endif

View file

@ -0,0 +1,61 @@
#include "LR2021.h"
#include "../LR11x0/LR_common.h"
#include <string.h>
#include <math.h>
#if !RADIOLIB_EXCLUDE_LR2021
int16_t LR2021::setFlrcModulationParams(uint8_t brBw, uint8_t cr, uint8_t pulseShape) {
uint8_t buff[] = { brBw, (uint8_t)((cr << 4) | (pulseShape & 0x0F)) };
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_FLRC_MODULATION_PARAMS, true, buff, sizeof(buff)));
}
int16_t LR2021::setFlrcPacketParams(uint8_t agcPreambleLen, uint8_t syncWordLen, uint8_t syncWordTx, uint8_t syncMatch, bool fixedLength, uint8_t crc, uint16_t payloadLen) {
uint8_t buff[] = {
(uint8_t)(((agcPreambleLen & 0x0F) << 2) | (syncWordLen / 2)),
(uint8_t)(((syncWordTx & 0x03) << 6) | ((syncMatch & 0x07) << 3) | ((uint8_t)fixedLength << 2) | (crc & 0x03)),
(uint8_t)((payloadLen >> 8) & 0xFF), (uint8_t)(payloadLen & 0xFF),
};
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_FLRC_PACKET_PARAMS, true, buff, sizeof(buff)));
}
int16_t LR2021::getFlrcRxStats(uint16_t* packetRx, uint16_t* packetCrcError, uint16_t* lenError) {
uint8_t buff[14] = { 0 };
int16_t state = this->SPIcommand(RADIOLIB_LR2021_CMD_GET_FLRC_RX_STATS, false, buff, sizeof(buff));
if(packetRx) { *packetRx = ((uint16_t)(buff[0]) << 8) | (uint16_t)buff[1]; }
if(packetCrcError) { *packetCrcError = ((uint16_t)(buff[2]) << 8) | (uint16_t)buff[3]; }
if(lenError) { *lenError = ((uint16_t)(buff[4]) << 8) | (uint16_t)buff[5]; }
return(state);
}
int16_t LR2021::getFlrcPacketStatus(uint16_t* packetLen, float* rssiAvg, float* rssiSync, uint8_t* syncWordNum) {
uint8_t buff[5] = { 0 };
int16_t state = this->SPIcommand(RADIOLIB_LR2021_CMD_GET_FLRC_PACKET_STATUS, false, buff, sizeof(buff));
uint16_t raw;
if(packetLen) { *packetLen = ((uint16_t)(buff[0]) << 8) | (uint16_t)buff[1]; }
if(rssiAvg) {
raw = (uint16_t)buff[2] << 1;
raw |= (buff[4] & 0x04) >> 2;
*rssiAvg = (float)raw / -2.0f;
}
if(rssiSync) {
raw = (uint16_t)buff[3] << 1;
raw |= (buff[4] & 0x01);
*rssiSync = (float)raw / -2.0f;
}
if(syncWordNum) { *syncWordNum = (buff[4] & 0xF0) >> 4; }
return(state);
}
int16_t LR2021::setFlrcSyncWord(uint8_t syncWordNum, uint32_t syncWord) {
uint8_t buff[] = {
syncWordNum,
(uint8_t)((syncWord >> 24) & 0xFF), (uint8_t)((syncWord >> 16) & 0xFF),
(uint8_t)((syncWord >> 8) & 0xFF), (uint8_t)(syncWord & 0xFF),
};
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_FLRC_SYNCWORD, true, buff, sizeof(buff)));
}
#endif

View file

@ -0,0 +1,96 @@
#include "LR2021.h"
#include "../LR11x0/LR_common.h"
#include <string.h>
#include <math.h>
#if !RADIOLIB_EXCLUDE_LR2021
int16_t LR2021::setGfskModulationParams(uint32_t bitRate, uint8_t pulseShape, uint8_t rxBw, uint32_t freqDev) {
uint8_t buff[] = {
(uint8_t)((bitRate >> 24) & 0xFF), (uint8_t)((bitRate >> 16) & 0xFF),
(uint8_t)((bitRate >> 8) & 0xFF), (uint8_t)(bitRate & 0xFF),
pulseShape, rxBw, (uint8_t)((freqDev >> 16) & 0xFF),
(uint8_t)((freqDev >> 8) & 0xFF), (uint8_t)(freqDev & 0xFF),
};
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_GFSK_MODULATION_PARAMS, true, buff, sizeof(buff)));
}
int16_t LR2021::setGfskPacketParams(uint16_t preambleLen, uint8_t preambleDetect, bool longPreamble, bool pldLenBits, uint8_t addrComp, uint8_t packetFormat, uint16_t payloadLen, uint8_t crc, uint8_t dcFree) {
uint8_t buff[] = {
(uint8_t)((preambleLen >> 8) & 0xFF), (uint8_t)(preambleLen & 0xFF), preambleDetect,
(uint8_t)(((uint8_t)longPreamble << 5) | ((uint8_t)pldLenBits << 4) | (addrComp << 2) | ((uint8_t)packetFormat & 0x03)),
(uint8_t)((payloadLen >> 8) & 0xFF), (uint8_t)(payloadLen & 0xFF),
(uint8_t)((crc << 4) | (dcFree << 4)),
};
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_GFSK_PACKET_PARAMS, true, buff, sizeof(buff)));
}
int16_t LR2021::setGfskWhiteningParams(uint8_t whitenType, uint16_t init) {
uint8_t buff[] = {
(uint8_t)((whitenType << 4) | (uint8_t)((init >> 8) & 0x0F)),
(uint8_t)(init & 0xFF),
};
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_GFSK_WHITENING_PARAMS, true, buff, sizeof(buff)));
}
int16_t LR2021::setGfskCrcParams(uint32_t poly, uint32_t init) {
uint8_t buff[] = {
(uint8_t)((poly >> 24) & 0xFF), (uint8_t)((poly >> 16) & 0xFF),
(uint8_t)((poly >> 8) & 0xFF), (uint8_t)(poly & 0xFF),
(uint8_t)((init >> 24) & 0xFF), (uint8_t)((init >> 16) & 0xFF),
(uint8_t)((init >> 8) & 0xFF), (uint8_t)(init & 0xFF),
};
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_GFSK_CRC_PARAMS, true, buff, sizeof(buff)));
}
int16_t LR2021::setGfskSyncword(const uint8_t* syncWord, size_t syncWordLen, bool msbFirst) {
uint8_t buff[9] = { 0 };
for(int8_t i = 7; i >= (int8_t) (RADIOLIB_LR2021_GFSK_SYNC_WORD_LEN - syncWordLen); i--) {
buff[i] = syncWord[i - (int8_t) (RADIOLIB_LR2021_GFSK_SYNC_WORD_LEN - syncWordLen)];
}
buff[8] = (uint8_t)msbFirst << 7 | ((syncWordLen*8) & 0x7F);
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_GFSK_SYNCWORD, true, buff, sizeof(buff)));
}
int16_t LR2021::setGfskAddress(uint8_t addrNode, uint8_t addrBroadcast) {
uint8_t buff[] = { addrNode, addrBroadcast };
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_GFSK_ADDRESS, true, buff, sizeof(buff)));
}
int16_t LR2021::getGfskRxStats(uint16_t* packetRx, uint16_t* packetCrcError, uint16_t* lenError, uint16_t* preambleDet, uint16_t* syncOk, uint16_t* syncFail, uint16_t* timeout) {
uint8_t buff[14] = { 0 };
int16_t state = this->SPIcommand(RADIOLIB_LR2021_CMD_GET_GFSK_RX_STATS, false, buff, sizeof(buff));
if(packetRx) { *packetRx = ((uint16_t)(buff[0]) << 8) | (uint16_t)buff[1]; }
if(packetCrcError) { *packetCrcError = ((uint16_t)(buff[2]) << 8) | (uint16_t)buff[3]; }
if(lenError) { *lenError = ((uint16_t)(buff[4]) << 8) | (uint16_t)buff[5]; }
if(preambleDet) { *preambleDet = ((uint16_t)(buff[6]) << 8) | (uint16_t)buff[7]; }
if(syncOk) { *syncOk = ((uint16_t)(buff[8]) << 8) | (uint16_t)buff[9]; }
if(syncFail) { *syncFail = ((uint16_t)(buff[10]) << 8) | (uint16_t)buff[11]; }
if(timeout) { *timeout = ((uint16_t)(buff[12]) << 8) | (uint16_t)buff[13]; }
return(state);
}
int16_t LR2021::getGfskPacketStatus(uint16_t* packetLen, float* rssiAvg, float* rssiSync, bool* addrMatchNode, bool* addrMatchBroadcast, float* lqi) {
uint8_t buff[6] = { 0 };
int16_t state = this->SPIcommand(RADIOLIB_LR2021_CMD_GET_GFSK_PACKET_STATUS, false, buff, sizeof(buff));
uint16_t raw;
if(packetLen) { *packetLen = ((uint16_t)(buff[0]) << 8) | (uint16_t)buff[1]; }
if(rssiAvg) {
raw = (uint16_t)buff[2] << 1;
raw |= (buff[4] & 0x04) >> 2;
*rssiAvg = (float)raw / -2.0f;
}
if(rssiSync) {
raw = (uint16_t)buff[3] << 1;
raw |= (buff[4] & 0x01);
*rssiSync = (float)raw / -2.0f;
}
if(addrMatchNode) { *addrMatchNode = (buff[4] & 0x10); }
if(addrMatchBroadcast) { *addrMatchBroadcast = (buff[4] & 0x20); }
if(lqi) { *lqi = buff[5] * 4.0f; }
return(state);
}
#endif

View file

@ -0,0 +1,130 @@
#include "LR2021.h"
#include "../LR11x0/LR_common.h"
#include <string.h>
#include <math.h>
#if !RADIOLIB_EXCLUDE_LR2021
int16_t LR2021::setLoRaModulationParams(uint8_t sf, uint8_t bw, uint8_t cr, uint8_t ldro) {
// calculate symbol length and enable low data rate optimization, if auto-configuration is enabled
if(this->ldroAuto) {
float symbolLength = (float)(uint32_t(1) << this->spreadingFactor) / (float)this->bandwidthKhz;
if(symbolLength >= 16.0f) {
this->ldrOptimize = RADIOLIB_LR2021_LORA_LDRO_ENABLED;
} else {
this->ldrOptimize = RADIOLIB_LR2021_LORA_LDRO_DISABLED;
}
} else {
this->ldrOptimize = ldro;
}
uint8_t buff[] = { (uint8_t)(((sf & 0x0F) << 4) | (bw & 0x0F)), (uint8_t)(((cr & 0x0F) << 4) | this->ldrOptimize) };
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_LORA_MODULATION_PARAMS, true, buff, sizeof(buff)));
}
int16_t LR2021::setLoRaPacketParams(uint16_t preambleLen, uint8_t hdrType, uint8_t payloadLen, uint8_t crcType, uint8_t invertIQ) {
uint8_t buff[] = {
(uint8_t)((preambleLen >> 8) & 0xFF), (uint8_t)(preambleLen & 0xFF), payloadLen,
(uint8_t)(((hdrType & 0x01) << 2) | ((crcType & 0x01) << 1) | (invertIQ & 0x01)),
};
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_LORA_PACKET_PARAMS, true, buff, sizeof(buff)));
}
int16_t LR2021::setLoRaSynchTimeout(uint8_t numSymbols, bool format) {
uint8_t buff[] = { numSymbols, (uint8_t)format };
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_LORA_SYNCH_TIMEOUT, true, buff, sizeof(buff)));
}
int16_t LR2021::setLoRaSyncword(uint8_t syncword) {
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_LORA_SYNCWORD, true, &syncword, sizeof(syncword)));
}
int16_t LR2021::setLoRaSideDetConfig(uint8_t* configs, size_t numSideDets) {
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_LORA_SIDE_DET_CONFIG, true, configs, numSideDets));
}
int16_t LR2021::setLoRaSideDetSyncword(uint8_t* syncwords, size_t numSideDets) {
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_LORA_SIDE_DET_SYNCWORD, true, syncwords, numSideDets));
}
int16_t LR2021::setLoRaCadParams(uint8_t numSymbols, bool preambleOnly, uint8_t pnrDelta, uint8_t cadExitMode, uint32_t timeout, uint8_t detPeak) {
uint8_t buff[] = {
numSymbols, (uint8_t)(((uint8_t)preambleOnly << 4) | (pnrDelta & 0x0F)), cadExitMode,
(uint8_t)((timeout >> 16) & 0xFF), (uint8_t)((timeout >> 8) & 0xFF), (uint8_t)(timeout & 0xFF),
(uint8_t)(detPeak & 0x7F)
};
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_LORA_CAD_PARAMS, true, buff, sizeof(buff)));
}
int16_t LR2021::setLoRaCad(void) {
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_LORA_CAD, true, NULL, 0));
}
int16_t LR2021::getLoRaRxStats(uint16_t* pktRxTotal, uint16_t* pktCrcError, uint16_t* headerCrcError, uint16_t* falseSynch) {
uint8_t buff[8] = { 0 };
int16_t state = this->SPIcommand(RADIOLIB_LR2021_CMD_GET_LORA_RX_STATS, false, buff, sizeof(buff));
if(pktRxTotal) { *pktRxTotal = ((uint16_t)(buff[0]) << 8) | (uint16_t)buff[1]; }
if(pktCrcError) { *pktCrcError = ((uint16_t)(buff[2]) << 8) | (uint16_t)buff[3]; }
if(headerCrcError) { *headerCrcError = ((uint16_t)(buff[4]) << 8) | (uint16_t)buff[5]; }
if(falseSynch) { *falseSynch = ((uint16_t)(buff[7]) << 8) | (uint16_t)buff[6]; }
return(state);
}
int16_t LR2021::getLoRaPacketStatus(uint8_t* crc, uint8_t* cr, uint8_t* packetLen, float* snrPacket, float* rssiPacket, float* rssiSignalPacket) {
uint8_t buff[6] = { 0 };
int16_t state = this->SPIcommand(RADIOLIB_LR2021_CMD_GET_LORA_PACKET_STATUS, false, buff, sizeof(buff));
uint16_t raw;
if(crc) { *crc = (buff[0] & 0x10) >> 4; }
if(cr) { *cr = buff[0] & 0x0F; }
if(packetLen) { *packetLen = buff[1]; }
if(snrPacket) { *snrPacket = (float)((int8_t)buff[2]) / 4.0f; }
if(rssiPacket) {
raw = (uint16_t)buff[3] << 1;
raw |= (buff[5] & 0x02) >> 1;
*rssiPacket = (float)raw / -2.0f;
}
if(rssiSignalPacket) {
raw = (uint16_t)buff[4] << 1;
raw |= buff[5] & 0x01;
*rssiSignalPacket = (float)raw / -2.0f;
}
return(state);
}
int16_t LR2021::setLoRaAddress(uint8_t addrLen, uint8_t addrPos, const uint8_t* addr) {
if(addrLen > 8) { return(RADIOLIB_ERR_UNKNOWN); }
uint8_t buff[9] = { (uint8_t)(((addrLen & 0x0F) << 4) | (addrPos & 0x0F)) };
memcpy(&buff[1], addr, addrLen);
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_LORA_ADDRESS, true, buff, sizeof(buff)));
}
int16_t LR2021::setLoRaHopping(uint8_t hopCtrl, uint16_t hopPeriod, const uint32_t* freqHops, size_t numFreqHops) {
if(numFreqHops > 40) { return(RADIOLIB_ERR_UNKNOWN); }
uint8_t buff[2 + 160] = { (uint8_t)(hopCtrl | ((hopPeriod & 0xF00) >> 8)), (uint8_t)(hopPeriod & 0xFF) };
for(uint8_t i = 0; i < numFreqHops; i++) {
buff[i + 2] = (freqHops[i] >> 24) & 0xFF;
buff[i + 3] = (freqHops[i] >> 16) & 0xFF;
buff[i + 4] = (freqHops[i] >> 8) & 0xFF;
buff[i + 5] = freqHops[i] & 0xFF;
}
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_LORA_HOPPING, true, buff, sizeof(buff)));
}
int16_t LR2021::setLoRaTxSync(uint8_t function, uint8_t dioNum) {
uint8_t buff[] = { (uint8_t)(function | (dioNum & 0x3F)) };
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_LORA_TX_SYNC, true, buff, sizeof(buff)));
}
int16_t LR2021::setLoRaSideDetCad(const uint8_t* pnrDelta, const uint8_t* detPeak, size_t numSideDets) {
uint8_t buff[6] = { 0 };
for(uint8_t i = 0; i < numSideDets; i++) {
if(i >= 3) { return(RADIOLIB_ERR_UNKNOWN); }
buff[2*i] = pnrDelta[i] & 0x0F;
buff[2*i + 1] = detPeak[i] & 0x7F;
}
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_LORA_SIDE_DET_CAD, true, buff, 2*numSideDets));
}
#endif

View file

@ -0,0 +1,35 @@
#include "LR2021.h"
#include "../LR11x0/LR_common.h"
#include <string.h>
#include <math.h>
#if !RADIOLIB_EXCLUDE_LR2021
int16_t LR2021::setBpskModulationParams(uint32_t bitRate, uint8_t pulseShape, bool diff, uint8_t diffInit) {
uint8_t buff[] = {
(uint8_t)((bitRate >> 24) & 0xFF), (uint8_t)((bitRate >> 16) & 0xFF),
(uint8_t)((bitRate >> 8) & 0xFF), (uint8_t)(bitRate & 0xFF),
(uint8_t)((pulseShape << 4) | ((uint8_t)diff << 2) | (diffInit & 0x03)),
};
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_BPSK_MODULATION_PARAMS, true, buff, sizeof(buff)));
}
int16_t LR2021::setBpskPacketParams(uint8_t payloadLen, uint8_t mode, bool sigFoxControlMsg, uint8_t sigFoxRank) {
uint8_t buff[] = {
payloadLen,
(uint8_t)((mode << 4) | ((uint8_t)sigFoxControlMsg << 2) | (sigFoxRank & 0x03)),
};
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_BPSK_PACKET_PARAMS, true, buff, sizeof(buff)));
}
int16_t LR2021::lrFhssSetSyncword(uint32_t syncWord) {
return(this->setU32(RADIOLIB_LR2021_CMD_LR_FHSS_SET_SYNCWORD, syncWord));
}
int16_t LR2021::setTxTestMode(uint8_t mode) {
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_TX_TEST_MODE, true, &mode, sizeof(mode)));
}
#endif

View file

@ -0,0 +1,100 @@
#include "LR2021.h"
#include "../LR11x0/LR_common.h"
#include <string.h>
#include <math.h>
#if !RADIOLIB_EXCLUDE_LR2021
int16_t LR2021::setOokModulationParams(uint32_t bitRate, uint8_t pulseShape, uint8_t rxBw, uint8_t depth) {
uint8_t buff[] = {
(uint8_t)((bitRate >> 24) & 0xFF), (uint8_t)((bitRate >> 16) & 0xFF),
(uint8_t)((bitRate >> 8) & 0xFF), (uint8_t)(bitRate & 0xFF),
pulseShape, rxBw, depth,
};
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_OOK_MODULATION_PARAMS, true, buff, sizeof(buff)));
}
int16_t LR2021::setOokPacketParams(uint16_t preambleLen, uint8_t addrComp, uint8_t packetFormat, uint16_t payloadLen, uint8_t crc, uint8_t manchester) {
uint8_t buff[] = {
(uint8_t)((preambleLen >> 8) & 0xFF), (uint8_t)(preambleLen & 0xFF),
(uint8_t)((addrComp << 2) | ((uint8_t)packetFormat & 0x03)),
(uint8_t)((payloadLen >> 8) & 0xFF), (uint8_t)(payloadLen & 0xFF),
(uint8_t)(((crc << 4) & 0xF0) | (manchester & 0x0F)),
};
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_OOK_PACKET_PARAMS, true, buff, sizeof(buff)));
}
int16_t LR2021::setOokCrcParams(uint32_t poly, uint32_t init) {
uint8_t buff[] = {
(uint8_t)((poly >> 24) & 0xFF), (uint8_t)((poly >> 16) & 0xFF),
(uint8_t)((poly >> 8) & 0xFF), (uint8_t)(poly & 0xFF),
(uint8_t)((init >> 24) & 0xFF), (uint8_t)((init >> 16) & 0xFF),
(uint8_t)((init >> 8) & 0xFF), (uint8_t)(init & 0xFF),
};
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_OOK_CRC_PARAMS, true, buff, sizeof(buff)));
}
int16_t LR2021::setOokSyncword(const uint8_t* syncWord, size_t syncWordLen, bool msbFirst) {
uint8_t buff[5] = { 0 };
for(size_t i = 0; i < syncWordLen; i++) {
buff[3 - i] = syncWord[i];
}
buff[4] = (uint8_t)msbFirst << 7 | ((syncWordLen*8) & 0x7F);
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_OOK_SYNCWORD, true, buff, sizeof(buff)));
}
int16_t LR2021::setOokAddress(uint8_t addrNode, uint8_t addrBroadcast) {
uint8_t buff[] = { addrNode, addrBroadcast };
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_OOK_ADDRESS, true, buff, sizeof(buff)));
}
int16_t LR2021::getOokRxStats(uint16_t* packetRx, uint16_t* crcError, uint16_t* lenError) {
uint8_t buff[6] = { 0 };
int16_t state = this->SPIcommand(RADIOLIB_LR2021_CMD_GET_OOK_RX_STATS, false, buff, sizeof(buff));
if(packetRx) { *packetRx = ((uint16_t)(buff[0]) << 8) | (uint16_t)buff[1]; }
if(crcError) { *crcError = ((uint16_t)(buff[2]) << 8) | (uint16_t)buff[3]; }
if(lenError) { *lenError = ((uint16_t)(buff[4]) << 8) | (uint16_t)buff[5]; }
return(state);
}
int16_t LR2021::getOokPacketStatus(uint16_t* packetLen, float* rssiAvg, float* rssiSync, bool* addrMatchNode, bool* addrMatchBroadcast, float* lqi) {
uint8_t buff[6] = { 0 };
int16_t state = this->SPIcommand(RADIOLIB_LR2021_CMD_GET_OOK_PACKET_STATUS, false, buff, sizeof(buff));
uint16_t raw;
if(packetLen) { *packetLen = ((uint16_t)(buff[0]) << 8) | (uint16_t)buff[1]; }
if(rssiAvg) {
raw = (uint16_t)buff[2] << 1;
raw |= (buff[4] & 0x04) >> 2;
*rssiAvg = (float)raw / -2.0f;
}
if(rssiSync) {
raw = (uint16_t)buff[3] << 1;
raw |= (buff[4] & 0x01);
*rssiSync = (float)raw / -2.0f;
}
if(addrMatchNode) { *addrMatchNode = (buff[4] & 0x10); }
if(addrMatchBroadcast) { *addrMatchBroadcast = (buff[4] & 0x20); }
if(lqi) { *lqi = buff[5] * 4.0f; }
return(state);
}
int16_t LR2021::setOokDetector(uint16_t preamblePattern, uint8_t patternLen, uint8_t patternNumRepeaters, bool syncWordRaw, bool sofDelimiterRising, uint8_t sofDelimiterLen) {
uint8_t buff[] = {
(uint8_t)((preamblePattern >> 8) & 0xFF), (uint8_t)(preamblePattern & 0xFF),
(uint8_t)(patternLen & 0x0F), (uint8_t)(patternNumRepeaters & 0x1F),
(uint8_t)(((uint8_t)syncWordRaw << 5) | ((uint8_t)sofDelimiterRising << 4) | (sofDelimiterLen & 0x0F)),
};
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_OOK_DETECTOR, true, buff, sizeof(buff)));
}
int16_t LR2021::setOokWhiteningParams(uint8_t bitIdx, uint16_t poly, uint16_t init) {
uint8_t buff[] = {
(uint8_t)((bitIdx << 4) | ((poly >> 8) & 0x0FF)), (uint8_t)(poly & 0xFF),
(uint8_t)((init >> 8) & 0xFF), (uint8_t)(init & 0xFF),
};
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_OOK_WHITENING_PARAMS, true, buff, sizeof(buff)));
}
#endif

View file

@ -0,0 +1,62 @@
#include "LR2021.h"
#include "../LR11x0/LR_common.h"
#include <string.h>
#include <math.h>
#if !RADIOLIB_EXCLUDE_LR2021
int16_t LR2021::setOqpskParams(uint8_t mode, uint8_t rxBw, uint8_t payloadLen, uint16_t preambleLen, bool addrFilt, bool fcsManual) {
uint8_t buff[] = {
mode, rxBw, payloadLen,
(uint8_t)((preambleLen >> 8) & 0xFF), (uint8_t)(preambleLen & 0xFF),
(uint8_t)((uint8_t)addrFilt << 1 | (uint8_t)fcsManual),
};
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_OQPSK_PARAMS, true, buff, sizeof(buff)));
}
int16_t LR2021::getOqpskRxStats(uint16_t* packetRx, uint16_t* crcError, uint16_t* lenError) {
uint8_t buff[6] = { 0 };
int16_t state = this->SPIcommand(RADIOLIB_LR2021_CMD_GET_OQPSK_RX_STATS, false, buff, sizeof(buff));
if(packetRx) { *packetRx = ((uint16_t)(buff[0]) << 8) | (uint16_t)buff[1]; }
if(crcError) { *crcError = ((uint16_t)(buff[2]) << 8) | (uint16_t)buff[3]; }
if(lenError) { *lenError = ((uint16_t)(buff[4]) << 8) | (uint16_t)buff[5]; }
return(state);
}
int16_t LR2021::getOqpskPacketStatus(uint8_t* rxHeader, uint16_t* payloadLen, float* rssiAvg, float* rssiSync, float* lqi) {
uint8_t buff[7] = { 0 };
int16_t state = this->SPIcommand(RADIOLIB_LR2021_CMD_GET_OQPSK_PACKET_STATUS, false, buff, sizeof(buff));
if(rxHeader) { *rxHeader = buff[0]; }
if(payloadLen) { *payloadLen = ((uint16_t)(buff[1]) << 8) | (uint16_t)buff[2]; }
uint16_t raw;
if(rssiAvg) {
raw = (uint16_t)buff[3] << 1;
raw |= (buff[5] & 0x04) >> 2;
*rssiAvg = (float)raw / -2.0f;
}
if(rssiSync) {
raw = (uint16_t)buff[4] << 1;
raw |= (buff[5] & 0x01);
*rssiSync = (float)raw / -2.0f;
}
if(lqi) { *lqi = buff[6] * 4.0f; }
return(state);
}
int16_t LR2021::setOqpskPacketLen(uint8_t len) {
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_OQPSK_PACKET_LEN, true, &len, sizeof(len)));
}
int16_t LR2021::setOqpskAddress(const uint8_t longDestAddr[8], uint16_t shortDestAddr, uint16_t panId, uint8_t transId) {
uint8_t buff[] = {
longDestAddr[7], longDestAddr[6], longDestAddr[5], longDestAddr[4],
longDestAddr[3], longDestAddr[2], longDestAddr[1], longDestAddr[0],
(uint8_t)((shortDestAddr >> 8) & 0xFF), (uint8_t)(shortDestAddr & 0xFF),
(uint8_t)((panId >> 8) & 0xFF), (uint8_t)(panId & 0xFF), transId,
};
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_OQPSK_ADDRESS, true, buff, sizeof(buff)));
}
#endif

View file

@ -0,0 +1,116 @@
#include "LR2021.h"
#include "../LR11x0/LR_common.h"
#include <string.h>
#include <math.h>
#if !RADIOLIB_EXCLUDE_LR2021
int16_t LR2021::setRfFrequency(uint32_t rfFreq) {
return(this->setU32(RADIOLIB_LR2021_CMD_SET_RF_FREQUENCY, rfFreq));
}
int16_t LR2021::setRxPath(uint8_t rxPath, uint8_t rxBoost) {
uint8_t buff[] = { (uint8_t)(rxPath & 0x01), (uint8_t)(rxBoost & 0x07) };
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_RX_PATH, true, buff, sizeof(buff)));
}
int16_t LR2021::getRssiInst(float* rssi) {
uint8_t buff[2] = { 0 };
int16_t state = this->SPIcommand(RADIOLIB_LR2021_CMD_GET_RSSI_INST, false, buff, sizeof(buff));
if(rssi) {
uint16_t raw = ((uint16_t)(buff[0]) << 1) | (uint16_t)((buff[1] >> 7) & 0x01);
*rssi = (float)raw/-2.0f;
}
return(state);
}
int16_t LR2021::setRssiCalibration(uint8_t rxPath, const uint16_t gain[RADIOLIB_LR2021_GAIN_TABLE_LENGTH], const uint8_t noiseFloor[RADIOLIB_LR2021_GAIN_TABLE_LENGTH]) {
uint8_t buff[1 + 3*RADIOLIB_LR2021_GAIN_TABLE_LENGTH] = { 0 };
buff[0] = rxPath;
for(uint8_t i = 0; i < RADIOLIB_LR2021_GAIN_TABLE_LENGTH; i++) {
buff[1 + 3*i] = (uint8_t)((gain[i] & 0x300) >> 8);
buff[2 + 3*i] = (uint8_t)(gain[i] & 0xFF);
buff[3 + 3*i] = noiseFloor[i];
}
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_RSSI_CALIBRATION, true, buff, sizeof(buff)));
}
int16_t LR2021::setTimestampSource(uint8_t index, uint8_t source) {
uint8_t buff[] = { (uint8_t)(((index & 0x03) << 4) | (source & 0x0F)) };
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_TIMESTAMP_SOURCE, true, buff, sizeof(buff)));
}
int16_t LR2021::getTimestampValue(uint8_t index, uint32_t* timestamp) {
uint8_t reqBuff[] = { (uint8_t)(index & 0x03) };
uint8_t rplBuff[4] = { 0 };
int16_t state = this->SPIcommand(RADIOLIB_LR2021_CMD_GET_TIMESTAMP_VALUE, false, rplBuff, sizeof(rplBuff), reqBuff, sizeof(reqBuff));
if(timestamp) { *timestamp = ((uint32_t)(rplBuff[0]) << 24) | ((uint32_t)(rplBuff[1]) << 16) | ((uint32_t)(rplBuff[2]) << 8) | (uint32_t)rplBuff[3]; }
return(state);
}
int16_t LR2021::setCca(uint32_t duration, uint8_t gain) {
uint8_t buff[] = {
(uint8_t)((duration >> 16) & 0xFF), (uint8_t)((duration >> 8) & 0xFF), (uint8_t)(duration & 0xFF), gain,
};
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_CCA, true, buff, sizeof(buff)));
}
int16_t LR2021::getCcaResult(float* rssiMin, float* rssiMax, float* rssiAvg) {
uint8_t buff[4] = { 0 };
int16_t state = this->SPIcommand(RADIOLIB_LR2021_CMD_GET_CCA_RESULT, false, buff, sizeof(buff));
uint16_t raw;
if(rssiMin) {
raw = ((uint16_t)(buff[0]) << 1) | (uint16_t)((buff[3] >> 2) & 0x01);
*rssiMin = (float)raw/-2.0f;
}
if(rssiMax) {
raw = ((uint16_t)(buff[1]) << 1) | (uint16_t)((buff[3] >> 1) & 0x01);
*rssiMax = (float)raw/-2.0f;
}
if(rssiAvg) {
raw = ((uint16_t)(buff[2]) << 1) | (uint16_t)((buff[3] >> 0) & 0x01);
*rssiAvg = (float)raw/-2.0f;
}
return(state);
}
int16_t LR2021::setCadParams(uint32_t cadTimeout, uint8_t threshold, uint8_t exitMode, uint32_t trxTimeout) {
uint8_t buff[] = {
(uint8_t)((cadTimeout >> 16) & 0xFF), (uint8_t)((cadTimeout >> 8) & 0xFF), (uint8_t)(cadTimeout & 0xFF),
threshold, (uint8_t)(exitMode & 0x03),
(uint8_t)((trxTimeout >> 16) & 0xFF), (uint8_t)((trxTimeout >> 8) & 0xFF), (uint8_t)(trxTimeout & 0xFF),
};
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_CAD_PARAMS, true, buff, sizeof(buff)));
}
int16_t LR2021::setCad(void) {
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_CAD, true, NULL, 0));
}
int16_t LR2021::selPa(uint8_t pa) {
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SEL_PA, true, &pa, sizeof(pa)));
}
int16_t LR2021::setPaConfig(uint8_t pa, uint8_t paLfMode, uint8_t paLfDutyCycle, uint8_t paLfSlices, uint8_t paHfDutyCycle) {
uint8_t buff[] = {
(uint8_t)(pa << 7), (uint8_t)(paLfMode & 0x03), (uint8_t)(paLfDutyCycle & 0xF0), (uint8_t)(paLfSlices & 0x0F), (uint8_t)(paHfDutyCycle & 0x1F),
};
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_PA_CONFIG, true, buff, sizeof(buff)));
}
int16_t LR2021::setTxParams(int8_t txPower, uint8_t rampTime) {
uint8_t buff[] = { (uint8_t)(txPower * 2), rampTime };
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_TX_PARAMS, true, buff, sizeof(buff)));
}
int16_t LR2021::setPacketType(uint8_t packetType) {
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_PACKET_TYPE, true, &packetType, sizeof(packetType)));
}
int16_t LR2021::getPacketType(uint8_t* packetType) {
return(this->SPIcommand(RADIOLIB_LR2021_CMD_GET_PACKET_TYPE, false, packetType, sizeof(uint8_t)));
}
#endif

View file

@ -0,0 +1,64 @@
#include "LR2021.h"
#include "../LR11x0/LR_common.h"
#include <string.h>
#include <math.h>
#if !RADIOLIB_EXCLUDE_LR2021
int16_t LR2021::setRangingAddr(uint32_t addr, uint8_t checkLen) {
uint8_t buff[] = {
(uint8_t)((addr >> 24) & 0xFF), (uint8_t)((addr >> 16) & 0xFF),
(uint8_t)((addr >> 8) & 0xFF), (uint8_t)(addr & 0xFF),
checkLen,
};
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_RANGING_ADDR, true, buff, sizeof(buff)));
}
int16_t LR2021::setRangingReqAddr(uint32_t addr) {
uint8_t buff[] = {
(uint8_t)((addr >> 24) & 0xFF), (uint8_t)((addr >> 16) & 0xFF),
(uint8_t)((addr >> 8) & 0xFF), (uint8_t)(addr & 0xFF),
};
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_RANGING_REQ_ADDR, true, buff, sizeof(buff)));
}
int16_t LR2021::getRangingResult(uint8_t type, uint32_t* rng1, uint8_t* rssi1, uint32_t* rng2) {
const uint8_t reqBuff[] = { type };
uint8_t rplBuff[7] = { 0 };
//! \TODO: [LR2021] implement AGC gains readout
size_t rplLen = (type == RADIOLIB_LR2021_RANGING_RESULT_TYPE_RAW) ? 7 : 4;
int16_t state = this->SPIcommand(RADIOLIB_LR2021_CMD_GET_RANGING_RESULT, false, rplBuff, sizeof(rplBuff), reqBuff, rplLen);
if(rng1) { *rng1 = ((uint32_t)(rplBuff[0]) << 16) | ((uint32_t)(rplBuff[1]) << 8) | (uint32_t)rplBuff[2]; }
if(rssi1) { *rssi1 = rplBuff[3]; }
if(rng2 && (type == RADIOLIB_LR2021_RANGING_RESULT_TYPE_RAW_EXT)) {
*rng2 = ((uint32_t)(rplBuff[4]) << 16) | ((uint32_t)(rplBuff[5]) << 8) | (uint32_t)rplBuff[6];
}
return(state);
}
int16_t LR2021::getRangingStats(uint16_t* exchangeValid, uint16_t* requestValid, uint16_t* responseDone, uint16_t* timeout, uint16_t* requestDiscarded) {
uint8_t buff[10] = { 0 };
int16_t state = this->SPIcommand(RADIOLIB_LR2021_CMD_GET_RANGING_STATS, false, buff, sizeof(buff));
if(exchangeValid) { *exchangeValid = ((uint16_t)(buff[0]) << 8) | (uint16_t)buff[1]; }
if(requestValid) { *requestValid = ((uint16_t)(buff[2]) << 8) | (uint16_t)buff[3]; }
if(responseDone) { *responseDone = ((uint16_t)(buff[4]) << 8) | (uint16_t)buff[5]; }
if(timeout) { *timeout = ((uint16_t)(buff[6]) << 8) | (uint16_t)buff[7]; }
if(requestDiscarded) { *requestDiscarded = ((uint16_t)(buff[8]) << 8) | (uint16_t)buff[9]; }
return(state);
}
int16_t LR2021::setRangingTxRxDelay(uint32_t delay) {
return(this->setU32(RADIOLIB_LR2021_CMD_SET_RANGING_TX_RX_DELAY, delay));
}
int16_t LR2021::setRangingParams(bool spyMode, uint8_t nbSymbols) {
uint8_t buff[] = { (uint8_t)(((uint8_t)spyMode << 6) | (nbSymbols & 0x3F)) };
return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_RANGING_PARAMS, true, buff, sizeof(buff)));
}
#endif

View file

@ -0,0 +1,527 @@
#if !defined(RADIOLIB_LR2021_COMMANDS_H)
#define RADIOLIB_LR2021_COMMANDS_H
#include "../../TypeDef.h"
#if !RADIOLIB_EXCLUDE_LR2021
// LR2021 SPI commands
#define RADIOLIB_LR2021_CMD_NOP (0x0000)
#define RADIOLIB_LR2021_CMD_READ_RX_FIFO (0x0001)
#define RADIOLIB_LR2021_CMD_WRITE_TX_FIFO (0x0002)
#define RADIOLIB_LR2021_CMD_WRITE_REG_MEM_32 (0x0104)
#define RADIOLIB_LR2021_CMD_WRITE_REG_MEM_MASK_32 (0x0105)
#define RADIOLIB_LR2021_CMD_READ_REG_MEM_32 (0x0106)
#define RADIOLIB_LR2021_CMD_SET_SLEEP (0x0127)
#define RADIOLIB_LR2021_CMD_SET_STANDBY (0x0128)
#define RADIOLIB_LR2021_CMD_SET_FS (0x0129)
#define RADIOLIB_LR2021_CMD_SET_ADDITIONAL_REG_TO_RETAIN (0x012A)
#define RADIOLIB_LR2021_CMD_SET_RX (0x020C)
#define RADIOLIB_LR2021_CMD_SET_TX (0x020D)
#define RADIOLIB_LR2021_CMD_SET_RX_TX_FALLBACK_MODE (0x0206)
#define RADIOLIB_LR2021_CMD_SET_RX_DUTY_CYCLE (0x0210)
#define RADIOLIB_LR2021_CMD_SET_AUTO_RX_TX (0x0211)
#define RADIOLIB_LR2021_CMD_GET_RX_PKT_LENGTH (0x0212)
#define RADIOLIB_LR2021_CMD_STOP_TIMEOUT_ON_PREAMBLE (0x0209)
#define RADIOLIB_LR2021_CMD_RESET_RX_STATS (0x020A)
#define RADIOLIB_LR2021_CMD_SET_DEFAULT_RX_TX_TIMEOUT (0x0215)
#define RADIOLIB_LR2021_CMD_SET_REG_MODE (0x0121)
#define RADIOLIB_LR2021_CMD_CALIBRATE (0x0122)
#define RADIOLIB_LR2021_CMD_CALIB_FRONT_END (0x0123)
#define RADIOLIB_LR2021_CMD_GET_V_BAT (0x0124)
#define RADIOLIB_LR2021_CMD_GET_TEMP (0x0125)
#define RADIOLIB_LR2021_CMD_SET_EOL_CONFIG (0x0130)
#define RADIOLIB_LR2021_CMD_GET_RANDOM_NUMBER (0x0126)
#define RADIOLIB_LR2021_CMD_GET_STATUS (0x0100)
#define RADIOLIB_LR2021_CMD_GET_VERSION (0x0101)
#define RADIOLIB_LR2021_CMD_CLEAR_ERRORS (0x0111)
#define RADIOLIB_LR2021_CMD_GET_ERRORS (0x0110)
#define RADIOLIB_LR2021_CMD_SET_DIO_FUNCTION (0x0112)
#define RADIOLIB_LR2021_CMD_SET_DIO_RF_SWITCH_CONFIG (0x0113)
#define RADIOLIB_LR2021_CMD_SET_DIO_IRQ_CONFIG (0x0115)
#define RADIOLIB_LR2021_CMD_CLEAR_IRQ (0x0116)
#define RADIOLIB_LR2021_CMD_GET_AND_CLEAR_IRQ_STATUS (0x0117)
#define RADIOLIB_LR2021_CMD_CONFIG_FIFO_IRQ (0x011A)
#define RADIOLIB_LR2021_CMD_GET_FIFO_IRQ_FLAGS (0x011B)
#define RADIOLIB_LR2021_CMD_CLEAR_FIFO_IRQ_FLAGS (0x0114)
#define RADIOLIB_LR2021_CMD_GET_AND_CLEAR_FIFO_IRQ_FLAGS (0x012E)
#define RADIOLIB_LR2021_CMD_GET_RX_FIFO_LEVEL (0x011C)
#define RADIOLIB_LR2021_CMD_GET_TX_FIFO_LEVEL (0x011D)
#define RADIOLIB_LR2021_CMD_CLEAR_RX_FIFO (0x011E)
#define RADIOLIB_LR2021_CMD_CLEAR_TX_FIFO (0x011F)
#define RADIOLIB_LR2021_CMD_CONFIG_LF_CLOCK (0x0118)
#define RADIOLIB_LR2021_CMD_CONFIG_CLK_OUTPUTS (0x0119)
#define RADIOLIB_LR2021_CMD_SET_TCXO_MODE (0x0120)
#define RADIOLIB_LR2021_CMD_SET_XOSC_CP_TRIM (0x0131)
#define RADIOLIB_LR2021_CMD_SET_RF_FREQUENCY (0x0200)
#define RADIOLIB_LR2021_CMD_SET_RX_PATH (0x0201)
#define RADIOLIB_LR2021_CMD_GET_RSSI_INST (0x020B)
#define RADIOLIB_LR2021_CMD_SET_RSSI_CALIBRATION (0x0205)
#define RADIOLIB_LR2021_CMD_SET_TIMESTAMP_SOURCE (0x0216)
#define RADIOLIB_LR2021_CMD_GET_TIMESTAMP_VALUE (0x0217)
#define RADIOLIB_LR2021_CMD_SET_CCA (0x0218)
#define RADIOLIB_LR2021_CMD_GET_CCA_RESULT (0x0219)
#define RADIOLIB_LR2021_CMD_SET_AGC_GAIN_MANUAL (0x021A)
#define RADIOLIB_LR2021_CMD_SET_CAD_PARAMS (0x021B)
#define RADIOLIB_LR2021_CMD_SET_CAD (0x021C)
#define RADIOLIB_LR2021_CMD_SEL_PA (0x020F)
#define RADIOLIB_LR2021_CMD_SET_PA_CONFIG (0x0202)
#define RADIOLIB_LR2021_CMD_SET_TX_PARAMS (0x0203)
#define RADIOLIB_LR2021_CMD_SET_PACKET_TYPE (0x0207)
#define RADIOLIB_LR2021_CMD_GET_PACKET_TYPE (0x0208)
#define RADIOLIB_LR2021_CMD_SET_LORA_MODULATION_PARAMS (0x0220)
#define RADIOLIB_LR2021_CMD_SET_LORA_PACKET_PARAMS (0x0221)
#define RADIOLIB_LR2021_CMD_SET_LORA_SYNCH_TIMEOUT (0x0222)
#define RADIOLIB_LR2021_CMD_SET_LORA_SYNCWORD (0x0223)
#define RADIOLIB_LR2021_CMD_SET_LORA_SIDE_DET_CONFIG (0x0224)
#define RADIOLIB_LR2021_CMD_SET_LORA_SIDE_DET_SYNCWORD (0x0225)
#define RADIOLIB_LR2021_CMD_SET_LORA_CAD_PARAMS (0x0227)
#define RADIOLIB_LR2021_CMD_SET_LORA_CAD (0x0228)
#define RADIOLIB_LR2021_CMD_GET_LORA_RX_STATS (0x0229)
#define RADIOLIB_LR2021_CMD_GET_LORA_PACKET_STATUS (0x022A)
#define RADIOLIB_LR2021_CMD_SET_LORA_ADDRESS (0x022B)
#define RADIOLIB_LR2021_CMD_SET_LORA_HOPPING (0x022C)
#define RADIOLIB_LR2021_CMD_SET_LORA_TX_SYNC (0x021D)
#define RADIOLIB_LR2021_CMD_SET_LORA_SIDE_DET_CAD (0x021E)
#define RADIOLIB_LR2021_CMD_SET_RANGING_ADDR (0x0278)
#define RADIOLIB_LR2021_CMD_SET_RANGING_REQ_ADDR (0x0279)
#define RADIOLIB_LR2021_CMD_GET_RANGING_RESULT (0x027A)
#define RADIOLIB_LR2021_CMD_GET_RANGING_STATS (0x027D)
#define RADIOLIB_LR2021_CMD_SET_RANGING_TX_RX_DELAY (0x027B)
#define RADIOLIB_LR2021_CMD_SET_RANGING_PARAMS (0x027C)
#define RADIOLIB_LR2021_CMD_SET_GFSK_MODULATION_PARAMS (0x0240)
#define RADIOLIB_LR2021_CMD_SET_GFSK_PACKET_PARAMS (0x0241)
#define RADIOLIB_LR2021_CMD_SET_GFSK_WHITENING_PARAMS (0x0242)
#define RADIOLIB_LR2021_CMD_SET_GFSK_CRC_PARAMS (0x0243)
#define RADIOLIB_LR2021_CMD_SET_GFSK_SYNCWORD (0x0244)
#define RADIOLIB_LR2021_CMD_SET_GFSK_ADDRESS (0x0245)
#define RADIOLIB_LR2021_CMD_GET_GFSK_RX_STATS (0x0246)
#define RADIOLIB_LR2021_CMD_GET_GFSK_PACKET_STATUS (0x0247)
#define RADIOLIB_LR2021_CMD_SET_WMBUS_PARAMS (0x026A)
#define RADIOLIB_LR2021_CMD_GET_WMBUS_RX_STATS (0x026C)
#define RADIOLIB_LR2021_CMD_GET_WMBUS_PACKET_STATUS (0x026D)
#define RADIOLIB_LR2021_CMD_SET_WMBUS_FILTERING_ADDRESS (0x026E)
#define RADIOLIB_LR2021_CMD_SET_WISUN_MODE (0x0270)
#define RADIOLIB_LR2021_CMD_SET_WISUN_PACKET_PARAMS (0x0271)
#define RADIOLIB_LR2021_CMD_GET_WISUN_RX_STATS (0x0272)
#define RADIOLIB_LR2021_CMD_GET_WISUN_PACKET_STATUS (0x0273)
#define RADIOLIB_LR2021_CMD_SET_WISUN_PACKET_LEN (0x0274)
#define RADIOLIB_LR2021_CMD_SET_ZWAVE_PARAMS (0x0297)
#define RADIOLIB_LR2021_CMD_SET_ZWAVE_HOME_ID_FILTERING (0x0298)
#define RADIOLIB_LR2021_CMD_GET_ZWAVE_RX_STATS (0x0299)
#define RADIOLIB_LR2021_CMD_GET_ZWAVE_PACKET_STATUS (0x029A)
#define RADIOLIB_LR2021_CMD_SET_ZWAVE_BEAM_FILTERING (0x029B)
#define RADIOLIB_LR2021_CMD_SET_ZWAVE_SCAN_CONFIG (0x029C)
#define RADIOLIB_LR2021_CMD_SET_ZWAVE_SCAN (0x029D)
#define RADIOLIB_LR2021_CMD_SET_BLE_MODULATION_PARAMS (0x0260)
#define RADIOLIB_LR2021_CMD_SET_BLE_CHANNEL_PARAMS (0x0261)
#define RADIOLIB_LR2021_CMD_SET_BLE_PDU_LEN (0x0266)
#define RADIOLIB_LR2021_CMD_SET_BLE_TX (0x0262)
#define RADIOLIB_LR2021_CMD_GET_BLE_RX_STATS (0x0264)
#define RADIOLIB_LR2021_CMD_GET_BLE_PACKET_STATUS (0x0265)
#define RADIOLIB_LR2021_CMD_SET_OQPSK_PARAMS (0x029F)
#define RADIOLIB_LR2021_CMD_GET_OQPSK_RX_STATS (0x02A0)
#define RADIOLIB_LR2021_CMD_GET_OQPSK_PACKET_STATUS (0x02A1)
#define RADIOLIB_LR2021_CMD_SET_OQPSK_PACKET_LEN (0x02A2)
#define RADIOLIB_LR2021_CMD_SET_OQPSK_ADDRESS (0x02A3)
#define RADIOLIB_LR2021_CMD_SET_BPSK_MODULATION_PARAMS (0x0250)
#define RADIOLIB_LR2021_CMD_SET_BPSK_PACKET_PARAMS (0x0251)
#define RADIOLIB_LR2021_CMD_SET_FLRC_MODULATION_PARAMS (0x0248)
#define RADIOLIB_LR2021_CMD_SET_FLRC_PACKET_PARAMS (0x0249)
#define RADIOLIB_LR2021_CMD_GET_FLRC_RX_STATS (0x024A)
#define RADIOLIB_LR2021_CMD_GET_FLRC_PACKET_STATUS (0x024B)
#define RADIOLIB_LR2021_CMD_SET_FLRC_SYNCWORD (0x024C)
#define RADIOLIB_LR2021_CMD_LR_FHSS_BUILD_FRAME (0x0256)
#define RADIOLIB_LR2021_CMD_LR_FHSS_SET_SYNCWORD (0x0257)
#define RADIOLIB_LR2021_CMD_SET_OOK_MODULATION_PARAMS (0x0281)
#define RADIOLIB_LR2021_CMD_SET_OOK_PACKET_PARAMS (0x0282)
#define RADIOLIB_LR2021_CMD_SET_OOK_CRC_PARAMS (0x0283)
#define RADIOLIB_LR2021_CMD_SET_OOK_SYNCWORD (0x0284)
#define RADIOLIB_LR2021_CMD_SET_OOK_ADDRESS (0x0285)
#define RADIOLIB_LR2021_CMD_GET_OOK_RX_STATS (0x0286)
#define RADIOLIB_LR2021_CMD_GET_OOK_PACKET_STATUS (0x0287)
#define RADIOLIB_LR2021_CMD_SET_OOK_DETECTOR (0x0288)
#define RADIOLIB_LR2021_CMD_SET_OOK_WHITENING_PARAMS (0x0289)
#define RADIOLIB_LR2021_CMD_SET_TX_TEST_MODE (0x020E)
// RADIOLIB_LR2021_CMD_SET_DIO_IRQ_CONFIG
#define RADIOLIB_LR2021_IRQ_RX_FIFO (0x01UL << 0) // 31 0 interrupt: Rx FIFO threshold reached
#define RADIOLIB_LR2021_IRQ_TX_FIFO (0x01UL << 1) // 31 0 Tx FIFO threshold reached
#define RADIOLIB_LR2021_IRQ_RNG_REQ_VALID (0x01UL << 2) // 31 0 ranging slave received valid request
#define RADIOLIB_LR2021_IRQ_TX_TIMESTAMP (0x01UL << 3) // 31 0 end of packet Tx timestamp
#define RADIOLIB_LR2021_IRQ_RX_TIMESTAMP (0x01UL << 4) // 31 0 end of packet Rx timestamp
#define RADIOLIB_LR2021_IRQ_PREAMBLE_DETECTED (0x01UL << 5) // 31 0 preamble detected
#define RADIOLIB_LR2021_IRQ_LORA_HEADER_VALID (0x01UL << 6) // 31 0 LoRa header received and valid
#define RADIOLIB_LR2021_IRQ_SYNCWORD_VALID (0x01UL << 6) // 31 0 sync word valid
#define RADIOLIB_LR2021_IRQ_CAD_DETECTED (0x01UL << 7) // 31 0 channel activity detected
#define RADIOLIB_LR2021_IRQ_LORA_HDR_TIMESTAMP (0x01UL << 8) // 31 0 LoRa header timestamp
#define RADIOLIB_LR2021_IRQ_LORA_HDR_CRC_ERROR (0x01UL << 9) // 31 0 LoRa header CRC error
#define RADIOLIB_LR2021_IRQ_EOL (0x01UL << 10) // 31 0 end of life
#define RADIOLIB_LR2021_IRQ_PA_OCP_OVP (0x01UL << 11) // 31 0 PA overcurrent/overvoltage triggered
#define RADIOLIB_LR2021_IRQ_LORA_TX_RX_HOP (0x01UL << 12) // 31 0 LoRa intra-packet hopping
#define RADIOLIB_LR2021_IRQ_SYNC_FAIL (0x01UL << 13) // 31 0 sync word match detection failed
#define RADIOLIB_LR2021_IRQ_LORA_SYMBOL_END (0x01UL << 14) // 31 0 symbol end
#define RADIOLIB_LR2021_IRQ_LORA_TIMESTAMP_STAT (0x01UL << 15) // 31 0 new stats available
#define RADIOLIB_LR2021_IRQ_ERROR (0x01UL << 16) // 31 0 error other than command error
#define RADIOLIB_LR2021_IRQ_CMD_ERROR (0x01UL << 17) // 31 0 command error
#define RADIOLIB_LR2021_IRQ_RX_DONE (0x01UL << 18) // 31 0 packet received
#define RADIOLIB_LR2021_IRQ_TX_DONE (0x01UL << 19) // 31 0 packet transmitted
#define RADIOLIB_LR2021_IRQ_CAD_DONE (0x01UL << 20) // 31 0 CAD finished
#define RADIOLIB_LR2021_IRQ_TIMEOUT (0x01UL << 21) // 31 0 Rx or Tx timeout
#define RADIOLIB_LR2021_IRQ_CRC_ERROR (0x01UL << 22) // 31 0 CRC error
#define RADIOLIB_LR2021_IRQ_LEN_ERROR (0x01UL << 23) // 31 0 length error on received packet
#define RADIOLIB_LR2021_IRQ_ADDR_ERROR (0x01UL << 24) // 31 0 packet with incorrect address received
#define RADIOLIB_LR2021_IRQ_FHSS (0x01UL << 25) // 31 0 FHSS intra-packet hopping
#define RADIOLIB_LR2021_IRQ_INTER_PACKET_FREQ (0x01UL << 26) // 31 0 inter packet hopping can load new frequency table
#define RADIOLIB_LR2021_IRQ_INTER_NEW_PAYLOAD (0x01UL << 27) // 31 0 inter packet hopping can load new payload
#define RADIOLIB_LR2021_IRQ_RNG_RESP_DONE (0x01UL << 28) // 31 0 slave ranging response sent
#define RADIOLIB_LR2021_IRQ_RNG_REQ_DIS (0x01UL << 29) // 31 0 ranging request discarded
#define RADIOLIB_LR2021_IRQ_RNG_EXCH_VALID (0x01UL << 30) // 31 0 master receive valid ranging response
#define RADIOLIB_LR2021_IRQ_RNG_TIMEOUT (0x01UL << 31) // 31 0 ranging timeout
#define RADIOLIB_LR2021_IRQ_ALL (0xFFFFFFFFUL) // 31 0 all interrupts
// RADIOLIB_LR2021_CMD_SET_SLEEP
#define RADIOLIB_LR2021_SLEEP_32K_CLK_DISABLED (0x00UL << 0) // 0 0 32 kHz clock: disabled
#define RADIOLIB_LR2021_SLEEP_32K_CLK_ENABLED (0x01UL << 0) // 0 0 enabled
#define RADIOLIB_LR2021_SLEEP_RETENTION_DISABLED (0x00UL << 1) // 1 1 configuration retention in sleep mode: disabled
#define RADIOLIB_LR2021_SLEEP_RETENTION_ENABLED (0x01UL << 1) // 1 1 enabled
// RADIOLIB_LR2021_CMD_SET_STANDBY
#define RADIOLIB_LR2021_STANDBY_RC (0x00UL << 0) // 7 0 standby mode: RC oscillator
#define RADIOLIB_LR2021_STANDBY_XOSC (0x01UL << 0) // 7 0 XOSC oscillator
// RADIOLIB_LR2021_CMD_SET_RX
#define RADIOLIB_LR2021_RX_TIMEOUT_NONE (0x000000UL) // 23 0 Rx timeout duration: no timeout (Rx single mode)
#define RADIOLIB_LR2021_RX_TIMEOUT_INF (0xFFFFFFUL) // 23 0 infinite (Rx continuous mode)
// RADIOLIB_LR2021_CMD_SET_TX
#define RADIOLIB_LR2021_TX_TIMEOUT_NONE (0x000000UL) // 23 0 disable Tx timeout
// RADIOLIB_LR2021_CMD_SET_RX_TX_FALLBACK_MODE
#define RADIOLIB_LR2021_FALLBACK_MODE_STBY_RC (0x01UL << 0) // 1 0 fallback mode after Rx/Tx: standby with RC
#define RADIOLIB_LR2021_FALLBACK_MODE_STBY_XOSC (0x02UL << 0) // 1 0 standby with XOSC
#define RADIOLIB_LR2021_FALLBACK_MODE_FS (0x03UL << 0) // 1 0 frequency synthesis
// RADIOLIB_LR2021_CMD_SET_RX_DUTY_CYCLE
#define RADIOLIB_LR2021_RX_DUTY_CYCLE_MODE_RX (0x00UL << 0) // 0 0 mode in Rx windows: Rx (default)
#define RADIOLIB_LR2021_RX_DUTY_CYCLE_MODE_CAD (0x01UL << 0) // 0 0 CAD
// RADIOLIB_LR20210_CMD_AUTO_TX_RX
#define RADIOLIB_LR2021_AUTO_MODE_NONE (0x00UL << 0) // 1 0 auto rx-tx mode: never enable auto rx-tx
#define RADIOLIB_LR2021_AUTO_MODE_ALWAYS (0x01UL << 0) // 1 0 auto rx-tx on every RxDone or TxDone event
#define RADIOLIB_LR2021_AUTO_MODE_OK (0x02UL << 0) // 1 0 auto rx-tx on valid Rx packet only (Tx always)
#define RADIOLIB_LR2021_AUTO_MODE_CLEAR_DISABLED (0x00UL << 7) // 7 7 automatically disable auto rx-tx on timeout: disabled
#define RADIOLIB_LR2021_AUTO_MODE_CLEAR_ENABLED (0x01UL << 7) // 7 7 enabled
// RADIOLIB_LR2021_CMD_SET_REG_MODE
#define RADIOLIB_LR2021_REG_MODE_SIMO_OFF (0x00UL << 0) // 7 0 SIMO mode: disabled
#define RADIOLIB_LR2021_REG_MODE_SIMO_NORMAL (0x02UL << 0) // 7 0 normal
#define RADIOLIB_LR2021_REG_MODE_RAMP_RES_2_US (0x00UL << 5) // 6 5 ramp timing resolution: 2 us
#define RADIOLIB_LR2021_REG_MODE_RAMP_RES_4_US (0x01UL << 5) // 6 5 4 us
#define RADIOLIB_LR2021_REG_MODE_RAMP_RES_8_US (0x02UL << 5) // 6 5 8 us
#define RADIOLIB_LR2021_REG_MODE_RAMP_RES_16_US (0x03UL << 5) // 6 5 16 us
#define RADIOLIB_LR2021_REG_MODE_RAMP_INDEX_RC2RU (0)
#define RADIOLIB_LR2021_REG_MODE_RAMP_INDEX_TX2RU (1)
#define RADIOLIB_LR2021_REG_MODE_RAMP_INDEX_RU2RC (2)
#define RADIOLIB_LR2021_REG_MODE_RAMP_INDEX_RAMP_DOWN (3)
// RADIOLIB_LR2021_CMD_CALIBRATE
#define RADIOLIB_LR2021_CALIBRATE_LF_RC (0x01UL << 0) // 0 0 blocks to calibrate: low-frequency RC
#define RADIOLIB_LR2021_CALIBRATE_HF_RC (0x01UL << 1) // 1 1 high-frequency RC
#define RADIOLIB_LR2021_CALIBRATE_PLL (0x01UL << 2) // 2 2 phase-locked loop
#define RADIOLIB_LR2021_CALIBRATE_AAF (0x01UL << 3) // 3 3 anti-aliasing filter
#define RADIOLIB_LR2021_CALIBRATE_MU (0x01UL << 5) // 4 4 measurement unit
#define RADIOLIB_LR2021_CALIBRATE_PA_OFF (0x01UL << 6) // 5 5 power amplifier offset
#define RADIOLIB_LR2021_CALIBRATE_ALL (0x6FUL << 0) // 7 0 everything
// RADIOLIB_LR2021_CMD_CALIB_FRONT_END
#define RADIOLIB_LR2021_CALIBRATE_FE_LF_PATH (0x00UL << 15) // 15 15 calibration path: low-frequency
#define RADIOLIB_LR2021_CALIBRATE_FE_HF_PATH (0x01UL << 15) // 15 15 high-frequency
#define RADIOLIB_LR2021_CAL_IMG_FREQ_TRIG_MHZ (20.0f)
#define RADIOLIB_LR2021_LF_CUTOFF_FREQ (1500.0f)
// RADIOLIB_LR2021_CMD_GET_V_BAT
#define RADIOLIB_LR2021_VBAT_FORMAT_RAW (0x00UL << 3) // 3 3 readout format: raw
#define RADIOLIB_LR2021_VBAT_FORMAT_MV (0x01UL << 3) // 3 3 millivolts
#define RADIOLIB_LR2021_MEAS_RESOLUTION_OFFSET (8)
// RADIOLIB_LR2021_CMD_GET_TEMP
#define RADIOLIB_LR2021_TEMP_SOURCE_VBE (0x00UL << 4) // 4 4 temperature source: sensor near Vbe junction
#define RADIOLIB_LR2021_TEMP_SOURCE_XOSC (0x01UL << 4) // 4 4 sensor near XOSC
#define RADIOLIB_LR2021_TEMP_FORMAT_RAW (0x00UL << 3) // 3 3 readout format: raw
#define RADIOLIB_LR2021_TEMP_FORMAT_DEG_C (0x01UL << 3) // 3 3 degrees Celsius
// RADIOLIB_LR2021_CMD_SET_EOL_CONFIG
#define RADIOLIB_LR2021_EOL_TRIM_1V6 (0x00UL << 1) // 3 1 EoL trigger threshold: 1.60 V
#define RADIOLIB_LR2021_EOL_TRIM_1V67 (0x01UL << 1) // 3 1 1.67 V
#define RADIOLIB_LR2021_EOL_TRIM_1V74 (0x02UL << 1) // 3 1 1.74 V
#define RADIOLIB_LR2021_EOL_TRIM_1V8 (0x03UL << 1) // 3 1 1.80 V
#define RADIOLIB_LR2021_EOL_TRIM_1V88 (0x04UL << 1) // 3 1 1.88 V (default)
#define RADIOLIB_LR2021_EOL_TRIM_1V95 (0x05UL << 1) // 3 1 1.95 V
#define RADIOLIB_LR2021_EOL_TRIM_2V0 (0x06UL << 1) // 3 1 2.00 V
#define RADIOLIB_LR2021_EOL_TRIM_2V1 (0x07UL << 1) // 3 1 2.10 V
// RADIOLIB_LR2021_CMD_GET_ERRORS
#define RADIOLIB_LR2021_HF_XOSC_START_ERR (0x01UL << 0) // 15 0 error: high-frequency XOSC failed to start
#define RADIOLIB_LR2021_LF_XOSC_START_ERR (0x01UL << 1) // 15 0 low-frequency XOSC failed to start
#define RADIOLIB_LR2021_PLL_LOCK_ERR (0x01UL << 2) // 15 0 PLL failed to lock
#define RADIOLIB_LR2021_LF_RC_CALIB_ERR (0x01UL << 3) // 15 0 low-frequency RC calibration failed
#define RADIOLIB_LR2021_HF_RC_CALIB_ERR (0x01UL << 4) // 15 0 high-frequency RC calibration failed
#define RADIOLIB_LR2021_PLL_CALIB_ERR (0x01UL << 5) // 15 0 PLL calibration failed
#define RADIOLIB_LR2021_AAF_CALIB_ERR (0x01UL << 6) // 15 0 anti-aliasing filter calibration failed
#define RADIOLIB_LR2021_IMG_CALIB_ERR (0x01UL << 7) // 15 0 image rejection calibration failed
#define RADIOLIB_LR2021_CHIP_BUSY_ERR (0x01UL << 8) // 15 0 Tx or Rx could not be processed because chips was busy
#define RADIOLIB_LR2021_RXFREQ_NO_FE_CAL_ERR (0x01UL << 9) // 15 0 front-end calibration nto available for this Rx frequency
#define RADIOLIB_LR2021_MEAS_UNIT_ADC_CALIB_ERR (0x01UL << 10) // 15 0 measurement unit ADC calibration failed
#define RADIOLIB_LR2021_PA_OFFSET_CALIB_ERR (0x01UL << 11) // 15 0 PA offset calibration failed
#define RADIOLIB_LR2021_PPF_CALIB_ERR (0x01UL << 12) // 15 0 poly-phase filter calibration failed
#define RADIOLIB_LR2021_SRC_CALIB_ERR (0x01UL << 13) // 15 0 self-reception cancellation calibration failed
#define RADIOLIB_LR2021_SRC_SATURATION_CALIB_ERR (0x01UL << 14) // 15 0 RSSI saturation during SRC calibration
#define RADIOLIB_LR2021_SRC_TOLERANCE_CALIB_ERR (0x01UL << 15) // 15 0 self-reception cancellation values out of tolernce
// RADIOLIB_LR2021_CMD_SET_DIO_FUNCTION
#define RADIOLIB_LR2021_DIO_FUNCTION_NONE (0x00UL << 4) // 7 4 DIO function: none
#define RADIOLIB_LR2021_DIO_FUNCTION_IRQ (0x01UL << 4) // 7 4 interrupt
#define RADIOLIB_LR2021_DIO_FUNCTION_RF_SWITCH (0x02UL << 4) // 7 4 RF switch
#define RADIOLIB_LR2021_DIO_FUNCTION_GPIO_OUTPUT_LOW (0x05UL << 4) // 7 4 low output
#define RADIOLIB_LR2021_DIO_FUNCTION_GPIO_OUTPUT_HIGH (0x06UL << 4) // 7 4 high output
#define RADIOLIB_LR2021_DIO_FUNCTION_HF_CLK_OUT (0x07UL << 4) // 7 4 high-frequency clock output
#define RADIOLIB_LR2021_DIO_FUNCTION_LF_CLK_OUT (0x08UL << 4) // 7 4 low-frequency clock output (DIO7-11 only)
#define RADIOLIB_LR2021_DIO_FUNCTION_TX_TRIGGER (0x09UL << 4) // 7 4 Tx trigger
#define RADIOLIB_LR2021_DIO_FUNCTION_RX_TRIGGER (0x0AUL << 4) // 7 4 Rx trigger
#define RADIOLIB_LR2021_DIO_SLEEP_PULL_NONE (0x00UL << 0) // 3 0 pull up/down in sleep mode: none
#define RADIOLIB_LR2021_DIO_SLEEP_PULL_DOWN (0x01UL << 0) // 3 0 pull-down
#define RADIOLIB_LR2021_DIO_SLEEP_PULL_UP (0x02UL << 0) // 3 0 pull-up
#define RADIOLIB_LR2021_DIO_SLEEP_PULL_AUTO (0x03UL << 0) // 3 0 auto
// RADIOLIB_LR2021_CMD_SET_DIO_RF_SWITCH_CONFIG
#define RADIOLIB_LR2021_DIO5 (RADIOLIB_LRXXXX_DIOx(0))
#define RADIOLIB_LR2021_DIO6 (RADIOLIB_LRXXXX_DIOx(1))
#define RADIOLIB_LR2021_DIO7 (RADIOLIB_LRXXXX_DIOx(2))
#define RADIOLIB_LR2021_DIO8 (RADIOLIB_LRXXXX_DIOx(3))
#define RADIOLIB_LR2021_DIO9 (RADIOLIB_LRXXXX_DIOx(4))
#define RADIOLIB_LR2021_DIO10 (RADIOLIB_LRXXXX_DIOx(5))
#define RADIOLIB_LR2021_DIO11 (RADIOLIB_LRXXXX_DIOx(6))
// RADIOLIB_LR2021_CMD_CONFIG_FIFO_IRQ
#define RADIOLIB_LR2021_FIFO_IRQ_EMPTY (0x01UL << 0) // 7 0 FIFO interrupt on: empty FIFO
#define RADIOLIB_LR2021_FIFO_IRQ_LOW (0x01UL << 1) // 7 0 level below threshold
#define RADIOLIB_LR2021_FIFO_IRQ_HIGH (0x01UL << 2) // 7 0 level above threshold
#define RADIOLIB_LR2021_FIFO_IRQ_FULL (0x01UL << 3) // 7 0 full FIFO
#define RADIOLIB_LR2021_FIFO_IRQ_OVERFLOW (0x01UL << 4) // 7 0 overflow
#define RADIOLIB_LR2021_FIFO_IRQ_UNDERFLOW (0x01UL << 5) // 7 0 underflow
// RADIOLIB_LR2021_CMD_CONFIG_LF_CLOCK
#define RADIOLIB_LR2021_LF_CLOCK_INTERNAL_RC (0x00UL << 0) // 7 0 low-frequency source: internal 32 kHz RC oscillator
#define RADIOLIB_LR2021_LF_CLOCK_EXTERNAL (0x02UL << 0) // 7 0 external 32.768 kHz signal on DIO11
// RADIOLIB_LR2021_CMD_SET_RX_PATH
#define RADIOLIB_LR2021_RX_PATH_LF (0x00UL << 0) // 7 0 Rx path: low-frequency
#define RADIOLIB_LR2021_RX_PATH_HF (0x01UL << 0) // 7 0 high-frequency
#define RADIOLIB_LR2021_RX_BOOST_LF (0x00UL << 0) // 7 0 Rx boost: low-frequency
#define RADIOLIB_LR2021_RX_BOOST_HF (0x04UL << 0) // 7 0 high-frequency
// RADIOLIB_LR2021_CMD_SET_RSSI_CALIBRATION
#define RADIOLIB_LR2021_RSSI_PATH_LF (0x01UL << 0) // 0 0 Rx path for RSSI: low-frequency
#define RADIOLIB_LR2021_RSSI_PATH_HF (0x01UL << 1) // 1 1 high-frequency
#define RADIOLIB_LR2021_GAIN_TABLE_LENGTH (27)
// RADIOLIB_LR2021_CMD_SET_TIMESTAMP_SOURCE
#define RADIOLIB_LR2021_TIMESTAMP_SOURCE_NONE (0x00UL << 0) // 3 0 timestamp source: none
#define RADIOLIB_LR2021_TIMESTAMP_SOURCE_TX_DONE (0x01UL << 0) // 3 0 Tx done
#define RADIOLIB_LR2021_TIMESTAMP_SOURCE_RX_DONE (0x02UL << 0) // 3 0 Rx done
#define RADIOLIB_LR2021_TIMESTAMP_SOURCE_SYNC (0x03UL << 0) // 3 0 sync
#define RADIOLIB_LR2021_TIMESTAMP_SOURCE_HEADER (0x04UL << 0) // 3 0 LoRa header
// RADIOLIB_LR2021_CMD_SET_CAD_PARAMS
#define RADIOLIB_LR2021_CAD_EXIT_MODE_FALLBACK (0x00UL << 0) // 1 0 CAD exit mode: the configured fallback mode
#define RADIOLIB_LR2021_CAD_EXIT_MODE_TX (0x01UL << 0) // 1 0 Tx
#define RADIOLIB_LR2021_CAD_EXIT_MODE_RX (0x02UL << 0) // 1 0 Rx
#define RADIOLIB_LR2021_CAD_PARAM_DEFAULT (0xFFUL << 0) // 7 0 used by the CAD methods to specify default parameter value
// RADIOLIB_LR2021_CMD_SEL_PA
#define RADIOLIB_LR2021_PA_LOW_POWER (0x00UL << 0) // 1 0 PA to use: low-power
#define RADIOLIB_LR2021_PA_HIGH_POWER (0x01UL << 0) // 1 0 high-power
// RADIOLIB_LR2021_CMD_SET_PA_CONFIG
#define RADIOLIB_LR2021_PA_LF_MODE_FSM (0x00UL << 0) // 1 0 PA LF mode: full single-ended mode
#define RADIOLIB_LR2021_PA_LF_DUTY_CYCLE_UNUSED (0x06UL << 4) // 7 4 PA LF duty cycle: PA not used
#define RADIOLIB_LR2021_PA_LF_SLICES_UNUSED (0x07UL << 0) // 3 0 PA LF slices: PA not used
#define RADIOLIB_LR2021_PA_HF_DUTY_CYCLE_UNUSED (0x10UL << 0) // 4 0 PA HF duty cycle: PA not used
// RADIOLIB_LR2021_CMD_SET_PACKET_TYPE
#define RADIOLIB_LR2021_PACKET_TYPE_LORA (0x00UL << 0) // 7 0 packet type: LoRa
#define RADIOLIB_LR2021_PACKET_TYPE_GFSK (0x02UL << 0) // 7 0 FSK
#define RADIOLIB_LR2021_PACKET_TYPE_BLE (0x03UL << 0) // 7 0 BLE
#define RADIOLIB_LR2021_PACKET_TYPE_RTTOF (0x04UL << 0) // 7 0 RTToF
#define RADIOLIB_LR2021_PACKET_TYPE_FLRC (0x05UL << 0) // 7 0 FLRC
#define RADIOLIB_LR2021_PACKET_TYPE_BPSK (0x06UL << 0) // 7 0 BPSK
#define RADIOLIB_LR2021_PACKET_TYPE_LR_FHSS (0x07UL << 0) // 7 0 LR-FHSS
#define RADIOLIB_LR2021_PACKET_TYPE_WM_BUS (0x08UL << 0) // 7 0 WM-BUS
#define RADIOLIB_LR2021_PACKET_TYPE_WI_SUN (0x09UL << 0) // 7 0 WI-SUN
#define RADIOLIB_LR2021_PACKET_TYPE_OOK (0x0AUL << 0) // 7 0 OOK
#define RADIOLIB_LR2021_PACKET_TYPE_RAW (0x0BUL << 0) // 7 0 RAW
#define RADIOLIB_LR2021_PACKET_TYPE_Z_WAVE (0x0CUL << 0) // 7 0 Z-WAVE
#define RADIOLIB_LR2021_PACKET_TYPE_OQPSK (0x0DUL << 0) // 7 0 OQPSK
#define RADIOLIB_LR2021_PACKET_TYPE_NONE (0xFFUL << 0) // 2 0 none
// RADIOLIB_LR2021_CMD_SET_LORA_MODULATION_PARAMS
#define RADIOLIB_LR2021_LORA_BW_31 (0x02UL << 0) // 3 0 LoRa bandwidth: 31.25 kHz
#define RADIOLIB_LR2021_LORA_BW_41 (0x0AUL << 0) // 3 0 41.67 kHz
#define RADIOLIB_LR2021_LORA_BW_83 (0x0BUL << 0) // 3 0 83.34 kHz
#define RADIOLIB_LR2021_LORA_BW_62 (0x03UL << 0) // 3 0 62.50 kHz
#define RADIOLIB_LR2021_LORA_BW_125 (0x04UL << 0) // 3 0 125 kHz
#define RADIOLIB_LR2021_LORA_BW_250 (0x05UL << 0) // 3 0 250 kHz
#define RADIOLIB_LR2021_LORA_BW_500 (0x06UL << 0) // 3 0 500 kHz
#define RADIOLIB_LR2021_LORA_BW_1000 (0x07UL << 0) // 3 0 1000 kHz
#define RADIOLIB_LR2021_LORA_BW_812 (0x0FUL << 0) // 3 0 812 kHz
#define RADIOLIB_LR2021_LORA_BW_406 (0x0EUL << 0) // 3 0 406 kHz
#define RADIOLIB_LR2021_LORA_BW_203 (0x0DUL << 0) // 3 0 203 kHz
#define RADIOLIB_LR2021_LORA_BW_101 (0x0CUL << 0) // 3 0 101 kHz
#define RADIOLIB_LR2021_LORA_CR_4_5 (0x01UL << 0) // 3 0 LoRa coding rate: 4/5
#define RADIOLIB_LR2021_LORA_CR_4_6 (0x02UL << 0) // 3 0 4/6
#define RADIOLIB_LR2021_LORA_CR_4_7 (0x03UL << 0) // 3 0 4/7
#define RADIOLIB_LR2021_LORA_CR_4_8 (0x04UL << 0) // 3 0 4/8
#define RADIOLIB_LR2021_LORA_CR_4_5_LI (0x05UL << 0) // 3 0 4/5 long interleaver
#define RADIOLIB_LR2021_LORA_CR_4_6_LI (0x06UL << 0) // 3 0 4/6 long interleaver
#define RADIOLIB_LR2021_LORA_CR_4_7_LI (0x07UL << 0) // 3 0 4/7 long interleaver
#define RADIOLIB_LR2021_LORA_LDRO_DISABLED (0x00UL << 0) // 1 0 LDRO/PPM configuration: disabled
#define RADIOLIB_LR2021_LORA_LDRO_ENABLED (0x01UL << 0) // 1 0 enabled
// RADIOLIB_LR2021_CMD_SET_LORA_PACKET_PARAMS
#define RADIOLIB_LR2021_LORA_HEADER_EXPLICIT (0x00UL << 2) // 2 2 LoRa header mode: explicit
#define RADIOLIB_LR2021_LORA_HEADER_IMPLICIT (0x01UL << 2) // 2 2 implicit
#define RADIOLIB_LR2021_LORA_CRC_DISABLED (0x00UL << 1) // 1 1 LoRa CRC: disabled
#define RADIOLIB_LR2021_LORA_CRC_ENABLED (0x01UL << 1) // 1 1 enabled
#define RADIOLIB_LR2021_LORA_IQ_STANDARD (0x00UL << 0) // 0 0 LoRa IQ: standard
#define RADIOLIB_LR2021_LORA_IQ_INVERTED (0x01UL << 0) // 0 0 inverted
// RADIOLIB_LR2021_CMD_SET_LORA_SYNCH_TIMEOUT
#define RADIOLIB_LR2021_LORA_SYNCH_TIMEOUT_FORMAT_SYMBOLS (0x00UL << 0) // 7 0 LoRa synch timeout format: number of symbols
#define RADIOLIB_LR2021_LORA_SYNCH_TIMEOUT_FORMAT_MANT_EXP (0x01UL << 0) // 7 0 mantissa-exponent
// RADIOLIB_LR2021_CMD_SET_LORA_SYNCWORD
#define RADIOLIB_LR2021_LORA_SYNC_WORD_PRIVATE (0x12UL << 0) // 7 0 LoRa sync word: 0x12 (private networks)
#define RADIOLIB_LR2021_LORA_SYNC_WORD_LORAWAN (0x34UL << 0) // 7 0 0x34 (LoRaWAN reserved)
// RADIOLIB_LR2021_CMD_SET_LORA_HOPPING
#define RADIOLIB_LR2021_LORA_HOPPING_DISABLED (0x00UL << 6) // 7 6 LoRa intra-packet hopping: disabled
#define RADIOLIB_LR2021_LORA_HOPPING_ENABLED (0x01UL << 6) // 7 6 enabled
// RADIOLIB_LR2021_CMD_SET_LORA_TX_SYNC
#define RADIOLIB_LR2021_LORA_TX_SYNC_DISABLED (0x00UL << 6) // 7 6 Tx sync: disabled
#define RADIOLIB_LR2021_LORA_TX_SYNC_MASTER (0x01UL << 6) // 7 6 master (wait for signal to transmit sync frame)
#define RADIOLIB_LR2021_LORA_TX_SYNC_SLAVE (0x02UL << 6) // 7 6 slave (output signal on sync frame)
// RADIOLIB_LR2021_CMD_GET_RANGING_RESULT
#define RADIOLIB_LR2021_RANGING_RESULT_TYPE_RAW (0x00UL << 0) // 7 0 ranging result type: raw
#define RADIOLIB_LR2021_RANGING_RESULT_TYPE_RAW_EXT (0x01UL << 0) // 7 0 extended raw
#define RADIOLIB_LR2021_RANGING_RESULT_TYPE_GAINS (0x02UL << 0) // 7 0 AGC gain steps
// RADIOLIB_LR2021_CMD_SET_GFSK_MODULATION_PARAMS
#define RADIOLIB_LR2021_GFSK_BPSK_OOK_BITRATE_BPS (0x00UL << 31) // 7 0 bitrate units: bits per second
#define RADIOLIB_LR2021_GFSK_BPSK_OOK_BITRATE_FRACTIONAL (0x01UL << 31) // 7 0 fractional (1/256 bps)
#define RADIOLIB_LR2021_GFSK_BPSK_FLRC_OOK_SHAPING_NONE (0x00UL << 0) // 7 0 shaping filter: none
#define RADIOLIB_LR2021_GFSK_BPSK_FLRC_OOK_SHAPING_GAUSS_BT_2_0 (0x02UL << 0) // 7 0 Gaussian, BT = 2.0
#define RADIOLIB_LR2021_GFSK_BPSK_FLRC_OOK_SHAPING_RRC_ROLLOFF_0_4 (0x03UL << 0) // 7 0 Root-Raised-Cosine with 0.4 roll-off
#define RADIOLIB_LR2021_GFSK_BPSK_FLRC_OOK_SHAPING_GAUSS_BT_0_3 (0x04UL << 0) // 7 0 Gaussian, BT = 0.3
#define RADIOLIB_LR2021_GFSK_BPSK_FLRC_OOK_SHAPING_GAUSS_BT_0_5 (0x05UL << 0) // 7 0 Gaussian, BT = 0.5
#define RADIOLIB_LR2021_GFSK_BPSK_FLRC_OOK_SHAPING_GAUSS_BT_0_7 (0x06UL << 0) // 7 0 Gaussian, BT = 0.7
#define RADIOLIB_LR2021_GFSK_BPSK_FLRC_OOK_SHAPING_GAUSS_BT_1_0 (0x07UL << 0) // 7 0 Gaussian, BT = 1.0
#define RADIOLIB_LR2021_GFSK_BPSK_FLRC_OOK_SHAPING_RRC_ROLLOFF_0_3 (0x08UL << 0) // 7 0 Root-Raised-Cosine with 0.3 roll-off
#define RADIOLIB_LR2021_GFSK_BPSK_FLRC_OOK_SHAPING_RRC_ROLLOFF_0_5 (0x09UL << 0) // 7 0 Root-Raised-Cosine with 0.5 roll-off
#define RADIOLIB_LR2021_GFSK_BPSK_FLRC_OOK_SHAPING_RRC_ROLLOFF_0_7 (0x0AUL << 0) // 7 0 Root-Raised-Cosine with 0.7 roll-off
// TODO implement the other bandwidths as well (and figure out a way how to calculate it)
#define RADIOLIB_LR2021_GFSK_OOK_RX_BW_4_8 (39) // 7 0 GFSK Rx bandwidth: 4.8 kHz
#define RADIOLIB_LR2021_GFSK_OOK_RX_BW_5_8 (215) // 7 0 5.8 kHz
#define RADIOLIB_LR2021_GFSK_OOK_RX_BW_7_4 (87) // 7 0 7.4 kHz
#define RADIOLIB_LR2021_GFSK_OOK_RX_BW_9_7 (38) // 7 0 9.6 kHz
#define RADIOLIB_LR2021_GFSK_OOK_RX_BW_12_0 (30) // 7 0 12.0 kHz
#define RADIOLIB_LR2021_GFSK_OOK_RX_BW_14_9 (86) // 7 0 14.9 kHz
#define RADIOLIB_LR2021_GFSK_OOK_RX_BW_19_2 (37) // 7 0 19.2 kHz
#define RADIOLIB_LR2021_GFSK_OOK_RX_BW_23_1 (213) // 7 0 21.3 kHz
#define RADIOLIB_LR2021_GFSK_OOK_RX_BW_29_8 (85) // 7 0 29.8 kHz
#define RADIOLIB_LR2021_GFSK_OOK_RX_BW_38_5 (36) // 7 0 38.5 kHz
#define RADIOLIB_LR2021_GFSK_OOK_RX_BW_46_3 (212) // 7 0 46.3 kHz
#define RADIOLIB_LR2021_GFSK_OOK_RX_BW_59_5 (84) // 7 0 59.5 kHz
#define RADIOLIB_LR2021_GFSK_OOK_RX_BW_76_9 (35) // 7 0 76.9 kHz
#define RADIOLIB_LR2021_GFSK_OOK_RX_BW_92_6 (211) // 7 0 92.6 kHz
#define RADIOLIB_LR2021_GFSK_OOK_RX_BW_119_0 (83) // 7 0 119.0 kHz
#define RADIOLIB_LR2021_GFSK_OOK_RX_BW_153_8 (34) // 7 0 153.8 kHz
#define RADIOLIB_LR2021_GFSK_OOK_RX_BW_185_2 (210) // 7 0 185.2 kHz
#define RADIOLIB_LR2021_GFSK_OOK_RX_BW_238_1 (82) // 7 0 238.1 kHz
#define RADIOLIB_LR2021_GFSK_OOK_RX_BW_307_7 (33) // 7 0 307.7 kHz
#define RADIOLIB_LR2021_GFSK_OOK_RX_BW_370_4 (209) // 7 0 370.4 kHz
#define RADIOLIB_LR2021_GFSK_OOK_RX_BW_476_2 (81) // 7 0 476.2 kHz
#define RADIOLIB_LR2021_GFSK_OOK_RX_BW_555_6 (216) // 7 0 555.6 kHz
#define RADIOLIB_LR2021_GFSK_OOK_RX_BW_666_7 (152) // 7 0 666.7 kHz
#define RADIOLIB_LR2021_GFSK_OOK_RX_BW_769_2 (24) // 7 0 769.2 kHz
#define RADIOLIB_LR2021_GFSK_OOK_RX_BW_1111 (200) // 7 0 1111 kHz
#define RADIOLIB_LR2021_GFSK_OOK_RX_BW_2222 (192) // 7 0 2222 kHz
#define RADIOLIB_LR2021_GFSK_OOK_RX_BW_2666 (128) // 7 0 2667 kHz
#define RADIOLIB_LR2021_GFSK_OOK_RX_BW_3076 (0) // 7 0 3077 kHz
// RADIOLIB_LR2021_CMD_SET_GFSK_PACKET_PARAMS
#define RADIOLIB_LR2021_GFSK_OOK_ADDR_FILT_DISABLED (0x00UL << 0) // 7 0 address filtering: disabled
#define RADIOLIB_LR2021_GFSK_OOK_ADDR_FILT_NODE (0x01UL << 0) // 7 0 node only
#define RADIOLIB_LR2021_GFSK_OOK_ADDR_FILT_NODE_BROADCAST (0x02UL << 0) // 7 0 node and broadcast
#define RADIOLIB_LR2021_GFSK_OOK_PACKET_FORMAT_FIXED (0x00UL << 0) // 7 0 packet format: fixed length
#define RADIOLIB_LR2021_GFSK_OOK_PACKET_FORMAT_VARIABLE_8BIT (0x01UL << 0) // 7 0 variable, 8-bit length
#define RADIOLIB_LR2021_GFSK_OOK_PACKET_FORMAT_VARIABLE_9BIT (0x02UL << 0) // 7 0 variable, 9-bit length (for SX128x compatibility)
#define RADIOLIB_LR2021_GFSK_OOK_PACKET_FORMAT_VARIABLE_15BIT (0x03UL << 0) // 7 0 variable, 15-bit length
#define RADIOLIB_LR2021_GFSK_OOK_CRC_OFF (0x00UL << 0) // 7 0 CRC: disabled
#define RADIOLIB_LR2021_GFSK_OOK_CRC8 (0x01UL << 0) // 7 0 1-byte
#define RADIOLIB_LR2021_GFSK_OOK_CRC16 (0x02UL << 0) // 7 0 2-byte
#define RADIOLIB_LR2021_GFSK_OOK_CRC24 (0x03UL << 0) // 7 0 3-byte
#define RADIOLIB_LR2021_GFSK_OOK_CRC32 (0x04UL << 0) // 7 0 4-byte
#define RADIOLIB_LR2021_GFSK_OOK_CRC8_INV (0x09UL << 0) // 7 0 1-byte, inverted
#define RADIOLIB_LR2021_GFSK_OOK_CRC16_INV (0x0AUL << 0) // 7 0 2-byte, inverted
#define RADIOLIB_LR2021_GFSK_OOK_CRC24_INV (0x0BUL << 0) // 7 0 3-byte, inverted
#define RADIOLIB_LR2021_GFSK_OOK_CRC32_INV (0x0CUL << 0) // 7 0 4-byte, inverted
// RADIOLIB_LR2021_CMD_SET_GFSK_WHITENING_PARAMS
#define RADIOLIB_LR2021_GFSK_WHITENING_TYPE_SX126X_LR11XX (0x00UL << 0) // 7 0 whitening type: compatible with SX126x and LR2021
#define RADIOLIB_LR2021_GFSK_WHITENING_TYPE_SX128X (0x01UL << 0) // 7 0 compatible with SX128x
// RADIOLIB_LR2021_CMD_SET_GFSK_SYNCWORD
#define RADIOLIB_LR2021_GFSK_SYNC_WORD_LEN (8)
// RADIOLIB_LR2021_CMD_SET_OQPSK_PARAMS
#define RADIOLIB_LR2021_OQPSK_TYPE_15_4 (0x00UL << 0) // 7 0 OQPSK type: 802.15.4 PHY, 250 kbps bit rate
// RADIOLIB_LR2021_CMD_SET_BPSK_PACKET_PARAMS
#define RADIOLIB_LR2021_BPSK_MODE_RAW (0x00UL << 0) // 7 0 encoding mode: raw
#define RADIOLIB_LR2021_BPSK_MODE_SIGFOX (0x01UL << 0) // 7 0 SigFox PHY
// RADIOLIB_LR2021_CMD_SET_FLRC_MODULATION_PARAMS
#define RADIOLIB_LR2021_FLRC_BR_2600 (0x00UL << 0) // 7 0 bitrate/bandwidth: 2600 kbps, 2666 kHz
#define RADIOLIB_LR2021_FLRC_BR_2080 (0x01UL << 0) // 7 0 2080 kbps, 2222 kHz
#define RADIOLIB_LR2021_FLRC_BR_1300 (0x02UL << 0) // 7 0 1300 kbps, 1333 kHz
#define RADIOLIB_LR2021_FLRC_BR_1040 (0x03UL << 0) // 7 0 1040 kbps, 1333 kHz
#define RADIOLIB_LR2021_FLRC_BR_650 (0x04UL << 0) // 7 0 650 kbps, 888 kHz
#define RADIOLIB_LR2021_FLRC_BR_520 (0x05UL << 0) // 7 0 520 kbps, 769 kHz
#define RADIOLIB_LR2021_FLRC_BR_325 (0x06UL << 0) // 7 0 325 kbps, 444 kHz
#define RADIOLIB_LR2021_FLRC_BR_260 (0x07UL << 0) // 7 0 260 kbps, 444 kHz
#define RADIOLIB_LR2021_FLRC_CR_1_2 (0x00UL << 0) // 7 0 coding rate: 1/2
#define RADIOLIB_LR2021_FLRC_CR_3_4 (0x01UL << 0) // 7 0 3/4
#define RADIOLIB_LR2021_FLRC_CR_1_0 (0x02UL << 0) // 7 0 1 (uncoded)
#define RADIOLIB_LR2021_FLRC_CR_2_3 (0x03UL << 0) // 7 0 2/3
// RADIOLIB_LR2021_CMD_SET_OOK_MODULATION_PARAMS
#define RADIOLIB_LR2021_OOK_DEPTH_FULL (0x00UL << 0) // 7 0 magnitude depth: limited by the PA
#define RADIOLIB_LR2021_OOK_DEPTH_20_DB (0x01UL << 0) // 7 0 20 dB maximum
// RADIOLIB_LR2021_CMD_SET_OOK_PACKET_PARAMS
#define RADIOLIB_LR2021_OOK_MANCHESTER_OFF (0x00UL << 0) // 3 0 Manchester encoding: disabled
#define RADIOLIB_LR2021_OOK_MANCHESTER_ON (0x01UL << 0) // 3 0 enabled
#define RADIOLIB_LR2021_OOK_MANCHESTER_ON_INV (0x09UL << 0) // 3 0 enabled, inverted
// RADIOLIB_LR2021_CMD_SET_TX_TEST_MODE
#define RADIOLIB_LR2021_TX_TEST_MODE_NORMAL_TX (0x00UL << 0) // 7 0 Tx test mode: normal
#define RADIOLIB_LR2021_TX_TEST_MODE_INF_PREAMBLE (0x01UL << 0) // 7 0 infinite preamble
#define RADIOLIB_LR2021_TX_TEST_MODE_CW (0x02UL << 0) // 7 0 continuous wave
#define RADIOLIB_LR2021_TX_TEST_MODE_PRBS9 (0x03UL << 0) // 7 0 pseudo-random bits
#endif
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,29 @@
#if !defined(RADIOLIB_LR2021_REGISTERS_H)
#define RADIOLIB_LR2021_REGISTERS_H
#include "../../TypeDef.h"
#if !RADIOLIB_EXCLUDE_LR2021
// LR2021 SPI registers
#define RADIOLIB_LR2021_REG_DCDC_FREQ_LF (0x80004C)
#define RADIOLIB_LR2021_REG_DCDC_SWITCHER (0xF20024)
#define RADIOLIB_LR2021_REG_RTTOF_RSSI_POWER_OFFSET (0xF30128)
#define RADIOLIB_LR2021_REG_RESULT_DEVIATION_CHANNEL_FILTER (0xF3013C)
#define RADIOLIB_LR2021_REG_RESULT_DEVIATION_DCC (0xF30134)
#define RADIOLIB_LR2021_REG_RTTOF_RSSI_MAX_GAIN (0xF301A4)
#define RADIOLIB_LR2021_REG_LORA_MODEM_TXRX_CFG0 (0xF30A14)
#define RADIOLIB_LR2021_REG_LORA_MODEM_MAIN_TX_CFG1 (0xF30A24)
#define RADIOLIB_LR2021_REG_LORA_EXT_FREQ_ERR_CTRL (0xF30A2C)
#define RADIOLIB_LR2021_REG_RTTOF_EXTENDED_STUCK (0xF30B50)
#define RADIOLIB_LR2021_REG_BLE_PHY_CODED_FREQ_DRIFT (0xF30C28)
#define RADIOLIB_LR2021_REG_OOK_DETECTION_THRESHOLD (0xF30E14)
#define RADIOLIB_LR2021_REG_RTTOF_RF_FREQ (0xF40144)
#define RADIOLIB_LR2021_REG_DCDC_ADC_CTRL (0xF40200)
#define RADIOLIB_LR2021_REG_OCP_CONTROL_UNLOCK (0xF40338)
#define RADIOLIB_LR2021_REG_OCP_THRESHOLDS (0xF40300)
#define RADIOLIB_LR2021_REG_DCDC_RX_PATH (0xF40430)
#endif
#endif

View file

@ -0,0 +1,42 @@
#if !defined(RADIOLIB_LR2021_TYPES_H)
#define RADIOLIB_LR2021_TYPES_H
#include "../../TypeDef.h"
#if !RADIOLIB_EXCLUDE_LR2021
/*!
\struct LR2021LrFhssHopTableEntry_t
\brief Structure to save information about LR-FHSS hopping table entry.
*/
struct LR2021LrFhssHopTableEntry_t {
bool hoppingEnable;
bool convertFreq;
uint16_t packetLen;
uint8_t numUsedFrequencies;
uint8_t numHoppingBlocks;
uint32_t freq;
uint16_t numSymbols;
};
/*!
\struct LR2021LoRaSideDetector_t
\brief Structure to configure multi-SF detection
*/
struct LR2021LoRaSideDetector_t {
/*! \brief Spreading factor value */
uint8_t sf;
/*! \brief Low datarate optimization enabled for this detector */
bool ldro;
/*! \brief IQ inversion for this detector */
bool invertIQ;
/*! \brief LoRa sync word for this detector */
uint8_t syncWord;
};
#endif
#endif