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);