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:
5:d6e7fb9446ff
Parent:
4:7a9007dfc0e5
--- a/main.cpp	Tue May 20 17:18:47 2014 +0000
+++ b/main.cpp	Mon Feb 16 01:53:18 2015 +0000
@@ -3,15 +3,55 @@
 
 /*
  * http://mbed.org/handbook/mbed-FRDM-KL25Z
+ *
+ * The program was tested with the FRDM-KL25Z board, with a Modtronix inAir9 SX1276 board mounted in
+ * a Modtronix SHD3I daughter board(iMod3).
+ *
+ * MODTRONIX Notes
+ * Use this app to test LORA modem.
+ * - Connect to FRDM-KL25Z, with inAIR9 connected to it (via SHD3I daughter board)
+ * - Connect to PC via USB
+ * - Start HyperTerminal on PC, at 57.6K baud
+ * - Various commands can now be executed on terminal. Use '?' for list of commands.
+ * - Use '.' to see current settings.
+ * 
+ * For example, to send test message:
+ * - Select mode in HyperTerminal. For example, type "t1" to configure for bw=250khz, sf=12, payload=9
+ * - Ensure CRC and "low datarate optimize" has correct setting.
+ * - Press "t" in terminal to send a "semtech starter kit" 9 byte message
+ *
+ * NOTE! Ensure "low datarate optimize" is same! In hyperTerminal "ld0" turns it off, and "ld1" turns it on.
+ *
+ * ========== Firmware for KL25Z ==========
+ * The default firmware listed on mbed.org puts a clock pulse on pin A5. To fix this, use alternative
+ * firmware (or unsolder resistor R24).
+ * - Download "OpenSDA Firmware" from http://www.pemicro.com/opensda/
+ * - Put KL25Z into bootloader mode (hold down button while plugging in SDA USB).
+ * - Drag "MSD-DEBUG-FRDM-KL25Z_Pemicro_v114.SDA" file onto it.
+ * - Reset KL25Z.
+ * - If the USB drivers do not automatically install, download and run "Windows USB Drivers" from
+ *   www.pemicro.com/opensda. After this, when you plug in the KL25Z next time, all drivers should
+ *   install correctly.
  */
 
+#define TARGET_KL25Z_SHD3I_INAIR8           /* FRDM-KL25Z + Modtronix inAir9 SX1276 board + SHD3I daughter board */
+#define AUTO_TRANSMIT                   0   /* Enable automatic transmission every 1000ms */
+#define FSK_LARGE_PKT_THRESHOLD         0x3f
+
 DigitalOut green(LED_GREEN);
+DigitalOut led2(LED_RED);
 
 Serial pc(USBTX, USBRX);
 
 uint8_t tx_cnt;
 char pcbuf[64];
 
+char mybuf[64];
+Timer tmr;
+int32_t t;
+uint8_t initDone;
+
+
 typedef enum {
     APP_NONE = 0,
     APP_CHAT
@@ -20,32 +60,60 @@
 app_e app = APP_NONE;
 
 
-const uint32_t frfs[] = {   /* frequency hopping table */
-    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)
-};
+
+//Defines for the FRDM-KL25Z board, with Modtronix SHD3I with an inAir9 SX1276 module mounted in it. 
+#ifdef TARGET_KL25Z_SHD3I_INAIR8
+//SCLK=D13, MISO=D12, MOSI=D11
+//CS=D7, Reset=A5
+//DIO0=D2, DIO1=D8, DIO2=D4, DIO3=A4, DIO4=N.C., DIO5=D3
+//           mosi, miso, sclk, cs,  rst,  dio0, dio1
+SX127x radio(D11,  D12,  D13,  D7,  PTC1, D2,   D8);
+//SX127x radio(D11,  D12,  D13,  D7,  A5, D2,   D8);
+#else
+//  pin:      3     8     1    7     10    12      5 
+//           mosi, miso, sclk, cs,   rst,  dio0,  dio1
+//           D11   D12   D13   D10   D9    D8     D2
+SX127x radio(PTD2, PTD3, PTD1, PTD0, PTD5, PTA13, PTD4);
+#endif
+
+
+//Required for V7 of SX127x library, but V7 doesn't work for this program!
+//DigitalOut rfsw1(PTC8);
+//DigitalOut rfsw2(PTC9);
 
