Ejemplo n.º 1
0
int bladerf_set_frequency(struct bladerf *dev,
                          bladerf_module module, unsigned int frequency)
{
    int status;
    MUTEX_LOCK(&dev->ctrl_lock);

    status = tuning_set_freq(dev, module, frequency);

    MUTEX_UNLOCK(&dev->ctrl_lock);
    return status;
}
Ejemplo n.º 2
0
static inline int apply_lms_dc_cals(struct bladerf *dev)
{
    int status = 0;
    struct bladerf_lms_dc_cals cals;
    const bool have_rx = BLADERF_HAS_RX_DC_CAL(dev);
    const bool have_tx = BLADERF_HAS_TX_DC_CAL(dev);

    cals.lpf_tuning = -1;
    cals.tx_lpf_i   = -1;
    cals.tx_lpf_q   = -1;
    cals.rx_lpf_i   = -1;
    cals.rx_lpf_q   = -1;
    cals.dc_ref     = -1;
    cals.rxvga2a_i  = -1;
    cals.rxvga2a_q  = -1;
    cals.rxvga2b_i  = -1;
    cals.rxvga2b_q  = -1;

    if (have_rx) {
        const struct bladerf_lms_dc_cals *reg_vals = &dev->cal.dc_rx->reg_vals;

        cals.lpf_tuning = reg_vals->lpf_tuning;
        cals.rx_lpf_i   = reg_vals->rx_lpf_i;
        cals.rx_lpf_q   = reg_vals->rx_lpf_q;
        cals.dc_ref     = reg_vals->dc_ref;
        cals.rxvga2a_i  = reg_vals->rxvga2a_i;
        cals.rxvga2a_q  = reg_vals->rxvga2a_q;
        cals.rxvga2b_i  = reg_vals->rxvga2b_i;
        cals.rxvga2b_q  = reg_vals->rxvga2b_q;
    }

    if (have_tx) {
        const struct bladerf_lms_dc_cals *reg_vals = &dev->cal.dc_tx->reg_vals;

        cals.tx_lpf_i = reg_vals->tx_lpf_i;
        cals.tx_lpf_q = reg_vals->tx_lpf_q;

        if (have_rx) {
            if (cals.lpf_tuning != reg_vals->lpf_tuning) {
                log_warning("LPF tuning mismatch in tables. "
                            "RX=0x%04x, TX=0x%04x",
                            cals.lpf_tuning, reg_vals->lpf_tuning);
            }
        } else {
            /* Have TX cal but no RX cal -- use the RX values that came along
             * for the ride when the TX table was generated */
            cals.rx_lpf_i   = reg_vals->rx_lpf_i;
            cals.rx_lpf_q   = reg_vals->rx_lpf_q;
            cals.dc_ref     = reg_vals->dc_ref;
            cals.rxvga2a_i  = reg_vals->rxvga2a_i;
            cals.rxvga2a_q  = reg_vals->rxvga2a_q;
            cals.rxvga2b_i  = reg_vals->rxvga2b_i;
            cals.rxvga2b_q  = reg_vals->rxvga2b_q;
        }
    }

    /* No TX table was loaded, so load LMS TX register cals from the RX table,
     * if available */
    if (have_rx && !have_tx) {
        const struct bladerf_lms_dc_cals *reg_vals = &dev->cal.dc_rx->reg_vals;

        cals.tx_lpf_i   = reg_vals->tx_lpf_i;
        cals.tx_lpf_q   = reg_vals->tx_lpf_q;
    }

    if (have_rx || have_tx) {
        status = lms_set_dc_cals(dev, &cals);

        /* Force a re-tune so that we can apply the appropriate I/Q DC offset
         * values from our calibration table */
        if (status == 0) {
            int rx_status = 0;
            int tx_status = 0;

            if (have_rx) {
                unsigned int rx_f;
                rx_status = tuning_get_freq(dev, BLADERF_MODULE_RX, &rx_f);
                if (rx_status == 0) {
                    rx_status = tuning_set_freq(dev, BLADERF_MODULE_RX, rx_f);
                }
            }

            if (have_tx) {
                unsigned int rx_f;
                rx_status = tuning_get_freq(dev, BLADERF_MODULE_RX, &rx_f);
                if (rx_status == 0) {
                    rx_status = tuning_set_freq(dev, BLADERF_MODULE_RX, rx_f);
                }
            }

            /* Report the first of any failures */
            status = (rx_status == 0) ? tx_status : rx_status;
        }
    }

    return status;
}
Ejemplo n.º 3
0
int init_device(struct bladerf *dev)
{
    int status;
    uint32_t val;

    /* Readback the GPIO values to see if they are default or already set */
    status = CONFIG_GPIO_READ( dev, &val );
    if (status != 0) {
        log_debug("Failed to read GPIO config %s\n", bladerf_strerror(status));
        return status;
    }

    if ((val & 0x7f) == 0) {
        log_verbose( "Default GPIO value found - initializing device\n" );

        /* Set the GPIO pins to enable the LMS and select the low band */
        status = CONFIG_GPIO_WRITE(dev, 0x57);
        if (status != 0) {
            return status;
        }

        /* Disable the front ends */
        status = lms_enable_rffe(dev, BLADERF_MODULE_TX, false);
        if (status != 0) {
            return status;
        }

        status = lms_enable_rffe(dev, BLADERF_MODULE_RX, false);
        if (status != 0) {
            return status;
        }

        /* Set the internal LMS register to enable RX and TX */
        status = LMS_WRITE(dev, 0x05, 0x3e);
        if (status != 0) {
            return status;
        }

        /* LMS FAQ: Improve TX spurious emission performance */
        status = LMS_WRITE(dev, 0x47, 0x40);
        if (status != 0) {
            return status;
        }

        /* LMS FAQ: Improve ADC performance */
        status = LMS_WRITE(dev, 0x59, 0x29);
        if (status != 0) {
            return status;
        }

        /* LMS FAQ: Common mode voltage for ADC */
        status = LMS_WRITE(dev, 0x64, 0x36);
        if (status != 0) {
            return status;
        }

        /* LMS FAQ: Higher LNA Gain */
        status = LMS_WRITE(dev, 0x79, 0x37);
        if (status != 0) {
            return status;
        }

        /* Set a default samplerate */
        status = si5338_set_sample_rate(dev, BLADERF_MODULE_TX, 1000000, NULL);
        if (status != 0) {
            return status;
        }

        status = si5338_set_sample_rate(dev, BLADERF_MODULE_RX, 1000000, NULL);
        if (status != 0) {
            return status;
        }

        /* Set a default frequency of 1GHz */
        status = tuning_set_freq(dev, BLADERF_MODULE_TX, 1000000000);
        if (status != 0) {
            return status;
        }

        status = tuning_set_freq(dev, BLADERF_MODULE_RX, 1000000000);
        if (status != 0) {
            return status;
        }

        /* Set the calibrated VCTCXO DAC value */
        status = DAC_WRITE(dev, dev->dac_trim);
        if (status != 0) {
            return status;
        }

        /* Set up LMS DC offset register calibration and initial IQ settings,
         * if any tables have been loaded already */
        status = apply_lms_dc_cals(dev);
    }

    return status;
}