From bddfe9799752e819561734c08058e7e02965ad9c Mon Sep 17 00:00:00 2001 From: Andrew Dennison Date: Mon, 29 May 2023 11:19:12 +1000 Subject: [PATCH 1/4] jlink: suport writeTDI() with tx=NULL fixes crash and is consistent with other jtag cables --- src/jlink.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/jlink.cpp b/src/jlink.cpp index af55a2b..4df3679 100644 --- a/src/jlink.cpp +++ b/src/jlink.cpp @@ -137,7 +137,10 @@ int Jlink::writeTDI(uint8_t *tx, uint8_t *rx, uint32_t len, bool end) xfer_len = len - rest; // reduce xfer len uint16_t tt = (xfer_len + 7) >> 3; // convert to Byte memset(_tms, tms, tt); // fill tms buffer - memcpy(_tdi, tx_ptr, tt); // fill tdi buffer + if (tx) + memcpy(_tdi, tx_ptr, tt); // fill tdi buffer + else + memset(_tdi, 0, tt); // clear tdi buffer _num_bits = xfer_len; // set buffer size in bit if (end && xfer_len + rest == len) { // last sequence: set tms 1 _last_tms = 1; From 23d65823aa82a96325f77f195dfcf7bc595f4ca5 Mon Sep 17 00:00:00 2001 From: Andrew Dennison Date: Mon, 29 May 2023 11:21:08 +1000 Subject: [PATCH 2/4] jlink: report skipped devices with verbose --- src/jlink.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/jlink.cpp b/src/jlink.cpp index 4df3679..b231bfe 100644 --- a/src/jlink.cpp +++ b/src/jlink.cpp @@ -50,8 +50,11 @@ Jlink::Jlink(uint32_t clkHz, int8_t verbose, int vid = VID, int pid = PID):_base throw std::runtime_error("libusb init failed\n"); // search for all compatible devices - if (!jlink_scan_usb(vid,pid)) + if (!jlink_scan_usb(vid,pid)) { + if (_verbose) + printf("vid:pid %04x:%04x\n", vid, pid); throw std::runtime_error("can't find compatible device"); + } // get device capacity if (!get_caps()) @@ -680,8 +683,13 @@ bool Jlink::jlink_scan_usb(int vid, int pid) return EXIT_FAILURE; } - if (desc.idProduct != pid || desc.idVendor != vid) + if (desc.idVendor != vid) continue; + if (desc.idProduct != pid) { + if (_verbose) + cerr << "skip pid" << hex << desc.idProduct << dec << endl; + continue; + } if (_verbose) printf("%04x:%04x (bus %d, device %2d)\n", From ec82dd646736ebf05f3bde407a5c67a3d4f848ba Mon Sep 17 00:00:00 2001 From: Andrew Dennison Date: Mon, 29 May 2023 11:22:33 +1000 Subject: [PATCH 3/4] jlink: support J-Link BASE and J-Trace PRO --- doc/cable.yml | 6 ++++++ src/cable.hpp | 2 ++ src/jlink.hpp | 9 +++++++-- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/doc/cable.yml b/doc/cable.yml index 27c049c..7452162 100644 --- a/doc/cable.yml +++ b/doc/cable.yml @@ -182,6 +182,12 @@ jlink: Description: SEGGER J-Link Debug Probes URL: https://www.segger.com/products/debug-probes/j-link + - Name: jlink_base + Description: SEGGER J-Link BASE Debug Probes + + - Name: jtrace_pro + Description: SEGGER J-Trace PRO Debug Probes + jtag-smt2-nc: diff --git a/src/cable.hpp b/src/cable.hpp index 30c3c95..7dcba63 100644 --- a/src/cable.hpp +++ b/src/cable.hpp @@ -107,6 +107,8 @@ static std::map cable_list = { {"ft4232", FTDI_SER(0x0403, 0x6011, FTDI_INTF_A, 0x08, 0x0B, 0x08, 0x0B)}, {"ecpix5-debug", FTDI_SER(0x0403, 0x6010, FTDI_INTF_A, 0xF8, 0xFB, 0xFF, 0xFF)}, {"jlink", CABLE_DEF(MODE_JLINK, 0x1366, 0x0105 )}, + {"jlink_base", CABLE_DEF(MODE_JLINK, 0x1366, 0x0101 )}, + {"jtrace_pro", CABLE_DEF(MODE_JLINK, 0x1366, 0x1020 )}, {"jtag-smt2-nc", FTDI_SER(0x0403, 0x6014, FTDI_INTF_A, 0xe8, 0xeb, 0x00, 0x60)}, {"lpc-link2", CMSIS_CL(0x1fc9, 0x0090 )}, {"orbtrace", CMSIS_CL(0x1209, 0x3443 )}, diff --git a/src/jlink.hpp b/src/jlink.hpp index 73ac7c0..99054f3 100644 --- a/src/jlink.hpp +++ b/src/jlink.hpp @@ -118,11 +118,16 @@ class Jlink: public JtagInterface { }; // JLink hardware type - const std::string jlink_hw_type[4] = { + const std::string jlink_hw_type[9] = { "J-Link", "J-Trace", "Flasher", - "J-Link Pro" + "J-Link Pro", + "", + "", + "", + "", + "J-Trace Pro" }; // Jlink configuration structure From 87b17ed9bfae0f805d2c7a95776b825c0d79cff6 Mon Sep 17 00:00:00 2001 From: Andrew Dennison Date: Thu, 1 Jun 2023 11:05:26 +1000 Subject: [PATCH 4/4] efinix: support using JTAG interfaces --- doc/vendors/efinix.rst | 24 ++++++++++++++++++++++++ src/efinix.cpp | 17 +++++++++++++---- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/doc/vendors/efinix.rst b/doc/vendors/efinix.rst index 8fe30dc..a47115b 100644 --- a/doc/vendors/efinix.rst +++ b/doc/vendors/efinix.rst @@ -25,3 +25,27 @@ or, for xyloni board Since openFPGALoader access the flash directly in SPI mode the ``-b fireant``, ``-b xyloni_spi`` is required (no autodetection possible). + +Trion and Titanium JTAG usage +========================================== + +*openFPGALoader* supports loading to RAM and SPI Flash with JTAG + +Tested with J-Link BASE + +bin file load +------------- + +.. code-block:: bash + + openFPGALoader --cable jlink_base -m /somewhere/project/outflow/*.bin + +hex file flash +------------- + +Example for ti60f225. +NOTE: JTAG chains with more than one device (eg --index-chain) are currently not supported for writing to SPI flash + +.. code-block:: bash + + openFPGALoader --cable jlink_base --fpga-part ti60f225 -f /somewhere/project/outflow/*.hex \ No newline at end of file diff --git a/src/efinix.cpp b/src/efinix.cpp index 6c6db3d..9436fd9 100644 --- a/src/efinix.cpp +++ b/src/efinix.cpp @@ -88,7 +88,7 @@ Efinix::Efinix(Jtag* jtag, const std::string &filename, } else if (board_name == "titanium_ti60_f225_jtag") { spi_board_name = "titanium_ti60_f225"; } else { - printInfo("Using efinix JTAG interface (no GPIO)"); + init_common(prg_type); return; } @@ -116,8 +116,10 @@ Efinix::Efinix(Jtag* jtag, const std::string &filename, void Efinix::init_common(const Device::prog_type_t &prg_type) { - _spi->gpio_set_input(_done_pin); - _spi->gpio_set_output(_rst_pin | _oe_pin); + if (_spi) { + _spi->gpio_set_input(_done_pin); + _spi->gpio_set_output(_rst_pin | _oe_pin); + } switch (prg_type) { case Device::WR_FLASH: @@ -142,8 +144,10 @@ Efinix::~Efinix() void Efinix::reset() { - if (!_spi) // not supported + if (!_spi) { + printError("jtag: reset not supported"); return; + } uint32_t timeout = 1000; _spi->gpio_clear(_rst_pin | _oe_pin); usleep(1000); @@ -218,6 +222,11 @@ void Efinix::program(unsigned int offset, bool unprotect_flash) bool Efinix::dumpFlash(uint32_t base_addr, uint32_t len) { + if (!_spi) { + printError("jtag: dumpFlash not supported"); + return false; + } + uint32_t timeout = 1000; _spi->gpio_clear(_rst_pin);