Compare commits

...

46 Commits

Author SHA1 Message Date
Gwenhael Goavec-Merou 78ab322615
Merge pull request #645 from ND-00/patch-1
add Adesto AT25DF321A support
2026-04-09 16:19:10 +02:00
ND-00 570b790aee
add Adesto AT25DF321A support
Add Adesto AT25DF321A (JEDEC 0x1f4701). Tested on GW2A-LV18QN144 with ft2232. Previously detected as unknown, unprotect failed. Fixed with bp_len=3 and global_lock=false.
2026-04-09 15:51:30 +03:00
Gwenhael Goavec-Merou daa8f26b66 altera: fix 64 bits hex display (PRIx64) 2026-04-08 17:31:39 +02:00
Gwenhael Goavec-Merou 2030920dd8 boards: Terasic Atum A3-Nano 2026-04-08 17:09:24 +02:00
Gwenhael Goavec-Merou ce8db7326c board: added Arrow AXE5000 (Altera Agilex 5 A5EC008BM16AE6S) 2026-04-08 17:06:44 +02:00
Gwenhael Goavec-Merou ae6f159765 doc/FPGAs: added Agilex 3/5 entries 2026-04-08 17:03:49 +02:00
Gwenhael Goavec-Merou f0ceffb46e part: added Agilex3 A3CZ135 2026-04-08 17:02:36 +02:00
Gwenhael Goavec-Merou 9833c7ee0b part: added Agilex5 A5EC008B 2026-04-08 17:02:16 +02:00
Gwenhael Goavec-Merou 764ce23f35 altera: agilex3/agilex5 support draft (memory only) 2026-04-08 16:51:45 +02:00
Gwenhael Goavec-Merou add9c95775 cable.hpp: fix ACBUS direction/value for usb-blasterIII 2026-04-07 16:15:58 +02:00
Gwenhael Goavec-Merou b0ff3b517c latticeBitParser: fix previous commit 2026-04-06 17:31:48 +02:00
Gwenhael Goavec-Merou b4bfad4b1c latticeBitParser: check file size during parse. Improved a bit parsing speed 2026-04-06 17:22:02 +02:00
Gwenhael Goavec-Merou 816d6558fe dfuFileParser: nitpick 2026-04-03 10:33:12 +02:00
Gwenhael Goavec-Merou 771b75aade mcsParser: added guard to avoir bound check failures. Improved code speed with c++17 2026-04-03 10:01:28 +02:00
Gwenhael Goavec-Merou 13c505ccc7 colognechip: fix -Wshift-op-parentheses warning 2026-04-03 07:48:50 +02:00
Gwenhael Goavec-Merou a56b9f61ca pofParser: added bound check tests 2026-04-01 10:58:22 +02:00
Gwenhael Goavec-Merou ff9e10085a pofParser: ARRAY2INT32: must be casted to uin32_t not uint16_t 2026-04-01 10:32:38 +02:00
Gwenhael Goavec-Merou 63c97410b6 bitparser.cpp: parserHeader. Added bound check and simplied type A
parsing
2026-04-01 10:17:59 +02:00
Gwenhael Goavec-Merou 3429d34a30
Merge pull request #642 from kjellpeterson-shotover/master
add support for MT25QU512 flash
2026-03-31 08:35:07 +02:00
Kjell Peterson ed5abef84f add support for MT25QU512 flash 2026-03-30 16:39:06 -06:00
Gwenhael Goavec-Merou fe1c2e669e fsparser.cpp: fixed idcode for GW1N(R/Z)-2x 2026-03-25 16:56:44 +01:00
Gwenhael Goavec-Merou 09812831ad
Merge pull request #639 from embicasGmbH/master
spiOverJtag: Add support for xcau10p
2026-03-25 15:46:25 +01:00
fllu 80c867d544 spiOverJtag: Add support for xcau10p 2026-03-25 15:29:39 +01:00
Gwenhael Goavec-Merou 9eeae91ab0
Merge pull request #638 from pu-cc/gatemate-a2-jtagbypass
src/colognechip.cpp: allow jtag-spi-bypass for A2
2026-03-25 10:22:55 +01:00
Gwenhael Goavec-Merou b84e319298
Merge pull request #637 from EmmanuelP/patch-1
Add support for Altera MAX10 10M16D IdCode:0x31030dd
2026-03-25 10:20:53 +01:00
Patrick Urban 8c397bd325 gatemate: allow jtag-spi-bypass for A2 2026-03-24 22:07:29 +01:00
Emmanuel Pacaud 1d005289d1 Add memory information for native Altera Max10 10M16D 2026-03-24 12:22:47 +01:00
Emmanuel Pacaud 9d3ba67ffd
Add support for Altera MAX10 10M16D IdCode:0x31030dd 2026-03-23 17:50:02 +01:00
Gwenhael Goavec-Merou 451beadfae main: #ifdef USE_LIBFTDI must be after the if 2026-03-22 15:03:45 +01:00
Gwenhael Goavec-Merou 44ad4df0e7 spiFlashdb: cosmetic/doc 2026-03-22 09:26:03 +01:00
Gwenhael Goavec-Merou 5d615ef993 spiFlashdb: GigaDevice GD25Q32C: typo 2026-03-22 09:16:48 +01:00
Gwenhael Goavec-Merou b3335344e0 spiFlashdb: GigaDevice GD25Q32C 2026-03-22 09:15:06 +01:00
Gwenhael Goavec-Merou a6a573f085 CMakeLists, all: removed epcqx class 2026-03-21 08:01:49 +01:00
Gwenhael Goavec-Merou 1ff73f3650 SPIInterface -> FlashInterface 2026-03-21 07:59:18 +01:00
Gwenhael Goavec-Merou 09838fa825 CMakeLists.txt, main: removed USE_DEVICE_ARG usage. Now --device/-d is always available 2026-03-20 15:14:19 +01:00
Gwenhael Goavec-Merou 4687fe3467 CMakeLists.txt: switch to c++17 (round two) 2026-03-18 15:44:07 +01:00
Gwenhael Goavec-Merou 9b1c568659 all/everything/world: removed using namespace std to be able to compile in c++17 with windows 2026-03-18 15:28:34 +01:00
Gwenhael Goavec-Merou 40491463bf Revert "CMakeLists.txt: switch to c++17"
This reverts commit 92833930e7.
2026-03-17 19:23:16 +01:00
Gwenhael Goavec-Merou 92833930e7 CMakeLists.txt: switch to c++17 2026-03-17 19:12:07 +01:00
Gwenhael Goavec-Merou ec591a9503
Merge pull request #636 from kevmo314/add-xcku095-support
Add XCKU095 support
2026-03-16 08:32:24 +01:00
Kevin Wang 85d68c4a46
Add XCKU095 support 2026-03-15 22:47:14 -04:00
Gwenhael Goavec-Merou 28efd18798 main,progressBar: --force-terminal-mode argument to force progress bar output as if connected to a terminal (#629) 2026-03-13 09:28:54 +01:00
Gwenhael Goavec-Merou 9d6cc15f51 ftdipp_mpsse: gpio_write: fix test (missing !) 2026-03-13 07:49:29 +01:00
Gwenhael Goavec-Merou c7f65d20b5 ftdipp_mpsse: fix message in setClkFreq 2026-03-13 07:48:14 +01:00
Gwenhael Goavec-Merou bb37f1ed4d dirtyJtag: rework error messages in constructor. Added a method to close USB (and to avoids to have multiple time the same piece of code) 2026-03-12 18:45:25 +01:00
Gwenhael Goavec-Merou 54595299d5 dirtyJtag: doc + nitpick 2026-03-12 18:25:19 +01:00
79 changed files with 1419 additions and 1200 deletions

View File

@ -162,7 +162,7 @@ endif()
#################################################################################################### ####################################################################################################
## specify the C++ standard ## specify the C++ standard
set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True) set(CMAKE_CXX_STANDARD_REQUIRED True)
set(CMAKE_CXX_FLAGS_DEBUG "-g -Wall -Wextra ${CMAKE_CXX_FLAGS_DEBUG}") set(CMAKE_CXX_FLAGS_DEBUG "-g -Wall -Wextra ${CMAKE_CXX_FLAGS_DEBUG}")
if(ENABLE_OPTIM AND NOT(CMAKE_BUILD_TYPE STREQUAL "Debug")) if(ENABLE_OPTIM AND NOT(CMAKE_BUILD_TYPE STREQUAL "Debug"))
@ -337,8 +337,7 @@ endif()
list(APPEND OPENFPGALOADER_SOURCE list(APPEND OPENFPGALOADER_SOURCE
src/bpiFlash.cpp src/bpiFlash.cpp
src/spiFlash.cpp src/spiFlash.cpp
src/spiInterface.cpp src/flashInterface.cpp
src/epcq.cpp
src/jtag.cpp src/jtag.cpp
) )
@ -348,8 +347,7 @@ list(APPEND OPENFPGALOADER_HEADERS
src/jtagInterface.hpp src/jtagInterface.hpp
src/spiFlash.hpp src/spiFlash.hpp
src/spiFlashdb.hpp src/spiFlashdb.hpp
src/epcq.hpp src/flashInterface.hpp
src/spiInterface.hpp
) )
# FTDI Based cables # FTDI Based cables
@ -675,10 +673,6 @@ if (ENABLE_UDEV)
target_link_libraries(openFPGALoader ${LIBUDEV_LIBRARIES}) target_link_libraries(openFPGALoader ${LIBUDEV_LIBRARIES})
endif() endif()
if (ENABLE_UDEV OR ENABLE_LIBGPIOD OR ENABLE_JETSONNANOGPIO)
add_definitions(-DUSE_DEVICE_ARG)
endif(ENABLE_UDEV OR ENABLE_LIBGPIOD OR ENABLE_JETSONNANOGPIO)
if (BUILD_STATIC) if (BUILD_STATIC)
set_target_properties(openFPGALoader PROPERTIES LINK_SEARCH_END_STATIC 1) set_target_properties(openFPGALoader PROPERTIES LINK_SEARCH_END_STATIC 1)
endif() endif()

View File

@ -85,7 +85,7 @@ Gowin:
Flash: EF Flash: EF
Intel: Altera:
- Description: Max II(CPLD) - Description: Max II(CPLD)
Model: EPM240T100C5N Model: EPM240T100C5N
@ -162,6 +162,20 @@ Intel:
Memory: SVF Memory: SVF
Flash: POF Flash: POF
- Description: Agilex 3
Model:
- A3CZ135
URL: https://www.altera.com/products/fpga/agilex/3
Memory: RBF
Flash: NT
- Description: Agilex 5
Model:
- A5EC008B
URL: https://www.altera.com/products/fpga/agilex/5
Memory: RBF
Flash: NT
Lattice: Lattice:

View File

@ -27,6 +27,20 @@
Memory: OK Memory: OK
Flash: OK Flash: OK
- ID: atumA3Nano
Description: Terasic Atum A3 Nano
URL: https://www.terasic.com.tw/cgi-bin/page/archive.pl?Language=English&No=1373
FPGA: Altera Agilex 3 A3CZ135BB18AE7S
Memory: OK
Flash: NT
- ID: axe5000
Description: A5EC008BM16AE6S FPGA Starter Kit
URL: https://www.arrow.com/en/products/axe5000/trenz-electronic-gmbh.html
FPGA: Altera Agilex 5 A5EC008BM16AE6S
Memory: OK
Flash: NT
- ID: litex-acorn-baseboard-mini - ID: litex-acorn-baseboard-mini
Description: The LiteX-Acorn-Baseboards are baseboards developed around the SQRL's Acorn board (or Nite/LiteFury) Description: The LiteX-Acorn-Baseboards are baseboards developed around the SQRL's Acorn board (or Nite/LiteFury)
URL: https://github.com/enjoy-digital/litex-acorn-baseboard/ URL: https://github.com/enjoy-digital/litex-acorn-baseboard/

View File

@ -14,6 +14,7 @@ XILINX_PARTS := xc3s500evq100 \
xcku040-ffva1156 xcku060-ffva1156 \ xcku040-ffva1156 xcku060-ffva1156 \
xcku5p-ffvb676 \ xcku5p-ffvb676 \
xcvu9p-flga2104 xcvu37p-fsvh2892 \ xcvu9p-flga2104 xcvu37p-fsvh2892 \
xcau10p-ffvb676 \
xcau15p-ffvb676 xcau15p-ffvb676
XILINX_BIT_FILES := $(addsuffix .bit.gz,$(addprefix spiOverJtag_, $(XILINX_PARTS))) XILINX_BIT_FILES := $(addsuffix .bit.gz,$(addprefix spiOverJtag_, $(XILINX_PARTS)))

View File

@ -151,6 +151,7 @@ if tool in ["ise", "vivado"]:
"xcvu37p-fsvh2892" : "xcvu37p_fsvh2892", "xcvu37p-fsvh2892" : "xcvu37p_fsvh2892",
"xcku3p-ffva676" : "xcku3p_ffva676", "xcku3p-ffva676" : "xcku3p_ffva676",
"xcku5p-ffvb676" : "xcku5p_ffvb676", "xcku5p-ffvb676" : "xcku5p_ffvb676",
"xcau10p-ffvb676" : "xcau10p_ffvb676",
"xcau15p-ffvb676" : "xcau15p_ffvb676", "xcau15p-ffvb676" : "xcau15p_ffvb676",
}.get(part, pkg_name) }.get(part, pkg_name)
if tool == "ise": if tool == "ise":
@ -212,6 +213,8 @@ if tool in ["ise", "vivado"]:
'paramtype': 'vlogdefine', 'paramtype': 'vlogdefine',
'description': 'secondary flash', 'description': 'secondary flash',
'default': 1} 'default': 1}
elif part == "xcau10p-ffvb676":
tool_options = {'part': part + '-1-e'}
elif part == "xcau15p-ffvb676": elif part == "xcau15p-ffvb676":
tool_options = {'part': part + '-2-e'} tool_options = {'part': part + '-2-e'}
else: else:

Binary file not shown.

View File

