Driver library for SX1272/SX1276 transceivers
Fork of SX127x by
sx127x_lora.h@7:c785b65d3db4, 2014-09-04 (annotated)
- Committer:
- efountain
- Date:
- Thu Sep 04 20:57:28 2014 +0000
- Revision:
- 7:c785b65d3db4
- Parent:
- 3:3bf2515b1eed
Updated SX127x library...NorAm Mote
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
dudmuck | 2:fdae76e1215e | 1 | #include "sx127x.h" |
dudmuck | 2:fdae76e1215e | 2 | |
dudmuck | 2:fdae76e1215e | 3 | // LoRa registers |
dudmuck | 2:fdae76e1215e | 4 | #define REG_LR_FIFOADDRPTR 0x0d |
dudmuck | 2:fdae76e1215e | 5 | #define REG_LR_FIFOTXBASEADDR 0x0e |
dudmuck | 2:fdae76e1215e | 6 | #define REG_LR_FIFORXBASEADDR 0x0f |
dudmuck | 2:fdae76e1215e | 7 | #define REG_LR_FIFORXCURRENTADDR /*REG_LR_RXDATAADDR*/ 0x10 |
dudmuck | 2:fdae76e1215e | 8 | #define REG_LR_IRQFLAGSMASK 0x11 |
dudmuck | 2:fdae76e1215e | 9 | #define REG_LR_IRQFLAGS 0x12 |
dudmuck | 2:fdae76e1215e | 10 | #define REG_LR_RXNBBYTES 0x13 |
dudmuck | 2:fdae76e1215e | 11 | #define REG_LR_RXHEADERCNTVALUE_MSB 0x14 |
dudmuck | 2:fdae76e1215e | 12 | #define REG_LR_RXHEADERCNTVALUE_LSB 0x15 |
dudmuck | 2:fdae76e1215e | 13 | #define REG_LR_RXPACKETCNTVALUE_MSB 0x16 |
dudmuck | 2:fdae76e1215e | 14 | #define REG_LR_RXPACKETCNTVALUE_LSB 0x17 |
dudmuck | 2:fdae76e1215e | 15 | #define REG_LR_MODEMSTAT 0x18 |
dudmuck | 2:fdae76e1215e | 16 | #define REG_LR_PKTSNRVALUE 0x19 |
dudmuck | 2:fdae76e1215e | 17 | #define REG_LR_PKTRSSIVALUE 0x1a |
dudmuck | 2:fdae76e1215e | 18 | #define REG_LR_RSSIVALUE 0x1b |
dudmuck | 2:fdae76e1215e | 19 | #define REG_LR_HOPCHANNEL 0x1c |
dudmuck | 2:fdae76e1215e | 20 | #define REG_LR_MODEMCONFIG 0x1d |
dudmuck | 2:fdae76e1215e | 21 | #define REG_LR_MODEMCONFIG2 0x1e |
dudmuck | 2:fdae76e1215e | 22 | #define REG_LR_SYMBTIMEOUTLSB 0x1f |
dudmuck | 2:fdae76e1215e | 23 | #define REG_LR_PREAMBLEMSB 0x20 |
dudmuck | 2:fdae76e1215e | 24 | #define REG_LR_PREAMBLELSB 0x21 |
dudmuck | 2:fdae76e1215e | 25 | #define REG_LR_PAYLOADLENGTH 0x22 // and RX length for implicit |
dudmuck | 2:fdae76e1215e | 26 | #define REG_LR_RX_MAX_PAYLOADLENGTH 0x23 // length limit for explicit mode |
dudmuck | 2:fdae76e1215e | 27 | #define REG_LR_HOPPERIOD 0x24 |
dudmuck | 2:fdae76e1215e | 28 | #define REG_LR_RXBYTEADDR /*REG_LR_RXDATAADDR*/ 0x25 |
dudmuck | 2:fdae76e1215e | 29 | #define REG_LR_MODEMCONFIG3 0x26 // sx1272 REG_LR_PPM_CORRECTION_MSB |
dudmuck | 2:fdae76e1215e | 30 | #define REG_LR_PPM_CORRECTION_LSB 0x27 |
dudmuck | 2:fdae76e1215e | 31 | #define REG_LR_TEST28 0x28 // est_freq_error |
dudmuck | 2:fdae76e1215e | 32 | #define REG_LR_TEST29 0x29 // est_freq_error |
dudmuck | 2:fdae76e1215e | 33 | #define REG_LR_TEST2A 0x2a // est_freq_error |
dudmuck | 2:fdae76e1215e | 34 | #define REG_LR_TEST2B 0x2b // |
dudmuck | 2:fdae76e1215e | 35 | #define REG_LR_WIDEBAND_RSSI 0x2c |
dudmuck | 2:fdae76e1215e | 36 | #define REG_LR_AGCH_TH 0x2d // agc_upper_th |
dudmuck | 2:fdae76e1215e | 37 | #define REG_LR_AGCL_TH 0x2e // agc_lower_th |
dudmuck | 2:fdae76e1215e | 38 | #define REG_LR_IFFRQH 0x2f // if_freq(12:8) |
dudmuck | 2:fdae76e1215e | 39 | #define REG_LR_IFFRQL 0x30 // if_freq(7:0) |
dudmuck | 2:fdae76e1215e | 40 | #define REG_LR_TEST31 0x31 // if_freq_auto, ... |
dudmuck | 2:fdae76e1215e | 41 | #define REG_LR_TEST32 0x32 // |
dudmuck | 2:fdae76e1215e | 42 | #define REG_LR_TEST33 0x33 |
dudmuck | 2:fdae76e1215e | 43 | #define REG_LR_DETECTION_THRESHOLD 0x37 |
dudmuck | 2:fdae76e1215e | 44 | |
dudmuck | 2:fdae76e1215e | 45 | typedef union { |
dudmuck | 2:fdae76e1215e | 46 | struct { // sx127x register 0x12 |
dudmuck | 2:fdae76e1215e | 47 | uint8_t CadDetected : 1; // 0 |
dudmuck | 2:fdae76e1215e | 48 | uint8_t FhssChangeChannel : 1; // 1 |
dudmuck | 2:fdae76e1215e | 49 | uint8_t CadDone : 1; // 2 |
dudmuck | 2:fdae76e1215e | 50 | uint8_t TxDone : 1; // 3 |
dudmuck | 2:fdae76e1215e | 51 | uint8_t ValidHeader : 1; // 4 |
dudmuck | 2:fdae76e1215e | 52 | uint8_t PayloadCrcError : 1; // 5 |
dudmuck | 2:fdae76e1215e | 53 | uint8_t RxDone : 1; // 6 |
dudmuck | 2:fdae76e1215e | 54 | uint8_t RxTimeout : 1; // 7 |
dudmuck | 2:fdae76e1215e | 55 | } bits; |
dudmuck | 2:fdae76e1215e | 56 | uint8_t octet; |
dudmuck | 2:fdae76e1215e | 57 | } RegIrqFlags_t; |
dudmuck | 2:fdae76e1215e | 58 | |
dudmuck | 2:fdae76e1215e | 59 | typedef union { |
dudmuck | 2:fdae76e1215e | 60 | struct { // sx127x register 0x18 |
dudmuck | 2:fdae76e1215e | 61 | uint8_t detect : 1; // 0 |
dudmuck | 2:fdae76e1215e | 62 | uint8_t sync : 1; // 1 |
dudmuck | 2:fdae76e1215e | 63 | uint8_t rx_ongoing : 1; // 2 |
dudmuck | 2:fdae76e1215e | 64 | uint8_t header_valid : 1; // 3 |
dudmuck | 2:fdae76e1215e | 65 | uint8_t clear : 1; // 4 |
dudmuck | 2:fdae76e1215e | 66 | uint8_t RxCodingRate : 3; // 5,6,7 |
dudmuck | 2:fdae76e1215e | 67 | } bits; |
dudmuck | 2:fdae76e1215e | 68 | uint8_t octet; |
dudmuck | 2:fdae76e1215e | 69 | } RegModemStatus_t; |
dudmuck | 2:fdae76e1215e | 70 | |
dudmuck | 2:fdae76e1215e | 71 | typedef union { |
dudmuck | 2:fdae76e1215e | 72 | struct { // sx127x register 0x1c |
dudmuck | 2:fdae76e1215e | 73 | uint8_t FhssPresentChannel : 6; // 0,1,2,3,4,5 |
dudmuck | 2:fdae76e1215e | 74 | uint8_t RxPayloadCrcOn : 1; // 6 |
dudmuck | 2:fdae76e1215e | 75 | uint8_t PllTimeout : 1; // 7 |
dudmuck | 2:fdae76e1215e | 76 | } bits; |
dudmuck | 2:fdae76e1215e | 77 | uint8_t octet; |
dudmuck | 2:fdae76e1215e | 78 | } RegHopChannel_t; |
dudmuck | 2:fdae76e1215e | 79 | |
dudmuck | 2:fdae76e1215e | 80 | typedef union { |
dudmuck | 2:fdae76e1215e | 81 | struct { // sx1276 register 0x1d |
dudmuck | 2:fdae76e1215e | 82 | uint8_t ImplicitHeaderModeOn : 1; // 0 |
dudmuck | 2:fdae76e1215e | 83 | uint8_t CodingRate : 3; // 1,2,3 |
dudmuck | 2:fdae76e1215e | 84 | uint8_t Bw : 4; // 4,5,6,7 |
dudmuck | 2:fdae76e1215e | 85 | } sx1276bits; |
dudmuck | 2:fdae76e1215e | 86 | struct { // sx1272 register 0x1d |
dudmuck | 2:fdae76e1215e | 87 | uint8_t LowDataRateOptimize : 1; // 0 ppm_offset: number of cyclic shifts possible to encode to symbol |
dudmuck | 2:fdae76e1215e | 88 | uint8_t RxPayloadCrcOn : 1; // 1 |
dudmuck | 2:fdae76e1215e | 89 | uint8_t ImplicitHeaderModeOn : 1; // 2 |
dudmuck | 2:fdae76e1215e | 90 | uint8_t CodingRate : 3; // 3,4,5 |
dudmuck | 2:fdae76e1215e | 91 | uint8_t Bw : 2; // 6,7 |
dudmuck | 2:fdae76e1215e | 92 | } sx1272bits; |
dudmuck | 2:fdae76e1215e | 93 | uint8_t octet; |
dudmuck | 2:fdae76e1215e | 94 | } RegModemConfig_t; |
dudmuck | 2:fdae76e1215e | 95 | |
dudmuck | 2:fdae76e1215e | 96 | typedef union { |
dudmuck | 2:fdae76e1215e | 97 | struct { // sx1276 register 0x1e |
dudmuck | 2:fdae76e1215e | 98 | uint8_t SymbTimeoutMsb : 2; // 0,1 |
dudmuck | 2:fdae76e1215e | 99 | uint8_t RxPayloadCrcOn : 1; // 2 |
dudmuck | 2:fdae76e1215e | 100 | uint8_t TxContinuousMode : 1; // 3 |
dudmuck | 2:fdae76e1215e | 101 | uint8_t SpreadingFactor : 4; // 4,5,6,7 |
dudmuck | 2:fdae76e1215e | 102 | } sx1276bits; |
dudmuck | 2:fdae76e1215e | 103 | struct { // sx1272 register 0x1e |
dudmuck | 2:fdae76e1215e | 104 | uint8_t SymbTimeoutMsb : 2; // 0,1 |
dudmuck | 2:fdae76e1215e | 105 | uint8_t AgcAutoOn : 1; // 2 |
dudmuck | 2:fdae76e1215e | 106 | uint8_t TxContinuousMode : 1; // 3 |
dudmuck | 2:fdae76e1215e | 107 | uint8_t SpreadingFactor : 4; // 4,5,6,7 |
dudmuck | 2:fdae76e1215e | 108 | } sx1272bits; |
dudmuck | 2:fdae76e1215e | 109 | uint8_t octet; |
dudmuck | 2:fdae76e1215e | 110 | } RegModemConfig2_t; |
dudmuck | 2:fdae76e1215e | 111 | |
dudmuck | 2:fdae76e1215e | 112 | typedef union { |
dudmuck | 2:fdae76e1215e | 113 | struct { // sx127x register 0x26 |
dudmuck | 2:fdae76e1215e | 114 | uint8_t reserved : 2; // 0,1 |
dudmuck | 2:fdae76e1215e | 115 | uint8_t AgcAutoOn : 1; // 2 |
dudmuck | 2:fdae76e1215e | 116 | uint8_t LowDataRateOptimize : 1; // 3 ppm_offset |
dudmuck | 2:fdae76e1215e | 117 | uint8_t unused : 4; // 4,5,6,7 |
dudmuck | 2:fdae76e1215e | 118 | } sx1276bits; |
dudmuck | 2:fdae76e1215e | 119 | uint8_t octet; |
dudmuck | 2:fdae76e1215e | 120 | uint8_t sx1272_ppm_correction_msb; |
dudmuck | 2:fdae76e1215e | 121 | } RegModemConfig3_t; |
dudmuck | 2:fdae76e1215e | 122 | |
dudmuck | 2:fdae76e1215e | 123 | |
dudmuck | 2:fdae76e1215e | 124 | typedef union { |
dudmuck | 2:fdae76e1215e | 125 | struct { // sx127x register 0x31 |
dudmuck | 2:fdae76e1215e | 126 | uint8_t detect_trig_same_peaks_nb : 3; // 0,1,2 |
dudmuck | 2:fdae76e1215e | 127 | uint8_t disable_pll_timeout : 1; // 3 |
dudmuck | 2:fdae76e1215e | 128 | uint8_t tracking_intergral : 2; // 4,5 |
dudmuck | 2:fdae76e1215e | 129 | uint8_t frame_sync_gain : 1; // 6 |
dudmuck | 2:fdae76e1215e | 130 | uint8_t if_freq_auto : 1; // 7 |
dudmuck | 2:fdae76e1215e | 131 | } bits; |
dudmuck | 2:fdae76e1215e | 132 | uint8_t octet; |
dudmuck | 2:fdae76e1215e | 133 | } RegTest31_t; |
dudmuck | 2:fdae76e1215e | 134 | |
dudmuck | 2:fdae76e1215e | 135 | //class SX127x_lora : public SX127x |
dudmuck | 2:fdae76e1215e | 136 | class SX127x_lora { |
dudmuck | 2:fdae76e1215e | 137 | public: |
dudmuck | 2:fdae76e1215e | 138 | //SX127x_lora(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName rst, PinName dio_0, PinName dio_1, PinName fem_ctx, PinName fem_cps); |
dudmuck | 3:3bf2515b1eed | 139 | SX127x_lora(SX127x& r); |
dudmuck | 2:fdae76e1215e | 140 | |
dudmuck | 2:fdae76e1215e | 141 | ~SX127x_lora(); |
dudmuck | 2:fdae76e1215e | 142 | |
dudmuck | 2:fdae76e1215e | 143 | /** changes from FSK mode to LoRa mdoe */ |
dudmuck | 2:fdae76e1215e | 144 | void enable(void); |
dudmuck | 2:fdae76e1215e | 145 | |
dudmuck | 2:fdae76e1215e | 146 | /** fills radio FIFO with payload contents, prior to transmission |
dudmuck | 2:fdae76e1215e | 147 | * @param len count of bytes to put into FIFO |
dudmuck | 2:fdae76e1215e | 148 | * @note tx_buf[] should contain desired payload (to send) prior to calling |
dudmuck | 2:fdae76e1215e | 149 | */ |
dudmuck | 2:fdae76e1215e | 150 | void write_fifo(uint8_t len); |
dudmuck | 2:fdae76e1215e | 151 | |
dudmuck | 2:fdae76e1215e | 152 | /** transmit a packet |
dudmuck | 2:fdae76e1215e | 153 | * @param len size of packet |
dudmuck | 2:fdae76e1215e | 154 | * @note Limited to (lora fifo size 256) |
dudmuck | 2:fdae76e1215e | 155 | */ |
dudmuck | 2:fdae76e1215e | 156 | void start_tx(uint8_t len); |
dudmuck | 2:fdae76e1215e | 157 | |
dudmuck | 2:fdae76e1215e | 158 | /** start receive mode |
dudmuck | 2:fdae76e1215e | 159 | * @note the variable service_action needs to be monitored to indicate read_fifo() needs to be called to pull packet from FIFO. |
dudmuck | 2:fdae76e1215e | 160 | */ |
dudmuck | 2:fdae76e1215e | 161 | void start_rx(void); |
dudmuck | 2:fdae76e1215e | 162 | |
dudmuck | 2:fdae76e1215e | 163 | /** Called by main program when indicated by service_action variable, to pull recevied packet from radio FIFO. |
dudmuck | 2:fdae76e1215e | 164 | * @returns count of bytes received |
dudmuck | 2:fdae76e1215e | 165 | * @note received packet in rx_buf[] |
dudmuck | 2:fdae76e1215e | 166 | */ |
dudmuck | 2:fdae76e1215e | 167 | void read_fifo(uint8_t len); |
dudmuck | 2:fdae76e1215e | 168 | |
dudmuck | 2:fdae76e1215e | 169 | /** CodingRate: how much FEC to encoding onto packet */ |
dudmuck | 2:fdae76e1215e | 170 | uint8_t getCodingRate(bool from_rx); // false:transmitted, true:last recevied packet |
dudmuck | 2:fdae76e1215e | 171 | void setCodingRate(uint8_t cr); |
dudmuck | 2:fdae76e1215e | 172 | |
dudmuck | 2:fdae76e1215e | 173 | /** HeaderMode: explicit mode sents CodingRate and payload length, implicit mode requires assumption by receiver */ |
dudmuck | 2:fdae76e1215e | 174 | bool getHeaderMode(void); |
dudmuck | 2:fdae76e1215e | 175 | void setHeaderMode(bool hm); |
dudmuck | 2:fdae76e1215e | 176 | |
dudmuck | 2:fdae76e1215e | 177 | /** bandwidth: SX1272 has three bandwidths. SX1276 adds more narrower bandwidths. */ |
dudmuck | 2:fdae76e1215e | 178 | uint8_t getBw(void); |
dudmuck | 2:fdae76e1215e | 179 | void setBw(uint8_t bw); |
dudmuck | 2:fdae76e1215e | 180 | |
dudmuck | 2:fdae76e1215e | 181 | /** spreading factor: trade-off between data rate and processing gain (link budget) */ |
dudmuck | 2:fdae76e1215e | 182 | uint8_t getSf(void); |
dudmuck | 2:fdae76e1215e | 183 | void setSf(uint8_t sf); |
dudmuck | 2:fdae76e1215e | 184 | |
dudmuck | 2:fdae76e1215e | 185 | /** enable CRC in transmitted packet */ |
dudmuck | 2:fdae76e1215e | 186 | bool getRxPayloadCrcOn(void); |
dudmuck | 2:fdae76e1215e | 187 | void setRxPayloadCrcOn(bool); |
dudmuck | 2:fdae76e1215e | 188 | |
dudmuck | 2:fdae76e1215e | 189 | bool getAgcAutoOn(void); |
dudmuck | 2:fdae76e1215e | 190 | void setAgcAutoOn(bool); |
dudmuck | 2:fdae76e1215e | 191 | |
dudmuck | 2:fdae76e1215e | 192 | float get_pkt_rssi(void); |
dudmuck | 2:fdae76e1215e | 193 | |
dudmuck | 2:fdae76e1215e | 194 | service_action_e service(void); // (SLIH) ISR bottom half |
dudmuck | 2:fdae76e1215e | 195 | |
dudmuck | 2:fdae76e1215e | 196 | bool poll_vh; |
dudmuck | 2:fdae76e1215e | 197 | |
dudmuck | 2:fdae76e1215e | 198 | RegIrqFlags_t RegIrqFlags; // 0x12 |
dudmuck | 2:fdae76e1215e | 199 | uint8_t RegRxNbBytes; // 0x13 |
dudmuck | 2:fdae76e1215e | 200 | RegModemStatus_t RegModemStatus; // 0x18 |
dudmuck | 2:fdae76e1215e | 201 | int8_t RegPktSnrValue; // 0x19 signed, s/n can be negative |
dudmuck | 2:fdae76e1215e | 202 | uint8_t RegPktRssiValue; // 0x1a |
dudmuck | 2:fdae76e1215e | 203 | RegHopChannel_t RegHopChannel; // 0x1c |
dudmuck | 2:fdae76e1215e | 204 | RegModemConfig_t RegModemConfig; // 0x1d |
dudmuck | 2:fdae76e1215e | 205 | RegModemConfig2_t RegModemConfig2; // 0x1e |
dudmuck | 2:fdae76e1215e | 206 | uint16_t RegPreamble; // 0x20->0x21 |
dudmuck | 2:fdae76e1215e | 207 | uint8_t RegPayloadLength; // 0x22 |
dudmuck | 2:fdae76e1215e | 208 | uint8_t RegRxMaxPayloadLength; // 0x23 |
dudmuck | 2:fdae76e1215e | 209 | uint8_t RegHopPeriod; // 0x24 |
dudmuck | 2:fdae76e1215e | 210 | RegModemConfig3_t RegModemConfig3; // 0x26 |
dudmuck | 2:fdae76e1215e | 211 | RegTest31_t RegTest31; // 0x31 |
dudmuck | 2:fdae76e1215e | 212 | |
dudmuck | 2:fdae76e1215e | 213 | private: |
dudmuck | 3:3bf2515b1eed | 214 | SX127x& m_xcvr; |
dudmuck | 2:fdae76e1215e | 215 | void set_nb_trig_peaks(int); |
dudmuck | 2:fdae76e1215e | 216 | }; |