hello world
Fork of lmic_MOTE_L152RC by
Embed:
(wiki syntax)
Show/hide line numbers
radio.cpp
00001 /******************************************************************************* 00002 * Copyright (c) 2014-2015 IBM Corporation. 00003 * All rights reserved. This program and the accompanying materials 00004 * are made available under the terms of the Eclipse Public License v1.0 00005 * which accompanies this distribution, and is available at 00006 * http://www.eclipse.org/legal/epl-v10.html 00007 * 00008 * Contributors: 00009 * IBM Zurich Research Lab - initial API, implementation and documentation 00010 *******************************************************************************/ 00011 00012 #include "lmic.h" 00013 #include "mbed.h" 00014 00015 // ---------------------------------------- 00016 // Registers Mapping 00017 #define RegFifo 0x00 // common 00018 #define RegOpMode 0x01 // common 00019 #define FSKRegBitrateMsb 0x02 00020 #define FSKRegBitrateLsb 0x03 00021 #define FSKRegFdevMsb 0x04 00022 #define FSKRegFdevLsb 0x05 00023 #define RegFrfMsb 0x06 // common 00024 #define RegFrfMid 0x07 // common 00025 #define RegFrfLsb 0x08 // common 00026 #define RegPaConfig 0x09 // common 00027 #define RegPaRamp 0x0A // common 00028 #define RegOcp 0x0B // common 00029 #define RegLna 0x0C // common 00030 #define FSKRegRxConfig 0x0D 00031 #define LORARegFifoAddrPtr 0x0D 00032 #define FSKRegRssiConfig 0x0E 00033 #define LORARegFifoTxBaseAddr 0x0E 00034 #define FSKRegRssiCollision 0x0F 00035 #define LORARegFifoRxBaseAddr 0x0F 00036 #define FSKRegRssiThresh 0x10 00037 #define LORARegFifoRxCurrentAddr 0x10 00038 #define FSKRegRssiValue 0x11 00039 #define LORARegIrqFlagsMask 0x11 00040 #define FSKRegRxBw 0x12 00041 #define LORARegIrqFlags 0x12 00042 #define FSKRegAfcBw 0x13 00043 #define LORARegRxNbBytes 0x13 00044 #define FSKRegOokPeak 0x14 00045 #define LORARegRxHeaderCntValueMsb 0x14 00046 #define FSKRegOokFix 0x15 00047 #define LORARegRxHeaderCntValueLsb 0x15 00048 #define FSKRegOokAvg 0x16 00049 #define LORARegRxPacketCntValueMsb 0x16 00050 #define LORARegRxpacketCntValueLsb 0x17 00051 #define LORARegModemStat 0x18 00052 #define LORARegPktSnrValue 0x19 00053 #define FSKRegAfcFei 0x1A 00054 #define LORARegPktRssiValue 0x1A 00055 #define FSKRegAfcMsb 0x1B 00056 #define LORARegRssiValue 0x1B 00057 #define FSKRegAfcLsb 0x1C 00058 #define LORARegHopChannel 0x1C 00059 #define FSKRegFeiMsb 0x1D 00060 #define LORARegModemConfig1 0x1D 00061 #define FSKRegFeiLsb 0x1E 00062 #define LORARegModemConfig2 0x1E 00063 #define FSKRegPreambleDetect 0x1F 00064 #define LORARegSymbTimeoutLsb 0x1F 00065 #define FSKRegRxTimeout1 0x20 00066 #define LORARegPreambleMsb 0x20 00067 #define FSKRegRxTimeout2 0x21 00068 #define LORARegPreambleLsb 0x21 00069 #define FSKRegRxTimeout3 0x22 00070 #define LORARegPayloadLength 0x22 00071 #define FSKRegRxDelay 0x23 00072 #define LORARegPayloadMaxLength 0x23 00073 #define FSKRegOsc 0x24 00074 #define LORARegHopPeriod 0x24 00075 #define FSKRegPreambleMsb 0x25 00076 #define LORARegFifoRxByteAddr 0x25 00077 #define LORARegModemConfig3 0x26 00078 #define FSKRegPreambleLsb 0x26 00079 #define FSKRegSyncConfig 0x27 00080 #define LORARegFeiMsb 0x28 00081 #define FSKRegSyncValue1 0x28 00082 #define LORAFeiMib 0x29 00083 #define FSKRegSyncValue2 0x29 00084 #define LORARegFeiLsb 0x2A 00085 #define FSKRegSyncValue3 0x2A 00086 #define FSKRegSyncValue4 0x2B 00087 #define LORARegRssiWideband 0x2C 00088 #define FSKRegSyncValue5 0x2C 00089 #define FSKRegSyncValue6 0x2D 00090 #define FSKRegSyncValue7 0x2E 00091 #define FSKRegSyncValue8 0x2F 00092 #define FSKRegPacketConfig1 0x30 00093 #define FSKRegPacketConfig2 0x31 00094 #define LORARegDetectOptimize 0x31 00095 #define FSKRegPayloadLength 0x32 00096 #define FSKRegNodeAdrs 0x33 00097 #define LORARegInvertIQ 0x33 00098 #define FSKRegBroadcastAdrs 0x34 00099 #define FSKRegFifoThresh 0x35 00100 #define FSKRegSeqConfig1 0x36 00101 #define FSKRegSeqConfig2 0x37 00102 #define LORARegDetectionThreshold 0x37 00103 #define FSKRegTimerResol 0x38 00104 #define FSKRegTimer1Coef 0x39 00105 #define LORARegSyncWord 0x39 00106 #define FSKRegTimer2Coef 0x3A 00107 #define FSKRegImageCal 0x3B 00108 #define LORARegTimingInvert 0x3B // bit2 in 0x3b set low when bit6 in 0x33 set hi (RX invert) 00109 #define FSKRegTemp 0x3C 00110 #define FSKRegLowBat 0x3D 00111 #define FSKRegIrqFlags1 0x3E 00112 #define FSKRegIrqFlags2 0x3F 00113 #define RegDioMapping1 0x40 // common 00114 #define RegDioMapping2 0x41 // common 00115 #define RegVersion 0x42 // common 00116 // #define RegAgcRef 0x43 // common 00117 // #define RegAgcThresh1 0x44 // common 00118 // #define RegAgcThresh2 0x45 // common 00119 // #define RegAgcThresh3 0x46 // common 00120 // #define RegPllHop 0x4B // common 00121 // #define RegTcxo 0x58 // common 00122 #define RegPaDac 0x5A // common 00123 // #define RegPll 0x5C // common 00124 // #define RegPllLowPn 0x5E // common 00125 // #define RegFormerTemp 0x6C // common 00126 // #define RegBitRateFrac 0x70 // common 00127 00128 // ---------------------------------------- 00129 // spread factors and mode for RegModemConfig2 00130 #define SX1272_MC2_FSK 0x00 00131 #define SX1272_MC2_SF7 0x70 00132 #define SX1272_MC2_SF8 0x80 00133 #define SX1272_MC2_SF9 0x90 00134 #define SX1272_MC2_SF10 0xA0 00135 #define SX1272_MC2_SF11 0xB0 00136 #define SX1272_MC2_SF12 0xC0 00137 // bandwidth for RegModemConfig1 00138 #define SX1272_MC1_BW_125 0x00 00139 #define SX1272_MC1_BW_250 0x40 00140 #define SX1272_MC1_BW_500 0x80 00141 // coding rate for RegModemConfig1 00142 #define SX1272_MC1_CR_4_5 0x08 00143 #define SX1272_MC1_CR_4_6 0x10 00144 #define SX1272_MC1_CR_4_7 0x18 00145 #define SX1272_MC1_CR_4_8 0x20 00146 #define SX1272_MC1_IMPLICIT_HEADER_MODE_ON 0x04 // required for receive 00147 #define SX1272_MC1_RX_PAYLOAD_CRCON 0x02 00148 #define SX1272_MC1_LOW_DATA_RATE_OPTIMIZE 0x01 // mandated for SF11 and SF12 00149 // transmit power configuration for RegPaConfig 00150 #define SX1272_PAC_PA_SELECT_PA_BOOST 0x80 00151 #define SX1272_PAC_PA_SELECT_RFIO_PIN 0x00 00152 00153 00154 // sx1276 RegModemConfig1 00155 #define SX1276_MC1_BW_125 0x70 00156 #define SX1276_MC1_BW_250 0x80 00157 #define SX1276_MC1_BW_500 0x90 00158 #define SX1276_MC1_CR_4_5 0x02 00159 #define SX1276_MC1_CR_4_6 0x04 00160 #define SX1276_MC1_CR_4_7 0x06 00161 #define SX1276_MC1_CR_4_8 0x08 00162 00163 #define SX1276_MC1_IMPLICIT_HEADER_MODE_ON 0x01 00164 00165 // sx1276 RegModemConfig2 00166 #define SX1276_MC2_RX_PAYLOAD_CRCON 0x04 00167 00168 // sx1276 RegModemConfig3 00169 #define SX1276_MC3_LOW_DATA_RATE_OPTIMIZE 0x08 00170 #define SX1276_MC3_AGCAUTO 0x04 00171 00172 // preamble for lora networks (nibbles swapped) 00173 #define LORA_MAC_PREAMBLE 0x34 00174 00175 #define RXLORA_RXMODE_RSSI_REG_MODEM_CONFIG1 0x0A 00176 #ifdef CFG_sx1276_radio 00177 #define RXLORA_RXMODE_RSSI_REG_MODEM_CONFIG2 0x70 00178 #elif defined(CFG_sx1272_radio) 00179 #define RXLORA_RXMODE_RSSI_REG_MODEM_CONFIG2 0x74 00180 #endif 00181 00182 00183 00184 // ---------------------------------------- 00185 // Constants for radio registers 00186 #define OPMODE_LORA 0x80 00187 #define OPMODE_MASK 0x07 00188 #define OPMODE_SLEEP 0x00 00189 #define OPMODE_STANDBY 0x01 00190 #define OPMODE_FSTX 0x02 00191 #define OPMODE_TX 0x03 00192 #define OPMODE_FSRX 0x04 00193 #define OPMODE_RX 0x05 00194 #define OPMODE_RX_SINGLE 0x06 00195 #define OPMODE_CAD 0x07 00196 00197 // ---------------------------------------- 00198 // Bits masking the corresponding IRQs from the radio 00199 #define IRQ_LORA_RXTOUT_MASK 0x80 00200 #define IRQ_LORA_RXDONE_MASK 0x40 00201 #define IRQ_LORA_CRCERR_MASK 0x20 00202 #define IRQ_LORA_HEADER_MASK 0x10 00203 #define IRQ_LORA_TXDONE_MASK 0x08 00204 #define IRQ_LORA_CDDONE_MASK 0x04 00205 #define IRQ_LORA_FHSSCH_MASK 0x02 00206 #define IRQ_LORA_CDDETD_MASK 0x01 00207 00208 #define IRQ_FSK1_MODEREADY_MASK 0x80 00209 #define IRQ_FSK1_RXREADY_MASK 0x40 00210 #define IRQ_FSK1_TXREADY_MASK 0x20 00211 #define IRQ_FSK1_PLLLOCK_MASK 0x10 00212 #define IRQ_FSK1_RSSI_MASK 0x08 00213 #define IRQ_FSK1_TIMEOUT_MASK 0x04 00214 #define IRQ_FSK1_PREAMBLEDETECT_MASK 0x02 00215 #define IRQ_FSK1_SYNCADDRESSMATCH_MASK 0x01 00216 #define IRQ_FSK2_FIFOFULL_MASK 0x80 00217 #define IRQ_FSK2_FIFOEMPTY_MASK 0x40 00218 #define IRQ_FSK2_FIFOLEVEL_MASK 0x20 00219 #define IRQ_FSK2_FIFOOVERRUN_MASK 0x10 00220 #define IRQ_FSK2_PACKETSENT_MASK 0x08 00221 #define IRQ_FSK2_PAYLOADREADY_MASK 0x04 00222 #define IRQ_FSK2_CRCOK_MASK 0x02 00223 #define IRQ_FSK2_LOWBAT_MASK 0x01 00224 00225 // ---------------------------------------- 00226 // DIO function mappings D0D1D2D3 00227 #define MAP_DIO0_LORA_RXDONE 0x00 // 00------ 00228 #define MAP_DIO0_LORA_TXDONE 0x40 // 01------ 00229 #define MAP_DIO1_LORA_RXTOUT 0x00 // --00---- 00230 #define MAP_DIO1_LORA_NOP 0x30 // --11---- 00231 #define MAP_DIO2_LORA_NOP 0x0c // ----11-- 00232 00233 #define MAP_DIO0_FSK_READY 0x00 // 00------ (packet sent / payload ready) 00234 #define MAP_DIO1_FSK_NOP 0x30 // --11---- 00235 #define MAP_DIO2_FSK_TXNOP 0x04 // ----01-- 00236 #define MAP_DIO2_FSK_TIMEOUT 0x08 // ----10-- 00237 00238 00239 // FSK IMAGECAL defines 00240 #define RF_IMAGECAL_AUTOIMAGECAL_MASK 0x7F 00241 #define RF_IMAGECAL_AUTOIMAGECAL_ON 0x80 00242 #define RF_IMAGECAL_AUTOIMAGECAL_OFF 0x00 // Default 00243 00244 #define RF_IMAGECAL_IMAGECAL_MASK 0xBF 00245 #define RF_IMAGECAL_IMAGECAL_START 0x40 00246 00247 #define RF_IMAGECAL_IMAGECAL_RUNNING 0x20 00248 #define RF_IMAGECAL_IMAGECAL_DONE 0x00 // Default 00249 00250 00251 // RADIO STATE 00252 // (initialized by radio_init(), used by radio_rand1()) 00253 static u1_t randbuf[16]; 00254 static u1_t PaSelect; 00255 00256 #ifdef CFG_sx1276_radio 00257 #define LNA_RX_GAIN (0x20|0x1) 00258 #elif defined(CFG_sx1272_radio) 00259 #define LNA_RX_GAIN (0x20|0x03) 00260 #else 00261 #error Missing CFG_sx1272_radio/CFG_sx1276_radio 00262 #endif 00263 00264 00265 static void writeReg (u1_t addr, u1_t data ) { 00266 hal_pin_nss(0); 00267 hal_spi(addr | 0x80); 00268 hal_spi(data); 00269 hal_pin_nss(1); 00270 } 00271 00272 static u1_t readReg (u1_t addr) { 00273 hal_pin_nss(0); 00274 hal_spi(addr & 0x7F); 00275 u1_t val = hal_spi(0x00); 00276 hal_pin_nss(1); 00277 return val; 00278 } 00279 00280 static void writeBuf (u1_t addr, xref2u1_t buf, u1_t len) { 00281 hal_pin_nss(0); 00282 hal_spi(addr | 0x80); 00283 for (u1_t i=0; i<len; i++) { 00284 hal_spi(buf[i]); 00285 } 00286 hal_pin_nss(1); 00287 } 00288 00289 static void readBuf (u1_t addr, xref2u1_t buf, u1_t len) { 00290 hal_pin_nss(0); 00291 hal_spi(addr & 0x7F); 00292 for (u1_t i=0; i<len; i++) { 00293 buf[i] = hal_spi(0x00); 00294 } 00295 hal_pin_nss(1); 00296 } 00297 00298 static void opmode (u1_t mode) { 00299 hal_opmode(mode, PaSelect); 00300 writeReg(RegOpMode, (readReg(RegOpMode) & ~OPMODE_MASK) | mode); 00301 } 00302 00303 static void opmodeLora() { 00304 u1_t u = OPMODE_LORA; 00305 #ifdef CFG_sx1276_radio 00306 u |= 0x8; // TBD: sx1276 high freq 00307 #endif 00308 writeReg(RegOpMode, u); 00309 } 00310 00311 static void opmodeFSK() { 00312 u1_t u = 0; 00313 #ifdef CFG_sx1276_radio 00314 u |= 0x8; // TBD: sx1276 high freq 00315 #endif 00316 writeReg(RegOpMode, u); 00317 } 00318 00319 // configure LoRa modem (cfg1, cfg2) 00320 static void configLoraModem () { 00321 sf_t sf = getSf(LMIC.rps); 00322 00323 #ifdef CFG_sx1276_radio 00324 u1_t mc1 = 0, mc2 = 0, mc3 = 0; 00325 00326 switch (getBw(LMIC.rps)) { 00327 case BW125: mc1 |= SX1276_MC1_BW_125; break; 00328 case BW250: mc1 |= SX1276_MC1_BW_250; break; 00329 case BW500: mc1 |= SX1276_MC1_BW_500; break; 00330 default: 00331 ASSERT(0); 00332 } 00333 switch( getCr(LMIC.rps) ) { 00334 case CR_4_5: mc1 |= SX1276_MC1_CR_4_5; break; 00335 case CR_4_6: mc1 |= SX1276_MC1_CR_4_6; break; 00336 case CR_4_7: mc1 |= SX1276_MC1_CR_4_7; break; 00337 case CR_4_8: mc1 |= SX1276_MC1_CR_4_8; break; 00338 default: 00339 ASSERT(0); 00340 } 00341 00342 if (getIh(LMIC.rps)) { 00343 mc1 |= SX1276_MC1_IMPLICIT_HEADER_MODE_ON; 00344 writeReg(LORARegPayloadLength, getIh(LMIC.rps)); // required length 00345 } 00346 // set ModemConfig1 00347 writeReg(LORARegModemConfig1, mc1); 00348 00349 mc2 = (SX1272_MC2_SF7 + ((sf-1)<<4)); 00350 if (getNocrc(LMIC.rps) == 0) { 00351 mc2 |= SX1276_MC2_RX_PAYLOAD_CRCON; 00352 } 00353 writeReg(LORARegModemConfig2, mc2); 00354 00355 mc3 = SX1276_MC3_AGCAUTO; 00356 if ((sf == SF11 || sf == SF12) && getBw(LMIC.rps) == BW125) { 00357 mc3 |= SX1276_MC3_LOW_DATA_RATE_OPTIMIZE; 00358 } 00359 writeReg(LORARegModemConfig3, mc3); 00360 #elif defined(CFG_sx1272_radio) 00361 u1_t mc1 = (getBw(LMIC.rps)<<6); 00362 00363 switch( getCr(LMIC.rps) ) { 00364 case CR_4_5: mc1 |= SX1272_MC1_CR_4_5; break; 00365 case CR_4_6: mc1 |= SX1272_MC1_CR_4_6; break; 00366 case CR_4_7: mc1 |= SX1272_MC1_CR_4_7; break; 00367 case CR_4_8: mc1 |= SX1272_MC1_CR_4_8; break; 00368 } 00369 00370 if ((sf == SF11 || sf == SF12) && getBw(LMIC.rps) == BW125) { 00371 mc1 |= SX1272_MC1_LOW_DATA_RATE_OPTIMIZE; 00372 } 00373 00374 if (getNocrc(LMIC.rps) == 0) { 00375 mc1 |= SX1272_MC1_RX_PAYLOAD_CRCON; 00376 } 00377 00378 if (getIh(LMIC.rps)) { 00379 mc1 |= SX1272_MC1_IMPLICIT_HEADER_MODE_ON; 00380 writeReg(LORARegPayloadLength, getIh(LMIC.rps)); // required length 00381 } 00382 // set ModemConfig1 00383 writeReg(LORARegModemConfig1, mc1); 00384 00385 // set ModemConfig2 (sf, AgcAutoOn=1 SymbTimeoutHi=00) 00386 writeReg(LORARegModemConfig2, (SX1272_MC2_SF7 + ((sf-1)<<4)) | 0x04); 00387 #else 00388 #error Missing CFG_sx1272_radio/CFG_sx1276_radio 00389 #endif /* CFG_sx1272_radio */ 00390 } 00391 00392 static void configChannel () { 00393 // set frequency: FQ = (FRF * 32 Mhz) / (2 ^ 19) 00394 u8_t frf = ((u8_t)LMIC.freq << 19) / 32000000; 00395 writeReg(RegFrfMsb, (u1_t)(frf>>16)); 00396 writeReg(RegFrfMid, (u1_t)(frf>> 8)); 00397 writeReg(RegFrfLsb, (u1_t)(frf>> 0)); 00398 } 00399 00400 //DigitalOut pd2(PTC1); // power amplifier voltage control pin *** TODO *** 00401 00402 /* pd2=0 pd2=1 00403 op pab rfo rfo 00404 0 4.6 18.5 27.0 00405 1 5.6 21.1 28.1 00406 2 6.7 23.3 29.1 00407 3 7.7 25.3 30.1 00408 4 8.8 26.2 30.7 00409 5 9.8 27.3 31.2 00410 6 10.7 28.1 31.6 00411 7 11.7 28.6 32.2 00412 8 12.8 29.2 32.4 00413 9 13.7 29.9 32.9 00414 10 14.7 30.5 33.1 00415 11 15.6 30.8 33.4 00416 12 16.4 30.9 33.6 00417 13 17.1 31.0 33.7 00418 14 17.8 31.1 33.7 00419 15 18.4 31.1 33.7 00420 */ 00421 // txpow: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 00422 static const u1_t boost_table[20] = { 0, 0, 0, 0, 0, 1, 2, 3, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 15 }; 00423 00424 // txpow: 20 21 22 23 24 25 26 27 28 29 30 00425 static const u1_t rfo_table[11] = { 1, 1, 1, 2, 2, 3, 4, 5, 6, 8, 9 }; 00426 00427 static void configPower () { 00428 printf("txpow:%d ", LMIC.txpow); 00429 #ifdef CFG_sx1276_radio 00430 // no boost used for now 00431 s1_t pw = (s1_t)LMIC.txpow; 00432 if(pw >= 17) { 00433 pw = 15; 00434 } else if(pw < 2) { 00435 pw = 2; 00436 } 00437 // check board type for BOOST pin 00438 writeReg(RegPaConfig, (u1_t)(0x80|(pw&0xf))); 00439 writeReg(RegPaDac, readReg(RegPaDac)|0x4); 00440 00441 #elif defined(CFG_sx1272_radio) 00442 00443 /* NA-mote TX power config: */ 00444 if (LMIC.txpow > 19) { 00445 PaSelect = 0x00; // use RFO 00446 writeReg(RegPaConfig, PaSelect | rfo_table[LMIC.txpow-20]); 00447 // pd2 = 0; 00448 } else { 00449 PaSelect = 0x80; // use PA_BOOST 00450 writeReg(RegPaConfig, PaSelect | boost_table[LMIC.txpow]); 00451 } 00452 //printf("PaConfig:%02x\r\n", readReg(RegPaConfig)); 00453 00454 #else 00455 #error Missing CFG_sx1272_radio/CFG_sx1276_radio 00456 #endif /* CFG_sx1272_radio */ 00457 } 00458 00459 static void txfsk () { 00460 // select FSK modem (from sleep mode) 00461 writeReg(RegOpMode, 0x10); // FSK, BT=0.5 00462 ASSERT(readReg(RegOpMode) == 0x10); 00463 // enter standby mode (required for FIFO loading)) 00464 opmode(OPMODE_STANDBY); 00465 // set bitrate 00466 writeReg(FSKRegBitrateMsb, 0x02); // 50kbps 00467 writeReg(FSKRegBitrateLsb, 0x80); 00468 // set frequency deviation 00469 writeReg(FSKRegFdevMsb, 0x01); // +/- 25kHz 00470 writeReg(FSKRegFdevLsb, 0x99); 00471 // frame and packet handler settings 00472 writeReg(FSKRegPreambleMsb, 0x00); 00473 writeReg(FSKRegPreambleLsb, 0x05); 00474 writeReg(FSKRegSyncConfig, 0x12); 00475 writeReg(FSKRegPacketConfig1, 0xD0); 00476 writeReg(FSKRegPacketConfig2, 0x40); 00477 writeReg(FSKRegSyncValue1, 0xC1); 00478 writeReg(FSKRegSyncValue2, 0x94); 00479 writeReg(FSKRegSyncValue3, 0xC1); 00480 // configure frequency 00481 configChannel(); 00482 // configure output power 00483 configPower(); 00484 00485 // set the IRQ mapping DIO0=PacketSent DIO1=NOP DIO2=NOP 00486 writeReg(RegDioMapping1, MAP_DIO0_FSK_READY|MAP_DIO1_FSK_NOP|MAP_DIO2_FSK_TXNOP); 00487 00488 // initialize the payload size and address pointers 00489 writeReg(FSKRegPayloadLength, LMIC.dataLen+1); // (insert length byte into payload)) 00490 00491 // download length byte and buffer to the radio FIFO 00492 writeReg(RegFifo, LMIC.dataLen); 00493 writeBuf(RegFifo, LMIC.frame, LMIC.dataLen); 00494 00495 // enable antenna switch for TX 00496 //hal_pin_rxtx(1); usint hal_opmode 00497 00498 // now we actually start the transmission 00499 opmode(OPMODE_TX); 00500 } 00501 00502 static void txlora () { 00503 // select LoRa modem (from sleep mode) 00504 //writeReg(RegOpMode, OPMODE_LORA); 00505 opmodeLora(); 00506 ASSERT((readReg(RegOpMode) & OPMODE_LORA) != 0); 00507 00508 // enter standby mode (required for FIFO loading)) 00509 opmode(OPMODE_STANDBY); 00510 // configure LoRa modem (cfg1, cfg2) 00511 configLoraModem(); 00512 // configure frequency 00513 configChannel(); 00514 // configure output power 00515 writeReg(RegPaRamp, (readReg(RegPaRamp) & 0xF0) | 0x08); // set PA ramp-up time 50 uSec 00516 configPower(); 00517 // set sync word 00518 writeReg(LORARegSyncWord, LORA_MAC_PREAMBLE); 00519 00520 // set the IRQ mapping DIO0=TxDone DIO1=NOP DIO2=NOP 00521 writeReg(RegDioMapping1, MAP_DIO0_LORA_TXDONE|MAP_DIO1_LORA_NOP|MAP_DIO2_LORA_NOP); 00522 // clear all radio IRQ flags 00523 writeReg(LORARegIrqFlags, 0xFF); 00524 // mask all IRQs but TxDone 00525 writeReg(LORARegIrqFlagsMask, ~IRQ_LORA_TXDONE_MASK); 00526 00527 // initialize the payload size and address pointers 00528 writeReg(LORARegFifoTxBaseAddr, 0x00); 00529 writeReg(LORARegFifoAddrPtr, 0x00); 00530 writeReg(LORARegPayloadLength, LMIC.dataLen); 00531 00532 // download buffer to the radio FIFO 00533 writeBuf(RegFifo, LMIC.frame, LMIC.dataLen); 00534 00535 // enable antenna switch for TX 00536 //hal_pin_rxtx(1); using hal_opmode 00537 00538 // now we actually start the transmission 00539 opmode(OPMODE_TX); 00540 } 00541 00542 // start transmitter (buf=LMIC.frame, len=LMIC.dataLen) 00543 static void starttx () { 00544 ASSERT( (readReg(RegOpMode) & OPMODE_MASK) == OPMODE_SLEEP ); 00545 if(getSf(LMIC.rps) == FSK) { // FSK modem 00546 txfsk(); 00547 } else { // LoRa modem 00548 txlora(); 00549 } 00550 // the radio will go back to STANDBY mode as soon as the TX is finished 00551 // the corresponding IRQ will inform us about completion. 00552 } 00553 00554 enum { RXMODE_SINGLE, RXMODE_SCAN, RXMODE_RSSI }; 00555 00556 static const u1_t rxlorairqmask[] = { 00557 [RXMODE_SINGLE] = IRQ_LORA_RXDONE_MASK|IRQ_LORA_RXTOUT_MASK, 00558 [RXMODE_SCAN] = IRQ_LORA_RXDONE_MASK, 00559 [RXMODE_RSSI] = 0x00, 00560 }; 00561 00562 // start LoRa receiver (time=LMIC.rxtime, timeout=LMIC.rxsyms, result=LMIC.frame[LMIC.dataLen]) 00563 static void rxlora (u1_t rxmode) { 00564 // select LoRa modem (from sleep mode) 00565 opmodeLora(); 00566 ASSERT((readReg(RegOpMode) & OPMODE_LORA) != 0); 00567 // enter standby mode (warm up)) 00568 opmode(OPMODE_STANDBY); 00569 // don't use MAC settings at startup 00570 if(rxmode == RXMODE_RSSI) { // use fixed settings for rssi scan 00571 writeReg(LORARegModemConfig1, RXLORA_RXMODE_RSSI_REG_MODEM_CONFIG1); 00572 writeReg(LORARegModemConfig2, RXLORA_RXMODE_RSSI_REG_MODEM_CONFIG2); 00573 } else { // single or continuous rx mode 00574 // configure LoRa modem (cfg1, cfg2) 00575 configLoraModem(); 00576 // configure frequency 00577 configChannel(); 00578 } 00579 // set LNA gain 00580 writeReg(RegLna, LNA_RX_GAIN); 00581 // set max payload size 00582 writeReg(LORARegPayloadMaxLength, 64); 00583 // use inverted I/Q signal (prevent mote-to-mote communication) 00584 writeReg(LORARegInvertIQ, readReg(LORARegInvertIQ)|(1<<6)); 00585 // set symbol timeout (for single rx) 00586 writeReg(LORARegSymbTimeoutLsb, LMIC.rxsyms); 00587 // set sync word 00588 writeReg(LORARegSyncWord, LORA_MAC_PREAMBLE); 00589 00590 // configure DIO mapping DIO0=RxDone DIO1=RxTout DIO2=NOP 00591 writeReg(RegDioMapping1, MAP_DIO0_LORA_RXDONE|MAP_DIO1_LORA_RXTOUT|MAP_DIO2_LORA_NOP); 00592 // clear all radio IRQ flags 00593 writeReg(LORARegIrqFlags, 0xFF); 00594 // enable required radio IRQs 00595 writeReg(LORARegIrqFlagsMask, ~rxlorairqmask[rxmode]); 00596 00597 // enable antenna switch for RX 00598 //hal_pin_rxtx(0); using hal_opmode 00599 00600 // now instruct the radio to receive 00601 if (rxmode == RXMODE_SINGLE) { // single rx 00602 hal_waitUntil(LMIC.rxtime); // busy wait until exact rx time 00603 opmode(OPMODE_RX_SINGLE); 00604 } else { // continous rx (scan or rssi) 00605 opmode(OPMODE_RX); 00606 } 00607 } 00608 00609 static void rxfsk (u1_t rxmode) { 00610 // only single rx (no continuous scanning, no noise sampling) 00611 ASSERT( rxmode == RXMODE_SINGLE ); 00612 // select FSK modem (from sleep mode) 00613 //writeReg(RegOpMode, 0x00); // (not LoRa) 00614 opmodeFSK(); 00615 ASSERT((readReg(RegOpMode) & OPMODE_LORA) == 0); 00616 // enter standby mode (warm up)) 00617 opmode(OPMODE_STANDBY); 00618 // configure frequency 00619 configChannel(); 00620 // set LNA gain 00621 //writeReg(RegLna, 0x20|0x03); // max gain, boost enable 00622 writeReg(RegLna, LNA_RX_GAIN); 00623 // configure receiver 00624 writeReg(FSKRegRxConfig, 0x1E); // AFC auto, AGC, trigger on preamble?!? 00625 // set receiver bandwidth 00626 writeReg(FSKRegRxBw, 0x0B); // 50kHz SSb 00627 // set AFC bandwidth 00628 writeReg(FSKRegAfcBw, 0x12); // 83.3kHz SSB 00629 // set preamble detection 00630 writeReg(FSKRegPreambleDetect, 0xAA); // enable, 2 bytes, 10 chip errors 00631 // set sync config 00632 writeReg(FSKRegSyncConfig, 0x12); // no auto restart, preamble 0xAA, enable, fill FIFO, 3 bytes sync 00633 // set packet config 00634 writeReg(FSKRegPacketConfig1, 0xD8); // var-length, whitening, crc, no auto-clear, no adr filter 00635 writeReg(FSKRegPacketConfig2, 0x40); // packet mode 00636 // set sync value 00637 writeReg(FSKRegSyncValue1, 0xC1); 00638 writeReg(FSKRegSyncValue2, 0x94); 00639 writeReg(FSKRegSyncValue3, 0xC1); 00640 // set preamble timeout 00641 writeReg(FSKRegRxTimeout2, 0xFF);//(LMIC.rxsyms+1)/2); 00642 // set bitrate 00643 writeReg(FSKRegBitrateMsb, 0x02); // 50kbps 00644 writeReg(FSKRegBitrateLsb, 0x80); 00645 // set frequency deviation 00646 writeReg(FSKRegFdevMsb, 0x01); // +/- 25kHz 00647 writeReg(FSKRegFdevLsb, 0x99); 00648 00649 // configure DIO mapping DIO0=PayloadReady DIO1=NOP DIO2=TimeOut 00650 writeReg(RegDioMapping1, MAP_DIO0_FSK_READY|MAP_DIO1_FSK_NOP|MAP_DIO2_FSK_TIMEOUT); 00651 00652 // enable antenna switch for RX 00653 //hal_pin_rxtx(0); using hal_opmode 00654 00655 // now instruct the radio to receive 00656 hal_waitUntil(LMIC.rxtime); // busy wait until exact rx time 00657 opmode(OPMODE_RX); // no single rx mode available in FSK 00658 } 00659 00660 static void startrx (u1_t rxmode) { 00661 ASSERT( (readReg(RegOpMode) & OPMODE_MASK) == OPMODE_SLEEP ); 00662 if(getSf(LMIC.rps) == FSK) { // FSK modem 00663 rxfsk(rxmode); 00664 } else { // LoRa modem 00665 rxlora(rxmode); 00666 } 00667 // the radio will go back to STANDBY mode as soon as the RX is finished 00668 // or timed out, and the corresponding IRQ will inform us about completion. 00669 } 00670 00671 // get random seed from wideband noise rssi 00672 void radio_init () { 00673 hal_disableIRQs(); 00674 00675 // manually reset radio 00676 #ifdef CFG_sx1276_radio 00677 hal_pin_rst(0); // drive RST pin low 00678 #else 00679 hal_pin_rst(1); // drive RST pin high 00680 #endif 00681 hal_waitUntil(os_getTime()+ms2osticks(1)); // wait >100us 00682 hal_pin_rst(2); // configure RST pin floating! 00683 hal_waitUntil(os_getTime()+ms2osticks(5)); // wait 5ms 00684 00685 opmode(OPMODE_SLEEP); 00686 00687 // some sanity checks, e.g., read version number 00688 u1_t v = readReg(RegVersion); 00689 #ifdef CFG_sx1276_radio 00690 ASSERT(v == 0x12 ); 00691 #elif defined(CFG_sx1272_radio) 00692 ASSERT(v == 0x22); 00693 #else 00694 #error Missing CFG_sx1272_radio/CFG_sx1276_radio 00695 #endif 00696 // seed 15-byte randomness via noise rssi 00697 rxlora(RXMODE_RSSI); 00698 while( (readReg(RegOpMode) & OPMODE_MASK) != OPMODE_RX ); // continuous rx 00699 for(int i=1; i<16; i++) { 00700 for(int j=0; j<8; j++) { 00701 u1_t b; // wait for two non-identical subsequent least-significant bits 00702 while( (b = readReg(LORARegRssiWideband) & 0x01) == (readReg(LORARegRssiWideband) & 0x01) ); 00703 randbuf[i] = (randbuf[i] << 1) | b; 00704 } 00705 } 00706 randbuf[0] = 16; // set initial index 00707 00708 #ifdef CFG_sx1276mb1_board 00709 // chain calibration 00710 writeReg(RegPaConfig, 0); 00711 00712 // Launch Rx chain calibration for LF band 00713 writeReg(FSKRegImageCal, (readReg(FSKRegImageCal) & RF_IMAGECAL_IMAGECAL_MASK)|RF_IMAGECAL_IMAGECAL_START); 00714 while((readReg(FSKRegImageCal)&RF_IMAGECAL_IMAGECAL_RUNNING) == RF_IMAGECAL_IMAGECAL_RUNNING){ ; } 00715 00716 // Sets a Frequency in HF band 00717 u4_t frf = 868000000; 00718 writeReg(RegFrfMsb, (u1_t)(frf>>16)); 00719 writeReg(RegFrfMid, (u1_t)(frf>> 8)); 00720 writeReg(RegFrfLsb, (u1_t)(frf>> 0)); 00721 00722 // Launch Rx chain calibration for HF band 00723 writeReg(FSKRegImageCal, (readReg(FSKRegImageCal) & RF_IMAGECAL_IMAGECAL_MASK)|RF_IMAGECAL_IMAGECAL_START); 00724 while((readReg(FSKRegImageCal) & RF_IMAGECAL_IMAGECAL_RUNNING) == RF_IMAGECAL_IMAGECAL_RUNNING) { ; } 00725 #endif /* CFG_sx1276mb1_board */ 00726 00727 /* SF12/500KHz RX improvement (0x1d/0x19 choice): must match setting of LORARegInvertIQ */ 00728 writeReg(LORARegTimingInvert, 0x19); 00729 00730 opmode(OPMODE_SLEEP); 00731 00732 hal_enableIRQs(); 00733 } 00734 00735 // return next random byte derived from seed buffer 00736 // (buf[0] holds index of next byte to be returned) 00737 u1_t radio_rand1 () { 00738 u1_t i = randbuf[0]; 00739 ASSERT( i != 0 ); 00740 if( i==16 ) { 00741 os_aes(AES_ENC, randbuf, 16); // encrypt seed with any key 00742 i = 0; 00743 } 00744 u1_t v = randbuf[i++]; 00745 randbuf[0] = i; 00746 return v; 00747 } 00748 00749 u1_t radio_rssi () { 00750 hal_disableIRQs(); 00751 u1_t r = readReg(LORARegRssiValue); 00752 hal_enableIRQs(); 00753 return r; 00754 } 00755 00756 static const u2_t LORA_RXDONE_FIXUP[] = { 00757 [FSK] = us2osticks(0), // ( 0 ticks) 00758 [SF7] = us2osticks(0), // ( 0 ticks) 00759 [SF8] = us2osticks(1648), // ( 54 ticks) 00760 [SF9] = us2osticks(3265), // ( 107 ticks) 00761 [SF10] = us2osticks(7049), // ( 231 ticks) 00762 [SF11] = us2osticks(13641), // ( 447 ticks) 00763 [SF12] = us2osticks(31189), // (1022 ticks) 00764 }; 00765 00766 // called by hal ext IRQ handler 00767 // (radio goes to stanby mode after tx/rx operations) 00768 void radio_irq_handler (u1_t dio) { 00769 ostime_t now = os_getTime(); 00770 if( (readReg(RegOpMode) & OPMODE_LORA) != 0) { // LORA modem 00771 u1_t flags = readReg(LORARegIrqFlags); 00772 if( flags & IRQ_LORA_TXDONE_MASK ) { 00773 // save exact tx time 00774 LMIC.txend = now - us2osticks(43); // TXDONE FIXUP 00775 } else if( flags & IRQ_LORA_RXDONE_MASK ) { 00776 // save exact rx time 00777 if(getBw(LMIC.rps) == BW125) { 00778 now -= LORA_RXDONE_FIXUP[getSf(LMIC.rps)]; 00779 } 00780 LMIC.rxtime = now; 00781 // read the PDU and inform the MAC that we received something 00782 LMIC.dataLen = (readReg(LORARegModemConfig1) & SX1272_MC1_IMPLICIT_HEADER_MODE_ON) ? 00783 readReg(LORARegPayloadLength) : readReg(LORARegRxNbBytes); 00784 // set FIFO read address pointer 00785 writeReg(LORARegFifoAddrPtr, readReg(LORARegFifoRxCurrentAddr)); 00786 // now read the FIFO 00787 readBuf(RegFifo, LMIC.frame, LMIC.dataLen); 00788 // read rx quality parameters 00789 LMIC.snr = readReg(LORARegPktSnrValue); // SNR [dB] * 4 00790 LMIC.rssi = readReg(LORARegPktRssiValue) - 125 + 64; // RSSI [dBm] (-196...+63) 00791 } else if( flags & IRQ_LORA_RXTOUT_MASK ) { 00792 // indicate timeout 00793 LMIC.dataLen = 0; 00794 } 00795 // mask all radio IRQs 00796 writeReg(LORARegIrqFlagsMask, 0xFF); 00797 // clear radio IRQ flags 00798 writeReg(LORARegIrqFlags, 0xFF); 00799 } else { // FSK modem 00800 u1_t flags1 = readReg(FSKRegIrqFlags1); 00801 u1_t flags2 = readReg(FSKRegIrqFlags2); 00802 if( flags2 & IRQ_FSK2_PACKETSENT_MASK ) { 00803 // save exact tx time 00804 LMIC.txend = now; 00805 } else if( flags2 & IRQ_FSK2_PAYLOADREADY_MASK ) { 00806 // save exact rx time 00807 LMIC.rxtime = now; 00808 // read the PDU and inform the MAC that we received something 00809 LMIC.dataLen = readReg(FSKRegPayloadLength); 00810 // now read the FIFO 00811 readBuf(RegFifo, LMIC.frame, LMIC.dataLen); 00812 // read rx quality parameters 00813 LMIC.snr = 0; // determine snr 00814 LMIC.rssi = 0; // determine rssi 00815 } else if( flags1 & IRQ_FSK1_TIMEOUT_MASK ) { 00816 // indicate timeout 00817 LMIC.dataLen = 0; 00818 } else { 00819 while(1); 00820 } 00821 } 00822 // go from stanby to sleep 00823 opmode(OPMODE_SLEEP); 00824 // run os job (use preset func ptr) 00825 os_setCallback(&LMIC.osjob, LMIC.osjob.func); 00826 } 00827 00828 void os_radio (u1_t mode) { 00829 hal_disableIRQs(); 00830 switch (mode) { 00831 case RADIO_RST: 00832 // put radio to sleep 00833 opmode(OPMODE_SLEEP); 00834 break; 00835 00836 case RADIO_TX: 00837 // transmit frame now 00838 starttx(); // buf=LMIC.frame, len=LMIC.dataLen 00839 break; 00840 00841 case RADIO_RX: 00842 // receive frame now (exactly at rxtime) 00843 startrx(RXMODE_SINGLE); // buf=LMIC.frame, time=LMIC.rxtime, timeout=LMIC.rxsyms 00844 break; 00845 00846 case RADIO_RXON: 00847 // start scanning for beacon now 00848 startrx(RXMODE_SCAN); // buf=LMIC.frame 00849 break; 00850 } 00851 hal_enableIRQs(); 00852 }
Generated on Mon Jul 18 2022 04:23:42 by 1.7.2