123

Committer:
dudmuck
Date:
Wed May 27 22:42:30 2015 +0000
Revision:
17:59279bc8cdab
Parent:
16:3de8e1c465eb
Child:
18:0ecb6adb7c0b
added support for LoRa inverted spectrum

Who changed what in which revision?

UserRevisionLine numberNew 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 15:3f3fc6792f97 42 #define REG_LR_TEST33 0x33 // invert IQ
dudmuck 11:4210303ac88d 43 #define REG_LR_CAD_PEAK_TO_NOISE_RATIO 0x34
dudmuck 11:4210303ac88d 44 #define REG_LR_CAD_MIN_PEAK 0x35
dudmuck 2:fdae76e1215e 45 #define REG_LR_DETECTION_THRESHOLD 0x37
dudmuck 11:4210303ac88d 46 #define REG_LR_SYNC_BYTE 0x39 // default 0x12 (value of 0x21 will isolate network)
dudmuck 17:59279bc8cdab 47 #define REG_LR_DRIFT_INVERT 0x3b
dudmuck 2:fdae76e1215e 48
dudmuck 2:fdae76e1215e 49 typedef union {
dudmuck 2:fdae76e1215e 50 struct { // sx127x register 0x12
dudmuck 2:fdae76e1215e 51 uint8_t CadDetected : 1; // 0
dudmuck 2:fdae76e1215e 52 uint8_t FhssChangeChannel : 1; // 1
dudmuck 2:fdae76e1215e 53 uint8_t CadDone : 1; // 2
dudmuck 2:fdae76e1215e 54 uint8_t TxDone : 1; // 3
dudmuck 2:fdae76e1215e 55 uint8_t ValidHeader : 1; // 4
dudmuck 2:fdae76e1215e 56 uint8_t PayloadCrcError : 1; // 5
dudmuck 2:fdae76e1215e 57 uint8_t RxDone : 1; // 6
dudmuck 2:fdae76e1215e 58 uint8_t RxTimeout : 1; // 7
dudmuck 2:fdae76e1215e 59 } bits;
dudmuck 2:fdae76e1215e 60 uint8_t octet;
dudmuck 2:fdae76e1215e 61 } RegIrqFlags_t;
dudmuck 2:fdae76e1215e 62
dudmuck 2:fdae76e1215e 63 typedef union {
dudmuck 2:fdae76e1215e 64 struct { // sx127x register 0x18
dudmuck 2:fdae76e1215e 65 uint8_t detect : 1; // 0
dudmuck 2:fdae76e1215e 66 uint8_t sync : 1; // 1
dudmuck 2:fdae76e1215e 67 uint8_t rx_ongoing : 1; // 2
dudmuck 2:fdae76e1215e 68 uint8_t header_valid : 1; // 3
dudmuck 2:fdae76e1215e 69 uint8_t clear : 1; // 4
dudmuck 2:fdae76e1215e 70 uint8_t RxCodingRate : 3; // 5,6,7
dudmuck 2:fdae76e1215e 71 } bits;
dudmuck 2:fdae76e1215e 72 uint8_t octet;
dudmuck 2:fdae76e1215e 73 } RegModemStatus_t;
dudmuck 2:fdae76e1215e 74
dudmuck 2:fdae76e1215e 75 typedef union {
dudmuck 2:fdae76e1215e 76 struct { // sx127x register 0x1c
dudmuck 2:fdae76e1215e 77 uint8_t FhssPresentChannel : 6; // 0,1,2,3,4,5
dudmuck 2:fdae76e1215e 78 uint8_t RxPayloadCrcOn : 1; // 6
dudmuck 2:fdae76e1215e 79 uint8_t PllTimeout : 1; // 7
dudmuck 2:fdae76e1215e 80 } bits;
dudmuck 2:fdae76e1215e 81 uint8_t octet;
dudmuck 2:fdae76e1215e 82 } RegHopChannel_t;
dudmuck 2:fdae76e1215e 83
dudmuck 2:fdae76e1215e 84 typedef union {
dudmuck 2:fdae76e1215e 85 struct { // sx1276 register 0x1d
dudmuck 2:fdae76e1215e 86 uint8_t ImplicitHeaderModeOn : 1; // 0
dudmuck 2:fdae76e1215e 87 uint8_t CodingRate : 3; // 1,2,3
dudmuck 2:fdae76e1215e 88 uint8_t Bw : 4; // 4,5,6,7
dudmuck 2:fdae76e1215e 89 } sx1276bits;
dudmuck 2:fdae76e1215e 90 struct { // sx1272 register 0x1d
dudmuck 2:fdae76e1215e 91 uint8_t LowDataRateOptimize : 1; // 0 ppm_offset: number of cyclic shifts possible to encode to symbol
dudmuck 2:fdae76e1215e 92 uint8_t RxPayloadCrcOn : 1; // 1
dudmuck 2:fdae76e1215e 93 uint8_t ImplicitHeaderModeOn : 1; // 2
dudmuck 2:fdae76e1215e 94 uint8_t CodingRate : 3; // 3,4,5
dudmuck 2:fdae76e1215e 95 uint8_t Bw : 2; // 6,7
dudmuck 2:fdae76e1215e 96 } sx1272bits;
dudmuck 2:fdae76e1215e 97 uint8_t octet;
dudmuck 2:fdae76e1215e 98 } RegModemConfig_t;
dudmuck 2:fdae76e1215e 99
dudmuck 2:fdae76e1215e 100 typedef union {
dudmuck 2:fdae76e1215e 101 struct { // sx1276 register 0x1e
dudmuck 2:fdae76e1215e 102 uint8_t SymbTimeoutMsb : 2; // 0,1
dudmuck 2:fdae76e1215e 103 uint8_t RxPayloadCrcOn : 1; // 2
dudmuck 2:fdae76e1215e 104 uint8_t TxContinuousMode : 1; // 3
dudmuck 2:fdae76e1215e 105 uint8_t SpreadingFactor : 4; // 4,5,6,7
dudmuck 2:fdae76e1215e 106 } sx1276bits;
dudmuck 2:fdae76e1215e 107 struct { // sx1272 register 0x1e
dudmuck 2:fdae76e1215e 108 uint8_t SymbTimeoutMsb : 2; // 0,1
dudmuck 2:fdae76e1215e 109 uint8_t AgcAutoOn : 1; // 2
dudmuck 2:fdae76e1215e 110 uint8_t TxContinuousMode : 1; // 3
dudmuck 2:fdae76e1215e 111 uint8_t SpreadingFactor : 4; // 4,5,6,7
dudmuck 2:fdae76e1215e 112 } sx1272bits;
dudmuck 2:fdae76e1215e 113 uint8_t octet;
dudmuck 2:fdae76e1215e 114 } RegModemConfig2_t;
dudmuck 2:fdae76e1215e 115
dudmuck 2:fdae76e1215e 116 typedef union {
dudmuck 2:fdae76e1215e 117 struct { // sx127x register 0x26
dudmuck 2:fdae76e1215e 118 uint8_t reserved : 2; // 0,1
dudmuck 2:fdae76e1215e 119 uint8_t AgcAutoOn : 1; // 2
dudmuck 10:7382c260c4b1 120 uint8_t LowDataRateOptimize : 1; // 3 ppm_offset, use when symbol duration exceeds 16ms
dudmuck 2:fdae76e1215e 121 uint8_t unused : 4; // 4,5,6,7
dudmuck 2:fdae76e1215e 122 } sx1276bits;
dudmuck 2:fdae76e1215e 123 uint8_t octet;
dudmuck 2:fdae76e1215e 124 uint8_t sx1272_ppm_correction_msb;
dudmuck 2:fdae76e1215e 125 } RegModemConfig3_t;
dudmuck 2:fdae76e1215e 126
dudmuck 2:fdae76e1215e 127
dudmuck 2:fdae76e1215e 128 typedef union {
dudmuck 2:fdae76e1215e 129 struct { // sx127x register 0x31
dudmuck 2:fdae76e1215e 130 uint8_t detect_trig_same_peaks_nb : 3; // 0,1,2
dudmuck 2:fdae76e1215e 131 uint8_t disable_pll_timeout : 1; // 3
dudmuck 2:fdae76e1215e 132 uint8_t tracking_intergral : 2; // 4,5
dudmuck 2:fdae76e1215e 133 uint8_t frame_sync_gain : 1; // 6
dudmuck 2:fdae76e1215e 134 uint8_t if_freq_auto : 1; // 7
dudmuck 2:fdae76e1215e 135 } bits;
dudmuck 2:fdae76e1215e 136 uint8_t octet;
dudmuck 2:fdae76e1215e 137 } RegTest31_t;
dudmuck 2:fdae76e1215e 138
dudmuck 15:3f3fc6792f97 139 typedef union {
dudmuck 15:3f3fc6792f97 140 struct { // sx127x register 0x33
dudmuck 17:59279bc8cdab 141 uint8_t chirp_invert_tx : 1; // 0 invert TX spreading sequence (default=1)
dudmuck 17:59279bc8cdab 142 uint8_t chirp_invert_rx : 1; // 1 invert chip direction in RX mode (default=1)
dudmuck 15:3f3fc6792f97 143 uint8_t sync_detect_th : 1; // 2 require 6dB despread SNR during preamble
dudmuck 15:3f3fc6792f97 144 uint8_t invert_coef_phase : 1; // 3
dudmuck 15:3f3fc6792f97 145 uint8_t invert_coef_amp : 1; // 4
dudmuck 15:3f3fc6792f97 146 uint8_t quad_correction_en : 1; // 5 enable IQ compensation
dudmuck 17:59279bc8cdab 147 uint8_t invert_i_q : 1; // 6 RX invert (default=0)
dudmuck 15:3f3fc6792f97 148 uint8_t start_rambist : 1; // 7
dudmuck 15:3f3fc6792f97 149 } bits;
dudmuck 15:3f3fc6792f97 150 uint8_t octet;
dudmuck 15:3f3fc6792f97 151 } RegTest33_t;
dudmuck 15:3f3fc6792f97 152
dudmuck 17:59279bc8cdab 153 typedef union {
dudmuck 17:59279bc8cdab 154 struct { // sx127x register 0x3b
dudmuck 17:59279bc8cdab 155 uint8_t coarse_sync : 1; // 0 must be set to 1
dudmuck 17:59279bc8cdab 156 uint8_t fine_sync : 1; // 1 must be clr to 0
dudmuck 17:59279bc8cdab 157 uint8_t invert_timing_error_per_symbol : 1; // 2 set to !invert_i_q
dudmuck 17:59279bc8cdab 158 uint8_t invert_freq_error : 1; // 3
dudmuck 17:59279bc8cdab 159 uint8_t invert_delta_sampling : 1; // 4 must be set to 1
dudmuck 17:59279bc8cdab 160 uint8_t reserved : 1; // 5 must be clr to 0
dudmuck 17:59279bc8cdab 161 uint8_t invert_fast_timing : 1; // 6
dudmuck 17:59279bc8cdab 162 uint8_t invert_carry_in : 1; // 7
dudmuck 17:59279bc8cdab 163 } bits;
dudmuck 17:59279bc8cdab 164 uint8_t octet;
dudmuck 17:59279bc8cdab 165 } RegDriftInvert_t;
dudmuck 17:59279bc8cdab 166
dudmuck 17:59279bc8cdab 167
dudmuck 2:fdae76e1215e 168 //class SX127x_lora : public SX127x
dudmuck 2:fdae76e1215e 169 class SX127x_lora {
dudmuck 2:fdae76e1215e 170 public:
dudmuck 2:fdae76e1215e 171 //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 172 SX127x_lora(SX127x& r);
dudmuck 2:fdae76e1215e 173
dudmuck 2:fdae76e1215e 174 ~SX127x_lora();
dudmuck 2:fdae76e1215e 175
dudmuck 2:fdae76e1215e 176 /** changes from FSK mode to LoRa mdoe */
dudmuck 2:fdae76e1215e 177 void enable(void);
dudmuck 2:fdae76e1215e 178
dudmuck 2:fdae76e1215e 179 /** fills radio FIFO with payload contents, prior to transmission
dudmuck 2:fdae76e1215e 180 * @param len count of bytes to put into FIFO
dudmuck 2:fdae76e1215e 181 * @note tx_buf[] should contain desired payload (to send) prior to calling
dudmuck 2:fdae76e1215e 182 */
dudmuck 2:fdae76e1215e 183 void write_fifo(uint8_t len);
dudmuck 2:fdae76e1215e 184
dudmuck 2:fdae76e1215e 185 /** transmit a packet
dudmuck 2:fdae76e1215e 186 * @param len size of packet
dudmuck 2:fdae76e1215e 187 * @note Limited to (lora fifo size 256)
dudmuck 2:fdae76e1215e 188 */
dudmuck 2:fdae76e1215e 189 void start_tx(uint8_t len);
dudmuck 2:fdae76e1215e 190
dudmuck 2:fdae76e1215e 191 /** start receive mode
dudmuck 2:fdae76e1215e 192 * @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 193 */
dudmuck 2:fdae76e1215e 194 void start_rx(void);
dudmuck 2:fdae76e1215e 195
dudmuck 2:fdae76e1215e 196 /** Called by main program when indicated by service_action variable, to pull recevied packet from radio FIFO.
dudmuck 2:fdae76e1215e 197 * @returns count of bytes received
dudmuck 2:fdae76e1215e 198 * @note received packet in rx_buf[]
dudmuck 2:fdae76e1215e 199 */
dudmuck 2:fdae76e1215e 200 void read_fifo(uint8_t len);
dudmuck 2:fdae76e1215e 201
dudmuck 2:fdae76e1215e 202 /** CodingRate: how much FEC to encoding onto packet */
dudmuck 2:fdae76e1215e 203 uint8_t getCodingRate(bool from_rx); // false:transmitted, true:last recevied packet
dudmuck 2:fdae76e1215e 204 void setCodingRate(uint8_t cr);
dudmuck 2:fdae76e1215e 205
dudmuck 2:fdae76e1215e 206 /** HeaderMode: explicit mode sents CodingRate and payload length, implicit mode requires assumption by receiver */
dudmuck 2:fdae76e1215e 207 bool getHeaderMode(void);
dudmuck 2:fdae76e1215e 208 void setHeaderMode(bool hm);
dudmuck 2:fdae76e1215e 209
dudmuck 2:fdae76e1215e 210 /** bandwidth: SX1272 has three bandwidths. SX1276 adds more narrower bandwidths. */
dudmuck 2:fdae76e1215e 211 uint8_t getBw(void);
dudmuck 2:fdae76e1215e 212 void setBw(uint8_t bw);
dudmuck 2:fdae76e1215e 213
dudmuck 16:3de8e1c465eb 214 /** Set bandwidth in KHz *
dudmuck 16:3de8e1c465eb 215 * @param khz lora bandwidth in KHz
dudmuck 16:3de8e1c465eb 216 */
dudmuck 16:3de8e1c465eb 217 void setBw_KHz(int khz);
dudmuck 16:3de8e1c465eb 218
dudmuck 2:fdae76e1215e 219 /** spreading factor: trade-off between data rate and processing gain (link budget) */
dudmuck 2:fdae76e1215e 220 uint8_t getSf(void);
dudmuck 2:fdae76e1215e 221 void setSf(uint8_t sf);
dudmuck 2:fdae76e1215e 222
dudmuck 2:fdae76e1215e 223 /** enable CRC in transmitted packet */
dudmuck 2:fdae76e1215e 224 bool getRxPayloadCrcOn(void);
dudmuck 2:fdae76e1215e 225 void setRxPayloadCrcOn(bool);
dudmuck 2:fdae76e1215e 226
dudmuck 2:fdae76e1215e 227 bool getAgcAutoOn(void);
dudmuck 2:fdae76e1215e 228 void setAgcAutoOn(bool);
dudmuck 2:fdae76e1215e 229
dudmuck 2:fdae76e1215e 230 float get_pkt_rssi(void);
dudmuck 2:fdae76e1215e 231
dudmuck 10:7382c260c4b1 232 /** retrieve symbol duration from bandwidth and spreading factor
dudmuck 10:7382c260c4b1 233 * @returns symbol duration in milliseconds
dudmuck 10:7382c260c4b1 234 */
dudmuck 10:7382c260c4b1 235 float get_symbol_period(void);
dudmuck 10:7382c260c4b1 236
dudmuck 2:fdae76e1215e 237 service_action_e service(void); // (SLIH) ISR bottom half
dudmuck 2:fdae76e1215e 238
dudmuck 2:fdae76e1215e 239 bool poll_vh;
dudmuck 2:fdae76e1215e 240
dudmuck 14:f39b9bf5290f 241 void set_nb_trig_peaks(int);
dudmuck 14:f39b9bf5290f 242
dudmuck 15:3f3fc6792f97 243 /** get receiver difference in RF frequency
dudmuck 15:3f3fc6792f97 244 * @returns hertz
dudmuck 15:3f3fc6792f97 245 * @note if receiver is lower in frequency than transmitter, a negative Hz will be returned
dudmuck 15:3f3fc6792f97 246 */
dudmuck 15:3f3fc6792f97 247 int get_freq_error_Hz(void);
dudmuck 15:3f3fc6792f97 248
dudmuck 17:59279bc8cdab 249
dudmuck 17:59279bc8cdab 250 /** invert transmitted spectrum */
dudmuck 17:59279bc8cdab 251 void invert_tx(bool);
dudmuck 17:59279bc8cdab 252
dudmuck 17:59279bc8cdab 253 /** invert spectrum on receiver */
dudmuck 17:59279bc8cdab 254 void invert_rx(bool);
dudmuck 17:59279bc8cdab 255
dudmuck 2:fdae76e1215e 256 RegIrqFlags_t RegIrqFlags; // 0x12
dudmuck 2:fdae76e1215e 257 uint8_t RegRxNbBytes; // 0x13
dudmuck 2:fdae76e1215e 258 RegModemStatus_t RegModemStatus; // 0x18
dudmuck 2:fdae76e1215e 259 int8_t RegPktSnrValue; // 0x19 signed, s/n can be negative
dudmuck 2:fdae76e1215e 260 uint8_t RegPktRssiValue; // 0x1a
dudmuck 2:fdae76e1215e 261 RegHopChannel_t RegHopChannel; // 0x1c
dudmuck 2:fdae76e1215e 262 RegModemConfig_t RegModemConfig; // 0x1d
dudmuck 2:fdae76e1215e 263 RegModemConfig2_t RegModemConfig2; // 0x1e
dudmuck 2:fdae76e1215e 264 uint16_t RegPreamble; // 0x20->0x21
dudmuck 2:fdae76e1215e 265 uint8_t RegPayloadLength; // 0x22
dudmuck 2:fdae76e1215e 266 uint8_t RegRxMaxPayloadLength; // 0x23
dudmuck 2:fdae76e1215e 267 uint8_t RegHopPeriod; // 0x24
dudmuck 2:fdae76e1215e 268 RegModemConfig3_t RegModemConfig3; // 0x26
dudmuck 2:fdae76e1215e 269 RegTest31_t RegTest31; // 0x31
dudmuck 17:59279bc8cdab 270 RegTest33_t RegTest33; // 0x33
dudmuck 17:59279bc8cdab 271 RegDriftInvert_t RegDriftInvert; // 0x3b
dudmuck 2:fdae76e1215e 272
dudmuck 9:ae1a71ccd730 273 SX127x& m_xcvr;
dudmuck 12:bda42457c34a 274
dudmuck 2:fdae76e1215e 275 private:
dudmuck 14:f39b9bf5290f 276
dudmuck 2:fdae76e1215e 277 };