Compare commits

..

57 Commits

Author SHA1 Message Date
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
Gwenhael Goavec-Merou 85be4fa02b prepare release v1.1.1 2026-03-11 19:24:32 +01:00
Gwenhael Goavec-Merou 09f272e785 main: displaySupported added one more space in list-boards 2026-03-11 11:14:37 +01:00
Gwenhael Goavec-Merou 1ab3c1bf6c main: moved SPI Flash to a dedicated function 2026-03-10 18:45:03 +01:00
Gwenhael Goavec-Merou 22fa006293 main: parse_opt: simplify/fix 2026-03-10 18:30:50 +01:00
Gwenhael Goavec-Merou 9935be220b xvc_client: reworks operator priority 2026-03-09 19:40:37 +01:00
Gwenhael Goavec-Merou 3eff88e331 ice40: fix detect_flash 2026-03-09 19:39:35 +01:00
Gwenhael Goavec-Merou 4ab6f220b9
Merge pull request #632 from smarsching/xvc-client-performance
Performance improvement for XVC client
2026-03-05 17:00:21 +01:00
Sebastian Marsching 485d9719b5 Send command and parameters in single operation.
This significantly improves the performance because it reduces the
number of round trips needed.
2026-03-05 16:26:46 +01:00
Gwenhael Goavec-Merou 21d2e46c4f latticeBitParser.cpp: revert/adapts commit 0bc2594469 (fails with CMSIS-DAP #634) 2026-03-04 10:28:23 +01:00
Gwenhael Goavec-Merou cde80a5a85
Merge pull request #635 from smarsching/xc7k325tfbg900
Add SPI over JTAG bitfile for XC7K325TFBG900
2026-03-04 07:51:45 +01:00
Sebastian Marsching 2d88b3dba6 Add SPI over JTAG bitfile for XC7K325TFBG900. 2026-03-03 23:21:33 +01:00
Gwenhael Goavec-Merou d9d6c30eed
Merge pull request #631 from smarsching/xvc-client-without-ftdi
Allow building XVC client without libftdi
2026-03-02 18:44:27 +01:00
Sebastian Marsching f2679b01af Allow building XVC client without libftdi.
Unlike the XVC server, the XVC client does not depend on libftdi, so
building it just depends on having separate flags for enabling it.
2026-03-01 19:49:07 +01:00
85 changed files with 1706 additions and 1452 deletions

View File

@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.10)
# set the project name
project(openFPGALoader VERSION "1.1.0" LANGUAGES CXX)
project(openFPGALoader VERSION "1.1.1" LANGUAGES CXX)
add_definitions(-DVERSION=\"v${PROJECT_VERSION}\")
#if(CMAKE_SYSTEM_NAME STREQUAL "Windows" AND NOT CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
@ -66,11 +66,13 @@ endif()
# XVC and RemoteBitbang are not available on Windows OS.
if (NOT ${CMAKE_SYSTEM_NAME} MATCHES "Windows")
option(ENABLE_REMOTEBITBANG "enable remote bitbang driver" ${ENABLE_CABLE_ALL})
option(ENABLE_XILINX_VIRTUAL_CABLE "enable Xilinx Virtual Cable (XVC) support" ${ENABLE_CABLE_ALL})
option(ENABLE_REMOTEBITBANG "enable remote bitbang driver" ${ENABLE_CABLE_ALL})
option(ENABLE_XILINX_VIRTUAL_CABLE_CLIENT "enable Xilinx Virtual Cable (XVC) client support" ${ENABLE_CABLE_ALL})
option(ENABLE_XILINX_VIRTUAL_CABLE_SERVER "enable Xilinx Virtual Cable (XVC) server support" ${ENABLE_CABLE_ALL})
else()
set(ENABLE_REMOTEBITBANG OFF)
set(ENABLE_XILINX_VIRTUAL_CABLE OFF)
set(ENABLE_REMOTEBITBANG OFF)
set(ENABLE_XILINX_VIRTUAL_CABLE_CLIENT OFF)
set(ENABLE_XILINX_VIRTUAL_CABLE_SERVER OFF)
endif()
####################################################################################################
@ -102,11 +104,11 @@ set(USE_LIBUSB_LL OFF)
# Only adds libftdi as dependency when a cable
# need this library.
if (ENABLE_FTDI_BASED_CABLE OR ENABLE_USB_BLASTERI OR ENABLE_XILINX_VIRTUAL_CABLE)
if (ENABLE_FTDI_BASED_CABLE OR ENABLE_USB_BLASTERI OR ENABLE_XILINX_VIRTUAL_CABLE_SERVER)
set(USE_LIBFTDI ON)
else()
message("disabled all cables based on FTDI devices")
endif(ENABLE_FTDI_BASED_CABLE OR ENABLE_USB_BLASTERI OR ENABLE_XILINX_VIRTUAL_CABLE)
endif(ENABLE_FTDI_BASED_CABLE OR ENABLE_USB_BLASTERI OR ENABLE_XILINX_VIRTUAL_CABLE_SERVER)
# Only adds libusb as dependency when a cable need this library
if (ENABLE_DFU OR ENABLE_ANLOGIC_CABLE OR ENABLE_CH347 OR ENABLE_DIRTYJTAG
@ -160,7 +162,7 @@ endif()
####################################################################################################
## specify the C++ standard
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
set(CMAKE_CXX_FLAGS_DEBUG "-g -Wall -Wextra ${CMAKE_CXX_FLAGS_DEBUG}")
if(ENABLE_OPTIM AND NOT(CMAKE_BUILD_TYPE STREQUAL "Debug"))
@ -335,8 +337,7 @@ endif()
list(APPEND OPENFPGALOADER_SOURCE
src/bpiFlash.cpp
src/spiFlash.cpp
src/spiInterface.cpp
src/epcq.cpp
src/flashInterface.cpp
src/jtag.cpp
)
@ -346,8 +347,7 @@ list(APPEND OPENFPGALOADER_HEADERS
src/jtagInterface.hpp
src/spiFlash.hpp
src/spiFlashdb.hpp
src/epcq.hpp
src/spiInterface.hpp
src/flashInterface.hpp
)
# FTDI Based cables
@ -591,9 +591,13 @@ add_definitions(-DENABLE_SVF_JTAG)
endif()
# Xilinx Virtual Cable
if (ENABLE_XILINX_VIRTUAL_CABLE)
list (APPEND OPENFPGALOADER_SOURCE src/xvc_client.cpp src/xvc_server.cpp)
list (APPEND OPENFPGALOADER_HEADERS src/xvc_client.hpp src/xvc_server.hpp)
if (ENABLE_XILINX_VIRTUAL_CABLE_CLIENT)
list (APPEND OPENFPGALOADER_SOURCE src/xvc_client.cpp)
list (APPEND OPENFPGALOADER_HEADERS src/xvc_client.hpp)
endif()
if (ENABLE_XILINX_VIRTUAL_CABLE_SERVER)
list (APPEND OPENFPGALOADER_SOURCE src/xvc_server.cpp)
list (APPEND OPENFPGALOADER_HEADERS src/xvc_server.hpp)
endif()
# Altera USB Blaster (I & II).
@ -669,10 +673,6 @@ if (ENABLE_UDEV)
target_link_libraries(openFPGALoader ${LIBUDEV_LIBRARIES})
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)
set_target_properties(openFPGALoader PROPERTIES LINK_SEARCH_END_STATIC 1)
endif()
@ -772,8 +772,16 @@ else()
message("Remote bitbang client support disabled")
endif()
if (ENABLE_XILINX_VIRTUAL_CABLE)
add_definitions(-DENABLE_XVC=1)
if (ENABLE_XILINX_VIRTUAL_CABLE_CLIENT)
add_definitions(-DENABLE_XVC_CLIENT=1)
set(CMAKE_EXE_LINKER_FLAGS "-pthread ${CMAKE_EXE_LINKER_FLAGS}")
message("Xilinx Virtual Client support enabled")
else()
message("Xilinx Virtual Client support disabled")
endif()
if (ENABLE_XILINX_VIRTUAL_CABLE_SERVER)
add_definitions(-DENABLE_XVC_SERVER=1)
set(CMAKE_EXE_LINKER_FLAGS "-pthread ${CMAKE_EXE_LINKER_FLAGS}")
message("Xilinx Virtual Server support enabled")
else()

View File

@ -48,5 +48,6 @@ set(CMAKE_EXE_LINKER_FLAGS_INIT "-static -static-libgcc -static-libstdc++")
set(ENABLE_UDEV OFF CACHE BOOL "" FORCE)
set(ENABLE_LIBGPIOD OFF CACHE BOOL "" FORCE)
set(ENABLE_REMOTEBITBANG OFF CACHE BOOL "" FORCE)
set(ENABLE_XILINX_VIRTUAL_CABLE OFF CACHE BOOL "" FORCE)
set(ENABLE_XILINX_VIRTUAL_CABLE_CLIENT OFF CACHE BOOL "" FORCE)
set(ENABLE_XILINX_VIRTUAL_CABLE_SERVER OFF CACHE BOOL "" FORCE)
set(BUILD_STATIC ON CACHE BOOL "" FORCE)

View File

@ -35,5 +35,6 @@ set(CMAKE_EXE_LINKER_FLAGS_INIT "-static -static-libgcc -static-libstdc++")
set(ENABLE_UDEV OFF CACHE BOOL "" FORCE)
set(ENABLE_LIBGPIOD OFF CACHE BOOL "" FORCE)
set(ENABLE_REMOTEBITBANG OFF CACHE BOOL "" FORCE)
set(ENABLE_XILINX_VIRTUAL_CABLE OFF CACHE BOOL "" FORCE)
set(ENABLE_XILINX_VIRTUAL_CABLE_CLIENT OFF CACHE BOOL "" FORCE)
set(ENABLE_XILINX_VIRTUAL_CABLE_SERVER OFF CACHE BOOL "" FORCE)
set(BUILD_STATIC ON CACHE BOOL "" FORCE)

View File

@ -85,7 +85,7 @@ Gowin:
Flash: EF
Intel:
Altera:
- Description: Max II(CPLD)
Model: EPM240T100C5N
@ -162,6 +162,20 @@ Intel:
Memory: SVF
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:

View File

@ -27,6 +27,20 @@
Memory: 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
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/

View File

@ -385,7 +385,8 @@ Example (enable FTDI-based cables and Xilinx devices only):
- ``ENABLE_USB_BLASTERII``: Enable Altera USB-Blaster II support.
- ``ENABLE_LIBGPIOD``: Enable libgpiod bitbang driver support (Linux only).
- ``ENABLE_REMOTEBITBANG``: Enable remote-bitbang driver support.
- ``ENABLE_XILINX_VIRTUAL_CABLE``: Enable Xilinx Virtual Cable (XVC) support.
- ``ENABLE_XILINX_VIRTUAL_CABLE_CLIENT``: Enable Xilinx Virtual Cable (XVC) client support.
- ``ENABLE_XILINX_VIRTUAL_CABLE_SERVER``: Enable Xilinx Virtual Cable (XVC) server support.
**Vendor options**

View File

@ -7,13 +7,14 @@ XILINX_PARTS := xc3s500evq100 \
xc7s6 xc7s15 xc7s25 xc7s50 xc7s75 xc7s100 \
xc7k70tfbg484 xc7k70tfbg676 \
xc7k160tffg676 \
xc7k325tffg676 xc7k325tffg900 \
xc7k325tfbg900 xc7k325tffg676 xc7k325tffg900 \
xc7k420tffg901 \
xcku3p-ffva676 \
xc7vx330tffg1157 \
xcku040-ffva1156 xcku060-ffva1156 \
xcku5p-ffvb676 \
xcvu9p-flga2104 xcvu37p-fsvh2892 \
xcau10p-ffvb676 \
xcau15p-ffvb676
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",
"xcku3p-ffva676" : "xcku3p_ffva676",
"xcku5p-ffvb676" : "xcku5p_ffvb676",
"xcau10p-ffvb676" : "xcau10p_ffvb676",
"xcau15p-ffvb676" : "xcau15p_ffvb676",
}.get(part, pkg_name)
if tool == "ise":
@ -212,6 +213,8 @@ if tool in ["ise", "vivado"]:
'paramtype': 'vlogdefine',
'description': 'secondary flash',
'default': 1}
elif part == "xcau10p-ffvb676":
tool_options = {'part': part + '-1-e'}
elif part == "xcau15p-ffvb676":
tool_options = {'part': part + '-2-e'}
else:

