From cb6250fae3c448dbcf8a780d8ea621c88a5b66d2 Mon Sep 17 00:00:00 2001 From: Thomas Jarosch Date: Fri, 19 Oct 2007 08:31:15 +0000 Subject: [PATCH] libftdi: (tomj) FTDICHIP-ID read support --- ChangeLog | 5 +++++ examples/simple.c | 7 +++++++ src/ftdi.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++- src/ftdi.h | 3 ++- 4 files changed, 66 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8b17f1a..e21a965 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +New in 0.11 +----------- +* Detection of R-type chips +* FTDIChip-ID read support (Peter Holik) + New in 0.10 ----------- * Examples for libftdi_usb_find_all and CBUS mode diff --git a/examples/simple.c b/examples/simple.c index 4156a92..d3599c5 100644 --- a/examples/simple.c +++ b/examples/simple.c @@ -19,6 +19,13 @@ int main(int argc, char **argv) return EXIT_FAILURE; } + // Read out FTDIChip-ID of R type chips + if (ftdic.type == TYPE_R) { + unsigned int chipid; + printf("ftdi_read_chipid: %d\n", ftdi_read_chipid(&ftdic, &chipid)); + printf("FTDI chipid: %X\n", chipid); + } + ftdi_usb_close(&ftdic); ftdi_deinit(&ftdic); diff --git a/src/ftdi.c b/src/ftdi.c index 096a03d..b029b01 100644 --- a/src/ftdi.c +++ b/src/ftdi.c @@ -315,7 +315,8 @@ int ftdi_usb_open_dev(struct ftdi_context *ftdi, struct usb_device *dev) ftdi->type = TYPE_2232C; if (!ftdi->index) ftdi->index = INTERFACE_A; - } + } else if (dev->descriptor.bcdDevice == 0x600) + ftdi->type = TYPE_R; ftdi_error_return(0, "all fine"); } @@ -1227,6 +1228,56 @@ int ftdi_read_eeprom(struct ftdi_context *ftdi, unsigned char *eeprom) return 0; } +/* + ftdi_read_chipid_shift does the bitshift operation needed for the FTDIChip-ID + Function is only used internally + \internal +*/ +static unsigned char ftdi_read_chipid_shift(unsigned char value) +{ + return ((value & 1) << 1) | + ((value & 2) << 5) | + ((value & 4) >> 2) | + ((value & 8) << 4) | + ((value & 16) >> 1) | + ((value & 32) >> 1) | + ((value & 64) >> 4) | + ((value & 128) >> 2); +} + +/** + Read the FTDIChip-ID from R-type devices + + \param ftdi pointer to ftdi_context + \param chipid Pointer to store FTDIChip-ID + + \retval 0: all fine + \retval -1: read failed +*/ +int ftdi_read_chipid(struct ftdi_context *ftdi, unsigned int *chipid) +{ + unsigned int a = 0, b = 0, result = -1; + + if (usb_control_msg(ftdi->usb_dev, 0xC0, 0x90, 0, 0x43, (char *)&a, 2, ftdi->usb_read_timeout) == 2) + { + a = a << 8 | a >> 8; + if (usb_control_msg(ftdi->usb_dev, 0xC0, 0x90, 0, 0x44, (char *)&b, 2, ftdi->usb_read_timeout) == 2) + { + b = b << 8 | b >> 8; + a = (a << 16) | b; + a = ftdi_read_chipid_shift(a) | ftdi_read_chipid_shift(a>>8)<<8; + a |= ftdi_read_chipid_shift(a>>16)<<16 | ftdi_read_chipid_shift(a>>24)<<24; + *chipid = a ^ 0xa5f0f7d1; + result = 0; + } + } + + if (result != 0) + ftdi_error_return(result, "read of FTDIChip-ID failed"); + + return 0; +} + /** Write eeprom diff --git a/src/ftdi.h b/src/ftdi.h index fd0d357..6d3c98d 100644 --- a/src/ftdi.h +++ b/src/ftdi.h @@ -20,7 +20,7 @@ #include /// FTDI chip type -enum ftdi_chip_type { TYPE_AM=0, TYPE_BM=1, TYPE_2232C=2 }; +enum ftdi_chip_type { TYPE_AM=0, TYPE_BM=1, TYPE_2232C=2, TYPE_R=3 }; /// Parity mode for ftdi_set_line_property() enum ftdi_parity_type { NONE=0, ODD=1, EVEN=2, MARK=3, SPACE=4 }; /// Number of stop bits for ftdi_set_line_property() @@ -266,6 +266,7 @@ extern "C" { // "eeprom" needs to be valid 128 byte eeprom (generated by the eeprom generator) // the checksum of the eeprom is valided int ftdi_read_eeprom(struct ftdi_context *ftdi, unsigned char *eeprom); + int ftdi_read_chipid(struct ftdi_context *ftdi, unsigned int *chipid); int ftdi_write_eeprom(struct ftdi_context *ftdi, unsigned char *eeprom); int ftdi_erase_eeprom(struct ftdi_context *ftdi); -- 1.7.1