Merge branch 'master' of https://github.com/ZhiyuanYuanNJ/openFPGALoader
This commit is contained in:
commit
32435dfd7d
|
|
@ -131,10 +131,10 @@ static std::map <std::string, target_board_t> board_list = {
|
|||
JTAG_BOARD("colorlight-i5", "", "cmsisdap", 0, 0, CABLE_DEFAULT),
|
||||
JTAG_BOARD("colorlight-i9", "", "cmsisdap", 0, 0, CABLE_DEFAULT),
|
||||
JTAG_BOARD("colorlight-i9+", "xc7a50tfgg484", "", 0, 0, CABLE_DEFAULT),
|
||||
JTAG_BOARD("crosslinknx_evn", "", "ft2232", 0, 0, CABLE_DEFAULT),
|
||||
JTAG_BOARD("certusnx_versa_evn", "", "ft2232", 0, 0, CABLE_DEFAULT),
|
||||
JTAG_BOARD("certuspronx_evn", "", "ft2232", 0, 0, CABLE_DEFAULT),
|
||||
JTAG_BOARD("certuspronx_versa_evn", "", "ft2232", 0, 0, CABLE_DEFAULT),
|
||||
JTAG_BOARD("crosslinknx_evn", "", "ft2232", 0, 0, CABLE_MHZ(1)),
|
||||
JTAG_BOARD("certusnx_versa_evn", "", "ft2232", 0, 0, CABLE_MHZ(1)),
|
||||
JTAG_BOARD("certuspronx_evn", "", "ft2232", 0, 0, CABLE_MHZ(1)),
|
||||
JTAG_BOARD("certuspronx_versa_evn", "", "ft2232", 0, 0, CABLE_MHZ(1)),
|
||||
JTAG_BOARD("cyc1000", "10cl025256", "ft2232", 0, 0, CABLE_DEFAULT),
|
||||
JTAG_BOARD("c10lp-refkit", "10cl055484", "ft2232", 0, 0, CABLE_DEFAULT),
|
||||
JTAG_BOARD("de0", "", "usb-blaster",0, 0, CABLE_DEFAULT),
|
||||
|
|
@ -160,7 +160,7 @@ static std::map <std::string, target_board_t> board_list = {
|
|||
SPI_BOARD("gatemate_evb_spi", "colognechip", "gatemate_evb_spi",
|
||||
DBUS4, DBUS5, CBUS0, DBUS3, DBUS0, DBUS1, DBUS2, 0, 0, CABLE_DEFAULT),
|
||||
JTAG_BOARD("genesys2", "xc7k325tffg900", "digilent_b", 0, 0, CABLE_DEFAULT),
|
||||
JTAG_BOARD("gr740-mini", "", "ft4232hp_b", 0, 0, CABLE_DEFAULT),
|
||||
JTAG_BOARD("gr740-mini", "", "ft4232hp_b", 0, 0, CABLE_MHZ(1)),
|
||||
JTAG_BOARD("hseda-xc6slx16", "xc6slx16ftg256", "", 0, 0, CABLE_DEFAULT),
|
||||
/* most ice40 boards uses the same pinout */
|
||||
SPI_BOARD("ice40_generic", "lattice", "ft2232",
|
||||
|
|
|
|||
50
src/dfu.cpp
50
src/dfu.cpp
|
|
@ -326,7 +326,7 @@ int DFU::searchDFUDevices()
|
|||
}
|
||||
} else if (_debug) {
|
||||
char mess[256];
|
||||
sprintf(mess,"Unable to open device: "
|
||||
snprintf(mess, 256, "Unable to open device: "
|
||||
"%04x:%04x (bus %d, device %2d) Error: %s -> skip\n",
|
||||
desc.idVendor, desc.idProduct,
|
||||
libusb_get_bus_number(usb_dev),
|
||||
|
|
@ -358,23 +358,35 @@ int DFU::searchIfDFU(struct libusb_device_handle *handle,
|
|||
/* configuration interface iteration */
|
||||
for (int if_idx=0; if_idx < cfg->bNumInterfaces; if_idx++) {
|
||||
const struct libusb_interface *uif = &cfg->interface[if_idx];
|
||||
std::vector<struct dfu_dev> dfu_dev_tmp;
|
||||
struct dfu_desc *dfu_desc;
|
||||
bool dfu_found = false;
|
||||
|
||||
/* altsettings interation */
|
||||
for (int intf_idx = 0; intf_idx < uif->num_altsetting; intf_idx++) {
|
||||
const struct libusb_interface_descriptor *intf = &uif->altsetting[intf_idx];
|
||||
uint8_t intfClass = intf->bInterfaceClass;
|
||||
uint8_t intfSubClass = intf->bInterfaceSubClass;
|
||||
if (_altsetting != -1 && _altsetting != intf_idx)
|
||||
continue;
|
||||
if (intfClass == 0xfe && intfSubClass == 0x01) {
|
||||
struct dfu_dev my_dev;
|
||||
if (_verbose)
|
||||
printInfo("DFU found");
|
||||
|
||||
/* dfu functional descriptor */
|
||||
/* not all DFU implementations provides a descriptor per altsettings
|
||||
* so don't stop directly.
|
||||
*/
|
||||
if (parseDFUDescriptor(intf, reinterpret_cast<uint8_t *>(&my_dev.dfu_desc),
|
||||
sizeof(my_dev.dfu_desc)) != 0)
|
||||
continue; // not compatible
|
||||
sizeof(my_dev.dfu_desc))) {
|
||||
dfu_desc = &my_dev.dfu_desc;
|
||||
dfu_found = true;
|
||||
}
|
||||
/* this altsetting is a DFU interface:
|
||||
* - if user has selected one altsetting current is only stored if it match
|
||||
* - otherwise all are stored
|
||||
*/
|
||||
if (_altsetting != -1 && _altsetting != intf_idx)
|
||||
continue;
|
||||
my_dev.vid = desc->idVendor;
|
||||
my_dev.pid = desc->idProduct;
|
||||
my_dev.altsettings = intf_idx;
|
||||
|
|
@ -397,9 +409,22 @@ int DFU::searchIfDFU(struct libusb_device_handle *handle,
|
|||
|
||||
int r = libusb_get_port_numbers(dev, my_dev.path, sizeof(my_dev.path));
|
||||
my_dev.path[r] = '\0';
|
||||
dfu_dev.push_back(my_dev);
|
||||
dfu_dev_tmp.push_back(my_dev);
|
||||
}
|
||||
}
|
||||
|
||||
/* At least one altsetting has a DFU descriptor */
|
||||
if (dfu_found) {
|
||||
/* with tinyDFU only one (the first) altsetting contains a descriptor
|
||||
* fill others with this information
|
||||
*/
|
||||
for (struct dfu_dev &d: dfu_dev_tmp) {
|
||||
if (d.dfu_desc.bDescriptorType == 0)
|
||||
memcpy(&d.dfu_desc, dfu_desc, sizeof(struct dfu_desc));
|
||||
}
|
||||
std::move(dfu_dev_tmp.begin(), dfu_dev_tmp.end(), std::back_inserter(dfu_dev));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
libusb_free_config_descriptor(cfg);
|
||||
|
|
@ -413,24 +438,29 @@ int DFU::searchIfDFU(struct libusb_device_handle *handle,
|
|||
* Since libusb has no support for those structure
|
||||
* fill a custom structure
|
||||
*/
|
||||
int DFU::parseDFUDescriptor(const struct libusb_interface_descriptor *intf,
|
||||
bool DFU::parseDFUDescriptor(const struct libusb_interface_descriptor *intf,
|
||||
uint8_t *dfu_desc, int dfu_desc_size)
|
||||
{
|
||||
const uint8_t *extra = intf->extra;
|
||||
int extra_len = intf->extra_length;
|
||||
|
||||
/* not all altsettings for a DFU device have a DFU descriptor
|
||||
* set to 0 to be able to detect a missing descriptor
|
||||
*/
|
||||
memset(dfu_desc, 0, 9);
|
||||
|
||||
if (extra_len < 9)
|
||||
return -1;
|
||||
return false;
|
||||
|
||||
/* map memory to structure */
|
||||
for (int j = 0; j + 1 < extra_len; j++) {
|
||||
if (extra[j+1] == 0x21) {
|
||||
memcpy(dfu_desc, (const void *)&extra[j], dfu_desc_size);
|
||||
break;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* abstraction to send/receive to control */
|
||||
|
|
|
|||
|
|
@ -206,9 +206,9 @@ class DFU {
|
|||
* \param[in] intf: interface descriptor with extra area
|
||||
* \param[out] dfu_desc: DFU descriptor
|
||||
* \param[in] dfu_desc_size: DFU descriptor structure size
|
||||
* \return -1 if extra len is too small, 0 otherwise
|
||||
* \return false if extra len is too small, true otherwise
|
||||
* */
|
||||
int parseDFUDescriptor(const struct libusb_interface_descriptor *intf,
|
||||
bool parseDFUDescriptor(const struct libusb_interface_descriptor *intf,
|
||||
uint8_t *dfu_desc, int dfu_desc_size);
|
||||
/*!
|
||||
* \brief try to open device specified by vid and pid. If found
|
||||
|
|
|
|||
|
|
@ -878,7 +878,7 @@ bool FTDIpp_MPSSE::search_with_dev(const string &device)
|
|||
usbdeviceparent, "busnum"), 10));
|
||||
_addr = static_cast<uint8_t>(udevstufftoint(udev_device_get_sysattr_value(
|
||||
usbdeviceparent, "devnum"), 10));
|
||||
sprintf(_product, "%s", udev_device_get_sysattr_value(usbdeviceparent, "product"));
|
||||
snprintf(_product, 64, "%s", udev_device_get_sysattr_value(usbdeviceparent, "product"));
|
||||
_vid = udevstufftoint(
|
||||
udev_device_get_sysattr_value(usbdeviceparent, "idVendor"), 16);
|
||||
_pid = udevstufftoint(udev_device_get_sysattr_value(
|
||||
|
|
|
|||
|
|
@ -883,8 +883,19 @@ void Gowin::sendClkUs(unsigned us)
|
|||
bool Gowin::eraseSRAM()
|
||||
{
|
||||
printInfo("Erase SRAM ", false);
|
||||
uint32_t status = readStatusReg();
|
||||
if (_verbose)
|
||||
displayReadReg("before erase sram", readStatusReg());
|
||||
displayReadReg("before erase sram", status);
|
||||
|
||||
// If flash is invalid, send extra cmd 0x3F before SRAM erase
|
||||
// This is required on GW5A-25
|
||||
bool auto_boot_2nd_fail = (status & 0x8) >> 3;
|
||||
if ((_idcode == 0x0001281B) && auto_boot_2nd_fail)
|
||||
{
|
||||
disableCfg();
|
||||
send_command(0x3F);
|
||||
send_command(NOOP);
|
||||
}
|
||||
|
||||
if (!enableCfg()) {
|
||||
printError("FAIL");
|
||||
|
|
|
|||
|
|
@ -1080,7 +1080,8 @@ void Lattice::displayReadReg(uint64_t dev)
|
|||
err = (dev >> 23)&0x07;
|
||||
}
|
||||
|
||||
printf("\t");
|
||||
printf("\tBSE Error Code\n");
|
||||
printf("\t\t");
|
||||
switch (err) {
|
||||
case 0:
|
||||
printf("No err\n");
|
||||
|
|
@ -1106,8 +1107,17 @@ void Lattice::displayReadReg(uint64_t dev)
|
|||
case 7:
|
||||
printf("SDM EOF\n");
|
||||
break;
|
||||
case 8:
|
||||
printf("Authentication ERR\n");
|
||||
break;
|
||||
case 9:
|
||||
printf("Authentication Setup ERR\n");
|
||||
break;
|
||||
case 10:
|
||||
printf("Bitstream Engine Timeout ERR\n");
|
||||
break;
|
||||
default:
|
||||
printf("unknown %x\n", err);
|
||||
printf("unknown error: %x\n", err);
|
||||
}
|
||||
|
||||
if (_fpga_family == NEXUS_FAMILY) {
|
||||
|
|
@ -1164,7 +1174,7 @@ void Lattice::displayReadReg(uint64_t dev)
|
|||
printf("Bitstream Engine Timeout ERR\n");
|
||||
break;
|
||||
default:
|
||||
printf("unknown %x\n", err);
|
||||
printf("unknown error: %x\n", err);
|
||||
}
|
||||
if ((dev >> 38) & 0x01) printf("\tBypass Mode\n");
|
||||
if ((dev >> 39) & 0x01) printf("\tFlow Through Mode\n");
|
||||
|
|
|
|||
|
|
@ -68,7 +68,8 @@ int LatticeBitParser::parseHeader()
|
|||
printError("Preamble key not found");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if ((uint8_t)_raw_data[pos-1] != 0xbd && (uint8_t)_raw_data[pos-1] != 0xbf) {
|
||||
//0xbe is the key for encrypted bitstreams in Nexus fpgas
|
||||
if ((uint8_t)_raw_data[pos-1] != 0xbd && (uint8_t)_raw_data[pos-1] != 0xbf && (uint8_t)_raw_data[pos-1] != 0xbe) {
|
||||
printError("Wrong preamble key");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
|
@ -98,7 +99,8 @@ int LatticeBitParser::parse()
|
|||
|
||||
/* check preamble */
|
||||
uint32_t preamble = (*(uint32_t *)&_raw_data[_endHeader+1]);
|
||||
if ((preamble != 0xb3bdffff) && (preamble != 0xb3bfffff)) {
|
||||
//0xb3beffff is the preamble for encrypted bitstreams in Nexus fpgas
|
||||
if ((preamble != 0xb3bdffff) && (preamble != 0xb3bfffff) && (preamble != 0xb3beffff)) {
|
||||
printError("Error: missing preamble\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -286,6 +286,20 @@ static std::map <uint32_t, flash_t> flash_list = {
|
|||
.bp_len = 4,
|
||||
.bp_offset = {(1 << 2), (1 << 3), (1 << 4), (1 << 5)}}
|
||||
},
|
||||
{0xc22016, {
|
||||
/* https://www.macronix.com/Lists/Datasheet/Attachments/8933/MX25L3233F,%203V,%2032Mb,%20v1.7.pdf */
|
||||
.manufacturer = "Macronix",
|
||||
.model = "MX25L3233F",
|
||||
.nr_sector = 256,
|
||||
.sector_erase = true,
|
||||
.subsector_erase = true,
|
||||
.has_extended = false,
|
||||
.tb_otp = true,
|
||||
.tb_offset = (1 << 3),
|
||||
.tb_register = CONFR,
|
||||
.bp_len = 5,
|
||||
.bp_offset = {(1 << 2), (1 << 3), (1 << 4), (1 << 5)}}
|
||||
},
|
||||
{0xc22018, {
|
||||
/* https://www.macronix.com/Lists/Datasheet/Attachments/8934/MX25L12833F,%203V,%20128Mb,%20v1.0.pdf */
|
||||
.manufacturer = "Macronix",
|
||||
|
|
|
|||
|
|
@ -99,7 +99,8 @@ int XVC_client::writeTMS(const uint8_t *tms, uint32_t len, bool flush_buffer,
|
|||
// buffer full -> write
|
||||
if (_num_bits == _buffer_size * 8) {
|
||||
// write
|
||||
ll_write(NULL);
|
||||
if(!ll_write(NULL))
|
||||
throw std::runtime_error("xvc ll_write fails");
|
||||
_num_bits = 0;
|
||||
}
|
||||
|
||||
|
|
@ -147,7 +148,8 @@ int XVC_client::writeTDI(const uint8_t *tx, uint8_t *rx, uint32_t len, bool end)
|
|||
uint16_t idx = _num_bits - 1;
|
||||
_tms[(idx >> 3)] |= (1 << (idx & 0x07));
|
||||
}
|
||||
ll_write((rx) ? rx_ptr : NULL); // write
|
||||
if(!ll_write((rx) ? rx_ptr : NULL)) // write
|
||||
throw std::runtime_error("xvc ll_write fails");
|
||||
|
||||
tx_ptr += tt;
|
||||
if (rx)
|
||||
|
|
@ -184,7 +186,8 @@ int XVC_client::toggleClk(uint8_t tms, uint8_t tdi, uint32_t clk_len)
|
|||
if (len < _num_bits)
|
||||
_num_bits = len;
|
||||
len -= _num_bits;
|
||||
ll_write(NULL);
|
||||
if(!ll_write(NULL))
|
||||
throw std::runtime_error("xvc ll_write fails");
|
||||
} while (len > 0);
|
||||
|
||||
return clk_len;
|
||||
|
|
@ -242,6 +245,23 @@ bool XVC_client::open_connection(const string &ip_addr)
|
|||
return true;
|
||||
}
|
||||
|
||||
static
|
||||
int sendall(int sock, const void* raw, size_t cnt, int flags)
|
||||
{
|
||||
const char *buf = (const char*)raw;
|
||||
size_t remaining = cnt;
|
||||
while (remaining) {
|
||||
ssize_t ret = send(sock, buf, remaining, flags);
|
||||
if (ret==0) // should not happen on Linux for a TCP socket
|
||||
throw std::logic_error("platform TCP send() returns zero?!?");
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
buf += ret;
|
||||
remaining -= ret;
|
||||
}
|
||||
return cnt; // success
|
||||
}
|
||||
|
||||
ssize_t XVC_client::xfer_pkt(const string &instr,
|
||||
const uint8_t *tx, uint32_t tx_size,
|
||||
uint8_t *rx, uint32_t rx_size)
|
||||
|
|
@ -249,13 +269,13 @@ ssize_t XVC_client::xfer_pkt(const string &instr,
|
|||
ssize_t len = tx_size;
|
||||
|
||||
/* 1. instruction */
|
||||
if (send(_sock, instr.c_str(), instr.size(), 0) == -1) {
|
||||
if (sendall(_sock, instr.c_str(), instr.size(), 0) == -1) {
|
||||
printError("Send instruction failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (tx) {
|
||||
if (send(_sock, tx, tx_size, 0) == -1) {
|
||||
if (sendall(_sock, tx, tx_size, 0) == -1) {
|
||||
printError("Send error");
|
||||
return -1;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue