Driver for SX1272 connected to Pulga devices using only DIO0 pins and polling (error states and timeout).

Dependents:   pulga-mbed-lorawan-gps mbed-lorawan-pulga mbed-lorawan-pulga-testing-channel mbed-lorawan-pulga-serial_rx ... more

Revision:
1:3bdd6f917bf5
Parent:
0:561d07a737bc
Child:
2:6c5853c2fd72
--- a/SX1272/SX1272_LoRaRadio.cpp	Thu Nov 12 19:26:24 2020 +0000
+++ b/SX1272/SX1272_LoRaRadio.cpp	Thu Nov 12 21:35:41 2020 +0000
@@ -47,8 +47,6 @@
 #define XTAL_FREQ                                   32000000
 #define FREQ_STEP                                   61.03515625
 
-
-
 enum RadioVariant {
     SX1272UNDEFINED = 0,
     SX1272MB2XAS,
@@ -139,8 +137,8 @@
 #define SIG_DIO1    0x02
 #define SIG_DIO2    0x04
 #define SIG_DIO3    0x08
-#define SIG_DIO4    0x10
-#define SIG_DIO5    0x20
+#define SIG_LRHOP   0x10
+#define SIG_LRCAD   0x20
 #define SIG_TIMOUT  0x40
 #define SIG_RXSYNC  0x80
 
@@ -174,7 +172,7 @@
     :   _spi(spi_mosi, spi_miso, spi_sclk),
         _chip_select(nss, 1),
         _reset_ctl(reset),
-        _dio0_ctl(dio0), _dio1_ctl(dio1), _dio2_ctl(dio2), _dio3_ctl(dio3), _dio4_ctl(dio4), _dio5_ctl(dio5),
+        _dio0_ctl(dio0), _dio1_ctl(dio1), _dio2_ctl(dio2),
         _rf_switch_ctl1(rf_switch_ctl1, 0), _rf_switch_ctl2(rf_switch_ctl2, 0), _txctl(txctl, 0), _rxctl(rxctl, 0),
         _ant_switch(antswitch, PIN_INPUT, PullUp, 0),
         _pwr_amp_ctl(pwr_amp_ctl),
@@ -192,8 +190,7 @@
     _rf_ctrls.txctl = txctl;
     
     _dio1_pin = dio1;
-    _dio4_pin = dio4;
-    _dio5_pin = dio5;
+    _dio2_pin = dio2;
 
     _radio_events = NULL;
 
@@ -319,6 +316,8 @@
     // stop timers
     tx_timeout_timer.detach();
     rx_sync_timer.detach();
+    lora_cad_timer.detach();
+    lora_hop_timer.detach();
 
     // put module in sleep mode
     set_operation_mode(RF_OPMODE_SLEEP);
@@ -846,7 +845,8 @@
 
         case MODEM_LORA:
 
-            if (_rf_settings.lora.freq_hop_on == true) {
+            if (_rf_settings.lora.freq_hop_on == true)
+            {
                 write_to_register(REG_LR_IRQFLAGSMASK,
                                   RFLR_IRQFLAGS_RXTIMEOUT |
                                   RFLR_IRQFLAGS_RXDONE |
@@ -862,7 +862,9 @@
                                   RFLR_DIOMAPPING1_DIO2_MASK) |
                                   RFLR_DIOMAPPING1_DIO0_01 |
                                   RFLR_DIOMAPPING1_DIO2_01);
-            } else {
+            }
+            else
+            {
                 write_to_register(REG_LR_IRQFLAGSMASK,
                                   RFLR_IRQFLAGS_RXTIMEOUT |
                                   RFLR_IRQFLAGS_RXDONE |
@@ -882,8 +884,15 @@
     }
 
     _rf_settings.state = RF_TX_RUNNING;
+    
     tx_timeout_timer.attach_us(callback(this, &SX1272_LoRaRadio::timeout_irq_isr),
                                timeout * 1000);
+    
+    if ((_rf_settings.modem == MODEM_LORA) && (_rf_settings.lora.freq_hop_on == true))
+    {
+        lora_hop_timer.attach_us(callback(this, &SX1272_LoRaRadio::lrhop_irq_isr), 1000);
+    }
+    
     set_operation_mode(RF_OPMODE_TRANSMITTER);
 }
 
@@ -1012,8 +1021,13 @@
     }
     else
     {
+        set_operation_mode(RFLR_OPMODE_RECEIVER_SINGLE);
         rx_sync_timer.attach_us(callback(this, &SX1272_LoRaRadio::rxsync_irq_isr), 1000);
-        set_operation_mode(RFLR_OPMODE_RECEIVER_SINGLE);
+    }
+    
+    if (_rf_settings.lora.freq_hop_on == true)
+    {
+        lora_hop_timer.attach_us(callback(this, &SX1272_LoRaRadio::lrhop_irq_isr), 1000);
     }
 }
 
