Driver library for SX1272/SX1276 transceivers
Dependents: LORA_RX LORA_TX WindConcentrator hid_test ... more
Driver library for SX1272 and SX1276 radio transceivers.
This device uses CSS modulation to provide much improved link budget. The RF hardware is same as in FSK devices, just with added LoRa spread-spectrum modem.
This library provides functions to configure radio chip and transmit & receive packets.
Using This Library
Library function service_radio()
must be called continuously from main loop, to service interrupts from radio.
Board Specific implementation
FunctionPointer for rf_switch
callback allows the program to implement control of RF switch unique to their board.
Example options are:
- SKY13373 for external power amplifier implementation. Requires two DigitalOut pins.
- SKY13350 using PA_BOOST. requires two DigitalOut pins.
- PE4259-63: controlled directly by radio chip, no software function needed. However, in the case of SX1276MB1xAS, the RXTX pin on IO2 should be driven by this callback function when R16 is installed (without R15) on this shield board.
Some configurations may need to force the use of RFO or PA_BOOST, or a board could offer both options. The rf_switch
function pointer callback should support the implementation choice on the board.
further reading
- LoRa modulation basics (dropbox PDF)
- OpenLoRa forum
sx127x_lora.h
- Committer:
- dudmuck
- Date:
- 2015-04-17
- Revision:
- 14:f39b9bf5290f
- Parent:
- 12:bda42457c34a
- Child:
- 15:3f3fc6792f97
File content as of revision 14:f39b9bf5290f:
#include "sx127x.h" // LoRa registers #define REG_LR_FIFOADDRPTR 0x0d #define REG_LR_FIFOTXBASEADDR 0x0e #define REG_LR_FIFORXBASEADDR 0x0f #define REG_LR_FIFORXCURRENTADDR /*REG_LR_RXDATAADDR*/ 0x10 #define REG_LR_IRQFLAGSMASK 0x11 #define REG_LR_IRQFLAGS 0x12 #define REG_LR_RXNBBYTES 0x13 #define REG_LR_RXHEADERCNTVALUE_MSB 0x14 #define REG_LR_RXHEADERCNTVALUE_LSB 0x15 #define REG_LR_RXPACKETCNTVALUE_MSB 0x16 #define REG_LR_RXPACKETCNTVALUE_LSB 0x17 #define REG_LR_MODEMSTAT 0x18 #define REG_LR_PKTSNRVALUE 0x19 #define REG_LR_PKTRSSIVALUE 0x1a #define REG_LR_RSSIVALUE 0x1b #define REG_LR_HOPCHANNEL 0x1c #define REG_LR_MODEMCONFIG 0x1d #define REG_LR_MODEMCONFIG2 0x1e #define REG_LR_SYMBTIMEOUTLSB 0x1f #define REG_LR_PREAMBLEMSB 0x20 #define REG_LR_PREAMBLELSB 0x21 #define REG_LR_PAYLOADLENGTH 0x22 // and RX length for implicit #define REG_LR_RX_MAX_PAYLOADLENGTH 0x23 // length limit for explicit mode #define REG_LR_HOPPERIOD 0x24 #define REG_LR_RXBYTEADDR /*REG_LR_RXDATAADDR*/ 0x25 #define REG_LR_MODEMCONFIG3 0x26 // sx1272 REG_LR_PPM_CORRECTION_MSB #define REG_LR_PPM_CORRECTION_LSB 0x27 #define REG_LR_TEST28 0x28 // est_freq_error #define REG_LR_TEST29 0x29 // est_freq_error #define REG_LR_TEST2A 0x2a // est_freq_error #define REG_LR_TEST2B 0x2b // #define REG_LR_WIDEBAND_RSSI 0x2c #define REG_LR_AGCH_TH 0x2d // agc_upper_th #define REG_LR_AGCL_TH 0x2e // agc_lower_th #define REG_LR_IFFRQH 0x2f // if_freq(12:8) #define REG_LR_IFFRQL 0x30 // if_freq(7:0) #define REG_LR_TEST31 0x31 // if_freq_auto, ... #define REG_LR_TEST32 0x32 // #define REG_LR_TEST33 0x33 #define REG_LR_CAD_PEAK_TO_NOISE_RATIO 0x34 #define REG_LR_CAD_MIN_PEAK 0x35 #define REG_LR_DETECTION_THRESHOLD 0x37 #define REG_LR_SYNC_BYTE 0x39 // default 0x12 (value of 0x21 will isolate network) typedef union { struct { // sx127x register 0x12 uint8_t CadDetected : 1; // 0 uint8_t FhssChangeChannel : 1; // 1 uint8_t CadDone : 1; // 2 uint8_t TxDone : 1; // 3 uint8_t ValidHeader : 1; // 4 uint8_t PayloadCrcError : 1; // 5 uint8_t RxDone : 1; // 6 uint8_t RxTimeout : 1; // 7 } bits; uint8_t octet; } RegIrqFlags_t; typedef union { struct { // sx127x register 0x18 uint8_t detect : 1; // 0 uint8_t sync : 1; // 1 uint8_t rx_ongoing : 1; // 2 uint8_t header_valid : 1; // 3 uint8_t clear : 1; // 4 uint8_t RxCodingRate : 3; // 5,6,7 } bits; uint8_t octet; } RegModemStatus_t; typedef union { struct { // sx127x register 0x1c uint8_t FhssPresentChannel : 6; // 0,1,2,3,4,5 uint8_t RxPayloadCrcOn : 1; // 6 uint8_t PllTimeout : 1; // 7 } bits; uint8_t octet; } RegHopChannel_t; typedef union { struct { // sx1276 register 0x1d uint8_t ImplicitHeaderModeOn : 1; // 0 uint8_t CodingRate : 3; // 1,2,3 uint8_t Bw : 4; // 4,5,6,7 } sx1276bits; struct { // sx1272 register 0x1d uint8_t LowDataRateOptimize : 1; // 0 ppm_offset: number of cyclic shifts possible to encode to symbol uint8_t RxPayloadCrcOn : 1; // 1 uint8_t ImplicitHeaderModeOn : 1; // 2 uint8_t CodingRate : 3; // 3,4,5 uint8_t Bw : 2; // 6,7 } sx1272bits; uint8_t octet; } RegModemConfig_t; typedef union { struct { // sx1276 register 0x1e uint8_t SymbTimeoutMsb : 2; // 0,1 uint8_t RxPayloadCrcOn : 1; // 2 uint8_t TxContinuousMode : 1; // 3 uint8_t SpreadingFactor : 4; // 4,5,6,7 } sx1276bits; struct { // sx1272 register 0x1e uint8_t SymbTimeoutMsb : 2; // 0,1 uint8_t AgcAutoOn : 1; // 2 uint8_t TxContinuousMode : 1; // 3 uint8_t SpreadingFactor : 4; // 4,5,6,7 } sx1272bits; uint8_t octet; } RegModemConfig2_t; typedef union { struct { // sx127x register 0x26 uint8_t reserved : 2; // 0,1 uint8_t AgcAutoOn : 1; // 2 uint8_t LowDataRateOptimize : 1; // 3 ppm_offset, use when symbol duration exceeds 16ms uint8_t unused : 4; // 4,5,6,7 } sx1276bits; uint8_t octet; uint8_t sx1272_ppm_correction_msb; } RegModemConfig3_t; typedef union { struct { // sx127x register 0x31 uint8_t detect_trig_same_peaks_nb : 3; // 0,1,2 uint8_t disable_pll_timeout : 1; // 3 uint8_t tracking_intergral : 2; // 4,5 uint8_t frame_sync_gain : 1; // 6 uint8_t if_freq_auto : 1; // 7 } bits; uint8_t octet; } RegTest31_t; //class SX127x_lora : public SX127x class SX127x_lora { public: //SX127x_lora(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName rst, PinName dio_0, PinName dio_1, PinName fem_ctx, PinName fem_cps); SX127x_lora(SX127x& r); ~SX127x_lora(); /** changes from FSK mode to LoRa mdoe */ void enable(void); /** fills radio FIFO with payload contents, prior to transmission * @param len count of bytes to put into FIFO * @note tx_buf[] should contain desired payload (to send) prior to calling */ void write_fifo(uint8_t len); /** transmit a packet * @param len size of packet * @note Limited to (lora fifo size 256) */ void start_tx(uint8_t len); /** start receive mode * @note the variable service_action needs to be monitored to indicate read_fifo() needs to be called to pull packet from FIFO. */ void start_rx(void); /** Called by main program when indicated by service_action variable, to pull recevied packet from radio FIFO. * @returns count of bytes received * @note received packet in rx_buf[] */ void read_fifo(uint8_t len); /** CodingRate: how much FEC to encoding onto packet */ uint8_t getCodingRate(bool from_rx); // false:transmitted, true:last recevied packet void setCodingRate(uint8_t cr); /** HeaderMode: explicit mode sents CodingRate and payload length, implicit mode requires assumption by receiver */ bool getHeaderMode(void); void setHeaderMode(bool hm); /** bandwidth: SX1272 has three bandwidths. SX1276 adds more narrower bandwidths. */ uint8_t getBw(void); void setBw(uint8_t bw); /** spreading factor: trade-off between data rate and processing gain (link budget) */ uint8_t getSf(void); void setSf(uint8_t sf); /** enable CRC in transmitted packet */ bool getRxPayloadCrcOn(void); void setRxPayloadCrcOn(bool); bool getAgcAutoOn(void); void setAgcAutoOn(bool); float get_pkt_rssi(void); /** retrieve symbol duration from bandwidth and spreading factor * @returns symbol duration in milliseconds */ float get_symbol_period(void); service_action_e service(void); // (SLIH) ISR bottom half bool poll_vh; void set_nb_trig_peaks(int); RegIrqFlags_t RegIrqFlags; // 0x12 uint8_t RegRxNbBytes; // 0x13 RegModemStatus_t RegModemStatus; // 0x18 int8_t RegPktSnrValue; // 0x19 signed, s/n can be negative uint8_t RegPktRssiValue; // 0x1a RegHopChannel_t RegHopChannel; // 0x1c RegModemConfig_t RegModemConfig; // 0x1d RegModemConfig2_t RegModemConfig2; // 0x1e uint16_t RegPreamble; // 0x20->0x21 uint8_t RegPayloadLength; // 0x22 uint8_t RegRxMaxPayloadLength; // 0x23 uint8_t RegHopPeriod; // 0x24 RegModemConfig3_t RegModemConfig3; // 0x26 RegTest31_t RegTest31; // 0x31 SX127x& m_xcvr; private: };