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:
Wed Feb 18 16:53:36 2015 +0000
Revision:
8:c9592cbc9f86
Parent:
7:927a05f84ede
Child:
9:ae1a71ccd730
fixed error in setSf() for SX1276

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 2:fdae76e1215e 150
dudmuck 2:fdae76e1215e 151 void SX127x_lora::setBw(uint8_t bw)
dudmuck 2:fdae76e1215e 152 {
dudmuck 2:fdae76e1215e 153 if (!m_xcvr.RegOpMode.bits.LongRangeMode)
dudmuck 2:fdae76e1215e 154 return;
dudmuck 2:fdae76e1215e 155
dudmuck 2:fdae76e1215e 156 if (m_xcvr.type == SX1276)
dudmuck 2:fdae76e1215e 157 RegModemConfig.sx1276bits.Bw = bw;
dudmuck 2:fdae76e1215e 158 else if (m_xcvr.type == SX1272) {
dudmuck 2:fdae76e1215e 159 RegModemConfig.sx1272bits.Bw = bw;
dudmuck 2:fdae76e1215e 160 if (RegModemConfig2.sx1272bits.SpreadingFactor > 10)
dudmuck 2:fdae76e1215e 161 RegModemConfig.sx1272bits.LowDataRateOptimize = 1;
dudmuck 2:fdae76e1215e 162 else
dudmuck 2:fdae76e1215e 163 RegModemConfig.sx1272bits.LowDataRateOptimize = 0;
dudmuck 2:fdae76e1215e 164 } else
dudmuck 2:fdae76e1215e 165 return;
dudmuck 2:fdae76e1215e 166
dudmuck 2:fdae76e1215e 167 m_xcvr.write_reg(REG_LR_MODEMCONFIG, RegModemConfig.octet);
dudmuck 2:fdae76e1215e 168 }
dudmuck 2:fdae76e1215e 169
dudmuck 2:fdae76e1215e 170
dudmuck 2:fdae76e1215e 171
dudmuck 2:fdae76e1215e 172 uint8_t SX127x_lora::getSf(void)
dudmuck 2:fdae76e1215e 173 {
dudmuck 2:fdae76e1215e 174 // spreading factor same between sx127[26]
dudmuck 2:fdae76e1215e 175 return RegModemConfig2.sx1276bits.SpreadingFactor;
dudmuck 2:fdae76e1215e 176 }
dudmuck 2:fdae76e1215e 177
dudmuck 2:fdae76e1215e 178 void SX127x_lora::set_nb_trig_peaks(int n)
dudmuck 2:fdae76e1215e 179 {
dudmuck 2:fdae76e1215e 180 RegTest31.bits.detect_trig_same_peaks_nb = n;
dudmuck 2:fdae76e1215e 181 m_xcvr.write_reg(REG_LR_TEST31, RegTest31.octet);
dudmuck 2:fdae76e1215e 182 }
dudmuck 2:fdae76e1215e 183
dudmuck 2:fdae76e1215e 184
dudmuck 2:fdae76e1215e 185 void SX127x_lora::setSf(uint8_t sf)
dudmuck 2:fdae76e1215e 186 {
dudmuck 2:fdae76e1215e 187 if (!m_xcvr.RegOpMode.bits.LongRangeMode)
dudmuck 2:fdae76e1215e 188 return;
dudmuck 2:fdae76e1215e 189
dudmuck 2:fdae76e1215e 190 // false detections vs missed detections tradeoff
dudmuck 2:fdae76e1215e 191 switch (sf) {
dudmuck 2:fdae76e1215e 192 case 6:
dudmuck 2:fdae76e1215e 193 set_nb_trig_peaks(3);
dudmuck 2:fdae76e1215e 194 break;
dudmuck 2:fdae76e1215e 195 case 7:
dudmuck 2:fdae76e1215e 196 set_nb_trig_peaks(4);
dudmuck 2:fdae76e1215e 197 break;
dudmuck 2:fdae76e1215e 198 default:
dudmuck 2:fdae76e1215e 199 set_nb_trig_peaks(5);
dudmuck 2:fdae76e1215e 200 break;
dudmuck 2:fdae76e1215e 201 }
dudmuck 2:fdae76e1215e 202
dudmuck 2:fdae76e1215e 203 // write register at 0x37 with value 0xc if at SF6
dudmuck 2:fdae76e1215e 204 if (sf < 7)
dudmuck 2:fdae76e1215e 205 m_xcvr.write_reg(REG_LR_DETECTION_THRESHOLD, 0x0c);
dudmuck 2:fdae76e1215e 206 else
dudmuck 2:fdae76e1215e 207 m_xcvr.write_reg(REG_LR_DETECTION_THRESHOLD, 0x0a);
dudmuck 2:fdae76e1215e 208
dudmuck 2:fdae76e1215e 209 RegModemConfig2.sx1276bits.SpreadingFactor = sf; // spreading factor same between sx127[26]
dudmuck 2:fdae76e1215e 210 m_xcvr.write_reg(REG_LR_MODEMCONFIG2, RegModemConfig2.octet);
dudmuck 2:fdae76e1215e 211
dudmuck 2:fdae76e1215e 212 if (m_xcvr.type == SX1272) {
dudmuck 2:fdae76e1215e 213 if (sf > 10 && RegModemConfig.sx1272bits.Bw == 0) // if bw=125KHz and sf11 or sf12
dudmuck 2:fdae76e1215e 214 RegModemConfig.sx1272bits.LowDataRateOptimize = 1;
dudmuck 2:fdae76e1215e 215 else
dudmuck 2:fdae76e1215e 216 RegModemConfig.sx1272bits.LowDataRateOptimize = 0;
dudmuck 2:fdae76e1215e 217 m_xcvr.write_reg(REG_LR_MODEMCONFIG, RegModemConfig.octet);
dudmuck 2:fdae76e1215e 218 } else if (m_xcvr.type == SX1276) {
dudmuck 8:c9592cbc9f86 219 if (sf > 10 && RegModemConfig.sx1276bits.Bw == 0) // if bw=125KHz and sf11 or sf12
dudmuck 2:fdae76e1215e 220 RegModemConfig3.sx1276bits.LowDataRateOptimize = 1;
dudmuck 2:fdae76e1215e 221 else
dudmuck 2:fdae76e1215e 222 RegModemConfig3.sx1276bits.LowDataRateOptimize = 0;
dudmuck 2:fdae76e1215e 223 m_xcvr.write_reg(REG_LR_MODEMCONFIG3, RegModemConfig3.octet);
dudmuck 2:fdae76e1215e 224 }
dudmuck 2:fdae76e1215e 225 }
dudmuck 2:fdae76e1215e 226
dudmuck 2:fdae76e1215e 227
dudmuck 2:fdae76e1215e 228
dudmuck 2:fdae76e1215e 229 bool SX127x_lora::getRxPayloadCrcOn(void)
dudmuck 2:fdae76e1215e 230 {
dudmuck 2:fdae76e1215e 231 if (m_xcvr.type == SX1276)
dudmuck 2:fdae76e1215e 232 return RegModemConfig2.sx1276bits.RxPayloadCrcOn;
dudmuck 2:fdae76e1215e 233 else if (m_xcvr.type == SX1272)
dudmuck 2:fdae76e1215e 234 return RegModemConfig.sx1272bits.RxPayloadCrcOn;
dudmuck 2:fdae76e1215e 235 else
dudmuck 2:fdae76e1215e 236 return 0;
dudmuck 2:fdae76e1215e 237 }
dudmuck 2:fdae76e1215e 238
dudmuck 2:fdae76e1215e 239
dudmuck 2:fdae76e1215e 240 void SX127x_lora::setRxPayloadCrcOn(bool on)
dudmuck 2:fdae76e1215e 241 {
dudmuck 2:fdae76e1215e 242 if (m_xcvr.type == SX1276) {
dudmuck 2:fdae76e1215e 243 RegModemConfig2.sx1276bits.RxPayloadCrcOn = on;
dudmuck 2:fdae76e1215e 244 m_xcvr.write_reg(REG_LR_MODEMCONFIG2, RegModemConfig2.octet);
dudmuck 2:fdae76e1215e 245 } else if (m_xcvr.type == SX1272) {
dudmuck 2:fdae76e1215e 246 RegModemConfig.sx1272bits.RxPayloadCrcOn = on;
dudmuck 2:fdae76e1215e 247 m_xcvr.write_reg(REG_LR_MODEMCONFIG, RegModemConfig.octet);
dudmuck 2:fdae76e1215e 248 }
dudmuck 2:fdae76e1215e 249 }
dudmuck 2:fdae76e1215e 250
dudmuck 2:fdae76e1215e 251
dudmuck 2:fdae76e1215e 252
dudmuck 2:fdae76e1215e 253 bool SX127x_lora::getAgcAutoOn(void)
dudmuck 2:fdae76e1215e 254 {
dudmuck 2:fdae76e1215e 255 if (m_xcvr.type == SX1276) {
dudmuck 2:fdae76e1215e 256 RegModemConfig3.octet = m_xcvr.read_reg(REG_LR_MODEMCONFIG3);
dudmuck 2:fdae76e1215e 257 return RegModemConfig3.sx1276bits.AgcAutoOn;
dudmuck 2:fdae76e1215e 258 } else if (m_xcvr.type == SX1272) {
dudmuck 2:fdae76e1215e 259 RegModemConfig2.octet = m_xcvr.read_reg(REG_LR_MODEMCONFIG2);
dudmuck 2:fdae76e1215e 260 return RegModemConfig2.sx1272bits.AgcAutoOn;
dudmuck 2:fdae76e1215e 261 } else
dudmuck 2:fdae76e1215e 262 return 0;
dudmuck 2:fdae76e1215e 263 }
dudmuck 2:fdae76e1215e 264
dudmuck 2:fdae76e1215e 265 void SX127x_lora::setAgcAutoOn(bool on)
dudmuck 2:fdae76e1215e 266 {
dudmuck 2:fdae76e1215e 267 if (m_xcvr.type == SX1276) {
dudmuck 2:fdae76e1215e 268 RegModemConfig3.sx1276bits.AgcAutoOn = on;
dudmuck 2:fdae76e1215e 269 m_xcvr.write_reg(REG_LR_MODEMCONFIG3, RegModemConfig3.octet);
dudmuck 2:fdae76e1215e 270 } else if (m_xcvr.type == SX1272) {
dudmuck 2:fdae76e1215e 271 RegModemConfig2.sx1272bits.AgcAutoOn = on;
dudmuck 2:fdae76e1215e 272 m_xcvr.write_reg(REG_LR_MODEMCONFIG2, RegModemConfig2.octet);
dudmuck 2:fdae76e1215e 273 }
dudmuck 2:fdae76e1215e 274
dudmuck 2:fdae76e1215e 275 }
dudmuck 2:fdae76e1215e 276
dudmuck 2:fdae76e1215e 277
dudmuck 2:fdae76e1215e 278
dudmuck 2:fdae76e1215e 279 void SX127x_lora::start_tx(uint8_t len)
dudmuck 7:927a05f84ede 280 {
dudmuck 2:fdae76e1215e 281 // DIO0 to TxDone
dudmuck 2:fdae76e1215e 282 if (m_xcvr.RegDioMapping1.bits.Dio0Mapping != 1) {
dudmuck 2:fdae76e1215e 283 m_xcvr.RegDioMapping1.bits.Dio0Mapping = 1;
dudmuck 2:fdae76e1215e 284 m_xcvr.write_reg(REG_DIOMAPPING1, m_xcvr.RegDioMapping1.octet);
dudmuck 2:fdae76e1215e 285 }
dudmuck 2:fdae76e1215e 286
dudmuck 2:fdae76e1215e 287 // set FifoPtrAddr to FifoTxPtrBase
dudmuck 2:fdae76e1215e 288 m_xcvr.write_reg(REG_LR_FIFOADDRPTR, m_xcvr.read_reg(REG_LR_FIFOTXBASEADDR));
dudmuck 2:fdae76e1215e 289
dudmuck 2:fdae76e1215e 290 // write PayloadLength bytes to fifo
dudmuck 2:fdae76e1215e 291 write_fifo(len);
dudmuck 7:927a05f84ede 292
dudmuck 2:fdae76e1215e 293 m_xcvr.set_opmode(RF_OPMODE_TRANSMITTER);
dudmuck 2:fdae76e1215e 294 }
dudmuck 2:fdae76e1215e 295
dudmuck 2:fdae76e1215e 296 void SX127x_lora::start_rx()
dudmuck 2:fdae76e1215e 297 {
dudmuck 2:fdae76e1215e 298 if (!m_xcvr.RegOpMode.bits.LongRangeMode)
dudmuck 2:fdae76e1215e 299 return;
dudmuck 2:fdae76e1215e 300
dudmuck 2:fdae76e1215e 301 if (m_xcvr.RegDioMapping1.bits.Dio0Mapping != 0) {
dudmuck 2:fdae76e1215e 302 m_xcvr.RegDioMapping1.bits.Dio0Mapping = 0; // DIO0 to RxDone
dudmuck 2:fdae76e1215e 303 m_xcvr.write_reg(REG_DIOMAPPING1, m_xcvr.RegDioMapping1.octet);
dudmuck 2:fdae76e1215e 304 }
dudmuck 2:fdae76e1215e 305
dudmuck 2:fdae76e1215e 306 m_xcvr.write_reg(REG_LR_FIFOADDRPTR, m_xcvr.read_reg(REG_LR_FIFORXBASEADDR));
dudmuck 7:927a05f84ede 307
dudmuck 2:fdae76e1215e 308 m_xcvr.set_opmode(RF_OPMODE_RECEIVER);
dudmuck 2:fdae76e1215e 309 }
dudmuck 2:fdae76e1215e 310
dudmuck 2:fdae76e1215e 311 float SX127x_lora::get_pkt_rssi()
dudmuck 2:fdae76e1215e 312 {
dudmuck 2:fdae76e1215e 313 /* TODO: calculating with pktSNR to give meaningful result below noise floor */
dudmuck 2:fdae76e1215e 314 if (m_xcvr.type == SX1276)
dudmuck 2:fdae76e1215e 315 return RegPktRssiValue - 137;
dudmuck 2:fdae76e1215e 316 else
dudmuck 2:fdae76e1215e 317 return RegPktRssiValue - 125;
dudmuck 2:fdae76e1215e 318 }
dudmuck 2:fdae76e1215e 319
dudmuck 2:fdae76e1215e 320 service_action_e SX127x_lora::service()
dudmuck 2:fdae76e1215e 321 {
dudmuck 2:fdae76e1215e 322 if (m_xcvr.RegOpMode.bits.Mode == RF_OPMODE_RECEIVER) {
dudmuck 2:fdae76e1215e 323 if (poll_vh) {
dudmuck 2:fdae76e1215e 324 RegIrqFlags.octet = m_xcvr.read_reg(REG_LR_IRQFLAGS);
dudmuck 2:fdae76e1215e 325 if (RegIrqFlags.bits.ValidHeader) {
dudmuck 2:fdae76e1215e 326 RegIrqFlags.octet = 0;
dudmuck 2:fdae76e1215e 327 RegIrqFlags.bits.ValidHeader = 1;
dudmuck 2:fdae76e1215e 328 m_xcvr.write_reg(REG_LR_IRQFLAGS, RegIrqFlags.octet);
dudmuck 2:fdae76e1215e 329 printf("VH\r\n");
dudmuck 2:fdae76e1215e 330 }
dudmuck 2:fdae76e1215e 331 }
dudmuck 2:fdae76e1215e 332 }
dudmuck 7:927a05f84ede 333
dudmuck 2:fdae76e1215e 334 if (m_xcvr.dio0 == 0)
dudmuck 2:fdae76e1215e 335 return SERVICE_NONE;
dudmuck 2:fdae76e1215e 336
dudmuck 2:fdae76e1215e 337 switch (m_xcvr.RegDioMapping1.bits.Dio0Mapping) {
dudmuck 2:fdae76e1215e 338 case 0: // RxDone
dudmuck 2:fdae76e1215e 339 /* user checks for CRC error in IrqFlags */
dudmuck 2:fdae76e1215e 340 RegIrqFlags.octet = m_xcvr.read_reg(REG_LR_IRQFLAGS); // save flags
dudmuck 2:fdae76e1215e 341 RegHopChannel.octet = m_xcvr.read_reg(REG_LR_HOPCHANNEL);
dudmuck 2:fdae76e1215e 342 //printf("[%02x]", RegIrqFlags.octet);
dudmuck 2:fdae76e1215e 343 m_xcvr.write_reg(REG_LR_IRQFLAGS, RegIrqFlags.octet); // clear flags in radio
dudmuck 2:fdae76e1215e 344
dudmuck 2:fdae76e1215e 345 /* any register of interest on received packet is read(saved) here */
dudmuck 2:fdae76e1215e 346 RegModemStatus.octet = m_xcvr.read_reg(REG_LR_MODEMSTAT);
dudmuck 2:fdae76e1215e 347 RegPktSnrValue = m_xcvr.read_reg(REG_LR_PKTSNRVALUE);
dudmuck 2:fdae76e1215e 348 RegPktRssiValue = m_xcvr.read_reg(REG_LR_PKTRSSIVALUE);
dudmuck 2:fdae76e1215e 349 RegRxNbBytes = m_xcvr.read_reg(REG_LR_RXNBBYTES);
dudmuck 2:fdae76e1215e 350
dudmuck 2:fdae76e1215e 351 m_xcvr.write_reg(REG_LR_FIFOADDRPTR, m_xcvr.read_reg(REG_LR_FIFORXCURRENTADDR));
dudmuck 2:fdae76e1215e 352 read_fifo(RegRxNbBytes);
dudmuck 2:fdae76e1215e 353 return SERVICE_READ_FIFO;
dudmuck 2:fdae76e1215e 354 case 1: // TxDone
dudmuck 2:fdae76e1215e 355 RegIrqFlags.octet = 0;
dudmuck 2:fdae76e1215e 356 RegIrqFlags.bits.TxDone = 1;
dudmuck 2:fdae76e1215e 357 m_xcvr.write_reg(REG_LR_IRQFLAGS, RegIrqFlags.octet);
dudmuck 2:fdae76e1215e 358 return SERVICE_TX_DONE;
dudmuck 2:fdae76e1215e 359 } // ...switch (RegDioMapping1.bits.Dio0Mapping)
dudmuck 2:fdae76e1215e 360
dudmuck 2:fdae76e1215e 361 return SERVICE_ERROR;
dudmuck 2:fdae76e1215e 362 }