@@ -1116,8 +1130,6 @@
     
     push_trace(SX1272_start_cad);
     
-    printf("start cad!\n");
-
     switch (_rf_settings.modem) {
         case MODEM_FSK:
             break;
@@ -1137,9 +1149,8 @@
                               RFLR_DIOMAPPING1_DIO3_00);
 
             set_operation_mode(RFLR_OPMODE_CAD);
-
             _rf_settings.state = RF_CAD;
-
+            lora_cad_timer.attach_us(callback(this, &SX1272_LoRaRadio::lrcad_irq_isr), 1000);
             break;
         default:
             break;
@@ -1178,6 +1189,8 @@
     push_trace(SX1272_standby);
     tx_timeout_timer.detach();
     rx_sync_timer.detach();
+    lora_cad_timer.detach();
+    lora_hop_timer.detach();
     set_operation_mode(RF_OPMODE_STANDBY);
     _rf_settings.state = RF_IDLE;
 }
@@ -1245,14 +1258,11 @@
         if (flags & SIG_DIO2) {
             handle_dio2_irq();
         }
-        if (flags & SIG_DIO3) {
-            handle_dio3_irq();
+        if (flags & SIG_LRHOP) {
+            handle_lrhop_irq();
         }
-        if (flags & SIG_DIO4) {
-            handle_dio4_irq();
-        }
-        if (flags & SIG_DIO5) {
-            handle_dio5_irq();
+        if (flags & SIG_LRCAD) {
+            handle_lrcad_irq();
         }
         if (flags & SIG_TIMOUT) {
             handle_timeout_irq();
@@ -1629,14 +1639,8 @@
         _dio1_ctl.rise(callback(this, &SX1272_LoRaRadio::dio1_irq_isr));
     }
     
-    _dio2_ctl.rise(callback(this, &SX1272_LoRaRadio::dio2_irq_isr));
-    _dio3_ctl.rise(callback(this, &SX1272_LoRaRadio::dio3_irq_isr));
-    
-    if (_dio4_pin != NC) {
-        _dio4_ctl.rise(callback(this, &SX1272_LoRaRadio::dio4_irq_isr));
-    }
-    if (_dio5_pin != NC) {
-        _dio5_ctl.rise(callback(this, &SX1272_LoRaRadio::dio5_irq_isr));
+    if (_dio2_pin != NC) {
+        _dio2_ctl.rise(callback(this, &SX1272_LoRaRadio::dio2_irq_isr));
     }
 }
 
@@ -1708,33 +1712,6 @@
 #endif
 }
 
-void SX1272_LoRaRadio::dio3_irq_isr()
-{
-#ifdef MBED_CONF_RTOS_PRESENT
-    irq_thread.flags_set(SIG_DIO3);
-#else
-    handle_dio3_irq();
-#endif
-}
-
-void SX1272_LoRaRadio::dio4_irq_isr()
-{
-#ifdef MBED_CONF_RTOS_PRESENT
-    irq_thread.flags_set(SIG_DIO4);
-#else
-    handle_dio4_irq();
-#endif
-}
-
-void SX1272_LoRaRadio::dio5_irq_isr()
-{
-#ifdef MBED_CONF_RTOS_PRESENT
-    irq_thread.flags_set(SIG_DIO5);
-#else
-    handle_dio5_irq();
-#endif
-}
-
 // This is not a hardware interrupt
 // we invoke it ourselves based upon
 // our timers
@@ -1756,6 +1733,24 @@
 #endif
 }
 
