Skip to content

Commit fe6247a

Browse files
committed
Turn get FTDI strings error into a warning.
Reporting of the chip serial number to the host can be disabled in FTDI EEPROM config (see SerNumEnable* variables in FT2XX Programmer's Guide). This can cause ftdi_usb_get_strings() to fail (specifically on Windows). Turn this failure into a warning, since it's not critical. This fixes #7. Also log libftdi error codes.
1 parent 7e9839e commit fe6247a

File tree

1 file changed

+61
-31
lines changed

1 file changed

+61
-31
lines changed

spi.c

Lines changed: 61 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ static int spi_ftdi_xfer(uint8_t *out_buf, uint8_t *in_buf, int size)
142142

143143
rc = ftdi_write_data(&ftdic, out_buf, size);
144144
if (rc < 0) {
145-
SPI_ERR("FTDI: write data failed: %s", ftdi_get_error_string(&ftdic));
145+
SPI_ERR("FTDI: write data failed: [%d] %s", rc, ftdi_get_error_string(&ftdic));
146146
return -1;
147147
}
148148
if (rc != size) {
@@ -167,7 +167,7 @@ static int spi_ftdi_xfer(uint8_t *out_buf, uint8_t *in_buf, int size)
167167
rc = ftdi_read_data(&ftdic, bufp, len);
168168

169169
if (rc < 0) {
170-
SPI_ERR("FTDI: read data failed: %s", ftdi_get_error_string(&ftdic));
170+
SPI_ERR("FTDI: read data failed: [%d] %s", rc, ftdi_get_error_string(&ftdic));
171171
return -1;
172172
}
173173

@@ -504,7 +504,7 @@ static int spi_enumerate_ports(void)
504504
LOG(DEBUG, "find all: 0x%04x:0x%04x", ftdi_device_ids[id].vid, ftdi_device_ids[id].pid);
505505
rc = ftdi_usb_find_all(&ftdic, &ftdevlist, ftdi_device_ids[id].vid, ftdi_device_ids[id].pid);
506506
if (rc < 0) {
507-
SPI_ERR("FTDI: ftdi_usb_find_all() failed: %s", ftdi_get_error_string(&ftdic));
507+
SPI_ERR("FTDI: ftdi_usb_find_all() failed: [%d] %s", rc, ftdi_get_error_string(&ftdic));
508508
return -1;
509509
}
510510
if (rc == 0)
@@ -513,14 +513,23 @@ static int spi_enumerate_ports(void)
513513
for (ftdev = ftdevlist; ftdev && spi_nports < SPI_MAX_PORTS; ftdev = ftdev->next) {
514514
spi_ports[spi_nports].vid = ftdi_device_ids[id].vid;
515515
spi_ports[spi_nports].pid = ftdi_device_ids[id].pid;
516-
517-
if (ftdi_usb_get_strings(&ftdic, ftdev->dev,
518-
spi_ports[spi_nports].manuf, sizeof(spi_ports[spi_nports].manuf),
519-
spi_ports[spi_nports].desc, sizeof(spi_ports[spi_nports].desc),
520-
spi_ports[spi_nports].serial, sizeof(spi_ports[spi_nports].serial)) < 0)
521-
{
522-
SPI_ERR("FTDI: ftdi_usb_get_strings() failed: %s", ftdi_get_error_string(&ftdic));
523-
return -1;
516+
memset(spi_ports[spi_nports].manuf, 0, sizeof(spi_ports[spi_nports].manuf));
517+
memset(spi_ports[spi_nports].desc, 0, sizeof(spi_ports[spi_nports].desc));
518+
memset(spi_ports[spi_nports].serial, 0, sizeof(spi_ports[spi_nports].serial));
519+
520+
rc = ftdi_usb_get_strings(&ftdic, ftdev->dev,
521+
spi_ports[spi_nports].manuf, sizeof(spi_ports[spi_nports].manuf),
522+
spi_ports[spi_nports].desc, sizeof(spi_ports[spi_nports].desc),
523+
spi_ports[spi_nports].serial, sizeof(spi_ports[spi_nports].serial));
524+
if (rc < 0) {
525+
/* It's not critical to have these strings, make it a warning. */
526+
LOG(WARN, "FTDI: ftdi_usb_get_strings() failed: [%d] %s", rc, ftdi_get_error_string(&ftdic));
527+
if (rc == -9) { /* "\retval -9: get serial number failed" */
528+
/* Serial number can be unavailable due to SerNumEnable*
529+
* settings in FTDI EEPROM. */
530+
LOG(WARN, "FTDI: getting serial number failed, probably SerNumEnable* is off in EEPROM");
531+
spi_ports[spi_nports].serial[0] = '\0';
532+
}
524533
}
525534
snprintf(spi_ports[spi_nports].name, sizeof(spi_ports[spi_nports].name),
526535
"%s %s", ftdi_device_ids[id].name, spi_ports[spi_nports].serial);
@@ -594,6 +603,7 @@ int spi_deinit(void)
594603

595604
int spi_set_clock(unsigned long spi_clk) {
596605
unsigned long ftdi_clk;
606+
int rc;
597607

598608
LOG(DEBUG, "(%lu)", spi_clk);
599609

@@ -625,9 +635,10 @@ int spi_set_clock(unsigned long spi_clk) {
625635
* http://developer.intra2net.com/mailarchive/html/libftdi/2010/msg00240.html
626636
*/
627637
LOG(INFO, "FTDI: setting SPI clock to %lu (FTDI baudrate %lu)", spi_clk, ftdi_clk / 16);
628-
if (ftdi_set_baudrate(&ftdic, ftdi_clk / 16) < 0) {
629-
SPI_ERR("FTDI: set baudrate %lu failed: %s",
630-
ftdi_clk / 16, ftdi_get_error_string(&ftdic));
638+
rc = ftdi_set_baudrate(&ftdic, ftdi_clk / 16);
639+
if (rc < 0) {
640+
SPI_ERR("FTDI: set baudrate %lu failed: [%d] %s",
641+
ftdi_clk / 16, rc, ftdi_get_error_string(&ftdic));
631642
return -1;
632643
}
633644

@@ -675,6 +686,9 @@ unsigned long spi_get_clock(void) {
675686

676687
int spi_open(int nport)
677688
{
689+
int rc;
690+
char *serial;
691+
678692
LOG(DEBUG, "(%d) spi_dev_open=%d", nport, spi_dev_open);
679693

680694
if (spi_dev_open > 0) {
@@ -695,40 +709,52 @@ int spi_open(int nport)
695709

696710
/*ftdi_set_interface(&ftdic, INTERFACE_A);*/ /* XXX for multichannel chips */
697711

698-
if (ftdi_usb_open_desc(&ftdic, spi_ports[nport].vid, spi_ports[nport].pid,
699-
NULL, spi_ports[nport].serial) < 0)
712+
/* Serial number can be unavailable due to SerNumEnable* settings in FTDI
713+
* EEPROM. Don't try to pass a serial number pointer for such a device to
714+
* ftdi_usb_open*(), or it will fail. See issue #7. */
715+
serial = spi_ports[nport].serial;
716+
if (serial[0] == '\0')
717+
serial = NULL;
718+
rc = ftdi_usb_open_desc(&ftdic, spi_ports[nport].vid, spi_ports[nport].pid,
719+
NULL, serial);
720+
if (rc < 0)
700721
{
701-
SPI_ERR("FTDI: ftdi_usb_open_desc() failed: %s", ftdi_get_error_string(&ftdic));
722+
SPI_ERR("FTDI: ftdi_usb_open_desc() failed: [%d] %s", rc, ftdi_get_error_string(&ftdic));
702723
goto open_err;
703724
}
704725

705726
spi_dev_open++;
706727

707728
LOG(INFO, "FTDI: using FTDI device: \"%s\"", spi_ports[nport].name);
708729

709-
if (ftdi_usb_reset(&ftdic) < 0) {
710-
SPI_ERR("FTDI: reset failed: %s", ftdi_get_error_string(&ftdic));
730+
rc = ftdi_usb_reset(&ftdic);
731+
if (rc < 0) {
732+
SPI_ERR("FTDI: reset failed: [%d] %s", rc, ftdi_get_error_string(&ftdic));
711733
goto open_err;
712734
}
713735

714-
if (ftdi_usb_purge_buffers(&ftdic) < 0) {
715-
SPI_ERR("FTDI: purge buffers failed: %s", ftdi_get_error_string(&ftdic));
736+
rc = ftdi_usb_purge_buffers(&ftdic);
737+
if (rc < 0) {
738+
SPI_ERR("FTDI: purge buffers failed: [%d] %s", rc, ftdi_get_error_string(&ftdic));
716739
goto open_err;
717740
}
718741

719742
/* Set 1 ms latency timer, see FTDI AN232B-04 */
720-
if (ftdi_set_latency_timer(&ftdic, 1) < 0) {
721-
SPI_ERR("FTDI: setting latency timer failed: %s", ftdi_get_error_string(&ftdic));
743+
rc = ftdi_set_latency_timer(&ftdic, 1);
744+
if (rc < 0) {
745+
SPI_ERR("FTDI: setting latency timer failed: [%d] %s", rc, ftdi_get_error_string(&ftdic));
722746
goto open_err;
723747
}
724748

725-
if (ftdi_set_bitmode(&ftdic, 0, BITMODE_RESET) < 0) {
726-
SPI_ERR("FTDI: reset bitmode failed: %s", ftdi_get_error_string(&ftdic));
749+
rc = ftdi_set_bitmode(&ftdic, 0, BITMODE_RESET);
750+
if (rc < 0) {
751+
SPI_ERR("FTDI: reset bitmode failed: [%d] %s", rc, ftdi_get_error_string(&ftdic));
727752
goto open_err;
728753
}
729754

730-
if (ftdi_set_bitmode(&ftdic, PINS_OUTPUT, BITMODE_SYNCBB) < 0) {
731-
SPI_ERR("FTDI: set synchronous bitbang mode failed: %s", ftdi_get_error_string(&ftdic));
755+
rc = ftdi_set_bitmode(&ftdic, PINS_OUTPUT, BITMODE_SYNCBB);
756+
if (rc < 0) {
757+
SPI_ERR("FTDI: set synchronous bitbang mode failed: [%d] %s", rc, ftdi_get_error_string(&ftdic));
732758
goto open_err;
733759
}
734760

@@ -912,6 +938,8 @@ void spi_output_stats(void)
912938

913939
int spi_close(void)
914940
{
941+
int rc;
942+
915943
LOG(DEBUG, "spi_nrefs=%d, spi_dev_open=%d", spi_nrefs, spi_dev_open);
916944

917945
if (spi_dev_open) {
@@ -926,14 +954,16 @@ int spi_close(void)
926954
ftdi_out_buf_offset = 0;
927955
}
928956

929-
if (ftdi_set_bitmode(&ftdic, 0, BITMODE_RESET) < 0) {
930-
SPI_ERR("FTDI: reset bitmode failed: %s",
957+
rc = ftdi_set_bitmode(&ftdic, 0, BITMODE_RESET);
958+
if (rc < 0) {
959+
SPI_ERR("FTDI: reset bitmode failed: [%d] %s", rc,
931960
ftdi_get_error_string(&ftdic));
932961
return -1;
933962
}
934963

935-
if (ftdi_usb_close(&ftdic) < 0) {
936-
SPI_ERR("FTDI: close failed: %s",
964+
rc = ftdi_usb_close(&ftdic);
965+
if (rc < 0) {
966+
SPI_ERR("FTDI: close failed: [%d] %s", rc,
937967
ftdi_get_error_string(&ftdic));
938968
return -1;
939969
}

0 commit comments

Comments
 (0)