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

main.cpp

Committer:
dudmuck
Date:
2014-03-26
Revision:
0:be215de91a68
Child:
1:1cd0afbed23c

File content as of revision 0:be215de91a68:

#include "sx127x.h"

/*
 * http://mbed.org/handbook/mbed-FRDM-KL25Z
 */

DigitalOut green(LED_GREEN);

Serial pc(USBTX, USBRX);

uint8_t tx_cnt;
char pcbuf[64];

typedef enum {
    APP_NONE = 0,
    APP_CHAT
} app_e;

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),
    MHZ_TO_FRF(905.0),
    MHZ_TO_FRF(906.0),
    MHZ_TO_FRF(907.0),
    MHZ_TO_FRF(908.0),
    MHZ_TO_FRF(909.0),
    MHZ_TO_FRF(910.0),
    MHZ_TO_FRF(911.0),
    MHZ_TO_FRF(912.0),
    MHZ_TO_FRF(913.0),
    MHZ_TO_FRF(914.0),
    MHZ_TO_FRF(915.0)
};

/******************************************************************************/

//  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);

void printLoraIrqs_(bool clear)
{
    //in radio class -- RegIrqFlags_t RegIrqFlags;

    //already read RegIrqFlags.octet = radio.read_reg(REG_LR_IRQFLAGS);
    printf("\r\nIrqFlags:");
    if (radio.RegIrqFlags.bits.CadDetected)
        printf("CadDetected ");
    if (radio.RegIrqFlags.bits.FhssChangeChannel) {
        //radio.RegHopChannel.octet = radio.read_reg(REG_LR_HOPCHANNEL);
        printf("FhssChangeChannel:%d ", radio.RegHopChannel.bits.FhssPresentChannel);
    }
    if (radio.RegIrqFlags.bits.CadDone)
        printf("CadDone ");
    if (radio.RegIrqFlags.bits.TxDone)
        printf("TxDone ");
    if (radio.RegIrqFlags.bits.ValidHeader)
        printf("ValidHeader ");
    if (radio.RegIrqFlags.bits.PayloadCrcError)
        printf("PayloadCrcError ");
    if (radio.RegIrqFlags.bits.RxDone)
        printf("RxDone ");  
    if (radio.RegIrqFlags.bits.RxTimeout)
        printf("RxTimeout ");

    printf("\r\n");

    if (clear)
        radio.write_reg(REG_LR_IRQFLAGS, radio.RegIrqFlags.octet);

}

void printCodingRate(bool from_rx)
{
    uint8_t d = radio.getCodingRate(from_rx);
    printf("CodingRate:");
    switch (d) {
        case 1: printf("4/5 "); break;
        case 2: printf("4/6 "); break;
        case 3: printf("4/7 "); break;
        case 4: printf("4/8 "); break;
        default:
            printf("%d ", d);
            break;
    }
}

void printHeaderMode()
{
    if (radio.getHeaderMode())
        printf("implicit ");
    else
        printf("explicit ");
}

void printBw()
{
    uint8_t bw = radio.getBw();
    
    printf("Bw:");
    if (radio.type == SX1276) {
        switch (radio.RegModemConfig.sx1276bits.Bw) {
            case 0: printf("7.8KHz "); break;
            case 1: printf("10.4KHz "); break;
            case 2: printf("15.6KHz "); break;
            case 3: printf("20.8KHz "); break;
            case 4: printf("31.25KHz "); break;
            case 5: printf("41.7KHz "); break;
            case 6: printf("62.5KHz "); break;
            case 7: printf("125KHz "); break;
            case 8: printf("250KHz "); break;
            case 9: printf("500KHz "); break;
            default: printf("%x ", radio.RegModemConfig.sx1276bits.Bw); break;
        }
    } else if (radio.type == SX1272) {
        switch (radio.RegModemConfig.sx1272bits.Bw) {
            case 0: printf("125KHz "); break;
            case 1: printf("250KHz "); break;
            case 2: printf("500KHz "); break;
            case 3: printf("11b "); break;
        }
    }
}

void printAllBw()
{
    int i, s;
    
    if (radio.type == SX1276) {
        s = radio.RegModemConfig.sx1276bits.Bw;    
        for (i = 0; i < 10; i++ ) {
            radio.RegModemConfig.sx1276bits.Bw = i;
            printf("%d ", i);
            printBw();
            printf("\r\n");
        }
        radio.RegModemConfig.sx1276bits.Bw = s;
    } else if (radio.type == SX1272) {
        s = radio.RegModemConfig.sx1272bits.Bw;    
        for (i = 0; i < 3; i++ ) {
            radio.RegModemConfig.sx1272bits.Bw = i;
            printf("%d ", i);
            printBw();
            printf("\r\n");
        }
        radio.RegModemConfig.sx1272bits.Bw = s;    
    }
}