+void SX1272_LoRaRadio::lrcad_irq_isr()
+{
+#ifdef MBED_CONF_RTOS_PRESENT
+    irq_thread.flags_set(SIG_LRCAD);
+#else
+    handle_lrcad_irq();
+#endif
+}
+
+void SX1272_LoRaRadio::lrhop_irq_isr()
+{
+#ifdef MBED_CONF_RTOS_PRESENT
+    irq_thread.flags_set(SIG_LRHOP);
+#else
+    handle_lrhop_irq();
+#endif
+}
+
 /******************************************************************************
  * Interrupt Handlers                                                         *
  *****************************************************************************/
@@ -2046,16 +2041,6 @@
 
                 break;
             case MODEM_LORA:
-                if( _rf_settings.lora.freq_hop_on == true )
-                {
-                    // Clear Irq
-                    write_to_register( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL );
-
-                    if( ( _radio_events != NULL ) && (_radio_events->fhss_change_channel ) )
-                    {
-                        _radio_events->fhss_change_channel((read_register( REG_LR_HOPCHANNEL ) & RFLR_HOPCHANNEL_CHANNEL_MASK ));
-                    }
-                }
                 break;
             default:
                 break;
@@ -2067,16 +2052,6 @@
             case MODEM_FSK:
                 break;
             case MODEM_LORA:
-                if( _rf_settings.lora.freq_hop_on == true )
-                {
-                    // Clear Irq
-                    write_to_register( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL );
-
-                    if( (_radio_events != NULL ) && ( _radio_events->fhss_change_channel ) )
-                    {
-                        _radio_events->fhss_change_channel((read_register( REG_LR_HOPCHANNEL ) & RFLR_HOPCHANNEL_CHANNEL_MASK ));
-                    }
-                }
                 break;
             default:
                 break;
@@ -2087,73 +2062,6 @@
     }
 }
 
