Exemple #1
0
bool sx127x_get_crc(const sx127x_t *dev)
{
#if defined(MODULE_SX1272)
    return (sx127x_reg_read(dev, SX127X_REG_LR_MODEMCONFIG1) &
            SX1272_RF_LORA_MODEMCONFIG1_RXPAYLOADCRC_MASK);
#else /* MODULE_SX1276 */
    return (sx127x_reg_read(dev, SX127X_REG_LR_MODEMCONFIG2) &
            SX1276_RF_LORA_MODEMCONFIG2_RXPAYLOADCRC_MASK);
#endif
}
Exemple #2
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 );
}
Exemple #3
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;
                    }
Exemple #4
0
uint8_t sx127x_get_max_payload_len(const sx127x_t *dev)
{
    switch (dev->settings.modem) {
        case SX127X_MODEM_FSK:
            return sx127x_reg_read(dev, SX127X_REG_PAYLOADLENGTH);

        case SX127X_MODEM_LORA:
            return sx127x_reg_read(dev, SX127X_REG_LR_PAYLOADMAXLENGTH);
    }

    /* should never be reached */
    return 0;
}
Exemple #5
0
void sx127x_set_op_mode(const sx127x_t *dev, uint8_t op_mode)
{
#if ENABLE_DEBUG
    switch(op_mode) {
    case SX127X_RF_OPMODE_SLEEP:
        DEBUG("[sx127x] Set op mode: SLEEP\n");
        break;
    case SX127X_RF_OPMODE_STANDBY:
        DEBUG("[sx127x] Set op mode: STANDBY\n");
        break;
    case SX127X_RF_OPMODE_RECEIVER_SINGLE:
        DEBUG("[sx127x] Set op mode: RECEIVER SINGLE\n");
        break;
    case SX127X_RF_OPMODE_RECEIVER:
        DEBUG("[sx127x] Set op mode: RECEIVER\n");
        break;
    case SX127X_RF_OPMODE_TRANSMITTER:
        DEBUG("[sx127x] Set op mode: TRANSMITTER\n");
        break;
    default:
        DEBUG("[sx127x] Set op mode: UNKNOWN (%d)\n", op_mode);
        break;
    }
#endif

    /* Replace previous mode value and setup new mode value */
    sx127x_reg_write(dev, SX127X_REG_OPMODE,
                     (sx127x_reg_read(dev, SX127X_REG_OPMODE) & SX127X_RF_OPMODE_MASK) | op_mode);
}
Exemple #6
0
void sx127x_set_crc(sx127x_t *dev, bool crc)
{
    DEBUG("[sx127x] Set CRC: %d\n", crc);
    _set_flag(dev, SX127X_ENABLE_CRC_FLAG, crc);

#if defined(MODULE_SX1272)
    uint8_t config2_reg = sx127x_reg_read(dev, SX127X_REG_LR_MODEMCONFIG1);
    config2_reg &= SX1272_RF_LORA_MODEMCONFIG1_RXPAYLOADCRC_MASK;
    config2_reg |= crc << 1;
    sx127x_reg_write(dev, SX127X_REG_LR_MODEMCONFIG1, config2_reg);
#else /* MODULE_SX1276 */
    uint8_t config2_reg = sx127x_reg_read(dev, SX127X_REG_LR_MODEMCONFIG2);
    config2_reg &= SX1276_RF_LORA_MODEMCONFIG2_RXPAYLOADCRC_MASK;
    config2_reg |= crc << 2;
    sx127x_reg_write(dev, SX127X_REG_LR_MODEMCONFIG2, config2_reg);
#endif
}
Exemple #7
0
void sx127x_set_symbol_timeout(sx127x_t *dev, uint16_t timeout)
{
    DEBUG("[sx127x] Set symbol timeout: %d\n", timeout);

    uint8_t config2_reg = sx127x_reg_read(dev, SX127X_REG_LR_MODEMCONFIG2);
    config2_reg &= SX127X_RF_LORA_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK;
    config2_reg |= (timeout >> 8) & ~SX127X_RF_LORA_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK;
    sx127x_reg_write(dev, SX127X_REG_LR_MODEMCONFIG2, config2_reg);
    sx127x_reg_write(dev, SX127X_REG_LR_SYMBTIMEOUTLSB, timeout & 0xFF);
}
Exemple #8
0
void sx127x_set_hop_period(sx127x_t *dev, uint8_t hop_period)
{
    DEBUG("[sx127x] Set Hop period: %d\n", hop_period);

    dev->settings.lora.freq_hop_period = hop_period;

    uint8_t tmp = sx127x_reg_read(dev, SX127X_REG_LR_PLLHOP);
    if (dev->settings.lora.flags & SX127X_CHANNEL_HOPPING_FLAG) {
        tmp |= SX127X_RF_LORA_PLLHOP_FASTHOP_ON;
        sx127x_reg_write(dev, SX127X_REG_LR_PLLHOP, tmp);
        sx127x_reg_write(dev, SX127X_REG_LR_HOPPERIOD, hop_period);
    }
}
Exemple #9
0
void sx127x_set_modem(sx127x_t *dev, uint8_t modem)
{
    DEBUG("[sx127x] set modem: %d\n", 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("[sx127x] already using modem: %d\n", modem);
        return;
    }

    dev->settings.modem = modem;

    switch (dev->settings.modem) {
        case SX127X_MODEM_FSK:
            /* Todo */
            break;
        case SX127X_MODEM_LORA:
            sx127x_set_op_mode(dev, SX127X_RF_OPMODE_SLEEP);
            sx127x_reg_write(dev, SX127X_REG_OPMODE,
                             (sx127x_reg_read(dev, SX127X_REG_OPMODE) &
                              SX127X_RF_LORA_OPMODE_LONGRANGEMODE_MASK) |
                             SX127X_RF_LORA_OPMODE_LONGRANGEMODE_ON);

            sx127x_reg_write(dev, SX127X_REG_DIOMAPPING1, 0x00);
            sx127x_reg_write(dev, SX127X_REG_DIOMAPPING2, 0x00);
            break;
        default:
            break;
    }
}
Exemple #10
0
static void _low_datarate_optimize(sx127x_t *dev)
{
    if ( ((dev->settings.lora.bandwidth == LORA_BW_125_KHZ) &&
          ((dev->settings.lora.datarate == LORA_SF11) ||
           (dev->settings.lora.datarate == LORA_SF12))) ||
         ((dev->settings.lora.bandwidth == LORA_BW_250_KHZ) &&
          (dev->settings.lora.datarate == LORA_SF12))) {
        dev->settings.lora.flags |= SX127X_LOW_DATARATE_OPTIMIZE_FLAG;
    } else {
        dev->settings.lora.flags &= ~SX127X_LOW_DATARATE_OPTIMIZE_FLAG;
    }

#if defined(MODULE_SX1272)
    sx127x_reg_write(dev, SX127X_REG_LR_MODEMCONFIG1,
                     (sx127x_reg_read(dev, SX127X_REG_LR_MODEMCONFIG1) &
                      SX127X_RF_LORA_MODEMCONFIG1_LOWDATARATEOPTIMIZE_MASK) |
                     ((dev->settings.lora.flags & SX127X_LOW_DATARATE_OPTIMIZE_FLAG)));
#else /* MODULE_SX1276 */
    sx127x_reg_write(dev, SX127X_REG_LR_MODEMCONFIG3,
                     (sx127x_reg_read(dev, SX127X_REG_LR_MODEMCONFIG3) &
                      SX127X_RF_LORA_MODEMCONFIG3_LOWDATARATEOPTIMIZE_MASK) |
                     ((dev->settings.lora.flags & SX127X_LOW_DATARATE_OPTIMIZE_FLAG) << 3));
#endif
}
Exemple #11
0
void sx127x_set_fixed_header_len_mode(sx127x_t *dev, bool fixed_len)
{
    DEBUG("[sx127x] Set fixed header length: %d\n", fixed_len);

    _set_flag(dev, SX127X_ENABLE_FIXED_HEADER_LENGTH_FLAG, fixed_len);

    uint8_t config1_reg = sx127x_reg_read(dev, SX127X_REG_LR_MODEMCONFIG1);
#if defined(MODULE_SX1272)
    config1_reg &= SX1272_RF_LORA_MODEMCONFIG1_IMPLICITHEADER_MASK;
    config1_reg |= fixed_len << 2;
#else /* MODULE_SX1276 */
    config1_reg &= SX1276_RF_LORA_MODEMCONFIG1_IMPLICITHEADER_MASK;
    config1_reg |= fixed_len;
#endif
    sx127x_reg_write(dev, SX127X_REG_LR_MODEMCONFIG1, config1_reg);
}
Exemple #12
0
void sx127x_set_iq_invert(sx127x_t *dev, bool iq_invert)
{
    DEBUG("[sx127x] Set IQ invert: %d\n", iq_invert);

    _set_flag(dev, SX127X_IQ_INVERTED_FLAG, iq_invert);

    sx127x_reg_write(dev, SX127X_REG_LR_INVERTIQ,
                     (sx127x_reg_read(dev, SX127X_REG_LR_INVERTIQ) &
                      SX127X_RF_LORA_INVERTIQ_RX_MASK &
                      SX127X_RF_LORA_INVERTIQ_TX_MASK) |
                      SX127X_RF_LORA_INVERTIQ_RX_OFF |
                     (iq_invert ? SX127X_RF_LORA_INVERTIQ_TX_ON : SX127X_RF_LORA_INVERTIQ_TX_OFF));

    sx127x_reg_write(dev, SX127X_REG_LR_INVERTIQ2,
                     (iq_invert ? SX127X_RF_LORA_INVERTIQ2_ON : SX127X_RF_LORA_INVERTIQ2_OFF));
}
Exemple #13
0
void sx127x_set_coding_rate(sx127x_t *dev, uint8_t coderate)
{
    DEBUG("[sx127x] Set coding rate: %d\n", coderate);

    dev->settings.lora.coderate = coderate;
    uint8_t config1_reg = sx127x_reg_read(dev, SX127X_REG_LR_MODEMCONFIG1);

#if defined(MODULE_SX1272)
    config1_reg &= SX1272_RF_LORA_MODEMCONFIG1_CODINGRATE_MASK;
    config1_reg |= coderate << 3;
#else /* MODULE_SX1276 */
    config1_reg &= SX1276_RF_LORA_MODEMCONFIG1_CODINGRATE_MASK;
    config1_reg |= coderate << 1;
#endif

    sx127x_reg_write(dev, SX127X_REG_LR_MODEMCONFIG1, config1_reg);
}
Exemple #14
0
static void _update_bandwidth(const sx127x_t *dev)
{
    uint8_t config1_reg = sx127x_reg_read(dev, SX127X_REG_LR_MODEMCONFIG1);
#if defined(MODULE_SX1272)
    config1_reg &= SX1272_RF_LORA_MODEMCONFIG1_BW_MASK;
    switch (dev->settings.lora.bandwidth) {
    case LORA_BW_125_KHZ:
        config1_reg |=  SX1272_RF_LORA_MODEMCONFIG1_BW_125_KHZ;
        break;
    case LORA_BW_250_KHZ:
        config1_reg |=  SX1272_RF_LORA_MODEMCONFIG1_BW_250_KHZ;
        break;
    case LORA_BW_500_KHZ:
        config1_reg |=  SX1272_RF_LORA_MODEMCONFIG1_BW_500_KHZ;
        break;
    default:
        DEBUG("Unsupported bandwidth, %d", dev->settings.lora.bandwidth);
        break;
    }
#else /* MODULE_SX1276 */
    config1_reg &= SX1276_RF_LORA_MODEMCONFIG1_BW_MASK;
    switch (dev->settings.lora.bandwidth) {
    case LORA_BW_125_KHZ:
        config1_reg |= SX1276_RF_LORA_MODEMCONFIG1_BW_125_KHZ;
        break;
    case LORA_BW_250_KHZ:
        config1_reg |=  SX1276_RF_LORA_MODEMCONFIG1_BW_250_KHZ;
        break;
    case LORA_BW_500_KHZ:
        config1_reg |=  SX1276_RF_LORA_MODEMCONFIG1_BW_500_KHZ;
        break;
    default:
        DEBUG("[sx127x] Unsupported bandwidth, %d\n",
              dev->settings.lora.bandwidth);
        break;
    }
#endif
    sx127x_reg_write(dev, SX127X_REG_LR_MODEMCONFIG1, config1_reg);
}
Exemple #15
0
void sx127x_set_spreading_factor(sx127x_t *dev, uint8_t datarate)
{
    DEBUG("[sx127x] Set spreading factor: %d\n", datarate);

    if (datarate == LORA_SF6 &&
        !(dev->settings.lora.flags & SX127X_ENABLE_FIXED_HEADER_LENGTH_FLAG)) {
        /* SF 6 is only valid when using explicit header mode */
        DEBUG("Spreading Factor 6 can only be used when explicit header "
              "mode is set, this mode is not supported by this driver."
              "Ignoring.\n");
        return;
    }

    dev->settings.lora.datarate = datarate;

    uint8_t config2_reg = sx127x_reg_read(dev, SX127X_REG_LR_MODEMCONFIG2);
    config2_reg &= SX127X_RF_LORA_MODEMCONFIG2_SF_MASK;
    config2_reg |= datarate << 4;
    sx127x_reg_write(dev, SX127X_REG_LR_MODEMCONFIG2, config2_reg);

    _low_datarate_optimize(dev);

    switch(dev->settings.lora.datarate) {
    case LORA_SF6:
        sx127x_reg_write(dev, SX127X_REG_LR_DETECTOPTIMIZE,
                         SX127X_RF_LORA_DETECTIONOPTIMIZE_SF6);
        sx127x_reg_write(dev, SX127X_REG_LR_DETECTIONTHRESHOLD,
                         SX127X_RF_LORA_DETECTIONTHRESH_SF6);
        break;
    default:
        sx127x_reg_write(dev, SX127X_REG_LR_DETECTOPTIMIZE,
                         SX127X_RF_LORA_DETECTIONOPTIMIZE_SF7_TO_SF12);
        sx127x_reg_write(dev, SX127X_REG_LR_DETECTIONTHRESHOLD,
                         SX127X_RF_LORA_DETECTIONTHRESH_SF7_TO_SF12);
        break;
    }
}
Exemple #16
0
int register_cmd(int argc, char **argv)
{
    if (argc < 2) {
        puts("usage: register <get | set>");
        return -1;
    }

    if (strstr(argv[1], "get") != NULL) {
        if (argc < 3) {
            puts("usage: register get <all | allinline | regnum>");
            return -1;
        }
        if (strcmp(argv[2], "all") == 0) {
            puts("- listing all registers -");
            uint8_t reg = 0, data = 0;
            /* Listing registers map */
            puts("Reg   0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F");
            for (unsigned i = 0; i <= 7; i++) {
                printf("0x%02X ", i << 4);

                for (unsigned j = 0; j <= 15; j++, reg++) {
                    data = sx127x_reg_read(&sx127x, reg);
                    printf("%02X ", data);
                }
                puts("");
            }
            puts("-done-");
            return 0;
        } else if (strcmp(argv[2], "allinline") == 0) {
            puts("- listing all registers in one line -");
            /* Listing registers map */
            for (uint16_t reg = 0; reg < 256; reg++) {
                printf("%02X ", sx127x_reg_read(&sx127x, (uint8_t) reg));
            }
            puts("- done -");
            return 0;
        } else {
            long int num = 0;
            /* Register number in hex */
            if (strstr(argv[2], "0x") != NULL) {
                num = strtol(argv[2], NULL, 16);
            } else {
                num = atoi(argv[2]);
            }
            if (num >= 0 && num <= 255) {
                printf("[regs] 0x%02X = 0x%02X\n",
                       (uint8_t) num,
                       sx127x_reg_read(&sx127x, (uint8_t) num));
            } else {
                puts("regs: invalid register number specified");
                return -1;
            }
        }
    } else if (strstr(argv[1], "set") != NULL) {
        if (argc < 4) {
            puts("usage: register set <regnum> <value>");
            return -1;
        }

        long num, val;

        /* Register number in hex */
        if (strstr(argv[2], "0x") != NULL) {
            num = strtol(argv[2], NULL, 16);
        } else {
            num = atoi(argv[2]);
        }

        /* Register value in hex */
        if (strstr(argv[3], "0x") != NULL) {
            val = strtol(argv[3], NULL, 16);
        } else {
            val = atoi(argv[3]);
        }

        sx127x_reg_write(&sx127x, (uint8_t) num, (uint8_t) val);
    }
    else {
        puts("usage: register get <all | allinline | regnum>");
        return -1;
    }

    return 0;
}
Exemple #17
0
uint32_t sx127x_get_channel(const sx127x_t *dev)
{
    return (((uint32_t)sx127x_reg_read(dev, SX127X_REG_FRFMSB) << 16) |
            (sx127x_reg_read(dev, SX127X_REG_FRFMID) << 8) |
            (sx127x_reg_read(dev, SX127X_REG_FRFLSB))) * LORA_FREQUENCY_RESOLUTION_DEFAULT;
}
Exemple #18
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);
    }
}
Exemple #19
0
void sx127x_set_tx_power(sx127x_t *dev, int8_t power)
{
    DEBUG("[sx127x] Set power: %d\n", power);

    dev->settings.lora.power = power;

    uint8_t pa_config = sx127x_reg_read(dev, SX127X_REG_PACONFIG);
#if defined(MODULE_SX1272)
    uint8_t pa_dac = sx127x_reg_read(dev, SX1272_REG_PADAC);
#else /* MODULE_SX1276 */
    uint8_t pa_dac = sx127x_reg_read(dev, SX1276_REG_PADAC);
#endif

    pa_config = ((pa_config & SX127X_RF_PACONFIG_PASELECT_MASK) |
                 sx127x_get_pa_select(dev));

#if defined(MODULE_SX1276)
    /* max power is 14dBm */
    pa_config = (pa_config & SX127X_RF_PACONFIG_MAX_POWER_MASK) | 0x70;
#endif

    sx127x_reg_write(dev, SX127X_REG_PARAMP, SX127X_RF_PARAMP_0050_US);

    if ((pa_config & SX127X_RF_PACONFIG_PASELECT_PABOOST)
        == SX127X_RF_PACONFIG_PASELECT_PABOOST) {
        if (power > 17) {
            pa_dac = ((pa_dac & SX127X_RF_PADAC_20DBM_MASK) |
                      SX127X_RF_PADAC_20DBM_ON);
        } else {
            pa_dac = ((pa_dac & SX127X_RF_PADAC_20DBM_MASK) |
                      SX127X_RF_PADAC_20DBM_OFF);
        }
        if ((pa_dac & SX127X_RF_PADAC_20DBM_ON) == SX127X_RF_PADAC_20DBM_ON) {
            if (power < 5) {
                power = 5;
            }
            if (power > 20) {
                power = 20;
            }

            pa_config = ((pa_config & SX127X_RF_PACONFIG_OUTPUTPOWER_MASK) |
                         (uint8_t)((uint16_t)(power - 5) & 0x0F));
        } else {
            if (power < 2) {
                power = 2;
            }
            if (power > 17) {
                power = 17;
            }

            pa_config = ((pa_config & SX127X_RF_PACONFIG_OUTPUTPOWER_MASK) |
                         (uint8_t)((uint16_t)(power - 2) & 0x0F));
        }
    } else {
        if (power < -1) {
            power = -1;
        }
        if (power > 14) {
            power = 14;
        }

        pa_config = ((pa_config & SX127X_RF_PACONFIG_OUTPUTPOWER_MASK) |
                     (uint8_t)((uint16_t)(power + 1) & 0x0F));
    }

    sx127x_reg_write(dev, SX127X_REG_PACONFIG, pa_config);
#if defined(MODULE_SX1272)
    sx127x_reg_write(dev, SX1272_REG_PADAC, pa_dac);
#else /* MODULE_SX1276 */
    sx127x_reg_write(dev, SX1276_REG_PADAC, pa_dac);
#endif
}
Exemple #20
0
uint8_t sx127x_get_payload_length(const sx127x_t *dev)
{
    return sx127x_reg_read(dev, SX127X_REG_LR_PAYLOADLENGTH);;
}
Exemple #21
0
uint8_t sx127x_get_op_mode(const sx127x_t *dev)
{
    return sx127x_reg_read(dev, SX127X_REG_OPMODE) & ~SX127X_RF_OPMODE_MASK;
}
Exemple #22
0
uint8_t sx127x_get_hop_period(const sx127x_t *dev)
{
    return sx127x_reg_read(dev, SX127X_REG_LR_HOPPERIOD);
}
Exemple #23
0
uint8_t sx127x_get_syncword(const sx127x_t *dev)
{
    return sx127x_reg_read(dev, SX127X_REG_LR_SYNCWORD);
}
Exemple #24
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;
}
Exemple #25
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 );
}