Version of personalized IMPACT LoRa

Fork of LMiC-10secs by Alcatel-Lucent IoT Development

Revision:
1:d3b7bde3995c
Parent:
0:62d1edcc13d1
diff -r 62d1edcc13d1 -r d3b7bde3995c radio.cpp
--- a/radio.cpp	Thu Jan 22 12:50:49 2015 +0000
+++ b/radio.cpp	Tue Mar 31 13:36:56 2015 +0000
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2014 IBM Corporation.
+ * Copyright (c) 2014-2015 IBM Corporation.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -14,15 +14,16 @@
  *                              USE_SMTC_RADIO_DRIVER preprocessing directive
  *                              in lmic.h
  *******************************************************************************/
+
 #include "lmic.h"
 
 #if USE_SMTC_RADIO_DRIVER
 #include "sx1276-hal.h"
 
 /*!
- * Syncword for lora networks (nibbles swapped)
+ * Syncword for lora networks
  */
-#define LORA_MAC_SYNCWORD           0x34
+#define LORA_MAC_SYNCWORD                           0x34
 
 /*
  * Callback functions prototypes
@@ -81,7 +82,7 @@
 {
     ostime_t now = os_getTime( );
     // save exact tx time
-    LMIC.txend = now - us2osticks( 43 ); // TXDONE FIXUP
+    LMIC.txend = now - us2osticks( RADIO_WAKEUP_TIME ); // TXDONE FIXUP
     
     // go from stanby to sleep
     Radio.Sleep( );
@@ -93,14 +94,18 @@
 {
     ostime_t now = os_getTime( );
     // save exact rx time
-    LMIC.rxtime = now - LORA_RXDONE_FIXUP[getSf( LMIC.rps )];
+    if( getBw( LMIC.rps ) == BW125 )
+    {
+        now -= LORA_RXDONE_FIXUP[getSf( LMIC.rps )];
+    }
+    LMIC.rxtime = now;
     // read the PDU and inform the MAC that we received something
     LMIC.dataLen = size;
     // now read the FIFO
     memcpy( LMIC.frame, payload, size );
     // read rx quality parameters
-    LMIC.rxq.snr  = snr; // SNR [dB] * 4
-    LMIC.rxq.rssi = rssi; // RSSI [dBm] (-196...+63)
+    LMIC.snr  = snr; // SNR [dB] * 4
+    LMIC.rssi = rssi; // RSSI [dBm] (-196...+63)
 
     // go from stanby to sleep
     Radio.Sleep( );
@@ -113,7 +118,8 @@
     ostime_t now = os_getTime( );
 
     // indicate error
-
+    LMIC.dataLen = 0;
+    
     // go from stanby to sleep
     Radio.Sleep( );
     // run os job (use preset func ptr)
@@ -230,7 +236,7 @@
         else
         { // LoRa modem
             
-            Radio.SetTxConfig( MODEM_LORA, LMIC.txpow, 0, getBw( LMIC.rps ), getSf( LMIC.rps ) + 6, getCr( LMIC.rps ) + 1, 8, getIh( LMIC.rps ) ? true : false, ( getNocrc(LMIC.rps) == 0 ) ? true : false, 0, 0, false, 3e6 );
+            Radio.SetTxConfig( MODEM_LORA, LMIC.txpow, 0, getBw( LMIC.rps ), getSf( LMIC.rps ) + 6, getCr( LMIC.rps ) + 1, 8, getIh( LMIC.rps ) ? true : false, ( getNocrc( LMIC.rps ) == 0 ) ? true : false, 0, 0, false, 3e6 );
         }
 
         //starttx( ); // buf=LMIC.frame, len=LMIC.dataLen
@@ -249,8 +255,14 @@
         }
         else
         { // LoRa modem
-            
-            Radio.SetRxConfig( MODEM_LORA, getBw( LMIC.rps ), getSf( LMIC.rps ) + 6, getCr( LMIC.rps ) + 1, 0, 8, LMIC.rxsyms, getIh( LMIC.rps ) ? true : false, getIh(LMIC.rps), ( getNocrc(LMIC.rps) == 0 ) ? true : false, 0, 0, true, false );
+            if( ( getSf( LMIC.rps ) <= SF9 ) && ( LMIC.rxsyms < 8 ) )
+            {
+                Radio.SetRxConfig( MODEM_LORA, getBw( LMIC.rps ), getSf( LMIC.rps ) + 6, getCr( LMIC.rps ) + 1, 0, 8, LMIC.rxsyms + 3, getIh( LMIC.rps ) ? true : false, getIh( LMIC.rps ), ( getNocrc( LMIC.rps ) == 0 ) ? true : false, 0, 0, true, false );
+            }
+            else
+            {
+                Radio.SetRxConfig( MODEM_LORA, getBw( LMIC.rps ), getSf( LMIC.rps ) + 6, getCr( LMIC.rps ) + 1, 0, 8, LMIC.rxsyms, getIh( LMIC.rps ) ? true : false, getIh( LMIC.rps ), ( getNocrc( LMIC.rps ) == 0 ) ? true : false, 0, 0, true, false );
+            }
         }
 
         // now instruct the radio to receive
@@ -279,10 +291,10 @@
         }
         else
         { // LoRa modem
-            Radio.SetRxConfig( MODEM_LORA, getBw( LMIC.rps ), getSf( LMIC.rps ) + 6, getCr( LMIC.rps ) + 1, 0, 8, LMIC.rxsyms, getIh( LMIC.rps ) ? true : false, getIh(LMIC.rps), ( getNocrc(LMIC.rps) == 0 ) ? true : false, 0, 0, true, true );
+            Radio.SetRxConfig( MODEM_LORA, getBw( LMIC.rps ), getSf( LMIC.rps ) + 6, getCr( LMIC.rps ) + 1, 0, 8, LMIC.rxsyms, getIh( LMIC.rps ) ? true : false, getIh( LMIC.rps ), ( getNocrc( LMIC.rps ) == 0 ) ? true : false, 0, 0, true, true );
         }
 
-        //startrx( RXMODE_SCAN) ; // buf = LMIC.frame
+        //startrx( RXMODE_SCAN ); // buf = LMIC.frame
         Radio.Rx( 0 );
         break;
     }
@@ -448,7 +460,7 @@
 #define SX1276_MC3_AGCAUTO                 0x04
 
 // preamble for lora networks (nibbles swapped)
-#define LORA_MAC_PREAMBLE           0x34
+#define LORA_MAC_PREAMBLE                  0x34
 
 #define RXLORA_RXMODE_RSSI_REG_MODEM_CONFIG1 0x0A
 #ifdef CFG_sx1276_radio
@@ -539,6 +551,12 @@
 #error Missing CFG_sx1272_radio/CFG_sx1276_radio
 #endif
 
+#define RADIO_DBG
+#if defined(RADIO_DBG)
+DigitalOut txStateIo( PB_8 );
+DigitalOut rxStateIo( PB_9 );
+#endif
+
 static void writeReg (u1_t addr, u1_t data ) {
     hal_pin_nss(0);
     hal_spi(addr | 0x80);
@@ -576,7 +594,7 @@
     writeReg(RegOpMode, (readReg(RegOpMode) & ~OPMODE_MASK) | mode);
 }
 
-static void opmodeLora(void) {
+static void opmodeLora() {
     u1_t u = OPMODE_LORA;
 #ifdef CFG_sx1276_radio
     u |= 0x8;   // TBD: sx1276 high freq
@@ -584,7 +602,7 @@
     writeReg(RegOpMode, u);
 }
 
-static void opmodeFSK(void) {
+static void opmodeFSK() {
     u1_t u = 0;
 #ifdef CFG_sx1276_radio
     u |= 0x8;   // TBD: sx1276 high freq
@@ -593,79 +611,79 @@
 }
 
 // configure LoRa modem (cfg1, cfg2)
-static void configLoraModem (void) {
+static void configLoraModem () {
     sf_t sf = getSf(LMIC.rps);
 
 #ifdef CFG_sx1276_radio
-    u1_t mc1 = 0, mc2 = 0, mc3 = 0;
+        u1_t mc1 = 0, mc2 = 0, mc3 = 0;
 
-    switch (getBw(LMIC.rps)) {
-    case BW125: mc1 |= SX1276_MC1_BW_125; break;
-    case BW250: mc1 |= SX1276_MC1_BW_250; break;
-    case BW500: mc1 |= SX1276_MC1_BW_500; break;
-    default:
-        ASSERT(0);
-    }
-    switch( getCr(LMIC.rps) ) {
-    case CR_4_5: mc1 |= SX1276_MC1_CR_4_5; break;
-    case CR_4_6: mc1 |= SX1276_MC1_CR_4_6; break;
-    case CR_4_7: mc1 |= SX1276_MC1_CR_4_7; break;
-    case CR_4_8: mc1 |= SX1276_MC1_CR_4_8; break;
-    default:
-        ASSERT(0);
-    }
+        switch (getBw(LMIC.rps)) {
+        case BW125: mc1 |= SX1276_MC1_BW_125; break;
+        case BW250: mc1 |= SX1276_MC1_BW_250; break;
+        case BW500: mc1 |= SX1276_MC1_BW_500; break;
+        default:
+            ASSERT(0);
+        }
+        switch( getCr(LMIC.rps) ) {
+        case CR_4_5: mc1 |= SX1276_MC1_CR_4_5; break;
+        case CR_4_6: mc1 |= SX1276_MC1_CR_4_6; break;
+        case CR_4_7: mc1 |= SX1276_MC1_CR_4_7; break;
+        case CR_4_8: mc1 |= SX1276_MC1_CR_4_8; break;
+        default:
+            ASSERT(0);
+        }
 
-    if (getIh(LMIC.rps)) {
-        mc1 |= SX1276_MC1_IMPLICIT_HEADER_MODE_ON;
-        writeReg(LORARegPayloadLength, getIh(LMIC.rps)); // required length
-    }
-    // set ModemConfig1
-    writeReg(LORARegModemConfig1, mc1);
+        if (getIh(LMIC.rps)) {
+            mc1 |= SX1276_MC1_IMPLICIT_HEADER_MODE_ON;
+            writeReg(LORARegPayloadLength, getIh(LMIC.rps)); // required length
+        }
+        // set ModemConfig1
+        writeReg(LORARegModemConfig1, mc1);
 
-    mc2 = (SX1272_MC2_SF7 + ((sf-1)<<4));
-    if (getNocrc(LMIC.rps) == 0) {
-        mc2 |= SX1276_MC2_RX_PAYLOAD_CRCON;
-    }
-    writeReg(LORARegModemConfig2, mc2);
-    
-    mc3 = SX1276_MC3_AGCAUTO;
-    if (sf == SF11 || sf == SF12) {
-        mc3 |= SX1276_MC3_LOW_DATA_RATE_OPTIMIZE;
-    }
-    writeReg(LORARegModemConfig3, mc3);
+        mc2 = (SX1272_MC2_SF7 + ((sf-1)<<4));
+        if (getNocrc(LMIC.rps) == 0) {
+            mc2 |= SX1276_MC2_RX_PAYLOAD_CRCON;
+        }
+        writeReg(LORARegModemConfig2, mc2);
+        
+        mc3 = SX1276_MC3_AGCAUTO;
+        if ((sf == SF11 || sf == SF12) && getBw(LMIC.rps) == BW125) {
+            mc3 |= SX1276_MC3_LOW_DATA_RATE_OPTIMIZE;
+        }
+        writeReg(LORARegModemConfig3, mc3);
 #elif CFG_sx1272_radio
-    u1_t mc1 = (getBw(LMIC.rps)<<6);
+        u1_t mc1 = (getBw(LMIC.rps)<<6);
 
-    switch( getCr(LMIC.rps) ) {
-    case CR_4_5: mc1 |= SX1272_MC1_CR_4_5; break;
-    case CR_4_6: mc1 |= SX1272_MC1_CR_4_6; break;
-    case CR_4_7: mc1 |= SX1272_MC1_CR_4_7; break;
-    case CR_4_8: mc1 |= SX1272_MC1_CR_4_8; break;
-    }
-    
-    if (sf == SF11 || sf == SF12) {
-        mc1 |= SX1272_MC1_LOW_DATA_RATE_OPTIMIZE;
-    }
-    
-    if (getNocrc(LMIC.rps) == 0) {
-        mc1 |= SX1272_MC1_RX_PAYLOAD_CRCON;
-    }
-    
-    if (getIh(LMIC.rps)) {
-        mc1 |= SX1272_MC1_IMPLICIT_HEADER_MODE_ON;
-        writeReg(LORARegPayloadLength, getIh(LMIC.rps)); // required length
-    }
-    // set ModemConfig1
-    writeReg(LORARegModemConfig1, mc1);
-    
-    // set ModemConfig2 (sf, AgcAutoOn=1 SymbTimeoutHi=00)
-    writeReg(LORARegModemConfig2, (SX1272_MC2_SF7 + ((sf-1)<<4)) | 0x04);
+        switch( getCr(LMIC.rps) ) {
+        case CR_4_5: mc1 |= SX1272_MC1_CR_4_5; break;
+        case CR_4_6: mc1 |= SX1272_MC1_CR_4_6; break;
+        case CR_4_7: mc1 |= SX1272_MC1_CR_4_7; break;
+        case CR_4_8: mc1 |= SX1272_MC1_CR_4_8; break;
+        }
+        
+        if ((sf == SF11 || sf == SF12) && getBw(LMIC.rps) == BW125) {
+            mc1 |= SX1272_MC1_LOW_DATA_RATE_OPTIMIZE;
+        }
+        
+        if (getNocrc(LMIC.rps) == 0) {
+            mc1 |= SX1272_MC1_RX_PAYLOAD_CRCON;
+        }
+        
+        if (getIh(LMIC.rps)) {
+            mc1 |= SX1272_MC1_IMPLICIT_HEADER_MODE_ON;
+            writeReg(LORARegPayloadLength, getIh(LMIC.rps)); // required length
+        }
+        // set ModemConfig1
+        writeReg(LORARegModemConfig1, mc1);
+        
+        // set ModemConfig2 (sf, AgcAutoOn=1 SymbTimeoutHi=00)
+        writeReg(LORARegModemConfig2, (SX1272_MC2_SF7 + ((sf-1)<<4)) | 0x04);
 #else
 #error Missing CFG_sx1272_radio/CFG_sx1276_radio
 #endif /* CFG_sx1272_radio */
 }
 
