OpenOCD
sysfsgpio.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 
3 /***************************************************************************
4  * Copyright (C) 2012 by Creative Product Design, marc @ cpdesign.com.au *
5  ***************************************************************************/
6 
7 /* 2014-12: Addition of the SWD protocol support is based on the initial work
8  * on bcm2835gpio.c by Paul Fertser and modifications by Jean-Christian de Rivaz. */
9 
40 #ifdef HAVE_CONFIG_H
41 #include "config.h"
42 #endif
43 
44 #include <helper/time_support.h>
45 #include <jtag/interface.h>
46 #include <transport/transport.h>
47 #include "bitbang.h"
48 
49 /*
50  * Helper func to determine if gpio number valid
51  *
52  * Assume here that there will be less than 10000 gpios on a system
53  */
54 static bool is_gpio_valid(int gpio)
55 {
56  return gpio >= 0 && gpio < 10000;
57 }
58 
59 /*
60  * Helper func to open, write to and close a file
61  * name and valstr must be null terminated.
62  *
63  * Returns negative on failure.
64  */
65 static int open_write_close(const char *name, const char *valstr)
66 {
67  int ret;
68  int fd = open(name, O_WRONLY);
69  if (fd < 0)
70  return fd;
71 
72  ret = write(fd, valstr, strlen(valstr));
73  close(fd);
74 
75  return ret;
76 }
77 
78 /*
79  * Helper func to unexport gpio from sysfs
80  */
81 static void unexport_sysfs_gpio(int gpio)
82 {
83  char gpiostr[5];
84 
85  if (!is_gpio_valid(gpio))
86  return;
87 
88  snprintf(gpiostr, sizeof(gpiostr), "%d", gpio);
89  if (open_write_close("/sys/class/gpio/unexport", gpiostr) < 0)
90  LOG_ERROR("Couldn't unexport gpio %d", gpio);
91 }
92 
93 /*
94  * Exports and sets up direction for gpio.
95  * If the gpio is an output, it is initialized according to init_high,
96  * otherwise it is ignored.
97  *
98  * If the gpio is already exported we just show a warning and continue; if
99  * openocd happened to crash (or was killed by user) then the gpios will not
100  * have been cleaned up.
101  */
102 static int setup_sysfs_gpio(int gpio, int is_output, int init_high)
103 {
104  struct timeval timeout, now;
105  char buf[40];
106  char gpiostr[5];
107  int ret;
108 
109  if (!is_gpio_valid(gpio))
110  return ERROR_OK;
111 
112  snprintf(gpiostr, sizeof(gpiostr), "%d", gpio);
113  ret = open_write_close("/sys/class/gpio/export", gpiostr);
114  if (ret < 0) {
115  if (errno == EBUSY) {
116  LOG_WARNING("gpio %d is already exported", gpio);
117  } else {
118  LOG_ERROR("Couldn't export gpio %d", gpio);
119  LOG_ERROR("sysfsgpio: %s", strerror(errno));
120  return ERROR_FAIL;
121  }
122  }
123 
125  timeval_add_time(&timeout, 0, 500000);
126 
127  snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/direction", gpio);
128  for (;;) {
129  ret = open_write_close(buf, is_output ? (init_high ? "high" : "low") : "in");
130  if (ret >= 0 || errno != EACCES)
131  break;
132  gettimeofday(&now, NULL);
133  if (timeval_compare(&now, &timeout) >= 0)
134  break;
135  jtag_sleep(10000);
136  }
137  if (ret < 0) {
138  LOG_ERROR("Couldn't set direction for gpio %d", gpio);
139  LOG_ERROR("sysfsgpio: %s", strerror(errno));
140  unexport_sysfs_gpio(gpio);
141  return ERROR_FAIL;
142  }
143 
144  snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/value", gpio);
145  for (;;) {
146  ret = open(buf, O_RDWR | O_NONBLOCK | O_SYNC);
147  if (ret >= 0 || errno != EACCES)
148  break;
149  gettimeofday(&now, NULL);
150  if (timeval_compare(&now, &timeout) >= 0)
151  break;
152  jtag_sleep(10000);
153  }
154  if (ret < 0) {
155  LOG_ERROR("Couldn't open value for gpio %d", gpio);
156  LOG_ERROR("sysfsgpio: %s", strerror(errno));
157  unexport_sysfs_gpio(gpio);
158  }
159 
160  return ret;
161 }
162 
163 /* gpio numbers for each gpio. Negative values are invalid */
164 static int tck_gpio = -1;
165 static int tms_gpio = -1;
166 static int tdi_gpio = -1;
167 static int tdo_gpio = -1;
168 static int trst_gpio = -1;
169 static int srst_gpio = -1;
170 static int swclk_gpio = -1;
171 static int swdio_gpio = -1;
172 
173 /*
174  * file descriptors for /sys/class/gpio/gpioXX/value
175  * Set up during init.
176  */
177 static int tck_fd = -1;
178 static int tms_fd = -1;
179 static int tdi_fd = -1;
180 static int tdo_fd = -1;
181 static int trst_fd = -1;
182 static int srst_fd = -1;
183 static int swclk_fd = -1;
184 static int swdio_fd = -1;
185 
186 static int last_swclk;
187 static int last_swdio;
188 static bool last_stored;
189 static bool swdio_input;
190 
191 static void sysfsgpio_swdio_drive(bool is_output)
192 {
193  char buf[40];
194  int ret;
195 
196  snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/direction", swdio_gpio);
197  ret = open_write_close(buf, is_output ? "high" : "in");
198  if (ret < 0) {
199  LOG_ERROR("Couldn't set direction for gpio %d", swdio_gpio);
200  LOG_ERROR("sysfsgpio: %s", strerror(errno));
201  }
202 
203  last_stored = false;
204  swdio_input = !is_output;
205 }
206 
207 static int sysfsgpio_swdio_read(void)
208 {
209  char buf[1];
210 
211  /* important to seek to signal sysfs of new read */
212  lseek(swdio_fd, 0, SEEK_SET);
213  int ret = read(swdio_fd, &buf, sizeof(buf));
214 
215  if (ret < 0) {
216  LOG_WARNING("reading swdio failed");
217  return 0;
218  }
219 
220  return buf[0] != '0';
221 }
222 
223 static int sysfsgpio_swd_write(int swclk, int swdio)
224 {
225  const char one[] = "1";
226  const char zero[] = "0";
227 
228  size_t bytes_written;
229 
230  if (!swdio_input) {
231  if (!last_stored || (swdio != last_swdio)) {
232  bytes_written = write(swdio_fd, swdio ? &one : &zero, 1);
233  if (bytes_written != 1)
234  LOG_WARNING("writing swdio failed");
235  }
236  }
237 
238  /* write swclk last */
239  if (!last_stored || (swclk != last_swclk)) {
240  bytes_written = write(swclk_fd, swclk ? &one : &zero, 1);
241  if (bytes_written != 1)
242  LOG_WARNING("writing swclk failed");
243  }
244 
245  last_swdio = swdio;
246  last_swclk = swclk;
247  last_stored = true;
248 
249  return ERROR_OK;
250 }
251 
252 /*
253  * Bitbang interface read of TDO
254  *
255  * The sysfs value will read back either '0' or '1'. The trick here is to call
256  * lseek to bypass buffering in the sysfs kernel driver.
257  */
259 {
260  char buf[1];
261 
262  /* important to seek to signal sysfs of new read */
263  lseek(tdo_fd, 0, SEEK_SET);
264  int ret = read(tdo_fd, &buf, sizeof(buf));
265 
266  if (ret < 0) {
267  LOG_WARNING("reading tdo failed");
268  return 0;
269  }
270 
271  return buf[0] == '0' ? BB_LOW : BB_HIGH;
272 }
273 
274 /*
275  * Bitbang interface write of TCK, TMS, TDI
276  *
277  * Seeing as this is the only function where the outputs are changed,
278  * we can cache the old value to avoid needlessly writing it.
279  */
280 static int sysfsgpio_write(int tck, int tms, int tdi)
281 {
282  const char one[] = "1";
283  const char zero[] = "0";
284 
285  static int last_tck;
286  static int last_tms;
287  static int last_tdi;
288 
289  static int first_time;
290  size_t bytes_written;
291 
292  if (!first_time) {
293  last_tck = !tck;
294  last_tms = !tms;
295  last_tdi = !tdi;
296  first_time = 1;
297  }
298 
299  if (tdi != last_tdi) {
300  bytes_written = write(tdi_fd, tdi ? &one : &zero, 1);
301  if (bytes_written != 1)
302  LOG_WARNING("writing tdi failed");
303  }
304 
305  if (tms != last_tms) {
306  bytes_written = write(tms_fd, tms ? &one : &zero, 1);
307  if (bytes_written != 1)
308  LOG_WARNING("writing tms failed");
309  }
310 
311  /* write clk last */
312  if (tck != last_tck) {
313  bytes_written = write(tck_fd, tck ? &one : &zero, 1);
314  if (bytes_written != 1)
315  LOG_WARNING("writing tck failed");
316  }
317 
318  last_tdi = tdi;
319  last_tms = tms;
320  last_tck = tck;
321 
322  return ERROR_OK;
323 }
324 
325 /*
326  * Bitbang interface to manipulate reset lines SRST and TRST
327  *
328  * (1) assert or (0) deassert reset lines
329  */
330 static int sysfsgpio_reset(int trst, int srst)
331 {
332  LOG_DEBUG("sysfsgpio_reset");
333  const char one[] = "1";
334  const char zero[] = "0";
335  size_t bytes_written;
336 
337  /* assume active low */
338  if (srst_fd >= 0) {
339  bytes_written = write(srst_fd, srst ? &zero : &one, 1);
340  if (bytes_written != 1)
341  LOG_WARNING("writing srst failed");
342  }
343 
344  /* assume active low */
345  if (trst_fd >= 0) {
346  bytes_written = write(trst_fd, trst ? &zero : &one, 1);
347  if (bytes_written != 1)
348  LOG_WARNING("writing trst failed");
349  }
350 
351  return ERROR_OK;
352 }
353 
354 COMMAND_HANDLER(sysfsgpio_handle_jtag_gpionums)
355 {
356  if (CMD_ARGC == 4) {
361  } else if (CMD_ARGC != 0) {
363  }
364 
366  "SysfsGPIO nums: tck = %d, tms = %d, tdi = %d, tdo = %d",
368 
369  return ERROR_OK;
370 }
371 
372 COMMAND_HANDLER(sysfsgpio_handle_jtag_gpionum_tck)
373 {
374  if (CMD_ARGC == 1)
376 
377  command_print(CMD, "SysfsGPIO num: tck = %d", tck_gpio);
378  return ERROR_OK;
379 }
380 
381 COMMAND_HANDLER(sysfsgpio_handle_jtag_gpionum_tms)
382 {
383  if (CMD_ARGC == 1)
385 
386  command_print(CMD, "SysfsGPIO num: tms = %d", tms_gpio);
387  return ERROR_OK;
388 }
389 
390 COMMAND_HANDLER(sysfsgpio_handle_jtag_gpionum_tdo)
391 {
392  if (CMD_ARGC == 1)
394 
395  command_print(CMD, "SysfsGPIO num: tdo = %d", tdo_gpio);
396  return ERROR_OK;
397 }
398 
399 COMMAND_HANDLER(sysfsgpio_handle_jtag_gpionum_tdi)
400 {
401  if (CMD_ARGC == 1)
403 
404  command_print(CMD, "SysfsGPIO num: tdi = %d", tdi_gpio);
405  return ERROR_OK;
406 }
407 
408 COMMAND_HANDLER(sysfsgpio_handle_jtag_gpionum_srst)
409 {
410  if (CMD_ARGC == 1)
412 
413  command_print(CMD, "SysfsGPIO num: srst = %d", srst_gpio);
414  return ERROR_OK;
415 }
416 
417 COMMAND_HANDLER(sysfsgpio_handle_jtag_gpionum_trst)
418 {
419  if (CMD_ARGC == 1)
421 
422  command_print(CMD, "SysfsGPIO num: trst = %d", trst_gpio);
423  return ERROR_OK;
424 }
425 
426 COMMAND_HANDLER(sysfsgpio_handle_swd_gpionums)
427 {
428  if (CMD_ARGC == 2) {
431  } else if (CMD_ARGC != 0) {
433  }
434 
436  "SysfsGPIO nums: swclk = %d, swdio = %d",
438 
439  return ERROR_OK;
440 }
441 
442 COMMAND_HANDLER(sysfsgpio_handle_swd_gpionum_swclk)
443 {
444  if (CMD_ARGC == 1)
446 
447  command_print(CMD, "SysfsGPIO num: swclk = %d", swclk_gpio);
448  return ERROR_OK;
449 }
450 
451 COMMAND_HANDLER(sysfsgpio_handle_swd_gpionum_swdio)
452 {
453  if (CMD_ARGC == 1)
455 
456  command_print(CMD, "SysfsGPIO num: swdio = %d", swdio_gpio);
457  return ERROR_OK;
458 }
459 
460 static const struct command_registration sysfsgpio_subcommand_handlers[] = {
461  {
462  .name = "jtag_nums",
463  .handler = &sysfsgpio_handle_jtag_gpionums,
464  .mode = COMMAND_CONFIG,
465  .help = "gpio numbers for tck, tms, tdi, tdo. (in that order)",
466  .usage = "[tck tms tdi tdo]",
467  },
468  {
469  .name = "tck_num",
470  .handler = &sysfsgpio_handle_jtag_gpionum_tck,
471  .mode = COMMAND_CONFIG,
472  .help = "gpio number for tck.",
473  .usage = "[tck]",
474  },
475  {
476  .name = "tms_num",
477  .handler = &sysfsgpio_handle_jtag_gpionum_tms,
478  .mode = COMMAND_CONFIG,
479  .help = "gpio number for tms.",
480  .usage = "[tms]",
481  },
482  {
483  .name = "tdo_num",
484  .handler = &sysfsgpio_handle_jtag_gpionum_tdo,
485  .mode = COMMAND_CONFIG,
486  .help = "gpio number for tdo.",
487  .usage = "[tdo]",
488  },
489  {
490  .name = "tdi_num",
491  .handler = &sysfsgpio_handle_jtag_gpionum_tdi,
492  .mode = COMMAND_CONFIG,
493  .help = "gpio number for tdi.",
494  .usage = "[tdi]",
495  },
496  {
497  .name = "srst_num",
498  .handler = &sysfsgpio_handle_jtag_gpionum_srst,
499  .mode = COMMAND_CONFIG,
500  .help = "gpio number for srst.",
501  .usage = "[srst]",
502  },
503  {
504  .name = "trst_num",
505  .handler = &sysfsgpio_handle_jtag_gpionum_trst,
506  .mode = COMMAND_CONFIG,
507  .help = "gpio number for trst.",
508  .usage = "[trst]",
509  },
510  {
511  .name = "swd_nums",
512  .handler = &sysfsgpio_handle_swd_gpionums,
513  .mode = COMMAND_CONFIG,
514  .help = "gpio numbers for swclk, swdio. (in that order)",
515  .usage = "[swclk swdio]",
516  },
517  {
518  .name = "swclk_num",
519  .handler = &sysfsgpio_handle_swd_gpionum_swclk,
520  .mode = COMMAND_CONFIG,
521  .help = "gpio number for swclk.",
522  .usage = "[swclk]",
523  },
524  {
525  .name = "swdio_num",
526  .handler = &sysfsgpio_handle_swd_gpionum_swdio,
527  .mode = COMMAND_CONFIG,
528  .help = "gpio number for swdio.",
529  .usage = "[swdio]",
530  },
532 };
533 
534 static const struct command_registration sysfsgpio_command_handlers[] = {
535  {
536  .name = "sysfsgpio",
537  .mode = COMMAND_ANY,
538  .help = "perform sysfsgpio management",
540  .usage = "",
541  },
543 };
544 
545 static int sysfsgpio_init(void);
546 static int sysfsgpio_quit(void);
547 
548 static const char * const sysfsgpio_transports[] = { "jtag", "swd", NULL };
549 
550 static struct jtag_interface sysfsgpio_interface = {
552  .execute_queue = bitbang_execute_queue,
553 };
554 
556  .name = "sysfsgpio",
557  .transports = sysfsgpio_transports,
558  .commands = sysfsgpio_command_handlers,
559 
560  .init = sysfsgpio_init,
561  .quit = sysfsgpio_quit,
562  .reset = sysfsgpio_reset,
563 
564  .jtag_ops = &sysfsgpio_interface,
565  .swd_ops = &bitbang_swd,
566 };
567 
568 static struct bitbang_interface sysfsgpio_bitbang = {
569  .read = sysfsgpio_read,
570  .write = sysfsgpio_write,
571  .swdio_read = sysfsgpio_swdio_read,
572  .swdio_drive = sysfsgpio_swdio_drive,
573  .swd_write = sysfsgpio_swd_write,
574  .blink = NULL,
575 };
576 
577 /* helper func to close and cleanup files only if they were valid/ used */
578 static void cleanup_fd(int fd, int gpio)
579 {
580  if (gpio >= 0) {
581  if (fd >= 0)
582  close(fd);
583 
584  unexport_sysfs_gpio(gpio);
585  }
586 }
587 
588 static void cleanup_all_fds(void)
589 {
590  if (transport_is_jtag()) {
596  }
597  if (transport_is_swd()) {
600  }
602 }
603 
605 {
606  if (!is_gpio_valid(tck_gpio))
607  return false;
608  if (!is_gpio_valid(tms_gpio))
609  return false;
610  if (!is_gpio_valid(tdi_gpio))
611  return false;
612  if (!is_gpio_valid(tdo_gpio))
613  return false;
614  return true;
615 }
616 
618 {
620  return false;
622  return false;
623  return true;
624 }
625 
626 static int sysfsgpio_init(void)
627 {
629 
630  LOG_INFO("SysfsGPIO JTAG/SWD bitbang driver");
631 
632  /*
633  * Configure TDO as an input, and TDI, TCK, TMS, TRST, SRST
634  * as outputs. Drive TDI and TCK low, and TMS/TRST/SRST high.
635  * For SWD, SWCLK and SWDIO are configures as output high.
636  */
637 
638  if (transport_is_jtag()) {
640  LOG_ERROR("Require tck, tms, tdi and tdo gpios for JTAG mode");
641  return ERROR_JTAG_INIT_FAILED;
642  }
643 
645  if (tck_fd < 0)
646  goto out_error;
647 
649  if (tms_fd < 0)
650  goto out_error;
651 
653  if (tdi_fd < 0)
654  goto out_error;
655 
657  if (tdo_fd < 0)
658  goto out_error;
659 
660  /* assume active low*/
661  if (trst_gpio >= 0) {
663  if (trst_fd < 0)
664  goto out_error;
665  }
666  }
667 
668  if (transport_is_swd()) {
670  LOG_ERROR("Require swclk and swdio gpio for SWD mode");
671  return ERROR_JTAG_INIT_FAILED;
672  }
673 
675  if (swclk_fd < 0)
676  goto out_error;
677 
679  if (swdio_fd < 0)
680  goto out_error;
681  }
682 
683  /* assume active low*/
684  if (srst_gpio >= 0) {
686  if (srst_fd < 0)
687  goto out_error;
688  }
689 
690  return ERROR_OK;
691 
692 out_error:
693  cleanup_all_fds();
694  return ERROR_JTAG_INIT_FAILED;
695 }
696 
697 static int sysfsgpio_quit(void)
698 {
699  cleanup_all_fds();
700  return ERROR_OK;
701 }
bool transport_is_swd(void)
Returns true if the current debug session is using SWD as its transport.
Definition: adi_v5_swd.c:776
static int last_tms
Definition: arm-jtag-ew.c:528
const char * name
Definition: armv4_5.c:76
int bitbang_execute_queue(struct jtag_command *cmd_queue)
Definition: bitbang.c:296
const struct swd_driver bitbang_swd
Definition: bitbang.c:617
bb_value_t
Definition: bitbang.h:17
@ BB_LOW
Definition: bitbang.h:18
@ BB_HIGH
Definition: bitbang.h:19
void command_print(struct command_invocation *cmd, const char *format,...)
Definition: command.c:443
#define CMD
Use this macro to access the command being handled, rather than accessing the variable directly.
Definition: command.h:141
#define CMD_ARGV
Use this macro to access the arguments for the command being handled, rather than accessing the varia...
Definition: command.h:156
#define ERROR_COMMAND_SYNTAX_ERROR
Definition: command.h:402
#define CMD_ARGC
Use this macro to access the number of arguments for the command being handled, rather than accessing...
Definition: command.h:151
#define COMMAND_PARSE_NUMBER(type, in, out)
parses the string in into out as a type, or prints a command error and passes the error code to the c...
Definition: command.h:442
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
Definition: command.h:253
@ COMMAND_CONFIG
Definition: command.h:41
@ COMMAND_ANY
Definition: command.h:42
#define DEBUG_CAP_TMS_SEQ
Definition: interface.h:187
bool transport_is_jtag(void)
Returns true if the current debug session is using JTAG as its transport.
Definition: jtag/core.c:1828
void jtag_sleep(uint32_t us)
Definition: jtag/core.c:1062
#define ERROR_JTAG_INIT_FAILED
Definition: jtag.h:553
#define LOG_WARNING(expr ...)
Definition: log.h:129
#define ERROR_FAIL
Definition: log.h:170
#define LOG_ERROR(expr ...)
Definition: log.h:132
#define LOG_INFO(expr ...)
Definition: log.h:126
#define LOG_DEBUG(expr ...)
Definition: log.h:109
#define ERROR_OK
Definition: log.h:164
#define zero
Definition: mips32.c:165
int gettimeofday(struct timeval *tv, struct timezone *tz)
Represents a driver for a debugging interface.
Definition: interface.h:207
const char *const name
The name of the interface driver.
Definition: interface.h:209
Low level callbacks (for bitbang).
Definition: bitbang.h:30
bb_value_t(* read)(void)
Sample TDO and return the value.
Definition: bitbang.h:32
const char * name
Definition: command.h:235
const char * usage
a string listing the options and arguments, required or optional
Definition: command.h:241
Represents a driver for a debugging interface.
Definition: interface.h:182
unsigned supported
Bit vector listing capabilities exposed by this driver.
Definition: interface.h:186
Definition: psoc6.c:84
static int srst_gpio
Definition: sysfsgpio.c:169
static struct jtag_interface sysfsgpio_interface
Definition: sysfsgpio.c:550
static void cleanup_fd(int fd, int gpio)
Definition: sysfsgpio.c:578
static const struct command_registration sysfsgpio_command_handlers[]
Definition: sysfsgpio.c:534
static int tdi_gpio
Definition: sysfsgpio.c:166
static int sysfsgpio_reset(int trst, int srst)
Definition: sysfsgpio.c:330
static bool last_stored
Definition: sysfsgpio.c:188
static struct bitbang_interface sysfsgpio_bitbang
Definition: sysfsgpio.c:568
static const char *const sysfsgpio_transports[]
Definition: sysfsgpio.c:548
static int swdio_gpio
Definition: sysfsgpio.c:171
static int sysfsgpio_init(void)
Definition: sysfsgpio.c:626
static int last_swclk
Definition: sysfsgpio.c:186
static int setup_sysfs_gpio(int gpio, int is_output, int init_high)
Definition: sysfsgpio.c:102
static int sysfsgpio_swdio_read(void)
Definition: sysfsgpio.c:207
static int tdi_fd
Definition: sysfsgpio.c:179
static void sysfsgpio_swdio_drive(bool is_output)
Definition: sysfsgpio.c:191
static int tdo_gpio
Definition: sysfsgpio.c:167
static int open_write_close(const char *name, const char *valstr)
Definition: sysfsgpio.c:65
static int swclk_gpio
Definition: sysfsgpio.c:170
static int tck_fd
Definition: sysfsgpio.c:177
static void cleanup_all_fds(void)
Definition: sysfsgpio.c:588
static void unexport_sysfs_gpio(int gpio)
Definition: sysfsgpio.c:81
static int trst_gpio
Definition: sysfsgpio.c:168
static int tdo_fd
Definition: sysfsgpio.c:180
static int swclk_fd
Definition: sysfsgpio.c:183
static int sysfsgpio_write(int tck, int tms, int tdi)
Definition: sysfsgpio.c:280
struct adapter_driver sysfsgpio_adapter_driver
Definition: sysfsgpio.c:555
static int trst_fd
Definition: sysfsgpio.c:181
static int sysfsgpio_quit(void)
Definition: sysfsgpio.c:697
static int tck_gpio
Definition: sysfsgpio.c:164
static int swdio_fd
Definition: sysfsgpio.c:184
static bool sysfsgpio_jtag_mode_possible(void)
Definition: sysfsgpio.c:604
static int sysfsgpio_swd_write(int swclk, int swdio)
Definition: sysfsgpio.c:223
static int tms_gpio
Definition: sysfsgpio.c:165
static bool is_gpio_valid(int gpio)
Definition: sysfsgpio.c:54
static int last_swdio
Definition: sysfsgpio.c:187
static bool swdio_input
Definition: sysfsgpio.c:189
static int tms_fd
Definition: sysfsgpio.c:178
static const struct command_registration sysfsgpio_subcommand_handlers[]
Definition: sysfsgpio.c:460
static int srst_fd
Definition: sysfsgpio.c:182
COMMAND_HANDLER(sysfsgpio_handle_jtag_gpionums)
Definition: sysfsgpio.c:354
static bool sysfsgpio_swd_mode_possible(void)
Definition: sysfsgpio.c:617
static bb_value_t sysfsgpio_read(void)
Definition: sysfsgpio.c:258
int timeval_compare(const struct timeval *x, const struct timeval *y)
Definition: time_support.c:55
int timeval_add_time(struct timeval *result, long sec, long usec)
Definition: time_support.c:41
#define NULL
Definition: usb.h:16