Exemplo n.º 1
0
int setup_sx1276_FSK(uint32_t frequency) {
    uint64_t freq_reg;
    uint8_t ModulationShaping = 0;
    uint8_t PllHop = 1;
    uint8_t LnaGain = 1;
    uint8_t LnaBoost = 3;
    uint8_t AdcBwAuto = 0;
    uint8_t AdcBw = 7;
    uint8_t AdcLowPwr = 0;
    uint8_t AdcTrim = 6;
    uint8_t AdcTest = 0;
    uint8_t RxBwExp = 2;
    uint8_t RxBwMant = 1;
    uint8_t RssiSmoothing = 5;
    uint8_t RssiOffset = 3;
    uint8_t reg_val;
    int x;

    /* Set in FSK mode */
    x = lgw_sx127x_reg_w(SX1276_REG_OPMODE, 0);
    wait_ms(100);
    x |= lgw_sx127x_reg_w(SX1276_REG_OPMODE, 0 | (ModulationShaping << 3)); /* Sleep mode, no FSK shaping */
    wait_ms(100);
    x |= lgw_sx127x_reg_w(SX1276_REG_OPMODE, 1 | (ModulationShaping << 3)); /* Standby mode, no FSK shaping */
    wait_ms(100);

    /* Set RF carrier frequency */
    x |= lgw_sx127x_reg_w(SX1276_REG_PLLHOP, PllHop << 7);
    freq_reg = ((uint64_t)frequency << 19) / (uint64_t)32000000;
    x |= lgw_sx127x_reg_w(SX1276_REG_FRFMSB, (freq_reg >> 16) & 0xFF);
    x |= lgw_sx127x_reg_w(SX1276_REG_FRFMID, (freq_reg >> 8) & 0xFF);
    x |= lgw_sx127x_reg_w(SX1276_REG_FRFLSB, (freq_reg >> 0) & 0xFF);

    /* Config */
    x |= lgw_sx127x_reg_w(SX1276_REG_LNA, LnaBoost | (LnaGain << 5)); /* Improved sensitivity, highest gain */
    x |= lgw_sx127x_reg_w(0x57, AdcBw | (AdcBwAuto << 3));
    x |= lgw_sx127x_reg_w(0x58, AdcTest | (AdcTrim << 4) | (AdcLowPwr << 7));

    /* set BR and FDEV for 200 kHz bandwidth*/
    x |= lgw_sx127x_reg_w(SX1276_REG_BITRATEMSB, 125);
    x |= lgw_sx127x_reg_w(SX1276_REG_BITRATELSB, 0);
    x |= lgw_sx127x_reg_w(SX1276_REG_FDEVMSB, 2);
    x |= lgw_sx127x_reg_w(SX1276_REG_FDEVLSB, 225);

    /* Config continues... */
    x |= lgw_sx127x_reg_w(SX1276_REG_RXCONFIG, 0); /* Disable AGC */
    x |= lgw_sx127x_reg_w(SX1276_REG_RSSICONFIG, RssiSmoothing | (RssiOffset << 3)); /* Set RSSI smoothing to 64 samples, RSSI offset 3dB */
    x |= lgw_sx127x_reg_w(SX1276_REG_RXBW, RxBwExp | (RxBwMant << 3)); /* RX BW = 100kHz, Mant=20, Exp=2 */
    x |= lgw_sx127x_reg_w(SX1276_REG_RXDELAY, 2);
    x |= lgw_sx127x_reg_w(SX1276_REG_PLL, 0x10); /* PLL BW set to 75 KHz */
    x |= lgw_sx127x_reg_w(0x43, 1); /* optimize PLL start-up time */

    if (x != LGW_REG_SUCCESS) {
        DEBUG_MSG("ERROR: Failed to configure SX1276\n");
        return x;
    }

    /* set Rx continuous mode */
    x = lgw_sx127x_reg_w(SX1276_REG_OPMODE, 5 | (ModulationShaping << 3)); /* Receiver Mode, no FSK shaping */
    wait_ms(500);
    x |= lgw_sx127x_reg_r(SX1276_REG_IRQFLAGS1, &reg_val);
    /* Check if RxReady and ModeReady */
    if ((TAKE_N_BITS_FROM(reg_val, 6, 1) == 0) || (TAKE_N_BITS_FROM(reg_val, 7, 1) == 0) || (x != LGW_REG_SUCCESS)) {
        DEBUG_MSG("ERROR: SX1276 failed to enter RX continuous mode\n");
        return LGW_REG_ERROR;
    }
    wait_ms(500);

    DEBUG_MSG("INFO: Successfully configured SX1276 for FSK modulation\n");

    return LGW_REG_SUCCESS;
}
Exemplo n.º 2
0
int main(int argc, char **argv)
{
    int i;
    int xi = 0;

    /* in/out variables */
    double f1 = 0.0;
    uint32_t f_init = 0; /* in Hz */
    uint32_t f_start = 0; /* in Hz */
    uint16_t loop_cnt = 0;
    int8_t rssi_target_dBm = -80;
    uint16_t scan_time_us = 128;
    uint32_t timestamp;
    uint8_t rssi_value;
    int8_t rssi_offset = DEFAULT_SX127X_RSSI_OFFSET;
    int32_t val, val2;
    int channel;
    uint32_t freq_offset;

    /* parse command line options */
    while ((i = getopt (argc, argv, "h:f:s:r:o:")) != -1) {
        switch (i) {
            case 'h':
                usage();
                return EXIT_FAILURE;
                break;

            case 'f':
                i = sscanf(optarg, "%lf", &f1);
                if ((i != 1) || (f1 < 30.0) || (f1 > 3000.0)) {
                    MSG("ERROR: Invalid LBT start frequency\n");
                    usage();
                    return EXIT_FAILURE;
                } else {
                    f_start = (uint32_t)((f1*1e6) + 0.5);/* .5 Hz offset to get rounding instead of truncating */
                }
                break;
            case 's':
                i = sscanf(optarg, "%i", &xi);
                if ((i != 1) || ((xi != 128) && (xi != 5000))) {
                    MSG("ERROR: scan_time_us must be 128 or 5000 \n");
                    usage();
                    return EXIT_FAILURE;
                } else {
                    scan_time_us = xi;
                }
                break;
            case 'r':
                i = sscanf(optarg, "%i", &xi);
                if ((i != 1) || ((xi < -128) && (xi > 0))) {
                    MSG("ERROR: rssi_target must be b/w -128 & 0 \n");
                    usage();
                    return EXIT_FAILURE;
                } else {
                    rssi_target_dBm = xi;
                }
                break;
            case 'o': /* -o <int>  SX127x RSSI offset [-128..127] */
                i = sscanf(optarg, "%i", &xi);
                if((i != 1) || (xi < -128) || (xi > 127)) {
                    MSG("ERROR: rssi_offset must be b/w -128 & 127\n");
                    usage();
                    return EXIT_FAILURE;
                } else {
                    rssi_offset = (int8_t)xi;
                }
                break;
            default:
                MSG("ERROR: argument parsing use -h option for help\n");
                usage();
                return EXIT_FAILURE;
        }
    }

    MSG("INFO: Starting LoRa Gateway v1.5 LBT test\n");

    /* configure signal handling */
    sigemptyset(&sigact.sa_mask);
    sigact.sa_flags = 0;
    sigact.sa_handler = sig_handler;
    sigaction(SIGQUIT, &sigact, NULL);
    sigaction(SIGINT, &sigact, NULL);
    sigaction(SIGTERM, &sigact, NULL);

    /* Connect to concentrator */
    i = lgw_connect(false, LGW_DEFAULT_NOTCH_FREQ);
    if (i != LGW_REG_SUCCESS) {
        MSG("ERROR: lgw_connect() did not return SUCCESS\n");
        return EXIT_FAILURE;
    }

    /* Check if FPGA supports LBT */
    lgw_fpga_reg_r(LGW_FPGA_FEATURE, &val);
    if (TAKE_N_BITS_FROM((uint8_t)val, 2, 1) != true) {
        MSG("ERROR: LBT is not supported (0x%x)\n", (uint8_t)val);
        return EXIT_FAILURE;
    }

    /* Get FPGA lowest frequency for LBT channels */
    lgw_fpga_reg_r(LGW_FPGA_LBT_INITIAL_FREQ, &val);
    switch (val) {
        case 0:
            f_init = 915000000;
            break;
        case 1:
            f_init = 863000000;
            break;
        default:
            MSG("ERROR: LBT start frequency %d is not supported\n", val);
            return EXIT_FAILURE;
    }

    /* Initialize 1st LBT channel freq if not given by user */
    if (f_start == 0) {
        f_start = f_init;
    } else if (f_start < f_init) {
        MSG("ERROR: LBT start frequency %u is not supported (f_init=%u)\n", f_start, f_init);
        return EXIT_FAILURE;
    }
    MSG("FREQ: %u\n", f_start);

    /* Configure SX127x and read few RSSI points */
    lgw_setup_sx127x(f_init, MOD_FSK, LGW_SX127X_RXBW_100K_HZ, rssi_offset); /* 200KHz LBT channels */
    for (i = 0; i < 100; i++) {
        lgw_sx127x_reg_r(0x11, &rssi_value); /* 0x11: RegRssiValue */
        MSG("SX127x RSSI:%i dBm\n", -(rssi_value/2));
        wait_ms(10);
    }

    /* Configure LBT */
    val = -2*(rssi_target_dBm);
    lgw_fpga_reg_w(LGW_FPGA_RSSI_TARGET, val);
    for (i = 0; i < LBT_CHANNEL_FREQ_NB; i++) {
        freq_offset = (f_start - f_init)/100E3 + i*2; /* 200KHz between each channel */
        lgw_fpga_reg_w(LGW_FPGA_LBT_CH0_FREQ_OFFSET+i, (int32_t)freq_offset);
        if (scan_time_us == 5000) { /* configured to 128 by default */
            lgw_fpga_reg_w(LGW_FPGA_LBT_SCAN_TIME_CH0+i, 1);
        }
    }

    lgw_fpga_reg_r(LGW_FPGA_RSSI_TARGET, &val);
    MSG("RSSI_TARGET = %d\n", val);
    if (val != (-2*rssi_target_dBm)) {
        MSG("ERROR: failed to read back RSSI target register value\n");
        return EXIT_FAILURE;
    }
    for (i = 0; i < LBT_CHANNEL_FREQ_NB; i++) {
        lgw_fpga_reg_r(LGW_FPGA_LBT_CH0_FREQ_OFFSET+i, &val);
        lgw_fpga_reg_r(LGW_FPGA_LBT_SCAN_TIME_CH0+i, &val2);
        MSG("CH_%i: freq=%u (offset=%i), scan_time=%u (%i)\n", i, (uint32_t)((val*100E3)+f_init), val, (val2==1)?5000:128, val2);
    }
    lgw_fpga_reg_r(LGW_FPGA_VERSION, &val);
    MSG("FPGA VERSION = %d\n", val);

    /* Enable LBT FSM */
    lgw_fpga_reg_w(LGW_FPGA_CTRL_FEATURE_START, 1);

    /* Start test */
    while ((quit_sig != 1) && (exit_sig != 1)) {
        MSG("~~~~\n");
        for (channel = 0; channel < LBT_CHANNEL_FREQ_NB; channel++) {
            /* Select LBT channel */
            lgw_fpga_reg_w(LGW_FPGA_LBT_TIMESTAMP_SELECT_CH, channel);

            /* Get last instant when the selected channel was free */
            lgw_fpga_reg_r(LGW_FPGA_LBT_TIMESTAMP_CH, &val);
            timestamp = (uint32_t)(val & 0x0000FFFF) * 256; /* 16bits (1LSB = 256µs) */
            MSG(" TIMESTAMP_CH%u = %u\n", channel, timestamp);
        }

        loop_cnt += 1;
        wait_ms(400);
    }

    /* close SPI link */
    i = lgw_disconnect();
    if (i != LGW_REG_SUCCESS) {
        MSG("ERROR: lgw_disconnect() did not return SUCCESS\n");
        return EXIT_FAILURE;
    }

    MSG("INFO: Exiting LoRa Gateway v1.5 LBT test successfully\n");
    return EXIT_SUCCESS;
}