Driver library for SX1272/SX1276 transceivers

Dependents:   LORA_RX LORA_TX WindConcentrator hid_test ... more

/media/uploads/dudmuck/lora.png

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.

/media/uploads/dudmuck/sx1272rf1_connector_300.jpg

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

Committer:
dudmuck
Date:
Fri Apr 17 01:32:32 2015 +0000
Revision:
13:1953e70522aa
Parent:
12:bda42457c34a
Child:
15:3f3fc6792f97
lora start_rx: start receiver sooner.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dudmuck 2:fdae76e1215e 1 #include "sx127x_lora.h"
dudmuck 2:fdae76e1215e 2
dudmuck 2:fdae76e1215e 3 /* SX127x driver
dudmuck 2:fdae76e1215e 4 * Copyright (c) 2013 Semtech
dudmuck 2:fdae76e1215e 5 *
dudmuck 2:fdae76e1215e 6 * Licensed under the Apache License, Version 2.0 (the "License");
dudmuck 2:fdae76e1215e 7 * you may not use this file except in compliance with the License.
dudmuck 2:fdae76e1215e 8 * You may obtain a copy of the License at
dudmuck 2:fdae76e1215e 9 *
dudmuck 2:fdae76e1215e 10 * http://www.apache.org/licenses/LICENSE-2.0
dudmuck 2:fdae76e1215e 11 *
dudmuck 2:fdae76e1215e 12 * Unless required by applicable law or agreed to in writing, software
dudmuck 2:fdae76e1215e 13 * distributed under the License is distributed on an "AS IS" BASIS,
dudmuck 2:fdae76e1215e 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
dudmuck 2:fdae76e1215e 15 * See the License for the specific language governing permissions and
dudmuck 2:fdae76e1215e 16 * limitations under the License.
dudmuck 2:fdae76e1215e 17 */
dudmuck 2:fdae76e1215e 18
dudmuck 3:3bf2515b1eed 19 SX127x_lora::SX127x_lora(SX127x& r) : m_xcvr(r)
dudmuck 2:fdae76e1215e 20 {
dudmuck 2:fdae76e1215e 21 RegModemConfig.octet = m_xcvr.read_reg(REG_LR_MODEMCONFIG);
dudmuck 2:fdae76e1215e 22 RegModemConfig2.octet = m_xcvr.read_reg(REG_LR_MODEMCONFIG2);
dudmuck 2:fdae76e1215e 23 RegTest31.octet = m_xcvr.read_reg(REG_LR_TEST31);
dudmuck 2:fdae76e1215e 24
dudmuck 2:fdae76e1215e 25 // CRC for TX is disabled by default
dudmuck 2:fdae76e1215e 26 setRxPayloadCrcOn(true);
dudmuck 2:fdae76e1215e 27 }
dudmuck 2:fdae76e1215e 28
dudmuck 2:fdae76e1215e 29 SX127x_lora::~SX127x_lora()
dudmuck 2:fdae76e1215e 30 {
dudmuck 2:fdae76e1215e 31 }
dudmuck 2:fdae76e1215e 32
dudmuck 2:fdae76e1215e 33 void SX127x_lora::write_fifo(uint8_t len)
dudmuck 2:fdae76e1215e 34 {
dudmuck 2:fdae76e1215e 35 int i;
dudmuck 2:fdae76e1215e 36
dudmuck 2:fdae76e1215e 37 m_xcvr.m_cs = 0;
dudmuck 2:fdae76e1215e 38 m_xcvr.m_spi.write(REG_FIFO | 0x80); // bit7 is high for writing to radio
dudmuck 2:fdae76e1215e 39
dudmuck 2:fdae76e1215e 40 for (i = 0; i < len; i++) {
dudmuck 2:fdae76e1215e 41 m_xcvr.m_spi.write(m_xcvr.tx_buf[i]);
dudmuck 2:fdae76e1215e 42 }
dudmuck 2:fdae76e1215e 43 m_xcvr.m_cs = 1;
dudmuck 2:fdae76e1215e 44 }
dudmuck 2:fdae76e1215e 45
dudmuck 2:fdae76e1215e 46 void SX127x_lora::read_fifo(uint8_t len)
dudmuck 2:fdae76e1215e 47 {
dudmuck 2:fdae76e1215e 48 int i;
dudmuck 2:fdae76e1215e 49
dudmuck 2:fdae76e1215e 50 m_xcvr.m_cs = 0;
dudmuck 2:fdae76e1215e 51 m_xcvr.m_spi.write(REG_FIFO); // bit7 is low for reading from radio
dudmuck 2:fdae76e1215e 52 for (i = 0; i < len; i++) {
dudmuck 2:fdae76e1215e 53 m_xcvr.rx_buf[i] = m_xcvr.m_spi.write(0);
dudmuck 2:fdae76e1215e 54 }
dudmuck 2:fdae76e1215e 55 m_xcvr.m_cs = 1;
dudmuck 2:fdae76e1215e 56 }
dudmuck 2:fdae76e1215e 57
dudmuck 2:fdae76e1215e 58 void SX127x_lora::enable()
dudmuck 2:fdae76e1215e 59 {
dudmuck 2:fdae76e1215e 60 m_xcvr.set_opmode(RF_OPMODE_SLEEP);
dudmuck 2:fdae76e1215e 61
dudmuck 2:fdae76e1215e 62 m_xcvr.RegOpMode.bits.LongRangeMode = 1;
dudmuck 2:fdae76e1215e 63 m_xcvr.write_reg(REG_OPMODE, m_xcvr.RegOpMode.octet);
dudmuck 2:fdae76e1215e 64
dudmuck 2:fdae76e1215e 65 /*RegOpMode.octet = read_reg(REG_OPMODE);
dudmuck 2:fdae76e1215e 66 printf("setloraon:%02x\r\n", RegOpMode.octet);*/
dudmuck 2:fdae76e1215e 67
dudmuck 2:fdae76e1215e 68
dudmuck 2:fdae76e1215e 69 /* // RxDone RxTimeout FhssChangeChannel CadDone
dudmuck 2:fdae76e1215e 70 SX1272LR->RegDioMapping1 = RFLR_DIOMAPPING1_DIO0_00 | RFLR_DIOMAPPING1_DIO1_00 | RFLR_DIOMAPPING1_DIO2_00 | RFLR_DIOMAPPING1_DIO3_00;
dudmuck 2:fdae76e1215e 71 // CadDetected ModeReady
dudmuck 2:fdae76e1215e 72 SX1272LR->RegDioMapping2 = RFLR_DIOMAPPING2_DIO4_00 | RFLR_DIOMAPPING2_DIO5_00;
dudmuck 2:fdae76e1215e 73 SX1272WriteBuffer( REG_LR_DIOMAPPING1, &SX1272LR->RegDioMapping1, 2 );*/
dudmuck 2:fdae76e1215e 74 m_xcvr.RegDioMapping1.bits.Dio0Mapping = 0; // DIO0 to RxDone
dudmuck 2:fdae76e1215e 75 m_xcvr.RegDioMapping1.bits.Dio1Mapping = 0;
dudmuck 2:fdae76e1215e 76 m_xcvr.write_reg(REG_DIOMAPPING1, m_xcvr.RegDioMapping1.octet);
dudmuck 2:fdae76e1215e 77
dudmuck 2:fdae76e1215e 78 // todo: read LoRa regsiters
dudmuck 2:fdae76e1215e 79 //SX1272ReadBuffer( REG_LR_OPMODE, SX1272Regs + 1, 0x70 - 1 );
dudmuck 2:fdae76e1215e 80
dudmuck 2:fdae76e1215e 81 m_xcvr.set_opmode(RF_OPMODE_STANDBY);
dudmuck 2:fdae76e1215e 82 }
dudmuck 2:fdae76e1215e 83
dudmuck 2:fdae76e1215e 84 uint8_t SX127x_lora::getCodingRate(bool from_rx)
dudmuck 2:fdae76e1215e 85 {
dudmuck 2:fdae76e1215e 86 if (from_rx) {
dudmuck 2:fdae76e1215e 87 // expected RegModemStatus was read on RxDone interrupt
dudmuck 2:fdae76e1215e 88 return RegModemStatus.bits.RxCodingRate;
dudmuck 2:fdae76e1215e 89 } else { // transmitted coding rate...
dudmuck 2:fdae76e1215e 90 if (m_xcvr.type == SX1276)
dudmuck 2:fdae76e1215e 91 return RegModemConfig.sx1276bits.CodingRate;
dudmuck 2:fdae76e1215e 92 else if (m_xcvr.type == SX1272)
dudmuck 2:fdae76e1215e 93 return RegModemConfig.sx1272bits.CodingRate;
dudmuck 2:fdae76e1215e 94 else
dudmuck 2:fdae76e1215e 95 return 0;
dudmuck 2:fdae76e1215e 96 }
dudmuck 2:fdae76e1215e 97 }
dudmuck 2:fdae76e1215e 98
dudmuck 2:fdae76e1215e 99
dudmuck 2:fdae76e1215e 100
dudmuck 2:fdae76e1215e 101 void SX127x_lora::setCodingRate(uint8_t cr)
dudmuck 2:fdae76e1215e 102 {
dudmuck 2:fdae76e1215e 103 if (!m_xcvr.RegOpMode.bits.LongRangeMode)
dudmuck 2:fdae76e1215e 104 return;
dudmuck 2:fdae76e1215e 105
dudmuck 2:fdae76e1215e 106 if (m_xcvr.type == SX1276)
dudmuck 2:fdae76e1215e 107 RegModemConfig.sx1276bits.CodingRate = cr;
dudmuck 2:fdae76e1215e 108 else if (m_xcvr.type == SX1272)
dudmuck 2:fdae76e1215e 109 RegModemConfig.sx1272bits.CodingRate = cr;
dudmuck 2:fdae76e1215e 110 else
dudmuck 2:fdae76e1215e 111 return;
dudmuck 2:fdae76e1215e 112
dudmuck 2:fdae76e1215e 113 m_xcvr.write_reg(REG_LR_MODEMCONFIG, RegModemConfig.octet);
dudmuck 2:fdae76e1215e 114 }
dudmuck 2:fdae76e1215e 115
dudmuck 2:fdae76e1215e 116
dudmuck 2:fdae76e1215e 117
dudmuck 2:fdae76e1215e 118 bool SX127x_lora::getHeaderMode(void)
dudmuck 2:fdae76e1215e 119 {
dudmuck 2:fdae76e1215e 120 if (m_xcvr.type == SX1276)
dudmuck 2:fdae76e1215e 121 return RegModemConfig.sx1276bits.ImplicitHeaderModeOn;
dudmuck 2:fdae76e1215e 122 else if (m_xcvr.type == SX1272)
dudmuck 2:fdae76e1215e 123 return RegModemConfig.sx1272bits.ImplicitHeaderModeOn;
dudmuck 2:fdae76e1215e 124 else
dudmuck 2:fdae76e1215e 125 return false;
dudmuck 2:fdae76e1215e 126 }
dudmuck 2:fdae76e1215e 127
dudmuck 2:fdae76e1215e 128 void SX127x_lora::setHeaderMode(bool hm)
dudmuck 2:fdae76e1215e 129 {
dudmuck 2:fdae76e1215e 130 if (m_xcvr.type == SX1276)
dudmuck 2:fdae76e1215e 131 RegModemConfig.sx1276bits.ImplicitHeaderModeOn = hm;
dudmuck 2:fdae76e1215e 132 else if (m_xcvr.type == SX1272)
dudmuck 2:fdae76e1215e 133 RegModemConfig.sx1272bits.ImplicitHeaderModeOn = hm;
dudmuck 2:fdae76e1215e 134 else
dudmuck 2:fdae76e1215e 135 return;
dudmuck 2:fdae76e1215e 136
dudmuck 2:fdae76e1215e 137 m_xcvr.write_reg(REG_LR_MODEMCONFIG, RegModemConfig.octet);
dudmuck 2:fdae76e1215e 138 }
dudmuck 2:fdae76e1215e 139
dudmuck 2:fdae76e1215e 140
dudmuck 2:fdae76e1215e 141 uint8_t SX127x_lora::getBw(void)
dudmuck 2:fdae76e1215e 142 {
dudmuck 2:fdae76e1215e 143 if (m_xcvr.type == SX1276)
dudmuck 2:fdae76e1215e 144 return RegModemConfig.sx1276bits.Bw;
dudmuck 2:fdae76e1215e 145 else if (m_xcvr.type == SX1272)
dudmuck 2:fdae76e1215e 146 return RegModemConfig.sx1272bits.Bw;
dudmuck 2:fdae76e1215e 147 else
dudmuck 2:fdae76e1215e 148 return 0;
dudmuck 2:fdae76e1215e 149 }
dudmuck 10:7382c260c4b1 150 float SX127x_lora::get_symbol_period()
dudmuck 10:7382c260c4b1 151 {
dudmuck 10:7382c260c4b1 152 float khz = 0;
dudmuck 10:7382c260c4b1 153
dudmuck 10:7382c260c4b1 154 if (m_xcvr.type == SX1276) {
dudmuck 10:7382c260c4b1 155 switch (RegModemConfig.sx1276bits.Bw) {
dudmuck 10:7382c260c4b1 156 case 0: khz = 7.8; break;
dudmuck 10:7382c260c4b1 157 case 1: khz = 10.4; break;
dudmuck 10:7382c260c4b1 158 case 2: khz = 15.6; break;
dudmuck 10:7382c260c4b1 159 case 3: khz = 20.8; break;
dudmuck 10:7382c260c4b1 160 case 4: khz = 31.25; break;
dudmuck 10:7382c260c4b1 161 case 5: khz = 41.7; break;
dudmuck 10:7382c260c4b1 162 case 6: khz = 62.5; break;
dudmuck 10:7382c260c4b1 163 case 7: khz = 125; break;
dudmuck 10:7382c260c4b1 164 case 8: khz = 250; break;
dudmuck 10:7382c260c4b1 165 case 9: khz = 500; break;
dudmuck 10:7382c260c4b1 166 }
dudmuck 10:7382c260c4b1 167 } else if (m_xcvr.type == SX1272) {
dudmuck 10:7382c260c4b1 168 switch (RegModemConfig.sx1272bits.Bw) {
dudmuck 10:7382c260c4b1 169 case 0: khz = 125; break;
dudmuck 10:7382c260c4b1 170 case 1: khz = 250; break;
dudmuck 10:7382c260c4b1 171 case 2: khz = 500; break;
dudmuck 10:7382c260c4b1 172 }
dudmuck 10:7382c260c4b1 173 }
dudmuck 10:7382c260c4b1 174
dudmuck 10:7382c260c4b1 175 // return symbol duration in milliseconds
dudmuck 10:7382c260c4b1 176 return (1 << RegModemConfig2.sx1276bits.SpreadingFactor) / khz;
dudmuck 10:7382c260c4b1 177 }
dudmuck 2:fdae76e1215e 178
dudmuck 2:fdae76e1215e 179 void SX127x_lora::setBw(uint8_t bw)
dudmuck 2:fdae76e1215e 180 {
dudmuck 2:fdae76e1215e 181 if (!m_xcvr.RegOpMode.bits.LongRangeMode)
dudmuck 2:fdae76e1215e 182 return;
dudmuck 2:fdae76e1215e 183
dudmuck 10:7382c260c4b1 184 if (m_xcvr.type == SX1276) {
dudmuck 2:fdae76e1215e 185 RegModemConfig.sx1276bits.Bw = bw;
dudmuck 10:7382c260c4b1 186 if (get_symbol_period() > 16)
dudmuck 10:7382c260c4b1 187 RegModemConfig3.sx1276bits.LowDataRateOptimize = 1;
dudmuck 10:7382c260c4b1 188 else
dudmuck 10:7382c260c4b1 189 RegModemConfig3.sx1276bits.LowDataRateOptimize = 0;
dudmuck 10:7382c260c4b1 190 m_xcvr.write_reg(REG_LR_MODEMCONFIG3, RegModemConfig3.octet);
dudmuck 10:7382c260c4b1 191 } else if (m_xcvr.type == SX1272) {
dudmuck 2:fdae76e1215e 192 RegModemConfig.sx1272bits.Bw = bw;
dudmuck 10:7382c260c4b1 193 if (get_symbol_period() > 16)
dudmuck 2:fdae76e1215e 194 RegModemConfig.sx1272bits.LowDataRateOptimize = 1;
dudmuck 2:fdae76e1215e 195 else
dudmuck 2:fdae76e1215e 196 RegModemConfig.sx1272bits.LowDataRateOptimize = 0;
dudmuck 2:fdae76e1215e 197 } else
dudmuck 2:fdae76e1215e 198 return;
dudmuck 2:fdae76e1215e 199
dudmuck 2:fdae76e1215e 200 m_xcvr.write_reg(REG_LR_MODEMCONFIG, RegModemConfig.octet);
dudmuck 2:fdae76e1215e 201 }
dudmuck 2:fdae76e1215e 202
dudmuck 2:fdae76e1215e 203
dudmuck 2:fdae76e1215e 204
dudmuck 2:fdae76e1215e 205 uint8_t SX127x_lora::getSf(void)
dudmuck 2:fdae76e1215e 206 {
dudmuck 2:fdae76e1215e 207 // spreading factor same between sx127[26]
dudmuck 2:fdae76e1215e 208 return RegModemConfig2.sx1276bits.SpreadingFactor;
dudmuck 2:fdae76e1215e 209 }
dudmuck 2:fdae76e1215e 210
dudmuck 2:fdae76e1215e 211 void SX127x_lora::set_nb_trig_peaks(int n)
dudmuck 2:fdae76e1215e 212 {
dudmuck 13:1953e70522aa 213 /* TODO: different requirements for RX_CONTINUOUS vs RX_SINGLE */
dudmuck 2:fdae76e1215e 214 RegTest31.bits.detect_trig_same_peaks_nb = n;
dudmuck 2:fdae76e1215e 215 m_xcvr.write_reg(REG_LR_TEST31, RegTest31.octet);
dudmuck 2:fdae76e1215e 216 }
dudmuck 2:fdae76e1215e 217
dudmuck 2:fdae76e1215e 218
dudmuck 2:fdae76e1215e 219 void SX127x_lora::setSf(uint8_t sf)
dudmuck 2:fdae76e1215e 220 {
dudmuck 2:fdae76e1215e 221 if (!m_xcvr.RegOpMode.bits.LongRangeMode)
dudmuck 2:fdae76e1215e 222 return;
dudmuck 2:fdae76e1215e 223
dudmuck 2:fdae76e1215e 224 // false detections vs missed detections tradeoff
dudmuck 2:fdae76e1215e 225 switch (sf) {
dudmuck 2:fdae76e1215e 226 case 6:
dudmuck 2:fdae76e1215e 227 set_nb_trig_peaks(3);
dudmuck 2:fdae76e1215e 228 break;
dudmuck 2:fdae76e1215e 229 case 7:
dudmuck 2:fdae76e1215e 230 set_nb_trig_peaks(4);
dudmuck 2:fdae76e1215e 231 break;
dudmuck 2:fdae76e1215e 232 default:
dudmuck 2:fdae76e1215e 233 set_nb_trig_peaks(5);
dudmuck 2:fdae76e1215e 234 break;
dudmuck 2:fdae76e1215e 235 }
dudmuck 2:fdae76e1215e 236
dudmuck 2:fdae76e1215e 237 // write register at 0x37 with value 0xc if at SF6
dudmuck 2:fdae76e1215e 238 if (sf < 7)
dudmuck 2:fdae76e1215e 239 m_xcvr.write_reg(REG_LR_DETECTION_THRESHOLD, 0x0c);
dudmuck 2:fdae76e1215e 240 else
dudmuck 2:fdae76e1215e 241 m_xcvr.write_reg(REG_LR_DETECTION_THRESHOLD, 0x0a);
dudmuck 2:fdae76e1215e 242
dudmuck 2:fdae76e1215e 243 RegModemConfig2.sx1276bits.SpreadingFactor = sf; // spreading factor same between sx127[26]
dudmuck 2:fdae76e1215e 244 m_xcvr.write_reg(REG_LR_MODEMCONFIG2, RegModemConfig2.octet);
dudmuck 2:fdae76e1215e 245
dudmuck 2:fdae76e1215e 246 if (m_xcvr.type == SX1272) {
dudmuck 10:7382c260c4b1 247 if (get_symbol_period() > 16)
dudmuck 2:fdae76e1215e 248 RegModemConfig.sx1272bits.LowDataRateOptimize = 1;
dudmuck 2:fdae76e1215e 249 else
dudmuck 2:fdae76e1215e 250 RegModemConfig.sx1272bits.LowDataRateOptimize = 0;
dudmuck 2:fdae76e1215e 251 m_xcvr.write_reg(REG_LR_MODEMCONFIG, RegModemConfig.octet);
dudmuck 2:fdae76e1215e 252 } else if (m_xcvr.type == SX1276) {
dudmuck 10:7382c260c4b1 253 if (get_symbol_period() > 16)
dudmuck 2:fdae76e1215e 254 RegModemConfig3.sx1276bits.LowDataRateOptimize = 1;
dudmuck 2:fdae76e1215e 255 else
dudmuck 2:fdae76e1215e 256 RegModemConfig3.sx1276bits.LowDataRateOptimize = 0;
dudmuck 2:fdae76e1215e 257 m_xcvr.write_reg(REG_LR_MODEMCONFIG3, RegModemConfig3.octet);
dudmuck 2:fdae76e1215e 258 }
dudmuck 2:fdae76e1215e 259 }
dudmuck 2:fdae76e1215e 260
dudmuck 2:fdae76e1215e 261
dudmuck 2:fdae76e1215e 262
dudmuck 2:fdae76e1215e 263 bool SX127x_lora::getRxPayloadCrcOn(void)
dudmuck 2:fdae76e1215e 264 {
dudmuck 2:fdae76e1215e 265 if (m_xcvr.type == SX1276)
dudmuck 2:fdae76e1215e 266 return RegModemConfig2.sx1276bits.RxPayloadCrcOn;
dudmuck 2:fdae76e1215e 267 else if (m_xcvr.type == SX1272)
dudmuck 2:fdae76e1215e 268 return RegModemConfig.sx1272bits.RxPayloadCrcOn;
dudmuck 2:fdae76e1215e 269 else
dudmuck 2:fdae76e1215e 270 return 0;
dudmuck 2:fdae76e1215e 271 }
dudmuck 2:fdae76e1215e 272
dudmuck 2:fdae76e1215e 273
dudmuck 2:fdae76e1215e 274 void SX127x_lora::setRxPayloadCrcOn(bool on)
dudmuck 2:fdae76e1215e 275 {
dudmuck 2:fdae76e1215e 276 if (m_xcvr.type == SX1276) {
dudmuck 2:fdae76e1215e 277 RegModemConfig2.sx1276bits.RxPayloadCrcOn = on;
dudmuck 2:fdae76e1215e 278 m_xcvr.write_reg(REG_LR_MODEMCONFIG2, RegModemConfig2.octet);
dudmuck 2:fdae76e1215e 279 } else if (m_xcvr.type == SX1272) {
dudmuck 2:fdae76e1215e 280 RegModemConfig.sx1272bits.RxPayloadCrcOn = on;
dudmuck 2:fdae76e1215e 281 m_xcvr.write_reg(REG_LR_MODEMCONFIG, RegModemConfig.octet);
dudmuck 2:fdae76e1215e 282 }
dudmuck 2:fdae76e1215e 283 }
dudmuck 2:fdae76e1215e 284
dudmuck 2:fdae76e1215e 285
dudmuck 2:fdae76e1215e 286
dudmuck 2:fdae76e1215e 287 bool SX127x_lora::getAgcAutoOn(void)
dudmuck 2:fdae76e1215e 288 {
dudmuck 2:fdae76e1215e 289 if (m_xcvr.type == SX1276) {
dudmuck 2:fdae76e1215e 290 RegModemConfig3.octet = m_xcvr.read_reg(REG_LR_MODEMCONFIG3);
dudmuck 2:fdae76e1215e 291 return RegModemConfig3.sx1276bits.AgcAutoOn;
dudmuck 2:fdae76e1215e 292 } else if (m_xcvr.type == SX1272) {
dudmuck 2:fdae76e1215e 293 RegModemConfig2.octet = m_xcvr.read_reg(REG_LR_MODEMCONFIG2);
dudmuck 2:fdae76e1215e 294 return RegModemConfig2.sx1272bits.AgcAutoOn;
dudmuck 2:fdae76e1215e 295 } else
dudmuck 2:fdae76e1215e 296 return 0;
dudmuck 2:fdae76e1215e 297 }
dudmuck 2:fdae76e1215e 298
dudmuck 2:fdae76e1215e 299 void SX127x_lora::setAgcAutoOn(bool on)
dudmuck 2:fdae76e1215e 300 {
dudmuck 2:fdae76e1215e 301 if (m_xcvr.type == SX1276) {
dudmuck 2:fdae76e1215e 302 RegModemConfig3.sx1276bits.AgcAutoOn = on;
dudmuck 2:fdae76e1215e 303 m_xcvr.write_reg(REG_LR_MODEMCONFIG3, RegModemConfig3.octet);
dudmuck 2:fdae76e1215e 304 } else if (m_xcvr.type == SX1272) {
dudmuck 2:fdae76e1215e 305 RegModemConfig2.sx1272bits.AgcAutoOn = on;
dudmuck 2:fdae76e1215e 306 m_xcvr.write_reg(REG_LR_MODEMCONFIG2, RegModemConfig2.octet);
dudmuck 2:fdae76e1215e 307 }
dudmuck 2:fdae76e1215e 308
dudmuck 2:fdae76e1215e 309 }
dudmuck 2:fdae76e1215e 310
dudmuck 2:fdae76e1215e 311 void SX127x_lora::start_tx(uint8_t len)
dudmuck 7:927a05f84ede 312 {
dudmuck 2:fdae76e1215e 313 // DIO0 to TxDone
dudmuck 2:fdae76e1215e 314 if (m_xcvr.RegDioMapping1.bits.Dio0Mapping != 1) {
dudmuck 2:fdae76e1215e 315 m_xcvr.RegDioMapping1.bits.Dio0Mapping = 1;
dudmuck 2:fdae76e1215e 316 m_xcvr.write_reg(REG_DIOMAPPING1, m_xcvr.RegDioMapping1.octet);
dudmuck 2:fdae76e1215e 317 }
dudmuck 2:fdae76e1215e 318
dudmuck 2:fdae76e1215e 319 // set FifoPtrAddr to FifoTxPtrBase
dudmuck 2:fdae76e1215e 320 m_xcvr.write_reg(REG_LR_FIFOADDRPTR, m_xcvr.read_reg(REG_LR_FIFOTXBASEADDR));
dudmuck 2:fdae76e1215e 321
dudmuck 2:fdae76e1215e 322 // write PayloadLength bytes to fifo
dudmuck 2:fdae76e1215e 323 write_fifo(len);
dudmuck 7:927a05f84ede 324
dudmuck 2:fdae76e1215e 325 m_xcvr.set_opmode(RF_OPMODE_TRANSMITTER);
dudmuck 2:fdae76e1215e 326 }
dudmuck 2:fdae76e1215e 327
dudmuck 2:fdae76e1215e 328 void SX127x_lora::start_rx()
dudmuck 2:fdae76e1215e 329 {
dudmuck 2:fdae76e1215e 330 if (!m_xcvr.RegOpMode.bits.LongRangeMode)
dudmuck 12:bda42457c34a 331 return; // fsk mode
dudmuck 12:bda42457c34a 332 if (m_xcvr.RegOpMode.sx1276LORAbits.AccessSharedReg)
dudmuck 12:bda42457c34a 333 return; // fsk page
dudmuck 13:1953e70522aa 334
dudmuck 13:1953e70522aa 335 m_xcvr.set_opmode(RF_OPMODE_RECEIVER);
dudmuck 2:fdae76e1215e 336
dudmuck 2:fdae76e1215e 337 if (m_xcvr.RegDioMapping1.bits.Dio0Mapping != 0) {
dudmuck 2:fdae76e1215e 338 m_xcvr.RegDioMapping1.bits.Dio0Mapping = 0; // DIO0 to RxDone
dudmuck 2:fdae76e1215e 339 m_xcvr.write_reg(REG_DIOMAPPING1, m_xcvr.RegDioMapping1.octet);
dudmuck 2:fdae76e1215e 340 }
dudmuck 2:fdae76e1215e 341
dudmuck 2:fdae76e1215e 342 m_xcvr.write_reg(REG_LR_FIFOADDRPTR, m_xcvr.read_reg(REG_LR_FIFORXBASEADDR));
dudmuck 2:fdae76e1215e 343 }
dudmuck 2:fdae76e1215e 344
dudmuck 2:fdae76e1215e 345 float SX127x_lora::get_pkt_rssi()
dudmuck 2:fdae76e1215e 346 {
dudmuck 2:fdae76e1215e 347 /* TODO: calculating with pktSNR to give meaningful result below noise floor */
dudmuck 2:fdae76e1215e 348 if (m_xcvr.type == SX1276)
dudmuck 2:fdae76e1215e 349 return RegPktRssiValue - 137;
dudmuck 2:fdae76e1215e 350 else
dudmuck 2:fdae76e1215e 351 return RegPktRssiValue - 125;
dudmuck 2:fdae76e1215e 352 }
dudmuck 2:fdae76e1215e 353
dudmuck 2:fdae76e1215e 354 service_action_e SX127x_lora::service()
dudmuck 2:fdae76e1215e 355 {
dudmuck 2:fdae76e1215e 356 if (m_xcvr.RegOpMode.bits.Mode == RF_OPMODE_RECEIVER) {
dudmuck 2:fdae76e1215e 357 if (poll_vh) {
dudmuck 2:fdae76e1215e 358 RegIrqFlags.octet = m_xcvr.read_reg(REG_LR_IRQFLAGS);
dudmuck 2:fdae76e1215e 359 if (RegIrqFlags.bits.ValidHeader) {
dudmuck 2:fdae76e1215e 360 RegIrqFlags.octet = 0;
dudmuck 2:fdae76e1215e 361 RegIrqFlags.bits.ValidHeader = 1;
dudmuck 2:fdae76e1215e 362 m_xcvr.write_reg(REG_LR_IRQFLAGS, RegIrqFlags.octet);
dudmuck 2:fdae76e1215e 363 printf("VH\r\n");
dudmuck 2:fdae76e1215e 364 }
dudmuck 2:fdae76e1215e 365 }
dudmuck 2:fdae76e1215e 366 }
dudmuck 7:927a05f84ede 367
dudmuck 2:fdae76e1215e 368 if (m_xcvr.dio0 == 0)
dudmuck 2:fdae76e1215e 369 return SERVICE_NONE;
dudmuck 2:fdae76e1215e 370
dudmuck 2:fdae76e1215e 371 switch (m_xcvr.RegDioMapping1.bits.Dio0Mapping) {
dudmuck 2:fdae76e1215e 372 case 0: // RxDone
dudmuck 2:fdae76e1215e 373 /* user checks for CRC error in IrqFlags */
dudmuck 2:fdae76e1215e 374 RegIrqFlags.octet = m_xcvr.read_reg(REG_LR_IRQFLAGS); // save flags
dudmuck 2:fdae76e1215e 375 RegHopChannel.octet = m_xcvr.read_reg(REG_LR_HOPCHANNEL);
dudmuck 2:fdae76e1215e 376 //printf("[%02x]", RegIrqFlags.octet);
dudmuck 2:fdae76e1215e 377 m_xcvr.write_reg(REG_LR_IRQFLAGS, RegIrqFlags.octet); // clear flags in radio
dudmuck 2:fdae76e1215e 378
dudmuck 2:fdae76e1215e 379 /* any register of interest on received packet is read(saved) here */
dudmuck 2:fdae76e1215e 380 RegModemStatus.octet = m_xcvr.read_reg(REG_LR_MODEMSTAT);
dudmuck 2:fdae76e1215e 381 RegPktSnrValue = m_xcvr.read_reg(REG_LR_PKTSNRVALUE);
dudmuck 2:fdae76e1215e 382 RegPktRssiValue = m_xcvr.read_reg(REG_LR_PKTRSSIVALUE);
dudmuck 2:fdae76e1215e 383 RegRxNbBytes = m_xcvr.read_reg(REG_LR_RXNBBYTES);
dudmuck 2:fdae76e1215e 384
dudmuck 2:fdae76e1215e 385 m_xcvr.write_reg(REG_LR_FIFOADDRPTR, m_xcvr.read_reg(REG_LR_FIFORXCURRENTADDR));
dudmuck 2:fdae76e1215e 386 read_fifo(RegRxNbBytes);
dudmuck 2:fdae76e1215e 387 return SERVICE_READ_FIFO;
dudmuck 2:fdae76e1215e 388 case 1: // TxDone
dudmuck 2:fdae76e1215e 389 RegIrqFlags.octet = 0;
dudmuck 2:fdae76e1215e 390 RegIrqFlags.bits.TxDone = 1;
dudmuck 2:fdae76e1215e 391 m_xcvr.write_reg(REG_LR_IRQFLAGS, RegIrqFlags.octet);
dudmuck 2:fdae76e1215e 392 return SERVICE_TX_DONE;
dudmuck 2:fdae76e1215e 393 } // ...switch (RegDioMapping1.bits.Dio0Mapping)
dudmuck 2:fdae76e1215e 394
dudmuck 2:fdae76e1215e 395 return SERVICE_ERROR;
dudmuck 12:bda42457c34a 396 }
dudmuck 12:bda42457c34a 397