star-mesh LoRa network

Dependencies:   sx12xx_hal

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers app_sx127x.cpp Source File

app_sx127x.cpp

00001 #include "sx12xx.h"
00002 #ifdef SX127x_H 
00003 #include "main.h"
00004 
00005 void lora_print_dio()
00006 {
00007     Radio::radio.RegDioMapping2.octet = Radio::radio.read_reg(REG_DIOMAPPING2);
00008     pc.printf("DIO5:");
00009     switch (Radio::radio.RegDioMapping2.bits.Dio5Mapping) {
00010         case 0: pc.printf("ModeReady"); break;
00011         case 1: pc.printf("ClkOut"); break;
00012         case 2: pc.printf("ClkOut"); break;
00013     }
00014     pc.printf(" DIO4:");
00015     switch (Radio::radio.RegDioMapping2.bits.Dio4Mapping) {
00016         case 0: pc.printf("CadDetected"); break;
00017         case 1: pc.printf("PllLock"); break;
00018         case 2: pc.printf("PllLock"); break;
00019     }    
00020     Radio::radio.RegDioMapping1.octet = Radio::radio.read_reg(REG_DIOMAPPING1);
00021     pc.printf(" DIO3:");
00022     switch (Radio::radio.RegDioMapping1.bits.Dio3Mapping) {
00023         case 0: pc.printf("CadDone"); break;
00024         case 1: pc.printf("ValidHeader"); break;
00025         case 2: pc.printf("PayloadCrcError"); break;
00026     }    
00027     pc.printf(" DIO2:");
00028     switch (Radio::radio.RegDioMapping1.bits.Dio2Mapping) {
00029         case 0:
00030         case 1:
00031         case 2:
00032             pc.printf("FhssChangeChannel");
00033             break;
00034     }    
00035     pc.printf(" DIO1:");
00036     switch (Radio::radio.RegDioMapping1.bits.Dio1Mapping) {
00037         case 0: pc.printf("RxTimeout"); break;
00038         case 1: pc.printf("FhssChangeChannel"); break;
00039         case 2: pc.printf("CadDetected"); break;
00040     }    
00041     pc.printf(" DIO0:");
00042     switch (Radio::radio.RegDioMapping1.bits.Dio0Mapping) {
00043         case 0: pc.printf("RxDone"); break;
00044         case 1: pc.printf("TxDone"); break;
00045         case 2: pc.printf("CadDone"); break;
00046     }    
00047     
00048     pc.printf("\r\n"); 
00049 }
00050 
00051 void lora_printAgcAutoOn()
00052 {
00053     pc.printf("AgcAutoOn:%d", Radio::lora.getAgcAutoOn());
00054 }
00055 
00056 void lora_printBw()
00057 {
00058     (void)Radio::lora.getBw();
00059     
00060     pc.printf("Bw:");
00061     if (Radio::radio.type == SX1276) {
00062         switch (Radio::lora.RegModemConfig.sx1276bits.Bw) {
00063             case 0: pc.printf("7.8KHz "); break;
00064             case 1: pc.printf("10.4KHz "); break;
00065             case 2: pc.printf("15.6KHz "); break;
00066             case 3: pc.printf("20.8KHz "); break;
00067             case 4: pc.printf("31.25KHz "); break;
00068             case 5: pc.printf("41.7KHz "); break;
00069             case 6: pc.printf("62.5KHz "); break;
00070             case 7: pc.printf("125KHz "); break;
00071             case 8: pc.printf("250KHz "); break;
00072             case 9: pc.printf("500KHz "); break;
00073             default: pc.printf("%x ", Radio::lora.RegModemConfig.sx1276bits.Bw); break;
00074         }
00075     } else if (Radio::radio.type == SX1272) {
00076         switch (Radio::lora.RegModemConfig.sx1272bits.Bw) {
00077             case 0: pc.printf("125KHz "); break;
00078             case 1: pc.printf("250KHz "); break;
00079             case 2: pc.printf("500KHz "); break;
00080             case 3: pc.printf("11b "); break;
00081         }
00082     }
00083 }
00084 
00085 void lora_printSf()
00086 {
00087     // spreading factor same between sx127[26]
00088     pc.printf("sf:%d ", Radio::lora.getSf());
00089 }
00090 
00091 void lora_printTxContinuousMode()
00092 {
00093     pc.printf("TxContinuousMode:%d ", Radio::lora.RegModemConfig2.sx1276bits.TxContinuousMode);    // same for sx1272 and sx1276
00094 }
00095 
00096 void radio_printLoraIrqs(bool clear)
00097 {
00098     //RegIrqFlags_t RegIrqFlags;
00099  
00100     Radio::lora.RegIrqFlags.octet = Radio::radio.read_reg(REG_LR_IRQFLAGS);
00101     pc.printf("\r\nIrqFlags:");
00102     if (Radio::lora.RegIrqFlags.bits.CadDetected)
00103         pc.printf("CadDetected ");
00104     if (Radio::lora.RegIrqFlags.bits.FhssChangeChannel) {
00105         //radio.RegHopChannel.octet = Radio::radio.read_reg(REG_LR_HOPCHANNEL);
00106         pc.printf("FhssChangeChannel:%d ", Radio::lora.RegHopChannel.bits.FhssPresentChannel);
00107     }
00108     if (Radio::lora.RegIrqFlags.bits.CadDone)
00109         pc.printf("CadDone ");
00110     if (Radio::lora.RegIrqFlags.bits.TxDone)
00111         pc.printf("TxDone ");
00112     if (Radio::lora.RegIrqFlags.bits.ValidHeader)
00113         pc.printf("ValidHeader ");
00114     if (Radio::lora.RegIrqFlags.bits.PayloadCrcError)
00115         pc.printf("PayloadCrcError ");
00116     if (Radio::lora.RegIrqFlags.bits.RxDone)
00117         pc.printf("RxDone ");  
00118     if (Radio::lora.RegIrqFlags.bits.RxTimeout)
00119         pc.printf("RxTimeout ");
00120  
00121     pc.printf("\r\n");
00122  
00123     if (clear)
00124         Radio::radio.write_reg(REG_LR_IRQFLAGS, Radio::lora.RegIrqFlags.octet);
00125  
00126 }
00127 
00128 void lora_printHeaderMode()
00129 {
00130     if (Radio::lora.getHeaderMode())
00131         pc.printf("implicit ");
00132     else
00133         pc.printf("explicit ");
00134 }
00135 
00136 void lora_printRxPayloadCrcOn()
00137 {
00138     bool on = Radio::lora.getRxPayloadCrcOn();
00139     pc.printf("RxPayloadCrcOn:%d = ", on);
00140     if (Radio::lora.getHeaderMode())
00141         pc.printf("Rx/");  // implicit mode
00142         
00143     if (on)
00144         pc.printf("Tx CRC Enabled\r\n");
00145     else
00146         pc.printf("Tx CRC disabled\r\n");
00147 }
00148 
00149 void lora_printCodingRate(bool from_rx)
00150 {
00151     uint8_t d = Radio::lora.getCodingRate(from_rx);
00152     pc.printf("CodingRate:");
00153     switch (d) {
00154         case 1: pc.printf("4/5 "); break;
00155         case 2: pc.printf("4/6 "); break;
00156         case 3: pc.printf("4/7 "); break;
00157         case 4: pc.printf("4/8 "); break;
00158         default:
00159             pc.printf("%d ", d);
00160             break;
00161     }
00162 }
00163  
00164 void lora_print_status()
00165 {    
00166     Radio::radio.RegOpMode.octet = Radio::radio.read_reg(REG_OPMODE);
00167     if (!Radio::radio.RegOpMode.bits.LongRangeMode) {
00168         pc.printf("FSK\r\n");
00169         return;
00170     }
00171     
00172     //lora_print_dio();
00173     pc.printf("LoRa ");
00174     
00175     // printing LoRa registers at 0x0d -> 0x3f
00176  
00177     Radio::lora.RegModemConfig.octet = Radio::radio.read_reg(REG_LR_MODEMCONFIG);
00178     Radio::lora.RegModemConfig2.octet = Radio::radio.read_reg(REG_LR_MODEMCONFIG2);
00179  
00180     lora_printCodingRate(false); // false: transmitted coding rate
00181     lora_printHeaderMode();
00182     lora_printBw();
00183     lora_printSf();
00184     lora_printRxPayloadCrcOn();
00185     // RegModemStat
00186     //pc.printf("ModemStat:0x%02x\r\n", Radio::radio.read_reg(REG_LR_MODEMSTAT));
00187  
00188     // fifo ptrs:
00189     Radio::lora.RegPayloadLength = Radio::radio.read_reg(REG_LR_PAYLOADLENGTH);
00190     Radio::lora.RegRxMaxPayloadLength = Radio::radio.read_reg(REG_LR_RX_MAX_PAYLOADLENGTH);
00191 /*    pc.printf("fifoptr=0x%02x txbase=0x%02x rxbase=0x%02x payloadLength=0x%02x maxlen=0x%02x",
00192         Radio::radio.read_reg(REG_LR_FIFOADDRPTR),
00193         Radio::radio.read_reg(REG_LR_FIFOTXBASEADDR),
00194         Radio::radio.read_reg(REG_LR_FIFORXBASEADDR),
00195         Radio::lora.RegPayloadLength,
00196         Radio::lora.RegRxMaxPayloadLength
00197     );*/
00198  
00199     pc.printf("dio0pin:%u ", Radio::radio.dio0.read());
00200     Radio::lora.RegIrqFlags.octet = Radio::radio.read_reg(REG_LR_IRQFLAGS);
00201     radio_printLoraIrqs(false);
00202  
00203 /*    Radio::lora.RegHopPeriod = Radio::radio.read_reg(REG_LR_HOPPERIOD);
00204     if (Radio::lora.RegHopPeriod != 0) {
00205         pc.printf("\r\nHopPeriod:0x%02x\r\n", Radio::lora.RegHopPeriod);
00206     }*/
00207  
00208     pc.printf("SymbTimeout:%d ", Radio::radio.read_u16(REG_LR_MODEMCONFIG2) & 0x3ff);
00209  
00210     Radio::lora.RegPreamble = Radio::radio.read_u16(REG_LR_PREAMBLEMSB);
00211     pc.printf("PreambleLength:%d ", Radio::lora.RegPreamble);
00212  
00213     if (Radio::radio.RegOpMode.bits.Mode == RF_OPMODE_RECEIVER || Radio::radio.RegOpMode.bits.Mode == RF_OPMODE_RECEIVER_SINGLE) {
00214         pc.printf("rssi:%ddBm ", Radio::lora.get_current_rssi());
00215     }
00216  
00217     //lora_printTxContinuousMode();
00218  
00219     pc.printf("\r\n");
00220     //lora_printAgcAutoOn();
00221     if (Radio::radio.type == SX1272) {
00222         pc.printf(" LowDataRateOptimize:%d\r\n", Radio::lora.RegModemConfig.sx1272bits.LowDataRateOptimize);
00223     }
00224  
00225     /*pc.printf("\r\nHeaderCount:%d PacketCount:%d, ",
00226         Radio::radio.read_u16(REG_LR_RXHEADERCNTVALUE_MSB), Radio::radio.read_u16(REG_LR_RXPACKETCNTVALUE_MSB));
00227         */
00228  
00229     /*pc.printf("Lora detection threshold:%02x\r\n", Radio::radio.read_reg(REG_LR_DETECTION_THRESHOLD));
00230     Radio::lora.RegTest31.octet = Radio::radio.read_reg(REG_LR_TEST31);
00231     pc.printf("detect_trig_same_peaks_nb:%d\r\n", Radio::lora.RegTest31.bits.detect_trig_same_peaks_nb);*/
00232  
00233     if (Radio::radio.type == SX1272) {
00234         Radio::lora.RegModemConfig.octet = Radio::radio.read_reg(REG_LR_MODEMCONFIG);
00235         pc.printf("LowDataRateOptimize:%d ", Radio::lora.RegModemConfig.sx1272bits.LowDataRateOptimize);
00236     } else if (Radio::radio.type == SX1276) {
00237         Radio::lora.RegModemConfig3.octet = Radio::radio.read_reg(REG_LR_MODEMCONFIG3);
00238         pc.printf("LowDataRateOptimize:%d ", Radio::lora.RegModemConfig3.sx1276bits.LowDataRateOptimize);        
00239     }
00240     
00241     pc.printf(" invert: rx=%d tx=%d\r\n", Radio::lora.RegTest33.bits.invert_i_q, !Radio::lora.RegTest33.bits.chirp_invert_tx);
00242     
00243     pc.printf("\r\n");
00244 }
00245 
00246 void
00247 printPa()
00248 {
00249     Radio::radio.RegPaConfig.octet = Radio::radio.read_reg(REG_PACONFIG);
00250     if (Radio::radio.RegPaConfig.bits.PaSelect) {
00251         float output_dBm = 17 - (15-Radio::radio.RegPaConfig.bits.OutputPower);
00252         pc.printf(" PABOOST OutputPower=%.1fdBm", output_dBm);
00253     } else {
00254         float pmax = (0.6*Radio::radio.RegPaConfig.bits.MaxPower) + 10.8;
00255         float output_dBm = pmax - (15-Radio::radio.RegPaConfig.bits.OutputPower);
00256 #ifdef TARGET_MTS_MDOT_F411RE
00257         pc.printf(" \x1b[31mRFO pmax=%.1fdBm OutputPower=%.1fdBm\x1b[0m", pmax, output_dBm);  // not connected
00258 #else
00259         pc.printf(" RFO pmax=%.1fdBm OutputPower=%.1fdBm", pmax, output_dBm);
00260 #endif
00261     }
00262 }
00263 
00264 bool isRadioRxing()
00265 {
00266     Radio::radio.RegOpMode.octet = Radio::radio.read_reg(REG_OPMODE);
00267     return Radio::radio.RegOpMode.bits.Mode == RF_OPMODE_RECEIVER || Radio::radio.RegOpMode.bits.Mode == RF_OPMODE_RECEIVER_SINGLE;
00268 }
00269 
00270 void radio_printOpMode()
00271 {
00272     Radio::radio.RegOpMode.octet = Radio::radio.read_reg(REG_OPMODE);
00273     switch (Radio::radio.RegOpMode.bits.Mode) {
00274         case RF_OPMODE_SLEEP: pc.printf("sleep"); break;
00275         case RF_OPMODE_STANDBY: pc.printf("stby"); break;
00276         case RF_OPMODE_SYNTHESIZER_TX: pc.printf("fstx"); break;
00277         case RF_OPMODE_TRANSMITTER: pc.printf("tx"); break;
00278         case RF_OPMODE_SYNTHESIZER_RX: pc.printf("fsrx"); break;
00279         case RF_OPMODE_RECEIVER: pc.printf("rx"); break;
00280         case 6:
00281             if (Radio::radio.RegOpMode.bits.LongRangeMode)
00282                 pc.printf("rxs");
00283             else
00284                 pc.printf("-6-");
00285             break;  // todo: different lora/fsk
00286         case 7:
00287             if (Radio::radio.RegOpMode.bits.LongRangeMode)
00288                 pc.printf("cad");
00289             else
00290                 pc.printf("-7-");
00291             break;  // todo: different lora/fsk
00292     }
00293 }
00294 
00295 void /* things always present, whether lora or fsk */
00296 common_print_status()
00297 {
00298     pc.printf("version:0x%02x %.3fMHz ", Radio::radio.read_reg(REG_VERSION), Radio::radio.get_frf_MHz());
00299     radio_printOpMode();
00300  
00301     printPa();
00302  
00303     Radio::radio.RegOcp.octet = Radio::radio.read_reg(REG_OCP);
00304     if (Radio::radio.RegOcp.bits.OcpOn) {
00305         int imax = 0;
00306         if (Radio::radio.RegOcp.bits.OcpTrim < 16)
00307             imax = 45 + (5 * Radio::radio.RegOcp.bits.OcpTrim);
00308         else if (Radio::radio.RegOcp.bits.OcpTrim < 28)
00309             imax = -30 + (10 * Radio::radio.RegOcp.bits.OcpTrim);
00310         else
00311             imax = 240;
00312         pc.printf(" OcpOn %dmA ", imax);
00313     } else
00314         pc.printf(" OcpOFF ");
00315  
00316     pc.printf("\r\n");
00317     
00318 #if 0
00319     if (per_en) {
00320         if (cadper_enable) {
00321             pc.printf("cadper %" PRIu32 ", ", num_cads);
00322         }
00323         pc.printf("per_tx_delay:%f\r\n", per_tx_delay);
00324         pc.printf("PER device ID:%d\r\n", per_id);
00325     }    
00326     
00327     if (poll_irq_en) {
00328         pc.printf("poll_irq_en\r\n");
00329         if (!Radio::radio.RegOpMode.bits.LongRangeMode) {
00330             pc.printf("saved irqs: %02x %02x\r\n", fsk_RegIrqFlags1_prev.octet, fsk_RegIrqFlags2_prev.octet);
00331         }
00332     }
00333 #endif /* if 0 */
00334  
00335 }
00336 
00337 void radio_print_status()
00338 {
00339     if (Radio::radio.type == SX1276) {
00340 #if defined(TARGET_MTS_MDOT_F411RE)
00341         pc.printf("\r\nSX1276 ");
00342 #else
00343         /*if (shield_type == SHIELD_TYPE_LAS)
00344             pc.printf("\r\nSX1276LAS ");
00345         if (shield_type == SHIELD_TYPE_MAS)
00346             pc.printf("\r\nSX1276MAS ");*/
00347         pc.printf("\r\n");
00348 #endif /* !TARGET_MTS_MDOT_F411RE */                       
00349     } else if (Radio::radio.type == SX1272)
00350         pc.printf("\r\nSX1272 ");
00351         
00352     Radio::radio.RegOpMode.octet = Radio::radio.read_reg(REG_OPMODE);
00353     if (Radio::radio.RegOpMode.bits.LongRangeMode)
00354         lora_print_status();
00355     /*else
00356         fsk_print_status();*/
00357     common_print_status();
00358 }
00359 
00360 void tx_dbm_print()
00361 {
00362     int dbm;
00363     RegPdsTrim1_t pds_trim;
00364     uint8_t adr, pa_test_adr;
00365 
00366     if (Radio::radio.type == SX1276) {
00367         adr = REG_PDSTRIM1_SX1276;
00368         pa_test_adr = REG_PATEST_SX1276;
00369     } else {
00370         adr = REG_PDSTRIM1_SX1272;
00371         pa_test_adr = REG_PATEST_SX1272;
00372     }
00373 
00374     if (Radio::radio.read_reg(pa_test_adr) & 0x20) {
00375         pds_trim.octet = Radio::radio.read_reg(adr);
00376 
00377         Radio::radio.RegPaConfig.octet = Radio::radio.read_reg(REG_PACONFIG);
00378         if (Radio::radio.RegPaConfig.bits.PaSelect) {
00379             dbm = Radio::radio.RegPaConfig.bits.OutputPower + pds_trim.bits.prog_txdac - 2;
00380         } else {
00381             dbm = Radio::radio.RegPaConfig.bits.OutputPower - 1;
00382         }
00383     } else {
00384         dbm = PA_OFF_DBM;
00385     }
00386     pc.printf("%d", dbm);
00387 }
00388 
00389 bool tx_dbm_write(int i)
00390 {
00391     uint8_t v, adr, pa_test_adr;
00392     RegPdsTrim1_t pds_trim;
00393 
00394     if (Radio::radio.type == SX1276) {
00395         adr = REG_PDSTRIM1_SX1276;
00396         pa_test_adr = REG_PATEST_SX1276;
00397     } else {
00398         adr = REG_PDSTRIM1_SX1272;
00399         pa_test_adr = REG_PATEST_SX1272;
00400     }
00401 
00402     v = Radio::radio.read_reg(pa_test_adr);
00403 
00404     if (i == PA_OFF_DBM) {
00405         /* for bench testing: prevent overloading receiving station (very low TX power) */
00406         v &= ~0x20; // turn off pu_regpa_n: disable PA
00407         Radio::radio.write_reg(pa_test_adr, v);
00408         return false;
00409     } else if ((v & 0x20) == 0) {
00410         v |= 0x20; // turn on pu_regpa_n: enable PA
00411         Radio::radio.write_reg(pa_test_adr, v);
00412     }
00413 
00414     pds_trim.octet = Radio::radio.read_reg(adr);
00415 
00416     if (Radio::radio.RegPaConfig.bits.PaSelect) {
00417         /* PABOOST used: +2dbm to +17, or +20 */
00418         if (i == 20) {
00419             pc.printf("+20dBm PADAC bias\r\n");
00420             i -= 3;
00421             pds_trim.bits.prog_txdac = 7;
00422             Radio::radio.write_reg(adr, pds_trim.octet);
00423         }
00424         if (i > 1)
00425                 Radio::radio.RegPaConfig.bits.OutputPower = i - 2;
00426     } else {
00427         /* RFO used: -1 to +14dbm */
00428         if (i < 15)
00429             Radio::radio.RegPaConfig.bits.OutputPower = i + 1;
00430     }
00431     Radio::radio.write_reg(REG_PACONFIG, Radio::radio.RegPaConfig.octet);
00432 
00433     return false;
00434 }
00435 
00436 void cmd_op(uint8_t argsAt)
00437 {
00438     int dbm;
00439     if (sscanf(pcbuf+argsAt, "%d", &dbm) == 1) {
00440         tx_dbm_write(dbm);
00441     }
00442 
00443     tx_dbm_print();
00444 }
00445 #endif /* ..SX127x_H */