Esempio n. 1
0
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 );
}
Esempio n. 2
0
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);
}
Esempio n. 3
0
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);
}
Esempio n. 4
0
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;
                    }
Esempio n. 5
0
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;
}
Esempio n. 6
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);
    }
}
Esempio n. 7
0
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 );
}