UART console application for testing SX1272/SX1276

Dependencies:   SX127x

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "sx127x_lora.h"
00002 #include "sx127x_fsk.h"
00003 #define __STDC_FORMAT_MACROS
00004 #include <inttypes.h>
00005 
00006 //#include "kermit.h"
00007 
00008 //#define FSK_PER
00009 //#define START_EIGER_RX
00010 //#define START_EIGER_TX
00011 //#define START_OOK_TX_TEST
00012 
00013 DigitalOut led1(LED1);
00014 Serial pc(USBTX, USBRX);
00015 
00016 uint8_t tx_cnt;
00017 char pcbuf[64];
00018 int pcbuf_len;
00019 
00020 typedef enum {
00021     APP_NONE = 0,
00022     APP_CHAT
00023 } app_e;
00024 
00025 app_e app = APP_NONE;
00026 
00027 #define FSK_LARGE_PKT_THRESHOLD  0x3f
00028 
00029 bool crc32_en;  // ethcrc
00030 
00031 /*********** cmd_ulrx()... ************/
00032 typedef enum {
00033     ULRX_STATE_OFF = 0,
00034     ULRX_STATE_NEED_LENGTH,
00035     ULRX_STATE_PAYLOAD,
00036     ULRX_STATE_SYNC1
00037 } ulrx_state_e;
00038 ulrx_state_e ulrx_state = ULRX_STATE_OFF;
00039 bool ulrx_enable;
00040 /*********** ...cmd_ulrx() ************/
00041 
00042 uint8_t rx_payload_idx;
00043 
00044 /************** fsk modeReady isr... **********/
00045 bool rx_payloadReady_int_en;  // cmd_prrx()
00046 #define N_RX_PKTS         32
00047 #define RX_PKT_SIZE_LIMIT      32
00048 uint8_t rx_pkts[N_RX_PKTS][RX_PKT_SIZE_LIMIT];
00049 uint8_t n_rx_pkts;
00050 /************** ...fsk modeReady isr **********/
00051 
00052 #ifdef TARGET_STM
00053 CRC_HandleTypeDef   CrcHandle;
00054 #endif /* TARGET_STM */
00055 
00056 int rssi_polling_thresh; // 0 = polling off
00057 bool ook_test_en;
00058 bool poll_irq_en;
00059 volatile RegIrqFlags2_t fsk_RegIrqFlags2_prev;
00060 volatile RegIrqFlags1_t fsk_RegIrqFlags1_prev;
00061 Timer rx_start_timer;
00062 uint32_t secs_rx_start;
00063 
00064 /***************************** eiger per: *************************************************/
00065 
00066 uint32_t num_cads;
00067 bool cadper_enable;
00068 bool per_en;
00069 float per_tx_delay = 0.1;
00070 int per_id;
00071 uint32_t PacketTxCnt, PacketTxCntEnd;
00072 uint32_t PacketPerOkCnt;
00073 int PacketRxSequencePrev;
00074 uint32_t PacketPerKoCnt;
00075 uint32_t PacketNormalCnt;
00076 Timeout per_timeout;
00077 
00078 
00079 
00080 /******************************************************************************/
00081 #ifdef TARGET_MTS_MDOT_F411RE
00082 //                mosi,      miso,     sclk,       cs,        rst,      dio0,      dio1
00083 //SX127x radio(LORA_MOSI, LORA_MISO, LORA_SCK, LORA_NSS, LORA_RESET, LORA_DIO0, LORA_DIO1);
00084 SPI spi(LORA_MOSI, LORA_MISO, LORA_SCK); // mosi, miso, sclk
00085 //           dio0, dio1, nss, spi, rst
00086 SX127x radio(LORA_DIO0, LORA_DIO1, LORA_NSS, spi, LORA_RESET); // multitech mdot
00087 
00088 DigitalIn dio3(LORA_DIO3);
00089 DigitalOut txctl(LORA_TXCTL);
00090 DigitalOut rxctl(LORA_RXCTL);
00091 
00092 void rfsw_callback()
00093 {
00094     /* SKY13350 */
00095     if (radio.RegOpMode.bits.Mode == RF_OPMODE_TRANSMITTER) {  // start of transmission
00096         txctl = 1;
00097         rxctl = 0;
00098     } else { // reception:
00099         txctl = 0;
00100         rxctl = 1;
00101     }
00102 }
00103 
00104 #define FSK_RSSI_OFFSET         0
00105 #define FSK_RSSI_SMOOTHING      2
00106 DigitalIn dio2(LORA_DIO2);
00107 DigitalIn dio4(LORA_DIO4);
00108 
00109 #elif defined(TARGET_DISCO_L072CZ_LRWAN1)    /********************* ...mDot **********************/ 
00110     /* Murata TypeABZ discovery board B-L072Z-LRWAN1 */
00111     //           mosi, miso, sclk,   cs,  rst,  dio0, dio1
00112     //SX127x radio(PA_7, PA_6, PB_3, PA_15, PC_0, PB_4, PB_1);
00113 
00114     SPI spi(PA_7, PA_6, PB_3); // mosi, miso, sclk
00115     //           dio0, dio1,  nss,  spi,  rst
00116     SX127x radio(PB_4, PB_1, PA_15, spi, PC_0); // sx1276 arduino shield
00117 
00118     DigitalIn dio2(PB_0);
00119     DigitalIn dio3(PC_13);
00120     #define FSK_RSSI_OFFSET         0
00121     #define FSK_RSSI_SMOOTHING      2
00122     #define CRF1    PA_1
00123     #define CRF2    PC_2
00124     #define CRF3    PC_1
00125     DigitalOut Vctl1(CRF1);
00126     DigitalOut Vctl2(CRF2);
00127     DigitalOut Vctl3(CRF3);
00128     
00129     void rfsw_callback()
00130     {
00131         if (radio.RegOpMode.bits.Mode == RF_OPMODE_TRANSMITTER) {
00132             Vctl1 = 0;        
00133             if (radio.RegPaConfig.bits.PaSelect) {
00134                 Vctl2 = 0;
00135                 Vctl3 = 1;                        
00136             } else {
00137                 Vctl2 = 1;
00138                 Vctl3 = 0;            
00139             }
00140         } else {
00141             if (radio.RegOpMode.bits.Mode == RF_OPMODE_RECEIVER || radio.RegOpMode.bits.Mode == RF_OPMODE_RECEIVER_SINGLE)
00142                 Vctl1 = 1;
00143             else
00144                 Vctl1 = 0;
00145             
00146             Vctl2 = 0;
00147             Vctl3 = 0;        
00148         }
00149     }    
00150 #else /***************** ..Type-ABZ and L073RZ *************/
00151 SPI spi(D11, D12, D13); // mosi, miso, sclk
00152 //           dio0, dio1, nss, spi, rst
00153 SX127x radio(  D2,   D3, D10, spi, A0); // sx1276 arduino shield
00154 
00155 // for SX1276 arduino shield:
00156 #ifdef TARGET_LPC11U6X
00157 DigitalInOut rfsw(P0_23);
00158 #else
00159 DigitalInOut rfsw(A4);
00160 #endif
00161 
00162 InterruptIn dio0int(D2);
00163 InterruptIn dio1int(D3);
00164 InterruptIn dio2int(D4);
00165 InterruptIn dio4int(D8);
00166 DigitalIn dio2(D4);
00167 DigitalIn dio3(D5);
00168 DigitalIn dio4(D8);
00169 DigitalIn dio5(D9);
00170 
00171 #if defined(TARGET_STM)
00172 DigitalOut pc3(PC_3);   // nucleo corner pin for misc indication
00173 #endif
00174 
00175 void rfsw_callback()
00176 {
00177     if (radio.RegOpMode.bits.Mode == RF_OPMODE_TRANSMITTER)
00178         rfsw = 1;
00179     else
00180         rfsw = 0;
00181 }
00182 
00183 #define FSK_RSSI_OFFSET         5
00184 #define FSK_RSSI_SMOOTHING      2
00185 
00186 typedef enum {
00187     SHIELD_TYPE_NONE = 0,
00188     SHIELD_TYPE_LAS,
00189     SHIELD_TYPE_MAS,
00190 } shield_type_e;
00191 shield_type_e shield_type;
00192 
00193 #endif /* !TARGET_MTS_MDOT_F411RE */
00194 
00195 SX127x_fsk fsk(radio);
00196 SX127x_lora lora(radio);
00197 //Kermit kermit(lora);
00198 
00199 #ifndef TARGET_DISCO_L072CZ_LRWAN1
00200 volatile bool saved_dio4;
00201 #endif
00202 
00203 uint32_t crcTable[256];
00204 void make_crc_table()
00205 {
00206     const uint32_t POLYNOMIAL = 0xEDB88320;
00207     uint32_t remainder;
00208     uint8_t b = 0;
00209     do{
00210         // Start with the data byte
00211         remainder = b;
00212         for (unsigned long bit = 8; bit > 0; --bit)
00213         {
00214             if (remainder & 1)
00215                 remainder = (remainder >> 1) ^ POLYNOMIAL;
00216             else
00217                 remainder = (remainder >> 1);
00218         }
00219         crcTable[(size_t)b] = remainder;
00220     } while(0 != ++b);
00221 }
00222 
00223 uint32_t gen_crc(const uint8_t *p, size_t n)
00224 {
00225     uint32_t crc = 0xffffffff;
00226     size_t i;
00227     for(i = 0; i < n; i++) {
00228         crc = crcTable[*p++ ^ (crc&0xff)] ^ (crc>>8);
00229     }
00230         
00231     return(~crc);
00232 }
00233 
00234 
00235 void printLoraIrqs_(bool clear)
00236 {
00237     //in radio class -- RegIrqFlags_t RegIrqFlags;
00238 
00239     //already read RegIrqFlags.octet = radio.read_reg(REG_LR_IRQFLAGS);
00240     printf("\r\nIrqFlags:");
00241     if (lora.RegIrqFlags.bits.CadDetected)
00242         printf("CadDetected ");
00243     if (lora.RegIrqFlags.bits.FhssChangeChannel) {
00244         //radio.RegHopChannel.octet = radio.read_reg(REG_LR_HOPCHANNEL);
00245         printf("FhssChangeChannel:%d ", lora.RegHopChannel.bits.FhssPresentChannel);
00246     }
00247     if (lora.RegIrqFlags.bits.CadDone)
00248         printf("CadDone ");
00249     if (lora.RegIrqFlags.bits.TxDone)
00250         printf("TxDone ");
00251     if (lora.RegIrqFlags.bits.ValidHeader)
00252         printf("ValidHeader ");
00253     if (lora.RegIrqFlags.bits.PayloadCrcError)
00254         printf("PayloadCrcError ");
00255     if (lora.RegIrqFlags.bits.RxDone)
00256         printf("RxDone ");  
00257     if (lora.RegIrqFlags.bits.RxTimeout)
00258         printf("RxTimeout ");
00259 
00260     printf("\r\n");
00261 
00262     if (clear)
00263         radio.write_reg(REG_LR_IRQFLAGS, lora.RegIrqFlags.octet);
00264 
00265 }
00266 
00267 void lora_printCodingRate(bool from_rx)
00268 {
00269     uint8_t d = lora.getCodingRate(from_rx);
00270     printf("CodingRate:");
00271     switch (d) {
00272         case 1: printf("4/5 "); break;
00273         case 2: printf("4/6 "); break;
00274         case 3: printf("4/7 "); break;
00275         case 4: printf("4/8 "); break;
00276         default:
00277             printf("%d ", d);
00278             break;
00279     }
00280 }
00281 
00282 void lora_printHeaderMode()
00283 {
00284     if (lora.getHeaderMode())
00285         printf("implicit ");
00286     else
00287         printf("explicit ");
00288 }
00289 
00290 void lora_printBw()
00291 {
00292     (void)lora.getBw();
00293     
00294     printf("Bw:");
00295     if (radio.type == SX1276) {
00296         switch (lora.RegModemConfig.sx1276bits.Bw) {
00297             case 0: printf("7.8KHz "); break;
00298             case 1: printf("10.4KHz "); break;
00299             case 2: printf("15.6KHz "); break;
00300             case 3: printf("20.8KHz "); break;
00301             case 4: printf("31.25KHz "); break;
00302             case 5: printf("41.7KHz "); break;
00303             case 6: printf("62.5KHz "); break;
00304             case 7: printf("125KHz "); break;
00305             case 8: printf("250KHz "); break;
00306             case 9: printf("500KHz "); break;
00307             default: printf("%x ", lora.RegModemConfig.sx1276bits.Bw); break;
00308         }
00309     } else if (radio.type == SX1272) {
00310         switch (lora.RegModemConfig.sx1272bits.Bw) {
00311             case 0: printf("125KHz "); break;
00312             case 1: printf("250KHz "); break;
00313             case 2: printf("500KHz "); break;
00314             case 3: printf("11b "); break;
00315         }
00316     }
00317 }
00318 
00319 void lora_printAllBw()
00320 {
00321     int i, s;
00322     
00323     if (radio.type == SX1276) {
00324         s = lora.RegModemConfig.sx1276bits.Bw;    
00325         for (i = 0; i < 10; i++ ) {
00326             lora.RegModemConfig.sx1276bits.Bw = i;
00327             printf("%d ", i);
00328             lora_printBw();
00329             printf("\r\n");
00330         }
00331         lora.RegModemConfig.sx1276bits.Bw = s;
00332     } else if (radio.type == SX1272) {
00333         s = lora.RegModemConfig.sx1272bits.Bw;    
00334         for (i = 0; i < 3; i++ ) {
00335             lora.RegModemConfig.sx1272bits.Bw = i;
00336             printf("%d ", i);
00337             lora_printBw();
00338             printf("\r\n");
00339         }
00340         lora.RegModemConfig.sx1272bits.Bw = s;    
00341     }
00342 }
00343 
00344 void lora_printSf()
00345 {
00346     // spreading factor same between sx127[26]
00347     printf("sf:%d ", lora.getSf());
00348 }
00349 
00350 void lora_printRxPayloadCrcOn()
00351 {
00352     bool on = lora.getRxPayloadCrcOn();
00353     printf("RxPayloadCrcOn:%d = ", on);
00354     if (lora.getHeaderMode())
00355         printf("Rx/");  // implicit mode
00356         
00357     if (on)
00358         printf("Tx CRC Enabled\r\n");
00359     else
00360         printf("Tx CRC disabled\r\n");
00361 }
00362 
00363 void lora_printTxContinuousMode()
00364 {
00365     printf("TxContinuousMode:%d ", lora.RegModemConfig2.sx1276bits.TxContinuousMode);    // same for sx1272 and sx1276
00366 }
00367 
00368 void lora_printAgcAutoOn()
00369 {
00370     printf("AgcAutoOn:%d", lora.getAgcAutoOn());
00371 }
00372 
00373 void lora_print_dio()
00374 {
00375     radio.RegDioMapping2.octet = radio.read_reg(REG_DIOMAPPING2);
00376     printf("DIO5:");
00377     switch (radio.RegDioMapping2.bits.Dio5Mapping) {
00378         case 0: printf("ModeReady"); break;
00379         case 1: printf("ClkOut"); break;
00380         case 2: printf("ClkOut"); break;
00381     }
00382     printf(" DIO4:");
00383     switch (radio.RegDioMapping2.bits.Dio4Mapping) {
00384         case 0: printf("CadDetected"); break;
00385         case 1: printf("PllLock"); break;
00386         case 2: printf("PllLock"); break;
00387     }    
00388     radio.RegDioMapping1.octet = radio.read_reg(REG_DIOMAPPING1);
00389     printf(" DIO3:");
00390     switch (radio.RegDioMapping1.bits.Dio3Mapping) {
00391         case 0: printf("CadDone"); break;
00392         case 1: printf("ValidHeader"); break;
00393         case 2: printf("PayloadCrcError"); break;
00394     }    
00395     printf(" DIO2:");
00396     switch (radio.RegDioMapping1.bits.Dio2Mapping) {
00397         case 0:
00398         case 1:
00399         case 2:
00400             printf("FhssChangeChannel");
00401             break;
00402     }    
00403     printf(" DIO1:");
00404     switch (radio.RegDioMapping1.bits.Dio1Mapping) {
00405         case 0: printf("RxTimeout"); break;
00406         case 1: printf("FhssChangeChannel"); break;
00407         case 2: printf("CadDetected"); break;
00408     }    
00409     printf(" DIO0:");
00410     switch (radio.RegDioMapping1.bits.Dio0Mapping) {
00411         case 0: printf("RxDone"); break;
00412         case 1: printf("TxDone"); break;
00413         case 2: printf("CadDone"); break;
00414     }    
00415     
00416     printf("\r\n"); 
00417 }
00418 
00419 void fsk_print_dio()
00420 {
00421     radio.RegDioMapping2.octet = radio.read_reg(REG_DIOMAPPING2);
00422     
00423     printf("DIO5:");
00424     switch (radio.RegDioMapping2.bits.Dio5Mapping) {
00425         case 0: printf("ClkOut"); break;
00426         case 1: printf("PllLock"); break;
00427         case 2:
00428             if (fsk.RegPktConfig2.bits.DataModePacket)
00429                 printf("data");
00430             else {
00431                 if (radio.RegDioMapping2.bits.MapPreambleDetect)
00432                     printf("preamble");
00433                 else
00434                     printf("rssi");
00435             }
00436             break;
00437         case 3: printf("ModeReady"); break;
00438     }
00439     
00440     printf(" DIO4:");
00441     switch (radio.RegDioMapping2.bits.Dio4Mapping) {
00442         case 0: printf("temp/eol"); break;
00443         case 1: printf("PllLock"); break;
00444         case 2: printf("TimeOut"); break;
00445         case 3:
00446             if (fsk.RegPktConfig2.bits.DataModePacket) {
00447                 if (radio.RegDioMapping2.bits.MapPreambleDetect)
00448                     printf("preamble");
00449                 else
00450                     printf("rssi");
00451             } else
00452                 printf("ModeReady");
00453             break;
00454     }
00455     
00456     radio.RegDioMapping1.octet = radio.read_reg(REG_DIOMAPPING1);
00457     
00458     printf(" DIO3:");
00459     if (fsk.RegPktConfig2.bits.DataModePacket) {
00460         if (radio.RegDioMapping1.bits.Dio3Mapping == 1)
00461             printf("TxReady");
00462         else
00463             printf("FifoEmpty");
00464     } else {
00465         switch (radio.RegDioMapping1.bits.Dio3Mapping) {
00466             case 0: printf("Timeout"); break;
00467             case 1:
00468                 if (radio.RegDioMapping2.bits.MapPreambleDetect)
00469                     printf("preamble");
00470                 else
00471                     printf("rssi");
00472                 break;
00473             case 2: printf("?automode_status?"); break;
00474             case 3: printf("TempChange/LowBat"); break;
00475         }
00476     }
00477     
00478     printf(" DIO2:");
00479     if (fsk.RegPktConfig2.bits.DataModePacket) {
00480         switch (radio.RegDioMapping1.bits.Dio2Mapping) {
00481             case 0: printf("FifoFull"); break;
00482             case 1: printf("RxReady"); break;
00483             case 2: printf("FifoFull/rx-timeout"); break;
00484             case 3: printf("FifoFull/rx-syncadrs"); break;
00485         }
00486     } else {
00487         printf("Data");
00488     }
00489     
00490     printf(" DIO1:");
00491     if (fsk.RegPktConfig2.bits.DataModePacket) {
00492         switch (radio.RegDioMapping1.bits.Dio1Mapping) {
00493             case 0: printf("FifoThresh"); break;
00494             case 1: printf("FifoEmpty"); break;
00495             case 2: printf("FifoFull"); break;
00496             case 3: printf("-3-"); break;
00497         }
00498     } else {
00499         switch (radio.RegDioMapping1.bits.Dio1Mapping) {
00500             case 0: printf("Dclk"); break;
00501             case 1:
00502                 if (radio.RegDioMapping2.bits.MapPreambleDetect)
00503                     printf("preamble");
00504                 else
00505                     printf("rssi");
00506                 break;
00507             case 2: printf("-2-"); break;
00508             case 3: printf("-3-"); break;
00509         }
00510     }
00511     
00512     printf(" DIO0:");
00513     if (fsk.RegPktConfig2.bits.DataModePacket) {
00514         switch (radio.RegDioMapping1.bits.Dio0Mapping) {
00515             case 0: printf("PayloadReady/PacketSent"); break;
00516             case 1: printf("CrcOk"); break;
00517             case 2: printf("-2-"); break;
00518             case 3: printf("TempChange/LowBat"); break;
00519         }
00520     } else {
00521         switch (radio.RegDioMapping1.bits.Dio0Mapping) {
00522             case 0: printf("SyncAdrs/TxReady"); break;
00523             case 1:
00524                 if (radio.RegDioMapping2.bits.MapPreambleDetect)
00525                     printf("preamble");
00526                 else
00527                     printf("rssi");
00528                 break;
00529             case 2: printf("RxReady"); break;
00530             case 3: printf("-3-"); break;
00531         }
00532     }
00533     printf("\r\n"); 
00534 }
00535 
00536 void lora_print_status()
00537 {    
00538     radio.RegOpMode.octet = radio.read_reg(REG_OPMODE);
00539     if (!radio.RegOpMode.bits.LongRangeMode) {
00540         printf("FSK\r\n");
00541         return;
00542     }
00543     
00544     lora_print_dio();
00545     printf("LoRa ");
00546     
00547     // printing LoRa registers at 0x0d -> 0x3f
00548 
00549     lora.RegModemConfig.octet = radio.read_reg(REG_LR_MODEMCONFIG);
00550     lora.RegModemConfig2.octet = radio.read_reg(REG_LR_MODEMCONFIG2);
00551 
00552     lora_printCodingRate(false); // false: transmitted coding rate
00553     lora_printHeaderMode();
00554     lora_printBw();
00555     lora_printSf();
00556     lora_printRxPayloadCrcOn();
00557     // RegModemStat
00558     printf("ModemStat:0x%02x\r\n", radio.read_reg(REG_LR_MODEMSTAT));
00559 
00560     // fifo ptrs:
00561     lora.RegPayloadLength = radio.read_reg(REG_LR_PAYLOADLENGTH);
00562     lora.RegRxMaxPayloadLength = radio.read_reg(REG_LR_RX_MAX_PAYLOADLENGTH);
00563     printf("fifoptr=0x%02x txbase=0x%02x rxbase=0x%02x payloadLength=0x%02x maxlen=0x%02x",
00564         radio.read_reg(REG_LR_FIFOADDRPTR),
00565         radio.read_reg(REG_LR_FIFOTXBASEADDR),
00566         radio.read_reg(REG_LR_FIFORXBASEADDR),
00567         lora.RegPayloadLength,
00568         lora.RegRxMaxPayloadLength
00569     );
00570 
00571     lora.RegIrqFlags.octet = radio.read_reg(REG_LR_IRQFLAGS);
00572     printLoraIrqs_(false);
00573 
00574     lora.RegHopPeriod = radio.read_reg(REG_LR_HOPPERIOD);
00575     if (lora.RegHopPeriod != 0) {
00576         printf("\r\nHopPeriod:0x%02x\r\n", lora.RegHopPeriod);
00577     }
00578 
00579     printf("SymbTimeout:%d ", radio.read_u16(REG_LR_MODEMCONFIG2) & 0x3ff);
00580 
00581     lora.RegPreamble = radio.read_u16(REG_LR_PREAMBLEMSB);
00582     printf("PreambleLength:%d ", lora.RegPreamble);
00583 
00584     if (radio.RegOpMode.bits.Mode == RF_OPMODE_RECEIVER || radio.RegOpMode.bits.Mode == RF_OPMODE_RECEIVER_SINGLE) {
00585         printf("rssi:%ddBm ", lora.get_current_rssi());
00586     }
00587 
00588     lora_printTxContinuousMode();
00589 
00590     printf("\r\n");
00591     lora_printAgcAutoOn();
00592     if (radio.type == SX1272) {
00593         printf(" LowDataRateOptimize:%d\r\n", lora.RegModemConfig.sx1272bits.LowDataRateOptimize);
00594     }
00595 
00596     printf("\r\nHeaderCount:%d PacketCount:%d, ",
00597         radio.read_u16(REG_LR_RXHEADERCNTVALUE_MSB), radio.read_u16(REG_LR_RXPACKETCNTVALUE_MSB));
00598 
00599     printf("Lora detection threshold:%02x\r\n", radio.read_reg(REG_LR_DETECTION_THRESHOLD));
00600     lora.RegTest31.octet = radio.read_reg(REG_LR_TEST31);
00601     printf("detect_trig_same_peaks_nb:%d\r\n", lora.RegTest31.bits.detect_trig_same_peaks_nb);
00602 
00603     if (radio.type == SX1272) {
00604         lora.RegModemConfig.octet = radio.read_reg(REG_LR_MODEMCONFIG);
00605         printf("LowDataRateOptimize:%d ", lora.RegModemConfig.sx1272bits.LowDataRateOptimize);
00606     } else if (radio.type == SX1276) {
00607         lora.RegModemConfig3.octet = radio.read_reg(REG_LR_MODEMCONFIG3);
00608         printf("LowDataRateOptimize:%d ", lora.RegModemConfig3.sx1276bits.LowDataRateOptimize);        
00609     }
00610     
00611     printf(" invert: rx=%d tx=%d\r\n", lora.RegTest33.bits.invert_i_q, !lora.RegTest33.bits.chirp_invert_tx);
00612     
00613     printf("\r\n");
00614     //printf("A %02x\r\n", radio.RegModemConfig2.octet);
00615 }
00616 
00617 uint16_t
00618 fsk_get_PayloadLength(void)
00619 {
00620     fsk.RegPktConfig2.word = radio.read_u16(REG_FSK_PACKETCONFIG2);
00621 
00622     return fsk.RegPktConfig2.bits.PayloadLength;
00623 }
00624 
00625 void fsk_printAddressFiltering()
00626 {
00627     uint8_t FSKRegNodeAdrs, FSKRegBroadcastAdrs;
00628     
00629     printf(" AddressFiltering:");
00630     switch (fsk.RegPktConfig1.bits.AddressFiltering) {
00631         case 0: printf("off"); break;
00632         case 1: // NodeAddress
00633             FSKRegNodeAdrs = radio.read_reg(REG_FSK_NODEADRS);
00634             printf("NodeAdrs:%02x\r\n", FSKRegNodeAdrs);
00635             break;
00636         case 2: // NodeAddress & BroadcastAddress
00637             FSKRegNodeAdrs = radio.read_reg(REG_FSK_NODEADRS);
00638             printf("NodeAdrs:%02x ", FSKRegNodeAdrs);
00639             FSKRegBroadcastAdrs = radio.read_reg(REG_FSK_BROADCASTADRS);
00640             printf("BroadcastAdrs:%02x\r\n", FSKRegBroadcastAdrs );
00641             break;
00642         default:
00643             printf("%d", fsk.RegPktConfig1.bits.AddressFiltering);
00644             break;
00645     }
00646 }
00647 
00648 void fsk_print_IrqFlags2()
00649 {
00650     RegIrqFlags2_t RegIrqFlags2;
00651     
00652     printf("IrqFlags2: ");
00653     RegIrqFlags2.octet = radio.read_reg(REG_FSK_IRQFLAGS2);
00654     if (RegIrqFlags2.bits.FifoFull)
00655         printf("FifoFull ");
00656     if (RegIrqFlags2.bits.FifoEmpty)
00657         printf("FifoEmpty ");
00658     if (RegIrqFlags2.bits.FifoLevel)
00659         printf("FifoLevel ");
00660     if (RegIrqFlags2.bits.FifoOverrun)
00661         printf("FifoOverrun ");
00662     if (RegIrqFlags2.bits.PacketSent)
00663         printf("PacketSent ");
00664     if (RegIrqFlags2.bits.PayloadReady)
00665         printf("PayloadReady ");
00666     if (RegIrqFlags2.bits.CrcOk)
00667         printf("CrcOk ");
00668     if (RegIrqFlags2.bits.LowBat)
00669         printf("LowBat ");
00670     printf("\r\n");
00671 }
00672 
00673 void
00674 fsk_print_status()
00675 {
00676     //uint16_t s;
00677     RegIrqFlags1_t RegIrqFlags1;
00678     
00679     if (radio.RegOpMode.bits.LongRangeMode) {
00680         printf("LoRa\r\n");
00681         return;
00682     }
00683     
00684     if (radio.RegOpMode.bits.ModulationType == 0) {
00685         printf("FSK ");
00686         switch (radio.RegOpMode.bits.ModulationShaping) {
00687             case 1: printf("BT1.0 "); break;
00688             case 2: printf("BT0.5 "); break;
00689             case 3: printf("BT0.3 "); break;
00690         }
00691     } else if (radio.RegOpMode.bits.ModulationType == 1) {
00692         printf("OOK ");
00693         switch (radio.RegOpMode.bits.ModulationShaping) {
00694             case 1: printf("Fcutoff=bitrate"); break;
00695             case 2: printf("Fcutoff=2*bitrate"); break;
00696             case 3: printf("?"); break;
00697         }        
00698     }
00699 
00700     printf("%" PRIu32 "bps fdev:%" PRIu32 "Hz\r\n", fsk.get_bitrate(), fsk.get_tx_fdev_hz());    
00701     
00702     fsk.RegPktConfig2.word = radio.read_u16(REG_FSK_PACKETCONFIG2);
00703     
00704     fsk_print_dio();
00705     
00706     printf("rxbw:%" PRIu32 "Hz ", fsk.get_rx_bw_hz(REG_FSK_RXBW));
00707     printf("afcbw:%" PRIu32 "Hz\r\n", fsk.get_rx_bw_hz(REG_FSK_AFCBW));
00708 
00709     fsk.RegRssiConfig.octet = radio.read_reg(REG_FSK_RSSICONFIG);
00710     printf("RssiOffset:%ddB smoothing:%dsamples\r\n", fsk.RegRssiConfig.bits.RssiOffset, 1 << (fsk.RegRssiConfig.bits.RssiSmoothing+1));
00711 
00712 
00713     fsk.RegSyncConfig.octet = radio.read_reg(REG_FSK_SYNCCONFIG);
00714 
00715     if (fsk.RegPktConfig2.bits.DataModePacket) {
00716         uint16_t len;
00717         /* packet mode */
00718         len = fsk_get_PayloadLength();
00719         printf("packet RegPayloadLength:0x%03x ", len);
00720 
00721         if (fsk.RegPktConfig2.bits.BeaconOn)
00722             printf("BeaconOn ");
00723 
00724         fsk.RegFifoThreshold.octet = radio.read_reg(REG_FSK_FIFOTHRESH);
00725         printf("FifoThreshold:%d TxStartCondition:", fsk.RegFifoThreshold.bits.FifoThreshold);
00726         if (fsk.RegFifoThreshold.bits.TxStartCondition)
00727             printf("!FifoEmpty");
00728         else
00729             printf("FifoLevel");
00730 
00731         printf("\r\nAutoRestartRxMode:");
00732         switch (fsk.RegSyncConfig.bits.AutoRestartRxMode) {
00733             case 0: printf("off "); break;
00734             case 1: printf("no-pll-wait "); break;
00735             case 2: printf("pll-wait "); break;
00736             case 3: printf("3 "); break;
00737         }
00738         //...todo
00739 
00740         printf("PreambleSize:%d ", radio.read_u16(REG_FSK_PREAMBLEMSB));
00741 
00742         fsk.RegOokPeak.octet = radio.read_reg(REG_FSK_OOKPEAK);
00743         if (fsk.RegOokPeak.bits.barker_en)
00744             printf("barker ");
00745         if (!fsk.RegOokPeak.bits.BitSyncOn)
00746             printf("BitSyncOff ");
00747         //...todo
00748 
00749         fsk.RegPktConfig1.octet = radio.read_reg(REG_FSK_PACKETCONFIG1);
00750         if (fsk.RegPktConfig1.bits.PacketFormatVariable)
00751             printf("variable");
00752         else
00753             printf("fixed");
00754         printf("-length\r\ncrc");
00755         if (fsk.RegPktConfig1.bits.CrcOn) {
00756             printf("On");
00757         } else
00758             printf("Off");
00759         printf(" crctype:");
00760         if (fsk.RegPktConfig1.bits.CrCWhiteningType)
00761             printf("IBM");
00762         else
00763             printf("CCITT");
00764         printf(" dcFree:");
00765         switch (fsk.RegPktConfig1.bits.DcFree) {
00766             case 0: printf("none "); break;
00767             case 1: printf("Manchester "); break;
00768             case 2: printf("Whitening "); break;
00769             case 3: printf("reserved "); break;
00770         }
00771         fsk_printAddressFiltering();
00772 
00773         printf("\r\n");
00774         fsk_print_IrqFlags2();
00775     } else {
00776         /* continuous mode */
00777         printf("continuous ");
00778     }
00779 
00780     fsk.RegPreambleDetect.octet = radio.read_reg(REG_FSK_PREAMBLEDETECT);
00781     printf("PreambleDetect:");
00782     if (fsk.RegPreambleDetect.bits.PreambleDetectorOn) {
00783         printf("size=%d,tol=%d ",
00784             fsk.RegPreambleDetect.bits.PreambleDetectorSize,
00785             fsk.RegPreambleDetect.bits.PreambleDetectorTol);
00786     } else
00787         printf("Off ");
00788 
00789     if (fsk.RegSyncConfig.bits.SyncOn) {
00790         printf(" syncsize:%d ", fsk.RegSyncConfig.bits.SyncSize);
00791         printf(" : %02x ", radio.read_reg(REG_FSK_SYNCVALUE1));
00792         printf("%02x ", radio.read_reg(REG_FSK_SYNCVALUE2));
00793         printf("%02x ", radio.read_reg(REG_FSK_SYNCVALUE3));
00794         printf("%02x ", radio.read_reg(REG_FSK_SYNCVALUE4));
00795     } else
00796         printf("Sync Off");
00797     printf("\r\n");   // end sync config
00798 
00799     fsk.RegAfcFei.octet = radio.read_reg(REG_FSK_AFCFEI);
00800     printf("afcAutoClear:");
00801     if (fsk.RegAfcFei.bits.AfcAutoClearOn)
00802         printf("On");
00803     else
00804         printf("OFF");
00805     printf(" afc:%dHz ", (int)(FREQ_STEP_HZ * radio.read_s16(REG_FSK_AFCMSB)));
00806 
00807     printf("fei:%dHz\r\n", (int)(FREQ_STEP_HZ * radio.read_s16(REG_FSK_FEIMSB)));
00808 
00809     fsk.RegRxConfig.octet = radio.read_reg(REG_FSK_RXCONFIG);
00810     printf("RxTrigger:");
00811     switch (fsk.RegRxConfig.bits.RxTrigger) {
00812         case 0: printf("none "); break;
00813         case 1: printf("rssi "); break;
00814         case 6: printf("preamble "); break;
00815         case 7: printf("both "); break;
00816         default: printf("-%d- ", fsk.RegRxConfig.bits.RxTrigger); break;
00817     }
00818     printf("AfcAuto:");
00819     if (fsk.RegRxConfig.bits.AfcAutoOn)
00820         printf("On ");
00821     else
00822         printf("OFF ");
00823         
00824     radio.RegLna.octet = radio.read_reg(REG_LNA);
00825     if (!fsk.RegRxConfig.bits.AgcAutoOn) {
00826         printf("AgcAutoOff:G%d ", radio.RegLna.bits.LnaGain);
00827     }
00828     printf("LnaBoostHF:%d ", radio.RegLna.bits.LnaBoostHF);
00829 
00830     fsk.RegTimerResol.octet = radio.read_reg(REG_FSK_TIMERRESOL);
00831     if (fsk.RegTimerResol.bits.hlm_started)
00832         printf("hlm_started ");
00833     else
00834         printf("hlm_stopped ");
00835 
00836     fsk.RegRssiThresh = radio.read_reg(REG_FSK_RSSITHRESH);
00837     printf("rssiThreshold:-%.1f@%02x ", fsk.RegRssiThresh / 2.0, REG_FSK_RSSITHRESH);
00838 
00839     radio.RegOpMode.octet = radio.read_reg(REG_OPMODE);
00840     if (radio.RegOpMode.bits.Mode == RF_OPMODE_RECEIVER ||
00841         radio.RegOpMode.bits.Mode == RF_OPMODE_SYNTHESIZER_RX)
00842     {
00843         printf("rssi:-%.1f ", radio.read_reg(REG_FSK_RSSIVALUE) / 2.0);
00844     }
00845 
00846     fsk.RegSeqConfig1.octet = radio.read_reg(REG_FSK_SEQCONFIG1);
00847     printf("\r\nsequencer: ");
00848     printf("FromStart:");
00849     switch (fsk.RegSeqConfig1.bits.FromStart) {
00850         case 0:
00851             printf("lowPowerSelection-");
00852             if (fsk.RegSeqConfig1.bits.LowPowerSelection)
00853                 printf("idle");
00854             else
00855                 printf("sequencerOff");
00856             break;
00857         case 1: printf("rx"); break;
00858         case 2: printf("tx"); break;
00859         case 3: printf("tx on fifolevel"); break;
00860     }
00861     printf(" lowPowerSelection:");
00862     if (fsk.RegSeqConfig1.bits.LowPowerSelection)
00863         printf("idle");
00864     else
00865         printf("SequencerOff");
00866     if (fsk.RegSeqConfig1.bits.FromStart != 0 && 
00867         fsk.RegSeqConfig1.bits.LowPowerSelection != 0)
00868     {   // if sequencer enabled:
00869         printf("\r\nsequencer: IdleMode:");
00870         if (fsk.RegSeqConfig1.bits.IdleMode)
00871             printf("Sleep");
00872         else
00873             printf("standby");
00874         printf("\r\nsequencer: FromIdle to:");
00875         if (fsk.RegSeqConfig1.bits.FromIdle)
00876             printf("rx");
00877         else
00878             printf("tx");
00879         printf("\r\nsequencer: FromTransmit to:");
00880         if (fsk.RegSeqConfig1.bits.FromTransmit)
00881             printf("rx-on-PacketSent");
00882         else {
00883             printf("lowPowerSelection-");
00884             if (fsk.RegSeqConfig1.bits.LowPowerSelection)
00885                 printf("idle");
00886             else
00887                 printf("SequencerOff");
00888             printf("-on-PacketSent");
00889         }
00890         fsk.RegSeqConfig2.octet = radio.read_reg(REG_FSK_SEQCONFIG2);
00891         printf("\r\nsequencer: FromReceive:");
00892         switch (fsk.RegSeqConfig2.bits.FromReceive) {
00893             case 1: printf("PacketRecevied on PayloadReady"); break;
00894             case 2: 
00895                 printf("lowPowerSelection-");
00896                 if (fsk.RegSeqConfig1.bits.LowPowerSelection)
00897                     printf("idle");
00898                 else
00899                     printf("SequencerOff");
00900                 printf("-on-payloadReady");
00901                 break;
00902             case 3: printf("PacketRecevied-on-CrcOk"); break;
00903             case 4: printf("SequencerOff-on-Rssi"); break;
00904             case 5: printf("SequencerOff-on-SyncAddress"); break;
00905             case 6: printf("SequencerOff-PreambleDetect"); break;
00906             default: printf("-%d-", fsk.RegSeqConfig2.bits.FromReceive); break;
00907         }
00908         printf("\r\nsequencer: FromRxTimeout:");
00909         switch (fsk.RegSeqConfig2.bits.FromRxTimeout) {
00910             case 0: printf("rx"); break;
00911             case 1: printf("tx"); break;
00912             case 2:
00913                 printf("lowPowerSelection-");
00914                 if (fsk.RegSeqConfig1.bits.LowPowerSelection)
00915                     printf("idle");
00916                 else
00917                     printf("SequencerOff");
00918                 break;
00919             case 3: printf("SequencerOff"); break;
00920         }
00921         printf("\r\nsequencer: FromPacketReceived to:");
00922         switch (fsk.RegSeqConfig2.bits.FromPacketReceived) {
00923             case 0: printf("SequencerOff"); break;
00924             case 1: printf("tx on FifoEmpty"); break;
00925             case 2:
00926                 printf("lowPowerSelection-");
00927                 if (fsk.RegSeqConfig1.bits.LowPowerSelection)
00928                 printf("idle");
00929                 else
00930                 printf("sequencerOff");
00931                 break;
00932             case 3: printf("rx via fs"); break;
00933             case 4: printf("rx"); break;
00934         }
00935 
00936         fsk.RegTimerResol.octet = radio.read_reg(REG_FSK_TIMERRESOL);
00937         printf("\r\nsequencer: timer1:");
00938         switch (fsk.RegTimerResol.bits.timer1_resol) {
00939             case 0: printf("off"); break;
00940             case 1: printf("%dus", radio.read_reg(REG_FSK_TIMER1COEF) * 64); break;
00941             case 2: printf("%.1fms", radio.read_reg(REG_FSK_TIMER1COEF) * 4.1); break;
00942             case 3: printf("%.1fs", radio.read_reg(REG_FSK_TIMER1COEF) * 0.262); break;
00943         }
00944 
00945         printf(" timer2:");
00946         switch (fsk.RegTimerResol.bits.timer2_resol) {
00947             case 0: printf("off"); break;
00948             case 1: printf("%dus", radio.read_reg(REG_FSK_TIMER2COEF) * 64); break;
00949             case 2: printf("%.1fms", radio.read_reg(REG_FSK_TIMER2COEF) * 4.1); break;
00950             case 3: printf("%.1fs", radio.read_reg(REG_FSK_TIMER2COEF) * 0.262); break;
00951         }
00952     } // ..if sequencer enabled
00953 
00954     printf("\r\nIrqFlags1:");
00955     RegIrqFlags1.octet = radio.read_reg(REG_FSK_IRQFLAGS1);
00956     if (RegIrqFlags1.bits.ModeReady)
00957         printf("ModeReady ");
00958     if (RegIrqFlags1.bits.RxReady)
00959         printf("RxReady ");
00960     if (RegIrqFlags1.bits.TxReady)
00961         printf("TxReady ");
00962     if (RegIrqFlags1.bits.PllLock)
00963         printf("PllLock ");
00964     if (RegIrqFlags1.bits.Rssi)
00965         printf("Rssi ");
00966     if (RegIrqFlags1.bits.Timeout)
00967         printf("Timeout ");
00968     if (RegIrqFlags1.bits.PreambleDetect)
00969         printf("PreambleDetect ");
00970     if (RegIrqFlags1.bits.SyncAddressMatch)
00971         printf("SyncAddressMatch ");
00972 
00973     printf("\r\n");
00974 
00975 /* TODO    if (!SX1272FSK->RegPktConfig1.bits.PacketFormatVariable) { // if fixed-length packet format:
00976         s = fsk_get_PayloadLength();
00977         if (s > FSK_LARGE_PKT_THRESHOLD)
00978             flags.fifo_flow_ctl = 1;
00979         else
00980             flags.fifo_flow_ctl = 0;
00981     }*/
00982 
00983     fsk.RegImageCal.octet = radio.read_reg(REG_FSK_IMAGECAL);
00984     if (fsk.RegImageCal.bits.TempMonitorOff) {
00985         printf("TempMonitorOff[\r0m\n");
00986     } else {
00987         printf("TempThreshold:");
00988         switch (fsk.RegImageCal.bits.TempThreshold) {
00989             case 0: printf("5C"); break;
00990             case 1: printf("10C"); break;
00991             case 2: printf("15C"); break;
00992             case 3: printf("20C"); break;
00993         }
00994         printf("\r\n");
00995     }
00996     if (fsk.RegImageCal.bits.ImageCalRunning)
00997         printf("ImageCalRunning[\r0m\n");
00998     
00999     if (rx_payloadReady_int_en) {
01000 #ifdef TARGET_DISCO_L072CZ_LRWAN1
01001         printf("n_rx_pkts:%u, dio:%u,%u,%u,%u\r\n", n_rx_pkts, dio3.read(), dio2.read(), radio.dio1.read(), radio.dio0.read());
01002 #else
01003         printf("n_rx_pkts:%u, dio:%u,%u,%u,%u,%u\r\n", n_rx_pkts, dio4.read(), dio3.read(), dio2.read(), radio.dio1.read(), radio.dio0.read());
01004 #endif
01005     }
01006 }
01007 
01008 void printOpMode()
01009 {
01010     radio.RegOpMode.octet = radio.read_reg(REG_OPMODE);
01011     switch (radio.RegOpMode.bits.Mode) {
01012         case RF_OPMODE_SLEEP: printf("sleep"); break;
01013         case RF_OPMODE_STANDBY: printf("stby"); break;
01014         case RF_OPMODE_SYNTHESIZER_TX: printf("fstx"); break;
01015         case RF_OPMODE_TRANSMITTER: printf("tx"); break;
01016         case RF_OPMODE_SYNTHESIZER_RX: printf("fsrx"); break;
01017         case RF_OPMODE_RECEIVER: printf("rx"); break;
01018         case 6:
01019             if (radio.RegOpMode.bits.LongRangeMode)
01020                 printf("rxs");
01021             else
01022                 printf("-6-");
01023             break;  // todo: different lora/fsk
01024         case 7:
01025             if (radio.RegOpMode.bits.LongRangeMode)
01026                 printf("cad");
01027             else
01028                 printf("-7-");
01029             break;  // todo: different lora/fsk
01030     }
01031 }
01032 
01033 void
01034 printPa()
01035 {
01036     radio.RegPaConfig.octet = radio.read_reg(REG_PACONFIG);
01037     if (radio.RegPaConfig.bits.PaSelect) {
01038         float output_dBm = 17 - (15-radio.RegPaConfig.bits.OutputPower);
01039         printf(" PABOOST OutputPower=%.1fdBm", output_dBm);
01040     } else {
01041         float pmax = (0.6*radio.RegPaConfig.bits.MaxPower) + 10.8;
01042         float output_dBm = pmax - (15-radio.RegPaConfig.bits.OutputPower);
01043 #ifdef TARGET_MTS_MDOT_F411RE
01044         printf(" \x1b[31mRFO pmax=%.1fdBm OutputPower=%.1fdBm\x1b[0m", pmax, output_dBm);  // not connected
01045 #else
01046         printf(" RFO pmax=%.1fdBm OutputPower=%.1fdBm", pmax, output_dBm);
01047 #endif
01048     }
01049 }
01050 
01051 void /* things always present, whether lora or fsk */
01052 common_print_status()
01053 {
01054     printf("version:0x%02x %.3fMHz ", radio.read_reg(REG_VERSION), radio.get_frf_MHz());
01055     printOpMode();
01056 
01057     printPa();
01058 
01059     radio.RegOcp.octet = radio.read_reg(REG_OCP);
01060     if (radio.RegOcp.bits.OcpOn) {
01061         int imax = 0;
01062         if (radio.RegOcp.bits.OcpTrim < 16)
01063             imax = 45 + (5 * radio.RegOcp.bits.OcpTrim);
01064         else if (radio.RegOcp.bits.OcpTrim < 28)
01065             imax = -30 + (10 * radio.RegOcp.bits.OcpTrim);
01066         else
01067             imax = 240;
01068         printf(" OcpOn %dmA ", imax);
01069     } else
01070         printf(" OcpOFF ");
01071 
01072     printf("\r\n");
01073     
01074     if (per_en) {
01075         if (cadper_enable) {
01076             printf("cadper %" PRIu32 ", ", num_cads);
01077         }
01078         printf("per_tx_delay:%f\r\n", per_tx_delay);
01079         printf("PER device ID:%d\r\n", per_id);
01080     }    
01081     
01082     if (poll_irq_en) {
01083         printf("poll_irq_en\r\n");
01084         if (!radio.RegOpMode.bits.LongRangeMode) {
01085             printf("saved irqs: %02x %02x\r\n", fsk_RegIrqFlags1_prev.octet, fsk_RegIrqFlags2_prev.octet);
01086         }
01087     }
01088 
01089 }
01090 
01091 void print_rx_buf(int len)
01092 {
01093     int i;
01094 
01095     printf("000:");
01096     for (i = 0; i < len; i++) {
01097         //printf("(%d)%02x ", i % 16, rx_buf[i]);
01098         printf("%02x ", radio.rx_buf[i]);
01099         if (i % 16 == 15 && i != len-1)
01100             printf("\r\n%03d:", i+1);
01101 
01102     }
01103     printf("\r\n");
01104 }
01105 
01106 void lora_print_rx_verbose(uint8_t dlen)
01107 {
01108     float dbm;
01109     printLoraIrqs_(false);
01110     if (lora.RegHopPeriod > 0) {
01111         lora.RegHopChannel.octet = radio.read_reg(REG_LR_HOPCHANNEL);
01112         printf("HopCH:%d ", lora.RegHopChannel.bits.FhssPresentChannel);
01113     }
01114     printf("%dHz ", lora.get_freq_error_Hz());
01115     lora_printCodingRate(true);  // true: of received packet
01116     dbm = lora.get_pkt_rssi();
01117     printf(" crc%s %.1fdB  %.1fdBm\r\n",
01118         lora.RegHopChannel.bits.RxPayloadCrcOn ? "On" : "OFF",
01119         lora.RegPktSnrValue / 4.0,
01120         dbm
01121     );
01122     print_rx_buf(dlen);
01123 }
01124 
01125 void set_per_en(bool en)
01126 {
01127     if (en) {
01128         if (radio.RegOpMode.bits.LongRangeMode) {
01129             if (radio.type == SX1272) {
01130                 lora.RegModemConfig.sx1272bits.LowDataRateOptimize = 1;
01131                 radio.write_reg(REG_LR_MODEMCONFIG, lora.RegModemConfig.octet);
01132             } else if (radio.type == SX1276) {
01133                 lora.RegModemConfig3.sx1276bits.LowDataRateOptimize = 1;
01134                 radio.write_reg(REG_LR_MODEMCONFIG3, lora.RegModemConfig3.octet);
01135             }
01136             lora.RegPayloadLength = 9;
01137             radio.write_reg(REG_LR_PAYLOADLENGTH, lora.RegPayloadLength);
01138             radio.RegDioMapping1.bits.Dio3Mapping = 1;  // to ValidHeader
01139             radio.write_reg(REG_DIOMAPPING1, radio.RegDioMapping1.octet);                                  
01140         } else {    // fsk..
01141             //fsk_tx_length = 9;
01142         }
01143         PacketRxSequencePrev = 0; // transmitter side PacketTxCnt is 1 at first TX
01144         //PacketRxSequence = 0;
01145         PacketPerKoCnt = 0;
01146         PacketPerOkCnt = 0;
01147         PacketNormalCnt = 0;
01148     } // ..if (per_en)
01149     else {
01150         per_timeout.detach();
01151     }    
01152     
01153     per_en = en; 
01154 }   
01155 
01156 void per_cb()
01157 {
01158     int i;
01159     
01160     PacketTxCnt++;
01161 
01162     radio.tx_buf[0] = per_id;
01163     radio.tx_buf[1] = PacketTxCnt >> 24;
01164     radio.tx_buf[2] = PacketTxCnt >> 16;
01165     radio.tx_buf[3] = PacketTxCnt >> 8;
01166     radio.tx_buf[4] = PacketTxCnt;
01167     radio.tx_buf[5] = 'P';
01168     radio.tx_buf[6] = 'E';
01169     radio.tx_buf[7] = 'R';
01170     radio.tx_buf[8] = 0;
01171     for (i = 0; i < 8; i++)
01172         radio.tx_buf[8] += radio.tx_buf[i];
01173 
01174     if (radio.RegOpMode.bits.LongRangeMode) {
01175         lora.start_tx(lora.RegPayloadLength);
01176     } else {
01177         fsk.start_tx(9);
01178     }    
01179     
01180     led1 = !led1.read();
01181     
01182     if (PacketTxCnt == PacketTxCntEnd) {
01183         set_per_en(false);
01184         return;
01185     }    
01186 }
01187 
01188 int per_parse_rx(uint8_t len)
01189 {
01190     if (len > 8 && radio.rx_buf[5] == 'P' && radio.rx_buf[6] == 'E' && radio.rx_buf[7] == 'R') {
01191         int i;
01192         float per;
01193 
01194         /* this is PER packet */
01195         int PacketRxSequence = (radio.rx_buf[1] << 24) | (radio.rx_buf[2] << 16) | (radio.rx_buf[3] << 8) | radio.rx_buf[4];
01196         PacketPerOkCnt++;
01197         
01198         if( PacketRxSequence <= PacketRxSequencePrev )
01199         { // Sequence went back => resynchronization
01200             // dont count missed packets this time
01201             i = 0;
01202         }
01203         else
01204         {
01205             // determine number of missed packets
01206             i = PacketRxSequence - PacketRxSequencePrev - 1;
01207         }
01208         
01209         led1 = !led1.read();
01210         // be ready for the next
01211         PacketRxSequencePrev = PacketRxSequence;
01212         // increment 'missed' counter for the RX session
01213         PacketPerKoCnt += i;
01214         per = ( (float)1.0 - ( float )PacketPerOkCnt / ( float )( PacketPerOkCnt + PacketPerKoCnt ) ) * (float)100.0;
01215         printf("%d, ok=%" PRIu32 " missed=%" PRIu32 " normal=%" PRIu32 " per:%.3f ", PacketRxSequence, PacketPerOkCnt, PacketPerKoCnt, PacketNormalCnt, per);
01216         if (radio.RegOpMode.bits.LongRangeMode)
01217             printf("pkt:%ddBm, snr:%.1fdB, %ddBm\r\n", lora.get_pkt_rssi(), lora.RegPktSnrValue / 4.0, lora.get_current_rssi());
01218         else {
01219             wait_us(10000);
01220             printf(" -%.1fdBm\r\n", radio.read_reg(REG_FSK_RSSIVALUE) / 2.0); 
01221         }
01222 
01223         return 1;
01224     } else {
01225         return 0;
01226     }    
01227 }
01228 
01229 typedef enum {
01230     ON_TXDONE_STATE_NONE = 0,
01231     ON_TXDONE_STATE_SYNC_HI_NIBBLE,
01232     ON_TXDONE_STATE_SYNC_LO_NIBBLE,
01233     ON_TXDONE_STATE_PAYLOAD_LENGTH,
01234 } on_txdone_state_e;
01235 
01236 on_txdone_state_e on_txdone_state;
01237 
01238 uint8_t lora_sync_byte;
01239 float on_txdone_delay;
01240 Timeout on_txdone_timeout;
01241 uint8_t on_txdone_repeat_cnt;
01242 
01243 void txdone_timeout_cb()
01244 {
01245     uint8_t nib;
01246     
01247     switch (on_txdone_state) {
01248         case ON_TXDONE_STATE_SYNC_HI_NIBBLE:
01249             nib = lora_sync_byte >> 4;
01250             if (nib >= 15) {
01251                 on_txdone_state = ON_TXDONE_STATE_SYNC_LO_NIBBLE;
01252                 lora_sync_byte = 0x00;
01253             } else
01254                 nib++;
01255                 
01256             lora_sync_byte = nib << 4;     
01257             
01258             radio.write_reg(REG_LR_SYNC_BYTE, lora_sync_byte);
01259             printf("upper %02x\r\n", lora_sync_byte);               
01260             break;
01261         case ON_TXDONE_STATE_SYNC_LO_NIBBLE:
01262             nib = lora_sync_byte & 0x0f;
01263             if (nib >= 15) {
01264                 on_txdone_state = ON_TXDONE_STATE_SYNC_LO_NIBBLE;
01265                 lora_sync_byte = 0x00;
01266             } else
01267                 nib++;
01268             
01269             lora_sync_byte = nib & 0x0f;   
01270             
01271             radio.write_reg(REG_LR_SYNC_BYTE, lora_sync_byte);
01272             printf("lower %02x\r\n", lora_sync_byte);                 
01273             break;
01274         case ON_TXDONE_STATE_PAYLOAD_LENGTH:
01275             if (++on_txdone_repeat_cnt >= 10) {
01276                 on_txdone_repeat_cnt = 0;
01277                 if (lora.RegPayloadLength == 255) {
01278                     lora.RegPayloadLength = 1;
01279                     printf("done\r\n");
01280                     on_txdone_state = ON_TXDONE_STATE_NONE;
01281                     return;
01282                 }
01283                 lora.RegPayloadLength++;
01284                 radio.write_reg(REG_LR_PAYLOADLENGTH, lora.RegPayloadLength);
01285                 printf("pl %d\r\n", lora.RegPayloadLength);
01286             }
01287             tx_cnt++;
01288             radio.tx_buf[0] = tx_cnt;     
01289             radio.tx_buf[1] = ~tx_cnt;              
01290             break;
01291         default:
01292             return;
01293     } // ..switch (on_txdone_state)
01294 
01295     lora.start_tx(lora.RegPayloadLength);
01296 }
01297 
01298   
01299 void
01300 poll_service_radio()
01301 {
01302     if (radio.RegOpMode.bits.LongRangeMode) {
01303     } else { // fsk:
01304         if (rx_payloadReady_int_en)
01305             return;
01306 
01307         /*RegIrqFlags2_t RegIrqFlags2;
01308         if (radio.RegOpMode.bits.Mode == RF_OPMODE_TRANSMITTER) {
01309             RegIrqFlags2.octet = radio.read_reg(REG_FSK_IRQFLAGS2);
01310             if (RegIrqFlags2.bits.PacketSent) {
01311                 radio.set_opmode(RF_OPMODE_SLEEP);
01312                 printf("poll mode fsk tx done\r\n");
01313             }
01314         }*/
01315         static uint8_t rssi;    
01316         RegIrqFlags2_t RegIrqFlags2;
01317         RegIrqFlags1_t RegIrqFlags1;
01318         RegIrqFlags1.octet = radio.read_reg(REG_FSK_IRQFLAGS1);
01319         if (RegIrqFlags1.octet != fsk_RegIrqFlags1_prev.octet) {
01320             printf("iF1:");
01321             if (RegIrqFlags1.bits.ModeReady ^ fsk_RegIrqFlags1_prev.bits.ModeReady) {
01322                 printf("ModeReady-");
01323                 if (RegIrqFlags1.bits.ModeReady)
01324                     printf("on ");
01325                 else
01326                     printf("off ");
01327             }
01328             if (RegIrqFlags1.bits.RxReady ^ fsk_RegIrqFlags1_prev.bits.RxReady) {
01329                 printf("RxReady-");
01330                 if (RegIrqFlags1.bits.RxReady)
01331                     printf("on ");
01332                 else
01333                     printf("off ");
01334             }
01335             if (RegIrqFlags1.bits.TxReady ^ fsk_RegIrqFlags1_prev.bits.TxReady) {
01336                 printf("TxReady-");
01337                 if (RegIrqFlags1.bits.TxReady)
01338                     printf("on ");
01339                 else
01340                     printf("off ");                
01341             }
01342             if (RegIrqFlags1.bits.PllLock ^ fsk_RegIrqFlags1_prev.bits.PllLock) {
01343                 printf("PllLock-");
01344                 if (RegIrqFlags1.bits.PllLock)
01345                     printf("on ");
01346                 else
01347                     printf("off ");                    
01348             }
01349             if (RegIrqFlags1.bits.Rssi ^ fsk_RegIrqFlags1_prev.bits.Rssi) {
01350                 printf("Rssi-");
01351                 if (RegIrqFlags1.bits.Rssi)
01352                     printf("on ");
01353                 else
01354                     printf("off ");                   
01355             }
01356             if (RegIrqFlags1.bits.Timeout ^ fsk_RegIrqFlags1_prev.bits.Timeout) {
01357                 printf("Timeout-");
01358                 if (RegIrqFlags1.bits.Timeout)
01359                     printf("on ");
01360                 else
01361                     printf("off ");                   
01362             }
01363             if (RegIrqFlags1.bits.PreambleDetect ^ fsk_RegIrqFlags1_prev.bits.PreambleDetect) {
01364                 printf("PreambleDetect-");
01365                 if (RegIrqFlags1.bits.PreambleDetect)
01366                     printf("on ");
01367                 else
01368                     printf("off ");                   
01369             }
01370             if (RegIrqFlags1.bits.SyncAddressMatch ^ fsk_RegIrqFlags1_prev.bits.SyncAddressMatch) {
01371                 printf("SyncAddressMatch-");
01372                 if (RegIrqFlags1.bits.SyncAddressMatch)
01373                     printf("on ");
01374                 else
01375                     printf("off ");                   
01376             }
01377             fsk_RegIrqFlags1_prev.octet = RegIrqFlags1.octet; 
01378             printf("\r\n");
01379             fflush(stdout); 
01380         }    
01381         RegIrqFlags2.octet = radio.read_reg(REG_FSK_IRQFLAGS2);
01382         if (RegIrqFlags2.octet != fsk_RegIrqFlags2_prev.octet) {
01383             printf("iF2:");
01384             if (RegIrqFlags2.bits.FifoFull ^ fsk_RegIrqFlags2_prev.bits.FifoFull) {
01385                 printf("FifoFull-");
01386                 if (RegIrqFlags2.bits.FifoFull)
01387                     printf("on ");
01388                 else
01389                     printf("off ");                   
01390             }
01391             if (RegIrqFlags2.bits.FifoEmpty ^ fsk_RegIrqFlags2_prev.bits.FifoEmpty) {
01392                 printf("FifoEmpty-");
01393                 if (RegIrqFlags2.bits.FifoEmpty)
01394                     printf("on ");
01395                 else {
01396                     printf("off ");                 
01397                     rssi = radio.read_reg(REG_FSK_RSSIVALUE);
01398                 }
01399             }
01400             if (RegIrqFlags2.bits.FifoLevel ^ fsk_RegIrqFlags2_prev.bits.FifoLevel) {
01401                 printf("FifoLevel-");
01402                 if (RegIrqFlags2.bits.FifoLevel)
01403                     printf("on ");
01404                 else
01405                     printf("off ");                 
01406             }
01407             if (RegIrqFlags2.bits.FifoOverrun ^ fsk_RegIrqFlags2_prev.bits.FifoOverrun) {
01408                 printf("FifoOverrun-");
01409                 if (RegIrqFlags2.bits.FifoOverrun)
01410                     printf("on ");
01411                 else
01412                     printf("off ");                 
01413             }
01414             if (RegIrqFlags2.bits.PacketSent ^ fsk_RegIrqFlags2_prev.bits.PacketSent) {
01415                 printf("PacketSent-");
01416                 if (RegIrqFlags2.bits.PacketSent) {
01417                     printf("on ");
01418                 } else
01419                     printf("off ");                 
01420             }
01421             if (RegIrqFlags2.bits.PayloadReady ^ fsk_RegIrqFlags2_prev.bits.PayloadReady) {
01422                 printf("PayloadReady-");
01423                 if (RegIrqFlags2.bits.PayloadReady)
01424                     printf("on ");
01425                 else
01426                     printf("off ");                 
01427             }
01428             if (RegIrqFlags2.bits.CrcOk ^ fsk_RegIrqFlags2_prev.bits.CrcOk) {
01429                 printf("CrcOk-");
01430                 if (RegIrqFlags2.bits.CrcOk)
01431                     printf("on ");
01432                 else
01433                     printf("off ");                 
01434             }
01435             if (RegIrqFlags2.bits.LowBat ^ fsk_RegIrqFlags2_prev.bits.LowBat) {
01436                 printf("LowBat-");
01437                 if (RegIrqFlags2.bits.LowBat)
01438                     printf("on ");
01439                 else
01440                     printf("off ");                 
01441             }
01442             fsk_RegIrqFlags2_prev.octet = RegIrqFlags2.octet;
01443             printf("\r\n");
01444             fflush(stdout); 
01445             
01446             if (RegIrqFlags2.bits.PacketSent) {
01447                 if (fsk.tx_done_sleep)
01448                     radio.set_opmode(RF_OPMODE_SLEEP);
01449                 else
01450                     radio.set_opmode(RF_OPMODE_STANDBY);                    
01451             }
01452 
01453             if (RegIrqFlags2.bits.CrcOk || RegIrqFlags2.bits.PayloadReady) {
01454                 if (fsk.RegRxConfig.bits.AfcAutoOn) {
01455                     fsk.RegAfcValue = radio.read_s16(REG_FSK_AFCMSB);      
01456                     printf("%dHz ", (int)(FREQ_STEP_HZ * fsk.RegAfcValue));  
01457                     if (rssi != 0) {
01458                         printf("pkt:-%.1fdBm ", rssi / 2.0);
01459                         rssi = 0;
01460                     }                                         
01461                 }
01462                 if (fsk.RegPktConfig1.bits.PacketFormatVariable) {
01463                     fsk.rx_buf_length = radio.read_reg(REG_FIFO);
01464                 } else {
01465                     fsk.rx_buf_length = fsk.RegPktConfig2.bits.PayloadLength;
01466                 }
01467                 
01468                 radio.m_cs = 0;
01469                 radio.m_spi.write(REG_FIFO); // bit7 is low for reading from radio
01470                 for (int i = 0; i < fsk.rx_buf_length; i++) {
01471                     radio.rx_buf[i] = radio.m_spi.write(0);
01472                 }
01473                 radio.m_cs = 1;                        
01474                 /****/
01475                 if (per_en) { 
01476                     if (!per_parse_rx(fsk.rx_buf_length)) {
01477                         PacketNormalCnt++;
01478                         print_rx_buf(fsk.rx_buf_length);                                                 
01479                     }                                       
01480                 } else {
01481                     print_rx_buf(fsk.rx_buf_length);                            
01482                 }
01483                 fflush(stdout);                    
01484             } // ..if CrcOk or PayloadReady
01485         } // ..if RegIrqFlags2 changed
01486     } // ...fsk
01487 }
01488 
01489 void cadper_service()
01490 {
01491     lora.RegIrqFlags.octet = radio.read_reg(REG_LR_IRQFLAGS);
01492     
01493 
01494     if (lora.RegIrqFlags.bits.CadDetected) {
01495         lora.start_rx(RF_OPMODE_RECEIVER_SINGLE);
01496         do {
01497             lora.RegIrqFlags.octet = radio.read_reg(REG_LR_IRQFLAGS);
01498             if (lora.RegIrqFlags.bits.RxDone) {
01499                 service_action_e act = lora.service();
01500                 if (act == SERVICE_READ_FIFO) {
01501                     if (!per_parse_rx(lora.RegRxNbBytes)) {
01502                         PacketNormalCnt++;
01503                         lora_print_rx_verbose(lora.RegRxNbBytes);                            
01504                     }                        
01505                 }
01506                 break;
01507             }
01508         } while (!lora.RegIrqFlags.bits.RxTimeout);
01509         radio.write_reg(REG_LR_IRQFLAGS, lora.RegIrqFlags.octet);
01510     }
01511     
01512     if (lora.RegIrqFlags.bits.CadDone) {
01513         lora.RegIrqFlags.octet = radio.read_reg(REG_LR_IRQFLAGS);
01514         num_cads++;
01515         radio.set_opmode(RF_OPMODE_CAD);
01516     }        
01517 
01518 }
01519 
01520 void cmd_restart_rx(uint8_t);
01521 int preamble_to_sync_us;
01522 #ifndef TARGET_DISCO_L072CZ_LRWAN1
01523 Timeout timeout_syncAddress;
01524 bool get_syncAddress;
01525 #endif
01526 float preamble_detect_at;
01527 
01528 void callback_sa_timeout()
01529 {
01530     printf("syncAddress timeout ");
01531     if (dio2.read() == 0) {
01532         //cmd_restart_rx(0);
01533         rx_start_timer.reset();
01534         radio.set_opmode(RF_OPMODE_STANDBY);
01535         printf("(false preamble detect at %f, secs:%lu)\r\n", preamble_detect_at, time(NULL) - secs_rx_start);
01536         secs_rx_start = time(NULL);
01537         radio.set_opmode(RF_OPMODE_RECEIVER);
01538     } else
01539         printf("\r\n");
01540 }   
01541 
01542 void
01543 service_radio()
01544 {
01545     service_action_e act;
01546     static uint8_t rssi = 0;
01547     
01548     if (radio.RegOpMode.bits.LongRangeMode) {
01549         if (rssi_polling_thresh != 0 && radio.RegOpMode.bits.Mode == RF_OPMODE_RECEIVER) {
01550             rssi = lora.get_current_rssi(); // dBm returned, negative value
01551 #if defined(TARGET_STM) && !defined(TARGET_DISCO_L072CZ_LRWAN1) && !defined(TARGET_MTS_MDOT_F411RE)
01552             if (rssi < rssi_polling_thresh)
01553                 pc3 = 0;    // signal weaker than threshold
01554             else
01555                 pc3 = 1;    // signal stronger than threshold            
01556 #endif
01557         }
01558         
01559         if (cadper_enable) {
01560             cadper_service();
01561         }
01562 
01563         act = lora.service();
01564     
01565         switch (act) {
01566             case SERVICE_READ_FIFO:
01567                 if (app == APP_NONE) {
01568                     if (per_en) {
01569                         if (!per_parse_rx(lora.RegRxNbBytes)) {
01570                             PacketNormalCnt++;
01571                             lora_print_rx_verbose(lora.RegRxNbBytes);                            
01572                         }
01573                     } else                     
01574                         lora_print_rx_verbose(lora.RegRxNbBytes);
01575                     fflush(stdout);
01576                 } else if (app == APP_CHAT) {
01577                     if (lora.RegHopChannel.bits.RxPayloadCrcOn) {
01578                         if (lora.RegIrqFlags.bits.PayloadCrcError)
01579                             printf("crcError\r\n");
01580                         else {
01581                             int n = lora.RegRxNbBytes;
01582                             radio.rx_buf[n++] = '\r';
01583                             radio.rx_buf[n++] = '\n';
01584                             radio.rx_buf[n] = 0; // null terminate
01585                             printf((char *)radio.rx_buf);
01586                         }
01587                     } else
01588                         printf("crcOff\r\n");
01589                         
01590                     // clear Irq flags
01591                     radio.write_reg(REG_LR_IRQFLAGS, lora.RegIrqFlags.octet);
01592                     // should still be in receive mode
01593                 }
01594                 break;
01595             case SERVICE_TX_DONE:
01596                 if (app == APP_CHAT) {
01597                     lora.start_rx(RF_OPMODE_RECEIVER);
01598                 } else if (per_en) {
01599                     per_timeout.attach(&per_cb, per_tx_delay); // start next TX              
01600                 } else if (on_txdone_state != ON_TXDONE_STATE_NONE) {
01601                     on_txdone_timeout.attach(&txdone_timeout_cb, on_txdone_delay);
01602                 }
01603                 break;
01604             case SERVICE_ERROR:
01605                 printf("error\r\n");
01606                 break;
01607             case SERVICE_NONE:
01608                 break;
01609         } // ...switch (act)
01610     } else {
01611         /* FSK: */
01612         
01613         if (rx_payloadReady_int_en)
01614             return; // radio service by ISR only
01615 
01616         if (ulrx_enable)
01617             return;
01618 
01619         act = fsk.service();
01620         
01621          switch (act) {
01622              case SERVICE_READ_FIFO:
01623                 if (app == APP_CHAT) {
01624                     int n = fsk.rx_buf_length;
01625                     radio.rx_buf[n++] = '\r';
01626                     radio.rx_buf[n++] = '\n';
01627                     radio.rx_buf[n] = 0; // null terminate
01628                     printf((char *)radio.rx_buf);                    
01629                 } else {
01630                     if (fsk.RegRxConfig.bits.AfcAutoOn) {
01631                         printf("%dHz ", (int)(FREQ_STEP_HZ * fsk.RegAfcValue));   
01632                         if (rssi != 0) {
01633                             printf("pkt:-%.1fdBm ", rssi / 2.0);
01634                             rssi = 0;
01635                         }    
01636                     }
01637                     if (per_en) { 
01638                         if (!per_parse_rx(fsk.rx_buf_length)) {
01639                             PacketNormalCnt++;
01640                             print_rx_buf(fsk.rx_buf_length);                                                 
01641                         }                                       
01642                     } else {
01643                         print_rx_buf(fsk.rx_buf_length);                            
01644                     }
01645                     
01646                 }
01647                 if (crc32_en) {
01648                     uint32_t c, *u32_ptr = (uint32_t*)&radio.rx_buf[fsk.rx_buf_length-4];
01649                     printf("rx crc:%08x, ", (unsigned int)(*u32_ptr));
01650                     c = gen_crc(radio.rx_buf, fsk.rx_buf_length-4);
01651                     printf("calc crc:%08x\r\n", (unsigned int)c);                    
01652                 }
01653                 fflush(stdout);
01654                 break;
01655             case SERVICE_TX_DONE:
01656                 if (ook_test_en)
01657                     radio.set_opmode(RF_OPMODE_SLEEP);
01658                 if (app == APP_CHAT) {
01659                     fsk.start_rx();
01660                 } else if (per_en) {
01661                     per_timeout.attach(&per_cb, per_tx_delay); // start next TX
01662                 }                
01663                 break;                
01664             case SERVICE_ERROR:
01665             case SERVICE_NONE:
01666                 break;                
01667         } // ...switch (act)
01668 
01669 #ifndef TARGET_DISCO_L072CZ_LRWAN1
01670         /* FSK receiver handling of preamble detection */
01671         if (radio.RegDioMapping2.bits.MapPreambleDetect && radio.RegDioMapping2.bits.Dio4Mapping == 3) {
01672             if (saved_dio4 != dio4.read()) {
01673                 //printf("predet-dio4:%d\r\n", dio4.read());
01674                 /* FSK: preamble detect state change */
01675                 if (dio4.read()) {
01676                     if (radio.RegDioMapping1.bits.Dio2Mapping == 3) {   // if we can see SyncAddress
01677                         get_syncAddress = true;
01678                         timeout_syncAddress.attach_us(callback_sa_timeout, preamble_to_sync_us);
01679                     }
01680                     /* how long after RX start is preamble detection occuring? */
01681                     //printf("preamble detect at %f\r\n", rx_start_timer.read());
01682                     preamble_detect_at = rx_start_timer.read(); 
01683                 } else {
01684                     get_syncAddress = false;
01685                     //printf("preamble detect clear\r\n");
01686                 }
01687                 saved_dio4 = dio4.read();
01688              }
01689          }  // ..if dio4 is 
01690              
01691          if (radio.RegDioMapping1.bits.Dio2Mapping == 3) {
01692              if (dio2.read()) {
01693                  if (get_syncAddress) {
01694                      timeout_syncAddress.detach();
01695                      get_syncAddress = false;
01696                  }                 
01697                  rssi = radio.read_reg(REG_FSK_RSSIVALUE);
01698              }
01699          }
01700 #endif /* !TARGET_DISCO_L072CZ_LRWAN1 */           
01701 
01702         if (rssi_polling_thresh != 0 && radio.RegOpMode.bits.Mode == RF_OPMODE_RECEIVER) {
01703             rssi = radio.read_reg(REG_FSK_RSSIVALUE);
01704             rssi = -rssi;
01705 #if defined(TARGET_STM) && !defined(TARGET_DISCO_L072CZ_LRWAN1) && !defined(TARGET_MTS_MDOT_F411RE)
01706             if (rssi < rssi_polling_thresh)
01707                 pc3 = 0;    // signal weaker than threshold
01708             else
01709                 pc3 = 1;    // signal stronger than threshold
01710 #endif
01711         }
01712 
01713     } // ...!radio.RegOpMode.bits.LongRangeMode
01714 }
01715 
01716 /*int get_kbd_str(char* buf, int size)
01717 {
01718     char c;
01719     int i;
01720     static int prev_len;
01721     
01722     for (i = 0;;) {
01723         if (pc.readable()) {
01724             c = pc.getc();
01725             if (c == 8 && i > 0) {
01726                 pc.putc(8);
01727                 pc.putc(' ');
01728                 pc.putc(8);
01729                 i--;
01730             } else if (c == '\r') {
01731                 if (i == 0) {
01732                     return prev_len; // repeat previous
01733                 } else {
01734                     buf[i] = 0; // null terminate
01735                     prev_len = i;
01736                     return i;
01737                 }
01738             } else if (c == 3) {
01739                 // ctrl-C abort
01740                 return -1;
01741             } else if (i < size) {
01742                 buf[i++] = c;
01743                 pc.putc(c);
01744             }
01745         } else {
01746             service_radio();
01747         }
01748     } // ...for()
01749 }*/
01750 
01751 void
01752 console_chat()
01753 {
01754     //int i, len = get_kbd_str(pcbuf, sizeof(pcbuf));
01755     
01756     service_radio();
01757     
01758     if (pcbuf_len < 0) {
01759         printf("chat abort\r\n");
01760         pcbuf_len = 0;
01761         app = APP_NONE;
01762         return;
01763     } else if (pcbuf_len == 0) {
01764         return;
01765     } else {
01766         int i;
01767         for (i = 0; i < pcbuf_len; i++)
01768             radio.tx_buf[i] = pcbuf[i];
01769         if (radio.RegOpMode.bits.LongRangeMode) {
01770             lora.RegPayloadLength = pcbuf_len;
01771             radio.write_reg(REG_LR_PAYLOADLENGTH, lora.RegPayloadLength);
01772             lora.start_tx(pcbuf_len);
01773         } else {
01774             fsk.start_tx(pcbuf_len);
01775         }
01776         pcbuf_len = 0;
01777         printf("\r\n");
01778     }
01779 }
01780 
01781 const uint8_t ookt_tx_payload[29] = {
01782     0x55, 0x55, 0x55, 0x55, 0xA9, 0x66, 0x69, 0x65,
01783     0x39, 0x53, 0xAA, 0xC3, 0xA6, 0x95, 0xC6, 0x3C,
01784     0x6A, 0x33, 0x33, 0xC6, 0xCA, 0xA6, 0x33, 0x33,
01785     0x55, 0x6A, 0xA6, 0xAA, 0x53
01786 };
01787 volatile unsigned int ook_tx_cnt = 0;
01788 
01789 void callback_ook_tx_test()
01790 {
01791     unsigned int i;  
01792     
01793     //radio.write_reg(REG_FSK_SYNCCONFIG, 0);
01794       
01795     printf("%u ookTx: ", ook_tx_cnt++);
01796     for (i = 0; i < sizeof(ookt_tx_payload); i++) {
01797         radio.tx_buf[i] = ookt_tx_payload[i];
01798         printf("%02x ", radio.tx_buf[i]);
01799     }
01800     printf("\r\n");
01801     
01802     //printf("syncConf:%x\r\n", radio.read_reg(REG_FSK_SYNCCONFIG));
01803     fsk.start_tx(sizeof(ookt_tx_payload));     
01804 }
01805 
01806 typedef enum {
01807     TXTICKER_STATE_OFF = 0,
01808     TXTICKER_STATE_TOGGLE_PAYLOAD_BIT,
01809     TXTICKER_STATE_CYCLE_PAYLOAD_LENGTH,
01810     TXTICKER_STATE_CYCLE_CODING_RATE,
01811     TXTICKER_STATE_TOG_HEADER_MODE,
01812     TXTICKER_STATE_TOG_CRC_ON,
01813     TXTICKER_STATE_CYCLE_SYNC_1,
01814     TXTICKER_STATE_CYCLE_SYNC_2,
01815     TXTICKER_STATE_RAMP_PAYLOAD_DATA_START,
01816     TXTICKER_STATE_RAMP_PAYLOAD_DATA,
01817     TXTICKER_STATE_SYMBOL_SWEEP,
01818     TXTICKER_STATE_TOGGLE_ALL_BITS_START,
01819     TXTICKER_STATE_TOGGLE_ALL_BITS,
01820 } txticker_state_e;
01821 
01822 txticker_state_e txticker_state;
01823 float tx_ticker_rate = 0.5;
01824 Ticker tx_ticker;
01825 
01826 uint8_t txticker_sync_byte;
01827 uint8_t payload_length_stop;
01828 uint8_t symbol_num;
01829 uint32_t symbol_sweep_bit_counter = 0;
01830 unsigned int symbol_sweep_bit_counter_stop; 
01831 uint8_t symbol_sweep_nbits;
01832 uint8_t byte_pad_length;
01833 
01834 uint8_t tab_current_byte_num;
01835 uint8_t tab_current_bit_in_byte;
01836 
01837 void fp_cb()
01838 {   
01839     int i;
01840     if (!radio.RegOpMode.bits.LongRangeMode)
01841         return;
01842           
01843     switch (txticker_state) {
01844     case TXTICKER_STATE_TOGGLE_PAYLOAD_BIT:
01845 /*
01846         {
01847             if (fp_tog_bit_ < 32) {
01848                 uint32_t bp = 1 << fp_tog_bit_;
01849                 fp_data ^= bp;
01850                 //printf("bp%02x ", bp);
01851             }
01852             memcpy(radio.tx_buf, &fp_data, fp_data_length);
01853             printf("TX ");
01854             for (i = 0; i < fp_data_length; i++)
01855                 printf("%02x ", radio.tx_buf[i]);
01856                 
01857             printf("\r\n");
01858             lora.start_tx(lora.RegPayloadLength);        
01859             break;
01860         }
01861 */
01862         tx_ticker.detach();
01863         break;
01864     case TXTICKER_STATE_CYCLE_PAYLOAD_LENGTH:
01865         {
01866             if (lora.RegPayloadLength > payload_length_stop)
01867                 lora.RegPayloadLength = 0;
01868             else
01869                 lora.RegPayloadLength++;
01870                 
01871             radio.write_reg(REG_LR_PAYLOADLENGTH, lora.RegPayloadLength);        
01872             lora.start_tx(lora.RegPayloadLength);
01873             printf("RegPayloadLength:%d\r\n", lora.RegPayloadLength);        
01874             break;
01875         }
01876     case TXTICKER_STATE_CYCLE_CODING_RATE:
01877         {
01878             uint8_t cr = lora.getCodingRate(false); // false: TX coding rate
01879             if (cr == 4)
01880                 cr = 0;
01881             else
01882                 cr++;
01883                 
01884             lora.setCodingRate(cr);
01885             lora.start_tx(lora.RegPayloadLength);
01886             printf("tx cr:%d\r\n", cr);        
01887             break;
01888         }
01889     case TXTICKER_STATE_TOG_HEADER_MODE:
01890         {
01891             lora.setHeaderMode(!lora.getHeaderMode());
01892             lora.start_tx(lora.RegPayloadLength);
01893             lora.RegModemConfig.octet = radio.read_reg(REG_LR_MODEMCONFIG);
01894             lora_printHeaderMode();
01895             printf("\r\n");          
01896             break;
01897         }
01898     case TXTICKER_STATE_TOG_CRC_ON:
01899         {
01900             lora.setRxPayloadCrcOn(!lora.getRxPayloadCrcOn());
01901             lora.start_tx(lora.RegPayloadLength);
01902             printf("crc on:%d\r\n", lora.getRxPayloadCrcOn());        
01903             break;
01904         }
01905     case TXTICKER_STATE_CYCLE_SYNC_1:
01906         {
01907             /* cycle hi nibble of 0x39 register */
01908             if ((txticker_sync_byte & 0xf0) == 0xf0)
01909                 txticker_sync_byte &= 0x0f;
01910             else
01911                 txticker_sync_byte += 0x10;
01912             radio.write_reg(REG_LR_SYNC_BYTE, txticker_sync_byte);
01913             lora.start_tx(lora.RegPayloadLength);
01914             printf("0x39: %02x\r\n", txticker_sync_byte);        
01915             break;
01916         }
01917     case TXTICKER_STATE_CYCLE_SYNC_2:
01918         {
01919             /* cycle lo nibble of 0x39 register */
01920             if ((txticker_sync_byte & 0x0f) == 0x0f)
01921                 txticker_sync_byte &= 0xf0;
01922             else
01923                 txticker_sync_byte += 0x01;
01924             radio.write_reg(REG_LR_SYNC_BYTE, txticker_sync_byte);
01925             lora.start_tx(lora.RegPayloadLength);
01926             printf("0x39: %02x\r\n", txticker_sync_byte);         
01927             break;
01928         }
01929     case TXTICKER_STATE_RAMP_PAYLOAD_DATA_START:
01930         txticker_state = TXTICKER_STATE_RAMP_PAYLOAD_DATA;
01931         for (i = 0; i < lora.RegPayloadLength; i++)
01932             radio.tx_buf[i] = 0;
01933 
01934         lora.start_tx(lora.RegPayloadLength);
01935         printf("payload start, len:%d\r\n", lora.RegPayloadLength);
01936         break;
01937     case TXTICKER_STATE_RAMP_PAYLOAD_DATA:
01938         for (i = lora.RegPayloadLength-1; i >= 0; i--) {
01939             //printf("i:%d ", i);
01940             if (radio.tx_buf[i] == 255) {
01941                 radio.tx_buf[i] = 0;
01942             } else {
01943                 radio.tx_buf[i]++;
01944                 break;
01945             }
01946         }
01947         //printf("\r\n");
01948         printf("send:");
01949         for (i = 0; i < lora.RegPayloadLength; i++) {
01950             printf("%02x ", radio.tx_buf[i]);
01951         }
01952         printf("\r\n");
01953         lora.start_tx(lora.RegPayloadLength);
01954         if (radio.tx_buf[0] == 255) {
01955             printf("payload ramp done\r\n");
01956             tx_ticker.detach();
01957         }
01958         break;
01959     case TXTICKER_STATE_SYMBOL_SWEEP:       // fpsNL command, where N=symbol num, L=nbytes
01960         {
01961             uint32_t mask;
01962             /*for (i = 0; i < lora.RegPayloadLength; i++)
01963                 radio.tx_buf[i] = 0;*/
01964             i = byte_pad_length;
01965             printf("bit_counter 0x%" PRIx32 " : ", symbol_sweep_bit_counter);
01966             for (int bn = 0; bn < symbol_sweep_nbits; bn += 2) {
01967                 /* 2 lsbits going into first byte */
01968                 mask = 1 << bn;
01969                 if (symbol_sweep_bit_counter & mask)
01970                     radio.tx_buf[i] |= 1 << symbol_num;
01971                 else
01972                     radio.tx_buf[i] &= ~(1 << symbol_num);
01973                 mask = 2 << bn;
01974                 if (symbol_sweep_bit_counter & mask)
01975                     radio.tx_buf[i] |= 0x10 << symbol_num;
01976                 else
01977                     radio.tx_buf[i] &= ~(0x10 << symbol_num);
01978                 //printf("%02x ", radio.tx_buf[i]);
01979                 i++;
01980             }
01981             for (i = 0; i < lora.RegPayloadLength; i++)
01982                 printf("%02x ", radio.tx_buf[i]);
01983             printf("\r\n");
01984             lora.start_tx(lora.RegPayloadLength);
01985             if (++symbol_sweep_bit_counter == symbol_sweep_bit_counter_stop) {
01986                 printf("stop\r\n");
01987                 tx_ticker.detach();
01988             }
01989         }
01990         break;
01991     case TXTICKER_STATE_TOGGLE_ALL_BITS_START:
01992         tab_current_byte_num = byte_pad_length;
01993         tab_current_bit_in_byte = 0;
01994         printf("tx ");
01995         for (i = 0; i < lora.RegPayloadLength; i++) {
01996             radio.tx_buf[i] = 0;
01997             printf("%02x ", radio.tx_buf[i]);
01998         }
01999         printf("\r\n");
02000         txticker_state = TXTICKER_STATE_TOGGLE_ALL_BITS;
02001         lora.start_tx(lora.RegPayloadLength);
02002         break;
02003     case TXTICKER_STATE_TOGGLE_ALL_BITS:
02004         {
02005             uint8_t mask = 1 << tab_current_bit_in_byte;
02006             radio.tx_buf[tab_current_byte_num] = mask;
02007             printf("bit%d in [%d]: tx ", tab_current_bit_in_byte, tab_current_byte_num);
02008             for (i = 0; i < lora.RegPayloadLength; i++) {
02009                 printf("%02x ", radio.tx_buf[i]);
02010             }
02011             printf("\r\n");            
02012             lora.start_tx(lora.RegPayloadLength);
02013             if (++tab_current_bit_in_byte == 8) {
02014                 radio.tx_buf[tab_current_byte_num] = 0;
02015                 tab_current_bit_in_byte = 0;
02016                 if (++tab_current_byte_num == lora.RegPayloadLength) {
02017                     tx_ticker.detach();
02018                 }
02019             }
02020         }
02021         break;
02022     default:
02023             tx_ticker.detach();
02024             break;
02025     } // ...switch (txticker_state)
02026 }
02027 
02028 void ook_test_tx(int len)
02029 {    
02030     int i;
02031     /*
02032     fsk.RegPktConfig2.bits.PayloadLength = i;
02033                     radio.write_u16(REG_FSK_PACKETCONFIG2, fsk.RegPktConfig2.word);fsk.RegPktConfig2.bits.PayloadLength = i;
02034                     radio.write_u16(REG_FSK_PACKETCONFIG2, fsk.RegPktConfig2.word);
02035                     */
02036     for (i = 0; i < 4; i++) {
02037         radio.tx_buf[i] = 0xaa;
02038     }
02039     
02040     printf("ooktx:");
02041     for (i = 0; i < len; i++) {
02042         radio.tx_buf[i+4] = rand() & 0xff;
02043         printf("%02x ", radio.tx_buf[i+4]);
02044     }
02045     printf("\r\n");
02046     fsk.start_tx(len+4); 
02047     
02048     while (radio.RegOpMode.bits.Mode == RF_OPMODE_TRANSMITTER) {
02049         if (poll_irq_en)
02050             poll_service_radio();
02051         else
02052             service_radio();      
02053     }
02054 }
02055 
02056 void cmd_init(uint8_t args_at)
02057 {
02058     printf("init\r\n");
02059     radio.init();
02060     if (!radio.RegOpMode.bits.LongRangeMode) {
02061         fsk.init();   // put FSK modem to some functioning default
02062     } else {
02063         // lora configuration is more simple
02064     }    
02065 }
02066 
02067 void cmd_per_tx_delay(uint8_t idx)
02068 {
02069     int i;
02070     if (pcbuf[idx] >= '0' && pcbuf[idx] <= '9') {
02071         sscanf(pcbuf+idx, "%d", &i);
02072         per_tx_delay = i / 1000.0;
02073     }
02074     printf("per_tx_delay:%dms\r\n", (int)(per_tx_delay * 1000));      
02075 }
02076 
02077 const uint8_t test_payload_A[7] = {
02078     0x80, 0x02, 0x58, 0xF5, 0xDF, 0xB8, 0x9E
02079 };
02080 
02081 const uint8_t test_payload_B[] = {
02082     0xca, 0xfe, 0xba, 0xbe
02083 };
02084 
02085 const uint8_t test_payload_C[0x1a] = {
02086     0x88, 0x39, 0x1F, 0xC6, 0xD3, 0xEB, 0xA4, 0xAC,
02087     0xFB, 0xB9, 0xBA, 0xB9, 0xBE, 0x13, 0x61, 0x4C,
02088     0x43, 0x83, 0x00, 0x92, 0x84, 0x00, 0x6F, 0x87,
02089     0x7C, 0xB2
02090 };
02091 
02092 void cmd_tx(uint8_t idx)
02093 {
02094     int i;
02095     static uint16_t fsk_tx_length;
02096 
02097     if (radio.RegOpMode.bits.LongRangeMode) {          
02098         if (pcbuf[idx] >= '0' && pcbuf[idx] <= '9') {
02099             sscanf(pcbuf+idx, "%d", &i);
02100             lora.RegPayloadLength = i;
02101             radio.write_reg(REG_LR_PAYLOADLENGTH, lora.RegPayloadLength);
02102         }
02103         
02104         if (pcbuf[idx] == 'A') {
02105         } else if (pcbuf[idx] == 'B') {
02106         } else if (pcbuf[idx] == 'C') {
02107         } else {        
02108             tx_cnt++;
02109             printf("payload:%02x\r\n", tx_cnt);
02110             
02111             for (i = 0; i < lora.RegPayloadLength; i++)
02112                 radio.tx_buf[i] = tx_cnt;
02113         }
02114         
02115         lora.start_tx(lora.RegPayloadLength);
02116     } else {    // FSK:
02117     
02118         /* always variable-length format */
02119         fsk.RegPktConfig1.octet = radio.read_reg(REG_FSK_PACKETCONFIG1);
02120         if (!fsk.RegPktConfig1.bits.PacketFormatVariable) {
02121             printf("fsk fixed->variable\r\n");
02122             fsk.RegPktConfig1.bits.PacketFormatVariable = 1;
02123             radio.write_reg(REG_FSK_PACKETCONFIG1, fsk.RegPktConfig1.octet);
02124         }
02125         
02126         if (pcbuf[idx] >= '0' && pcbuf[idx] <= '9') {
02127             sscanf(pcbuf+idx, "%d", &i);
02128             fsk_tx_length = i;
02129         }
02130         if (ook_test_en) {
02131             ook_test_tx(fsk_tx_length);
02132         } else {
02133             if (radio.RegOpMode.bits.Mode != RF_OPMODE_TRANSMITTER) { // if not already busy transmitting
02134                 if (pcbuf[idx] == 'A') {
02135                     fsk_tx_length = sizeof(test_payload_A);
02136                     memcpy(radio.tx_buf, test_payload_A, fsk_tx_length);
02137                 } else if (pcbuf[idx] == 'B') {
02138                     fsk_tx_length = sizeof(test_payload_B);
02139                     memcpy(radio.tx_buf, test_payload_B, fsk_tx_length);                    
02140                 } else if (pcbuf[idx] == 'C') {
02141                     fsk_tx_length = sizeof(test_payload_C);
02142                     memcpy(radio.tx_buf, test_payload_C, fsk_tx_length);                    
02143                 } else {   
02144                     tx_cnt++;
02145                     printf("payload:%02x\r\n", tx_cnt);
02146                     for (i = 0; i < fsk_tx_length; i++) {
02147                         radio.tx_buf[i] = tx_cnt;
02148                     }
02149                 }
02150                 
02151                 fsk.start_tx(fsk_tx_length);
02152             }
02153         }
02154     } // !LoRa                
02155 
02156 }
02157 
02158 volatile uint16_t long_byte_count, long_byte_count_at_full;
02159 
02160 const uint8_t test_preamble_sync[] = {
02161     0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x33, 0xcb, 0x82
02162 };
02163 
02164 void _ulm_write_fifo(uint8_t len)
02165 {
02166     uint8_t i;
02167     
02168     //dio2 is FifoFull
02169     radio.m_cs = 0;
02170     radio.m_spi.write(REG_FIFO | 0x80); // bit7 is high for writing to radio
02171     
02172     for (i = 0; i < len; ) {
02173         //printf("_%02x\r\n", radio.tx_buf[i]);
02174         radio.m_spi.write(radio.tx_buf[i++]);
02175         long_byte_count++;
02176         if (dio2) {
02177             long_byte_count_at_full = long_byte_count;
02178             while (radio.dio1)
02179                 ;
02180         }
02181     }
02182     radio.m_cs = 1;
02183 }
02184 
02185 int write_buf_to_fifo(const uint8_t* send_buf, uint8_t target_length)
02186 {
02187     /* block until all is written */
02188     uint8_t total_sent = 0;
02189     
02190     //printf("wbtf %u\r\n", target_length);
02191     while (target_length > total_sent) {
02192         uint8_t this_length = target_length - total_sent;
02193         memcpy(radio.tx_buf+total_sent, send_buf+total_sent, this_length);
02194         _ulm_write_fifo(this_length);
02195         total_sent += this_length;
02196     }
02197     return total_sent;
02198 }
02199 
02200 #define TEST_PAYLOAD        test_payload_C
02201 //#define TEST_PAYLOAD        test_payload_A
02202 void cmd_long_tx(uint8_t idx)
02203 {
02204     unsigned int pkt_cnt = 0;
02205     bool first_pkt;
02206     /* transmit multipe packets without any time between packets (back to back) */
02207     
02208     if (pcbuf[idx] >= '0' && pcbuf[idx] <= '9') {
02209         sscanf(pcbuf+idx, "%u", &pkt_cnt);
02210     }
02211     
02212     printf("tx %u pkts\r\n", pkt_cnt);
02213     if (pkt_cnt < 1)
02214         return;
02215         
02216     radio.RegDioMapping2.octet = radio.read_reg(REG_DIOMAPPING2);
02217     radio.RegDioMapping2.bits.Dio5Mapping = 2;  // data output to observation
02218     radio.RegDioMapping2.bits.Dio4Mapping = 3;  // output preamble detect indication
02219     radio.RegDioMapping2.bits.MapPreambleDetect = 1;
02220     radio.write_reg(REG_DIOMAPPING2, radio.RegDioMapping2.octet);
02221         
02222     //unlimited packet length mode
02223     fsk.RegPktConfig1.octet = radio.read_reg(REG_FSK_PACKETCONFIG1);
02224     fsk.RegPktConfig1.bits.PacketFormatVariable = 0;    // fixed length format
02225     radio.write_reg(REG_FSK_PACKETCONFIG1, fsk.RegPktConfig1.octet);
02226     
02227     fsk.RegPktConfig2.word = radio.read_u16(REG_FSK_PACKETCONFIG2);
02228     fsk.RegPktConfig2.bits.PayloadLength = 0;
02229     radio.write_u16(REG_FSK_PACKETCONFIG2, fsk.RegPktConfig2.word);
02230     //DIO3 to FifoEmpty (for end of tx)
02231     radio.RegDioMapping1.octet = radio.read_reg(REG_DIOMAPPING1);
02232     radio.RegDioMapping1.bits.Dio3Mapping = 0;  // FifoEmpty
02233     //DIO2 to FifoFull
02234     radio.RegDioMapping1.bits.Dio2Mapping = 0;  // FIfoFull
02235     //DIO1 to FifoLevel
02236     radio.RegDioMapping1.bits.Dio1Mapping = 0;  // FifoLevel
02237     radio.RegDioMapping1.bits.Dio0Mapping = 0;  // PacketSent
02238     radio.write_reg(REG_DIOMAPPING1, radio.RegDioMapping1.octet); 
02239     //FifoThreshold to approx 1/5th full
02240     fsk.RegFifoThreshold.octet = radio.read_reg(REG_FSK_FIFOTHRESH);  
02241     fsk.RegFifoThreshold.bits.FifoThreshold = sizeof(TEST_PAYLOAD)-1; // allow single packet
02242     // tx start condition to FifoLevel
02243     fsk.RegFifoThreshold.bits.TxStartCondition = 0; // start on FifoLevel
02244     radio.write_reg(REG_FSK_FIFOTHRESH, fsk.RegFifoThreshold.octet);
02245     
02246     long_byte_count = 0;
02247     long_byte_count_at_full = 0xffff;
02248     
02249     radio.set_opmode(RF_OPMODE_TRANSMITTER);
02250     first_pkt = true;   // preamble+sync sent by packet engine only for first packet
02251     for (; pkt_cnt > 0; pkt_cnt--) {
02252         uint8_t len;
02253         if (first_pkt)
02254             first_pkt = false;
02255         else {
02256             if (dio3) {
02257                 printf("fail-empty\r\n");
02258             }
02259             write_buf_to_fifo(test_preamble_sync, sizeof(test_preamble_sync));
02260         }
02261         
02262         len = sizeof(TEST_PAYLOAD); //TEST_PAYLOAD doesnt start with length
02263         write_buf_to_fifo(&len, 1);
02264         write_buf_to_fifo(TEST_PAYLOAD, sizeof(TEST_PAYLOAD));        
02265     } // ..
02266 
02267     rx_start_timer.reset();
02268     rx_start_timer.start();
02269     while (!dio3) {
02270         if (rx_start_timer.read() > 1) {
02271             printf("fifoEmpty fail\r\n");
02272             radio.set_opmode(RF_OPMODE_STANDBY);
02273             return;
02274         }
02275     }
02276 
02277     rx_start_timer.reset();
02278     rx_start_timer.start();
02279     while (!radio.dio0) {
02280         if (rx_start_timer.read() > 3) {
02281             printf("PacketSent fail\r\n");
02282             radio.set_opmode(RF_OPMODE_STANDBY);
02283             return;
02284         }        
02285     }
02286     wait_us(100);
02287     radio.set_opmode(RF_OPMODE_STANDBY);
02288     printf("done ok %u, %u\r\n", long_byte_count, long_byte_count_at_full);
02289 
02290 }
02291 
02292 void cmd_hw_reset(uint8_t idx)
02293 {
02294     printf("hw_reset()\r\n");
02295     radio.hw_reset();
02296     ook_test_en = false;
02297     poll_irq_en = false;
02298 }
02299 
02300 void cmd_read_all_regs(uint8_t idx)
02301 {
02302     uint8_t a, d;
02303     
02304     // read all registers
02305     for (a = 1; a < 0x71; a++) {
02306         d = radio.read_reg(a);
02307         printf("%02x: %02x\r\n", a, d);
02308     }
02309 }
02310 
02311 void cmd_read_current_rssi(uint8_t idx)
02312 {
02313     if (radio.RegOpMode.bits.Mode != RF_OPMODE_RECEIVER) {
02314         radio.set_opmode(RF_OPMODE_RECEIVER);
02315         wait_us(10000);
02316     }
02317     if (radio.RegOpMode.bits.LongRangeMode)
02318         printf("rssi:%ddBm\r\n", lora.get_current_rssi());
02319     else
02320         printf("rssi:-%.1f\r\n", radio.read_reg(REG_FSK_RSSIVALUE) / 2.0);
02321 }
02322 
02323 void cmd_rssi_polling(uint8_t idx)
02324 {
02325     if ((pcbuf[idx] >= '0' && pcbuf[idx] <= '9') || pcbuf[idx] == '-') {
02326         sscanf(pcbuf+idx, "%d", &rssi_polling_thresh);  
02327     }
02328     printf("rssi_polling_thresh:%d\r\n", rssi_polling_thresh);
02329 }
02330 
02331 void cmd_lora_continuous_tx(uint8_t idx)
02332 {
02333     /* TxContinuousMode same for sx1272 and sx1276 */
02334     lora.RegModemConfig2.octet = radio.read_reg(REG_LR_MODEMCONFIG2);
02335     lora.RegModemConfig2.sx1276bits.TxContinuousMode ^= 1;   
02336     radio.write_reg(REG_LR_MODEMCONFIG2, lora.RegModemConfig2.octet);
02337     lora.RegModemConfig2.octet = radio.read_reg(REG_LR_MODEMCONFIG2);
02338     
02339     lora_printTxContinuousMode();
02340     printf("\r\n");
02341 }
02342 
02343 void cmd_fsk_test_case(uint8_t idx)
02344 {
02345     if (pcbuf[idx] < '0' || pcbuf[idx] > '9') {
02346         printf("%" PRIu32 "bps fdev:%" PRIu32 "hz ", fsk.get_bitrate(), fsk.get_tx_fdev_hz());
02347         printf("rxbw:%" PRIu32 "Hz ", fsk.get_rx_bw_hz(REG_FSK_RXBW));
02348         printf("afcbw:%" PRIu32 "Hz preambleLen:%" PRIu16 "\r\n", fsk.get_rx_bw_hz(REG_FSK_AFCBW), radio.read_u16(REG_FSK_PREAMBLEMSB));        
02349     } else {
02350         radio.set_opmode(RF_OPMODE_STANDBY);
02351         per_tx_delay = 0.3;
02352         
02353         if (radio.read_reg(REG_FSK_SYNCVALUE1) == 0x55 && radio.read_reg(REG_FSK_SYNCVALUE2)) {
02354             fsk.RegSyncConfig.octet = radio.read_reg(REG_FSK_SYNCCONFIG);    
02355             fsk.RegSyncConfig.bits.SyncSize = 2;
02356             radio.write_reg(REG_FSK_SYNCCONFIG, fsk.RegSyncConfig.octet);
02357             radio.write_reg(REG_FSK_SYNCVALUE3, 0x90);
02358             radio.write_reg(REG_FSK_SYNCVALUE2, 0x4e);
02359             radio.write_reg(REG_FSK_SYNCVALUE1, 0x63);              
02360         }
02361         
02362         fsk.RegPreambleDetect.octet = radio.read_reg(REG_FSK_PREAMBLEDETECT);
02363         fsk.RegPreambleDetect.bits.PreambleDetectorOn = 1;
02364         radio.write_reg(REG_FSK_PREAMBLEDETECT, fsk.RegPreambleDetect.octet);                 
02365         
02366         fsk.RegRxConfig.octet = radio.read_reg(REG_FSK_RXCONFIG);
02367         fsk.RegRxConfig.bits.AfcAutoOn = 1;
02368         fsk.RegRxConfig.bits.AgcAutoOn = 1;
02369         fsk.RegRxConfig.bits.RxTrigger = 7; // both
02370         radio.write_reg(REG_FSK_RXCONFIG, fsk.RegRxConfig.octet);    
02371         
02372         fsk.RegPreambleDetect.bits.PreambleDetectorOn = 1;
02373         fsk.RegPreambleDetect.bits.PreambleDetectorSize = 1;
02374         fsk.RegPreambleDetect.bits.PreambleDetectorTol = 10;
02375         radio.write_reg(REG_FSK_PREAMBLEDETECT, fsk.RegPreambleDetect.octet);            
02376         
02377         switch (pcbuf[idx]) {
02378             case '0':
02379                 fsk.set_bitrate(4800);
02380                 fsk.set_tx_fdev_hz(5005);
02381                 fsk.set_rx_dcc_bw_hz(10417, 0);  // rxbw
02382                 fsk.set_rx_dcc_bw_hz(50000, 1);  // afcbw
02383                 radio.write_u16(REG_FSK_PREAMBLEMSB, 8);                    
02384                 break;
02385             case '1':
02386                 fsk.set_bitrate(50000);
02387                 fsk.set_tx_fdev_hz(25000);
02388                 fsk.set_rx_dcc_bw_hz(62500, 0);  // rxbw
02389                 fsk.set_rx_dcc_bw_hz(100000, 1);  // afcbw
02390                 radio.write_u16(REG_FSK_PREAMBLEMSB, 9);                    
02391                 break;           
02392             case '2':
02393                 fsk.set_bitrate(38400);
02394                 fsk.set_tx_fdev_hz(20020);
02395                 fsk.set_rx_dcc_bw_hz(50000, 0);  // rxbw
02396                 fsk.set_rx_dcc_bw_hz(100000, 1);  // afcbw
02397                 radio.write_u16(REG_FSK_PREAMBLEMSB, 8);                        
02398                 break;
02399             case '3':
02400                 fsk.set_bitrate(1201);
02401                 fsk.set_tx_fdev_hz(20020);
02402                 fsk.set_rx_dcc_bw_hz(25000, 0);  // rxbw
02403                 fsk.set_rx_dcc_bw_hz(50000, 1);  // afcbw
02404                 radio.write_u16(REG_FSK_PREAMBLEMSB, 8);                 
02405                 break;    
02406             case '4':
02407                 fsk.set_bitrate(1201);
02408                 fsk.set_tx_fdev_hz(4028);
02409                 fsk.set_rx_dcc_bw_hz(7813, 0);  // rxbw
02410                 fsk.set_rx_dcc_bw_hz(25000, 1);  // afcbw
02411                 radio.write_u16(REG_FSK_PREAMBLEMSB, 8);
02412                 break;
02413             case '5':
02414                 fsk.set_bitrate(1201);
02415                 fsk.set_tx_fdev_hz(4028);
02416                 fsk.set_rx_dcc_bw_hz(5208, 0);  // rxbw
02417                 fsk.set_rx_dcc_bw_hz(10417, 1);  // afcbw
02418                 radio.write_u16(REG_FSK_PREAMBLEMSB, 8);                    
02419                 break;   
02420             case '6':
02421                 fsk.set_bitrate(65536);
02422                 fsk.set_tx_fdev_hz(16384);
02423                 fsk.set_rx_dcc_bw_hz(62500, 0);  // rxbw
02424                 fsk.set_rx_dcc_bw_hz(100000, 1);  // afcbw
02425                 
02426                 fsk.RegPktConfig1.octet = radio.read_reg(REG_FSK_PACKETCONFIG1);
02427                 fsk.RegPktConfig1.bits.CrcOn = 0;
02428                 radio.write_reg(REG_FSK_PACKETCONFIG1, fsk.RegPktConfig1.octet);
02429         
02430                 radio.write_u16(REG_FSK_PREAMBLEMSB, 5);             
02431                 fsk.RegSyncConfig.octet = radio.read_reg(REG_FSK_SYNCCONFIG);    
02432                 fsk.RegSyncConfig.bits.SyncSize = 2;
02433                 fsk.RegSyncConfig.bits.SyncOn = 1;
02434                 radio.write_reg(REG_FSK_SYNCCONFIG, fsk.RegSyncConfig.octet);
02435                 radio.write_reg(REG_FSK_SYNCVALUE1, 0x33);
02436                 radio.write_reg(REG_FSK_SYNCVALUE2, 0xcb);
02437                 radio.write_reg(REG_FSK_SYNCVALUE3, 0x82);    
02438                 
02439                 radio.RegOpMode.octet = radio.read_reg(REG_OPMODE);
02440                 radio.RegOpMode.bits.ModulationType = 0;    // 0 = FSK 
02441                 radio.RegOpMode.bits.ModulationShaping = 2; // 2=BT0.5
02442                 radio.write_reg(REG_OPMODE, radio.RegOpMode.octet);
02443                 
02444                 fsk.RegAfcFei.octet = radio.read_reg(REG_FSK_AFCFEI);
02445                 fsk.RegAfcFei.bits.AfcAutoClearOn = 0;
02446                 radio.write_reg(REG_FSK_AFCFEI, fsk.RegAfcFei.octet);
02447                 
02448                 fsk.RegRxConfig.bits.RxTrigger = 6; // preamble
02449                 radio.write_reg(REG_FSK_RXCONFIG, fsk.RegRxConfig.octet);
02450                 radio.RegDioMapping2.bits.Dio4Mapping = 3;
02451                 radio.RegDioMapping2.bits.MapPreambleDetect = 1;    // dio4 to preambleDetect in RX
02452                 radio.write_reg(REG_DIOMAPPING2, radio.RegDioMapping2.octet);     
02453                 radio.RegDioMapping1.bits.Dio2Mapping = 3;  // dio2 to SyncAddress in RX
02454                 radio.RegDioMapping1.bits.Dio1Mapping = 1;  // to FifoEmpty
02455                 radio.write_reg(REG_DIOMAPPING1, radio.RegDioMapping1.octet);                                   
02456                 break;                                                                                           
02457         } // ...switch (pcbuf[idx])
02458         printf("%" PRIu32 "bps fdev:%" PRIu32 "hz ", fsk.get_bitrate(), fsk.get_tx_fdev_hz());
02459         printf("rxbw:%" PRIu32 "Hz ", fsk.get_rx_bw_hz(REG_FSK_RXBW));
02460         printf("afcbw:%" PRIu32 "Hz preambleLen:%" PRIu16 "\r\n", fsk.get_rx_bw_hz(REG_FSK_AFCBW), radio.read_u16(REG_FSK_PREAMBLEMSB));  
02461         
02462         /* time between preamble occurring and syncAddress occuring 
02463          * = bitrate in microseconds * 8 * (preamble bytes + sync bytes)
02464          */
02465         preamble_to_sync_us = (1.0 / fsk.get_bitrate())*1e6 * 8 * (radio.read_u16(REG_FSK_PREAMBLEMSB)+1 + fsk.RegSyncConfig.bits.SyncSize+2);
02466         //printf("bitrate:%d, %f\r\n", fsk.get_bitrate(), 1.0 / fsk.get_bitrate()*1e6);
02467         printf("preamble_to_sync_us:%d\r\n", preamble_to_sync_us);
02468     }
02469 }
02470 
02471 void cmd_restart_rx(uint8_t idx)
02472 {
02473     fsk.RegRxConfig.octet = radio.read_reg(REG_FSK_RXCONFIG);
02474     fsk.RegRxConfig.bits.RestartRxWithoutPllLock = 1;
02475     radio.write_reg(REG_FSK_RXCONFIG, fsk.RegRxConfig.octet);
02476     rx_start_timer.reset();
02477     secs_rx_start = time(NULL);
02478     fsk.RegRxConfig.bits.RestartRxWithoutPllLock = 0;
02479     printf("RestartRxWithoutPllLock\r\n");
02480 }
02481 
02482 void cmd_toggle_modem(uint8_t idx)
02483 {
02484     ook_test_en = false;
02485     poll_irq_en = false;
02486     if (radio.RegOpMode.bits.LongRangeMode)
02487         fsk.enable(false);
02488     else
02489         lora.enable();
02490 
02491     radio.RegOpMode.octet = radio.read_reg(REG_OPMODE);
02492     if (radio.RegOpMode.bits.LongRangeMode)
02493         printf("LoRa\r\n");
02494     else
02495         printf("FSK\r\n");
02496 }
02497 
02498 void cmd_empty_fifo(uint8_t idx)
02499 {
02500     RegIrqFlags2_t RegIrqFlags2;
02501     RegIrqFlags2.octet = radio.read_reg(REG_FSK_IRQFLAGS2);
02502     while (!RegIrqFlags2.bits.FifoEmpty) {
02503         if (pc.readable())
02504             break;
02505         printf("%02x\r\n", radio.read_reg(REG_FIFO));
02506         RegIrqFlags2.octet = radio.read_reg(REG_FSK_IRQFLAGS2);
02507     }
02508 }
02509 
02510 void cmd_print_status(uint8_t idx)
02511 {
02512     if (radio.type == SX1276) {
02513 #if defined(TARGET_MTS_MDOT_F411RE)
02514         printf("\r\nSX1276 ");
02515 #else
02516         if (shield_type == SHIELD_TYPE_LAS)
02517             printf("\r\nSX1276LAS ");
02518         if (shield_type == SHIELD_TYPE_MAS)
02519             printf("\r\nSX1276MAS ");
02520 #endif /* !TARGET_MTS_MDOT_F411RE */                       
02521     } else if (radio.type == SX1272)
02522         printf("\r\nSX1272 ");
02523         
02524     radio.RegOpMode.octet = radio.read_reg(REG_OPMODE);
02525     if (radio.RegOpMode.bits.LongRangeMode)
02526         lora_print_status();
02527     else
02528         fsk_print_status();
02529     common_print_status();
02530 }
02531                 
02532 void cmd_hop_period(uint8_t idx)
02533 {
02534     int i;
02535     if (pcbuf[idx] >= '0' && pcbuf[idx] <= '9') {
02536         sscanf(pcbuf+idx, "%d", &i);
02537         lora.RegHopPeriod = i;
02538         radio.write_reg(REG_LR_HOPPERIOD, lora.RegHopPeriod);
02539         if (radio.RegDioMapping1.bits.Dio1Mapping != 1) {
02540             radio.RegDioMapping1.bits.Dio1Mapping = 1;
02541             radio.write_reg(REG_DIOMAPPING1, radio.RegDioMapping1.octet);
02542         }
02543     }
02544     lora.RegHopPeriod = radio.read_reg(REG_LR_HOPPERIOD);
02545     printf("HopPeriod:0x%02x\r\n", lora.RegHopPeriod);
02546 }       
02547 
02548 void cmd_lora_ppg(uint8_t idx)
02549 {
02550     int i;
02551     if (pcbuf[idx] != 0) {
02552         sscanf(pcbuf+idx, "%x", &i);
02553         radio.write_reg(REG_LR_SYNC_BYTE, i);
02554     }
02555     printf("lora sync:0x%02x\r\n", radio.read_reg(REG_LR_SYNC_BYTE));
02556 }
02557 
02558 void cmd_rssi_offset(uint8_t idx)
02559 {
02560     int i;
02561     if (pcbuf[idx] >= '0' && pcbuf[idx] <= '9') {
02562         sscanf(pcbuf+idx, "%d", &i);
02563         fsk.RegRssiConfig.bits.RssiOffset = i;
02564         radio.write_reg(REG_FSK_RSSICONFIG, fsk.RegRssiConfig.octet);
02565     }            
02566     fsk.RegRssiConfig.octet = radio.read_reg(REG_FSK_RSSICONFIG);          
02567     printf("RssiOffset:%d\r\n", fsk.RegRssiConfig.bits.RssiOffset); 
02568 } 
02569 
02570 void cmd_rssi_smoothing(uint8_t idx)
02571 {
02572     int i;
02573     if (pcbuf[idx] >= '0' && pcbuf[idx] <= '9') {
02574         sscanf(pcbuf+idx, "%d", &i);
02575         fsk.RegRssiConfig.bits.RssiSmoothing = i;
02576         radio.write_reg(REG_FSK_RSSICONFIG, fsk.RegRssiConfig.octet);
02577     }                        
02578     fsk.RegRssiConfig.octet = radio.read_reg(REG_FSK_RSSICONFIG);
02579     printf("RssiSmoothing:%d\r\n", fsk.RegRssiConfig.bits.RssiSmoothing); 
02580 }
02581 
02582 void cmd_rssi_threshold(uint8_t idx)
02583 {
02584     if ((pcbuf[idx] >= '0' && pcbuf[idx] <= '9') || pcbuf[idx] == '-') {
02585         float dbm;
02586         sscanf(pcbuf+idx, "%f", &dbm);
02587         dbm *= (float)2.0;
02588         fsk.RegRssiThresh = (int)fabs(dbm);
02589         radio.write_reg(REG_FSK_RSSITHRESH, fsk.RegRssiThresh);
02590     }                                    
02591     fsk.RegRssiThresh = radio.read_reg(REG_FSK_RSSITHRESH);
02592     printf("rssiThreshold:-%.1f\r\n", fsk.RegRssiThresh / 2.0); 
02593 }
02594 
02595 void cmd_rx_trigger(uint8_t idx)
02596 {
02597     printf("RxTrigger:");
02598     switch (fsk.RegRxConfig.bits.RxTrigger) {
02599         case 0: fsk.RegRxConfig.bits.RxTrigger = 1;
02600             printf("rssi\r\n");
02601             break;
02602         case 1: fsk.RegRxConfig.bits.RxTrigger = 6;
02603             printf("preamble\r\n");
02604             break;
02605         case 6: fsk.RegRxConfig.bits.RxTrigger = 7;
02606             printf("both\r\n");
02607             break;
02608         case 7: fsk.RegRxConfig.bits.RxTrigger = 0;
02609             printf("none\r\n");
02610             break;
02611         default: fsk.RegRxConfig.bits.RxTrigger = 0;
02612             printf("none\r\n");
02613             break;
02614         }
02615     radio.write_reg(REG_FSK_RXCONFIG, fsk.RegRxConfig.octet);
02616 }
02617 
02618 void cmd_cadper(uint8_t idx)
02619 {
02620     set_per_en(true);
02621 
02622     PacketNormalCnt = 0;
02623     PacketRxSequencePrev = 0;   // transmitter side PacketTxCnt is 1 at first TX
02624     PacketPerKoCnt = 0;
02625     PacketPerOkCnt = 0;
02626             
02627     cadper_enable = true;
02628 
02629     lora.RegIrqFlags.octet = radio.read_reg(REG_LR_IRQFLAGS);
02630     /* clear any stale flag */
02631     radio.write_reg(REG_LR_IRQFLAGS, lora.RegIrqFlags.octet);
02632     
02633     /* start first CAD */
02634     radio.set_opmode(RF_OPMODE_CAD);
02635     num_cads = 0;    
02636 }
02637 
02638 #if 0
02639 void cmd_cadrx(uint8_t idx)
02640 {
02641     int n_tries = 1;
02642     lora.RegIrqFlags.octet = radio.read_reg(REG_LR_IRQFLAGS);
02643     /* clear any stale flag */
02644     radio.write_reg(REG_LR_IRQFLAGS, lora.RegIrqFlags.octet);
02645     
02646     if (pcbuf[idx] >= '0' && pcbuf[idx] <= '9') {
02647         sscanf(pcbuf+idx, "%d", &n_tries);
02648     }
02649     
02650     while (n_tries > 0) {
02651         radio.set_opmode(RF_OPMODE_CAD);
02652         
02653         do {
02654             lora.RegIrqFlags.octet = radio.read_reg(REG_LR_IRQFLAGS);
02655         } while (!lora.RegIrqFlags.bits.CadDetected && !lora.RegIrqFlags.bits.CadDone);
02656         if (lora.RegIrqFlags.bits.CadDetected) {
02657             lora.start_rx(RF_OPMODE_RECEIVER_SINGLE);            
02658             n_tries = 1;    // end
02659             printf("CadDetected ");
02660         }
02661         if (lora.RegIrqFlags.bits.CadDone) {
02662             printf("CadDone ");
02663         }
02664         
02665         radio.write_reg(REG_LR_IRQFLAGS, lora.RegIrqFlags.octet);
02666         printf("\r\n");
02667         n_tries--;
02668     }    
02669 }
02670 #endif /* #if 0 */
02671 
02672 void cmd_cad(uint8_t idx)
02673 {
02674     int n_tries = 1;
02675     lora.RegIrqFlags.octet = radio.read_reg(REG_LR_IRQFLAGS);
02676     /* clear any stale flag */
02677     radio.write_reg(REG_LR_IRQFLAGS, lora.RegIrqFlags.octet);
02678     
02679     if (pcbuf[idx] >= '0' && pcbuf[idx] <= '9') {
02680         sscanf(pcbuf+idx, "%d", &n_tries);
02681     }
02682     
02683     while (n_tries > 0) {
02684         radio.set_opmode(RF_OPMODE_CAD);
02685         
02686         do {
02687             lora.RegIrqFlags.octet = radio.read_reg(REG_LR_IRQFLAGS);
02688         } while (!lora.RegIrqFlags.bits.CadDetected && !lora.RegIrqFlags.bits.CadDone);
02689         if (lora.RegIrqFlags.bits.CadDetected) {
02690             n_tries = 1;    // end
02691             printf("CadDetected ");
02692         }
02693         if (lora.RegIrqFlags.bits.CadDone) {
02694             if (n_tries == 1)  // print on last try
02695                 printf("CadDone ");
02696         }
02697         
02698         radio.write_reg(REG_LR_IRQFLAGS, lora.RegIrqFlags.octet);
02699         n_tries--;
02700     }
02701     printf("\r\n");
02702 }
02703 
02704 void cmd_rx_timeout(uint8_t idx)
02705 {
02706     int symb_timeout;
02707     uint16_t reg_u16 = radio.read_u16(REG_LR_MODEMCONFIG2);
02708     
02709     if (pcbuf[idx] >= '0' && pcbuf[idx] <= '9') {
02710         sscanf(pcbuf+idx, "%d", &symb_timeout);
02711         reg_u16 &= 0xfc00;
02712         reg_u16 |= symb_timeout;
02713         radio.write_u16(REG_LR_MODEMCONFIG2, reg_u16);
02714     }
02715     reg_u16 = radio.read_u16(REG_LR_MODEMCONFIG2);
02716     printf("SymbTimeout:%d\r\n", reg_u16 & 0x3ff);
02717 }
02718 
02719 void cmd_rx_single(uint8_t idx)
02720 {
02721     lora.start_rx(RF_OPMODE_RECEIVER_SINGLE);
02722 }
02723 
02724 void preamble_without_sync()
02725 {
02726     printf("preamble_without_sync Afc:%dHz\r\n", (int)(FREQ_STEP_HZ * radio.read_s16(REG_FSK_AFCMSB))); 
02727     fsk.RegRxConfig.bits.RestartRxWithoutPllLock = 1;
02728     radio.write_reg(REG_FSK_RXCONFIG, fsk.RegRxConfig.octet); 
02729 }
02730 
02731 Timeout pd_timeout;
02732 Timeout sync_timeout;
02733 void preamble_detect_isr()
02734 {
02735     // only used between frames, on background noise
02736     pd_timeout.attach_us(&preamble_without_sync, 1500); // 122us per byte
02737 }
02738 
02739 void cmd_rx(uint8_t idx)
02740 {    
02741     set_per_en(false);
02742   
02743     if (radio.RegOpMode.bits.LongRangeMode)
02744         lora.start_rx(RF_OPMODE_RECEIVER);
02745     else {
02746         if (poll_irq_en) {
02747             fsk_RegIrqFlags2_prev.octet = 0;
02748             fsk_RegIrqFlags1_prev.octet = 0; 
02749         }
02750         
02751         rx_start_timer.start();
02752         secs_rx_start = time(NULL);
02753         fsk.start_rx();
02754         radio.RegDioMapping1.bits.Dio2Mapping = 3;  // dio2 to syncadrs
02755         radio.write_reg(REG_DIOMAPPING1, radio.RegDioMapping1.octet); 
02756         if (radio.HF) {
02757             fsk.RegRssiConfig.octet = radio.read_reg(REG_FSK_RSSICONFIG);
02758             fsk.RegRssiConfig.bits.RssiOffset = FSK_RSSI_OFFSET;
02759             fsk.RegRssiConfig.bits.RssiSmoothing = FSK_RSSI_SMOOTHING;
02760             radio.write_reg(REG_FSK_RSSICONFIG, fsk.RegRssiConfig.octet);
02761         }               
02762         
02763         // sync shadow regsiters
02764         radio.RegDioMapping1.octet = radio.read_reg(REG_DIOMAPPING1);
02765         radio.RegDioMapping2.octet = radio.read_reg(REG_DIOMAPPING2);
02766     }
02767 }
02768 
02769 void cmd_radio_reg_read(uint8_t idx)
02770 {
02771     int i;
02772     sscanf(pcbuf+idx, "%x", &i);
02773     printf("%02x: %02x\r\n", i, radio.read_reg(i));
02774 }
02775 
02776 void cmd_radio_reg_write(uint8_t idx)
02777 {
02778     int i, n;
02779     sscanf(pcbuf+idx, "%x %x", &i, &n);
02780     radio.write_reg(i, n);
02781     printf("%02x: %02x\r\n", i, radio.read_reg(i));
02782 }
02783 
02784 void cmd_mod_shaping(uint8_t idx)
02785 {
02786     uint8_t s = fsk.get_modulation_shaping();
02787     
02788     if (s == 3)
02789         s = 0;
02790     else
02791         s++;
02792         
02793     fsk.set_modulation_shaping(s);
02794     
02795     if (radio.RegOpMode.bits.ModulationType == 0) {
02796         printf("FSK ");
02797         switch (s) {
02798             case 0: printf("off"); break;
02799             case 1: printf("BT1.0 "); break;
02800             case 2: printf("BT0.5 "); break;
02801             case 3: printf("BT0.3 "); break;
02802         }
02803     } else if (radio.RegOpMode.bits.ModulationType == 1) {
02804         printf("OOK ");
02805         switch (s) {
02806             case 0: printf("off"); break;
02807             case 1: printf("Fcutoff=bitrate"); break;
02808             case 2: printf("Fcutoff=2*bitrate"); break;
02809             case 3: printf("?"); break;
02810         }        
02811     }    
02812     
02813     printf("\r\n");      
02814 }
02815 
02816 void cmd_MapPreambleDetect(uint8_t idx)
02817 {
02818     radio.RegDioMapping2.bits.MapPreambleDetect ^= 1;
02819     radio.write_reg(REG_DIOMAPPING2, radio.RegDioMapping2.octet);
02820     printf("MapPreambleDetect:");
02821     if (radio.RegDioMapping2.bits.MapPreambleDetect)
02822         printf("preamble\r\n");
02823     else
02824         printf("rssi\r\n");
02825 }
02826 
02827 void cmd_bgr(uint8_t idx)
02828 {
02829     RegPdsTrim1_t pds_trim;
02830     uint8_t adr;
02831     if (radio.type == SX1276)
02832         adr = REG_PDSTRIM1_SX1276;
02833     else
02834         adr = REG_PDSTRIM1_SX1272;
02835        
02836     pds_trim.octet = radio.read_reg(adr);         
02837     if (pcbuf[idx] >= '0' && pcbuf[idx] <= '9') {
02838         int i;
02839         sscanf(&pcbuf[idx], "%d", &i);
02840         pds_trim.bits.prog_txdac = i;
02841     }
02842     radio.write_reg(adr, pds_trim.octet);
02843     printf("prog_txdac:%.1fuA\r\n", 2.5 + (pds_trim.bits.prog_txdac * 0.625));
02844     /* increase OCP threshold to allow more power */
02845     radio.RegOcp.octet = radio.read_reg(REG_OCP);
02846     if (radio.RegOcp.bits.OcpTrim < 16) {
02847         radio.RegOcp.bits.OcpTrim = 16;
02848         radio.write_reg(REG_OCP, radio.RegOcp.octet);
02849     }    
02850 }   
02851 
02852 void cmd_ook(uint8_t idx)
02853 {
02854     fsk.set_bitrate(32768);
02855     radio.write_u16(REG_FSK_PREAMBLEMSB, 0);    // zero preamble length
02856     radio.RegOpMode.bits.ModulationType = 1; // to ook mode
02857     radio.write_reg(REG_OPMODE, radio.RegOpMode.octet);
02858     fsk.RegSyncConfig.bits.SyncOn = 0;
02859     radio.write_reg(REG_FSK_SYNCCONFIG, fsk.RegSyncConfig.octet);
02860     ook_test_en = true;
02861     printf("OOK\r\n");
02862 }
02863 
02864 void cmd_ocp(uint8_t idx)
02865 {
02866     int i;
02867     if (pcbuf[idx] >= '0' && pcbuf[idx] <= '9') {
02868         sscanf(pcbuf+idx, "%d", &i);
02869         if (i < 130)
02870             radio.RegOcp.bits.OcpTrim = (i - 45) / 5;
02871         else
02872             radio.RegOcp.bits.OcpTrim = (i + 30) / 10;
02873         radio.write_reg(REG_OCP, radio.RegOcp.octet);
02874     }            
02875     radio.RegOcp.octet = radio.read_reg(REG_OCP);
02876     if (radio.RegOcp.bits.OcpTrim < 16)
02877         i = 45 + (5 * radio.RegOcp.bits.OcpTrim);
02878     else if (radio.RegOcp.bits.OcpTrim < 28)
02879         i = (10 * radio.RegOcp.bits.OcpTrim) - 30;
02880     else
02881         i = 240;
02882     printf("Ocp: %dmA\r\n", i); 
02883 }
02884 
02885 void cmd_op(uint8_t idx)
02886 {
02887     int i, dbm;
02888     RegPdsTrim1_t pds_trim;
02889     uint8_t adr;
02890     if (radio.type == SX1276)
02891         adr = REG_PDSTRIM1_SX1276;
02892     else
02893         adr = REG_PDSTRIM1_SX1272;
02894        
02895     pds_trim.octet = radio.read_reg(adr);   
02896                 
02897     if (pcbuf[idx] >= '0' && (pcbuf[idx] <= '9' || pcbuf[idx] == '-')) {
02898         sscanf(pcbuf+idx, "%d", &i);
02899         if (radio.RegPaConfig.bits.PaSelect) {
02900             /* PABOOST used: +2dbm to +17, or +20 */
02901             if (i == 20) {
02902                 printf("+20dBm PADAC bias\r\n");
02903                 i -= 3;
02904                 pds_trim.bits.prog_txdac = 7;
02905                 radio.write_reg(adr, pds_trim.octet);
02906             }
02907             if (i > 1)
02908                     radio.RegPaConfig.bits.OutputPower = i - 2;
02909         } else {
02910             /* RFO used: -1 to +14dbm */
02911             if (i < 15)
02912                 radio.RegPaConfig.bits.OutputPower = i + 1;
02913         }
02914         radio.write_reg(REG_PACONFIG, radio.RegPaConfig.octet);
02915     }
02916     radio.RegPaConfig.octet = radio.read_reg(REG_PACONFIG);
02917     if (radio.RegPaConfig.bits.PaSelect) {
02918         printf("PA_BOOST ");
02919         dbm = radio.RegPaConfig.bits.OutputPower + pds_trim.bits.prog_txdac - 2;
02920     } else {
02921         printf("RFO ");
02922         dbm = radio.RegPaConfig.bits.OutputPower - 1;
02923     }
02924     printf("OutputPower:%ddBm\r\n", dbm);
02925 }
02926 
02927 
02928 
02929 void cmd_fsk_agcauto(uint8_t idx)
02930 {
02931     fsk.RegRxConfig.octet = radio.read_reg(REG_FSK_RXCONFIG);
02932     fsk.RegRxConfig.bits.AgcAutoOn ^= 1;
02933     printf("AgcAuto:");
02934     if (fsk.RegRxConfig.bits.AgcAutoOn)
02935         printf("On\r\n");
02936     else
02937         printf("OFF\r\n");          
02938     radio.write_reg(REG_FSK_RXCONFIG, fsk.RegRxConfig.octet); 
02939 }
02940 
02941 void cmd_fsk_afcauto(uint8_t idx)
02942 {
02943     fsk.RegRxConfig.octet = radio.read_reg(REG_FSK_RXCONFIG);            
02944     fsk.RegRxConfig.bits.AfcAutoOn ^= 1;
02945     radio.write_reg(REG_FSK_RXCONFIG, fsk.RegRxConfig.octet);
02946     printf("AfcAuto:");
02947     if (fsk.RegRxConfig.bits.AfcAutoOn)
02948         printf("On\r\n");
02949     else
02950         printf("OFF\r\n");
02951 }
02952 
02953 void cmd_crc32(uint8_t idx)
02954 {
02955     crc32_en ^= true;
02956     printf("crc32_en:%u\r\n", crc32_en);
02957 }
02958 
02959 void cmd_crcOn(uint8_t idx)
02960 {
02961     if (radio.RegOpMode.bits.LongRangeMode) {
02962         lora.setRxPayloadCrcOn(!lora.getRxPayloadCrcOn());
02963         lora_printRxPayloadCrcOn();
02964     } else {
02965         printf("CrcOn:");
02966         fsk.RegPktConfig1.bits.CrcOn ^= 1;
02967         radio.write_reg(REG_FSK_PACKETCONFIG1, fsk.RegPktConfig1.octet);
02968         if (fsk.RegPktConfig1.bits.CrcOn)
02969             printf("On\r\n");
02970         else
02971             printf("Off\r\n");
02972         if (fsk.RegPktConfig2.bits.DataModePacket && radio.RegOpMode.bits.Mode == RF_OPMODE_RECEIVER) {
02973             fsk.config_dio0_for_pktmode_rx();
02974         }
02975     }
02976     printf("\r\n");  
02977 } 
02978 
02979 #ifdef LORA_TX_TEST
02980 void cmd_lora_fixed_payload_symbol(uint8_t idx) // fixed payload, symbol test
02981 {
02982     int n, i;
02983     
02984     symbol_num = pcbuf[idx] - '0';
02985     sscanf(pcbuf+idx+2, "%d", &i);
02986     n = i >> 2; // num nibbles
02987     printf("%d nibbles: ", n);
02988     lora.RegPayloadLength = byte_pad_length;
02989     while (n > 0) {
02990         lora.RegPayloadLength++;
02991         n -= 2; // one byte = two nibbles
02992     }
02993     printf("%d bytes\r\n", lora.RegPayloadLength);
02994     symbol_sweep_nbits = i >> 2;
02995     symbol_sweep_bit_counter = 0;
02996     symbol_sweep_bit_counter_stop = 1 << symbol_sweep_nbits;    // one bit per nibble used in symbol (2bits per byte)
02997     printf("sweep symbol %d, length bytes:%d nbits:%d stop:0x%x\r\n", symbol_num, lora.RegPayloadLength, symbol_sweep_nbits, symbol_sweep_bit_counter_stop);
02998     txticker_state = TXTICKER_STATE_SYMBOL_SWEEP;
02999     radio.write_reg(REG_LR_PAYLOADLENGTH, lora.RegPayloadLength);
03000     tx_ticker.attach(&fp_cb, tx_ticker_rate);
03001 }
03002 
03003 void cmd_fixed_payload_offset(uint8_t idx)
03004 {
03005     int i;
03006     if (pcbuf[idx] >='0' && pcbuf[idx] <= '9') {
03007         sscanf(pcbuf+idx, "%d", &i);
03008         byte_pad_length = i;
03009     }
03010     printf("byte_pad_length:%d\r\n", byte_pad_length);
03011 }
03012 
03013 void cmd_lora_fixed_payload(uint8_t idx)
03014 {
03015     int n, a, i, d = 0;
03016     for (i = idx; i < pcbuf_len; ) {
03017         //printf("scan:\"%s\"\r\n", pcbuf+i);
03018         sscanf(pcbuf+i, "%x", &n);
03019         //printf("n:%x\r\n", n);
03020         radio.tx_buf[d] = n;
03021         printf("%02x ", n);
03022         while (pcbuf[i] == ' ')
03023             i++;
03024         //printf("%d pcbuf[i]:%x\r\n", i, pcbuf[i]);
03025         for (a = i; pcbuf[a] != ' '; a++)
03026             if (a >= pcbuf_len)
03027                 break;
03028         i = a;
03029         while (pcbuf[i] == ' ') {
03030             i++;                 
03031             if (i >= pcbuf_len)
03032                 break;
03033         }   
03034         d++;
03035     }
03036     lora.RegPayloadLength = d;
03037     printf("\r\nlora.RegPayloadLength:%d\r\n", lora.RegPayloadLength);
03038     radio.write_reg(REG_LR_PAYLOADLENGTH, lora.RegPayloadLength);
03039     lora.start_tx(lora.RegPayloadLength);
03040 }
03041 
03042 void cmd_lora_toggle_crcOn(uint8_t idx)
03043 {
03044     /* test lora crc on/off */
03045     lora.RegPayloadLength = 1;
03046     radio.write_reg(REG_LR_PAYLOADLENGTH, lora.RegPayloadLength);           
03047     txticker_state = TXTICKER_STATE_TOG_CRC_ON;
03048     tx_ticker.attach(&fp_cb, tx_ticker_rate);
03049 }
03050 
03051 void lora_cycle_payload_length(uint8_t idx)
03052 {
03053     int i;
03054     if (pcbuf[idx] >= '0' && pcbuf[idx] <= '9') {
03055         sscanf(pcbuf+idx, "%d", &i);
03056         payload_length_stop = i;
03057     }
03058     txticker_state = TXTICKER_STATE_CYCLE_PAYLOAD_LENGTH;
03059     tx_ticker.attach(&fp_cb, tx_ticker_rate);
03060 }
03061 
03062 void cmd_lora_data_ramp(uint8_t idx)
03063 {
03064     // lora payload data ramping
03065     lora.RegPayloadLength = pcbuf[idx] - '0';
03066     radio.write_reg(REG_LR_PAYLOADLENGTH, lora.RegPayloadLength);           
03067     txticker_state = TXTICKER_STATE_RAMP_PAYLOAD_DATA_START;
03068     tx_ticker.attach(&fp_cb, tx_ticker_rate);
03069 }
03070 
03071 void cmd_lora_sync_lo_nibble(uint8_t idx)
03072 {
03073     lora_sync_byte = 0x00;
03074     on_txdone_state = ON_TXDONE_STATE_SYNC_LO_NIBBLE;
03075     on_txdone_delay = 0.100;
03076     txdone_timeout_cb();
03077     //sync_sweep_timeout.attach(&txdone_timeout_cb, sync_sweep_delay);
03078 }
03079 
03080 void cmd_lora_toggle_header_mode(uint8_t idx)
03081 {
03082     lora.RegPayloadLength = 1;
03083     radio.write_reg(REG_LR_PAYLOADLENGTH, lora.RegPayloadLength);           
03084     txticker_state = TXTICKER_STATE_TOG_HEADER_MODE;
03085     tx_ticker.attach(&fp_cb, tx_ticker_rate);
03086 }
03087 
03088 void cmd_lora_sync_sweep(uint8_t idx)
03089 {
03090     lora.RegPayloadLength = 1;
03091     radio.write_reg(REG_LR_PAYLOADLENGTH, lora.RegPayloadLength);
03092     txticker_sync_byte = 0x12;
03093     if (pcbuf[idx] == '1')
03094         txticker_state = TXTICKER_STATE_CYCLE_SYNC_1;
03095     else if (pcbuf[idx] == '2')
03096         txticker_state = TXTICKER_STATE_CYCLE_SYNC_2;
03097     tx_ticker.attach(&fp_cb, tx_ticker_rate);
03098 }
03099 
03100 void cmd_lora_all_payload_lengths(uint8_t idx)
03101 {
03102     on_txdone_repeat_cnt = 0;
03103     on_txdone_state = ON_TXDONE_STATE_PAYLOAD_LENGTH;
03104     on_txdone_delay = 0.200;
03105     txdone_timeout_cb();
03106     lora.RegPayloadLength = 0;
03107     radio.write_reg(REG_LR_PAYLOADLENGTH, lora.RegPayloadLength);
03108 }
03109 
03110 void cmd_lora_toggle_all_bits(uint8_t idx)
03111 {
03112     lora.RegPayloadLength = (pcbuf[idx] - '0') + byte_pad_length;
03113     radio.write_reg(REG_LR_PAYLOADLENGTH, lora.RegPayloadLength); 
03114     txticker_state = TXTICKER_STATE_TOGGLE_ALL_BITS_START;
03115     printf("tab byte length:%d\r\n", lora.RegPayloadLength);
03116 
03117     if (lora.RegPayloadLength > 0)
03118         tx_ticker.attach(&fp_cb, tx_ticker_rate);
03119 }
03120 
03121 void cmd_lora_cycle_codingrates(uint8_t idx)
03122 {
03123     lora.RegPayloadLength = 1;
03124     radio.write_reg(REG_LR_PAYLOADLENGTH, lora.RegPayloadLength);     
03125     txticker_state = TXTICKER_STATE_CYCLE_CODING_RATE;
03126     tx_ticker.attach(&fp_cb, tx_ticker_rate);
03127 }
03128 #endif /* LORA_TX_TEST */
03129 
03130 void cmd_codingRate(uint8_t idx)
03131 {
03132     if (pcbuf[idx] >= '0' && pcbuf[idx] <= '9')
03133         lora.setCodingRate(pcbuf[idx] - '0');
03134      lora.RegModemConfig.octet = radio.read_reg(REG_LR_MODEMCONFIG);
03135      lora_printCodingRate(false);    // false: transmitted
03136      printf("\r\n");
03137 }
03138 
03139 void cmd_lora_header_mode(uint8_t idx)
03140 {
03141     lora.setHeaderMode(!lora.getHeaderMode());
03142     lora.RegModemConfig.octet = radio.read_reg(REG_LR_MODEMCONFIG);
03143     lora_printHeaderMode();
03144     printf("\r\n");
03145 }
03146 
03147 void cmd_fsk_AfcAutoClearOn(uint8_t idx)
03148 {
03149     fsk.RegAfcFei.bits.AfcAutoClearOn ^= 1;
03150     printf("AfcAutoClearOn: ");
03151     radio.write_reg(REG_FSK_AFCFEI, fsk.RegAfcFei.octet);
03152     if (fsk.RegAfcFei.bits.AfcAutoClearOn)
03153         printf("ON\r\n");
03154     else
03155         printf("off\r\n");
03156 }
03157 
03158 void cmd_fsk_AutoRestartRxMode(uint8_t idx)
03159 {
03160     fsk.RegSyncConfig.bits.AutoRestartRxMode++;
03161     radio.write_reg(REG_FSK_SYNCCONFIG, fsk.RegSyncConfig.octet);
03162     fsk.RegSyncConfig.octet = radio.read_reg(REG_FSK_SYNCCONFIG);
03163     printf("AutoRestartRxMode:");
03164     switch (fsk.RegSyncConfig.bits.AutoRestartRxMode) {
03165         case 0: printf("off "); break;
03166         case 1: printf("no-pll-wait "); break;
03167         case 2: printf("pll-wait "); break;
03168         case 3: printf("3 "); break;
03169     }
03170     printf("\r\n");   
03171 }
03172 
03173 void cmd_AfcClear(uint8_t idx)
03174 {
03175     printf("clear afc: ");
03176     fsk.RegAfcFei.bits.AfcClear = 1;
03177     radio.write_reg(REG_FSK_AFCFEI, fsk.RegAfcFei.octet);
03178     fsk.RegAfcFei.bits.AfcClear = 0; 
03179     printf("%dHz\r\n", (int)(FREQ_STEP_HZ * radio.read_s16(REG_FSK_AFCMSB)));
03180 }
03181 
03182 void cmd_fsk_bitrate(uint8_t idx)
03183 {
03184     if (pcbuf[idx] >= '0' && pcbuf[idx] <= '9') {
03185         float kbits;
03186         sscanf(&pcbuf[idx], "%f", &kbits);
03187         fsk.set_bitrate((int)(kbits*1000));
03188     }
03189     printf("%fkbps\r\n", fsk.get_bitrate()/(float)1000.0); 
03190 }
03191 
03192 void cmd_bandwidth(uint8_t idx)
03193 {
03194     int i;
03195     float f;
03196     if (radio.RegOpMode.bits.LongRangeMode) {
03197         if (pcbuf[idx] >= '0' && pcbuf[idx] <= '9') {
03198             radio.set_opmode(RF_OPMODE_STANDBY);
03199             sscanf(&pcbuf[idx], "%d", &i);
03200             lora.setBw_KHz(i);
03201         } else
03202             lora_printAllBw();
03203         lora.RegModemConfig.octet = radio.read_reg(REG_LR_MODEMCONFIG);
03204         printf("current ");
03205         lora_printBw();
03206         printf("\r\n");
03207     } else { // FSK:
03208         if (pcbuf[idx] == 'a') {
03209             idx++;
03210             if (pcbuf[idx] >= '0' && pcbuf[idx] <= '9') {
03211                 radio.set_opmode(RF_OPMODE_STANDBY);
03212                 sscanf(&pcbuf[idx], "%f", &f);
03213                 fsk.set_rx_dcc_bw_hz((int)(f*(float)1000.0), 1);
03214             }
03215             printf("afcbw:%.3fkHz\r\n", fsk.get_rx_bw_hz(REG_FSK_AFCBW)/1000.0);
03216         } else {
03217             if (pcbuf[idx] >= '0' && pcbuf[idx] <= '9') {
03218                 radio.set_opmode(RF_OPMODE_STANDBY);
03219                 sscanf(&pcbuf[idx], "%f", &f);
03220                 fsk.set_rx_dcc_bw_hz((int)(f*(float)1000.0), 0);
03221             }
03222             printf("rxbw:%.3fkHz\r\n", fsk.get_rx_bw_hz(REG_FSK_RXBW)/1000.0);
03223         }
03224     }
03225 }
03226 
03227 void cmd_lora_poll_validHeader(uint8_t idx)
03228 {
03229     lora.poll_vh ^= 1;
03230     printf("poll_vh:%d\r\n", lora.poll_vh);
03231 }
03232 
03233 void cmd_fsk_syncword(uint8_t idx)
03234 {
03235     int i, d = 0;
03236     uint8_t reg_addr = REG_FSK_SYNCVALUE1;
03237     
03238     fsk.RegSyncConfig.octet = radio.read_reg(REG_FSK_SYNCCONFIG);
03239     
03240     if (pcbuf_len != idx) { // something to write?
03241         for (i = idx; i < pcbuf_len; ) {
03242             int a, n;
03243             sscanf(pcbuf+i, "%x", &n);
03244             radio.write_reg(reg_addr++, n);
03245             //printf("%02x ", n);
03246             while (pcbuf[i] == ' ')
03247                 i++;
03248             for (a = i; pcbuf[a] != ' '; a++)
03249                 if (a >= pcbuf_len)
03250                     break;
03251             i = a;
03252             while (pcbuf[i] == ' ') {
03253                 i++;                 
03254                 if (i >= pcbuf_len)
03255                     break;
03256             }   
03257             d++;
03258         }    
03259      
03260         fsk.RegSyncConfig.bits.SyncSize = reg_addr - REG_FSK_SYNCVALUE1 - 1;
03261         radio.write_reg(REG_FSK_SYNCCONFIG, fsk.RegSyncConfig.octet);
03262     }
03263     
03264     printf("%d: ", fsk.RegSyncConfig.bits.SyncSize);
03265     for (i = 0; i <= fsk.RegSyncConfig.bits.SyncSize; i++)
03266         printf("%02x ", radio.read_reg(REG_FSK_SYNCVALUE1+i));
03267     printf("\r\n");
03268 }
03269 
03270 void cmd_fsk_syncOn(uint8_t idx)
03271 {
03272     fsk.RegSyncConfig.bits.SyncOn ^= 1;
03273     radio.write_reg(REG_FSK_SYNCCONFIG, fsk.RegSyncConfig.octet);
03274     printf("SyncOn:%d\r\n", fsk.RegSyncConfig.bits.SyncOn);
03275 }
03276 
03277 void cmd_fsk_bitsync(uint8_t idx)
03278 {
03279     fsk.RegOokPeak.octet = radio.read_reg(REG_FSK_OOKPEAK);
03280     fsk.RegOokPeak.bits.BitSyncOn ^= 1;
03281     radio.write_reg(REG_FSK_OOKPEAK, fsk.RegOokPeak.octet);
03282     if (fsk.RegOokPeak.bits.BitSyncOn)
03283         printf("BitSyncOn\r\n");
03284     else
03285         printf("BitSync Off\r\n");
03286 }
03287 
03288 void cmd_lora_sf(uint8_t idx)
03289 {
03290     int i;
03291     if (pcbuf[idx] >= '0' && pcbuf[idx] <= '9') {
03292         sscanf(pcbuf+idx, "%d", &i);
03293         lora.setSf(i);
03294         if (i == 6 && !lora.getHeaderMode()) {
03295             printf("SF6: to implicit header mode\r\n");
03296             lora.setHeaderMode(true);
03297         }
03298     }
03299     lora.RegModemConfig2.octet = radio.read_reg(REG_LR_MODEMCONFIG2);
03300     lora_printSf();
03301     printf("\r\n");
03302 }
03303 
03304 void cmd_fsk_TxStartCondition(uint8_t idx)
03305 {
03306     fsk.RegFifoThreshold.bits.TxStartCondition ^= 1;
03307     radio.write_reg(REG_FSK_FIFOTHRESH, fsk.RegFifoThreshold.octet);
03308     printf("TxStartCondition:");
03309     if (fsk.RegFifoThreshold.bits.TxStartCondition)
03310         printf("!FifoEmpty\r\n");
03311     else
03312         printf("FifoLevel\r\n"); 
03313 }        
03314 
03315 void cmd_fsk_read_fei(uint8_t idx)
03316 {
03317     printf("fei:%dHz\r\n", (int)(FREQ_STEP_HZ * radio.read_s16(REG_FSK_FEIMSB)));
03318 }
03319 
03320 void cmd_fsk_fdev(uint8_t idx)
03321 {
03322     if (pcbuf[idx] >= '0' && pcbuf[idx] <= '9') {
03323         float khz;
03324         sscanf(pcbuf+idx, "%f", &khz);
03325         fsk.set_tx_fdev_hz((int)(khz*1000));
03326     }
03327     printf("fdev:%fKHz\r\n", fsk.get_tx_fdev_hz()/(float)1000.0);
03328 }
03329 
03330 void cmd_spifreq(uint8_t idx)
03331 {
03332     if (pcbuf[idx] >= '0' && pcbuf[idx] <= '9') {
03333         int hz, MHz;
03334         sscanf(pcbuf+idx, "%d", &MHz);
03335         hz = MHz * 1000000;
03336         printf("spi hz:%u\r\n", hz);
03337         radio.m_spi.frequency(hz);
03338     }
03339 }
03340 
03341 void cmd_frf(uint8_t idx)
03342 {
03343     if (pcbuf[idx] >= '0' && pcbuf[idx] <= '9') {
03344         float MHz;
03345         sscanf(pcbuf+idx, "%f", &MHz);
03346         //printf("MHz:%f\r\n", MHz);
03347         radio.set_frf_MHz(MHz);
03348     }
03349     printf("%fMHz\r\n", radio.get_frf_MHz());
03350 #if !defined(TARGET_MTS_MDOT_F411RE) && !defined(TARGET_DISCO_L072CZ_LRWAN1)
03351     radio.RegPaConfig.octet = radio.read_reg(REG_PACONFIG);
03352     if (shield_type == SHIELD_TYPE_LAS) {
03353         // LAS HF=PA_BOOST  LF=RFO
03354         if (radio.HF)
03355             radio.RegPaConfig.bits.PaSelect = 1;
03356         else
03357             radio.RegPaConfig.bits.PaSelect = 0;
03358     }
03359     radio.write_reg(REG_PACONFIG, radio.RegPaConfig.octet);          
03360 #endif /* !TARGET_MTS_MDOT_F411RE */
03361 }
03362 
03363 void cmd_fsk_PacketFormat(uint8_t idx)
03364 {
03365     printf("PacketFormat:");
03366     fsk.RegPktConfig1.bits.PacketFormatVariable ^= 1;
03367     radio.write_reg(REG_FSK_PACKETCONFIG1, fsk.RegPktConfig1.octet);
03368     if (fsk.RegPktConfig1.bits.PacketFormatVariable)
03369         printf("variable\r\n");
03370     else
03371         printf("fixed\r\n");
03372 }
03373 
03374 void cmd_payload_length(uint8_t idx)
03375 {
03376     int i;
03377     if (pcbuf[idx] >= '0' && pcbuf[idx] <= '9') {
03378         sscanf(pcbuf+idx, "%d", &i);
03379         if (radio.RegOpMode.bits.LongRangeMode) {
03380             lora.RegPayloadLength = i;
03381             radio.write_reg(REG_LR_PAYLOADLENGTH, lora.RegPayloadLength);
03382         } else {
03383             fsk.RegPktConfig2.bits.PayloadLength = i;
03384             radio.write_u16(REG_FSK_PACKETCONFIG2, fsk.RegPktConfig2.word);
03385         }
03386     }
03387     if (radio.RegOpMode.bits.LongRangeMode) {
03388         lora.RegPayloadLength = radio.read_reg(REG_LR_PAYLOADLENGTH);
03389         printf("PayloadLength:%d\r\n", lora.RegPayloadLength);
03390     } else {
03391         printf("PayloadLength:%d\r\n", fsk_get_PayloadLength());
03392     }
03393 }
03394 
03395 void cmd_paRamp(uint8_t idx)
03396 {
03397     int i;
03398     uint8_t reg_par = radio.read_reg(REG_PARAMP);
03399     uint8_t PaRamp = reg_par & 0x0f;
03400     reg_par &= 0xf0;
03401     if (PaRamp == 15)
03402         PaRamp = 0;
03403     else
03404         PaRamp++;
03405     radio.write_reg(REG_PARAMP, reg_par | PaRamp);
03406     printf("PaRamp:");
03407     switch (PaRamp) {
03408         case 0: i = 3400; break;
03409         case 1: i = 2000; break;
03410         case 2: i = 1000; break;
03411         case 3: i = 500; break;                
03412         case 4: i = 250; break;
03413         case 5: i = 125; break;
03414         case 6: i = 100; break;
03415         case 7: i = 62; break;                 
03416         case 8: i = 50; break;
03417         case 9: i = 40; break;
03418         case 10: i = 31; break;
03419         case 11: i = 25; break;                
03420         case 12: i = 20; break;
03421         case 13: i = 15; break;
03422         case 14: i = 12; break;
03423         case 15: i = 10; break;                
03424     }
03425     printf("%dus\r\n", i);
03426 }
03427 
03428 void cmd_paSelect(uint8_t idx)
03429 {
03430     radio.RegPaConfig.bits.PaSelect ^= 1;
03431     radio.write_reg(REG_PACONFIG, radio.RegPaConfig.octet);
03432     printPa();
03433     printf("\r\n");
03434 }
03435 
03436 void cmd_poll_irq_en(uint8_t idx)
03437 {
03438     poll_irq_en ^= 1;
03439     printf("poll_irq_en:");
03440     if (poll_irq_en) {
03441         printf("irqFlags register\r\n");
03442         fsk_RegIrqFlags1_prev.octet = 0;
03443         fsk_RegIrqFlags2_prev.octet = 0;
03444     } else
03445         printf("DIO pin interrupt\r\n");
03446 }
03447 
03448 void cmd_per_id(uint8_t idx)
03449 {
03450     if (pcbuf[idx] >= '0' && pcbuf[idx] <= '9') {
03451         sscanf(pcbuf+idx, "%d", &per_id);
03452     }
03453     printf("PER device ID:%d\r\n", per_id);
03454 }
03455 
03456 void cmd_pertx(uint8_t idx)
03457 {
03458     int i;
03459     
03460     if (cadper_enable)
03461         cadper_enable = false;
03462     
03463     set_per_en(true);
03464     if (pcbuf[idx] >= '0' && pcbuf[idx] <= '9') {
03465         sscanf(pcbuf+idx, "%d", &i);
03466         PacketTxCntEnd = i;
03467     }
03468     PacketTxCnt = 0;
03469     per_timeout.attach(&per_cb, per_tx_delay);  
03470 }
03471 
03472 void cmd_perrx(uint8_t idx)
03473 {
03474     set_per_en(true);
03475 
03476     PacketNormalCnt = 0;
03477     PacketRxSequencePrev = 0; // transmitter side PacketTxCnt is 1 at first TX
03478     PacketPerKoCnt = 0;
03479     PacketPerOkCnt = 0;                
03480     //dio3.rise(&dio3_cb);
03481 
03482     if (radio.RegOpMode.bits.LongRangeMode)
03483         lora.start_rx(RF_OPMODE_RECEIVER);
03484     else {
03485         fsk.start_rx();
03486         radio.RegDioMapping1.bits.Dio2Mapping = 3;  // dio2 to syncadrs
03487         radio.write_reg(REG_DIOMAPPING1, radio.RegDioMapping1.octet); 
03488         if (radio.HF) {
03489             fsk.RegRssiConfig.octet = radio.read_reg(REG_FSK_RSSICONFIG);
03490             fsk.RegRssiConfig.bits.RssiOffset = FSK_RSSI_OFFSET;
03491             fsk.RegRssiConfig.bits.RssiSmoothing = FSK_RSSI_SMOOTHING;
03492             radio.write_reg(REG_FSK_RSSICONFIG, fsk.RegRssiConfig.octet);
03493         }                                
03494     }    
03495 }
03496 
03497 void cmd_fsk_PreambleDetectorOn(uint8_t idx)
03498 {
03499     fsk.RegPreambleDetect.bits.PreambleDetectorOn ^= 1;
03500     radio.write_reg(REG_FSK_PREAMBLEDETECT, fsk.RegPreambleDetect.octet);
03501     printf("PreambleDetector:");
03502     if (fsk.RegPreambleDetect.bits.PreambleDetectorOn)
03503         printf("On\r\n");
03504     else
03505         printf("OFF\r\n"); 
03506 }
03507 
03508 void cmd_fsk_PreambleDetectorSize(uint8_t idx)
03509 {
03510     int i;
03511     if (pcbuf[idx] >= '0' && pcbuf[idx] <= '9') {
03512         sscanf(pcbuf+idx, "%d", &i);
03513         fsk.RegPreambleDetect.bits.PreambleDetectorSize = i;
03514     }
03515     printf("PreambleDetectorSize:%d\r\n", fsk.RegPreambleDetect.bits.PreambleDetectorSize);
03516     radio.write_reg(REG_FSK_PREAMBLEDETECT, fsk.RegPreambleDetect.octet); 
03517 }
03518 
03519 void cmd_fsk_PreambleDetectorTol(uint8_t idx)
03520 {
03521     int i;
03522     if (pcbuf[idx] >= '0' && pcbuf[idx] <= '9') {
03523         sscanf(pcbuf+idx, "%d", &i);
03524         fsk.RegPreambleDetect.bits.PreambleDetectorTol = i;
03525     }
03526     printf("PreambleDetectorTol:%d\r\n", fsk.RegPreambleDetect.bits.PreambleDetectorTol);                
03527     radio.write_reg(REG_FSK_PREAMBLEDETECT, fsk.RegPreambleDetect.octet);  
03528 }
03529 
03530 void cmd_PreambleSize(uint8_t idx)
03531 {
03532     int i;
03533     if (radio.RegOpMode.bits.LongRangeMode) {
03534         if (pcbuf[idx] >= '0' && pcbuf[idx] <= '9') {
03535             sscanf(pcbuf+idx, "%d", &i);
03536             radio.write_u16(REG_LR_PREAMBLEMSB, i);
03537         }
03538         lora.RegPreamble = radio.read_u16(REG_LR_PREAMBLEMSB);
03539         printf("lora PreambleLength:%d\r\n", lora.RegPreamble);                
03540     } else {    
03541         if (pcbuf[idx] >= '0' && pcbuf[idx] <= '9') {
03542             sscanf(pcbuf+idx, "%d", &i);  
03543             radio.write_u16(REG_FSK_PREAMBLEMSB, i);
03544         }
03545         printf("PreambleSize:%d\r\n", radio.read_u16(REG_FSK_PREAMBLEMSB));
03546     }
03547 }
03548 
03549 void cmd_fsk_PreamblePolarity(uint8_t idx)
03550 {
03551     fsk.RegSyncConfig.octet = radio.read_reg(REG_FSK_SYNCCONFIG);
03552     fsk.RegSyncConfig.bits.PreamblePolarity ^= 1;
03553     radio.write_reg(REG_FSK_SYNCCONFIG, fsk.RegSyncConfig.octet);
03554     if (fsk.RegSyncConfig.bits.PreamblePolarity)
03555         printf("0x55\r\n");
03556     else
03557         printf("0xaa\r\n");
03558 }
03559 
03560 void cmd_pllbw(uint8_t idx)
03561 {
03562     RegPll_t pll;
03563     if (radio.type == SX1272) {
03564         // 0x5c and 0x5e registers
03565         pll.octet = radio.read_reg(REG_PLL_SX1272);
03566         if (pll.bits.PllBandwidth == 3)
03567             pll.bits.PllBandwidth = 0;
03568         else
03569             pll.bits.PllBandwidth++;
03570         radio.write_reg(REG_PLL_SX1272, pll.octet);
03571         pll.octet = radio.read_reg(REG_PLL_LOWPN_SX1272);
03572         if (pll.bits.PllBandwidth == 3)
03573             pll.bits.PllBandwidth = 0;
03574         else
03575             pll.bits.PllBandwidth++;
03576         radio.write_reg(REG_PLL_LOWPN_SX1272, pll.octet);                
03577     } else if (radio.type == SX1276) {
03578         // 0x70 register
03579         pll.octet = radio.read_reg(REG_PLL_SX1276);
03580         if (pll.bits.PllBandwidth == 3)
03581             pll.bits.PllBandwidth = 0;
03582         else
03583             pll.bits.PllBandwidth++;
03584         radio.write_reg(REG_PLL_SX1276, pll.octet);                  
03585     }
03586     switch (pll.bits.PllBandwidth) {
03587         case 0: printf("75"); break;
03588         case 1: printf("150"); break;
03589         case 2: printf("225"); break;
03590         case 3: printf("300"); break;
03591     }
03592     printf("KHz\r\n");
03593 }
03594 
03595 void cmd_lna_boost(uint8_t idx)
03596 {
03597     radio.RegLna.octet = radio.read_reg(REG_LNA);
03598     if (radio.RegLna.bits.LnaBoostHF == 3)
03599         radio.RegLna.bits.LnaBoostHF = 0; 
03600     else 
03601         radio.RegLna.bits.LnaBoostHF++;
03602     radio.write_reg(REG_LNA, radio.RegLna.octet);            
03603     printf("LNA-boost:%d\r\n", radio.RegLna.bits.LnaBoostHF);
03604 }
03605 
03606 void cmd_LowDataRateOptimize(uint8_t idx)
03607 {
03608     if (radio.type == SX1272) {
03609         lora.RegModemConfig.octet = radio.read_reg(REG_LR_MODEMCONFIG);
03610         lora.RegModemConfig.sx1272bits.LowDataRateOptimize ^= 1;
03611         printf("LowDataRateOptimize:%d\r\n", lora.RegModemConfig.sx1272bits.LowDataRateOptimize);
03612         radio.write_reg(REG_LR_MODEMCONFIG, lora.RegModemConfig.octet);
03613     } else if (radio.type == SX1276) {
03614         lora.RegModemConfig3.octet = radio.read_reg(REG_LR_MODEMCONFIG3);
03615         lora.RegModemConfig3.sx1276bits.LowDataRateOptimize ^= 1;
03616         printf("LowDataRateOptimize:%d\r\n", lora.RegModemConfig3.sx1276bits.LowDataRateOptimize); 
03617         radio.write_reg(REG_LR_MODEMCONFIG3, lora.RegModemConfig3.octet);
03618     }
03619 }
03620 
03621 void cmd_fsk_FifoThreshold(uint8_t idx)
03622 {
03623     int i;
03624     fsk.RegFifoThreshold.octet = radio.read_reg(REG_FSK_FIFOTHRESH);  
03625     if (pcbuf[idx] >= '0' && pcbuf[idx] <= '9') {
03626         sscanf(pcbuf+idx, "%d", &i);
03627         fsk.RegFifoThreshold.bits.FifoThreshold = i;
03628     }
03629     radio.write_reg(REG_FSK_FIFOTHRESH, fsk.RegFifoThreshold.octet);
03630     printf("FifoThreshold:%d\r\n", fsk.RegFifoThreshold.bits.FifoThreshold);
03631     fsk.RegFifoThreshold.octet = radio.read_reg(REG_FSK_FIFOTHRESH); 
03632 }
03633 
03634 void cmd_tx_ticker_rate(uint8_t idx)
03635 {
03636     if (pcbuf[idx] != 0) {
03637         sscanf(pcbuf+idx, "%f", &tx_ticker_rate);
03638     }
03639     printf("tx_ticker_rate:%f\r\n", tx_ticker_rate);
03640 }
03641 
03642 void cmd_lora_tx_invert(uint8_t idx)
03643 {
03644     lora.invert_tx(lora.RegTest33.bits.chirp_invert_tx);
03645     printf("chirp_invert_tx :%d\r\n", lora.RegTest33.bits.chirp_invert_tx);    
03646 }
03647     
03648 void cmd_lora_rx_invert(uint8_t idx)
03649 {
03650     lora.invert_rx(!lora.RegTest33.bits.invert_i_q);
03651     printf("rx invert_i_q:%d\r\n", lora.RegTest33.bits.invert_i_q);    
03652 }
03653 
03654 void cmd_fsk_dcfree(uint8_t idx)
03655 {
03656     fsk.RegPktConfig1.octet = radio.read_reg(REG_FSK_PACKETCONFIG1);
03657     if (fsk.RegPktConfig1.bits.DcFree == 3)
03658         fsk.RegPktConfig1.bits.DcFree = 0;
03659     else
03660         fsk.RegPktConfig1.bits.DcFree++;
03661     printf(" dcFree:");
03662     switch (fsk.RegPktConfig1.bits.DcFree) {
03663         case 0: printf("none "); break;
03664         case 1: printf("Manchester "); break;
03665         case 2: printf("Whitening "); break;
03666         case 3: printf("reserved "); break;
03667     }
03668     radio.write_reg(REG_FSK_PACKETCONFIG1, fsk.RegPktConfig1.octet); 
03669     printf("\r\n"); 
03670 }
03671 
03672 void cmd_bt(uint8_t idx)
03673 {
03674     radio.RegOpMode.octet = radio.read_reg(REG_OPMODE);
03675     if (radio.RegOpMode.bits.ModulationType != 0) {
03676         printf("!fsk\r\n");
03677         return;
03678     }
03679         
03680     if (pcbuf[idx] >= '0' && pcbuf[idx] <= '9') {
03681         float bt;
03682         sscanf(pcbuf+idx, "%f", &bt);
03683         if (bt > 1.0)
03684             radio.RegOpMode.bits.ModulationShaping = 0;    // 0 = no shaping
03685         else if (bt > 0.6)
03686             radio.RegOpMode.bits.ModulationShaping = 1;    // 1 = BT1.0
03687         else if (bt > 0.4)
03688             radio.RegOpMode.bits.ModulationShaping = 2;    // 2 = BT0.5
03689         else
03690             radio.RegOpMode.bits.ModulationShaping = 3;    // 3 = BT0.3
03691     }
03692     radio.write_reg(REG_OPMODE, radio.RegOpMode.octet);
03693     switch (radio.RegOpMode.bits.ModulationShaping) {
03694         case 0: printf("no-shaping "); break;
03695         case 1: printf("BT1.0 "); break;
03696         case 2: printf("BT0.5 "); break;
03697         case 3: printf("BT0.3 "); break;
03698     }    
03699     printf("\r\n");
03700 }
03701 
03702 void cmd_fsk_DataMode(uint8_t idx)
03703 {
03704     fsk.RegPktConfig2.word = radio.read_u16(REG_FSK_PACKETCONFIG2);
03705     fsk.RegPktConfig2.bits.DataModePacket ^= 1;
03706     radio.write_u16(REG_FSK_PACKETCONFIG2, fsk.RegPktConfig2.word);  
03707     printf("datamode:");
03708     if (fsk.RegPktConfig2.bits.DataModePacket)
03709         printf("packet\r\n");
03710     else
03711         printf("continuous\r\n");
03712 }
03713 
03714 void cmd_show_dio(uint8_t idx)
03715 {
03716     if (radio.RegOpMode.bits.LongRangeMode)
03717         lora_print_dio();
03718     else
03719         fsk_print_dio(); 
03720 }
03721 
03722 void cmd_set_dio(uint8_t idx)
03723 {
03724     switch (pcbuf[idx]) {
03725         case '0':
03726             radio.RegDioMapping1.bits.Dio0Mapping++;
03727             radio.write_reg(REG_DIOMAPPING1, radio.RegDioMapping1.octet);
03728             break;
03729         case '1':
03730             radio.RegDioMapping1.bits.Dio1Mapping++;
03731             radio.write_reg(REG_DIOMAPPING1, radio.RegDioMapping1.octet);
03732             break;    
03733         case '2':
03734             radio.RegDioMapping1.bits.Dio2Mapping++;
03735             radio.write_reg(REG_DIOMAPPING1, radio.RegDioMapping1.octet);
03736             break;
03737         case '3':
03738             radio.RegDioMapping1.bits.Dio3Mapping++;
03739             radio.write_reg(REG_DIOMAPPING1, radio.RegDioMapping1.octet);
03740             break;
03741         case '4':
03742             radio.RegDioMapping2.bits.Dio4Mapping++;
03743             radio.write_reg(REG_DIOMAPPING2, radio.RegDioMapping2.octet);
03744             break; 
03745         case '5':
03746             radio.RegDioMapping2.bits.Dio5Mapping++;
03747             radio.write_reg(REG_DIOMAPPING2, radio.RegDioMapping2.octet);
03748             break;                                                                                             
03749     } // ...switch (pcbuf[idx])
03750     if (radio.RegOpMode.bits.LongRangeMode)
03751         lora_print_dio();
03752     else
03753         fsk_print_dio();
03754 }
03755 
03756 void cmd_mode_standby(uint8_t idx)
03757 {
03758     radio.set_opmode(RF_OPMODE_STANDBY);
03759     printf("standby\r\n");
03760 }
03761     
03762 void cmd_mode_sleep(uint8_t idx)
03763 {
03764     radio.set_opmode(RF_OPMODE_SLEEP);
03765     printf("sleep\r\n");
03766 }
03767 
03768 void cmd_mode_fstx(uint8_t idx)
03769     {
03770     radio.set_opmode(RF_OPMODE_SYNTHESIZER_TX);
03771     printf("fstx\r\n");
03772 }
03773 
03774 void cmd_mode_fsrx(uint8_t idx)
03775 {
03776     radio.set_opmode(RF_OPMODE_SYNTHESIZER_RX);
03777     printf("fsrx\r\n");
03778 }
03779 
03780 void cmd_chat(uint8_t idx)
03781 {
03782     app = APP_CHAT;
03783     lora.start_rx(RF_OPMODE_RECEIVER);
03784     printf("chat start\r\n");
03785 }
03786 
03787 void cmd_OokThreshType(uint8_t idx)
03788 {
03789     fsk.RegOokPeak.octet = radio.read_reg(REG_FSK_OOKPEAK);
03790     if (fsk.RegOokPeak.bits.OokThreshType == 2)
03791         fsk.RegOokPeak.bits.OokThreshType = 0;
03792     else
03793         fsk.RegOokPeak.bits.OokThreshType++;
03794 
03795     radio.write_reg(REG_FSK_OOKPEAK, fsk.RegOokPeak.octet);
03796     printf("OokThreshType:");
03797     switch (fsk.RegOokPeak.bits.OokThreshType) {
03798         case 0: printf("fixed"); break;
03799         case 1: printf("peak"); break;
03800         case 2: printf("average"); break;
03801         case 3: printf("?"); break;
03802     }
03803     printf("\r\n");
03804 }
03805 
03806 void cmd_OokPeakTheshStep(uint8_t idx)
03807 {
03808     float f;
03809     fsk.RegOokPeak.octet = radio.read_reg(REG_FSK_OOKPEAK);
03810     if (fsk.RegOokPeak.bits.OokPeakThreshStep == 7)
03811         fsk.RegOokPeak.bits.OokPeakThreshStep = 0;
03812     else
03813         fsk.RegOokPeak.bits.OokPeakThreshStep++;    
03814 
03815     radio.write_reg(REG_FSK_OOKPEAK, fsk.RegOokPeak.octet);
03816     switch (fsk.RegOokPeak.bits.OokPeakThreshStep) {
03817         case 0: f = 0.5; break;
03818         case 1: f = 1; break;
03819         case 2: f = 1.5; break;
03820         case 3: f = 2; break;
03821         case 4: f = 3; break;
03822         case 5: f = 4; break;
03823         case 6: f = 5; break;
03824         case 7: f = 6; break;                                                        
03825     }    
03826     printf("OokPeakThreshStep:%.1fdB\r\n", f); 
03827 }
03828 
03829 void cmd_OokFixedThresh(uint8_t idx)
03830 {
03831     int i;
03832     if (pcbuf[idx] >= '0' && pcbuf[idx] <= '9') {
03833         sscanf(pcbuf+idx, "%d", &i);
03834         radio.write_reg(REG_FSK_OOKFIX, i);
03835     }
03836     i = radio.read_reg(REG_FSK_OOKFIX);
03837     printf("OokFixedThreshold:%d\r\n", i);
03838 } 
03839 
03840 void cmd_clkout(uint8_t idx)
03841 {
03842     RegOsc_t reg_osc;
03843     reg_osc.octet = radio.read_reg(REG_FSK_OSC);
03844     if (reg_osc.bits.ClkOut == 7)
03845         reg_osc.bits.ClkOut = 0;
03846     else
03847         reg_osc.bits.ClkOut++;
03848         
03849     printf("ClkOut:%d\r\n", reg_osc.bits.ClkOut);
03850     radio.write_reg(REG_FSK_OSC, reg_osc.octet);
03851 }
03852 
03853 void cmd_ook_tx_test(uint8_t idx)
03854 {
03855     radio.set_frf_MHz(915.0);
03856 
03857     radio.RegOpMode.octet = radio.read_reg(REG_OPMODE);
03858     if (radio.RegOpMode.bits.LongRangeMode)
03859         cmd_toggle_modem(0);
03860         
03861     fsk.RegPktConfig1.octet = radio.read_reg(REG_FSK_PACKETCONFIG1);
03862     fsk.RegPktConfig1.bits.CrcOn = 0;
03863     radio.write_reg(REG_FSK_PACKETCONFIG1, fsk.RegPktConfig1.octet);    
03864     
03865     radio.RegDioMapping2.octet = radio.read_reg(REG_DIOMAPPING2);
03866     radio.RegDioMapping2.bits.Dio5Mapping = 2;  // Data
03867     radio.write_reg(REG_DIOMAPPING2, radio.RegDioMapping2.octet);
03868     
03869     radio.RegDioMapping1.octet = radio.read_reg(REG_DIOMAPPING1);
03870     radio.RegDioMapping1.bits.Dio3Mapping = 1;  // TxReady
03871     radio.write_reg(REG_DIOMAPPING1, radio.RegDioMapping1.octet);
03872     
03873     //radio.write_reg(REG_FSK_SYNCCONFIG, 0);
03874     cmd_ook(0);
03875     radio.write_reg(REG_FSK_SYNCCONFIG, 0);
03876 /*    radio.write_u16(REG_FSK_PREAMBLEMSB, 4);    // preamble length
03877     
03878     fsk.RegSyncConfig.octet = radio.read_reg(REG_FSK_SYNCCONFIG);
03879     fsk.RegSyncConfig.bits.SyncOn = 1;
03880     radio.write_reg(REG_FSK_SYNCCONFIG, fsk.RegSyncConfig.octet);
03881 
03882     //              0123456
03883     sprintf(pcbuf, "syncw a9 66 69 65");
03884     cmd_fsk_syncword(6);*/
03885     tx_ticker.attach(&callback_ook_tx_test, tx_ticker_rate);
03886 }
03887      
03888 void cmd_help(uint8_t args_at);
03889 
03890 typedef enum {
03891     MODEM_BOTH,
03892     MODEM_FSK,
03893     MODEM_LORA
03894 } modem_e;
03895 
03896 typedef struct {
03897     modem_e modem;
03898     const char* const cmd;
03899     void (*handler)(uint8_t args_at);
03900     const char* const arg_descr;
03901     const char* const description;
03902 } menu_item_t;
03903 
03904 const menu_item_t menu_items[] = 
03905 {   /* after first character, command names must be [A-Za-z] */
03906     { MODEM_BOTH, "chat", cmd_chat, "","start keyboard chat"}, 
03907     { MODEM_BOTH, "rssi", cmd_read_current_rssi, "","(RX) read instantaneous RSSI"}, 
03908     { MODEM_BOTH, "prssi", cmd_rssi_polling, "<%d>","dbm of rssi polling, 0 = off"}, 
03909     { MODEM_BOTH, "txpd", cmd_per_tx_delay, "<%d>","get/set PER tx delay (in milliseconds)"},
03910     { MODEM_BOTH, "pertx", cmd_pertx, "<%d pkt count>","start Eiger PER TX"},
03911     { MODEM_BOTH, "perrx", cmd_perrx, "","start Eiger PER RX"},
03912     { MODEM_BOTH, "pres", cmd_PreambleSize, "<%d>", "get/set PreambleSize"},
03913     { MODEM_BOTH, "pllbw", cmd_pllbw, "", "increment pllbw"},
03914     { MODEM_BOTH, "lnab", cmd_lna_boost, "", "(RX) increment LNA boost"},
03915     { MODEM_BOTH, "stby", cmd_mode_standby, "", "set chip mode to standby"},
03916     { MODEM_BOTH, "sleep", cmd_mode_sleep, "", "set chip mode to sleep"},
03917     { MODEM_BOTH, "fstx", cmd_mode_fstx, "", "set chip mode to fstx"},
03918     { MODEM_BOTH, "fsrx", cmd_mode_fsrx, "", "set chip mode to fsrx"}, 
03919     { MODEM_BOTH, "crcon", cmd_crcOn, "","toggle crcOn"},
03920     { MODEM_BOTH, "ethcrc", cmd_crc32, "","toggle enable software crc32"},
03921     { MODEM_BOTH, "spif", cmd_spifreq, "<MHz>","change SPI clock frequency"},
03922     { MODEM_BOTH, "payl", cmd_payload_length, "<%d>","get/set payload length"},   
03923     { MODEM_BOTH, "bgr", cmd_bgr, "<%d>","(TX) get/set reference for TX DAC"},
03924     { MODEM_BOTH, "ocp", cmd_ocp, "<%d>","(TX) get/set milliamps current limit"},
03925     { MODEM_BOTH, "frf", cmd_frf, "<MHz>","get/set RF center frequency"},
03926     { MODEM_BOTH, "pas", cmd_paSelect, "","(TX) toggle RFO/PA_BOOST"},
03927     { MODEM_BOTH, "pid", cmd_per_id, "<%d>","get/set ID number in Eiger PER packet"},
03928     { MODEM_BOTH, "dio", cmd_show_dio, "","print dio mapping"},         
03929     
03930     { MODEM_FSK, "clkout", cmd_clkout, "","increment ClkOut divider"}, 
03931     { MODEM_FSK, "ookt", cmd_OokThreshType, "","(RX) increment OokThreshType"}, 
03932     { MODEM_FSK, "ooks", cmd_OokPeakTheshStep, "","(RX) increment OokPeakTheshStep"}, 
03933     { MODEM_FSK, "sqlch", cmd_OokFixedThresh, "<%d>","(RX) get/set OokFixedThresh"}, 
03934     { MODEM_FSK, "rssit", cmd_rssi_threshold, "<-dBm>","(RX) get/set rssi threshold"}, 
03935     { MODEM_FSK, "rssis", cmd_rssi_smoothing, "<%d>","(RX) get/set rssi smoothing"}, 
03936     { MODEM_FSK, "rssio", cmd_rssi_offset, "<%d>","(RX) get/set rssi offset"},
03937     { MODEM_FSK, "mods", cmd_mod_shaping, "", "(TX) increment modulation shaping"},  
03938     { MODEM_FSK, "agcauto", cmd_fsk_agcauto, "", "(RX) toggle AgcAutoOn"},
03939     { MODEM_FSK, "afcauto", cmd_fsk_afcauto, "", "(RX) toggle AfcAutoOn"},
03940     { MODEM_FSK, "syncw", cmd_fsk_syncword, "<hex bytes>", "get/set syncword"},
03941     { MODEM_FSK, "syncon", cmd_fsk_syncOn, "", "toggle SyncOn (frame sync, SFD enable)"},
03942     { MODEM_FSK, "bitsync", cmd_fsk_bitsync, "", "toggle BitSyncOn (continuous mode only)"},
03943     { MODEM_FSK, "fifot", cmd_fsk_TxStartCondition, "", "(TX) toggle TxStartCondition"},
03944     { MODEM_FSK, "pktf", cmd_fsk_PacketFormat, "", "toggle PacketFormat fixed/variable length"},
03945     { MODEM_FSK, "poll", cmd_poll_irq_en, "", "toggle poll_irq_en"},
03946     { MODEM_FSK, "prep", cmd_fsk_PreamblePolarity, "", "toggle PreamblePolarity"},
03947     { MODEM_FSK, "datam", cmd_fsk_DataMode, "", "toggle DataMode (packet/continuous)"},    
03948     { MODEM_FSK, "rxt", cmd_rx_trigger, "","(RX) increment RxTrigger"},
03949     { MODEM_FSK, "ook", cmd_ook, "","enter OOK mode"},
03950     { MODEM_FSK, "otx", cmd_ook_tx_test, "","start ook tx repeat"},
03951     { MODEM_FSK, "fei", cmd_fsk_read_fei, "","(RX) read FEI"},
03952     { MODEM_FSK, "fdev", cmd_fsk_fdev, "<kHz>","(TX) get/set fdev"},
03953     { MODEM_FSK, "par", cmd_paRamp, "","(TX) increment paRamp"},
03954     { MODEM_FSK, "pde", cmd_fsk_PreambleDetectorOn, "","(RX) toggle PreambleDetectorOn"},
03955     { MODEM_FSK, "pds", cmd_fsk_PreambleDetectorSize, "<%d>","(RX) get/set PreambleDetectorSize"},
03956     { MODEM_FSK, "pdt", cmd_fsk_PreambleDetectorTol, "<%d>","(RX) get/set PreambleDetectorTol"},
03957     { MODEM_FSK, "thr", cmd_fsk_FifoThreshold, "<%d>","get/set FifoThreshold"},
03958     { MODEM_FSK, "dcf", cmd_fsk_dcfree, "","(RX) increment DcFree"},
03959     { MODEM_FSK, "br", cmd_fsk_bitrate, "<%f kbps>","get/set bitrate"},
03960     { MODEM_FSK, "ac", cmd_AfcClear, "","(RX) AfcClear"},
03961     { MODEM_FSK, "ar", cmd_fsk_AutoRestartRxMode, "","(RX) increment AutoRestartRxMode"},
03962     { MODEM_FSK, "alc", cmd_fsk_AfcAutoClearOn, "","(RX) toggle AfcAutoClearOn"},
03963     { MODEM_FSK, "mp", cmd_MapPreambleDetect, "","(RX) toggle MapPreambleDetect"},
03964     { MODEM_FSK, "rrx", cmd_restart_rx, "","restart RX"},  
03965     { MODEM_BOTH, "op", cmd_op, "<dBm>","(TX) get/set TX power"}, 
03966     { MODEM_FSK, "bt", cmd_bt, "","get/set BT"},  
03967     { MODEM_FSK, "ltx", cmd_long_tx, "<%d>","long tx"},
03968     
03969 #ifdef LORA_TX_TEST
03970     { MODEM_LORA, "apl", cmd_lora_all_payload_lengths, "","(TXTEST) sweep payload lengths 0->255"},
03971     { MODEM_LORA, "csn", cmd_lora_sync_sweep, "[12]","(TXTEST) sweep ppg symbol"},
03972     { MODEM_LORA, "ss", cmd_lora_sync_lo_nibble, "","(TXTEST) ppg low nibble"},
03973     { MODEM_LORA, "cpl", lora_cycle_payload_length, "[%d stop]","(TXTEST) sweep payload length"},
03974     { MODEM_LORA, "ro", cmd_lora_data_ramp, "[%d bytes]","(TXTEST) sweep payload data"},
03975     { MODEM_LORA, "ccr", cmd_lora_cycle_codingrates, "","(TXTEST) cycle coding rates"},
03976     { MODEM_LORA, "fps", cmd_lora_fixed_payload_symbol, "[symbol_num n_bits]","(TXTEST) sweep symbol, n_bits=bits per symbol set (sf8=24, sf9=28, etc)"},    
03977     { MODEM_LORA, "fpo", cmd_fixed_payload_offset, "<nbytes>","(TXTEST) padding offset for fp tests"},
03978     { MODEM_LORA, "fp", cmd_lora_fixed_payload, "[bytes]","(TXTEST) fixed payload"},
03979     { MODEM_LORA, "tab", cmd_lora_toggle_all_bits, "[byte length]","(TXTEST) toggle all bits"},
03980     { MODEM_LORA, "tcrc", cmd_lora_toggle_crcOn, "","(TXTEST) toggle crcOn"},
03981     { MODEM_LORA, "thm", cmd_lora_toggle_header_mode, "","(TXTEST) toggle explicit/implicit"},
03982 #endif /* LORA_TX_TEST */ 
03983     
03984     { MODEM_BOTH, "ttr", cmd_tx_ticker_rate, "<%f seconds>","(TXTEST) get/set tx_ticker rate"},
03985     { MODEM_LORA, "cadper", cmd_cadper, "","Eiger PER RX using CAD" },
03986     { MODEM_LORA, "cad", cmd_cad, "<%d num tries>","(RX) run channel activity detection" },
03987     { MODEM_LORA, "iqinv", cmd_lora_rx_invert, "","(RX) toggle RX IQ invert" },
03988     { MODEM_LORA, "cin", cmd_lora_tx_invert, "","(TX) toggle TX IQ invert" },   
03989     { MODEM_LORA, "lhp", cmd_hop_period, "<%d>","(RX) get/set hop period"},
03990     { MODEM_LORA, "sync", cmd_lora_ppg, "<%x>","get/set sync (post-preamble gap)"},
03991     { MODEM_LORA, "cr", cmd_codingRate, "<1-4>","get/set codingRate"},
03992     { MODEM_LORA, "lhm", cmd_lora_header_mode, "","toggle explicit/implicit"},
03993     { MODEM_LORA, "vh", cmd_lora_poll_validHeader, "","toggle polling of validHeader"},
03994     { MODEM_LORA, "sf", cmd_lora_sf, "<%d>","get/set spreadingFactor"}, 
03995     { MODEM_LORA, "ldr", cmd_LowDataRateOptimize, "","toggle LowDataRateOptimize"}, 
03996     { MODEM_LORA, "txc", cmd_lora_continuous_tx, "","(TX) toggle TxContinuousMode"},
03997     { MODEM_BOTH, "tx", cmd_tx, "<%d>","transmit packet. optional payload length"},    
03998     { MODEM_BOTH, "bw", cmd_bandwidth, "<kHz>","get/set bandwith"},
03999     { MODEM_LORA, "rxt", cmd_rx_timeout, "<%d>","(RX) get/set SymbTimeout"},
04000     { MODEM_LORA, "rxs", cmd_rx_single, "","start RX_SINGLE"},
04001     { MODEM_BOTH, "rx", cmd_rx, "","start RX"},   
04002         
04003     { MODEM_BOTH, "h", cmd_hw_reset, "","hardware reset"},
04004     { MODEM_BOTH, "i", cmd_init, "","initialize radio driver"},
04005     { MODEM_BOTH, "R", cmd_read_all_regs, "","read all radio registers"},
04006     { MODEM_BOTH, "r", cmd_radio_reg_read, "[%x]","read single radio register"},
04007     { MODEM_BOTH, "w", cmd_radio_reg_write, "[%x %x]","write single radio register"},
04008 
04009     { MODEM_BOTH, "L", cmd_toggle_modem, "","toggle between LoRa / FSK"},   
04010     { MODEM_FSK, "E", cmd_empty_fifo, "","empty out FIFO"}, 
04011     { MODEM_FSK, "c", cmd_fsk_test_case, "<%d>","get/set test cases"},
04012     { MODEM_BOTH, "d", cmd_set_dio, "<%d pin num>","increment dio mapping"},
04013     { MODEM_BOTH, ".", cmd_print_status, "","print status"},
04014     { MODEM_BOTH, "?", cmd_help, "","this list of commands"},
04015     { MODEM_BOTH, NULL, NULL, NULL, NULL }
04016 };
04017 
04018 void cmd_help(uint8_t args_at)
04019 {
04020     int i;
04021     
04022     for (i = 0; menu_items[i].cmd != NULL ; i++) {
04023         if (menu_items[i].modem == MODEM_BOTH)
04024             printf("%s%s\t%s\r\n", menu_items[i].cmd, menu_items[i].arg_descr, menu_items[i].description);
04025     }
04026     
04027     if (radio.RegOpMode.bits.LongRangeMode) {
04028         for (i = 0; menu_items[i].cmd != NULL ; i++) {
04029             if (menu_items[i].modem == MODEM_LORA)
04030                 printf("%s%s\t(LoRa) %s\r\n", menu_items[i].cmd, menu_items[i].arg_descr, menu_items[i].description);            
04031         }
04032     } else {
04033         for (i = 0; menu_items[i].cmd != NULL ; i++) {
04034             if (menu_items[i].modem == MODEM_FSK)
04035                 printf("%s%s\t(FSK) %s\r\n", menu_items[i].cmd, menu_items[i].arg_descr, menu_items[i].description);
04036         }
04037     }
04038 }
04039 
04040 void
04041 console()
04042 {
04043     int i;
04044     uint8_t user_cmd_len;
04045     
04046     if (poll_irq_en)
04047         poll_service_radio();
04048     else
04049         service_radio();    
04050         
04051     if (pcbuf_len < 0) {
04052         printf("abort\r\n");
04053         rx_payloadReady_int_en = false;
04054         cadper_enable = false;
04055         per_en = false;
04056         pcbuf_len = 0;
04057         if ((radio.RegOpMode.bits.Mode != RF_OPMODE_SLEEP) && (radio.RegOpMode.bits.Mode != RF_OPMODE_STANDBY)) {
04058             radio.set_opmode(RF_OPMODE_STANDBY);
04059         }
04060         on_txdone_state = ON_TXDONE_STATE_NONE;
04061         tx_ticker.detach();
04062         return;
04063     }
04064     if (pcbuf_len == 0)
04065         return;
04066         
04067     printf("\r\n");
04068         
04069     /* get end of user-entered command */
04070     user_cmd_len = 1;   // first character can be any character
04071     for (i = 1; i <= pcbuf_len; i++) {
04072         if (pcbuf[i] < 'A' || (pcbuf[i] > 'Z' && pcbuf[i] < 'a') || pcbuf[i] > 'z') {
04073             user_cmd_len = i;
04074             break;
04075         }
04076     }
04077 
04078     for (i = 0; menu_items[i].cmd != NULL ; i++) {
04079         int mi_len = strlen(menu_items[i].cmd);
04080         if (radio.RegOpMode.bits.LongRangeMode) {
04081             if (menu_items[i].modem == MODEM_FSK)
04082                 continue;  // FSK commands not used in LoRa
04083         } else {
04084             if (menu_items[i].modem == MODEM_LORA)
04085                 continue;  // LoRa commands not used in FSK            
04086         }
04087 
04088         if (menu_items[i].handler && user_cmd_len == mi_len && (strncmp(pcbuf, menu_items[i].cmd, mi_len) == 0)) {
04089             while (pcbuf[mi_len] == ' ')   // skip past spaces
04090                 mi_len++;
04091             menu_items[i].handler(mi_len);
04092             break;
04093         }
04094     }
04095    
04096     pcbuf_len = 0;
04097     printf("> ");
04098     fflush(stdout); 
04099 }
04100 
04101 void rx_callback()
04102 {
04103     static uint8_t pcbuf_idx = 0;
04104     static uint8_t prev_len = 0;;
04105     char c = pc.getc();
04106     /*if (kermit.uart_rx_enabled) {
04107         kermit.rx_callback(c);
04108     } else*/ {
04109         if (c == 8) {
04110             if (pcbuf_idx > 0) {
04111                 pc.putc(8);
04112                 pc.putc(' ');
04113                 pc.putc(8);
04114                 pcbuf_idx--;
04115             }
04116         } else if (c == 3) {    // ctrl-C
04117             pcbuf_len = -1;
04118         } else if (c == '\r') {
04119             if (pcbuf_idx == 0) {
04120                 pcbuf_len = prev_len;
04121             } else {
04122                 pcbuf[pcbuf_idx] = 0;   // null terminate
04123                 prev_len = pcbuf_idx;
04124                 pcbuf_idx = 0;
04125                 pcbuf_len = prev_len;
04126             }
04127         }/* else if (c == SOH) {
04128             kermit.uart_rx_enable();
04129         }*/ else if (pcbuf_idx < sizeof(pcbuf)) {
04130             pcbuf[pcbuf_idx++] = c;
04131             pc.putc(c);
04132         }
04133     }
04134 }
04135 
04136 int main()
04137 {    
04138 #if defined(TARGET_NUCLEO_L152RE) && defined(USE_DEBUGGER)
04139     DBGMCU_Config(DBGMCU_SLEEP,   ENABLE);
04140     DBGMCU_Config(DBGMCU_STOP,    ENABLE);
04141     DBGMCU_Config(DBGMCU_STANDBY, ENABLE);
04142 #endif
04143 
04144     pc.baud(57600);
04145     printf("\r\nmain()\r\n");
04146     
04147     pc.attach(rx_callback);
04148     
04149     make_crc_table();
04150     
04151 #if !defined(TARGET_MTS_MDOT_F411RE) && !defined(TARGET_DISCO_L072CZ_LRWAN1)
04152     rfsw.input();
04153     if (rfsw.read()) {
04154         shield_type = SHIELD_TYPE_LAS;
04155         printf("LAS\r\n");
04156     } else {
04157         shield_type = SHIELD_TYPE_MAS;
04158         printf("MAS\r\n");
04159     }
04160     
04161     rfsw.output();
04162 #endif /* !TARGET_MTS_MDOT_F411RE */    
04163     radio.rf_switch = rfsw_callback;
04164     
04165 #ifdef FSK_PER
04166     fsk.enable(false);
04167     fsk.RegSyncConfig.octet = radio.read_reg(REG_FSK_SYNCCONFIG);    
04168     fsk.RegSyncConfig.bits.SyncSize = 2;
04169     radio.write_reg(REG_FSK_SYNCCONFIG, fsk.RegSyncConfig.octet);
04170     radio.write_reg(REG_FSK_SYNCVALUE3, 0x90);
04171     radio.write_reg(REG_FSK_SYNCVALUE2, 0x4e);
04172     radio.write_reg(REG_FSK_SYNCVALUE1, 0x63);  
04173     
04174     fsk.RegPreambleDetect.bits.PreambleDetectorOn = 1;
04175     fsk.RegPreambleDetect.bits.PreambleDetectorSize = 1;
04176     fsk.RegPreambleDetect.bits.PreambleDetectorTol = 10;
04177     radio.write_reg(REG_FSK_PREAMBLEDETECT, fsk.RegPreambleDetect.octet);     
04178     
04179     fsk.RegRxConfig.octet = radio.read_reg(REG_FSK_RXCONFIG);
04180     fsk.RegRxConfig.bits.AfcAutoOn = 1;
04181     fsk.RegRxConfig.bits.AgcAutoOn = 1;
04182     fsk.RegRxConfig.bits.RxTrigger = 7;
04183     radio.write_reg(REG_FSK_RXCONFIG, fsk.RegRxConfig.octet);   
04184     
04185     radio.set_opmode(RF_OPMODE_STANDBY);
04186     fsk.set_rx_dcc_bw_hz(41666, 1);  // afcbw
04187     fsk.set_rx_dcc_bw_hz(20833, 0);  // rxbw
04188     
04189     fsk.set_tx_fdev_hz(10000);
04190     
04191     radio.write_u16(REG_FSK_PREAMBLEMSB, 8);
04192     
04193     fsk.RegPktConfig2.bits.PayloadLength = 64;
04194     radio.write_u16(REG_FSK_PACKETCONFIG2, fsk.RegPktConfig2.word);    
04195     
04196     radio.RegDioMapping2.octet = radio.read_reg(REG_DIOMAPPING2);
04197     radio.RegDioMapping2.bits.Dio5Mapping = 2;  // data output to observation
04198     radio.RegDioMapping2.bits.Dio4Mapping = 3;  // output preamble detect indication
04199     radio.RegDioMapping2.bits.MapPreambleDetect = 1;
04200     radio.write_reg(REG_DIOMAPPING2, radio.RegDioMapping2.octet);    
04201     
04202     RegPreambleDetect.bits.PreambleDetectorOn = 1;
04203     RegPreambleDetect.bits.PreambleDetectorSize = 1;
04204     RegPreambleDetect.bits.PreambleDetectorTol = 10;
04205     write_reg(REG_FSK_PREAMBLEDETECT, RegPreambleDetect.octet);  
04206                 
04207 #endif /* FSK_PER */
04208 
04209 #ifdef START_EIGER_TX
04210     uint8_t addr;
04211     radio.set_frf_MHz(915.0);
04212     
04213     radio.RegOcp.octet = radio.read_reg(REG_OCP);    
04214     radio.RegOcp.bits.OcpTrim = 20;
04215     radio.write_reg(REG_OCP, radio.RegOcp.octet);
04216     
04217     RegPdsTrim1_t pds_trim;
04218     if (radio.type == SX1276)
04219         addr = REG_PDSTRIM1_SX1276;
04220     else
04221         addr = REG_PDSTRIM1_SX1272;
04222         
04223     pds_trim.octet = radio.read_reg(addr);
04224     pds_trim.bits.prog_txdac = 7;
04225     radio.write_reg(addr, pds_trim.octet);          
04226                   
04227 #ifndef FSK_PER
04228     lora.enable();
04229     lora.setSf(10);
04230     if (radio.type == SX1276)
04231         lora.setBw(7);  // 7 == 125khz
04232 #endif
04233     
04234     toggle_per_en();
04235     PacketTxCnt = 0;
04236     per_timeout.attach(&per_cb, per_tx_delay);
04237 #endif /* START_EIGER_TX */
04238 
04239 #ifdef START_EIGER_RX
04240 
04241     radio.set_frf_MHz(915.0);
04242     radio.RegPaConfig.bits.PaSelect = 1;    // 0: use RFO for sx1276 shield,  1==PA_BOOST
04243     radio.write_reg(REG_PACONFIG, radio.RegPaConfig.octet);   
04244     
04245     toggle_per_en();
04246     PacketNormalCnt = 0;
04247     PacketRxSequencePrev = 0;
04248     PacketPerKoCnt = 0;
04249     PacketPerOkCnt = 0;       
04250     
04251 #ifndef FSK_PER
04252     lora.enable();
04253     lora.setSf(10); 
04254     if (radio.type == SX1276)
04255         lora.setBw(7);  // 7 == 125khz
04256     lora.start_rx();
04257 #else
04258     fsk.start_rx();
04259     radio.RegDioMapping1.bits.Dio2Mapping = 3;  // dio2 to syncadrs
04260     radio.write_reg(REG_DIOMAPPING1, radio.RegDioMapping1.octet); 
04261     
04262     if (radio.HF) {
04263         fsk.RegRssiConfig.octet = radio.read_reg(REG_FSK_RSSICONFIG);
04264         fsk.RegRssiConfig.bits.RssiOffset = FSK_RSSI_OFFSET;
04265         fsk.RegRssiConfig.bits.RssiSmoothing = FSK_RSSI_SMOOTHING;        
04266         radio.write_reg(REG_FSK_RSSICONFIG, fsk.RegRssiConfig.octet);
04267     }
04268 #endif
04269 
04270     if (radio.HF) {
04271         radio.RegLna.bits.LnaBoostHF = 3;
04272         radio.write_reg(REG_LNA, radio.RegLna.octet);
04273     }
04274 
04275 #endif /* START_EIGER_RX */
04276 
04277     (void)radio.get_frf_MHz();
04278     radio.RegPaConfig.octet = radio.read_reg(REG_PACONFIG);
04279 #if defined(TARGET_MTS_MDOT_F411RE)
04280     radio.RegPaConfig.bits.PaSelect = 1;    // mDot uses PA_BOOST
04281 #else
04282     if (shield_type == SHIELD_TYPE_LAS) {
04283         // LAS HF=PA_BOOST  LF=RFO
04284         if (radio.HF)
04285             radio.RegPaConfig.bits.PaSelect = 1;
04286         else
04287             radio.RegPaConfig.bits.PaSelect = 0;
04288     } else if (shield_type == SHIELD_TYPE_MAS) {
04289         // MAS HF=RFO  LF=RFO
04290         radio.RegPaConfig.bits.PaSelect = 0;        
04291     }
04292 #endif
04293     radio.RegPaConfig.bits.OutputPower = 15;
04294     radio.write_reg(REG_PACONFIG, radio.RegPaConfig.octet);
04295       
04296 #ifdef START_OOK_TX_TEST
04297     cmd_ook_tx_test(0);
04298 #endif /* START_OOK_TX_TEST */
04299 
04300     while(1) {
04301         switch (app) {
04302             case APP_NONE:
04303                 console();
04304                 break;
04305             case APP_CHAT:
04306                 console_chat();
04307                 break;
04308         } // ...switch (app)
04309 
04310 #if TARGET_NUCLEO_L152RE        
04311         //sleep();
04312 #endif
04313     } // ...while(1)
04314 }
04315