drivers/am335xgpio: Migrate to adapter gpio commands

Use the new "adapter gpio" commands to configure the GPIOs used by the
am335xgpio driver. The AM335x has 4 GPIO 'chips' (chip number 0-3
inclusive), with each one providing 32 GPIOs (gpio_num 0-31 inclusive).

Change-Id: I7c63c0e4763657ea51790c43fc40d32b7c3580bb
Signed-off-by: Steve Marple <stevemarple@googlemail.com>
Reviewed-on: https://review.openocd.org/c/openocd/+/6984
Tested-by: jenkins
Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com>
This commit is contained in:
Steve Marple 2022-05-17 21:51:17 +01:00 committed by Antonio Borneo
parent 82fd400542
commit ace028262b
6 changed files with 405 additions and 517 deletions

View File

@ -3387,86 +3387,16 @@ registers directly. The memory mapping requires read and write permission to
kernel memory; if /dev/gpiomem exists it will be used, otherwise /dev/mem will kernel memory; if /dev/gpiomem exists it will be used, otherwise /dev/mem will
be used. The driver restores the GPIO state on exit. be used. The driver restores the GPIO state on exit.
All four GPIO ports are available. GPIOs numbered 0 to 31 are mapped to GPIO port All four GPIO ports are available. GPIO configuration is handled by the generic
0, GPIO numbers 32 to 63 are mapped to GPIO port 1 and so on. command @ref{adapter gpio, @command{adapter gpio}}.
See @file{interface/beaglebone-swd-native.cfg} for a sample configuration file.
@deffn {Config Command} {am335xgpio jtag_nums} @var{tck} @var{tms} @var{tdi} @var{tdo}
Set JTAG transport GPIO numbers for TCK, TMS, TDI, and TDO (in that order).
Must be specified to enable JTAG transport. These pins can also be specified
individually.
@end deffn
@deffn {Config Command} {am335xgpio tck_num} @var{tck}
Set TCK GPIO number. Must be specified to enable JTAG transport. Can also be
specified using the configuration command @command{am335xgpio jtag_nums}.
@end deffn
@deffn {Config Command} {am335xgpio tms_num} @var{tms}
Set TMS GPIO number. Must be specified to enable JTAG transport. Can also be
specified using the configuration command @command{am335xgpio jtag_nums}.
@end deffn
@deffn {Config Command} {am335xgpio tdo_num} @var{tdo}
Set TDO GPIO number. Must be specified to enable JTAG transport. Can also be
specified using the configuration command @command{am335xgpio jtag_nums}.
@end deffn
@deffn {Config Command} {am335xgpio tdi_num} @var{tdi}
Set TDI GPIO number. Must be specified to enable JTAG transport. Can also be
specified using the configuration command @command{am335xgpio jtag_nums}.
@end deffn
@deffn {Config Command} {am335xgpio swd_nums} @var{swclk} @var{swdio}
Set SWD transport GPIO numbers for SWCLK and SWDIO (in that order). Must be
specified to enable SWD transport. These pins can also be specified individually.
@end deffn
@deffn {Config Command} {am335xgpio swclk_num} @var{swclk}
Set SWCLK GPIO number. Must be specified to enable SWD transport. Can also be
specified using the configuration command @command{am335xgpio swd_nums}.
@end deffn
@deffn {Config Command} {am335xgpio swdio_num} @var{swdio}
Set SWDIO GPIO number. Must be specified to enable SWD transport. Can also be
specified using the configuration command @command{am335xgpio swd_nums}.
@end deffn
@deffn {Config Command} {am335xgpio swdio_dir_num} @var{swdio_dir}
Set SWDIO direction control pin GPIO number. If specified, this pin can be used
to control the direction of an external buffer on the SWDIO pin. The direction
control state can be set with the command @command{am335xgpio
swdio_dir_output_state}. If not specified this feature is disabled.
@end deffn
@deffn {Config Command} {am335xgpio swdio_dir_output_state} @var{output_state}
Set the state required for an external SWDIO buffer to be an output. Valid
values are @option{on} (default) and @option{off}.
@end deffn
@deffn {Config Command} {am335xgpio srst_num} @var{srst}
Set SRST GPIO number. Must be specified to enable SRST.
@end deffn
@deffn {Config Command} {am335xgpio trst_num} @var{trst}
Set TRST GPIO number. Must be specified to enable TRST.
@end deffn
@deffn {Config Command} {am335xgpio led_num} @var{led}
Set activity LED GPIO number. If not specified an activity LED is not enabled.
@end deffn
@deffn {Config Command} {am335xgpio led_on_state} @var{on_state}
Set required logic level for the LED to be on. Valid values are @option{on}
(default) and @option{off}.
@end deffn
@deffn {Config Command} {am335xgpio speed_coeffs} @var{speed_coeff} @var{speed_offset} @deffn {Config Command} {am335xgpio speed_coeffs} @var{speed_coeff} @var{speed_offset}
Set SPEED_COEFF and SPEED_OFFSET for delay calculations. If unspecified Set SPEED_COEFF and SPEED_OFFSET for delay calculations. If unspecified
speed_coeff defaults to 600000 and speed_offset defaults to 575. speed_coeff defaults to 600000 and speed_offset defaults to 575.
@end deffn @end deffn
See @file{interface/beaglebone-swd-native.cfg} for a sample configuration file.
@end deffn @end deffn

View File

