void sx127x_set_tx(sx127x_t *dev) { switch (dev->settings.modem) { case SX127X_MODEM_FSK: /* todo */ break; case SX127X_MODEM_LORA: { if (dev->settings.lora.flags & SX127X_CHANNEL_HOPPING_FLAG) { sx127x_reg_write(dev, SX127X_REG_LR_IRQFLAGSMASK, SX127X_RF_LORA_IRQFLAGS_RXTIMEOUT | SX127X_RF_LORA_IRQFLAGS_RXDONE | SX127X_RF_LORA_IRQFLAGS_PAYLOADCRCERROR | SX127X_RF_LORA_IRQFLAGS_VALIDHEADER | /* RFLR_IRQFLAGS_TXDONE | */ SX127X_RF_LORA_IRQFLAGS_CADDONE | /* RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL | */ SX127X_RF_LORA_IRQFLAGS_CADDETECTED); /* DIO0=TxDone, DIO2=FhssChangeChannel */ sx127x_reg_write(dev, SX127X_REG_DIOMAPPING1, (sx127x_reg_read(dev, SX127X_REG_DIOMAPPING1 ) & SX127X_RF_LORA_DIOMAPPING1_DIO0_MASK & SX127X_RF_LORA_DIOMAPPING1_DIO2_MASK) | SX127X_RF_LORA_DIOMAPPING1_DIO0_01 | SX127X_RF_LORA_DIOMAPPING1_DIO2_00); } else { sx127x_reg_write(dev, SX127X_REG_LR_IRQFLAGSMASK, SX127X_RF_LORA_IRQFLAGS_RXTIMEOUT | SX127X_RF_LORA_IRQFLAGS_RXDONE | SX127X_RF_LORA_IRQFLAGS_PAYLOADCRCERROR | SX127X_RF_LORA_IRQFLAGS_VALIDHEADER | /* RFLR_IRQFLAGS_TXDONE | */ SX127X_RF_LORA_IRQFLAGS_CADDONE | SX127X_RF_LORA_IRQFLAGS_FHSSCHANGEDCHANNEL | SX127X_RF_LORA_IRQFLAGS_CADDETECTED); /* DIO0=TxDone */ sx127x_reg_write(dev, SX127X_REG_DIOMAPPING1, (sx127x_reg_read(dev, SX127X_REG_DIOMAPPING1) & SX127X_RF_LORA_DIOMAPPING1_DIO0_MASK) | SX127X_RF_LORA_DIOMAPPING1_DIO0_01); } } break; } sx127x_set_state(dev, SX127X_RF_RX_RUNNING); if (dev->settings.lora.tx_timeout != 0) { xtimer_set(&(dev->_internal.tx_timeout_timer), dev->settings.lora.tx_timeout); } sx127x_set_op_mode(dev, SX127X_RF_OPMODE_TRANSMITTER ); }
void sx127x_set_standby(sx127x_t *dev) { DEBUG("[sx127x] Set standby\n"); /* Disable running timers */ xtimer_remove(&dev->_internal.tx_timeout_timer); xtimer_remove(&dev->_internal.rx_timeout_timer); sx127x_set_op_mode(dev, SX127X_RF_OPMODE_STANDBY); sx127x_set_state(dev, SX127X_RF_IDLE); }
void sx127x_set_sleep(sx127x_t *dev) { DEBUG("[sx127x] Set sleep\n"); /* Disable running timers */ xtimer_remove(&dev->_internal.tx_timeout_timer); xtimer_remove(&dev->_internal.rx_timeout_timer); /* Put chip into sleep */ sx127x_set_op_mode(dev, SX127X_RF_OPMODE_SLEEP); sx127x_set_state(dev, SX127X_RF_IDLE); }
static int _recv(netdev_t *netdev, void *buf, size_t len, void *info) { sx127x_t *dev = (sx127x_t*) netdev; volatile uint8_t irq_flags = 0; uint8_t size = 0; switch (dev->settings.modem) { case SX127X_MODEM_FSK: /* todo */ break; case SX127X_MODEM_LORA: /* Clear IRQ */ sx127x_reg_write(dev, SX127X_REG_LR_IRQFLAGS, SX127X_RF_LORA_IRQFLAGS_RXDONE); irq_flags = sx127x_reg_read(dev, SX127X_REG_LR_IRQFLAGS); if ( (irq_flags & SX127X_RF_LORA_IRQFLAGS_PAYLOADCRCERROR_MASK) == SX127X_RF_LORA_IRQFLAGS_PAYLOADCRCERROR) { /* Clear IRQ */ sx127x_reg_write(dev, SX127X_REG_LR_IRQFLAGS, SX127X_RF_LORA_IRQFLAGS_PAYLOADCRCERROR); if (!(dev->settings.lora.flags & SX127X_RX_CONTINUOUS_FLAG)) { sx127x_set_state(dev, SX127X_RF_IDLE); } xtimer_remove(&dev->_internal.rx_timeout_timer); netdev->event_callback(netdev, NETDEV_EVENT_CRC_ERROR); return -EBADMSG; } netdev_sx127x_lora_packet_info_t *packet_info = info; if (packet_info) { /* there is no LQI for LoRa */ packet_info->lqi = 0; uint8_t snr_value = sx127x_reg_read(dev, SX127X_REG_LR_PKTSNRVALUE); if (snr_value & 0x80) { /* The SNR is negative */ /* Invert and divide by 4 */ packet_info->snr = -1 * ((~snr_value + 1) & 0xFF) >> 2; } else { /* Divide by 4 */ packet_info->snr = (snr_value & 0xFF) >> 2; } int16_t rssi = sx127x_reg_read(dev, SX127X_REG_LR_PKTRSSIVALUE); if (packet_info->snr < 0) { #if defined(MODULE_SX1272) packet_info->rssi = SX127X_RSSI_OFFSET + rssi + (rssi >> 4) + packet_info->snr; #else /* MODULE_SX1276 */ if (dev->settings.channel > SX127X_RF_MID_BAND_THRESH) { packet_info->rssi = SX127X_RSSI_OFFSET_HF + rssi + (rssi >> 4) + packet_info->snr; }
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 already in transmitting " "state.\n"); return -ENOTSUP; } uint8_t size; size = _get_tx_len(vector, count); switch (dev->settings.modem) { case SX127X_MODEM_FSK: /* todo */ break; case SX127X_MODEM_LORA: /* Initializes the payload size */ sx127x_set_payload_length(dev, size); /* Full buffer used for Tx */ sx127x_reg_write(dev, SX127X_REG_LR_FIFOTXBASEADDR, 0x00); sx127x_reg_write(dev, SX127X_REG_LR_FIFOADDRPTR, 0x00); /* FIFO operations can not take place in Sleep mode * So wake up the chip */ if (sx127x_get_op_mode(dev) == SX127X_RF_OPMODE_SLEEP) { sx127x_set_standby(dev); xtimer_usleep(SX127X_RADIO_WAKEUP_TIME); /* wait for chip wake up */ } /* Write payload buffer */ for (size_t i = 0; i < count; i++) { sx127x_write_fifo(dev, vector[i].iov_base, vector[i].iov_len); } break; default: puts("sx127x_netdev, Unsupported modem"); break; } /* Enable TXDONE interrupt */ sx127x_reg_write(dev, SX127X_REG_LR_IRQFLAGSMASK, SX127X_RF_LORA_IRQFLAGS_RXTIMEOUT | SX127X_RF_LORA_IRQFLAGS_RXDONE | SX127X_RF_LORA_IRQFLAGS_PAYLOADCRCERROR | SX127X_RF_LORA_IRQFLAGS_VALIDHEADER | /* SX127X_RF_LORA_IRQFLAGS_TXDONE | */ SX127X_RF_LORA_IRQFLAGS_CADDONE | SX127X_RF_LORA_IRQFLAGS_FHSSCHANGEDCHANNEL | SX127X_RF_LORA_IRQFLAGS_CADDETECTED); /* Set TXDONE interrupt to the DIO0 line */ sx127x_reg_write(dev, SX127X_REG_DIOMAPPING1, (sx127x_reg_read(dev, SX127X_REG_DIOMAPPING1) & SX127X_RF_LORA_DIOMAPPING1_DIO0_MASK) | SX127X_RF_LORA_DIOMAPPING1_DIO0_01); /* Start TX timeout timer */ xtimer_set(&dev->_internal.tx_timeout_timer, dev->settings.lora.tx_timeout); /* Put chip into transfer mode */ sx127x_set_state(dev, SX127X_RF_TX_RUNNING); sx127x_set_op_mode(dev, SX127X_RF_OPMODE_TRANSMITTER); return 0; }
void sx127x_set_rx(sx127x_t *dev) { DEBUG("[sx127x] Set RX\n"); switch (dev->settings.modem) { case SX127X_MODEM_FSK: /* todo */ 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) | ((dev->settings.lora.flags & SX127X_IQ_INVERTED_FLAG) ? SX127X_RF_LORA_INVERTIQ_RX_ON :SX127X_RF_LORA_INVERTIQ_RX_OFF) | 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)); #if defined(MODULE_SX1276) /* ERRATA 2.3 - Receiver Spurious Reception of a LoRa Signal */ if (dev->settings.lora.bandwidth < 9) { sx127x_reg_write(dev, SX127X_REG_LR_DETECTOPTIMIZE, sx127x_reg_read(dev, SX127X_REG_LR_DETECTOPTIMIZE) & 0x7F); sx127x_reg_write(dev, SX127X_REG_LR_TEST30, 0x00); switch (dev->settings.lora.bandwidth) { case LORA_BW_125_KHZ: /* 125 kHz */ sx127x_reg_write(dev, SX127X_REG_LR_TEST2F, 0x40); break; case LORA_BW_250_KHZ: /* 250 kHz */ sx127x_reg_write(dev, SX127X_REG_LR_TEST2F, 0x40); break; default: break; } } else { sx127x_reg_write(dev, SX127X_REG_LR_DETECTOPTIMIZE, sx127x_reg_read(dev, SX127X_REG_LR_DETECTOPTIMIZE) | 0x80); } #endif /* Setup interrupts */ if (dev->settings.lora.flags & SX127X_CHANNEL_HOPPING_FLAG) { sx127x_reg_write(dev, SX127X_REG_LR_IRQFLAGSMASK, /* SX127X_RF_LORA_IRQFLAGS_RXTIMEOUT | SX127X_RF_LORA_IRQFLAGS_RXDONE | SX127X_RF_LORA_IRQFLAGS_PAYLOADCRCERROR | */ SX127X_RF_LORA_IRQFLAGS_VALIDHEADER | SX127X_RF_LORA_IRQFLAGS_TXDONE | SX127X_RF_LORA_IRQFLAGS_CADDONE | /* SX127X_RF_LORA_IRQFLAGS_FHSSCHANGEDCHANNEL | */ SX127X_RF_LORA_IRQFLAGS_CADDETECTED); /* DIO0=RxDone, DIO2=FhssChangeChannel */ sx127x_reg_write(dev, SX127X_REG_DIOMAPPING1, (sx127x_reg_read(dev, SX127X_REG_DIOMAPPING1) & SX127X_RF_LORA_DIOMAPPING1_DIO0_MASK & SX127X_RF_LORA_DIOMAPPING1_DIO2_MASK) | SX127X_RF_LORA_DIOMAPPING1_DIO0_00 | SX127X_RF_LORA_DIOMAPPING1_DIO2_00); } else { sx127x_reg_write(dev, SX127X_REG_LR_IRQFLAGSMASK, /* SX127X_RF_LORA_IRQFLAGS_RXTIMEOUT | SX127X_RF_LORA_IRQFLAGS_RXDONE | SX127X_RF_LORA_IRQFLAGS_PAYLOADCRCERROR | */ SX127X_RF_LORA_IRQFLAGS_VALIDHEADER | SX127X_RF_LORA_IRQFLAGS_TXDONE | SX127X_RF_LORA_IRQFLAGS_CADDONE | SX127X_RF_LORA_IRQFLAGS_FHSSCHANGEDCHANNEL | SX127X_RF_LORA_IRQFLAGS_CADDETECTED); /* DIO0=RxDone */ sx127x_reg_write(dev, SX127X_REG_DIOMAPPING1, (sx127x_reg_read(dev, SX127X_REG_DIOMAPPING1) & SX127X_RF_LORA_DIOMAPPING1_DIO0_MASK) | SX127X_RF_LORA_DIOMAPPING1_DIO0_00); } sx127x_reg_write(dev, SX127X_REG_LR_FIFORXBASEADDR, 0); sx127x_reg_write(dev, SX127X_REG_LR_FIFOADDRPTR, 0); } break; } sx127x_set_state(dev, SX127X_RF_RX_RUNNING); if (dev->settings.lora.rx_timeout != 0) { xtimer_set(&(dev->_internal.rx_timeout_timer), dev->settings.lora.rx_timeout); } if (dev->settings.lora.flags & SX127X_RX_CONTINUOUS_FLAG) { sx127x_set_op_mode(dev, SX127X_RF_LORA_OPMODE_RECEIVER); } else { sx127x_set_op_mode(dev, SX127X_RF_LORA_OPMODE_RECEIVER_SINGLE); } }
void sx127x_set_tx(sx127x_t *dev) { #ifdef SX127X_USE_RX_SWITCH gpio_clear(dev->params.rx_switch_pin); #endif #ifdef SX127X_USE_TX_SWITCH gpio_set(dev->params.tx_switch_pin); #endif switch (dev->settings.modem) { case SX127X_MODEM_FSK: /* todo */ break; case SX127X_MODEM_LORA: { if (dev->settings.lora.flags & SX127X_CHANNEL_HOPPING_FLAG) { sx127x_reg_write(dev, SX127X_REG_LR_IRQFLAGSMASK, SX127X_RF_LORA_IRQFLAGS_RXTIMEOUT | SX127X_RF_LORA_IRQFLAGS_RXDONE | SX127X_RF_LORA_IRQFLAGS_PAYLOADCRCERROR | SX127X_RF_LORA_IRQFLAGS_VALIDHEADER | /* RFLR_IRQFLAGS_TXDONE | */ SX127X_RF_LORA_IRQFLAGS_CADDONE | /* RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL | */ SX127X_RF_LORA_IRQFLAGS_CADDETECTED); /* DIO0=TxDone, DIO2=FhssChangeChannel */ sx127x_reg_write(dev, SX127X_REG_DIOMAPPING1, (sx127x_reg_read(dev, SX127X_REG_DIOMAPPING1 ) & SX127X_RF_LORA_DIOMAPPING1_DIO0_MASK & SX127X_RF_LORA_DIOMAPPING1_DIO2_MASK) | SX127X_RF_LORA_DIOMAPPING1_DIO0_01 | SX127X_RF_LORA_DIOMAPPING1_DIO2_00); } else { /* Enable TXDONE interrupt */ sx127x_reg_write(dev, SX127X_REG_LR_IRQFLAGSMASK, SX127X_RF_LORA_IRQFLAGS_RXTIMEOUT | SX127X_RF_LORA_IRQFLAGS_RXDONE | SX127X_RF_LORA_IRQFLAGS_PAYLOADCRCERROR | SX127X_RF_LORA_IRQFLAGS_VALIDHEADER | /* SX127X_RF_LORA_IRQFLAGS_TXDONE | */ SX127X_RF_LORA_IRQFLAGS_CADDONE | SX127X_RF_LORA_IRQFLAGS_FHSSCHANGEDCHANNEL | SX127X_RF_LORA_IRQFLAGS_CADDETECTED); /* Set TXDONE interrupt to the DIO0 line */ sx127x_reg_write(dev, SX127X_REG_DIOMAPPING1, (sx127x_reg_read(dev, SX127X_REG_DIOMAPPING1) & SX127X_RF_LORA_DIOMAPPING1_DIO0_MASK) | SX127X_RF_LORA_DIOMAPPING1_DIO0_01); } } break; } sx127x_set_state(dev, SX127X_RF_TX_RUNNING); /* Start TX timeout timer */ if (dev->settings.lora.tx_timeout != 0) { xtimer_set(&(dev->_internal.tx_timeout_timer), dev->settings.lora.tx_timeout); } /* Put chip into transfer mode */ sx127x_set_op_mode(dev, SX127X_RF_OPMODE_TRANSMITTER ); }