⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ftdi.c

📁 libftdi - A library (using libusb) to talk to FTDI s FT2232C, FT232BM and FT245BM type chips includ
💻 C
📖 第 1 页 / 共 3 页
字号:
    ftdi->bitbang_enabled = 1;    return 0;}/**    Disable bitbang mode.    \param ftdi pointer to ftdi_context    \retval  0: all fine    \retval -1: can't disable bitbang mode*/int ftdi_disable_bitbang(struct ftdi_context *ftdi){    if (usb_control_msg(ftdi->usb_dev, 0x40, 0x0B, 0, ftdi->index, NULL, 0, ftdi->usb_write_timeout) != 0)        ftdi_error_return(-1, "unable to leave bitbang mode. Perhaps not a BM type chip?");    ftdi->bitbang_enabled = 0;    return 0;}/**    Enable advanced bitbang mode for FT2232C chips.    \param ftdi pointer to ftdi_context    \param bitmask Bitmask to configure lines.           HIGH/ON value configures a line as output.    \param mode Bitbang mode: 1 for normal mode, 2 for SPI mode    \retval  0: all fine    \retval -1: can't enable bitbang mode*/int ftdi_set_bitmode(struct ftdi_context *ftdi, unsigned char bitmask, unsigned char mode){    unsigned short usb_val;    usb_val = bitmask; // low byte: bitmask    usb_val |= (mode << 8);    if (usb_control_msg(ftdi->usb_dev, 0x40, 0x0B, usb_val, ftdi->index, NULL, 0, ftdi->usb_write_timeout) != 0)        ftdi_error_return(-1, "unable to configure bitbang mode. Perhaps not a 2232C type chip?");    ftdi->bitbang_mode = mode;    ftdi->bitbang_enabled = (mode == BITMODE_BITBANG || mode == BITMODE_SYNCBB)?1:0;    return 0;}/**    Directly read pin state. Useful for bitbang mode.    \param ftdi pointer to ftdi_context    \param pins Pointer to store pins into    \retval  0: all fine    \retval -1: read pins failed*/int ftdi_read_pins(struct ftdi_context *ftdi, unsigned char *pins){    if (usb_control_msg(ftdi->usb_dev, 0xC0, 0x0C, 0, ftdi->index, (char *)pins, 1, ftdi->usb_read_timeout) != 1)        ftdi_error_return(-1, "read pins failed");    return 0;}/**    Set latency timer    The FTDI chip keeps data in the internal buffer for a specific    amount of time if the buffer is not full yet to decrease    load on the usb bus.    \param ftdi pointer to ftdi_context    \param latency Value between 1 and 255    \retval  0: all fine    \retval -1: latency out of range    \retval -2: unable to set latency timer*/int ftdi_set_latency_timer(struct ftdi_context *ftdi, unsigned char latency){    unsigned short usb_val;    if (latency < 1)        ftdi_error_return(-1, "latency out of range. Only valid for 1-255");    usb_val = latency;    if (usb_control_msg(ftdi->usb_dev, 0x40, 0x09, usb_val, ftdi->index, NULL, 0, ftdi->usb_write_timeout) != 0)        ftdi_error_return(-2, "unable to set latency timer");    return 0;}/**    Get latency timer    \param ftdi pointer to ftdi_context    \param latency Pointer to store latency value in    \retval  0: all fine    \retval -1: unable to get latency timer*/int ftdi_get_latency_timer(struct ftdi_context *ftdi, unsigned char *latency){    unsigned short usb_val;    if (usb_control_msg(ftdi->usb_dev, 0xC0, 0x0A, 0, ftdi->index, (char *)&usb_val, 1, ftdi->usb_read_timeout) != 1)        ftdi_error_return(-1, "reading latency timer failed");    *latency = (unsigned char)usb_val;    return 0;}/**    Init eeprom with default values.    \param eeprom Pointer to ftdi_eeprom*/void ftdi_eeprom_initdefaults(struct ftdi_eeprom *eeprom){    eeprom->vendor_id = 0x0403;    eeprom->product_id = 0x6001;    eeprom->self_powered = 1;    eeprom->remote_wakeup = 1;    eeprom->BM_type_chip = 1;    eeprom->in_is_isochronous = 0;    eeprom->out_is_isochronous = 0;    eeprom->suspend_pull_downs = 0;    eeprom->use_serial = 0;    eeprom->change_usb_version = 0;    eeprom->usb_version = 0x0200;    eeprom->max_power = 0;    eeprom->manufacturer = NULL;    eeprom->product = NULL;    eeprom->serial = NULL;}/**   Build binary output from ftdi_eeprom structure.   Output is suitable for ftdi_write_eeprom().   \param eeprom Pointer to ftdi_eeprom   \param output Buffer of 128 bytes to store eeprom image to   \retval >0: used eeprom size   \retval -1: eeprom size (128 bytes) exceeded by custom strings*/int ftdi_eeprom_build(struct ftdi_eeprom *eeprom, unsigned char *output){    unsigned char i, j;    unsigned short checksum, value;    unsigned char manufacturer_size = 0, product_size = 0, serial_size = 0;    int size_check;    if (eeprom->manufacturer != NULL)        manufacturer_size = strlen(eeprom->manufacturer);    if (eeprom->product != NULL)        product_size = strlen(eeprom->product);    if (eeprom->serial != NULL)        serial_size = strlen(eeprom->serial);    size_check = 128; // eeprom is 128 bytes    size_check -= 28; // 28 are always in use (fixed)    size_check -= manufacturer_size*2;    size_check -= product_size*2;    size_check -= serial_size*2;    // eeprom size exceeded?    if (size_check < 0)        return (-1);    // empty eeprom    memset (output, 0, 128);    // Addr 00: Stay 00 00    // Addr 02: Vendor ID    output[0x02] = eeprom->vendor_id;    output[0x03] = eeprom->vendor_id >> 8;    // Addr 04: Product ID    output[0x04] = eeprom->product_id;    output[0x05] = eeprom->product_id >> 8;    // Addr 06: Device release number (0400h for BM features)    output[0x06] = 0x00;    if (eeprom->BM_type_chip == 1)        output[0x07] = 0x04;    else        output[0x07] = 0x02;    // Addr 08: Config descriptor    // Bit 1: remote wakeup if 1    // Bit 0: self powered if 1    //    j = 0;    if (eeprom->self_powered == 1)        j = j | 1;    if (eeprom->remote_wakeup == 1)        j = j | 2;    output[0x08] = j;    // Addr 09: Max power consumption: max power = value * 2 mA    output[0x09] = eeprom->max_power;    ;    // Addr 0A: Chip configuration    // Bit 7: 0 - reserved    // Bit 6: 0 - reserved    // Bit 5: 0 - reserved    // Bit 4: 1 - Change USB version    // Bit 3: 1 - Use the serial number string    // Bit 2: 1 - Enable suspend pull downs for lower power    // Bit 1: 1 - Out EndPoint is Isochronous    // Bit 0: 1 - In EndPoint is Isochronous    //    j = 0;    if (eeprom->in_is_isochronous == 1)        j = j | 1;    if (eeprom->out_is_isochronous == 1)        j = j | 2;    if (eeprom->suspend_pull_downs == 1)        j = j | 4;    if (eeprom->use_serial == 1)        j = j | 8;    if (eeprom->change_usb_version == 1)        j = j | 16;    output[0x0A] = j;    // Addr 0B: reserved    output[0x0B] = 0x00;    // Addr 0C: USB version low byte when 0x0A bit 4 is set    // Addr 0D: USB version high byte when 0x0A bit 4 is set    if (eeprom->change_usb_version == 1) {        output[0x0C] = eeprom->usb_version;        output[0x0D] = eeprom->usb_version >> 8;    }    // Addr 0E: Offset of the manufacturer string + 0x80    output[0x0E] = 0x14 + 0x80;    // Addr 0F: Length of manufacturer string    output[0x0F] = manufacturer_size*2 + 2;    // Addr 10: Offset of the product string + 0x80, calculated later    // Addr 11: Length of product string    output[0x11] = product_size*2 + 2;    // Addr 12: Offset of the serial string + 0x80, calculated later    // Addr 13: Length of serial string    output[0x13] = serial_size*2 + 2;    // Dynamic content    output[0x14] = manufacturer_size*2 + 2;    output[0x15] = 0x03; // type: string    i = 0x16, j = 0;    // Output manufacturer    for (j = 0; j < manufacturer_size; j++) {        output[i] = eeprom->manufacturer[j], i++;        output[i] = 0x00, i++;    }    // Output product name    output[0x10] = i + 0x80;  // calculate offset    output[i] = product_size*2 + 2, i++;    output[i] = 0x03, i++;    for (j = 0; j < product_size; j++) {        output[i] = eeprom->product[j], i++;        output[i] = 0x00, i++;    }    // Output serial    output[0x12] = i + 0x80; // calculate offset    output[i] = serial_size*2 + 2, i++;    output[i] = 0x03, i++;    for (j = 0; j < serial_size; j++) {        output[i] = eeprom->serial[j], i++;        output[i] = 0x00, i++;    }    // calculate checksum    checksum = 0xAAAA;    for (i = 0; i < 63; i++) {        value = output[i*2];        value += output[(i*2)+1] << 8;        checksum = value^checksum;        checksum = (checksum << 1) | (checksum >> 15);    }    output[0x7E] = checksum;    output[0x7F] = checksum >> 8;    return size_check;}/**    Read eeprom    \param ftdi pointer to ftdi_context    \param eeprom Pointer to store eeprom into    \retval  0: all fine    \retval -1: read failed*/int ftdi_read_eeprom(struct ftdi_context *ftdi, unsigned char *eeprom){    int i;    for (i = 0; i < 64; i++) {        if (usb_control_msg(ftdi->usb_dev, 0xC0, 0x90, 0, i, eeprom+(i*2), 2, ftdi->usb_read_timeout) != 2)            ftdi_error_return(-1, "reading eeprom failed");    }    return 0;}/**    Write eeprom    \param ftdi pointer to ftdi_context    \param eeprom Pointer to read eeprom from    \retval  0: all fine    \retval -1: read failed*/int ftdi_write_eeprom(struct ftdi_context *ftdi, unsigned char *eeprom){    unsigned short usb_val;    int i;    for (i = 0; i < 64; i++) {        usb_val = eeprom[i*2];        usb_val += eeprom[(i*2)+1] << 8;        if (usb_control_msg(ftdi->usb_dev, 0x40, 0x91, usb_val, i, NULL, 0, ftdi->usb_write_timeout) != 0)            ftdi_error_return(-1, "unable to write eeprom");    }    return 0;}/**    Erase eeprom    \param ftdi pointer to ftdi_context    \retval  0: all fine    \retval -1: erase failed*/int ftdi_erase_eeprom(struct ftdi_context *ftdi){    if (usb_control_msg(ftdi->usb_dev, 0x40, 0x92, 0, 0, NULL, 0, ftdi->usb_write_timeout) != 0)        ftdi_error_return(-1, "unable to erase eeprom");    return 0;}/**    Get string representation for last error code    \param ftdi pointer to ftdi_context    \retval Pointer to error string*/char *ftdi_get_error_string (struct ftdi_context *ftdi){    return ftdi->error_str;}/*    Flow control code by Lorenz Moesenlechner (lorenz@hcilab.org)    and Matthias Kranz  (matthias@hcilab.org)*//**    Set flowcontrol for ftdi chip    \param ftdi pointer to ftdi_context    \param flowctrl flow control to use. should be            SIO_DISABLE_FLOW_CTRL, SIO_RTS_CTS_HS, SIO_DTR_DSR_HS or SIO_XON_XOFF_HS       \retval  0: all fine    \retval -1: set flow control failed*/int ftdi_setflowctrl(struct ftdi_context *ftdi, int flowctrl){    if (usb_control_msg(ftdi->usb_dev, SIO_SET_FLOW_CTRL_REQUEST_TYPE,                        SIO_SET_FLOW_CTRL_REQUEST, 0, (flowctrl | ftdi->interface),                        NULL, 0, ftdi->usb_write_timeout) != 0)        ftdi_error_return(-1, "set flow control failed");    return 0;}/**    Set dtr line    \param ftdi pointer to ftdi_context    \param state state to set line to (1 or 0)    \retval  0: all fine    \retval -1: set dtr failed*/int ftdi_setdtr(struct ftdi_context *ftdi, int state){    unsigned short usb_val;    if (state)        usb_val = SIO_SET_DTR_HIGH;    else        usb_val = SIO_SET_DTR_LOW;    if (usb_control_msg(ftdi->usb_dev, SIO_SET_MODEM_CTRL_REQUEST_TYPE,                        SIO_SET_MODEM_CTRL_REQUEST, usb_val, ftdi->interface,                        NULL, 0, ftdi->usb_write_timeout) != 0)        ftdi_error_return(-1, "set dtr failed");    return 0;}/**    Set rts line    \param ftdi pointer to ftdi_context    \param state state to set line to (1 or 0)    \retval  0: all fine    \retval -1 set rts failed*/int ftdi_setrts(struct ftdi_context *ftdi, int state){    unsigned short usb_val;    if (state)        usb_val = SIO_SET_RTS_HIGH;    else        usb_val = SIO_SET_RTS_LOW;    if (usb_control_msg(ftdi->usb_dev, SIO_SET_MODEM_CTRL_REQUEST_TYPE,                        SIO_SET_MODEM_CTRL_REQUEST, usb_val, ftdi->interface,                        NULL, 0, ftdi->usb_write_timeout) != 0)        ftdi_error_return(-1, "set of rts failed");    return 0;}/* @} end of doxygen libftdi group */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -