diff --git a/drivers/include/sx127x.h b/drivers/include/sx127x.h
index 06eb1450fb512dd423414a5a438240cafd0944b9..07ed8d40cdc0838f5d132ade0973ea6a41b80e9f 100644
--- a/drivers/include/sx127x.h
+++ b/drivers/include/sx127x.h
@@ -322,34 +322,6 @@ void sx127x_init_radio_settings(sx127x_t *dev);
  */
 uint32_t sx127x_random(sx127x_t *dev);
 
-/**
- * @brief   sx127x DIO0 IRQ handler.
- *
- * @param[in] arg                      An sx127x device instance
- */
-void sx127x_on_dio0(void *arg);
-
-/**
- * @brief   sx127x DIO1 IRQ handler.
- *
- * @param[in] arg                      An sx127x device instance
- */
-void sx127x_on_dio1(void *arg);
-
-/**
- * @brief   sx127x DIO2 IRQ handler.
- *
- * @param[in] arg                      An sx127x device instance
- */
-void sx127x_on_dio2(void *arg);
-
-/**
- * @brief   sx127x DIO3 IRQ handler.
- *
- * @param[in] arg                      An sx127x device instance
- */
-void sx127x_on_dio3(void *arg);
-
 /**
  * @brief   Start a channel activity detection.
  *
diff --git a/drivers/sx127x/include/sx127x_registers.h b/drivers/sx127x/include/sx127x_registers.h
index 0ec6775d227b085e2b7d7aa2a2bd2edf648b0dc2..82ce7b345be2531008cd5b24f200e0d90cf2b2d8 100644
--- a/drivers/sx127x/include/sx127x_registers.h
+++ b/drivers/sx127x/include/sx127x_registers.h
@@ -597,6 +597,7 @@ extern "C" {
 #define SX127X_RF_OPMODE_TRANSMITTER                                 (0x03)
 #define SX127X_RF_OPMODE_SYNTHESIZER_RX                              (0x04)
 #define SX127X_RF_OPMODE_RECEIVER                                    (0x05)
+#define SX127X_RF_OPMODE_RECEIVER_SINGLE                             (0x06)
 
 /* RegBitRate (bits/sec) */
 #define SX127X_RF_BITRATEMSB_1200_BPS                                (0x68)
diff --git a/drivers/sx127x/sx127x.c b/drivers/sx127x/sx127x.c
index 362acc1c24b924d3fd1ac99757b7a74521e84341..b806958cb89ed5b157c94dac2e7cba0239c9de1b 100644
--- a/drivers/sx127x/sx127x.c
+++ b/drivers/sx127x/sx127x.c
@@ -201,158 +201,6 @@ static void sx127x_on_dio3_isr(void *arg)
 }
 
 /* Internal event handlers */
