Terminal for sending and receiving data via Semtech SX1276 chip. It uses the FRDM-KL25Z board, with a Modtronix inAir9 SX1276 board, and Modtronix SHD3I shield. The inAir9 module is mounted in iMod port 3 of the SHD3I module. The SHD3I shield is mounted on the FRDM-KL25Z board.

Dependencies:   SX127x_modtronix mbed

Fork of chat_sx127x by wayne roberts

Revision:
1:1cd0afbed23c
Parent:
0:be215de91a68
Child:
2:c6b23a43a9d9
--- a/main.cpp	Wed Mar 26 01:13:30 2014 +0000
+++ b/main.cpp	Wed Apr 30 22:51:34 2014 +0000
@@ -1,4 +1,5 @@
-#include "sx127x.h"
+#include "sx127x_lora.h"
+#include "sx127x_fsk.h"
 
 /*
  * http://mbed.org/handbook/mbed-FRDM-KL25Z
@@ -19,8 +20,6 @@
 app_e app = APP_NONE;
 
 
-/*const uint32_t my_frf_a = 914.0 / FREQ_STEP_MHZ;
-const uint32_t my_frf_b = 915.0 / FREQ_STEP_MHZ;*/
 const uint32_t frfs[] = {
     MHZ_TO_FRF(903.0),
     MHZ_TO_FRF(904.0),
@@ -37,11 +36,15 @@
     MHZ_TO_FRF(915.0)
 };
 
+#define FSK_LARGE_PKT_THRESHOLD  0x3f
+
 /******************************************************************************/
 
-//  pin:      3     8     1      7    10    12     5   20    18
+//  pin:       3     8     1      7    10    12     5   20    18
 //           mosi, miso, sclk,   cs,  rst,  dio0, dio1, fctx, fcps 
 SX127x radio(PTD2, PTD3, PTD1, PTD0, PTD5, PTA13, PTD4, PTC9, PTC8);