View File

@ -0,0 +1,6 @@
NET "csn" LOC = U19 | IOSTANDARD = LVCMOS33;
NET "sdi_dq0" LOC = P24 | IOSTANDARD = LVCMOS33;
NET "sdo_dq1" LOC = R25 | IOSTANDARD = LVCMOS33;
NET "wpn_dq2" LOC = R20 | IOSTANDARD = LVCMOS33;
NET "hldn_dq3" LOC = R21 | IOSTANDARD = LVCMOS33;

View File

@ -0,0 +1,12 @@
set_property CFGBVS VCCO [current_design]
set_property CONFIG_VOLTAGE 3.3 [current_design]
set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]
set_property BITSTREAM.CONFIG.CONFIGRATE 33 [current_design]
set_property BITSTREAM.CONFIG.SPI_BUSWIDTH {4} [current_design]
set_property -dict {PACKAGE_PIN U19 IOSTANDARD LVTTL} [get_ports {csn}]
set_property -dict {PACKAGE_PIN P24 IOSTANDARD LVTTL} [get_ports {sdi_dq0}]
set_property -dict {PACKAGE_PIN R25 IOSTANDARD LVTTL} [get_ports {sdo_dq1}]
set_property -dict {PACKAGE_PIN R20 IOSTANDARD LVTTL} [get_ports {wpn_dq2}]
set_property -dict {PACKAGE_PIN R21 IOSTANDARD LVTTL} [get_ports {hldn_dq3}]

Binary file not shown.

Binary file not shown.

View File

