123

Committer:
dudmuck
Date:
Tue Jun 02 01:25:47 2015 +0000
Revision:
18:0ecb6adb7c0b
Parent:
17:59279bc8cdab
Child:
19:1ee6ef1ab73f
sx1276 optimization for frequency error with 500KHz bw

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