+SX127x_fsk fsk(radio);
+SX127x_lora lora(radio);
 
 void printLoraIrqs_(bool clear)
 {
@@ -49,35 +52,35 @@
 
     //already read RegIrqFlags.octet = radio.read_reg(REG_LR_IRQFLAGS);
     printf("\r\nIrqFlags:");
-    if (radio.RegIrqFlags.bits.CadDetected)
+    if (lora.RegIrqFlags.bits.CadDetected)
         printf("CadDetected ");
-    if (radio.RegIrqFlags.bits.FhssChangeChannel) {
+    if (lora.RegIrqFlags.bits.FhssChangeChannel) {
         //radio.RegHopChannel.octet = radio.read_reg(REG_LR_HOPCHANNEL);
-        printf("FhssChangeChannel:%d ", radio.RegHopChannel.bits.FhssPresentChannel);
+        printf("FhssChangeChannel:%d ", lora.RegHopChannel.bits.FhssPresentChannel);
     }
-    if (radio.RegIrqFlags.bits.CadDone)
+    if (lora.RegIrqFlags.bits.CadDone)
         printf("CadDone ");
-    if (radio.RegIrqFlags.bits.TxDone)
+    if (lora.RegIrqFlags.bits.TxDone)
         printf("TxDone ");
-    if (radio.RegIrqFlags.bits.ValidHeader)
+    if (lora.RegIrqFlags.bits.ValidHeader)
         printf("ValidHeader ");
-    if (radio.RegIrqFlags.bits.PayloadCrcError)
+    if (lora.RegIrqFlags.bits.PayloadCrcError)
         printf("PayloadCrcError ");
-    if (radio.RegIrqFlags.bits.RxDone)
+    if (lora.RegIrqFlags.bits.RxDone)
         printf("RxDone ");  
-    if (radio.RegIrqFlags.bits.RxTimeout)
+    if (lora.RegIrqFlags.bits.RxTimeout)
         printf("RxTimeout ");
 
     printf("\r\n");
 
     if (clear)
-        radio.write_reg(REG_LR_IRQFLAGS, radio.RegIrqFlags.octet);
+        radio.write_reg(REG_LR_IRQFLAGS, lora.RegIrqFlags.octet);
 
 }
 
-void printCodingRate(bool from_rx)
+void lora_printCodingRate(bool from_rx)
 {
-    uint8_t d = radio.getCodingRate(from_rx);
+    uint8_t d = lora.getCodingRate(from_rx);
     printf("CodingRate:");
     switch (d) {
         case 1: printf("4/5 "); break;
@@ -90,21 +93,21 @@
     }
 }
 
-void printHeaderMode()
+void lora_printHeaderMode()
 {
-    if (radio.getHeaderMode())
+    if (lora.getHeaderMode())
         printf("implicit ");
     else
         printf("explicit ");
 }
 
-void printBw()
+void lora_printBw()
 {
-    uint8_t bw = radio.getBw();
+    uint8_t bw = lora.getBw();
     
     printf("Bw:");
     if (radio.type == SX1276) {
-        switch (radio.RegModemConfig.sx1276bits.Bw) {
+        switch (lora.RegModemConfig.sx1276bits.Bw) {
             case 0: printf("7.8KHz "); break;
             case 1: printf("10.4KHz "); break;
             case 2: printf("15.6KHz "); break;
@@ -115,10 +118,10 @@
             case 7: printf("125KHz "); break;
             case 8: printf("250KHz "); break;
             case 9: printf("500KHz "); break;
-            default: printf("%x ", radio.RegModemConfig.sx1276bits.Bw); break;
+            default: printf("%x ", lora.RegModemConfig.sx1276bits.Bw); break;
         }
     } else if (radio.type == SX1272) {
-        switch (radio.RegModemConfig.sx1272bits.Bw) {
+        switch (lora.RegModemConfig.sx1272bits.Bw) {
             case 0: printf("125KHz "); break;
             case 1: printf("250KHz "); break;
             case 2: printf("500KHz "); break;
@@ -127,40 +130,40 @@
     }
 }
 
-void printAllBw()
+void lora_printAllBw()
 {
     int i, s;
     
     if (radio.type == SX1276) {
-        s = radio.RegModemConfig.sx1276bits.Bw;    
+        s = lora.RegModemConfig.sx1276bits.Bw;    
         for (i = 0; i < 10; i++ ) {
-            radio.RegModemConfig.sx1276bits.Bw = i;
+            lora.RegModemConfig.sx1276bits.Bw = i;
             printf("%d ", i);
-            printBw();
+            lora_printBw();
             printf("\r\n");
         }
-        radio.RegModemConfig.sx1276bits.Bw = s;
+        lora.RegModemConfig.sx1276bits.Bw = s;
     } else if (radio.type == SX1272) {
-        s = radio.RegModemConfig.sx1272bits.Bw;    
+        s = lora.RegModemConfig.sx1272bits.Bw;    
         for (i = 0; i < 3; i++ ) {
-            radio.RegModemConfig.sx1272bits.Bw = i;
+            lora.RegModemConfig.sx1272bits.Bw = i;
             printf("%d ", i);
-            printBw();
+            lora_printBw();
             printf("\r\n");
         }
-        radio.RegModemConfig.sx1272bits.Bw = s;    
+        lora.RegModemConfig.sx1272bits.Bw = s;    
     }
 }
 
-void printSf()
+void lora_printSf()
 {
     // spreading factor same between sx127[26]
-    printf("sf:%d ", radio.getSf());
+    printf("sf:%d ", lora.getSf());
 }
 
-void printRxPayloadCrcOn()
+void lora_printRxPayloadCrcOn()
 {
-    bool on = radio.getRxPayloadCrcOn();
+    bool on = lora.getRxPayloadCrcOn();
     //printf("RxPayloadCrcOn:%s ", on ? "on" : "off");
     if (on)
         printf("RxPayloadCrcOn:1 = Tx CRC Enabled\r\n");
@@ -168,19 +171,19 @@
         printf("RxPayloadCrcOn:1 = no Tx CRC\r\n");
 }
 
-void printTxContinuousMode()
+void lora_printTxContinuousMode()
 {
-    printf("TxContinuousMode:%d ", radio.RegModemConfig2.sx1276bits.TxContinuousMode);    // same for sx1272 and sx1276
+    printf("TxContinuousMode:%d ", lora.RegModemConfig2.sx1276bits.TxContinuousMode);    // same for sx1272 and sx1276
 }
 
-void printAgcAutoOn()
+void lora_printAgcAutoOn()
 {
-    printf("AgcAutoOn:%d", radio.getAgcAutoOn());
+    printf("AgcAutoOn:%d", lora.getAgcAutoOn());
 }
 
-void print_dio()
+void lora_print_dio()
 {
-       radio.RegDioMapping2.octet = radio.read_reg(REG_DIOMAPPING2);
+    radio.RegDioMapping2.octet = radio.read_reg(REG_DIOMAPPING2);
     printf("DIO5:");
     switch (radio.RegDioMapping2.bits.Dio5Mapping) {
         case 0: printf("ModeReady"); break;
@@ -224,6 +227,110 @@
     printf("\r\n"); 
 }
 
+void fsk_print_dio()
+{
+    radio.RegDioMapping2.octet = radio.read_reg(REG_DIOMAPPING2);
+    
+    switch (radio.RegDioMapping2.bits.Dio5Mapping) {
+        case 0: printf("ClkOut"); break;
+        case 1: printf("PllLock"); break;
+        case 2:
+            if (fsk.RegPktConfig2.bits.DataModePacket)
+                printf("data");
+            else {
+                if (radio.RegDioMapping2.bits.MapPreambleDetect)
+                    printf("preamble");
+                else
+                    printf("rssi");
+            }
+            break;
+        case 3: printf("ModeReady"); break;
+    }
+    
+    switch (radio.RegDioMapping2.bits.Dio4Mapping) {
+        case 0: printf("temp/eol"); break;
+        case 1: printf("PllLock"); break;
+        case 2: printf("TimeOut"); break;
+        case 3:
+            if (fsk.RegPktConfig2.bits.DataModePacket) {
+                if (radio.RegDioMapping2.bits.MapPreambleDetect)
+                    printf("preamble");
+                else
+                    printf("rssi");
+            } else
+                printf("ModeReady");
+            break;
+    }
+    
+    radio.RegDioMapping1.octet = radio.read_reg(REG_DIOMAPPING1);
+    
+    switch (radio.RegDioMapping1.bits.Dio3Mapping) {
+        case 0: printf("Timeout"); break;
+        case 1:
+            if (radio.RegDioMapping2.bits.MapPreambleDetect)
+                printf("preamble");
+            else
+                printf("rssi");
+            break;
+        case 2: printf("?automode_status?"); break;
+        case 3: printf("TempChange/LowBat"); break;
+    }
+    
+    if (fsk.RegPktConfig2.bits.DataModePacket) {
+        switch (radio.RegDioMapping1.bits.Dio2Mapping) {
+            case 0: printf("FifoFull"); break;
+            case 1: printf("RxReady"); break;
+            case 2: printf("FifoFull/rx-timeout"); break;
+            case 3: printf("FifoFull/rx-syncadrs"); break;
+        }
+    } else {
+        printf("Data");
+    }
+    
+    if (fsk.RegPktConfig2.bits.DataModePacket) {
+        switch (radio.RegDioMapping1.bits.Dio1Mapping) {
+            case 0: printf("FifoThresh"); break;
+            case 1: printf("FifoEmpty"); break;
+            case 2: printf("FifoFull"); break;
+            case 3: printf("-3-"); break;
+        }
+    } else {
+        switch (radio.RegDioMapping1.bits.Dio1Mapping) {
+            case 0: printf("Dclk"); break;
+            case 1:
+                if (radio.RegDioMapping2.bits.MapPreambleDetect)
+                    printf("preamble");
+                else
+                    printf("rssi");
+                break;
+            case 2: printf("-2-"); break;
+            case 3: printf("-3-"); break;
+        }
+    }
+    
+    if (fsk.RegPktConfig2.bits.DataModePacket) {
+        switch (radio.RegDioMapping1.bits.Dio0Mapping) {
+            case 0: printf("PayloadReady/PacketSent"); break;
+            case 1: printf("CrcOk"); break;
+            case 2: printf("-2-"); break;
+            case 3: printf("TempChange/LowBat"); break;
+        }
+    } else {
+        switch (radio.RegDioMapping1.bits.Dio0Mapping) {
+            case 0: printf("SyncAdrs/TxReady"); break;
+            case 1:
+                if (radio.RegDioMapping2.bits.MapPreambleDetect)
+                    printf("preamble");
+                else
+                    printf("rssi");
+                break;
+            case 2: printf("RxReady"); break;
+            case 3: printf("-3-"); break;
+        }
+    }
+    printf("\r\n"); 
+}
+
 void lora_print_status()
 {
     uint8_t d;
@@ -239,45 +346,45 @@
         return;
     }
     
-    print_dio();
+    lora_print_dio();
     printf("LoRa ");
     
     // printing LoRa registers at 0x0d -> 0x3f
 
-    radio.RegModemConfig.octet = radio.read_reg(REG_LR_MODEMCONFIG);
-    radio.RegModemConfig2.octet = radio.read_reg(REG_LR_MODEMCONFIG2);
+    lora.RegModemConfig.octet = radio.read_reg(REG_LR_MODEMCONFIG);
+    lora.RegModemConfig2.octet = radio.read_reg(REG_LR_MODEMCONFIG2);
 
-    printCodingRate(false); // false: transmitted coding rate
-    printHeaderMode();
-    printBw();
-    printSf();
-    printRxPayloadCrcOn();
+    lora_printCodingRate(false); // false: transmitted coding rate
+    lora_printHeaderMode();
+    lora_printBw();
+    lora_printSf();
+    lora_printRxPayloadCrcOn();
     // RegModemStat
     printf("ModemStat:0x%02x\r\n", radio.read_reg(REG_LR_MODEMSTAT));
 
     // fifo ptrs:
-    radio.RegPayloadLength = radio.read_reg(REG_LR_PAYLOADLENGTH);
-    radio.RegRxMaxPayloadLength = radio.read_reg(REG_LR_RX_MAX_PAYLOADLENGTH);
+    lora.RegPayloadLength = radio.read_reg(REG_LR_PAYLOADLENGTH);
+    lora.RegRxMaxPayloadLength = radio.read_reg(REG_LR_RX_MAX_PAYLOADLENGTH);
     printf("fifoptr=0x%02x txbase=0x%02x rxbase=0x%02x payloadLength=0x%02x maxlen=0x%02x",
         radio.read_reg(REG_LR_FIFOADDRPTR),
         radio.read_reg(REG_LR_FIFOTXBASEADDR),
         radio.read_reg(REG_LR_FIFORXBASEADDR),
-        radio.RegPayloadLength,
-        radio.RegRxMaxPayloadLength
+        lora.RegPayloadLength,
+        lora.RegRxMaxPayloadLength
     );
 
-    radio.RegIrqFlags.octet = radio.read_reg(REG_LR_IRQFLAGS);
+    lora.RegIrqFlags.octet = radio.read_reg(REG_LR_IRQFLAGS);
     printLoraIrqs_(false);
 
-    radio.RegHopPeriod = radio.read_reg(REG_LR_HOPPERIOD);
-    if (radio.RegHopPeriod != 0) {
-        printf("\r\nHopPeriod:0x%02x\r\n", radio.RegHopPeriod);
+    lora.RegHopPeriod = radio.read_reg(REG_LR_HOPPERIOD);
+    if (lora.RegHopPeriod != 0) {
+        printf("\r\nHopPeriod:0x%02x\r\n", lora.RegHopPeriod);
     }
 
     printf("SymbTimeout:0x%03x ", radio.read_u16(REG_LR_MODEMCONFIG2) & 0x3ff);
 
-    radio.RegPreamble = radio.read_u16(REG_LR_PREAMBLEMSB);
-    printf("PreambleLength:0x%03x ", radio.RegPreamble);
+    lora.RegPreamble = radio.read_u16(REG_LR_PREAMBLEMSB);
+    printf("PreambleLength:0x%03x ", lora.RegPreamble);
     
 
     if (radio.RegOpMode.bits.Mode == RF_OPMODE_RECEIVER || radio.RegOpMode.bits.Mode == RF_OPMODE_RECEIVER_SINGLE) {
@@ -285,33 +392,429 @@
         printf("rssi:%ddBm ", d-120);
     }
 
-    printTxContinuousMode();
+    lora_printTxContinuousMode();
 
     printf("\r\n");
-    printAgcAutoOn();
+    lora_printAgcAutoOn();
     if (radio.type == SX1272) {
-        printf(" LowDataRateOptimize:%d\r\n", radio.RegModemConfig.sx1272bits.LowDataRateOptimize);
+        printf(" LowDataRateOptimize:%d\r\n", lora.RegModemConfig.sx1272bits.LowDataRateOptimize);
     }
 
     printf("\r\nHeaderCount:%d PacketCount:%d, ",
         radio.read_u16(REG_LR_RXHEADERCNTVALUE_MSB), radio.read_u16(REG_LR_RXPACKETCNTVALUE_MSB));
 
     printf("Lora detection threshold:%02x\r\n", radio.read_reg(REG_LR_DETECTION_THRESHOLD));
-    radio.RegTest31.octet = radio.read_reg(REG_LR_TEST31);
-    printf("detect_trig_same_peaks_nb:%d\r\n", radio.RegTest31.bits.detect_trig_same_peaks_nb);
+    lora.RegTest31.octet = radio.read_reg(REG_LR_TEST31);
+    printf("detect_trig_same_peaks_nb:%d\r\n", lora.RegTest31.bits.detect_trig_same_peaks_nb);
 
     if (radio.type == SX1272) {
-        radio.RegModemConfig.octet = radio.read_reg(REG_LR_MODEMCONFIG);
-        printf("LowDataRateOptimize:%d\r\n", radio.RegModemConfig.sx1272bits.LowDataRateOptimize);
+        lora.RegModemConfig.octet = radio.read_reg(REG_LR_MODEMCONFIG);
+        printf("LowDataRateOptimize:%d\r\n", lora.RegModemConfig.sx1272bits.LowDataRateOptimize);
     } else if (radio.type == SX1276) {
-        radio.RegModemConfig3.octet = radio.read_reg(REG_LR_MODEMCONFIG3);
-        printf("LowDataRateOptimize:%d\r\n", radio.RegModemConfig3.sx1276bits.LowDataRateOptimize);        
+        lora.RegModemConfig3.octet = radio.read_reg(REG_LR_MODEMCONFIG3);
+        printf("LowDataRateOptimize:%d\r\n", lora.RegModemConfig3.sx1276bits.LowDataRateOptimize);        
     }
     
     printf("\r\n");
     //printf("A %02x\r\n", radio.RegModemConfig2.octet);
 }
 
+uint32_t fsk_get_bitrate(void)
+{
+    uint16_t br = radio.read_u16(REG_FSK_BITRATEMSB);
+
+    if (br == 0)
+        return 0;
+    else
+        return XTAL_FREQ / br;
+}
+
+uint32_t fsk_get_tx_fdev_hz(void)
+{
+    uint16_t fdev = radio.read_u16(REG_FSK_FDEVMSB);
+    return fdev * FREQ_STEP_HZ;
+}
+
+uint16_t
+fsk_get_PayloadLength(void)
+{
+    fsk.RegPktConfig2.word = radio.read_u16(REG_FSK_PACKETCONFIG2);
+
+    return fsk.RegPktConfig2.bits.PayloadLength;
+}
+
+void fsk_printAddressFiltering()
+{
+    uint8_t FSKRegNodeAdrs, FSKRegBroadcastAdrs;
+    
+    printf(" AddressFiltering:");
+    switch (fsk.RegPktConfig1.bits.AddressFiltering) {
+        case 0: printf("off"); break;
+        case 1: // NodeAddress
+            FSKRegNodeAdrs = radio.read_reg(REG_FSK_NODEADRS);
+            printf("NodeAdrs:%02x\n", FSKRegNodeAdrs);
+            break;
+        case 2: // NodeAddress & BroadcastAddress
+            FSKRegNodeAdrs = radio.read_reg(REG_FSK_NODEADRS);
+            printf("NodeAdrs:%02x ", FSKRegNodeAdrs);
+            FSKRegBroadcastAdrs = radio.read_reg(REG_FSK_BROADCASTADRS);
+            printf("BroadcastAdrs:%02x\n", FSKRegBroadcastAdrs );
+            break;
+        default:
+            printf("%d", fsk.RegPktConfig1.bits.AddressFiltering);
+            break;
+    }
+}
+
+void fsk_print_IrqFlags2()
+{
+    FSKRegIrqFlags2_t FSKRegIrqFlags2;
+    
+    printf("IrqFlags2: ");
+    FSKRegIrqFlags2.octet = radio.read_reg(REG_FSK_IRQFLAGS2);
+    if (FSKRegIrqFlags2.bits.FifoFull)
+        printf("FifoFull ");
+    if (FSKRegIrqFlags2.bits.FifoEmpty)
+        printf("FifoEmpty ");
+    if (FSKRegIrqFlags2.bits.FifoLevel)
+        printf("FifoLevel ");
+    if (FSKRegIrqFlags2.bits.FifoOverrun)
+        printf("FifoOverrun ");
+    if (FSKRegIrqFlags2.bits.PacketSent)
+        printf("PacketSent ");
+    if (FSKRegIrqFlags2.bits.PayloadReady)
+        printf("PayloadReady ");
+    if (FSKRegIrqFlags2.bits.CrcOk)
+        printf("CrcOk ");
+    if (FSKRegIrqFlags2.bits.LowBat)
+        printf("LowBat ");
+    printf("\n");
+}
+
+void
+fsk_print_status()
+{
+    //uint16_t s;
+    FSKRegIrqFlags1_t FSKRegIrqFlags1;
+    
+    if (radio.RegOpMode.bits.LongRangeMode) {
+        printf("LoRa\r\n");
+        return;
+    }
+    
+    if (radio.RegOpMode.bits.ModulationType == 0) {
+        printf("FSK ");
+        switch (radio.RegOpMode.bits.ModulationShaping) {
+            case 1: printf("BT1.0 "); break;
+            case 2: printf("BT0.5 "); break;
+            case 3: printf("BT0.3 "); break;
+        }
+    } else if (radio.RegOpMode.bits.ModulationType == 1) {
+        printf("OOK ");
+    }
+
+    printf("%dbps fdev:%dHz\r\n", fsk_get_bitrate(), fsk_get_tx_fdev_hz());    
+    
+    fsk.RegPktConfig2.word = radio.read_u16(REG_FSK_PACKETCONFIG2);
+    
+    fsk_print_dio();
+    
+    printf("rxbw:%dHz ", fsk.get_rx_bw_hz(REG_FSK_RXBW));
+    printf("afcbw:%dHz\r\n", fsk.get_rx_bw_hz(REG_FSK_AFCBW));
+
+    fsk.RegRssiConfig.octet = radio.read_reg(REG_FSK_RSSICONFIG);
+    printf("RssiOffset:%ddB smoothing:%dsamples\r\n", fsk.RegRssiConfig.bits.RssiOffset, 1 << (fsk.RegRssiConfig.bits.RssiSmoothing+1));
+
+
+    fsk.RegSyncConfig.octet = radio.read_reg(REG_FSK_SYNCCONFIG);
+
+    if (fsk.RegPktConfig2.bits.DataModePacket) {
+        uint16_t len;
+        /* packet mode */
+        len = fsk_get_PayloadLength();
+        printf("packet RegPayloadLength:0x%03x ", len);
+
+        if (fsk.RegPktConfig2.bits.BeaconOn)
+            printf("BeaconOn ");
+
+        fsk.RegFifoThreshold.octet = radio.read_reg(REG_FSK_FIFOTHRESH);
+        printf("FifoThreshold:%d TxStartCondition:", fsk.RegFifoThreshold.bits.FifoThreshold);
+        if (fsk.RegFifoThreshold.bits.TxStartCondition)
+            printf("!FifoEmpty");
+        else
+            printf("FifoLevel");
+
+        printf("\r\nAutoRestartRxMode:");
+        switch (fsk.RegSyncConfig.bits.AutoRestartRxMode) {
+            case 0: printf("off "); break;
+            case 1: printf("no-pll-wait "); break;
+            case 2: printf("pll-wait "); break;
+            case 3: printf("3 "); break;
+        }
+        //...todo
+
+        printf("PreambleSize:%d ", radio.read_u16(REG_FSK_PREAMBLEMSB));
+
+        fsk.RegOokPeak.octet = radio.read_reg(REG_FSK_OOKPEAK);
+        if (fsk.RegOokPeak.bits.barker_en)
+            printf("barker ");
+        if (!fsk.RegOokPeak.bits.BitSyncOn)
+            printf("BitSyncOff ");
+        //...todo
+
+        fsk.RegPktConfig1.octet = radio.read_reg(REG_FSK_PACKETCONFIG1);
+        if (fsk.RegPktConfig1.bits.PacketFormatVariable)
+            printf("variable");
+        else
+            printf("fixed");
+        printf("-length\r\ncrc");
+        if (fsk.RegPktConfig1.bits.CrcOn) {
+            printf("On");
+        } else
+            printf("Off");
+        printf(" crctype:");
+        if (fsk.RegPktConfig1.bits.CrCWhiteningType)
+            printf("IBM");
+        else
+            printf("CCITT");
+        printf(" dcFree:");
+        switch (fsk.RegPktConfig1.bits.DcFree) {
+            case 0: printf("none "); break;
+            case 1: printf("Manchester "); break;
+            case 2: printf("Whitening "); break;
+            case 3: printf("reserved "); break;
+        }
+        fsk_printAddressFiltering();
+
+        printf("\r\n");
+        fsk_print_IrqFlags2();
+        printf("\r\n");
+    } else {
+        /* continuous mode */
+        printf("continuous ");
+    }
+
+    fsk.RegPreambleDetect.octet = radio.read_reg(REG_FSK_PREAMBLEDETECT);
+    printf("PreambleDetect:");
+    if (fsk.RegPreambleDetect.bits.PreambleDetectorOn) {
+        printf("size=%d,tol=%d ",
+            fsk.RegPreambleDetect.bits.PreambleDetectorSize,
+            fsk.RegPreambleDetect.bits.PreambleDetectorTol);
+    } else
+        printf("Off ");
+
+    printf(" syncsize:%d ", fsk.RegSyncConfig.bits.SyncSize);
+    printf(" : %02x ", radio.read_reg(REG_FSK_SYNCVALUE1));
+    printf("%02x ", radio.read_reg(REG_FSK_SYNCVALUE2));
+    printf("%02x ", radio.read_reg(REG_FSK_SYNCVALUE3));
+    printf("%02x ", radio.read_reg(REG_FSK_SYNCVALUE4));
+    printf("\r\n");   // end sync config
+
+    fsk.RegAfcFei.octet = radio.read_reg(REG_FSK_AFCFEI);
+    printf("afcAutoClear:");
+    if (fsk.RegAfcFei.bits.AfcAutoClearOn)
+        printf("On");
+    else
+        printf("OFF");
+    printf(" afc:%dHz ", (int)(FREQ_STEP_HZ * radio.read_s16(REG_FSK_AFCMSB)));
+
+    printf("fei:%dHz\r\n", (int)(FREQ_STEP_HZ * radio.read_s16(REG_FSK_FEIMSB)));
+
+    fsk.RegRxConfig.octet = radio.read_reg(REG_FSK_RXCONFIG);
+    printf("RxTrigger:");
+    switch (fsk.RegRxConfig.bits.RxTrigger) {
+        case 0: printf("none "); break;
+        case 1: printf("rssi "); break;
+        case 6: printf("preamble "); break;
+        case 7: printf("both "); break;
+        default: printf("-%d- ", fsk.RegRxConfig.bits.RxTrigger); break;
+    }
+    printf("AfcAuto:");
+    if (fsk.RegRxConfig.bits.AfcAutoOn)
+        printf("On ");
+    else
+        printf("OFF ");
+    if (!fsk.RegRxConfig.bits.AgcAutoOn) {
+        radio.RegLna.octet = radio.read_reg(REG_LNA);
+        printf("AgcAutoOff:G%d ", radio.RegLna.bits.LnaGain);
+    }
+
+    fsk.RegTimerResol.octet = radio.read_reg(REG_FSK_TIMERRESOL);
+    if (fsk.RegTimerResol.bits.hlm_started)
+        printf("hlm_started ");
+    else
+        printf("hlm_stopped ");
+
+    fsk.RegRssiThresh = radio.read_reg(REG_FSK_RSSITHRESH);
+    printf("rssiThreshold:-%.1f@%02x ", fsk.RegRssiThresh / 2.0, REG_FSK_RSSITHRESH);
+
+    radio.RegOpMode.octet = radio.read_reg(REG_OPMODE);
+    if (radio.RegOpMode.bits.Mode == RF_OPMODE_RECEIVER ||
+        radio.RegOpMode.bits.Mode == RF_OPMODE_SYNTHESIZER_RX)
+    {
+        printf("rssi:-%.1f ", radio.read_reg(REG_FSK_RSSIVALUE) / 2.0);
+    }
+
+    fsk.RegSeqConfig1.octet = radio.read_reg(REG_FSK_SEQCONFIG1);
+    printf("\r\nsequencer: ");
+    printf("FromStart:");
+    switch (fsk.RegSeqConfig1.bits.FromStart) {
+        case 0:
+            printf("lowPowerSelection-");
+            if (fsk.RegSeqConfig1.bits.LowPowerSelection)
+                printf("idle");
+            else
+                printf("sequencerOff");
+            break;
+        case 1: printf("rx"); break;
+        case 2: printf("tx"); break;
+        case 3: printf("tx on fifolevel"); break;
+    }
+    printf(" lowPowerSelection:");
+    if (fsk.RegSeqConfig1.bits.LowPowerSelection)
+        printf("idle");
+    else
+        printf("SequencerOff");
+    if (fsk.RegSeqConfig1.bits.FromStart != 0 && 
+        fsk.RegSeqConfig1.bits.LowPowerSelection != 0)
+    {   // if sequencer enabled:
+        printf("\r\nsequencer: IdleMode:");
+        if (fsk.RegSeqConfig1.bits.IdleMode)
+            printf("Sleep");
+        else
+            printf("standby");
+        printf("\r\nsequencer: FromIdle to:");
+        if (fsk.RegSeqConfig1.bits.FromIdle)
+            printf("rx");
+        else
+            printf("tx");
+        printf("\r\nsequencer: FromTransmit to:");
+        if (fsk.RegSeqConfig1.bits.FromTransmit)
+            printf("rx-on-PacketSent");
+        else {
+            printf("lowPowerSelection-");
+            if (fsk.RegSeqConfig1.bits.LowPowerSelection)
+                printf("idle");
+            else
+                printf("SequencerOff");
+            printf("-on-PacketSent");
+        }
+        fsk.RegSeqConfig2.octet = radio.read_reg(REG_FSK_SEQCONFIG2);
+        printf("\r\nsequencer: FromReceive:");
+        switch (fsk.RegSeqConfig2.bits.FromReceive) {
+            case 1: printf("PacketRecevied on PayloadReady"); break;
+            case 2: 
+                printf("lowPowerSelection-");
+                if (fsk.RegSeqConfig1.bits.LowPowerSelection)
+                    printf("idle");
+                else
+                    printf("SequencerOff");
+                printf("-on-payloadReady");
+                break;
+            case 3: printf("PacketRecevied-on-CrcOk"); break;
+            case 4: printf("SequencerOff-on-Rssi"); break;
+            case 5: printf("SequencerOff-on-SyncAddress"); break;
+            case 6: printf("SequencerOff-PreambleDetect"); break;
+            default: printf("-%d-", fsk.RegSeqConfig2.bits.FromReceive); break;
+        }
+        printf("\r\nsequencer: FromRxTimeout:");
+        switch (fsk.RegSeqConfig2.bits.FromRxTimeout) {
+            case 0: printf("rx"); break;
+            case 1: printf("tx"); break;
+            case 2:
+                printf("lowPowerSelection-");
+                if (fsk.RegSeqConfig1.bits.LowPowerSelection)
+                    printf("idle");
+                else
+                    printf("SequencerOff");
+                break;
+            case 3: printf("SequencerOff"); break;
+        }
+        printf("\r\nsequencer: FromPacketReceived to:");
+        switch (fsk.RegSeqConfig2.bits.FromPacketReceived) {
+            case 0: printf("SequencerOff"); break;
+            case 1: printf("tx on FifoEmpty"); break;
+            case 2:
+                printf("lowPowerSelection-");
+                if (fsk.RegSeqConfig1.bits.LowPowerSelection)
+                printf("idle");
+                else
+                printf("sequencerOff");
+                break;
+            case 3: printf("rx via fs"); break;
+            case 4: printf("rx"); break;
+        }
+
+        fsk.RegTimerResol.octet = radio.read_reg(REG_FSK_TIMERRESOL);
+        printf("\r\nsequencer: timer1:");
+        switch (fsk.RegTimerResol.bits.timer1_resol) {
+            case 0: printf("off"); break;
+            case 1: printf("%dus", radio.read_reg(REG_FSK_TIMER1COEF) * 64); break;
+            case 2: printf("%.1fms", radio.read_reg(REG_FSK_TIMER1COEF) * 4.1); break;
+            case 3: printf("%.1fs", radio.read_reg(REG_FSK_TIMER1COEF) * 0.262); break;
+        }
+
+        printf(" timer2:");
+        switch (fsk.RegTimerResol.bits.timer2_resol) {
+            case 0: printf("off"); break;
+            case 1: printf("%dus", radio.read_reg(REG_FSK_TIMER2COEF) * 64); break;
+            case 2: printf("%.1fms", radio.read_reg(REG_FSK_TIMER2COEF) * 4.1); break;
+            case 3: printf("%.1fs", radio.read_reg(REG_FSK_TIMER2COEF) * 0.262); break;
+        }
+    } // ..if sequencer enabled
+
+    printf("\r\nIrqFlags1:");
+    FSKRegIrqFlags1.octet = radio.read_reg(REG_FSK_IRQFLAGS1);
+    if (FSKRegIrqFlags1.bits.ModeReady)
+        printf("ModeReady ");
+    if (FSKRegIrqFlags1.bits.RxReady)
+        printf("RxReady ");
+    if (FSKRegIrqFlags1.bits.TxReady)
+        printf("TxReady ");
+    if (FSKRegIrqFlags1.bits.PllLock)
+        printf("PllLock ");
+    if (FSKRegIrqFlags1.bits.Rssi)
+        printf("Rssi ");
+    if (FSKRegIrqFlags1.bits.Timeout)
+        printf("Timeout ");
+    if (FSKRegIrqFlags1.bits.PreambleDetect)
+        printf("PreambleDetect ");
+    if (FSKRegIrqFlags1.bits.SyncAddressMatch)
+        printf("SyncAddressMatch ");
+
+    printf("\r\n");
+
+/* TODO    if (!SX1272FSK->RegPktConfig1.bits.PacketFormatVariable) { // if fixed-length packet format:
+        s = fsk_get_PayloadLength();
+        if (s > FSK_LARGE_PKT_THRESHOLD)
+            flags.fifo_flow_ctl = 1;
+        else
+            flags.fifo_flow_ctl = 0;
+    }*/
+
+    fsk.RegImageCal.octet = radio.read_reg(REG_FSK_IMAGECAL);
+    if (fsk.RegImageCal.bits.TempMonitorOff) {
+        printf("TempMonitorOff[\r0m\n");
+    } else {
+        printf("TempThreshold:");
+        switch (fsk.RegImageCal.bits.TempThreshold) {
+            case 0: printf("5C"); break;
+            case 1: printf("10C"); break;
+            case 2: printf("15C"); break;
+            case 3: printf("20C"); break;
+        }
+        printf("\r\n");
+    }
+    if (fsk.RegImageCal.bits.ImageCalRunning)
+        printf("ImageCalRunning[\r0m\n");
+
+/*    printf("flags.fifo_flow_ctl:%d pktidx:%d rx_pktlen:%d", flags.fifo_flow_ctl, pktidx, rx_pktlen);
+    printf("\n");
+
+    //printf("DIO0_PIN:%d\n", digitalRead(DIO0_PIN));
+    printf("pkt_buf_len=%d remaining=%d\n", pk*/
+}
+
 void printOpMode()
 {
     radio.RegOpMode.octet = radio.read_reg(REG_OPMODE);
@@ -394,51 +897,65 @@
 void
 service_radio()
 {
-    service_action_e act = radio.service();
+    service_action_e act;
+    
+    if (radio.RegOpMode.bits.LongRangeMode) {
+        act = lora.service();
     
-    switch (act) {
-        case SERVICE_READ_FIFO:
-            if (app == APP_NONE) {     
-                printLoraIrqs_(false);
-                if (radio.RegHopPeriod > 0) {
-                    radio.RegHopChannel.octet = radio.read_reg(REG_LR_HOPCHANNEL);
-                    printf("HopCH:%d ", radio.RegHopChannel.bits.FhssPresentChannel);
+        switch (act) {
+            case SERVICE_READ_FIFO:
+                float dbm;
+                if (app == APP_NONE) {     
+                    printLoraIrqs_(false);
+                    if (lora.RegHopPeriod > 0) {
+                        lora.RegHopChannel.octet = radio.read_reg(REG_LR_HOPCHANNEL);
+                        printf("HopCH:%d ", lora.RegHopChannel.bits.FhssPresentChannel);
+                    }
+                    lora_printCodingRate(true);  // true: of received packet
+                    dbm = lora.get_pkt_rssi();
+                    printf(" crc%s %.1fdB  %.1fdBm\r\n",
+                        lora.RegHopChannel.bits.RxPayloadCrcOn ? "On" : "OFF",
+                        lora.RegPktSnrValue / 4.0,
+                        dbm
+                    );
+                    print_rx_buf(lora.RegRxNbBytes);
+                } else if (app == APP_CHAT) {
+                    if (lora.RegHopChannel.bits.RxPayloadCrcOn) {
+                        if (lora.RegIrqFlags.bits.PayloadCrcError)
+                            printf("crcError\r\n");
+                        else {
+                            int n = lora.RegRxNbBytes;
+                            radio.rx_buf[n++] = '\r';
+                            radio.rx_buf[n++] = '\n';
+                            radio.rx_buf[n] = 0; // null terminate
+                            printf((char *)radio.rx_buf);
+                        }
+                    } else
+                        printf("crcOff\r\n");
+                        
+                    // clear Irq flags
+                    radio.write_reg(REG_LR_IRQFLAGS, lora.RegIrqFlags.octet);
+                    // should still be in receive mode
                 }
-                printCodingRate(true);  // true: of received packet
-                printf(" crc%s %.1fdB %ddBm\r\n",
-                    radio.RegHopChannel.bits.RxPayloadCrcOn ? "On" : "OFF",
-                    radio.RegPktSnrValue / 4.0,
-                    radio.RegPktRssiValue - 137
-                );
-                print_rx_buf(radio.RegRxNbBytes);
-            } else if (app == APP_CHAT) {
-                if (radio.RegHopChannel.bits.RxPayloadCrcOn) {
-                    if (radio.RegIrqFlags.bits.PayloadCrcError)
-                        printf("crcError\r\n");
-                    else {
-                        int n = radio.RegRxNbBytes;
-                        radio.rx_buf[n++] = '\r';
-                        radio.rx_buf[n++] = '\n';
-                        radio.rx_buf[n] = 0; // null terminate
-                        printf((char *)radio.rx_buf);
-                    }
-                } else
-                    printf("crcOff\r\n");
-                    
-                // clear Irq flags
-                radio.write_reg(REG_LR_IRQFLAGS, radio.RegIrqFlags.octet);
-                // should still be in receive mode
-            }
-            break;
-        case SERVICE_TX_DONE:
-            if (app == APP_CHAT) {
-                radio.lora_start_rx();
-            }
-            break;
-        case SERVICE_ERROR:
-            printf("error\r\n");
-            break;
-    } // ...switch (act)
+                break;
+            case SERVICE_TX_DONE:
+                if (app == APP_CHAT) {
+                    lora.start_rx();
+                }
+                break;
+            case SERVICE_ERROR:
+                printf("error\r\n");
+                break;
+        } // ...switch (act)
+    } else {
+        /* FSK: */
+        act = fsk.service();
+        
+         switch (act) {
+             case SERVICE_READ_FIFO:
+                break;
+         } // ...switch (act)
+    }
 }
 
 void user_init(void)
@@ -491,9 +1008,12 @@
     } else {
         for (i = 0; i < len; i++)
             radio.tx_buf[i] = pcbuf[i];
-        radio.RegPayloadLength = len;
-        radio.write_reg(REG_LR_PAYLOADLENGTH, radio.RegPayloadLength);  
-        radio.lora_start_tx(len);
+        if (radio.RegOpMode.bits.LongRangeMode) {
+            lora.RegPayloadLength = len;
+            radio.write_reg(REG_LR_PAYLOADLENGTH, lora.RegPayloadLength);
+            lora.start_tx(len);
+        } else
+            printf("todo fsk tx\r\n");
         printf("\r\n");
     }
 }
@@ -503,6 +1023,7 @@
 {
     int len, i;
     uint8_t a, d;
+    static uint16_t fsk_tx_length;
         
     len = get_kbd_str(pcbuf, sizeof(pcbuf));
     if (len < 0) {
@@ -530,19 +1051,21 @@
                 }
                 break;
             case 'T':
-                radio.RegModemConfig2.octet = radio.read_reg(REG_LR_MODEMCONFIG2);
-                //printf("a %02x\r\n", radio.RegModemConfig2.octet);
-                radio.RegModemConfig2.sx1276bits.TxContinuousMode ^= 1;   // same for sx1272 and sx1276
-                //printf("b %02x\r\n", radio.RegModemConfig2.octet);
-                radio.write_reg(REG_LR_MODEMCONFIG2, radio.RegModemConfig2.octet);
-                radio.RegModemConfig2.octet = radio.read_reg(REG_LR_MODEMCONFIG);
-                //printf("c %02x\r\n", radio.RegModemConfig2.octet);
-                printTxContinuousMode();
-                printf("\r\n");
+                if (radio.RegOpMode.bits.LongRangeMode) {
+                    lora.RegModemConfig2.octet = radio.read_reg(REG_LR_MODEMCONFIG2);
+                    //printf("a %02x\r\n", radio.RegModemConfig2.octet);
+                    lora.RegModemConfig2.sx1276bits.TxContinuousMode ^= 1;   // same for sx1272 and sx1276
+                    //printf("b %02x\r\n", radio.RegModemConfig2.octet);
+                    radio.write_reg(REG_LR_MODEMCONFIG2, lora.RegModemConfig2.octet);
+                    lora.RegModemConfig2.octet = radio.read_reg(REG_LR_MODEMCONFIG);
+                    //printf("c %02x\r\n", radio.RegModemConfig2.octet);
+                    lora_printTxContinuousMode();
+                    printf("\r\n");
+                }
                 break;
             case 'C':
-                radio.setRxPayloadCrcOn(!radio.getRxPayloadCrcOn());
-                printRxPayloadCrcOn();
+                lora.setRxPayloadCrcOn(!lora.getRxPayloadCrcOn());
+                lora_printRxPayloadCrcOn();
                 printf("\r\n");
                 break;
             case 'B':
@@ -550,52 +1073,83 @@
                 radio.write_reg(REG_PACONFIG, radio.RegPaConfig.octet);
                 printPa();
                 printf("\r\n");
-                break;                    
+                break;
+            case 'L':  
+                if (radio.RegOpMode.bits.LongRangeMode)
+                    fsk.enable();
+                else
+                    lora.enable();
+
+                radio.RegOpMode.octet = radio.read_reg(REG_OPMODE);
+                if (radio.RegOpMode.bits.LongRangeMode)
+                    printf("LoRa\r\n");
+                else
+                    printf("FSK\r\n");                
+                break;                  
             case '?':
+                printf("L           toggle LongRangeMode/FSK\r\n");
                 printf("i           radio_init\r\n");
                 printf("h           hw_reset\r\n");
-                printf("hm          toggle explicit/explicit header mode\r\n");
-                printf("tx[ %%d]     transmit\r\n");
-                printf("rx          receive\r\n");
-                printf("cr[1234]    set coding rate\r\n");
-                printf("bw[%%d]      get/set bandwidth\r\n");
-                printf("sf[%%d]      get/set spreading factor\r\n");
-                printf("pl[%%d]      get/set RegPayloadLength\r\n");
+                printf("tx[%%d]     transmit\r\n");
+                printf("rx          receive\r\n");   
                 printf("C           toggle crcOn\r\n");
-                printf("T           toggle TxContinuousMode\r\n");
                 printf("op[%%d]     get/set output power\r\n");
-                printf("hp[%%d]     get/set hop period\r\n");
-                printf("d[0-5]      change DIO pin assignment\r\n");                               
+                printf("d[0-5]      change DIO pin assignment\r\n");
+                if (radio.RegOpMode.bits.LongRangeMode) {
+                    printf("pl[%%d]     LORA get/set RegPayloadLength\r\n");
+                    printf("cr[1234]    LORA set coding rate \r\n");
+                    printf("bw[%%d]     LORA get/set bandwidth\r\n");
+                    printf("sf[%%d]     LORA get/set spreading factor\r\n");
+                    printf("T           LORA toggle TxContinuousMode\r\n");
+                    printf("hp[%%d]     LORA get/set hop period\r\n");
+                    printf("hm          LORA toggle explicit/explicit header mode\r\n");
+                } else {
+                    printf("bw[%%d]     FSK get-set rxbw\n");
+                }
                 break;
             case '.':
-                lora_print_status();
+                if (radio.RegOpMode.bits.LongRangeMode)
+                    lora_print_status();
+                else
+                    fsk_print_status();
                 common_print_status();
                 break;
         } // ...switch (pcbuf[0])
     } else {
         if (pcbuf[0] == 't' && pcbuf[1] == 'x') { // TX
-            if (pcbuf[2] == ' ') {
-                sscanf(pcbuf+3, "%d", &i);
-                radio.RegPayloadLength = i;
+            if (radio.RegOpMode.bits.LongRangeMode) {
+                if (pcbuf[2] >= '0' && pcbuf[2] <= '9') {
+                    sscanf(pcbuf+3, "%d", &i);
+                    lora.RegPayloadLength = i;
+                }
+                tx_cnt++;
+                for (i = 0; i < lora.RegPayloadLength; i++)
+                    radio.tx_buf[i] = tx_cnt;
+                lora.start_tx(lora.RegPayloadLength);
+            } else {
+                if (pcbuf[2] >= '0' && pcbuf[2] <= '9') {
+                    sscanf(pcbuf+3, "%d", &i);
+                    fsk_tx_length = i;
+                }
+                tx_cnt++;
+                for (i = 0; i < fsk_tx_length; i++)
+                    radio.tx_buf[i] = tx_cnt;
+                fsk.start_tx(fsk_tx_length);
             }
-            tx_cnt++;
-            for (i = 0; i < radio.RegPayloadLength; i++)
-                radio.tx_buf[i] = tx_cnt;
-            radio.lora_start_tx(radio.RegPayloadLength);
-        } else if (pcbuf[0] == 'h' && pcbuf[1] == 'p') { //
+        } else if (pcbuf[0] == 'h' && pcbuf[1] == 'p' && radio.RegOpMode.bits.LongRangeMode) {
             if (pcbuf[2] >= '0' && pcbuf[2] <= '9') {
                 sscanf(pcbuf+2, "%d", &i);
-                radio.RegHopPeriod = i;
-                radio.write_reg(REG_LR_HOPPERIOD, radio.RegHopPeriod);
+                lora.RegHopPeriod = i;
+                radio.write_reg(REG_LR_HOPPERIOD, lora.RegHopPeriod);
                 if (radio.RegDioMapping1.bits.Dio1Mapping != 1) {
                     radio.RegDioMapping1.bits.Dio1Mapping = 1;
                     radio.write_reg(REG_DIOMAPPING1, radio.RegDioMapping1.octet);
                 }
             }
-            radio.RegHopPeriod = radio.read_reg(REG_LR_HOPPERIOD);
-            printf("HopPeriod:0x%02x\r\n", radio.RegHopPeriod);
+            lora.RegHopPeriod = radio.read_reg(REG_LR_HOPPERIOD);
+            printf("HopPeriod:0x%02x\r\n", lora.RegHopPeriod);
         } else if (pcbuf[0] == 'r' && pcbuf[1] == 'x') { // RX
-            radio.lora_start_rx();
+            lora.start_rx();
         } else if (pcbuf[0] == 'r' && pcbuf[1] == ' ') { // read single register
             sscanf(pcbuf+2, "%x", &i);
             printf("%02x: %02x\r\n", i, radio.read_reg(i));
@@ -611,42 +1165,60 @@
             }
             radio.RegPaConfig.octet = radio.read_reg(REG_PACONFIG);
             printf("OutputPower:%d\r\n", radio.RegPaConfig.bits.OutputPower);
-        } else if (pcbuf[0] == 'c' && pcbuf[1] == 'r') {
+        } else if (pcbuf[0] == 'c' && pcbuf[1] == 'r' && radio.RegOpMode.bits.LongRangeMode) {
             if (pcbuf[2] >= '0' && pcbuf[2] <= '9')
-                radio.setCodingRate(pcbuf[2] - '0');
-             radio.RegModemConfig.octet = radio.read_reg(REG_LR_MODEMCONFIG);
-             printCodingRate(false);    // false: transmitted
+                lora.setCodingRate(pcbuf[2] - '0');
+             lora.RegModemConfig.octet = radio.read_reg(REG_LR_MODEMCONFIG);
+             lora_printCodingRate(false);    // false: transmitted
              printf("\r\n");
-        } else if (pcbuf[0] == 'h' && pcbuf[1] == 'm') {    // toggle implicit/explicit
-            radio.setHeaderMode(!radio.getHeaderMode());
-            radio.RegModemConfig.octet = radio.read_reg(REG_LR_MODEMCONFIG);
-            printHeaderMode();
+        } else if (pcbuf[0] == 'h' && pcbuf[1] == 'm' && radio.RegOpMode.bits.LongRangeMode) {    // toggle implicit/explicit
+            lora.setHeaderMode(!lora.getHeaderMode());
+            lora.RegModemConfig.octet = radio.read_reg(REG_LR_MODEMCONFIG);
+            lora_printHeaderMode();
             printf("\r\n");
         } else if (pcbuf[0] == 'b' && pcbuf[1] == 'w') {
-            if (pcbuf[2] >= '0' && pcbuf[2] <= '9') {
-                radio.set_opmode(RF_OPMODE_STANDBY);
-                sscanf(&pcbuf[2], "%d", &i);
-                radio.setBw(i);
-            } else
-                printAllBw();
-            radio.RegModemConfig.octet = radio.read_reg(REG_LR_MODEMCONFIG);
-            printf("current ");
-            printBw();
-            printf("\r\n");
+            if (radio.RegOpMode.bits.LongRangeMode) {
+                if (pcbuf[2] >= '0' && pcbuf[2] <= '9') {
+                    radio.set_opmode(RF_OPMODE_STANDBY);
+                    sscanf(&pcbuf[2], "%d", &i);
+                    lora.setBw(i);
+                } else
+                    lora_printAllBw();
+                lora.RegModemConfig.octet = radio.read_reg(REG_LR_MODEMCONFIG);
+                printf("current ");
+                lora_printBw();
+                printf("\r\n");
+            } else { // FSK:
+                if (pcbuf[2] == 'a') {
+                    if (pcbuf[3] >= '0' && pcbuf[3] <= '9') {
+                        radio.set_opmode(RF_OPMODE_STANDBY);
+                        sscanf(&pcbuf[3], "%d", &i);
+                        fsk.set_rx_dcc_bw_hz(i, 1);
+                    }
+                    printf("afcbw:%dHz\r\n", fsk.get_rx_bw_hz(REG_FSK_AFCBW));
+                } else {
+                    if (pcbuf[2] >= '0' && pcbuf[2] <= '9') {
+                        radio.set_opmode(RF_OPMODE_STANDBY);
+                        sscanf(&pcbuf[2], "%d", &i);
+                        fsk.set_rx_dcc_bw_hz(i, 0);
+                    }
+                    printf("rxbw:%dHz\r\n", fsk.get_rx_bw_hz(REG_FSK_RXBW));
+                }
+            }
         } else if (pcbuf[0] == 'v' && pcbuf[1] == 'h') {
-            radio.poll_vh ^= 1;
-            printf("poll_vh:%d\r\n", radio.poll_vh);
-        } else if (pcbuf[0] == 's' && pcbuf[1] == 'f') {
+            lora.poll_vh ^= 1;
+            printf("poll_vh:%d\r\n", lora.poll_vh);
+        } else if (pcbuf[0] == 's' && pcbuf[1] == 'f' && radio.RegOpMode.bits.LongRangeMode) {
             if (pcbuf[2] >= '0' && pcbuf[2] <= '9') {
                 sscanf(pcbuf+2, "%d", &i);
-                radio.setSf(i);
-                if (i == 6 && !radio.getHeaderMode()) {
+                lora.setSf(i);
+                if (i == 6 && !lora.getHeaderMode()) {
                     printf("SF6: to implicit header mode\r\n");
-                    radio.setHeaderMode(true);
+                    lora.setHeaderMode(true);
                 }
             }
-            radio.RegModemConfig2.octet = radio.read_reg(REG_LR_MODEMCONFIG2);
-            printSf();
+            lora.RegModemConfig2.octet = radio.read_reg(REG_LR_MODEMCONFIG2);
+            lora_printSf();
             printf("\r\n");
         } else if (pcbuf[0] == 'f' && pcbuf[1] == 'r' && pcbuf[2] == 'f') {
             if (pcbuf[3] >= '0' && pcbuf[3] <= '9') {
@@ -656,14 +1228,14 @@
                 radio.set_frf_MHz(MHz);
             } else
                 printf("%fMHz\r\n", radio.get_frf_MHz());
-        } else if (pcbuf[0] == 'p' && pcbuf[1] == 'l') {
+        } else if (pcbuf[0] == 'p' && pcbuf[1] == 'l' && radio.RegOpMode.bits.LongRangeMode) {
             if (pcbuf[2] >= '0' && pcbuf[2] <= '9') {
                 sscanf(pcbuf+2, "%d", &i);
-                radio.RegPayloadLength = i;
-                radio.write_reg(REG_LR_PAYLOADLENGTH, radio.RegPayloadLength);             
+                lora.RegPayloadLength = i;
+                radio.write_reg(REG_LR_PAYLOADLENGTH, lora.RegPayloadLength);             
             }
-            radio.RegPayloadLength = radio.read_reg(REG_LR_PAYLOADLENGTH);
-            printf("PayloadLength:%d\r\n", radio.RegPayloadLength);
+            lora.RegPayloadLength = radio.read_reg(REG_LR_PAYLOADLENGTH);
+            printf("PayloadLength:%d\r\n", lora.RegPayloadLength);
         } else if (pcbuf[0] == 'd' && pcbuf[1] >= '0' && pcbuf[1] <= '5') {
             switch (pcbuf[1]) {
                 case '0':
@@ -691,14 +1263,17 @@
                     radio.write_reg(REG_DIOMAPPING1, radio.RegDioMapping2.octet);
                     break;                                                                                             
             } // ...switch (pcbuf[1])
-            print_dio();
+            if (radio.RegOpMode.bits.LongRangeMode)
+                lora_print_dio();
+            else
+                fsk_print_dio();
         } else if (pcbuf[0] == 's' && pcbuf[1] == 't' && pcbuf[2] == 'b') {
             radio.set_opmode(RF_OPMODE_STANDBY);
         } else if (pcbuf[0] == 's' && pcbuf[1] == 'l' && pcbuf[2] == 'e') {
             radio.set_opmode(RF_OPMODE_SLEEP);
         } else if (pcbuf[0] == 'c' && pcbuf[1] == 'h' && pcbuf[2] == 'a') {
             app = APP_CHAT;
-            radio.lora_start_rx();
+            lora.start_rx();
             printf("chat start\r\n");
         }           
     }