-void SX1272_LoRaRadio::handle_dio3_irq( void )
-{
-    push_trace(SX1272_dio3_irq);
-    
-    switch( _rf_settings.modem )
-    {
-    case MODEM_FSK:
-        break;
-    case MODEM_LORA:
-        if( ( read_register( REG_LR_IRQFLAGS ) & RFLR_IRQFLAGS_CADDETECTED ) == RFLR_IRQFLAGS_CADDETECTED )
-        {
-            // Clear Irq
-            write_to_register( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_CADDETECTED | RFLR_IRQFLAGS_CADDONE );
-            if( ( _radio_events != NULL ) && ( _radio_events->cad_done ) )
-            {
-                _radio_events->cad_done( true );
-            }
-        }
-        else
-        {
-            // Clear Irq
-            write_to_register( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_CADDONE );
-            if( ( _radio_events != NULL ) && ( _radio_events->cad_done ) )
-            {
-                _radio_events->cad_done( false );
-            }
-        }
-        break;
-    default:
-        break;
-    }
-}
-
-void SX1272_LoRaRadio::handle_dio4_irq(void)
-{
-    push_trace(SX1272_dio4_irq);
-    
-    // is asserted when a preamble is detected (FSK modem only)
-    switch (_rf_settings.modem) {
-        case MODEM_FSK: {
-            if (_rf_settings.fsk_packet_handler.preamble_detected == 0) {
-                _rf_settings.fsk_packet_handler.preamble_detected = 1;
-            }
-        }
-            break;
-        case MODEM_LORA:
-            break;
-        default:
-            break;
-    }
-}
-
-void SX1272_LoRaRadio::handle_dio5_irq()
-{
-    push_trace(SX1272_dio5_irq);
-    
-    switch( _rf_settings.modem )
-    {
-    case MODEM_FSK:
-        break;
-    case MODEM_LORA:
-        break;
-    default:
-        break;
-    }
-}
-
 void SX1272_LoRaRadio::handle_timeout_irq()
 {
     push_trace(SX1272_timeout_irq);
@@ -2188,26 +2096,95 @@
 {
     rx_sync_timer.detach();
     
-    if (_rf_settings.state == RF_RX_RUNNING)
+    if (_rf_settings.modem != MODEM_LORA) {
+        return;
+    }
+    if (_rf_settings.state != RF_RX_RUNNING) {
+        return;
+    }
+    
+    if((read_register(REG_OPMODE) & 0x7) == RFLR_OPMODE_RECEIVER_SINGLE)
+    {
+        rx_sync_timer.attach_us(callback(this, &SX1272_LoRaRadio::rxsync_irq_isr), 1000);
+    }
+    else
     {
-        if((read_register(REG_OPMODE) & 0x7) == RFLR_OPMODE_RECEIVER_SINGLE)
+        push_trace(SX1272_rxsymb_irq);
+            
+        // Sync time out
+        _rf_settings.state = RF_IDLE;
+            
+        if ((_radio_events != NULL) && (_radio_events->rx_timeout)) {
+            _radio_events->rx_timeout();
+        }
+    }
+}
+
+void SX1272_LoRaRadio::handle_lrcad_irq()
+{
+    lora_cad_timer.detach();
+    
+    if (_rf_settings.modem != MODEM_LORA) {
+        return;
+    }
+    if (_rf_settings.state != RF_CAD) {
+        return;
+    }
+    
+    if((read_register(REG_OPMODE) & 0x7) == RFLR_OPMODE_CAD)
+    {
+        lora_cad_timer.attach_us(callback(this, &SX1272_LoRaRadio::lrcad_irq_isr), 1000);
+    }
+    else
+    {
+        _rf_settings.state = RF_IDLE;
+            
+        if( ( read_register( REG_LR_IRQFLAGS ) & RFLR_IRQFLAGS_CADDETECTED ) == RFLR_IRQFLAGS_CADDETECTED )
         {
-            rx_sync_timer.attach_us(callback(this, &SX1272_LoRaRadio::rxsync_irq_isr), 1000);
+            // Clear Irq
+            write_to_register( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_CADDETECTED | RFLR_IRQFLAGS_CADDONE );
+                
+            if( ( _radio_events != NULL ) && ( _radio_events->cad_done ) )
+            {
+                _radio_events->cad_done( true );
+            }
         }
         else
         {
-            push_trace(SX1272_rxsymb_irq);
-            
-            // Sync time out
-            _rf_settings.state = RF_IDLE;
-            
-            if ((_radio_events != NULL) && (_radio_events->rx_timeout)) {
-                _radio_events->rx_timeout();
+            // Clear Irq
+            write_to_register( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_CADDONE );
+            if( ( _radio_events != NULL ) && ( _radio_events->cad_done ) )
+            {
+                _radio_events->cad_done( false );
             }
         }
     }
 }
 
+void SX1272_LoRaRadio::handle_lrhop_irq()
+{
+    lora_hop_timer.detach();
+    
+    if ((_rf_settings.state != RF_TX_RUNNING) && (_rf_settings.state != RF_RX_RUNNING)) {
+        return;
+    }
+    if ((_rf_settings.modem != MODEM_LORA) || (_rf_settings.lora.freq_hop_on == false)) {
+        return;
+    }
+    
+    lora_hop_timer.attach_us(callback(this, &SX1272_LoRaRadio::lrhop_irq_isr), 1000);
+        
+    if((read_register(REG_LR_IRQFLAGS) & RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL) == RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL)
+    {
+        write_to_register( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL );
+        
+        if((_radio_events != NULL) && (_radio_events->fhss_change_channel))
+        {
+            _radio_events->fhss_change_channel((read_register( REG_LR_HOPCHANNEL ) & RFLR_HOPCHANNEL_CHANNEL_MASK));
+        }
+    }
+}
+
 bool SX1272_LoRaRadio::pop_trace(SX1272_Trace &trace)
 {
     if (trace_buf.empty()) {