-void sx127x_on_dio0(void *arg)
-{
-    sx127x_t *dev = (sx127x_t *) arg;
-    netdev_t *netdev = (netdev_t*) &dev->netdev;
-
-    switch (dev->settings.state) {
-        case SX127X_RF_RX_RUNNING:
-            netdev->event_callback(netdev, NETDEV_EVENT_RX_COMPLETE);
-            break;
-        case SX127X_RF_TX_RUNNING:
-            xtimer_remove(&dev->_internal.tx_timeout_timer);
-            switch (dev->settings.modem) {
-                case SX127X_MODEM_LORA:
-                    /* Clear IRQ */
-                    sx127x_reg_write(dev, SX127X_REG_LR_IRQFLAGS,
-                                     SX127X_RF_LORA_IRQFLAGS_TXDONE);
-                /* Intentional fall-through */
-                case SX127X_MODEM_FSK:
-                default:
-                    sx127x_set_state(dev, SX127X_RF_IDLE);
-                    netdev->event_callback(netdev, NETDEV_EVENT_TX_COMPLETE);
-                    break;
-            }
-            break;
-        case SX127X_RF_IDLE:
-            printf("sx127x_on_dio0: IDLE state\n");
-            break;
-        default:
-            printf("sx127x_on_dio0: Unknown state [%d]\n", dev->settings.state);
-            break;
-    }
-}
-
-void sx127x_on_dio1(void *arg)
-{
-    /* Get interrupt context */
-    sx127x_t *dev = (sx127x_t *) arg;
-    netdev_t *netdev = (netdev_t*) &dev->netdev;
-
-    switch (dev->settings.state) {
-        case SX127X_RF_RX_RUNNING:
-            switch (dev->settings.modem) {
-                case SX127X_MODEM_FSK:
-                    /* todo */
-                    break;
-                case SX127X_MODEM_LORA:
-                    xtimer_remove(&dev->_internal.rx_timeout_timer);
-                    /*  Clear Irq */
-                    sx127x_reg_write(dev, SX127X_REG_LR_IRQFLAGS, SX127X_RF_LORA_IRQFLAGS_RXTIMEOUT);
-                    sx127x_set_state(dev, SX127X_RF_IDLE);
-                    netdev->event_callback(netdev, NETDEV_EVENT_RX_TIMEOUT);
-                    break;
-                default:
-                    break;
-            }
-            break;
-        case SX127X_RF_TX_RUNNING:
-            switch (dev->settings.modem) {
-                case SX127X_MODEM_FSK:
-                    /* todo */
-                    break;
-                case SX127X_MODEM_LORA:
-                    break;
-                default:
-                    break;
-            }
-            break;
-        default:
-            puts("sx127x_on_dio1: Unknown state");
-            break;
-    }
-}
-
-void sx127x_on_dio2(void *arg)
-{
-    /* Get interrupt context */
-    sx127x_t *dev = (sx127x_t *) arg;
-    netdev_t *netdev = (netdev_t*) dev;
-
-    switch (dev->settings.state) {
-        case SX127X_RF_RX_RUNNING:
-            switch (dev->settings.modem) {
-                case SX127X_MODEM_FSK:
-                    /* todo */
-                    break;
-                case SX127X_MODEM_LORA:
-                    if (dev->settings.lora.flags & SX127X_CHANNEL_HOPPING_FLAG) {
-                        /* Clear IRQ */
-                        sx127x_reg_write(dev, SX127X_REG_LR_IRQFLAGS,
-                                         SX127X_RF_LORA_IRQFLAGS_FHSSCHANGEDCHANNEL);
-
-                        dev->_internal.last_channel = (sx127x_reg_read(dev, SX127X_REG_LR_HOPCHANNEL) &
-                                                       SX127X_RF_LORA_HOPCHANNEL_CHANNEL_MASK);
-                        netdev->event_callback(netdev, NETDEV_EVENT_FHSS_CHANGE_CHANNEL);
-                    }
-
-                    break;
-                default:
-                    break;
-            }
-            break;
-        case SX127X_RF_TX_RUNNING:
-            switch (dev->settings.modem) {
-                case SX127X_MODEM_FSK:
-                    break;
-                case SX127X_MODEM_LORA:
-                    if (dev->settings.lora.flags & SX127X_CHANNEL_HOPPING_FLAG) {
-                        /* Clear IRQ */
-                        sx127x_reg_write(dev, SX127X_REG_LR_IRQFLAGS,
-                                         SX127X_RF_LORA_IRQFLAGS_FHSSCHANGEDCHANNEL);
-
-                        dev->_internal.last_channel = (sx127x_reg_read(dev, SX127X_REG_LR_HOPCHANNEL) &
-                                                       SX127X_RF_LORA_HOPCHANNEL_CHANNEL_MASK);
-                        netdev->event_callback(netdev, NETDEV_EVENT_FHSS_CHANGE_CHANNEL);
-                    }
-                    break;
-                default:
-                    break;
-            }
-            break;
-        default:
-            puts("sx127x_on_dio2: Unknown state");
-            break;
-    }
-}
-
-void sx127x_on_dio3(void *arg)
-{
-    /* Get interrupt context */
-    sx127x_t *dev = (sx127x_t *) arg;
-    netdev_t *netdev = (netdev_t *) dev;
-
-    switch (dev->settings.modem) {
-        case SX127X_MODEM_FSK:
-            break;
-        case SX127X_MODEM_LORA:
-            /* Clear IRQ */
-            sx127x_reg_write(dev, SX127X_REG_LR_IRQFLAGS,
-                             SX127X_RF_LORA_IRQFLAGS_CADDETECTED |
-                             SX127X_RF_LORA_IRQFLAGS_CADDONE);
-
-            /* Send event message */
-            dev->_internal.is_last_cad_success = (sx127x_reg_read(dev, SX127X_REG_LR_IRQFLAGS) &
-                                                  SX127X_RF_LORA_IRQFLAGS_CADDETECTED) == SX127X_RF_LORA_IRQFLAGS_CADDETECTED;
-            netdev->event_callback(netdev, NETDEV_EVENT_CAD_DONE);
-            break;
-        default:
-            puts("sx127x_on_dio3: Unknown modem");
-            break;
-    }
-}
-
 static void _init_isrs(sx127x_t *dev)
 {
     if (gpio_init_int(dev->params.dio0_pin, GPIO_IN, GPIO_RISING, sx127x_on_dio0_isr, dev) < 0) {
diff --git a/drivers/sx127x/sx127x_getset.c b/drivers/sx127x/sx127x_getset.c
index 1da4e987cd53c17f3402d3a9c534cc271332a21c..33e19831bf6fa939e48b35b8eee1d2da2dc762f6 100644
--- a/drivers/sx127x/sx127x_getset.c
+++ b/drivers/sx127x/sx127x_getset.c
@@ -63,6 +63,20 @@ void sx127x_set_state(sx127x_t *dev, uint8_t state)
 
 void sx127x_set_modem(sx127x_t *dev, uint8_t modem)
 {
+    if ((sx127x_reg_read(dev, SX127X_REG_OPMODE) & SX127X_RF_LORA_OPMODE_LONGRANGEMODE_ON) != 0) {
+        dev->settings.modem = SX127X_MODEM_LORA;
+    }
+    else {
+        dev->settings.modem = SX127X_MODEM_FSK;
+    }
+
+    /* Skip if unchanged to avoid resetting the transceiver below (may end up
+     * in crashes) */
+    if (dev->settings.modem == modem) {
+        DEBUG("[DEBUG] already using modem: %d\n", modem);
+        return;
+    }
+
     DEBUG("[DEBUG] set modem: %d\n", modem);
 
     dev->settings.modem = modem;
@@ -215,6 +229,12 @@ void sx127x_set_rx(sx127x_t *dev)
             break;
         case SX127X_MODEM_LORA:
         {
+            sx127x_reg_write(dev, SX127X_REG_LR_INVERTIQ,
+                             ((sx127x_reg_read(dev, SX127X_REG_LR_INVERTIQ) &
+                               SX127X_RF_LORA_INVERTIQ_TX_MASK &
+                               SX127X_RF_LORA_INVERTIQ_RX_MASK) |
+                              SX127X_RF_LORA_INVERTIQ_RX_ON |
+                              SX127X_RF_LORA_INVERTIQ_TX_OFF));
             sx127x_reg_write(dev, SX127X_REG_LR_INVERTIQ2,
                              ((dev->settings.lora.flags & SX127X_IQ_INVERTED_FLAG) ? SX127X_RF_LORA_INVERTIQ2_ON : SX127X_RF_LORA_INVERTIQ2_OFF));
 
@@ -401,6 +421,9 @@ void sx127x_set_op_mode(const sx127x_t *dev, uint8_t op_mode)
     case SX127X_RF_OPMODE_STANDBY:
         DEBUG("[DEBUG] Set op mode: STANDBY\n");
         break;
+    case SX127X_RF_OPMODE_RECEIVER_SINGLE:
+        DEBUG("[DEBUG] Set op mode: RECEIVER SINGLE\n");
+        break;
     case SX127X_RF_OPMODE_RECEIVER:
         DEBUG("[DEBUG] Set op mode: RECEIVER\n");
         break;
@@ -408,7 +431,7 @@ void sx127x_set_op_mode(const sx127x_t *dev, uint8_t op_mode)
         DEBUG("[DEBUG] Set op mode: TRANSMITTER\n");
         break;
     default:
-        DEBUG("[DEBUG] Set op mode: UNKNOWN\n");
+        DEBUG("[DEBUG] Set op mode: UNKNOWN (%d)\n", op_mode);
         break;
     }
 #endif
diff --git a/drivers/sx127x/sx127x_netdev.c b/drivers/sx127x/sx127x_netdev.c
index 14687af423ec87e7e32c553d50fea6835e143887..682cad349689461cf50f00189d525f0689c8566a 100644
--- a/drivers/sx127x/sx127x_netdev.c
+++ b/drivers/sx127x/sx127x_netdev.c
@@ -35,6 +35,10 @@
 static uint8_t _get_tx_len(const struct iovec *vector, unsigned count);
 static int _set_state(sx127x_t *dev, netopt_state_t state);
 static int _get_state(sx127x_t *dev, void *val);
+void _on_dio0_irq(void *arg);
+void _on_dio1_irq(void *arg);
+void _on_dio2_irq(void *arg);
+void _on_dio3_irq(void *arg);
 
 /* Netdev driver api functions */
 static int _send(netdev_t *netdev, const struct iovec *vector, unsigned count);
@@ -58,7 +62,7 @@ static int _send(netdev_t *netdev, const struct iovec *vector, unsigned count)
     sx127x_t *dev = (sx127x_t*) netdev;
 
     if (sx127x_get_state(dev) == SX127X_RF_TX_RUNNING) {
-        DEBUG("[WARNING] Cannot send packet: radio alredy in transmitting "
+        DEBUG("[WARNING] Cannot send packet: radio already in transmitting "
               "state.\n");
         return -ENOTSUP;
     }
@@ -254,19 +258,19 @@ static void _isr(netdev_t *netdev)
 
     switch (irq) {
         case SX127X_IRQ_DIO0:
-            sx127x_on_dio0(dev);
+            _on_dio0_irq(dev);
             break;
 
         case SX127X_IRQ_DIO1:
-            sx127x_on_dio1(dev);
+            _on_dio1_irq(dev);
             break;
 
         case SX127X_IRQ_DIO2:
-            sx127x_on_dio2(dev);
+            _on_dio2_irq(dev);
             break;
 
         case SX127X_IRQ_DIO3:
-            sx127x_on_dio3(dev);
+            _on_dio3_irq(dev);
             break;
 
         default:
@@ -538,3 +542,156 @@ static int _get_state(sx127x_t *dev, void *val)
     memcpy(val, &state, sizeof(netopt_state_t));
     return sizeof(netopt_state_t);
 }
+
+void _on_dio0_irq(void *arg)
+{
+    sx127x_t *dev = (sx127x_t *) arg;
+    netdev_t *netdev = (netdev_t*) &dev->netdev;
+
+    switch (dev->settings.state) {
+        case SX127X_RF_RX_RUNNING:
+            netdev->event_callback(netdev, NETDEV_EVENT_RX_COMPLETE);
+            break;
+        case SX127X_RF_TX_RUNNING:
+            xtimer_remove(&dev->_internal.tx_timeout_timer);
+            switch (dev->settings.modem) {
+                case SX127X_MODEM_LORA:
+                    /* Clear IRQ */
+                    sx127x_reg_write(dev, SX127X_REG_LR_IRQFLAGS,
+                                     SX127X_RF_LORA_IRQFLAGS_TXDONE);
+                /* Intentional fall-through */
+                case SX127X_MODEM_FSK:
+                default:
+                    sx127x_set_state(dev, SX127X_RF_IDLE);
+                    netdev->event_callback(netdev, NETDEV_EVENT_TX_COMPLETE);
+                    break;
+            }
+            break;
+        case SX127X_RF_IDLE:
+            printf("sx127x_on_dio0: IDLE state\n");
+            break;
+        default:
+            printf("sx127x_on_dio0: Unknown state [%d]\n", dev->settings.state);
+            break;
+    }
+}
+
+void _on_dio1_irq(void *arg)
+{
+    /* Get interrupt context */
+    sx127x_t *dev = (sx127x_t *) arg;
+    netdev_t *netdev = (netdev_t*) &dev->netdev;
+
+    switch (dev->settings.state) {
+        case SX127X_RF_RX_RUNNING:
+            switch (dev->settings.modem) {
+                case SX127X_MODEM_FSK:
+                    /* todo */
+                    break;
+                case SX127X_MODEM_LORA:
+                    xtimer_remove(&dev->_internal.rx_timeout_timer);
+                    /*  Clear Irq */
+                    sx127x_reg_write(dev, SX127X_REG_LR_IRQFLAGS, SX127X_RF_LORA_IRQFLAGS_RXTIMEOUT);
+                    sx127x_set_state(dev, SX127X_RF_IDLE);
+                    netdev->event_callback(netdev, NETDEV_EVENT_RX_TIMEOUT);
+                    break;
+                default:
+                    break;
+            }
+            break;
+        case SX127X_RF_TX_RUNNING:
+            switch (dev->settings.modem) {
+                case SX127X_MODEM_FSK:
+                    /* todo */
+                    break;
+                case SX127X_MODEM_LORA:
+                    break;
+                default:
+                    break;
+            }
+            break;
+        default:
+            puts("sx127x_on_dio1: Unknown state");
+            break;
+    }
+}
+
+void _on_dio2_irq(void *arg)
+{
+    /* Get interrupt context */
+    sx127x_t *dev = (sx127x_t *) arg;
+    netdev_t *netdev = (netdev_t*) dev;
+
+    switch (dev->settings.state) {
+        case SX127X_RF_RX_RUNNING:
+            switch (dev->settings.modem) {
+                case SX127X_MODEM_FSK:
+                    /* todo */
+                    break;
+                case SX127X_MODEM_LORA:
+                    if (dev->settings.lora.flags & SX127X_CHANNEL_HOPPING_FLAG) {
+                        /* Clear IRQ */
+                        sx127x_reg_write(dev, SX127X_REG_LR_IRQFLAGS,
+                                         SX127X_RF_LORA_IRQFLAGS_FHSSCHANGEDCHANNEL);
+
+                        dev->_internal.last_channel = (sx127x_reg_read(dev, SX127X_REG_LR_HOPCHANNEL) &
+                                                       SX127X_RF_LORA_HOPCHANNEL_CHANNEL_MASK);
+                        netdev->event_callback(netdev, NETDEV_EVENT_FHSS_CHANGE_CHANNEL);
+                    }
+
+                    break;
+                default:
+                    break;
+            }
+            break;
+        case SX127X_RF_TX_RUNNING:
+            switch (dev->settings.modem) {
+                case SX127X_MODEM_FSK:
+                    break;
+                case SX127X_MODEM_LORA:
+                    if (dev->settings.lora.flags & SX127X_CHANNEL_HOPPING_FLAG) {
+                        /* Clear IRQ */
+                        sx127x_reg_write(dev, SX127X_REG_LR_IRQFLAGS,
+                                         SX127X_RF_LORA_IRQFLAGS_FHSSCHANGEDCHANNEL);
+
+                        dev->_internal.last_channel = (sx127x_reg_read(dev, SX127X_REG_LR_HOPCHANNEL) &
+                                                       SX127X_RF_LORA_HOPCHANNEL_CHANNEL_MASK);
+                        netdev->event_callback(netdev, NETDEV_EVENT_FHSS_CHANGE_CHANNEL);
+                    }
+                    break;
+                default:
+                    break;
+            }
+            break;
+        default:
+            puts("sx127x_on_dio2: Unknown state");
+            break;
+    }
+}
+
+void _on_dio3_irq(void *arg)
+{
+    /* Get interrupt context */
+    sx127x_t *dev = (sx127x_t *) arg;
+    netdev_t *netdev = (netdev_t *) dev;
+
+    switch (dev->settings.modem) {
+        case SX127X_MODEM_FSK:
+            break;
+        case SX127X_MODEM_LORA:
+            /* Clear IRQ */
+            sx127x_reg_write(dev, SX127X_REG_LR_IRQFLAGS,
+                             SX127X_RF_LORA_IRQFLAGS_CADDETECTED |
+                             SX127X_RF_LORA_IRQFLAGS_CADDONE);
+
+            /* Send event message */
+            dev->_internal.is_last_cad_success = ((sx127x_reg_read(dev, SX127X_REG_LR_IRQFLAGS) &
+                                                   SX127X_RF_LORA_IRQFLAGS_CADDETECTED) ==
+                                                  SX127X_RF_LORA_IRQFLAGS_CADDETECTED);
+            netdev->event_callback(netdev, NETDEV_EVENT_CAD_DONE);
+            break;
+        default:
+            puts("sx127x_on_dio3: Unknown modem");
+            break;
+    }
+}
\ No newline at end of file
diff --git a/tests/driver_sx127x/main.c b/tests/driver_sx127x/main.c
index cf7dae6e2c07a99abd569f1a81360d9de8c017b6..64b4652a8992058428e9248453076cea97f122eb 100644
--- a/tests/driver_sx127x/main.c
+++ b/tests/driver_sx127x/main.c
@@ -308,11 +308,13 @@ static void _event_cb(netdev_t *dev, netdev_event_t event)
                        (int)packet_info.time_on_air);
                 break;
             case NETDEV_EVENT_TX_COMPLETE:
+                sx127x_set_sleep(&sx127x);
                 puts("Transmission completed");
                 break;
             case NETDEV_EVENT_CAD_DONE:
                 break;
             case NETDEV_EVENT_TX_TIMEOUT:
+                sx127x_set_sleep(&sx127x);
                 break;
             default:
                 printf("Unexpected netdev event received: %d\n", event);