Exemplo n.º 1
0
void Eeprom::set_size(int size)
{
    return ftdi_eeprom_setsize(d->context, &d->eeprom, size);
}
int main(int argc, char *argv[])
{
    int ret, i;
    struct ftdi_device_list *devlist, *curdev;
    struct ftdi_context ftdic;
    struct ftdi_eeprom  eeprom;

    for (i = 0; i < CBUS_NUM; i++)
    {
        apcCBUS[i] = NULL;
    }

    {
        static struct option long_options[] =
        {

            {"help",                    no_argument,        NULL, 'h'},
            {"verbosity",               required_argument,  NULL, 'V'},

            {"vid",                     required_argument,  NULL, 'v'},
            {"pid",                     required_argument,  NULL, 'p'},

            {"manufacturer",            required_argument,  NULL, 'm'},
            {"description",             required_argument,  NULL, 'd'},

            {"serial",                  required_argument,  NULL, 's'},
            {"autoserial",              required_argument,  NULL, 'a'},

            {"C0",                      required_argument,  NULL, '0'},
            {"C1",                      required_argument,  NULL, '1'},
            {"C2",                      required_argument,  NULL, '2'},
            {"C3",                      required_argument,  NULL, '3'},
            {"C4",                      required_argument,  NULL, '4'},

            { NULL, 0, NULL, 0}
        };
        signed char opt;
        int option_index;

        while ((opt = getopt_long(argc, argv, "hV:v:p:m:d:s:a:0:1:2:3:4:", long_options, &option_index)) != -1)
        {
            switch (opt)
            {
            case 'h':
                print_usage_exit(argv);
                break;

            case 'V':
                if (iMyStrtoul(&u32Verbosity, optarg, "verbosity", 2))
                {
                    return EXIT_FAILURE;
                }
                break;

            case 'v':
                if (iMyStrtoul(&u32VID, optarg, "vendor id", 0xFFFF))
                {
                    return EXIT_FAILURE;
                }
                break;

            case 'p':
                if (iMyStrtoul(&u32PID, optarg, "product id", 0xFFFF))
                {
                    return EXIT_FAILURE;
                }
                break;

            case 'm':
                pcManufacturer = optarg;
                break;

            case 'd':
                pcDescription = optarg;
                break;

            case 's':
                pcSerial = optarg;
                break;

            case 'a':
                pcAutoSerial = optarg;
                break;

            case '0':
                apcCBUS[0] = optarg;
                break;

            case '1':
                apcCBUS[1] = optarg;
                break;

            case '2':
                apcCBUS[2] = optarg;
                break;

            case '3':
                apcCBUS[3] = optarg;
                break;

            case '4':
                apcCBUS[4] = optarg;
                break;

            default: /* '?' */
                print_usage_exit(argv);
            }
        }
    }

    printf("FTProg FTDI Programmer version %s\n\r", Version);

    /* Handle serial numbers */
    if (pcSerial && pcAutoSerial)
    {
        fprintf(stderr, "Please specify only one of serial number and autoserial\n\r");
        return EXIT_FAILURE;
    }

    if (pcSerial)
    {
        if (strlen(pcSerial) != 8)
        {
            fprintf(stderr, "Serial number must be 8 character string\n\r");
            return EXIT_FAILURE;
        }
    }

    if (pcAutoSerial)
    {
        int fd;
        if (strlen(pcAutoSerial) != 2)
        {
            fprintf(stderr, "Serial number prefix must be 2 character string\n\r");
            return EXIT_FAILURE;
        }

        pcSerial = malloc(sizeof(char) * 9);
        if (!pcSerial)
        {
            fprintf(stderr, "Memory error\n");
            return EXIT_FAILURE;
        }
        pcSerial[0] = pcAutoSerial[0];
        pcSerial[1] = pcAutoSerial[1];

        if ((fd = open("/dev/urandom", O_RDONLY)) < 0)
        {
            fprintf(stderr, "Could not open /dev/urandom (%s)\n\r", strerror(errno));
            return EXIT_FAILURE;
        }
        for (i = 2; i < 8; i++)
        {
            uint32_t j;
            read(fd, &j, 1);
            pcSerial[i] = "0123456789ABCDEF"[j % 16];
        }
        close(fd);

        pcSerial[8] = '\0';
        if (u32Verbosity > 0)
        {
            printf("Autogenerated serial number: '%s'\n", pcSerial);
        }
    }


    for (i = 0; i < CBUS_NUM; i++)
    {
        if (apcCBUS[i])
        {
            int j, iFound = 0;
            for (j = 0; j < (sizeof(asCBUSModeLookup)/sizeof(tsCBUSModeLookup)); j++)
            {
                if (strcmp(apcCBUS[i], asCBUSModeLookup[j].pcDescription) == 0)
                {
                    iFound = 1;
                    apsCBUS_Function[i] = &asCBUSModeLookup[j];
                }
            }
            if (!iFound)
            {
                fprintf(stderr, "Invalid C%d '%s'\n\r", i, apcCBUS[i]);
                return EXIT_FAILURE;
            }
        }
    }

    if (ftdi_init(&ftdic) < 0)
    {
        fprintf(stderr, "ftdi_init failed\n");
        return EXIT_FAILURE;
    }

    if ((ret = ftdi_usb_find_all(&ftdic, &devlist, u32VID, u32PID)) < 0)
    {
        fprintf(stderr, "ftdi_usb_find_all failed: %d (%s)\n", ret, ftdi_get_error_string(&ftdic));
        return EXIT_FAILURE;
    }

    printf("Number of FTDI devices found: %d\n", ret);

    for (i=0, curdev = devlist; curdev != NULL; i++, curdev = curdev->next)
    {
        printf(" Updating device: %d\n\r", i);

        if ((ret = ftdi_usb_open_dev(&ftdic, curdev->dev)) < 0)
        {
            fprintf(stderr, "ftdi_usb_open_dev failed: %d (%s)\n", ret, ftdi_get_error_string(&ftdic));
            return EXIT_FAILURE;
        }

        // Read out FTDIChip-ID of R type chips
        if (ftdic.type == TYPE_R)
        {
            unsigned char *pcEepromBuffer = NULL;
            unsigned int chipid;

            if ((ret = ftdi_read_chipid(&ftdic, &chipid)) < 0)
            {
                fprintf(stderr, "ftdi_read_chipid failed: %d (%s)\n", ret, ftdi_get_error_string(&ftdic));
                return EXIT_FAILURE;
            }

            printf("  FTDI chipid: %X\n", chipid);

            /* EEPROM is 160 bytes */
            ftdi_eeprom_setsize(&ftdic, &eeprom, 160);

            printf("  EEPROM size: %d bytes\n", ftdic.eeprom_size);
            pcEepromBuffer = malloc(ftdic.eeprom_size);
            if (!pcEepromBuffer)
            {
                fprintf(stderr, "Memory error!");
                return EXIT_FAILURE;
            }
            else
            {

                int i;
                if ((ret = ftdi_read_eeprom(&ftdic, pcEepromBuffer)) < 0)
                {
                    fprintf(stderr, "ftdi_read_eeprom failed: %d (%s)\n", ret, ftdi_get_error_string(&ftdic));
                    return EXIT_FAILURE;
                }
                if ((ret = ftdi_eeprom_decode(&eeprom, pcEepromBuffer, ftdic.eeprom_size)) < 0)
                {
                    if (ret != -1)
                    {
                        /* Avoid errors due to hard coded size causing checksum to fail. */
                        fprintf(stderr, "Error decoding eeprom buffer: %d (%s)\n", ret, ftdi_get_error_string(&ftdic));
                        return EXIT_FAILURE;
                    }
                }

                if (u32Verbosity > 0)
                {
                    printf("    Current Vendor: %d, %s\n", eeprom.vendor_id, eeprom.manufacturer);
                    printf("    Current Product: %d, %s\n", eeprom.product_id, eeprom.product);
                    printf("    Current Serial: %s\n", eeprom.serial);

                    if (u32Verbosity >= 2)
                    {
                        printf("      Current EEPROM Contents\n\r");
                        for (i = 0; i < ftdic.eeprom_size; i+=2)
                        {
                            if ((i % 16) == 0)
                            {
                                printf("        %04x:", i/2);
                            }
                            printf(" 0x%02x%02x", pcEepromBuffer[i],pcEepromBuffer[i+1]);
                            if ((i % 16) == 14)
                            {
                                printf("\n\r");
                            }
                        }
                    }
                }

                if (pcManufacturer)
                {
                    printf("  Setting manufacturer: '%s'\n\r", pcManufacturer);
                    free(eeprom.manufacturer);
                    eeprom.manufacturer     = pcManufacturer;
                }

                if (pcDescription)
                {
                    printf("  Setting description: '%s'\n\r", pcDescription);
                    free(eeprom.product);
                    eeprom.product          = pcDescription;
                }

                if (pcSerial)
                {
                    printf("  Setting serial number: '%s'\n\r", pcSerial);
                    free(eeprom.serial);
                    eeprom.serial           = pcSerial;
                }

                for (i = 0; i < CBUS_NUM; i++)
                {
                    if (apcCBUS[i])
                    {
                        /* Argument given */
                        printf("  Setting C%d: '%s' (%d)\n\r", i,
                               apsCBUS_Function[i]->pcDescription,
                               apsCBUS_Function[i]->iCBUSMode);

                        eeprom.cbus_function[i] = apsCBUS_Function[i]->iCBUSMode;
                    }
                }

                /* EEPROM is 160 bytes */
                ftdi_eeprom_setsize(&ftdic, &eeprom, 160);

                if ((ret = ftdi_eeprom_build(&eeprom, pcEepromBuffer)) < 0)
                {
                    fprintf(stderr, "ftdi_eeprom_build failed: %d (%s)\n\r", ret, ftdi_get_error_string(&ftdic));
                    return -1;
                }

                if ((ret = ftdi_write_eeprom(&ftdic, pcEepromBuffer)) < 0)
                {
                    fprintf(stderr, "ftdi_write_eeprom failed: %d (%s)\n", ret, ftdi_get_error_string(&ftdic));
                    return -1;
                }
                printf("  Wrote new EEPROM data successfully\n\r");
            }
        }

        if ((ret = ftdi_usb_close(&ftdic)) < 0)
        {
            fprintf(stderr, "ftdi_usb_close failed: %d (%s)\n\r", ret, ftdi_get_error_string(&ftdic));
            return EXIT_FAILURE;
        }
    }

    ftdi_list_free(&devlist);
    ftdi_deinit(&ftdic);
    return EXIT_SUCCESS;
}