@ -5,6 +5,7 @@
#include "altera.hpp" #include "altera.hpp"
#include <inttypes.h>
#include <string.h> #include <string.h>
#include <map> #include <map>
@ -12,7 +13,6 @@
#include "common.hpp" #include "common.hpp"
#include "device.hpp" #include "device.hpp"
#include "epcq.hpp"
#include "jtag.hpp" #include "jtag.hpp"
#include "progressBar.hpp" #include "progressBar.hpp"
#include "rawParser.hpp" #include "rawParser.hpp"
@ -34,7 +34,7 @@ Altera::Altera(Jtag *jtag, const std::string &filename,
const std::string &flash_sectors, const std::string &flash_sectors,
bool skip_load_bridge, bool skip_reset): bool skip_load_bridge, bool skip_reset):
Device(jtag, filename, file_type, verify, verbose), Device(jtag, filename, file_type, verify, verbose),
SPIInterface(filename, verbose, 256, verify, skip_load_bridge, FlashInterface(filename, verbose, 256, verify, skip_load_bridge,
skip_reset), skip_reset),
_device_package(device_package), _spiOverJtagPath(spiOverJtagPath), _device_package(device_package), _spiOverJtagPath(spiOverJtagPath),
_vir_addr(0x1000), _vir_length(14), _clk_period(1), _vir_addr(0x1000), _vir_length(14), _clk_period(1),
@ -42,9 +42,13 @@ Altera::Altera(Jtag *jtag, const std::string &filename,
{ {
/* check device family */ /* check device family */
_idcode = _jtag->get_target_device_id(); _idcode = _jtag->get_target_device_id();
string family = fpga_list[_idcode].family; std::string family = fpga_list[_idcode].family;
if (family == "MAX 10") { if (family == "MAX 10") {
_fpga_family = MAX10_FAMILY; _fpga_family = MAX10_FAMILY;
} else if (family == "agilex 3") {
_fpga_family = AGILEX3_FAMILY;
} else if (family == "agilex 5") {
_fpga_family = AGILEX5_FAMILY;
} else { } else {
_fpga_family = CYCLONE_MISC; // FIXME _fpga_family = CYCLONE_MISC; // FIXME
} }
@ -243,6 +247,16 @@ void Altera::program(unsigned int offset, bool unprotect_flash)
return; return;
} }
/* Specific case for Agilex */
if (_fpga_family == AGILEX3_FAMILY || _fpga_family == AGILEX5_FAMILY) {
if (_mode != Device::MEM_MODE) {
printError("Altera: Error Write to flash for Agilex not supported");
return;
}
agilex_program();
return;
}
/* in all case we consider svf is mandatory /* in all case we consider svf is mandatory
* MEM_MODE : svf file provided for constructor * MEM_MODE : svf file provided for constructor
* is the bitstream to use * is the bitstream to use
@ -274,7 +288,7 @@ void Altera::program(unsigned int offset, bool unprotect_flash)
throw std::runtime_error(e.what()); throw std::runtime_error(e.what());
} }
if (!SPIInterface::write(offset, data, length, unprotect_flash)) if (!FlashInterface::write(offset, data, length, unprotect_flash))
throw std::runtime_error("Fail to write data"); throw std::runtime_error("Fail to write data");
} }
} }
@ -349,6 +363,15 @@ const std::map<uint32_t, Altera::max10_mem_t> Altera::max10_memory_map = {
// CHECKME: this line // CHECKME: this line
.pgm_success_addr = 0x0015} // program success addr .pgm_success_addr = 0x0015} // program success addr
}, },
{0x031030dd, { // 10M16D
.check_addr0 = 0x80009, // check_addr0
.dsm_addr = 0x0000, .dsm_len = 1024, // DSM
.ufm_addr = 0x0400, .ufm_len = {4096, 4096}, // UFM
.cfm_addr = 0x2400, .cfm_len = {67584, 28672, 38912}, // CFM
.sectors_erase_addr = {0x17ffff, 0x27ffff, 0x37ffff, 0x47ffff, 0x57ffff}, // sectors erase address
.done_bit_addr = 0x0011, // done bit
.pgm_success_addr = 0x0015} // program success addr
},
}; };
/* Write an arbitrary file in UFM1, UFM0 by default and also CFM2 and CFM1 if /* Write an arbitrary file in UFM1, UFM0 by default and also CFM2 and CFM1 if
@ -1002,6 +1025,276 @@ bool Altera::sectors_mask_start_end_addr(const Altera::max10_mem_t *mem,
return true; return true;
} }
/* ---------------------------------- */
/* Agilex 3/5 */
/* ---------------------------------- */
#define AGILEX_ISC_PROGRAM {0x02, 0x00}
#define AGILEX_COMMAND {0x01, 0x02}
#define AGILEX_ISC_SR {0x02, 0x02}
#define AGILEX_IRFLOW {0x08, 0x02}
#define AGILEX_BYPASS {0xff, 0x03}
#define uintStarTo64(__input__) ( \
(static_cast<uint64_t>(__input__[4]) << 32) | \
(static_cast<uint64_t>(__input__[3]) << 24) | \
(static_cast<uint64_t>(__input__[2]) << 16) | \
(static_cast<uint64_t>(__input__[1]) << 8) | \
(static_cast<uint64_t>(__input__[0]) << 0))
#define DWORDToCharStar(__dword__) { \
static_cast<unsigned char>((__dword__ >> 0) & 0xff), \
static_cast<unsigned char>((__dword__ >> 8) & 0xff), \
static_cast<unsigned char>((__dword__ >> 16) & 0xff), \
static_cast<unsigned char>((__dword__ >> 24) & 0xff), \
static_cast<unsigned char>((__dword__ >> 32) & 0xff) \
}
// Depends to the JTAG frequency?
static uint32_t agilex_toggle_length = 16;
bool Altera::agilex_poll_status(uint64_t *expected, uint64_t *mask,
uint32_t check_len, int max_poll)
{
const uint8_t isc_sr[2] = AGILEX_ISC_SR;
_jtag->shiftIR((unsigned char *)isc_sr, NULL, IRLENGTH);
_jtag->toggleClk(agilex_toggle_length);
if (_verbose)
printf("Begin\n");
for (uint32_t check = 0; check < check_len; check++) {
bool match = false;
const uint64_t exp = expected[check];
const uint64_t msk = mask[check];
for (int i = 0; i < max_poll && !match; i++) {
uint8_t status[5];
_jtag->shiftDR(NULL, status, 34);
_jtag->toggleClk(agilex_toggle_length);
uint64_t res = uintStarTo64(status) & 0x3FFFFFFFF;
if (_verbose) {
printf("%2d/%3d: 0x%08" PRIx64 "0x%08" PRIx64 "%08" PRIx64 " ",
check, i, res, res & msk, exp & msk);
for (int a = 0; a < 5; a++)
printf("%02x ", status[a]);
printf("\n");
}
// It's silly but mask must be applied to expected
// too...
match = ((res & msk) == (msk & exp));
}
if (!match)
return false;
}
return true;
}
bool Altera::agilex_send_instruction(const uint8_t *cmd, const uint64_t *tx,
uint64_t *rx, uint32_t length)
{
unsigned char rx_pkt[5];
_jtag->shiftIR((unsigned char *)cmd, NULL, IRLENGTH);
_jtag->toggleClk(agilex_toggle_length);
if (!rx && !tx)
return true;
for (uint32_t i = 0; i < length; i++) {
const uint64_t v = (tx) ? tx[i] : 0;
const unsigned char tx_pkt[] = DWORDToCharStar(v);
_jtag->shiftDR((tx)? tx_pkt : NULL, (rx) ? rx_pkt : NULL, 34);
_jtag->toggleClk(agilex_toggle_length);
if (rx)
rx[i] = uintStarTo64(rx_pkt);
}
return true;
}
bool Altera::agilex_isc_init()
{
const uint8_t cmd[2] = AGILEX_COMMAND;
/* Everything is magic here.
* stp0 and step2 are constant for AGILEX3 and AGILEX5 (at least
* with tested devices)
* stp1 is partially constant: 3 Words changes between synthesis
* (jam file) but if this value match the check everything is fine
*/
const uint64_t stp0[3] = {0x000000000, 0x300000000, 0x200000000};
const uint64_t stp1[3] = {0x000000000, 0x1F0001001, 0x27E2DA938};
const uint64_t stp2[2] = {0x000000000, 0x200000005};
if (!agilex_send_instruction(cmd, stp0, NULL, 3)) {
printError("Altera: Error during step0 write configuration");
return false;
}
/* Again: magic words */
uint64_t stp0_exp = 0x000000003;
uint64_t stp0_mask = 0x3FDFFFFFD;
if (!agilex_poll_status(&stp0_exp, &stp0_mask, 1)) {
printf("Altera: STP0: poll failed\n");
return false;
}
/* Device specific configuration */
if (!agilex_send_instruction(cmd, stp1, NULL, 3)) {
printError("Altera: Error during step0 write configuration");
return false;
}
/* Again: magic words */
uint64_t stp1_exp[] = {0x3C0004001, (0x3FFFFFFFF & ((stp1[2] << 2) | 0x03))};
uint64_t stp1_mask[] = {0x3FDFFFFFD, 0x3FFFFFFFD};
if (!agilex_poll_status(stp1_exp, stp1_mask, 2)) {
printError("Altera: Error during Device specific configuration step");
return false;
}
/* Enter ISC Configure mode */
if (!agilex_send_instruction(cmd, stp2, NULL, 2)) {
printError("Altera: Error during enter ISC Configure write");
return false;
}
uint64_t stp2_exp = 0x000000003;
uint64_t stp2_mask = 0x3FDFFFFFD;
if (!agilex_poll_status(&stp2_exp, &stp2_mask, 1, 300)) {
printError("Error during ISC configure mode");
return false;
}
return true;
}
bool Altera::agilex_exit_and_conf_done()
{
const uint8_t cmd[2] = AGILEX_COMMAND;
const uint8_t sr[2] = AGILEX_ISC_SR;
const uint8_t bypass[2] = AGILEX_BYPASS;
const uint8_t done0[5] = {0x00, 0x00, 0x00, 0x00, 0x00};
const uint8_t done1[5] = {0x04, 0x00, 0x00, 0x00, 0x02};
_jtag->shiftIR((unsigned char *)cmd, NULL, IRLENGTH);
_jtag->toggleClk(agilex_toggle_length);
_jtag->shiftDR((unsigned char *)done0, NULL, 34);
_jtag->toggleClk(agilex_toggle_length);
_jtag->shiftDR((unsigned char *)done1, NULL, 34);
_jtag->toggleClk(agilex_toggle_length);
_jtag->shiftIR((unsigned char *)sr, NULL, IRLENGTH);
_jtag->toggleClk(agilex_toggle_length);
uint8_t stat_tx[5];
uint8_t stat_rx[5];
memset(stat_tx, 0, 5);
uint64_t status;
do {
_jtag->shiftDR((unsigned char *)stat_tx, stat_rx, 34);
_jtag->toggleClk(agilex_toggle_length);
status = uintStarTo64(stat_rx);
} while ((status & 0x01) != 0);
_jtag->shiftIR((unsigned char *)bypass, NULL, IRLENGTH);
_jtag->toggleClk(agilex_toggle_length);
return true;
}
bool Altera::agilex_load_bitstream(const uint8_t *data, const uint32_t length)
{
const uint8_t stat_cmd[2] = AGILEX_IRFLOW;
const uint8_t cmd[2] = AGILEX_ISC_PROGRAM;
const uint8_t start[5] = {0x07, 0x00, 0x00, 0x00, 0x00};
const uint32_t xfer_min_length = 4096;
const uint32_t xfer_max_length = 65536;
uint8_t buffer[xfer_max_length + 9];
buffer[0] = 0xff;
buffer[1] = 0xff;
buffer[2] = 0xff;
buffer[3] = 0xff;
buffer[4] = 0x00;
buffer[5] = 0x2a;
buffer[6] = 0x7e;
buffer[7] = 0xa1;
uint8_t *ptr = &buffer[8];
/* Pre command */
_jtag->shiftIR((unsigned char *)stat_cmd, NULL, IRLENGTH);
_jtag->toggleClk(agilex_toggle_length);
_jtag->shiftDR((unsigned char *)start, NULL, 34);
_jtag->toggleClk(agilex_toggle_length);
uint32_t wr_pos = 0;
uint32_t curr_xfer_len = xfer_min_length;
ProgressBar progress("Load SRAM", length, 50, false);
while (wr_pos < length) {
uint32_t xfer_len = std::min(curr_xfer_len, length - wr_pos);
memcpy(ptr, &data[wr_pos], xfer_len);
ptr[xfer_len] = 0;
_jtag->shiftIR((unsigned char *)cmd, NULL, IRLENGTH);
_jtag->toggleClk(agilex_toggle_length);
_jtag->shiftDR((unsigned char *)buffer, NULL, 64 + 1 + xfer_len * 8);
_jtag->toggleClk(agilex_toggle_length);
/* loop until status bit0 low */
uint8_t stat_tx[5] = {0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t stat_rx[5];
uint64_t res;
bool busy, error;
do {
_jtag->shiftIR((unsigned char *)stat_cmd, NULL, IRLENGTH);
_jtag->toggleClk(agilex_toggle_length);
_jtag->shiftDR((unsigned char *)stat_tx, stat_rx, 37);
_jtag->toggleClk(agilex_toggle_length);
res = uintStarTo64(stat_rx);
busy = ((res >> 0) & 0x01);
error = ((res >> 1) & 0x01);
if (error) {
progress.fail();
printError("Device Configuration Error");
return false;
}
stat_tx[0] = 0x01;
} while(busy);
const uint32_t offset_after_write = wr_pos + curr_xfer_len;
// next position is provided by the FPGA
// it's a x 4
wr_pos = res & (~0x03);
/* search if we have to increase or reduce curr_xfer_len */
if (offset_after_write == wr_pos)
curr_xfer_len = std::min(curr_xfer_len * 2, xfer_max_length);
else
curr_xfer_len = std::max(curr_xfer_len / 2, xfer_min_length);
progress.display(wr_pos);
}
progress.done();
return true;
}
bool Altera::agilex_program()
{
RawParser rbf(_filename, _verbose);
rbf.parse();
const uint32_t rbf_length = rbf.getLength() / 8;
const uint8_t *rbf_data = rbf.getData();
if (!agilex_isc_init())
return false;
if (!agilex_load_bitstream(rbf_data, rbf_length))
return false;
if (!agilex_exit_and_conf_done())
return false;
return true;
}
/* SPI interface */ /* SPI interface */
int Altera::spi_put(uint8_t cmd, const uint8_t *tx, uint8_t *rx, uint32_t len) int Altera::spi_put(uint8_t cmd, const uint8_t *tx, uint8_t *rx, uint32_t len)

View File

@ -11,10 +11,10 @@
#include "device.hpp" #include "device.hpp"
#include "jtag.hpp" #include "jtag.hpp"
#include "rawParser.hpp" #include "rawParser.hpp"
#include "spiInterface.hpp" #include "flashInterface.hpp"
#include "svf_jtag.hpp" #include "svf_jtag.hpp"
class Altera: public Device, SPIInterface { class Altera: public Device, FlashInterface {
public: public:
Altera(Jtag *jtag, const std::string &filename, Altera(Jtag *jtag, const std::string &filename,
const std::string &file_type, const std::string &file_type,
@ -39,7 +39,7 @@ class Altera: public Device, SPIInterface {
bool dumpFlash(uint32_t base_addr, uint32_t len) override { bool dumpFlash(uint32_t base_addr, uint32_t len) override {
if (_fpga_family == MAX10_FAMILY) if (_fpga_family == MAX10_FAMILY)
return max10_dump(); return max10_dump();
return SPIInterface::dump(base_addr, len); return FlashInterface::dump(base_addr, len);
} }
uint32_t idCode() override; uint32_t idCode() override;
@ -53,25 +53,25 @@ class Altera: public Device, SPIInterface {
* \brief display SPI flash ID and status register * \brief display SPI flash ID and status register
*/ */
bool detect_flash() override { bool detect_flash() override {
return SPIInterface::detect_flash(); return FlashInterface::detect_flash();
} }
/*! /*!
* \brief protect SPI flash blocks * \brief protect SPI flash blocks
*/ */
bool protect_flash(uint32_t len) override { bool protect_flash(uint32_t len) override {
return SPIInterface::protect_flash(len); return FlashInterface::protect_flash(len);
} }
/*! /*!
* \brief unprotect SPI flash blocks * \brief unprotect SPI flash blocks
*/ */
bool unprotect_flash() override { bool unprotect_flash() override {
return SPIInterface::unprotect_flash(); return FlashInterface::unprotect_flash();
} }
/*! /*!
* \brief bulk erase SPI flash * \brief bulk erase SPI flash
*/ */
bool bulk_erase_flash() override { bool bulk_erase_flash() override {
return SPIInterface::bulk_erase_flash(); return FlashInterface::bulk_erase_flash();
} }
int spi_put(uint8_t cmd, const uint8_t *tx, uint8_t *rx, int spi_put(uint8_t cmd, const uint8_t *tx, uint8_t *rx,
@ -90,10 +90,25 @@ class Altera: public Device, SPIInterface {
MAX10_FAMILY = 1, MAX10_FAMILY = 1,
CYCLONE5_FAMILY = 2, CYCLONE5_FAMILY = 2,
CYCLONE10_FAMILY = 3, CYCLONE10_FAMILY = 3,
STRATIXV_FAMILY = 3, STRATIXV_FAMILY = 4,
AGILEX3_FAMILY = 5,
AGILEX5_FAMILY = 6,
CYCLONE_MISC = 10, // Fixme: idcode shared CYCLONE_MISC = 10, // Fixme: idcode shared
UNKNOWN_FAMILY = 999 UNKNOWN_FAMILY = 999
}; };
/**************************/
/* agilex specific */
/**************************/
bool agilex_poll_status(uint64_t *expected, uint64_t *mask, uint32_t check_len,
int max_poll=50);
bool agilex_send_instruction(const uint8_t *cmd, const uint64_t *tx,
uint64_t *rx, uint32_t length);
bool agilex_isc_init();
bool agilex_exit_and_conf_done();
bool agilex_load_bitstream(const uint8_t *data, const uint32_t length);
bool agilex_program();
/*************************/ /*************************/
/* max10 specific */ /* max10 specific */
/*************************/ /*************************/

View File

@ -29,7 +29,7 @@ Anlogic::Anlogic(Jtag *jtag, const std::string &filename,
const std::string &file_type, const std::string &file_type,
Device::prog_type_t prg_type, bool verify, int8_t verbose): Device::prog_type_t prg_type, bool verify, int8_t verbose):
Device(jtag, filename, file_type, verify, verbose), Device(jtag, filename, file_type, verify, verbose),
SPIInterface(filename, verbose, 0, verify), _target_freq(0) FlashInterface(filename, verbose, 0, verify), _target_freq(0)
{ {
if (prg_type == Device::RD_FLASH) { if (prg_type == Device::RD_FLASH) {
_mode = Device::READ_MODE; _mode = Device::READ_MODE;
@ -81,7 +81,7 @@ void Anlogic::program(unsigned int offset, bool unprotect_flash)
int len = bit.getLength() / 8; int len = bit.getLength() / 8;
if (_mode == Device::SPI_MODE) { if (_mode == Device::SPI_MODE) {
SPIInterface::write(offset, data, len, unprotect_flash); FlashInterface::write(offset, data, len, unprotect_flash);
return; return;
} }

View File

@ -11,10 +11,10 @@
#include "bitparser.hpp" #include "bitparser.hpp"
#include "device.hpp" #include "device.hpp"
#include "jtag.hpp" #include "jtag.hpp"
#include "spiInterface.hpp" #include "flashInterface.hpp"
#include "svf_jtag.hpp" #include "svf_jtag.hpp"
class Anlogic: public Device, SPIInterface { class Anlogic: public Device, FlashInterface {
public: public:
Anlogic(Jtag *jtag, const std::string &filename, Anlogic(Jtag *jtag, const std::string &filename,
const std::string &file_type, const std::string &file_type,
@ -30,21 +30,21 @@ class Anlogic: public Device, SPIInterface {
* \brief protect SPI flash blocks * \brief protect SPI flash blocks
*/ */
bool protect_flash(uint32_t len) override { bool protect_flash(uint32_t len) override {
return SPIInterface::protect_flash(len); return FlashInterface::protect_flash(len);
} }
/*! /*!
* \brief protect SPI flash blocks * \brief protect SPI flash blocks
*/ */
bool unprotect_flash() override { bool unprotect_flash() override {
return SPIInterface::unprotect_flash(); return FlashInterface::unprotect_flash();
} }
/*! /*!
* \brief bulk erase SPI flash * \brief bulk erase SPI flash
*/ */
bool bulk_erase_flash() override { bool bulk_erase_flash() override {
return SPIInterface::bulk_erase_flash(); return FlashInterface::bulk_erase_flash();
} }
/*! /*!
@ -54,7 +54,7 @@ class Anlogic: public Device, SPIInterface {
* \return false if something wrong * \return false if something wrong
*/ */
virtual bool dumpFlash(uint32_t base_addr, uint32_t len) override { virtual bool dumpFlash(uint32_t base_addr, uint32_t len) override {
return SPIInterface::dump(base_addr, len); return FlashInterface::dump(base_addr, len);
} }
int spi_put(uint8_t cmd, const uint8_t *tx, uint8_t *rx, int spi_put(uint8_t cmd, const uint8_t *tx, uint8_t *rx,

View File

@ -18,9 +18,8 @@
#include "anlogicBitParser.hpp" #include "anlogicBitParser.hpp"
#include "display.hpp" #include "display.hpp"
using namespace std;
AnlogicBitParser::AnlogicBitParser(const string &filename, bool reverseOrder, AnlogicBitParser::AnlogicBitParser(const std::string &filename, bool reverseOrder,
bool verbose): bool verbose):
ConfigBitstreamParser(filename, ConfigBitstreamParser::BIN_MODE, verbose), ConfigBitstreamParser(filename, ConfigBitstreamParser::BIN_MODE, verbose),
_reverseOrder(reverseOrder) _reverseOrder(reverseOrder)
@ -37,8 +36,8 @@ int AnlogicBitParser::parseHeader()
{ {
int ret = 0; int ret = 0;
string buffer; std::string buffer;
istringstream lineStream(_raw_data); std::istringstream lineStream(_raw_data);
while (std::getline(lineStream, buffer, '\n')) { while (std::getline(lineStream, buffer, '\n')) {
ret += buffer.size() + 1; ret += buffer.size() + 1;
@ -53,13 +52,13 @@ int AnlogicBitParser::parseHeader()
return -1; return -1;
} }
string content = buffer.substr(2); // drop '# ' std::string content = buffer.substr(2); // drop '# '
size_t pos = content.find(':'); size_t pos = content.find(':');
if (pos == string::npos) { if (pos == std::string::npos) {
_hdr["tool"] = content; _hdr["tool"] = content;
} else { } else {
string entry = content.substr(0, pos); std::string entry = content.substr(0, pos);
string val = content.substr(pos+2); std::string val = content.substr(pos+2);
_hdr[entry] = val; _hdr[entry] = val;
} }
} }

View File

@ -15,7 +15,6 @@
#include "anlogicCable.hpp" #include "anlogicCable.hpp"
#include "display.hpp" #include "display.hpp"
using namespace std;
#define ANLOGICCABLE_VIDv1 0x0547 #define ANLOGICCABLE_VIDv1 0x0547
#define ANLOGICCABLE_VIDv2 0x336C #define ANLOGICCABLE_VIDv2 0x336C
@ -59,8 +58,7 @@ AnlogicCable::AnlogicCable(uint32_t clkHZ):
int ret; int ret;
if (libusb_init(&usb_ctx) < 0) { if (libusb_init(&usb_ctx) < 0) {
cerr << "libusb init failed" << endl; throw std::runtime_error("libusb init failed");
throw std::exception();
} }
/* First: Try with original (old) VID */ /* First: Try with original (old) VID */
@ -72,23 +70,20 @@ AnlogicCable::AnlogicCable(uint32_t clkHZ):
ANLOGICCABLE_VIDv2, ANLOGICCABLE_PID); ANLOGICCABLE_VIDv2, ANLOGICCABLE_PID);
if (!dev_handle) { if (!dev_handle) {
cerr << "fails to open device" << endl;
libusb_exit(usb_ctx); libusb_exit(usb_ctx);
throw std::exception(); throw std::runtime_error("fails to open device");
} }
} }
ret = libusb_claim_interface(dev_handle, 0); ret = libusb_claim_interface(dev_handle, 0);
if (ret) { if (ret) {
cerr << "libusb error while claiming DirtyJTAG interface #0" << endl;
libusb_close(dev_handle); libusb_close(dev_handle);
libusb_exit(usb_ctx); libusb_exit(usb_ctx);
throw std::exception(); throw std::runtime_error("libusb error while claiming AnlogicCable interface #0");
} }
if (setClkFreq(clkHZ) < 0) { if (setClkFreq(clkHZ) < 0) {
cerr << "Fail to set frequency" << endl; throw std::runtime_error("Fail to set frequency");
throw std::exception();
} }
} }
@ -140,7 +135,7 @@ int AnlogicCable::setClkFreq(uint32_t clkHZ)
ret = libusb_bulk_transfer(dev_handle, ANLOGICCABLE_CONF_EP, ret = libusb_bulk_transfer(dev_handle, ANLOGICCABLE_CONF_EP,
buf, 2, &actual_length, 1000); buf, 2, &actual_length, 1000);
if (ret < 0) { if (ret < 0) {
cerr << "setClkFreq: usb bulk write failed " << ret << endl; printError("setClkFreq: usb bulk write failed " + std::to_string(ret));
return -EXIT_FAILURE; return -EXIT_FAILURE;
} }
@ -293,14 +288,14 @@ int AnlogicCable::write(uint8_t *in_buf, uint8_t *out_buf, int len, int rd_len)
int ret = libusb_bulk_transfer(dev_handle, ANLOGICCABLE_WRITE_EP, int ret = libusb_bulk_transfer(dev_handle, ANLOGICCABLE_WRITE_EP,
in_buf, len, &actual_length, 1000); in_buf, len, &actual_length, 1000);
if (ret < 0) { if (ret < 0) {
cerr << "write: usb bulk write failed " << ret << endl; printError("write: usb bulk write failed " + std::to_string(ret));
return -EXIT_FAILURE; return -EXIT_FAILURE;
} }
/* all write must be followed by a read */ /* all write must be followed by a read */
ret = libusb_bulk_transfer(dev_handle, ANLOGICCABLE_READ_EP, ret = libusb_bulk_transfer(dev_handle, ANLOGICCABLE_READ_EP,
in_buf, len, &actual_length, 1000); in_buf, len, &actual_length, 1000);
if (ret < 0) { if (ret < 0) {
cerr << "write: usb bulk read failed " << ret << endl; printError("write: usb bulk read failed " + std::to_string(ret));
return -EXIT_FAILURE; return -EXIT_FAILURE;
} }

View File

@ -18,12 +18,11 @@
#include <winsock2.h> #include <winsock2.h>
#endif #endif
using namespace std;
#define display(...) \ #define display(...) \
do { if (_verbose) fprintf(stdout, __VA_ARGS__);} while(0) do { if (_verbose) fprintf(stdout, __VA_ARGS__);} while(0)
BitParser::BitParser(const string &filename, bool reverseOrder, bool verbose): BitParser::BitParser(const std::string &filename, bool reverseOrder, bool verbose):
ConfigBitstreamParser(filename, ConfigBitstreamParser::BIN_MODE, ConfigBitstreamParser(filename, ConfigBitstreamParser::BIN_MODE,
verbose), _reverseOrder(reverseOrder) verbose), _reverseOrder(reverseOrder)
{ {
@ -37,49 +36,86 @@ int BitParser::parseHeader()
{ {
int pos_data = 0; int pos_data = 0;
int ret = 1; int ret = 1;
short length; uint16_t length;
string tmp; std::string tmp;
int pos, prev_pos;
/* Field 1 : misc header */ /* Field 1 : misc header */
if (_raw_data.size() < 2) {
printError("BitParser: Bound check failure. Can't read Field 1 length");
return -1;
}
length = *(uint16_t *)&_raw_data[0]; length = *(uint16_t *)&_raw_data[0];
length = ntohs(length); length = ntohs(length);
pos_data += length + 2; pos_data += length + 2;
length = *(uint16_t *)&_raw_data[pos_data]; if (pos_data + 2 >= static_cast<int>(_raw_data.size())) {
length = ntohs(length); printError("BitParser: Bound check failure. Can't read Field 2 length");
return -1;
}
length = ((static_cast<uint16_t>(_raw_data[pos_data]) & 0xff) << 8) |
((static_cast<uint16_t>(_raw_data[pos_data + 1]) & 0xff) << 0);
pos_data += 2; pos_data += 2;
while (1) { while (1) {
/* type */ /* type */
uint8_t type; if (pos_data >= static_cast<int>(_raw_data.size())) {
type = (uint8_t)_raw_data[pos_data++]; printError("BitParser: Bound check failure. Field type");
return -1;
}
const uint8_t type = (uint8_t)_raw_data[pos_data++];
if (type != 'e') { if (type != 'e') {
length = *(uint16_t *)&_raw_data[pos_data]; if (pos_data + 2 >= static_cast<int>(_raw_data.size())) {
length = ntohs(length); printError("BitParser: Bound check failure, Field length");
return -1;
}
length = ((static_cast<uint16_t>(_raw_data[pos_data]) & 0xff) << 8) |
((static_cast<uint16_t>(_raw_data[pos_data + 1]) & 0xff) << 0);
pos_data += 2; pos_data += 2;
} else { } else {
length = 4; length = 4;
} }
if (static_cast<int>(_raw_data.size()) < pos_data + length) {
printError("BitParser: Bound check failure. Field Data");
return -1;
}
tmp = _raw_data.substr(pos_data, length); tmp = _raw_data.substr(pos_data, length);
pos_data += length; pos_data += length;
switch (type) { switch (type) {
case 'a': /* design name:userid:synthesize tool version */ case 'a': { /* design name:userid:synthesize tool version */
prev_pos = 0; std::stringstream ss(tmp);
pos = tmp.find(";"); std::string token;
_hdr["design_name"] = tmp.substr(prev_pos, pos); bool first = true;
prev_pos = pos+1;
pos = tmp.find(";", prev_pos); while (std::getline(ss, token, ';')) {
prev_pos = tmp.find("=", prev_pos) + 1; if (first) {
_hdr["userID"] = tmp.substr(prev_pos, pos-prev_pos); _hdr["design_name"] = token;
prev_pos = pos+1; first = false;
continue;
}
prev_pos = tmp.find("=", prev_pos) + 1; auto pos = token.find('=');
_hdr["toolVersion"] = tmp.substr(prev_pos, length-prev_pos); if (pos != std::string::npos) {
break; auto key = token.substr(0, pos);
if (length < pos + 1) {
printError("Failed to find for key");
return -1;
}
auto value = token.substr(pos + 1);
if (key == "UserID") {
_hdr["userId"] = value;
} else if (key == "Version") {
_hdr["version"] = value;
} else {
printError("Unknown key " + key);
return -1;
}
}
}
} break;
case 'b': /* FPGA model */ case 'b': /* FPGA model */
_hdr["part_name"] = tmp.substr(0, length); _hdr["part_name"] = tmp.substr(0, length);
break; break;
@ -108,6 +144,10 @@ int BitParser::parse()
{ {
/* process all field */ /* process all field */
int pos = parseHeader(); int pos = parseHeader();
if (pos == -1) {
printError("BitParser: parseHeader failed");
return 1;
}
/* _bit_length is length of data to send */ /* _bit_length is length of data to send */
int rest_of_file_length = _file_size - pos; int rest_of_file_length = _file_size - pos;

View File

@ -113,6 +113,8 @@ static std::map <std::string, target_board_t> board_list = {
JTAG_BOARD("ac701", "xc7a200tfbg676", "digilent", SPI_FLASH, 0, 0, CABLE_DEFAULT), JTAG_BOARD("ac701", "xc7a200tfbg676", "digilent", SPI_FLASH, 0, 0, CABLE_DEFAULT),
JTAG_BOARD("acornCle215", "xc7a200tsbg484", "", SPI_FLASH, 0, 0, CABLE_DEFAULT), JTAG_BOARD("acornCle215", "xc7a200tsbg484", "", SPI_FLASH, 0, 0, CABLE_DEFAULT),
JTAG_BOARD("analogMax", "", "ft2232", SPI_FLASH, 0, 0, CABLE_DEFAULT), JTAG_BOARD("analogMax", "", "ft2232", SPI_FLASH, 0, 0, CABLE_DEFAULT),
JTAG_BOARD("atumA3Nano", "", "usb-blasterIII", SPI_FLASH, 0, 0, CABLE_DEFAULT),
JTAG_BOARD("axe5000", "", "usb-blasterIII", SPI_FLASH, 0, 0, CABLE_DEFAULT),
JTAG_BOARD("litex-acorn-baseboard-mini", "xc7a200tsbg484", "", SPI_FLASH, 0, 0, CABLE_DEFAULT), JTAG_BOARD("litex-acorn-baseboard-mini", "xc7a200tsbg484", "", SPI_FLASH, 0, 0, CABLE_DEFAULT),
JTAG_BOARD("alchitry_au", "xc7a35tftg256", "ft2232", SPI_FLASH, 0, 0, CABLE_DEFAULT), JTAG_BOARD("alchitry_au", "xc7a35tftg256", "ft2232", SPI_FLASH, 0, 0, CABLE_DEFAULT),
JTAG_BOARD("alchitry_au_plus","xc7a100tftg256", "ft2232", SPI_FLASH, 0, 0, CABLE_DEFAULT), JTAG_BOARD("alchitry_au_plus","xc7a100tftg256", "ft2232", SPI_FLASH, 0, 0, CABLE_DEFAULT),

View File

@ -135,7 +135,7 @@ static std::map <std::string, cable_t> cable_list = {
{"usb-blaster_2", CABLE_DEF(MODE_USBBLASTER, 0x09Fb, 0x6003 )}, {"usb-blaster_2", CABLE_DEF(MODE_USBBLASTER, 0x09Fb, 0x6003 )},
{"usb-blasterII", CABLE_DEF(MODE_USBBLASTER, 0x09Fb, 0x6810 )}, {"usb-blasterII", CABLE_DEF(MODE_USBBLASTER, 0x09Fb, 0x6810 )},
{"usb-blasterII_1", CABLE_DEF(MODE_USBBLASTER, 0x09Fb, 0x6010 )}, {"usb-blasterII_1", CABLE_DEF(MODE_USBBLASTER, 0x09Fb, 0x6010 )},
{"usb-blasterIII", FTDI_SER(0x09fb, 0x6022, FTDI_INTF_A, 0x08, 0x3B, 0x00, 0x00)}, {"usb-blasterIII", FTDI_SER(0x09fb, 0x6022, FTDI_INTF_A, 0x08, 0x3B, 0x58, 0xb0)},
{"xvc-client", CABLE_DEF(MODE_XVC_CLIENT, 0x0000, 0x0000 )}, {"xvc-client", CABLE_DEF(MODE_XVC_CLIENT, 0x0000, 0x0000 )},
#ifdef ENABLE_LIBGPIOD #ifdef ENABLE_LIBGPIOD
{"libgpiod", CABLE_DEF(MODE_LIBGPIOD_BITBANG, 0, 0x0000 )}, {"libgpiod", CABLE_DEF(MODE_LIBGPIOD_BITBANG, 0, 0x0000 )},

View File

@ -19,7 +19,6 @@
#include "ch347jtag.hpp" #include "ch347jtag.hpp"
#include "display.hpp" #include "display.hpp"
using namespace std;
#define CH347JTAG_VID 0x1a86 #define CH347JTAG_VID 0x1a86
#define CH347T_JTAG_PID 0x55dd //ch347T #define CH347T_JTAG_PID 0x55dd //ch347T
@ -64,12 +63,12 @@ int CH347Jtag::usb_xfer(unsigned wlen, unsigned rlen, unsigned *ract, bool defer
} }
if (obuf - _obuf > MAX_BUFFER) { if (obuf - _obuf > MAX_BUFFER) {
throw runtime_error("buffer overflow"); throw std::runtime_error("buffer overflow");
} }
wlen += obuf - _obuf; wlen += obuf - _obuf;
if (wlen > MAX_BUFFER) { if (wlen > MAX_BUFFER) {
throw runtime_error("buffer overflow"); throw std::runtime_error("buffer overflow");
} }
obuf = _obuf; obuf = _obuf;
@ -293,8 +292,8 @@ int CH347Jtag::writeTMS(const uint8_t *tms, uint32_t len, bool flush_buffer,
obuf[2] = (wlen - 3) >> 8; obuf[2] = (wlen - 3) >> 8;
int ret = usb_xfer(wlen, 0, 0, !flush_buffer); int ret = usb_xfer(wlen, 0, 0, !flush_buffer);
if (ret < 0) { if (ret < 0) {
cerr << "writeTMS: usb bulk write failed: " << printError(std::string("writeTMS: usb bulk write failed: ")
libusb_strerror(static_cast<libusb_error>(ret)) << endl; + std::string(libusb_strerror(static_cast<libusb_error>(ret))));
return -EXIT_FAILURE; return -EXIT_FAILURE;
} }
ptr = obuf; ptr = obuf;
@ -332,8 +331,8 @@ int CH347Jtag::toggleClk(__attribute__((unused)) uint8_t tms,
obuf[2] = (wlen - 3) >> 8; obuf[2] = (wlen - 3) >> 8;
int ret = usb_xfer(wlen, 0, 0, true); int ret = usb_xfer(wlen, 0, 0, true);
if (ret < 0) { if (ret < 0) {
cerr << "writeCLK: usb bulk write failed: " << printError(std::string("writeCLK: usb bulk write failed: ")
libusb_strerror(static_cast<libusb_error>(ret)) << endl; + std::string(libusb_strerror(static_cast<libusb_error>(ret))));
return -EXIT_FAILURE; return -EXIT_FAILURE;
} }
ptr = obuf; ptr = obuf;
@ -371,15 +370,15 @@ int CH347Jtag::writeTDI(const uint8_t *tx, uint8_t *rx, uint32_t len, bool end)
unsigned actual_length = 0; unsigned actual_length = 0;
int ret = usb_xfer(chunk + 3, (rx) ? chunk + 3 : 0, &actual_length, rx == 0 && get_obuf_length()); int ret = usb_xfer(chunk + 3, (rx) ? chunk + 3 : 0, &actual_length, rx == 0 && get_obuf_length());
if (ret < 0) { if (ret < 0) {
cerr << "writeTDI: usb bulk read failed: " << printError(std::string("writeTDI: usb bulk read failed: ")
libusb_strerror(static_cast<libusb_error>(ret)) << endl; + std::string(libusb_strerror(static_cast<libusb_error>(ret))));
return -EXIT_FAILURE; return -EXIT_FAILURE;
} }
if (!rx) if (!rx)
continue; continue;
unsigned size = ibuf[1] + ibuf[2] * 0x100; unsigned size = ibuf[1] + ibuf[2] * 0x100;
if (ibuf[0] != CMD_BYTES_WR || actual_length - 3 != size) { if (ibuf[0] != CMD_BYTES_WR || actual_length - 3 != size) {
cerr << "writeTDI: invalid read data: " << ret << endl; printError("writeTDI: invalid read data: " + std::to_string(ret));
return -EXIT_FAILURE; return -EXIT_FAILURE;
} }
memcpy(rptr, &ibuf[3], size); memcpy(rptr, &ibuf[3], size);
@ -414,8 +413,8 @@ int CH347Jtag::writeTDI(const uint8_t *tx, uint8_t *rx, uint32_t len, bool end)
int ret = usb_xfer(wlen, (rx) ? (bits + 3) : 0, &actual_length, rx == nullptr); int ret = usb_xfer(wlen, (rx) ? (bits + 3) : 0, &actual_length, rx == nullptr);
if (ret < 0) { if (ret < 0) {
cerr << "writeTDI: usb bulk read failed: " << printError(std::string("writeTDI: usb bulk read failed: ")
libusb_strerror(static_cast<libusb_error>(ret)) << endl; + std::string(libusb_strerror(static_cast<libusb_error>(ret))));
return -EXIT_FAILURE; return -EXIT_FAILURE;
} }
if (!rx) if (!rx)
@ -424,7 +423,7 @@ int CH347Jtag::writeTDI(const uint8_t *tx, uint8_t *rx, uint32_t len, bool end)
unsigned size = ibuf[1] + ibuf[2] * 0x100; unsigned size = ibuf[1] + ibuf[2] * 0x100;
if (ibuf[0] != CMD_BITS_WR || actual_length - 3 != size) { if (ibuf[0] != CMD_BITS_WR || actual_length - 3 != size) {
cerr << "writeTDI: invalid read data: " << endl; printError("writeTDI: invalid read data: ");
return -EXIT_FAILURE; return -EXIT_FAILURE;
} }
for (unsigned i = 0; i < size; ++i) { for (unsigned i = 0; i < size; ++i) {

View File

@ -16,7 +16,6 @@
#include "ch552_jtag.hpp" #include "ch552_jtag.hpp"
#include "ftdipp_mpsse.hpp" #include "ftdipp_mpsse.hpp"
using namespace std;
#define DEBUG 0 #define DEBUG 0
@ -30,7 +29,7 @@ using namespace std;
#endif #endif
CH552_jtag::CH552_jtag(const cable_t &cable, CH552_jtag::CH552_jtag(const cable_t &cable,
const string &dev, const string &serial, uint32_t clkHZ, const std::string &dev, const std::string &serial, uint32_t clkHZ,
int8_t verbose): int8_t verbose):
FTDIpp_MPSSE(cable, dev, serial, clkHZ, verbose), _to_read(0) FTDIpp_MPSSE(cable, dev, serial, clkHZ, verbose), _to_read(0)
{ {

View File

@ -21,7 +21,6 @@
#include "cmsisDAP.hpp" #include "cmsisDAP.hpp"
using namespace std;
#define DAP_JTAG_SEQ_TDO_CAPTURE (1 << 7) #define DAP_JTAG_SEQ_TDO_CAPTURE (1 << 7)
#define DAP_JTAG_SEQ_TMS_SHIFT(x) ((x & 0x01) << 6) #define DAP_JTAG_SEQ_TMS_SHIFT(x) ((x & 0x01) << 6)
@ -49,7 +48,7 @@ enum cmsisdap_info_id {
INFO_ID_PID = 0x02, // Get the Product ID (string). INFO_ID_PID = 0x02, // Get the Product ID (string).
INFO_ID_SERNUM = 0x03, // Get the Serial Number (string). INFO_ID_SERNUM = 0x03, // Get the Serial Number (string).
INFO_ID_FWVERS = 0x04, // Get the CMSIS-DAP Firmware INFO_ID_FWVERS = 0x04, // Get the CMSIS-DAP Firmware
// Version (string). // Version (string).
INFO_ID_TARGET_DEV_VENDOR = 0x05, // Get the Target Device Vendor (string). INFO_ID_TARGET_DEV_VENDOR = 0x05, // Get the Target Device Vendor (string).
INFO_ID_TARGET_DEV_NAME = 0x06, // Get the Target Device Name (string). INFO_ID_TARGET_DEV_NAME = 0x06, // Get the Target Device Name (string).
INFO_ID_HWCAP = 0xF0, // Get information about the INFO_ID_HWCAP = 0xF0, // Get information about the
@ -60,7 +59,7 @@ enum cmsisdap_info_id {
INFO_ID_MAX_PKT_SZ = 0xFF // Get the maximum Packet Size (SHORT). INFO_ID_MAX_PKT_SZ = 0xFF // Get the maximum Packet Size (SHORT).
}; };
static map<uint8_t, string> cmsisdap_info_id_str = { static std::map<uint8_t, std::string> cmsisdap_info_id_str = {
{INFO_ID_VID, "VID"}, {INFO_ID_VID, "VID"},
{INFO_ID_PID, "PID"}, {INFO_ID_PID, "PID"},
{INFO_ID_SERNUM, "serial number"}, {INFO_ID_SERNUM, "serial number"},
@ -159,7 +158,7 @@ CmsisDAP::CmsisDAP(const cable_t &cable, int index, int8_t verbose):_verbose(ver
_vid = dev_found[_device_idx]->vendor_id; _vid = dev_found[_device_idx]->vendor_id;
_pid = dev_found[_device_idx]->product_id; _pid = dev_found[_device_idx]->product_id;
if (dev_found[_device_idx]->serial_number != NULL) if (dev_found[_device_idx]->serial_number != NULL)
_serial_number = wstring(dev_found[_device_idx]->serial_number); _serial_number = std::wstring(dev_found[_device_idx]->serial_number);
/* open the device */ /* open the device */
_dev = hid_open_path(dev_found[_device_idx]->path); _dev = hid_open_path(dev_found[_device_idx]->path);
if (!_dev) { if (!_dev) {

View File

@ -186,7 +186,7 @@ bool CologneChip::detect_flash()
printInfo("Read Flash ", false); printInfo("Read Flash ", false);
try { try {
std::unique_ptr<SPIFlash> flash(_spi ? std::unique_ptr<SPIFlash> flash(_spi ?
new SPIFlash(reinterpret_cast<SPIInterface *>(_spi), false, _verbose): new SPIFlash(reinterpret_cast<FlashInterface *>(_spi), false, _verbose):
new SPIFlash(this, false, _verbose)); new SPIFlash(this, false, _verbose));
flash->read_id(); flash->read_id();
flash->display_status_reg(); flash->display_status_reg();
@ -210,7 +210,7 @@ bool CologneChip::dumpFlash(uint32_t base_addr, uint32_t len)
printInfo("Read Flash ", false); printInfo("Read Flash ", false);
try { try {
std::unique_ptr<SPIFlash> flash(_spi ? std::unique_ptr<SPIFlash> flash(_spi ?
new SPIFlash(reinterpret_cast<SPIInterface *>(_spi), false, _verbose): new SPIFlash(reinterpret_cast<FlashInterface *>(_spi), false, _verbose):
new SPIFlash(this, false, _verbose)); new SPIFlash(this, false, _verbose));
flash->dump(_filename, base_addr, len); flash->dump(_filename, base_addr, len);
} catch (std::exception &e) { } catch (std::exception &e) {
@ -227,7 +227,7 @@ bool CologneChip::dumpFlash(uint32_t base_addr, uint32_t len)
*/ */
bool CologneChip::set_quad_bit(bool set_quad) bool CologneChip::set_quad_bit(bool set_quad)
{ {
if (!SPIInterface::set_quad_bit(set_quad)) { if (!FlashInterface::set_quad_bit(set_quad)) {
return false; return false;
} }
@ -239,7 +239,7 @@ bool CologneChip::set_quad_bit(bool set_quad)
*/ */
bool CologneChip::bulk_erase_flash() bool CologneChip::bulk_erase_flash()
{ {
if (!SPIInterface::bulk_erase_flash()) { if (!FlashInterface::bulk_erase_flash()) {
return false; return false;
} }
@ -323,7 +323,7 @@ void CologneChip::programSPI_flash(unsigned int offset, const uint8_t *data,
_spi->gpio_clear(_rstn_pin | _oen_pin); _spi->gpio_clear(_rstn_pin | _oen_pin);
usleep(SLEEP_US); usleep(SLEEP_US);
SPIFlash flash(reinterpret_cast<SPIInterface *>(_spi), unprotect_flash, SPIFlash flash(reinterpret_cast<FlashInterface *>(_spi), unprotect_flash,
_verbose); _verbose);
flash.erase_and_prog(offset, data, length); flash.erase_and_prog(offset, data, length);
@ -425,16 +425,18 @@ int CologneChip::spi_put(uint8_t cmd, const uint8_t *tx, uint8_t *rx, uint32_t l
jtx[i+1] = ConfigBitstreamParser::reverseByte(tx[i]); jtx[i+1] = ConfigBitstreamParser::reverseByte(tx[i]);
} }
_jtag->shiftIR(JTAG_SPI_BYPASS, 6, Jtag::SELECT_DR_SCAN); _jtag->shiftIR(JTAG_SPI_BYPASS, 6, Jtag::SHIFT_DR);
int test = (rx == NULL) ? 8*xfer_len+1 : 8*xfer_len+2; int drlen = (rx == NULL) ? 8*xfer_len : 8*xfer_len+1;
_jtag->shiftDR(jtx, (rx == NULL)? NULL: jrx, test, Jtag::SELECT_DR_SCAN); _jtag->read_write(jtx, (rx == NULL) ? NULL : jrx, drlen, false);
int shift = _jtag->get_devices_list().size();
if (rx != NULL) { if (rx != NULL) {
for (uint32_t i=0; i < len; i++) { for (uint32_t i=0; i < len; i++) {
uint8_t b0 = ConfigBitstreamParser::reverseByte(jrx[i+1]); uint8_t b0 = ConfigBitstreamParser::reverseByte(jrx[i+1]);
uint8_t b1 = ConfigBitstreamParser::reverseByte(jrx[i+2]); uint8_t b1 = ConfigBitstreamParser::reverseByte(jrx[i+2]);
rx[i] = (b0 << 1) | ((b1 >> 7) & 0x01); rx[i] = (b0 << shift) | (b1 >> (8-shift));
} }
} }
return 0; return 0;
@ -482,11 +484,13 @@ int CologneChip::spi_wait(uint8_t cmd, uint8_t mask, uint8_t cond,
_jtag->shiftIR(JTAG_SPI_BYPASS, 6, Jtag::SHIFT_DR); _jtag->shiftIR(JTAG_SPI_BYPASS, 6, Jtag::SHIFT_DR);
_jtag->read_write(&tx, NULL, 8, 0); _jtag->read_write(&tx, NULL, 8, 0);
int shift = _jtag->get_devices_list().size();
do { do {
_jtag->read_write(dummy, rx, 16, 0); _jtag->read_write(dummy, rx, 16, 0);
uint8_t b0 = ConfigBitstreamParser::reverseByte(rx[0]); uint8_t b0 = ConfigBitstreamParser::reverseByte(rx[0]);
uint8_t b1 = ConfigBitstreamParser::reverseByte(rx[1]); uint8_t b1 = ConfigBitstreamParser::reverseByte(rx[1]);
tmp = (b0 << 1) | ((b1 >> 7) & 0x01); tmp = (b0 << shift) | (b1 >> (8-shift));
count++; count++;
if (count == timeout) { if (count == timeout) {

View File

@ -23,7 +23,7 @@
#include "spiFlash.hpp" #include "spiFlash.hpp"
#include "progressBar.hpp" #include "progressBar.hpp"
class CologneChip: public Device, SPIInterface { class CologneChip: public Device, FlashInterface {
public: public:
CologneChip(FtdiSpi *spi, const std::string &filename, CologneChip(FtdiSpi *spi, const std::string &filename,
const std::string &file_type, Device::prog_type_t prg_type, const std::string &file_type, Device::prog_type_t prg_type,

View File

@ -26,9 +26,8 @@
#include "configBitstreamParser.hpp" #include "configBitstreamParser.hpp"
using namespace std;
ConfigBitstreamParser::ConfigBitstreamParser(const string &filename, int mode, ConfigBitstreamParser::ConfigBitstreamParser(const std::string &filename, int mode,
bool verbose): _filename(filename), _bit_length(0), bool verbose): _filename(filename), _bit_length(0),
_file_size(0), _verbose(verbose), _file_size(0), _verbose(verbose),
_bit_data(), _raw_data(), _hdr() _bit_data(), _raw_data(), _hdr()
@ -40,7 +39,7 @@ ConfigBitstreamParser::ConfigBitstreamParser(const string &filename, int mode,
FILE *_fd = fopen(filename.c_str(), "rb"); FILE *_fd = fopen(filename.c_str(), "rb");
if (!_fd) { if (!_fd) {
/* if file not found it's maybe a gz -> try without gz */ /* if file not found it's maybe a gz -> try without gz */
if (offset != string::npos) { if (offset != std::string::npos) {
_filename = filename.substr(0, offset); _filename = filename.substr(0, offset);
_fd = fopen(_filename.c_str(), "rb"); _fd = fopen(_filename.c_str(), "rb");
} }
@ -61,10 +60,10 @@ ConfigBitstreamParser::ConfigBitstreamParser(const string &filename, int mode,
if (ret != _file_size) if (ret != _file_size)
throw std::runtime_error("Error: fail to read " + _filename); throw std::runtime_error("Error: fail to read " + _filename);
if (offset != string::npos) { if (offset != std::string::npos) {
string extension = _filename.substr(_filename.find_last_of(".") +1); std::string extension = _filename.substr(_filename.find_last_of(".") +1);
if (extension == "gz" || extension == "gzip") { if (extension == "gz" || extension == "gzip") {
string tmp; std::string tmp;
tmp.reserve(_file_size); tmp.reserve(_file_size);
if (!decompress_bitstream(_raw_data, &tmp)) if (!decompress_bitstream(_raw_data, &tmp))
throw std::runtime_error("Error: decompress failed"); throw std::runtime_error("Error: decompress failed");
@ -77,7 +76,7 @@ ConfigBitstreamParser::ConfigBitstreamParser(const string &filename, int mode,
} else if (!isatty(fileno(stdin))) { } else if (!isatty(fileno(stdin))) {
_file_size = 0; _file_size = 0;
string tmp; std::string tmp;
tmp.resize(4096); tmp.resize(4096);
size_t size; size_t size;
@ -95,7 +94,7 @@ ConfigBitstreamParser::~ConfigBitstreamParser()
{ {
} }
string ConfigBitstreamParser::getHeaderVal(string key) std::string ConfigBitstreamParser::getHeaderVal(std::string key)
{ {
auto val = _hdr.find(key); auto val = _hdr.find(key);
if (val == _hdr.end()) if (val == _hdr.end())
@ -107,7 +106,7 @@ void ConfigBitstreamParser::displayHeader()
{ {
if (_hdr.empty()) if (_hdr.empty())
return; return;
cout << "bitstream header infos" << endl; printInfo("bitstream header infos");
for (auto it = _hdr.begin(); it != _hdr.end(); it++) { for (auto it = _hdr.begin(); it != _hdr.end(); it++) {
printInfo((*it).first + ": ", false); printInfo((*it).first + ": ", false);
printSuccess((*it).second); printSuccess((*it).second);
@ -165,7 +164,7 @@ uint32_t ConfigBitstreamParser::reverse_32(const uint32_t src)
(revertByteArr[(src >> 24) & 0xff] << 0); (revertByteArr[(src >> 24) & 0xff] << 0);
} }
bool ConfigBitstreamParser::decompress_bitstream(string source, string *dest) bool ConfigBitstreamParser::decompress_bitstream(std::string source, std::string *dest)
{ {
#ifndef HAS_ZLIB #ifndef HAS_ZLIB
(void)source; (void)source;

View File

@ -8,9 +8,8 @@
#include "device.hpp" #include "device.hpp"
using namespace std;
Device::Device(Jtag *jtag, string filename, const string &file_type, Device::Device(Jtag *jtag, std::string filename, const std::string &file_type,
bool verify, int8_t verbose): bool verify, int8_t verbose):
_filename(filename), _filename(filename),
_file_extension(filename.substr(filename.find_last_of(".") +1)), _file_extension(filename.substr(filename.find_last_of(".") +1)),
@ -24,13 +23,13 @@ Device::Device(Jtag *jtag, string filename, const string &file_type,
} else if (!filename.empty()) { } else if (!filename.empty()) {
size_t offset = filename.find_last_of("."); size_t offset = filename.find_last_of(".");
/* no extension => consider raw */ /* no extension => consider raw */
if (offset == string::npos) { if (offset == std::string::npos) {
_file_extension = "raw"; _file_extension = "raw";
/* compressed file ? */ /* compressed file ? */
} else if (_file_extension.substr(0, 2) == "gz") { } else if (_file_extension.substr(0, 2) == "gz") {
size_t offset2 = filename.find_last_of(".", offset - 1); size_t offset2 = filename.find_last_of(".", offset - 1);
/* no more extension -> error */ /* no more extension -> error */
if (offset2 == string::npos) { if (offset2 == std::string::npos) {
char mess[256]; char mess[256];
snprintf(mess, sizeof(mess), "\nfile %s is compressed\n" snprintf(mess, sizeof(mess), "\nfile %s is compressed\n"
"but can't determine real type\n" "but can't determine real type\n"
@ -46,7 +45,7 @@ Device::Device(Jtag *jtag, string filename, const string &file_type,
_jtag = jtag; _jtag = jtag;
if (verbose > 0) if (verbose > 0)
cout << "File type : " << _file_extension << endl; std::cout << "File type : " << _file_extension << std::endl;
} }
Device::~Device() {} Device::~Device() {}

View File

@ -21,7 +21,6 @@
#include "dfu.hpp" #include "dfu.hpp"
using namespace std;
/* USB request write */ /* USB request write */
static const uint8_t DFU_REQUEST_OUT = LIBUSB_ENDPOINT_OUT | static const uint8_t DFU_REQUEST_OUT = LIBUSB_ENDPOINT_OUT |
@ -46,7 +45,7 @@ enum dfu_cmd {
* - index as jtag chain (fix issue when more than one device connected) * - index as jtag chain (fix issue when more than one device connected)
*/ */
DFU::DFU(const string &filename, bool bypass_bitstream, DFU::DFU(const std::string &filename, bool bypass_bitstream,
uint16_t vid, uint16_t pid, int16_t altsetting, uint16_t vid, uint16_t pid, int16_t altsetting,
int verbose_lvl):_verbose(verbose_lvl > 0), _debug(verbose_lvl > 1), int verbose_lvl):_verbose(verbose_lvl > 0), _debug(verbose_lvl > 1),
_quiet(verbose_lvl < 0), dev_idx(0), _vid(0), _pid(0), _quiet(verbose_lvl < 0), dev_idx(0), _vid(0), _pid(0),
@ -68,7 +67,7 @@ DFU::DFU(const string &filename, bool bypass_bitstream,
printSuccess("DONE"); printSuccess("DONE");
} catch (std::exception &e) { } catch (std::exception &e) {
printError("FAIL"); printError("FAIL");
throw runtime_error("Error: Fail to open file"); throw std::runtime_error("Error: Fail to open file");
} }
printInfo("Parse file ", false); printInfo("Parse file ", false);
@ -78,7 +77,7 @@ DFU::DFU(const string &filename, bool bypass_bitstream,
} catch (std::exception &e) { } catch (std::exception &e) {
printError("FAIL"); printError("FAIL");
delete _bit; delete _bit;
throw runtime_error("Error: Fail to parse file"); throw std::runtime_error("Error: Fail to parse file");
} }
if (_verbose > 0) if (_verbose > 0)
@ -301,7 +300,7 @@ int DFU::searchDFUDevices()
/* iteration */ /* iteration */
ssize_t list_size = libusb_get_device_list(usb_ctx, &dev_list); ssize_t list_size = libusb_get_device_list(usb_ctx, &dev_list);
if (_verbose) if (_verbose)
printInfo("found " + to_string(list_size) + " USB device"); printInfo("found " + std::to_string(list_size) + " USB device");
while ((usb_dev = dev_list[i++]) != NULL) { while ((usb_dev = dev_list[i++]) != NULL) {
struct libusb_device_descriptor desc; struct libusb_device_descriptor desc;
@ -352,7 +351,7 @@ int DFU::searchIfDFU(struct libusb_device_handle *handle,
struct libusb_config_descriptor *cfg; struct libusb_config_descriptor *cfg;
int ret = libusb_get_config_descriptor(dev, i, &cfg); int ret = libusb_get_config_descriptor(dev, i, &cfg);
if (ret != 0) { if (ret != 0) {
printError("Fail to retrieve config_descriptor " + to_string(i)); printError("Fail to retrieve config_descriptor " + std::to_string(i));
return 1; return 1;
} }
/* configuration interface iteration */ /* configuration interface iteration */
@ -499,7 +498,7 @@ int DFU::set_state(char newState)
return -1; return -1;
if (status.bState != STATE_appDETACH || if (status.bState != STATE_appDETACH ||
status.bStatus != STATUS_OK) { status.bStatus != STATUS_OK) {
cerr << dfu_dev_status_val[status.bStatus] << endl; std::cerr << dfu_dev_status_val[status.bStatus] << std::endl;
return -1; return -1;
} }
break; break;
@ -571,7 +570,7 @@ int DFU::set_state(char newState)
return ret; return ret;
if (status.bState != newState || if (status.bState != newState ||
status.bStatus != STATUS_OK) { status.bStatus != STATUS_OK) {
cerr << dfu_dev_status_val[status.bStatus] << endl; std::cerr << dfu_dev_status_val[status.bStatus] << std::endl;
return -1; return -1;
} }
break; break;
@ -635,7 +634,7 @@ int DFU::poll_state(uint8_t state) {
do { do {
ret = get_status(&status); ret = get_status(&status);
if (ret <= 0) { if (ret <= 0) {
printError("Error: poll state " + string(libusb_error_name(ret))); printError("Error: poll state " + std::string(libusb_error_name(ret)));
break; break;
} }
/* millisecond */ /* millisecond */
@ -800,7 +799,7 @@ int DFU::download()
//ret = set_state(STATE_dfuMANIFEST_SYNC); //ret = set_state(STATE_dfuMANIFEST_SYNC);
ret = send(true, DFU_DNLOAD, transaction, NULL, 0); ret = send(true, DFU_DNLOAD, transaction, NULL, 0);
if (ret < 0) { if (ret < 0) {
printError("Error: fail to change state " + to_string(ret)); printError("Error: fail to change state " + std::to_string(ret));
return -6; return -6;
} }

View File

@ -10,7 +10,6 @@
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include <algorithm>
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
#include <sstream> #include <sstream>
@ -22,7 +21,6 @@
#include "display.hpp" #include "display.hpp"
#include "dfuFileParser.hpp" #include "dfuFileParser.hpp"
using namespace std;
/* USB Device firmware Upgrade Specification, Revision 1.1 B.1 */ /* USB Device firmware Upgrade Specification, Revision 1.1 B.1 */
/* p. 42 */ /* p. 42 */
@ -71,7 +69,7 @@ static const uint32_t crc32tbl[] = {
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d}; 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d};
DFUFileParser::DFUFileParser(const string &filename, bool verbose): DFUFileParser::DFUFileParser(const std::string &filename, bool verbose):
ConfigBitstreamParser(filename, ConfigBitstreamParser::BIN_MODE, verbose), ConfigBitstreamParser(filename, ConfigBitstreamParser::BIN_MODE, verbose),
_bcdDFU(0), _idVendor(0), _idProduct(0), _bcdDevice(0), _bcdDFU(0), _idVendor(0), _idProduct(0), _bcdDevice(0),
_dwCRC(0), _bLength(0) _dwCRC(0), _bLength(0)
@ -81,7 +79,6 @@ DFUFileParser::DFUFileParser(const string &filename, bool verbose):
/* p.40-47 */ /* p.40-47 */
int DFUFileParser::parseHeader() int DFUFileParser::parseHeader()
{ {
string ucDfuSignature;
/* check size: If file size <= 16 /* check size: If file size <= 16
* no space for suffix and/or bitstream * no space for suffix and/or bitstream
* */ * */
@ -89,11 +86,9 @@ int DFUFileParser::parseHeader()
return -1; return -1;
/* first check DFU signature : /* first check DFU signature :
* must be equal to 'DFU' * stored as 'UFD' (reversed 'DFU') in the file
*/ */
ucDfuSignature = _raw_data.substr(_file_size-8, 3); if (_raw_data.compare(_file_size - 8, 3, "UFD") != 0) {
reverse(ucDfuSignature.begin(), ucDfuSignature.end());
if (ucDfuSignature != "DFU") {
if (_verbose) if (_verbose)
printWarn("Not a DFU file"); printWarn("Not a DFU file");
return 0; return 0;
@ -103,41 +98,49 @@ int DFUFileParser::parseHeader()
(((uint32_t)_raw_data[_file_size - 3] & 0xff) << 8) | (((uint32_t)_raw_data[_file_size - 3] & 0xff) << 8) |
(((uint32_t)_raw_data[_file_size - 2] & 0xff) << 16) | (((uint32_t)_raw_data[_file_size - 2] & 0xff) << 16) |
(((uint32_t)_raw_data[_file_size - 1] & 0xff) << 24); (((uint32_t)_raw_data[_file_size - 1] & 0xff) << 24);
_bLength = _raw_data[_file_size - 5]; _bLength = static_cast<uint8_t>(_raw_data[_file_size - 5]);
_bcdDFU = (_raw_data[_file_size - 10] << 0) | if (_bLength > _file_size) {
(_raw_data[_file_size - 9] << 8); printError("Error: invalid DFU suffix length");
_idVendor = (_raw_data[_file_size - 12] << 0) | return -1;
(_raw_data[_file_size - 11] << 8); }
_idProduct = (((uint16_t)_raw_data[_file_size - 14] & 0xff) << 0) | _bcdDFU =
(((uint16_t)_raw_data[_file_size - 13] & 0xff) << 8); (static_cast<uint16_t>(_raw_data[_file_size - 10] & 0xff) << 0) |
_bcdDevice = (_raw_data[_file_size - 16] << 0) | (static_cast<uint16_t>(_raw_data[_file_size - 9] & 0xff) << 8);
(_raw_data[_file_size - 15] << 8); _idVendor =
(static_cast<uint16_t>(_raw_data[_file_size - 12] & 0xff) << 0) |
(static_cast<uint16_t>(_raw_data[_file_size - 11] & 0xff) << 8);
_idProduct =
(static_cast<uint16_t>(_raw_data[_file_size - 14] & 0xff) << 0) |
(static_cast<uint16_t>(_raw_data[_file_size - 13] & 0xff) << 8);
_bcdDevice =
(static_cast<uint16_t>(_raw_data[_file_size - 16] & 0xff) << 0) |
(static_cast<uint16_t>(_raw_data[_file_size - 15] & 0xff) << 8);
/* yes it's silly but it's simpliest way */ /* yes it's silly but it's simpliest way */
_hdr = {{"dwCRC", string(11, ' ')}, {"bLength", ""}, _hdr = {{"dwCRC", std::string(11, ' ')}, {"bLength", ""},
{"ucDfuSignature", string(4, ' ')}, {"bcdDFU", string(7, ' ')}, {"ucDfuSignature", std::string(4, ' ')}, {"bcdDFU", std::string(7, ' ')},
{"idVendor", string(7, ' ')}, {"idProduct", string(7, ' ')}, {"idVendor", std::string(7, ' ')}, {"idProduct", std::string(7, ' ')},
{"bcdDevice", string(7, ' ')}}; {"bcdDevice", std::string(7, ' ')}};
char __buf[16]; char __buf[16];
int __buf_valid_bytes; int __buf_valid_bytes;
__buf_valid_bytes = snprintf(__buf, 11, "0x%08x", _dwCRC); __buf_valid_bytes = snprintf(__buf, 11, "0x%08x", _dwCRC);
_hdr["dwCRC"] = string(__buf, __buf_valid_bytes); _hdr["dwCRC"] = std::string(__buf, __buf_valid_bytes);
_hdr["dwCRC"].resize(11, ' '); _hdr["dwCRC"].resize(11, ' ');
_hdr["bLength"] = to_string(_bLength); _hdr["bLength"] = std::to_string(_bLength);
_hdr["ucDfuSignature"] = ucDfuSignature; _hdr["ucDfuSignature"] = "DFU";
__buf_valid_bytes = snprintf(__buf, 7, "0x%04x", _bcdDFU); __buf_valid_bytes = snprintf(__buf, 7, "0x%04x", _bcdDFU);
_hdr["bcdDFU"] = string(__buf, __buf_valid_bytes); _hdr["bcdDFU"] = std::string(__buf, __buf_valid_bytes);
_hdr["bcdDFU"].resize(7, ' '); _hdr["bcdDFU"].resize(7, ' ');
__buf_valid_bytes = snprintf(__buf, 7, "0x%04x", _idVendor); __buf_valid_bytes = snprintf(__buf, 7, "0x%04x", _idVendor);
_hdr["idVendor"] = string(__buf, __buf_valid_bytes); _hdr["idVendor"] = std::string(__buf, __buf_valid_bytes);
_hdr["idVendor"].resize(7, ' '); _hdr["idVendor"].resize(7, ' ');
__buf_valid_bytes = snprintf(__buf, 7, "0x%04x", _idProduct); __buf_valid_bytes = snprintf(__buf, 7, "0x%04x", _idProduct);
_hdr["idProduct"] = string(__buf, __buf_valid_bytes); _hdr["idProduct"] = std::string(__buf, __buf_valid_bytes);
_hdr["idProduct"].resize(7, ' '); _hdr["idProduct"].resize(7, ' ');
__buf_valid_bytes = snprintf(__buf, 7, "0x%04x", _bcdDevice); __buf_valid_bytes = snprintf(__buf, 7, "0x%04x", _bcdDevice);
_hdr["bcdDevice"] = string(__buf, __buf_valid_bytes); _hdr["bcdDevice"] = std::string(__buf, __buf_valid_bytes);
_hdr["bcdDevice"].resize(7, ' '); _hdr["bcdDevice"].resize(7, ' ');
return 1; return 1;
@ -149,14 +152,13 @@ int DFUFileParser::parse()
if (ret < 0) if (ret < 0)
return EXIT_FAILURE; return EXIT_FAILURE;
_bit_data.resize(_file_size - _bLength); _bit_data.assign(_raw_data.begin(), _raw_data.begin() + (_file_size - _bLength));
std::move(_raw_data.begin(), _raw_data.end(), _bit_data.begin());
/* If file contains suffix check CRC */ /* If file contains suffix check CRC */
if (ret != 0) { if (ret != 0) {
/* check if CRC match content */ /* check if CRC match content */
uint32_t crc = 0xffffffff; uint32_t crc = 0xffffffff;
for (int i = 0; i < _file_size-4; i++) for (int i = 0; i < _file_size - 4; i++)
crc = crc32tbl[(crc ^ (uint8_t)_raw_data[i]) & 0xff] ^ (crc >> 8); crc = crc32tbl[(crc ^ (uint8_t)_raw_data[i]) & 0xff] ^ (crc >> 8);
if (crc != _dwCRC) { if (crc != _dwCRC) {

View File

@ -37,12 +37,12 @@ class DFUFileParser: public ConfigBitstreamParser {
* \brief return vendor id associated * \brief return vendor id associated
* \return _idVendor * \return _idVendor
*/ */
uint16_t vendorID() {return _idVendor;} uint16_t vendorID() const noexcept {return _idVendor;}
/*! /*!
* \brief return product id associated * \brief return product id associated
* \return _idProduct * \return _idProduct
*/ */
uint16_t productID() {return _idProduct;} uint16_t productID() const noexcept {return _idProduct;}
private: private:
/*! /*!

View File

@ -16,7 +16,6 @@
#include "dirtyJtag.hpp" #include "dirtyJtag.hpp"
#include "display.hpp" #include "display.hpp"
using namespace std;
#define DIRTYJTAG_VID 0x1209 #define DIRTYJTAG_VID 0x1209
#define DIRTYJTAG_PID 0xC0CA #define DIRTYJTAG_PID 0xC0CA
@ -52,7 +51,6 @@ struct version_specific
static version_specific v_options[4] ={{0, 240}, {0, 240}, {NO_READ, 496}, static version_specific v_options[4] ={{0, 240}, {0, 240}, {NO_READ, 496},
{NO_READ, 4000}}; {NO_READ, 4000}};
enum dirtyJtagSig { enum dirtyJtagSig {
SIG_TCK = (1 << 1), SIG_TCK = (1 << 1),
SIG_TDI = (1 << 2), SIG_TDI = (1 << 2),
@ -62,47 +60,57 @@ enum dirtyJtagSig {
SIG_SRST = (1 << 6) SIG_SRST = (1 << 6)
}; };
DirtyJtag::DirtyJtag(uint32_t clkHZ, int8_t verbose, uint16_t vid, uint16_t pid): DirtyJtag::DirtyJtag(uint32_t clkHz, int8_t verbose, uint16_t vid, uint16_t pid):
_verbose(verbose), _verbose(verbose),
dev_handle(NULL), usb_ctx(NULL), _tdi(0), _tms(0), _version(0) dev_handle(NULL), usb_ctx(NULL), _tdi(0), _tms(0), _version(0)
{ {
int ret; int ret;
if (libusb_init(&usb_ctx) < 0) { if (libusb_init(&usb_ctx) < 0)
cerr << "libusb init failed" << endl; throw std::runtime_error("DirtyJtag: libusb init failed");
throw std::exception();
}
dev_handle = libusb_open_device_with_vid_pid(usb_ctx, vid, pid); dev_handle = libusb_open_device_with_vid_pid(usb_ctx, vid, pid);
if (!dev_handle) { if (!dev_handle) {
cerr << "fails to open device" << endl;
libusb_exit(usb_ctx); libusb_exit(usb_ctx);
throw std::exception(); throw std::runtime_error("DirtyJtag: fails to open device");
} }
ret = libusb_claim_interface(dev_handle, DIRTYJTAG_INTF); ret = libusb_claim_interface(dev_handle, DIRTYJTAG_INTF);
if (ret) { if (ret) {
cerr << "libusb error while claiming DirtyJTAG interface" << endl;
libusb_close(dev_handle); libusb_close(dev_handle);
dev_handle = NULL;
libusb_exit(usb_ctx); libusb_exit(usb_ctx);
throw std::exception(); usb_ctx = NULL;
throw std::runtime_error("DirtyJtag: libusb error while claiming interface");
} }
if (!getVersion()) if (!getVersion()) {
throw std::runtime_error("Fail to get version"); close_usb();
throw std::runtime_error("DirtyJtag: Fail to get version");
}
if (setClkFreq(clkHZ) < 0) { if (setClkFreq(clkHz) < 0) {
cerr << "Fail to set frequency" << endl; close_usb();
throw std::exception(); throw std::runtime_error("Fail to set frequency");
}
}
void DirtyJtag::close_usb()
{
if (dev_handle) {
libusb_release_interface(dev_handle, DIRTYJTAG_INTF);
libusb_close(dev_handle);
dev_handle = NULL;
}
if (usb_ctx) {
libusb_exit(usb_ctx);
usb_ctx = NULL;
} }
} }
DirtyJtag::~DirtyJtag() DirtyJtag::~DirtyJtag()
{ {
if (dev_handle) close_usb();
libusb_close(dev_handle);
if (usb_ctx)
libusb_exit(usb_ctx);
} }
bool DirtyJtag::getVersion() bool DirtyJtag::getVersion()
@ -115,14 +123,14 @@ bool DirtyJtag::getVersion()
ret = libusb_bulk_transfer(dev_handle, DIRTYJTAG_WRITE_EP, ret = libusb_bulk_transfer(dev_handle, DIRTYJTAG_WRITE_EP,
buf, 2, &actual_length, DIRTYJTAG_TIMEOUT); buf, 2, &actual_length, DIRTYJTAG_TIMEOUT);
if (ret < 0) { if (ret < 0) {
cerr << "getVersion: usb bulk write failed " << ret << endl; std::cerr << "getVersion: usb bulk write failed " << ret << std::endl;
return false; return false;
} }
do { do {
ret = libusb_bulk_transfer(dev_handle, DIRTYJTAG_READ_EP, ret = libusb_bulk_transfer(dev_handle, DIRTYJTAG_READ_EP,
rx_buf, 64, &actual_length, DIRTYJTAG_TIMEOUT); rx_buf, 64, &actual_length, DIRTYJTAG_TIMEOUT);
if (ret < 0) { if (ret < 0) {
cerr << "getVersion: read: usb bulk read failed " << ret << endl; std::cerr << "getVersion: read: usb bulk read failed " << ret << std::endl;
return false; return false;
} }
} while (actual_length == 0); } while (actual_length == 0);
@ -133,40 +141,40 @@ bool DirtyJtag::getVersion()
} else if (!strncmp("DJTAG3\n", (char*)rx_buf, 7)) { } else if (!strncmp("DJTAG3\n", (char*)rx_buf, 7)) {
_version = 3; _version = 3;
} else { } else {
cerr << "dirtyJtag version unknown" << endl; std::cerr << "dirtyJtag version unknown" << std::endl;
_version = 0; _version = 0;
} }
return true; return true;
} }
int DirtyJtag::setClkFreq(uint32_t clkHZ) int DirtyJtag::setClkFreq(uint32_t clkHz)
{ {
int actual_length; int actual_length;
int ret, req_freq = clkHZ; int ret, req_freq = clkHz;
if (clkHZ > 16000000) { if (clkHz > 16000000) {
printWarn("DirtyJTAG probe limited to 16000kHz"); printWarn("DirtyJTAG probe limited to 16000 kHz");
clkHZ = 16000000; clkHz = 16000000;
} }
_clkHZ = clkHZ; _clkHZ = clkHz;
printInfo("Jtag frequency : requested " + std::to_string(req_freq) + printInfo("Jtag frequency : requested " + std::to_string(req_freq) +
"Hz -> real " + std::to_string(clkHZ) + "Hz"); " Hz -> real " + std::to_string(clkHz) + " Hz");
uint8_t buf[] = {CMD_FREQ, uint8_t buf[] = {CMD_FREQ,
static_cast<uint8_t>(0xff & ((clkHZ / 1000) >> 8)), static_cast<uint8_t>(0xff & ((clkHz / 1000) >> 8)),
static_cast<uint8_t>(0xff & ((clkHZ / 1000) )), static_cast<uint8_t>(0xff & ((clkHz / 1000) )),
CMD_STOP}; CMD_STOP};
ret = libusb_bulk_transfer(dev_handle, DIRTYJTAG_WRITE_EP, ret = libusb_bulk_transfer(dev_handle, DIRTYJTAG_WRITE_EP,
buf, 4, &actual_length, DIRTYJTAG_TIMEOUT); buf, 4, &actual_length, DIRTYJTAG_TIMEOUT);
if (ret < 0) { if (ret < 0) {
cerr << "setClkFreq: usb bulk write failed " << ret << endl; std::cerr << "setClkFreq: usb bulk write failed " << ret << std::endl;
return -EXIT_FAILURE; return -EXIT_FAILURE;
} }
return clkHZ; return clkHz;
} }
int DirtyJtag::writeTMS(const uint8_t *tms, uint32_t len, int DirtyJtag::writeTMS(const uint8_t *tms, uint32_t len,
@ -205,7 +213,7 @@ int DirtyJtag::writeTMS(const uint8_t *tms, uint32_t len,
buf, buffer_idx, &actual_length, buf, buffer_idx, &actual_length,
DIRTYJTAG_TIMEOUT); DIRTYJTAG_TIMEOUT);
if (ret < 0) { if (ret < 0) {
cerr << "writeTMS: usb bulk write failed " << ret << endl; std::cerr << "writeTMS: usb bulk write failed " << ret << std::endl;
return -EXIT_FAILURE; return -EXIT_FAILURE;
} }
buffer_idx = 0; buffer_idx = 0;
@ -228,7 +236,7 @@ int DirtyJtag::toggleClk(__attribute__((unused)) uint8_t tms,
int ret = libusb_bulk_transfer(dev_handle, DIRTYJTAG_WRITE_EP, int ret = libusb_bulk_transfer(dev_handle, DIRTYJTAG_WRITE_EP,
buf, 4, &actual_length, DIRTYJTAG_TIMEOUT); buf, 4, &actual_length, DIRTYJTAG_TIMEOUT);
if (ret < 0) { if (ret < 0) {
cerr << "toggleClk: usb bulk write failed " << ret << endl; std::cerr << "toggleClk: usb bulk write failed " << ret << std::endl;
return -EXIT_FAILURE; return -EXIT_FAILURE;
} }
clk_len -= buf[2]; clk_len -= buf[2];
@ -294,11 +302,11 @@ int DirtyJtag::writeTDI(const uint8_t *tx, uint8_t *rx, uint32_t len, bool end)
(unsigned char *)tx_buf, xfer_len, (unsigned char *)tx_buf, xfer_len,
&actual_length, DIRTYJTAG_TIMEOUT); &actual_length, DIRTYJTAG_TIMEOUT);
if ((ret < 0) || (actual_length != xfer_len)) { if ((ret < 0) || (actual_length != xfer_len)) {
cerr << "writeTDI: fill: usb bulk write failed " << ret << std::cerr << "writeTDI: fill: usb bulk write failed " << ret <<
"actual length: " << actual_length << endl; "actual length: " << actual_length << std::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
// cerr << actual_length << ", " << bit_to_send << endl; // std::cerr << actual_length << ", " << bit_to_send << std::endl;
if (rx || (_version <= 1)) { if (rx || (_version <= 1)) {
const int transfer_length = (bit_to_send > 255) ? byte_to_send : 32; const int transfer_length = (bit_to_send > 255) ? byte_to_send : 32;
@ -306,7 +314,7 @@ int DirtyJtag::writeTDI(const uint8_t *tx, uint8_t *rx, uint32_t len, bool end)
ret = libusb_bulk_transfer(dev_handle, DIRTYJTAG_READ_EP, ret = libusb_bulk_transfer(dev_handle, DIRTYJTAG_READ_EP,
rx_buf, transfer_length, &actual_length, DIRTYJTAG_TIMEOUT); rx_buf, transfer_length, &actual_length, DIRTYJTAG_TIMEOUT);
if (ret < 0) { if (ret < 0) {
cerr << "writeTDI: read: usb bulk read failed " << ret << endl; std::cerr << "writeTDI: read: usb bulk read failed " << ret << std::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
} while (actual_length == 0); } while (actual_length == 0);
@ -320,11 +328,11 @@ int DirtyJtag::writeTDI(const uint8_t *tx, uint8_t *rx, uint32_t len, bool end)
} }
/* Last xfer: /* Last xfer:
* if bit_to_send is not a multiple of 8bits a shift must * if bit_to_send is not a multiple of 8bits a shift must
* be applied to align rigth the last Byte * be applied to align right the last Byte
*/ */
if (bit_to_send < max_bit_transfer_length) { if (bit_to_send < max_bit_transfer_length) {
const uint32_t b = (bit_to_send >> 3) << 3; // floor const uint32_t b = (bit_to_send >> 3) << 3; // floor
if (b < bit_to_send) { // difference ? if (b < bit_to_send) { // difference ?
const uint32_t diff = bit_to_send - b; const uint32_t diff = bit_to_send - b;
const uint8_t t = rx_ptr[(rx_cnt-1) >> 3] >> (8 - diff); const uint8_t t = rx_ptr[(rx_cnt-1) >> 3] >> (8 - diff);
rx_ptr[(rx_cnt - 1) >> 3] = t; rx_ptr[(rx_cnt - 1) >> 3] = t;
@ -336,7 +344,7 @@ int DirtyJtag::writeTDI(const uint8_t *tx, uint8_t *rx, uint32_t len, bool end)
tx_ptr += byte_to_send; tx_ptr += byte_to_send;
} }
/* this step exist only with [D|I]R_SHIFT */ /* Final single-bit step used only for DR/IR SHIFT end transitions. */
if (end) { if (end) {
int pos = len-1; int pos = len-1;
uint8_t sig; uint8_t sig;
@ -360,7 +368,7 @@ int DirtyJtag::writeTDI(const uint8_t *tx, uint8_t *rx, uint32_t len, bool end)
if (libusb_bulk_transfer(dev_handle, DIRTYJTAG_WRITE_EP, if (libusb_bulk_transfer(dev_handle, DIRTYJTAG_WRITE_EP,
buf, 8, &actual_length, buf, 8, &actual_length,
DIRTYJTAG_TIMEOUT) < 0) { DIRTYJTAG_TIMEOUT) < 0) {
cerr << "writeTDI: last bit error: usb bulk write failed 1" << endl; std::cerr << "writeTDI: last bit error: usb bulk write failed 1" << std::endl;
return -EXIT_FAILURE; return -EXIT_FAILURE;
} }
@ -368,7 +376,7 @@ int DirtyJtag::writeTDI(const uint8_t *tx, uint8_t *rx, uint32_t len, bool end)
if (libusb_bulk_transfer(dev_handle, DIRTYJTAG_READ_EP, if (libusb_bulk_transfer(dev_handle, DIRTYJTAG_READ_EP,
&sig, 1, &actual_length, &sig, 1, &actual_length,
DIRTYJTAG_TIMEOUT) < 0) { DIRTYJTAG_TIMEOUT) < 0) {
cerr << "writeTDI: last bit error: usb bulk read failed" << endl; std::cerr << "writeTDI: last bit error: usb bulk read failed" << std::endl;
return -EXIT_FAILURE; return -EXIT_FAILURE;
} }
} while (actual_length == 0); } while (actual_length == 0);
@ -381,13 +389,13 @@ int DirtyJtag::writeTDI(const uint8_t *tx, uint8_t *rx, uint32_t len, bool end)
if (libusb_bulk_transfer(dev_handle, DIRTYJTAG_WRITE_EP, if (libusb_bulk_transfer(dev_handle, DIRTYJTAG_WRITE_EP,
buf, 4, &actual_length, buf, 4, &actual_length,
DIRTYJTAG_TIMEOUT) < 0) { DIRTYJTAG_TIMEOUT) < 0) {
cerr << "writeTDI: last bit error: usb bulk write failed 2" << endl; std::cerr << "writeTDI: last bit error: usb bulk write failed 2" << std::endl;
return -EXIT_FAILURE; return -EXIT_FAILURE;
} }
} else { } else {
if (toggleClk(_tms, _tdi, 1)) { if (toggleClk(_tms, _tdi, 1)) {
cerr << "writeTDI: last bit error" << endl; std::cerr << "writeTDI: last bit error" << std::endl;
return -EXIT_FAILURE; return -EXIT_FAILURE;
} }
} }
@ -395,8 +403,8 @@ int DirtyJtag::writeTDI(const uint8_t *tx, uint8_t *rx, uint32_t len, bool end)
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
/* GPIOs */ /* GPIO helpers */
/* Read GPIOs */ /* Read GPIO signal state */
uint8_t DirtyJtag::gpio_get() uint8_t DirtyJtag::gpio_get()
{ {
int actual_length; int actual_length;
@ -437,12 +445,13 @@ bool DirtyJtag::_set_gpio_level(uint8_t gpio, uint8_t val)
return true; return true;
} }
/* update selected gpio */ /* Set selected GPIO bits */
bool DirtyJtag::gpio_set(uint8_t gpio) bool DirtyJtag::gpio_set(uint8_t gpio)
{ {
return _set_gpio_level(gpio, gpio); return _set_gpio_level(gpio, gpio);
} }
/* Clear selected GPIO bits */
bool DirtyJtag::gpio_clear(uint8_t gpio) bool DirtyJtag::gpio_clear(uint8_t gpio)
{ {
return _set_gpio_level(gpio, 0); return _set_gpio_level(gpio, 0);

View File

@ -11,24 +11,45 @@
#include "jtagInterface.hpp" #include "jtagInterface.hpp"
/*! /*!
* \file DirtyJtag.hpp * \file dirtyJtag.hpp
* \class DirtyJtag * \class DirtyJtag
* \brief concrete class between jtag implementation and FTDI capable bitbang mode * \brief concrete class between jtag implementation and DirtyJTAG probe
* \author Gwenhael Goavec-Merou * \author Gwenhael Goavec-Merou
*/ */
class DirtyJtag : public JtagInterface { class DirtyJtag : public JtagInterface {
public: public:
DirtyJtag(uint32_t clkHZ, int8_t verbose, uint16_t vid = 0x1209, uint16_t pid = 0xC0CA); DirtyJtag(uint32_t clkHz, int8_t verbose, uint16_t vid = 0x1209, uint16_t pid = 0xC0CA);
virtual ~DirtyJtag(); virtual ~DirtyJtag();
int setClkFreq(uint32_t clkHZ) override; int setClkFreq(uint32_t clkHz) override;
/* TMS */ /*!
int writeTMS(const uint8_t *tms, uint32_t len, bool flush_buffer, const uint8_t tdi = 1) override; * \brief drive TMS to move in JTAG state machine
/* TDI */ * \param tms serie of TMS state
int writeTDI(const uint8_t *tx, uint8_t *rx, uint32_t len, bool end) override; * \param len number of TMS state
/* clk */ * \param flush_buffer force flushing the buffer
* \param tdi TDI constant value
* \return number of state written
*/
int writeTMS(const uint8_t *tms, uint32_t len, bool flush_buffer, const uint8_t tdi = 1) override;
/*!
* \brief send TDI bits (mainly in shift DR/IR state)
* \param tx array of TDI values (used to write)
* \param rx array of TDO values (used when read)
* \param len number of bit to send/receive
* \param end in JTAG state machine last bit and tms are set in same time
* \return number of bit written and/or read
*/
int writeTDI(const uint8_t *tx, uint8_t *rx, uint32_t len, bool end) override;
/*!
* \brief toggle clock with static tms and tdi
* \param tms state of tms signal
* \param tdo state of tdo signal
* \param clk_len number of clock cycle
* \return number of clock cycle send
*/
int toggleClk(uint8_t tms, uint8_t tdo, uint32_t clk_len) override; int toggleClk(uint8_t tms, uint8_t tdo, uint32_t clk_len) override;
/*! /*!
@ -36,13 +57,12 @@ class DirtyJtag : public JtagInterface {
* \return _buffer_size divided by 2 (two byte for clk) and divided by 8 (one * \return _buffer_size divided by 2 (two byte for clk) and divided by 8 (one
* state == one byte) * state == one byte)
*/ */
int get_buffer_size() override { return 0;} int get_buffer_size() override { return 0; }
bool isFull() override { return false;} bool isFull() override { return false; }
int flush() override; int flush() override;
/* access gpio */
/* read gpio */ /* read gpio */
uint8_t gpio_get(); uint8_t gpio_get();
/* update selected gpio */ /* update selected gpio */
@ -54,11 +74,13 @@ class DirtyJtag : public JtagInterface {
int sendBitBang(uint8_t mask, uint8_t val, uint8_t *read, bool last); int sendBitBang(uint8_t mask, uint8_t val, uint8_t *read, bool last);
bool getVersion(); bool getVersion();
bool _set_gpio_level(uint8_t gpio, uint8_t val); bool _set_gpio_level(uint8_t gpio, uint8_t val);
libusb_device_handle *dev_handle; /* USB */
void close_usb();
libusb_device_handle *dev_handle;
libusb_context *usb_ctx; libusb_context *usb_ctx;
uint8_t _tdi; uint8_t _tdi;
uint8_t _tms; uint8_t _tms;
uint8_t _version; uint8_t _version;

View File

@ -47,7 +47,7 @@ Efinix::Efinix(Jtag* jtag, const std::string &filename,
const std::string &board_name, const std::string &device_package, const std::string &board_name, const std::string &device_package,
const std::string &spiOverJtagPath, bool verify, int8_t verbose): const std::string &spiOverJtagPath, bool verify, int8_t verbose):
Device(jtag, filename, file_type, verify, verbose), Device(jtag, filename, file_type, verify, verbose),
SPIInterface(filename, verbose, 256, false, false, false), FlashInterface(filename, verbose, 256, false, false, false),
_spi(NULL), _rst_pin(0), _done_pin(0), _cs_pin(0), _spi(NULL), _rst_pin(0), _done_pin(0), _cs_pin(0),
_oe_pin(0), _fpga_family(UNKNOWN_FAMILY), _irlen(0), _oe_pin(0), _fpga_family(UNKNOWN_FAMILY), _irlen(0),
_device_package(device_package), _spiOverJtagPath(spiOverJtagPath) _device_package(device_package), _spiOverJtagPath(spiOverJtagPath)
@ -238,7 +238,7 @@ void Efinix::program(unsigned int offset, bool unprotect_flash)
break; break;
case FLASH_MODE: case FLASH_MODE:
if (_jtag) if (_jtag)
ret = SPIInterface::write(offset, const_cast<uint8_t *>(data), ret = FlashInterface::write(offset, const_cast<uint8_t *>(data),
length, unprotect_flash); length, unprotect_flash);
else else
ret = programSPI(offset, data, length, unprotect_flash); ret = programSPI(offset, data, length, unprotect_flash);
@ -257,7 +257,7 @@ void Efinix::program(unsigned int offset, bool unprotect_flash)
bool Efinix::detect_flash() bool Efinix::detect_flash()
{ {
if (_jtag) { if (_jtag) {
return SPIInterface::detect_flash(); return FlashInterface::detect_flash();
} }
#if 0 #if 0
@ -265,7 +265,7 @@ bool Efinix::detect_flash()
* uncomment it and submit a PR! */ * uncomment it and submit a PR! */
_spi->gpio_clear(_rst_pin); _spi->gpio_clear(_rst_pin);
bool rv = reinterpret_cast<SPIInterface *>(_spi)->detect_flash(); bool rv = reinterpret_cast<FlashInterface *>(_spi)->detect_flash();
reset(); reset();
@ -279,8 +279,8 @@ bool Efinix::detect_flash()
bool Efinix::dumpFlash(uint32_t base_addr, uint32_t len) bool Efinix::dumpFlash(uint32_t base_addr, uint32_t len)
{ {
if (_jtag) { if (_jtag) {
SPIInterface::set_filename(_filename); FlashInterface::set_filename(_filename);
return SPIInterface::dump(base_addr, len); return FlashInterface::dump(base_addr, len);
} }
uint32_t timeout = 1000; uint32_t timeout = 1000;
@ -289,7 +289,7 @@ bool Efinix::dumpFlash(uint32_t base_addr, uint32_t len)
/* prepare SPI access */ /* prepare SPI access */
printInfo("Read Flash ", false); printInfo("Read Flash ", false);
try { try {
SPIFlash flash(reinterpret_cast<SPIInterface *>(_spi), false, _verbose); SPIFlash flash(reinterpret_cast<FlashInterface *>(_spi), false, _verbose);
flash.reset(); flash.reset();
flash.power_up(); flash.power_up();
flash.dump(_filename, base_addr, len); flash.dump(_filename, base_addr, len);
@ -322,7 +322,7 @@ bool Efinix::programSPI(unsigned int offset, const uint8_t *data,
bool ret = true; bool ret = true;
_spi->gpio_clear(_rst_pin | _oe_pin); _spi->gpio_clear(_rst_pin | _oe_pin);
SPIFlash flash(reinterpret_cast<SPIInterface *>(_spi), unprotect_flash, SPIFlash flash(reinterpret_cast<FlashInterface *>(_spi), unprotect_flash,
_verbose); _verbose);
flash.reset(); flash.reset();
flash.power_up(); flash.power_up();

View File

@ -12,9 +12,9 @@
#include "ftdiJtagMPSSE.hpp" #include "ftdiJtagMPSSE.hpp"
#include "ftdispi.hpp" #include "ftdispi.hpp"
#include "jtag.hpp" #include "jtag.hpp"
#include "spiInterface.hpp" #include "flashInterface.hpp"
class Efinix: public Device, SPIInterface { class Efinix: public Device, FlashInterface {
public: public:
Efinix(FtdiSpi *spi, const std::string &filename, Efinix(FtdiSpi *spi, const std::string &filename,
const std::string &file_type, const std::string &file_type,

View File

@ -10,19 +10,18 @@
#include "display.hpp" #include "display.hpp"
#include "efinixHexParser.hpp" #include "efinixHexParser.hpp"
using namespace std;
EfinixHexParser::EfinixHexParser(const string &filename): EfinixHexParser::EfinixHexParser(const std::string &filename):
ConfigBitstreamParser(filename, ConfigBitstreamParser::ASCII_MODE, ConfigBitstreamParser(filename, ConfigBitstreamParser::ASCII_MODE,
false) false)
{} {}
int EfinixHexParser::parseHeader() int EfinixHexParser::parseHeader()
{ {
string buffer; std::string buffer;
istringstream lineStream(_raw_data); std::istringstream lineStream(_raw_data);
int bytesRead = 0; int bytesRead = 0;
string headerText; std::string headerText;
bool foundPaddedBits = false; bool foundPaddedBits = false;
while (std::getline(lineStream, buffer, '\n')) { while (std::getline(lineStream, buffer, '\n')) {
@ -40,20 +39,20 @@ int EfinixHexParser::parseHeader()
break; break;
} }
if (headerText.find("PADDED_BITS") != string::npos) if (headerText.find("PADDED_BITS") != std::string::npos)
foundPaddedBits = true; foundPaddedBits = true;
} }
size_t pos; size_t pos;
if ((pos = headerText.find("Mode: ")) != string::npos) { if ((pos = headerText.find("Mode: ")) != std::string::npos) {
size_t end = headerText.find('\n', pos); size_t end = headerText.find('\n', pos);
_hdr["mode"] = headerText.substr(pos + 6, end - pos - 6); _hdr["mode"] = headerText.substr(pos + 6, end - pos - 6);
} }
if ((pos = headerText.find("Width: ")) != string::npos) { if ((pos = headerText.find("Width: ")) != std::string::npos) {
size_t end = headerText.find('\n', pos); size_t end = headerText.find('\n', pos);
_hdr["width"] = headerText.substr(pos + 7, end - pos - 7); _hdr["width"] = headerText.substr(pos + 7, end - pos - 7);
} }
if ((pos = headerText.find("Device: ")) != string::npos) { if ((pos = headerText.find("Device: ")) != std::string::npos) {
size_t end = headerText.find('\n', pos); size_t end = headerText.find('\n', pos);
_hdr["device"] = headerText.substr(pos + 8, end - pos - 8); _hdr["device"] = headerText.substr(pos + 8, end - pos - 8);
} }
@ -63,10 +62,10 @@ int EfinixHexParser::parseHeader()
int EfinixHexParser::parse() int EfinixHexParser::parse()
{ {
string buffer; std::string buffer;
parseHeader(); parseHeader();
istringstream lineStream(_raw_data); std::istringstream lineStream(_raw_data);
while (std::getline(lineStream, buffer, '\n')) { while (std::getline(lineStream, buffer, '\n')) {
_bit_data.push_back(std::stol(buffer, nullptr, 16)); _bit_data.push_back(std::stol(buffer, nullptr, 16));

View File

@ -1,77 +0,0 @@
// SPDX-License-Identifier: Apache-2.0
/*
* Copyright (C) 2019 Gwenhael Goavec-Merou <gwenhael.goavec-merou@trabucayre.com>
*/
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include "epcq.hpp"
#define RD_STATUS_REG 0x05
# define STATUS_REG_WEL (0x01 << 1)
# define STATUS_REG_WIP (0x01 << 0)
#define RD_BYTE_REG 0x03
#define RD_DEV_ID_REG 0x9F
#define RD_SILICON_ID_REG 0xAB
#define RD_FAST_READ_REG 0x0B
/* TBD */
#define WR_ENABLE_REG 0x06
#define WR_DISABLE_REG 0x04
#define WR_STATUS_REG 0x01
#define WR_BYTES_REG 0x02
/* TBD */
#define ERASE_BULK_REG 0xC7
#define ERASE_SECTOR_REG 0xD8
#define ERASE_SUBSECTOR_REG 0x20
#define RD_SFDP_REG_REG 0x5A
#define SECTOR_SIZE 65536
void EPCQ::dumpJICFile(char *jic_file, char *out_file, size_t max_len)
{
int offset = 0xA1;
unsigned char c;
size_t i = 0;
FILE *jic = fopen(jic_file, "r");
fseek(jic, offset, SEEK_SET);
FILE *out = fopen(out_file, "w");
for (i=0; i < max_len && (1 == fread(&c, 1, 1, jic)); i++) {
fprintf(out, "%zx %x\n", i, c);
}
fclose(jic);
fclose(out);
}
void EPCQ::read_id()
{
unsigned char rx_buf[5];
/* read EPCQ device id */
/* 2 dummy_byte + 1byte */
_spi->spi_put(0x9F, NULL, rx_buf, 3);
_device_id = rx_buf[2];
if (_verbose)
printf("device id 0x%x attendu 0x15\n", _device_id);
/* read EPCQ silicon id */
/* 3 dummy_byte + 1 byte*/
_spi->spi_put(0xAB, NULL, rx_buf, 4);
_silicon_id = rx_buf[3];
if (_verbose)
printf("silicon id 0x%x attendu 0x14\n", _silicon_id);
}
void EPCQ::reset()
{
printf("reset\n");
_spi->spi_put(0x66, NULL, NULL, 0);
_spi->spi_put(0x99, NULL, NULL, 0);
}
EPCQ::EPCQ(SPIInterface *spi, bool unprotect_flash, int8_t verbose):
SPIFlash(spi, unprotect_flash, verbose), _device_id(0), _silicon_id(0)
{}
EPCQ::~EPCQ()
{}

View File

@ -1,41 +0,0 @@
// SPDX-License-Identifier: Apache-2.0
/*
* Copyright (C) 2019 Gwenhael Goavec-Merou <gwenhael.goavec-merou@trabucayre.com>
*/
#ifndef SRC_EPCQ_HPP_
#define SRC_EPCQ_HPP_
#include <cstdint>
#include <iostream>
#include <vector>
#include "spiInterface.hpp"
#include "spiFlash.hpp"
using namespace std;
class EPCQ: public SPIFlash {
public:
EPCQ(SPIInterface *spi, bool unprotect_flash, int8_t verbose);
~EPCQ();
void read_id() override;
void reset() override;
/* not supported */
void power_up() override {}
void power_down() override {}
private:
unsigned char convertLSB(unsigned char src);
/* trash */
void dumpJICFile(char *jic_file, char *out_file, size_t max_len);
unsigned char _device_id;
unsigned char _silicon_id;
};
#endif // SRC_EPCQ_HPP_

View File

@ -1,279 +0,0 @@
// SPDX-License-Identifier: Apache-2.0
/*
* Copyright (C) 2019 Gwenhael Goavec-Merou <gwenhael.goavec-merou@trabucayre.com>
*/
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include "epcq2.hpp"
#define RD_STATUS_REG 0x05
# define STATUS_REG_WEL (0x01 << 1)
# define STATUS_REG_WIP (0x01 << 0)
#define RD_BYTE_REG 0x03
#define RD_DEV_ID_REG 0x9F
#define RD_SILICON_ID_REG 0xAB
#define RD_FAST_READ_REG 0x0B
/* TBD */
#define WR_ENABLE_REG 0x06
#define WR_DISABLE_REG 0x04
#define WR_STATUS_REG 0x01
#define WR_BYTES_REG 0x02
/* TBD */
#define ERASE_BULK_REG 0xC7
#define ERASE_SECTOR_REG 0xD8
#define ERASE_SUBSECTOR_REG 0x20
#define RD_SFDP_REG_REG 0x5A
#define SECTOR_SIZE 65536
/* EPCQ wait for LSB first data
* so we simply reconstruct a new char with reverse
*/
unsigned char EPCQ::convertLSB(unsigned char src)
{
unsigned char res = 0;
for (int i=0; i < 8; i++)
res = (res << 1) | ((src >> i) & 0x01);
return res;
}
/* wait for WEL goes high by reading
* status register in a loop
*/
#if 0
void EPCQ::wait_wel()
{
uint8_t cmd = RD_STATUS_REG, recv;
_spi.setCSmode(FtdiSpi::SPI_CS_MANUAL);
_spi.clearCs();
_spi.ft2232_spi_wr_and_rd(1, &cmd, NULL);
do {
_spi.ft2232_spi_wr_and_rd(1, NULL, &recv);
} while(!(recv & STATUS_REG_WEL));
_spi.setCs();
_spi.setCSmode(FtdiSpi::SPI_CS_AUTO);
}
#endif
/* wait for WIP goes low by reading
* status register in a loop
*/
#if 0
void EPCQ::wait_wip()
{
uint8_t cmd = RD_STATUS_REG, recv;
_spi.setCSmode( FtdiSpi::SPI_CS_MANUAL);
_spi.clearCs();
_spi.ft2232_spi_wr_and_rd(1, &cmd, NULL);
do {
_spi.ft2232_spi_wr_and_rd(1, NULL, &recv);
} while(0x00 != (recv & STATUS_REG_WIP));
_spi.setCs();
_spi.setCSmode( FtdiSpi::SPI_CS_AUTO);
}
#endif
/* enable write enable */
#if 0
int EPCQ::do_write_enable()
{
uint8_t cmd;
cmd = WR_ENABLE_REG;
_spi.ft2232_spi_wr_and_rd(1, &cmd, NULL);
wait_wel();
return 0;
}
#endif
/* currently we erase sector but it's possible to
* do sector + subsector to reduce erase
*/
#if 0
int EPCQ::erase_sector(char start_sector, char nb_sectors)
{
uint8_t buffer[4] = {ERASE_SECTOR_REG, 0, 0, 0};
uint32_t base_addr = start_sector * SECTOR_SIZE;
/* 1. enable write
* 2. send opcode + address in targeted sector
* 3. wait for end.
*/
printf("erase %d sectors\n", nb_sectors);
for (base_addr = start_sector * SECTOR_SIZE; nb_sectors >= 0; nb_sectors--, base_addr += SECTOR_SIZE) {
/* allow write */
do_write_enable();
/* send addr in the current sector */
buffer[1] = (base_addr >> 16) & 0xff;
buffer[2] = (base_addr >> 8) & 0x0ff;
buffer[3] = (base_addr) & 0x0ff;
printf("%d %d %x %x %x %x ", nb_sectors, base_addr, buffer[0], buffer[1], buffer[2], buffer[3]);
if (_spi.ft2232_spi_wr_and_rd(4, buffer, NULL) < 0) {
cout << "Write error in erase_sector\n" << endl;
return -1;
}
/* read status reg, wait for WIP goes low */
wait_wip();
printf("sector %d ok\n", nb_sectors);
}
printf("erase : end\n");
return 0;
}
#endif
/* write must be do by 256bytes. Before writing next 256bytes we must
* wait for WIP goes low
*/
#if 0
void EPCQ::program(unsigned int start_offset, string filename, bool reverse)
{
FILE *fd;
int file_size, nb_sect, i, ii;
unsigned char buffer[256 + 4], rd_buffer[256], start_sector;
int nb_iter, len, nb_read, offset = start_offset;
/* 1. we need to know the size of the bistream
* 2. according to the same we compute number of sector needed
* 3. we erase sectors
* 4. we write new content
*/
fd = fopen(filename.c_str(), "r");
if (!fd) {
cout << "Error opening " << filename << endl;
return;
}
fseek(fd, 0, SEEK_END);
file_size = ftell(fd);
fseek(fd, 0, SEEK_SET);
/* compute number of sector used */
nb_sect = file_size / SECTOR_SIZE;
nb_sect += ((file_size % SECTOR_SIZE) ? 1 : 0);
/* compute number of iterations */
nb_iter = file_size / 256;
nb_iter += ((file_size % 256) ? 1 : 0);
len = file_size;
/* compute start sector */
start_sector = start_offset / SECTOR_SIZE;
printf("erase %d sectors starting at 0x%x (sector %d)\n", nb_sect, offset, start_sector);
erase_sector(start_sector, (char)nb_sect);
/* now start programming */
if (_verbose) {
printf("program in ");
if (reverse)
printf("reverse mode\n");
else
printf("direct mode\n");
}
buffer[0] = WR_BYTES_REG;
for (i= 0; i < nb_iter; i++) {
do_write_enable();
nb_read = fread(rd_buffer, 1, 256, fd);
if (nb_read == 0) {
printf("problem reading the source file\n");
break;
}
buffer[1] = (offset >> 16) & 0xff;
buffer[2] = (offset >> 8) & 0xff;
buffer[3] = offset & 0xff;
memcpy(&buffer[4], rd_buffer, nb_read);
for (ii= 0; ii < nb_read; ii++)
buffer[ii+4] = (reverse) ? convertLSB(rd_buffer[ii]):rd_buffer[ii];
_spi.ft2232_spi_wr_and_rd(nb_read+4, buffer, NULL);
wait_wip();
len -= nb_read;
offset += nb_read;
if ((i % 10) == 0)
printf("%s sector done len %d %d %d\n", __func__, len, i, nb_iter);
}
fclose(fd);
}
#endif
void EPCQ::dumpJICFile(char *jic_file, char *out_file, size_t max_len)
{
int offset = 0xA1;
unsigned char c;
size_t i=0;
FILE *jic = fopen(jic_file, "r");
fseek(jic, offset, SEEK_SET);
FILE *out = fopen(out_file, "w");
for (i=0; i < max_len && (1 == fread(&c, 1, 1, jic)); i++) {
fprintf(out, "%zx %x\n", i, c);
}
fclose(jic);
fclose(out);
}
#if 0
void EPCQ::dumpflash(char *dest_file, int size)
{
(void)size;
(void)dest_file;
int i;
unsigned char tx_buf[5] = {RD_FAST_READ_REG, 0, 0, 0, 0};
/* 1 byte cmd + 3 byte addr + 8 dummy clk cycle -> 1 byte */
int realByteToRead = 2097380;
realByteToRead = 0x1FFFFF;
realByteToRead = 718569;
unsigned char big_buf[realByteToRead];
_spi.ft2232_spi_wr_then_rd(tx_buf, 5, big_buf, realByteToRead);
FILE *fd = fopen("flash_dump.dd", "w");
FILE *fd_txt = fopen("flash_dump.txt", "w");
unsigned char c;
for (i=0; i<realByteToRead; i++) {
c = convertLSB(big_buf[i]);
fwrite(&c, 1, 1, fd);
fprintf(fd_txt, "%x %x\n", i, c);
}
fclose(fd);
fclose(fd_txt);
}
#endif
void EPCQ::read_id()
{
unsigned char tx_buf[5];
unsigned char rx_buf[5];
/* read EPCQ device id */
tx_buf[0] = 0x9f;
/* 2 dummy_byte + 1byte */
_spi->spi_put(0x9F, NULL, rx_buf, 3);
_device_id = rx_buf[2];
if (_verbose)
printf("device id 0x%x expected 0x15\n", _device_id);
/* read EPCQ silicon id */
//tx_buf[0] = 0xAB;
/* 3 dummy_byte + 1 byte*/
_spi->spi_put(0xAB, NULL, rx_buf, 4);
_silicon_id = rx_buf[3];
if (_verbose)
printf("silicon id 0x%x expected 0x14\n", _silicon_id);
}
EPCQ::EPCQ(SPIInterface *spi, int8_t verbose):SPIFlash(spi, verbose)
{}
EPCQ::~EPCQ()
{}

View File

@ -1,39 +0,0 @@
// SPDX-License-Identifier: Apache-2.0
/*
* Copyright (C) 2019 Gwenhael Goavec-Merou <gwenhael.goavec-merou@trabucayre.com>
*/
#include <iostream>
#include <vector>
#include "spiInterface.hpp"
#include "spiFlash.hpp"
using namespace std;
class EPCQ: public SPIFlash {
public:
EPCQ(SPIInterface *spi, int8_t verbose);
~EPCQ();
void read_id() override;
//void program(unsigned int start_offset, string filename, bool reverse=true);
//int erase_sector(char start_sector, char nb_sectors);
//void dumpflash(char *dest_file, int size);
/* not supported */
virtual void power_up() override {}
virtual void power_down() override {}
private:
unsigned char convertLSB(unsigned char src);
//void wait_wel();
//void wait_wip();
//int do_write_enable();
/* trash */
void dumpJICFile(char *jic_file, char *out_file, size_t max_len);
unsigned char _device_id;
unsigned char _silicon_id;
};

View File

@ -113,7 +113,6 @@ this description is a copy from openocd/src/jtag/drivers/esp_usb_jtag.c
#include "esp_usb_jtag.hpp" #include "esp_usb_jtag.hpp"
#include "display.hpp" #include "display.hpp"
using namespace std;
#define ESPUSBJTAG_VID 0x303A #define ESPUSBJTAG_VID 0x303A
#define ESPUSBJTAG_PID 0x1001 #define ESPUSBJTAG_PID 0x1001
@ -257,7 +256,7 @@ esp_usb_jtag::esp_usb_jtag(uint32_t clkHZ, int8_t verbose, int vid = ESPUSBJTAG_
char mess[256]; char mess[256];
if (libusb_init(&usb_ctx) < 0) { if (libusb_init(&usb_ctx) < 0) {
cerr << "libusb init failed" << endl; std::cerr << "libusb init failed" << std::endl;
throw std::exception(); throw std::exception();
} }
@ -282,7 +281,7 @@ esp_usb_jtag::esp_usb_jtag(uint32_t clkHZ, int8_t verbose, int vid = ESPUSBJTAG_
ret = libusb_claim_interface(dev_handle, ESPUSBJTAG_INTF); ret = libusb_claim_interface(dev_handle, ESPUSBJTAG_INTF);
if (ret) { if (ret) {
cerr << "libusb error while claiming esp_usb_jtag interface of device vid:pid 0x" << std::hex << vid << ":0x" << std::hex << pid << endl; std::cerr << "libusb error while claiming esp_usb_jtag interface of device vid:pid 0x" << std::hex << vid << ":0x" << std::hex << pid << std::endl;
libusb_close(dev_handle); libusb_close(dev_handle);
libusb_exit(usb_ctx); libusb_exit(usb_ctx);
throw std::exception(); throw std::exception();
@ -293,7 +292,7 @@ esp_usb_jtag::esp_usb_jtag(uint32_t clkHZ, int8_t verbose, int vid = ESPUSBJTAG_
throw std::runtime_error("Fail to get version"); throw std::runtime_error("Fail to get version");
if (setClkFreq(clkHZ) < 0) { if (setClkFreq(clkHZ) < 0) {
cerr << "Fail to set frequency" << endl; std::cerr << "Fail to set frequency" << std::endl;
throw std::exception(); throw std::exception();
} }
} }
@ -331,8 +330,8 @@ bool esp_usb_jtag::getVersion()
} }
for(int i = 0; i < jtag_caps_read_len; i++) for(int i = 0; i < jtag_caps_read_len; i++)
cerr << " 0x" << std::hex << (int)(jtag_caps_desc[i]); std::cerr << " 0x" << std::hex << (int)(jtag_caps_desc[i]);
cerr << endl; std::cerr << std::endl;
_base_speed_khz = UINT32_MAX; _base_speed_khz = UINT32_MAX;
_div_min = 1; _div_min = 1;
@ -342,20 +341,20 @@ bool esp_usb_jtag::getVersion()
VEND_DESCR_BUILTIN_JTAG_CAPS ? JTAG_BUILTIN_DESCR_START_OFF : JTAG_EUB_DESCR_START_OFF; VEND_DESCR_BUILTIN_JTAG_CAPS ? JTAG_BUILTIN_DESCR_START_OFF : JTAG_EUB_DESCR_START_OFF;
if (p + sizeof(struct jtag_proto_caps_hdr) > (unsigned int)jtag_caps_read_len) { if (p + sizeof(struct jtag_proto_caps_hdr) > (unsigned int)jtag_caps_read_len) {
cerr << "esp_usb_jtag: not enough data to get header" << endl; std::cerr << "esp_usb_jtag: not enough data to get header" << std::endl;
// goto out; // goto out;
} }
struct jtag_proto_caps_hdr *hdr = (struct jtag_proto_caps_hdr *)&jtag_caps_desc[p]; struct jtag_proto_caps_hdr *hdr = (struct jtag_proto_caps_hdr *)&jtag_caps_desc[p];
if (hdr->proto_ver != JTAG_PROTO_CAPS_VER) { if (hdr->proto_ver != JTAG_PROTO_CAPS_VER) {
cerr << "esp_usb_jtag: unknown jtag_caps descriptor version 0x" << std::hex std::cerr << "esp_usb_jtag: unknown jtag_caps descriptor version 0x" << std::hex
<< hdr->proto_ver << endl; << hdr->proto_ver << std::endl;
// goto out; // goto out;
} }
if (hdr->length > jtag_caps_read_len) { if (hdr->length > jtag_caps_read_len) {
cerr << "esp_usb_jtag: header length (" << hdr->length std::cerr << "esp_usb_jtag: header length (" << hdr->length
<< ") bigger then max read bytes (" << jtag_caps_read_len << ") bigger then max read bytes (" << jtag_caps_read_len
<< ")" << endl; << ")" << std::endl;
// goto out; // goto out;
} }
@ -367,7 +366,7 @@ bool esp_usb_jtag::getVersion()
struct jtag_gen_hdr *dhdr = (struct jtag_gen_hdr *)&jtag_caps_desc[p]; struct jtag_gen_hdr *dhdr = (struct jtag_gen_hdr *)&jtag_caps_desc[p];
if (dhdr->type == JTAG_PROTO_CAPS_SPEED_APB_TYPE) { if (dhdr->type == JTAG_PROTO_CAPS_SPEED_APB_TYPE) {
if (p + sizeof(struct jtag_proto_caps_speed_apb) < hdr->length) { if (p + sizeof(struct jtag_proto_caps_speed_apb) < hdr->length) {
cerr << "esp_usb_jtag: not enough data to get caps speed" << endl; std::cerr << "esp_usb_jtag: not enough data to get caps speed" << std::endl;
return false; return false;
} }
struct jtag_proto_caps_speed_apb *spcap = (struct jtag_proto_caps_speed_apb *)dhdr; struct jtag_proto_caps_speed_apb *spcap = (struct jtag_proto_caps_speed_apb *)dhdr;
@ -378,15 +377,15 @@ bool esp_usb_jtag::getVersion()
/* TODO: mark in priv that this is apb-derived and as such may change if apb /* TODO: mark in priv that this is apb-derived and as such may change if apb
* ever changes? */ * ever changes? */
} else { } else {
cerr << "esp_usb_jtag: unknown caps type 0x" << dhdr->type << endl;; std::cerr << "esp_usb_jtag: unknown caps type 0x" << dhdr->type << std::endl;;
} }
p += dhdr->length; p += dhdr->length;
} }
if (priv->base_speed_khz == UINT32_MAX) { if (priv->base_speed_khz == UINT32_MAX) {
cerr << "esp_usb_jtag: No speed caps found... using sane-ish defaults." << endl; std::cerr << "esp_usb_jtag: No speed caps found... using sane-ish defaults." << std::endl;
_base_speed_khz = 1000; _base_speed_khz = 1000;
} }
cerr << "esp_usb_jtag: Device found. Base speed " << std::dec << _base_speed_khz << " KHz, div range " << (int)_div_min << " to " << (int)_div_max << endl; std::cerr << "esp_usb_jtag: Device found. Base speed " << std::dec << _base_speed_khz << " KHz, div range " << (int)_div_min << " to " << (int)_div_max << std::endl;
_version = 1; // currently only protocol version 1 exists _version = 1; // currently only protocol version 1 exists
@ -434,7 +433,7 @@ int esp_usb_jtag::setClkFreq(uint32_t clkHZ)
/*timeout ms*/ ESPUSBJTAG_TIMEOUT_MS); /*timeout ms*/ ESPUSBJTAG_TIMEOUT_MS);
if (ret != 0) { if (ret != 0) {
cerr << "setClkFreq: usb bulk write failed " << ret << endl; std::cerr << "setClkFreq: usb bulk write failed " << ret << std::endl;
return -EXIT_FAILURE; return -EXIT_FAILURE;
} }
@ -503,7 +502,7 @@ int esp_usb_jtag::writeTMS(const uint8_t *tms, uint32_t len, bool flush_buffer,
return -EXIT_FAILURE; return -EXIT_FAILURE;
} }
if (_verbose) if (_verbose)
cerr << "tms" << endl; std::cerr << "tms" << std::endl;
} }
return len; return len;
@ -579,11 +578,11 @@ int esp_usb_jtag::setio(int srst, int tms, int tdi, int tck)
/*timeout ms*/ ESPUSBJTAG_TIMEOUT_MS); /*timeout ms*/ ESPUSBJTAG_TIMEOUT_MS);
if (ret != 0) { if (ret != 0) {
cerr << "setio: control write failed " << ret << endl; std::cerr << "setio: control write failed " << ret << std::endl;
return -EXIT_FAILURE; return -EXIT_FAILURE;
} }
if (_verbose) if (_verbose)
cerr << "setio 0x" << std::hex << wvalue << endl; std::cerr << "setio 0x" << std::hex << wvalue << std::endl;
return 0; return 0;
} }
@ -708,12 +707,12 @@ int esp_usb_jtag::writeTDI(const uint8_t *tx, uint8_t *rx, uint32_t len, bool en
// last byte in buf will have data in both nibbles, no flush // last byte in buf will have data in both nibbles, no flush
// exec order: high-nibble-first, low-nibble-second // exec order: high-nibble-first, low-nibble-second
if (_verbose) { if (_verbose) {
cerr << "is high nibble=" << (int)is_high_nibble << endl; std::cerr << "is high nibble=" << (int)is_high_nibble << std::endl;
//int bits_in_tx_buf = 0; //int bits_in_tx_buf = 0;
for(uint32_t i = 0; i < (len + 7) >> 3; i++) for(uint32_t i = 0; i < (len + 7) >> 3; i++)
cerr << " " << std::hex << (int)tdi[i]; std::cerr << " " << std::hex << (int)tdi[i];
cerr << endl; std::cerr << std::endl;
cerr << "tdi_bits "; std::cerr << "tdi_bits ";
} }
for (uint32_t pos = 0; pos < len; pos += xfer_len) { for (uint32_t pos = 0; pos < len; pos += xfer_len) {
@ -739,7 +738,7 @@ int esp_usb_jtag::writeTDI(const uint8_t *tx, uint8_t *rx, uint32_t len, bool en
uint32_t curr_pos = pos + i; uint32_t curr_pos = pos + i;
_tdi = (tdi[curr_pos >> 3] >> (curr_pos & 7)) & 1; // get i'th bit from rx _tdi = (tdi[curr_pos >> 3] >> (curr_pos & 7)) & 1; // get i'th bit from rx
if (_verbose) if (_verbose)
cerr << (int)_tdi; std::cerr << (int)_tdi;
if (end && curr_pos == len - 1) if (end && curr_pos == len - 1)
_tms = 1; _tms = 1;
const uint8_t cmd = CMD_CLK(tdo, _tdi, _tms); // with TDO capture const uint8_t cmd = CMD_CLK(tdo, _tdi, _tms); // with TDO capture
@ -768,7 +767,7 @@ int esp_usb_jtag::writeTDI(const uint8_t *tx, uint8_t *rx, uint32_t len, bool en
return -EXIT_FAILURE; return -EXIT_FAILURE;
} }
if (_verbose) if (_verbose)
cerr << "writeTDI write 0x" << tx_buffer_idx << " bytes" << endl; std::cerr << "writeTDI write 0x" << tx_buffer_idx << " bytes" << std::endl;
if (rx) { if (rx) {
flush(); // must flush before reading flush(); // must flush before reading
// TODO support odd len for TDO // TODO support odd len for TDO
@ -788,7 +787,7 @@ int esp_usb_jtag::writeTDI(const uint8_t *tx, uint8_t *rx, uint32_t len, bool en
nb_try++; nb_try++;
} while (nb_try < 3 && ret == 0); } while (nb_try < 3 && ret == 0);
if (_verbose) if (_verbose)
cerr << "writeTDI read " << std::to_string(ret) << endl; std::cerr << "writeTDI read " << std::to_string(ret) << std::endl;
if (read_byte_len != ret) { if (read_byte_len != ret) {
snprintf(mess, 256, "writeTDI: usb bulk read expected=%d received=%d", read_byte_len, ret); snprintf(mess, 256, "writeTDI: usb bulk read expected=%d received=%d", read_byte_len, ret);
printError(mess); printError(mess);

View File

@ -63,9 +63,8 @@
# define FEATURE_CORE_CLK_SEL (0x03 << 30) /* Core Clock Sel */ # define FEATURE_CORE_CLK_SEL (0x03 << 30) /* Core Clock Sel */
using namespace std;
FeaParser::FeaParser(const string &filename, bool verbose): FeaParser::FeaParser(const std::string &filename, bool verbose):
ConfigBitstreamParser(filename, ConfigBitstreamParser::BIN_MODE, verbose), ConfigBitstreamParser(filename, ConfigBitstreamParser::BIN_MODE, verbose),
_feabits(0), _has_feabits(false) _feabits(0), _has_feabits(false)
{ {
@ -76,14 +75,14 @@ FeaParser::FeaParser(const string &filename, bool verbose):
/* fill a vector with consecutive lines, beginning with 0 or 1, until EOF /* fill a vector with consecutive lines, beginning with 0 or 1, until EOF
* \brief read a line with '\r''\n' or '\n' termination * \brief read a line with '\r''\n' or '\n' termination
* check if last char is '\r' * check if last char is '\r'
* \return a vector of lines without [\r]\n * \return a std::vector of lines without [\r]\n
*/ */
vector<string> FeaParser::readFeaFile() std::vector<std::string> FeaParser::readFeaFile()
{ {
vector<string> lines; std::vector<std::string> lines;
while (true) { while (true) {
string buffer; std::string buffer;
std::getline(_ss, buffer, '\n'); std::getline(_ss, buffer, '\n');
if (buffer.empty()) if (buffer.empty())
break; break;
@ -230,16 +229,16 @@ void FeaParser::displayHeader()
* 1: xxxx\n : feature Row (96 bits) * 1: xxxx\n : feature Row (96 bits)
* 2: yyyy*\n : feabits (32 bits) * 2: yyyy*\n : feabits (32 bits)
*/ */
void FeaParser::parseFeatureRowAndFeabits(const vector<string> &content) void FeaParser::parseFeatureRowAndFeabits(const std::vector<std::string> &content)
{ {
printf("Parsing Feature Row & FEAbits...\n"); printf("Parsing Feature Row & FEAbits...\n");
string featuresRow = content[0]; std::string featuresRow = content[0];
//printf("Features: [%s]\n", featuresRow.c_str()); //printf("Features: [%s]\n", featuresRow.c_str());
for (size_t i = 0; i < featuresRow.size(); i++) for (size_t i = 0; i < featuresRow.size(); i++)
_featuresRow[3 - (i/32) - 1] |= ((featuresRow[i] - '0') << (32 - (i%32) - 1)); _featuresRow[3 - (i/32) - 1] |= ((featuresRow[i] - '0') << (32 - (i%32) - 1));
string feabits = content[1]; std::string feabits = content[1];
//printf("Feabits: [%s]\n", feabits.c_str()); //printf("Feabits: [%s]\n", feabits.c_str());
_feabits = 0; _feabits = 0;
for (size_t i = 0; i < feabits.size(); i++) { for (size_t i = 0; i < feabits.size(); i++) {
@ -249,7 +248,7 @@ void FeaParser::parseFeatureRowAndFeabits(const vector<string> &content)
int FeaParser::parse() int FeaParser::parse()
{ {
std::vector<string>lines; std::vector<std::string>lines;
_ss.str(_raw_data); _ss.str(_raw_data);

View File

@ -7,14 +7,14 @@
#include <vector> #include <vector>
#include "display.hpp" #include "display.hpp"
#include "spiInterface.hpp" #include "flashInterface.hpp"
#include "spiFlash.hpp" #include "spiFlash.hpp"
SPIInterface::SPIInterface():_spif_verbose(0), _spif_rd_burst(0), FlashInterface::FlashInterface():_spif_verbose(0), _spif_rd_burst(0),
_spif_verify(false), _skip_load_bridge(false) _spif_verify(false), _skip_load_bridge(false)
{} {}
SPIInterface::SPIInterface(const std::string &filename, int8_t verbose, FlashInterface::FlashInterface(const std::string &filename, int8_t verbose,
uint32_t rd_burst, bool verify, bool skip_load_bridge, uint32_t rd_burst, bool verify, bool skip_load_bridge,
bool skip_reset): bool skip_reset):
_spif_verbose(verbose), _spif_rd_burst(rd_burst), _spif_verbose(verbose), _spif_rd_burst(rd_burst),
@ -23,7 +23,7 @@ SPIInterface::SPIInterface(const std::string &filename, int8_t verbose,
{} {}
/* spiFlash generic acces */ /* spiFlash generic acces */
bool SPIInterface::detect_flash() bool FlashInterface::detect_flash()
{ {
bool ret = true; bool ret = true;
@ -53,7 +53,7 @@ bool SPIInterface::detect_flash()
return post_flash_access() && ret; return post_flash_access() && ret;
} }
bool SPIInterface::protect_flash(uint32_t len) bool FlashInterface::protect_flash(uint32_t len)
{ {
bool ret = true; bool ret = true;
printInfo("protect_flash:"); printInfo("protect_flash:");
@ -84,7 +84,7 @@ bool SPIInterface::protect_flash(uint32_t len)
return post_flash_access() && ret; return post_flash_access() && ret;
} }
bool SPIInterface::unprotect_flash() bool FlashInterface::unprotect_flash()
{ {
bool ret = true; bool ret = true;
@ -115,7 +115,7 @@ bool SPIInterface::unprotect_flash()
return post_flash_access() && ret; return post_flash_access() && ret;
} }
bool SPIInterface::set_quad_bit(bool set_quad) bool FlashInterface::set_quad_bit(bool set_quad)
{ {
bool ret = true; bool ret = true;
@ -146,7 +146,7 @@ bool SPIInterface::set_quad_bit(bool set_quad)
return post_flash_access() && ret; return post_flash_access() && ret;
} }
bool SPIInterface::bulk_erase_flash() bool FlashInterface::bulk_erase_flash()
{ {
bool ret = true; bool ret = true;
printInfo("bulk_erase:"); printInfo("bulk_erase:");
@ -177,7 +177,7 @@ bool SPIInterface::bulk_erase_flash()
return post_flash_access() && ret; return post_flash_access() && ret;
} }
bool SPIInterface::write(const std::vector<FlashDataSection>&sections, bool FlashInterface::write(const std::vector<FlashDataSection>&sections,
bool unprotect_flash, bool full_erase) bool unprotect_flash, bool full_erase)
{ {
bool ret = true; bool ret = true;
@ -202,7 +202,7 @@ bool SPIInterface::write(const std::vector<FlashDataSection>&sections,
return ret && ret2; return ret && ret2;
} }
bool SPIInterface::write(uint32_t offset, const uint8_t *data, uint32_t len, bool FlashInterface::write(uint32_t offset, const uint8_t *data, uint32_t len,
bool unprotect_flash) bool unprotect_flash)
{ {
bool ret = true; bool ret = true;
@ -227,7 +227,7 @@ bool SPIInterface::write(uint32_t offset, const uint8_t *data, uint32_t len,
return ret && ret2; return ret && ret2;
} }
bool SPIInterface::read(uint8_t *data, uint32_t base_addr, uint32_t len) bool FlashInterface::read(uint8_t *data, uint32_t base_addr, uint32_t len)
{ {
bool ret = true; bool ret = true;
/* enable SPI flash access */ /* enable SPI flash access */
@ -246,7 +246,7 @@ bool SPIInterface::read(uint8_t *data, uint32_t base_addr, uint32_t len)
return post_flash_access() && ret == 0; return post_flash_access() && ret == 0;
} }
bool SPIInterface::dump(uint32_t base_addr, uint32_t len) bool FlashInterface::dump(uint32_t base_addr, uint32_t len)
{ {
bool ret = true; bool ret = true;
/* enable SPI flash access */ /* enable SPI flash access */

View File

@ -3,8 +3,8 @@
* Copyright (C) 2020 Gwenhael Goavec-Merou <gwenhael.goavec-merou@trabucayre.com> * Copyright (C) 2020 Gwenhael Goavec-Merou <gwenhael.goavec-merou@trabucayre.com>
*/ */
#ifndef SRC_SPIINTERFACE_HPP_ #ifndef SRC_FLASHINTERFACE_HPP_
#define SRC_SPIINTERFACE_HPP_ #define SRC_FLASHINTERFACE_HPP_
#include <cstdint> #include <cstdint>
#include <iostream> #include <iostream>
@ -12,21 +12,21 @@
#include <vector> #include <vector>
/*! /*!
* \file SPIInterface.hpp * \file FlashInterface.hpp
* \class SPIInterface * \class FlashInterface
* \brief abstract class between spi implementation and converters * \brief abstract class between spi implementation and converters
* \author Gwenhael Goavec-Merou * \author Gwenhael Goavec-Merou
*/ */
class FlashDataSection; class FlashDataSection;
class SPIInterface { class FlashInterface {
public: public:
SPIInterface(); FlashInterface();
SPIInterface(const std::string &filename, int8_t verbose, FlashInterface(const std::string &filename, int8_t verbose,
uint32_t rd_burst, bool verify, bool skip_load_bridge = false, uint32_t rd_burst, bool verify, bool skip_load_bridge = false,
bool skip_reset = false); bool skip_reset = false);
virtual ~SPIInterface() {} virtual ~FlashInterface() {}
bool detect_flash(); bool detect_flash();
bool protect_flash(uint32_t len); bool protect_flash(uint32_t len);
@ -131,4 +131,4 @@ class SPIInterface {
private: private:
std::string _spif_filename; std::string _spif_filename;
}; };
#endif // SRC_SPIINTERFACE_HPP_ #endif // SRC_FLASHINTERFACE_HPP_

View File

@ -11,9 +11,8 @@
#include "fsparser.hpp" #include "fsparser.hpp"
#include "display.hpp" #include "display.hpp"
using namespace std;
FsParser::FsParser(const string &filename, bool reverseByte, bool verbose): FsParser::FsParser(const std::string &filename, bool reverseByte, bool verbose):
ConfigBitstreamParser(filename, ConfigBitstreamParser::ASCII_MODE, ConfigBitstreamParser(filename, ConfigBitstreamParser::ASCII_MODE,
verbose), _reverseByte(reverseByte), _end_header(0), _checksum(0), verbose), _reverseByte(reverseByte), _end_header(0), _checksum(0),
_8Zero(0xff), _4Zero(0xff), _2Zero(0xff), _8Zero(0xff), _4Zero(0xff), _2Zero(0xff),
@ -36,11 +35,11 @@ uint64_t FsParser::bitToVal(const char *bits, int len)
int FsParser::parseHeader() int FsParser::parseHeader()
{ {
int ret = 0; int ret = 0;
string buffer; std::string buffer;
int line_index = 0; int line_index = 0;
bool in_header = true; bool in_header = true;
istringstream lineStream(_raw_data); std::istringstream lineStream(_raw_data);
while (std::getline(lineStream, buffer, '\n')) { while (std::getline(lineStream, buffer, '\n')) {
ret += buffer.size() + 1; ret += buffer.size() + 1;
@ -69,12 +68,12 @@ int FsParser::parseHeader()
case 0x06: /* idCode */ case 0x06: /* idCode */
_idcode = (0xffffffff & val); _idcode = (0xffffffff & val);
__buf_valid_bytes = snprintf(__buf, 9, "%08x", _idcode); __buf_valid_bytes = snprintf(__buf, 9, "%08x", _idcode);
_hdr["idcode"] = string(__buf, __buf_valid_bytes); _hdr["idcode"] = std::string(__buf, __buf_valid_bytes);
_hdr["idcode"].resize(8, ' '); _hdr["idcode"].resize(8, ' ');
break; break;
case 0x0A: /* user code or checksum ? */ case 0x0A: /* user code or checksum ? */
__buf_valid_bytes = snprintf(__buf, 9, "%08x", (uint32_t)(0xffffffff & val)); __buf_valid_bytes = snprintf(__buf, 9, "%08x", (uint32_t)(0xffffffff & val));
_hdr["CheckSum"] = string(__buf, __buf_valid_bytes); _hdr["CheckSum"] = std::string(__buf, __buf_valid_bytes);
_hdr["CheckSum"].resize(8, ' '); _hdr["CheckSum"].resize(8, ' ');
break; break;
case 0x0B: /* only present when bit_security is set */ case 0x0B: /* only present when bit_security is set */
@ -90,7 +89,7 @@ int FsParser::parseHeader()
} else { } else {
rate = 2500000; // default rate = 2500000; // default
} }
_hdr["LoadingRate"] = to_string(rate); _hdr["LoadingRate"] = std::to_string(rate);
_compressed = (val >> 13) & 1; _compressed = (val >> 13) & 1;
_hdr["Compress"] = (_compressed) ? "ON" : "OFF"; _hdr["Compress"] = (_compressed) ? "ON" : "OFF";
_hdr["ProgramDoneBypass"] = ((val >> 12) & 1) ? "ON" : "OFF"; _hdr["ProgramDoneBypass"] = ((val >> 12) & 1) ? "ON" : "OFF";
@ -112,7 +111,7 @@ int FsParser::parseHeader()
uint32_t flash_addr; uint32_t flash_addr;
flash_addr = val & 0xffffffff; flash_addr = val & 0xffffffff;
__buf_valid_bytes = snprintf(__buf, 9, "%08x", flash_addr); __buf_valid_bytes = snprintf(__buf, 9, "%08x", flash_addr);
_hdr["SPIAddr"] = string(__buf, __buf_valid_bytes); _hdr["SPIAddr"] = std::string(__buf, __buf_valid_bytes);
_hdr["SPIAddr"].resize(8, ' '); _hdr["SPIAddr"].resize(8, ' ');
break; break;
@ -123,7 +122,7 @@ int FsParser::parseHeader()
crc = 0x01 & (val >> 23); crc = 0x01 & (val >> 23);
_hdr["CRCCheck"] = (crc) ? "ON" : "OFF"; _hdr["CRCCheck"] = (crc) ? "ON" : "OFF";
_hdr["ConfDataLength"] = to_string(0xffff & val); _hdr["ConfDataLength"] = std::to_string(0xffff & val);
_end_header = line_index; _end_header = line_index;
break; break;
} }
@ -136,7 +135,7 @@ int FsParser::parseHeader()
int FsParser::parse() int FsParser::parse()
{ {
string tmp; std::string tmp;
/* GW1N-6 and GW1N(R)-9 are address length not multiple of byte */ /* GW1N-6 and GW1N(R)-9 are address length not multiple of byte */
int padding = 0; int padding = 0;
@ -171,7 +170,7 @@ int FsParser::parse()
nb_line = 274; nb_line = 274;
break; break;
case 0x0100181b: /* GW1N-2 */ case 0x0100181b: /* GW1N-2 */
case 0x1100181b: /* GW1N-2B */ case 0x0120681b: /* GW1N(R/Z)-2/2B/2C, GW1N-1P5/1P5B/1P5C */
case 0x0300081b: /* GW1NS-2 */ case 0x0300081b: /* GW1NS-2 */
case 0x0300181b: /* GW1NSx-2C */ case 0x0300181b: /* GW1NSx-2C */
case 0x0100981b: /* GW1NSR-4C (warning! not documented) */ case 0x0100981b: /* GW1NSR-4C (warning! not documented) */
@ -236,17 +235,17 @@ int FsParser::parse()
drop += 2 * 8; drop += 2 * 8;
for (auto &&ll = _lstRawData.begin(); for (auto &&ll = _lstRawData.begin();
ll != _lstRawData.end(); ll++) { ll != _lstRawData.end(); ll++) {
string l = ""; std::string l = "";
string line = *ll; std::string line = *ll;
if (_compressed) { if (_compressed) {
for (size_t i = 0; i < line.size()-drop; i+=8) { for (size_t i = 0; i < line.size()-drop; i+=8) {
uint8_t c = bitToVal((const char *)&line[i], 8); uint8_t c = bitToVal((const char *)&line[i], 8);
if (c == _8Zero) if (c == _8Zero)
l += string(8*8, '0'); l += std::string(8*8, '0');
else if (c == _4Zero) else if (c == _4Zero)
l += string(4*8, '0'); l += std::string(4*8, '0');
else if (c == _2Zero) else if (c == _2Zero)
l += string(2*8, '0'); l += std::string(2*8, '0');
else else
l += line.substr(i, 8); l += line.substr(i, 8);
} }

View File

@ -17,7 +17,6 @@
#include "ftdiJtagBitbang.hpp" #include "ftdiJtagBitbang.hpp"
#include "ftdipp_mpsse.hpp" #include "ftdipp_mpsse.hpp"
using namespace std;
#define DEBUG 0 #define DEBUG 0
@ -31,7 +30,7 @@ using namespace std;
#endif #endif
FtdiJtagBitBang::FtdiJtagBitBang(const cable_t &cable, FtdiJtagBitBang::FtdiJtagBitBang(const cable_t &cable,
const jtag_pins_conf_t *pin_conf, const string &dev, const jtag_pins_conf_t *pin_conf, const std::string &dev,
const std::string &serial, uint32_t clkHZ, int8_t verbose): const std::string &serial, uint32_t clkHZ, int8_t verbose):
FTDIpp_MPSSE(cable, dev, serial, clkHZ, verbose), _bitmode(0), FTDIpp_MPSSE(cable, dev, serial, clkHZ, verbose), _bitmode(0),
_curr_tms(0), _rx_size(0) _curr_tms(0), _rx_size(0)

View File

@ -17,7 +17,6 @@
#include "ftdiJtagMPSSE.hpp" #include "ftdiJtagMPSSE.hpp"
#include "ftdipp_mpsse.hpp" #include "ftdipp_mpsse.hpp"
using namespace std;
#define DEBUG 0 #define DEBUG 0
@ -31,7 +30,7 @@ using namespace std;
#endif #endif
FtdiJtagMPSSE::FtdiJtagMPSSE(const cable_t &cable, FtdiJtagMPSSE::FtdiJtagMPSSE(const cable_t &cable,
const string &dev, const string &serial, uint32_t clkHZ, const std::string &dev, const std::string &serial, uint32_t clkHZ,
bool invert_read_edge, int8_t verbose): bool invert_read_edge, int8_t verbose):
FTDIpp_MPSSE(cable, dev, serial, clkHZ, verbose), _ch552WA(false), FTDIpp_MPSSE(cable, dev, serial, clkHZ, verbose), _ch552WA(false),
_cmd8EWA(false), _cmd8EWA(false),

View File

@ -20,13 +20,12 @@
#include "display.hpp" #include "display.hpp"
#include "ftdipp_mpsse.hpp" #include "ftdipp_mpsse.hpp"
using namespace std;
//#define DEBUG 1 //#define DEBUG 1
#define display(...) \ #define display(...) \
do { if (_verbose) fprintf(stdout, __VA_ARGS__);}while(0) do { if (_verbose) fprintf(stdout, __VA_ARGS__);}while(0)
FTDIpp_MPSSE::FTDIpp_MPSSE(const cable_t &cable, const string &dev, FTDIpp_MPSSE::FTDIpp_MPSSE(const cable_t &cable, const std::string &dev,
const std::string &serial, uint32_t clkHZ, int8_t verbose): const std::string &serial, uint32_t clkHZ, int8_t verbose):
_verbose(verbose > 2), _cable(cable.config), _vid(0), _verbose(verbose > 2), _cable(cable.config), _vid(0),
_pid(0), _index(0), _pid(0), _index(0),
@ -41,7 +40,7 @@ FTDIpp_MPSSE::FTDIpp_MPSSE(const cable_t &cable, const string &dev,
strcpy(_product, ""); strcpy(_product, "");
if (!dev.empty()) { if (!dev.empty()) {
if (!search_with_dev(dev)) { if (!search_with_dev(dev)) {
cerr << "No cable found" << endl; std::cerr << "No cable found" << std::endl;
throw std::runtime_error("No cable found"); throw std::runtime_error("No cable found");
} }
} else { } else {
@ -159,7 +158,7 @@ void FTDIpp_MPSSE::open_device(const std::string &serial, unsigned int baudrate)
_ftdi = ftdi_new(); _ftdi = ftdi_new();
if (_ftdi == NULL) { if (_ftdi == NULL) {
cout << "open_device: failed to initialize ftdi" << endl; std::cout << "open_device: failed to initialize ftdi" << std::endl;
throw std::runtime_error("open_device: failed to initialize ftdi"); throw std::runtime_error("open_device: failed to initialize ftdi");
} }
#if (ATTACH_KERNEL && (FTDI_VERSION >= 105)) #if (ATTACH_KERNEL && (FTDI_VERSION >= 105))
@ -277,14 +276,14 @@ int FTDIpp_MPSSE::init(unsigned char latency, unsigned char bitmask_mode,
if ((ret = ftdi_usb_reset(_ftdi)) < 0) { if ((ret = ftdi_usb_reset(_ftdi)) < 0) {
printError("FTDI reset error with code " + printError("FTDI reset error with code " +
std::to_string(ret) + " (" + std::to_string(ret) + " (" +
string(ftdi_get_error_string(_ftdi)) + ")"); std::string(ftdi_get_error_string(_ftdi)) + ")");
return ret; return ret;
} }
if ((ret = ftdi_set_bitmode(_ftdi, 0x00, BITMODE_RESET)) < 0) { if ((ret = ftdi_set_bitmode(_ftdi, 0x00, BITMODE_RESET)) < 0) {
printError("FTDI bitmode reset error with code " + printError("FTDI bitmode reset error with code " +
std::to_string(ret) + " (" + std::to_string(ret) + " (" +
string(ftdi_get_error_string(_ftdi)) + ")"); std::string(ftdi_get_error_string(_ftdi)) + ")");
return ret; return ret;
} }
@ -295,27 +294,27 @@ int FTDIpp_MPSSE::init(unsigned char latency, unsigned char bitmask_mode,
#endif #endif
printError("FTDI flush buffer error with code " + printError("FTDI flush buffer error with code " +
std::to_string(ret) + " (" + std::to_string(ret) + " (" +
string(ftdi_get_error_string(_ftdi)) + ")"); std::string(ftdi_get_error_string(_ftdi)) + ")");
return ret; return ret;
} }
if ((ret = ftdi_set_latency_timer(_ftdi, latency)) < 0) { if ((ret = ftdi_set_latency_timer(_ftdi, latency)) < 0) {
printError("FTDI set latency timer error with code " + printError("FTDI set latency timer error with code " +
std::to_string(ret) + " (" + std::to_string(ret) + " (" +
string(ftdi_get_error_string(_ftdi)) + ")"); std::string(ftdi_get_error_string(_ftdi)) + ")");
return ret; return ret;
} }
/* enable mode */ /* enable mode */
if ((ret = ftdi_set_bitmode(_ftdi, bitmask_mode, mode)) < 0) { if ((ret = ftdi_set_bitmode(_ftdi, bitmask_mode, mode)) < 0) {
printError("FTDI bitmode config error with code " + printError("FTDI bitmode config error with code " +
std::to_string(ret) + " (" + std::to_string(ret) + " (" +
string(ftdi_get_error_string(_ftdi)) + ")"); std::string(ftdi_get_error_string(_ftdi)) + ")");
return ret; return ret;
} }
if (mode == BITMODE_MPSSE) { if (mode == BITMODE_MPSSE) {
unsigned char buf1[5]; unsigned char buf1[5];
if ((ret = ftdi_read_data(_ftdi, buf1, 5)) < 0) { if ((ret = ftdi_read_data(_ftdi, buf1, 5)) < 0) {
printError("fail to read data " + printError("fail to read data " +
string(ftdi_get_error_string(_ftdi))); std::string(ftdi_get_error_string(_ftdi)));
return -1; return -1;
} }
@ -344,24 +343,24 @@ int FTDIpp_MPSSE::init(unsigned char latency, unsigned char bitmask_mode,
} }
if ((ret = mpsse_store(buf_cmd, to_wr)) < 0) { if ((ret = mpsse_store(buf_cmd, to_wr)) < 0) {
printError("fail to store buffer " + printError("fail to store buffer " +
string(ftdi_get_error_string(_ftdi))); std::string(ftdi_get_error_string(_ftdi)));
return -1; return -1;
} }
if (mpsse_write() < 0) { if (mpsse_write() < 0) {
printError("fail to write buffer " + printError("fail to write buffer " +
string(ftdi_get_error_string(_ftdi))); std::string(ftdi_get_error_string(_ftdi)));
return -1; return -1;
} }
} }
if (ftdi_read_data_set_chunksize(_ftdi, _buffer_size) < 0) { if (ftdi_read_data_set_chunksize(_ftdi, _buffer_size) < 0) {
printError("fail to set read chunk size: " + printError("fail to set read chunk size: " +
string(ftdi_get_error_string(_ftdi))); std::string(ftdi_get_error_string(_ftdi)));
return -1; return -1;
} }
if (ftdi_write_data_set_chunksize(_ftdi, _buffer_size) < 0) { if (ftdi_write_data_set_chunksize(_ftdi, _buffer_size) < 0) {
printError("fail to set write chunk size: " + printError("fail to set write chunk size: " +
string(ftdi_get_error_string(_ftdi))); std::string(ftdi_get_error_string(_ftdi)));
return -1; return -1;
} }
@ -382,7 +381,7 @@ int FTDIpp_MPSSE::setClkFreq(uint32_t clkHZ)
#else #else
if ((ret = ftdi_tcioflush(_ftdi)) < 0) { if ((ret = ftdi_tcioflush(_ftdi)) < 0) {
printError("selfClkFreq: fail to flush buffers: " + printError("selfClkFreq: fail to flush buffers: " +
string(ftdi_get_error_string(_ftdi))); std::string(ftdi_get_error_string(_ftdi)));
return ret; return ret;
} }
@ -402,7 +401,7 @@ int FTDIpp_MPSSE::setClkFreq(uint32_t clkHZ)
} }
if (_clkHZ > base_freq / 2) { if (_clkHZ > base_freq / 2) {
printWarn("Jtag probe limited to %d MHz" + std::to_string(base_freq / 2)); printWarn("Jtag probe limited to " + std::to_string(base_freq / 2) + " Hz");
_clkHZ = base_freq / 2; _clkHZ = base_freq / 2;
} }
@ -421,7 +420,7 @@ int FTDIpp_MPSSE::setClkFreq(uint32_t clkHZ)
__buf_valid_bytes = snprintf(__buf, 10, "%3.2fKHz", clkHZ / 1e3); __buf_valid_bytes = snprintf(__buf, 10, "%3.2fKHz", clkHZ / 1e3);
else else
__buf_valid_bytes = snprintf(__buf, 10, "%3u.00Hz", clkHZ); __buf_valid_bytes = snprintf(__buf, 10, "%3u.00Hz", clkHZ);
string clkHZ_str(__buf, __buf_valid_bytes); std::string clkHZ_str(__buf, __buf_valid_bytes);
clkHZ_str.resize(10, ' '); clkHZ_str.resize(10, ' ');
if (real_freq >= 1e6) if (real_freq >= 1e6)
__buf_valid_bytes = snprintf(__buf, 9, "%2.2fMHz", real_freq / 1e6); __buf_valid_bytes = snprintf(__buf, 9, "%2.2fMHz", real_freq / 1e6);
@ -429,7 +428,7 @@ int FTDIpp_MPSSE::setClkFreq(uint32_t clkHZ)
__buf_valid_bytes = snprintf(__buf, 10, "%3.2fKHz", real_freq / 1e3); __buf_valid_bytes = snprintf(__buf, 10, "%3.2fKHz", real_freq / 1e3);
else else
__buf_valid_bytes = snprintf(__buf, 10, "%3.2fHz", real_freq); __buf_valid_bytes = snprintf(__buf, 10, "%3.2fHz", real_freq);
string real_freq_str(__buf, __buf_valid_bytes); std::string real_freq_str(__buf, __buf_valid_bytes);
real_freq_str.resize(10, ' '); real_freq_str.resize(10, ' ');
@ -453,13 +452,13 @@ int FTDIpp_MPSSE::setClkFreq(uint32_t clkHZ)
} }
if ((ret = ftdi_read_data(_ftdi, buffer, 4)) < 0) { if ((ret = ftdi_read_data(_ftdi, buffer, 4)) < 0) {
printError("selfClkFreq: fail to read: " + printError("selfClkFreq: fail to read: " +
string(ftdi_get_error_string(_ftdi))); std::string(ftdi_get_error_string(_ftdi)));
return ret; return ret;
} }
_clkHZ = real_freq; _clkHZ = real_freq;
return real_freq; return (int)real_freq;
} }
int FTDIpp_MPSSE::mpsse_store(unsigned char c) int FTDIpp_MPSSE::mpsse_store(unsigned char c)
@ -478,7 +477,7 @@ int FTDIpp_MPSSE::mpsse_store(unsigned char *buff, int len)
if ((ret = mpsse_write()) < 0) { if ((ret = mpsse_write()) < 0) {
printError("mpsse_store: fails to first flush " + printError("mpsse_store: fails to first flush " +
std::to_string(ret) + " " + std::to_string(ret) + " " +
string(ftdi_get_error_string(_ftdi))); std::string(ftdi_get_error_string(_ftdi)));
return ret; return ret;
} }
} }
@ -493,7 +492,7 @@ int FTDIpp_MPSSE::mpsse_store(unsigned char *buff, int len)
if ((ret = mpsse_write()) < 0) { if ((ret = mpsse_write()) < 0) {
printError("mpsse_store: fails to first flush " + printError("mpsse_store: fails to first flush " +
std::to_string(ret) + " " + std::to_string(ret) + " " +
string(ftdi_get_error_string(_ftdi))); std::string(ftdi_get_error_string(_ftdi)));
return ret; return ret;
} }
ptr += store_size; ptr += store_size;
@ -523,7 +522,7 @@ int FTDIpp_MPSSE::mpsse_write()
if ((ret = ftdi_write_data(_ftdi, _buffer, _num)) != _num) { if ((ret = ftdi_write_data(_ftdi, _buffer, _num)) != _num) {
printError("mpsse_write: fail to write with error " + printError("mpsse_write: fail to write with error " +
std::to_string(ret) + " (" + std::to_string(ret) + " (" +
string(ftdi_get_error_string(_ftdi)) + ")"); std::string(ftdi_get_error_string(_ftdi)) + ")");
return ret; return ret;
} }
@ -541,14 +540,14 @@ int FTDIpp_MPSSE::mpsse_read(unsigned char *rx_buff, int len)
if ((ret = mpsse_store(SEND_IMMEDIATE)) < 0) { if ((ret = mpsse_store(SEND_IMMEDIATE)) < 0) {
printError("mpsse_read: fail to store with error: " + printError("mpsse_read: fail to store with error: " +
std::to_string(ret) + " (" + std::to_string(ret) + " (" +
string(ftdi_get_error_string(_ftdi)) + ")"); std::string(ftdi_get_error_string(_ftdi)) + ")");
return ret; return ret;
} }
if ((ret = mpsse_write()) < 0) { if ((ret = mpsse_write()) < 0) {
printError("mpsse_read: fail to flush buffer with error: " + printError("mpsse_read: fail to flush buffer with error: " +
std::to_string(ret) + " (" + std::to_string(ret) + " (" +
string(ftdi_get_error_string(_ftdi)) + ")"); std::string(ftdi_get_error_string(_ftdi)) + ")");
return ret; return ret;
} }
@ -710,7 +709,7 @@ bool FTDIpp_MPSSE::gpio_write(uint8_t gpio, bool low_pins)
else else
_cable.bit_high_val = gpio; _cable.bit_high_val = gpio;
if (__gpio_write(low_pins)) if (!__gpio_write(low_pins))
return false; return false;
return (mpsse_write() >= 0); return (mpsse_write() >= 0);
} }
@ -825,7 +824,7 @@ unsigned int FTDIpp_MPSSE::udevstufftoint(const char *udevstring, int base)
return (ret); return (ret);
} }
bool FTDIpp_MPSSE::search_with_dev(const string &device) bool FTDIpp_MPSSE::search_with_dev(const std::string &device)
{ {
struct udev *udev; struct udev *udev;
struct udev_device *dev, *usbdeviceparent; struct udev_device *dev, *usbdeviceparent;
@ -899,7 +898,7 @@ unsigned int FTDIpp_MPSSE::udevstufftoint(const char *udevstring, int base)
(void)base; (void)base;
return 0; return 0;
} }
bool FTDIpp_MPSSE::search_with_dev(const string &device) bool FTDIpp_MPSSE::search_with_dev(const std::string &device)
{ {
(void)device; (void)device;
return false; return false;

View File

@ -243,7 +243,7 @@ int FtdiSpi::ft2232_spi_wr_and_rd(//struct ftdi_spi *spi,
return 0; return 0;
} }
/* method spiInterface::spi_put */ /* method flashInterface::spi_put */
int FtdiSpi::spi_put(uint8_t cmd, const uint8_t *tx, uint8_t *rx, uint32_t len) int FtdiSpi::spi_put(uint8_t cmd, const uint8_t *tx, uint8_t *rx, uint32_t len)
{ {
uint32_t xfer_len = len + 1; uint32_t xfer_len = len + 1;
@ -266,13 +266,13 @@ int FtdiSpi::spi_put(uint8_t cmd, const uint8_t *tx, uint8_t *rx, uint32_t len)
return 0; return 0;
} }
/* method spiInterface::spi_put */ /* method flashInterface::spi_put */
int FtdiSpi::spi_put(const uint8_t *tx, uint8_t *rx, uint32_t len) int FtdiSpi::spi_put(const uint8_t *tx, uint8_t *rx, uint32_t len)
{ {
return ft2232_spi_wr_and_rd(len, tx, rx); return ft2232_spi_wr_and_rd(len, tx, rx);
} }
/* method spiInterface::spi_wait /* method flashInterface::spi_wait
*/ */
int FtdiSpi::spi_wait(uint8_t cmd, uint8_t mask, uint8_t cond, int FtdiSpi::spi_wait(uint8_t cmd, uint8_t mask, uint8_t cond,
uint32_t timeout, bool verbose) uint32_t timeout, bool verbose)

View File

@ -13,9 +13,9 @@
#include "board.hpp" #include "board.hpp"
#include "cable.hpp" #include "cable.hpp"
#include "ftdipp_mpsse.hpp" #include "ftdipp_mpsse.hpp"
#include "spiInterface.hpp" #include "flashInterface.hpp"
class FtdiSpi : public FTDIpp_MPSSE, SPIInterface { class FtdiSpi : public FTDIpp_MPSSE, FlashInterface {
public: public:
enum SPI_endianness { enum SPI_endianness {
SPI_MSB_FIRST = 0, SPI_MSB_FIRST = 0,

View File

@ -15,14 +15,13 @@
#include "fx2_ll.hpp" #include "fx2_ll.hpp"
#include "ihexParser.hpp" #include "ihexParser.hpp"
using namespace std;
#define FX2_FIRM_LOAD 0xA0 #define FX2_FIRM_LOAD 0xA0
#define FX2_GCR_CPUCS 0xe600 #define FX2_GCR_CPUCS 0xe600
#define FX2_GCR_CPUCS_8051_RES (1 << 0) #define FX2_GCR_CPUCS_8051_RES (1 << 0)
FX2_ll::FX2_ll(uint16_t uninit_vid, uint16_t uninit_pid, FX2_ll::FX2_ll(uint16_t uninit_vid, uint16_t uninit_pid,
uint16_t vid, uint16_t pid, const string &firmware_path) uint16_t vid, uint16_t pid, const std::string &firmware_path)
{ {
int ret; int ret;
bool reenum = false; bool reenum = false;
@ -168,7 +167,7 @@ int FX2_ll::read_ctrl(uint8_t bRequest, uint16_t wValue,
* and 64B by 64B * and 64B by 64B
* set CPU in reset state before and restart after * set CPU in reset state before and restart after
*/ */
bool FX2_ll::load_firmware(string firmware_path) bool FX2_ll::load_firmware(std::string firmware_path)
{ {
IhexParser ihex(firmware_path, false, true); IhexParser ihex(firmware_path, false, true);
ihex.parse(); ihex.parse();
@ -177,7 +176,7 @@ bool FX2_ll::load_firmware(string firmware_path)
if (!reset(1)) if (!reset(1))
return false; return false;
/* load */ /* load */
vector<IhexParser::data_line_t> data = ihex.getDataArray(); std::vector<IhexParser::data_line_t> data = ihex.getDataArray();
for (size_t i = 0; i < data.size(); i++) { for (size_t i = 0; i < data.size(); i++) {
IhexParser::data_line_t data_line = data[i]; IhexParser::data_line_t data_line = data[i];

View File

@ -21,7 +21,6 @@
#include "rawParser.hpp" #include "rawParser.hpp"
#include "spiFlash.hpp" #include "spiFlash.hpp"
using namespace std;
#ifdef STATUS_TIMEOUT #ifdef STATUS_TIMEOUT
// defined in the Windows headers included by libftdi.h // defined in the Windows headers included by libftdi.h
@ -75,11 +74,11 @@ using namespace std;
#define BSCAN_GW1NSR_4C_SPI_DO (1 << 1) #define BSCAN_GW1NSR_4C_SPI_DO (1 << 1)
#define BSCAN_GW1NSR_4C_SPI_MSK (1 << 0) #define BSCAN_GW1NSR_4C_SPI_MSK (1 << 0)
Gowin::Gowin(Jtag *jtag, const string filename, const string &file_type, std::string mcufw, Gowin::Gowin(Jtag *jtag, const std::string filename, const std::string &file_type, std::string mcufw,
Device::prog_type_t prg_type, bool external_flash, Device::prog_type_t prg_type, bool external_flash,
bool verify, int8_t verbose, const std::string& user_flash) bool verify, int8_t verbose, const std::string& user_flash)
: Device(jtag, filename, file_type, verify, verbose), : Device(jtag, filename, file_type, verify, verbose),
SPIInterface(filename, verbose, 0, verify, false, false), FlashInterface(filename, verbose, 0, verify, false, false),
_idcode(0), is_gw1n1(false), is_gw1n4(false), is_gw1n9(false), _idcode(0), is_gw1n1(false), is_gw1n4(false), is_gw1n9(false),
is_gw2a(false), is_gw5a(false), is_gw2a(false), is_gw5a(false),
_external_flash(external_flash), _external_flash(external_flash),
@ -128,7 +127,7 @@ Gowin::Gowin(Jtag *jtag, const string filename, const string &file_type, std::st
/* for fs file check match with targeted device */ /* for fs file check match with targeted device */
if (_file_extension == "fs") { if (_file_extension == "fs") {
string idcode_str = _fs->getHeaderVal("idcode"); std::string idcode_str = _fs->getHeaderVal("idcode");
uint32_t fs_idcode = std::stoul(idcode_str.c_str(), NULL, 16); uint32_t fs_idcode = std::stoul(idcode_str.c_str(), NULL, 16);
if ((fs_idcode & 0x0fffffff) != _idcode) { if ((fs_idcode & 0x0fffffff) != _idcode) {
char mess[256]; char mess[256];
@ -437,7 +436,7 @@ void Gowin::checkCRC()
* is used, try to compare with this value * is used, try to compare with this value
*/ */
try { try {
string hdr = _fs->getHeaderVal("checkSum"); std::string hdr = _fs->getHeaderVal("checkSum");
if (!hdr.empty()) { if (!hdr.empty()) {
if (ucode == strtol(hdr.c_str(), NULL, 16)) if (ucode == strtol(hdr.c_str(), NULL, 16))
goto success; goto success;

View File

@ -16,9 +16,9 @@
#include "device.hpp" #include "device.hpp"
#include "jtag.hpp" #include "jtag.hpp"
#include "jtagInterface.hpp" #include "jtagInterface.hpp"
#include "spiInterface.hpp" #include "flashInterface.hpp"
class Gowin: public Device, SPIInterface { class Gowin: public Device, FlashInterface {
public: public:
Gowin(Jtag *jtag, std::string filename, const std::string &file_type, Gowin(Jtag *jtag, std::string filename, const std::string &file_type,
std::string mcufw, Device::prog_type_t prg_type, std::string mcufw, Device::prog_type_t prg_type,
@ -32,18 +32,18 @@ class Gowin: public Device, SPIInterface {
/* spi interface */ /* spi interface */
bool detect_flash() override { bool detect_flash() override {
if (is_gw5a || is_gw2a) if (is_gw5a || is_gw2a)
return SPIInterface::detect_flash(); return FlashInterface::detect_flash();
printError("detect flash not supported"); return false;} printError("detect flash not supported"); return false;}
bool protect_flash(uint32_t len) override { bool protect_flash(uint32_t len) override {
(void) len; (void) len;
printError("protect flash not supported"); return false;} printError("protect flash not supported"); return false;}
bool unprotect_flash() override { bool unprotect_flash() override {
if (is_gw5a) if (is_gw5a)
return SPIInterface::unprotect_flash(); return FlashInterface::unprotect_flash();
printError("unprotect flash not supported"); return false;} printError("unprotect flash not supported"); return false;}
bool bulk_erase_flash() override { bool bulk_erase_flash() override {
if (is_gw5a || is_gw2a) if (is_gw5a || is_gw2a)
return SPIInterface::bulk_erase_flash(); return FlashInterface::bulk_erase_flash();
printError("bulk erase flash not supported"); return false;} printError("bulk erase flash not supported"); return false;}
bool dumpFlash(uint32_t base_addr, uint32_t len) override; bool dumpFlash(uint32_t base_addr, uint32_t len) override;
int spi_put(uint8_t cmd, const uint8_t *tx, uint8_t *rx, int spi_put(uint8_t cmd, const uint8_t *tx, uint8_t *rx,

View File

@ -136,7 +136,7 @@ void Ice40::program(unsigned int offset, bool unprotect_flash)
_spi->gpio_clear(_rst_pin); _spi->gpio_clear(_rst_pin);
SPIFlash flash(reinterpret_cast<SPIInterface *>(_spi), unprotect_flash, SPIFlash flash(reinterpret_cast<FlashInterface *>(_spi), unprotect_flash,
_verbose_level); _verbose_level);
flash.erase_and_prog(offset, data, length); flash.erase_and_prog(offset, data, length);
@ -154,7 +154,7 @@ bool Ice40::detect_flash()
prepare_flash_access(); prepare_flash_access();
printInfo("Read Flash ", false); printInfo("Read Flash ", false);
try { try {
SPIFlash flash(reinterpret_cast<SPIInterface *>(_spi), false, _verbose_level); SPIFlash flash(reinterpret_cast<FlashInterface *>(_spi), false, _verbose_level);
flash.read_id(); flash.read_id();
flash.display_status_reg(); flash.display_status_reg();
} catch (std::exception &e) { } catch (std::exception &e) {
@ -173,7 +173,7 @@ bool Ice40::dumpFlash(uint32_t base_addr, uint32_t len)
prepare_flash_access(); prepare_flash_access();
printInfo("Read Flash ", false); printInfo("Read Flash ", false);
try { try {
SPIFlash flash(reinterpret_cast<SPIInterface *>(_spi), false, _verbose_level); SPIFlash flash(reinterpret_cast<FlashInterface *>(_spi), false, _verbose_level);
flash.reset(); flash.reset();
flash.power_up(); flash.power_up();
flash.dump(_filename, base_addr, len); flash.dump(_filename, base_addr, len);
@ -193,7 +193,7 @@ bool Ice40::protect_flash(uint32_t len)
prepare_flash_access(); prepare_flash_access();
/* acess */ /* acess */
try { try {
SPIFlash flash(reinterpret_cast<SPIInterface *>(_spi), false, _verbose_level); SPIFlash flash(reinterpret_cast<FlashInterface *>(_spi), false, _verbose_level);
/* configure flash protection */ /* configure flash protection */
if (flash.enable_protection(len) == -1) if (flash.enable_protection(len) == -1)
return false; return false;
@ -213,7 +213,7 @@ bool Ice40::unprotect_flash()
prepare_flash_access(); prepare_flash_access();
/* acess */ /* acess */
try { try {
SPIFlash flash(reinterpret_cast<SPIInterface *>(_spi), false, _verbose_level); SPIFlash flash(reinterpret_cast<FlashInterface *>(_spi), false, _verbose_level);
/* configure flash protection */ /* configure flash protection */
if (flash.disable_protection() == -1) if (flash.disable_protection() == -1)
return false; return false;
@ -233,7 +233,7 @@ bool Ice40::bulk_erase_flash()
prepare_flash_access(); prepare_flash_access();
/* acess */ /* acess */
try { try {
SPIFlash flash(reinterpret_cast<SPIInterface *>(_spi), false, _verbose_level); SPIFlash flash(reinterpret_cast<FlashInterface *>(_spi), false, _verbose_level);
/* bulk erase flash */ /* bulk erase flash */
if (flash.bulk_erase() == -1) if (flash.bulk_erase() == -1)
return false; return false;

View File

@ -10,9 +10,9 @@
#include "device.hpp" #include "device.hpp"
#include "ftdispi.hpp" #include "ftdispi.hpp"
#include "spiInterface.hpp" #include "flashInterface.hpp"
class Ice40: public Device, SPIInterface { class Ice40: public Device, FlashInterface {
public: public:
Ice40(FtdiSpi *spi, const std::string &filename, Ice40(FtdiSpi *spi, const std::string &filename,
const std::string &file_type, const std::string &file_type,

View File

@ -11,7 +11,6 @@
#include "display.hpp" #include "display.hpp"
#include "ihexParser.hpp" #include "ihexParser.hpp"
using namespace std;
/* line format /* line format
* :LLAAAATTHH...HHCC * :LLAAAATTHH...HHCC
@ -34,7 +33,7 @@ using namespace std;
#define TYPE_BASE 7 #define TYPE_BASE 7
#define DATA_BASE 9 #define DATA_BASE 9
IhexParser::IhexParser(const string &filename, bool reverseOrder, bool verbose): IhexParser::IhexParser(const std::string &filename, bool reverseOrder, bool verbose):
ConfigBitstreamParser(filename, ConfigBitstreamParser::ASCII_MODE, ConfigBitstreamParser(filename, ConfigBitstreamParser::ASCII_MODE,
verbose), verbose),
_base_addr(0), _reverseOrder(reverseOrder) _base_addr(0), _reverseOrder(reverseOrder)
@ -42,8 +41,8 @@ IhexParser::IhexParser(const string &filename, bool reverseOrder, bool verbose):
int IhexParser::parse() int IhexParser::parse()
{ {
string str; std::string str;
istringstream lineStream(_raw_data); std::istringstream lineStream(_raw_data);
uint16_t next_addr = 0; uint16_t next_addr = 0;
bool is_first = true; bool is_first = true;

View File

@ -29,9 +29,8 @@
* - be less lattice compliant * - be less lattice compliant
*/ */
using namespace std;
JedParser::JedParser(const string &filename, bool verbose): JedParser::JedParser(const std::string &filename, bool verbose):
ConfigBitstreamParser(filename, ConfigBitstreamParser::BIN_MODE, verbose), ConfigBitstreamParser(filename, ConfigBitstreamParser::BIN_MODE, verbose),
_fuse_count(0), _pin_count(0), _max_vect_test(0), _fuse_count(0), _pin_count(0), _max_vect_test(0),
_featuresRow(0), _feabits(0), _has_feabits(false), _checksum(0), _featuresRow(0), _feabits(0), _has_feabits(false), _checksum(0),
@ -46,9 +45,9 @@ JedParser::JedParser(const string &filename, bool verbose):
* check if last char is '\r' * check if last char is '\r'
* \return the line without [\r]\n * \return the line without [\r]\n
*/ */
string JedParser::readline() std::string JedParser::readline()
{ {
string buffer; std::string buffer;
std::getline(_ss, buffer, '\n'); std::getline(_ss, buffer, '\n');
if (!buffer.empty()) { if (!buffer.empty()) {
/* if '\r' is present -> drop */ /* if '\r' is present -> drop */
@ -60,10 +59,10 @@ string JedParser::readline()
/* fill a vector with consecutive lines until '*' /* fill a vector with consecutive lines until '*'
*/ */
vector<string> JedParser::readJEDLine() std::vector<std::string> JedParser::readJEDLine()
{ {
string buffer; std::string buffer;
vector<string> lines; std::vector<std::string> lines;
bool inLine = true; bool inLine = true;
do { do {
@ -83,10 +82,10 @@ vector<string> JedParser::readJEDLine()
/* convert one serie ASCII 1/0 to a vector of /* convert one serie ASCII 1/0 to a vector of
* unsigned char * unsigned char
*/ */
void JedParser::buildDataArray(const string &content, struct jed_data &jed) void JedParser::buildDataArray(const std::string &content, struct jed_data &jed)
{ {
size_t data_len = content.size(); size_t data_len = content.size();
string tmp_buff; std::string tmp_buff;
fuselist += content; fuselist += content;
for (size_t i = 0; i < content.size(); i+=8) { for (size_t i = 0; i < content.size(); i+=8) {
uint8_t data = 0; uint8_t data = 0;
@ -104,11 +103,11 @@ void JedParser::buildDataArray(const string &content, struct jed_data &jed)
* unsigned char * unsigned char
* string must be up to 8 bits * string must be up to 8 bits
*/ */
void JedParser::buildDataArray(const vector<string> &content, void JedParser::buildDataArray(const std::vector<std::string> &content,
struct jed_data &jed) struct jed_data &jed)
{ {
size_t data_len = 0; size_t data_len = 0;
string tmp_buff; std::string tmp_buff;
for (size_t i = 0; i < content.size(); i++) { for (size_t i = 0; i < content.size(); i++) {
uint8_t data = 0; uint8_t data = 0;
data_len += content[i].size(); data_len += content[i].size();
@ -183,20 +182,20 @@ void JedParser::displayHeader()
* 1: Exxxx\n : feature Row * 1: Exxxx\n : feature Row
* 2: yyyy*\n : feabits * 2: yyyy*\n : feabits
*/ */
void JedParser::parseEField(const vector<string> &content) void JedParser::parseEField(const std::vector<std::string> &content)
{ {
_featuresRow = 0; _featuresRow = 0;
string featuresRow = content[0].substr(1); std::string featuresRow = content[0].substr(1);
for (size_t i = 0; i < featuresRow.size(); ++i) for (size_t i = 0; i < featuresRow.size(); ++i)
_featuresRow |= (uint64_t(featuresRow[i] - '0') << i); _featuresRow |= (uint64_t(featuresRow[i] - '0') << i);
string feabits = content[1]; std::string feabits = content[1];
_feabits = 0; _feabits = 0;
for (size_t i = 0; i < feabits.size(); i++) { for (size_t i = 0; i < feabits.size(); i++) {
_feabits |= ((feabits[i] - '0') << i); _feabits |= ((feabits[i] - '0') << i);
} }
} }
void JedParser::parseLField(const vector<string> &content) void JedParser::parseLField(const std::vector<std::string> &content)
{ {
int start_offset; int start_offset;
sscanf(content[0].substr(1).c_str(), "%d", &start_offset); sscanf(content[0].substr(1).c_str(), "%d", &start_offset);
@ -216,8 +215,8 @@ void JedParser::parseLField(const vector<string> &content)
} else { } else {
// search space // search space
std::istringstream iss(content[0]); std::istringstream iss(content[0]);
vector<string> myList((std::istream_iterator<string>(iss)), std::vector<std::string> myList((std::istream_iterator<std::string>(iss)),
std::istream_iterator<string>()); std::istream_iterator<std::string>());
myList.erase(myList.begin()); myList.erase(myList.begin());
@ -228,11 +227,11 @@ void JedParser::parseLField(const vector<string> &content)
int JedParser::parse() int JedParser::parse()
{ {
string previousNote; std::string previousNote;
_ss.str(_raw_data); _ss.str(_raw_data);
string content; std::string content;
/* JED file may have some ASCII line before STX (0x02) /* JED file may have some ASCII line before STX (0x02)
* read until STX or EOF * read until STX or EOF
@ -261,7 +260,7 @@ int JedParser::parse()
/* read full content /* read full content
* JED file end fix ETX (0x03) + file checksum + \n * JED file end fix ETX (0x03) + file checksum + \n
*/ */
std::vector<string>lines; std::vector<std::string>lines;
int first_pos; int first_pos;
char instr; char instr;
do { do {
@ -297,7 +296,7 @@ int JedParser::parse()
_max_vect_test = count; _max_vect_test = count;
break; break;
default: default:
cerr << "Error for 'Q' unknown qualifier " << lines[0] << endl; std::cerr << "Error for 'Q' unknown qualifier " << lines[0] << std::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
break; break;
@ -316,7 +315,7 @@ int JedParser::parse()
break; break;
case 0x03: case 0x03:
if (_verbose) if (_verbose)
cout << "end" << endl; std::cout << "end" << std::endl;
break; break;
case 'E': case 'E':
parseEField(lines); parseEField(lines);
@ -344,7 +343,7 @@ int JedParser::parse()
break; break;
default: default:
printf("inconnu\n"); printf("inconnu\n");
cout << lines[0]<< endl; std::cout << lines[0]<< std::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
} while (instr != 0x03); } while (instr != 0x03);

View File

@ -22,7 +22,6 @@
#define VID 0x1366 #define VID 0x1366
#define PID 0x0105 #define PID 0x0105
using namespace std;
// convert 2Byte to 1 short // convert 2Byte to 1 short
#define CONV_16B(_val) ((((uint16_t) _val[0]) << 0) | \ #define CONV_16B(_val) ((((uint16_t) _val[0]) << 0) | \
@ -458,13 +457,13 @@ bool Jlink::write_device(const uint8_t *buf, uint32_t size)
return ((uint32_t)recv == size); return ((uint32_t)recv == size);
} }
string Jlink::get_version() std::string Jlink::get_version()
{ {
uint16_t length = 0; uint16_t length = 0;
cmd_read(EMU_CMD_VERSION, &length); cmd_read(EMU_CMD_VERSION, &length);
uint8_t version[length]; uint8_t version[length];
read_device(version, length); read_device(version, length);
return string(reinterpret_cast<char*>(version)); return std::string(reinterpret_cast<char*>(version));
} }
int Jlink::get_hw_version() int Jlink::get_hw_version()
@ -689,7 +688,7 @@ bool Jlink::jlink_scan_usb(int vid, int pid)
continue; continue;
if (desc.idProduct != pid) { if (desc.idProduct != pid) {
if (_verbose) if (_verbose)
cerr << "skip pid" << hex << desc.idProduct << dec << endl; std::cerr << "skip pid" << std::hex << desc.idProduct << std::dec << std::endl;
continue; continue;
} }

View File

@ -59,7 +59,6 @@
#include "xvc_client.hpp" #include "xvc_client.hpp"
#endif #endif
using namespace std;
#define DEBUG 0 #define DEBUG 0
@ -94,10 +93,10 @@ using namespace std;
*/ */
Jtag::Jtag(const cable_t &cable, const jtag_pins_conf_t *pin_conf, Jtag::Jtag(const cable_t &cable, const jtag_pins_conf_t *pin_conf,
const string &dev, const std::string &dev,
const string &serial, uint32_t clkHZ, int8_t verbose, const std::string &serial, uint32_t clkHZ, int8_t verbose,
const string &ip_adr, int port, const std::string &ip_adr, int port,
const bool invert_read_edge, const string &firmware_path, const bool invert_read_edge, const std::string &firmware_path,
const std::map<uint32_t, misc_device> &user_misc_devs): const std::map<uint32_t, misc_device> &user_misc_devs):
_verbose(verbose > 1), _verbose(verbose > 1),
_state(RUN_TEST_IDLE), _state(RUN_TEST_IDLE),
@ -344,7 +343,7 @@ int Jtag::device_select(unsigned index)
* after the selected one * after the selected one
*/ */
_dr_bits_after = device_index; _dr_bits_after = device_index;
_dr_bits = vector<uint8_t>((std::max(_dr_bits_after, _dr_bits_before) + 7)/8, 0); _dr_bits = std::vector<uint8_t>((std::max(_dr_bits_after, _dr_bits_before) + 7)/8, 0);
/* when the device is not alone and not /* when the device is not alone and not
* the first a serie of bypass must be * the first a serie of bypass must be
@ -361,7 +360,7 @@ int Jtag::device_select(unsigned index)
_ir_bits_before = 0; _ir_bits_before = 0;
for (unsigned i = device_index + 1; i < _devices_list.size(); ++i) for (unsigned i = device_index + 1; i < _devices_list.size(); ++i)
_ir_bits_before += _irlength_list[i]; _ir_bits_before += _irlength_list[i];
_ir_bits = vector<uint8_t>((std::max(_ir_bits_before, _ir_bits_after) + 7) / 8, 0xff); // BYPASS command is all-ones _ir_bits = std::vector<uint8_t>((std::max(_ir_bits_before, _ir_bits_after) + 7) / 8, 0xff); // BYPASS command is all-ones
return device_index; return device_index;
} }
@ -466,7 +465,7 @@ int Jtag::shiftDR(const uint8_t *tdi, unsigned char *tdo, int drlen, tapState_t
int Jtag::shiftIR(unsigned char tdi, int irlen, tapState_t end_state) int Jtag::shiftIR(unsigned char tdi, int irlen, tapState_t end_state)
{ {
if (irlen > 8) { if (irlen > 8) {
cerr << "Error: this method this direct char don't support more than 1 byte" << endl; std::cerr << "Error: this method this direct char don't support more than 1 byte" << std::endl;
return -1; return -1;
} }
return shiftIR(&tdi, NULL, irlen, end_state); return shiftIR(&tdi, NULL, irlen, end_state);

View File

@ -27,7 +27,6 @@
#include "part.hpp" #include "part.hpp"
#include "spiFlash.hpp" #include "spiFlash.hpp"
using namespace std;
#define ISC_ENABLE 0xC6 /* ISC_ENABLE - Offline Mode */ #define ISC_ENABLE 0xC6 /* ISC_ENABLE - Offline Mode */
# define ISC_ENABLE_FLASH_MODE (1 << 3) # define ISC_ENABLE_FLASH_MODE (1 << 3)
@ -162,10 +161,10 @@ using namespace std;
/* Nexus */ /* Nexus */
#define REG_NEXUS_STATUS_BSE_ERR_MASK (0x0f << 24) #define REG_NEXUS_STATUS_BSE_ERR_MASK (0x0f << 24)
Lattice::Lattice(Jtag *jtag, const string filename, const string &file_type, Lattice::Lattice(Jtag *jtag, const std::string filename, const std::string &file_type,
Device::prog_type_t prg_type, std::string flash_sector, bool verify, int8_t verbose, bool skip_load_bridge, bool skip_reset): Device::prog_type_t prg_type, std::string flash_sector, bool verify, int8_t verbose, bool skip_load_bridge, bool skip_reset):
Device(jtag, filename, file_type, verify, verbose), Device(jtag, filename, file_type, verify, verbose),
SPIInterface(filename, verbose, 0, verify, skip_load_bridge, skip_reset), FlashInterface(filename, verbose, 0, verify, skip_load_bridge, skip_reset),
_fpga_family(UNKNOWN_FAMILY), _flash_sector(LATTICE_FLASH_UNDEFINED) _fpga_family(UNKNOWN_FAMILY), _flash_sector(LATTICE_FLASH_UNDEFINED)
{ {
if (prg_type == Device::RD_FLASH) { if (prg_type == Device::RD_FLASH) {
@ -188,7 +187,7 @@ Lattice::Lattice(Jtag *jtag, const string filename, const string &file_type,
} }
/* check device family */ /* check device family */
uint32_t idcode = _jtag->get_target_device_id(); uint32_t idcode = _jtag->get_target_device_id();
string family = fpga_list[idcode].family; std::string family = fpga_list[idcode].family;
if (family == "MachXO2") { if (family == "MachXO2") {
_fpga_family = MACHXO2_FAMILY; _fpga_family = MACHXO2_FAMILY;
} else if (family == "MachXO3L" || family == "MachXO3LF") { } else if (family == "MachXO3L" || family == "MachXO3LF") {
@ -643,7 +642,7 @@ bool Lattice::program_intFlash(ConfigBitstreamParser *_cbp)
uint16_t ufm_start = 0; uint16_t ufm_start = 0;
uint16_t feabits; uint16_t feabits;
uint8_t eraseMode = 0; uint8_t eraseMode = 0;
vector<string> ufm_data, cfg_data, ebr_data; std::vector<std::string> ufm_data, cfg_data, ebr_data;
/* bypass */ /* bypass */
wr_rd(0xff, NULL, 0, NULL, 0); wr_rd(0xff, NULL, 0, NULL, 0);
@ -663,7 +662,7 @@ bool Lattice::program_intFlash(ConfigBitstreamParser *_cbp)
if (_file_extension == "jed") { if (_file_extension == "jed") {
JedParser *_jed = reinterpret_cast<JedParser *>(_cbp); JedParser *_jed = reinterpret_cast<JedParser *>(_cbp);
for (size_t i = 0; i < _jed->nb_section(); i++) { for (size_t i = 0; i < _jed->nb_section(); i++) {
string note = _jed->noteForSection(i); std::string note = _jed->noteForSection(i);
if (note == "TAG DATA") { if (note == "TAG DATA") {
eraseMode |= FLASH_ERASE_UFM; eraseMode |= FLASH_ERASE_UFM;
ufm_data = _jed->data_for_section(i); ufm_data = _jed->data_for_section(i);
@ -839,7 +838,7 @@ bool Lattice::post_flash_access()
_skip_reset = true; // avoid infinite loop _skip_reset = true; // avoid infinite loop
/* read flash 0 -> 255 */ /* read flash 0 -> 255 */
uint8_t buffer[256]; uint8_t buffer[256];
ret = SPIInterface::read(buffer, 0, 256); ret = FlashInterface::read(buffer, 0, 256);
loadConfiguration(); // reset again loadConfiguration(); // reset again
/* read ok? check if everything == 0xff */ /* read ok? check if everything == 0xff */
@ -988,9 +987,9 @@ bool Lattice::program_extFlash(unsigned int offset, bool unprotect_flash)
if (_file_extension == "mcs") { if (_file_extension == "mcs") {
McsParser *parser = (McsParser *)_bit; McsParser *parser = (McsParser *)_bit;
ret = SPIInterface::write(parser->getRecords(), unprotect_flash, true); ret = FlashInterface::write(parser->getRecords(), unprotect_flash, true);
} else { } else {
ret = SPIInterface::write(offset, _bit->getData(), _bit->getLength() / 8, ret = FlashInterface::write(offset, _bit->getData(), _bit->getLength() / 8,
unprotect_flash); unprotect_flash);
} }
@ -1536,7 +1535,7 @@ bool Lattice::pollBusyFlag(bool verbose)
if (verbose) if (verbose)
printf("pollBusyFlag :%02x\n", rx); printf("pollBusyFlag :%02x\n", rx);
if (timeout == 100000000){ if (timeout == 100000000){
cerr << "timeout" << endl; std::cerr << "timeout" << std::endl;
return false; return false;
} else { } else {
timeout++; timeout++;
@ -1586,7 +1585,7 @@ bool Lattice::flashErase(uint32_t mask)
return true; return true;
} }
bool Lattice::flashProg(uint32_t start_addr, const string &name, vector<string> data) bool Lattice::flashProg(uint32_t start_addr, const std::string &name, std::vector<std::string> data)
{ {
(void)start_addr; (void)start_addr;
ProgressBar progress("Writing " + name, data.size(), 50, _quiet); ProgressBar progress("Writing " + name, data.size(), 50, _quiet);
@ -2225,7 +2224,7 @@ bool Lattice::program_fea_MachXO3D()
bool Lattice::program_intFlash_MachXO3D(JedParser& _jed) bool Lattice::program_intFlash_MachXO3D(JedParser& _jed)
{ {
uint32_t erase_op = 0, prog_op = 0; uint32_t erase_op = 0, prog_op = 0;
vector<string> data; std::vector<std::string> data;
int offset, fuse_count; int offset, fuse_count;
/* bypass */ /* bypass */
@ -2251,7 +2250,7 @@ bool Lattice::program_intFlash_MachXO3D(JedParser& _jed)
/* if no data, nothing to do */ /* if no data, nothing to do */
continue; continue;
} }
string note = _jed.noteForSection(i); std::string note = _jed.noteForSection(i);
offset = _jed.offset_for_section(i) / 128; offset = _jed.offset_for_section(i) / 128;
erase_op = 0; erase_op = 0;

View File

@ -17,9 +17,9 @@
#include "jedParser.hpp" #include "jedParser.hpp"
#include "feaparser.hpp" #include "feaparser.hpp"
#include "latticeBitParser.hpp" #include "latticeBitParser.hpp"
#include "spiInterface.hpp" #include "flashInterface.hpp"
class Lattice: public Device, SPIInterface { class Lattice: public Device, FlashInterface {
public: public:
Lattice(Jtag *jtag, std::string filename, const std::string &file_type, Lattice(Jtag *jtag, std::string filename, const std::string &file_type,
Device::prog_type_t prg_type, std::string flash_sector, bool verify, Device::prog_type_t prg_type, std::string flash_sector, bool verify,
@ -34,32 +34,32 @@ class Lattice: public Device, SPIInterface {
bool Verify(std::vector<std::string> data, bool unlock = false, bool Verify(std::vector<std::string> data, bool unlock = false,
uint32_t flash_area = 0); uint32_t flash_area = 0);
bool dumpFlash(uint32_t base_addr, uint32_t len) override { bool dumpFlash(uint32_t base_addr, uint32_t len) override {
return SPIInterface::dump(base_addr, len); return FlashInterface::dump(base_addr, len);
} }
/*! /*!
* \brief display SPI flash ID and status register * \brief display SPI flash ID and status register
*/ */
bool detect_flash() override { bool detect_flash() override {
return SPIInterface::detect_flash(); return FlashInterface::detect_flash();
} }
/*! /*!
* \brief protect SPI flash blocks * \brief protect SPI flash blocks
*/ */
bool protect_flash(uint32_t len) override { bool protect_flash(uint32_t len) override {
return SPIInterface::protect_flash(len); return FlashInterface::protect_flash(len);
} }
/*! /*!
* \brief protect SPI flash blocks * \brief protect SPI flash blocks
*/ */
bool unprotect_flash() override { bool unprotect_flash() override {
return SPIInterface::unprotect_flash(); return FlashInterface::unprotect_flash();
} }
/*! /*!
* \brief bulk erase SPI flash * \brief bulk erase SPI flash
*/ */
bool bulk_erase_flash() override { bool bulk_erase_flash() override {
return SPIInterface::bulk_erase_flash(); return FlashInterface::bulk_erase_flash();
} }
/* spi interface */ /* spi interface */

View File

@ -7,11 +7,11 @@
#include <stdlib.h> #include <stdlib.h>
#include <algorithm> #include <algorithm>
#include <functional> #include <charconv>
#include <cctype> #include <cctype>
#include <iostream> #include <iostream>
#include <locale> #include <locale>
#include <sstream> #include <string_view>
#include <utility> #include <utility>
#include "display.hpp" #include "display.hpp"
@ -19,9 +19,8 @@
#include "latticeBitParser.hpp" #include "latticeBitParser.hpp"
using namespace std;
LatticeBitParser::LatticeBitParser(const string &filename, bool machxo2, bool ecp3, LatticeBitParser::LatticeBitParser(const std::string &filename, bool machxo2, bool ecp3,
bool verbose): bool verbose):
ConfigBitstreamParser(filename, ConfigBitstreamParser::BIN_MODE, verbose), ConfigBitstreamParser(filename, ConfigBitstreamParser::BIN_MODE, verbose),
_endHeader(0), _is_machXO2(machxo2), _is_ecp3(ecp3) _endHeader(0), _is_machXO2(machxo2), _is_ecp3(ecp3)
@ -31,62 +30,107 @@ LatticeBitParser::~LatticeBitParser()
{ {
} }
std::string LatticeBitParser::fmtIdcode(uint32_t id)
{
char tmp[8], buf[9] = "00000000";
std::to_chars_result conv = std::to_chars(tmp, tmp + 8, id, 16);
char *ptr = conv.ptr;
memcpy(buf + (8 - (ptr - tmp)), tmp, ptr - tmp);
return std::string(buf, 8);
}
int LatticeBitParser::parseHeader() int LatticeBitParser::parseHeader()
{ {
int currPos = 0; int currPos = 0;
if (_raw_data.empty()) {
printError("LatticeBitParser: empty bitstream");
return EXIT_FAILURE;
}
const uint32_t file_size = static_cast<uint32_t>(_raw_data.size());
/* check header signature */ /* check header signature */
/* radiant .bit start with LSCC */ /* radiant .bit start with LSCC */
if (_raw_data[0] == 'L') { if (_raw_data[0] == 'L') {
if (_raw_data.substr(0, 4) != "LSCC") { if (file_size < 4) {
printError("LatticeBitParser: bitstream too small");
return EXIT_FAILURE;
}
if (_raw_data.compare(0, 4, "LSCC") != 0) {
printf("Wrong File %s\n", _raw_data.substr(0, 4).c_str()); printf("Wrong File %s\n", _raw_data.substr(0, 4).c_str());
return EXIT_FAILURE; return EXIT_FAILURE;
} }
currPos += 4; currPos += 4;
} }
/* Check if bitstream size may store at least 0xff00 + another 0xff */
if (file_size <= currPos + 3) {
printError("LatticeBitParser: bitstream too small");
return EXIT_FAILURE;
}
/* bit file comment area start with 0xff00 */ /* bit file comment area start with 0xff00 */
if ((uint8_t)_raw_data[currPos] != 0xff || if ((uint8_t)_raw_data[currPos] != 0xff ||
(uint8_t)_raw_data[currPos + 1] != 0x00) { (uint8_t)_raw_data[currPos + 1] != 0x00) {
printf("Wrong File %02x%02x\n", (uint8_t) _raw_data[currPos], printf("Wrong File %02x%02x\n", (uint8_t) _raw_data[currPos],
(uint8_t)_raw_data[currPos]); (uint8_t)_raw_data[currPos + 1]);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
currPos+=2; currPos += 2;
_endHeader = _raw_data.find(0xff, currPos); _endHeader = _raw_data.find(0xff, currPos);
if (_endHeader == string::npos) { if (_endHeader == std::string::npos) {
printError("Error: preamble not found\n"); printError("Error: preamble not found\n");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
/* .bit for MACHXO3D seems to have more 0xff before preamble key */ /* .bit for MACHXO3D seems to have more 0xff before preamble key */
size_t pos = _raw_data.find(0xb3, _endHeader); size_t pos = _raw_data.find(0xb3, _endHeader);
if (pos == string::npos) { if (pos == std::string::npos) {
printError("Preamble key not found"); printError("Preamble key not found");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
/* preamble must have at least 3 x 0xff + enc_key byte before 0xb3 */
if (pos < _endHeader + 4) {
printError("LatticeBitParser: wrong preamble size");
return EXIT_FAILURE;
}
//0xbe is the key for encrypted bitstreams in Nexus fpgas //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) { const uint8_t enc_key = static_cast<uint8_t>(_raw_data[pos - 1]);
if (enc_key != 0xbd && enc_key != 0xbf && enc_key != 0xbe) {
printError("Wrong preamble key"); printError("Wrong preamble key");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
_endHeader = pos - 4; // align to 3 Dummy Bytes + preamble (ie. Header start offset). _endHeader = pos - 4; // align to 3 Dummy Bytes + preamble (ie. Header start offset).
if (currPos >= _endHeader) {
printError("LatticeBitParser: no header");
return EXIT_FAILURE;
}
/* parse header */ /* parse header */
istringstream lineStream(_raw_data.substr(currPos, _endHeader - currPos)); std::string_view lineStream(_raw_data.data() + currPos, _endHeader - currPos);
string buff; while (!lineStream.empty()) {
while (std::getline(lineStream, buff, '\0')) { const size_t null_pos = lineStream.find('\0');
pos = buff.find_first_of(':', 0); const std::string_view buff = lineStream.substr(0, null_pos);
if (pos != string::npos) { pos = buff.find(':');
string key(buff.substr(0, pos)); if (pos != std::string_view::npos) {
string val(buff.substr(pos+1, buff.size())); const std::string_view key = buff.substr(0, pos);
int startPos = val.find_first_not_of(" "); const std::string_view val = buff.substr(pos + 1);
int endPos = val.find_last_not_of(" ")+1; const size_t startPos = val.find_first_not_of(' ');
_hdr[key] = val.substr(startPos, endPos).c_str(); if (startPos != std::string_view::npos) {
const size_t endPos = val.find_last_not_of(' ');
_hdr.insert_or_assign(std::string(key),
std::string(val.substr(startPos, endPos - startPos + 1)));
}
} }
if (null_pos == std::string_view::npos)
break;
lineStream = lineStream.substr(null_pos + 1);
} }
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
@ -94,10 +138,14 @@ int LatticeBitParser::parseHeader()
int LatticeBitParser::parse() int LatticeBitParser::parse()
{ {
/* until 0xFFFFBDB3 0xFFFF */ /* until 0xFFFFBDB3 0xFFFF */
if (parseHeader() < 0) if (parseHeader() != EXIT_SUCCESS)
return EXIT_FAILURE; return EXIT_FAILURE;
/* check preamble */ /* check preamble */
if (_endHeader + 4 >= _raw_data.size()) {
printError("LatticeBitParser: truncated preamble");
return EXIT_FAILURE;
}
uint32_t preamble = (*(uint32_t *)&_raw_data[_endHeader + 1]); uint32_t preamble = (*(uint32_t *)&_raw_data[_endHeader + 1]);
//0xb3beffff is the preamble for encrypted bitstreams in Nexus fpgas //0xb3beffff is the preamble for encrypted bitstreams in Nexus fpgas
if ((preamble != 0xb3bdffff) && (preamble != 0xb3bfffff) && (preamble != 0xb3beffff)) { if ((preamble != 0xb3bdffff) && (preamble != 0xb3bfffff) && (preamble != 0xb3beffff)) {
@ -117,18 +165,26 @@ int LatticeBitParser::parse()
printError("encrypted bitstream not supported for machXO2"); printError("encrypted bitstream not supported for machXO2");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
string part = getHeaderVal("Part"); std::map<std::string, std::string>::const_iterator part_it = _hdr.find("Part");
string subpart = part.substr(0, part.find_last_of("-")); if (part_it == _hdr.end()) {
for (auto && fpga : fpga_list) { printError("LatticeBitParser: Missing Part in header section");
return EXIT_FAILURE;
}
std::string_view subpart(part_it->second);
const size_t pos = subpart.find_last_of('-');
if (pos == std::string_view::npos) {
printError("LatticeBitParser: invalid Part string");
return EXIT_FAILURE;
}
subpart = subpart.substr(0, pos);
for (const std::pair<const uint32_t, fpga_model> &fpga : fpga_list) {
if (fpga.second.manufacturer != "lattice") if (fpga.second.manufacturer != "lattice")
continue; continue;
string model = fpga.second.model; const std::string_view model = fpga.second.model;
if (subpart.compare(0, model.size(), model) == 0) { if (subpart.compare(0, model.size(), model) == 0) {
char __buf[10]; _hdr["idcode"] = fmtIdcode(fpga.first);
int __buf_valid_bytes; break;
__buf_valid_bytes = snprintf(__buf, 9, "%08x", fpga.first);
_hdr["idcode"] = string(__buf, __buf_valid_bytes);
_hdr["idcode"].resize(8, ' ');
} }
} }
} }
@ -141,26 +197,24 @@ int LatticeBitParser::parse()
* Here the header contains 3x8 Dummy bit + preamble so only * Here the header contains 3x8 Dummy bit + preamble so only
* 13bits 8x13= 112bits must be added as padding. * 13bits 8x13= 112bits must be added as padding.
*/ */
const uint32_t offset = (_is_ecp3) ? 14 : 0; const uint32_t offset = (_is_ecp3) ? 13 : 0;
_bit_data.resize(_raw_data.size() - _endHeader + offset); _bit_data.resize(_raw_data.size() - _endHeader + offset);
if (_is_ecp3) { if (_is_ecp3)
std::string tmp(13, 0xff); std::fill_n(_bit_data.begin(), offset, uint8_t{0xff});
std::move(tmp.begin(), tmp.end(), _bit_data.begin());
}
std::move(_raw_data.begin() + _endHeader, _raw_data.end(), _bit_data.begin() + offset); std::move(_raw_data.begin() + _endHeader, _raw_data.end(), _bit_data.begin() + offset);
_bit_length = _bit_data.size() * 8; _bit_length = _bit_data.size() * 8;
} else { } else {
_endHeader++; _endHeader++;
const uint32_t len = _raw_data.size() - _endHeader; const size_t len = _raw_data.size() - _endHeader;
uint32_t max_len = 16; const size_t array_len = (len + 15) / 16;
for (uint32_t i = 0; i < len; i+=max_len) { _bit_array.reserve(array_len);
std::string tmp(16, 0xff); for (size_t i = 0; i < len; i += 16) {
/* each line must have 16B */ const size_t max_len = std::min<size_t>(16, len - i);
if (len < i + max_len) _bit_array.emplace_back(16, '\xff');
max_len = len - i; std::string &tmp = _bit_array.back();
for (uint32_t pos = 0; pos < max_len; pos++) for (uint32_t pos = 0; pos < max_len; pos++)
tmp[pos] = reverseByte(_raw_data[i+pos+_endHeader]); tmp[pos] = static_cast<char>(reverseByte(
_bit_array.push_back(std::move(tmp)); static_cast<uint8_t>(_raw_data[_endHeader + i + pos])));
} }
_bit_length = _bit_array.size() * 16 * 8; _bit_length = _bit_array.size() * 16 * 8;
} }
@ -183,52 +237,73 @@ int LatticeBitParser::parse()
bool LatticeBitParser::parseCfgData() bool LatticeBitParser::parseCfgData()
{ {
uint8_t *ptr; const uint8_t *raw = reinterpret_cast<const uint8_t *>(_raw_data.data());
const size_t raw_size = _raw_data.size();
const uint8_t *ptr;
size_t pos = _endHeader + 5; // drop 16 Dummy bits and preamble size_t pos = _endHeader + 5; // drop 16 Dummy bits and preamble
uint32_t idcode; uint32_t idcode;
char __buf[10];
int __buf_valid_bytes; while (pos < raw_size) {
while (pos < _raw_data.size()) { uint8_t cmd = raw[pos++];
uint8_t cmd = (uint8_t) _raw_data[pos++];
switch (cmd) { switch (cmd) {
case BYPASS: case BYPASS:
break; break;
case LSC_RESET_CRC: case LSC_RESET_CRC:
if (pos + 3 > raw_size) {
printError("LatticeBitParser: truncated bitstream");
return false;
}
pos += 3; pos += 3;
break; break;
case ECP3_VERIFY_ID: case ECP3_VERIFY_ID:
ptr = (uint8_t*)&_raw_data[pos]; if (pos + 7 > raw_size) {
printError("LatticeBitParser: truncated bitstream");
return false;
}
ptr = raw + pos;
idcode = (((uint32_t)reverseByte(ptr[6])) << 24) | idcode = (((uint32_t)reverseByte(ptr[6])) << 24) |
(((uint32_t)reverseByte(ptr[5])) << 16) | (((uint32_t)reverseByte(ptr[5])) << 16) |
(((uint32_t)reverseByte(ptr[4])) << 8) | (((uint32_t)reverseByte(ptr[4])) << 8) |
(((uint32_t)reverseByte(ptr[3])) << 0); (((uint32_t)reverseByte(ptr[3])) << 0);
__buf_valid_bytes = snprintf(__buf, 9, "%08x", idcode); _hdr["idcode"] = fmtIdcode(idcode);
_hdr["idcode"] = string(__buf, __buf_valid_bytes);
_hdr["idcode"].resize(8, ' ');
pos += 7; pos += 7;
if (!_is_machXO2) if (!_is_machXO2)
return true; return true;
break; break;
case VERIFY_ID: case VERIFY_ID:
ptr = (uint8_t*)&_raw_data[pos]; if (pos + 7 > raw_size) {
printError("LatticeBitParser: truncated bitstream");
return false;
}
ptr = raw + pos;
idcode = (((uint32_t)ptr[3]) << 24) | idcode = (((uint32_t)ptr[3]) << 24) |
(((uint32_t)ptr[4]) << 16) | (((uint32_t)ptr[4]) << 16) |
(((uint32_t)ptr[5]) << 8) | (((uint32_t)ptr[5]) << 8) |
(((uint32_t)ptr[6]) << 0); (((uint32_t)ptr[6]) << 0);
__buf_valid_bytes = snprintf(__buf, 9, "%08x", idcode); _hdr["idcode"] = fmtIdcode(idcode);
_hdr["idcode"] = string(__buf, __buf_valid_bytes);
_hdr["idcode"].resize(8, ' ');
pos += 7; pos += 7;
if (!_is_machXO2) if (!_is_machXO2)
return true; return true;
break; break;
case LSC_WRITE_COMP_DIC: case LSC_WRITE_COMP_DIC:
if (pos + 11 > raw_size) {
printError("LatticeBitParser: truncated bitstream");
return false;
}
pos += 11; pos += 11;
break; break;
case LSC_PROG_CNTRL0: case LSC_PROG_CNTRL0:
if (pos + 7 > raw_size) {
printError("LatticeBitParser: truncated bitstream");
return false;
}
pos += 7; pos += 7;
break; break;
case LSC_INIT_ADDRESS: case LSC_INIT_ADDRESS:
if (pos + 3 > raw_size) {
printError("LatticeBitParser: truncated bitstream");
return false;
}
pos += 3; pos += 3;
break; break;
case LSC_PROG_INCR_CMP: case LSC_PROG_INCR_CMP:
@ -239,6 +314,10 @@ bool LatticeBitParser::parseCfgData()
return false; return false;
case LSC_SPI_MODE: // optional: 0x79 + mode (fast-read:0x49, case LSC_SPI_MODE: // optional: 0x79 + mode (fast-read:0x49,
// dual-spi:0x51, qspi:0x59) + 2 x 0x00 // dual-spi:0x51, qspi:0x59) + 2 x 0x00
if (pos + 3 > raw_size) {
printError("LatticeBitParser: truncated bitstream");
return false;
}
pos += 3; pos += 3;
break; break;
default: default:

View File

@ -24,11 +24,17 @@ class LatticeBitParser: public ConfigBitstreamParser {
* \brief return configuration data with structure similar to jedec * \brief return configuration data with structure similar to jedec
* \return configuration data * \return configuration data
*/ */
std::vector<std::string> getDataArray() {return _bit_array;} std::vector<std::string> &getDataArray() {return _bit_array;}
private: private:
int parseHeader(); int parseHeader();
bool parseCfgData(); bool parseCfgData();
/*!
* \brief format a 32-bit value as 8 zero-padded lowercase hex digits
* \param[in] id: value to format
* \return 8-character hex string
*/
static std::string fmtIdcode(uint32_t id);
size_t _endHeader; size_t _endHeader;
bool _is_machXO2; bool _is_machXO2;
bool _is_ecp3; bool _is_ecp3;

View File

@ -20,7 +20,6 @@
#include "display.hpp" #include "display.hpp"
#include "libusb_ll.hpp" #include "libusb_ll.hpp"
using namespace std;
libusb_ll::libusb_ll(int vid, int pid, int8_t _verbose): libusb_ll::libusb_ll(int vid, int pid, int8_t _verbose):
_usb_ctx(nullptr), _verbose(_verbose >= 2) _usb_ctx(nullptr), _verbose(_verbose >= 2)

View File

@ -54,6 +54,7 @@
#endif #endif
#include "jtag.hpp" #include "jtag.hpp"
#include "part.hpp" #include "part.hpp"
#include "progressBar.hpp"
#include "spiFlash.hpp" #include "spiFlash.hpp"
#include "rawParser.hpp" #include "rawParser.hpp"
#ifdef ENABLE_XILINX_SUPPORT #ifdef ENABLE_XILINX_SUPPORT
@ -68,22 +69,22 @@
#define DEFAULT_FREQ 6000000 #define DEFAULT_FREQ 6000000
using namespace std;
struct arguments { struct arguments {
int8_t verbose; int8_t verbose;
bool force_terminal_mode;
bool reset, detect, detect_flash, verify, scan_usb; bool reset, detect, detect_flash, verify, scan_usb;
unsigned int offset; unsigned int offset;
string bit_file; std::string bit_file;
string secondary_bit_file; std::string secondary_bit_file;
string device; std::string device;
string cable; std::string cable;
string ftdi_serial; std::string ftdi_serial;
int ftdi_channel; int ftdi_channel;
int status_pin; int status_pin;
uint32_t freq; uint32_t freq;
bool invert_read_edge; bool invert_read_edge;
string board; std::string board;
bool pin_config; bool pin_config;
bool list_cables; bool list_cables;
bool list_boards; bool list_boards;
@ -92,13 +93,13 @@ struct arguments {
bool is_list_command; bool is_list_command;
bool spi; bool spi;
bool dfu; bool dfu;
string file_type; std::string file_type;
string fpga_part; std::string fpga_part;
string bridge_path; std::string bridge_path;
string probe_firmware; std::string probe_firmware;
int index_chain; int index_chain;
unsigned int file_size; unsigned int file_size;
string target_flash; std::string target_flash;
bool external_flash; bool external_flash;
bool spi_flash_type; bool spi_flash_type;
int16_t altsetting; int16_t altsetting;
@ -107,26 +108,26 @@ struct arguments {
int16_t cable_index; int16_t cable_index;
uint8_t bus_addr; uint8_t bus_addr;
uint8_t device_addr; uint8_t device_addr;
string ip_adr; std::string ip_adr;
uint32_t protect_flash; uint32_t protect_flash;
bool unprotect_flash; bool unprotect_flash;
bool enable_quad; bool enable_quad;
bool disable_quad; bool disable_quad;
bool bulk_erase_flash; bool bulk_erase_flash;
string flash_sector; std::string flash_sector;
bool skip_load_bridge; bool skip_load_bridge;
bool skip_reset; bool skip_reset;
/* xvc server */ /* xvc server */
bool xvc; bool xvc;
int port; int port;
string interface; std::string interface;
string mcufw; std::string mcufw;
bool conmcu; bool conmcu;
std::map<uint32_t, misc_device> user_misc_devs; std::map<uint32_t, misc_device> user_misc_devs;
bool read_dna; bool read_dna;
bool read_xadc; bool read_xadc;
string read_register; std::string read_register;
string user_flash; std::string user_flash;
}; };
int run_xvc_server(const struct arguments &args, const cable_t &cable, int run_xvc_server(const struct arguments &args, const cable_t &cable,
@ -149,7 +150,9 @@ int main(int argc, char **argv)
jtag_pins_conf_t pins_config = {0, 0, 0, 0, 0, 0}; jtag_pins_conf_t pins_config = {0, 0, 0, 0, 0, 0};
/* command line args. */ /* command line args. */
struct arguments args = {0, struct arguments args = {
/* verbose, force_terminal_mode */
0, false,
//reset, detect, detect_flash, verify, scan_usb //reset, detect, detect_flash, verify, scan_usb
false, false, false, false, false, false, false, false, false, false,
0, "", "", "", "-", "", -1, 0, "", "", "", "-", "", -1,
@ -172,15 +175,18 @@ int main(int argc, char **argv)
if (ret != 0) if (ret != 0)
return (ret == 1) ? EXIT_SUCCESS : EXIT_FAILURE; return (ret == 1) ? EXIT_SUCCESS : EXIT_FAILURE;
if (args.force_terminal_mode)
ProgressBar::setForceTerminalMode();
if (args.is_list_command) { if (args.is_list_command) {
displaySupported(args); displaySupported(args);
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
if (args.prg_type == Device::WR_SRAM) if (args.prg_type == Device::WR_SRAM)
cout << "write to ram" << endl; std::cout << "write to ram" << std::endl;
if (args.prg_type == Device::WR_FLASH) if (args.prg_type == Device::WR_FLASH)
cout << "write to flash" << endl; std::cout << "write to flash" << std::endl;
if (args.board[0] != '-') { if (args.board[0] != '-') {
if (board_list.find(args.board) != board_list.end()) { if (board_list.find(args.board) != board_list.end()) {
@ -208,7 +214,7 @@ int main(int argc, char **argv)
if (args.cable[0] == '-') { // no user selection if (args.cable[0] == '-') { // no user selection
args.cable = (*t).first; // use board default cable args.cable = (*t).first; // use board default cable
} else { } else {
cout << "Board default cable overridden with " << args.cable << endl; std::cout << "Board default cable overridden with " << args.cable << std::endl;
} }
} }
@ -289,16 +295,17 @@ int main(int argc, char **argv)
cable.config.index = args.cable_index; cable.config.index = args.cable_index;
cable.config.status_pin = args.status_pin; cable.config.status_pin = args.status_pin;
#ifdef USE_LIBFTDI
/* ----------------------- */ /* ----------------------- */
/* SPI FLASH direct access */ /* SPI FLASH direct access */
/* ----------------------- */ /* ----------------------- */
if (args.spi || (board && board->mode == COMM_SPI)) if (args.spi || (board && board->mode == COMM_SPI)) {
#ifdef USE_LIBFTDI
return spi_comm(args, cable, &pins_config, board); return spi_comm(args, cable, &pins_config, board);
#else #else
printError("SPI Flash Direct access: disabled at build time"); printError("SPI Flash Direct access: disabled at build time");
return EXIT_FAILURE; return EXIT_FAILURE;
#endif #endif
}
/* ------------------- */ /* ------------------- */
/* DFU access */ /* DFU access */
@ -335,7 +342,7 @@ int main(int argc, char **argv)
dfu = new DFU(args.bit_file, args.detect, vid, pid, altsetting, dfu = new DFU(args.bit_file, args.detect, vid, pid, altsetting,
args.verbose); args.verbose);
} catch (std::exception &e) { } catch (std::exception &e) {
printError("DFU init failed with: " + string(e.what())); printError("DFU init failed with: " + std::string(e.what()));
return EXIT_FAILURE; return EXIT_FAILURE;
} }
/* if verbose or detect: display device */ /* if verbose or detect: display device */
@ -349,7 +356,7 @@ int main(int argc, char **argv)
try { try {
dfu->download(); dfu->download();
} catch (std::exception &e) { } catch (std::exception &e) {
printError("DFU download failed with: " + string(e.what())); printError("DFU download failed with: " + std::string(e.what()));
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -387,18 +394,18 @@ int main(int argc, char **argv)
args.invert_read_edge, args.probe_firmware, args.invert_read_edge, args.probe_firmware,
args.user_misc_devs); args.user_misc_devs);
} catch (std::exception &e) { } catch (std::exception &e) {
printError("JTAG init failed with: " + string(e.what())); printError("JTAG init failed with: " + std::string(e.what()));
return EXIT_FAILURE; return EXIT_FAILURE;
} }
/* chain detection */ /* chain detection */
vector<uint32_t> listDev = jtag->get_devices_list(); std::vector<uint32_t> listDev = jtag->get_devices_list();
size_t found = listDev.size(); size_t found = listDev.size();
int idcode = -1; int idcode = -1;
size_t index = 0; size_t index = 0;
if (args.verbose > 0) if (args.verbose > 0)
cout << "found " << std::to_string(found) << " devices" << endl; std::cout << "found " << std::to_string(found) << " devices" << std::endl;
/* in verbose mode or when detect /* in verbose mode or when detect
* display full chain with details * display full chain with details
@ -468,7 +475,7 @@ int main(int argc, char **argv)
/* detect svf file and program the device */ /* detect svf file and program the device */
if (!args.file_type.compare("svf") || if (!args.file_type.compare("svf") ||
args.bit_file.find(".svf") != string::npos) { args.bit_file.find(".svf") != std::string::npos) {
#ifdef ENABLE_SVF_JTAG #ifdef ENABLE_SVF_JTAG
SVF_jtag *svf = new SVF_jtag(jtag, args.verbose); SVF_jtag *svf = new SVF_jtag(jtag, args.verbose);
try { try {
@ -488,12 +495,12 @@ int main(int argc, char **argv)
* mainly used in conjunction with --index-chain * mainly used in conjunction with --index-chain
*/ */
if (fpga_list.find(idcode) == fpga_list.end()) { if (fpga_list.find(idcode) == fpga_list.end()) {
cerr << "Error: device " << hex << idcode << " not supported" << endl; std::cerr << "Error: device " << std::hex << idcode << " not supported" << std::endl;
delete(jtag); delete(jtag);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
string fab = fpga_list[idcode].manufacturer; std::string fab = fpga_list[idcode].manufacturer;
Device *fpga; Device *fpga;
@ -571,7 +578,7 @@ int main(int argc, char **argv)
return EXIT_FAILURE; return EXIT_FAILURE;
} }
} catch (std::exception &e) { } catch (std::exception &e) {
printError("Error: Failed to claim FPGA device: " + string(e.what())); printError("Error: Failed to claim FPGA device: " + std::string(e.what()));
delete(jtag); delete(jtag);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -583,7 +590,7 @@ int main(int argc, char **argv)
try { try {
fpga->program(args.offset, args.unprotect_flash); fpga->program(args.offset, args.unprotect_flash);
} catch (std::exception &e) { } catch (std::exception &e) {
printError("Error: Failed to program FPGA: " + string(e.what())); printError("Error: Failed to program FPGA: " + std::string(e.what()));
delete(fpga); delete(fpga);
delete(jtag); delete(jtag);
return EXIT_FAILURE; return EXIT_FAILURE;
@ -670,7 +677,7 @@ int run_xvc_server(const struct arguments &args, const cable_t &cable,
xvc->close_connection(); xvc->close_connection();
delete xvc; delete xvc;
} catch (std::exception &e) { } catch (std::exception &e) {
printError("XVC_server failed with " + string(e.what())); printError("XVC_server failed with " + std::string(e.what()));
return EXIT_FAILURE; return EXIT_FAILURE;
} }
printInfo("Xilinx Virtual Cable Stopped! "); printInfo("Xilinx Virtual Cable Stopped! ");
@ -786,7 +793,7 @@ int spi_comm(struct arguments args, const cable_t &cable,
spi->gpio_clear(board->reset_pin, true); spi->gpio_clear(board->reset_pin, true);
} }
SPIFlash flash((SPIInterface *)spi, args.unprotect_flash, args.verbose); SPIFlash flash((FlashInterface *)spi, args.unprotect_flash, args.verbose);
flash.display_status_reg(); flash.display_status_reg();
if (args.prg_type != Device::RD_FLASH && if (args.prg_type != Device::RD_FLASH &&
@ -814,7 +821,7 @@ int spi_comm(struct arguments args, const cable_t &cable,
try { try {
flash.erase_and_prog(args.offset, bit->getData(), bit->getLength()/8); flash.erase_and_prog(args.offset, bit->getData(), bit->getLength()/8);
} catch (std::exception &e) { } catch (std::exception &e) {
printError("FAIL: " + string(e.what())); printError("FAIL: " + std::string(e.what()));
} }
if (args.verify) if (args.verify)
@ -850,7 +857,7 @@ int spi_comm(struct arguments args, const cable_t &cable,
// parse double from string in engineering notation // parse double from string in engineering notation
// can deal with postfixes k and m, add more when required // can deal with postfixes k and m, add more when required
static int parse_eng(string arg, double *dst) { static int parse_eng(std::string arg, double *dst) {
try { try {
size_t end; size_t end;
double base = stod(arg, &end); double base = stod(arg, &end);
@ -872,7 +879,7 @@ static int parse_eng(string arg, double *dst) {
return EINVAL; return EINVAL;
} }
} catch (...) { } catch (...) {
cerr << "error : speed: invalid format" << endl; std::cerr << "error : speed: invalid format" << std::endl;
return EINVAL; return EINVAL;
} }
} }
@ -881,8 +888,8 @@ static int parse_eng(string arg, double *dst) {
int parse_opt(int argc, char **argv, struct arguments *args, int parse_opt(int argc, char **argv, struct arguments *args,
jtag_pins_conf_t *pins_config) jtag_pins_conf_t *pins_config)
{ {
string freqo; std::string freqo;
vector<string> pins, bus_dev_num; std::vector<std::string> pins, bus_dev_num;
bool verbose = false, quiet = false; bool verbose = false, quiet = false;
int8_t verbose_level = -2; int8_t verbose_level = -2;
try { try {
@ -902,11 +909,11 @@ int parse_opt(int argc, char **argv, struct arguments *args,
" UltraScale boards)", " UltraScale boards)",
cxxopts::value<std::string>(args->secondary_bit_file)) cxxopts::value<std::string>(args->secondary_bit_file))
("b,board", "board name, may be used instead of cable", ("b,board", "board name, may be used instead of cable",
cxxopts::value<string>(args->board)) cxxopts::value<std::string>(args->board))
("B,bridge", "disable spiOverJtag model detection by providing " ("B,bridge", "disable spiOverJtag model detection by providing "
"bitstream(intel/xilinx)", "bitstream(intel/xilinx)",
cxxopts::value<string>(args->bridge_path)) cxxopts::value<std::string>(args->bridge_path))
("c,cable", "jtag interface", cxxopts::value<string>(args->cable)) ("c,cable", "jtag interface", cxxopts::value<std::string>(args->cable))
("status-pin", ("status-pin",
"JTAG mode / FTDI: GPIO pin number to use as a status indicator (active low)", "JTAG mode / FTDI: GPIO pin number to use as a status indicator (active low)",
cxxopts::value<int>(args->status_pin)) cxxopts::value<int>(args->status_pin))
@ -919,16 +926,14 @@ int parse_opt(int argc, char **argv, struct arguments *args,
cxxopts::value<int16_t>(args->cable_index)) cxxopts::value<int16_t>(args->cable_index))
("busdev-num", ("busdev-num",
"select a probe by it bus and device number (bus_num:device_addr)", "select a probe by it bus and device number (bus_num:device_addr)",
cxxopts::value<vector<string>>(bus_dev_num)) cxxopts::value<std::vector<std::string>>(bus_dev_num))
("ftdi-serial", "FTDI chip serial number", ("ftdi-serial", "FTDI chip serial number",
cxxopts::value<string>(args->ftdi_serial)) cxxopts::value<std::string>(args->ftdi_serial))
("ftdi-channel", ("ftdi-channel",
"FTDI chip channel number (channels 0-3 map to A-D)", "FTDI chip channel number (channels 0-3 map to A-D)",
cxxopts::value<int>(args->ftdi_channel)) cxxopts::value<int>(args->ftdi_channel))
#if defined(USE_DEVICE_ARG)
("d,device", "device to use (/dev/ttyUSBx)", ("d,device", "device to use (/dev/ttyUSBx)",
cxxopts::value<string>(args->device)) cxxopts::value<std::string>(args->device))
#endif
("detect", "detect FPGA, add -f to show connected flash", ("detect", "detect FPGA, add -f to show connected flash",
cxxopts::value<bool>(args->detect)) cxxopts::value<bool>(args->detect))
("dfu", "DFU mode", cxxopts::value<bool>(args->dfu)) ("dfu", "DFU mode", cxxopts::value<bool>(args->dfu))
@ -942,7 +947,7 @@ int parse_opt(int argc, char **argv, struct arguments *args,
("target-flash", ("target-flash",
"for boards with multiple flash chips (some Xilinx UltraScale" "for boards with multiple flash chips (some Xilinx UltraScale"
" boards), select the target flash: primary (default), secondary or both", " boards), select the target flash: primary (default), secondary or both",
cxxopts::value<string>(args->target_flash)) cxxopts::value<std::string>(args->target_flash))
("external-flash", ("external-flash",
"select ext flash for device with internal and external storage", "select ext flash for device with internal and external storage",
cxxopts::value<bool>(args->external_flash)) cxxopts::value<bool>(args->external_flash))
@ -951,20 +956,20 @@ int parse_opt(int argc, char **argv, struct arguments *args,
cxxopts::value<unsigned int>(args->file_size)) cxxopts::value<unsigned int>(args->file_size))
("file-type", ("file-type",
"provides file type instead of let's deduced by using extension", "provides file type instead of let's deduced by using extension",
cxxopts::value<string>(args->file_type)) cxxopts::value<std::string>(args->file_type))
("flash-sector", "flash sector (Lattice and Altera MAX10 parts only)", ("flash-sector", "flash sector (Lattice and Altera MAX10 parts only)",
cxxopts::value<string>(args->flash_sector)) cxxopts::value<std::string>(args->flash_sector))
("fpga-part", "fpga model flavor + package", ("fpga-part", "fpga model flavor + package",
cxxopts::value<string>(args->fpga_part)) cxxopts::value<std::string>(args->fpga_part))
("freq", "jtag frequency (Hz)", cxxopts::value<string>(freqo)) ("freq", "jtag frequency (Hz)", cxxopts::value<std::string>(freqo))
("f,write-flash", ("f,write-flash",
"write bitstream in flash (default: false)") "write bitstream in flash (default: false)")
("index-chain", "device index in JTAG-chain", ("index-chain", "device index in JTAG-chain",
cxxopts::value<int>(args->index_chain)) cxxopts::value<int>(args->index_chain))
("misc-device", "add JTAG non-FPGA devices <idcode,irlen,name>", ("misc-device", "add JTAG non-FPGA devices <idcode,irlen,name>",
cxxopts::value<vector<string>>()) cxxopts::value<std::vector<std::string>>())
("ip", "IP address (XVC and remote bitbang client)", ("ip", "IP address (XVC and remote bitbang client)",
cxxopts::value<string>(args->ip_adr)) cxxopts::value<std::string>(args->ip_adr))
("list-boards", "list all supported boards", ("list-boards", "list all supported boards",
cxxopts::value<bool>(args->list_boards)) cxxopts::value<bool>(args->list_boards))
("list-cables", "list all supported cables", ("list-cables", "list all supported cables",
@ -976,9 +981,9 @@ int parse_opt(int argc, char **argv, struct arguments *args,
("o,offset", "Start address (in bytes) for read/write into non volatile memory (default: 0)", ("o,offset", "Start address (in bytes) for read/write into non volatile memory (default: 0)",
cxxopts::value<unsigned int>(args->offset)) cxxopts::value<unsigned int>(args->offset))
("pins", "pin config TDI:TDO:TCK:TMS or MOSI:MISO:SCK:CS[:HOLDN:WPN]", ("pins", "pin config TDI:TDO:TCK:TMS or MOSI:MISO:SCK:CS[:HOLDN:WPN]",
cxxopts::value<vector<string>>(pins)) cxxopts::value<std::vector<std::string>>(pins))
("probe-firmware", "firmware for JTAG probe (usbBlasterII)", ("probe-firmware", "firmware for JTAG probe (usbBlasterII)",
cxxopts::value<string>(args->probe_firmware)) cxxopts::value<std::string>(args->probe_firmware))
("protect-flash", "protect SPI flash area", ("protect-flash", "protect SPI flash area",
cxxopts::value<uint32_t>(args->protect_flash)) cxxopts::value<uint32_t>(args->protect_flash))
("quiet", "Produce quiet output (no progress bar)", ("quiet", "Produce quiet output (no progress bar)",
@ -998,6 +1003,9 @@ int parse_opt(int argc, char **argv, struct arguments *args,
("v,verbose", "Produce verbose output", cxxopts::value<bool>(verbose)) ("v,verbose", "Produce verbose output", cxxopts::value<bool>(verbose))
("verbose-level", "verbose level -1: quiet, 0: normal, 1:verbose, 2:debug", ("verbose-level", "verbose level -1: quiet, 0: normal, 1:verbose, 2:debug",
cxxopts::value<int8_t>(verbose_level)) cxxopts::value<int8_t>(verbose_level))
("force-terminal-mode",
"force progress bar output as if connected to a terminal",
cxxopts::value<bool>(args->force_terminal_mode))
("h,help", "Give this help list") ("h,help", "Give this help list")
("verify", "Verify write operation (SPI Flash only)", ("verify", "Verify write operation (SPI Flash only)",
cxxopts::value<bool>(args->verify)) cxxopts::value<bool>(args->verify))
@ -1016,16 +1024,16 @@ int parse_opt(int argc, char **argv, struct arguments *args,
("X,read-xadc", "Read XADC (Xilinx FPGA only)", ("X,read-xadc", "Read XADC (Xilinx FPGA only)",
cxxopts::value<bool>(args->read_xadc)) cxxopts::value<bool>(args->read_xadc))
("read-register", "Read Status Register(Xilinx FPGA only)", ("read-register", "Read Status Register(Xilinx FPGA only)",
cxxopts::value<string>(args->read_register)) cxxopts::value<std::string>(args->read_register))
("user-flash", "User flash file (Gowin LittleBee FPGA only)", ("user-flash", "User flash file (Gowin LittleBee FPGA only)",
cxxopts::value<string>(args->user_flash)) cxxopts::value<std::string>(args->user_flash))
("V,Version", "Print program version"); ("V,Version", "Print program version");
options.parse_positional({"bitstream"}); options.parse_positional({"bitstream"});
auto result = options.parse(argc, argv); auto result = options.parse(argc, argv);
if (result.count("help")) { if (result.count("help")) {
cout << options.help() << endl; std::cout << options.help() << std::endl;
return 1; return 1;
} }
@ -1048,7 +1056,7 @@ int parse_opt(int argc, char **argv, struct arguments *args,
} }
if (result.count("Version")) { if (result.count("Version")) {
cout << "openFPGALoader " << VERSION << endl; std::cout << "openFPGALoader " << VERSION << std::endl;
return 1; return 1;
} }
@ -1192,7 +1200,7 @@ int parse_opt(int argc, char **argv, struct arguments *args,
!args->detect !args->detect
) { ) {
printError("Error: secondary bitfile not specified"); printError("Error: secondary bitfile not specified");
cout << options.help() << endl; std::cout << options.help() << std::endl;
return -1; return -1;
} }
} }
@ -1225,7 +1233,7 @@ int parse_opt(int argc, char **argv, struct arguments *args,
!args->read_xadc && !args->read_xadc &&
args->read_register.empty()) { args->read_register.empty()) {
printError("Error: bitfile not specified"); printError("Error: bitfile not specified");
cout << options.help() << endl; std::cout << options.help() << std::endl;
return -1; return -1;
} }
@ -1237,7 +1245,7 @@ int parse_opt(int argc, char **argv, struct arguments *args,
args->detect_flash = true; args->detect_flash = true;
} }
} catch (const cxxopts::OptionException& e) { } catch (const cxxopts::OptionException& e) {
printError("Error parsing options: " + string(e.what())); printError("Error parsing options: " + std::string(e.what()));
return -1; return -1;
} }
@ -1248,27 +1256,27 @@ int parse_opt(int argc, char **argv, struct arguments *args,
void displaySupported(const struct arguments &args) void displaySupported(const struct arguments &args)
{ {
if (args.list_cables == true) { if (args.list_cables == true) {
stringstream t; std::stringstream t;
t << setw(25) << left << "cable name" << "vid:pid"; t << std::setw(25) << std::left << "cable name" << "vid:pid";
printSuccess(t.str()); printSuccess(t.str());
for (auto b = cable_list.begin(); b != cable_list.end(); b++) { for (auto b = cable_list.begin(); b != cable_list.end(); b++) {
cable_t c = (*b).second; cable_t c = (*b).second;
stringstream ss; std::stringstream ss;
ss << setw(25) << left << (*b).first; ss << std::setw(25) << std::left << (*b).first;
ss << "0x" << hex << right << setw(4) << setfill('0') << c.vid ss << "0x" << std::hex << std::right << std::setw(4) << std::setfill('0') << c.vid
<< ":" << setw(4) << c.pid; << ":" << std::setw(4) << c.pid;
printInfo(ss.str()); printInfo(ss.str());
} }
cout << endl; std::cout << std::endl;
} }
if (args.list_boards) { if (args.list_boards) {
stringstream t; std::stringstream t;
t << setw(27) << left << "board name" << setw(19) << "cable_name"; t << std::setw(27) << std::left << "board name" << std::setw(19) << "cable_name";
t << setw(25) << "fpga_part"; t << std::setw(25) << "fpga_part";
printSuccess(t.str()); printSuccess(t.str());
for (auto b = board_list.begin(); b != board_list.end(); b++) { for (auto b = board_list.begin(); b != board_list.end(); b++) {
stringstream ss; std::stringstream ss;
target_board_t c = (*b).second; target_board_t c = (*b).second;
std::string cable_name = c.cable_name; std::string cable_name = c.cable_name;
std::string fpga_part = c.fpga_part; std::string fpga_part = c.fpga_part;
@ -1276,28 +1284,28 @@ void displaySupported(const struct arguments &args)
cable_name = "Undefined"; cable_name = "Undefined";
if (fpga_part.size() == 0) if (fpga_part.size() == 0)
fpga_part = "Undefined"; fpga_part = "Undefined";
ss << setw(27) << left << (*b).first << setw(19) << cable_name; ss << std::setw(27) << std::left << (*b).first << std::setw(19) << cable_name;
ss << setw(25)<< fpga_part; ss << std::setw(25)<< fpga_part;
printInfo(ss.str()); printInfo(ss.str());
} }
cout << endl; std::cout << std::endl;
} }
if (args.list_fpga) { if (args.list_fpga) {
stringstream t; std::stringstream t;
t << setw(12) << left << "IDCode" << setw(14) << "manufacturer"; t << std::setw(12) << std::left << "IDCode" << std::setw(14) << "manufacturer";
t << setw(16) << "family" << setw(20) << "model"; t << std::setw(16) << "family" << std::setw(20) << "model";
printSuccess(t.str()); printSuccess(t.str());
for (auto b = fpga_list.begin(); b != fpga_list.end(); b++) { for (auto b = fpga_list.begin(); b != fpga_list.end(); b++) {
fpga_model fpga = (*b).second; fpga_model fpga = (*b).second;
stringstream ss, idCode; std::stringstream ss, idCode;
idCode << "0x" << hex << setw(8) << setfill('0') << (*b).first; idCode << "0x" << std::hex << std::setw(8) << std::setfill('0') << (*b).first;
ss << setw(12) << left << idCode.str(); ss << std::setw(12) << std::left << idCode.str();
ss << setw(14) << fpga.manufacturer << setw(16) << fpga.family; ss << std::setw(14) << fpga.manufacturer << std::setw(16) << fpga.family;
ss << setw(20) << fpga.model; ss << std::setw(20) << fpga.model;
printInfo(ss.str()); printInfo(ss.str());
} }
cout << endl; std::cout << std::endl;
} }
#ifdef ENABLE_USB_SCAN #ifdef ENABLE_USB_SCAN

View File

@ -3,15 +3,17 @@
* Copyright (C) 2019 Gwenhael Goavec-Merou <gwenhael.goavec-merou@trabucayre.com> * Copyright (C) 2019 Gwenhael Goavec-Merou <gwenhael.goavec-merou@trabucayre.com>
*/ */
#include <algorithm>
#include <array> #include <array>
#include <sstream> #include <charconv>
#include <limits>
#include <string> #include <string>
#include <string_view>
#include "configBitstreamParser.hpp" #include "configBitstreamParser.hpp"
#include "display.hpp" #include "display.hpp"
#include "mcsParser.hpp" #include "mcsParser.hpp"
using namespace std;
/* line format /* line format
* :LLAAAATTHH...HHCC * :LLAAAATTHH...HHCC
@ -34,49 +36,105 @@ using namespace std;
#define TYPE_BASE 7 #define TYPE_BASE 7
#define DATA_BASE 9 #define DATA_BASE 9
McsParser::McsParser(const string &filename, bool reverseOrder, bool verbose): McsParser::McsParser(const std::string &filename, bool reverseOrder, bool verbose):
ConfigBitstreamParser(filename, ConfigBitstreamParser::ASCII_MODE, ConfigBitstreamParser(filename, ConfigBitstreamParser::ASCII_MODE,
verbose), verbose),
_base_addr(0), _reverseOrder(reverseOrder) _base_addr(0), _reverseOrder(reverseOrder), _records()
{} {}
int McsParser::parse() int McsParser::parse()
{ {
string str; std::string_view data(_raw_data);
istringstream lineStream(_raw_data);
FlashDataSection *rec = nullptr; FlashDataSection *rec = nullptr;
bool must_stop = false; bool must_stop = false;
size_t flash_size = 0;
std::array<uint8_t, 255> tmp_buf{}; // max size for one data line std::array<uint8_t, 255> tmp_buf{}; // max size for one data line
while (std::getline(lineStream, str, '\n') && !must_stop) { while (!data.empty() && !must_stop) {
uint8_t sum = 0, tmp, byteLen, type, checksum; const size_t nl_pos = data.find('\n');
uint16_t addr; std::string_view str = data.substr(0,
uint32_t loc_addr; nl_pos != std::string_view::npos ? nl_pos : data.size());
data = (nl_pos != std::string_view::npos)
? data.substr(nl_pos + 1) : std::string_view{};
uint8_t sum = 0, tmp = 0, byteLen = 0, type = 0, checksum = 0;
uint16_t addr = 0;
uint32_t loc_addr = 0;
/* if '\r' is present -> drop */ /* if '\r' is present -> drop */
if (str.back() == '\r') if (!str.empty() && str.back() == '\r')
str.pop_back(); str.remove_suffix(1);
const char *line = str.data();
const size_t line_len = str.size();
/* line can't be empty */
if (line_len == 0) {
printError("Error: file corrupted: empty line");
return false;
}
if (str[0] != ':') { if (str[0] != ':') {
printError("Error: a line must start with ':'"); printError("Error: a line must start with ':'");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
/* A line must have at least TYPE_BASE + 2 char (1 Byte) */
if (line_len < (TYPE_BASE + 2)) {
printf("Error: line too short");
return EXIT_FAILURE;
}
/* len */ /* len */
sscanf((char *)&str[LEN_BASE], "%2hhx", &byteLen); auto ret = std::from_chars(line + LEN_BASE,
line + LEN_BASE + 2, byteLen, 16);
if (ret.ec != std::errc{} || ret.ptr != line + LEN_BASE + 2) {
printError("Error: malformed length field");
return EXIT_FAILURE;
}
/* address */ /* address */
sscanf((char *)&str[ADDR_BASE], "%4hx", &addr); ret = std::from_chars(line + ADDR_BASE,
line + ADDR_BASE + 4, addr, 16);
if (ret.ec != std::errc{} || ret.ptr != line + ADDR_BASE + 4) {
printError("Error: malformed address field");
return EXIT_FAILURE;
}
/* type */ /* type */
sscanf((char *)&str[TYPE_BASE], "%2hhx", &type); ret = std::from_chars(line + TYPE_BASE,
line + TYPE_BASE + 2, type, 16);
if (ret.ec != std::errc{} || ret.ptr != line + TYPE_BASE + 2) {
printError("Error: malformed type field");
return EXIT_FAILURE;
}
const size_t checksum_offset = DATA_BASE + (static_cast<size_t>(byteLen) * 2);
/* check if line contains enought char for data + checksum */
if (line_len < (checksum_offset + 2)) {
printf("Error: line too short");
return EXIT_FAILURE;
}
/* checksum */ /* checksum */
sscanf((char *)&str[DATA_BASE + byteLen * 2], "%2hhx", &checksum); ret = std::from_chars(line + checksum_offset,
line + checksum_offset + 2, checksum, 16);
if (ret.ec != std::errc{} || ret.ptr != line + checksum_offset + 2) {
printError("Error: malformed checksum field");
return EXIT_FAILURE;
}
sum = byteLen + type + (addr & 0xff) + ((addr >> 8) & 0xff); sum = byteLen + type + (addr & 0xff) + ((addr >> 8) & 0xff);
switch (type) { switch (type) {
case 0: { /* Data + addr */ case 0: { /* Data + addr */
loc_addr = _base_addr + addr; loc_addr = _base_addr + addr;
const size_t end = static_cast<size_t>(loc_addr) + byteLen;
if (end < static_cast<size_t>(loc_addr)) {
printError("Error: record size overflow");
return EXIT_FAILURE;
}
flash_size = std::max(flash_size, end);
/* Check current record: /* Check current record:
* Create if null * Create if null
@ -87,10 +145,14 @@ int McsParser::parse()
rec = &_records.back(); rec = &_records.back();
} }
const char *ptr = (char *)&str[DATA_BASE]; const char *ptr = line + DATA_BASE;
for (uint16_t i = 0; i < byteLen; i++, ptr += 2) { for (uint16_t i = 0; i < byteLen; i++, ptr += 2) {
sscanf(ptr, "%2hhx", &tmp); ret = std::from_chars(ptr, ptr + 2, tmp, 16);
if (ret.ec != std::errc{} || ret.ptr != ptr + 2) {
printError("Error: malformed data field");
return EXIT_FAILURE;
}
tmp_buf[i] = _reverseOrder ? reverseByte(tmp) : tmp; tmp_buf[i] = _reverseOrder ? reverseByte(tmp) : tmp;
sum += tmp; sum += tmp;
} }
@ -101,7 +163,16 @@ int McsParser::parse()
must_stop = true; must_stop = true;
break; break;
case 4: /* Extended linear addr */ case 4: /* Extended linear addr */
sscanf((char*)&str[DATA_BASE], "%4x", &loc_addr); if (byteLen != 2) {
printError("Error for line with type 4: data field too short");
return EXIT_FAILURE;
}
ret = std::from_chars(line + DATA_BASE,
line + DATA_BASE + 4, loc_addr, 16);
if (ret.ec != std::errc{} || ret.ptr != line + DATA_BASE + 4) {
printError("Error: malformed extended linear address");
return EXIT_FAILURE;
}
_base_addr = (loc_addr << 16); _base_addr = (loc_addr << 16);
sum += (loc_addr & 0xff) + ((loc_addr >> 8) & 0xff); sum += (loc_addr & 0xff) + ((loc_addr >> 8) & 0xff);
break; break;
@ -116,17 +187,30 @@ int McsParser::parse()
} }
} }
const uint32_t nbRecord = getRecordCount(); const size_t nbRecord = getRecordCount();
const uint32_t record_base = getRecordBaseAddr(nbRecord - 1); if (nbRecord == 0) {
const uint32_t record_length = getRecordLength(nbRecord - 1); printError("No record found: is empty file?");
const uint32_t flash_size = record_base + record_length; return EXIT_FAILURE;
}
_bit_data.assign(flash_size, 0xff); _bit_data.assign(flash_size, 0xff);
if (flash_size > static_cast<size_t>(std::numeric_limits<int>::max() / 8)) {
printError("Error: bitstream too large");
return EXIT_FAILURE;
}
_bit_length = flash_size * 8; _bit_length = flash_size * 8;
for (uint32_t i = 0; i < nbRecord; i++) { for (const FlashDataSection& section : _records) {
const uint32_t record_base = getRecordBaseAddr(i); const size_t start = section.getStartAddr();
const std::vector<uint8_t> rec = getRecordData(i); const size_t length = section.getLength();
std::copy(rec.begin(), rec.end(), _bit_data.begin() + record_base);
if (start > _bit_data.size() || length > (_bit_data.size() - start)) {
printError("Error: record out of range");
return EXIT_FAILURE;
}
std::copy(section.getRecord().begin(),
section.getRecord().end(),
_bit_data.begin() + start);
} }
return EXIT_SUCCESS; return EXIT_SUCCESS;

View File

@ -124,6 +124,7 @@ static std::map <uint32_t, fpga_model> fpga_list = {
{0x13823093, {"xilinx", "kintexus", "xcku035", 6}}, {0x13823093, {"xilinx", "kintexus", "xcku035", 6}},
{0x13822093, {"xilinx", "kintexus", "xcku040", 6}}, {0x13822093, {"xilinx", "kintexus", "xcku040", 6}},
{0x13919093, {"xilinx", "kintexus", "xcku060", 6}}, {0x13919093, {"xilinx", "kintexus", "xcku060", 6}},
{0x23844093, {"xilinx", "kintexus", "xcku095", 6}},
{0x1390d093, {"xilinx", "kintexus", "xcku115", 6}}, {0x1390d093, {"xilinx", "kintexus", "xcku115", 6}},
/* Xilinx Ultrascale / Virtex */ /* Xilinx Ultrascale / Virtex */
@ -279,6 +280,7 @@ static std::map <uint32_t, fpga_model> fpga_list = {
{0x0318d0dd, {"altera", "MAX 10", "10M40S", 10}}, {0x0318d0dd, {"altera", "MAX 10", "10M40S", 10}},
{0x031850dd, {"altera", "MAX 10", "10M50S", 10}}, {0x031850dd, {"altera", "MAX 10", "10M50S", 10}},
/** dual-supply **/ /** dual-supply **/
{0x031030dd, {"altera", "MAX 10", "10M16D", 10}},
{0x031050dd, {"altera", "MAX 10", "10M50D", 10}}, {0x031050dd, {"altera", "MAX 10", "10M50D", 10}},
/* Altera Stratix V */ /* Altera Stratix V */
@ -304,6 +306,12 @@ static std::map <uint32_t, fpga_model> fpga_list = {
{0x02e650dd, {"altera", "arria 10", "SX570", 10}}, {0x02e650dd, {"altera", "arria 10", "SX570", 10}},
{0x02e050dd, {"altera", "arria 10", "SX660", 10}}, {0x02e050dd, {"altera", "arria 10", "SX660", 10}},
/* Altera Agilex 3 */
{0x436db0dd, {"altera", "agilex 3", "A3CZ135", 10}},
/* Altera Agilex 5 */
{0x4369c0dd, {"altera", "agilex 5", "A5EC008B", 10}},
/**************************************************************************/ /**************************************************************************/
/* Efinix */ /* Efinix */
/**************************************************************************/ /**************************************************************************/

View File

@ -67,6 +67,7 @@ void POFParser::displayHeader()
int POFParser::parse() int POFParser::parse()
{ {
const uint32_t file_size = static_cast<uint32_t>(_file_size);
uint8_t *ptr = (uint8_t *)_raw_data.data(); uint8_t *ptr = (uint8_t *)_raw_data.data();
uint32_t pos = 0; uint32_t pos = 0;
@ -77,6 +78,10 @@ int POFParser::parse()
pos += 4; pos += 4;
/* unknown */ /* unknown */
if (_verbose) { if (_verbose) {
if ((pos + 4) > file_size) {
printError("POFParser: Can't read first section");
return -1;
}
uint32_t first_section = ARRAY2INT32(ptr); uint32_t first_section = ARRAY2INT32(ptr);
printf("first section: %08x %4u\n", first_section, first_section); printf("first section: %08x %4u\n", first_section, first_section);
} }
@ -84,18 +89,39 @@ int POFParser::parse()
pos += 4; pos += 4;
/* number of packets */ /* number of packets */
if (_verbose) { if (_verbose) {
if ((pos + 4) > file_size) {
printError("POFParser: Can't read first section");
return -1;
}
uint32_t num_packets = ARRAY2INT32(ptr); uint32_t num_packets = ARRAY2INT32(ptr);
printf("number of packets: %08x %4u\n", num_packets, num_packets); printf("number of packets: %08x %4u\n", num_packets, num_packets);
} }
pos += 4; pos += 4;
/* 16bit code + 32bits size + content */ /* 16bit code + 32bits size + content */
while (pos < static_cast<uint32_t>(_file_size)) { while (pos < file_size) {
if ((pos + 2) > file_size) {
printError("POFParser: Bound check failure: can't read flag");
return -1;
}
uint16_t flag = ARRAY2INT16((&_raw_data.data()[pos])); uint16_t flag = ARRAY2INT16((&_raw_data.data()[pos]));
pos += 2; pos += 2;
if ((pos + 4) > file_size) {
printError("POFParser: Bound check failure: can't read size");
return -1;
}
uint32_t size = ARRAY2INT32((&_raw_data.data()[pos])); uint32_t size = ARRAY2INT32((&_raw_data.data()[pos]));
pos += 4; pos += 4;
pos += parseSection(flag, pos, size); if ((pos >= file_size) || ((pos + size) > file_size)) {
printError("POFParser: Bound check: can't parse section");
return -1;
}
uint32_t ret = parseSection(flag, pos, size);
if (ret != size) {
printError("POFParser: parseSection Failed");
return -1;
}
pos += ret;
} }
/* update pointers to memory area */ /* update pointers to memory area */
@ -147,6 +173,10 @@ uint32_t POFParser::parseSection(uint16_t flag, uint32_t pos, uint32_t size)
_hdr["design_name"] = _raw_data.substr(pos, size); _hdr["design_name"] = _raw_data.substr(pos, size);
break; break;
case 0x08: // last packet: CRC ? case 0x08: // last packet: CRC ?
if (size < 2) {
printError("POFParser: flag 0x08 failed size too small");
return 0;
}
_hdr["maybeCRC"] = std::to_string(ARRAY2INT16((&_raw_data.data()[pos]))); _hdr["maybeCRC"] = std::to_string(ARRAY2INT16((&_raw_data.data()[pos])));
break; break;
case 0x11: // cfg data case 0x11: // cfg data
@ -154,6 +184,10 @@ uint32_t POFParser::parseSection(uint16_t flag, uint32_t pos, uint32_t size)
// followed by UFM/CFM/DSM data // followed by UFM/CFM/DSM data
if (_verbose) { if (_verbose) {
content = _raw_data.substr(pos, size); content = _raw_data.substr(pos, size);
if ((3 * 4) > size) {
printError("POFParser: can't display 0x11 area");
return -1;
}
uint32_t val0 = ARRAY2INT32((&content.c_str()[0])); uint32_t val0 = ARRAY2INT32((&content.c_str()[0]));
uint32_t val1 = ARRAY2INT32((&content.c_str()[4])); uint32_t val1 = ARRAY2INT32((&content.c_str()[4]));
uint32_t val2 = ARRAY2INT32((&content.c_str()[8])); uint32_t val2 = ARRAY2INT32((&content.c_str()[8]));
@ -170,6 +204,10 @@ uint32_t POFParser::parseSection(uint16_t flag, uint32_t pos, uint32_t size)
case 0x13: // contains usercode / checksum case 0x13: // contains usercode / checksum
_hdr["usercode"] = std::to_string(ARRAY2INT32((&_raw_data.data()[pos+size-4]))); _hdr["usercode"] = std::to_string(ARRAY2INT32((&_raw_data.data()[pos+size-4])));
if (_verbose) { if (_verbose) {
if (size < 12) {
printf("POFParser: Can't display flag 0x13 area");
return -1;
}
t = _raw_data.substr(pos, size); t = _raw_data.substr(pos, size);
for (size_t i = 0; i < t.size(); i++) for (size_t i = 0; i < t.size(); i++)
printf("%02x ", static_cast<uint8_t>(t[i])); printf("%02x ", static_cast<uint8_t>(t[i]));

View File

@ -18,10 +18,10 @@
(static_cast<uint16_t>(_array_[1] & 0x00ff) << 8)) (static_cast<uint16_t>(_array_[1] & 0x00ff) << 8))
#define ARRAY2INT32(_array_) ( \ #define ARRAY2INT32(_array_) ( \
(static_cast<uint16_t>(_array_[0] & 0x00ff) << 0) | \ (static_cast<uint32_t>(_array_[0] & 0x00ff) << 0) | \
(static_cast<uint16_t>(_array_[1] & 0x00ff) << 8) | \ (static_cast<uint32_t>(_array_[1] & 0x00ff) << 8) | \
(static_cast<uint16_t>(_array_[2] & 0x00ff) << 16) | \ (static_cast<uint32_t>(_array_[2] & 0x00ff) << 16) | \
(static_cast<uint16_t>(_array_[3] & 0x00ff) << 24)) (static_cast<uint32_t>(_array_[3] & 0x00ff) << 24))
/*! /*!
* \file pofParser.hpp * \file pofParser.hpp

View File

@ -11,13 +11,21 @@
#include "progressBar.hpp" #include "progressBar.hpp"
#include "display.hpp" #include "display.hpp"
bool ProgressBar::_force_terminal_mode = false;
ProgressBar::ProgressBar(const std::string &mess, int maxValue, ProgressBar::ProgressBar(const std::string &mess, int maxValue,
int progressLen, bool quiet): _mess(mess), _maxValue(maxValue), int progressLen, bool quiet): _mess(mess), _maxValue(maxValue),
_progressLen(progressLen), last_time(std::chrono::system_clock::now()), _progressLen(progressLen), last_time(std::chrono::system_clock::now()),
_quiet(quiet), _first(true), _is_tty(isatty(STDOUT_FILENO) == 1) _quiet(quiet), _first(true),
_is_tty(_force_terminal_mode || isatty(STDOUT_FILENO) == 1)
{ {
} }
void ProgressBar::setForceTerminalMode()
{
_force_terminal_mode = true;
}
void ProgressBar::display(int value, char force) void ProgressBar::display(int value, char force)
{ {
if (_quiet) { if (_quiet) {

View File

@ -12,6 +12,7 @@ class ProgressBar {
public: public:
ProgressBar(const std::string &mess, int maxValue, int progressLen, ProgressBar(const std::string &mess, int maxValue, int progressLen,
bool quiet = false); bool quiet = false);
static void setForceTerminalMode();
void display(int value, char force = 0); void display(int value, char force = 0);
void done(); void done();
void fail(); void fail();
@ -24,6 +25,7 @@ class ProgressBar {
bool _quiet; bool _quiet;
bool _first; bool _first;
bool _is_tty; bool _is_tty;
static bool _force_terminal_mode;
}; };
#endif #endif

View File

@ -10,9 +10,8 @@
#include "display.hpp" #include "display.hpp"
#include "rawParser.hpp" #include "rawParser.hpp"
using namespace std;
RawParser::RawParser(const string &filename, bool reverseOrder): RawParser::RawParser(const std::string &filename, bool reverseOrder):
ConfigBitstreamParser(filename, ConfigBitstreamParser::BIN_MODE, ConfigBitstreamParser(filename, ConfigBitstreamParser::BIN_MODE,
false), _reverseOrder(reverseOrder) false), _reverseOrder(reverseOrder)
{} {}

View File

@ -26,7 +26,6 @@
#include "display.hpp" #include "display.hpp"
using namespace std;
#define TCK_OFFSET 2 #define TCK_OFFSET 2
#define TMS_OFFSET 1 #define TMS_OFFSET 1
@ -170,7 +169,7 @@ int RemoteBitbang_client::setClkFreq(uint32_t clkHz)
return clkHz; return clkHz;
} }
bool RemoteBitbang_client::open_connection(const string &ip_addr) bool RemoteBitbang_client::open_connection(const std::string &ip_addr)
{ {
struct sockaddr_in addr; struct sockaddr_in addr;
addr.sin_family = AF_INET; addr.sin_family = AF_INET;

View File

@ -16,7 +16,7 @@
#include "display.hpp" #include "display.hpp"
#include "spiFlash.hpp" #include "spiFlash.hpp"
#include "spiFlashdb.hpp" #include "spiFlashdb.hpp"
#include "spiInterface.hpp" #include "flashInterface.hpp"
/* read/write status register : 0B addr + 0 dummy */ /* read/write status register : 0B addr + 0 dummy */
#define FLASH_WRSR 0x01 #define FLASH_WRSR 0x01
@ -84,7 +84,7 @@
/* Global Block Protection unlock */ /* Global Block Protection unlock */
#define FLASH_ULBPR 0x98 #define FLASH_ULBPR 0x98
SPIFlash::SPIFlash(SPIInterface *spi, bool unprotect, int8_t verbose): SPIFlash::SPIFlash(FlashInterface *spi, bool unprotect, int8_t verbose):
_spi(spi), _verbose(verbose), _jedec_id(0), _spi(spi), _verbose(verbose), _jedec_id(0),
_flash_model(NULL), _unprotect(unprotect), _must_relock(false), _flash_model(NULL), _unprotect(unprotect), _must_relock(false),
_status(0) _status(0)

View File

@ -9,7 +9,7 @@
#include <map> #include <map>
#include <string> #include <string>
#include "spiInterface.hpp" #include "flashInterface.hpp"
#include "spiFlashdb.hpp" #include "spiFlashdb.hpp"
/* Flash memory section record /* Flash memory section record
@ -40,7 +40,7 @@ class FlashDataSection {
class SPIFlash { class SPIFlash {
public: public:
SPIFlash(SPIInterface *spi, bool unprotect, int8_t verbose); SPIFlash(FlashInterface *spi, bool unprotect, int8_t verbose);
/* power */ /* power */
virtual void power_up(); virtual void power_up();
virtual void power_down(); virtual void power_down();
@ -173,7 +173,7 @@ class SPIFlash {
*/ */
uint8_t len_to_bp(uint32_t len); uint8_t len_to_bp(uint32_t len);
SPIInterface *_spi; FlashInterface *_spi;
int8_t _verbose; int8_t _verbose;
uint32_t _jedec_id; /**< CHIP ID */ uint32_t _jedec_id; /**< CHIP ID */
flash_t *_flash_model; /**< detect flash model */ flash_t *_flash_model; /**< detect flash model */

View File

@ -322,6 +322,22 @@ static std::map <uint32_t, flash_t> flash_list = {
.quad_mask = 0, .quad_mask = 0,
.global_lock = false, .global_lock = false,
}}, }},
{0x20bb20, {
.manufacturer = "micron",
.model = "MT25QU512",
.nr_sector = 1024,
.sector_erase = true,
.subsector_erase = true,
.has_extended = true,
.tb_otp = false,
.tb_offset = (1 << 5),
.tb_register = STATR,
.bp_len = 4,
.bp_offset = {(1 << 2), (1 << 3), (1 << 4), (1 << 6)},
.quad_register = NONER,
.quad_mask = 0,
.global_lock = false,
}},
{0x20bb21, { {0x20bb21, {
.manufacturer = "micron", .manufacturer = "micron",
.model = "MT25QU01G", .model = "MT25QU01G",
@ -585,6 +601,23 @@ static std::map <uint32_t, flash_t> flash_list = {
.quad_mask = (1 << 6), .quad_mask = (1 << 6),
.global_lock = false, .global_lock = false,
}}, }},
{0xc84016, {
/* https://cdn.compacttool.ru/downloads/GD25Q32%20datasheet.pdf */
.manufacturer = "GigaDevice",
.model = "GD25Q32C",
.nr_sector = 64,
.sector_erase = true,
.subsector_erase = true,
.has_extended = false,
.tb_otp = false,
.tb_offset = (1 << 14), // CMP
.tb_register = STATR,
.bp_len = 4,
.bp_offset = {(1 << 2), (1 << 3), (1 << 4), (1 << 5)},
.quad_register = STATR,
.quad_mask = (1 << 6),
.global_lock = false,
}},
{0xc22817, { {0xc22817, {
/* https://www.macronix.com/Lists/Datasheet/Attachments/8868/MX25R6435F,%20Wide%20Range,%2064Mb,%20v1.6.pdf */ /* https://www.macronix.com/Lists/Datasheet/Attachments/8868/MX25R6435F,%20Wide%20Range,%2064Mb,%20v1.6.pdf */
.manufacturer = "Macronix", .manufacturer = "Macronix",
@ -780,7 +813,22 @@ static std::map <uint32_t, flash_t> flash_list = {
.quad_mask = (1 << 1), .quad_mask = (1 << 1),
.global_lock = false, .global_lock = false,
}}, }},
{0x1f4701, {
.manufacturer = "Adesto",
.model = "AT25DF321A",
.nr_sector = 64,
.sector_erase = true,
.subsector_erase = true,
.has_extended = false,
.tb_otp = false,
.tb_offset = (1 << 3),
.tb_register = STATR,
.bp_len = 3,
.bp_offset = {(1 << 2), (1 << 3), (1 << 4), 0},
.quad_register = NONER,
.quad_mask = 0,
.global_lock = false,
}},
}; };
#endif // SRC_SPIFLASHDB_HPP_ #endif // SRC_SPIFLASHDB_HPP_

View File

@ -18,12 +18,11 @@
#include "jtag.hpp" #include "jtag.hpp"
using namespace std;
void SVF_jtag::split_str(string const &str, vector<string> &vparse) void SVF_jtag::split_str(std::string const &str, std::vector<std::string> &vparse)
{ {
string token; std::string token;
istringstream tokenStream(str); std::istringstream tokenStream(str);
while (getline(tokenStream, token, ' ')) while (getline(tokenStream, token, ' '))
vparse.push_back(token); vparse.push_back(token);
} }
@ -37,7 +36,7 @@ void SVF_jtag::clear_XYR(svf_XYR &t)
t.smask.clear(); t.smask.clear();
} }
static unsigned char *parse_hex(string const &in, size_t byte_length, static unsigned char *parse_hex(std::string const &in, size_t byte_length,
bool default_value) bool default_value)
{ {
unsigned char *txbuf = new unsigned char[byte_length]; unsigned char *txbuf = new unsigned char[byte_length];
@ -67,13 +66,13 @@ static unsigned char *parse_hex(string const &in, size_t byte_length,
* tdo si absent on s'en fout * tdo si absent on s'en fout
* TODO: ameliorer l'analyse des chaines de caracteres * TODO: ameliorer l'analyse des chaines de caracteres
*/ */
void SVF_jtag::parse_XYR(vector<string> const &vstr, svf_XYR &t) void SVF_jtag::parse_XYR(std::vector<std::string> const &vstr, svf_XYR &t)
{ {
if (_verbose) if (_verbose)
cout << endl; std::cout << std::endl;
int mode = 0; int mode = 0;
string s; std::string s;
string full_line; std::string full_line;
full_line.reserve(1276); full_line.reserve(1276);
int write_data = -1; int write_data = -1;
@ -168,14 +167,14 @@ void SVF_jtag::parse_XYR(vector<string> const &vstr, svf_XYR &t)
unsigned char *maskbuf = parse_hex(t.mask, byte_len, t.mask.empty() ? 1 : 0); unsigned char *maskbuf = parse_hex(t.mask, byte_len, t.mask.empty() ? 1 : 0);
for (size_t i = 0; i < byte_len; i++) { for (size_t i = 0; i < byte_len; i++) {
if ((read_buffer[i] ^ tdobuf[i]) & maskbuf[i]) { if ((read_buffer[i] ^ tdobuf[i]) & maskbuf[i]) {
cerr << "TDO value "; std::cerr << "TDO value ";
for (int j = byte_len - 1; j >= 0; j--) { for (int j = byte_len - 1; j >= 0; j--) {
cerr << uppercase << hex << int(read_buffer[j]); std::cerr << std::uppercase << std::hex << int(read_buffer[j]);
} }
cerr << " isn't the one expected: " << uppercase << t.tdo << endl; std::cerr << " isn't the one expected: " << std::uppercase << t.tdo << std::endl;
delete[] tdobuf; delete[] tdobuf;
delete[] maskbuf; delete[] maskbuf;
throw exception(); throw std::exception();
} }
} }
delete[] tdobuf; delete[] tdobuf;
@ -187,7 +186,7 @@ void SVF_jtag::parse_XYR(vector<string> const &vstr, svf_XYR &t)
} }
/* Implementation partielle de la spec */ /* Implementation partielle de la spec */
void SVF_jtag::parse_runtest(vector<string> const &vstr) void SVF_jtag::parse_runtest(std::vector<std::string> const &vstr)
{ {
unsigned int pos = 1; unsigned int pos = 1;
int nb_iter = 0; int nb_iter = 0;
@ -238,105 +237,105 @@ void SVF_jtag::parse_runtest(vector<string> const &vstr)
_jtag->set_state(_end_state); _jtag->set_state(_end_state);
} }
void SVF_jtag::handle_instruction(vector<string> const &vstr) void SVF_jtag::handle_instruction(std::vector<std::string> const &vstr)
{ {
if (!vstr[0].compare("FREQUENCY")) { if (!vstr[0].compare("FREQUENCY")) {
_freq_hz = atof(vstr[1].c_str()); _freq_hz = atof(vstr[1].c_str());
if (_verbose) { if (_verbose) {
cout << "frequency value " << vstr[1] << " unit " << vstr[2]; std::cout << "frequency value " << vstr[1] << " unit " << vstr[2];
cout << _freq_hz << endl; std::cout << _freq_hz << std::endl;
} }
_jtag->setClkFreq(_freq_hz); _jtag->setClkFreq(_freq_hz);
} else if (!vstr[0].compare("TRST")) { } else if (!vstr[0].compare("TRST")) {
if (_verbose) cout << "trst value : " << vstr[1] << endl; if (_verbose) std::cout << "trst value : " << vstr[1] << std::endl;
} else if (!vstr[0].compare("ENDDR")) { } else if (!vstr[0].compare("ENDDR")) {
if (_verbose) cout << "enddr value : " << vstr[1] << endl; if (_verbose) std::cout << "enddr value : " << vstr[1] << std::endl;
_enddr = (Jtag::tapState_t)fsm_state[vstr[1]]; _enddr = (Jtag::tapState_t)fsm_state[vstr[1]];
} else if (!vstr[0].compare("ENDIR")) { } else if (!vstr[0].compare("ENDIR")) {
if (_verbose) cout << "endir value : " << vstr[1] << endl; if (_verbose) std::cout << "endir value : " << vstr[1] << std::endl;
_endir = (Jtag::tapState_t)fsm_state[vstr[1]]; _endir = (Jtag::tapState_t)fsm_state[vstr[1]];
} else if (!vstr[0].compare("STATE")) { } else if (!vstr[0].compare("STATE")) {
if (_verbose) cout << "state value : " << vstr[1] << endl; if (_verbose) std::cout << "state value : " << vstr[1] << std::endl;
_jtag->set_state((Jtag::tapState_t)fsm_state[vstr[1]]); _jtag->set_state((Jtag::tapState_t)fsm_state[vstr[1]]);
} else if (!vstr[0].compare("RUNTEST")) { } else if (!vstr[0].compare("RUNTEST")) {
parse_runtest(vstr); parse_runtest(vstr);
} else if (!vstr[0].compare("HIR")) { } else if (!vstr[0].compare("HIR")) {
parse_XYR(vstr, hir); parse_XYR(vstr, hir);
if (hir.len > 0) { if (hir.len > 0) {
cerr << "HIR length supported is only 0 " << endl; std::cerr << "HIR length supported is only 0 " << std::endl;
} }
if (_verbose) { if (_verbose) {
cout << "HIR" << endl; std::cout << "HIR" << std::endl;
cout << "\tlen : " << hir.len << endl; std::cout << "\tlen : " << hir.len << std::endl;
cout << "\ttdo : " << hir.tdo.size()*4 << endl; std::cout << "\ttdo : " << hir.tdo.size()*4 << std::endl;
cout << "\ttdi : " << hir.tdi.size()*4 << endl; std::cout << "\ttdi : " << hir.tdi.size()*4 << std::endl;
cout << "\tmask : " << hir.mask.size()*4 << endl; std::cout << "\tmask : " << hir.mask.size()*4 << std::endl;
cout << "\tsmask : " << hir.smask.size()*4 << endl; std::cout << "\tsmask : " << hir.smask.size()*4 << std::endl;
} }
} else if (!vstr[0].compare("HDR")) { } else if (!vstr[0].compare("HDR")) {
parse_XYR(vstr, hdr); parse_XYR(vstr, hdr);
if (hdr.len > 0) { if (hdr.len > 0) {
cerr << "HDR length supported is only 0" << endl; std::cerr << "HDR length supported is only 0" << std::endl;
} }
if (_verbose) { if (_verbose) {
cout << "HDR" << endl; std::cout << "HDR" << std::endl;
cout << "\tlen : " << hdr.len << endl; std::cout << "\tlen : " << hdr.len << std::endl;
cout << "\ttdo : " << hdr.tdo.size()*4 << endl; std::cout << "\ttdo : " << hdr.tdo.size()*4 << std::endl;
cout << "\ttdi : " << hdr.tdi.size()*4 << endl; std::cout << "\ttdi : " << hdr.tdi.size()*4 << std::endl;
cout << "\tmask : " << hdr.mask.size()*4 << endl; std::cout << "\tmask : " << hdr.mask.size()*4 << std::endl;
cout << "\tsmask : " << hdr.smask.size()*4 << endl; std::cout << "\tsmask : " << hdr.smask.size()*4 << std::endl;
} }
} else if (!vstr[0].compare("SIR")) { } else if (!vstr[0].compare("SIR")) {
parse_XYR(vstr, sir); parse_XYR(vstr, sir);
if (_verbose) { if (_verbose) {
for (auto &&t : vstr) for (auto &&t : vstr)
cout << t << " "; std::cout << t << " ";
cout << endl; std::cout << std::endl;
cout << "\tlen : " << sir.len << endl; std::cout << "\tlen : " << sir.len << std::endl;
cout << "\ttdo : " << sir.tdo.size()*4 << endl; std::cout << "\ttdo : " << sir.tdo.size()*4 << std::endl;
cout << "\ttdi : " << sir.tdi.size()*4 << endl; std::cout << "\ttdi : " << sir.tdi.size()*4 << std::endl;
cout << "\tmask : " << sir.mask.size()*4 << endl; std::cout << "\tmask : " << sir.mask.size()*4 << std::endl;
cout << "\tsmask : " << sir.smask.size()*4 << endl; std::cout << "\tsmask : " << sir.smask.size()*4 << std::endl;
} }
} else if (!vstr[0].compare("SDR")) { } else if (!vstr[0].compare("SDR")) {
parse_XYR(vstr, sdr); parse_XYR(vstr, sdr);
if (_verbose) { if (_verbose) {
cout << "SDR" << endl; std::cout << "SDR" << std::endl;
cout << "\tlen : " << sdr.len << endl; std::cout << "\tlen : " << sdr.len << std::endl;
cout << "\ttdo : " << sdr.tdo.size()*4 << endl; std::cout << "\ttdo : " << sdr.tdo.size()*4 << std::endl;
cout << "\ttdi : " << sdr.tdi.size()*4 << endl; std::cout << "\ttdi : " << sdr.tdi.size()*4 << std::endl;
cout << "\tmask : " << sdr.mask.size()*4 << endl; std::cout << "\tmask : " << sdr.mask.size()*4 << std::endl;
cout << "\tsmask : " << sdr.smask.size()*4 << endl; std::cout << "\tsmask : " << sdr.smask.size()*4 << std::endl;
} }
} else if (!vstr[0].compare("TDR")) { } else if (!vstr[0].compare("TDR")) {
parse_XYR(vstr, tdr); parse_XYR(vstr, tdr);
if (tdr.len > 0) { if (tdr.len > 0) {
cerr << "TDR length supported is only 0" << endl; std::cerr << "TDR length supported is only 0" << std::endl;
} }
if (_verbose) { if (_verbose) {
cout << "TDR" << endl; std::cout << "TDR" << std::endl;
cout << "\tlen : " << tdr.len << endl; std::cout << "\tlen : " << tdr.len << std::endl;
cout << "\ttdo : " << tdr.tdo.size() * 4 << endl; std::cout << "\ttdo : " << tdr.tdo.size() * 4 << std::endl;
cout << "\ttdi : " << tdr.tdi.size() * 4 << endl; std::cout << "\ttdi : " << tdr.tdi.size() * 4 << std::endl;
cout << "\tmask : " << tdr.mask.size() * 4 << endl; std::cout << "\tmask : " << tdr.mask.size() * 4 << std::endl;
cout << "\tsmask : " << tdr.smask.size() * 4 << endl; std::cout << "\tsmask : " << tdr.smask.size() * 4 << std::endl;
} }
} else if (!vstr[0].compare("TIR")) { } else if (!vstr[0].compare("TIR")) {
parse_XYR(vstr, tir); parse_XYR(vstr, tir);
if (tir.len > 0) { if (tir.len > 0) {
cerr << "TIR length supported is only 0" << endl; std::cerr << "TIR length supported is only 0" << std::endl;
} }
if (_verbose) { if (_verbose) {
cout << "TIR" << endl; std::cout << "TIR" << std::endl;
cout << "\tlen : " << tir.len << endl; std::cout << "\tlen : " << tir.len << std::endl;
cout << "\ttdo : " << tir.tdo.size() * 4 << endl; std::cout << "\ttdo : " << tir.tdo.size() * 4 << std::endl;
cout << "\ttdi : " << tir.tdi.size() * 4 << endl; std::cout << "\ttdi : " << tir.tdi.size() * 4 << std::endl;
cout << "\tmask : " << tir.mask.size() * 4 << endl; std::cout << "\tmask : " << tir.mask.size() * 4 << std::endl;
cout << "\tsmask : " << tir.smask.size() * 4 << endl; std::cout << "\tsmask : " << tir.smask.size() * 4 << std::endl;
} }
} else { } else {
cout << "error: unhandled instruction " << vstr[0] << endl; std::cout << "error: unhandled instruction " << vstr[0] << std::endl;
throw exception(); throw std::exception();
} }
} }
@ -358,16 +357,16 @@ bool is_space(char x) {
* concat continuous lines * concat continuous lines
* and pass instruction to handle_instruction * and pass instruction to handle_instruction
*/ */
void SVF_jtag::parse(string filename) void SVF_jtag::parse(std::string filename)
{ {
string str; std::string str;
vector<string> vstr; std::vector<std::string> vstr;
bool is_complete; bool is_complete;
ifstream fs; std::ifstream fs;
fs.open(filename); fs.open(filename);
if (!fs.is_open()) { if (!fs.is_open()) {
cerr << "Error opening svf file " << filename << endl; std::cerr << "Error opening svf file " << filename << std::endl;
return; return;
} }
unsigned int lineno = 0; unsigned int lineno = 0;
@ -391,8 +390,8 @@ void SVF_jtag::parse(string filename)
if (vstr[0].compare("HDR") && vstr[0].compare("HIR") if (vstr[0].compare("HDR") && vstr[0].compare("HIR")
&& vstr[0].compare("SDR") && vstr[0].compare("SIR")) { && vstr[0].compare("SDR") && vstr[0].compare("SIR")) {
for (auto &&word : vstr) for (auto &&word : vstr)
cout << word << " "; std::cout << word << " ";
cout << endl; std::cout << std::endl;
} }
} }
handle_instruction(vstr); handle_instruction(vstr);
@ -400,11 +399,11 @@ void SVF_jtag::parse(string filename)
} }
} }
} }
catch (exception &e) catch (std::exception &e)
{ {
cerr << "Cannot proceed because of error(s) at line " << lineno << endl; std::cerr << "Cannot proceed because of error(s) at line " << lineno << std::endl;
throw; throw;
} }
cout << "end of SVF file" << endl; std::cout << "end of SVF file" << std::endl;
} }

View File

@ -11,31 +11,30 @@
#include <map> #include <map>
#include "jtag.hpp" #include "jtag.hpp"
using namespace std;
class SVF_jtag { class SVF_jtag {
public: public:
SVF_jtag(Jtag *jtag, bool verbose); SVF_jtag(Jtag *jtag, bool verbose);
~SVF_jtag(); ~SVF_jtag();
void parse(string filename); void parse(std::string filename);
void setVerbose(bool verbose) {_verbose = verbose;} void setVerbose(bool verbose) {_verbose = verbose;}
private: private:
typedef struct { typedef struct {
uint32_t len; uint32_t len;
string tdo; std::string tdo;
string tdi; std::string tdi;
string mask; std::string mask;
string smask; std::string smask;
} svf_XYR; } svf_XYR;
void split_str(string const &str, vector<string> &vparse); void split_str(const std::string &str, std::vector<std::string> &vparse);
void clear_XYR(svf_XYR &t); void clear_XYR(svf_XYR &t);
void parse_XYR(vector<string> const &vstr/*, svf_stat &svfs*/, svf_XYR &t); void parse_XYR(const std::vector<std::string> &vstr/*, svf_stat &svfs*/, svf_XYR &t);
void parse_runtest(vector<string> const &vstr); void parse_runtest(const std::vector<std::string> &vstr);
void handle_instruction(vector<string> const &vstr); void handle_instruction(const std::vector<std::string> &vstr);
map <string, uint8_t> fsm_state = { std::map<std::string, uint8_t> fsm_state = {
{"RESET", 0}, {"RESET", 0},
{"IDLE", 1}, {"IDLE", 1},
{"DRSELECT", 2}, {"DRSELECT", 2},

View File

@ -19,7 +19,6 @@
#include "fx2_ll.hpp" #include "fx2_ll.hpp"
#include "usbBlaster.hpp" #include "usbBlaster.hpp"
using namespace std;
#define DO_READ (1 << 6) #define DO_READ (1 << 6)
#define DO_WRITE (0 << 6) #define DO_WRITE (0 << 6)
@ -358,10 +357,8 @@ UsbBlasterI::UsbBlasterI()
{ {
int ret; int ret;
_ftdi = ftdi_new(); _ftdi = ftdi_new();
if (_ftdi == NULL) { if (_ftdi == NULL)
cout << "open_device: failed to initialize ftdi" << endl; throw std::runtime_error("open_device: failed to initialize ftdi");
throw std::exception();
}
ret = ftdi_usb_open(_ftdi, 0x09fb, 0x6001); ret = ftdi_usb_open(_ftdi, 0x09fb, 0x6001);
if (ret < 0) { if (ret < 0) {
@ -446,7 +443,7 @@ int UsbBlasterI::write(uint8_t *wr_buf, int wr_len,
* USB Blash II specific implementation * USB Blash II specific implementation
*/ */
UsbBlasterII::UsbBlasterII(const string &firmware_path) UsbBlasterII::UsbBlasterII(const std::string &firmware_path)
{ {
std::string fpath; std::string fpath;
uint8_t buf[5]; uint8_t buf[5];

View File

@ -31,7 +31,7 @@
#endif #endif
#include "rawParser.hpp" #include "rawParser.hpp"
#include "spiFlash.hpp" #include "spiFlash.hpp"
#include "spiInterface.hpp" #include "flashInterface.hpp"
#include "xilinx.hpp" #include "xilinx.hpp"
#include "xilinxMapParser.hpp" #include "xilinxMapParser.hpp"
@ -279,7 +279,7 @@ Xilinx::Xilinx(Jtag *jtag, const std::string &filename,
bool verify, int8_t verbose, bool verify, int8_t verbose,
bool skip_load_bridge, bool skip_reset, bool read_dna, bool read_xadc): bool skip_load_bridge, bool skip_reset, bool read_dna, bool read_xadc):
Device(jtag, filename, file_type, verify, verbose), Device(jtag, filename, file_type, verify, verbose),
SPIInterface(filename, verbose, 256, verify, skip_load_bridge, FlashInterface(filename, verbose, 256, verify, skip_load_bridge,
skip_reset), skip_reset),
_device_package(device_package), _spiOverJtagPath(spiOverJtagPath), _device_package(device_package), _spiOverJtagPath(spiOverJtagPath),
_irlen(6), _secondary_filename(secondary_filename), _soj_is_v2(false), _irlen(6), _secondary_filename(secondary_filename), _soj_is_v2(false),
@ -842,11 +842,11 @@ void Xilinx::program_spi(ConfigBitstreamParser * bit, std::string extention,
throw std::runtime_error("called with null bitstream"); throw std::runtime_error("called with null bitstream");
if (extention == "mcs") { if (extention == "mcs") {
McsParser *parser = (McsParser *)bit; McsParser *parser = (McsParser *)bit;
SPIInterface::write(parser->getRecords(), unprotect_flash, true); FlashInterface::write(parser->getRecords(), unprotect_flash, true);
} else { } else {
const uint8_t *data = bit->getData(); const uint8_t *data = bit->getData();
int length = bit->getLength() / 8; int length = bit->getLength() / 8;
SPIInterface::write(offset, data, length, unprotect_flash); FlashInterface::write(offset, data, length, unprotect_flash);
} }
} }
@ -1261,14 +1261,14 @@ bool Xilinx::dumpFlash(uint32_t base_addr, uint32_t len)
if (_flash_chips & PRIMARY_FLASH) { if (_flash_chips & PRIMARY_FLASH) {
select_flash_chip(PRIMARY_FLASH); select_flash_chip(PRIMARY_FLASH);
SPIInterface::set_filename(_filename); FlashInterface::set_filename(_filename);
if (!SPIInterface::dump(base_addr, len)) if (!FlashInterface::dump(base_addr, len))
return false; return false;
} }
if (_flash_chips & SECONDARY_FLASH) { if (_flash_chips & SECONDARY_FLASH) {
select_flash_chip(SECONDARY_FLASH); select_flash_chip(SECONDARY_FLASH);
SPIInterface::set_filename(_secondary_filename); FlashInterface::set_filename(_secondary_filename);
if (!SPIInterface::dump(base_addr, len)) if (!FlashInterface::dump(base_addr, len))
return false; return false;
} }
@ -1279,12 +1279,12 @@ bool Xilinx::detect_flash()
{ {
if (_flash_chips & PRIMARY_FLASH) { if (_flash_chips & PRIMARY_FLASH) {
select_flash_chip(PRIMARY_FLASH); select_flash_chip(PRIMARY_FLASH);
if (!SPIInterface::detect_flash()) if (!FlashInterface::detect_flash())
return false; return false;
} }
if (_flash_chips & SECONDARY_FLASH) { if (_flash_chips & SECONDARY_FLASH) {
select_flash_chip(SECONDARY_FLASH); select_flash_chip(SECONDARY_FLASH);
if (!SPIInterface::detect_flash()) if (!FlashInterface::detect_flash())
return false; return false;
} }
return true; return true;
@ -1294,12 +1294,12 @@ bool Xilinx::protect_flash(uint32_t len)
{ {
if (_flash_chips & PRIMARY_FLASH) { if (_flash_chips & PRIMARY_FLASH) {
select_flash_chip(PRIMARY_FLASH); select_flash_chip(PRIMARY_FLASH);
if (!SPIInterface::protect_flash(len)) if (!FlashInterface::protect_flash(len))
return false; return false;
} }
if (_flash_chips & SECONDARY_FLASH) { if (_flash_chips & SECONDARY_FLASH) {
select_flash_chip(SECONDARY_FLASH); select_flash_chip(SECONDARY_FLASH);
if (!SPIInterface::protect_flash(len)) if (!FlashInterface::protect_flash(len))
return false; return false;
} }
return true; return true;
@ -1309,12 +1309,12 @@ bool Xilinx::unprotect_flash()
{ {
if (_flash_chips & PRIMARY_FLASH) { if (_flash_chips & PRIMARY_FLASH) {
select_flash_chip(PRIMARY_FLASH); select_flash_chip(PRIMARY_FLASH);
if (!SPIInterface::unprotect_flash()) if (!FlashInterface::unprotect_flash())
return false; return false;
} }
if (_flash_chips & SECONDARY_FLASH) { if (_flash_chips & SECONDARY_FLASH) {
select_flash_chip(SECONDARY_FLASH); select_flash_chip(SECONDARY_FLASH);
if (!SPIInterface::unprotect_flash()) if (!FlashInterface::unprotect_flash())
return false; return false;
} }
return true; return true;
@ -1324,12 +1324,12 @@ bool Xilinx::set_quad_bit(bool set_quad)
{ {
if (_flash_chips & PRIMARY_FLASH) { if (_flash_chips & PRIMARY_FLASH) {
select_flash_chip(PRIMARY_FLASH); select_flash_chip(PRIMARY_FLASH);
if (!SPIInterface::set_quad_bit(set_quad)) if (!FlashInterface::set_quad_bit(set_quad))
return false; return false;
} }
if (_flash_chips & SECONDARY_FLASH) { if (_flash_chips & SECONDARY_FLASH) {
select_flash_chip(SECONDARY_FLASH); select_flash_chip(SECONDARY_FLASH);
if (!SPIInterface::set_quad_bit(set_quad)) if (!FlashInterface::set_quad_bit(set_quad))
return false; return false;
} }
return true; return true;
@ -1339,12 +1339,12 @@ bool Xilinx::bulk_erase_flash()
{ {
if (_flash_chips & PRIMARY_FLASH) { if (_flash_chips & PRIMARY_FLASH) {
select_flash_chip(PRIMARY_FLASH); select_flash_chip(PRIMARY_FLASH);
if (!SPIInterface::bulk_erase_flash()) if (!FlashInterface::bulk_erase_flash())
return false; return false;
} }
if (_flash_chips & SECONDARY_FLASH) { if (_flash_chips & SECONDARY_FLASH) {
select_flash_chip(SECONDARY_FLASH); select_flash_chip(SECONDARY_FLASH);
if (!SPIInterface::bulk_erase_flash()) if (!FlashInterface::bulk_erase_flash())
return false; return false;
} }
return true; return true;

View File

@ -16,9 +16,9 @@
#include "device.hpp" #include "device.hpp"
#include "jedParser.hpp" #include "jedParser.hpp"
#include "jtag.hpp" #include "jtag.hpp"
#include "spiInterface.hpp" #include "flashInterface.hpp"
class Xilinx: public Device, SPIInterface { class Xilinx: public Device, FlashInterface {
public: public:
Xilinx(Jtag *jtag, const std::string &filename, Xilinx(Jtag *jtag, const std::string &filename,
const std::string &secondary_filename, const std::string &secondary_filename,

View File

@ -14,9 +14,8 @@
#include "jedParser.hpp" #include "jedParser.hpp"
#include "xilinxMapParser.hpp" #include "xilinxMapParser.hpp"
using namespace std;
XilinxMapParser::XilinxMapParser(const string &filename, XilinxMapParser::XilinxMapParser(const std::string &filename,
uint16_t num_row, uint16_t num_col, uint16_t num_row, uint16_t num_col,
JedParser *jed, const uint32_t usercode, JedParser *jed, const uint32_t usercode,
bool verbose): ConfigBitstreamParser(filename, bool verbose): ConfigBitstreamParser(filename,
@ -61,7 +60,7 @@ int XilinxMapParser::parse()
} else { } else {
empty = false; // current line is not fully empty empty = false; // current line is not fully empty
int len = end_pos - prev_pos; // section len int len = end_pos - prev_pos; // section len
string cnt = line.substr(prev_pos, len); // line substring std::string cnt = line.substr(prev_pos, len); // line substring
if (cnt[0] <= '9' && cnt[0] >= '0') { // numeric value (index) if (cnt[0] <= '9' && cnt[0] >= '0') { // numeric value (index)
map_val = std::stoi(cnt, nullptr, 10); map_val = std::stoi(cnt, nullptr, 10);
} else { // information (done, spare, user, ...) } else { // information (done, spare, user, ...)

View File

@ -25,7 +25,6 @@
#include "display.hpp" #include "display.hpp"
using namespace std;
XVC_client::XVC_client(const std::string &ip_addr, int port, XVC_client::XVC_client(const std::string &ip_addr, int port,
uint32_t clkHz, int8_t verbose): uint32_t clkHz, int8_t verbose):
@ -41,7 +40,7 @@ XVC_client::XVC_client(const std::string &ip_addr, int port,
throw std::runtime_error("can't read info"); throw std::runtime_error("can't read info");
std::regex r("[_:]"); std::regex r("[_:]");
string rep((const char *)buffer); std::string rep((const char *)buffer);
std::sregex_token_iterator start{ rep.begin(), rep.end(), r, -1 }, end; std::sregex_token_iterator start{ rep.begin(), rep.end(), r, -1 }, end;
std::vector<std::string> toto(start, end); std::vector<std::string> toto(start, end);
@ -223,7 +222,7 @@ int XVC_client::setClkFreq(uint32_t clkHz)
return _clkHZ; return _clkHZ;
} }
bool XVC_client::open_connection(const string &ip_addr) bool XVC_client::open_connection(const std::string &ip_addr)
{ {
struct sockaddr_in addr; struct sockaddr_in addr;
addr.sin_family = AF_INET; addr.sin_family = AF_INET;
@ -262,12 +261,12 @@ int sendall(int sock, const void* raw, size_t cnt, int flags)
return cnt; // success return cnt; // success
} }
ssize_t XVC_client::xfer_pkt(const string &instr, ssize_t XVC_client::xfer_pkt(const std::string &instr,
const uint8_t *tx, uint32_t tx_size, const uint8_t *tx, uint32_t tx_size,
uint8_t *rx, uint32_t rx_size) uint8_t *rx, uint32_t rx_size)
{ {
ssize_t len = tx_size; ssize_t len = tx_size;
vector<uint8_t> buffer(instr.size() + ((tx) ? tx_size : 0)); std::vector<uint8_t> buffer(instr.size() + ((tx) ? tx_size : 0));
memcpy(buffer.data(), instr.c_str(), instr.size()); memcpy(buffer.data(), instr.c_str(), instr.size());
if (tx) if (tx)
memcpy(buffer.data() + instr.size(), tx, tx_size); memcpy(buffer.data() + instr.size(), tx, tx_size);

View File

@ -20,13 +20,12 @@
#include "cable.hpp" #include "cable.hpp"
#include "display.hpp" #include "display.hpp"
using namespace std;
XVC_server::XVC_server(int port, const cable_t & cable, XVC_server::XVC_server(int port, const cable_t & cable,
const jtag_pins_conf_t * pin_conf, string dev, const jtag_pins_conf_t * pin_conf, std::string dev,
const string & serial, uint32_t clkHZ, int8_t verbose, const std::string & serial, uint32_t clkHZ, int8_t verbose,
const string & ip_adr, const bool invert_read_edge, const std::string & ip_adr, const bool invert_read_edge,
const string & firmware_path):_verbose(verbose > 1), const std::string & firmware_path):_verbose(verbose > 1),
_jtag(NULL), _port(port), _sock(-1), _jtag(NULL), _port(port), _sock(-1),
_is_stopped(false), _must_stop(false), _is_stopped(false), _must_stop(false),
_buffer_size(2048), _state(Jtag::RUN_TEST_IDLE) _buffer_size(2048), _state(Jtag::RUN_TEST_IDLE)
@ -282,7 +281,7 @@ int XVC_server::handle_data(int fd)
if (_verbose) { if (_verbose) {
printInfo(std::to_string((int)time(NULL)) + printInfo(std::to_string((int)time(NULL)) +
" : Received command: 'getinfo'"); " : Received command: 'getinfo'");
printInfo("\t Replied with " + string(xvcInfo)); printInfo("\t Replied with " + std::string(xvcInfo));
} }
break; break;
/* settck */ /* settck */
@ -329,7 +328,7 @@ int XVC_server::handle_data(int fd)
" : Received command: 'shift'"); " : Received command: 'shift'");
} }
} else { } else {
printError("invalid cmd '" + string(cmd) + "'"); printError("invalid cmd '" + std::string(cmd) + "'");
return 1; return 1;
} }

View File

@ -17,14 +17,12 @@
#include "jtag.hpp" #include "jtag.hpp"
using namespace std;
class XVC_server { class XVC_server {
public: public:
XVC_server(int port, const cable_t &cable, const jtag_pins_conf_t *pin_conf, XVC_server(int port, const cable_t &cable, const jtag_pins_conf_t *pin_conf,
string dev, const string &serial, uint32_t clkHZ, int8_t verbose, std::string dev, const std::string &serial, uint32_t clkHZ, int8_t verbose,
const string &ip_adr, const std::string &ip_adr,
const bool invert_read_edge, const string &firmware_path); const bool invert_read_edge, const std::string &firmware_path);
~XVC_server(); ~XVC_server();
/*! /*!