@ -5,6 +5,7 @@
#include "altera.hpp"
#include <inttypes.h>
#include <string.h>
#include <map>
@ -12,7 +13,6 @@
#include "common.hpp"
#include "device.hpp"
#include "epcq.hpp"
#include "jtag.hpp"
#include "progressBar.hpp"
#include "rawParser.hpp"
@ -34,7 +34,7 @@ Altera::Altera(Jtag *jtag, const std::string &filename,
const std::string &flash_sectors,
bool skip_load_bridge, bool skip_reset):
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),
_device_package(device_package), _spiOverJtagPath(spiOverJtagPath),
_vir_addr(0x1000), _vir_length(14), _clk_period(1),
@ -42,9 +42,13 @@ Altera::Altera(Jtag *jtag, const std::string &filename,
{
/* check device family */
_idcode = _jtag->get_target_device_id();
string family = fpga_list[_idcode].family;
std::string family = fpga_list[_idcode].family;
if (family == "MAX 10") {
_fpga_family = MAX10_FAMILY;
} else if (family == "agilex 3") {
_fpga_family = AGILEX3_FAMILY;
} else if (family == "agilex 5") {
_fpga_family = AGILEX5_FAMILY;
} else {
_fpga_family = CYCLONE_MISC; // FIXME
}
@ -243,6 +247,16 @@ void Altera::program(unsigned int offset, bool unprotect_flash)
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
* MEM_MODE : svf file provided for constructor
* is the bitstream to use
@ -274,7 +288,7 @@ void Altera::program(unsigned int offset, bool unprotect_flash)
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");
}
}
@ -349,6 +363,15 @@ const std::map<uint32_t, Altera::max10_mem_t> Altera::max10_memory_map = {
// CHECKME: this line
.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
@ -1002,6 +1025,276 @@ bool Altera::sectors_mask_start_end_addr(const Altera::max10_mem_t *mem,
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 */
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 "jtag.hpp"
#include "rawParser.hpp"
#include "spiInterface.hpp"
#include "flashInterface.hpp"
#include "svf_jtag.hpp"
class Altera: public Device, SPIInterface {
class Altera: public Device, FlashInterface {
public:
Altera(Jtag *jtag, const std::string &filename,
const std::string &file_type,
@ -39,7 +39,7 @@ class Altera: public Device, SPIInterface {
bool dumpFlash(uint32_t base_addr, uint32_t len) override {
if (_fpga_family == MAX10_FAMILY)
return max10_dump();
return SPIInterface::dump(base_addr, len);
return FlashInterface::dump(base_addr, len);
}
uint32_t idCode() override;
@ -53,25 +53,25 @@ class Altera: public Device, SPIInterface {
* \brief display SPI flash ID and status register
*/
bool detect_flash() override {
return SPIInterface::detect_flash();
return FlashInterface::detect_flash();
}
/*!
* \brief protect SPI flash blocks
*/
bool protect_flash(uint32_t len) override {
return SPIInterface::protect_flash(len);
return FlashInterface::protect_flash(len);
}
/*!
* \brief unprotect SPI flash blocks
*/
bool unprotect_flash() override {
return SPIInterface::unprotect_flash();
return FlashInterface::unprotect_flash();
}
/*!
* \brief bulk erase SPI flash
*/
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,
@ -90,10 +90,25 @@ class Altera: public Device, SPIInterface {
MAX10_FAMILY = 1,
CYCLONE5_FAMILY = 2,
CYCLONE10_FAMILY = 3,
STRATIXV_FAMILY = 3,
STRATIXV_FAMILY = 4,
AGILEX3_FAMILY = 5,
AGILEX5_FAMILY = 6,
CYCLONE_MISC = 10, // Fixme: idcode shared
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 */
/*************************/

View File

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

View File

@ -11,10 +11,10 @@
#include "bitparser.hpp"
#include "device.hpp"
#include "jtag.hpp"
#include "spiInterface.hpp"
#include "flashInterface.hpp"
#include "svf_jtag.hpp"
class Anlogic: public Device, SPIInterface {
class Anlogic: public Device, FlashInterface {
public:
Anlogic(Jtag *jtag, const std::string &filename,
const std::string &file_type,
@ -30,21 +30,21 @@ class Anlogic: public Device, SPIInterface {
* \brief protect SPI flash blocks
*/
bool protect_flash(uint32_t len) override {
return SPIInterface::protect_flash(len);
return FlashInterface::protect_flash(len);
}
/*!
* \brief protect SPI flash blocks
*/
bool unprotect_flash() override {
return SPIInterface::unprotect_flash();
return FlashInterface::unprotect_flash();
}
/*!
* \brief bulk erase SPI flash
*/
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
*/
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,

View File

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

View File

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

View File

@ -18,12 +18,11 @@
#include <winsock2.h>
#endif
using namespace std;
#define display(...) \
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,
verbose), _reverseOrder(reverseOrder)
{
@ -37,49 +36,86 @@ int BitParser::parseHeader()
{
int pos_data = 0;
int ret = 1;
short length;
string tmp;
int pos, prev_pos;
uint16_t length;
std::string tmp;
/* 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 = ntohs(length);
pos_data += length + 2;
length = *(uint16_t *)&_raw_data[pos_data];
length = ntohs(length);
if (pos_data + 2 >= static_cast<int>(_raw_data.size())) {
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;
while (1) {
/* type */
uint8_t type;
type = (uint8_t)_raw_data[pos_data++];
if (pos_data >= static_cast<int>(_raw_data.size())) {
printError("BitParser: Bound check failure. Field type");
return -1;
}
const uint8_t type = (uint8_t)_raw_data[pos_data++];
if (type != 'e') {
length = *(uint16_t *)&_raw_data[pos_data];
length = ntohs(length);
if (pos_data + 2 >= static_cast<int>(_raw_data.size())) {
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;
} else {
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);
pos_data += length;
switch (type) {
case 'a': /* design name:userid:synthesize tool version */
prev_pos = 0;
pos = tmp.find(";");
_hdr["design_name"] = tmp.substr(prev_pos, pos);
prev_pos = pos+1;
case 'a': { /* design name:userid:synthesize tool version */
std::stringstream ss(tmp);
std::string token;
bool first = true;
pos = tmp.find(";", prev_pos);
prev_pos = tmp.find("=", prev_pos) + 1;
_hdr["userID"] = tmp.substr(prev_pos, pos-prev_pos);
prev_pos = pos+1;
while (std::getline(ss, token, ';')) {
if (first) {
_hdr["design_name"] = token;
first = false;
continue;
}
prev_pos = tmp.find("=", prev_pos) + 1;
_hdr["toolVersion"] = tmp.substr(prev_pos, length-prev_pos);
break;
auto pos = token.find('=');
if (pos != std::string::npos) {
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 */
_hdr["part_name"] = tmp.substr(0, length);
break;
@ -108,6 +144,10 @@ int BitParser::parse()
{
/* process all field */
int pos = parseHeader();
if (pos == -1) {
printError("BitParser: parseHeader failed");
return 1;
}
/* _bit_length is length of data to send */
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("acornCle215", "xc7a200tsbg484", "", 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("alchitry_au", "xc7a35tftg256", "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-blasterII", CABLE_DEF(MODE_USBBLASTER, 0x09Fb, 0x6810 )},
{"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 )},
#ifdef ENABLE_LIBGPIOD
{"libgpiod", CABLE_DEF(MODE_LIBGPIOD_BITBANG, 0, 0x0000 )},

View File

@ -19,7 +19,6 @@
#include "ch347jtag.hpp"
#include "display.hpp"
using namespace std;
#define CH347JTAG_VID 0x1a86
#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) {
throw runtime_error("buffer overflow");
throw std::runtime_error("buffer overflow");
}
wlen += obuf - _obuf;
if (wlen > MAX_BUFFER) {
throw runtime_error("buffer overflow");
throw std::runtime_error("buffer overflow");
}
obuf = _obuf;
@ -293,8 +292,8 @@ int CH347Jtag::writeTMS(const uint8_t *tms, uint32_t len, bool flush_buffer,
obuf[2] = (wlen - 3) >> 8;
int ret = usb_xfer(wlen, 0, 0, !flush_buffer);
if (ret < 0) {
cerr << "writeTMS: usb bulk write failed: " <<
libusb_strerror(static_cast<libusb_error>(ret)) << endl;
printError(std::string("writeTMS: usb bulk write failed: ")
+ std::string(libusb_strerror(static_cast<libusb_error>(ret))));
return -EXIT_FAILURE;
}
ptr = obuf;
@ -332,8 +331,8 @@ int CH347Jtag::toggleClk(__attribute__((unused)) uint8_t tms,
obuf[2] = (wlen - 3) >> 8;
int ret = usb_xfer(wlen, 0, 0, true);
if (ret < 0) {
cerr << "writeCLK: usb bulk write failed: " <<
libusb_strerror(static_cast<libusb_error>(ret)) << endl;
printError(std::string("writeCLK: usb bulk write failed: ")
+ std::string(libusb_strerror(static_cast<libusb_error>(ret))));
return -EXIT_FAILURE;
}
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;
int ret = usb_xfer(chunk + 3, (rx) ? chunk + 3 : 0, &actual_length, rx == 0 && get_obuf_length());
if (ret < 0) {
cerr << "writeTDI: usb bulk read failed: " <<
libusb_strerror(static_cast<libusb_error>(ret)) << endl;
printError(std::string("writeTDI: usb bulk read failed: ")
+ std::string(libusb_strerror(static_cast<libusb_error>(ret))));
return -EXIT_FAILURE;
}
if (!rx)
continue;
unsigned size = ibuf[1] + ibuf[2] * 0x100;
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;
}
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);
if (ret < 0) {
cerr << "writeTDI: usb bulk read failed: " <<
libusb_strerror(static_cast<libusb_error>(ret)) << endl;
printError(std::string("writeTDI: usb bulk read failed: ")
+ std::string(libusb_strerror(static_cast<libusb_error>(ret))));
return -EXIT_FAILURE;
}
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;
if (ibuf[0] != CMD_BITS_WR || actual_length - 3 != size) {
cerr << "writeTDI: invalid read data: " << endl;
printError("writeTDI: invalid read data: ");
return -EXIT_FAILURE;
}
for (unsigned i = 0; i < size; ++i) {

View File

@ -16,7 +16,6 @@
#include "ch552_jtag.hpp"
#include "ftdipp_mpsse.hpp"
using namespace std;
#define DEBUG 0
@ -30,7 +29,7 @@ using namespace std;
#endif
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):
FTDIpp_MPSSE(cable, dev, serial, clkHZ, verbose), _to_read(0)
{

View File

@ -21,7 +21,6 @@
#include "cmsisDAP.hpp"
using namespace std;
#define DAP_JTAG_SEQ_TDO_CAPTURE (1 << 7)
#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_SERNUM = 0x03, // Get the Serial Number (string).
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_NAME = 0x06, // Get the Target Device Name (string).
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).
};
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_PID, "PID"},
{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;
_pid = dev_found[_device_idx]->product_id;
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 */
_dev = hid_open_path(dev_found[_device_idx]->path);
if (!_dev) {

View File

@ -186,7 +186,7 @@ bool CologneChip::detect_flash()
printInfo("Read Flash ", false);
try {
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));
flash->read_id();
flash->display_status_reg();
@ -210,7 +210,7 @@ bool CologneChip::dumpFlash(uint32_t base_addr, uint32_t len)
printInfo("Read Flash ", false);
try {
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));
flash->dump(_filename, base_addr, len);
} 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)
{
if (!SPIInterface::set_quad_bit(set_quad)) {
if (!FlashInterface::set_quad_bit(set_quad)) {
return false;
}
@ -239,7 +239,7 @@ bool CologneChip::set_quad_bit(bool set_quad)
*/
bool CologneChip::bulk_erase_flash()
{
if (!SPIInterface::bulk_erase_flash()) {
if (!FlashInterface::bulk_erase_flash()) {
return false;
}
@ -323,7 +323,7 @@ void CologneChip::programSPI_flash(unsigned int offset, const uint8_t *data,
_spi->gpio_clear(_rstn_pin | _oen_pin);
usleep(SLEEP_US);
SPIFlash flash(reinterpret_cast<SPIInterface *>(_spi), unprotect_flash,
SPIFlash flash(reinterpret_cast<FlashInterface *>(_spi), unprotect_flash,
_verbose);
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]);
}
_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;
_jtag->shiftDR(jtx, (rx == NULL)? NULL: jrx, test, Jtag::SELECT_DR_SCAN);
int drlen = (rx == NULL) ? 8*xfer_len : 8*xfer_len+1;
_jtag->read_write(jtx, (rx == NULL) ? NULL : jrx, drlen, false);
int shift = _jtag->get_devices_list().size();
if (rx != NULL) {
for (uint32_t i=0; i < len; i++) {
uint8_t b0 = ConfigBitstreamParser::reverseByte(jrx[i+1]);
uint8_t b1 = ConfigBitstreamParser::reverseByte(jrx[i+2]);
rx[i] = (b0 << 1) | ((b1 >> 7) & 0x01);
rx[i] = (b0 << shift) | (b1 >> (8-shift));
}
}
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->read_write(&tx, NULL, 8, 0);
int shift = _jtag->get_devices_list().size();
do {
_jtag->read_write(dummy, rx, 16, 0);
uint8_t b0 = ConfigBitstreamParser::reverseByte(rx[0]);
uint8_t b1 = ConfigBitstreamParser::reverseByte(rx[1]);
tmp = (b0 << 1) | ((b1 >> 7) & 0x01);
tmp = (b0 << shift) | (b1 >> (8-shift));
count++;
if (count == timeout) {

View File

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

View File

@ -26,9 +26,8 @@
#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),
_file_size(0), _verbose(verbose),
_bit_data(), _raw_data(), _hdr()
@ -40,7 +39,7 @@ ConfigBitstreamParser::ConfigBitstreamParser(const string &filename, int mode,
FILE *_fd = fopen(filename.c_str(), "rb");
if (!_fd) {
/* 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);
_fd = fopen(_filename.c_str(), "rb");
}
@ -61,10 +60,10 @@ ConfigBitstreamParser::ConfigBitstreamParser(const string &filename, int mode,
if (ret != _file_size)
throw std::runtime_error("Error: fail to read " + _filename);
if (offset != string::npos) {
string extension = _filename.substr(_filename.find_last_of(".") +1);
if (offset != std::string::npos) {
std::string extension = _filename.substr(_filename.find_last_of(".") +1);
if (extension == "gz" || extension == "gzip") {
string tmp;
std::string tmp;
tmp.reserve(_file_size);
if (!decompress_bitstream(_raw_data, &tmp))
throw std::runtime_error("Error: decompress failed");
@ -77,7 +76,7 @@ ConfigBitstreamParser::ConfigBitstreamParser(const string &filename, int mode,
} else if (!isatty(fileno(stdin))) {
_file_size = 0;
string tmp;
std::string tmp;
tmp.resize(4096);
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);
if (val == _hdr.end())
@ -107,7 +106,7 @@ void ConfigBitstreamParser::displayHeader()
{
if (_hdr.empty())
return;
cout << "bitstream header infos" << endl;
printInfo("bitstream header infos");
for (auto it = _hdr.begin(); it != _hdr.end(); it++) {
printInfo((*it).first + ": ", false);
printSuccess((*it).second);
@ -165,7 +164,7 @@ uint32_t ConfigBitstreamParser::reverse_32(const uint32_t src)
(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
(void)source;

View File

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

View File

@ -21,7 +21,6 @@
#include "dfu.hpp"
using namespace std;
/* USB request write */
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)
*/
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,
int verbose_lvl):_verbose(verbose_lvl > 0), _debug(verbose_lvl > 1),
_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");
} catch (std::exception &e) {
printError("FAIL");
throw runtime_error("Error: Fail to open file");
throw std::runtime_error("Error: Fail to open file");
}
printInfo("Parse file ", false);
@ -78,7 +77,7 @@ DFU::DFU(const string &filename, bool bypass_bitstream,
} catch (std::exception &e) {
printError("FAIL");
delete _bit;
throw runtime_error("Error: Fail to parse file");
throw std::runtime_error("Error: Fail to parse file");
}
if (_verbose > 0)
@ -301,7 +300,7 @@ int DFU::searchDFUDevices()
/* iteration */
ssize_t list_size = libusb_get_device_list(usb_ctx, &dev_list);
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) {
struct libusb_device_descriptor desc;
@ -352,7 +351,7 @@ int DFU::searchIfDFU(struct libusb_device_handle *handle,
struct libusb_config_descriptor *cfg;
int ret = libusb_get_config_descriptor(dev, i, &cfg);
if (ret != 0) {
printError("Fail to retrieve config_descriptor " + to_string(i));
printError("Fail to retrieve config_descriptor " + std::to_string(i));
return 1;
}
/* configuration interface iteration */
@ -499,7 +498,7 @@ int DFU::set_state(char newState)
return -1;
if (status.bState != STATE_appDETACH ||
status.bStatus != STATUS_OK) {
cerr << dfu_dev_status_val[status.bStatus] << endl;
std::cerr << dfu_dev_status_val[status.bStatus] << std::endl;
return -1;
}
break;
@ -571,7 +570,7 @@ int DFU::set_state(char newState)
return ret;
if (status.bState != newState ||
status.bStatus != STATUS_OK) {
cerr << dfu_dev_status_val[status.bStatus] << endl;
std::cerr << dfu_dev_status_val[status.bStatus] << std::endl;
return -1;
}
break;
@ -635,7 +634,7 @@ int DFU::poll_state(uint8_t state) {
do {
ret = get_status(&status);
if (ret <= 0) {
printError("Error: poll state " + string(libusb_error_name(ret)));
printError("Error: poll state " + std::string(libusb_error_name(ret)));
break;
}
/* millisecond */
@ -800,7 +799,7 @@ int DFU::download()
//ret = set_state(STATE_dfuMANIFEST_SYNC);
ret = send(true, DFU_DNLOAD, transaction, NULL, 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;
}

View File

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

View File

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

View File

@ -16,7 +16,6 @@
#include "dirtyJtag.hpp"
#include "display.hpp"
using namespace std;
#define DIRTYJTAG_VID 0x1209
#define DIRTYJTAG_PID 0xC0CA
@ -52,7 +51,6 @@ struct version_specific
static version_specific v_options[4] ={{0, 240}, {0, 240}, {NO_READ, 496},
{NO_READ, 4000}};
enum dirtyJtagSig {
SIG_TCK = (1 << 1),
SIG_TDI = (1 << 2),
@ -62,47 +60,57 @@ enum dirtyJtagSig {
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),
dev_handle(NULL), usb_ctx(NULL), _tdi(0), _tms(0), _version(0)
{
int ret;
if (libusb_init(&usb_ctx) < 0) {
cerr << "libusb init failed" << endl;
throw std::exception();
}
if (libusb_init(&usb_ctx) < 0)
throw std::runtime_error("DirtyJtag: libusb init failed");
dev_handle = libusb_open_device_with_vid_pid(usb_ctx, vid, pid);
if (!dev_handle) {
cerr << "fails to open device" << endl;
libusb_exit(usb_ctx);
throw std::exception();
throw std::runtime_error("DirtyJtag: fails to open device");
}
ret = libusb_claim_interface(dev_handle, DIRTYJTAG_INTF);
if (ret) {
cerr << "libusb error while claiming DirtyJTAG interface" << endl;
libusb_close(dev_handle);
dev_handle = NULL;
libusb_exit(usb_ctx);
throw std::exception();
usb_ctx = NULL;
throw std::runtime_error("DirtyJtag: libusb error while claiming interface");
}
if (!getVersion())
throw std::runtime_error("Fail to get version");
if (!getVersion()) {
close_usb();
throw std::runtime_error("DirtyJtag: Fail to get version");
}
if (setClkFreq(clkHZ) < 0) {
cerr << "Fail to set frequency" << endl;
throw std::exception();
if (setClkFreq(clkHz) < 0) {
close_usb();
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()
{
if (dev_handle)
libusb_close(dev_handle);
if (usb_ctx)
libusb_exit(usb_ctx);
close_usb();
}
bool DirtyJtag::getVersion()
@ -115,14 +123,14 @@ bool DirtyJtag::getVersion()
ret = libusb_bulk_transfer(dev_handle, DIRTYJTAG_WRITE_EP,
buf, 2, &actual_length, DIRTYJTAG_TIMEOUT);
if (ret < 0) {
cerr << "getVersion: usb bulk write failed " << ret << endl;
std::cerr << "getVersion: usb bulk write failed " << ret << std::endl;
return false;
}
do {
ret = libusb_bulk_transfer(dev_handle, DIRTYJTAG_READ_EP,
rx_buf, 64, &actual_length, DIRTYJTAG_TIMEOUT);
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;
}
} while (actual_length == 0);
@ -133,40 +141,40 @@ bool DirtyJtag::getVersion()
} else if (!strncmp("DJTAG3\n", (char*)rx_buf, 7)) {
_version = 3;
} else {
cerr << "dirtyJtag version unknown" << endl;
std::cerr << "dirtyJtag version unknown" << std::endl;
_version = 0;
}
return true;
}
int DirtyJtag::setClkFreq(uint32_t clkHZ)
int DirtyJtag::setClkFreq(uint32_t clkHz)
{
int actual_length;
int ret, req_freq = clkHZ;
int ret, req_freq = clkHz;
if (clkHZ > 16000000) {
printWarn("DirtyJTAG probe limited to 16000kHz");
clkHZ = 16000000;
if (clkHz > 16000000) {
printWarn("DirtyJTAG probe limited to 16000 kHz");
clkHz = 16000000;
}
_clkHZ = clkHZ;
_clkHZ = clkHz;
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,
static_cast<uint8_t>(0xff & ((clkHZ / 1000) >> 8)),
static_cast<uint8_t>(0xff & ((clkHZ / 1000) )),
static_cast<uint8_t>(0xff & ((clkHz / 1000) >> 8)),
static_cast<uint8_t>(0xff & ((clkHz / 1000) )),
CMD_STOP};
ret = libusb_bulk_transfer(dev_handle, DIRTYJTAG_WRITE_EP,
buf, 4, &actual_length, DIRTYJTAG_TIMEOUT);
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 clkHZ;
return clkHz;
}
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,
DIRTYJTAG_TIMEOUT);
if (ret < 0) {
cerr << "writeTMS: usb bulk write failed " << ret << endl;
std::cerr << "writeTMS: usb bulk write failed " << ret << std::endl;
return -EXIT_FAILURE;
}
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,
buf, 4, &actual_length, DIRTYJTAG_TIMEOUT);
if (ret < 0) {
cerr << "toggleClk: usb bulk write failed " << ret << endl;
std::cerr << "toggleClk: usb bulk write failed " << ret << std::endl;
return -EXIT_FAILURE;
}
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,
&actual_length, DIRTYJTAG_TIMEOUT);
if ((ret < 0) || (actual_length != xfer_len)) {
cerr << "writeTDI: fill: usb bulk write failed " << ret <<
"actual length: " << actual_length << endl;
std::cerr << "writeTDI: fill: usb bulk write failed " << ret <<
"actual length: " << actual_length << std::endl;
return EXIT_FAILURE;
}
// cerr << actual_length << ", " << bit_to_send << endl;
// std::cerr << actual_length << ", " << bit_to_send << std::endl;
if (rx || (_version <= 1)) {
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,
rx_buf, transfer_length, &actual_length, DIRTYJTAG_TIMEOUT);
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;
}
} 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:
* 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) {
const uint32_t b = (bit_to_send >> 3) << 3; // floor
if (b < bit_to_send) { // difference ?
const uint32_t b = (bit_to_send >> 3) << 3; // floor
if (b < bit_to_send) { // difference ?
const uint32_t diff = bit_to_send - b;
const uint8_t t = rx_ptr[(rx_cnt-1) >> 3] >> (8 - diff);
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;
}
/* this step exist only with [D|I]R_SHIFT */
/* Final single-bit step used only for DR/IR SHIFT end transitions. */
if (end) {
int pos = len-1;
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,
buf, 8, &actual_length,
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;
}
@ -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,
&sig, 1, &actual_length,
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;
}
} 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,
buf, 4, &actual_length,
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;
}
} else {
if (toggleClk(_tms, _tdi, 1)) {
cerr << "writeTDI: last bit error" << endl;
std::cerr << "writeTDI: last bit error" << std::endl;
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;
}
/* GPIOs */
/* Read GPIOs */
/* GPIO helpers */
/* Read GPIO signal state */
uint8_t DirtyJtag::gpio_get()
{
int actual_length;
@ -437,12 +445,13 @@ bool DirtyJtag::_set_gpio_level(uint8_t gpio, uint8_t val)
return true;
}
/* update selected gpio */
/* Set selected GPIO bits */
bool DirtyJtag::gpio_set(uint8_t gpio)
{
return _set_gpio_level(gpio, gpio);
}
/* Clear selected GPIO bits */
bool DirtyJtag::gpio_clear(uint8_t gpio)
{
return _set_gpio_level(gpio, 0);

View File

@ -11,24 +11,45 @@
#include "jtagInterface.hpp"
/*!
* \file DirtyJtag.hpp
* \file dirtyJtag.hpp
* \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
*/
class DirtyJtag : public JtagInterface {
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();
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;
/* TDI */
int writeTDI(const uint8_t *tx, uint8_t *rx, uint32_t len, bool end) override;
/* clk */
/*!
* \brief drive TMS to move in JTAG state machine
* \param tms serie of TMS state
* \param len number of TMS state
* \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;
/*!
@ -36,13 +57,12 @@ class DirtyJtag : public JtagInterface {
* \return _buffer_size divided by 2 (two byte for clk) and divided by 8 (one
* 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;
/* access gpio */
/* read gpio */
uint8_t gpio_get();
/* update selected gpio */
@ -54,11 +74,13 @@ class DirtyJtag : public JtagInterface {
int sendBitBang(uint8_t mask, uint8_t val, uint8_t *read, bool last);
bool getVersion();
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;
uint8_t _tdi;
uint8_t _tms;
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 &spiOverJtagPath, bool verify, int8_t 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),
_oe_pin(0), _fpga_family(UNKNOWN_FAMILY), _irlen(0),
_device_package(device_package), _spiOverJtagPath(spiOverJtagPath)
@ -238,7 +238,7 @@ void Efinix::program(unsigned int offset, bool unprotect_flash)
break;
case FLASH_MODE:
if (_jtag)
ret = SPIInterface::write(offset, const_cast<uint8_t *>(data),
ret = FlashInterface::write(offset, const_cast<uint8_t *>(data),
length, unprotect_flash);
else
ret = programSPI(offset, data, length, unprotect_flash);
@ -257,7 +257,7 @@ void Efinix::program(unsigned int offset, bool unprotect_flash)
bool Efinix::detect_flash()
{
if (_jtag) {
return SPIInterface::detect_flash();
return FlashInterface::detect_flash();
}
#if 0
@ -265,7 +265,7 @@ bool Efinix::detect_flash()
* uncomment it and submit a PR! */
_spi->gpio_clear(_rst_pin);
bool rv = reinterpret_cast<SPIInterface *>(_spi)->detect_flash();
bool rv = reinterpret_cast<FlashInterface *>(_spi)->detect_flash();
reset();
@ -279,8 +279,8 @@ bool Efinix::detect_flash()
bool Efinix::dumpFlash(uint32_t base_addr, uint32_t len)
{
if (_jtag) {
SPIInterface::set_filename(_filename);
return SPIInterface::dump(base_addr, len);
FlashInterface::set_filename(_filename);
return FlashInterface::dump(base_addr, len);
}
uint32_t timeout = 1000;
@ -289,7 +289,7 @@ bool Efinix::dumpFlash(uint32_t base_addr, uint32_t len)
/* prepare SPI access */
printInfo("Read Flash ", false);
try {
SPIFlash flash(reinterpret_cast<SPIInterface *>(_spi), false, _verbose);
SPIFlash flash(reinterpret_cast<FlashInterface *>(_spi), false, _verbose);
flash.reset();
flash.power_up();
flash.dump(_filename, base_addr, len);
@ -322,7 +322,7 @@ bool Efinix::programSPI(unsigned int offset, const uint8_t *data,
bool ret = true;
_spi->gpio_clear(_rst_pin | _oe_pin);
SPIFlash flash(reinterpret_cast<SPIInterface *>(_spi), unprotect_flash,
SPIFlash flash(reinterpret_cast<FlashInterface *>(_spi), unprotect_flash,
_verbose);
flash.reset();
flash.power_up();

View File

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

View File

@ -10,19 +10,18 @@
#include "display.hpp"
#include "efinixHexParser.hpp"
using namespace std;
EfinixHexParser::EfinixHexParser(const string &filename):
EfinixHexParser::EfinixHexParser(const std::string &filename):
ConfigBitstreamParser(filename, ConfigBitstreamParser::ASCII_MODE,
false)
{}
int EfinixHexParser::parseHeader()
{
string buffer;
istringstream lineStream(_raw_data);
std::string buffer;
std::istringstream lineStream(_raw_data);
int bytesRead = 0;
string headerText;
std::string headerText;
bool foundPaddedBits = false;
while (std::getline(lineStream, buffer, '\n')) {
@ -40,20 +39,20 @@ int EfinixHexParser::parseHeader()
break;
}
if (headerText.find("PADDED_BITS") != string::npos)
if (headerText.find("PADDED_BITS") != std::string::npos)
foundPaddedBits = true;
}
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);
_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);
_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);
_hdr["device"] = headerText.substr(pos + 8, end - pos - 8);
}
@ -63,10 +62,10 @@ int EfinixHexParser::parseHeader()
int EfinixHexParser::parse()
{
string buffer;
std::string buffer;
parseHeader();
istringstream lineStream(_raw_data);
std::istringstream lineStream(_raw_data);
while (std::getline(lineStream, buffer, '\n')) {
_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 "display.hpp"
using namespace std;
#define ESPUSBJTAG_VID 0x303A
#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];
if (libusb_init(&usb_ctx) < 0) {
cerr << "libusb init failed" << endl;
std::cerr << "libusb init failed" << std::endl;
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);
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_exit(usb_ctx);
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");
if (setClkFreq(clkHZ) < 0) {
cerr << "Fail to set frequency" << endl;
std::cerr << "Fail to set frequency" << std::endl;
throw std::exception();
}
}
@ -331,8 +330,8 @@ bool esp_usb_jtag::getVersion()
}
for(int i = 0; i < jtag_caps_read_len; i++)
cerr << " 0x" << std::hex << (int)(jtag_caps_desc[i]);
cerr << endl;
std::cerr << " 0x" << std::hex << (int)(jtag_caps_desc[i]);
std::cerr << std::endl;
_base_speed_khz = UINT32_MAX;
_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;
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;
}
struct jtag_proto_caps_hdr *hdr = (struct jtag_proto_caps_hdr *)&jtag_caps_desc[p];
if (hdr->proto_ver != JTAG_PROTO_CAPS_VER) {
cerr << "esp_usb_jtag: unknown jtag_caps descriptor version 0x" << std::hex
<< hdr->proto_ver << endl;
std::cerr << "esp_usb_jtag: unknown jtag_caps descriptor version 0x" << std::hex
<< hdr->proto_ver << std::endl;
// goto out;
}
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
<< ")" << endl;
<< ")" << std::endl;
// goto out;
}
@ -367,7 +366,7 @@ bool esp_usb_jtag::getVersion()
struct jtag_gen_hdr *dhdr = (struct jtag_gen_hdr *)&jtag_caps_desc[p];
if (dhdr->type == JTAG_PROTO_CAPS_SPEED_APB_TYPE) {
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;
}
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
* ever changes? */
} 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;
}
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;
}
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
@ -434,7 +433,7 @@ int esp_usb_jtag::setClkFreq(uint32_t clkHZ)
/*timeout ms*/ ESPUSBJTAG_TIMEOUT_MS);
if (ret != 0) {
cerr << "setClkFreq: usb bulk write failed " << ret << endl;
std::cerr << "setClkFreq: usb bulk write failed " << ret << std::endl;
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;
}
if (_verbose)
cerr << "tms" << endl;
std::cerr << "tms" << std::endl;
}
return len;
@ -579,11 +578,11 @@ int esp_usb_jtag::setio(int srst, int tms, int tdi, int tck)
/*timeout ms*/ ESPUSBJTAG_TIMEOUT_MS);
if (ret != 0) {
cerr << "setio: control write failed " << ret << endl;
std::cerr << "setio: control write failed " << ret << std::endl;
return -EXIT_FAILURE;
}
if (_verbose)
cerr << "setio 0x" << std::hex << wvalue << endl;
std::cerr << "setio 0x" << std::hex << wvalue << std::endl;
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
// exec order: high-nibble-first, low-nibble-second
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;
for(uint32_t i = 0; i < (len + 7) >> 3; i++)
cerr << " " << std::hex << (int)tdi[i];
cerr << endl;
cerr << "tdi_bits ";
std::cerr << " " << std::hex << (int)tdi[i];
std::cerr << std::endl;
std::cerr << "tdi_bits ";
}
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;
_tdi = (tdi[curr_pos >> 3] >> (curr_pos & 7)) & 1; // get i'th bit from rx
if (_verbose)
cerr << (int)_tdi;
std::cerr << (int)_tdi;
if (end && curr_pos == len - 1)
_tms = 1;
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;
}
if (_verbose)
cerr << "writeTDI write 0x" << tx_buffer_idx << " bytes" << endl;
std::cerr << "writeTDI write 0x" << tx_buffer_idx << " bytes" << std::endl;
if (rx) {
flush(); // must flush before reading
// 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++;
} while (nb_try < 3 && ret == 0);
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) {
snprintf(mess, 256, "writeTDI: usb bulk read expected=%d received=%d", read_byte_len, ret);
printError(mess);

View File

@ -63,9 +63,8 @@
# 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),
_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
* \brief read a line with '\r''\n' or '\n' termination
* 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) {
string buffer;
std::string buffer;
std::getline(_ss, buffer, '\n');
if (buffer.empty())
break;
@ -230,16 +229,16 @@ void FeaParser::displayHeader()
* 1: xxxx\n : feature Row (96 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");
string featuresRow = content[0];
std::string featuresRow = content[0];
//printf("Features: [%s]\n", featuresRow.c_str());
for (size_t i = 0; i < featuresRow.size(); i++)
_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());
_feabits = 0;
for (size_t i = 0; i < feabits.size(); i++) {
@ -249,7 +248,7 @@ void FeaParser::parseFeatureRowAndFeabits(const vector<string> &content)
int FeaParser::parse()
{
std::vector<string>lines;
std::vector<std::string>lines;
_ss.str(_raw_data);

View File

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

View File

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

View File

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

View File

@ -17,7 +17,6 @@
#include "ftdiJtagBitbang.hpp"
#include "ftdipp_mpsse.hpp"
using namespace std;
#define DEBUG 0
@ -31,7 +30,7 @@ using namespace std;
#endif
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):
FTDIpp_MPSSE(cable, dev, serial, clkHZ, verbose), _bitmode(0),
_curr_tms(0), _rx_size(0)

View File

@ -17,7 +17,6 @@
#include "ftdiJtagMPSSE.hpp"
#include "ftdipp_mpsse.hpp"
using namespace std;
#define DEBUG 0
@ -31,7 +30,7 @@ using namespace std;
#endif
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):
FTDIpp_MPSSE(cable, dev, serial, clkHZ, verbose), _ch552WA(false),
_cmd8EWA(false),

View File

@ -20,13 +20,12 @@
#include "display.hpp"
#include "ftdipp_mpsse.hpp"
using namespace std;
//#define DEBUG 1
#define display(...) \
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):
_verbose(verbose > 2), _cable(cable.config), _vid(0),
_pid(0), _index(0),
@ -41,7 +40,7 @@ FTDIpp_MPSSE::FTDIpp_MPSSE(const cable_t &cable, const string &dev,
strcpy(_product, "");
if (!dev.empty()) {
if (!search_with_dev(dev)) {
cerr << "No cable found" << endl;
std::cerr << "No cable found" << std::endl;
throw std::runtime_error("No cable found");
}
} else {
@ -159,7 +158,7 @@ void FTDIpp_MPSSE::open_device(const std::string &serial, unsigned int baudrate)
_ftdi = ftdi_new();
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");
}
#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) {
printError("FTDI reset error with code " +
std::to_string(ret) + " (" +
string(ftdi_get_error_string(_ftdi)) + ")");
std::string(ftdi_get_error_string(_ftdi)) + ")");
return ret;
}
if ((ret = ftdi_set_bitmode(_ftdi, 0x00, BITMODE_RESET)) < 0) {
printError("FTDI bitmode reset error with code " +
std::to_string(ret) + " (" +
string(ftdi_get_error_string(_ftdi)) + ")");
std::string(ftdi_get_error_string(_ftdi)) + ")");
return ret;
}
@ -295,27 +294,27 @@ int FTDIpp_MPSSE::init(unsigned char latency, unsigned char bitmask_mode,
#endif
printError("FTDI flush buffer error with code " +
std::to_string(ret) + " (" +
string(ftdi_get_error_string(_ftdi)) + ")");
std::string(ftdi_get_error_string(_ftdi)) + ")");
return ret;
}
if ((ret = ftdi_set_latency_timer(_ftdi, latency)) < 0) {
printError("FTDI set latency timer error with code " +
std::to_string(ret) + " (" +
string(ftdi_get_error_string(_ftdi)) + ")");
std::string(ftdi_get_error_string(_ftdi)) + ")");
return ret;
}
/* enable mode */
if ((ret = ftdi_set_bitmode(_ftdi, bitmask_mode, mode)) < 0) {
printError("FTDI bitmode config error with code " +
std::to_string(ret) + " (" +
string(ftdi_get_error_string(_ftdi)) + ")");
std::string(ftdi_get_error_string(_ftdi)) + ")");
return ret;
}
if (mode == BITMODE_MPSSE) {
unsigned char buf1[5];
if ((ret = ftdi_read_data(_ftdi, buf1, 5)) < 0) {
printError("fail to read data " +
string(ftdi_get_error_string(_ftdi)));
std::string(ftdi_get_error_string(_ftdi)));
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) {
printError("fail to store buffer " +
string(ftdi_get_error_string(_ftdi)));
std::string(ftdi_get_error_string(_ftdi)));
return -1;
}
if (mpsse_write() < 0) {
printError("fail to write buffer " +
string(ftdi_get_error_string(_ftdi)));
std::string(ftdi_get_error_string(_ftdi)));
return -1;
}
}
if (ftdi_read_data_set_chunksize(_ftdi, _buffer_size) < 0) {
printError("fail to set read chunk size: " +
string(ftdi_get_error_string(_ftdi)));
std::string(ftdi_get_error_string(_ftdi)));
return -1;
}
if (ftdi_write_data_set_chunksize(_ftdi, _buffer_size) < 0) {
printError("fail to set write chunk size: " +
string(ftdi_get_error_string(_ftdi)));
std::string(ftdi_get_error_string(_ftdi)));
return -1;
}
@ -382,7 +381,7 @@ int FTDIpp_MPSSE::setClkFreq(uint32_t clkHZ)
#else
if ((ret = ftdi_tcioflush(_ftdi)) < 0) {
printError("selfClkFreq: fail to flush buffers: " +
string(ftdi_get_error_string(_ftdi)));
std::string(ftdi_get_error_string(_ftdi)));
return ret;
}
@ -402,7 +401,7 @@ int FTDIpp_MPSSE::setClkFreq(uint32_t clkHZ)
}
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;
}
@ -421,7 +420,7 @@ int FTDIpp_MPSSE::setClkFreq(uint32_t clkHZ)
__buf_valid_bytes = snprintf(__buf, 10, "%3.2fKHz", clkHZ / 1e3);
else
__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, ' ');
if (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);
else
__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, ' ');
@ -453,13 +452,13 @@ int FTDIpp_MPSSE::setClkFreq(uint32_t clkHZ)
}
if ((ret = ftdi_read_data(_ftdi, buffer, 4)) < 0) {
printError("selfClkFreq: fail to read: " +
string(ftdi_get_error_string(_ftdi)));
std::string(ftdi_get_error_string(_ftdi)));
return ret;
}
_clkHZ = real_freq;
return real_freq;
return (int)real_freq;
}
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) {
printError("mpsse_store: fails to first flush " +
std::to_string(ret) + " " +
string(ftdi_get_error_string(_ftdi)));
std::string(ftdi_get_error_string(_ftdi)));
return ret;
}
}
@ -493,7 +492,7 @@ int FTDIpp_MPSSE::mpsse_store(unsigned char *buff, int len)
if ((ret = mpsse_write()) < 0) {
printError("mpsse_store: fails to first flush " +
std::to_string(ret) + " " +
string(ftdi_get_error_string(_ftdi)));
std::string(ftdi_get_error_string(_ftdi)));
return ret;
}
ptr += store_size;
@ -523,7 +522,7 @@ int FTDIpp_MPSSE::mpsse_write()
if ((ret = ftdi_write_data(_ftdi, _buffer, _num)) != _num) {
printError("mpsse_write: fail to write with error " +
std::to_string(ret) + " (" +
string(ftdi_get_error_string(_ftdi)) + ")");
std::string(ftdi_get_error_string(_ftdi)) + ")");
return ret;
}
@ -541,14 +540,14 @@ int FTDIpp_MPSSE::mpsse_read(unsigned char *rx_buff, int len)
if ((ret = mpsse_store(SEND_IMMEDIATE)) < 0) {
printError("mpsse_read: fail to store with error: " +
std::to_string(ret) + " (" +
string(ftdi_get_error_string(_ftdi)) + ")");
std::string(ftdi_get_error_string(_ftdi)) + ")");
return ret;
}
if ((ret = mpsse_write()) < 0) {
printError("mpsse_read: fail to flush buffer with error: " +
std::to_string(ret) + " (" +
string(ftdi_get_error_string(_ftdi)) + ")");
std::string(ftdi_get_error_string(_ftdi)) + ")");
return ret;
}
@ -710,7 +709,7 @@ bool FTDIpp_MPSSE::gpio_write(uint8_t gpio, bool low_pins)
else
_cable.bit_high_val = gpio;
if (__gpio_write(low_pins))
if (!__gpio_write(low_pins))
return false;
return (mpsse_write() >= 0);
}
@ -825,7 +824,7 @@ unsigned int FTDIpp_MPSSE::udevstufftoint(const char *udevstring, int base)
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_device *dev, *usbdeviceparent;
@ -899,7 +898,7 @@ unsigned int FTDIpp_MPSSE::udevstufftoint(const char *udevstring, int base)
(void)base;
return 0;
}
bool FTDIpp_MPSSE::search_with_dev(const string &device)
bool FTDIpp_MPSSE::search_with_dev(const std::string &device)
{
(void)device;
return false;

View File

@ -243,7 +243,7 @@ int FtdiSpi::ft2232_spi_wr_and_rd(//struct ftdi_spi *spi,
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)
{
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;
}
/* method spiInterface::spi_put */
/* method flashInterface::spi_put */
int FtdiSpi::spi_put(const uint8_t *tx, uint8_t *rx, uint32_t len)
{
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,
uint32_t timeout, bool verbose)

View File

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

View File

@ -15,14 +15,13 @@
#include "fx2_ll.hpp"
#include "ihexParser.hpp"
using namespace std;
#define FX2_FIRM_LOAD 0xA0
#define FX2_GCR_CPUCS 0xe600
#define FX2_GCR_CPUCS_8051_RES (1 << 0)
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;
bool reenum = false;
@ -168,7 +167,7 @@ int FX2_ll::read_ctrl(uint8_t bRequest, uint16_t wValue,
* and 64B by 64B
* 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);
ihex.parse();
@ -177,7 +176,7 @@ bool FX2_ll::load_firmware(string firmware_path)
if (!reset(1))
return false;
/* 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++) {
IhexParser::data_line_t data_line = data[i];

View File

@ -21,7 +21,6 @@
#include "rawParser.hpp"
#include "spiFlash.hpp"
using namespace std;
#ifdef STATUS_TIMEOUT
// 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_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,
bool verify, int8_t verbose, const std::string& user_flash)
: 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),
is_gw2a(false), is_gw5a(false),
_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 */
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);
if ((fs_idcode & 0x0fffffff) != _idcode) {
char mess[256];
@ -437,7 +436,7 @@ void Gowin::checkCRC()
* is used, try to compare with this value
*/
try {
string hdr = _fs->getHeaderVal("checkSum");
std::string hdr = _fs->getHeaderVal("checkSum");
if (!hdr.empty()) {
if (ucode == strtol(hdr.c_str(), NULL, 16))
goto success;

View File

@ -16,9 +16,9 @@
#include "device.hpp"
#include "jtag.hpp"
#include "jtagInterface.hpp"
#include "spiInterface.hpp"
#include "flashInterface.hpp"
class Gowin: public Device, SPIInterface {
class Gowin: public Device, FlashInterface {
public:
Gowin(Jtag *jtag, std::string filename, const std::string &file_type,
std::string mcufw, Device::prog_type_t prg_type,
@ -32,18 +32,18 @@ class Gowin: public Device, SPIInterface {
/* spi interface */
bool detect_flash() override {
if (is_gw5a || is_gw2a)
return SPIInterface::detect_flash();
return FlashInterface::detect_flash();
printError("detect flash not supported"); return false;}
bool protect_flash(uint32_t len) override {
(void) len;
printError("protect flash not supported"); return false;}
bool unprotect_flash() override {
if (is_gw5a)
return SPIInterface::unprotect_flash();
return FlashInterface::unprotect_flash();
printError("unprotect flash not supported"); return false;}
bool bulk_erase_flash() override {
if (is_gw5a || is_gw2a)
return SPIInterface::bulk_erase_flash();
return FlashInterface::bulk_erase_flash();
printError("bulk erase flash not supported"); return false;}
bool dumpFlash(uint32_t base_addr, uint32_t len) override;
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);
SPIFlash flash(reinterpret_cast<SPIInterface *>(_spi), unprotect_flash,
SPIFlash flash(reinterpret_cast<FlashInterface *>(_spi), unprotect_flash,
_verbose_level);
flash.erase_and_prog(offset, data, length);
@ -148,13 +148,32 @@ void Ice40::program(unsigned int offset, bool unprotect_flash)
post_flash_access();
}
bool Ice40::detect_flash()
{
/* prepare SPI access */
prepare_flash_access();
printInfo("Read Flash ", false);
try {
SPIFlash flash(reinterpret_cast<FlashInterface *>(_spi), false, _verbose_level);
flash.read_id();
flash.display_status_reg();
} catch (std::exception &e) {
printError("Fail");
printError(std::string(e.what()));
return false;
}
/* release SPI access / reload */
return post_flash_access();
}
bool Ice40::dumpFlash(uint32_t base_addr, uint32_t len)
{
/* prepare SPI access */
prepare_flash_access();
printInfo("Read Flash ", false);
try {
SPIFlash flash(reinterpret_cast<SPIInterface *>(_spi), false, _verbose_level);
SPIFlash flash(reinterpret_cast<FlashInterface *>(_spi), false, _verbose_level);
flash.reset();
flash.power_up();
flash.dump(_filename, base_addr, len);
@ -174,7 +193,7 @@ bool Ice40::protect_flash(uint32_t len)
prepare_flash_access();
/* acess */
try {
SPIFlash flash(reinterpret_cast<SPIInterface *>(_spi), false, _verbose_level);
SPIFlash flash(reinterpret_cast<FlashInterface *>(_spi), false, _verbose_level);
/* configure flash protection */
if (flash.enable_protection(len) == -1)
return false;
@ -194,7 +213,7 @@ bool Ice40::unprotect_flash()
prepare_flash_access();
/* acess */
try {
SPIFlash flash(reinterpret_cast<SPIInterface *>(_spi), false, _verbose_level);
SPIFlash flash(reinterpret_cast<FlashInterface *>(_spi), false, _verbose_level);
/* configure flash protection */
if (flash.disable_protection() == -1)
return false;
@ -214,7 +233,7 @@ bool Ice40::bulk_erase_flash()
prepare_flash_access();
/* acess */
try {
SPIFlash flash(reinterpret_cast<SPIInterface *>(_spi), false, _verbose_level);
SPIFlash flash(reinterpret_cast<FlashInterface *>(_spi), false, _verbose_level);
/* bulk erase flash */
if (flash.bulk_erase() == -1)
return false;

View File

@ -10,9 +10,9 @@
#include "device.hpp"
#include "ftdispi.hpp"
#include "spiInterface.hpp"
#include "flashInterface.hpp"
class Ice40: public Device, SPIInterface {
class Ice40: public Device, FlashInterface {
public:
Ice40(FtdiSpi *spi, const std::string &filename,
const std::string &file_type,
@ -24,9 +24,7 @@ class Ice40: public Device, SPIInterface {
void program(unsigned int offset, bool unprotect_flash) override;
bool program_cram(const uint8_t *data, uint32_t length);
bool dumpFlash(uint32_t base_addr, uint32_t len) override;
bool detect_flash() override {
return SPIInterface::detect_flash();
}
bool detect_flash() override;
bool protect_flash(uint32_t len) override;
bool unprotect_flash() override;
bool bulk_erase_flash() override;

View File

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

View File

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

View File

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

View File

@ -55,11 +55,10 @@
#ifdef ENABLE_USBBLASTER
#include "usbBlaster.hpp"
#endif
#ifdef ENABLE_XVC
#ifdef ENABLE_XVC_CLIENT
#include "xvc_client.hpp"
#endif
using namespace std;
#define DEBUG 0
@ -94,10 +93,10 @@ using namespace std;
*/
Jtag::Jtag(const cable_t &cable, const jtag_pins_conf_t *pin_conf,
const string &dev,
const string &serial, uint32_t clkHZ, int8_t verbose,
const string &ip_adr, int port,
const bool invert_read_edge, const string &firmware_path,
const std::string &dev,
const std::string &serial, uint32_t clkHZ, int8_t verbose,
const std::string &ip_adr, int port,
const bool invert_read_edge, const std::string &firmware_path,
const std::map<uint32_t, misc_device> &user_misc_devs):
_verbose(verbose > 1),
_state(RUN_TEST_IDLE),
@ -186,7 +185,7 @@ Jtag::Jtag(const cable_t &cable, const jtag_pins_conf_t *pin_conf,
throw std::exception();
#endif
case MODE_XVC_CLIENT:
#ifdef ENABLE_XVC
#ifdef ENABLE_XVC_CLIENT
_jtag = new XVC_client(ip_adr, port, clkHZ, verbose);
break;
#else
@ -344,7 +343,7 @@ int Jtag::device_select(unsigned index)
* after the selected one
*/
_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
* the first a serie of bypass must be
@ -361,7 +360,7 @@ int Jtag::device_select(unsigned index)
_ir_bits_before = 0;
for (unsigned i = device_index + 1; i < _devices_list.size(); ++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;
}
@ -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)
{
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 shiftIR(&tdi, NULL, irlen, end_state);

View File

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

View File

@ -17,9 +17,9 @@
#include "jedParser.hpp"
#include "feaparser.hpp"
#include "latticeBitParser.hpp"
#include "spiInterface.hpp"
#include "flashInterface.hpp"
class Lattice: public Device, SPIInterface {
class Lattice: public Device, FlashInterface {
public:
Lattice(Jtag *jtag, std::string filename, const std::string &file_type,
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,
uint32_t flash_area = 0);
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
*/
bool detect_flash() override {
return SPIInterface::detect_flash();
return FlashInterface::detect_flash();
}
/*!
* \brief protect SPI flash blocks
*/
bool protect_flash(uint32_t len) override {
return SPIInterface::protect_flash(len);
return FlashInterface::protect_flash(len);
}
/*!
* \brief protect SPI flash blocks
*/
bool unprotect_flash() override {
return SPIInterface::unprotect_flash();
return FlashInterface::unprotect_flash();
}
/*!
* \brief bulk erase SPI flash
*/
bool bulk_erase_flash() override {
return SPIInterface::bulk_erase_flash();
return FlashInterface::bulk_erase_flash();
}
/* spi interface */

View File

@ -7,11 +7,11 @@
#include <stdlib.h>
#include <algorithm>
#include <functional>
#include <charconv>
#include <cctype>
#include <iostream>
#include <locale>
#include <sstream>
#include <string_view>
#include <utility>
#include "display.hpp"
@ -19,9 +19,8 @@
#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):
ConfigBitstreamParser(filename, ConfigBitstreamParser::BIN_MODE, verbose),
_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 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 */
/* radiant .bit start with LSCC */
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());
return EXIT_FAILURE;
}
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 */
if ((uint8_t)_raw_data[currPos] != 0xff ||
(uint8_t)_raw_data[currPos + 1] != 0x00) {
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;
}
currPos+=2;
currPos += 2;
_endHeader = _raw_data.find(0xff, currPos);
if (_endHeader == string::npos) {
if (_endHeader == std::string::npos) {
printError("Error: preamble not found\n");
return EXIT_FAILURE;
}
/* .bit for MACHXO3D seems to have more 0xff before preamble key */
size_t pos = _raw_data.find(0xb3, _endHeader);
if (pos == string::npos) {
if (pos == std::string::npos) {
printError("Preamble key not found");
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
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");
return EXIT_FAILURE;
}
_endHeader = pos - 3; // align to 2 Dummy bits + 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 */
istringstream lineStream(_raw_data.substr(currPos, _endHeader - currPos - 1));
string buff;
while (std::getline(lineStream, buff, '\0')) {
pos = buff.find_first_of(':', 0);
if (pos != string::npos) {
string key(buff.substr(0, pos));
string val(buff.substr(pos+1, buff.size()));
int startPos = val.find_first_not_of(" ");
int endPos = val.find_last_not_of(" ")+1;
_hdr[key] = val.substr(startPos, endPos).c_str();
std::string_view lineStream(_raw_data.data() + currPos, _endHeader - currPos);
while (!lineStream.empty()) {
const size_t null_pos = lineStream.find('\0');
const std::string_view buff = lineStream.substr(0, null_pos);
pos = buff.find(':');
if (pos != std::string_view::npos) {
const std::string_view key = buff.substr(0, pos);
const std::string_view val = buff.substr(pos + 1);
const size_t startPos = val.find_first_not_of(' ');
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;
}
@ -94,11 +138,15 @@ int LatticeBitParser::parseHeader()
int LatticeBitParser::parse()
{
/* until 0xFFFFBDB3 0xFFFF */
if (parseHeader() < 0)
if (parseHeader() != EXIT_SUCCESS)
return EXIT_FAILURE;
/* check preamble */
uint32_t preamble = (*(uint32_t *)&_raw_data[_endHeader]);
if (_endHeader + 4 >= _raw_data.size()) {
printError("LatticeBitParser: truncated preamble");
return EXIT_FAILURE;
}
uint32_t preamble = (*(uint32_t *)&_raw_data[_endHeader + 1]);
//0xb3beffff is the preamble for encrypted bitstreams in Nexus fpgas
if ((preamble != 0xb3bdffff) && (preamble != 0xb3bfffff) && (preamble != 0xb3beffff)) {
printError("Error: missing preamble\n");
@ -117,18 +165,26 @@ int LatticeBitParser::parse()
printError("encrypted bitstream not supported for machXO2");
return EXIT_FAILURE;
}
string part = getHeaderVal("Part");
string subpart = part.substr(0, part.find_last_of("-"));
for (auto && fpga : fpga_list) {
std::map<std::string, std::string>::const_iterator part_it = _hdr.find("Part");
if (part_it == _hdr.end()) {
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")
continue;
string model = fpga.second.model;
const std::string_view model = fpga.second.model;
if (subpart.compare(0, model.size(), model) == 0) {
char __buf[10];
int __buf_valid_bytes;
__buf_valid_bytes = snprintf(__buf, 9, "%08x", fpga.first);
_hdr["idcode"] = string(__buf, __buf_valid_bytes);
_hdr["idcode"].resize(8, ' ');
_hdr["idcode"] = fmtIdcode(fpga.first);
break;
}
}
}
@ -138,28 +194,27 @@ int LatticeBitParser::parse()
/* According to FPGA-TN-02192-3.4
* the Lattice ECP3 must trasnmit at least 128 clock pulses before
* receiving the preamble.
* Here the header contains 16 Dummy bit + preamble so only
* 14bits 8x14= 112bits must be added as padding.
* Here the header contains 3x8 Dummy bit + preamble so only
* 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);
if (_is_ecp3) {
std::string tmp(14, 0xff);
std::move(tmp.begin(), tmp.end(), _bit_data.begin());
}
if (_is_ecp3)
std::fill_n(_bit_data.begin(), offset, uint8_t{0xff});
std::move(_raw_data.begin() + _endHeader, _raw_data.end(), _bit_data.begin() + offset);
_bit_length = _bit_data.size() * 8;
} else {
const uint32_t len = _raw_data.size() - _endHeader;
uint32_t max_len = 16;
for (uint32_t i = 0; i < len; i+=max_len) {
std::string tmp(16, 0xff);
/* each line must have 16B */
if (len < i + max_len)
max_len = len - i;
_endHeader++;
const size_t len = _raw_data.size() - _endHeader;
const size_t array_len = (len + 15) / 16;
_bit_array.reserve(array_len);
for (size_t i = 0; i < len; i += 16) {
const size_t max_len = std::min<size_t>(16, len - i);
_bit_array.emplace_back(16, '\xff');
std::string &tmp = _bit_array.back();
for (uint32_t pos = 0; pos < max_len; pos++)
tmp[pos] = reverseByte(_raw_data[i+pos+_endHeader]);
_bit_array.push_back(std::move(tmp));
tmp[pos] = static_cast<char>(reverseByte(
static_cast<uint8_t>(_raw_data[_endHeader + i + pos])));
}
_bit_length = _bit_array.size() * 16 * 8;
}
@ -182,52 +237,73 @@ int LatticeBitParser::parse()
bool LatticeBitParser::parseCfgData()
{
uint8_t *ptr;
size_t pos = _endHeader + 4; // drop 16 Dummy bits and preamble
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
uint32_t idcode;
char __buf[10];
int __buf_valid_bytes;
while (pos < _raw_data.size()) {
uint8_t cmd = (uint8_t) _raw_data[pos++];
while (pos < raw_size) {
uint8_t cmd = raw[pos++];
switch (cmd) {
case BYPASS:
break;
case LSC_RESET_CRC:
if (pos + 3 > raw_size) {
printError("LatticeBitParser: truncated bitstream");
return false;
}
pos += 3;
break;
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) |
(((uint32_t)reverseByte(ptr[5])) << 16) |
(((uint32_t)reverseByte(ptr[4])) << 8) |
(((uint32_t)reverseByte(ptr[3])) << 0);
__buf_valid_bytes = snprintf(__buf, 9, "%08x", idcode);
_hdr["idcode"] = string(__buf, __buf_valid_bytes);
_hdr["idcode"].resize(8, ' ');
_hdr["idcode"] = fmtIdcode(idcode);
pos += 7;
if (!_is_machXO2)
return true;
break;
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) |
(((uint32_t)ptr[4]) << 16) |
(((uint32_t)ptr[5]) << 8) |
(((uint32_t)ptr[6]) << 0);
__buf_valid_bytes = snprintf(__buf, 9, "%08x", idcode);
_hdr["idcode"] = string(__buf, __buf_valid_bytes);
_hdr["idcode"].resize(8, ' ');
_hdr["idcode"] = fmtIdcode(idcode);
pos += 7;
if (!_is_machXO2)
return true;
break;
case LSC_WRITE_COMP_DIC:
if (pos + 11 > raw_size) {
printError("LatticeBitParser: truncated bitstream");
return false;
}
pos += 11;
break;
case LSC_PROG_CNTRL0:
case LSC_PROG_CNTRL0:
if (pos + 7 > raw_size) {
printError("LatticeBitParser: truncated bitstream");
return false;
}
pos += 7;
break;
case LSC_INIT_ADDRESS:
if (pos + 3 > raw_size) {
printError("LatticeBitParser: truncated bitstream");
return false;
}
pos += 3;
break;
case LSC_PROG_INCR_CMP:
@ -238,6 +314,10 @@ bool LatticeBitParser::parseCfgData()
return false;
case LSC_SPI_MODE: // optional: 0x79 + mode (fast-read:0x49,
// dual-spi:0x51, qspi:0x59) + 2 x 0x00
if (pos + 3 > raw_size) {
printError("LatticeBitParser: truncated bitstream");
return false;
}
pos += 3;
break;
default:

View File

@ -24,11 +24,17 @@ class LatticeBitParser: public ConfigBitstreamParser {
* \brief return configuration data with structure similar to jedec
* \return configuration data
*/
std::vector<std::string> getDataArray() {return _bit_array;}
std::vector<std::string> &getDataArray() {return _bit_array;}
private:
int parseHeader();
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;
bool _is_machXO2;
bool _is_ecp3;

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -3,15 +3,17 @@
* Copyright (C) 2019 Gwenhael Goavec-Merou <gwenhael.goavec-merou@trabucayre.com>
*/
#include <algorithm>
#include <array>
#include <sstream>
#include <charconv>
#include <limits>
#include <string>
#include <string_view>
#include "configBitstreamParser.hpp"
#include "display.hpp"
#include "mcsParser.hpp"
using namespace std;
/* line format
* :LLAAAATTHH...HHCC
@ -34,49 +36,105 @@ using namespace std;
#define TYPE_BASE 7
#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,
verbose),
_base_addr(0), _reverseOrder(reverseOrder)
_base_addr(0), _reverseOrder(reverseOrder), _records()
{}
int McsParser::parse()
{
string str;
istringstream lineStream(_raw_data);
std::string_view data(_raw_data);
FlashDataSection *rec = nullptr;
bool must_stop = false;
size_t flash_size = 0;
std::array<uint8_t, 255> tmp_buf{}; // max size for one data line
while (std::getline(lineStream, str, '\n') && !must_stop) {
uint8_t sum = 0, tmp, byteLen, type, checksum;
uint16_t addr;
uint32_t loc_addr;
while (!data.empty() && !must_stop) {
const size_t nl_pos = data.find('\n');
std::string_view str = data.substr(0,
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 (str.back() == '\r')
str.pop_back();
if (!str.empty() && str.back() == '\r')
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] != ':') {
printError("Error: a line must start with ':'");
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 */
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 */
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 */
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 */
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);
switch (type) {
case 0: { /* Data + 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:
* Create if null
@ -87,10 +145,14 @@ int McsParser::parse()
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) {
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;
sum += tmp;
}
@ -101,7 +163,16 @@ int McsParser::parse()
must_stop = true;
break;
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);
sum += (loc_addr & 0xff) + ((loc_addr >> 8) & 0xff);
break;
@ -116,17 +187,30 @@ int McsParser::parse()
}
}
const uint32_t nbRecord = getRecordCount();
const uint32_t record_base = getRecordBaseAddr(nbRecord - 1);
const uint32_t record_length = getRecordLength(nbRecord - 1);
const uint32_t flash_size = record_base + record_length;
const size_t nbRecord = getRecordCount();
if (nbRecord == 0) {
printError("No record found: is empty file?");
return EXIT_FAILURE;
}
_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;
for (uint32_t i = 0; i < nbRecord; i++) {
const uint32_t record_base = getRecordBaseAddr(i);
const std::vector<uint8_t> rec = getRecordData(i);
std::copy(rec.begin(), rec.end(), _bit_data.begin() + record_base);
for (const FlashDataSection& section : _records) {
const size_t start = section.getStartAddr();
const size_t length = section.getLength();
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;

View File

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

View File

@ -67,6 +67,7 @@ void POFParser::displayHeader()
int POFParser::parse()
{
const uint32_t file_size = static_cast<uint32_t>(_file_size);
uint8_t *ptr = (uint8_t *)_raw_data.data();
uint32_t pos = 0;
@ -77,6 +78,10 @@ int POFParser::parse()
pos += 4;
/* unknown */
if (_verbose) {
if ((pos + 4) > file_size) {
printError("POFParser: Can't read first section");
return -1;
}
uint32_t first_section = ARRAY2INT32(ptr);
printf("first section: %08x %4u\n", first_section, first_section);
}
@ -84,18 +89,39 @@ int POFParser::parse()
pos += 4;
/* number of packets */
if (_verbose) {
if ((pos + 4) > file_size) {
printError("POFParser: Can't read first section");
return -1;
}
uint32_t num_packets = ARRAY2INT32(ptr);
printf("number of packets: %08x %4u\n", num_packets, num_packets);
}
pos += 4;
/* 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]));
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]));
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 */
@ -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);
break;
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])));
break;
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
if (_verbose) {
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 val1 = ARRAY2INT32((&content.c_str()[4]));
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
_hdr["usercode"] = std::to_string(ARRAY2INT32((&_raw_data.data()[pos+size-4])));
if (_verbose) {
if (size < 12) {
printf("POFParser: Can't display flag 0x13 area");
return -1;
}
t = _raw_data.substr(pos, size);
for (size_t i = 0; i < t.size(); i++)
printf("%02x ", static_cast<uint8_t>(t[i]));

View File

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

View File

@ -11,13 +11,21 @@
#include "progressBar.hpp"
#include "display.hpp"
bool ProgressBar::_force_terminal_mode = false;
ProgressBar::ProgressBar(const std::string &mess, int maxValue,
int progressLen, bool quiet): _mess(mess), _maxValue(maxValue),
_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)
{
if (_quiet) {

View File

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

View File

@ -10,9 +10,8 @@
#include "display.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,
false), _reverseOrder(reverseOrder)
{}

View File

@ -26,7 +26,6 @@
#include "display.hpp"
using namespace std;
#define TCK_OFFSET 2
#define TMS_OFFSET 1
@ -170,7 +169,7 @@ int RemoteBitbang_client::setClkFreq(uint32_t 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;
addr.sin_family = AF_INET;

View File

@ -16,7 +16,7 @@
#include "display.hpp"
#include "spiFlash.hpp"
#include "spiFlashdb.hpp"
#include "spiInterface.hpp"
#include "flashInterface.hpp"
/* read/write status register : 0B addr + 0 dummy */
#define FLASH_WRSR 0x01
@ -84,7 +84,7 @@
/* Global Block Protection unlock */
#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),
_flash_model(NULL), _unprotect(unprotect), _must_relock(false),
_status(0)

View File

@ -9,7 +9,7 @@
#include <map>
#include <string>
#include "spiInterface.hpp"
#include "flashInterface.hpp"
#include "spiFlashdb.hpp"
/* Flash memory section record
@ -40,7 +40,7 @@ class FlashDataSection {
class SPIFlash {
public:
SPIFlash(SPIInterface *spi, bool unprotect, int8_t verbose);
SPIFlash(FlashInterface *spi, bool unprotect, int8_t verbose);
/* power */
virtual void power_up();
virtual void power_down();
@ -173,7 +173,7 @@ class SPIFlash {
*/
uint8_t len_to_bp(uint32_t len);
SPIInterface *_spi;
FlashInterface *_spi;
int8_t _verbose;
uint32_t _jedec_id; /**< CHIP ID */
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,
.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, {
.manufacturer = "micron",
.model = "MT25QU01G",
@ -585,6 +601,23 @@ static std::map <uint32_t, flash_t> flash_list = {
.quad_mask = (1 << 6),
.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, {
/* https://www.macronix.com/Lists/Datasheet/Attachments/8868/MX25R6435F,%20Wide%20Range,%2064Mb,%20v1.6.pdf */
.manufacturer = "Macronix",

View File

@ -18,12 +18,11 @@
#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;
istringstream tokenStream(str);
std::string token;
std::istringstream tokenStream(str);
while (getline(tokenStream, token, ' '))
vparse.push_back(token);
}
@ -37,7 +36,7 @@ void SVF_jtag::clear_XYR(svf_XYR &t)
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)
{
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
* 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)
cout << endl;
std::cout << std::endl;
int mode = 0;
string s;
string full_line;
std::string s;
std::string full_line;
full_line.reserve(1276);
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);
for (size_t i = 0; i < byte_len; 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--) {
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[] maskbuf;
throw exception();
throw std::exception();
}
}
delete[] tdobuf;
@ -187,7 +186,7 @@ void SVF_jtag::parse_XYR(vector<string> const &vstr, svf_XYR &t)
}
/* 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;
int nb_iter = 0;
@ -238,105 +237,105 @@ void SVF_jtag::parse_runtest(vector<string> const &vstr)
_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")) {
_freq_hz = atof(vstr[1].c_str());
if (_verbose) {
cout << "frequency value " << vstr[1] << " unit " << vstr[2];
cout << _freq_hz << endl;
std::cout << "frequency value " << vstr[1] << " unit " << vstr[2];
std::cout << _freq_hz << std::endl;
}
_jtag->setClkFreq(_freq_hz);
} 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")) {
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]];
} 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]];
} 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]]);
} else if (!vstr[0].compare("RUNTEST")) {
parse_runtest(vstr);
} else if (!vstr[0].compare("HIR")) {
parse_XYR(vstr, hir);
if (hir.len > 0) {
cerr << "HIR length supported is only 0 " << endl;
std::cerr << "HIR length supported is only 0 " << std::endl;
}
if (_verbose) {
cout << "HIR" << endl;
cout << "\tlen : " << hir.len << endl;
cout << "\ttdo : " << hir.tdo.size()*4 << endl;
cout << "\ttdi : " << hir.tdi.size()*4 << endl;
cout << "\tmask : " << hir.mask.size()*4 << endl;
cout << "\tsmask : " << hir.smask.size()*4 << endl;
std::cout << "HIR" << std::endl;
std::cout << "\tlen : " << hir.len << std::endl;
std::cout << "\ttdo : " << hir.tdo.size()*4 << std::endl;
std::cout << "\ttdi : " << hir.tdi.size()*4 << std::endl;
std::cout << "\tmask : " << hir.mask.size()*4 << std::endl;
std::cout << "\tsmask : " << hir.smask.size()*4 << std::endl;
}
} else if (!vstr[0].compare("HDR")) {
parse_XYR(vstr, hdr);
if (hdr.len > 0) {
cerr << "HDR length supported is only 0" << endl;
std::cerr << "HDR length supported is only 0" << std::endl;
}
if (_verbose) {
cout << "HDR" << endl;
cout << "\tlen : " << hdr.len << endl;
cout << "\ttdo : " << hdr.tdo.size()*4 << endl;
cout << "\ttdi : " << hdr.tdi.size()*4 << endl;
cout << "\tmask : " << hdr.mask.size()*4 << endl;
cout << "\tsmask : " << hdr.smask.size()*4 << endl;
std::cout << "HDR" << std::endl;
std::cout << "\tlen : " << hdr.len << std::endl;
std::cout << "\ttdo : " << hdr.tdo.size()*4 << std::endl;
std::cout << "\ttdi : " << hdr.tdi.size()*4 << std::endl;
std::cout << "\tmask : " << hdr.mask.size()*4 << std::endl;
std::cout << "\tsmask : " << hdr.smask.size()*4 << std::endl;
}
} else if (!vstr[0].compare("SIR")) {
parse_XYR(vstr, sir);
if (_verbose) {
for (auto &&t : vstr)
cout << t << " ";
cout << endl;
cout << "\tlen : " << sir.len << endl;
cout << "\ttdo : " << sir.tdo.size()*4 << endl;
cout << "\ttdi : " << sir.tdi.size()*4 << endl;
cout << "\tmask : " << sir.mask.size()*4 << endl;
cout << "\tsmask : " << sir.smask.size()*4 << endl;
std::cout << t << " ";
std::cout << std::endl;
std::cout << "\tlen : " << sir.len << std::endl;
std::cout << "\ttdo : " << sir.tdo.size()*4 << std::endl;
std::cout << "\ttdi : " << sir.tdi.size()*4 << std::endl;
std::cout << "\tmask : " << sir.mask.size()*4 << std::endl;
std::cout << "\tsmask : " << sir.smask.size()*4 << std::endl;
}
} else if (!vstr[0].compare("SDR")) {
parse_XYR(vstr, sdr);
if (_verbose) {
cout << "SDR" << endl;
cout << "\tlen : " << sdr.len << endl;
cout << "\ttdo : " << sdr.tdo.size()*4 << endl;
cout << "\ttdi : " << sdr.tdi.size()*4 << endl;
cout << "\tmask : " << sdr.mask.size()*4 << endl;
cout << "\tsmask : " << sdr.smask.size()*4 << endl;
std::cout << "SDR" << std::endl;
std::cout << "\tlen : " << sdr.len << std::endl;
std::cout << "\ttdo : " << sdr.tdo.size()*4 << std::endl;
std::cout << "\ttdi : " << sdr.tdi.size()*4 << std::endl;
std::cout << "\tmask : " << sdr.mask.size()*4 << std::endl;
std::cout << "\tsmask : " << sdr.smask.size()*4 << std::endl;
}
} else if (!vstr[0].compare("TDR")) {
parse_XYR(vstr, tdr);
if (tdr.len > 0) {
cerr << "TDR length supported is only 0" << endl;
std::cerr << "TDR length supported is only 0" << std::endl;
}
if (_verbose) {
cout << "TDR" << endl;
cout << "\tlen : " << tdr.len << endl;
cout << "\ttdo : " << tdr.tdo.size() * 4 << endl;
cout << "\ttdi : " << tdr.tdi.size() * 4 << endl;
cout << "\tmask : " << tdr.mask.size() * 4 << endl;
cout << "\tsmask : " << tdr.smask.size() * 4 << endl;
std::cout << "TDR" << std::endl;
std::cout << "\tlen : " << tdr.len << std::endl;
std::cout << "\ttdo : " << tdr.tdo.size() * 4 << std::endl;
std::cout << "\ttdi : " << tdr.tdi.size() * 4 << std::endl;
std::cout << "\tmask : " << tdr.mask.size() * 4 << std::endl;
std::cout << "\tsmask : " << tdr.smask.size() * 4 << std::endl;
}
} else if (!vstr[0].compare("TIR")) {
parse_XYR(vstr, tir);
if (tir.len > 0) {
cerr << "TIR length supported is only 0" << endl;
std::cerr << "TIR length supported is only 0" << std::endl;
}
if (_verbose) {
cout << "TIR" << endl;
cout << "\tlen : " << tir.len << endl;
cout << "\ttdo : " << tir.tdo.size() * 4 << endl;
cout << "\ttdi : " << tir.tdi.size() * 4 << endl;
cout << "\tmask : " << tir.mask.size() * 4 << endl;
cout << "\tsmask : " << tir.smask.size() * 4 << endl;
std::cout << "TIR" << std::endl;
std::cout << "\tlen : " << tir.len << std::endl;
std::cout << "\ttdo : " << tir.tdo.size() * 4 << std::endl;
std::cout << "\ttdi : " << tir.tdi.size() * 4 << std::endl;
std::cout << "\tmask : " << tir.mask.size() * 4 << std::endl;
std::cout << "\tsmask : " << tir.smask.size() * 4 << std::endl;
}
} else {
cout << "error: unhandled instruction " << vstr[0] << endl;
throw exception();
std::cout << "error: unhandled instruction " << vstr[0] << std::endl;
throw std::exception();
}
}
@ -358,16 +357,16 @@ bool is_space(char x) {
* concat continuous lines
* and pass instruction to handle_instruction
*/
void SVF_jtag::parse(string filename)
void SVF_jtag::parse(std::string filename)
{
string str;
vector<string> vstr;
std::string str;
std::vector<std::string> vstr;
bool is_complete;
ifstream fs;
std::ifstream fs;
fs.open(filename);
if (!fs.is_open()) {
cerr << "Error opening svf file " << filename << endl;
std::cerr << "Error opening svf file " << filename << std::endl;
return;
}
unsigned int lineno = 0;
@ -391,8 +390,8 @@ void SVF_jtag::parse(string filename)
if (vstr[0].compare("HDR") && vstr[0].compare("HIR")
&& vstr[0].compare("SDR") && vstr[0].compare("SIR")) {
for (auto &&word : vstr)
cout << word << " ";
cout << endl;
std::cout << word << " ";
std::cout << std::endl;
}
}
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;
}
cout << "end of SVF file" << endl;
std::cout << "end of SVF file" << std::endl;
}

View File

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

View File

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

View File

@ -31,7 +31,7 @@
#endif
#include "rawParser.hpp"
#include "spiFlash.hpp"
#include "spiInterface.hpp"
#include "flashInterface.hpp"
#include "xilinx.hpp"
#include "xilinxMapParser.hpp"
@ -279,7 +279,7 @@ Xilinx::Xilinx(Jtag *jtag, const std::string &filename,
bool verify, int8_t verbose,
bool skip_load_bridge, bool skip_reset, bool read_dna, bool read_xadc):
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),
_device_package(device_package), _spiOverJtagPath(spiOverJtagPath),
_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");
if (extention == "mcs") {
McsParser *parser = (McsParser *)bit;
SPIInterface::write(parser->getRecords(), unprotect_flash, true);
FlashInterface::write(parser->getRecords(), unprotect_flash, true);
} else {
const uint8_t *data = bit->getData();
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) {
select_flash_chip(PRIMARY_FLASH);
SPIInterface::set_filename(_filename);
if (!SPIInterface::dump(base_addr, len))
FlashInterface::set_filename(_filename);
if (!FlashInterface::dump(base_addr, len))
return false;
}
if (_flash_chips & SECONDARY_FLASH) {
select_flash_chip(SECONDARY_FLASH);
SPIInterface::set_filename(_secondary_filename);
if (!SPIInterface::dump(base_addr, len))
FlashInterface::set_filename(_secondary_filename);
if (!FlashInterface::dump(base_addr, len))
return false;
}
@ -1279,12 +1279,12 @@ bool Xilinx::detect_flash()
{
if (_flash_chips & PRIMARY_FLASH) {
select_flash_chip(PRIMARY_FLASH);
if (!SPIInterface::detect_flash())
if (!FlashInterface::detect_flash())
return false;
}
if (_flash_chips & SECONDARY_FLASH) {
select_flash_chip(SECONDARY_FLASH);
if (!SPIInterface::detect_flash())
if (!FlashInterface::detect_flash())
return false;
}
return true;
@ -1294,12 +1294,12 @@ bool Xilinx::protect_flash(uint32_t len)
{
if (_flash_chips & PRIMARY_FLASH) {
select_flash_chip(PRIMARY_FLASH);
if (!SPIInterface::protect_flash(len))
if (!FlashInterface::protect_flash(len))
return false;
}
if (_flash_chips & SECONDARY_FLASH) {
select_flash_chip(SECONDARY_FLASH);
if (!SPIInterface::protect_flash(len))
if (!FlashInterface::protect_flash(len))
return false;
}
return true;
@ -1309,12 +1309,12 @@ bool Xilinx::unprotect_flash()
{
if (_flash_chips & PRIMARY_FLASH) {
select_flash_chip(PRIMARY_FLASH);
if (!SPIInterface::unprotect_flash())
if (!FlashInterface::unprotect_flash())
return false;
}
if (_flash_chips & SECONDARY_FLASH) {
select_flash_chip(SECONDARY_FLASH);
if (!SPIInterface::unprotect_flash())
if (!FlashInterface::unprotect_flash())
return false;
}
return true;
@ -1324,12 +1324,12 @@ bool Xilinx::set_quad_bit(bool set_quad)
{
if (_flash_chips & PRIMARY_FLASH) {
select_flash_chip(PRIMARY_FLASH);
if (!SPIInterface::set_quad_bit(set_quad))
if (!FlashInterface::set_quad_bit(set_quad))
return false;
}
if (_flash_chips & SECONDARY_FLASH) {
select_flash_chip(SECONDARY_FLASH);
if (!SPIInterface::set_quad_bit(set_quad))
if (!FlashInterface::set_quad_bit(set_quad))
return false;
}
return true;
@ -1339,12 +1339,12 @@ bool Xilinx::bulk_erase_flash()
{
if (_flash_chips & PRIMARY_FLASH) {
select_flash_chip(PRIMARY_FLASH);
if (!SPIInterface::bulk_erase_flash())
if (!FlashInterface::bulk_erase_flash())
return false;
}
if (_flash_chips & SECONDARY_FLASH) {
select_flash_chip(SECONDARY_FLASH);
if (!SPIInterface::bulk_erase_flash())
if (!FlashInterface::bulk_erase_flash())
return false;
}
return true;

View File

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

View File

@ -14,9 +14,8 @@
#include "jedParser.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,
JedParser *jed, const uint32_t usercode,
bool verbose): ConfigBitstreamParser(filename,
@ -61,7 +60,7 @@ int XilinxMapParser::parse()
} else {
empty = false; // current line is not fully empty
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)
map_val = std::stoi(cnt, nullptr, 10);
} else { // information (done, spare, user, ...)

View File

@ -25,7 +25,6 @@
#include "display.hpp"
using namespace std;
XVC_client::XVC_client(const std::string &ip_addr, int port,
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");
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::vector<std::string> toto(start, end);
@ -223,7 +222,7 @@ int XVC_client::setClkFreq(uint32_t 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;
addr.sin_family = AF_INET;
@ -262,25 +261,21 @@ int sendall(int sock, const void* raw, size_t cnt, int flags)
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,
uint8_t *rx, uint32_t rx_size)
{
ssize_t len = tx_size;
std::vector<uint8_t> buffer(instr.size() + ((tx) ? tx_size : 0));
memcpy(buffer.data(), instr.c_str(), instr.size());
if (tx)
memcpy(buffer.data() + instr.size(), tx, tx_size);
/* 1. instruction */
if (sendall(_sock, instr.c_str(), instr.size(), 0) == -1) {
printError("Send instruction failed");
if (sendall(_sock, buffer.data(), buffer.size(), 0) == -1) {
printError("Send failed");
return -1;
}
if (tx) {
if (sendall(_sock, tx, tx_size, 0) == -1) {
printError("Send error");
return -1;
}
}
if (rx) {
len = recv(_sock, rx, rx_size, 0);
if (len < 0) {

View File

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

View File

@ -17,14 +17,12 @@
#include "jtag.hpp"
using namespace std;
class XVC_server {
public:
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,
const string &ip_adr,
const bool invert_read_edge, const string &firmware_path);
std::string dev, const std::string &serial, uint32_t clkHZ, int8_t verbose,
const std::string &ip_adr,
const bool invert_read_edge, const std::string &firmware_path);
~XVC_server();
/*!