-static void configChannel (void) {
+static void configChannel () {
     // set frequency: FQ = (FRF * 32 Mhz) / (2 ^ 19)
     u8_t frf = ((u8_t)LMIC.freq << 19) / 32000000;
     writeReg(RegFrfMsb, (u1_t)(frf>>16));
@@ -675,26 +693,26 @@
 
 
 
-static void configPower (void) {
+static void configPower () {
 #ifdef CFG_sx1276_radio
     // no boost used for now
     s1_t pw = (s1_t)LMIC.txpow;
-    if(pw > 14) {
-    pw = 14;
-    } else if(pw < -1) {
-    pw = -1;
+    if(pw >= 17) {
+        pw = 15;
+    } else if(pw < 2) {
+        pw = 2;
     }
     // check board type for BOOST pin
-    writeReg(RegPaConfig, (u1_t)(0x00|((pw+1)&0xf)));
+    writeReg(RegPaConfig, (u1_t)(0x80|(pw&0xf)));
     writeReg(RegPaDac, readReg(RegPaDac)|0x4);
 
 #elif CFG_sx1272_radio
     // set PA config (2-17 dBm using PA_BOOST)
     s1_t pw = (s1_t)LMIC.txpow;
     if(pw > 17) {
-    pw = 17;
+        pw = 17;
     } else if(pw < 2) {
-    pw = 2;
+        pw = 2;
     }
     writeReg(RegPaConfig, (u1_t)(0x80|(pw-2)));
 #else
@@ -702,12 +720,16 @@
 #endif /* CFG_sx1272_radio */
 }
 
-static void txfsk (void) {
+static void txfsk () {
     // select FSK modem (from sleep mode)
     writeReg(RegOpMode, 0x10); // FSK, BT=0.5
     ASSERT(readReg(RegOpMode) == 0x10);
     // enter standby mode (required for FIFO loading))
     opmode(OPMODE_STANDBY);
+#if defined(RADIO_DBG)
+    txStateIo = 0;
+    rxStateIo = 0;
+#endif
     // set bitrate
     writeReg(FSKRegBitrateMsb, 0x02); // 50kbps
     writeReg(FSKRegBitrateLsb, 0x80);
@@ -743,9 +765,12 @@
     
     // now we actually start the transmission
     opmode(OPMODE_TX);
+#if defined(RADIO_DBG)
+    txStateIo = 1;
+#endif
 }
 
-static void txlora (void) {
+static void txlora () {
     // select LoRa modem (from sleep mode)
     //writeReg(RegOpMode, OPMODE_LORA);
     opmodeLora();
@@ -753,6 +778,10 @@
 
     // enter standby mode (required for FIFO loading))
     opmode(OPMODE_STANDBY);
+#if defined(RADIO_DBG)
+    txStateIo = 0;
+    rxStateIo = 0;
+#endif
     // configure LoRa modem (cfg1, cfg2)
     configLoraModem();
     // configure frequency
@@ -786,7 +815,7 @@
 }
 
 // start transmitter (buf=LMIC.frame, len=LMIC.dataLen)
-static void starttx (void) {
+static void starttx () {
     ASSERT( (readReg(RegOpMode) & OPMODE_MASK) == OPMODE_SLEEP );
     if(getSf(LMIC.rps) == FSK) { // FSK modem
         txfsk();
@@ -812,6 +841,10 @@
     ASSERT((readReg(RegOpMode) & OPMODE_LORA) != 0);
     // enter standby mode (warm up))
     opmode(OPMODE_STANDBY);
+#if defined(RADIO_DBG)
+    txStateIo = 0;
+    rxStateIo = 0;
+#endif
     // don't use MAC settings at startup
     if(rxmode == RXMODE_RSSI) { // use fixed settings for rssi scan
         writeReg(LORARegModemConfig1, RXLORA_RXMODE_RSSI_REG_MODEM_CONFIG1);
@@ -846,9 +879,15 @@
     // now instruct the radio to receive
     if (rxmode == RXMODE_SINGLE) { // single rx
         hal_waitUntil(LMIC.rxtime); // busy wait until exact rx time
-    opmode(OPMODE_RX_SINGLE);
+        opmode(OPMODE_RX_SINGLE);
+#if defined(RADIO_DBG)
+        rxStateIo = 1;
+#endif
     } else { // continous rx (scan or rssi)
-    opmode(OPMODE_RX); 
+        opmode(OPMODE_RX); 
+#if defined(RADIO_DBG)
+        rxStateIo = 1;
+#endif
     }
 }
 
@@ -861,6 +900,10 @@
     ASSERT((readReg(RegOpMode) & OPMODE_LORA) == 0);
     // enter standby mode (warm up))
     opmode(OPMODE_STANDBY);
+#if defined(RADIO_DBG)
+    txStateIo = 0;
+    rxStateIo = 0;
+#endif
     // configure frequency
     configChannel();
     // set LNA gain
@@ -901,6 +944,9 @@
     // now instruct the radio to receive
     hal_waitUntil(LMIC.rxtime); // busy wait until exact rx time
     opmode(OPMODE_RX); // no single rx mode available in FSK
+#if defined(RADIO_DBG)
+    rxStateIo = 1;
+#endif
 }
 
 static void startrx (u1_t rxmode) {
@@ -915,7 +961,7 @@
 }
 
 // get random seed from wideband noise rssi
-void radio_init (void) {
+void radio_init () {
     hal_disableIRQs();
 
     // manually reset radio
@@ -929,6 +975,10 @@
     hal_waitUntil(os_getTime()+ms2osticks(5)); // wait 5ms
 
     opmode(OPMODE_SLEEP);
+#if defined(RADIO_DBG)
+    txStateIo = 0;
+    rxStateIo = 0;
+#endif
     // some sanity checks, e.g., read version number
     u1_t v = readReg(RegVersion);
 #ifdef CFG_sx1276_radio
@@ -950,7 +1000,7 @@
     }
     randbuf[0] = 16; // set initial index
   
-#ifdef CFG_sx1276_radio
+#ifdef CFG_sx1276mb1_board
     // chain calibration
     writeReg(RegPaConfig, 0);
     
@@ -967,15 +1017,19 @@
     // Launch Rx chain calibration for HF band 
     writeReg(FSKRegImageCal, (readReg(FSKRegImageCal) & RF_IMAGECAL_IMAGECAL_MASK)|RF_IMAGECAL_IMAGECAL_START);
     while((readReg(FSKRegImageCal) & RF_IMAGECAL_IMAGECAL_RUNNING) == RF_IMAGECAL_IMAGECAL_RUNNING) { ; }
-#endif /* CFG_sx1276_radio */
+#endif /* CFG_sx1276mb1_board */
 
     opmode(OPMODE_SLEEP);
+#if defined(RADIO_DBG)
+    txStateIo = 0;
+    rxStateIo = 0;
+#endif
     hal_enableIRQs();
 }
 
 // return next random byte derived from seed buffer
 // (buf[0] holds index of next byte to be returned)
-u1_t radio_rand1 (void) {
+u1_t radio_rand1 () {
     u1_t i = randbuf[0];
     ASSERT( i != 0 );
     if( i==16 ) {
@@ -987,7 +1041,7 @@
     return v;
 }
 
-u1_t radio_rssi (void) {
+u1_t radio_rssi () {
     hal_disableIRQs();
     u1_t r = readReg(LORARegRssiValue);
     hal_enableIRQs();
@@ -1009,56 +1063,63 @@
 void radio_irq_handler (u1_t dio) {
     ostime_t now = os_getTime();
     if( (readReg(RegOpMode) & OPMODE_LORA) != 0) { // LORA modem
-    u1_t flags = readReg(LORARegIrqFlags);
-    if( flags & IRQ_LORA_TXDONE_MASK ) {
-        // save exact tx time
-        LMIC.txend = now - us2osticks(43); // TXDONE FIXUP
-    } else if( flags & IRQ_LORA_RXDONE_MASK ) {
-        // save exact rx time
-        LMIC.rxtime = now - LORA_RXDONE_FIXUP[getSf(LMIC.rps)];
-        // read the PDU and inform the MAC that we received something
-        LMIC.dataLen = (readReg(LORARegModemConfig1) & SX1272_MC1_IMPLICIT_HEADER_MODE_ON) ?
-        readReg(LORARegPayloadLength) : readReg(LORARegRxNbBytes);
-        // set FIFO read address pointer
-        writeReg(LORARegFifoAddrPtr, readReg(LORARegFifoRxCurrentAddr)); 
-        // now read the FIFO
-        readBuf(RegFifo, LMIC.frame, LMIC.dataLen);
-        // read rx quality parameters
-        LMIC.rxq.snr  = readReg(LORARegPktSnrValue); // SNR [dB] * 4
-        LMIC.rxq.rssi = readReg(LORARegPktRssiValue) - 125 + 64; // RSSI [dBm] (-196...+63)
-    } else if( flags & IRQ_LORA_RXTOUT_MASK ) {
-        // indicate timeout
-        LMIC.dataLen = 0;
-    }
+        u1_t flags = readReg(LORARegIrqFlags);
+        if( flags & IRQ_LORA_TXDONE_MASK ) {
+            // save exact tx time
+            LMIC.txend = now - us2osticks(43); // TXDONE FIXUP
+        } else if( flags & IRQ_LORA_RXDONE_MASK ) {
+            // save exact rx time
+            if(getBw(LMIC.rps) == BW125) {
+                now -= LORA_RXDONE_FIXUP[getSf(LMIC.rps)];
+            }
+            LMIC.rxtime = now;
+            // read the PDU and inform the MAC that we received something
+            LMIC.dataLen = (readReg(LORARegModemConfig1) & SX1272_MC1_IMPLICIT_HEADER_MODE_ON) ?
+                readReg(LORARegPayloadLength) : readReg(LORARegRxNbBytes);
+            // set FIFO read address pointer
+            writeReg(LORARegFifoAddrPtr, readReg(LORARegFifoRxCurrentAddr)); 
+            // now read the FIFO
+            readBuf(RegFifo, LMIC.frame, LMIC.dataLen);
+            // read rx quality parameters
+            LMIC.snr  = readReg(LORARegPktSnrValue); // SNR [dB] * 4
+            LMIC.rssi = readReg(LORARegPktRssiValue) - 125 + 64; // RSSI [dBm] (-196...+63)
+        } else if( flags & IRQ_LORA_RXTOUT_MASK ) {
+            // indicate timeout
+            LMIC.dataLen = 0;
+        }
         // mask all radio IRQs
         writeReg(LORARegIrqFlagsMask, 0xFF);
         // clear radio IRQ flags
         writeReg(LORARegIrqFlags, 0xFF);
     } else { // FSK modem
-    u1_t flags1 = readReg(FSKRegIrqFlags1);
-    u1_t flags2 = readReg(FSKRegIrqFlags2);
-    if( flags2 & IRQ_FSK2_PACKETSENT_MASK ) {
-        // save exact tx time
-        LMIC.txend = now;
+        u1_t flags1 = readReg(FSKRegIrqFlags1);
+        u1_t flags2 = readReg(FSKRegIrqFlags2);
+        if( flags2 & IRQ_FSK2_PACKETSENT_MASK ) {
+            // save exact tx time
+            LMIC.txend = now;
         } else if( flags2 & IRQ_FSK2_PAYLOADREADY_MASK ) {
-        // save exact rx time
-        LMIC.rxtime = now;
-        // read the PDU and inform the MAC that we received something
-        LMIC.dataLen = readReg(FSKRegPayloadLength);
-        // now read the FIFO
-        readBuf(RegFifo, LMIC.frame, LMIC.dataLen);
-        // read rx quality parameters
-        LMIC.rxq.snr  = 0; // determine snr
-        LMIC.rxq.rssi = 0; // determine rssi
-    } else if( flags1 & IRQ_FSK1_TIMEOUT_MASK ) {
-        // indicate timeout
-        LMIC.dataLen = 0;
-    } else {
+            // save exact rx time
+            LMIC.rxtime = now;
+            // read the PDU and inform the MAC that we received something
+            LMIC.dataLen = readReg(FSKRegPayloadLength);
+            // now read the FIFO
+            readBuf(RegFifo, LMIC.frame, LMIC.dataLen);
+            // read rx quality parameters
+            LMIC.snr  = 0; // determine snr
+            LMIC.rssi = 0; // determine rssi
+        } else if( flags1 & IRQ_FSK1_TIMEOUT_MASK ) {
+            // indicate timeout
+            LMIC.dataLen = 0;
+        } else {
             while(1);
         }
     }
     // go from stanby to sleep
     opmode(OPMODE_SLEEP);
+#if defined(RADIO_DBG)
+    txStateIo = 0;
+    rxStateIo = 0;
+#endif
     // run os job (use preset func ptr)
     os_setCallback(&LMIC.osjob, LMIC.osjob.func);
 }
@@ -1069,21 +1130,34 @@
       case RADIO_RST:
         // put radio to sleep
         opmode(OPMODE_SLEEP);
+#if defined(RADIO_DBG)
+        txStateIo = 0;
+        rxStateIo = 0;
+#endif
         break;
 
       case RADIO_TX:
-    // transmit frame now
+        // transmit frame now
         starttx(); // buf=LMIC.frame, len=LMIC.dataLen
+#if defined(RADIO_DBG)
+        txStateIo = 1;
+#endif
         break;
       
       case RADIO_RX:
-    // receive frame now (exactly at rxtime)
+        // receive frame now (exactly at rxtime)
         startrx(RXMODE_SINGLE); // buf=LMIC.frame, time=LMIC.rxtime, timeout=LMIC.rxsyms
+#if defined(RADIO_DBG)
+        rxStateIo = 1;
+#endif
         break;
 
       case RADIO_RXON:
         // start scanning for beacon now
         startrx(RXMODE_SCAN); // buf=LMIC.frame
+#if defined(RADIO_DBG)
+        rxStateIo = 1;
+#endif
         break;
     }
     hal_enableIRQs();