void printSf()
{
    // spreading factor same between sx127[26]
    printf("sf:%d ", radio.getSf());
}

void printRxPayloadCrcOn()
{
    bool on = radio.getRxPayloadCrcOn();
    //printf("RxPayloadCrcOn:%s ", on ? "on" : "off");
    if (on)
        printf("RxPayloadCrcOn:1 = Tx CRC Enabled\r\n");
    else
        printf("RxPayloadCrcOn:1 = no Tx CRC\r\n");
}

void printTxContinuousMode()
{
    printf("TxContinuousMode:%d ", radio.RegModemConfig2.sx1276bits.TxContinuousMode);    // same for sx1272 and sx1276
}

void printAgcAutoOn()
{
    printf("AgcAutoOn:%d", radio.getAgcAutoOn());
}

void print_dio()
{
       radio.RegDioMapping2.octet = radio.read_reg(REG_DIOMAPPING2);
    printf("DIO5:");
    switch (radio.RegDioMapping2.bits.Dio5Mapping) {
        case 0: printf("ModeReady"); break;
        case 1: printf("ClkOut"); break;
        case 2: printf("ClkOut"); break;
    }
    printf(" DIO4:");
    switch (radio.RegDioMapping2.bits.Dio4Mapping) {
        case 0: printf("CadDetected"); break;
        case 1: printf("PllLock"); break;
        case 2: printf("PllLock"); break;
    }    
    radio.RegDioMapping1.octet = radio.read_reg(REG_DIOMAPPING1);
    printf(" DIO3:");
    switch (radio.RegDioMapping1.bits.Dio3Mapping) {
        case 0: printf("CadDone"); break;
        case 1: printf("ValidHeader"); break;
        case 2: printf("PayloadCrcError"); break;
    }    
    printf(" DIO2:");
    switch (radio.RegDioMapping1.bits.Dio2Mapping) {
        case 0:
        case 1:
        case 2:
            printf("FhssChangeChannel");
            break;
    }    
    printf(" DIO1:");
    switch (radio.RegDioMapping1.bits.Dio1Mapping) {
        case 0: printf("RxTimeout"); break;
        case 1: printf("FhssChangeChannel"); break;
        case 2: printf("CadDetected"); break;
    }    
    printf(" DIO0:");
    switch (radio.RegDioMapping1.bits.Dio0Mapping) {
        case 0: printf("RxDone"); break;
        case 1: printf("TxDone"); break;
        case 2: printf("CadDone"); break;
    }    
    
    printf("\r\n"); 
}

void lora_print_status()
{
    uint8_t d;
    
    if (radio.type == SX1276)
        printf("\r\nSX1276 ");
    else if (radio.type == SX1272)
        printf("\r\nSX1272 ");
    
    radio.RegOpMode.octet = radio.read_reg(REG_OPMODE);
    if (!radio.RegOpMode.bits.LongRangeMode) {
        printf("FSK\r\n");
        return;
    }
    
    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);

    printCodingRate(false); // false: transmitted coding rate
    printHeaderMode();
    printBw();
    printSf();
    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);
    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
    );

    radio.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);
    }

    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);
    

    if (radio.RegOpMode.bits.Mode == RF_OPMODE_RECEIVER || radio.RegOpMode.bits.Mode == RF_OPMODE_RECEIVER_SINGLE) {
        d = radio.read_reg(REG_LR_RSSIVALUE);
        printf("rssi:%ddBm ", d-120);
    }

    printTxContinuousMode();

    printf("\r\n");
    printAgcAutoOn();
    if (radio.type == SX1272) {
        printf(" LowDataRateOptimize:%d\r\n", radio.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);

    if (radio.type == SX1272) {
        radio.RegModemConfig.octet = radio.read_reg(REG_LR_MODEMCONFIG);
        printf("LowDataRateOptimize:%d\r\n", radio.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);        
    }
    
    printf("\r\n");
    //printf("A %02x\r\n", radio.RegModemConfig2.octet);
}

