Exemplo n.º 1
0
static int write_image(struct cli_state *s, struct params *p, const char *argv0)
{
    int status;
    FILE *f;
    long data_size;
    struct bladerf_image *image = NULL;

    f = expand_and_open(p->data_file, "rb");
    if (!f) {
        return CMD_RET_FILEOP;
    }

    if (fseek(f, 0, SEEK_END) != 0) {
        status = CMD_RET_FILEOP;
        goto write_image_out;
    }

    data_size = ftell(f);
    if (data_size < 0) {
        status = CMD_RET_FILEOP;
        goto write_image_out;
    }

    if ((uint32_t)data_size > p->max_length) {
        status = CMD_RET_INVPARAM;
        cli_err(s, argv0, "The provided data file is too large for the specified flash region.");
        goto write_image_out;
    }

    if (fseek(f, 0, SEEK_SET) != 0) {
        status = CMD_RET_FILEOP;
        goto write_image_out;
    }

    image = bladerf_alloc_image(p->type, p->address, data_size);
    if (!image) {
        status = CMD_RET_MEM;
        goto write_image_out;
    }

    if (fread(image->data, 1, data_size, f) != (size_t)data_size) {
        status = CMD_RET_FILEOP;
        goto write_image_out;
    }

    memcpy(image->serial, p->serial, BLADERF_SERIAL_LENGTH - 1);

    status = bladerf_image_write(image, p->img_file);
    if (status != 0) {
        s->last_lib_error = status;
        status = CMD_RET_LIBBLADERF;
    }

write_image_out:
    fclose(f);
    bladerf_free_image(image);
    return status;
}
Exemplo n.º 2
0
struct bladerf_image * bladerf_alloc_cal_image(bladerf_fpga_size fpga_size,
                                               uint16_t vctcxo_trim)
{
    struct bladerf_image *image;
    int status;

    image = bladerf_alloc_image(BLADERF_IMAGE_TYPE_CALIBRATION,
                                BLADERF_FLASH_ADDR_CAL,
                                BLADERF_FLASH_BYTE_LEN_CAL);

    if (!image) {
        return NULL;
    }

    status = make_cal_region(fpga_size, vctcxo_trim,
                             image->data, image->length);

    if (status != 0) {
        bladerf_free_image(image);
        image = NULL;
    }

    return image;
}
Exemplo n.º 3
0
static int print_image_metadata(struct cli_state *s, struct params *p,
                                const char *argv0)
{
    int status = 0;
    struct bladerf_image *image;
    char datetime[64];
    struct tm *timeval;
    time_t time_tmp;
    int i;

    image = bladerf_alloc_image(BLADERF_IMAGE_TYPE_INVALID, 0, 0);
    if (!image) {
        return CMD_RET_MEM;
    }

    status = bladerf_image_read(image, p->img_file);

    if (status == 0) {
        printf("\n");
        printf("Checksum: ");

        for (i = 0; i < BLADERF_IMAGE_CHECKSUM_LEN; i++) {
            printf("%02x", image->checksum[i]);
        }

        printf("\nImage format version: %d.%d.%d\n", image->version.major,
               image->version.minor, image->version.patch);

        time_tmp = image->timestamp;
        timeval = localtime(&time_tmp);
        if (timeval) {
            memset(datetime, 0, sizeof(datetime));
            strftime(datetime, sizeof(datetime) - 1, "%Y-%m-%d %H:%M:%S", timeval);
        } else {
            strncpy(datetime, "Invalid value", sizeof(datetime));
        }

        printf("Timestamp: %s\n", datetime);
        printf("Serial #: %s\n", image->serial);

        switch (image->type) {
            case BLADERF_IMAGE_TYPE_RAW:
                printf("Image type: Raw\n");
                break;

            case BLADERF_IMAGE_TYPE_CALIBRATION:
                printf("Image type: Calibration data\n");
                break;

            case BLADERF_IMAGE_TYPE_FIRMWARE:
                printf("Image type: Firmware\n");
                break;

            case BLADERF_IMAGE_TYPE_FPGA_40KLE:
                printf("Image type: 40 kLE FPGA metadata and bitstream\n");
                break;

            case BLADERF_IMAGE_TYPE_FPGA_115KLE:
                printf("Image type: 115 kLE FPGA metadata and bitstream\n");
                break;

            default:
                printf("Type: Unknown\n");
                break;
        }

        printf("Address: 0x%08" PRIx32 "\n", image->address);
        printf("Length:  0x%08" PRIx32 "\n", image->length);

        printf("\n");
    } else {
        if (status == BLADERF_ERR_INVAL) {
            cli_err(s, argv0, "Image contains invalid fields or data.");
            status = CMD_RET_INVPARAM;
        }

        s->last_lib_error = status;
        status = CMD_RET_LIBBLADERF;
    }

    bladerf_free_image(image);
    return status;
}
Exemplo n.º 4
0
/* See libbladeRF's dc_cal_table.c for the packed table data format */
int calibrate_dc_gen_tbl(struct cli_state *s, bladerf_module module,
                         const char *filename, unsigned int f_low,
                         unsigned f_inc, unsigned int f_high)
{
    int retval, status;
    size_t off;
    struct bladerf_lms_dc_cals lms_dc_cals;
    unsigned int f;
    struct settings settings;
    bladerf_loopback loopback_backup;
    struct bladerf_image *image = NULL;

    const uint16_t magic = HOST_TO_LE16(0x1ab1);
    const uint32_t reserved = HOST_TO_LE32(0x00000000);
    const uint32_t tbl_version = HOST_TO_LE32(0x00000001);

    const size_t lms_data_size = 10; /* 10 uint8_t register values */

    const uint32_t n_frequencies = (f_high - f_low) / f_inc + 1;
    const uint32_t n_frequencies_le = HOST_TO_LE32(n_frequencies);

    const size_t entry_size = sizeof(uint32_t) +   /* Frequency */
                              2 * sizeof(int16_t); /* DC I and Q valus */

    const size_t table_size = n_frequencies * entry_size;

    const size_t data_size = sizeof(magic) + sizeof(reserved) +
                             sizeof(tbl_version) + sizeof(n_frequencies_le) +
                             lms_data_size + table_size;

    assert(data_size <= UINT_MAX);

    status = backup_and_update_settings(s->dev, module, &settings);
    if (status != 0) {
        return status;
    }

    status = bladerf_get_loopback(s->dev, &loopback_backup);
    if (status != 0) {
        return status;
    }

    status = bladerf_lms_get_dc_cals(s->dev, &lms_dc_cals);
    if (status != 0) {
        goto out;
    }

    if (module == BLADERF_MODULE_RX) {
        image = bladerf_alloc_image(BLADERF_IMAGE_TYPE_RX_DC_CAL,
                                    0xffffffff, (unsigned int) data_size);
    } else {
        image = bladerf_alloc_image(BLADERF_IMAGE_TYPE_TX_DC_CAL,
                                    0xffffffff, (unsigned int) data_size);
    }

    if (image == NULL) {
        status = BLADERF_ERR_MEM;
        goto out;
    }

    status = bladerf_get_serial(s->dev, image->serial);
    if (status != 0) {
        goto out;
    }

    if (module == BLADERF_MODULE_RX) {
        status = bladerf_set_loopback(s->dev, BLADERF_LB_NONE);
        if (status != 0) {
            goto out;
        }
    }

    off = 0;

    memcpy(&image->data[off], &magic, sizeof(magic));
    off += sizeof(magic);

    memcpy(&image->data[off], &reserved, sizeof(reserved));
    off += sizeof(reserved);

    memcpy(&image->data[off], &tbl_version, sizeof(tbl_version));
    off += sizeof(tbl_version);

    memcpy(&image->data[off], &n_frequencies_le, sizeof(n_frequencies_le));
    off += sizeof(n_frequencies_le);

    image->data[off++] = (uint8_t)lms_dc_cals.lpf_tuning;
    image->data[off++] = (uint8_t)lms_dc_cals.tx_lpf_i;
    image->data[off++] = (uint8_t)lms_dc_cals.tx_lpf_q;
    image->data[off++] = (uint8_t)lms_dc_cals.rx_lpf_i;
    image->data[off++] = (uint8_t)lms_dc_cals.rx_lpf_q;
    image->data[off++] = (uint8_t)lms_dc_cals.dc_ref;
    image->data[off++] = (uint8_t)lms_dc_cals.rxvga2a_i;
    image->data[off++] = (uint8_t)lms_dc_cals.rxvga2a_q;
    image->data[off++] = (uint8_t)lms_dc_cals.rxvga2b_i;
    image->data[off++] = (uint8_t)lms_dc_cals.rxvga2b_q;

    putchar('\n');

    for (f = f_low; f <= f_high; f += f_inc) {
        const uint32_t frequency = HOST_TO_LE32((uint32_t)f);
        int16_t dc_i, dc_q;

        printf("  Calibrating @ %u Hz...", f);

        status = bladerf_set_frequency(s->dev, module, f);
        if (status != 0) {
            goto out;
        }

        if (module == BLADERF_MODULE_RX) {
            int16_t error_i, error_q;
            status = calibrate_dc_rx(s, &dc_i, &dc_q, &error_i, &error_q);
            printf("    I=%-4d (avg: %-4d), Q=%-4d (avg: %-4d)\r",
                    dc_i, error_i, dc_q, error_q);
        } else {
            float error_i, error_q;
            status = calibrate_dc_tx(s, &dc_i, &dc_q, &error_i, &error_q);
            printf("    I=%-4d (avg: %3.3f), Q=%-4d (avg: %3.3f)\r",
                    dc_i, error_i, dc_q, error_q);
        }

        if (status != 0) {
            goto out;
        }

        fflush(stdout);

        dc_i = HOST_TO_LE16(dc_i);
        dc_q = HOST_TO_LE16(dc_q);

        memcpy(&image->data[off], &frequency, sizeof(frequency));
        off += sizeof(frequency);

        memcpy(&image->data[off], &dc_i, sizeof(dc_i));
        off += sizeof(dc_i);

        memcpy(&image->data[off], &dc_q, sizeof(dc_q));
        off += sizeof(dc_q);
    }

    status = bladerf_image_write(image, filename);

    printf("\n  Done.\n\n");

out:
    retval = status;

    if (module == BLADERF_MODULE_RX) {
        status = bladerf_set_loopback(s->dev, loopback_backup);
        retval = first_error(retval, status);
    }

    status = bladerf_enable_module(s->dev, BLADERF_MODULE_RX, false);
    retval = first_error(retval, status);

    status = restore_settings(s->dev, module, &settings);
    retval = first_error(retval, status);

    bladerf_free_image(image);
    return retval;
}
Exemplo n.º 5
0
int cmd_flash_init_cal(struct cli_state *state, int argc, char **argv)
{
    int rv;
    bool ok;
    uint16_t dac;
    bladerf_fpga_size fpga_size;
    struct bladerf_image *image = NULL;

    if(argc != 3 && argc != 4) {
        return CMD_RET_NARGS;
    }

    rv = str2fpga(argv[1], &fpga_size);
    if (rv != 0) {
        cli_err(state, argv[0], "Invalid FPGA provided.");
        return rv;
    }

    dac = str2uint(argv[2], 0, 0xffff, &ok);
    if(!ok) {
        cli_err(state, argv[0], "Invalid VCTCXO trim value provided.");
        return CMD_RET_INVPARAM;
    }

    image = bladerf_alloc_cal_image(fpga_size, dac);
    if (!image) {
        return CMD_RET_MEM;
    }

    if (argc == 3) {
        rv = flash_check_state(state, argv[0]);
        if (rv != 0) {
            goto cmd_flash_init_cal_out;
        }

        rv = bladerf_program_flash_unaligned(state->dev, image->address,
                                             image->data, image->length);
        if(rv < 0) {
            cli_err(state, argv[0],
            "Failed to write calibration data.\n"
            "\n"
            "This may have resulted in a corrupted flash. If the device fails to\n"
            "boot at the next power cycle, re-flash the firmware.\n"
            "\n"
            "See the following page for more information:\n"
            "  https://github.com/Nuand/bladeRF/wiki/Upgrading-bladeRF-firmware\n"
            );

            state->last_lib_error = rv;
            rv = CMD_RET_LIBBLADERF;
        } else {
            rv = 0;
        }
    } else {
        assert(argc == 4);
        rv = bladerf_image_write(image, argv[3]);
    }

cmd_flash_init_cal_out:
    bladerf_free_image(image);
    return rv;
}
Exemplo n.º 6
0
/* See libbladeRF's dc_cal_table.c for the packed table data format */
int calibrate_dc_gen_tbl(struct cli_state *s, bladerf_module module,
                         const char *filename, unsigned int f_low,
                         unsigned f_inc, unsigned int f_high)
{
    int retval, status;
    size_t off;
    struct bladerf_lms_dc_cals lms_dc_cals;
    unsigned int f;
    struct settings settings;
    bladerf_loopback loopback_backup;
    struct bladerf_image *image = NULL;
    FILE *write_check;

    const uint16_t magic = HOST_TO_LE16(0x1ab1);
    const uint32_t reserved = HOST_TO_LE32(0x00000000);
    const uint32_t tbl_version = HOST_TO_LE32(0x00000001);

    const size_t lms_data_size = 10; /* 10 uint8_t register values */

    const uint32_t n_frequencies = (f_high - f_low) / f_inc + 1;
    const uint32_t n_frequencies_le = HOST_TO_LE32(n_frequencies);

    const size_t entry_size = sizeof(uint32_t) +   /* Frequency */
                              2 * sizeof(int16_t); /* DC I and Q valus */

    const size_t table_size = n_frequencies * entry_size;

    const size_t data_size = sizeof(magic) + sizeof(reserved) +
                             sizeof(tbl_version) + sizeof(n_frequencies_le) +
                             lms_data_size + table_size;

    assert(data_size <= UINT_MAX);

    /* This operation may take a bit of time, so let's make sure we
     * actually have write access before kicking things off.  Note that
     * access is checked later when the file is actually written.
     */
    write_check = fopen(filename, "wb");
    if (write_check == NULL) {
        if (errno == EACCES) {
            return BLADERF_ERR_PERMISSION;
        } else {
            return BLADERF_ERR_IO;
        }
    } else {
        fclose(write_check);

        /* Not much we care to do if this fails. Throw away the return value
         * to make this explicit to our static analysis tools */
        (void) remove(filename);
    }

    status = backup_and_update_settings(s->dev, module, &settings);
    if (status != 0) {
        return status;
    }

    status = bladerf_get_loopback(s->dev, &loopback_backup);
    if (status != 0) {
        return status;
    }

    status = bladerf_lms_get_dc_cals(s->dev, &lms_dc_cals);
    if (status != 0) {
        goto out;
    }

    if (module == BLADERF_MODULE_RX) {
        image = bladerf_alloc_image(BLADERF_IMAGE_TYPE_RX_DC_CAL,
                                    0xffffffff, (unsigned int) data_size);
    } else {
        image = bladerf_alloc_image(BLADERF_IMAGE_TYPE_TX_DC_CAL,
                                    0xffffffff, (unsigned int) data_size);
    }

    if (image == NULL) {
        status = BLADERF_ERR_MEM;
        goto out;
    }

    status = bladerf_get_serial(s->dev, image->serial);
    if (status != 0) {
        goto out;
    }

    if (module == BLADERF_MODULE_RX) {
        status = bladerf_set_loopback(s->dev, BLADERF_LB_NONE);
        if (status != 0) {
            goto out;
        }
    }

    off = 0;

    memcpy(&image->data[off], &magic, sizeof(magic));
    off += sizeof(magic);

    memcpy(&image->data[off], &reserved, sizeof(reserved));
    off += sizeof(reserved);

    memcpy(&image->data[off], &tbl_version, sizeof(tbl_version));
    off += sizeof(tbl_version);

    memcpy(&image->data[off], &n_frequencies_le, sizeof(n_frequencies_le));
    off += sizeof(n_frequencies_le);

    image->data[off++] = (uint8_t)lms_dc_cals.lpf_tuning;
    image->data[off++] = (uint8_t)lms_dc_cals.tx_lpf_i;
    image->data[off++] = (uint8_t)lms_dc_cals.tx_lpf_q;
    image->data[off++] = (uint8_t)lms_dc_cals.rx_lpf_i;
    image->data[off++] = (uint8_t)lms_dc_cals.rx_lpf_q;
    image->data[off++] = (uint8_t)lms_dc_cals.dc_ref;
    image->data[off++] = (uint8_t)lms_dc_cals.rxvga2a_i;
    image->data[off++] = (uint8_t)lms_dc_cals.rxvga2a_q;
    image->data[off++] = (uint8_t)lms_dc_cals.rxvga2b_i;
    image->data[off++] = (uint8_t)lms_dc_cals.rxvga2b_q;

    putchar('\n');

    for (f = f_low; f <= f_high; f += f_inc) {
        const uint32_t frequency = HOST_TO_LE32((uint32_t)f);
        int16_t dc_i, dc_q;

        printf("  Calibrating @ %u Hz...", f);

        status = bladerf_set_frequency(s->dev, module, f);
        if (status != 0) {
            goto out;
        }

        if (module == BLADERF_MODULE_RX) {
            int16_t error_i, error_q;
            status = calibrate_dc_rx(s, &dc_i, &dc_q, &error_i, &error_q);
            printf("    I=%-4d (avg: %-4d), Q=%-4d (avg: %-4d)\r",
                    dc_i, error_i, dc_q, error_q);
        } else {
            float error_i, error_q;
            status = calibrate_dc_tx(s, &dc_i, &dc_q, &error_i, &error_q);
            printf("    I=%-4d (avg: %3.3f), Q=%-4d (avg: %3.3f)\r",
                    dc_i, error_i, dc_q, error_q);
        }

        if (status != 0) {
            goto out;
        }

        fflush(stdout);

        dc_i = HOST_TO_LE16(dc_i);
        dc_q = HOST_TO_LE16(dc_q);

        memcpy(&image->data[off], &frequency, sizeof(frequency));
        off += sizeof(frequency);

        memcpy(&image->data[off], &dc_i, sizeof(dc_i));
        off += sizeof(dc_i);

        memcpy(&image->data[off], &dc_q, sizeof(dc_q));
        off += sizeof(dc_q);
    }

    status = bladerf_image_write(image, filename);

    printf("\n  Done.\n\n");

out:
    retval = status;

    if (module == BLADERF_MODULE_RX) {
        status = bladerf_set_loopback(s->dev, loopback_backup);
        retval = first_error(retval, status);
    }

    status = bladerf_enable_module(s->dev, BLADERF_MODULE_RX, false);
    retval = first_error(retval, status);

    status = restore_settings(s->dev, module, &settings);
    retval = first_error(retval, status);

    bladerf_free_image(image);
    return retval;
}
Exemplo n.º 7
0
int cmd_flash_restore(struct cli_state *state, int argc, char **argv)
{
    int rv;
    struct bladerf_image *image = NULL;
    struct options opt;
    uint32_t addr, len;

    memset(&opt, 0, sizeof(opt));

    rv = parse_argv(state, argc, argv, &opt);
    if (rv < 0)
        return rv;

    rv = flash_check_state(state, argv[0]);
    if (rv != 0) {
        goto cmd_flash_restore_out;
    }

    image = bladerf_alloc_image(BLADERF_IMAGE_TYPE_INVALID, 0, 0);
    if (!image) {
        rv = CMD_RET_MEM;
        goto cmd_flash_restore_out;
    }

    rv = bladerf_image_read(image, opt.file);
    if (rv < 0) {
        rv_error(rv, "Failed to read flash image from file.");
        goto cmd_flash_restore_out;
    }

    if (opt.override_defaults) {
        addr = opt.address;
        len = u32_min(opt.len, image->length);

        if (len < opt.len) {
            printf("  Warning: Reduced length because only %u bytes are in "
                   "the image.\n", opt.len);
        }

    } else {
        addr = image->address;
        len = image->length;
    }

    rv = bladerf_program_flash_unaligned(state->dev, addr, image->data, len);
    if (rv < 0) {
        cli_err(state, argv[0],
        "Failed to restore flash region.\n"
        "\n"
        "Flash contents may be corrupted. If the device fails to boot at successive\n"
        "power-ons, see the following wiki page for recovery instructions:"
        "  https://github.com/Nuand/bladeRF/wiki/Upgrading-bladeRF-firmware"
        );
        goto cmd_flash_restore_out;
    }

    rv = CMD_RET_OK;

cmd_flash_restore_out:
    free(opt.file);
    bladerf_free_image(image);
    return rv;
}