From 33eaf588697e5543a87a3cde6581e0baae141b78 Mon Sep 17 00:00:00 2001 From: jgroman Date: Sat, 27 Jan 2024 13:02:46 +0100 Subject: [PATCH] Add faulty MPSEE cmd 8E workaround --- src/ftdiJtagMPSSE.cpp | 11 +++++++++-- src/ftdiJtagMPSSE.hpp | 1 + src/ftdipp_mpsse.cpp | 26 ++++++++++++++++++++++++++ src/ftdipp_mpsse.hpp | 2 ++ 4 files changed, 38 insertions(+), 2 deletions(-) diff --git a/src/ftdiJtagMPSSE.cpp b/src/ftdiJtagMPSSE.cpp index 4af3172..0291fd8 100644 --- a/src/ftdiJtagMPSSE.cpp +++ b/src/ftdiJtagMPSSE.cpp @@ -34,6 +34,7 @@ FtdiJtagMPSSE::FtdiJtagMPSSE(const cable_t &cable, const string &dev, const string &serial, uint32_t clkHZ, bool invert_read_edge, int8_t verbose): FTDIpp_MPSSE(cable, dev, serial, clkHZ, verbose), _ch552WA(false), + _cmd8EWA(false), _write_mode(MPSSE_WRITE_NEG), // always write on neg edge _read_mode(0), _invert_read_edge(invert_read_edge), // false: pos, true: neg @@ -73,6 +74,12 @@ void FtdiJtagMPSSE::init_internal(const mpsse_bit_config &cable) _ch552WA = true; } + // This Sipeed firmware does not support MPSEE 0x8E, 0x8F commands properly + if ( (!strncmp((const char *)_imanufacturer, "SIPEED", 6)) + && (!strncmp((const char *)_iserialnumber, "2023112818", 10)) ) { + _cmd8EWA = true; + } + display("%x\n", cable.bit_low_val); display("%x\n", cable.bit_low_dir); display("%x\n", cable.bit_high_val); @@ -174,8 +181,8 @@ int FtdiJtagMPSSE::toggleClk(uint8_t tms, uint8_t tdi, uint32_t clk_len) * with 2232H, 4242H & 232H */ - if (_ftdi->type == TYPE_2232H || _ftdi->type == TYPE_4232H || - _ftdi->type == TYPE_232H) { + if ((_ftdi->type == TYPE_2232H || _ftdi->type == TYPE_4232H || + _ftdi->type == TYPE_232H) && !_cmd8EWA) { uint8_t buf[] = {static_cast(0x8f), 0, 0}; while (len) { unsigned int chunk = len; diff --git a/src/ftdiJtagMPSSE.hpp b/src/ftdiJtagMPSSE.hpp index 323f647..10b1065 100644 --- a/src/ftdiJtagMPSSE.hpp +++ b/src/ftdiJtagMPSSE.hpp @@ -106,6 +106,7 @@ class FtdiJtagMPSSE : public JtagInterface, public FTDIpp_MPSSE { */ void config_edge(); bool _ch552WA; /* avoid errors with SiPeed tangNano */ + bool _cmd8EWA; /* avoid errors with Sipeed FT2232H emulation */ uint8_t _write_mode; /**< write edge configuration */ uint8_t _read_mode; /**< read edge configuration */ bool _invert_read_edge; /**< read edge selection (false: pos, true: neg) */ diff --git a/src/ftdipp_mpsse.cpp b/src/ftdipp_mpsse.cpp index 197114e..10bcef1 100644 --- a/src/ftdipp_mpsse.cpp +++ b/src/ftdipp_mpsse.cpp @@ -91,6 +91,32 @@ FTDIpp_MPSSE::FTDIpp_MPSSE(const cable_t &cable, const string &dev, printWarn(err); memset(_iproduct,'\0', 200); } + + ret = (libusb_error)libusb_get_string_descriptor_ascii(_ftdi->usb_dev, + usb_desc.iManufacturer, _imanufacturer, 200); + /* when FTDI device has no iManufacturer, libusb returns an error + * but there is no distinction between real error and empty field + */ + if (ret < 0) { + snprintf(err, sizeof(err), + "Can't read iManufacturer field from FTDI: " + "considered as empty string"); + printWarn(err); + memset(_imanufacturer,'\0', 200); + } + + ret = (libusb_error)libusb_get_string_descriptor_ascii(_ftdi->usb_dev, + usb_desc.iSerialNumber, _iserialnumber, 200); + /* when FTDI device has no iSerialNumber, libusb returns an error + * but there is no distinction between real error and empty field + */ + if (ret < 0) { + snprintf(err, sizeof(err), + "Can't read iSerialNumber field from FTDI: " + "considered as empty string"); + printWarn(err); + memset(_iserialnumber,'\0', 200); + } } FTDIpp_MPSSE::~FTDIpp_MPSSE() diff --git a/src/ftdipp_mpsse.hpp b/src/ftdipp_mpsse.hpp index 43547ad..defa4f7 100644 --- a/src/ftdipp_mpsse.hpp +++ b/src/ftdipp_mpsse.hpp @@ -81,6 +81,8 @@ class FTDIpp_MPSSE { int _num; unsigned char *_buffer; uint8_t _iproduct[200]; + uint8_t _imanufacturer[200]; + uint8_t _iserialnumber[200]; }; #endif