Merge pull request #423 from jgroman/master
Add faulty MPSEE cmd 8E workaround
This commit is contained in:
commit
f9c1aa4eed
|
|
@ -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<uint8_t>(0x8f), 0, 0};
|
||||
while (len) {
|
||||
unsigned int chunk = len;
|
||||
|
|
|
|||
|
|
@ -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) */
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue