OpenOCD
am335xgpio.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 
3 /***************************************************************************
4  * Copyright (C) 2022 by Steve Marple, stevemarple@googlemail.com *
5  * *
6  * Based on bcm2835gpio.c and linuxgpiod.c *
7  ***************************************************************************/
8 
9 #ifdef HAVE_CONFIG_H
10 #include "config.h"
11 #endif
12 
13 #include <jtag/adapter.h>
14 #include <jtag/interface.h>
15 #include <transport/transport.h>
16 #include "bitbang.h"
17 
18 #include <sys/mman.h>
19 
20 /* GPIO register base addresses. Values taken from "AM335x and AMIC110 Sitara
21  * Processors Technical Reference Manual", Chapter 2 Memory Map.
22  */
23 #define AM335XGPIO_NUM_GPIO_PER_CHIP 32
24 #define AM335XGPIO_NUM_GPIO_CHIPS 4
25 #define AM335XGPIO_GPIO0_HW_ADDR 0x44E07000
26 #define AM335XGPIO_GPIO1_HW_ADDR 0x4804C000
27 #define AM335XGPIO_GPIO2_HW_ADDR 0x481AC000
28 #define AM335XGPIO_GPIO3_HW_ADDR 0x481AE000
29 
30 /* 32-bit offsets from GPIO chip base address. Values taken from "AM335x and
31  * AMIC110 Sitara Processors Technical Reference Manual", Chapter 25
32  * General-Purpose Input/Output.
33  */
34 #define AM335XGPIO_GPIO_OE_OFFSET (0x134 / 4)
35 #define AM335XGPIO_GPIO_DATAIN_OFFSET (0x138 / 4)
36 #define AM335XGPIO_GPIO_DATAOUT_OFFSET (0x13C / 4) /* DATAOUT register uses 0 for output, 1 for input */
37 #define AM335XGPIO_GPIO_CLEARDATAOUT_OFFSET (0x190 / 4)
38 #define AM335XGPIO_GPIO_SETDATAOUT_OFFSET (0x194 / 4)
39 
40 #define AM335XGPIO_READ_REG(chip_num, offset) \
41  (*(am335xgpio_gpio_chip_mmap_addr[(chip_num)] + (offset)))
42 
43 #define AM335XGPIO_WRITE_REG(chip_num, offset, value) \
44  (*(am335xgpio_gpio_chip_mmap_addr[(chip_num)] + (offset)) = (value))
45 
46 #define AM335XGPIO_SET_REG_BITS(chip_num, offset, bit_mask) \
47  (*(am335xgpio_gpio_chip_mmap_addr[(chip_num)] + (offset)) |= (bit_mask))
48 
49 #define AM335XGPIO_CLEAR_REG_BITS(chip_num, offset, bit_mask) \
50  (*(am335xgpio_gpio_chip_mmap_addr[(chip_num)] + (offset)) &= ~(bit_mask))
51 
52 #define AM335XGPIO_SET_INPUT(gpio_config) \
53  AM335XGPIO_SET_REG_BITS((gpio_config)->chip_num, AM335XGPIO_GPIO_OE_OFFSET, BIT((gpio_config)->gpio_num))
54 #define AM335XGPIO_SET_OUTPUT(gpio_config) \
55  AM335XGPIO_CLEAR_REG_BITS((gpio_config)->chip_num, AM335XGPIO_GPIO_OE_OFFSET, BIT((gpio_config)->gpio_num))
56 #define AM335XGPIO_SET_HIGH(gpio_config) \
57  AM335XGPIO_WRITE_REG((gpio_config)->chip_num, AM335XGPIO_GPIO_SETDATAOUT_OFFSET, BIT((gpio_config)->gpio_num))
58 #define AM335XGPIO_SET_LOW(gpio_config) \
59  AM335XGPIO_WRITE_REG((gpio_config)->chip_num, AM335XGPIO_GPIO_CLEARDATAOUT_OFFSET, BIT((gpio_config)->gpio_num))
60 
65 };
66 
72 };
73 
74 /* Memory-mapped address pointers */
76 
77 static int dev_mem_fd;
79 
80 /* Transition delay coefficients */
81 static int speed_coeff = 600000;
82 static int speed_offset = 575;
83 static unsigned int jtag_delay;
84 
86 
87 static bool is_gpio_config_valid(const struct adapter_gpio_config *gpio_config)
88 {
89  return gpio_config->chip_num < AM335XGPIO_NUM_GPIO_CHIPS
90  && gpio_config->gpio_num < AM335XGPIO_NUM_GPIO_PER_CHIP;
91 }
92 
93 static int get_gpio_value(const struct adapter_gpio_config *gpio_config)
94 {
95  unsigned int shift = gpio_config->gpio_num;
96  uint32_t value = AM335XGPIO_READ_REG(gpio_config->chip_num, AM335XGPIO_GPIO_DATAIN_OFFSET);
97  value = (value >> shift) & 1;
98  return value ^ (gpio_config->active_low ? 1 : 0);
99 }
100 
101 static void set_gpio_value(const struct adapter_gpio_config *gpio_config, int value)
102 {
103  value = value ^ (gpio_config->active_low ? 1 : 0);
104  switch (gpio_config->drive) {
106  if (value)
107  AM335XGPIO_SET_HIGH(gpio_config);
108  else
109  AM335XGPIO_SET_LOW(gpio_config);
110  /* For performance reasons assume the GPIO is already set as an output
111  * and therefore the call can be omitted here.
112  */
113  break;
115  if (value) {
116  AM335XGPIO_SET_INPUT(gpio_config);
117  } else {
118  AM335XGPIO_SET_LOW(gpio_config);
119  AM335XGPIO_SET_OUTPUT(gpio_config);
120  }
121  break;
123  if (value) {
124  AM335XGPIO_SET_HIGH(gpio_config);
125  AM335XGPIO_SET_OUTPUT(gpio_config);
126  } else {
127  AM335XGPIO_SET_INPUT(gpio_config);
128  }
129  break;
130  }
131 }
132 
133 static enum amx335gpio_initial_gpio_mode get_gpio_mode(const struct adapter_gpio_config *gpio_config)
134 {
135  if (AM335XGPIO_READ_REG(gpio_config->chip_num, AM335XGPIO_GPIO_OE_OFFSET) & BIT(gpio_config->gpio_num))
137 
138  /* Return output level too so that pin mode can be fully restored */
139  if (AM335XGPIO_READ_REG(gpio_config->chip_num, AM335XGPIO_GPIO_DATAOUT_OFFSET) & BIT(gpio_config->gpio_num))
142 }
143 
144 static const char *get_gpio_mode_name(enum amx335gpio_initial_gpio_mode gpio_mode)
145 {
146  switch (gpio_mode) {
148  return "input";
150  return "output (low)";
152  return "output (high)";
153  }
154  return "unknown";
155 }
156 
158 {
160  return;
161 
163  LOG_DEBUG("saved GPIO mode for %s (GPIO %d %d): %s",
166 
168  LOG_WARNING("am335xgpio does not support pull-up or pull-down settings (signal %s)",
169  adapter_gpio_get_name(idx));
170  }
171 
172  switch (adapter_gpio_config[idx].init_state) {
175  break;
178  break;
181  break;
182  }
183 
184  /* Direction for non push-pull is already set by set_gpio_value() */
188 }
189 
191 {
193  switch (initial_gpio_mode[idx]) {
196  break;
200  break;
204  break;
205  }
206  }
207 }
208 
210 {
212 }
213 
214 static int am335xgpio_write(int tck, int tms, int tdi)
215 {
218  set_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_TCK], tck); /* Write clock last */
219 
220  for (unsigned int i = 0; i < jtag_delay; ++i)
221  asm volatile ("");
222 
223  return ERROR_OK;
224 }
225 
226 static int am335xgpio_swd_write(int swclk, int swdio)
227 {
229  set_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWCLK], swclk); /* Write clock last */
230 
231  for (unsigned int i = 0; i < jtag_delay; ++i)
232  asm volatile ("");
233 
234  return ERROR_OK;
235 }
236 
237 /* (1) assert or (0) deassert reset lines */
238 static int am335xgpio_reset(int trst, int srst)
239 {
240  /* As the "adapter reset_config" command keeps the srst and trst gpio drive
241  * mode settings in sync we can use our standard set_gpio_value() function
242  * that honours drive mode and active low.
243  */
246 
249 
250  LOG_DEBUG("trst %d gpio: %d %d, srst %d gpio: %d %d",
251  trst,
254  srst,
257  return ERROR_OK;
258 }
259 
260 static void am335xgpio_swdio_drive(bool is_output)
261 {
262  if (is_output) {
266  } else {
270  }
271 }
272 
273 static int am335xgpio_swdio_read(void)
274 {
276 }
277 
278 static int am335xgpio_blink(bool on)
279 {
282 
283  return ERROR_OK;
284 }
285 
286 static struct bitbang_interface am335xgpio_bitbang = {
288  .write = am335xgpio_write,
289  .swdio_read = am335xgpio_swdio_read,
290  .swdio_drive = am335xgpio_swdio_drive,
291  .swd_write = am335xgpio_swd_write,
292  .blink = am335xgpio_blink
293 };
294 
295 static int am335xgpio_khz(int khz, int *jtag_speed)
296 {
297  if (!khz) {
298  LOG_DEBUG("RCLK not supported");
299  return ERROR_FAIL;
300  }
301  *jtag_speed = speed_coeff / khz - speed_offset;
302  if (*jtag_speed < 0)
303  *jtag_speed = 0;
304  return ERROR_OK;
305 }
306 
307 static int am335xgpio_speed_div(int speed, int *khz)
308 {
309  *khz = speed_coeff / (speed + speed_offset);
310  return ERROR_OK;
311 }
312 
313 static int am335xgpio_speed(int speed)
314 {
315  jtag_delay = speed;
316  return ERROR_OK;
317 }
318 
319 COMMAND_HANDLER(am335xgpio_handle_speed_coeffs)
320 {
321  if (CMD_ARGC == 2) {
324  }
325 
326  command_print(CMD, "AM335x GPIO config: speed_coeffs = %d, speed_offset = %d",
328  return ERROR_OK;
329 }
330 
332  {
333  .name = "speed_coeffs",
334  .handler = am335xgpio_handle_speed_coeffs,
335  .mode = COMMAND_CONFIG,
336  .help = "SPEED_COEFF and SPEED_OFFSET for delay calculations.",
337  .usage = "[SPEED_COEFF SPEED_OFFSET]",
338  },
340 };
341 
342 static const struct command_registration am335xgpio_command_handlers[] = {
343  {
344  .name = "am335xgpio",
345  .mode = COMMAND_ANY,
346  .help = "perform am335xgpio management",
348  .usage = "",
349  },
351 };
352 
353 static const char * const am335xgpio_transports[] = { "jtag", "swd", NULL };
354 
355 static struct jtag_interface am335xgpio_interface = {
357  .execute_queue = bitbang_execute_queue,
358 };
359 
361 {
363  return false;
365  return false;
367  return false;
369  return false;
370  return true;
371 }
372 
374 {
376  return false;
378  return false;
379  return true;
380 }
381 
382 static void am335xgpio_munmap(void)
383 {
384  for (unsigned int i = 0; i < AM335XGPIO_NUM_GPIO_CHIPS && am335xgpio_gpio_chip_mmap_addr[i] != MAP_FAILED; ++i)
385  if (munmap((void *)am335xgpio_gpio_chip_mmap_addr[i], sysconf(_SC_PAGE_SIZE)) < 0)
386  LOG_ERROR("Cannot unmap GPIO memory for chip %d: %s", i, strerror(errno));
387 }
388 
389 static int am335xgpio_init(void)
390 {
391  LOG_INFO("AM335x GPIO JTAG/SWD bitbang driver");
392 
395 
397  LOG_ERROR("Require tck, tms, tdi and tdo gpios for JTAG mode");
398  return ERROR_JTAG_INIT_FAILED;
399  }
400 
402  LOG_ERROR("Require swclk and swdio gpio for SWD mode");
403  return ERROR_JTAG_INIT_FAILED;
404  }
405 
406  dev_mem_fd = open("/dev/gpiomem", O_RDWR | O_SYNC);
407  if (dev_mem_fd < 0) {
408  LOG_DEBUG("Cannot open /dev/gpiomem, fallback to /dev/mem");
409  dev_mem_fd = open("/dev/mem", O_RDWR | O_SYNC);
410  }
411  if (dev_mem_fd < 0) {
412  LOG_ERROR("open: %s", strerror(errno));
413  return ERROR_JTAG_INIT_FAILED;
414  }
415 
416  for (unsigned int i = 0; i < AM335XGPIO_NUM_GPIO_CHIPS; ++i) {
417  am335xgpio_gpio_chip_mmap_addr[i] = mmap(NULL, sysconf(_SC_PAGE_SIZE), PROT_READ | PROT_WRITE,
418  MAP_SHARED, dev_mem_fd, am335xgpio_gpio_chip_hw_addr[i]);
419 
420  if (am335xgpio_gpio_chip_mmap_addr[i] == MAP_FAILED) {
421  LOG_ERROR("mmap: %s", strerror(errno));
423  close(dev_mem_fd);
424  return ERROR_JTAG_INIT_FAILED;
425  }
426  }
427  close(dev_mem_fd);
428 
429  /* Configure JTAG/SWD signals. Default directions and initial states are handled
430  * by adapter.c and "adapter gpio" command.
431  */
432  if (transport_is_jtag()) {
438  }
439 
440  if (transport_is_swd()) {
441  /* swdio and its buffer should be initialized in the order that prevents
442  * two outputs from being connected together. This will occur if the
443  * swdio GPIO of the AM335x is configured as an output while its
444  * external buffer is configured to send the swdio signal from the
445  * target to the AM335x.
446  */
450  } else {
453  }
454 
456  }
457 
460 
461  return ERROR_OK;
462 }
463 
464 static int am335xgpio_quit(void)
465 {
466  if (transport_is_jtag()) {
472  }
473 
474  if (transport_is_swd()) {
475  /* Restore swdio/swdio_dir to their initial modes, even if that means
476  * connecting two outputs. Begin by making swdio an input so that the
477  * current and final states of swdio and swdio_dir do not have to be
478  * considered to calculate the safe restoration order.
479  */
483 
485  }
486 
489 
491 
492  return ERROR_OK;
493 }
494 
496  .name = "am335xgpio",
497  .transports = am335xgpio_transports,
498  .commands = am335xgpio_command_handlers,
499 
500  .init = am335xgpio_init,
501  .quit = am335xgpio_quit,
502  .reset = am335xgpio_reset,
503  .speed = am335xgpio_speed,
504  .khz = am335xgpio_khz,
505  .speed_div = am335xgpio_speed_div,
506 
507  .jtag_ops = &am335xgpio_interface,
508  .swd_ops = &bitbang_swd,
509 };
const struct adapter_gpio_config * adapter_gpio_get_config(void)
Retrieves gpio configuration set with command "adapter gpio <signal_name>".
Definition: adapter.c:1221
const char * adapter_gpio_get_name(enum adapter_gpio_config_index idx)
Retrieves gpio name.
Definition: adapter.c:1215
@ ADAPTER_GPIO_INIT_STATE_ACTIVE
Definition: adapter.h:32
@ ADAPTER_GPIO_INIT_STATE_INPUT
Definition: adapter.h:33
@ ADAPTER_GPIO_INIT_STATE_INACTIVE
Definition: adapter.h:31
adapter_gpio_config_index
Adapter GPIO.
Definition: adapter.h:44
@ ADAPTER_GPIO_IDX_LED
Definition: adapter.h:54
@ ADAPTER_GPIO_IDX_NUM
Definition: adapter.h:55
@ ADAPTER_GPIO_IDX_SWCLK
Definition: adapter.h:52
@ ADAPTER_GPIO_IDX_SWDIO_DIR
Definition: adapter.h:51
@ ADAPTER_GPIO_IDX_SRST
Definition: adapter.h:53
@ ADAPTER_GPIO_IDX_TRST
Definition: adapter.h:49
@ ADAPTER_GPIO_IDX_TDI
Definition: adapter.h:46
@ ADAPTER_GPIO_IDX_TMS
Definition: adapter.h:47
@ ADAPTER_GPIO_IDX_TCK
Definition: adapter.h:48
@ ADAPTER_GPIO_IDX_TDO
Definition: adapter.h:45
@ ADAPTER_GPIO_IDX_SWDIO
Definition: adapter.h:50
@ ADAPTER_GPIO_PULL_NONE
Definition: adapter.h:38
@ ADAPTER_GPIO_DRIVE_MODE_OPEN_SOURCE
Definition: adapter.h:19
@ ADAPTER_GPIO_DRIVE_MODE_OPEN_DRAIN
Definition: adapter.h:18
@ ADAPTER_GPIO_DRIVE_MODE_PUSH_PULL
Definition: adapter.h:17
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 am335xgpio_swdio_read(void)
Definition: am335xgpio.c:273
static int am335xgpio_quit(void)
Definition: am335xgpio.c:464
static const struct command_registration am335xgpio_command_handlers[]
Definition: am335xgpio.c:342
static const char * get_gpio_mode_name(enum amx335gpio_initial_gpio_mode gpio_mode)
Definition: am335xgpio.c:144
#define AM335XGPIO_SET_OUTPUT(gpio_config)
Definition: am335xgpio.c:54
static int am335xgpio_write(int tck, int tms, int tdi)
Definition: am335xgpio.c:214
#define AM335XGPIO_SET_HIGH(gpio_config)
Definition: am335xgpio.c:56
#define AM335XGPIO_NUM_GPIO_PER_CHIP
Definition: am335xgpio.c:23
static void restore_gpio(enum adapter_gpio_config_index idx)
Definition: am335xgpio.c:190
static void am335xgpio_munmap(void)
Definition: am335xgpio.c:382
static int am335xgpio_speed_div(int speed, int *khz)
Definition: am335xgpio.c:307
#define AM335XGPIO_GPIO_DATAOUT_OFFSET
Definition: am335xgpio.c:36
static bool am335xgpio_swd_mode_possible(void)
Definition: am335xgpio.c:373
#define AM335XGPIO_GPIO3_HW_ADDR
Definition: am335xgpio.c:28
static int am335xgpio_init(void)
Definition: am335xgpio.c:389
#define AM335XGPIO_GPIO2_HW_ADDR
Definition: am335xgpio.c:27
#define AM335XGPIO_GPIO_OE_OFFSET
Definition: am335xgpio.c:34
static const uint32_t am335xgpio_gpio_chip_hw_addr[AM335XGPIO_NUM_GPIO_CHIPS]
Definition: am335xgpio.c:67
static int am335xgpio_speed(int speed)
Definition: am335xgpio.c:313
#define AM335XGPIO_SET_INPUT(gpio_config)
Definition: am335xgpio.c:52
static volatile uint32_t * am335xgpio_gpio_chip_mmap_addr[AM335XGPIO_NUM_GPIO_CHIPS]
Definition: am335xgpio.c:75
static unsigned int jtag_delay
Definition: am335xgpio.c:83
#define AM335XGPIO_READ_REG(chip_num, offset)
Definition: am335xgpio.c:40
static int am335xgpio_khz(int khz, int *jtag_speed)
Definition: am335xgpio.c:295
static struct jtag_interface am335xgpio_interface
Definition: am335xgpio.c:355
struct adapter_driver am335xgpio_adapter_driver
Definition: am335xgpio.c:495
static int dev_mem_fd
Definition: am335xgpio.c:77
static const struct command_registration am335xgpio_subcommand_handlers[]
Definition: am335xgpio.c:331
amx335gpio_initial_gpio_mode
Definition: am335xgpio.c:61
@ AM335XGPIO_GPIO_MODE_OUTPUT_LOW
Definition: am335xgpio.c:63
@ AM335XGPIO_GPIO_MODE_OUTPUT_HIGH
Definition: am335xgpio.c:64
@ AM335XGPIO_GPIO_MODE_INPUT
Definition: am335xgpio.c:62
static int speed_coeff
Definition: am335xgpio.c:81
#define AM335XGPIO_NUM_GPIO_CHIPS
Definition: am335xgpio.c:24
static const struct adapter_gpio_config * adapter_gpio_config
Definition: am335xgpio.c:85
static int am335xgpio_swd_write(int swclk, int swdio)
Definition: am335xgpio.c:226
COMMAND_HANDLER(am335xgpio_handle_speed_coeffs)
Definition: am335xgpio.c:319
static void set_gpio_value(const struct adapter_gpio_config *gpio_config, int value)
Definition: am335xgpio.c:101
#define AM335XGPIO_SET_LOW(gpio_config)
Definition: am335xgpio.c:58
static bool is_gpio_config_valid(const struct adapter_gpio_config *gpio_config)
Definition: am335xgpio.c:87
#define AM335XGPIO_GPIO0_HW_ADDR
Definition: am335xgpio.c:25
static const char *const am335xgpio_transports[]
Definition: am335xgpio.c:353
static int speed_offset
Definition: am335xgpio.c:82
static enum amx335gpio_initial_gpio_mode get_gpio_mode(const struct adapter_gpio_config *gpio_config)
Definition: am335xgpio.c:133
#define AM335XGPIO_GPIO_DATAIN_OFFSET
Definition: am335xgpio.c:35
static void am335xgpio_swdio_drive(bool is_output)
Definition: am335xgpio.c:260
static int get_gpio_value(const struct adapter_gpio_config *gpio_config)
Definition: am335xgpio.c:93
static enum amx335gpio_initial_gpio_mode initial_gpio_mode[ADAPTER_GPIO_IDX_NUM]
Definition: am335xgpio.c:78
static void initialize_gpio(enum adapter_gpio_config_index idx)
Definition: am335xgpio.c:157
#define AM335XGPIO_GPIO1_HW_ADDR
Definition: am335xgpio.c:26
static struct bitbang_interface am335xgpio_bitbang
Definition: am335xgpio.c:286
static bool am335xgpio_jtag_mode_possible(void)
Definition: am335xgpio.c:360
static int am335xgpio_blink(bool on)
Definition: am335xgpio.c:278
static bb_value_t am335xgpio_read(void)
Definition: am335xgpio.c:209
static int am335xgpio_reset(int trst, int srst)
Definition: am335xgpio.c:238
int bitbang_execute_queue(struct jtag_command *cmd_queue)
Definition: bitbang.c:293
const struct swd_driver bitbang_swd
Definition: bitbang.c:614
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 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:1827
#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 BIT(nr)
Definition: stm32l4x.h:18
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
Configuration options for a single GPIO.
Definition: adapter.h:59
unsigned int gpio_num
Definition: adapter.h:60
unsigned int chip_num
Definition: adapter.h:61
enum adapter_gpio_pull pull
Definition: adapter.h:65
enum adapter_gpio_init_state init_state
Definition: adapter.h:63
enum adapter_gpio_drive_mode drive
Definition: adapter.h:62
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 int supported
Bit vector listing capabilities exposed by this driver.
Definition: interface.h:186
#define NULL
Definition: usb.h:16