diff --git a/CMakeLists.txt b/CMakeLists.txt index 4b6ba62..c692d1e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -240,7 +240,12 @@ if (ENABLE_LIBGPIOD) add_definitions(-DENABLE_LIBGPIOD=1) target_sources(openFPGALoader PRIVATE src/libgpiodJtagBitbang.cpp) list (APPEND OPENFPGALOADER_HEADERS src/libgpiodJtagBitbang.hpp) - message("libgpiod support enabled") + if (LIBGPIOD_VERSION VERSION_GREATER_EQUAL 2) + message("libgpiod v2 support enabled") + add_definitions(-DGPIOD_APIV2) + else() + message("libgpiod v1 support enabled") + endif() endif(ENABLE_LIBGPIOD) if (ENABLE_JETSONNANOGPIO) diff --git a/src/cable.hpp b/src/cable.hpp index ee346cf..30c3c95 100644 --- a/src/cable.hpp +++ b/src/cable.hpp @@ -8,6 +8,7 @@ #include #include +#include /*! * \brief define type of communication diff --git a/src/epcq.hpp b/src/epcq.hpp index 652be5d..cde12ea 100644 --- a/src/epcq.hpp +++ b/src/epcq.hpp @@ -6,8 +6,10 @@ #ifndef SRC_EPCQ_HPP_ #define SRC_EPCQ_HPP_ +#include #include #include + #include "spiInterface.hpp" #include "spiFlash.hpp" diff --git a/src/jtagInterface.hpp b/src/jtagInterface.hpp index adc10f3..77b3572 100644 --- a/src/jtagInterface.hpp +++ b/src/jtagInterface.hpp @@ -6,6 +6,7 @@ #ifndef _JTAGINTERFACE_H_ #define _JTAGINTERFACE_H_ +#include #include #include diff --git a/src/libgpiodJtagBitbang.cpp b/src/libgpiodJtagBitbang.cpp index 5583d3d..bdc603f 100644 --- a/src/libgpiodJtagBitbang.cpp +++ b/src/libgpiodJtagBitbang.cpp @@ -57,7 +57,11 @@ LibgpiodJtagBitbang::LibgpiodJtagBitbang( } /* Validate pins */ - int pins[] = {_tck_pin, _tms_pin, _tdi_pin, _tdo_pin}; +#ifdef GPIOD_APIV2 + const unsigned int pins[] = {_tck_pin, _tms_pin, _tdi_pin, _tdo_pin}; +#else + const int pins[] = {_tck_pin, _tms_pin, _tdi_pin, _tdo_pin}; +#endif for (uint32_t i = 0; i < sizeof(pins) / sizeof(pins[0]); i++) { if (pins[i] < 0 || pins[i] >= 1000) { display("Pin %d is outside of valid range\n", pins[i]); @@ -78,10 +82,68 @@ LibgpiodJtagBitbang::LibgpiodJtagBitbang( throw std::runtime_error("Unable to open gpio chip\n"); } +#ifdef GPIOD_APIV2 + _tdo_req_cfg = gpiod_request_config_new(); + _tdi_req_cfg = gpiod_request_config_new(); + _tck_req_cfg = gpiod_request_config_new(); + _tms_req_cfg = gpiod_request_config_new(); + + gpiod_request_config_set_consumer(_tdo_req_cfg, "_tdo"); + gpiod_request_config_set_consumer(_tdi_req_cfg, "_tdi"); + gpiod_request_config_set_consumer(_tck_req_cfg, "_tck"); + gpiod_request_config_set_consumer(_tms_req_cfg, "_tms"); + + _tdo_settings = gpiod_line_settings_new(); + _tdi_settings = gpiod_line_settings_new(); + _tck_settings = gpiod_line_settings_new(); + _tms_settings = gpiod_line_settings_new(); + + gpiod_line_settings_set_direction( + _tdo_settings, GPIOD_LINE_DIRECTION_INPUT); + gpiod_line_settings_set_direction( + _tdi_settings, GPIOD_LINE_DIRECTION_OUTPUT); + gpiod_line_settings_set_direction( + _tck_settings, GPIOD_LINE_DIRECTION_OUTPUT); + gpiod_line_settings_set_direction( + _tms_settings, GPIOD_LINE_DIRECTION_OUTPUT); + + gpiod_line_settings_set_bias( + _tdo_settings, GPIOD_LINE_BIAS_DISABLED); + gpiod_line_settings_set_bias( + _tdi_settings, GPIOD_LINE_BIAS_DISABLED); + gpiod_line_settings_set_bias( + _tck_settings, GPIOD_LINE_BIAS_DISABLED); + gpiod_line_settings_set_bias( + _tms_settings, GPIOD_LINE_BIAS_DISABLED); + + _tdo_line_cfg = gpiod_line_config_new(); + _tdi_line_cfg = gpiod_line_config_new(); + _tck_line_cfg = gpiod_line_config_new(); + _tms_line_cfg = gpiod_line_config_new(); + + gpiod_line_config_add_line_settings( + _tdo_line_cfg, &_tdo_pin, 1, _tdo_settings); + gpiod_line_config_add_line_settings( + _tdi_line_cfg, &_tdi_pin, 1, _tdi_settings); + gpiod_line_config_add_line_settings( + _tck_line_cfg, &_tck_pin, 1, _tck_settings); + gpiod_line_config_add_line_settings( + _tms_line_cfg, &_tms_pin, 1, _tms_settings); + + _tdo_request = gpiod_chip_request_lines( + _chip, _tdo_req_cfg, _tdo_line_cfg); + _tdi_request = gpiod_chip_request_lines( + _chip, _tdi_req_cfg, _tdi_line_cfg); + _tck_request = gpiod_chip_request_lines( + _chip, _tck_req_cfg, _tck_line_cfg); + _tms_request = gpiod_chip_request_lines( + _chip, _tms_req_cfg, _tms_line_cfg); +#else _tdo_line = get_line(_tdo_pin, 0, GPIOD_LINE_REQUEST_DIRECTION_INPUT); _tdi_line = get_line(_tdi_pin, 0, GPIOD_LINE_REQUEST_DIRECTION_OUTPUT); _tck_line = get_line(_tck_pin, 0, GPIOD_LINE_REQUEST_DIRECTION_OUTPUT); _tms_line = get_line(_tms_pin, 1, GPIOD_LINE_REQUEST_DIRECTION_OUTPUT); +#endif _curr_tdi = 0; _curr_tck = 0; @@ -94,6 +156,35 @@ LibgpiodJtagBitbang::LibgpiodJtagBitbang( LibgpiodJtagBitbang::~LibgpiodJtagBitbang() { +#ifdef GPIOD_APIV2 + if (_tms_request) + gpiod_line_request_release(_tms_request); + if (_tms_line_cfg) + gpiod_line_config_free(_tms_line_cfg); + if (_tms_settings) + gpiod_line_settings_free(_tms_settings); + + if (_tck_request) + gpiod_line_request_release(_tck_request); + if (_tck_line_cfg) + gpiod_line_config_free(_tck_line_cfg); + if (_tck_settings) + gpiod_line_settings_free(_tck_settings); + + if (_tdi_request) + gpiod_line_request_release(_tdi_request); + if (_tdi_line_cfg) + gpiod_line_config_free(_tdi_line_cfg); + if (_tdi_settings) + gpiod_line_settings_free(_tdi_settings); + + if (_tdo_request) + gpiod_line_request_release(_tdo_request); + if (_tdo_line_cfg) + gpiod_line_config_free(_tdo_line_cfg); + if (_tdo_settings) + gpiod_line_settings_free(_tdo_settings); +#else if (_tms_line) gpiod_line_release(_tms_line); @@ -105,11 +196,13 @@ LibgpiodJtagBitbang::~LibgpiodJtagBitbang() if (_tdo_line) gpiod_line_release(_tdo_line); +#endif if (_chip) gpiod_chip_close(_chip); } +#ifndef GPIOD_APIV2 gpiod_line *LibgpiodJtagBitbang::get_line(unsigned int offset, int val, int dir) { gpiod_line *line = gpiod_chip_get_line(_chip, offset); @@ -132,21 +225,40 @@ gpiod_line *LibgpiodJtagBitbang::get_line(unsigned int offset, int val, int dir) return line; } +#endif int LibgpiodJtagBitbang::update_pins(int tck, int tms, int tdi) { if (tdi != _curr_tdi) { +#ifdef GPIOD_APIV2 + if (gpiod_line_request_set_value(_tdi_request, _tdi_pin, + (tdi == 0) ? GPIOD_LINE_VALUE_INACTIVE : + GPIOD_LINE_VALUE_ACTIVE) < 0) +#else if (gpiod_line_set_value(_tdi_line, tdi) < 0) +#endif display("Unable to set gpio pin tdi\n"); } if (tms != _curr_tms) { +#ifdef GPIOD_APIV2 + if (gpiod_line_request_set_value(_tms_request, _tms_pin, + (tms == 0) ? GPIOD_LINE_VALUE_INACTIVE : + GPIOD_LINE_VALUE_ACTIVE) < 0) +#else if (gpiod_line_set_value(_tms_line, tms) < 0) +#endif display("Unable to set gpio pin tms\n"); } if (tck != _curr_tck) { +#ifdef GPIOD_APIV2 + if (gpiod_line_request_set_value(_tck_request, _tck_pin, + (tck == 0) ? GPIOD_LINE_VALUE_INACTIVE : + GPIOD_LINE_VALUE_ACTIVE) < 0) +#else if (gpiod_line_set_value(_tck_line, tck) < 0) +#endif display("Unable to set gpio pin tck\n"); } @@ -159,7 +271,18 @@ int LibgpiodJtagBitbang::update_pins(int tck, int tms, int tdi) int LibgpiodJtagBitbang::read_tdo() { +#ifdef GPIOD_APIV2 + gpiod_line_value req = gpiod_line_request_get_value( + _tdo_request, _tdo_pin); + if (req == GPIOD_LINE_VALUE_ERROR) + { + display("Error reading TDO line\n"); + throw std::runtime_error("Error reading TDO line\n"); + } + return (req == GPIOD_LINE_VALUE_ACTIVE) ? 1 : 0; +#else return gpiod_line_get_value(_tdo_line); +#endif } int LibgpiodJtagBitbang::setClkFreq(__attribute__((unused)) uint32_t clkHZ) diff --git a/src/libgpiodJtagBitbang.hpp b/src/libgpiodJtagBitbang.hpp index f5491d9..b77bd20 100644 --- a/src/libgpiodJtagBitbang.hpp +++ b/src/libgpiodJtagBitbang.hpp @@ -11,6 +11,8 @@ #include +#include "gpiod.h" + #include "board.hpp" #include "jtagInterface.hpp" @@ -40,23 +42,54 @@ class LibgpiodJtagBitbang : public JtagInterface { int flush() override { return 0; } private: +#ifndef GPIOD_APIV2 gpiod_line *get_line(unsigned int offset, int val, int dir); +#endif int update_pins(int tck, int tms, int tdi); int read_tdo(); bool _verbose; +#ifdef GPIOD_APIV2 + unsigned int _tck_pin; + unsigned int _tms_pin; + unsigned int _tdo_pin; + unsigned int _tdi_pin; +#else int _tck_pin; int _tms_pin; int _tdo_pin; int _tdi_pin; +#endif gpiod_chip *_chip; +#ifdef GPIOD_APIV2 + gpiod_request_config *_tck_req_cfg; + gpiod_request_config *_tms_req_cfg; + gpiod_request_config *_tdo_req_cfg; + gpiod_request_config *_tdi_req_cfg; + + gpiod_line_config *_tck_line_cfg; + gpiod_line_config *_tms_line_cfg; + gpiod_line_config *_tdo_line_cfg; + gpiod_line_config *_tdi_line_cfg; + + gpiod_line_settings *_tck_settings; + gpiod_line_settings *_tms_settings; + gpiod_line_settings *_tdo_settings; + gpiod_line_settings *_tdi_settings; + + gpiod_line_request *_tdo_request; + gpiod_line_request *_tdi_request; + gpiod_line_request *_tck_request; + gpiod_line_request *_tms_request; +#else gpiod_line *_tck_line; gpiod_line *_tms_line; gpiod_line *_tdo_line; gpiod_line *_tdi_line; +#endif int _curr_tms; int _curr_tdi; diff --git a/src/spiInterface.hpp b/src/spiInterface.hpp index 63b9ed5..76880ba 100644 --- a/src/spiInterface.hpp +++ b/src/spiInterface.hpp @@ -6,6 +6,7 @@ #ifndef SRC_SPIINTERFACE_HPP_ #define SRC_SPIINTERFACE_HPP_ +#include #include #include #include