From 28e54f83bbd6b882b0c589b3bce4cf61a1b84217 Mon Sep 17 00:00:00 2001 From: Arek Makarenko Date: Sat, 26 Oct 2024 21:02:40 +0100 Subject: [PATCH 1/9] New cable type gpiod_creator and gpiod_voice based on libgpiod. --- CMakeLists.txt | 12 ++-- cabledb.cpp | 6 ++ cabledb.h | 4 +- cablelist.txt | 2 + iogpiodpi.cpp | 153 ++++++++++++++++++++++++++++++++++++++++ iogpiodpi.h | 33 +++++++++ iogpiomatrixcreator.cpp | 7 ++ iogpiomatrixcreator.h | 12 ++++ iogpiomatrixvoice.cpp | 6 ++ iogpiomatrixvoice.h | 12 ++++ utilities.cpp | 16 +++++ 11 files changed, 257 insertions(+), 6 deletions(-) create mode 100644 iogpiodpi.cpp create mode 100644 iogpiodpi.h create mode 100644 iogpiomatrixcreator.cpp create mode 100644 iogpiomatrixcreator.h create mode 100644 iogpiomatrixvoice.cpp create mode 100644 iogpiomatrixvoice.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 96e410d..259f310 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -137,7 +137,7 @@ if(USE_WIRINGPI) add_definitions( -DUSE_WIRINGPI ) endif(USE_WIRINGPI) -add_library(xc3sproglib STATIC sysfs.cpp sysfscreator.cpp sysfsvoice.cpp ioftdi.cpp +add_library(xc3sproglib STATIC iogpiomatrixcreator.cpp iogpiomatrixvoice.cpp iogpiodpi.cpp sysfs.cpp sysfscreator.cpp sysfsvoice.cpp ioftdi.cpp iofx2.cpp devicedb.cpp jtag.cpp jedecfile.cpp bitfile.cpp iobase.cpp progalgxc95x.cpp utilities.cpp progalgxcf.cpp progalgxcfp.cpp progalgxc3s.cpp @@ -150,18 +150,20 @@ if(USE_WIRINGPI) set(LIBS ${LIBS} wiringPiDev wiringPi) endif(USE_WIRINGPI) +set(GPIO_LIBS ${GPIO_LIBS} gpiod) + add_executable(xc2c_warp xc2c_warp.cpp) -target_link_libraries(xc2c_warp xc3sproglib ${CONDITIONAL_LIBS}) +target_link_libraries(xc2c_warp xc3sproglib ${CONDITIONAL_LIBS} ${GPIO_LIBS}) add_executable(detectchain detectchain.cpp cables.h devices.h) -target_link_libraries(detectchain xc3sproglib ${LIBFTDI_LIBRARIES} ${LIBFTD2XX_LIBRARIES} ${CONDITIONAL_LIBS} ${LIBS} ) +target_link_libraries(detectchain xc3sproglib ${LIBFTDI_LIBRARIES} ${LIBFTD2XX_LIBRARIES} ${CONDITIONAL_LIBS} ${LIBS} ${GPIO_LIBS}) add_executable(xc3sprog xc3sprog.cpp javr.cpp srecfile.cpp progalgavr.cpp devices.h) -target_link_libraries(xc3sprog xc3sproglib ${LIBFTDI_LIBRARIES} ${LIBFTD2XX_LIBRARIES} ${CONDITIONAL_LIBS} ${LIBS} ) +target_link_libraries(xc3sprog xc3sproglib ${LIBFTDI_LIBRARIES} ${LIBFTD2XX_LIBRARIES} ${CONDITIONAL_LIBS} ${LIBS} ${GPIO_LIBS}) add_executable(readdna readdna.cpp devices.h) -target_link_libraries(readdna xc3sproglib ${LIBFTDI_LIBRARIES} ${LIBFTD2XX_LIBRARIES} ${CONDITIONAL_LIBS} ${LIBS} ) +target_link_libraries(readdna xc3sproglib ${LIBFTDI_LIBRARIES} ${LIBFTD2XX_LIBRARIES} ${CONDITIONAL_LIBS} ${LIBS} ${GPIO_LIBS}) diff --git a/cabledb.cpp b/cabledb.cpp index bc98fe5..7e7e959 100644 --- a/cabledb.cpp +++ b/cabledb.cpp @@ -163,6 +163,10 @@ CABLES_TYPES CableDB::getCableType(const char *given_name) return CABLE_MATRIX_CREATOR; if (strcasecmp(given_name, "matrix_voice") == 0) return CABLE_MATRIX_VOICE; + if (strcasecmp(given_name, "gpiod_creator") == 0) + return CABLE_GPIOD_CREATOR; + if (strcasecmp(given_name, "gpiod_voice") == 0) + return CABLE_GPIOD_VOICE; return CABLE_UNKNOWN; } @@ -179,6 +183,8 @@ const char *CableDB::getCableName(const CABLES_TYPES type ) case CABLE_MATRIX_VOICE: return "matrix_voice"; case CABLE_SYSFS_GPIO_CREATOR: return "sysfsgpio_creator"; case CABLE_SYSFS_GPIO_VOICE: return "sysfsgpio_voice"; + case CABLE_GPIOD_CREATOR: return "gpiod_creator"; + case CABLE_GPIOD_VOICE: return "gpiod_voice"; case CABLE_NONE: return "none"; case CABLE_UNKNOWN: return "unknown"; } diff --git a/cabledb.h b/cabledb.h index 312d885..1dce3f7 100644 --- a/cabledb.h +++ b/cabledb.h @@ -34,7 +34,9 @@ enum CABLES_TYPES CABLE_SYSFS_GPIO_CREATOR, CABLE_SYSFS_GPIO_VOICE, CABLE_MATRIX_CREATOR, - CABLE_MATRIX_VOICE + CABLE_MATRIX_VOICE, + CABLE_GPIOD_CREATOR, + CABLE_GPIOD_VOICE }; struct cable_t diff --git a/cablelist.txt b/cablelist.txt index 6408e3b..d0b1d5e 100644 --- a/cablelist.txt +++ b/cablelist.txt @@ -47,4 +47,6 @@ sysfsgpio_creator sysfsgpio_creator 0 NULL sysfsgpio_voice sysfsgpio_voice 0 NULL matrix_creator matrix_creator 0 NULL matrix_voice matrix_voice 0 NULL +gpiod_creator gpiod_creator 0 NULL +gpiod_voice gpiod_voice 0 NULL mimas_a7 ftdi 15000000 0x2A19:0x1009::2:0x00:0x4B:0x00:0x00 diff --git a/iogpiodpi.cpp b/iogpiodpi.cpp new file mode 100644 index 0000000..84b248f --- /dev/null +++ b/iogpiodpi.cpp @@ -0,0 +1,153 @@ +#include +#include + + +IOGPIODPi::IOGPIODPi(int tms, int tck, int tdi, int tdo) + : TMSPin(tms), TCKPin(tck), TDIPin(tdi), TDOPin(tdo) +{ + chip = gpiod_chip_open_by_name("gpiochip0"); + + if (!chip) { + perror("Open chip failed"); + } + + TMSline = gpiod_chip_get_line(chip, TMSPin); + TCKline = gpiod_chip_get_line(chip, TCKPin); + TDIline = gpiod_chip_get_line(chip, TDIPin); + TDOline = gpiod_chip_get_line(chip, TDOPin); + + if (!TMSline) { + perror("TMSline line config failed"); + gpiod_chip_close(chip); + } + + if (!TCKline) { + perror("TCKline line config failed"); + gpiod_chip_close(chip); + } + + if (!TDIline) { + perror("TDIline line config failed"); + gpiod_chip_close(chip); + } + + if (!TDOline) { + perror("TDOline line config failed"); + gpiod_chip_close(chip); + } + + int ret; + + ret = gpiod_line_request_output(TMSline, "Consumer", 0); + if (ret < 0) { + perror("Request TMSline as output failed"); + gpiod_line_release(TMSline); + gpiod_chip_close(chip); + } + + ret = gpiod_line_request_output(TCKline, "Consumer", 0); + if (ret < 0) { + perror("Request TCKline as output failed"); + gpiod_line_release(TCKline); + gpiod_chip_close(chip); + } + + ret = gpiod_line_request_output(TDIline, "Consumer", 0); + if (ret < 0) { + perror("Request TDIline as output failed"); + gpiod_line_release(TDIline); + gpiod_chip_close(chip); + } + + ret = gpiod_line_request_input(TDOline, "Consumer"); + if (ret < 0) { + perror("Request TDOline as input failed"); + gpiod_line_release(TDOline); + gpiod_chip_close(chip); + } + +} + +IOGPIODPi::~IOGPIODPi() +{ + gpiod_line_release(TMSline); + gpiod_line_release(TCKline); + gpiod_line_release(TDIline); + gpiod_line_release(TDOline); + gpiod_chip_close(chip); +} + +void IOGPIODPi::txrx_block(const unsigned char *tdi, unsigned char *tdo, int length, bool last) +{ + + // std::cerr << "txrx_block" << std::endl; + int i=0; + int j=0; + unsigned char tdo_byte=0; + unsigned char tdi_byte; + if (tdi) + tdi_byte = tdi[j]; + + while(i>1; + i++; + if((i%8)==0){ // Next byte + if(tdo) + tdo[j]=tdo_byte; // Save the TDO byte + tdo_byte=0; + j++; + if (tdi) + tdi_byte=tdi[j]; // Get the next TDI byte + } + }; + tdo_byte=tdo_byte+(txrx(last, (tdi_byte&1)==1)<<(i%8)); + if(tdo) + tdo[j]=tdo_byte; + + gpiod_line_set_value(TCKline, 0); + return; +} + +void IOGPIODPi::tx_tms(unsigned char *pat, int length, int force) +{ + int i; + unsigned char tms; + for (i = 0; i < length; i++) + { + if ((i & 0x7) == 0) + tms = pat[i>>3]; + tx((tms & 0x01), true); + tms = tms >> 1; + } + + gpiod_line_set_value(TCKline, 0); +} + +void IOGPIODPi::tx(bool tms, bool tdi) +{ + gpiod_line_set_value(TCKline, 0); + + if(tdi) + gpiod_line_set_value(TDIline, 1); + else + gpiod_line_set_value(TDIline, 0); + + if(tms) + gpiod_line_set_value(TMSline, 1); + else + gpiod_line_set_value(TMSline, 0); + + gpiod_line_set_value(TCKline, 1); +} + + +bool IOGPIODPi::txrx(bool tms, bool tdi) +{ + + // std::cerr << "txrx" << gpiod_line_get_value(TDOline) << std::endl; + tx(tms, tdi); + return gpiod_line_get_value(TDOline); + // return digitalRead(TDOPin); +} diff --git a/iogpiodpi.h b/iogpiodpi.h new file mode 100644 index 0000000..64e04e4 --- /dev/null +++ b/iogpiodpi.h @@ -0,0 +1,33 @@ +#ifndef __IO_GPIOD_PI__ +#define __IO_GPIOD_PI__ + +#include "iobase.h" +#include + +class IOGPIODPi : public IOBase +{ + public: + IOGPIODPi(int tms, int tck, int tdi, int tdo); + virtual ~IOGPIODPi(); + + protected: + void tx(bool tms, bool tdi); + bool txrx(bool tms, bool tdi); + + void txrx_block(const unsigned char *tdi, unsigned char *tdo, int length, bool last); + void tx_tms(unsigned char *pat, int length, int force); + + int TMSPin; + int TCKPin; + int TDIPin; + int TDOPin; + + private: + struct gpiod_chip *chip; + struct gpiod_line *TMSline; + struct gpiod_line *TCKline; + struct gpiod_line *TDIline; + struct gpiod_line *TDOline; +}; + +#endif \ No newline at end of file diff --git a/iogpiomatrixcreator.cpp b/iogpiomatrixcreator.cpp new file mode 100644 index 0000000..ef2c3c3 --- /dev/null +++ b/iogpiomatrixcreator.cpp @@ -0,0 +1,7 @@ +#include "iogpiomatrixcreator.h" + +IOGPIOMatrixCreator::IOGPIOMatrixCreator() + : IOGPIODPi(4, 17, 22, 27) +{ +} + diff --git a/iogpiomatrixcreator.h b/iogpiomatrixcreator.h new file mode 100644 index 0000000..5653f53 --- /dev/null +++ b/iogpiomatrixcreator.h @@ -0,0 +1,12 @@ +#ifndef __IO_GPIO_MATRIX_CREATOR__ +#define __IO_GPIO_MATRIX_CREATOR__ + +#include "iogpiodpi.h" + +class IOGPIOMatrixCreator : public IOGPIODPi +{ + public: + IOGPIOMatrixCreator(); +}; + +#endif diff --git a/iogpiomatrixvoice.cpp b/iogpiomatrixvoice.cpp new file mode 100644 index 0000000..2623f22 --- /dev/null +++ b/iogpiomatrixvoice.cpp @@ -0,0 +1,6 @@ +#include "iogpiomatrixvoice.h" + +IOGPIOMatrixVoice::IOGPIOMatrixVoice() + : IOGPIODPi(17, 27, 23, 22) +{ +} \ No newline at end of file diff --git a/iogpiomatrixvoice.h b/iogpiomatrixvoice.h new file mode 100644 index 0000000..ea15e16 --- /dev/null +++ b/iogpiomatrixvoice.h @@ -0,0 +1,12 @@ +#ifndef __IO_GPIO_MATRIX_VOICE__ +#define __IO_GPIO_MATRIX_VOICE__ + +#include "iogpiodpi.h" + +class IOGPIOMatrixVoice : public IOGPIODPi +{ + public: + IOGPIOMatrixVoice(); +}; + +#endif diff --git a/utilities.cpp b/utilities.cpp index cd093dd..37d54cb 100644 --- a/utilities.cpp +++ b/utilities.cpp @@ -15,6 +15,8 @@ #include "sysfsvoice.h" #include "iomatrixcreator.h" #include "iomatrixvoice.h" +#include "iogpiomatrixcreator.h" +#include "iogpiomatrixvoice.h" #include "utilities.h" extern char *optarg; @@ -114,6 +116,18 @@ int getIO( std::auto_ptr *io, struct cable_t * cable, char const *dev, res = io->get()->Init(cable, serial, use_freq); } #endif /*USE_WIRINGPI*/ + else if(cable->cabletype == CABLE_GPIOD_CREATOR) + { + io->reset(new IOGPIOMatrixCreator()); + io->get()->setVerbose(verbose); + res = io->get()->Init(cable, serial, use_freq); + } + else if(cable->cabletype == CABLE_GPIOD_VOICE) + { + io->reset(new IOGPIOMatrixVoice()); + io->get()->setVerbose(verbose); + res = io->get()->Init(cable, serial, use_freq); + } else { fprintf(stderr, "Unknown Cable \"%s\" \n", getCableName(cable->cabletype)); @@ -132,6 +146,8 @@ const char *getCableName(int type) case CABLE_SYSFS_GPIO_CREATOR: return "sysfsgpio_creator"; break; case CABLE_SYSFS_GPIO_VOICE: return "sysfsgpio_voice"; break; case CABLE_UNKNOWN: return "unknown"; break; + case CABLE_GPIOD_CREATOR: return "gpiod_creator"; break; + case CABLE_GPIOD_VOICE: return "gpiod_voice"; break; default: return "Unknown"; } From 1b2b5c4746d009bfc3abe7cef052221392869dbb Mon Sep 17 00:00:00 2001 From: Arek Makarenko Date: Sun, 27 Oct 2024 10:24:12 +0000 Subject: [PATCH 2/9] Remove deprecated cables Some minor styling changes --- .drone.yml | 2 +- CMakeLists.txt | 18 ++---- cabledb.cpp | 12 ---- cabledb.h | 4 -- cablelist.txt | 4 -- iogpiodpi.cpp | 16 ++--- iomatrixcreator.cpp | 7 --- iomatrixcreator.h | 12 ---- iomatrixvoice.cpp | 7 --- iomatrixvoice.h | 12 ---- iowiringpi.cpp | 90 --------------------------- iowiringpi.h | 25 -------- sysfs.cpp | 145 -------------------------------------------- sysfs.h | 38 ------------ sysfscreator.cpp | 7 --- sysfscreator.h | 12 ---- sysfsvoice.cpp | 7 --- sysfsvoice.h | 12 ---- utilities.cpp | 35 +---------- xc3sprog.cpp | 1 - 20 files changed, 15 insertions(+), 451 deletions(-) delete mode 100644 iomatrixcreator.cpp delete mode 100644 iomatrixcreator.h delete mode 100644 iomatrixvoice.cpp delete mode 100644 iomatrixvoice.h delete mode 100644 iowiringpi.cpp delete mode 100644 iowiringpi.h delete mode 100644 sysfs.cpp delete mode 100644 sysfs.h delete mode 100644 sysfscreator.cpp delete mode 100644 sysfscreator.h delete mode 100644 sysfsvoice.cpp delete mode 100644 sysfsvoice.h diff --git a/.drone.yml b/.drone.yml index a46cc6c..f48b311 100644 --- a/.drone.yml +++ b/.drone.yml @@ -8,7 +8,7 @@ pipeline: commands: - echo "build-debs for ${ARCHITECTURE}-${DISTRIBUTION}-${CODENAME}:${IMAGE_TAG}" - ${UPDATE_CMD} - - apt-get install --yes --no-install-recommends wiringpi libftdi-dev + - apt-get install --yes --no-install-recommends libftdi-dev - debuild -us -uc -b - mv ../*.deb . diff --git a/CMakeLists.txt b/CMakeLists.txt index 259f310..9d7cd74 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -130,14 +130,7 @@ ADD_CUSTOM_COMMAND(OUTPUT cables.h INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_BINARY_DIR}) -option(USE_WIRINGPI "Use WiringPi" ON) - -if(USE_WIRINGPI) - set (CONDITIONAL_FILES ${CONDITIONAL_FILES} "iomatrixcreator.cpp" "iomatrixvoice.cpp" "iowiringpi.cpp") - add_definitions( -DUSE_WIRINGPI ) -endif(USE_WIRINGPI) - -add_library(xc3sproglib STATIC iogpiomatrixcreator.cpp iogpiomatrixvoice.cpp iogpiodpi.cpp sysfs.cpp sysfscreator.cpp sysfsvoice.cpp ioftdi.cpp +add_library(xc3sproglib STATIC iogpiomatrixcreator.cpp iogpiomatrixvoice.cpp iogpiodpi.cpp ioftdi.cpp iofx2.cpp devicedb.cpp jtag.cpp jedecfile.cpp bitfile.cpp iobase.cpp progalgxc95x.cpp utilities.cpp progalgxcf.cpp progalgxcfp.cpp progalgxc3s.cpp @@ -146,9 +139,6 @@ add_library(xc3sproglib STATIC iogpiomatrixcreator.cpp iogpiomatrixvoice.cpp io cabledb.cpp pdioverjtag.cpp xmega_pdi_nvm.cpp ${CONDITIONAL_FILES} devices.h cables.h) -if(USE_WIRINGPI) - set(LIBS ${LIBS} wiringPiDev wiringPi) -endif(USE_WIRINGPI) set(GPIO_LIBS ${GPIO_LIBS} gpiod) @@ -156,14 +146,14 @@ add_executable(xc2c_warp xc2c_warp.cpp) target_link_libraries(xc2c_warp xc3sproglib ${CONDITIONAL_LIBS} ${GPIO_LIBS}) add_executable(detectchain detectchain.cpp cables.h devices.h) -target_link_libraries(detectchain xc3sproglib ${LIBFTDI_LIBRARIES} ${LIBFTD2XX_LIBRARIES} ${CONDITIONAL_LIBS} ${LIBS} ${GPIO_LIBS}) +target_link_libraries(detectchain xc3sproglib ${LIBFTDI_LIBRARIES} ${LIBFTD2XX_LIBRARIES} ${CONDITIONAL_LIBS} ${GPIO_LIBS}) add_executable(xc3sprog xc3sprog.cpp javr.cpp srecfile.cpp progalgavr.cpp devices.h) -target_link_libraries(xc3sprog xc3sproglib ${LIBFTDI_LIBRARIES} ${LIBFTD2XX_LIBRARIES} ${CONDITIONAL_LIBS} ${LIBS} ${GPIO_LIBS}) +target_link_libraries(xc3sprog xc3sproglib ${LIBFTDI_LIBRARIES} ${LIBFTD2XX_LIBRARIES} ${CONDITIONAL_LIBS} ${GPIO_LIBS}) add_executable(readdna readdna.cpp devices.h) -target_link_libraries(readdna xc3sproglib ${LIBFTDI_LIBRARIES} ${LIBFTD2XX_LIBRARIES} ${CONDITIONAL_LIBS} ${LIBS} ${GPIO_LIBS}) +target_link_libraries(readdna xc3sproglib ${LIBFTDI_LIBRARIES} ${LIBFTD2XX_LIBRARIES} ${CONDITIONAL_LIBS} ${GPIO_LIBS}) diff --git a/cabledb.cpp b/cabledb.cpp index 7e7e959..a380cf7 100644 --- a/cabledb.cpp +++ b/cabledb.cpp @@ -155,14 +155,6 @@ CABLES_TYPES CableDB::getCableType(const char *given_name) return CABLE_FX2; if (strcasecmp(given_name, "xpc") == 0) return CABLE_XPC; - if (strcasecmp(given_name, "sysfsgpio_creator") == 0) - return CABLE_SYSFS_GPIO_CREATOR; - if (strcasecmp(given_name, "sysfsgpio_voice") == 0) - return CABLE_SYSFS_GPIO_VOICE; - if (strcasecmp(given_name, "matrix_creator") == 0) - return CABLE_MATRIX_CREATOR; - if (strcasecmp(given_name, "matrix_voice") == 0) - return CABLE_MATRIX_VOICE; if (strcasecmp(given_name, "gpiod_creator") == 0) return CABLE_GPIOD_CREATOR; if (strcasecmp(given_name, "gpiod_voice") == 0) @@ -179,10 +171,6 @@ const char *CableDB::getCableName(const CABLES_TYPES type ) case CABLE_FTDI: return "ftdi"; case CABLE_FX2: return "fx2"; case CABLE_XPC: return "xpc"; - case CABLE_MATRIX_CREATOR: return "matrix_creator"; - case CABLE_MATRIX_VOICE: return "matrix_voice"; - case CABLE_SYSFS_GPIO_CREATOR: return "sysfsgpio_creator"; - case CABLE_SYSFS_GPIO_VOICE: return "sysfsgpio_voice"; case CABLE_GPIOD_CREATOR: return "gpiod_creator"; case CABLE_GPIOD_VOICE: return "gpiod_voice"; case CABLE_NONE: return "none"; diff --git a/cabledb.h b/cabledb.h index 1dce3f7..c6ce7e3 100644 --- a/cabledb.h +++ b/cabledb.h @@ -31,10 +31,6 @@ enum CABLES_TYPES CABLE_FTDI, CABLE_FX2, CABLE_XPC, - CABLE_SYSFS_GPIO_CREATOR, - CABLE_SYSFS_GPIO_VOICE, - CABLE_MATRIX_CREATOR, - CABLE_MATRIX_VOICE, CABLE_GPIOD_CREATOR, CABLE_GPIOD_VOICE }; diff --git a/cablelist.txt b/cablelist.txt index d0b1d5e..acef1e1 100644 --- a/cablelist.txt +++ b/cablelist.txt @@ -43,10 +43,6 @@ jtaghs2 ftdi 6000000 0x0403:0x6014:Digilent USB Device:0:0xe8:0xeb:0x00 turtelizer ftdi 1500000 0x0403:0xbdc8:Turtelizer JTAG/RS232 Adapter:0:0x00:0x10:0x00:0x0 arm-usb-ocd-h ftdi 1500000 0x15ba:0x002b::1:0x00:0x10:0x00:0x08 tumpa ftdi 1500000 0x0403:0x8a98:TIAO USB Multi-Protocol Adapter:1 -sysfsgpio_creator sysfsgpio_creator 0 NULL -sysfsgpio_voice sysfsgpio_voice 0 NULL -matrix_creator matrix_creator 0 NULL -matrix_voice matrix_voice 0 NULL gpiod_creator gpiod_creator 0 NULL gpiod_voice gpiod_voice 0 NULL mimas_a7 ftdi 15000000 0x2A19:0x1009::2:0x00:0x4B:0x00:0x00 diff --git a/iogpiodpi.cpp b/iogpiodpi.cpp index 84b248f..7cbdea9 100644 --- a/iogpiodpi.cpp +++ b/iogpiodpi.cpp @@ -127,17 +127,17 @@ void IOGPIODPi::tx_tms(unsigned char *pat, int length, int force) void IOGPIODPi::tx(bool tms, bool tdi) { - gpiod_line_set_value(TCKline, 0); + gpiod_line_set_value(TCKline, 0); - if(tdi) - gpiod_line_set_value(TDIline, 1); - else - gpiod_line_set_value(TDIline, 0); + if(tdi) + gpiod_line_set_value(TDIline, 1); + else + gpiod_line_set_value(TDIline, 0); - if(tms) - gpiod_line_set_value(TMSline, 1); + if(tms) + gpiod_line_set_value(TMSline, 1); else - gpiod_line_set_value(TMSline, 0); + gpiod_line_set_value(TMSline, 0); gpiod_line_set_value(TCKline, 1); } diff --git a/iomatrixcreator.cpp b/iomatrixcreator.cpp deleted file mode 100644 index 3139090..0000000 --- a/iomatrixcreator.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include "iomatrixcreator.h" - -IOMatrixCreator::IOMatrixCreator() - : IOWiringPi(4, 17, 22, 27) -{ -} - diff --git a/iomatrixcreator.h b/iomatrixcreator.h deleted file mode 100644 index 1fb50a8..0000000 --- a/iomatrixcreator.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef __IO_MATRIX_CREATOR__ -#define __IO_MATRIX_CREATOR__ - -#include "iowiringpi.h" - -class IOMatrixCreator : public IOWiringPi -{ - public: - IOMatrixCreator(); -}; - -#endif diff --git a/iomatrixvoice.cpp b/iomatrixvoice.cpp deleted file mode 100644 index 934da3b..0000000 --- a/iomatrixvoice.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include "iomatrixvoice.h" - -IOMatrixVoice::IOMatrixVoice() - : IOWiringPi(17, 27, 23, 22) -{ -} - diff --git a/iomatrixvoice.h b/iomatrixvoice.h deleted file mode 100644 index 2f9d0b7..0000000 --- a/iomatrixvoice.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef __IO_MATRIX_VOICE__ -#define __IO_MATRIX_VOICE__ - -#include "iowiringpi.h" - -class IOMatrixVoice : public IOWiringPi -{ - public: - IOMatrixVoice(); -}; - -#endif diff --git a/iowiringpi.cpp b/iowiringpi.cpp deleted file mode 100644 index 49ea760..0000000 --- a/iowiringpi.cpp +++ /dev/null @@ -1,90 +0,0 @@ -#include "iowiringpi.h" - -#include - -IOWiringPi::IOWiringPi(int tms, int tck, int tdi, int tdo) - : TMSPin(tms), TCKPin(tck), TDIPin(tdi), TDOPin(tdo) -{ - wiringPiSetupGpio(); - pinMode(TDIPin, OUTPUT); - pinMode(TMSPin, OUTPUT); - pinMode(TCKPin, OUTPUT); - pinMode(TDOPin, INPUT); -} - -IOWiringPi::~IOWiringPi() -{ -} - -void IOWiringPi::txrx_block(const unsigned char *tdi, unsigned char *tdo, int length, bool last) -{ - int i=0; - int j=0; - unsigned char tdo_byte=0; - unsigned char tdi_byte; - if (tdi) - tdi_byte = tdi[j]; - - while(i>1; - i++; - if((i%8)==0){ // Next byte - if(tdo) - tdo[j]=tdo_byte; // Save the TDO byte - tdo_byte=0; - j++; - if (tdi) - tdi_byte=tdi[j]; // Get the next TDI byte - } - }; - tdo_byte=tdo_byte+(txrx(last, (tdi_byte&1)==1)<<(i%8)); - if(tdo) - tdo[j]=tdo_byte; - - digitalWrite(TCKPin, LOW); - return; -} - -void IOWiringPi::tx_tms(unsigned char *pat, int length, int force) -{ - int i; - unsigned char tms; - for (i = 0; i < length; i++) - { - if ((i & 0x7) == 0) - tms = pat[i>>3]; - tx((tms & 0x01), true); - tms = tms >> 1; - } - - digitalWrite(TCKPin, LOW); -} - -void IOWiringPi::tx(bool tms, bool tdi) -{ - digitalWrite(TCKPin, LOW); - - if(tdi) - digitalWrite(TDIPin, HIGH); - else - digitalWrite(TDIPin, LOW); - - if(tms) - digitalWrite(TMSPin, HIGH); - else - digitalWrite(TMSPin, LOW); - - digitalWrite(TCKPin, HIGH); -} - - -bool IOWiringPi::txrx(bool tms, bool tdi) -{ - tx(tms, tdi); - - return digitalRead(TDOPin); -} - - diff --git a/iowiringpi.h b/iowiringpi.h deleted file mode 100644 index 08e74de..0000000 --- a/iowiringpi.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef __IO_WIRING_PI__ -#define __IO_WIRING_PI__ - -#include "iobase.h" - -class IOWiringPi : public IOBase -{ - public: - IOWiringPi(int tms, int tck, int tdi, int tdo); - virtual ~IOWiringPi(); - - protected: - void tx(bool tms, bool tdi); - bool txrx(bool tms, bool tdi); - - void txrx_block(const unsigned char *tdi, unsigned char *tdo, int length, bool last); - void tx_tms(unsigned char *pat, int length, int force); - - int TMSPin; - int TCKPin; - int TDIPin; - int TDOPin; -}; - -#endif diff --git a/sysfs.cpp b/sysfs.cpp deleted file mode 100644 index 2a0667d..0000000 --- a/sysfs.cpp +++ /dev/null @@ -1,145 +0,0 @@ -#include "sysfs.h" - -#include -#include -#include -#include -#include -#include -#include - -#include - -IOSysFsGPIO::IOSysFsGPIO(int tms, int tck, int tdi, int tdo) - : TMSPin(tms), TCKPin(tck), TDIPin(tdi), TDOPin(tdo), tck_fd(-1), tms_fd(-1), tdi_fd(-1), tdo_fd(-1), one("1"), zero("0") -{ - tdi_fd = setup_gpio(TDIPin, 0); - tms_fd = setup_gpio(TMSPin, 0); - tck_fd = setup_gpio(TCKPin, 0); - tdo_fd = setup_gpio(TDOPin, 1); -} - -IOSysFsGPIO::~IOSysFsGPIO() { - unexport_gpio(TDIPin); - unexport_gpio(TMSPin); - unexport_gpio(TCKPin); - unexport_gpio(TDOPin); -} - -void IOSysFsGPIO::txrx_block(const unsigned char *tdi, unsigned char *tdo, - int length, bool last) { - int i = 0; - int j = 0; - unsigned char tdo_byte = 0; - unsigned char tdi_byte; - - if (tdi) tdi_byte = tdi[j]; - - while (i < length - 1) { - tdo_byte = tdo_byte + (txrx(false, (tdi_byte & 1) == 1) << (i % 8)); - if (tdi) tdi_byte = tdi_byte >> 1; - i++; - if ((i % 8) == 0) { // Next byte - if (tdo) tdo[j] = tdo_byte; // Save the TDO byte - tdo_byte = 0; - j++; - if (tdi) tdi_byte = tdi[j]; // Get the next TDI byte - } - }; - tdo_byte = tdo_byte + (txrx(last, (tdi_byte & 1) == 1) << (i % 8)); - if (tdo) tdo[j] = tdo_byte; - - write(tck_fd, zero, 1); - - return; -} - -void IOSysFsGPIO::tx_tms(unsigned char *pat, int length, int force) { - int i; - unsigned char tms; - for (i = 0; i < length; i++) { - if ((i & 0x7) == 0) tms = pat[i >> 3]; - tx((tms & 0x01), true); - tms = tms >> 1; - } - - write(tck_fd, zero, 1); -} - -void IOSysFsGPIO::tx(bool tms, bool tdi) { - write(tck_fd, zero, 1); - - write(tdi_fd, tdi ? one : zero, 1); - - write(tms_fd, tms ? one : zero, 1); - - write(tck_fd, one, 1); -} - -bool IOSysFsGPIO::txrx(bool tms, bool tdi) { - static char buf[1]; - - tx(tms, tdi); - - lseek(tdo_fd, 0, SEEK_SET); - - if (read(tdo_fd, &buf, sizeof(buf)) < 0) { - /* reading tdo failed */ - return false; - } - return buf[0] != '0'; -} - -int IOSysFsGPIO::open_write_close(const char *name, const char *valstr) { - int ret; - int fd = open(name, O_WRONLY); - if (fd < 0) return fd; - - ret = write(fd, valstr, strlen(valstr)); - close(fd); - - return ret; -} - -int IOSysFsGPIO::setup_gpio(int gpio, int is_input) { - char buf[40]; - char gpiostr[4]; - - snprintf(gpiostr, sizeof(gpiostr), "%d", gpio); - if (open_write_close("/sys/class/gpio/export", gpiostr) < 0) { - if (errno == EBUSY) { - std::cerr << "WARNING: gpio " << gpio << " already exported" << std::endl; - } else { - std::cerr << "ERROR: Couldn't export gpio " << gpio << std::endl; - return 0; - } - } - - snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/direction", gpio); - if (open_write_close(buf, is_input ? "in" : "out") < 0) { - std::cerr << "ERROR: Couldn't set direction for gpio " << gpio << std::endl; - unexport_gpio(gpio); - return 0; - } - - snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/value", gpio); - int fd = open(buf, O_RDWR | O_NONBLOCK | O_SYNC); - if (fd < 0) { - std::cerr << "ERROR: Couldn't open value for gpio " << gpio << std::endl; - unexport_gpio(gpio); - } - - return fd; -} - -void IOSysFsGPIO::unexport_gpio(int gpio) { - char gpiostr[4]; - - if (!is_gpio_valid(gpio)) return; - - snprintf(gpiostr, sizeof(gpiostr), "%d", gpio); - if (open_write_close("/sys/class/gpio/unexport", gpiostr) < - 0) { // LOG_ERROR("Couldn't unexport gpio %d", gpio); - } - return; -} diff --git a/sysfs.h b/sysfs.h deleted file mode 100644 index 5435b88..0000000 --- a/sysfs.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef __IO_SYSFS__ -#define __IO_SYSFS__ - -#include "iobase.h" - -class IOSysFsGPIO : public IOBase { - public: - IOSysFsGPIO(int tms, int tck, int tdi, int tdo); - virtual ~IOSysFsGPIO(); - - private: - void tx(bool tms, bool tdi); - bool txrx(bool tms, bool tdi); - - void txrx_block(const unsigned char *tdi, unsigned char *tdo, int length, - bool last); - void tx_tms(unsigned char *pat, int length, int force); - - int open_write_close(const char *name, const char *valstr); - int setup_gpio(int gpio, int is_input); - void unexport_gpio(int gpio); - bool is_gpio_valid(int gpio) { return gpio >= 0 && gpio < 1000; } - - private: - int TMSPin; - int TCKPin; - int TDIPin; - int TDOPin; - - int tck_fd; - int tms_fd; - int tdi_fd; - int tdo_fd; - - const char *one; - const char *zero; -}; -#endif diff --git a/sysfscreator.cpp b/sysfscreator.cpp deleted file mode 100644 index 432d5c8..0000000 --- a/sysfscreator.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include "sysfscreator.h" - -IOSysFsMatrixCreator::IOSysFsMatrixCreator() - : IOSysFsGPIO(4, 17, 22, 27) -{ -} - diff --git a/sysfscreator.h b/sysfscreator.h deleted file mode 100644 index 4e73676..0000000 --- a/sysfscreator.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef __IO_SYSFS_CREATOR__ -#define __IO_SYSFS_CREATOR__ - -#include "sysfs.h" - -class IOSysFsMatrixCreator : public IOSysFsGPIO -{ - public: - IOSysFsMatrixCreator(); -}; - -#endif diff --git a/sysfsvoice.cpp b/sysfsvoice.cpp deleted file mode 100644 index 472d80b..0000000 --- a/sysfsvoice.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include "sysfsvoice.h" - -IOSysFsMatrixVoice::IOSysFsMatrixVoice() - : IOSysFsGPIO(17, 27, 23, 22) -{ -} - diff --git a/sysfsvoice.h b/sysfsvoice.h deleted file mode 100644 index 6b3f4a9..0000000 --- a/sysfsvoice.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef __IO_SYSFS_VOICE__ -#define __IO_SYSFS_VOICE__ - -#include "sysfs.h" - -class IOSysFsMatrixVoice : public IOSysFsGPIO -{ - public: - IOSysFsMatrixVoice(); -}; - -#endif diff --git a/utilities.cpp b/utilities.cpp index 37d54cb..5a4081f 100644 --- a/utilities.cpp +++ b/utilities.cpp @@ -11,10 +11,6 @@ #include "iofx2.h" #include "ioftdi.h" #include "ioxpc.h" -#include "sysfscreator.h" -#include "sysfsvoice.h" -#include "iomatrixcreator.h" -#include "iomatrixvoice.h" #include "iogpiomatrixcreator.h" #include "iogpiomatrixvoice.h" #include "utilities.h" @@ -90,32 +86,6 @@ int getIO( std::auto_ptr *io, struct cable_t * cable, char const *dev, io->get()->setVerbose(verbose); res = io->get()->Init(cable, serial, use_freq); } - else if(cable->cabletype == CABLE_SYSFS_GPIO_CREATOR) - { - io->reset(new IOSysFsMatrixCreator()); - io->get()->setVerbose(verbose); - res = io->get()->Init(cable, serial, use_freq); - } - else if(cable->cabletype == CABLE_SYSFS_GPIO_VOICE) - { - io->reset(new IOSysFsMatrixVoice()); - io->get()->setVerbose(verbose); - res = io->get()->Init(cable, serial, use_freq); - } -#ifdef USE_WIRINGPI - else if(cable->cabletype == CABLE_MATRIX_CREATOR) - { - io->reset(new IOMatrixCreator()); - io->get()->setVerbose(verbose); - res = io->get()->Init(cable, serial, use_freq); - } - else if(cable->cabletype == CABLE_MATRIX_VOICE) - { - io->reset(new IOMatrixVoice()); - io->get()->setVerbose(verbose); - res = io->get()->Init(cable, serial, use_freq); - } -#endif /*USE_WIRINGPI*/ else if(cable->cabletype == CABLE_GPIOD_CREATOR) { io->reset(new IOGPIOMatrixCreator()); @@ -143,11 +113,10 @@ const char *getCableName(int type) case CABLE_FTDI: return "ftdi"; break; case CABLE_FX2: return "fx2"; break; case CABLE_XPC: return "xpc"; break; - case CABLE_SYSFS_GPIO_CREATOR: return "sysfsgpio_creator"; break; - case CABLE_SYSFS_GPIO_VOICE: return "sysfsgpio_voice"; break; - case CABLE_UNKNOWN: return "unknown"; break; case CABLE_GPIOD_CREATOR: return "gpiod_creator"; break; case CABLE_GPIOD_VOICE: return "gpiod_voice"; break; + case CABLE_UNKNOWN: return "unknown"; break; + default: return "Unknown"; } diff --git a/xc3sprog.cpp b/xc3sprog.cpp index 1a36816..53accdf 100644 --- a/xc3sprog.cpp +++ b/xc3sprog.cpp @@ -42,7 +42,6 @@ Dmitry Teytelman [dimtey@gmail.com] 14 Jun 2006 [applied 13 Aug 2006]: #include "iofx2.h" #include "ioftdi.h" #include "ioxpc.h" -#include "sysfs.h" #include "bitfile.h" #include "jtag.h" #include "devicedb.h" From d19cbf47c199f8d0d68be3fa161102614f5e56dc Mon Sep 17 00:00:00 2001 From: arkadiuszmakarenko Date: Sun, 27 Oct 2024 10:58:24 +0000 Subject: [PATCH 3/9] Update README.md --- README.md | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/README.md b/README.md index a4b239f..d1024fc 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,48 @@ +# Raspberry Pi specific fork + +This fork repurposed this project and replaced obsolete librarary sysfs, and p` as it was not working reliably enough to program without frequent mismatch errors or validation errors. + +## Installation +This project has been tested on Raspberry Pi 4 with Bullseye 32-bit and Bookworm 32-bit and 64-bit. +It was checked only on cpld Xillinx XC9500XL series. + + +``` +sudo apt install build-essential libusb-dev libftdi-dev libgpiod-dev git cmake +git clone https://github.com/arkadiuszmakarenko/xc3sprog.git +mkdir xc3sprog/build +cd xc3sprog/build +cmake .. +make +sudo make install +``` +## Connecting GPIO +cable type : gpiod_creator + +|GPIO |Header Pin |Function| +--- | --- | ---| +|4|7|TMS| +|17|11|TCK| +|22|13|TDO| +|27|15|TDI| + +## JTAG Chain discovery + +``` +sudo xc3sprog -c gpiod_creator -j + +``` + +## Programming +``` +xc3sprog -c gpio_creator -v -p 0 {filename}.jed +``` + +--- +Old docs +--- + + # Installation ``` From 0e45e6694c3485c04253097b6de4dd90ba9d9950 Mon Sep 17 00:00:00 2001 From: arkadiuszmakarenko Date: Sun, 27 Oct 2024 10:59:50 +0000 Subject: [PATCH 4/9] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d1024fc..1f8dae5 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ sudo xc3sprog -c gpiod_creator -j ## Programming ``` -xc3sprog -c gpio_creator -v -p 0 {filename}.jed +xc3sprog -c gpio_creator -v -p {chain poistion eg. 0} {filename}.jed ``` --- From 077c699abcda447766d09ac2e5fc2000208aeacb Mon Sep 17 00:00:00 2001 From: arkadiuszmakarenko Date: Sun, 27 Oct 2024 11:34:30 +0000 Subject: [PATCH 5/9] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1f8dae5..8e5c77a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Raspberry Pi specific fork -This fork repurposed this project and replaced obsolete librarary sysfs, and p` as it was not working reliably enough to program without frequent mismatch errors or validation errors. +This fork repurposed this project and replaced obsolete librarary sysfs, and wiringpi as it was not working reliably enough to program without frequent mismatch errors or validation errors. ## Installation This project has been tested on Raspberry Pi 4 with Bullseye 32-bit and Bookworm 32-bit and 64-bit. From 927e0bb50e568c11341ad3379da572480ba38183 Mon Sep 17 00:00:00 2001 From: arkadiuszmakarenko Date: Thu, 28 Nov 2024 21:34:10 +0000 Subject: [PATCH 6/9] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8e5c77a..2e1d061 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ sudo xc3sprog -c gpiod_creator -j ## Programming ``` -xc3sprog -c gpio_creator -v -p {chain poistion eg. 0} {filename}.jed +xc3sprog -c gpiod_creator -v -p {chain poistion eg. 0} {filename}.jed ``` --- From 80c5b9f2f5b2e4ec661f8fbc2ea61fe1281b5ad9 Mon Sep 17 00:00:00 2001 From: Bernie Innocenti Date: Wed, 25 Feb 2026 13:55:14 +0100 Subject: [PATCH 7/9] gpiod: migrate Raspberry Pi backend to libgpiod 2.x API --- iogpiodpi.cpp | 154 ++++++++++++++++++++++++++++++-------------------- iogpiodpi.h | 10 ++-- 2 files changed, 98 insertions(+), 66 deletions(-) diff --git a/iogpiodpi.cpp b/iogpiodpi.cpp index 7cbdea9..21aaa06 100644 --- a/iogpiodpi.cpp +++ b/iogpiodpi.cpp @@ -1,80 +1,112 @@ -#include +#include "iogpiodpi.h" #include - IOGPIODPi::IOGPIODPi(int tms, int tck, int tdi, int tdo) : TMSPin(tms), TCKPin(tck), TDIPin(tdi), TDOPin(tdo) { - chip = gpiod_chip_open_by_name("gpiochip0"); + chip = NULL; + TMSreq = NULL; + TCKreq = NULL; + TDIreq = NULL; + TDOreq = NULL; + chip = gpiod_chip_open("/dev/gpiochip0"); if (!chip) { - perror("Open chip failed"); - } - - TMSline = gpiod_chip_get_line(chip, TMSPin); - TCKline = gpiod_chip_get_line(chip, TCKPin); - TDIline = gpiod_chip_get_line(chip, TDIPin); - TDOline = gpiod_chip_get_line(chip, TDOPin); - - if (!TMSline) { - perror("TMSline line config failed"); - gpiod_chip_close(chip); + perror("Open chip failed"); + return; } - if (!TCKline) { - perror("TCKline line config failed"); - gpiod_chip_close(chip); + struct gpiod_request_config *request_config = gpiod_request_config_new(); + struct gpiod_line_config *line_config = gpiod_line_config_new(); + struct gpiod_line_settings *line_settings = gpiod_line_settings_new(); + if (!request_config || !line_config || !line_settings) { + perror("Unable to create libgpiod config objects"); + goto cleanup; } - if (!TDIline) { - perror("TDIline line config failed"); - gpiod_chip_close(chip); - } + gpiod_request_config_set_consumer(request_config, "Consumer"); - if (!TDOline) { - perror("TDOline line config failed"); - gpiod_chip_close(chip); - } + unsigned int offset; - int ret; + gpiod_line_settings_set_direction(line_settings, GPIOD_LINE_DIRECTION_OUTPUT); + gpiod_line_settings_set_output_value(line_settings, GPIOD_LINE_VALUE_INACTIVE); - ret = gpiod_line_request_output(TMSline, "Consumer", 0); - if (ret < 0) { - perror("Request TMSline as output failed"); - gpiod_line_release(TMSline); - gpiod_chip_close(chip); + offset = TMSPin; + if (gpiod_line_config_add_line_settings(line_config, &offset, 1, line_settings) < 0) { + perror("TMS line config failed"); + goto cleanup; } + TMSreq = gpiod_chip_request_lines(chip, request_config, line_config); + if (!TMSreq) { + perror("Request TMS as output failed"); + goto cleanup; + } + gpiod_line_config_reset(line_config); - ret = gpiod_line_request_output(TCKline, "Consumer", 0); - if (ret < 0) { - perror("Request TCKline as output failed"); - gpiod_line_release(TCKline); - gpiod_chip_close(chip); + offset = TCKPin; + if (gpiod_line_config_add_line_settings(line_config, &offset, 1, line_settings) < 0) { + perror("TCK line config failed"); + goto cleanup; + } + TCKreq = gpiod_chip_request_lines(chip, request_config, line_config); + if (!TCKreq) { + perror("Request TCK as output failed"); + goto cleanup; } + gpiod_line_config_reset(line_config); - ret = gpiod_line_request_output(TDIline, "Consumer", 0); - if (ret < 0) { - perror("Request TDIline as output failed"); - gpiod_line_release(TDIline); - gpiod_chip_close(chip); + offset = TDIPin; + if (gpiod_line_config_add_line_settings(line_config, &offset, 1, line_settings) < 0) { + perror("TDI line config failed"); + goto cleanup; + } + TDIreq = gpiod_chip_request_lines(chip, request_config, line_config); + if (!TDIreq) { + perror("Request TDI as output failed"); + goto cleanup; } + gpiod_line_config_reset(line_config); - ret = gpiod_line_request_input(TDOline, "Consumer"); - if (ret < 0) { - perror("Request TDOline as input failed"); - gpiod_line_release(TDOline); - gpiod_chip_close(chip); + gpiod_line_settings_set_direction(line_settings, GPIOD_LINE_DIRECTION_INPUT); + offset = TDOPin; + if (gpiod_line_config_add_line_settings(line_config, &offset, 1, line_settings) < 0) { + perror("TDO line config failed"); + goto cleanup; + } + TDOreq = gpiod_chip_request_lines(chip, request_config, line_config); + if (!TDOreq) { + perror("Request TDO as input failed"); + goto cleanup; } +cleanup: + gpiod_line_settings_free(line_settings); + gpiod_line_config_free(line_config); + gpiod_request_config_free(request_config); + + if (!TMSreq || !TCKreq || !TDIreq || !TDOreq) { + if (TMSreq) gpiod_line_request_release(TMSreq); + if (TCKreq) gpiod_line_request_release(TCKreq); + if (TDIreq) gpiod_line_request_release(TDIreq); + if (TDOreq) gpiod_line_request_release(TDOreq); + TMSreq = NULL; + TCKreq = NULL; + TDIreq = NULL; + TDOreq = NULL; + if (chip) { + gpiod_chip_close(chip); + chip = NULL; + } + } } IOGPIODPi::~IOGPIODPi() { - gpiod_line_release(TMSline); - gpiod_line_release(TCKline); - gpiod_line_release(TDIline); - gpiod_line_release(TDOline); - gpiod_chip_close(chip); + if (TMSreq) gpiod_line_request_release(TMSreq); + if (TCKreq) gpiod_line_request_release(TCKreq); + if (TDIreq) gpiod_line_request_release(TDIreq); + if (TDOreq) gpiod_line_request_release(TDOreq); + if (chip) gpiod_chip_close(chip); } void IOGPIODPi::txrx_block(const unsigned char *tdi, unsigned char *tdo, int length, bool last) @@ -106,7 +138,7 @@ void IOGPIODPi::txrx_block(const unsigned char *tdi, unsigned char *tdo, int len if(tdo) tdo[j]=tdo_byte; - gpiod_line_set_value(TCKline, 0); + gpiod_line_request_set_value(TCKreq, TCKPin, GPIOD_LINE_VALUE_INACTIVE); return; } @@ -122,32 +154,32 @@ void IOGPIODPi::tx_tms(unsigned char *pat, int length, int force) tms = tms >> 1; } - gpiod_line_set_value(TCKline, 0); + gpiod_line_request_set_value(TCKreq, TCKPin, GPIOD_LINE_VALUE_INACTIVE); } void IOGPIODPi::tx(bool tms, bool tdi) { - gpiod_line_set_value(TCKline, 0); + gpiod_line_request_set_value(TCKreq, TCKPin, GPIOD_LINE_VALUE_INACTIVE); if(tdi) - gpiod_line_set_value(TDIline, 1); + gpiod_line_request_set_value(TDIreq, TDIPin, GPIOD_LINE_VALUE_ACTIVE); else - gpiod_line_set_value(TDIline, 0); + gpiod_line_request_set_value(TDIreq, TDIPin, GPIOD_LINE_VALUE_INACTIVE); if(tms) - gpiod_line_set_value(TMSline, 1); + gpiod_line_request_set_value(TMSreq, TMSPin, GPIOD_LINE_VALUE_ACTIVE); else - gpiod_line_set_value(TMSline, 0); + gpiod_line_request_set_value(TMSreq, TMSPin, GPIOD_LINE_VALUE_INACTIVE); - gpiod_line_set_value(TCKline, 1); + gpiod_line_request_set_value(TCKreq, TCKPin, GPIOD_LINE_VALUE_ACTIVE); } bool IOGPIODPi::txrx(bool tms, bool tdi) { - // std::cerr << "txrx" << gpiod_line_get_value(TDOline) << std::endl; + // std::cerr << "txrx" << gpiod_line_request_get_value(TDOreq, TDOPin) << std::endl; tx(tms, tdi); - return gpiod_line_get_value(TDOline); + return gpiod_line_request_get_value(TDOreq, TDOPin) == GPIOD_LINE_VALUE_ACTIVE; // return digitalRead(TDOPin); } diff --git a/iogpiodpi.h b/iogpiodpi.h index 64e04e4..0a82929 100644 --- a/iogpiodpi.h +++ b/iogpiodpi.h @@ -24,10 +24,10 @@ class IOGPIODPi : public IOBase private: struct gpiod_chip *chip; - struct gpiod_line *TMSline; - struct gpiod_line *TCKline; - struct gpiod_line *TDIline; - struct gpiod_line *TDOline; + struct gpiod_line_request *TMSreq; + struct gpiod_line_request *TCKreq; + struct gpiod_line_request *TDIreq; + struct gpiod_line_request *TDOreq; }; -#endif \ No newline at end of file +#endif From ece2f354b273bb8b29e91682726cf8c0ba55badc Mon Sep 17 00:00:00 2001 From: Bernie Innocenti Date: Wed, 25 Feb 2026 13:57:29 +0100 Subject: [PATCH 8/9] cmake: support libftdi1 in Findlibftdi --- Findlibftdi.cmake | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Findlibftdi.cmake b/Findlibftdi.cmake index 88d6ba0..90fafe5 100644 --- a/Findlibftdi.cmake +++ b/Findlibftdi.cmake @@ -17,7 +17,10 @@ if (NOT LIBFTDI_FOUND) if(NOT WIN32) include(FindPkgConfig) - pkg_check_modules(LIBFTDI_PKG libftdi) + pkg_check_modules(LIBFTDI_PKG QUIET libftdi) + if(NOT LIBFTDI_PKG_FOUND) + pkg_check_modules(LIBFTDI_PKG QUIET libftdi1) + endif(NOT LIBFTDI_PKG_FOUND) endif(NOT WIN32) find_path(LIBFTDI_INCLUDE_DIR @@ -25,6 +28,8 @@ if (NOT LIBFTDI_FOUND) ftdi.h HINTS ${LIBFTDI_PKG_INCLUDE_DIRS} + PATH_SUFFIXES + libftdi1 PATHS /usr/include /usr/local/include @@ -38,10 +43,12 @@ if (NOT LIBFTDI_FOUND) find_library(LIBFTDI_LIBRARIES NAMES ftdi + ftdi1 HINTS ${LIBFTDI_PKG_LIBRARY_DIRS} PATHS /usr/lib + /usr/lib64 /usr/local/lib ) From 55eaddd381b4f5ff12c6b9851834db44644e4d09 Mon Sep 17 00:00:00 2001 From: Bernie Innocenti Date: Wed, 25 Feb 2026 16:40:27 +0100 Subject: [PATCH 9/9] cmake: update project files for modern CMake --- CMakeLists.txt | 24 ++++++++++++------------ javr/CMakeLists.txt | 4 ++-- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9d7cd74..d0eda3a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,20 +1,20 @@ # Project +cmake_minimum_required(VERSION 3.10) project(xc3sprog) set(xc3sprog_VERSION_MAJOR 0) set(xc3sprog_VERSION_MINOR 0) -SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}") +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}") set(CMAKE_CXX_FLAGS "-g -Wall") -cmake_minimum_required(VERSION 2.6) -if(${WIN32}) +if(WIN32) set(USE_STATIC_FTDI ON) -IF( ${CMAKE_COMPILER_IS_GNUCXX} ) +IF(CMAKE_COMPILER_IS_GNUCXX) # link libstdc++ and others statically add_definitions( -D__USE_MINGW_ANSI_STDIO ) SET (CMAKE_EXE_LINKER_FLAGS "-static-libstdc++ -static-libgcc") -ENDIF( ${CMAKE_COMPILER_IS_GNUCXX} ) -endif(${WIN32}) +ENDIF() +endif() option(USE_FTD2XX "Use FTDI libFTD2XX instead of free libftdi" ON) @@ -60,14 +60,14 @@ set(CPACK_PACKAGE_DESCRIPTION "JTAG Progarmming tools") set(CPACK_PACKAGE_DESCRIPTION_SUMMARY ${CPACK_PACKAGE_DESCRIPTION} ) # Package settings -if(${UNIX}) +if(UNIX) set(CPACK_GENERATOR "DEB;RPM") set(CPACK_CMAKE_GENERATOR "Unix Makefiles") set(CPACK_PACKAGE_NAME ${PROJECT_NAME}) set(CPACK_PACKAGE_FILE_NAME ${PROJECT_NAME}-${VERSION_STRING}${PACK_ARCH}) -endif(${UNIX}) +endif() -if(${WIN32}) +if(WIN32) set(CPACK_GENERATOR "NSIS") set(CPACK_CMAKE_GENERATOR "MinGW Makefiles") set(CPACK_PACKAGE_NAME "${PROJECT_NAME}") @@ -76,7 +76,7 @@ if(${WIN32}) set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${VERSION_STRING}-win32") set(CPACK_NSIS_DISPLAY_NAME "libftdi") set(CPACK_NSIS_MODIFY_PATH "ON") -endif(${WIN32}) +endif() set(CPACK_RESOURCE_FILE_LICENSE ${CMAKE_SOURCE_DIR}/LICENSE) @@ -85,9 +85,9 @@ set(CPACK_SOURCE_IGNORE_FILES "\\\\.svn" "build*") set(CPACK_SOURCE_PACKAGE_FILE_NAME ${CPACK_PACKAGE_FILE_NAME}) # Subdirectories -if(${UNIX}) +if(UNIX) set(CPACK_SET_DESTDIR "ON") -endif(${UNIX}) +endif() #link libusb dynamic at runtime on windows at at compile time else #this circumvents a problem with Debian diff --git a/javr/CMakeLists.txt b/javr/CMakeLists.txt index 7df5a69..2b2aa65 100644 --- a/javr/CMakeLists.txt +++ b/javr/CMakeLists.txt @@ -1,7 +1,7 @@ # Project +cmake_minimum_required(VERSION 3.10) project(javr) -SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}") -cmake_minimum_required(VERSION 2.6) +list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}") include_directories (${XC3SPROG_SOURCE_DIR}) link_directories (${XC3SPROG_BINARY_DIR}/xc3sproglib)