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  char buf[40];
105  char gpiostr[5];
106  int ret;
107 
108  if (!is_gpio_valid(gpio))
109  return ERROR_OK;
110 
111  snprintf(gpiostr, sizeof(gpiostr), "%d", gpio);
112  ret = open_write_close("/sys/class/gpio/export", gpiostr);
113  if (ret < 0) {
114  if (errno == EBUSY) {
115  LOG_WARNING("gpio %d is already exported", gpio);
116  } else {
117  LOG_ERROR("Couldn't export gpio %d", gpio);
118  LOG_ERROR("sysfsgpio: %s", strerror(errno));
119  return ERROR_FAIL;
120  }
121  }
122 
123  // 500 ms timeout
124  int64_t then = timeval_ms() + 500;
125 
126  snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/direction", gpio);
127  for (;;) {
128  ret = open_write_close(buf, is_output ? (init_high ? "high" : "low") : "in");
129  if (ret >= 0 || errno != EACCES)
130  break;
131  if (timeval_ms() >= then)
132  break;
133  jtag_sleep(10000);
134  }
135  if (ret < 0) {
136  LOG_ERROR("Couldn't set direction for gpio %d", gpio);
137  LOG_ERROR("sysfsgpio: %s", strerror(errno));
138  unexport_sysfs_gpio(gpio);
139  return ERROR_FAIL;
140  }
141 
142  snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/value", gpio);
143  for (;;) {
144  ret = open(buf, O_RDWR | O_NONBLOCK | O_SYNC);
145  if (ret >= 0 || errno != EACCES)
146  break;
147  if (timeval_ms() >= then)
148  break;
149  jtag_sleep(10000);
150  }
151  if (ret < 0) {
152  LOG_ERROR("Couldn't open value for gpio %d", gpio);
153  LOG_ERROR("sysfsgpio: %s", strerror(errno));
154  unexport_sysfs_gpio(gpio);
155  }
156 
157  return ret;
158 }
159 
160 /* gpio numbers for each gpio. Negative values are invalid */
161 static int tck_gpio = -1;
162 static int tms_gpio = -1;
163 static int tdi_gpio = -1;
164 static int tdo_gpio = -1;
165 static int trst_gpio = -1;
166 static int srst_gpio = -1;
167 static int swclk_gpio = -1;
168 static int swdio_gpio = -1;
169 
170 /*
171  * file descriptors for /sys/class/gpio/gpioXX/value
172  * Set up during init.
173  */
174 static int tck_fd = -1;
175 static int tms_fd = -1;
176 static int tdi_fd = -1;
177 static int tdo_fd = -1;
178 static int trst_fd = -1;
179 static int srst_fd = -1;
180 static int swclk_fd = -1;
181 static int swdio_fd = -1;
182 
183 static int last_swclk;
184 static int last_swdio;
185 static bool last_stored;
186 static bool swdio_input;
187 
188 static void sysfsgpio_swdio_drive(bool is_output)
189 {
190  char buf[40];
191  int ret;
192 
193  snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/direction", swdio_gpio);
194  ret = open_write_close(buf, is_output ? "high" : "in");
195  if (ret < 0) {
196  LOG_ERROR("Couldn't set direction for gpio %d", swdio_gpio);
197  LOG_ERROR("sysfsgpio: %s", strerror(errno));
198  }
199 
200  last_stored = false;
201  swdio_input = !is_output;
202 }
203 
204 static int sysfsgpio_swdio_read(void)
205 {
206  char buf[1];
207 
208  /* important to seek to signal sysfs of new read */
209  lseek(swdio_fd, 0, SEEK_SET);
210  int ret = read(swdio_fd, &buf, sizeof(buf));
211 
212  if (ret < 0) {
213  LOG_WARNING("reading swdio failed");
214  return 0;
215  }
216 
217  return buf[0] != '0';
218 }
219 
220 static int sysfsgpio_swd_write(int swclk, int swdio)
221 {
222  const char one[] = "1";
223  const char zero[] = "0";
224 
225  size_t bytes_written;
226 
227  if (!swdio_input) {
228  if (!last_stored || (swdio != last_swdio)) {
229  bytes_written = write(swdio_fd, swdio ? &one : &zero, 1);
230  if (bytes_written != 1)
231  LOG_WARNING("writing swdio failed");
232  }
233  }
234 
235  /* write swclk last */
236  if (!last_stored || (swclk != last_swclk)) {
237  bytes_written = write(swclk_fd, swclk ? &one : &zero, 1);
238  if (bytes_written != 1)
239  LOG_WARNING("writing swclk failed");
240  }
241 
242  last_swdio = swdio;
243  last_swclk = swclk;
244  last_stored = true;
245 
246  return ERROR_OK;
247 }
248 
249 /*
250  * Bitbang interface read of TDO
251  *
252  * The sysfs value will read back either '0' or '1'. The trick here is to call
253  * lseek to bypass buffering in the sysfs kernel driver.
254  */
255 static enum bb_value sysfsgpio_read(void)
256 {
257  char buf[1];
258 
259  /* important to seek to signal sysfs of new read */
260  lseek(tdo_fd, 0, SEEK_SET);
261  int ret = read(tdo_fd, &buf, sizeof(buf));
262 
263  if (ret < 0) {
264  LOG_WARNING("reading tdo failed");
265  return 0;
266  }
267 
268  return buf[0] == '0' ? BB_LOW : BB_HIGH;
269 }
270 
271 /*
272  * Bitbang interface write of TCK, TMS, TDI
273  *
274  * Seeing as this is the only function where the outputs are changed,
275  * we can cache the old value to avoid needlessly writing it.
276  */
277 static int sysfsgpio_write(int tck, int tms, int tdi)
278 {
279  const char one[] = "1";
280  const char zero[] = "0";
281 
282  static int last_tck;
283  static int last_tms;
284  static int last_tdi;
285 
286  static int first_time;
287  size_t bytes_written;
288 
289  if (!first_time) {
290  last_tck = !tck;
291  last_tms = !tms;
292  last_tdi = !tdi;
293  first_time = 1;
294  }
295 
296  if (tdi != last_tdi) {
297  bytes_written = write(tdi_fd, tdi ? &one : &zero, 1);
298  if (bytes_written != 1)
299  LOG_WARNING("writing tdi failed");
300  }
301 
302  if (tms != last_tms) {
303  bytes_written = write(tms_fd, tms ? &one : &zero, 1);
304  if (bytes_written != 1)
305  LOG_WARNING("writing tms failed");
306  }
307 
308  /* write clk last */
309  if (tck != last_tck) {
310  bytes_written = write(tck_fd, tck ? &one : &zero, 1);
311  if (bytes_written != 1)
312  LOG_WARNING("writing tck failed");
313  }
314 
315  last_tdi = tdi;
316  last_tms = tms;
317  last_tck = tck;
318 
319  return ERROR_OK;
320 }
321 
322 /*
323  * Bitbang interface to manipulate reset lines SRST and TRST
324  *
325  * (1) assert or (0) deassert reset lines
326  */
327 static int sysfsgpio_reset(int trst, int srst)
328 {
329  LOG_DEBUG("sysfsgpio_reset");
330  const char one[] = "1";
331  const char zero[] = "0";
332  size_t bytes_written;
333 
334  /* assume active low */
335  if (srst_fd >= 0) {
336  bytes_written = write(srst_fd, srst ? &zero : &one, 1);
337  if (bytes_written != 1)
338  LOG_WARNING("writing srst failed");
339  }
340 
341  /* assume active low */
342  if (trst_fd >= 0) {
343  bytes_written = write(trst_fd, trst ? &zero : &one, 1);
344  if (bytes_written != 1)
345  LOG_WARNING("writing trst failed");
346  }
347 
348  return ERROR_OK;
349 }
350 
351 COMMAND_HANDLER(sysfsgpio_handle_jtag_gpionums)
352 {
353  if (CMD_ARGC == 4) {
358  } else if (CMD_ARGC != 0) {
360  }
361 
363  "SysfsGPIO nums: tck = %d, tms = %d, tdi = %d, tdo = %d",
365 
366  return ERROR_OK;
367 }
368 
369 COMMAND_HANDLER(sysfsgpio_handle_jtag_gpionum_tck)
370 {
371  if (CMD_ARGC == 1)
373 
374  command_print(CMD, "SysfsGPIO num: tck = %d", tck_gpio);
375  return ERROR_OK;
376 }
377 
378 COMMAND_HANDLER(sysfsgpio_handle_jtag_gpionum_tms)
379 {
380  if (CMD_ARGC == 1)
382 
383  command_print(CMD, "SysfsGPIO num: tms = %d", tms_gpio);
384  return ERROR_OK;
385 }
386 
387 COMMAND_HANDLER(sysfsgpio_handle_jtag_gpionum_tdo)
388 {
389  if (CMD_ARGC == 1)
391 
392  command_print(CMD, "SysfsGPIO num: tdo = %d", tdo_gpio);
393  return ERROR_OK;
394 }
395 
396 COMMAND_HANDLER(sysfsgpio_handle_jtag_gpionum_tdi)
397 {
398  if (CMD_ARGC == 1)
400 
401  command_print(CMD, "SysfsGPIO num: tdi = %d", tdi_gpio);
402  return ERROR_OK;
403 }
404 
405 COMMAND_HANDLER(sysfsgpio_handle_jtag_gpionum_srst)
406 {
407  if (CMD_ARGC == 1)
409 
410  command_print(CMD, "SysfsGPIO num: srst = %d", srst_gpio);
411  return ERROR_OK;
412 }
413 
414 COMMAND_HANDLER(sysfsgpio_handle_jtag_gpionum_trst)
415 {
416  if (CMD_ARGC == 1)
418 
419  command_print(CMD, "SysfsGPIO num: trst = %d", trst_gpio);
420  return ERROR_OK;
421 }
422 
423 COMMAND_HANDLER(sysfsgpio_handle_swd_gpionums)
424 {
425  if (CMD_ARGC == 2) {
428  } else if (CMD_ARGC != 0) {
430  }
431 
433  "SysfsGPIO nums: swclk = %d, swdio = %d",
435 
436  return ERROR_OK;
437 }
438 
439 COMMAND_HANDLER(sysfsgpio_handle_swd_gpionum_swclk)
440 {
441  if (CMD_ARGC == 1)
443 
444  command_print(CMD, "SysfsGPIO num: swclk = %d", swclk_gpio);
445  return ERROR_OK;
446 }
447 
448 COMMAND_HANDLER(sysfsgpio_handle_swd_gpionum_swdio)
449 {
450  if (CMD_ARGC == 1)
452 
453  command_print(CMD, "SysfsGPIO num: swdio = %d", swdio_gpio);
454  return ERROR_OK;
455 }
456 
457 static const struct command_registration sysfsgpio_subcommand_handlers[] = {
458  {
459  .name = "jtag_nums",
460  .handler = &sysfsgpio_handle_jtag_gpionums,
461  .mode = COMMAND_CONFIG,
462  .help = "gpio numbers for tck, tms, tdi, tdo. (in that order)",
463  .usage = "[tck tms tdi tdo]",
464  },
465  {
466  .name = "tck_num",
467  .handler = &sysfsgpio_handle_jtag_gpionum_tck,
468  .mode = COMMAND_CONFIG,
469  .help = "gpio number for tck.",
470  .usage = "[tck]",
471  },
472  {
473  .name = "tms_num",
474  .handler = &sysfsgpio_handle_jtag_gpionum_tms,
475  .mode = COMMAND_CONFIG,
476  .help = "gpio number for tms.",
477  .usage = "[tms]",
478  },
479  {
480  .name = "tdo_num",
481  .handler = &sysfsgpio_handle_jtag_gpionum_tdo,
482  .mode = COMMAND_CONFIG,
483  .help = "gpio number for tdo.",
484  .usage = "[tdo]",
485  },
486  {
487  .name = "tdi_num",
488  .handler = &sysfsgpio_handle_jtag_gpionum_tdi,
489  .mode = COMMAND_CONFIG,
490  .help = "gpio number for tdi.",
491  .usage = "[tdi]",
492  },
493  {
494  .name = "srst_num",
495  .handler = &sysfsgpio_handle_jtag_gpionum_srst,
496  .mode = COMMAND_CONFIG,
497  .help = "gpio number for srst.",
498  .usage = "[srst]",
499  },
500  {
501  .name = "trst_num",
502  .handler = &sysfsgpio_handle_jtag_gpionum_trst,
503  .mode = COMMAND_CONFIG,
504  .help = "gpio number for trst.",
505  .usage = "[trst]",
506  },
507  {
508  .name = "swd_nums",
509  .handler = &sysfsgpio_handle_swd_gpionums,
510  .mode = COMMAND_CONFIG,
511  .help = "gpio numbers for swclk, swdio. (in that order)",
512  .usage = "[swclk swdio]",
513  },
514  {
515  .name = "swclk_num",
516  .handler = &sysfsgpio_handle_swd_gpionum_swclk,
517  .mode = COMMAND_CONFIG,
518  .help = "gpio number for swclk.",
519  .usage = "[swclk]",
520  },
521  {
522  .name = "swdio_num",
523  .handler = &sysfsgpio_handle_swd_gpionum_swdio,
524  .mode = COMMAND_CONFIG,
525  .help = "gpio number for swdio.",
526  .usage = "[swdio]",
527  },
529 };
530 
531 static const struct command_registration sysfsgpio_command_handlers[] = {
532  {
533  .name = "sysfsgpio",
534  .mode = COMMAND_ANY,
535  .help = "perform sysfsgpio management",
537  .usage = "",
538  },
540 };
541 
542 static int sysfsgpio_init(void);
543 static int sysfsgpio_quit(void);
544 
545 static struct jtag_interface sysfsgpio_interface = {
547  .execute_queue = bitbang_execute_queue,
548 };
549 
551  .name = "sysfsgpio",
552  .transport_ids = TRANSPORT_JTAG | TRANSPORT_SWD,
553  .transport_preferred_id = TRANSPORT_JTAG,
554  .commands = sysfsgpio_command_handlers,
555 
556  .init = sysfsgpio_init,
557  .quit = sysfsgpio_quit,
558  .reset = sysfsgpio_reset,
559 
560  .jtag_ops = &sysfsgpio_interface,
561  .swd_ops = &bitbang_swd,
562 };
563 
564 static const struct bitbang_interface sysfsgpio_bitbang = {
565  .read = sysfsgpio_read,
566  .write = sysfsgpio_write,
567  .swdio_read = sysfsgpio_swdio_read,
568  .swdio_drive = sysfsgpio_swdio_drive,
569  .swd_write = sysfsgpio_swd_write,
570  .blink = NULL,
571 };
572 
573 /* helper func to close and cleanup files only if they were valid/ used */
574 static void cleanup_fd(int fd, int gpio)
575 {
576  if (gpio >= 0) {
577  if (fd >= 0)
578  close(fd);
579 
580  unexport_sysfs_gpio(gpio);
581  }
582 }
583 
584 static void cleanup_all_fds(void)
585 {
586  if (transport_is_jtag()) {
592  }
593  if (transport_is_swd()) {
596  }
598 }
599 
601 {
602  if (!is_gpio_valid(tck_gpio))
603  return false;
604  if (!is_gpio_valid(tms_gpio))
605  return false;
606  if (!is_gpio_valid(tdi_gpio))
607  return false;
608  if (!is_gpio_valid(tdo_gpio))
609  return false;
610  return true;
611 }
612 
614 {
616  return false;
618  return false;
619  return true;
620 }
621 
622 static int sysfsgpio_init(void)
623 {
625 
626  LOG_INFO("SysfsGPIO JTAG/SWD bitbang driver");
627 
628  /*
629  * Configure TDO as an input, and TDI, TCK, TMS, TRST, SRST
630  * as outputs. Drive TDI and TCK low, and TMS/TRST/SRST high.
631  * For SWD, SWCLK and SWDIO are configures as output high.
632  */
633 
634  if (transport_is_jtag()) {
636  LOG_ERROR("Require tck, tms, tdi and tdo gpios for JTAG mode");
637  return ERROR_JTAG_INIT_FAILED;
638  }
639 
641  if (tck_fd < 0)
642  goto out_error;
643 
645  if (tms_fd < 0)
646  goto out_error;
647 
649  if (tdi_fd < 0)
650  goto out_error;
651 
653  if (tdo_fd < 0)
654  goto out_error;
655 
656  /* assume active low*/
657  if (trst_gpio >= 0) {
659  if (trst_fd < 0)
660  goto out_error;
661  }
662  }
663 
664  if (transport_is_swd()) {
666  LOG_ERROR("Require swclk and swdio gpio for SWD mode");
667  return ERROR_JTAG_INIT_FAILED;
668  }
669 
671  if (swclk_fd < 0)
672  goto out_error;
673 
675  if (swdio_fd < 0)
676  goto out_error;
677  }
678 
679  /* assume active low*/
680  if (srst_gpio >= 0) {
682  if (srst_fd < 0)
683  goto out_error;
684  }
685 
686  return ERROR_OK;
687 
688 out_error:
689  cleanup_all_fds();
690  return ERROR_JTAG_INIT_FAILED;
691 }
692 
693 static int sysfsgpio_quit(void)
694 {
695  cleanup_all_fds();
696  return ERROR_OK;
697 }
bool transport_is_swd(void)
Returns true if the current debug session is using SWD as its transport.
Definition: adi_v5_swd.c:772
static int last_tms
Definition: arm-jtag-ew.c:522
const char * name
Definition: armv4_5.c:75
int bitbang_execute_queue(struct jtag_command *cmd_queue)
Definition: bitbang.c:293
const struct swd_driver bitbang_swd
Definition: bitbang.c:616
bb_value
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:389
#define CMD
Use this macro to access the command being handled, rather than accessing the variable directly.
Definition: command.h:146
#define CMD_ARGV
Use this macro to access the arguments for the command being handled, rather than accessing the varia...
Definition: command.h:161
#define ERROR_COMMAND_SYNTAX_ERROR
Definition: command.h:405
#define CMD_ARGC
Use this macro to access the number of arguments for the command being handled, rather than accessing...
Definition: command.h:156
#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:445
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
Definition: command.h:256
@ COMMAND_CONFIG
Definition: command.h:41
@ COMMAND_ANY
Definition: command.h:42
#define DEBUG_CAP_TMS_SEQ
Definition: interface.h:188
bool transport_is_jtag(void)
Returns true if the current debug session is using JTAG as its transport.
Definition: jtag/core.c:1839
void jtag_sleep(uint32_t us)
Definition: jtag/core.c:1074
#define ERROR_JTAG_INIT_FAILED
Definition: jtag.h:552
#define LOG_WARNING(expr ...)
Definition: log.h:144
#define ERROR_FAIL
Definition: log.h:188
#define LOG_ERROR(expr ...)
Definition: log.h:147
#define LOG_INFO(expr ...)
Definition: log.h:141
#define LOG_DEBUG(expr ...)
Definition: log.h:124
#define ERROR_OK
Definition: log.h:182
#define zero
Definition: mips32.c:181
Represents a driver for a debugging interface.
Definition: interface.h:208
const char *const name
The name of the interface driver.
Definition: interface.h:210
Low level callbacks (for bitbang).
Definition: bitbang.h:30
enum bb_value(* read)(void)
Sample TDO and return the value.
Definition: bitbang.h:32
const char * name
Definition: command.h:239
const char * usage
a string listing the options and arguments, required or optional
Definition: command.h:244
Represents a driver for a debugging interface.
Definition: interface.h:183
unsigned int supported
Bit vector listing capabilities exposed by this driver.
Definition: interface.h:187
static int srst_gpio
Definition: sysfsgpio.c:166
static struct jtag_interface sysfsgpio_interface
Definition: sysfsgpio.c:545
static void cleanup_fd(int fd, int gpio)
Definition: sysfsgpio.c:574
static const struct command_registration sysfsgpio_command_handlers[]
Definition: sysfsgpio.c:531
static int tdi_gpio
Definition: sysfsgpio.c:163
static int sysfsgpio_reset(int trst, int srst)
Definition: sysfsgpio.c:327
static bool last_stored
Definition: sysfsgpio.c:185
static int swdio_gpio
Definition: sysfsgpio.c:168
static int sysfsgpio_init(void)
Definition: sysfsgpio.c:622
static int last_swclk
Definition: sysfsgpio.c:183
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:204
static enum bb_value sysfsgpio_read(void)
Definition: sysfsgpio.c:255
static int tdi_fd
Definition: sysfsgpio.c:176
static void sysfsgpio_swdio_drive(bool is_output)
Definition: sysfsgpio.c:188
static int tdo_gpio
Definition: sysfsgpio.c:164
static int open_write_close(const char *name, const char *valstr)
Definition: sysfsgpio.c:65
static int swclk_gpio
Definition: sysfsgpio.c:167
static int tck_fd
Definition: sysfsgpio.c:174
static void cleanup_all_fds(void)
Definition: sysfsgpio.c:584
static void unexport_sysfs_gpio(int gpio)
Definition: sysfsgpio.c:81
static int trst_gpio
Definition: sysfsgpio.c:165
static int tdo_fd
Definition: sysfsgpio.c:177
static int swclk_fd
Definition: sysfsgpio.c:180
static int sysfsgpio_write(int tck, int tms, int tdi)
Definition: sysfsgpio.c:277
static const struct bitbang_interface sysfsgpio_bitbang
Definition: sysfsgpio.c:564
struct adapter_driver sysfsgpio_adapter_driver
Definition: sysfsgpio.c:550
static int trst_fd
Definition: sysfsgpio.c:178
static int sysfsgpio_quit(void)
Definition: sysfsgpio.c:693
static int tck_gpio
Definition: sysfsgpio.c:161
static int swdio_fd
Definition: sysfsgpio.c:181
static bool sysfsgpio_jtag_mode_possible(void)
Definition: sysfsgpio.c:600
static int sysfsgpio_swd_write(int swclk, int swdio)
Definition: sysfsgpio.c:220
static int tms_gpio
Definition: sysfsgpio.c:162
static bool is_gpio_valid(int gpio)
Definition: sysfsgpio.c:54
static int last_swdio
Definition: sysfsgpio.c:184
static bool swdio_input
Definition: sysfsgpio.c:186
static int tms_fd
Definition: sysfsgpio.c:175
static const struct command_registration sysfsgpio_subcommand_handlers[]
Definition: sysfsgpio.c:457
static int srst_fd
Definition: sysfsgpio.c:179
COMMAND_HANDLER(sysfsgpio_handle_jtag_gpionums)
Definition: sysfsgpio.c:351
static bool sysfsgpio_swd_mode_possible(void)
Definition: sysfsgpio.c:613
int64_t timeval_ms(void)
#define TRANSPORT_SWD
Definition: transport.h:20
#define TRANSPORT_JTAG
Definition: transport.h:19
#define NULL
Definition: usb.h:16