@ -10,23 +10,24 @@
#include "config.h" #include "config.h"
#endif #endif
#include <jtag/adapter.h>
#include <jtag/interface.h> #include <jtag/interface.h>
#include <transport/transport.h> #include <transport/transport.h>
#include "bitbang.h" #include "bitbang.h"
#include <sys/mman.h> #include <sys/mman.h>
/* /* GPIO register base addresses. Values taken from "AM335x and AMIC110 Sitara
* GPIO register base addresses. Values taken from "AM335x and AMIC110 Sitara
* Processors Technical Reference Manual", Chapter 2 Memory Map. * Processors Technical Reference Manual", Chapter 2 Memory Map.
*/ */
#define AM335XGPIO_NUM_GPIO_PORTS 4 #define AM335XGPIO_NUM_GPIO_PER_CHIP 32
#define AM335XGPIO_NUM_GPIO_CHIPS 4
#define AM335XGPIO_GPIO0_HW_ADDR 0x44E07000 #define AM335XGPIO_GPIO0_HW_ADDR 0x44E07000
#define AM335XGPIO_GPIO1_HW_ADDR 0x4804C000 #define AM335XGPIO_GPIO1_HW_ADDR 0x4804C000
#define AM335XGPIO_GPIO2_HW_ADDR 0x481AC000 #define AM335XGPIO_GPIO2_HW_ADDR 0x481AC000
#define AM335XGPIO_GPIO3_HW_ADDR 0x481AE000 #define AM335XGPIO_GPIO3_HW_ADDR 0x481AE000
/* 32-bit offsets from GPIO port base address. Values taken from "AM335x and /* 32-bit offsets from GPIO chip base address. Values taken from "AM335x and
* AMIC110 Sitara Processors Technical Reference Manual", Chapter 25 * AMIC110 Sitara Processors Technical Reference Manual", Chapter 25
* General-Purpose Input/Output. * General-Purpose Input/Output.
*/ */
@ -36,34 +37,34 @@
#define AM335XGPIO_GPIO_CLEARDATAOUT_OFFSET (0x190 / 4) #define AM335XGPIO_GPIO_CLEARDATAOUT_OFFSET (0x190 / 4)
#define AM335XGPIO_GPIO_SETDATAOUT_OFFSET (0x194 / 4) #define AM335XGPIO_GPIO_SETDATAOUT_OFFSET (0x194 / 4)
/* GPIOs are integer values; need to map to a port module, and the pin within #define AM335XGPIO_READ_REG(chip_num, offset) \
* that module. GPIOs 0 to 31 map to GPIO0, 32 to 63 to GPIO1 etc. This scheme (*(am335xgpio_gpio_chip_mmap_addr[(chip_num)] + (offset)))
* matches that used by Linux on the BeagleBone.
*/
#define AM335XGPIO_PORT_NUM(gpio_num) ((gpio_num) / 32)
#define AM335XGPIO_BIT_NUM(gpio_num) ((gpio_num) % 32)
#define AM335XGPIO_BIT_MASK(gpio_num) BIT(AM335XGPIO_BIT_NUM(gpio_num))
#define AM335XGPIO_READ_REG(gpio_num, offset) \ #define AM335XGPIO_WRITE_REG(chip_num, offset, value) \
(*(am335xgpio_gpio_port_mmap_addr[AM335XGPIO_PORT_NUM(gpio_num)] + (offset))) (*(am335xgpio_gpio_chip_mmap_addr[(chip_num)] + (offset)) = (value))
#define AM335XGPIO_WRITE_REG(gpio_num, offset, value) \ #define AM335XGPIO_SET_REG_BITS(chip_num, offset, bit_mask) \
(*(am335xgpio_gpio_port_mmap_addr[AM335XGPIO_PORT_NUM(gpio_num)] + (offset)) = (value)) (*(am335xgpio_gpio_chip_mmap_addr[(chip_num)] + (offset)) |= (bit_mask))
#define AM335XGPIO_SET_REG_BITS(gpio_num, offset, bit_mask) \ #define AM335XGPIO_CLEAR_REG_BITS(chip_num, offset, bit_mask) \
(*(am335xgpio_gpio_port_mmap_addr[AM335XGPIO_PORT_NUM(gpio_num)] + (offset)) |= (bit_mask)) (*(am335xgpio_gpio_chip_mmap_addr[(chip_num)] + (offset)) &= ~(bit_mask))
#define AM335XGPIO_CLEAR_REG_BITS(gpio_num, offset, bit_mask) \ #define AM335XGPIO_SET_INPUT(gpio_config) \
(*(am335xgpio_gpio_port_mmap_addr[AM335XGPIO_PORT_NUM(gpio_num)] + (offset)) &= ~(bit_mask)) AM335XGPIO_SET_REG_BITS((gpio_config)->chip_num, AM335XGPIO_GPIO_OE_OFFSET, BIT((gpio_config)->gpio_num))
#define AM335XGPIO_SET_OUTPUT(gpio_config) \
AM335XGPIO_CLEAR_REG_BITS((gpio_config)->chip_num, AM335XGPIO_GPIO_OE_OFFSET, BIT((gpio_config)->gpio_num))
#define AM335XGPIO_SET_HIGH(gpio_config) \
AM335XGPIO_WRITE_REG((gpio_config)->chip_num, AM335XGPIO_GPIO_SETDATAOUT_OFFSET, BIT((gpio_config)->gpio_num))
#define AM335XGPIO_SET_LOW(gpio_config) \
AM335XGPIO_WRITE_REG((gpio_config)->chip_num, AM335XGPIO_GPIO_CLEARDATAOUT_OFFSET, BIT((gpio_config)->gpio_num))
enum amx335gpio_gpio_mode { enum amx335gpio_initial_gpio_mode {
AM335XGPIO_GPIO_MODE_INPUT, AM335XGPIO_GPIO_MODE_INPUT,
AM335XGPIO_GPIO_MODE_OUTPUT, /* To set output mode but not state */
AM335XGPIO_GPIO_MODE_OUTPUT_LOW, AM335XGPIO_GPIO_MODE_OUTPUT_LOW,
AM335XGPIO_GPIO_MODE_OUTPUT_HIGH, AM335XGPIO_GPIO_MODE_OUTPUT_HIGH,
}; };
static const uint32_t am335xgpio_gpio_port_hw_addr[AM335XGPIO_NUM_GPIO_PORTS] = { static const uint32_t am335xgpio_gpio_chip_hw_addr[AM335XGPIO_NUM_GPIO_CHIPS] = {
AM335XGPIO_GPIO0_HW_ADDR, AM335XGPIO_GPIO0_HW_ADDR,
AM335XGPIO_GPIO1_HW_ADDR, AM335XGPIO_GPIO1_HW_ADDR,
AM335XGPIO_GPIO2_HW_ADDR, AM335XGPIO_GPIO2_HW_ADDR,
@ -71,117 +72,151 @@ static const uint32_t am335xgpio_gpio_port_hw_addr[AM335XGPIO_NUM_GPIO_PORTS] =
}; };
/* Memory-mapped address pointers */ /* Memory-mapped address pointers */
static volatile uint32_t *am335xgpio_gpio_port_mmap_addr[AM335XGPIO_NUM_GPIO_PORTS]; static volatile uint32_t *am335xgpio_gpio_chip_mmap_addr[AM335XGPIO_NUM_GPIO_CHIPS];
static int dev_mem_fd; static int dev_mem_fd;
static enum amx335gpio_initial_gpio_mode initial_gpio_mode[ADAPTER_GPIO_IDX_NUM];
/* GPIO numbers for each signal. Negative values are invalid */
static int tck_gpio = -1;
static enum amx335gpio_gpio_mode tck_gpio_mode;
static int tms_gpio = -1;
static enum amx335gpio_gpio_mode tms_gpio_mode;
static int tdi_gpio = -1;
static enum amx335gpio_gpio_mode tdi_gpio_mode;
static int tdo_gpio = -1;
static enum amx335gpio_gpio_mode tdo_gpio_mode;
static int trst_gpio = -1;
static enum amx335gpio_gpio_mode trst_gpio_mode;
static int srst_gpio = -1;
static enum amx335gpio_gpio_mode srst_gpio_mode;
static int swclk_gpio = -1;
static enum amx335gpio_gpio_mode swclk_gpio_mode;
static int swdio_gpio = -1;
static enum amx335gpio_gpio_mode swdio_gpio_mode;
static int swdio_dir_gpio = -1;
static enum amx335gpio_gpio_mode swdio_dir_gpio_mode;
static int led_gpio = -1;
static enum amx335gpio_gpio_mode led_gpio_mode = -1;
static bool swdio_dir_is_active_high = true; /* Active state means output */
static bool led_is_active_high = true;
/* Transition delay coefficients */ /* Transition delay coefficients */
static int speed_coeff = 600000; static int speed_coeff = 600000;
static int speed_offset = 575; static int speed_offset = 575;
static unsigned int jtag_delay; static unsigned int jtag_delay;
static int is_gpio_valid(int gpio_num) static const struct adapter_gpio_config *adapter_gpio_config;
static bool is_gpio_config_valid(const struct adapter_gpio_config *gpio_config)
{ {
return gpio_num >= 0 && gpio_num < (32 * AM335XGPIO_NUM_GPIO_PORTS); return gpio_config->chip_num >= 0
&& gpio_config->chip_num < AM335XGPIO_NUM_GPIO_CHIPS
&& gpio_config->gpio_num >= 0
&& gpio_config->gpio_num < AM335XGPIO_NUM_GPIO_PER_CHIP;
} }
static int get_gpio_value(int gpio_num) static int get_gpio_value(const struct adapter_gpio_config *gpio_config)
{ {
unsigned int shift = AM335XGPIO_BIT_NUM(gpio_num); unsigned int shift = gpio_config->gpio_num;
return (AM335XGPIO_READ_REG(gpio_num, AM335XGPIO_GPIO_DATAIN_OFFSET) >> shift) & 1; uint32_t value = AM335XGPIO_READ_REG(gpio_config->chip_num, AM335XGPIO_GPIO_DATAIN_OFFSET);
value = (value >> shift) & 1;
return value ^ (gpio_config->active_low ? 1 : 0);
} }
static void set_gpio_value(int gpio_num, int value) static void set_gpio_value(const struct adapter_gpio_config *gpio_config, int value)
{ {
value = value ^ (gpio_config->active_low ? 1 : 0);
switch (gpio_config->drive) {
case ADAPTER_GPIO_DRIVE_MODE_PUSH_PULL:
if (value) if (value)
AM335XGPIO_WRITE_REG(gpio_num, AM335XGPIO_GPIO_SETDATAOUT_OFFSET, AM335XGPIO_BIT_MASK(gpio_num)); AM335XGPIO_SET_HIGH(gpio_config);
else else
AM335XGPIO_WRITE_REG(gpio_num, AM335XGPIO_GPIO_CLEARDATAOUT_OFFSET, AM335XGPIO_BIT_MASK(gpio_num)); AM335XGPIO_SET_LOW(gpio_config);
/* For performance reasons assume the GPIO is already set as an output
* and therefore the call can be omitted here.
*/
break;
case ADAPTER_GPIO_DRIVE_MODE_OPEN_DRAIN:
if (value) {
AM335XGPIO_SET_INPUT(gpio_config);
} else {
AM335XGPIO_SET_LOW(gpio_config);
AM335XGPIO_SET_OUTPUT(gpio_config);
}
break;
case ADAPTER_GPIO_DRIVE_MODE_OPEN_SOURCE:
if (value) {
AM335XGPIO_SET_HIGH(gpio_config);
AM335XGPIO_SET_OUTPUT(gpio_config);
} else {
AM335XGPIO_SET_INPUT(gpio_config);
}
break;
}
} }
static enum amx335gpio_gpio_mode get_gpio_mode(int gpio_num) static enum amx335gpio_initial_gpio_mode get_gpio_mode(const struct adapter_gpio_config *gpio_config)
{ {
if (AM335XGPIO_READ_REG(gpio_num, AM335XGPIO_GPIO_OE_OFFSET) & AM335XGPIO_BIT_MASK(gpio_num)) { if (AM335XGPIO_READ_REG(gpio_config->chip_num, AM335XGPIO_GPIO_OE_OFFSET) & BIT(gpio_config->gpio_num))
return AM335XGPIO_GPIO_MODE_INPUT; return AM335XGPIO_GPIO_MODE_INPUT;
} else {
/* Return output level too so that pin mode can be fully restored */ /* Return output level too so that pin mode can be fully restored */
if (AM335XGPIO_READ_REG(gpio_num, AM335XGPIO_GPIO_DATAOUT_OFFSET) & AM335XGPIO_BIT_MASK(gpio_num)) if (AM335XGPIO_READ_REG(gpio_config->chip_num, AM335XGPIO_GPIO_DATAOUT_OFFSET) & BIT(gpio_config->gpio_num))
return AM335XGPIO_GPIO_MODE_OUTPUT_HIGH; return AM335XGPIO_GPIO_MODE_OUTPUT_HIGH;
else
return AM335XGPIO_GPIO_MODE_OUTPUT_LOW; return AM335XGPIO_GPIO_MODE_OUTPUT_LOW;
} }
}
static void set_gpio_mode(int gpio_num, enum amx335gpio_gpio_mode gpio_mode) static const char *get_gpio_mode_name(enum amx335gpio_initial_gpio_mode gpio_mode)
{
if (gpio_mode == AM335XGPIO_GPIO_MODE_INPUT) {
AM335XGPIO_SET_REG_BITS(gpio_num, AM335XGPIO_GPIO_OE_OFFSET, AM335XGPIO_BIT_MASK(gpio_num));
return;
}
if (gpio_mode == AM335XGPIO_GPIO_MODE_OUTPUT_LOW)
set_gpio_value(gpio_num, 0);
if (gpio_mode == AM335XGPIO_GPIO_MODE_OUTPUT_HIGH)
set_gpio_value(gpio_num, 1);
if (gpio_mode == AM335XGPIO_GPIO_MODE_OUTPUT ||
gpio_mode == AM335XGPIO_GPIO_MODE_OUTPUT_LOW ||
gpio_mode == AM335XGPIO_GPIO_MODE_OUTPUT_HIGH) {
AM335XGPIO_CLEAR_REG_BITS(gpio_num, AM335XGPIO_GPIO_OE_OFFSET, AM335XGPIO_BIT_MASK(gpio_num));
}
}
static const char *get_gpio_mode_name(enum amx335gpio_gpio_mode gpio_mode)
{ {
switch (gpio_mode) { switch (gpio_mode) {
case AM335XGPIO_GPIO_MODE_INPUT: case AM335XGPIO_GPIO_MODE_INPUT:
return "input"; return "input";
case AM335XGPIO_GPIO_MODE_OUTPUT:
return "output";
case AM335XGPIO_GPIO_MODE_OUTPUT_LOW: case AM335XGPIO_GPIO_MODE_OUTPUT_LOW:
return "output (low)"; return "output (low)";
case AM335XGPIO_GPIO_MODE_OUTPUT_HIGH: case AM335XGPIO_GPIO_MODE_OUTPUT_HIGH:
return "output (high)"; return "output (high)";
default: }
return "unknown"; return "unknown";
} }
static void initialize_gpio(enum adapter_gpio_config_index idx)
{
if (!is_gpio_config_valid(&adapter_gpio_config[idx]))
return;
initial_gpio_mode[idx] = get_gpio_mode(&adapter_gpio_config[idx]);
LOG_DEBUG("saved GPIO mode for %s (GPIO %d %d): %s",
adapter_gpio_get_name(idx), adapter_gpio_config[idx].chip_num, adapter_gpio_config[idx].gpio_num,
get_gpio_mode_name(initial_gpio_mode[idx]));
if (adapter_gpio_config[idx].pull != ADAPTER_GPIO_PULL_NONE) {
LOG_WARNING("am335xgpio does not support pull-up or pull-down settings (signal %s)",
adapter_gpio_get_name(idx));
}
switch (adapter_gpio_config[idx].init_state) {
case ADAPTER_GPIO_INIT_STATE_INACTIVE:
set_gpio_value(&adapter_gpio_config[idx], 0);
break;
case ADAPTER_GPIO_INIT_STATE_ACTIVE:
set_gpio_value(&adapter_gpio_config[idx], 1);
break;
case ADAPTER_GPIO_INIT_STATE_INPUT:
AM335XGPIO_SET_INPUT(&adapter_gpio_config[idx]);
break;
}
/* Direction for non push-pull is already set by set_gpio_value() */
if (adapter_gpio_config[idx].drive == ADAPTER_GPIO_DRIVE_MODE_PUSH_PULL)
AM335XGPIO_SET_OUTPUT(&adapter_gpio_config[idx]);
}
static void restore_gpio(enum adapter_gpio_config_index idx)
{
if (is_gpio_config_valid(&adapter_gpio_config[idx])) {
switch (initial_gpio_mode[idx]) {
case AM335XGPIO_GPIO_MODE_INPUT:
AM335XGPIO_SET_INPUT(&adapter_gpio_config[idx]);
break;
case AM335XGPIO_GPIO_MODE_OUTPUT_LOW:
AM335XGPIO_SET_LOW(&adapter_gpio_config[idx]);
AM335XGPIO_SET_OUTPUT(&adapter_gpio_config[idx]);
break;
case AM335XGPIO_GPIO_MODE_OUTPUT_HIGH:
AM335XGPIO_SET_HIGH(&adapter_gpio_config[idx]);
AM335XGPIO_SET_OUTPUT(&adapter_gpio_config[idx]);
break;
}
}
} }
static bb_value_t am335xgpio_read(void) static bb_value_t am335xgpio_read(void)
{ {
return get_gpio_value(tdo_gpio) ? BB_HIGH : BB_LOW; return get_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_TDO]) ? BB_HIGH : BB_LOW;
} }
static int am335xgpio_write(int tck, int tms, int tdi) static int am335xgpio_write(int tck, int tms, int tdi)
{ {
set_gpio_value(tdi_gpio, tdi); set_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_TDI], tdi);
set_gpio_value(tms_gpio, tms); set_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_TMS], tms);
set_gpio_value(tck_gpio, tck); /* Write clock last */ set_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_TCK], tck); /* Write clock last */
for (unsigned int i = 0; i < jtag_delay; ++i) for (unsigned int i = 0; i < jtag_delay; ++i)
asm volatile (""); asm volatile ("");
@ -191,8 +226,8 @@ static int am335xgpio_write(int tck, int tms, int tdi)
static int am335xgpio_swd_write(int swclk, int swdio) static int am335xgpio_swd_write(int swclk, int swdio)
{ {
set_gpio_value(swdio_gpio, swdio); set_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO], swdio);
set_gpio_value(swclk_gpio, swclk); /* Write clock last */ set_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWCLK], swclk); /* Write clock last */
for (unsigned int i = 0; i < jtag_delay; ++i) for (unsigned int i = 0; i < jtag_delay; ++i)
asm volatile (""); asm volatile ("");
@ -203,49 +238,45 @@ static int am335xgpio_swd_write(int swclk, int swdio)
/* (1) assert or (0) deassert reset lines */ /* (1) assert or (0) deassert reset lines */
static int am335xgpio_reset(int trst, int srst) static int am335xgpio_reset(int trst, int srst)
{ {
/* assume active low */ /* As the "adapter reset_config" command keeps the srst and trst gpio drive
if (is_gpio_valid(srst_gpio)) { * mode settings in sync we can use our standard set_gpio_value() function
if (jtag_get_reset_config() & RESET_SRST_PUSH_PULL) * that honours drive mode and active low.
set_gpio_mode(srst_gpio, srst ? AM335XGPIO_GPIO_MODE_OUTPUT_LOW : AM335XGPIO_GPIO_MODE_OUTPUT_HIGH); */
else if (is_gpio_config_valid(&adapter_gpio_config[ADAPTER_GPIO_IDX_SRST]))
set_gpio_mode(srst_gpio, srst ? AM335XGPIO_GPIO_MODE_OUTPUT_LOW : AM335XGPIO_GPIO_MODE_INPUT); set_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_SRST], srst);
}
/* assume active low */ if (is_gpio_config_valid(&adapter_gpio_config[ADAPTER_GPIO_IDX_TRST]))
if (is_gpio_valid(trst_gpio)) { set_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_TRST], trst);
if (jtag_get_reset_config() & RESET_TRST_OPEN_DRAIN)
set_gpio_mode(trst_gpio, trst ? AM335XGPIO_GPIO_MODE_OUTPUT_LOW : AM335XGPIO_GPIO_MODE_INPUT);
else
set_gpio_mode(trst_gpio, trst ? AM335XGPIO_GPIO_MODE_OUTPUT_LOW : AM335XGPIO_GPIO_MODE_OUTPUT_HIGH);
}
LOG_DEBUG("am335xgpio_reset(%d, %d), trst_gpio: %d (%s), srst_gpio: %d (%s)", LOG_DEBUG("am335xgpio_reset(%d, %d), trst_gpio: %d %d, srst_gpio: %d %d",
trst, srst, trst, srst,
trst_gpio, get_gpio_mode_name(get_gpio_mode(trst_gpio)), adapter_gpio_config[ADAPTER_GPIO_IDX_TRST].chip_num, adapter_gpio_config[ADAPTER_GPIO_IDX_TRST].gpio_num,
srst_gpio, get_gpio_mode_name(get_gpio_mode(srst_gpio))); adapter_gpio_config[ADAPTER_GPIO_IDX_SRST].chip_num, adapter_gpio_config[ADAPTER_GPIO_IDX_SRST].gpio_num);
return ERROR_OK; return ERROR_OK;
} }
static void am335xgpio_swdio_drive(bool is_output) static void am335xgpio_swdio_drive(bool is_output)
{ {
if (is_output) { if (is_output) {
set_gpio_value(swdio_dir_gpio, swdio_dir_is_active_high ? 1 : 0); if (is_gpio_config_valid(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO_DIR]))
set_gpio_mode(swdio_gpio, AM335XGPIO_GPIO_MODE_OUTPUT); set_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO_DIR], 1);
AM335XGPIO_SET_OUTPUT(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO]);
} else { } else {
set_gpio_mode(swdio_gpio, AM335XGPIO_GPIO_MODE_INPUT); AM335XGPIO_SET_INPUT(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO]);
set_gpio_value(swdio_dir_gpio, swdio_dir_is_active_high ? 0 : 1); if (is_gpio_config_valid(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO_DIR]))
set_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO_DIR], 0);
} }
} }
static int am335xgpio_swdio_read(void) static int am335xgpio_swdio_read(void)
{ {
return get_gpio_value(swdio_gpio); return get_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO]);
} }
static int am335xgpio_blink(int on) static int am335xgpio_blink(int on)
{ {
if (is_gpio_valid(led_gpio)) if (is_gpio_config_valid(&adapter_gpio_config[ADAPTER_GPIO_IDX_LED]))
set_gpio_value(led_gpio, (!on ^ led_is_active_high) ? 1 : 0); set_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_LED], on);
return ERROR_OK; return ERROR_OK;
} }
@ -283,144 +314,6 @@ static int am335xgpio_speed(int speed)
return ERROR_OK; return ERROR_OK;
} }
COMMAND_HANDLER(am335xgpio_handle_jtag_gpionums)
{
if (CMD_ARGC == 4) {
COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tck_gpio);
COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], tms_gpio);
COMMAND_PARSE_NUMBER(int, CMD_ARGV[2], tdi_gpio);
COMMAND_PARSE_NUMBER(int, CMD_ARGV[3], tdo_gpio);
} else if (CMD_ARGC != 0) {
return ERROR_COMMAND_SYNTAX_ERROR;
}
command_print(CMD, "AM335x GPIO config: tck = %d, tms = %d, tdi = %d, tdo = %d",
tck_gpio, tms_gpio, tdi_gpio, tdo_gpio);
return ERROR_OK;
}
COMMAND_HANDLER(am335xgpio_handle_jtag_gpionum_tck)
{
if (CMD_ARGC == 1)
COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tck_gpio);
command_print(CMD, "AM335x GPIO config: tck = %d", tck_gpio);
return ERROR_OK;
}
COMMAND_HANDLER(am335xgpio_handle_jtag_gpionum_tms)
{
if (CMD_ARGC == 1)
COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tms_gpio);
command_print(CMD, "AM335x GPIO config: tms = %d", tms_gpio);
return ERROR_OK;
}
COMMAND_HANDLER(am335xgpio_handle_jtag_gpionum_tdo)
{
if (CMD_ARGC == 1)
COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tdo_gpio);
command_print(CMD, "AM335x GPIO config: tdo = %d", tdo_gpio);
return ERROR_OK;
}
COMMAND_HANDLER(am335xgpio_handle_jtag_gpionum_tdi)
{
if (CMD_ARGC == 1)
COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tdi_gpio);
command_print(CMD, "AM335x GPIO config: tdi = %d", tdi_gpio);
return ERROR_OK;
}
COMMAND_HANDLER(am335xgpio_handle_jtag_gpionum_srst)
{
if (CMD_ARGC == 1)
COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], srst_gpio);
command_print(CMD, "AM335x GPIO config: srst = %d", srst_gpio);
return ERROR_OK;
}
COMMAND_HANDLER(am335xgpio_handle_jtag_gpionum_trst)
{
if (CMD_ARGC == 1)
COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], trst_gpio);
command_print(CMD, "AM335x GPIO config: trst = %d", trst_gpio);
return ERROR_OK;
}
COMMAND_HANDLER(am335xgpio_handle_swd_gpionums)
{
if (CMD_ARGC == 2) {
COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], swclk_gpio);
COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], swdio_gpio);
} else if (CMD_ARGC != 0) {
return ERROR_COMMAND_SYNTAX_ERROR;
}
command_print(CMD, "AM335x GPIO config: swclk = %d, swdio = %d", swclk_gpio, swdio_gpio);
return ERROR_OK;
}
COMMAND_HANDLER(am335xgpio_handle_swd_gpionum_swclk)
{
if (CMD_ARGC == 1)
COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], swclk_gpio);
command_print(CMD, "AM335x GPIO config: swclk = %d", swclk_gpio);
return ERROR_OK;
}
COMMAND_HANDLER(am335xgpio_handle_swd_gpionum_swdio)
{
if (CMD_ARGC == 1)
COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], swdio_gpio);
command_print(CMD, "AM335x GPIO config: swdio = %d", swdio_gpio);
return ERROR_OK;
}
COMMAND_HANDLER(am335xgpio_handle_swd_gpionum_swdio_dir)
{
if (CMD_ARGC == 1)
COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], swdio_dir_gpio);
command_print(CMD, "AM335x GPIO config: swdio_dir = %d", swdio_dir_gpio);
return ERROR_OK;
}
COMMAND_HANDLER(am335xgpio_handle_swd_dir_output_state)
{
if (CMD_ARGC == 1)
COMMAND_PARSE_BOOL(CMD_ARGV[0], swdio_dir_is_active_high, "high", "low");
command_print(CMD, "AM335x GPIO config: swdio_dir_output_state = %s", swdio_dir_is_active_high ? "high" : "low");
return ERROR_OK;
}
COMMAND_HANDLER(am335xgpio_handle_gpionum_led)
{
if (CMD_ARGC == 1)
COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], led_gpio);
command_print(CMD, "AM335x GPIO config: led = %d", led_gpio);
return ERROR_OK;
}
COMMAND_HANDLER(am335xgpio_handle_led_on_state)
{
if (CMD_ARGC == 1)
COMMAND_PARSE_BOOL(CMD_ARGV[0], led_is_active_high, "high", "low");
command_print(CMD, "AM335x GPIO config: led_on_state = %s", led_is_active_high ? "high" : "low");
return ERROR_OK;
}
COMMAND_HANDLER(am335xgpio_handle_speed_coeffs) COMMAND_HANDLER(am335xgpio_handle_speed_coeffs)
{ {
if (CMD_ARGC == 2) { if (CMD_ARGC == 2) {
@ -434,104 +327,6 @@ COMMAND_HANDLER(am335xgpio_handle_speed_coeffs)
} }
static const struct command_registration am335xgpio_subcommand_handlers[] = { static const struct command_registration am335xgpio_subcommand_handlers[] = {
{
.name = "jtag_nums",
.handler = am335xgpio_handle_jtag_gpionums,
.mode = COMMAND_CONFIG,
.help = "gpio numbers for tck, tms, tdi, tdo (in that order).",
.usage = "[tck tms tdi tdo]",
},
{
.name = "tck_num",
.handler = am335xgpio_handle_jtag_gpionum_tck,
.mode = COMMAND_CONFIG,
.help = "gpio number for tck.",
.usage = "[tck]",
},
{
.name = "tms_num",
.handler = am335xgpio_handle_jtag_gpionum_tms,
.mode = COMMAND_CONFIG,
.help = "gpio number for tms.",
.usage = "[tms]",
},
{
.name = "tdo_num",
.handler = am335xgpio_handle_jtag_gpionum_tdo,
.mode = COMMAND_CONFIG,
.help = "gpio number for tdo.",
.usage = "[tdo]",
},
{
.name = "tdi_num",
.handler = am335xgpio_handle_jtag_gpionum_tdi,
.mode = COMMAND_CONFIG,
.help = "gpio number for tdi.",
.usage = "[tdi]",
},
{
.name = "swd_nums",
.handler = am335xgpio_handle_swd_gpionums,
.mode = COMMAND_CONFIG,
.help = "gpio numbers for swclk, swdio (in that order).",
.usage = "[swclk swdio]",
},
{
.name = "swclk_num",
.handler = am335xgpio_handle_swd_gpionum_swclk,
.mode = COMMAND_CONFIG,
.help = "gpio number for swclk.",
.usage = "[swclk]",
},
{
.name = "swdio_num",
.handler = am335xgpio_handle_swd_gpionum_swdio,
.mode = COMMAND_CONFIG,
.help = "gpio number for swdio.",
.usage = "[swdio]",
},
{
.name = "swdio_dir_num",
.handler = am335xgpio_handle_swd_gpionum_swdio_dir,
.mode = COMMAND_CONFIG,
.help = "gpio number for swdio direction control pin.",
.usage = "[swdio_dir]",
},
{
.name = "swdio_dir_output_state",
.handler = am335xgpio_handle_swd_dir_output_state,
.mode = COMMAND_CONFIG,
.help = "required state for swdio_dir pin to select SWDIO buffer to be output.",
.usage = "['off'|'on']",
},
{
.name = "srst_num",
.handler = am335xgpio_handle_jtag_gpionum_srst,
.mode = COMMAND_CONFIG,
.help = "gpio number for srst.",
.usage = "[srst]",
},
{
.name = "trst_num",
.handler = am335xgpio_handle_jtag_gpionum_trst,
.mode = COMMAND_CONFIG,
.help = "gpio number for trst.",
.usage = "[trst]",
},
{
.name = "led_num",
.handler = am335xgpio_handle_gpionum_led,
.mode = COMMAND_CONFIG,
.help = "gpio number for led.",
.usage = "[led]",
},
{
.name = "led_on_state",
.handler = am335xgpio_handle_led_on_state,
.mode = COMMAND_CONFIG,
.help = "required state for led pin to turn on LED.",
.usage = "['off'|'on']",
},
{ {
.name = "speed_coeffs", .name = "speed_coeffs",
.handler = am335xgpio_handle_speed_coeffs, .handler = am335xgpio_handle_speed_coeffs,
@ -562,32 +357,33 @@ static struct jtag_interface am335xgpio_interface = {
static bool am335xgpio_jtag_mode_possible(void) static bool am335xgpio_jtag_mode_possible(void)
{ {
if (!is_gpio_valid(tck_gpio)) if (!is_gpio_config_valid(&adapter_gpio_config[ADAPTER_GPIO_IDX_TCK]))
return false; return false;
if (!is_gpio_valid(tms_gpio)) if (!is_gpio_config_valid(&adapter_gpio_config[ADAPTER_GPIO_IDX_TMS]))
return false; return false;
if (!is_gpio_valid(tdi_gpio)) if (!is_gpio_config_valid(&adapter_gpio_config[ADAPTER_GPIO_IDX_TDI]))
return false; return false;
if (!is_gpio_valid(tdo_gpio)) if (!is_gpio_config_valid(&adapter_gpio_config[ADAPTER_GPIO_IDX_TDO]))
return false; return false;
return true; return true;
} }
static bool am335xgpio_swd_mode_possible(void) static bool am335xgpio_swd_mode_possible(void)
{ {
if (!is_gpio_valid(swclk_gpio)) if (!is_gpio_config_valid(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWCLK]))
return false; return false;
if (!is_gpio_valid(swdio_gpio)) if (!is_gpio_config_valid(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO]))
return false; return false;
return true; return true;
} }
static int am335xgpio_init(void) static int am335xgpio_init(void)
{ {
bitbang_interface = &am335xgpio_bitbang;
LOG_INFO("AM335x GPIO JTAG/SWD bitbang driver"); LOG_INFO("AM335x GPIO JTAG/SWD bitbang driver");
bitbang_interface = &am335xgpio_bitbang;
adapter_gpio_config = adapter_gpio_get_config();
if (transport_is_jtag() && !am335xgpio_jtag_mode_possible()) { if (transport_is_jtag() && !am335xgpio_jtag_mode_possible()) {
LOG_ERROR("Require tck, tms, tdi and tdo gpios for JTAG mode"); LOG_ERROR("Require tck, tms, tdi and tdo gpios for JTAG mode");
return ERROR_JTAG_INIT_FAILED; return ERROR_JTAG_INIT_FAILED;
@ -608,99 +404,77 @@ static int am335xgpio_init(void)
return ERROR_JTAG_INIT_FAILED; return ERROR_JTAG_INIT_FAILED;
} }
for (unsigned int i = 0; i < AM335XGPIO_NUM_GPIO_PORTS; ++i) { for (unsigned int i = 0; i < AM335XGPIO_NUM_GPIO_CHIPS; ++i) {
am335xgpio_gpio_port_mmap_addr[i] = mmap(NULL, sysconf(_SC_PAGE_SIZE), PROT_READ | PROT_WRITE, am335xgpio_gpio_chip_mmap_addr[i] = mmap(NULL, sysconf(_SC_PAGE_SIZE), PROT_READ | PROT_WRITE,
MAP_SHARED, dev_mem_fd, am335xgpio_gpio_port_hw_addr[i]); MAP_SHARED, dev_mem_fd, am335xgpio_gpio_chip_hw_addr[i]);
if (am335xgpio_gpio_port_mmap_addr[i] == MAP_FAILED) { if (am335xgpio_gpio_chip_mmap_addr[i] == MAP_FAILED) {
LOG_ERROR("mmap: %s", strerror(errno)); LOG_ERROR("mmap: %s", strerror(errno));
close(dev_mem_fd); close(dev_mem_fd);
return ERROR_JTAG_INIT_FAILED; return ERROR_JTAG_INIT_FAILED;
} }
} }
/* /* Configure JTAG/SWD signals. Default directions and initial states are handled
* Configure TDO as an input, and TDI, TCK, TMS, TRST, SRST as outputs. * by adapter.c and "adapter gpio" command.
* Drive TDI and TCK low, and TMS high.
*/ */
if (transport_is_jtag()) { if (transport_is_jtag()) {
tdo_gpio_mode = get_gpio_mode(tdo_gpio); initialize_gpio(ADAPTER_GPIO_IDX_TDO);
tdi_gpio_mode = get_gpio_mode(tdi_gpio); initialize_gpio(ADAPTER_GPIO_IDX_TDI);
tck_gpio_mode = get_gpio_mode(tck_gpio); initialize_gpio(ADAPTER_GPIO_IDX_TMS);
tms_gpio_mode = get_gpio_mode(tms_gpio); initialize_gpio(ADAPTER_GPIO_IDX_TCK);
LOG_DEBUG("saved GPIO mode for tdo (GPIO #%d): %s", tdo_gpio, get_gpio_mode_name(tdo_gpio_mode)); initialize_gpio(ADAPTER_GPIO_IDX_TRST);
LOG_DEBUG("saved GPIO mode for tdi (GPIO #%d): %s", tdi_gpio, get_gpio_mode_name(tdi_gpio_mode));
LOG_DEBUG("saved GPIO mode for tck (GPIO #%d): %s", tck_gpio, get_gpio_mode_name(tck_gpio_mode));
LOG_DEBUG("saved GPIO mode for tms (GPIO #%d): %s", tms_gpio, get_gpio_mode_name(tms_gpio_mode));
set_gpio_mode(tdo_gpio, AM335XGPIO_GPIO_MODE_INPUT);
set_gpio_mode(tdi_gpio, AM335XGPIO_GPIO_MODE_OUTPUT_LOW);
set_gpio_mode(tms_gpio, AM335XGPIO_GPIO_MODE_OUTPUT_HIGH);
set_gpio_mode(tck_gpio, AM335XGPIO_GPIO_MODE_OUTPUT_LOW);
if (is_gpio_valid(trst_gpio)) {
trst_gpio_mode = get_gpio_mode(trst_gpio);
LOG_DEBUG("saved GPIO mode for trst (GPIO #%d): %s", trst_gpio, get_gpio_mode_name(trst_gpio_mode));
}
} }
if (transport_is_swd()) { if (transport_is_swd()) {
swclk_gpio_mode = get_gpio_mode(swclk_gpio); /* swdio and its buffer should be initialized in the order that prevents
swdio_gpio_mode = get_gpio_mode(swdio_gpio); * two outputs from being connected together. This will occur if the
LOG_DEBUG("saved GPIO mode for swclk (GPIO #%d): %s", swclk_gpio, get_gpio_mode_name(swclk_gpio_mode)); * swdio GPIO of the AM335x is configured as an output while its
LOG_DEBUG("saved GPIO mode for swdio (GPIO #%d): %s", swdio_gpio, get_gpio_mode_name(swdio_gpio_mode)); * external buffer is configured to send the swdio signal from the
if (is_gpio_valid(swdio_dir_gpio)) { * target to the AM335x.
swdio_dir_gpio_mode = get_gpio_mode(swdio_dir_gpio); */
LOG_DEBUG("saved GPIO mode for swdio_dir (GPIO #%d): %s", if (adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO].init_state == ADAPTER_GPIO_INIT_STATE_INPUT) {
swdio_dir_gpio, get_gpio_mode_name(swdio_dir_gpio_mode)); initialize_gpio(ADAPTER_GPIO_IDX_SWDIO);
set_gpio_mode(swdio_dir_gpio, initialize_gpio(ADAPTER_GPIO_IDX_SWDIO_DIR);
swdio_dir_is_active_high ? AM335XGPIO_GPIO_MODE_OUTPUT_HIGH : AM335XGPIO_GPIO_MODE_OUTPUT_LOW); } else {
initialize_gpio(ADAPTER_GPIO_IDX_SWDIO_DIR);
} initialize_gpio(ADAPTER_GPIO_IDX_SWDIO);
set_gpio_mode(swdio_gpio, AM335XGPIO_GPIO_MODE_OUTPUT_LOW);
set_gpio_mode(swclk_gpio, AM335XGPIO_GPIO_MODE_OUTPUT_LOW);
} }
if (is_gpio_valid(srst_gpio)) { initialize_gpio(ADAPTER_GPIO_IDX_SWCLK);
srst_gpio_mode = get_gpio_mode(srst_gpio);
LOG_DEBUG("saved GPIO mode for srst (GPIO #%d): %s", srst_gpio, get_gpio_mode_name(srst_gpio_mode));
} }
if (is_gpio_valid(led_gpio)) { initialize_gpio(ADAPTER_GPIO_IDX_SRST);
led_gpio_mode = get_gpio_mode(led_gpio); initialize_gpio(ADAPTER_GPIO_IDX_LED);
LOG_DEBUG("saved GPIO mode for led (GPIO #%d): %s", led_gpio, get_gpio_mode_name(led_gpio_mode));
set_gpio_mode(led_gpio,
led_is_active_high ? AM335XGPIO_GPIO_MODE_OUTPUT_LOW : AM335XGPIO_GPIO_MODE_OUTPUT_HIGH);
}
/* Set GPIO modes for TRST and SRST and make both inactive */
am335xgpio_reset(0, 0);
return ERROR_OK; return ERROR_OK;
} }
static int am335xgpio_quit(void) static int am335xgpio_quit(void)
{ {
if (transport_is_jtag()) { if (transport_is_jtag()) {
set_gpio_mode(tdo_gpio, tdo_gpio_mode); restore_gpio(ADAPTER_GPIO_IDX_TDO);
set_gpio_mode(tdi_gpio, tdi_gpio_mode); restore_gpio(ADAPTER_GPIO_IDX_TDI);
set_gpio_mode(tck_gpio, tck_gpio_mode); restore_gpio(ADAPTER_GPIO_IDX_TMS);
set_gpio_mode(tms_gpio, tms_gpio_mode); restore_gpio(ADAPTER_GPIO_IDX_TCK);
if (is_gpio_valid(trst_gpio)) restore_gpio(ADAPTER_GPIO_IDX_TRST);
set_gpio_mode(trst_gpio, trst_gpio_mode);
} }
if (transport_is_swd()) { if (transport_is_swd()) {
set_gpio_mode(swclk_gpio, swclk_gpio_mode); /* Restore swdio/swdio_dir to their initial modes, even if that means
set_gpio_mode(swdio_gpio, swdio_gpio_mode); * connecting two outputs. Begin by making swdio an input so that the
if (is_gpio_valid(swdio_dir_gpio)) * current and final states of swdio and swdio_dir do not have to be
set_gpio_mode(swdio_dir_gpio, swdio_dir_gpio_mode); * considered to calculate the safe restoration order.
*/
AM335XGPIO_SET_INPUT(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO]);
restore_gpio(ADAPTER_GPIO_IDX_SWDIO_DIR);
restore_gpio(ADAPTER_GPIO_IDX_SWDIO);
restore_gpio(ADAPTER_GPIO_IDX_SWCLK);
} }
if (is_gpio_valid(srst_gpio)) restore_gpio(ADAPTER_GPIO_IDX_SRST);
set_gpio_mode(srst_gpio, srst_gpio_mode); restore_gpio(ADAPTER_GPIO_IDX_LED);
if (is_gpio_valid(led_gpio))
set_gpio_mode(led_gpio, led_gpio_mode);
return ERROR_OK; return ERROR_OK;
} }

View File

@ -863,4 +863,106 @@ proc "xds110 serial" {args} {
eval adapter serial $args eval adapter serial $args
} }
lappend _telnet_autocomplete_skip "am335xgpio jtag_nums"
proc "am335xgpio jtag_nums" {tck_num tms_num tdi_num tdo_num} {
echo "DEPRECATED! use 'adapter gpio tck; adapter gpio tms; adapter gpio tdi; adapter gpio tdo' not 'am335xgpio jtag_nums'"
eval adapter gpio tck [expr {$tck_num % 32}] -chip [expr {$tck_num / 32}]
eval adapter gpio tms [expr {$tms_num % 32}] -chip [expr {$tms_num / 32}]
eval adapter gpio tdi [expr {$tdi_num % 32}] -chip [expr {$tdi_num / 32}]
eval adapter gpio tdo [expr {$tdo_num % 32}] -chip [expr {$tdo_num / 32}]
}
lappend _telnet_autocomplete_skip "am335xgpio tck_num"
proc "am335xgpio tck_num" {num} {
echo "DEPRECATED! use 'adapter gpio tck' not 'am335xgpio tck_num'"
eval adapter gpio tck [expr {$num % 32}] -chip [expr {$num / 32}]
}
lappend _telnet_autocomplete_skip "am335xgpio tms_num"
proc "am335xgpio tms_num" {num} {
echo "DEPRECATED! use 'adapter gpio tms' not 'am335xgpio tms_num'"
eval adapter gpio tms [expr {$num % 32}] -chip [expr {$num / 32}]
}
lappend _telnet_autocomplete_skip "am335xgpio tdi_num"
proc "am335xgpio tdi_num" {num} {
echo "DEPRECATED! use 'adapter gpio tdi' not 'am335xgpio tdi_num'"
eval adapter gpio tdi [expr {$num % 32}] -chip [expr {$num / 32}]
}
lappend _telnet_autocomplete_skip "am335xgpio tdo_num"
proc "am335xgpio tdo_num" {num} {
echo "DEPRECATED! use 'adapter gpio tdo' not 'am335xgpio tdo_num'"
eval adapter gpio tdo [expr {$num % 32}] -chip [expr {$num / 32}]
}
lappend _telnet_autocomplete_skip "am335xgpio swd_nums"
proc "am335xgpio swd_nums" {swclk swdio} {
echo "DEPRECATED! use 'adapter gpio swclk; adapter gpio swdio' not 'am335xgpio jtag_nums'"
eval adapter gpio swclk [expr {$swclk % 32}] -chip [expr {$swclk / 32}]
eval adapter gpio swdio [expr {$swdio % 32}] -chip [expr {$swdio / 32}]
}
lappend _telnet_autocomplete_skip "am335xgpio swclk_num"
proc "am335xgpio swclk_num" {num} {
echo "DEPRECATED! use 'adapter gpio swclk' not 'am335xgpio swclk_num'"
eval adapter gpio swclk [expr {$num % 32}] -chip [expr {$num / 32}]
}
lappend _telnet_autocomplete_skip "am335xgpio swdio_num"
proc "am335xgpio swdio_num" {num} {
echo "DEPRECATED! use 'adapter gpio swdio' not 'am335xgpio swdio_num'"
eval adapter gpio swdio [expr {$num % 32}] -chip [expr {$num / 32}]
}
lappend _telnet_autocomplete_skip "am335xgpio swdio_dir_num"
proc "am335xgpio swdio_dir_num" {num} {
echo "DEPRECATED! use 'adapter gpio swdio_dir' not 'am335xgpio swdio_dir_num'"
eval adapter gpio swdio_dir [expr {$num % 32}] -chip [expr {$num / 32}]
}
lappend _telnet_autocomplete_skip "am335xgpio swdio_dir_output_state"
proc "am335xgpio swdio_dir_output_state" {state} {
echo "DEPRECATED! use 'adapter gpio swdio_dir -active-high' or 'adapter gpio swdio_dir -active-low', not 'am335xgpio swdio_dir_output_state'"
switch $state {
"high"
{eval adapter gpio swdio_dir -active-high}
"low"
{eval adapter gpio swdio_dir -active-low}
default
{return -code 1 -level 1 "am335xgpio swdio_dir_output_state: syntax error"}
}
}
lappend _telnet_autocomplete_skip "am335xgpio srst_num"
proc "am335xgpio srst_num" {num} {
echo "DEPRECATED! use 'adapter gpio srst' not 'am335xgpio srst_num'"
eval adapter gpio srst [expr {$num % 32}] -chip [expr {$num / 32}]
}
lappend _telnet_autocomplete_skip "am335xgpio trst_num"
proc "am335xgpio trst_num" {num} {
echo "DEPRECATED! use 'adapter gpio trst' not 'am335xgpio trst_num'"
eval adapter gpio trst [expr {$num % 32}] -chip [expr {$num / 32}]
}
lappend _telnet_autocomplete_skip "am335xgpio led_num"
proc "am335xgpio led_num" {num} {
echo "DEPRECATED! use 'adapter gpio led' not 'am335xgpio led_num'"
eval adapter gpio led [expr {$num % 32}] -chip [expr {$num / 32}]
}
lappend _telnet_autocomplete_skip "am335xgpio led_on_state"
proc "am335xgpio led_on_state" {state} {
echo "DEPRECATED! use 'adapter gpio led -active-high' or 'adapter gpio led -active-low', not 'am335xgpio led_on_state'"
switch $state {
"high"
{eval adapter gpio led -active-high}
"low"
{eval adapter gpio led -active-low}
default
{return -code 1 -level 1 "am335xgpio led_on_state: syntax error"}
}
}
# END MIGRATION AIDS # END MIGRATION AIDS

View File

@ -16,13 +16,21 @@ adapter driver am335xgpio
# am335xgpio speed SPEED_COEFF SPEED_OFFSET # am335xgpio speed SPEED_COEFF SPEED_OFFSET
am335xgpio speed_coeffs 600000 575 am335xgpio speed_coeffs 600000 575
am335xgpio tdo_num 20 # BeagleBone pin P9_41
am335xgpio tdi_num 60 adapter gpio tdo 20 -chip 0
am335xgpio tms_num 4
am335xgpio tck_num 2
am335xgpio led_num 51 # BeagleBone pin P9_12
am335xgpio led_on_state on adapter gpio tdi 28 -chip 1
am335xgpio srst_num 65 # BeagleBone pin P9_18
adapter gpio tms 4 -chip 0
# BeagleBone pin P9_22
adapter gpio tck 2 -chip 0
# BeagleBone pin P9_16
adapter gpio led 19 -chip 1
# BeagleBone pin P8_18
adapter gpio srst 1 -chip 2
reset_config srst_only srst_push_pull reset_config srst_only srst_push_pull

View File

@ -16,14 +16,18 @@ adapter driver am335xgpio
# am335xgpio speed SPEED_COEFF SPEED_OFFSET # am335xgpio speed SPEED_COEFF SPEED_OFFSET
am335xgpio speed_coeffs 600000 575 am335xgpio speed_coeffs 600000 575
am335xgpio swclk_num 2 # BeagleBone pin P9_22
am335xgpio swdio_num 4 adapter gpio swclk 2 -chip 0
am335xgpio swdio_dir_num 60
am335xgpio swdio_dir_output_state on # BeagleBone pin P9_18
adapter gpio swdio 4 -chip 0
# BeagleBone pin P9_12
adapter gpio swdio_dir 28 -chip 1
# USR0 LED # USR0 LED
am335xgpio led_num 53 adapter gpio led 21 -chip 1
am335xgpio led_on_state on
am335xgpio srst_num 65 # BeagleBone pin P8_18
adapter gpio srst 1 -chip 2
reset_config srst_only srst_push_pull reset_config srst_only srst_push_pull

View File

@ -0,0 +1,70 @@
# SPDX-License-Identifier: GPL-2.0-or-later
# OpenOCD script to test that the deprecated "am335xgpio *" commands produce the
# expected results. Run this command as:
#
# openocd -f <path>/test-linuxgpiod-deprecated-commands.cfg
# Raise an error if the "actual" value does not match the "expected" value. Trim
# whitespace (including newlines) from strings before comparing.
proc expected_value {expected actual} {
if {[string trim $expected] ne [string trim $actual]} {
error [puts "ERROR: '${actual}' != '${expected}'"]
}
}
adapter driver am335xgpio
am335xgpio jtag_nums 1 2 3 4
expected_value "adapter gpio tck (output): num 1, chip 0, active-high, push-pull, pull-none, init-state inactive" [eval adapter gpio tck]
expected_value "adapter gpio tms (output): num 2, chip 0, active-high, push-pull, pull-none, init-state active" [eval adapter gpio tms]
expected_value "adapter gpio tdi (output): num 3, chip 0, active-high, push-pull, pull-none, init-state inactive" [eval adapter gpio tdi]
expected_value "adapter gpio tdo (input): num 4, chip 0, active-high, pull-none, init-state input" [eval adapter gpio tdo]
am335xgpio tck_num 5
expected_value "adapter gpio tck (output): num 5, chip 0, active-high, push-pull, pull-none, init-state inactive" [eval adapter gpio tck]
am335xgpio tms_num 6
expected_value "adapter gpio tms (output): num 6, chip 0, active-high, push-pull, pull-none, init-state active" [eval adapter gpio tms]
am335xgpio tdi_num 7
expected_value "adapter gpio tdi (output): num 7, chip 0, active-high, push-pull, pull-none, init-state inactive" [eval adapter gpio tdi]
am335xgpio tdo_num 8
expected_value "adapter gpio tdo (input): num 8, chip 0, active-high, pull-none, init-state input" [eval adapter gpio tdo]
am335xgpio swd_nums 9 10
expected_value "adapter gpio swclk (output): num 9, chip 0, active-high, push-pull, pull-none, init-state inactive" [eval adapter gpio swclk]
expected_value "adapter gpio swdio (bidirectional): num 10, chip 0, active-high, push-pull, pull-none, init-state inactive" [eval adapter gpio swdio]
am335xgpio swclk_num 11
expected_value "adapter gpio swclk (output): num 11, chip 0, active-high, push-pull, pull-none, init-state inactive" [eval adapter gpio swclk]
am335xgpio swdio_num 12
expected_value "adapter gpio swdio (bidirectional): num 12, chip 0, active-high, push-pull, pull-none, init-state inactive" [eval adapter gpio swdio]
am335xgpio swdio_dir_num 13
expected_value "adapter gpio swdio_dir (output): num 13, chip 0, active-high, push-pull, pull-none" [eval adapter gpio swdio_dir]
am335xgpio swdio_dir_output_state low
expected_value "adapter gpio swdio_dir (output): num 13, chip 0, active-low, push-pull, pull-none" [eval adapter gpio swdio_dir]
am335xgpio swdio_dir_output_state high
expected_value "adapter gpio swdio_dir (output): num 13, chip 0, active-high, push-pull, pull-none" [eval adapter gpio swdio_dir]
am335xgpio srst_num 14
expected_value "adapter gpio srst (output): num 14, chip 0, active-low, pull-none, init-state inactive" [eval adapter gpio srst]
am335xgpio trst_num 15
expected_value "adapter gpio trst (output): num 15, chip 0, active-low, pull-none, init-state inactive" [eval adapter gpio trst]
am335xgpio led_num 16
expected_value "adapter gpio led (output): num 16, chip 0, active-high, push-pull, pull-none, init-state inactive" [eval adapter gpio led]
am335xgpio led_on_state low
expected_value "adapter gpio led (output): num 16, chip 0, active-low, push-pull, pull-none, init-state inactive" [eval adapter gpio led]
am335xgpio led_on_state high
expected_value "adapter gpio led (output): num 16, chip 0, active-high, push-pull, pull-none, init-state inactive" [eval adapter gpio led]
puts "SUCCESS"