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

Files at this revision

API Documentation at this revision

Comitter:
modtronix
Date:
Mon Feb 16 01:53:18 2015 +0000
Parent:
4:7a9007dfc0e5
Commit message:
Terminal for sending and receiving data via Semtech SX1276 chip.

Changed in this revision

SX127x.lib Show diff for this revision Revisions of this file
SX127x_modtronix.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show diff for this revision Revisions of this file
mbed.lib Show annotated file Show diff for this revision Revisions of this file
--- a/SX127x.lib	Tue May 20 17:18:47 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-http://mbed.org/users/dudmuck/code/SX127x/#d987ac2836bf
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SX127x_modtronix.lib	Mon Feb 16 01:53:18 2015 +0000
@@ -0,0 +1,1 @@
+http://developer.mbed.org/users/modtronix/code/SX127x_modtronix/#3d148697c0d3
--- 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)
 }
 
+
--- a/mbed.bld	Tue May 20 17:18:47 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-http://mbed.org/users/mbed_official/code/mbed/builds/7d30d6019079
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.lib	Mon Feb 16 01:53:18 2015 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/#e188a91d3eaa