-#define FSK_LARGE_PKT_THRESHOLD  0x3f
-
-/******************************************************************************/
+void rfsw_callback()
+{
+    /*
+    if (radio.RegOpMode.bits.Mode == RF_OPMODE_TRANSMITTER) {  // start of transmission
+        if (radio.HF) {
+            if (radio.RegPaConfig.bits.PaSelect) { // if PA_BOOST
+                rfsw2 = 0;
+                rfsw1 = 1;
+            } else { // RFO to power amp
+                rfsw2 = 1;
+                rfsw1 = 0;            
+            }
+        } else {
+            // todo: sx1276
+        }
+    } else if (radio.RegOpMode.bits.Mode == RF_OPMODE_RECEIVER || radio.RegOpMode.bits.Mode == RF_OPMODE_CAD) { // start of reception
+        if (radio.HF) {
+            rfsw2 = 1;
+            rfsw1 = 1;              
+        } else {
+            // todo: sx1276
+        }
+    } else { // RF switch shutdown
+        rfsw2 = 0;
+        rfsw1 = 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);
 SX127x_fsk fsk(radio);
 SX127x_lora lora(radio);
 
+
 void printLoraIrqs_(bool clear)
 {
     //in radio class -- RegIrqFlags_t RegIrqFlags;
@@ -998,8 +1066,39 @@
             }
         } else {
             service_radio();
+
+            //Enable Auto Transmit
+#if (AUTO_TRANSMIT==1)
+            if (tmr.read_ms() > t) {
+                t = t + 1000;
+                if (initDone==3) {
+                    led2 = !led2;
+                    strcpy(buf, "t");
+                }
+                else {
+                    if (initDone==0) {
+                        // 't1' = Lora, F=915MHz, BW=500, SF=12, Payload Lenght=9
+                        // 't2' = Lora, F=915MHz, BW=250, SF=12, Payload Lenght=9
+                        // 't3' = Lora, F=915MHz, BW=125, SF=12, Payload Lenght=9
+                        // 't4' = Lora, F=915MHz, BW=62.5, SF=12, Payload Lenght=9
+                        strcpy(buf, "t2");
+                    }
+                    else if (initDone==1) {
+                        strcpy(buf, "C");   //Toggle CRC, first time this is sent CRC is turned off
+                    }
+                    else if (initDone==2) {
+                        strcpy(buf, "ld1"); //Low Datarate Optimize on
+                    }
+                    initDone++;
+                }
+                pc.puts(buf);
+                pc.putc('\r');
+                return strlen(buf);
+            }   //if (tmr.read_ms() > t) {
+#endif
         }
     } // ...for()
+            
 }
 
 void
@@ -1011,6 +1110,7 @@
         app = APP_NONE;
         return;
     } else {
+        printf("console_chat....\r\n");
         for (i = 0; i < len; i++)
             radio.tx_buf[i] = pcbuf[i];
         if (radio.RegOpMode.bits.LongRangeMode) {
@@ -1031,13 +1131,13 @@
     uint32_t ui;
     uint8_t a, d;
     static uint16_t fsk_tx_length;
-        
+    
     len = get_kbd_str(pcbuf, sizeof(pcbuf));
     if (len < 0) {
         printf("abort\r\n");
         return;
     }
-    
+
     printf("\r\n");
     if (len == 1) {
         switch (pcbuf[0]) {
@@ -1122,6 +1222,46 @@
                         printf("FifoLevel\r\n");                    
                 }
                 break;
+            case 't':
+                if (radio.RegOpMode.bits.LongRangeMode) {
+                    printf("Test...\r\n");
+
+                    //MODTRONIX
+                    //For the devkit, in LoRa mode, the packet is built up as follows.
+                    //Preample = 8
+                    //Header = 8
+                    //Payload 0: Platform ID
+                    //Payload 1-4: Packet Count
+                    //Payload 5: 'P'
+                    //Payload 6: 'E'
+                    //Payload 7: 'R'
+                    //Payload 8: FCS
+                    
+                    //Platform ID
+                    radio.tx_buf[0] = 0;
+                    
+                    //Count
+                    radio.tx_buf[1] = 0;
+                    radio.tx_buf[2] = 0;
+                    radio.tx_buf[3] = 0;
+                    radio.tx_buf[4] = tx_cnt++;
+                    
+                    //PER
+                    radio.tx_buf[5] = 'P';
+                    radio.tx_buf[6] = 'E';
+                    radio.tx_buf[7] = 'R';
+                    
+                    //FCS
+                    radio.tx_buf[8] = 0;
+                    
+                    lora.RegPayloadLength = 9;
+                    lora.start_tx(lora.RegPayloadLength);
+                }
+                else {
+                    printf("Not LoRa Mode!\r\n");
+                }
+                    
+                break;
             case 'f':
                 if (!radio.RegOpMode.bits.LongRangeMode) {
                     printf("PacketFormat:");
@@ -1177,6 +1317,7 @@
                     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");
+                    printf("ld[%%d]    LORA get/set low datarate optimize\r\n");
                 } else {
                     printf("bw[a][%%d] FSK get-set rxbw (bwa=afcbw)\r\n");
                     printf("br[%%d]    FSK get-set bitrate\r\n");
@@ -1229,6 +1370,56 @@
                     fsk.start_tx(fsk_tx_length);
                 }
             }
+        //MODTRONIX Added
+        // 't1' = Lora, F=915MHz, BW=500, SF=12, Payload Lenght=9
+        // 't2' = Lora, F=915MHz, BW=250, SF=12, Payload Lenght=9
+        // 't3' = Lora, F=915MHz, BW=125, SF=12, Payload Lenght=9
+        // 't4' = Lora, F=915MHz, BW=62.5, SF=12, Payload Lenght=9
+        } else if (pcbuf[0] == 't' &&  (pcbuf[1] >= '0' && pcbuf[1] <= '9')) {
+            //Lora mode
+            if (!radio.RegOpMode.bits.LongRangeMode) {
+                lora.enable();
+            }
+            radio.RegOpMode.octet = radio.read_reg(REG_OPMODE);
+            if (radio.RegOpMode.bits.LongRangeMode)
+                printf("LoRa\r\n");
+            else
+                printf("FSK\r\n");
+                
+            //BW = 250k (9=500, 8=250, 7=125, 6=62.5)
+            sscanf(pcbuf+1, "%d", &i);
+            radio.set_opmode(RF_OPMODE_STANDBY);
+            lora.setBw(10-i);   //1=9, 2=8, ....
+            lora.RegModemConfig.octet = radio.read_reg(REG_LR_MODEMCONFIG);
+            printf("Current ");
+            lora_printBw();
+            printf("\r\n");
+
+            //Frequency = 915MHz
+            radio.set_frf_MHz(915);
+            printf("%fMHz\r\n", radio.get_frf_MHz());
+   
+            //SF=12
+            lora.setSf(12);
+            printf("SF=12\r\n");
+
+            //Payload Length = 9
+            lora.RegPayloadLength = 9;
+            radio.write_reg(REG_LR_PAYLOADLENGTH, lora.RegPayloadLength);            
+            lora.RegPayloadLength = radio.read_reg(REG_LR_PAYLOADLENGTH);
+            printf("PayloadLength:%d\r\n", lora.RegPayloadLength);
+        //MODTRONIX
+        //Toggle "LowDataRateOptimize bit
+        } else if (pcbuf[0] == 'l' && pcbuf[1] == 'd' && (pcbuf[2] == '0' || pcbuf[2] == '1') && radio.RegOpMode.bits.LongRangeMode) {
+            lora.setLowDataRateOptimize(pcbuf[2]=='0'?0:1);
+
+            if (radio.type == SX1272) {
+                lora.RegModemConfig.octet = radio.read_reg(REG_LR_MODEMCONFIG);
+                printf("LowDataRateOptimize:%d\r\n", lora.RegModemConfig.sx1272bits.LowDataRateOptimize);
+            } else if (radio.type == SX1276) {
+                lora.RegModemConfig3.octet = radio.read_reg(REG_LR_MODEMCONFIG3);
+                printf("LowDataRateOptimize:%d\r\n", lora.RegModemConfig3.sx1276bits.LowDataRateOptimize);        
+            }
         } else if (pcbuf[0] == 'h' && pcbuf[1] == 'p' && radio.RegOpMode.bits.LongRangeMode) {
             if (pcbuf[2] >= '0' && pcbuf[2] <= '9') {
                 sscanf(pcbuf+2, "%d", &i);
@@ -1401,7 +1592,7 @@
             }
             fsk.RegSyncConfig.octet = radio.read_reg(REG_FSK_SYNCCONFIG);
             printf("SyncSize:%d\r\n", fsk.RegSyncConfig.bits.SyncSize);
-        } else if (pcbuf[0] == 's' && pcbuf[1] == 'f' && radio.RegOpMode.bits.LongRangeMode) {
+        } else if (pcbuf[0] == 's' && pcbuf[1] == 'f' && radio.RegOpMode.bits.LongRangeMode) {  //sf%d = SF
             if (pcbuf[2] >= '0' && pcbuf[2] <= '9') {
                 sscanf(pcbuf+2, "%d", &i);
                 lora.setSf(i);
@@ -1419,7 +1610,7 @@
                 fsk.set_tx_fdev_hz(i);
             }
             printf("fdev:%dHz\r\n", fsk.get_tx_fdev_hz());
-        } else if (pcbuf[0] == 'f' && pcbuf[1] == 'r' && pcbuf[2] == 'f') {
+        } else if (pcbuf[0] == 'f' && pcbuf[1] == 'r' && pcbuf[2] == 'f') {     //fr
             if (pcbuf[3] >= '0' && pcbuf[3] <= '9') {
                 float MHz;
                 sscanf(pcbuf+3, "%f", &MHz);
@@ -1427,7 +1618,7 @@
                 radio.set_frf_MHz(MHz);
             }
             printf("%fMHz\r\n", radio.get_frf_MHz());
-        } else if (pcbuf[0] == 'p' && pcbuf[1] == 'r' && pcbuf[2] == 'e') {
+        } else if (pcbuf[0] == 'p' && pcbuf[1] == 'r' && pcbuf[2] == 'e') {     //pr%d = preamble length
             if (radio.RegOpMode.bits.LongRangeMode) {
                 if (pcbuf[3] >= '0' && pcbuf[3] <= '9') {
                     sscanf(pcbuf+3, "%d", &i);
@@ -1442,7 +1633,7 @@
                 }
                 printf("FSK TX PreambleSize:%d\r\n", radio.read_u16(REG_FSK_PREAMBLEMSB));
             }
-        } else if (pcbuf[0] == 'p' && pcbuf[1] == 't' && !radio.RegOpMode.bits.LongRangeMode) {
+        } else if (pcbuf[0] == 'p' && pcbuf[1] == 't' && !radio.RegOpMode.bits.LongRangeMode) { //pt%d = PreambleDetectTo
             if (pcbuf[2] >= '0' && pcbuf[2] <= '9') {
                 sscanf(pcbuf+2, "%d", &i);
                 fsk.RegPreambleDetect.bits.PreambleDetectorTol = i;
@@ -1458,7 +1649,7 @@
                 printf("On\r\n");
             else
                 printf("OFF\r\n");            
-        } else if (pcbuf[0] == 'p' && pcbuf[1] == 'l' && radio.RegOpMode.bits.LongRangeMode) {
+        } else if (pcbuf[0] == 'p' && pcbuf[1] == 'l' && radio.RegOpMode.bits.LongRangeMode) {  //pl%d = Payload Length
             if (pcbuf[2] >= '0' && pcbuf[2] <= '9') {
                 sscanf(pcbuf+2, "%d", &i);
                 lora.RegPayloadLength = i;
@@ -1509,16 +1700,21 @@
     }
     printf("> ");
     fflush(stdout);
-        
+       
 }
 
 int main()
 {  
-
     pc.baud(57600);
     
-    radio.frfs = frfs;
-
+    mybuf[0] = 0;
+    initDone=0;
+    tmr.start();
+    t = tmr.read_ms() + 5000;   //Start transmitting messages after ? seconds
+    
+    //Required for V7 of SX127x library, but V7 doesn't work for this program!
+    radio.rf_switch.attach(rfsw_callback);
+    
     while(1) {
         switch (app) {
             case APP_NONE:
@@ -1528,6 +1724,8 @@
                 console_chat();
                 break;
         } // ...switch (app)
+        
     } // ...while(1)
 }
 
+