void printOpMode()
{
    radio.RegOpMode.octet = radio.read_reg(REG_OPMODE);
    switch (radio.RegOpMode.bits.Mode) {
        case RF_OPMODE_SLEEP: printf("sleep"); break;
        case RF_OPMODE_STANDBY: printf("stby"); break;
        case RF_OPMODE_SYNTHESIZER_TX: printf("fstx"); break;
        case RF_OPMODE_TRANSMITTER: printf("tx"); break;
        case RF_OPMODE_SYNTHESIZER_RX: printf("fsrx"); break;
        case RF_OPMODE_RECEIVER: printf("rx"); break;
        case 6:
            if (radio.RegOpMode.bits.LongRangeMode)
                printf("rxs");
            else
                printf("-6-");
            break;  // todo: different lora/fsk
        case 7:
            if (radio.RegOpMode.bits.LongRangeMode)
                printf("cad");
            else
                printf("-7-");
            break;  // todo: different lora/fsk
    }
}

void
printPa()
{
    radio.RegPaConfig.octet = radio.read_reg(REG_PACONFIG);
    if (radio.RegPaConfig.bits.PaSelect) {
        float output_dBm = 17 - (15-radio.RegPaConfig.bits.OutputPower);
        printf(" PABOOST OutputPower=%.1fdBm", output_dBm);
    } else {
        float pmax = (0.6*radio.RegPaConfig.bits.MaxPower) + 10.8;
        float output_dBm = pmax - (15-radio.RegPaConfig.bits.OutputPower);
        printf(" RFO pmax=%.1fdBm OutputPower=%.1fdBm", pmax, output_dBm);
    }
}

void /* things always present, whether lora or fsk */
common_print_status()
{
    printf("version:0x%02x %.3fMHz ", radio.read_reg(REG_VERSION), radio.get_frf_MHz());
    printOpMode();

    printPa();

    radio.RegOcp.octet = radio.read_reg(REG_OCP);
    if (radio.RegOcp.bits.OcpOn) {
        int imax = 0;
        if (radio.RegOcp.bits.OcpTrim < 16)
            imax = 45 + (5 * radio.RegOcp.bits.OcpTrim);
        else if (radio.RegOcp.bits.OcpTrim < 28)
            imax = -30 + (10 * radio.RegOcp.bits.OcpTrim);
        else
            imax = 240;
        printf(" OcpOn %dmA ", imax);
    } else
        printf(" OcpOFF ");

    printf("\r\n");

}

void print_rx_buf(int len)
{
    int i;

    printf("000:");
    for (i = 0; i < len; i++) {
        //printf("(%d)%02x ", i % 16, rx_buf[i]);
        printf("%02x ", radio.rx_buf[i]);
        if (i % 16 == 15 && i != len-1)
            printf("\r\n%03d:", i+1);

    }
    printf("\r\n");
}

void
service_radio()
{
    service_action_e act = radio.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);
                }
                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)
}

void user_init(void)
{
    // set desired spreadingfactor, bandwidth, MHz, etc.
}

int get_kbd_str(char* buf, int size)
{
    char c;
    int i;
    static int prev_len;
    
    for (i = 0;;) {
        if (pc.readable()) {
            c = pc.getc();
            if (c == 8 && i > 0) {
                pc.putc(8);
                pc.putc(' ');
                pc.putc(8);
                i--;
            } else if (c == '\r') {
                if (i == 0) {
                    return prev_len; // repeat previous
                } else {
                    buf[i] = 0; // null terminate
                    prev_len = i;
                    return i;
                }
            } else if (c == 3) {
                // ctrl-C abort
                return -1;
            } else if (i < size) {
                buf[i++] = c;
                pc.putc(c);
            }
        } else
            service_radio();
    } // ...for()
}

void
console_chat()
{
    int i, len = get_kbd_str(pcbuf, sizeof(pcbuf));
    if (len < 0) {
        printf("chat abort\r\n");
        app = APP_NONE;
        return;
    } 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);
        printf("\r\n");
    }
}

