123

Committer:
dudmuck
Date:
Mon Jul 18 21:13:50 2016 +0000
Revision:
26:4876e515ff4c
Parent:
23:1df3dddcb43e
Child:
27:da6341d9d5b1
FSK/OOK TX shutdown time corrected on PacketSent event.

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 19:1ee6ef1ab73f 21 if (!m_xcvr.RegOpMode.bits.LongRangeMode)
dudmuck 19:1ee6ef1ab73f 22 enable();
dudmuck 19:1ee6ef1ab73f 23
dudmuck 2:fdae76e1215e 24 RegModemConfig.octet = m_xcvr.read_reg(REG_LR_MODEMCONFIG);
dudmuck 2:fdae76e1215e 25 RegModemConfig2.octet = m_xcvr.read_reg(REG_LR_MODEMCONFIG2);
dudmuck 2:fdae76e1215e 26 RegTest31.octet = m_xcvr.read_reg(REG_LR_TEST31);
dudmuck 17:59279bc8cdab 27 RegTest33.octet = m_xcvr.read_reg(REG_LR_TEST33); // invert_i_q
dudmuck 17:59279bc8cdab 28 RegDriftInvert.octet = m_xcvr.read_reg(REG_LR_DRIFT_INVERT);
dudmuck 19:1ee6ef1ab73f 29 RegGainDrift.octet = m_xcvr.read_reg(REG_LR_GAIN_DRIFT);
dudmuck 19:1ee6ef1ab73f 30
dudmuck 19:1ee6ef1ab73f 31 if (m_xcvr.type == SX1276) {
dudmuck 19:1ee6ef1ab73f 32 RegAutoDrift.octet = m_xcvr.read_reg(REG_LR_SX1276_AUTO_DRIFT);
dudmuck 19:1ee6ef1ab73f 33 }
dudmuck 2:fdae76e1215e 34 }
dudmuck 2:fdae76e1215e 35
dudmuck 2:fdae76e1215e 36 SX127x_lora::~SX127x_lora()
dudmuck 2:fdae76e1215e 37 {
dudmuck 2:fdae76e1215e 38 }
dudmuck 2:fdae76e1215e 39
dudmuck 2:fdae76e1215e 40 void SX127x_lora::write_fifo(uint8_t len)
dudmuck 2:fdae76e1215e 41 {
dudmuck 2:fdae76e1215e 42 int i;
dudmuck 2:fdae76e1215e 43
dudmuck 2:fdae76e1215e 44 m_xcvr.m_cs = 0;
dudmuck 2:fdae76e1215e 45 m_xcvr.m_spi.write(REG_FIFO | 0x80); // bit7 is high for writing to radio
dudmuck 2:fdae76e1215e 46
dudmuck 2:fdae76e1215e 47 for (i = 0; i < len; i++) {
dudmuck 2:fdae76e1215e 48 m_xcvr.m_spi.write(m_xcvr.tx_buf[i]);
dudmuck 2:fdae76e1215e 49 }
dudmuck 2:fdae76e1215e 50 m_xcvr.m_cs = 1;
dudmuck 2:fdae76e1215e 51 }
dudmuck 2:fdae76e1215e 52
dudmuck 2:fdae76e1215e 53 void SX127x_lora::read_fifo(uint8_t len)
dudmuck 2:fdae76e1215e 54 {
dudmuck 2:fdae76e1215e 55 int i;
dudmuck 2:fdae76e1215e 56
dudmuck 2:fdae76e1215e 57 m_xcvr.m_cs = 0;
dudmuck 2:fdae76e1215e 58 m_xcvr.m_spi.write(REG_FIFO); // bit7 is low for reading from radio
dudmuck 2:fdae76e1215e 59 for (i = 0; i < len; i++) {
dudmuck 2:fdae76e1215e 60 m_xcvr.rx_buf[i] = m_xcvr.m_spi.write(0);
dudmuck 2:fdae76e1215e 61 }
dudmuck 2:fdae76e1215e 62 m_xcvr.m_cs = 1;
dudmuck 2:fdae76e1215e 63 }
dudmuck 2:fdae76e1215e 64
dudmuck 2:fdae76e1215e 65 void SX127x_lora::enable()
dudmuck 2:fdae76e1215e 66 {
dudmuck 2:fdae76e1215e 67 m_xcvr.set_opmode(RF_OPMODE_SLEEP);
dudmuck 2:fdae76e1215e 68
dudmuck 2:fdae76e1215e 69 m_xcvr.RegOpMode.bits.LongRangeMode = 1;
dudmuck 2:fdae76e1215e 70 m_xcvr.write_reg(REG_OPMODE, m_xcvr.RegOpMode.octet);
dudmuck 2:fdae76e1215e 71
dudmuck 2:fdae76e1215e 72 m_xcvr.RegDioMapping1.bits.Dio0Mapping = 0; // DIO0 to RxDone
dudmuck 2:fdae76e1215e 73 m_xcvr.RegDioMapping1.bits.Dio1Mapping = 0;
dudmuck 2:fdae76e1215e 74 m_xcvr.write_reg(REG_DIOMAPPING1, m_xcvr.RegDioMapping1.octet);
dudmuck 2:fdae76e1215e 75
dudmuck 2:fdae76e1215e 76 m_xcvr.set_opmode(RF_OPMODE_STANDBY);
dudmuck 2:fdae76e1215e 77 }
dudmuck 2:fdae76e1215e 78
dudmuck 2:fdae76e1215e 79 uint8_t SX127x_lora::getCodingRate(bool from_rx)
dudmuck 2:fdae76e1215e 80 {
dudmuck 2:fdae76e1215e 81 if (from_rx) {
dudmuck 2:fdae76e1215e 82 // expected RegModemStatus was read on RxDone interrupt
dudmuck 2:fdae76e1215e 83 return RegModemStatus.bits.RxCodingRate;
dudmuck 2:fdae76e1215e 84 } else { // transmitted coding rate...
dudmuck 2:fdae76e1215e 85 if (m_xcvr.type == SX1276)
dudmuck 2:fdae76e1215e 86 return RegModemConfig.sx1276bits.CodingRate;
dudmuck 2:fdae76e1215e 87 else if (m_xcvr.type == SX1272)
dudmuck 2:fdae76e1215e 88 return RegModemConfig.sx1272bits.CodingRate;
dudmuck 2:fdae76e1215e 89 else
dudmuck 2:fdae76e1215e 90 return 0;
dudmuck 2:fdae76e1215e 91 }
dudmuck 2:fdae76e1215e 92 }
dudmuck 2:fdae76e1215e 93
dudmuck 2:fdae76e1215e 94
dudmuck 2:fdae76e1215e 95
dudmuck 2:fdae76e1215e 96 void SX127x_lora::setCodingRate(uint8_t cr)
dudmuck 2:fdae76e1215e 97 {
dudmuck 2:fdae76e1215e 98 if (!m_xcvr.RegOpMode.bits.LongRangeMode)
dudmuck 2:fdae76e1215e 99 return;
dudmuck 2:fdae76e1215e 100
dudmuck 2:fdae76e1215e 101 if (m_xcvr.type == SX1276)
dudmuck 2:fdae76e1215e 102 RegModemConfig.sx1276bits.CodingRate = cr;
dudmuck 2:fdae76e1215e 103 else if (m_xcvr.type == SX1272)
dudmuck 2:fdae76e1215e 104 RegModemConfig.sx1272bits.CodingRate = cr;
dudmuck 2:fdae76e1215e 105 else
dudmuck 2:fdae76e1215e 106 return;
dudmuck 2:fdae76e1215e 107
dudmuck 2:fdae76e1215e 108 m_xcvr.write_reg(REG_LR_MODEMCONFIG, RegModemConfig.octet);
dudmuck 2:fdae76e1215e 109 }
dudmuck 2:fdae76e1215e 110
dudmuck 2:fdae76e1215e 111
dudmuck 2:fdae76e1215e 112
dudmuck 2:fdae76e1215e 113 bool SX127x_lora::getHeaderMode(void)
dudmuck 2:fdae76e1215e 114 {
dudmuck 26:4876e515ff4c 115 if (m_xcvr.type == SX1276) {
dudmuck 26:4876e515ff4c 116 RegModemConfig.octet = m_xcvr.read_reg(REG_LR_MODEMCONFIG);
dudmuck 2:fdae76e1215e 117 return RegModemConfig.sx1276bits.ImplicitHeaderModeOn;
dudmuck 26:4876e515ff4c 118 } else if (m_xcvr.type == SX1272) {
dudmuck 26:4876e515ff4c 119 RegModemConfig.octet = m_xcvr.read_reg(REG_LR_MODEMCONFIG);
dudmuck 2:fdae76e1215e 120 return RegModemConfig.sx1272bits.ImplicitHeaderModeOn;
dudmuck 26:4876e515ff4c 121 } else
dudmuck 2:fdae76e1215e 122 return false;
dudmuck 2:fdae76e1215e 123 }
dudmuck 2:fdae76e1215e 124
dudmuck 2:fdae76e1215e 125 void SX127x_lora::setHeaderMode(bool hm)
dudmuck 2:fdae76e1215e 126 {
dudmuck 2:fdae76e1215e 127 if (m_xcvr.type == SX1276)
dudmuck 2:fdae76e1215e 128 RegModemConfig.sx1276bits.ImplicitHeaderModeOn = hm;
dudmuck 2:fdae76e1215e 129 else if (m_xcvr.type == SX1272)
dudmuck 2:fdae76e1215e 130 RegModemConfig.sx1272bits.ImplicitHeaderModeOn = hm;
dudmuck 2:fdae76e1215e 131 else
dudmuck 2:fdae76e1215e 132 return;
dudmuck 2:fdae76e1215e 133
dudmuck 2:fdae76e1215e 134 m_xcvr.write_reg(REG_LR_MODEMCONFIG, RegModemConfig.octet);
dudmuck 2:fdae76e1215e 135 }
dudmuck 2:fdae76e1215e 136
dudmuck 2:fdae76e1215e 137
dudmuck 2:fdae76e1215e 138 uint8_t SX127x_lora::getBw(void)
dudmuck 2:fdae76e1215e 139 {
dudmuck 2:fdae76e1215e 140 if (m_xcvr.type == SX1276)
dudmuck 2:fdae76e1215e 141 return RegModemConfig.sx1276bits.Bw;
dudmuck 2:fdae76e1215e 142 else if (m_xcvr.type == SX1272)
dudmuck 2:fdae76e1215e 143 return RegModemConfig.sx1272bits.Bw;
dudmuck 2:fdae76e1215e 144 else
dudmuck 2:fdae76e1215e 145 return 0;
dudmuck 2:fdae76e1215e 146 }
dudmuck 15:3f3fc6792f97 147
dudmuck 15:3f3fc6792f97 148 int SX127x_lora::get_freq_error_Hz()
dudmuck 15:3f3fc6792f97 149 {
dudmuck 15:3f3fc6792f97 150 int freq_error;
dudmuck 15:3f3fc6792f97 151 float f, khz = 0;
dudmuck 15:3f3fc6792f97 152 freq_error = m_xcvr.read_reg(REG_LR_TEST28);
dudmuck 15:3f3fc6792f97 153 freq_error <<= 8;
dudmuck 15:3f3fc6792f97 154 freq_error += m_xcvr.read_reg(REG_LR_TEST29);
dudmuck 15:3f3fc6792f97 155 freq_error <<= 8;
dudmuck 15:3f3fc6792f97 156 freq_error += m_xcvr.read_reg(REG_LR_TEST2A);
dudmuck 15:3f3fc6792f97 157 if (freq_error & 0x80000) { // 20bit value is negative
dudmuck 15:3f3fc6792f97 158 //signed 20bit to 32bit
dudmuck 15:3f3fc6792f97 159 freq_error |= 0xfff00000;
dudmuck 15:3f3fc6792f97 160 }
dudmuck 15:3f3fc6792f97 161 f = freq_error / (float)XTAL_FREQ;
dudmuck 15:3f3fc6792f97 162 f *= (float)0x1000000; // 2^24
dudmuck 15:3f3fc6792f97 163 if (m_xcvr.type == SX1272) {
dudmuck 15:3f3fc6792f97 164 switch (RegModemConfig.sx1272bits.Bw) {
dudmuck 15:3f3fc6792f97 165 case 0: khz = 125; break;
dudmuck 15:3f3fc6792f97 166 case 1: khz = 250; break;
dudmuck 15:3f3fc6792f97 167 case 2: khz = 500; break;
dudmuck 15:3f3fc6792f97 168 }
dudmuck 15:3f3fc6792f97 169 } else if (m_xcvr.type == SX1276) {
dudmuck 15:3f3fc6792f97 170 switch (RegModemConfig.sx1276bits.Bw) {
dudmuck 15:3f3fc6792f97 171 case 0: khz = 7.8; break;
dudmuck 15:3f3fc6792f97 172 case 1: khz = 10.4; break;
dudmuck 15:3f3fc6792f97 173 case 2: khz = 15.6; break;
dudmuck 15:3f3fc6792f97 174 case 3: khz = 20.8; break;
dudmuck 15:3f3fc6792f97 175 case 4: khz = 31.25; break;
dudmuck 15:3f3fc6792f97 176 case 5: khz = 41.7; break;
dudmuck 15:3f3fc6792f97 177 case 6: khz = 62.5; break;
dudmuck 15:3f3fc6792f97 178 case 7: khz = 125; break;
dudmuck 15:3f3fc6792f97 179 case 8: khz = 250; break;
dudmuck 15:3f3fc6792f97 180 case 9: khz = 500; break;
dudmuck 15:3f3fc6792f97 181 }
dudmuck 15:3f3fc6792f97 182 }
dudmuck 15:3f3fc6792f97 183 f *= khz / 500;
dudmuck 15:3f3fc6792f97 184 return (int)f;
dudmuck 15:3f3fc6792f97 185 }
dudmuck 15:3f3fc6792f97 186
dudmuck 10:7382c260c4b1 187 float SX127x_lora::get_symbol_period()
dudmuck 10:7382c260c4b1 188 {
dudmuck 10:7382c260c4b1 189 float khz = 0;
dudmuck 10:7382c260c4b1 190
dudmuck 10:7382c260c4b1 191 if (m_xcvr.type == SX1276) {
dudmuck 10:7382c260c4b1 192 switch (RegModemConfig.sx1276bits.Bw) {
dudmuck 10:7382c260c4b1 193 case 0: khz = 7.8; break;
dudmuck 10:7382c260c4b1 194 case 1: khz = 10.4; break;
dudmuck 10:7382c260c4b1 195 case 2: khz = 15.6; break;
dudmuck 10:7382c260c4b1 196 case 3: khz = 20.8; break;
dudmuck 10:7382c260c4b1 197 case 4: khz = 31.25; break;
dudmuck 10:7382c260c4b1 198 case 5: khz = 41.7; break;
dudmuck 10:7382c260c4b1 199 case 6: khz = 62.5; break;
dudmuck 10:7382c260c4b1 200 case 7: khz = 125; break;
dudmuck 10:7382c260c4b1 201 case 8: khz = 250; break;
dudmuck 10:7382c260c4b1 202 case 9: khz = 500; break;
dudmuck 10:7382c260c4b1 203 }
dudmuck 10:7382c260c4b1 204 } else if (m_xcvr.type == SX1272) {
dudmuck 10:7382c260c4b1 205 switch (RegModemConfig.sx1272bits.Bw) {
dudmuck 10:7382c260c4b1 206 case 0: khz = 125; break;
dudmuck 10:7382c260c4b1 207 case 1: khz = 250; break;
dudmuck 10:7382c260c4b1 208 case 2: khz = 500; break;
dudmuck 10:7382c260c4b1 209 }
dudmuck 10:7382c260c4b1 210 }
dudmuck 10:7382c260c4b1 211
dudmuck 10:7382c260c4b1 212 // return symbol duration in milliseconds
dudmuck 10:7382c260c4b1 213 return (1 << RegModemConfig2.sx1276bits.SpreadingFactor) / khz;
dudmuck 10:7382c260c4b1 214 }
dudmuck 2:fdae76e1215e 215
dudmuck 16:3de8e1c465eb 216 void SX127x_lora::setBw_KHz(int khz)
dudmuck 16:3de8e1c465eb 217 {
dudmuck 16:3de8e1c465eb 218 uint8_t bw = 0;
dudmuck 16:3de8e1c465eb 219
dudmuck 16:3de8e1c465eb 220 if (m_xcvr.type == SX1276) {
dudmuck 16:3de8e1c465eb 221 if (khz <= 8) bw = 0;
dudmuck 16:3de8e1c465eb 222 else if (khz <= 11) bw = 1;
dudmuck 16:3de8e1c465eb 223 else if (khz <= 16) bw = 2;
dudmuck 16:3de8e1c465eb 224 else if (khz <= 21) bw = 3;
dudmuck 16:3de8e1c465eb 225 else if (khz <= 32) bw = 4;
dudmuck 16:3de8e1c465eb 226 else if (khz <= 42) bw = 5;
dudmuck 16:3de8e1c465eb 227 else if (khz <= 63) bw = 6;
dudmuck 16:3de8e1c465eb 228 else if (khz <= 125) bw = 7;
dudmuck 16:3de8e1c465eb 229 else if (khz <= 250) bw = 8;
dudmuck 16:3de8e1c465eb 230 else if (khz <= 500) bw = 9;
dudmuck 16:3de8e1c465eb 231 } else if (m_xcvr.type == SX1272) {
dudmuck 16:3de8e1c465eb 232 if (khz <= 125) bw = 0;
dudmuck 16:3de8e1c465eb 233 else if (khz <= 250) bw = 1;
dudmuck 16:3de8e1c465eb 234 else if (khz <= 500) bw = 2;
dudmuck 16:3de8e1c465eb 235 }
dudmuck 16:3de8e1c465eb 236
dudmuck 16:3de8e1c465eb 237 setBw(bw);
dudmuck 16:3de8e1c465eb 238 }
dudmuck 16:3de8e1c465eb 239
dudmuck 2:fdae76e1215e 240 void SX127x_lora::setBw(uint8_t bw)
dudmuck 2:fdae76e1215e 241 {
dudmuck 2:fdae76e1215e 242 if (!m_xcvr.RegOpMode.bits.LongRangeMode)
dudmuck 2:fdae76e1215e 243 return;
dudmuck 2:fdae76e1215e 244
dudmuck 19:1ee6ef1ab73f 245 if (m_xcvr.type == SX1276) {
dudmuck 2:fdae76e1215e 246 RegModemConfig.sx1276bits.Bw = bw;
dudmuck 10:7382c260c4b1 247 if (get_symbol_period() > 16)
dudmuck 10:7382c260c4b1 248 RegModemConfig3.sx1276bits.LowDataRateOptimize = 1;
dudmuck 10:7382c260c4b1 249 else
dudmuck 10:7382c260c4b1 250 RegModemConfig3.sx1276bits.LowDataRateOptimize = 0;
dudmuck 19:1ee6ef1ab73f 251 m_xcvr.write_reg(REG_LR_MODEMCONFIG3, RegModemConfig3.octet);
dudmuck 10:7382c260c4b1 252 } else if (m_xcvr.type == SX1272) {
dudmuck 2:fdae76e1215e 253 RegModemConfig.sx1272bits.Bw = bw;
dudmuck 10:7382c260c4b1 254 if (get_symbol_period() > 16)
dudmuck 2:fdae76e1215e 255 RegModemConfig.sx1272bits.LowDataRateOptimize = 1;
dudmuck 2:fdae76e1215e 256 else
dudmuck 2:fdae76e1215e 257 RegModemConfig.sx1272bits.LowDataRateOptimize = 0;
dudmuck 2:fdae76e1215e 258 } else
dudmuck 2:fdae76e1215e 259 return;
dudmuck 2:fdae76e1215e 260
dudmuck 2:fdae76e1215e 261 m_xcvr.write_reg(REG_LR_MODEMCONFIG, RegModemConfig.octet);
dudmuck 2:fdae76e1215e 262 }
dudmuck 2:fdae76e1215e 263
dudmuck 2:fdae76e1215e 264
dudmuck 2:fdae76e1215e 265
dudmuck 2:fdae76e1215e 266 uint8_t SX127x_lora::getSf(void)
dudmuck 2:fdae76e1215e 267 {
dudmuck 2:fdae76e1215e 268 // spreading factor same between sx127[26]
dudmuck 2:fdae76e1215e 269 return RegModemConfig2.sx1276bits.SpreadingFactor;
dudmuck 2:fdae76e1215e 270 }
dudmuck 2:fdae76e1215e 271
dudmuck 2:fdae76e1215e 272 void SX127x_lora::set_nb_trig_peaks(int n)
dudmuck 2:fdae76e1215e 273 {
dudmuck 13:1953e70522aa 274 /* TODO: different requirements for RX_CONTINUOUS vs RX_SINGLE */
dudmuck 2:fdae76e1215e 275 RegTest31.bits.detect_trig_same_peaks_nb = n;
dudmuck 2:fdae76e1215e 276 m_xcvr.write_reg(REG_LR_TEST31, RegTest31.octet);
dudmuck 2:fdae76e1215e 277 }
dudmuck 2:fdae76e1215e 278
dudmuck 2:fdae76e1215e 279
dudmuck 2:fdae76e1215e 280 void SX127x_lora::setSf(uint8_t sf)
dudmuck 2:fdae76e1215e 281 {
dudmuck 2:fdae76e1215e 282 if (!m_xcvr.RegOpMode.bits.LongRangeMode)
dudmuck 19:1ee6ef1ab73f 283 return;
dudmuck 19:1ee6ef1ab73f 284
dudmuck 2:fdae76e1215e 285 // write register at 0x37 with value 0xc if at SF6
dudmuck 2:fdae76e1215e 286 if (sf < 7)
dudmuck 2:fdae76e1215e 287 m_xcvr.write_reg(REG_LR_DETECTION_THRESHOLD, 0x0c);
dudmuck 2:fdae76e1215e 288 else
dudmuck 2:fdae76e1215e 289 m_xcvr.write_reg(REG_LR_DETECTION_THRESHOLD, 0x0a);
dudmuck 2:fdae76e1215e 290
dudmuck 2:fdae76e1215e 291 RegModemConfig2.sx1276bits.SpreadingFactor = sf; // spreading factor same between sx127[26]
dudmuck 2:fdae76e1215e 292 m_xcvr.write_reg(REG_LR_MODEMCONFIG2, RegModemConfig2.octet);
dudmuck 2:fdae76e1215e 293
dudmuck 2:fdae76e1215e 294 if (m_xcvr.type == SX1272) {
dudmuck 10:7382c260c4b1 295 if (get_symbol_period() > 16)
dudmuck 2:fdae76e1215e 296 RegModemConfig.sx1272bits.LowDataRateOptimize = 1;
dudmuck 2:fdae76e1215e 297 else
dudmuck 2:fdae76e1215e 298 RegModemConfig.sx1272bits.LowDataRateOptimize = 0;
dudmuck 2:fdae76e1215e 299 m_xcvr.write_reg(REG_LR_MODEMCONFIG, RegModemConfig.octet);
dudmuck 2:fdae76e1215e 300 } else if (m_xcvr.type == SX1276) {
dudmuck 10:7382c260c4b1 301 if (get_symbol_period() > 16)
dudmuck 2:fdae76e1215e 302 RegModemConfig3.sx1276bits.LowDataRateOptimize = 1;
dudmuck 2:fdae76e1215e 303 else
dudmuck 2:fdae76e1215e 304 RegModemConfig3.sx1276bits.LowDataRateOptimize = 0;
dudmuck 2:fdae76e1215e 305 m_xcvr.write_reg(REG_LR_MODEMCONFIG3, RegModemConfig3.octet);
dudmuck 2:fdae76e1215e 306 }
dudmuck 2:fdae76e1215e 307 }
dudmuck 2:fdae76e1215e 308
dudmuck 2:fdae76e1215e 309
dudmuck 2:fdae76e1215e 310
dudmuck 2:fdae76e1215e 311 bool SX127x_lora::getRxPayloadCrcOn(void)
dudmuck 2:fdae76e1215e 312 {
dudmuck 26:4876e515ff4c 313 /* RxPayloadCrcOn enables CRC generation in transmitter */
dudmuck 26:4876e515ff4c 314 /* in implicit mode, this bit also enables CRC in receiver */
dudmuck 26:4876e515ff4c 315 if (m_xcvr.type == SX1276) {
dudmuck 26:4876e515ff4c 316 RegModemConfig2.octet = m_xcvr.read_reg(REG_LR_MODEMCONFIG2);
dudmuck 2:fdae76e1215e 317 return RegModemConfig2.sx1276bits.RxPayloadCrcOn;
dudmuck 26:4876e515ff4c 318 } else if (m_xcvr.type == SX1272) {
dudmuck 26:4876e515ff4c 319 RegModemConfig.octet = m_xcvr.read_reg(REG_LR_MODEMCONFIG);
dudmuck 2:fdae76e1215e 320 return RegModemConfig.sx1272bits.RxPayloadCrcOn;
dudmuck 26:4876e515ff4c 321 } else
dudmuck 2:fdae76e1215e 322 return 0;
dudmuck 2:fdae76e1215e 323 }
dudmuck 2:fdae76e1215e 324
dudmuck 2:fdae76e1215e 325
dudmuck 2:fdae76e1215e 326 void SX127x_lora::setRxPayloadCrcOn(bool on)
dudmuck 2:fdae76e1215e 327 {
dudmuck 2:fdae76e1215e 328 if (m_xcvr.type == SX1276) {
dudmuck 2:fdae76e1215e 329 RegModemConfig2.sx1276bits.RxPayloadCrcOn = on;
dudmuck 2:fdae76e1215e 330 m_xcvr.write_reg(REG_LR_MODEMCONFIG2, RegModemConfig2.octet);
dudmuck 2:fdae76e1215e 331 } else if (m_xcvr.type == SX1272) {
dudmuck 2:fdae76e1215e 332 RegModemConfig.sx1272bits.RxPayloadCrcOn = on;
dudmuck 2:fdae76e1215e 333 m_xcvr.write_reg(REG_LR_MODEMCONFIG, RegModemConfig.octet);
dudmuck 2:fdae76e1215e 334 }
dudmuck 2:fdae76e1215e 335 }
dudmuck 2:fdae76e1215e 336
dudmuck 2:fdae76e1215e 337
dudmuck 2:fdae76e1215e 338
dudmuck 2:fdae76e1215e 339 bool SX127x_lora::getAgcAutoOn(void)
dudmuck 2:fdae76e1215e 340 {
dudmuck 2:fdae76e1215e 341 if (m_xcvr.type == SX1276) {
dudmuck 2:fdae76e1215e 342 RegModemConfig3.octet = m_xcvr.read_reg(REG_LR_MODEMCONFIG3);
dudmuck 2:fdae76e1215e 343 return RegModemConfig3.sx1276bits.AgcAutoOn;
dudmuck 2:fdae76e1215e 344 } else if (m_xcvr.type == SX1272) {
dudmuck 2:fdae76e1215e 345 RegModemConfig2.octet = m_xcvr.read_reg(REG_LR_MODEMCONFIG2);
dudmuck 2:fdae76e1215e 346 return RegModemConfig2.sx1272bits.AgcAutoOn;
dudmuck 2:fdae76e1215e 347 } else
dudmuck 2:fdae76e1215e 348 return 0;
dudmuck 2:fdae76e1215e 349 }
dudmuck 2:fdae76e1215e 350
dudmuck 2:fdae76e1215e 351 void SX127x_lora::setAgcAutoOn(bool on)
dudmuck 2:fdae76e1215e 352 {
dudmuck 2:fdae76e1215e 353 if (m_xcvr.type == SX1276) {
dudmuck 2:fdae76e1215e 354 RegModemConfig3.sx1276bits.AgcAutoOn = on;
dudmuck 2:fdae76e1215e 355 m_xcvr.write_reg(REG_LR_MODEMCONFIG3, RegModemConfig3.octet);
dudmuck 2:fdae76e1215e 356 } else if (m_xcvr.type == SX1272) {
dudmuck 2:fdae76e1215e 357 RegModemConfig2.sx1272bits.AgcAutoOn = on;
dudmuck 2:fdae76e1215e 358 m_xcvr.write_reg(REG_LR_MODEMCONFIG2, RegModemConfig2.octet);
dudmuck 2:fdae76e1215e 359 }
dudmuck 2:fdae76e1215e 360
dudmuck 2:fdae76e1215e 361 }
dudmuck 2:fdae76e1215e 362
dudmuck 17:59279bc8cdab 363 void SX127x_lora::invert_tx(bool inv)
dudmuck 17:59279bc8cdab 364 {
dudmuck 17:59279bc8cdab 365 RegTest33.bits.chirp_invert_tx = !inv;
dudmuck 17:59279bc8cdab 366 m_xcvr.write_reg(REG_LR_TEST33, RegTest33.octet);
dudmuck 17:59279bc8cdab 367 }
dudmuck 17:59279bc8cdab 368
dudmuck 17:59279bc8cdab 369 void SX127x_lora::invert_rx(bool inv)
dudmuck 17:59279bc8cdab 370 {
dudmuck 17:59279bc8cdab 371 RegTest33.bits.invert_i_q = inv;
dudmuck 17:59279bc8cdab 372 m_xcvr.write_reg(REG_LR_TEST33, RegTest33.octet);
dudmuck 17:59279bc8cdab 373 /**/
dudmuck 17:59279bc8cdab 374 RegDriftInvert.bits.invert_timing_error_per_symbol = !RegTest33.bits.invert_i_q;
dudmuck 17:59279bc8cdab 375 m_xcvr.write_reg(REG_LR_DRIFT_INVERT, RegDriftInvert.octet);
dudmuck 17:59279bc8cdab 376 }
dudmuck 17:59279bc8cdab 377
dudmuck 2:fdae76e1215e 378 void SX127x_lora::start_tx(uint8_t len)
dudmuck 7:927a05f84ede 379 {
dudmuck 2:fdae76e1215e 380 // DIO0 to TxDone
dudmuck 2:fdae76e1215e 381 if (m_xcvr.RegDioMapping1.bits.Dio0Mapping != 1) {
dudmuck 2:fdae76e1215e 382 m_xcvr.RegDioMapping1.bits.Dio0Mapping = 1;
dudmuck 2:fdae76e1215e 383 m_xcvr.write_reg(REG_DIOMAPPING1, m_xcvr.RegDioMapping1.octet);
dudmuck 2:fdae76e1215e 384 }
dudmuck 2:fdae76e1215e 385
dudmuck 2:fdae76e1215e 386 // set FifoPtrAddr to FifoTxPtrBase
dudmuck 2:fdae76e1215e 387 m_xcvr.write_reg(REG_LR_FIFOADDRPTR, m_xcvr.read_reg(REG_LR_FIFOTXBASEADDR));
dudmuck 2:fdae76e1215e 388
dudmuck 2:fdae76e1215e 389 // write PayloadLength bytes to fifo
dudmuck 2:fdae76e1215e 390 write_fifo(len);
dudmuck 7:927a05f84ede 391
dudmuck 2:fdae76e1215e 392 m_xcvr.set_opmode(RF_OPMODE_TRANSMITTER);
dudmuck 2:fdae76e1215e 393 }
dudmuck 2:fdae76e1215e 394
dudmuck 2:fdae76e1215e 395 void SX127x_lora::start_rx()
dudmuck 2:fdae76e1215e 396 {
dudmuck 2:fdae76e1215e 397 if (!m_xcvr.RegOpMode.bits.LongRangeMode)
dudmuck 12:bda42457c34a 398 return; // fsk mode
dudmuck 12:bda42457c34a 399 if (m_xcvr.RegOpMode.sx1276LORAbits.AccessSharedReg)
dudmuck 12:bda42457c34a 400 return; // fsk page
dudmuck 13:1953e70522aa 401
dudmuck 19:1ee6ef1ab73f 402 if (m_xcvr.type == SX1276) {
dudmuck 19:1ee6ef1ab73f 403 if (RegModemConfig.sx1276bits.Bw == 9) { // if 500KHz bw: improved tolerance of reference frequency error
dudmuck 19:1ee6ef1ab73f 404 if (RegAutoDrift.bits.freq_to_time_drift_auto) {
dudmuck 19:1ee6ef1ab73f 405 RegAutoDrift.bits.freq_to_time_drift_auto = 0;
dudmuck 19:1ee6ef1ab73f 406 m_xcvr.write_reg(REG_LR_SX1276_AUTO_DRIFT, RegAutoDrift.octet);
dudmuck 19:1ee6ef1ab73f 407 }
dudmuck 19:1ee6ef1ab73f 408 if (m_xcvr.HF) {
dudmuck 19:1ee6ef1ab73f 409 // > 525MHz
dudmuck 19:1ee6ef1ab73f 410 if (RegGainDrift.bits.freq_to_time_drift != 0x24) {
dudmuck 19:1ee6ef1ab73f 411 RegGainDrift.bits.freq_to_time_drift = 0x24;
dudmuck 19:1ee6ef1ab73f 412 m_xcvr.write_reg(REG_LR_GAIN_DRIFT, RegGainDrift.octet);
dudmuck 19:1ee6ef1ab73f 413 }
dudmuck 19:1ee6ef1ab73f 414 } else {
dudmuck 19:1ee6ef1ab73f 415 // < 525MHz
dudmuck 19:1ee6ef1ab73f 416 if (RegGainDrift.bits.freq_to_time_drift != 0x3f) {
dudmuck 19:1ee6ef1ab73f 417 RegGainDrift.bits.freq_to_time_drift = 0x3f;
dudmuck 19:1ee6ef1ab73f 418 m_xcvr.write_reg(REG_LR_GAIN_DRIFT, RegGainDrift.octet);
dudmuck 19:1ee6ef1ab73f 419 }
dudmuck 19:1ee6ef1ab73f 420 }
dudmuck 19:1ee6ef1ab73f 421
dudmuck 19:1ee6ef1ab73f 422 } else {
dudmuck 19:1ee6ef1ab73f 423 if (!RegAutoDrift.bits.freq_to_time_drift_auto) {
dudmuck 19:1ee6ef1ab73f 424 RegAutoDrift.bits.freq_to_time_drift_auto = 1;
dudmuck 19:1ee6ef1ab73f 425 m_xcvr.write_reg(REG_LR_SX1276_AUTO_DRIFT, RegAutoDrift.octet);
dudmuck 19:1ee6ef1ab73f 426 }
dudmuck 19:1ee6ef1ab73f 427 }
dudmuck 19:1ee6ef1ab73f 428 } // ... if (m_xcvr.type == SX1276)
dudmuck 19:1ee6ef1ab73f 429
dudmuck 19:1ee6ef1ab73f 430 // RX_CONTINUOUS: false detections vs missed detections tradeoff
dudmuck 19:1ee6ef1ab73f 431 switch (RegModemConfig2.sx1276bits.SpreadingFactor) {
dudmuck 19:1ee6ef1ab73f 432 case 6:
dudmuck 19:1ee6ef1ab73f 433 set_nb_trig_peaks(3);
dudmuck 19:1ee6ef1ab73f 434 break;
dudmuck 19:1ee6ef1ab73f 435 case 7:
dudmuck 19:1ee6ef1ab73f 436 set_nb_trig_peaks(4);
dudmuck 19:1ee6ef1ab73f 437 break;
dudmuck 19:1ee6ef1ab73f 438 default:
dudmuck 19:1ee6ef1ab73f 439 set_nb_trig_peaks(5);
dudmuck 19:1ee6ef1ab73f 440 break;
dudmuck 19:1ee6ef1ab73f 441 }
dudmuck 19:1ee6ef1ab73f 442
dudmuck 13:1953e70522aa 443 m_xcvr.set_opmode(RF_OPMODE_RECEIVER);
dudmuck 2:fdae76e1215e 444
dudmuck 2:fdae76e1215e 445 if (m_xcvr.RegDioMapping1.bits.Dio0Mapping != 0) {
dudmuck 2:fdae76e1215e 446 m_xcvr.RegDioMapping1.bits.Dio0Mapping = 0; // DIO0 to RxDone
dudmuck 2:fdae76e1215e 447 m_xcvr.write_reg(REG_DIOMAPPING1, m_xcvr.RegDioMapping1.octet);
dudmuck 2:fdae76e1215e 448 }
dudmuck 2:fdae76e1215e 449
dudmuck 2:fdae76e1215e 450 m_xcvr.write_reg(REG_LR_FIFOADDRPTR, m_xcvr.read_reg(REG_LR_FIFORXBASEADDR));
dudmuck 2:fdae76e1215e 451 }
dudmuck 2:fdae76e1215e 452
dudmuck 23:1df3dddcb43e 453 int SX127x_lora::get_pkt_rssi()
dudmuck 2:fdae76e1215e 454 {
dudmuck 23:1df3dddcb43e 455 if (m_xcvr.type == SX1276) {
dudmuck 23:1df3dddcb43e 456 if (m_xcvr.HF)
dudmuck 23:1df3dddcb43e 457 return RegPktRssiValue - 157;
dudmuck 23:1df3dddcb43e 458 else
dudmuck 23:1df3dddcb43e 459 return RegPktRssiValue - 164;
dudmuck 23:1df3dddcb43e 460 } else
dudmuck 2:fdae76e1215e 461 return RegPktRssiValue - 125;
dudmuck 2:fdae76e1215e 462 }
dudmuck 2:fdae76e1215e 463
dudmuck 23:1df3dddcb43e 464 int SX127x_lora::get_current_rssi()
dudmuck 23:1df3dddcb43e 465 {
dudmuck 23:1df3dddcb43e 466 uint8_t v = m_xcvr.read_reg(REG_LR_RSSIVALUE);
dudmuck 23:1df3dddcb43e 467 if (m_xcvr.type == SX1276) {
dudmuck 23:1df3dddcb43e 468 if (m_xcvr.HF)
dudmuck 23:1df3dddcb43e 469 return v - 157;
dudmuck 23:1df3dddcb43e 470 else
dudmuck 23:1df3dddcb43e 471 return v - 164;
dudmuck 23:1df3dddcb43e 472 } else
dudmuck 23:1df3dddcb43e 473 return v - 125;
dudmuck 23:1df3dddcb43e 474 }
dudmuck 23:1df3dddcb43e 475
dudmuck 2:fdae76e1215e 476 service_action_e SX127x_lora::service()
dudmuck 2:fdae76e1215e 477 {
dudmuck 2:fdae76e1215e 478 if (m_xcvr.RegOpMode.bits.Mode == RF_OPMODE_RECEIVER) {
dudmuck 2:fdae76e1215e 479 if (poll_vh) {
dudmuck 2:fdae76e1215e 480 RegIrqFlags.octet = m_xcvr.read_reg(REG_LR_IRQFLAGS);
dudmuck 2:fdae76e1215e 481 if (RegIrqFlags.bits.ValidHeader) {
dudmuck 2:fdae76e1215e 482 RegIrqFlags.octet = 0;
dudmuck 2:fdae76e1215e 483 RegIrqFlags.bits.ValidHeader = 1;
dudmuck 2:fdae76e1215e 484 m_xcvr.write_reg(REG_LR_IRQFLAGS, RegIrqFlags.octet);
dudmuck 2:fdae76e1215e 485 printf("VH\r\n");
dudmuck 2:fdae76e1215e 486 }
dudmuck 2:fdae76e1215e 487 }
dudmuck 2:fdae76e1215e 488 }
dudmuck 7:927a05f84ede 489
dudmuck 2:fdae76e1215e 490 if (m_xcvr.dio0 == 0)
dudmuck 2:fdae76e1215e 491 return SERVICE_NONE;
dudmuck 2:fdae76e1215e 492
dudmuck 2:fdae76e1215e 493 switch (m_xcvr.RegDioMapping1.bits.Dio0Mapping) {
dudmuck 2:fdae76e1215e 494 case 0: // RxDone
dudmuck 2:fdae76e1215e 495 /* user checks for CRC error in IrqFlags */
dudmuck 2:fdae76e1215e 496 RegIrqFlags.octet = m_xcvr.read_reg(REG_LR_IRQFLAGS); // save flags
dudmuck 2:fdae76e1215e 497 RegHopChannel.octet = m_xcvr.read_reg(REG_LR_HOPCHANNEL);
dudmuck 2:fdae76e1215e 498 //printf("[%02x]", RegIrqFlags.octet);
dudmuck 2:fdae76e1215e 499 m_xcvr.write_reg(REG_LR_IRQFLAGS, RegIrqFlags.octet); // clear flags in radio
dudmuck 2:fdae76e1215e 500
dudmuck 2:fdae76e1215e 501 /* any register of interest on received packet is read(saved) here */
dudmuck 2:fdae76e1215e 502 RegModemStatus.octet = m_xcvr.read_reg(REG_LR_MODEMSTAT);
dudmuck 2:fdae76e1215e 503 RegPktSnrValue = m_xcvr.read_reg(REG_LR_PKTSNRVALUE);
dudmuck 2:fdae76e1215e 504 RegPktRssiValue = m_xcvr.read_reg(REG_LR_PKTRSSIVALUE);
dudmuck 2:fdae76e1215e 505 RegRxNbBytes = m_xcvr.read_reg(REG_LR_RXNBBYTES);
dudmuck 2:fdae76e1215e 506
dudmuck 2:fdae76e1215e 507 m_xcvr.write_reg(REG_LR_FIFOADDRPTR, m_xcvr.read_reg(REG_LR_FIFORXCURRENTADDR));
dudmuck 2:fdae76e1215e 508 read_fifo(RegRxNbBytes);
dudmuck 2:fdae76e1215e 509 return SERVICE_READ_FIFO;
dudmuck 2:fdae76e1215e 510 case 1: // TxDone
dudmuck 2:fdae76e1215e 511 RegIrqFlags.octet = 0;
dudmuck 2:fdae76e1215e 512 RegIrqFlags.bits.TxDone = 1;
dudmuck 2:fdae76e1215e 513 m_xcvr.write_reg(REG_LR_IRQFLAGS, RegIrqFlags.octet);
dudmuck 2:fdae76e1215e 514 return SERVICE_TX_DONE;
dudmuck 2:fdae76e1215e 515 } // ...switch (RegDioMapping1.bits.Dio0Mapping)
dudmuck 2:fdae76e1215e 516
dudmuck 2:fdae76e1215e 517 return SERVICE_ERROR;
dudmuck 12:bda42457c34a 518 }
dudmuck 12:bda42457c34a 519