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