@@ -57,6 +57,10 @@ LibgpiodJtagBitbang::LibgpiodJtagBitbang(
5757 /* Validate pins */
5858#ifdef GPIOD_APIV2
5959 const unsigned int pins[] = {_tck_pin, _tms_pin, _tdi_pin, _tdo_pin};
60+ _out_pins[0 ] = _tdi_group[0 ] = _tms_group[0 ] = _tck_pin;
61+ _out_pins[1 ] = _tdi_group[1 ] = _tdi_pin;
62+ _out_pins[2 ] = _tms_group[1 ] = _tms_pin;
63+ _out_pins[3 ] = _tdo_pin;
6064#else
6165 const int pins[] = {_tck_pin, _tms_pin, _tdi_pin, _tdo_pin};
6266#endif
@@ -81,72 +85,49 @@ LibgpiodJtagBitbang::LibgpiodJtagBitbang(
8185 }
8286
8387#ifdef GPIOD_APIV2
84- _tdo_req_cfg = gpiod_request_config_new ();
85- _tdi_req_cfg = gpiod_request_config_new ();
86- _tck_req_cfg = gpiod_request_config_new ();
87- _tms_req_cfg = gpiod_request_config_new ();
88+ _curr_tms = GPIOD_LINE_VALUE_ACTIVE;
89+ _curr_tdi = GPIOD_LINE_VALUE_INACTIVE;
8890
89- gpiod_request_config_set_consumer (_tdo_req_cfg, " _tdo" );
90- gpiod_request_config_set_consumer (_tdi_req_cfg, " _tdi" );
91- gpiod_request_config_set_consumer (_tck_req_cfg, " _tck" );
92- gpiod_request_config_set_consumer (_tms_req_cfg, " _tms" );
91+ _out_req_cfg = gpiod_request_config_new ();
9392
94- _tdo_settings = gpiod_line_settings_new ( );
95- _tdi_settings = gpiod_line_settings_new ();
96- _tck_settings = gpiod_line_settings_new ();
97- _tms_settings = gpiod_line_settings_new ();
93+ gpiod_request_config_set_consumer (_out_req_cfg, " openFPGALoader_out " );
94+
95+ _out_settings = gpiod_line_settings_new ();
96+ _in_settings = gpiod_line_settings_new ();
9897
9998 gpiod_line_settings_set_direction (
100- _tdo_settings, GPIOD_LINE_DIRECTION_INPUT);
101- gpiod_line_settings_set_direction (
102- _tdi_settings, GPIOD_LINE_DIRECTION_OUTPUT);
103- gpiod_line_settings_set_direction (
104- _tck_settings, GPIOD_LINE_DIRECTION_OUTPUT);
99+ _in_settings, GPIOD_LINE_DIRECTION_INPUT);
105100 gpiod_line_settings_set_direction (
106- _tms_settings , GPIOD_LINE_DIRECTION_OUTPUT);
101+ _out_settings , GPIOD_LINE_DIRECTION_OUTPUT);
107102
108103 gpiod_line_settings_set_bias (
109- _tdo_settings, GPIOD_LINE_BIAS_DISABLED);
110- gpiod_line_settings_set_bias (
111- _tdi_settings, GPIOD_LINE_BIAS_DISABLED);
104+ _in_settings, GPIOD_LINE_BIAS_DISABLED);
112105 gpiod_line_settings_set_bias (
113- _tck_settings, GPIOD_LINE_BIAS_DISABLED);
114- gpiod_line_settings_set_bias (
115- _tms_settings, GPIOD_LINE_BIAS_DISABLED);
106+ _out_settings, GPIOD_LINE_BIAS_DISABLED);
116107
117- _tdo_line_cfg = gpiod_line_config_new ();
118- _tdi_line_cfg = gpiod_line_config_new ();
119- _tck_line_cfg = gpiod_line_config_new ();
120- _tms_line_cfg = gpiod_line_config_new ();
108+ _out_line_cfg = gpiod_line_config_new ();
121109
122110 gpiod_line_config_add_line_settings (
123- _tdo_line_cfg, &_tdo_pin, 1 , _tdo_settings);
124- gpiod_line_config_add_line_settings (
125- _tdi_line_cfg, &_tdi_pin, 1 , _tdi_settings);
126- gpiod_line_config_add_line_settings (
127- _tck_line_cfg, &_tck_pin, 1 , _tck_settings);
111+ _out_line_cfg, _out_pins, 3 , _out_settings);
128112 gpiod_line_config_add_line_settings (
129- _tms_line_cfg, &_tms_pin, 1 , _tms_settings);
130-
131- _tdo_request = gpiod_chip_request_lines (
132- _chip, _tdo_req_cfg, _tdo_line_cfg);
133- _tdi_request = gpiod_chip_request_lines (
134- _chip, _tdi_req_cfg, _tdi_line_cfg);
135- _tck_request = gpiod_chip_request_lines (
136- _chip, _tck_req_cfg, _tck_line_cfg);
137- _tms_request = gpiod_chip_request_lines (
138- _chip, _tms_req_cfg, _tms_line_cfg);
113+ _out_line_cfg, &_out_pins[3 ], 1 , _in_settings);
114+
115+ _out_request = gpiod_chip_request_lines (
116+ _chip, _out_req_cfg, _out_line_cfg);
117+
118+ /* set default values for all GPIOs */
119+ enum gpiod_line_value val[3 ] = {GPIOD_LINE_VALUE_INACTIVE, _curr_tdi, _curr_tms};
120+ gpiod_line_request_set_values_subset (_out_request, 3 , _out_pins, val);
139121#else
122+ _curr_tdi = 0 ;
123+ _curr_tms = 1 ;
140124 _tdo_line = get_line (_tdo_pin, 0 , GPIOD_LINE_REQUEST_DIRECTION_INPUT);
141125 _tdi_line = get_line (_tdi_pin, 0 , GPIOD_LINE_REQUEST_DIRECTION_OUTPUT);
142126 _tck_line = get_line (_tck_pin, 0 , GPIOD_LINE_REQUEST_DIRECTION_OUTPUT);
143127 _tms_line = get_line (_tms_pin, 1 , GPIOD_LINE_REQUEST_DIRECTION_OUTPUT);
144128#endif
145129
146- _curr_tdi = 0 ;
147130 _curr_tck = 0 ;
148- _curr_tms = 1 ;
149-
150131 // FIXME: I'm unsure how this value should be set.
151132 // Maybe experiment, or think through what it should be.
152133 _clkHZ = 5000000 ;
@@ -155,33 +136,16 @@ LibgpiodJtagBitbang::LibgpiodJtagBitbang(
155136LibgpiodJtagBitbang::~LibgpiodJtagBitbang ()
156137{
157138#ifdef GPIOD_APIV2
158- if (_tms_request)
159- gpiod_line_request_release (_tms_request);
160- if (_tms_line_cfg)
161- gpiod_line_config_free (_tms_line_cfg);
162- if (_tms_settings)
163- gpiod_line_settings_free (_tms_settings);
164-
165- if (_tck_request)
166- gpiod_line_request_release (_tck_request);
167- if (_tck_line_cfg)
168- gpiod_line_config_free (_tck_line_cfg);
169- if (_tck_settings)
170- gpiod_line_settings_free (_tck_settings);
171-
172- if (_tdi_request)
173- gpiod_line_request_release (_tdi_request);
174- if (_tdi_line_cfg)
175- gpiod_line_config_free (_tdi_line_cfg);
176- if (_tdi_settings)
177- gpiod_line_settings_free (_tdi_settings);
178-
179- if (_tdo_request)
180- gpiod_line_request_release (_tdo_request);
181- if (_tdo_line_cfg)
182- gpiod_line_config_free (_tdo_line_cfg);
183- if (_tdo_settings)
184- gpiod_line_settings_free (_tdo_settings);
139+ if (_out_request)
140+ gpiod_line_request_release (_out_request);
141+
142+ if (_out_line_cfg)
143+ gpiod_line_config_free (_out_line_cfg);
144+
145+ if (_out_settings)
146+ gpiod_line_settings_free (_out_settings);
147+ if (_in_settings)
148+ gpiod_line_settings_free (_in_settings);
185149#else
186150 if (_tms_line)
187151 gpiod_line_release (_tms_line);
@@ -225,44 +189,50 @@ gpiod_line *LibgpiodJtagBitbang::get_line(unsigned int offset, int val, int dir)
225189}
226190#endif
227191
192+ #ifdef GPIOD_APIV2
193+ int LibgpiodJtagBitbang::update_pins (gpiod_line_value tms, gpiod_line_value tdi)
194+ #else
228195int LibgpiodJtagBitbang::update_pins (int tck, int tms, int tdi)
196+ #endif
229197{
230- if (tdi != _curr_tdi) {
231198#ifdef GPIOD_APIV2
232- if (gpiod_line_request_set_value (_tdi_request, _tdi_pin,
233- (tdi == 0 ) ? GPIOD_LINE_VALUE_INACTIVE :
234- GPIOD_LINE_VALUE_ACTIVE) < 0 )
199+ enum gpiod_line_value val[3 ] = {GPIOD_LINE_VALUE_INACTIVE, tdi, tms};
200+ bool tdi_wr = tdi != _curr_tdi;
201+ bool tms_wr = tms != _curr_tms;
202+
203+ if (tdi_wr & tms_wr) {
204+ gpiod_line_request_set_values_subset (_out_request, 3 , _out_pins, val);
205+ } else if (tdi_wr) {
206+ gpiod_line_request_set_values_subset (_out_request, 2 , _tdi_group, val);
207+ } else if (tms_wr) {
208+ val[1 ] = tms;
209+ gpiod_line_request_set_values_subset (_out_request, 2 , _tms_group, val);
210+ } else {
211+ gpiod_line_request_set_value (_out_request, _tck_pin,
212+ GPIOD_LINE_VALUE_INACTIVE);
213+ }
214+ gpiod_line_request_set_value (_out_request, _tck_pin,
215+ GPIOD_LINE_VALUE_ACTIVE);
235216#else
217+ if (tdi != _curr_tdi) {
236218 if (gpiod_line_set_value (_tdi_line, tdi) < 0 )
237- #endif
238219 display (" Unable to set gpio pin tdi\n " );
239220 }
240221
241222 if (tms != _curr_tms) {
242- #ifdef GPIOD_APIV2
243- if (gpiod_line_request_set_value (_tms_request, _tms_pin,
244- (tms == 0 ) ? GPIOD_LINE_VALUE_INACTIVE :
245- GPIOD_LINE_VALUE_ACTIVE) < 0 )
246- #else
247223 if (gpiod_line_set_value (_tms_line, tms) < 0 )
248- #endif
249224 display (" Unable to set gpio pin tms\n " );
250225 }
251226
252227 if (tck != _curr_tck) {
253- #ifdef GPIOD_APIV2
254- if (gpiod_line_request_set_value (_tck_request, _tck_pin,
255- (tck == 0 ) ? GPIOD_LINE_VALUE_INACTIVE :
256- GPIOD_LINE_VALUE_ACTIVE) < 0 )
257- #else
258228 if (gpiod_line_set_value (_tck_line, tck) < 0 )
259- #endif
260229 display (" Unable to set gpio pin tck\n " );
261230 }
262231
232+ _curr_tck = tck;
233+ #endif
263234 _curr_tdi = tdi;
264235 _curr_tms = tms;
265- _curr_tck = tck;
266236
267237 return 0 ;
268238}
@@ -271,7 +241,7 @@ int LibgpiodJtagBitbang::read_tdo()
271241{
272242#ifdef GPIOD_APIV2
273243 gpiod_line_value req = gpiod_line_request_get_value (
274- _tdo_request , _tdo_pin);
244+ _out_request , _tdo_pin);
275245 if (req == GPIOD_LINE_VALUE_ERROR)
276246 {
277247 display (" Error reading TDO line\n " );
@@ -295,32 +265,51 @@ int LibgpiodJtagBitbang::writeTMS(const uint8_t *tms_buf, uint32_t len,
295265 __attribute__ ((unused)) bool flush_buffer,
296266 __attribute__((unused)) uint8_t tdi)
297267{
298- int tms;
299-
300268 if (len == 0 ) // nothing -> stop
301269 return len;
302270
303271 for (uint32_t i = 0 ; i < len; i++) {
304- tms = ((tms_buf[i >> 3 ] & (1 << (i & 7 ))) ? 1 : 0 );
272+ #ifdef GPIOD_APIV2
273+ gpiod_line_value tms = ((tms_buf[i >> 3 ] & (1 << (i & 7 ))) ?
274+ GPIOD_LINE_VALUE_ACTIVE : GPIOD_LINE_VALUE_INACTIVE);
275+ update_pins (tms, _curr_tdi);
276+ #else
277+ int tms = ((tms_buf[i >> 3 ] & (1 << (i & 7 ))) ? 1 : 0 );
305278
306279 update_pins (0 , tms, 0 );
307280 update_pins (1 , tms, 0 );
281+ #endif
308282 }
309283
310- update_pins (0 , tms, 0 );
311-
312284 return len;
313285}
314286
315287int LibgpiodJtagBitbang::writeTDI (const uint8_t *tx, uint8_t *rx, uint32_t len, bool end)
316288{
289+ #ifdef GPIOD_APIV2
290+ gpiod_line_value tdi = GPIOD_LINE_VALUE_INACTIVE;
291+ #else
317292 int tms = _curr_tms;
318293 int tdi = _curr_tdi;
294+ #endif
319295
320296 if (rx)
321297 memset (rx, 0 , len / 8 );
322298
323299 for (uint32_t i = 0 ; i < len; i++) {
300+ #ifdef GPIOD_APIV2
301+ if (tx) {
302+ tdi = (tx[i >> 3 ] & (1 << (i & 7 ))) ?
303+ GPIOD_LINE_VALUE_ACTIVE : GPIOD_LINE_VALUE_INACTIVE;
304+ }
305+
306+ /* When TMS needs to be also updated (because of end) */
307+ if (end && (i == len - 1 )) {
308+ update_pins (GPIOD_LINE_VALUE_ACTIVE, tdi);
309+ } else {
310+ update_pins (GPIOD_LINE_VALUE_INACTIVE, tdi);
311+ }
312+ #else
324313 if (end && (i == len - 1 ))
325314 tms = 1 ;
326315
@@ -329,26 +318,28 @@ int LibgpiodJtagBitbang::writeTDI(const uint8_t *tx, uint8_t *rx, uint32_t len,
329318
330319 update_pins (0 , tms, tdi);
331320 update_pins (1 , tms, tdi);
321+ #endif
332322
333323 if (rx) {
334324 if (read_tdo () > 0 )
335325 rx[i >> 3 ] |= 1 << (i & 7 );
336326 }
337327 }
338328
339- update_pins (0 , tms, tdi);
340-
341329 return len;
342330}
343331
344332int LibgpiodJtagBitbang::toggleClk (uint8_t tms, uint8_t tdi, uint32_t clk_len)
345333{
346334 for (uint32_t i = 0 ; i < clk_len; i++) {
335+ #ifdef GPIOD_APIV2
336+ gpiod_line_request_set_value (_out_request, _tck_pin, GPIOD_LINE_VALUE_INACTIVE);
337+ gpiod_line_request_set_value (_out_request, _tck_pin, GPIOD_LINE_VALUE_ACTIVE);
338+ #else
347339 update_pins (0 , tms, tdi);
348340 update_pins (1 , tms, tdi);
341+ #endif
349342 }
350343
351- update_pins (0 , tms, tdi);
352-
353344 return clk_len;
354345}
0 commit comments