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
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("[42mValidHeader[0m "); if (radio.RegIrqFlags.bits.PayloadCrcError) printf("[41mPayloadCrcError[0m "); if (radio.RegIrqFlags.bits.RxDone) printf("[42mRxDone[0m "); 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("[7msleep[0m"); break; case RF_OPMODE_STANDBY: printf("[7mstby[0m"); break; case RF_OPMODE_SYNTHESIZER_TX: printf("[33mfstx[0m"); break; case RF_OPMODE_TRANSMITTER: printf("[31mtx[0m"); break; case RF_OPMODE_SYNTHESIZER_RX: printf("[33mfsrx[0m"); break; case RF_OPMODE_RECEIVER: printf("[32mrx[0m"); break; case 6: if (radio.RegOpMode.bits.LongRangeMode) printf("[42mrxs[0m"); else printf("-6-"); break; // todo: different lora/fsk case 7: if (radio.RegOpMode.bits.LongRangeMode) printf("[45mcad[0m"); 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) }