void
console()
{
    int len, i;
    uint8_t a, d;
        
    len = get_kbd_str(pcbuf, sizeof(pcbuf));
    if (len < 0) {
        printf("abort\r\n");
        return;
    }
    
    printf("\r\n");
    if (len == 1) {
        switch (pcbuf[0]) {
            case 'i':
                radio.init();
                user_init();
                break;
            case 'h':
                printf("hw_reset()\r\n");
                radio.hw_reset();
                break;
            case 'R':
                // read all registers
                for (a = 1; a < 0x71; a++) {
                    d = radio.read_reg(a);
                    //update_shadow_regs(selected_radio, a, d); 
                    printf("%02x: %02x\r\n", a, d);
                }
                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");
                break;
            case 'C':
                radio.setRxPayloadCrcOn(!radio.getRxPayloadCrcOn());
                printRxPayloadCrcOn();
                printf("\r\n");
                break;
            case 'B':
                radio.RegPaConfig.bits.PaSelect ^= 1;
                radio.write_reg(REG_PACONFIG, radio.RegPaConfig.octet);
                printPa();
                printf("\r\n");
                break;                    
            case '?':
                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("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");                               
                break;
            case '.':
                lora_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;
            }
            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') { //
            if (pcbuf[2] >= '0' && pcbuf[2] <= '9') {
                sscanf(pcbuf+2, "%d", &i);
                radio.RegHopPeriod = i;
                radio.write_reg(REG_LR_HOPPERIOD, radio.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);
        } else if (pcbuf[0] == 'r' && pcbuf[1] == 'x') { // RX
            radio.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));
        } else if (pcbuf[0] == 'w' && pcbuf[1] == ' ') { // write single register
            sscanf(pcbuf+2, "%x %x", &i, &len);
            radio.write_reg(i, len);
            printf("%02x: %02x\r\n", i, radio.read_reg(i));
        } else if (pcbuf[0] == 'o' && pcbuf[1] == 'p') {
            if (pcbuf[2] >= '0' && pcbuf[2] <= '9') {
                sscanf(pcbuf+2, "%d", &i);
                radio.RegPaConfig.bits.OutputPower = i;
                radio.write_reg(REG_PACONFIG, radio.RegPaConfig.octet);
            }
            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') {
            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
             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();
            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");
        } 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') {
            if (pcbuf[2] >= '0' && pcbuf[2] <= '9') {
                sscanf(pcbuf+2, "%d", &i);
                radio.setSf(i);
                if (i == 6 && !radio.getHeaderMode()) {
                    printf("SF6: to implicit header mode\r\n");
                    radio.setHeaderMode(true);
                }
            }
            radio.RegModemConfig2.octet = radio.read_reg(REG_LR_MODEMCONFIG2);
            printSf();
            printf("\r\n");
        } else if (pcbuf[0] == 'f' && pcbuf[1] == 'r' && pcbuf[2] == 'f') {
            if (pcbuf[3] >= '0' && pcbuf[3] <= '9') {
                float MHz;
                sscanf(pcbuf+3, "%f", &MHz);
                //printf("MHz:%f\r\n", MHz);
                radio.set_frf_MHz(MHz);
            } else
                printf("%fMHz\r\n", radio.get_frf_MHz());
        } else if (pcbuf[0] == 'p' && pcbuf[1] == 'l') {
            if (pcbuf[2] >= '0' && pcbuf[2] <= '9') {
                sscanf(pcbuf+2, "%d", &i);
                radio.RegPayloadLength = i;
                radio.write_reg(REG_LR_PAYLOADLENGTH, radio.RegPayloadLength);             
            }
            radio.RegPayloadLength = radio.read_reg(REG_LR_PAYLOADLENGTH);
            printf("PayloadLength:%d\r\n", radio.RegPayloadLength);
        } else if (pcbuf[0] == 'd' && pcbuf[1] >= '0' && pcbuf[1] <= '5') {
            switch (pcbuf[1]) {
                case '0':
                    radio.RegDioMapping1.bits.Dio0Mapping++;
                    radio.write_reg(REG_DIOMAPPING1, radio.RegDioMapping1.octet);
                    break;
                case '1':
                    radio.RegDioMapping1.bits.Dio1Mapping++;
                    radio.write_reg(REG_DIOMAPPING1, radio.RegDioMapping1.octet);
                    break;    
                case '2':
                    radio.RegDioMapping1.bits.Dio2Mapping++;
                    radio.write_reg(REG_DIOMAPPING1, radio.RegDioMapping1.octet);
                    break;
                case '3':
                    radio.RegDioMapping1.bits.Dio3Mapping++;
                    radio.write_reg(REG_DIOMAPPING1, radio.RegDioMapping1.octet);
                    break;
                case '4':
                    radio.RegDioMapping2.bits.Dio4Mapping++;
                    radio.write_reg(REG_DIOMAPPING1, radio.RegDioMapping2.octet);
                    break; 
                case '5':
                    radio.RegDioMapping2.bits.Dio5Mapping++;
                    radio.write_reg(REG_DIOMAPPING1, radio.RegDioMapping2.octet);
                    break;                                                                                             
            } // ...switch (pcbuf[1])
            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();
            printf("chat start\r\n");
        }           
    }
    printf("> ");
    fflush(stdout);
        
}

int main()
{  

    pc.baud(57600);
    user_init();
    
    radio.frfs = frfs;

    while(1) {
        switch (app) {
            case APP_NONE:
                console();
                break;
            case APP_CHAT:
                console_chat();
                break;
        } // ...switch (app)
    } // ...while(1)
}