| /* |
| * Author: Jon Trulson <jtrulson@ics.com> |
| * Copyright (c) 2015 Intel Corporation. |
| * |
| * Thanks to Semtech for their example code at: |
| * https://github.com/Lora-net/LoRaMac-node |
| * released under a modified BSD license, for many clues as to how to |
| * initialize and operate this radio properly. |
| * See src/sx1276/LICENSE.txt |
| * |
| * Permission is hereby granted, free of charge, to any person obtaining |
| * a copy of this software and associated documentation files (the |
| * "Software"), to deal in the Software without restriction, including |
| * without limitation the rights to use, copy, modify, merge, publish, |
| * distribute, sublicense, and/or sell copies of the Software, and to |
| * permit persons to whom the Software is furnished to do so, subject to |
| * the following conditions: |
| * |
| * The above copyright notice and this permission notice shall be |
| * included in all copies or substantial portions of the Software. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
| * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
| * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
| * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE |
| * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION |
| * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |
| * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| */ |
| |
| #pragma once |
| |
| #include <string> |
| |
| #include <sys/time.h> |
| #include <sys/select.h> |
| #include <sys/types.h> |
| #include <sys/stat.h> |
| #include <pthread.h> |
| |
| #include <mraa/common.hpp> |
| #include <mraa/spi.hpp> |
| #include <mraa/gpio.hpp> |
| |
| // Our crystal oscillator frequency (32Mhz) |
| #define FXOSC_FREQ 32000000.0 |
| |
| // Our freq stepping resolution (in Hz) if FXOSC_FREQ is 32Mhz |
| // (FXOSC_FREQ / 2^19) = |
| #define FXOSC_STEP 61.03515625 |
| |
| namespace upm { |
| |
| /** |
| * @brief SX1276 LoRa/FSK modem |
| * @defgroup sx1276 libupm-sx1276 |
| * @ingroup spi gpio wifi |
| */ |
| |
| /** |
| * @library sx1276 |
| * @sensor sx1276 |
| * @comname SX1276 LoRa/FSK modem |
| * @altname SX1277 SX1278 SX1279 |
| * @type wifi |
| * @man semtech |
| * @con spi gpio |
| * @web http://www.digikey.com/product-search/en?vendor=0&keywords=SX1276MB1LAS |
| * |
| * @brief API for the SX1276 LoRa/FSK modem |
| * |
| * The SX1276 is a FSK/OOK/LoRa modem capable of both Low Frequency |
| * and High Frequency communication. |
| * |
| * It requires a 3.3v power supply, do not use 5v. |
| * |
| * Frequency Hopping Spread Spectrum (FHSS) is not currently supported. |
| * |
| * While not all of the functionality of this device is supported |
| * initially, methods and register definitions are provided that |
| * should allow an end user to implement whatever features are |
| * required. |
| * |
| * FSK send/receive example |
| * @snippet sx1276-fsk.cxx Interesting |
| * LORA send/receive example |
| * @snippet sx1276-lora.cxx Interesting |
| */ |
| |
| class SX1276 { |
| public: |
| |
| // The default chip revision |
| static const uint8_t chipRevision = 0x12; |
| |
| |
| // total FIFO size |
| static const int FIFO_SIZE = 256; |
| |
| // differentiator between high and low bands |
| static const int RF_MID_BAND_THRESH = 525000000; |
| |
| // LoRa RSSI offsets depending on LF or HF bands |
| static const int LOR_RSSI_OFFSET_HF = -157; |
| static const int LOR_RSSI_OFFSET_LF = -164; |
| |
| /** |
| * What modem we are configured for |
| */ |
| typedef enum { |
| MODEM_LORA = 0, |
| MODEM_FSK |
| } RADIO_MODEM_T; |
| |
| /** |
| * Events that can occurr during a TX or RX operation. |
| * |
| * When sending or receiving a packet (calling setTx()/send() or |
| * setRx()), the state will be initialized to ESTATE_EXEC to |
| * indicate the operation is in progress. Once an event has |
| * occurred, this state will be updated accordingly. |
| * |
| * For receiving, if RX_DONE is set, then it is safe to retrieve |
| * the rx buffer (via getRxBuffer()/getRxBufferStr()) as well as |
| * query the RSSI and SNR. On RX_ERROR, these values will be the |
| * same as they were last set during the last RX_DONE event. |
| */ |
| typedef enum { |
| REVENT_DONE = 0, // operation completed successfully |
| REVENT_EXEC, // runninsg something |
| REVENT_ERROR, // failed, crc error, sync timeout |
| REVENT_TIMEOUT // timed out |
| } RADIO_EVENT_T; |
| |
| /** |
| * SX1276 registers |
| * |
| * NOTE: reserved registers must not be written into or read from. |
| * Reserved bitfields must always be 0. |
| * |
| * This device has a set of "common" registers, as well as |
| * registers that represent different things depending on whether |
| * the device in in LoRa mode or FSK/OOK mode. So here, we will |
| * prefix the register names with COM (common), LOR (LoRa mode), |
| * and FSK (FSK/OOK mode) accordingly. |
| */ |
| typedef enum { |
| COM_RegFifo = 0x00, // FIFO r/w access |
| COM_RegOpMode = 0x01, // LoRa/FSK |
| |
| FSK_RegBitrateMsb = 0x02, |
| LOR_Reserved02 = 0x02, // reserved |
| |
| FSK_RegBitrateLsb = 0x03, |
| LOR_Reserved03 = 0x03, // reserved |
| |
| FSK_RegFdevMsb = 0x04, // freq deviation |
| LOR_Reserved04 = 0x04, // reserved |
| |
| FSK_RegFdevLsb = 0x05, |
| LOR_Reserved05 = 0x05, // reserved |
| |
| COM_RegFrfMsb = 0x06, // carrier freq |
| COM_RegFrfMid = 0x07, |
| COM_RegFrfLsb = 0x08, |
| COM_RegPaConfig = 0x09, |
| COM_RegPaRamp = 0x0a, |
| |
| COM_RegOcp = 0x0b, // overcurrent protection |
| COM_RegLna = 0x0c, |
| |
| FSK_RegRxConfig = 0x0d, |
| LOR_RegFifoAddrPtr = 0x0d, |
| |
| FSK_RegRssiConfg = 0x0e, |
| LOR_RegFifoTxBaseAddr = 0x0e, |
| |
| FSK_RegRssiCollision = 0x0f, |
| LOR_RegFifoRxBaseAddr = 0x0f, |
| |
| FSK_RegRssiThresh = 0x10, |
| LOR_RegFifoRxCurrentAddr = 0x10, |
| |
| FSK_RegRssiValue = 0x11, |
| LOR_RegIrqFlagsMask = 0x11, |
| |
| FSK_RegRxBw = 0x12, |
| LOR_RegIrqFlags = 0x12, |
| |
| FSK_RegAfcBw = 0x13, // automatic freq cntrl |
| LOR_RegRxNbBytes = 0x13, // received pkt len |
| |
| FSK_RegOokPeak = 0x14, |
| LOR_RegRxHeaderCntValueMsb = 0x14, |
| |
| FSK_RegOokFix = 0x15, |
| LOR_RegRxHeaderCntValueLsb = 0x15, |
| |
| FSK_RegOokAvg = 0x16, |
| LOR_RegRxPacketCntValueMsb = 0x16, |
| |
| FSK_Reserved17 = 0x17, // reserved |
| LOR_RegRxPacketCntValueLsb = 0x17, |
| |
| FSK_Reserved18 = 0x18, // reserved |
| LOR_RegModemStat = 0x18, |
| |
| FSK_Reserved19 = 0x19, // reserved |
| LOR_RegPktSnrValue = 0x19, |
| |
| FSK_RegAfcFei = 0x1a, |
| LOR_RegPktRssiValue = 0x1a, |
| |
| FSK_RegAfcMsb = 0x1b, |
| LOR_RegRssiValue = 0x1b, |
| |
| FSK_RegAfcLsb = 0x1c, |
| LOR_RegHopChannel = 0x1c, // fhss starting channel |
| |
| FSK_RegFeiMsb = 0x1d, |
| LOR_RegModemConfig1 = 0x1d, |
| |
| FSK_RegFeiLsb = 0x1e, |
| LOR_RegModemConfig2 = 0x1e, |
| |
| FSK_RegPreambleDetect = 0x1f, |
| LOR_RegSymbTimeoutLsb = 0x1f, |
| |
| FSK_RegRxTimeout1 = 0x20, |
| LOR_RegPreambleMsb = 0x20, |
| |
| FSK_RegRxTimeout2 = 0x21, |
| LOR_RegPreambleLsb = 0x21, |
| |
| FSK_RegRxTimeout3 = 0x22, |
| LOR_RegPayloadLength = 0x22, |
| |
| FSK_RegRxDelay = 0x23, |
| LOR_RegMaxPayloadLength = 0x23, |
| |
| FSK_RegOsc = 0x24, |
| LOR_RegHopPeriod = 0x24, |
| |
| FSK_RegPreambleMsb = 0x25, |
| LOR_RegFifoRxByteAddr = 0x25, |
| |
| FSK_RegPreambleLsb = 0x26, |
| LOR_RegModemConfig3 = 0x26, |
| |
| FSK_RegSyncConfig = 0x27, |
| LOR_Reserved27 = 0x27, // reserved |
| |
| FSK_RegSyncValue1 = 0x28, |
| LOR_RegFeiMsb = 0x28, |
| |
| FSK_RegSyncValue2 = 0x29, |
| LOR_RegFeiMid = 0x29, |
| |
| FSK_RegSyncValue3 = 0x2a, |
| LOR_RegFeiLsb = 0x2a, |
| |
| FSK_RegSyncValue4 = 0x2b, |
| LOR_Reserved2b = 0x2b, // reserved |
| |
| FSK_RegSyncValue5 = 0x2c, |
| LOR_RegRssiWideband = 0x2c, |
| |
| FSK_RegSyncValue6 = 0x2d, |
| LOR_Reserved2d = 0x2d, // reserved |
| |
| FSK_RegSyncValue7 = 0x2e, |
| LOR_Reserved2e = 0x2e, // reserved |
| |
| FSK_RegSyncValue8 = 0x2f, |
| LOR_Reserved2f = 0x2f, // reserved |
| |
| FSK_RegPacketConfig1 = 0x30, |
| LOR_Reserved30 = 0x30, // reserved |
| |
| FSK_RegPacketConfig2 = 0x31, |
| LOR_RegDetectOptimize = 0x31, |
| |
| FSK_RegPayloadLength = 0x32, |
| LOR_Reserved32 = 0x32, // reserved |
| |
| FSK_RegNodeAddr = 0x33, |
| LOR_RegInvertIQ = 0x33, |
| |
| FSK_RegBroadcastAddr = 0x34, |
| LOR_Reserved34 = 0x34, // reserved |
| |
| FSK_RegFifoThresh = 0x35, |
| LOR_Reserved35 = 0x35, // reserved |
| |
| FSK_RegSeqConfig1 = 0x36, |
| LOR_Reserved36 = 0x36, // reserved |
| |
| FSK_RegSeqConfig2 = 0x37, |
| LOR_RegDetectionThreshold = 0x37, |
| |
| FSK_RegTimerResol = 0x38, |
| LOR_Reserved38 = 0x38, // reserved |
| |
| FSK_RegTimer1Coeff = 0x39, |
| LOR_RegSyncWord = 0x39, |
| |
| FSK_RegTimer2Coeff = 0x3a, |
| LOR_Reserved3a = 0x3a, // reserved |
| |
| FSK_RegImageCal = 0x3b, |
| LOR_Reserved3b = 0x3b, // reserved (in datasheet)? |
| LOR_RegInvertIQ2 = 0x3b, // does not exist in datasheet |
| // but used in Semtech code. |
| // UNDOCUMENTED |
| |
| FSK_RegTemp = 0x3c, |
| LOR_Reserved3c = 0x3c, // reserved |
| |
| FSK_RegLowBat = 0x3d, |
| LOR_Reserved3d = 0x3d, // reserved |
| |
| FSK_RegIrqFlags1 = 0x3e, |
| LOR_Reserved3e = 0x3e, // reserved |
| |
| FSK_RegIrqFlags2 = 0x3f, |
| LOR_Reserved3f = 0x3f, // reserved |
| |
| COM_RegDioMapping1 = 0x40, // DIO0-DIO3 |
| COM_RegDioMapping2 = 0x41, // DIO4-DIO5, clk out freq |
| |
| COM_RegVersion = 0x42, // Semtech ID (silicon revision) |
| |
| // 0x43 reserved |
| |
| // The data sheet says this is FSK only, but the semtech code |
| // implies this is only valid for LoRa. So for now, assume the |
| // datasheet is wrong. |
| // |
| // FSK_RegPllHop = 0x44, |
| // LOR_Reserved44 = 0x44, // reserved |
| |
| FSK_Reserved44 = 0x44, |
| LOR_RegPllHop = 0x44, |
| |
| // 0x45-0x4a reserved |
| |
| COM_RegTcxo = 0x4b, |
| |
| // 0x4c reserved |
| |
| COM_RegPaDac = 0x4d, |
| |
| // 0x4e-0x5a reserved |
| |
| COM_RegFormerTemp = 0x5b, |
| |
| // 0x5c reserved |
| |
| FSK_RegBitRateFrac = 0x5d, |
| LOR_Reserved5d = 0x5d, // reserved |
| |
| // 0x5e-0x60 reserved |
| |
| COM_RegAgcRef = 0x61, |
| COM_RegAgcThresh1 = 0x62, |
| COM_RegAgcThresh2 = 0x63, |
| COM_RegAgcThresh3 = 0x64, |
| |
| // 0x65-0x6f reserved |
| |
| COM_RegPll = 0x70 |
| |
| // 0x71-0xff reserved |
| } SX1276_REGS_T; |
| |
| /** |
| * OpMode register (differing bitfields depending on mode) |
| */ |
| typedef enum { |
| OPMODE_Mode0 = 0x01, // operating modes (sleep, etc) |
| OPMODE_Mode1 = 0x02, |
| OPMODE_Mode2 = 0x04, |
| _OPMODE_Mode_MASK = 7, |
| _OPMODE_Mode_SHIFT = 0, |
| |
| OPMODE_LowFrequencyModeOn = 0x08, |
| |
| // 0x10 reserved |
| |
| OPMODE_FSK_ModulationType0 = 0x20, |
| OPMODE_FSK_ModulationType1 = 0x40, |
| _OPMODE_FSK_ModulationType_MASK = 3, |
| _OPMODE_FSK_ModulationType_SHIFT = 5, |
| |
| OPMODE_LOR_Reserved0x20 = 0x20, |
| |
| OPMODE_LOR_AccessSharedReg = 0x40, // tmp sw to FSK regs |
| |
| OPMODE_LongRangeMode = 0x80 // LoRa mode enable(1), else FSK |
| } OPMODE_BITS_T; |
| |
| |
| /** |
| * Mode values |
| */ |
| typedef enum { |
| MODE_Sleep = 0, |
| MODE_Standby = 1, |
| MODE_FSTX = 2, // freq synth |
| MODE_TxMode = 3, |
| MODE_FSRX = 4, // freq synth |
| |
| MODE_FSK_RxMode = 5, |
| MODE_LOR_RxContinuous = 5, // continuous rx mode |
| |
| MODE_FSK_Reserved6 = 6, |
| MODE_LOR_RxSingle = 6, // single packet rx mode |
| |
| MODE_FSK_Reserved7 = 7, |
| MODE_LOR_CAD = 7 // channel activity detection |
| } MODE_T; |
| |
| /** |
| * FSK_ModulationType values |
| */ |
| typedef enum { |
| MODULATION_FSK = 0, // freq shift keying |
| MODULATION_OOK = 1, // on/off keying |
| // 2-3 reserved |
| } FSK_MODULATION_TYPE_T; |
| |
| /** |
| * RegPaConfig register |
| */ |
| typedef enum { |
| PACONFIG_OutputPower0 = 0x01, |
| PACONFIG_OutputPower1 = 0x02, |
| PACONFIG_OutputPower2 = 0x04, |
| PACONFIG_OutputPower3 = 0x08, |
| _PACONFIG_OutputPower_MASK = 15, |
| _PACONFIG_OutputPower_SHIFT = 0, |
| |
| PACONFIG_MaxPower0 = 0x10, |
| PACONFIG_MaxPower1 = 0x20, |
| PACONFIG_MaxPower2 = 0x40, |
| _PACONFIG_MaxPower_MASK = 7, |
| _PACONFIG_MaxPower_SHIFT = 4, |
| |
| PACONFIG_PaSelect = 0x80 // PA output pin, |
| // 0 = 14dBm, 1 = 20dBm |
| } PACONFIG_BITS_T; |
| |
| /** |
| * RegPaRamp register |
| */ |
| typedef enum { |
| PARAMP_PaRamp0 = 0x01, // rise/fall of ramp up/down |
| PARAMP_PaRamp1 = 0x02, |
| PARAMP_PaRamp2 = 0x04, |
| PARAMP_PaRamp3 = 0x08, |
| _PARAMP_PaRamp_MASK = 15, |
| _PARAMP_PaRamp_SHIFT = 0, |
| |
| // 0x10 reserved |
| |
| // LORA 0x20-0x40 reserved |
| |
| PARAMP_FSK_ModulationShaping0 = 0x20, |
| PARAMP_FSK_ModulationShaping1 = 0x40, |
| _PARAMP_FSK_ModulationShaping_MASK = 3, |
| _PARAMP_FSK_ModulationShaping_SHIFT = 5 |
| |
| // 0x80 reserved |
| } PARAMP_BITS_T; |
| |
| /** |
| * PARAMP_PaRamp values |
| */ |
| typedef enum { |
| PARAMP_3_4MS = 0, // 3.4ms |
| PARAMP_2MS = 1, |
| PARAMP_1MS = 2, |
| PARAMP_500US = 3, // 500us |
| PARAMP_250US = 4, |
| PARAMP_125US = 5, |
| PARAMP_100US = 6, |
| PARAMP_62US = 7, |
| PARAMP_50US = 8, |
| PARAMP_40US = 9, |
| PARAMP_31US = 10, |
| PARAMP_25US = 11, |
| PARAMP_20US = 12, |
| PARAMP_15US = 13, |
| PARAMP_12US = 14, |
| PARAMP_10US = 15 |
| } PARAMP_T; |
| |
| /** |
| * PARAMP_ModulationShaping values. Note, these mean different |
| * things depending on whether you are using FSK or OOK. Hence |
| * the FSK/OOK dups. We will also name these as 'MODSHAPING_', rather |
| * than the lengthy 'MODULATIONSHAPING... ' |
| */ |
| typedef enum { |
| MODSHAPING_NOSHAPING = 0, |
| |
| // FSK |
| MODSHAPING_FSK_GaussianFilterBT1 = 1, // BT = 1.0 |
| MODSHAPING_FSK_GaussianFilterBT05 = 2, // BT = 0.5 |
| MODSHAPING_FSK_GaussianFilterBT03 = 3, // BT = 0.3 |
| |
| // OOK |
| MODSHAPING_OOK_FCutoffBitRate = 1, // Fcutoff = BitRate |
| MODSHAPING_OOK_FCutoffBitRate2 = 2 // Fcutoff = 2*BitRate |
| |
| // for OOK, 3 is reserved |
| } MODSHAPING_T; |
| |
| /** |
| * RegOcp register (see datasheet for OcpTrim values) |
| */ |
| typedef enum { |
| OCP_OcpTrim0 = 0x01, |
| OCP_OcpTrim1 = 0x02, |
| OCP_OcpTrim2 = 0x04, |
| OCP_OcpTrim3 = 0x08, |
| _OCP_OcpTrim_MASK = 15, |
| _OCP_OcpTrim_SHIFT = 0, |
| |
| OCP_OcpOn = 0x10 |
| |
| // 0x20-0x80 reserved |
| } OCP_BITS_T; |
| |
| /** |
| * Lna register |
| */ |
| typedef enum { |
| LNA_LnaBoostHf0 = 0x01, |
| LNA_LnaBoostHf1 = 0x02, |
| _LNA_LnaBoostHf_MASK = 3, |
| _LNA_LnaBoostHf_SHIFT = 0, |
| |
| // 0x04 reserved |
| |
| LNA_LnaBoostLf0 = 0x08, |
| LNA_LnaBoostLf1 = 0x10, |
| _LNA_LnaBoostLf_MASK = 3, |
| _LNA_LnaBoostLf_SHIFT = 3, |
| |
| LNA_LnaGain0 = 0x20, |
| LNA_LnaGain1 = 0x40, |
| LNA_LnaGain2 = 0x80, |
| _LNA_LnaGain_MASK = 7, |
| _LNA_LnaGain_SHIFT = 5 |
| } LNA_BITS_T; |
| |
| /** |
| * LnaBoostHf values |
| */ |
| typedef enum { |
| LNABOOSTHF_Default = 0, |
| // 1-2 reserved |
| LNABOOSTHF_BoostOn = 3, // 150% LNA current |
| } LNABOOSTHF_T; |
| |
| /** |
| * LnaBoostLf values |
| */ |
| typedef enum { |
| LNABOOSTLF_Default = 0 |
| // 1-3 reserved |
| } LNABOOSTLF_T; |
| |
| /** |
| * LnaGain values |
| */ |
| typedef enum { |
| // 0 reserved |
| LNAGAIN_G1 = 1, // max gain |
| LNAGAIN_G2 = 2, |
| LNAGAIN_G3 = 3, |
| LNAGAIN_G4 = 4, |
| LNAGAIN_G5 = 5, |
| LNAGAIN_G6 = 6 // minimum gain |
| // 7 reserved |
| } LNAGAIN_T; |
| |
| /** |
| * FSK_RxConfig register. See Table 24 in the data sheet for |
| * the meanings of the RxTrigger values. |
| */ |
| typedef enum { |
| RXCONFIG_RxTrigger0 = 0x01, |
| RXCONFIG_RxTrigger1 = 0x02, |
| RXCONFIG_RxTrigger2 = 0x04, |
| _RXCONFIG_RxTrigger_MASK = 7, |
| _RXCONFIG_RxTrigger_SHIFT = 0, |
| |
| RXCONFIG_AgcAutoOn = 0x08, |
| RXCONFIG_AfcAutoOn = 0x10, |
| RXCONFIG_RestartRxWithPllLock = 0x20, |
| RXCONFIG_RestartRxWithoutPllLock = 0x40, |
| RXCONFIG_RestartRxOnCollision = 0x80 |
| } RXCONFIG_BITS_T; |
| |
| /** |
| * FSK_RssiConfig register |
| */ |
| typedef enum { |
| RSSICONFIG_RssiSmoothing0 = 0x01, // RSSI sampling/averaging |
| RSSICONFIG_RssiSmoothing1 = 0x02, |
| RSSICONFIG_RssiSmoothing2 = 0x04, |
| _RSSICONFIG_RssiSmoothing_MASK = 7, |
| _RSSICONFIG_RssiSmoothing_SHIFT = 0, |
| |
| RSSICONFIG_RssiOffset0 = 0x08, // 2's complement offset |
| RSSICONFIG_RssiOffset1 = 0x10, |
| RSSICONFIG_RssiOffset2 = 0x20, |
| RSSICONFIG_RssiOffset3 = 0x40, |
| RSSICONFIG_RssiOffset4 = 0x80, |
| _RSSICONFIG_RssiOffset_MASK = 31, |
| _RSSICONFIG_RssiOffset_SHIFT = 3 |
| } RSSICONFIG_BITS_T; |
| |
| /** |
| * RssiSmoothing values |
| */ |
| typedef enum { |
| RSSISMOOTHING_2 = 0, // 2 samples used |
| RSSISMOOTHING_4 = 1, |
| RSSISMOOTHING_8 = 2, |
| RSSISMOOTHING_16 = 3, |
| RSSISMOOTHING_32 = 4, |
| RSSISMOOTHING_64 = 5, |
| RSSISMOOTHING_128 = 6, |
| RSSISMOOTHING_256 = 7 |
| } RSSISMOOTHING_T; |
| |
| /** |
| * LOR_RegIrqFlagsMask and LOR_RegIrqFlags registers |
| */ |
| typedef enum { |
| LOR_IRQFLAG_CadDetected = 0x01, |
| LOR_IRQFLAG_FhssChangeChannel = 0x02, |
| LOR_IRQFLAG_CadDone = 0x04, |
| LOR_IRQFLAG_TxDone = 0x08, |
| |
| LOR_IRQFLAG_ValidHeader = 0x10, |
| LOR_IRQFLAG_PayloadCrcError = 0x20, |
| LOR_IRQFLAG_RxDone = 0x40, |
| LOR_IRQFLAG_RxTimeout = 0x80 |
| } LOR_IRQFLAG_BITS_T; |
| |
| /** |
| * FSK_RxBw register and FSK_RegAfcBw registers |
| */ |
| typedef enum { |
| RXBW_RxBwExp0 = 0x01, |
| RXBW_RxBwExp1 = 0x02, |
| RXBW_RxBwExp2 = 0x04, |
| _RXBW_RxBwExp_MASK = 7, |
| _RXBW_RxBwExp_SHIFT = 0, |
| |
| RXBW_RxBwMant0 = 0x08, |
| RXBW_RxBwMant1 = 0x10, |
| _RXBW_RxBwMant_MASK = 3, |
| _RXBW_RxBwMant_SHIFT = 3, |
| // 0x20-0x80 reserved |
| } RXBW_BITS_T; |
| |
| /** |
| * RXBW_RxBwMant values |
| */ |
| typedef enum { |
| RXBWMANT_0 = 0, |
| RXBWMANT_1 = 1, |
| RXBWMANT_2 = 2 |
| // 3 reserved |
| } RXBWMANT_T; |
| |
| /** |
| * RXBW_RxBwExp values |
| */ |
| typedef enum { |
| RXBWEXP_1 = 1, |
| RXBWEXP_2 = 2, |
| RXBWEXP_3 = 3, |
| RXBWEXP_4 = 4, |
| RXBWEXP_5 = 5, |
| RXBWEXP_6 = 6, |
| RXBWEXP_7 = 7 |
| // other values reserved |
| } RXBWEXP_T; |
| |
| /** |
| * FSK_OokPeak register |
| */ |
| typedef enum { |
| OOKPEAK_OokPeakThreshStep0 = 0x01, |
| OOKPEAK_OokPeakThreshStep1 = 0x02, |
| OOKPEAK_OokPeakThreshStep2 = 0x04, |
| _OOKPEAK_OokPeakThreshStep_MASK = 7, |
| _OOKPEAK_OokPeakThreshStep_SHIFT = 0, |
| |
| OOKPEAK_OokThreshType0 = 0x08, |
| OOKPEAK_OokThreshType1 = 0x10, |
| _OOKPEAK_OokThreshType_MASK = 3, |
| _OOKPEAK_OokThreshType_SHIFT = 3, |
| |
| OOKPEAK_BitSyncOn = 0x20, |
| |
| // 0x40-0x80 reserved |
| } OOKPEAK_BITS_T; |
| |
| /** |
| * OokPeakThreshStep values |
| */ |
| typedef enum { |
| OOKPEAKTHRESHSTEP_05dB = 0, // dec of RSSI threshold 0.5dB |
| OOKPEAKTHRESHSTEP_1dB = 1, // 1 dB |
| OOKPEAKTHRESHSTEP_15dB = 2, // 1.5 dB |
| OOKPEAKTHRESHSTEP_2dB = 3, // 2 dB |
| OOKPEAKTHRESHSTEP_3dB = 4, |
| OOKPEAKTHRESHSTEP_4dB = 5, |
| OOKPEAKTHRESHSTEP_5dB = 6, |
| OOKPEAKTHRESHSTEP_6dB = 7 |
| } OOKPEAKTHRESHSTEP_T; |
| |
| /** |
| * OokPeakThreshType values |
| */ |
| typedef enum { |
| OOKTHRESHTYPE_FIXED = 0, |
| OOKTHRESHTYPE_PEAK = 1, |
| OOKTHRESHTYPE_AVERAGE = 2 |
| // 3 reserved |
| } OOKTHRESHTYPE_T; |
| |
| /** |
| * FSK_OokAvg register |
| */ |
| typedef enum { |
| OOKAVG_OokAvgThreshFilt0 = 0x01, |
| OOKAVG_OokAvgThreshFilt1 = 0x02, |
| _OOKAVG_OokAvgThreshFilt_MASK = 3, |
| _OOKAVG_OokAvgThreshFilt_SHIFT = 0, |
| |
| OOKAVG_OokAvgOffset0 = 0x04, |
| OOKAVG_OokAvgOffset1 = 0x08, |
| _OOKAVG_OokAvgOffset_MASK = 3, |
| _OOKAVG_OokAvgOffset_SHIFT = 2, |
| |
| // 0x10 reserved |
| |
| OOKAVG_OokPeakThreshDec0 = 0x20, |
| OOKAVG_OokPeakThreshDec1 = 0x40, |
| OOKAVG_OokPeakThreshDec2 = 0x80, |
| _OOKAVG_OokPeakThreshDec_MASK = 7, |
| _OOKAVG_OokPeakThreshDec_SHIFT = 5 |
| } OOKAVG_BITS_T; |
| |
| /** |
| * OokAvgThreshFilt values |
| */ |
| typedef enum { |
| OOKAVGTHRESHFILT_32 = 0, // filter coedd in avg mode |
| OOKAVGTHRESHFILT_8 = 1, |
| OOKAVGTHRESHFILT_4 = 2, |
| OOKAVGTHRESHFILT_2 = 3 |
| } OOKAVGTHRESHFILT_T; |
| |
| /** |
| * OokAvgOffset values |
| */ |
| typedef enum { |
| OOKAVGOFFSET_0 = 0, // 0.0dB |
| OOKAVGOFFSET_2 = 1, |
| OOKAVGOFFSET_4 = 2, |
| OOKAVGOFFSET_6 = 3 |
| } OOKAVGOFFSET_T; |
| |
| /** |
| * OokPeakThreshDec values |
| */ |
| typedef enum { |
| OOKPEAKTHRESHDEC_1_1 = 0, // once per chip |
| OOKPEAKTHRESHDEC_1_2 = 1, // once every 2 chips... |
| OOKPEAKTHRESHDEC_1_4 = 2, |
| OOKPEAKTHRESHDEC_1_8 = 3, |
| OOKPEAKTHRESHDEC_2_1 = 4, // twice per chip |
| OOKPEAKTHRESHDEC_4_1 = 5, // 4 times every chip... |
| OOKPEAKTHRESHDEC_8_1 = 6, |
| OOKPEAKTHRESHDEC_16_1 = 7 |
| } OOKPEAKTHRESHDEC_T; |
| |
| /** |
| * LOR_ModemStat register |
| */ |
| typedef enum { |
| MODEMSTAT_SignalDetected = 0x01, |
| MODEMSTAT_SignalSynchronized = 0x02, |
| MODEMSTAT_RxOngoing = 0x04, |
| MODEMSTAT_HeaderInfoValid = 0x08, |
| MODEMSTAT_ModemClear = 0x10, |
| |
| MODEMSTAT_RxCodingRate0 = 0x20, |
| MODEMSTAT_RxCodingRate1 = 0x40, |
| MODEMSTAT_RxCodingRate2 = 0x80, |
| _MODEMSTAT_RxCodingRate_MASK = 7, |
| _MODEMSTAT_RxCodingRate_SHIFT = 5 |
| } MODEMSTAT_BITS_T; |
| |
| /** |
| * FSK_RegAfcFei register |
| */ |
| typedef enum { |
| AFCFEI_AfcAutoClearOn = 0x01, |
| AFCFEI_AfcClear = 0x02, |
| |
| // 0x04-0x08 reserved |
| |
| AFCFEI_AgcStart = 0x10 |
| |
| // 0x20-0x80 reserved |
| } AFCFEI_BITS_T; |
| |
| /** |
| * LOR_HopChannel register |
| */ |
| typedef enum { |
| HOPCHANNEL_FhssPresentChannel0 = 0x01, // current freq hopping channel |
| HOPCHANNEL_FhssPresentChannel1 = 0x02, |
| HOPCHANNEL_FhssPresentChannel2 = 0x04, |
| HOPCHANNEL_FhssPresentChannel3 = 0x08, |
| HOPCHANNEL_FhssPresentChannel4 = 0x10, |
| HOPCHANNEL_FhssPresentChannel5 = 0x20, |
| _HOPCHANNEL_FhssPresentChannel_MASK = 63, |
| _HOPCHANNEL_FhssPresentChannel_SHIFT = 0, |
| |
| HOPCHANNEL_CrcOnPayload = 0x40, |
| HOPCHANNEL_PllTimeout = 0x80 |
| } HOPCHANNEL_BITS_T; |
| |
| /** |
| * LOR_ModemConfig1 register |
| */ |
| typedef enum { |
| MODEMCONFIG1_ImplicitHeaderModeOn = 0x01, |
| |
| MODEMCONFIG1_CodingRate0 = 0x02, |
| MODEMCONFIG1_CodingRate1 = 0x04, |
| MODEMCONFIG1_CodingRate2 = 0x08, |
| _MODEMCONFIG1_CodingRate_MASK = 7, |
| _MODEMCONFIG1_CodingRate_SHIFT = 0, |
| |
| MODEMCONFIG1_Bw0 = 0x10, |
| MODEMCONFIG1_Bw1 = 0x20, |
| MODEMCONFIG1_Bw2 = 0x40, |
| MODEMCONFIG1_Bw3 = 0x80, |
| _MODEMCONFIG1_Bw_MASK = 15, |
| _MODEMCONFIG1_Bw_SHIFT = 4 |
| } MODEMCONFIG1_BITS_T; |
| |
| /** |
| * CodingRate values |
| */ |
| typedef enum { |
| CODINGRATE_4_5 = 1, // Error coding rate 4/5 |
| CODINGRATE_4_6 = 2, |
| CODINGRATE_4_7 = 3, |
| CODINGRATE_4_8 = 4 |
| } CODINGRATE_T; |
| |
| /** |
| * Bw values |
| */ |
| typedef enum { |
| BW_7_8 = 0, // 7.8Khz |
| BW_10_4 = 1, |
| BW_15_6 = 2, |
| BW_20_8 = 3, |
| BW_31_25 = 4, |
| BW_41_7 = 5, |
| BW_62_5 = 6, |
| BW_125 = 7, |
| BW_250 = 8, |
| BW_500 = 9 |
| |
| // BW250 and BW500 not supported in lower band (169Mhz) |
| } BW_T; |
| |
| /** |
| * LOR_ModemConfig2 register |
| */ |
| typedef enum { |
| MODEMCONFIG2_SymbTimeoutMsb0 = 0x01, |
| MODEMCONFIG2_SymbTimeoutMsb1 = 0x02, |
| _MODEMCONFIG2_SymbTimeoutMsb_MASK = 3, |
| _MODEMCONFIG2_SymbTimeoutMsb_SHIFT = 0, |
| |
| MODEMCONFIG2_RxPayloadCrcOn = 0x04, |
| |
| MODEMCONFIG2_TxContinuousMode = 0x08, |
| |
| MODEMCONFIG2_SpreadingFactor0 = 0x10, |
| MODEMCONFIG2_SpreadingFactor1 = 0x20, |
| MODEMCONFIG2_SpreadingFactor2 = 0x40, |
| MODEMCONFIG2_SpreadingFactor3 = 0x80, |
| _MODEMCONFIG2_SpreadingFactor_MASK = 15, |
| _MODEMCONFIG2_SpreadingFactor_SHIFT = 4, |
| } MODEMCONFIG2_BITS_T; |
| |
| /** |
| * SpreadingFactor values (expressed as a base-2 logarithm) |
| */ |
| typedef enum { |
| SPREADINGFACTOR_64 = 6, // 64 chips/symbol |
| SPREADINGFACTOR_128 = 7, |
| SPREADINGFACTOR_256 = 8, |
| SPREADINGFACTOR_512 = 9, |
| SPREADINGFACTOR_1024 = 10, |
| SPREADINGFACTOR_2048 = 11, |
| SPREADINGFACTOR_4096 = 12 |
| |
| // other values reserved |
| } SPREADINGFACTOR_T; |
| |
| /** |
| * FSK_PreableDetect register |
| */ |
| typedef enum { |
| PREABLEDETECT_PreambleDetectorTol0 = 0x01, |
| PREABLEDETECT_PreambleDetectorTol1 = 0x02, |
| PREABLEDETECT_PreambleDetectorTol2 = 0x04, |
| PREABLEDETECT_PreambleDetectorTol3 = 0x08, |
| PREABLEDETECT_PreambleDetectorTol4 = 0x10, |
| _PREABLEDETECT_PreambleDetectorTol4_MASK = 31, |
| _PREABLEDETECT_PreambleDetectorTol4_SHIFT = 0, |
| |
| PREABLEDETECT_PreambleDetectorSize0 = 0x20, |
| PREABLEDETECT_PreambleDetectorSize1 = 0x40, |
| _PREABLEDETECT_PreambleDetectorSize_MASK = 3, |
| _PREABLEDETECT_PreambleDetectorSize_SHIFT = 5, |
| |
| PREABLEDETECT_PreambleDetectorOn = 0x80 |
| } PREAMBLEDETECT_BITS_T; |
| |
| /** |
| * PreambleDetectorSize values |
| */ |
| typedef enum { |
| PREAMBLEDETECTORSIZE_1 = 0, // 1 byte |
| PREAMBLEDETECTORSIZE_2 = 1, |
| PREAMBLEDETECTORSIZE_3 = 2 |
| |
| // other values reserved |
| } PREAMBLEDETECTORSIZE_T; |
| |
| /** |
| * FSK_Osc register |
| */ |
| typedef enum { |
| OSC_ClkOut0 = 0x01, // clk output freq |
| OSC_ClkOut1 = 0x02, |
| OSC_ClkOut2 = 0x04, |
| _OSC_ClkOut_MASK = 7, |
| _OSC_ClkOut_SHIFT = 0, |
| |
| OSC_RcCalStart = 0x08 |
| |
| // other bits reserved |
| } OSC_BITS_T; |
| |
| /** |
| * ClkOut values |
| */ |
| typedef enum { |
| CLKOUT_1 = 0, // FXOSC |
| CLKOUT_2 = 1, // FXOSC / 2 ... |
| CLKOUT_4 = 2, |
| CLKOUT_8 = 3, |
| CLKOUT_16 = 4, |
| CLKOUT_32 = 5, |
| CLKOUT_RC = 6, // RC, (automatically enabled) |
| CLKOUT_OFF = 7 // clkout off |
| } CLKOUT_T; |
| |
| /** |
| * LOR_ModemConfig3 register |
| */ |
| typedef enum { |
| // 0x01-0x02 reserved |
| |
| MODEMCONFIG3_AgcAutoOn = 0x04, |
| MODEMCONFIG3_LowDataRateOptimize = 0x08 // req. for SF11 and SF12 and |
| // BW125 |
| |
| // 0x10-0x80 reserved |
| } MODEMCONFIG3_BITS_T; |
| |
| /** |
| * FSK_SyncConfig register |
| */ |
| typedef enum { |
| SYNCCONFIG_SyncSize0 = 0x01, |
| SYNCCONFIG_SyncSize1 = 0x02, |
| SYNCCONFIG_SyncSize2 = 0x04, |
| _SYNCCONFIG_SyncSize_MASK = 7, |
| _SYNCCONFIG_SyncSize_SHIFT = 0, |
| |
| // 0x08 reserved |
| |
| SYNCCONFIG_SyncOn = 0x10, |
| SYNCCONFIG_PreamblePolarity = 0x20, |
| |
| SYNCCONFIG_AutoRestartMode0 = 0x40, |
| SYNCCONFIG_AutoRestartMode1 = 0x80, |
| _SYNCCONFIG_AutoRestartMode_MASK = 3, |
| _SYNCCONFIG_AutoRestartMode_SHIFT = 6, |
| } SYNCCONFIG_BITS_T; |
| |
| /** |
| * AutoRestartMode values |
| */ |
| typedef enum { |
| AUTORESTARTMODE_OFF = 0, |
| AUTORESTARTMODE_ON_NOPLL = 1, // don't wait for PLL resync |
| AUTORESTARTMODE_ON_PLL = 2 // wait for PLL resync |
| // other values reserved |
| } AUTORESTARTMODE_T; |
| |
| /** |
| * LOR_FeiMsb register (4 bit MSB of Fei value) |
| */ |
| typedef enum { |
| FEIMSB_FreqError0 = 0x01, |
| FEIMSB_FreqError1 = 0x02, |
| FEIMSB_FreqError2 = 0x04, |
| FEIMSB_FreqError3 = 0x08, |
| _FEIMSB_FreqError_MASK = 15, |
| _FEIMSB_FreqError_SHIFT = 0 |
| |
| // 0x10-0x80 reserved |
| } FEIMSB_BITS_T; |
| |
| /** |
| * FSK_PacketConfig1 register |
| */ |
| typedef enum { |
| PACKETCONFIG1_CrcWhiteningType = 0x01, |
| |
| PACKETCONFIG1_AddressFiltering0 = 0x02, |
| PACKETCONFIG1_AddressFiltering1 = 0x04, |
| _PACKETCONFIG1_AddressFiltering_MASK = 3, |
| _PACKETCONFIG1_AddressFiltering_SHIFT = 1, |
| |
| PACKETCONFIG1_CrcAutoClearOff = 0x08, |
| PACKETCONFIG1_CrcOn = 0x10, |
| |
| PACKETCONFIG1_DcFree0 = 0x20, |
| PACKETCONFIG1_DcFree1 = 0x40, |
| _PACKETCONFIG1_DcFree_MASK = 3, |
| _PACKETCONFIG1_DcFree_SHIFT = 5, |
| |
| PACKETCONFIG1_PacketFormat = 0x80 // fixed(0) or variable(1) |
| } PACKETCONFIG1_BITS_T; |
| |
| /** |
| * AddressFiltering values |
| */ |
| typedef enum { |
| ADDRESSFILTERING_NONE = 0, |
| ADDRESSFILTERING_NODE = 1, // must match node addr |
| ADDRESSFILTERING_NODE_BROADCAST = 2, // match node or broadcast |
| } ADDRESSFILTERING_T; |
| |
| /** |
| * DcFree values (DC-free encoding/decoding schemes) |
| */ |
| typedef enum { |
| DCFREE_NONE = 0, |
| DCFREE_MANCHESTER = 1, |
| DCFREE_WHITENING = 2 |
| // other values reserved |
| } DCFREE_T; |
| |
| /** |
| * FSK_PacketConfig2 register |
| */ |
| typedef enum { |
| PACKETCONFIG2_PayloadLengthMsb0 = 0x01, |
| PACKETCONFIG2_PayloadLengthMsb1 = 0x02, |
| PACKETCONFIG2_PayloadLengthMsb2 = 0x04, |
| _PACKETCONFIG2_PayloadLengthMsb_MASK = 7, |
| _PACKETCONFIG2_PayloadLengthMsb_SHIFT = 0, |
| |
| PACKETCONFIG2_BeaconOn = 0x08, |
| |
| // 0x10 reserved (linked to io-homecontrol compat mode (?)) |
| |
| PACKETCONFIG2_IoHomeOn = 0x20, |
| PACKETCONFIG2_DataMode = 0x40, // continuous(0), packet(1) |
| |
| // 0x80 reserved |
| } PACKETCONFIG2_BITS_T; |
| |
| /** |
| * LOR_DetectOptimize register |
| */ |
| typedef enum { |
| DETECTOPTIMIZE_DetectionOptimize0 = 0x01, |
| DETECTOPTIMIZE_DetectionOptimize1 = 0x02, |
| DETECTOPTIMIZE_DetectionOptimize2 = 0x04, |
| _DETECTOPTIMIZE_DetectionOptimize_MASK = 7, |
| _DETECTOPTIMIZE_DetectionOptimize_SHIFT = 0 |
| |
| // 0x08-0x80 reserved |
| } DETECTOPTIMIZE_BITS_T; |
| |
| /** |
| * DetectionOptimize values |
| */ |
| typedef enum { |
| DETECTIONOPTIMIZE_SF7_SF12 = 3, |
| DETECTIONOPTIMIZE_SF6 = 5 |
| |
| // other values reserved |
| } DETECTIONOPTIMIZE_T; |
| |
| /** |
| * LOR_InvertIQ register |
| */ |
| typedef enum { |
| INVERTIQ_InvertIQTxOff = 0x01, // invert LoRa I & Q signals |
| // UNDOCUMENTED |
| |
| // 0x01-0x20 reserved |
| |
| INVERTIQ_InvertIQRx = 0x40 // invert LoRa I & Q signals |
| |
| // 0x80 reserved |
| } INVERTIQ_BITS_T; |
| |
| /** |
| * FSK_FifoThresh register |
| */ |
| typedef enum { |
| FIFOTHRESH_FifoThreshold0 = 0x01, |
| FIFOTHRESH_FifoThreshold1 = 0x02, |
| FIFOTHRESH_FifoThreshold2 = 0x04, |
| FIFOTHRESH_FifoThreshold3 = 0x08, |
| FIFOTHRESH_FifoThreshold4 = 0x10, |
| FIFOTHRESH_FifoThreshold5 = 0x20, |
| _FIFOTHRESH_FifoThreshold_MASK = 63, |
| _FIFOTHRESH_FifoThreshold_SHIFT = 0, |
| |
| // 0x40 reserved |
| |
| FIFOTHRESH_TxStartCondition = 0x80 |
| } FIFOTHRESH_BITS_T; |
| |
| /** |
| * FSK_SeqConfig1 register |
| */ |
| typedef enum { |
| SEQCONFIG1_FromTransit = 0x01, |
| SEQCONFIG1_FromIdle = 0x02, |
| SEQCONFIG1_LowPowerSelection = 0x04, |
| |
| SEQCONFIG1_FromStart0 = 0x08, |
| SEQCONFIG1_FromStart1 = 0x10, |
| _SEQCONFIG1_FromStart_MASK = 3, |
| _SEQCONFIG1_FromStart_SHIFT = 3, |
| |
| SEQCONFIG1_IdleMode = 0x20, |
| SEQCONFIG1_SequencerStop = 0x40, |
| SEQCONFIG1_SequencerStart = 0x80 |
| } SEQCONFIG1_BITS_T; |
| |
| /** |
| * FromStart values |
| */ |
| typedef enum { |
| FROMSTART_ToLowPowerSelection = 0, |
| FROMSTART_ToReceiveState = 1, |
| FROMSTART_ToTransmitState = 2, |
| FROMSTART_ToTransmitStateOnFifoLevel = 3 |
| } FROMSTART_T; |
| |
| /** |
| * FSK_SeqConfig2 register |
| */ |
| typedef enum { |
| SEQCONFIG2_FromPacketReceived0 = 0x01, |
| SEQCONFIG2_FromPacketReceived1 = 0x02, |
| SEQCONFIG2_FromPacketReceived2 = 0x04, |
| _SEQCONFIG2_FromPacketReceived_MASK = 7, |
| _SEQCONFIG2_FromPacketReceived_SHIFT = 0, |
| |
| SEQCONFIG2_FromRxTimeout0 = 0x08, |
| SEQCONFIG2_FromRxTimeout1 = 0x10, |
| _SEQCONFIG2_FromRxTimeout_MASK = 3, |
| _SEQCONFIG2_FromRxTimeout_SHIFT = 3, |
| |
| SEQCONFIG2_FromReceive0 = 0x20, |
| SEQCONFIG2_FromReceive1 = 0x40, |
| SEQCONFIG2_FromReceive2 = 0x80, |
| _SEQCONFIG2_FromReceive_MASK = 3, |
| _SEQCONFIG2_FromReceive_SHIFT = 5 |
| } SEQCONFIG2_BITS_T; |
| |
| /** |
| * FromPacketReceived values |
| */ |
| typedef enum { |
| FROMPACKETRECEIVED_ToSequencerOff = 0, |
| FROMPACKETRECEIVED_ToTransmitStateOnFifoEmpty = 1, |
| FROMPACKETRECEIVED_ToLowPowerSelection = 2, |
| FROMPACKETRECEIVED_ToReceiveViaFS = 3, // if freq was changed |
| FROMPACKETRECEIVED_ToReceive = 4 // if freq was not changed |
| |
| // other values reserved |
| } FROMPACKETRECEIVED_T; |
| |
| /** |
| * FromRxTimeout values |
| */ |
| typedef enum { |
| FROMRXTIMEOUT_ToReceiveViaReceiveStart = 0, |
| FROMRXTIMEOUT_ToTransmitState = 1, |
| FROMRXTIMEOUT_ToLowPowerSelection = 2, |
| FROMRXTIMEOUT_ToSequencerOffState = 3 |
| } FROMRXTIMEOUT_T; |
| |
| /** |
| * FromReceive values |
| */ |
| typedef enum { |
| FROMRECEIVE_ToPcketReceived = 1, |
| FROMRECEIVE_ToLowPowerSelection = 2, |
| FROMRECEIVE_ToPacketReceived = 3, |
| FROMRECEIVE_ToSequencerOffOnRSSI = 4, // RSSI interrupt |
| FROMRECEIVE_ToSequencerOffOnSync = 5, // SyncAddr interrupt |
| FROMRECEIVE_ToSequencerOffOnPreambleDetect = 6, // PreambleDetect intr |
| // other values reserved |
| } FROMRECEIVE_T; |
| |
| /** |
| * FSK_TimerResol register |
| */ |
| typedef enum { |
| TIMERRESOL_Timer2Resolution0 = 0x01, |
| TIMERRESOL_Timer2Resolution1 = 0x02, |
| _TIMERRESOL_Timer2Resolution_MASK = 3, |
| _TIMERRESOL_Timer2Resolution_SHIFT = 0, |
| |
| TIMERRESOL_Timer1Resolution0 = 0x04, |
| TIMERRESOL_Timer1Resolution1 = 0x08, |
| _TIMERRESOL_Timer1Resolution_MASK = 3, |
| _TIMERRESOL_Timer1Resolution_SHIFT = 2 |
| |
| // 0x10-0x80 reserved |
| } TIMERRESOL_BITS_T; |
| |
| /** |
| * Timer1/Timer2Resolution values |
| */ |
| typedef enum { |
| TIMERRESOLUTION_DISABLED = 0, |
| TIMERRESOLUTION_64us = 1, // 64us |
| TIMERRESOLUTION_4_1ms = 2, // 4.1ms |
| TIMERRESOLUTION_262ms = 3 // 262ms |
| } TIMERRESOLUTION_T; |
| |
| /** |
| * FSK_ImageCal register |
| */ |
| typedef enum { |
| IMAGECAL_TempMonitorOff = 0x01, |
| |
| IMAGECAL_TempThreshold0 = 0x02, |
| IMAGECAL_TempThreshold1 = 0x04, |
| _IMAGECAL_TempThreshold_MASK = 3, |
| _IMAGECAL_TempThreshold_SHIFT = 1, |
| |
| IMAGECAL_TenpChange = 0x08, |
| |
| // 0x10 reserved |
| |
| IMAGECAL_ImageCalRunning = 0x20, |
| IMAGECAL_ImageCalStart = 0x40, |
| IMAGECAL_AutoImageCalOn = 0x80 |
| } IMAGECAL_BITS_T; |
| |
| /** |
| * TempThreshold values |
| */ |
| typedef enum { |
| TEMPTHRESHOLD_5C = 0, // temp change to trigger new I/Q |
| TEMPTHRESHOLD_10C = 1, // calibration |
| TEMPTHRESHOLD_15C = 2, |
| TEMPTHRESHOLD_20C = 3 |
| } TEMPTHRESHOLD_T; |
| |
| /** |
| * FSK_LowBat register |
| */ |
| typedef enum { |
| LOWBAT_LowBatTrim0 = 0x01, |
| LOWBAT_LowBatTrim1 = 0x02, |
| LOWBAT_LowBatTrim2 = 0x04, |
| _LOWBAT_LowBatTrim_MASK = 7, |
| _LOWBAT_LowBatTrim_SHIFT = 0, |
| |
| LOWBAT_LowBatOn = 0x08 |
| |
| // 0x10-0z80 reserved |
| } LOWBAT_BITS_T; |
| |
| /** |
| * LowBatTrim values |
| */ |
| typedef enum { |
| LOWBATTRIM_1_695 = 0, // 1.695v |
| LOWBATTRIM_1_764 = 1, |
| LOWBATTRIM_1_835 = 2, |
| LOWBATTRIM_1_905 = 3, |
| LOWBATTRIM_1_976 = 4, |
| LOWBATTRIM_2_045 = 5, |
| LOWBATTRIM_2_116 = 6, |
| LOWBATTRIM_2_185 = 7 |
| } LOWBATTRIM_T; |
| |
| /** |
| * FSK_IrqFlags1 register |
| */ |
| typedef enum { |
| IRQFLAGS1_SyncAddressMatch = 0x01, |
| IRQFLAGS1_PreambleDetect = 0x02, |
| IRQFLAGS1_Timeout = 0x04, |
| IRQFLAGS1_Rssi = 0x08, |
| IRQFLAGS1_PllLock = 0x10, |
| IRQFLAGS1_TxReady = 0x20, |
| IRQFLAGS1_RxReady = 0x40, |
| IRQFLAGS1_ModeReady = 0x80 |
| } IRQFLAGS1_BITS_T; |
| |
| /** |
| * FSK_IrqFlags2 register |
| */ |
| typedef enum { |
| IRQFLAGS2_LowBat = 0x01, |
| IRQFLAGS2_CrcOk = 0x02, |
| IRQFLAGS2_PayloadReady = 0x04, |
| IRQFLAGS2_PacketSent = 0x08, |
| IRQFLAGS2_FifoOverrun = 0x10, |
| IRQFLAGS2_FifoLevel = 0x20, |
| IRQFLAGS2_FifoEmpty = 0x40, |
| IRQFLAGS2_FifoFull = 0x80 |
| } IRQFLAGS2_BITS_T; |
| |
| /** |
| * COM_DioMapping1 register. See Tables 18, 29, and 30 in the |
| * datasheet for the different mappings depending on mode. |
| */ |
| typedef enum { |
| DOIMAPPING1_Dio3Mapping0 = 0x01, |
| DOIMAPPING1_Dio3Mapping1 = 0x02, |
| DOIMAPPING1_Dio3Mapping_MASK = 3, |
| DOIMAPPING1_Dio3Mapping_SHIFT = 0, |
| |
| DOIMAPPING1_Dio2Mapping0 = 0x04, |
| DOIMAPPING1_Dio2Mapping1 = 0x08, |
| DOIMAPPING1_Dio2Mapping_MASK = 3, |
| DOIMAPPING1_Dio2Mapping_SHIFT = 2, |
| |
| DOIMAPPING1_Dio1Mapping0 = 0x10, |
| DOIMAPPING1_Dio1Mapping1 = 0x20, |
| DOIMAPPING1_Dio1Mapping_MASK = 3, |
| DOIMAPPING1_Dio1Mapping_SHIFT = 4, |
| |
| DOIMAPPING1_Dio0Mapping0 = 0x40, |
| DOIMAPPING1_Dio0Mapping1 = 0x80, |
| DOIMAPPING1_Dio0Mapping_MASK = 3, |
| DOIMAPPING1_Dio0Mapping_SHIFT = 6, |
| } DIOMAPPING1_BITS_T; |
| |
| |
| /** |
| * COM_DioMapping2 register. See Tables 18, 29, and 30 in the |
| * datasheet for the different mappings depending on mode. |
| */ |
| typedef enum { |
| DOIMAPPING2_MapPreambleDetect = 0x01, // rssi intr(0), preambledet(1) |
| |
| // 0x02-0x08 reserved |
| |
| DOIMAPPING2_Dio5Mapping0 = 0x10, |
| DOIMAPPING2_Dio5Mapping1 = 0x20, |
| DOIMAPPING2_Dio5Mapping_MASK = 3, |
| DOIMAPPING2_Dio5Mapping_SHIFT = 4, |
| |
| DOIMAPPING2_Dio4Mapping0 = 0x40, |
| DOIMAPPING2_Dio4Mapping1 = 0x80, |
| DOIMAPPING2_Dio4Mapping_MASK = 3, |
| DOIMAPPING2_Dio4Mapping_SHIFT = 6, |
| } DIOMAPPING2_BITS_T; |
| |
| /** |
| * DioXMapping values |
| * |
| * These differ depending on LoRa, FSK packet, and FSK continous |
| * modes. See Tables 29, 30 (FSK), and 18 (LoRa) in the datasheet |
| * for details. |
| */ |
| typedef enum { |
| DIOMAPPING_00 = 0, |
| DIOMAPPING_01 = 1, |
| DIOMAPPING_10 = 2, |
| DIOMAPPING_11 = 3 |
| } DIOMAPPING_T; |
| |
| |
| /** |
| * LOR_PllHop (or FSK_PllHop depending on who you believe) register |
| */ |
| typedef enum { |
| // 0x01-0x40 reserved |
| |
| PLLHOP_FastHopOn = 0x80 |
| } PLLHOP_BITS_T; |
| |
| /** |
| * COM_Tcxo register |
| */ |
| typedef enum { |
| // 0x01-0x08 reserved |
| |
| TCXO_TcxoOn = 0x10 |
| |
| // 0x20-0x80 reserved |
| } TCXO_BITS_T; |
| |
| /** |
| * COM_PaDac register |
| */ |
| typedef enum { |
| PADAC_PaDac0 = 0x01, |
| PADAC_PaDac1 = 0x02, |
| PADAC_PaDac2 = 0x04, |
| _PADAC_PaDac_MASK = 7, |
| _PADAC_PaDac_SHIFT = 0 |
| |
| // 0x08-0x80 reserved |
| } PADAC_BITS_T; |
| |
| /** |
| * PaDac values |
| */ |
| typedef enum { |
| PADAC_DEFAULT = 4, |
| PADAC_BOOST = 7 // +20dBm on PA_BOOST when |
| // OuputPower = 1111 |
| // other values reserved |
| } PADAC_T; |
| |
| /** |
| * FSK_BitRateFrac register |
| */ |
| typedef enum { |
| BITRATEFRAC_BitRateFrac0 = 0x01, |
| BITRATEFRAC_BitRateFrac1 = 0x02, |
| BITRATEFRAC_BitRateFrac2 = 0x04, |
| BITRATEFRAC_BitRateFrac3 = 0x08, |
| _BITRATEFRAC_BitRateFrac_MASK = 15, |
| _BITRATEFRAC_BitRateFrac_SHIFT = 0 |
| |
| // 0x10-0x80 reserved |
| } BITRATEFRAC_BITS_T; |
| |
| /** |
| * COM_AgcRef register |
| * |
| * These registers have 2 sets of values depending on whether |
| * LowFrequencyModeOn is set or unset. |
| */ |
| typedef enum { |
| AGCREF_AgcReferenceLevel0 = 0x01, |
| AGCREF_AgcReferenceLevel1 = 0x02, |
| AGCREF_AgcReferenceLevel2 = 0x04, |
| AGCREF_AgcReferenceLevel3 = 0x08, |
| AGCREF_AgcReferenceLevel4 = 0x10, |
| AGCREF_AgcReferenceLevel5 = 0x20, |
| _AGCREF_AgcReferenceLevel_MASK = 63, |
| _AGCREF_AgcReferenceLevel_SHIFT = 0 |
| |
| // 0x40-0x80 reserved |
| } ACFREF_BITS_T; |
| |
| /** |
| * COM_AgcThresh1 register |
| * |
| * These registers have 2 sets of values depending on whether |
| * LowFrequencyModeOn is set or unset. |
| */ |
| typedef enum { |
| AGCTHRESH1_AcgStep10 = 0x01, |
| AGCTHRESH1_AcgStep11 = 0x02, |
| AGCTHRESH1_AcgStep12 = 0x04, |
| AGCTHRESH1_AcgStep13 = 0x08, |
| _AGCTHRESH1_AcgStep1_MASK = 15, |
| _AGCTHRESH1_AcgStep1_SHIFT = 0, |
| |
| // 0x10-0x80 reserved |
| } ACGTHRESH1_BITS_T; |
| |
| /** |
| * COM_AgcThresh2 register |
| * |
| * These registers have 2 sets of values depending on whether |
| * LowFrequencyModeOn is set or unset. |
| */ |
| typedef enum { |
| AGCTHRESH2_AcgStep30 = 0x01, |
| AGCTHRESH2_AcgStep31 = 0x02, |
| AGCTHRESH2_AcgStep32 = 0x04, |
| AGCTHRESH2_AcgStep33 = 0x08, |
| _AGCTHRESH2_AcgStep3_MASK = 15, |
| _AGCTHRESH2_AcgStep3_SHIFT = 0, |
| |
| AGCTHRESH2_AcgStep20 = 0x10, |
| AGCTHRESH2_AcgStep21 = 0x20, |
| AGCTHRESH2_AcgStep22 = 0x40, |
| AGCTHRESH2_AcgStep23 = 0x80, |
| _AGCTHRESH2_AcgStep2_MASK = 15, |
| _AGCTHRESH2_AcgStep2_SHIFT = 4 |
| } ACGTHRESH2_BITS_T; |
| |
| /** |
| * LOR_RegDetectionThreshold values |
| */ |
| typedef enum { |
| LOR_DetectionThreshold_SF7_SF12 = 0x0a, |
| LOR_DetectionThreshold_SF6 = 0x0c |
| } LOR_DETECTIONTHRESHOLD_T; |
| |
| /** |
| * COM_AgcThresh3 register |
| * |
| * These registers have 2 sets of values depending on whether |
| * LowFrequencyModeOn is set or unset. |
| */ |
| typedef enum { |
| AGCTHRESH3_AcgStep50 = 0x01, |
| AGCTHRESH3_AcgStep51 = 0x02, |
| AGCTHRESH3_AcgStep52 = 0x04, |
| AGCTHRESH3_AcgStep53 = 0x08, |
| _AGCTHRESH3_AcgStep5_MASK = 15, |
| _AGCTHRESH3_AcgStep5_SHIFT = 0, |
| |
| AGCTHRESH3_AcgStep40 = 0x10, |
| AGCTHRESH3_AcgStep41 = 0x20, |
| AGCTHRESH3_AcgStep42 = 0x40, |
| AGCTHRESH3_AcgStep43 = 0x80, |
| _AGCTHRESH3_AcgStep4_MASK = 15, |
| _AGCTHRESH3_AcgStep4_SHIFT = 4 |
| } ACGTHRESH3_BITS_T; |
| |
| |
| /** |
| * SX1276 constructor |
| * |
| * Since this is a shield, you will not have much choice as to |
| * what pins are used. |
| * |
| * @param chipRev chip revision, default is 0x12 |
| * @param bus spi bus to use |
| * @param cs GPIO pin to use as SPI Chip Select |
| * @param reset GPIO pin to use as reset (A0=GPIO14) |
| * @param dio0 GPIO pin to use as reset DIO0 intr |
| * @param dio1 GPIO pin to use as reset DIO1 intr |
| * @param dio2 GPIO pin to use as reset DIO2 intr |
| * @param dio3 GPIO pin to use as reset DIO3 intr |
| * @param dio4 GPIO pin to use as reset DIO4 intr |
| * @param dio5 GPIO pin to use as reset DIO5 intr |
| */ |
| SX1276(uint8_t chipRev=chipRevision, int bus=1, int cs=10, int resetPin=14, |
| int dio0=2, int dio1=3, int dio2=4, int dio3=5, int dio4=17, |
| int dio5=9); |
| |
| /** |
| * SX1276 Destructor |
| */ |
| ~SX1276(); |
| |
| /** |
| * read a register |
| * |
| * @param reg the register to read |
| * @return the value of the register |
| */ |
| uint8_t readReg(uint8_t reg); |
| |
| /** |
| * write to a register |
| * |
| * @param reg the register to write to |
| * @param val the value to write |
| * @return true if successful, false otherwise |
| */ |
| bool writeReg(uint8_t reg, uint8_t val); |
| |
| /** |
| * return the chip revision |
| * |
| * @return the chip revision (usually 0x12) |
| */ |
| uint8_t getChipVersion(); |
| |
| /** |
| * reset the modem |
| */ |
| void reset(); |
| |
| /** |
| * read the FIFO into a buffer |
| * |
| * @param buffer The buffer to read data into |
| * @param len The length of the buffer |
| */ |
| void readFifo(uint8_t *buffer, int len); |
| |
| /** |
| * write a buffer into the FIFO |
| * |
| * @param buffer The buffer containing the data to write |
| * @param len The length of the buffer |
| */ |
| void writeFifo(uint8_t *buffer, int len); |
| |
| /** |
| * Set the frequency to transmit and receive on |
| * |
| * @param freq The frequency to set |
| */ |
| void setChannel(uint32_t freq); |
| |
| /** |
| * Set the operating mode |
| * |
| * @param opMode One of the MODE_T values |
| */ |
| void setOpMode(MODE_T opMode); |
| |
| /** |
| * Set the modem to access. This can be either the LORA or |
| * KSK/OOK modem. |
| * |
| * @param modem One of the MODEM_T values |
| */ |
| void setModem(RADIO_MODEM_T modem); |
| |
| /** |
| * Place the SX1276 into sleep mode |
| */ |
| void setSleep(); |
| |
| /** |
| * Place the SX1276 into standby mode |
| */ |
| void setStandby(); |
| |
| /** |
| * Return the current Received Signal Strength Indicator for the |
| * given modem |
| * |
| * @param modem One of the MODEM_T values |
| */ |
| int16_t getRSSI(RADIO_MODEM_T modem); |
| |
| /** |
| * Check to see if a given channel is free by comparing the RSSI |
| * to the supplied threshold. |
| * |
| * @param modem One of the MODEM_T values |
| * @param freq The channel to check |
| * @param rssiThreshold The RSSI threshold, over which the channel |
| * os considerd in use. |
| */ |
| bool isChannelFree(RADIO_MODEM_T modem, uint32_t freq, int16_t rssiThresh); |
| |
| /** |
| * Send the supplied string. This writes the string into the FIFO |
| * and places the modem in transmit mode (via setTx()). This is a |
| * wrapper around send(). |
| * |
| * @param buffer The buffer to send |
| * @param timeout The timeout in milliseconds |
| * @return one of the RADIO_EVENT_T values |
| */ |
| RADIO_EVENT_T sendStr(std::string buffer, int timeout); |
| |
| /** |
| * Send the supplied buffer. The writes the buffer into the FIFO |
| * and places the modem in transmit mode (via setTx()). |
| * |
| * @param buffer The buffer to send |
| * @param size The size of the buffer |
| * @param timeout The timeout in milliseconds |
| * @return one of the RADIO_EVENT_T values |
| */ |
| RADIO_EVENT_T send(uint8_t *buffer, uint8_t size, int timeout); |
| |
| /** |
| * Set the receive configuration for a modem. It is important |
| * that both the receive and transmit configurations match in order |
| * for communication to work between two radios. |
| * |
| * @param modem One of the MODEM_T values |
| |
| * @param bandwidth The bandwidth to use. Valid values are |
| * FSK : >= 2600 and <= 250000 Hz |
| * LoRa: [125 kHz, 250 kHz, 500 kHz] |
| * @param datarate Sets the Datarate |
| * FSK : 600..300000 bits/s |
| * LoRa: [6: 64, 7: 128, 8: 256, 9: 512, |
| * 10: 1024, 11: 2048, 12: 4096 chips] |
| * @param coderate Sets the coding rate (LoRa only) |
| * FSK : N/A ( set to 0 ) |
| * LoRa: [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8] |
| * @param bandwidthAfc Sets the AFC Bandwidth (FSK only) |
| * FSK : >= 2600 and <= 250000 Hz |
| * LoRa: N/A ( set to 0 ) |
| * @param preambleLen Sets the Preamble length |
| * FSK : Number of bytes |
| * LoRa: Length in symbols (the hardware adds |
| * 4 more symbols) |
| * @param symbTimeout Sets the RxSingle timeout value (LoRa only) |
| * FSK : N/A ( set to 0 ) |
| * LoRa: timeout in symbols |
| * @param fixLen Fixed length packets [false: variable, true: fixed] |
| * @param payloadLen Sets payload length when fixed lenght is used |
| * @param crcOn Enables/Disables the CRC [false: OFF, true: ON] |
| * @param FreqHopOn Enables disables the intra-packet frequency hopping |
| * FSK : N/A ( set to 0 ) |
| * LoRa: [false: OFF, true: ON] |
| * @param HopPeriod Number of symbols bewteen each hop |
| * FSK : N/A ( set to 0 ) |
| * LoRa: Number of symbols |
| * @param iqInverted Inverts IQ signals (LoRa only) |
| * FSK : N/A ( set to 0 ) |
| * LoRa: [false: not inverted, true: inverted] |
| * @param rxContinuous Sets the reception in continuous mode |
| * [false: single mode, true: continuous mode] |
| */ |
| void setRxConfig(RADIO_MODEM_T modem, uint32_t bandwidth, |
| uint32_t datarate, uint8_t coderate, |
| uint32_t bandwidthAfc, uint16_t preambleLen, |
| uint16_t symbTimeout, bool fixLen, |
| uint8_t payloadLen, |
| bool crcOn, bool freqHopOn, uint8_t hopPeriod, |
| bool iqInverted, bool rxContinuous); |
| |
| /** |
| * Set the transmit configuration for a modem. It is important |
| * that both the receive and transmit configurations match in order |
| * for communication to work between two radios. |
| * |
| * @param modem One of the MODEM_T values |
| * @param power Sets the output power [dBm] |
| * @param fdev Sets the frequency deviation (FSK only) |
| * FSK : [Hz] |
| * LoRa: 0 |
| * @param bandwidth Sets the bandwidth (LoRa only) |
| * FSK : 0 |
| * LoRa: [125 kHz, 250 kHz, |
| * or 500 kHz] |
| * @param datarate Sets the Datarate |
| * FSK : 600..300000 bits/s |
| * LoRa: [6: 64, 7: 128, 8: 256, 9: 512, |
| * 10: 1024, 11: 2048, 12: 4096 chips] |
| * @param coderate Sets the coding rate (LoRa only) |
| * FSK : N/A ( set to 0 ) |
| * LoRa: [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8] |
| * @param preambleLen Sets the preamble length |
| * FSK : Number of bytes |
| * LoRa: Length in symbols (the hardware adds |
| * 4 more symbols) |
| * @param fixLen Fixed length packets [false: variable, true: fixed] |
| * @param crcOn Enables disables the CRC [false: OFF, true: ON] |
| * @param FreqHopOn Enables disables the intra-packet frequency hopping |
| * FSK : N/A ( set to 0 ) |
| * LoRa: [false: OFF, true: ON] |
| * @param HopPeriod Number of symbols bewteen each hop |
| * FSK : N/A ( set to 0 ) |
| * LoRa: Number of symbols |
| * @param iqInverted Inverts IQ signals (LoRa only) |
| * FSK : N/A ( set to 0 ) |
| * LoRa: [false: not inverted, true: inverted] |
| */ |
| void setTxConfig(RADIO_MODEM_T modem, int8_t power, uint32_t fdev, |
| uint32_t bandwidth, uint32_t datarate, |
| uint8_t coderate, uint16_t preambleLen, |
| bool fixLen, bool crcOn, bool freqHopOn, |
| uint8_t hopPeriod, bool iqInverted); |
| |
| /** |
| * Start a receive operation. The method will return when |
| * completed, either successfully, or in error (crc, or other |
| * issue). If completed successfully, the returned buffer can be |
| * read via getRxBuffer() or getRxBufferStr(). In addition, |
| * values for RSSI and SNR (Lora only) can be retrieved. |
| * |
| * @param timeout The timeout in milliseconds |
| * @return one of the RADIO_EVENT_T values |
| */ |
| RADIO_EVENT_T setRx(uint32_t timeout); |
| |
| /** |
| * Upon a successful receive, this method can be used to retrieve |
| * the received packet. |
| * |
| * @return The received buffer in a std::string |
| */ |
| std::string getRxBufferStr() |
| { |
| std::string rBuffer((char *)m_rxBuffer, getRxLen()); |
| return rBuffer; |
| }; |
| |
| /** |
| * Upon a successful receive, this method can be used to retrieve |
| * the received packet. |
| * |
| * @return a pointer to the received buffer. You can use |
| * getRxLen() to determine the number of valid bytes present. |
| */ |
| uint8_t *getRxBuffer() |
| { |
| return (uint8_t*)m_rxBuffer; |
| }; |
| |
| /** |
| * Upon a successful receive, this method can be used to retrieve |
| * the received packet's Received Signal Strength Indicator (RSSI) |
| * value. |
| * |
| * @return RSSI value |
| */ |
| int getRxRSSI() |
| { |
| return m_rxRSSI; |
| }; |
| |
| /** |
| * Upon a successful receive, this method can be used to retrieve |
| * the received packet's Signal to Noise (SNR) value. |
| * |
| * @return SNR value |
| */ |
| int getRxSNR() |
| { |
| return m_rxSNR; |
| }; |
| |
| /** |
| * Upon a successful receive, this method can be used to retrieve |
| * the number of bytes received. |
| * |
| * @return the number of bytes received |
| */ |
| int getRxLen() |
| { |
| return m_rxLen; |
| }; |
| |
| |
| protected: |
| // I/O |
| mraa::Spi m_spi; |
| mraa::Gpio m_gpioCS; |
| mraa::Gpio m_gpioReset; |
| |
| mraa::Gpio m_gpioDIO0; |
| mraa::Gpio m_gpioDIO1; |
| mraa::Gpio m_gpioDIO2; |
| mraa::Gpio m_gpioDIO3; |
| mraa::Gpio m_gpioDIO4; |
| mraa::Gpio m_gpioDIO5; |
| |
| // calibration called during init() |
| void rxChainCalibration(); |
| |
| // interrupt handlers |
| static void onDio0Irq(void *ctx); |
| static void onDio1Irq(void *ctx); |
| static void onDio2Irq(void *ctx); |
| static void onDio3Irq(void *ctx); |
| static void onDio4Irq(void *ctx); |
| static void onDio5Irq(void *ctx); |
| |
| /** |
| * What internal state are we in |
| */ |
| typedef enum { |
| STATE_IDLE = 0, |
| STATE_RX_RUNNING, |
| STATE_TX_RUNNING, |
| STATE_CAD |
| } RADIO_STATES_T; |
| |
| // needs to be OR'd onto registers for SPI write |
| static const uint8_t m_writeMode = 0x80; |
| |
| // initialize the chip |
| void init(); |
| |
| // Start a transmit event (you should use send() or sendStr() |
| // rather than call this function directly. |
| RADIO_EVENT_T setTx(int timeout); |
| |
| void startCAD(); // non-functional/non-tested |
| |
| // not really used, maybe it should be |
| void setMaxPayloadLength(RADIO_MODEM_T modem, uint8_t max); |
| |
| // Chip Select control (active LOW) |
| void csOn() |
| { |
| m_gpioCS.write(0); |
| }; |
| |
| void csOff() |
| { |
| m_gpioCS.write(1); |
| }; |
| |
| private: |
| // Thse structs will generate SWIG warnings, as we do not expose |
| // this data, they can be ignored. |
| |
| // stored settings for the FSK modem |
| typedef struct |
| { |
| int8_t Power; |
| uint32_t Fdev; |
| uint32_t Bandwidth; |
| uint32_t BandwidthAfc; |
| uint32_t Datarate; |
| uint16_t PreambleLen; |
| bool FixLen; |
| uint8_t PayloadLen; |
| bool CrcOn; |
| bool IqInverted; |
| bool RxContinuous; |
| } radioFskSettings_t; |
| |
| // stored settings for the LoRa modem |
| typedef struct |
| { |
| int8_t Power; |
| uint32_t Bandwidth; |
| uint32_t Datarate; |
| bool LowDatarateOptimize; |
| uint8_t Coderate; |
| uint16_t PreambleLen; |
| bool FixLen; |
| uint8_t PayloadLen; |
| bool CrcOn; |
| bool FreqHopOn; |
| uint8_t HopPeriod; |
| bool IqInverted; |
| bool RxContinuous; |
| } radioLoRaSettings_t; |
| |
| // FSK packet handler state |
| typedef struct |
| { |
| uint8_t PreambleDetected; |
| uint8_t SyncWordDetected; |
| int8_t RssiValue; |
| int32_t AfcValue; |
| uint8_t RxGain; |
| uint16_t Size; |
| uint16_t NbBytes; |
| uint8_t FifoThresh; |
| uint8_t ChunkSize; |
| } radioFskPacketHandler_t; |
| |
| // LoRa packet handler state |
| typedef struct |
| { |
| int8_t SnrValue; |
| int16_t RssiValue; |
| uint8_t Size; |
| } radioLoRaPacketHandler_t; |
| |
| // our radio settings |
| struct { |
| RADIO_MODEM_T modem; |
| volatile RADIO_STATES_T state; |
| uint32_t channel; |
| |
| radioFskSettings_t fskSettings; |
| volatile radioFskPacketHandler_t fskPacketHandler; |
| |
| radioLoRaSettings_t loraSettings; |
| volatile radioLoRaPacketHandler_t loraPacketHandler; |
| } m_settings; |
| |
| uint8_t lookupFSKBandWidth(uint32_t bw); |
| |
| // received data (on successfull completion) |
| volatile int m_rxRSSI; |
| volatile int m_rxSNR; |
| volatile int m_rxLen; |
| uint8_t m_rxBuffer[FIFO_SIZE]; |
| |
| // for coordinating interrupt access |
| pthread_mutex_t m_intrLock; |
| |
| void lockIntrs() { pthread_mutex_lock(&m_intrLock); }; |
| void unlockIntrs() { pthread_mutex_unlock(&m_intrLock); }; |
| |
| // current radio event status |
| volatile RADIO_EVENT_T m_radioEvent; |
| |
| // timer support |
| struct timeval m_startTime; |
| void initClock(); |
| uint32_t getMillis(); |
| }; |
| } |
| |
| |