drivers/bcm2835gpio: Migrate to adapter gpio commands
authorSteve Marple <stevemarple@googlemail.com>
Sat, 25 Jun 2022 22:45:18 +0000 (23:45 +0100)
committerAntonio Borneo <borneo.antonio@gmail.com>
Tue, 13 Sep 2022 22:17:14 +0000 (22:17 +0000)
Use the new "adapter gpio" commands to configure the GPIOs used by the
bcm2835gpio driver. The driver supports only 1 chip (gpiochip0).

The reset function now honours the srst_open_drain and trst_open_drain
options.

Signed-off-by: Steve Marple <stevemarple@googlemail.com>
Change-Id: I5b6c68b16362000cf5141a83394549d2bf3af108
Reviewed-on: https://review.openocd.org/c/openocd/+/7123
Tested-by: jenkins
Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com>
doc/openocd.texi
src/jtag/drivers/bcm2835gpio.c
src/jtag/startup.tcl
tcl/interface/jtag_hat_rpi2.cfg
tcl/interface/raspberrypi-native.cfg
tcl/interface/raspberrypi2-native.cfg
testing/test-bcm2835gpio-deprecated-commands.cfg [new file with mode: 0644]

index 3e56079fe5a7280f1f7ffb95012d10f88a40dd9b..fc86429d16f722884b2809b2b4bbc851f009357f 100644 (file)
@@ -3292,66 +3292,12 @@ able to coexist nicely with both sysfs bitbanging and various
 peripherals' kernel drivers. The driver restores the previous
 configuration on exit.
 
 peripherals' kernel drivers. The driver restores the previous
 configuration on exit.
 
-GPIO numbers >= 32 can't be used for performance reasons.
+GPIO numbers >= 32 can't be used for performance reasons. GPIO configuration is
+handled by the generic command @ref{adapter gpio, @command{adapter gpio}}.
 
 See @file{interface/raspberrypi-native.cfg} for a sample config and
 pinout.
 
 
 See @file{interface/raspberrypi-native.cfg} for a sample config and
 pinout.
 
-@deffn {Config Command} {bcm2835gpio 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} {bcm2835gpio tck_num} @var{tck}
-Set TCK GPIO number. Must be specified to enable JTAG transport. Can also be
-specified using the configuration command @command{bcm2835gpio jtag_nums}.
-@end deffn
-
-@deffn {Config Command} {bcm2835gpio tms_num} @var{tms}
-Set TMS GPIO number. Must be specified to enable JTAG transport. Can also be
-specified using the configuration command @command{bcm2835gpio jtag_nums}.
-@end deffn
-
-@deffn {Config Command} {bcm2835gpio tdo_num} @var{tdo}
-Set TDO GPIO number. Must be specified to enable JTAG transport. Can also be
-specified using the configuration command @command{bcm2835gpio jtag_nums}.
-@end deffn
-
-@deffn {Config Command} {bcm2835gpio tdi_num} @var{tdi}
-Set TDI GPIO number. Must be specified to enable JTAG transport. Can also be
-specified using the configuration command @command{bcm2835gpio jtag_nums}.
-@end deffn
-
-@deffn {Config Command} {bcm2835gpio 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} {bcm2835gpio swclk_num} @var{swclk}
-Set SWCLK GPIO number. Must be specified to enable SWD transport. Can also be
-specified using the configuration command @command{bcm2835gpio swd_nums}.
-@end deffn
-
-@deffn {Config Command} {bcm2835gpio swdio_num} @var{swdio}
-Set SWDIO GPIO number. Must be specified to enable SWD transport. Can also be
-specified using the configuration command @command{bcm2835gpio swd_nums}.
-@end deffn
-
-@deffn {Config Command} {bcm2835gpio swdio_dir_num} @var{swdio} @var{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 (set=output
-mode, clear=input mode). If not specified, this feature is disabled.
-@end deffn
-
-@deffn {Config Command} {bcm2835gpio srst_num} @var{srst}
-Set SRST GPIO number. Must be specified to enable SRST.
-@end deffn
-
-@deffn {Config Command} {bcm2835gpio trst_num} @var{trst}
-Set TRST GPIO number. Must be specified to enable TRST.
-@end deffn
-
 @deffn {Config Command} {bcm2835gpio speed_coeffs} @var{speed_coeff} @var{speed_offset}
 Set SPEED_COEFF and SPEED_OFFSET for delay calculations. If unspecified,
 speed_coeff defaults to 113714, and speed_offset defaults to 28.
 @deffn {Config Command} {bcm2835gpio speed_coeffs} @var{speed_coeff} @var{speed_offset}
 Set SPEED_COEFF and SPEED_OFFSET for delay calculations. If unspecified,
 speed_coeff defaults to 113714, and speed_offset defaults to 28.
index 0bbbc6fced2f5d75f80d0f9b12697a4f92d3e0b9..f1538dda7f13a7b91db4457c001f579e48a460aa 100644 (file)
@@ -12,6 +12,7 @@
 #include "config.h"
 #endif
 
 #include "config.h"
 #endif
 
+#include <jtag/adapter.h>
 #include <jtag/interface.h>
 #include <transport/transport.h>
 #include "bitbang.h"
 #include <jtag/interface.h>
 #include <transport/transport.h>
 #include "bitbang.h"
@@ -24,13 +25,17 @@ uint32_t bcm2835_peri_base = 0x20000000;
 #define BCM2835_PADS_GPIO_0_27         (bcm2835_peri_base + 0x100000)
 #define BCM2835_PADS_GPIO_0_27_OFFSET  (0x2c / 4)
 
 #define BCM2835_PADS_GPIO_0_27         (bcm2835_peri_base + 0x100000)
 #define BCM2835_PADS_GPIO_0_27_OFFSET  (0x2c / 4)
 
+/* See "GPIO Function Select Registers (GPFSELn)" in "Broadcom BCM2835 ARM Peripherals" datasheet. */
+#define BCM2835_GPIO_MODE_INPUT 0
+#define BCM2835_GPIO_MODE_OUTPUT 1
+
 /* GPIO setup macros */
 #define MODE_GPIO(g) (*(pio_base+((g)/10))>>(((g)%10)*3) & 7)
 #define INP_GPIO(g) do { *(pio_base+((g)/10)) &= ~(7<<(((g)%10)*3)); } while (0)
 #define SET_MODE_GPIO(g, m) do { /* clear the mode bits first, then set as necessary */ \
                INP_GPIO(g);                                            \
                *(pio_base+((g)/10)) |=  ((m)<<(((g)%10)*3)); } while (0)
 /* GPIO setup macros */
 #define MODE_GPIO(g) (*(pio_base+((g)/10))>>(((g)%10)*3) & 7)
 #define INP_GPIO(g) do { *(pio_base+((g)/10)) &= ~(7<<(((g)%10)*3)); } while (0)
 #define SET_MODE_GPIO(g, m) do { /* clear the mode bits first, then set as necessary */ \
                INP_GPIO(g);                                            \
                *(pio_base+((g)/10)) |=  ((m)<<(((g)%10)*3)); } while (0)
-#define OUT_GPIO(g) SET_MODE_GPIO(g, 1)
+#define OUT_GPIO(g) SET_MODE_GPIO(g, BCM2835_GPIO_MODE_OUTPUT)
 
 #define GPIO_SET (*(pio_base+7))  /* sets   bits which are 1, ignores bits which are 0 */
 #define GPIO_CLR (*(pio_base+10)) /* clears bits which are 1, ignores bits which are 0 */
 
 #define GPIO_SET (*(pio_base+7))  /* sets   bits which are 1, ignores bits which are 0 */
 #define GPIO_CLR (*(pio_base+10)) /* clears bits which are 1, ignores bits which are 0 */
@@ -40,64 +45,109 @@ static int dev_mem_fd;
 static volatile uint32_t *pio_base = MAP_FAILED;
 static volatile uint32_t *pads_base = MAP_FAILED;
 
 static volatile uint32_t *pio_base = MAP_FAILED;
 static volatile uint32_t *pads_base = MAP_FAILED;
 
-static bb_value_t bcm2835gpio_read(void);
-static int bcm2835gpio_write(int tck, int tms, int tdi);
-
-static int bcm2835_swdio_read(void);
-static void bcm2835_swdio_drive(bool is_output);
-static int bcm2835gpio_swd_write(int swclk, int swdio);
-
-static int bcm2835gpio_init(void);
-static int bcm2835gpio_quit(void);
-
-static struct bitbang_interface bcm2835gpio_bitbang = {
-       .read = bcm2835gpio_read,
-       .write = bcm2835gpio_write,
-       .swdio_read = bcm2835_swdio_read,
-       .swdio_drive = bcm2835_swdio_drive,
-       .swd_write = bcm2835gpio_swd_write,
-       .blink = NULL
-};
-
-/* GPIO numbers for each signal. Negative values are invalid */
-static int tck_gpio = -1;
-static int tck_gpio_mode;
-static int tms_gpio = -1;
-static int tms_gpio_mode;
-static int tdi_gpio = -1;
-static int tdi_gpio_mode;
-static int tdo_gpio = -1;
-static int tdo_gpio_mode;
-static int trst_gpio = -1;
-static int trst_gpio_mode;
-static int srst_gpio = -1;
-static int srst_gpio_mode;
-static int swclk_gpio = -1;
-static int swclk_gpio_mode;
-static int swdio_gpio = -1;
-static int swdio_gpio_mode;
-static int swdio_dir_gpio = -1;
-static int swdio_dir_gpio_mode;
-
 /* Transition delay coefficients */
 static int speed_coeff = 113714;
 static int speed_offset = 28;
 static unsigned int jtag_delay;
 
 /* Transition delay coefficients */
 static int speed_coeff = 113714;
 static int speed_offset = 28;
 static unsigned int jtag_delay;
 
-static int is_gpio_valid(int gpio)
+static const struct adapter_gpio_config *adapter_gpio_config;
+static int initial_gpio_mode[ADAPTER_GPIO_IDX_NUM];
+
+static bool is_gpio_config_valid(enum adapter_gpio_config_index idx)
 {
 {
-       return gpio >= 0 && gpio <= 31;
+       /* Only chip 0 is supported, accept unset value (-1) too */
+       return adapter_gpio_config[idx].chip_num >= -1
+               && adapter_gpio_config[idx].chip_num <= 0
+               && adapter_gpio_config[idx].gpio_num >= 0
+               && adapter_gpio_config[idx].gpio_num <= 31;
+}
+
+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)
+                       GPIO_SET = 1 << gpio_config->gpio_num;
+               else
+                       GPIO_CLR = 1 << gpio_config->gpio_num;
+               /* 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) {
+                       INP_GPIO(gpio_config->gpio_num);
+               } else {
+                       GPIO_CLR = 1 << gpio_config->gpio_num;
+                       OUT_GPIO(gpio_config->gpio_num);
+               }
+               break;
+       case ADAPTER_GPIO_DRIVE_MODE_OPEN_SOURCE:
+               if (value) {
+                       GPIO_SET = 1 << gpio_config->gpio_num;
+                       OUT_GPIO(gpio_config->gpio_num);
+               } else {
+                       INP_GPIO(gpio_config->gpio_num);
+               }
+               break;
+       }
+}
+
+static void restore_gpio(enum adapter_gpio_config_index idx)
+{
+       if (is_gpio_config_valid(idx))
+               SET_MODE_GPIO(adapter_gpio_config[idx].gpio_num, initial_gpio_mode[idx]);
+}
+
+static void initialize_gpio(enum adapter_gpio_config_index idx)
+{
+       if (!is_gpio_config_valid(idx))
+               return;
+
+       initial_gpio_mode[idx] = MODE_GPIO(adapter_gpio_config[idx].gpio_num);
+       LOG_DEBUG("saved GPIO mode for %s (GPIO %d %d): %d",
+                       adapter_gpio_get_name(idx), adapter_gpio_config[idx].chip_num, adapter_gpio_config[idx].gpio_num,
+                       initial_gpio_mode[idx]);
+
+       if (adapter_gpio_config[idx].pull != ADAPTER_GPIO_PULL_NONE) {
+               LOG_WARNING("BCM2835 GPIO 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:
+               INP_GPIO(adapter_gpio_config[idx].gpio_num);
+               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)
+               OUT_GPIO(adapter_gpio_config[idx].gpio_num);
 }
 
 static bb_value_t bcm2835gpio_read(void)
 {
 }
 
 static bb_value_t bcm2835gpio_read(void)
 {
-       return (GPIO_LEV & 1<<tdo_gpio) ? BB_HIGH : BB_LOW;
+       unsigned int shift = adapter_gpio_config[ADAPTER_GPIO_IDX_TDO].gpio_num;
+       uint32_t value = (GPIO_LEV >> shift) & 1;
+       return value ^ (adapter_gpio_config[ADAPTER_GPIO_IDX_TDO].active_low ? BB_HIGH : BB_LOW);
+
 }
 
 static int bcm2835gpio_write(int tck, int tms, int tdi)
 {
 }
 
 static int bcm2835gpio_write(int tck, int tms, int tdi)
 {
-       uint32_t set = tck<<tck_gpio | tms<<tms_gpio | tdi<<tdi_gpio;
-       uint32_t clear = !tck<<tck_gpio | !tms<<tms_gpio | !tdi<<tdi_gpio;
+       uint32_t set = tck << adapter_gpio_config[ADAPTER_GPIO_IDX_TCK].gpio_num |
+                       tms << adapter_gpio_config[ADAPTER_GPIO_IDX_TMS].gpio_num |
+                       tdi << adapter_gpio_config[ADAPTER_GPIO_IDX_TDI].gpio_num;
+       uint32_t clear = !tck << adapter_gpio_config[ADAPTER_GPIO_IDX_TCK].gpio_num |
+                       !tms << adapter_gpio_config[ADAPTER_GPIO_IDX_TMS].gpio_num |
+                       !tdi << adapter_gpio_config[ADAPTER_GPIO_IDX_TDI].gpio_num;
 
        GPIO_SET = set;
        GPIO_CLR = clear;
 
        GPIO_SET = set;
        GPIO_CLR = clear;
@@ -108,10 +158,16 @@ static int bcm2835gpio_write(int tck, int tms, int tdi)
        return ERROR_OK;
 }
 
        return ERROR_OK;
 }
 
-static int bcm2835gpio_swd_write(int swclk, int swdio)
+/* Requires push-pull drive mode for swclk and swdio */
+static int bcm2835gpio_swd_write_fast(int swclk, int swdio)
 {
 {
-       uint32_t set = swclk << swclk_gpio | swdio << swdio_gpio;
-       uint32_t clear = !swclk << swclk_gpio | !swdio << swdio_gpio;
+       swclk = swclk ^ (adapter_gpio_config[ADAPTER_GPIO_IDX_SWCLK].active_low ? 1 : 0);
+       swdio = swdio ^ (adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO].active_low ? 1 : 0);
+
+       uint32_t set = swclk << adapter_gpio_config[ADAPTER_GPIO_IDX_SWCLK].gpio_num |
+                                       swdio << adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO].gpio_num;
+       uint32_t clear = !swclk << adapter_gpio_config[ADAPTER_GPIO_IDX_SWCLK].gpio_num |
+                                       !swdio << adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO].gpio_num;
 
        GPIO_SET = set;
        GPIO_CLR = clear;
 
        GPIO_SET = set;
        GPIO_CLR = clear;
@@ -122,55 +178,62 @@ static int bcm2835gpio_swd_write(int swclk, int swdio)
        return ERROR_OK;
 }
 
        return ERROR_OK;
 }
 
-/* (1) assert or (0) deassert reset lines */
-static int bcm2835gpio_reset(int trst, int srst)
+/* Generic mode that works for open-drain/open-source drive modes, but slower */
+static int bcm2835gpio_swd_write_generic(int swclk, int swdio)
 {
 {
-       uint32_t set = 0;
-       uint32_t clear = 0;
+       set_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO], swdio);
+       set_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWCLK], swclk); /* Write clock last */
 
 
-       if (is_gpio_valid(trst_gpio)) {
-               set |= !trst<<trst_gpio;
-               clear |= trst<<trst_gpio;
-       }
+       for (unsigned int i = 0; i < jtag_delay; ++i)
+               asm volatile ("");
 
 
-       if (is_gpio_valid(srst_gpio)) {
-               set |= !srst<<srst_gpio;
-               clear |= srst<<srst_gpio;
-       }
+       return ERROR_OK;
+}
 
 
-       GPIO_SET = set;
-       GPIO_CLR = clear;
+/* (1) assert or (0) deassert reset lines */
+static int bcm2835gpio_reset(int trst, int srst)
+{
+       /* As the "adapter reset_config" command keeps the srst and trst gpio drive
+        * mode settings in sync we can use our standard set_gpio_value() function
+        * that honours drive mode and active low.
+        */
+       if (is_gpio_config_valid(ADAPTER_GPIO_IDX_SRST))
+               set_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_SRST], srst);
 
 
+       if (is_gpio_config_valid(ADAPTER_GPIO_IDX_TRST))
+               set_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_TRST], trst);
+
+       LOG_DEBUG("BCM2835 GPIO: bcm2835gpio_reset(%d, %d), trst_gpio: %d %d, srst_gpio: %d %d",
+               trst, srst,
+               adapter_gpio_config[ADAPTER_GPIO_IDX_TRST].chip_num, adapter_gpio_config[ADAPTER_GPIO_IDX_TRST].gpio_num,
+               adapter_gpio_config[ADAPTER_GPIO_IDX_SRST].chip_num, adapter_gpio_config[ADAPTER_GPIO_IDX_SRST].gpio_num);
        return ERROR_OK;
 }
 
 static void bcm2835_swdio_drive(bool is_output)
 {
        return ERROR_OK;
 }
 
 static void bcm2835_swdio_drive(bool is_output)
 {
-       if (is_gpio_valid(swdio_dir_gpio)) {
-               if (is_output) {
-                       GPIO_SET = 1 << swdio_dir_gpio;
-                       OUT_GPIO(swdio_gpio);
-               } else {
-                       INP_GPIO(swdio_gpio);
-                       GPIO_CLR = 1 << swdio_dir_gpio;
-               }
+       if (is_output) {
+               if (is_gpio_config_valid(ADAPTER_GPIO_IDX_SWDIO_DIR))
+                       set_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO_DIR], 1);
+               OUT_GPIO(adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO].gpio_num);
        } else {
        } else {
-               if (is_output)
-                       OUT_GPIO(swdio_gpio);
-               else
-                       INP_GPIO(swdio_gpio);
+               INP_GPIO(adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO].gpio_num);
+               if (is_gpio_config_valid(ADAPTER_GPIO_IDX_SWDIO_DIR))
+                       set_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO_DIR], 0);
        }
 }
 
 static int bcm2835_swdio_read(void)
 {
        }
 }
 
 static int bcm2835_swdio_read(void)
 {
-       return !!(GPIO_LEV & 1 << swdio_gpio);
+       unsigned int shift = adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO].gpio_num;
+       uint32_t value = (GPIO_LEV >> shift) & 1;
+       return value ^ (adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO].active_low ? 1 : 0);
 }
 
 static int bcm2835gpio_khz(int khz, int *jtag_speed)
 {
        if (!khz) {
 }
 
 static int bcm2835gpio_khz(int khz, int *jtag_speed)
 {
        if (!khz) {
-               LOG_DEBUG("RCLK not supported");
+               LOG_DEBUG("BCM2835 GPIO: RCLK not supported");
                return ERROR_FAIL;
        }
        *jtag_speed = speed_coeff/khz - speed_offset;
                return ERROR_FAIL;
        }
        *jtag_speed = speed_coeff/khz - speed_offset;
@@ -191,121 +254,6 @@ static int bcm2835gpio_speed(int speed)
        return ERROR_OK;
 }
 
        return ERROR_OK;
 }
 
-COMMAND_HANDLER(bcm2835gpio_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,
-                       "BCM2835 GPIO config: tck = %d, tms = %d, tdi = %d, tdo = %d",
-                       tck_gpio, tms_gpio, tdi_gpio, tdo_gpio);
-
-       return ERROR_OK;
-}
-
-COMMAND_HANDLER(bcm2835gpio_handle_jtag_gpionum_tck)
-{
-       if (CMD_ARGC == 1)
-               COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tck_gpio);
-
-       command_print(CMD, "BCM2835 GPIO config: tck = %d", tck_gpio);
-       return ERROR_OK;
-}
-
-COMMAND_HANDLER(bcm2835gpio_handle_jtag_gpionum_tms)
-{
-       if (CMD_ARGC == 1)
-               COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tms_gpio);
-
-       command_print(CMD, "BCM2835 GPIO config: tms = %d", tms_gpio);
-       return ERROR_OK;
-}
-
-COMMAND_HANDLER(bcm2835gpio_handle_jtag_gpionum_tdo)
-{
-       if (CMD_ARGC == 1)
-               COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tdo_gpio);
-
-       command_print(CMD, "BCM2835 GPIO config: tdo = %d", tdo_gpio);
-       return ERROR_OK;
-}
-
-COMMAND_HANDLER(bcm2835gpio_handle_jtag_gpionum_tdi)
-{
-       if (CMD_ARGC == 1)
-               COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tdi_gpio);
-
-       command_print(CMD, "BCM2835 GPIO config: tdi = %d", tdi_gpio);
-       return ERROR_OK;
-}
-
-COMMAND_HANDLER(bcm2835gpio_handle_jtag_gpionum_srst)
-{
-       if (CMD_ARGC == 1)
-               COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], srst_gpio);
-
-       command_print(CMD, "BCM2835 GPIO config: srst = %d", srst_gpio);
-       return ERROR_OK;
-}
-
-COMMAND_HANDLER(bcm2835gpio_handle_jtag_gpionum_trst)
-{
-       if (CMD_ARGC == 1)
-               COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], trst_gpio);
-
-       command_print(CMD, "BCM2835 GPIO config: trst = %d", trst_gpio);
-       return ERROR_OK;
-}
-
-COMMAND_HANDLER(bcm2835gpio_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,
-                       "BCM2835 GPIO nums: swclk = %d, swdio = %d",
-                       swclk_gpio, swdio_gpio);
-
-       return ERROR_OK;
-}
-
-COMMAND_HANDLER(bcm2835gpio_handle_swd_gpionum_swclk)
-{
-       if (CMD_ARGC == 1)
-               COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], swclk_gpio);
-
-       command_print(CMD, "BCM2835 num: swclk = %d", swclk_gpio);
-       return ERROR_OK;
-}
-
-COMMAND_HANDLER(bcm2835gpio_handle_swd_gpionum_swdio)
-{
-       if (CMD_ARGC == 1)
-               COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], swdio_gpio);
-
-       command_print(CMD, "BCM2835 num: swdio = %d", swdio_gpio);
-       return ERROR_OK;
-}
-
-COMMAND_HANDLER(bcm2835gpio_handle_swd_dir_gpionum_swdio)
-{
-       if (CMD_ARGC == 1)
-               COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], swdio_dir_gpio);
-
-       command_print(CMD, "BCM2835 num: swdio_dir = %d", swdio_dir_gpio);
-       return ERROR_OK;
-}
-
 COMMAND_HANDLER(bcm2835gpio_handle_speed_coeffs)
 {
        if (CMD_ARGC == 2) {
 COMMAND_HANDLER(bcm2835gpio_handle_speed_coeffs)
 {
        if (CMD_ARGC == 2) {
@@ -329,83 +277,6 @@ COMMAND_HANDLER(bcm2835gpio_handle_peripheral_base)
 }
 
 static const struct command_registration bcm2835gpio_subcommand_handlers[] = {
 }
 
 static const struct command_registration bcm2835gpio_subcommand_handlers[] = {
-       {
-               .name = "jtag_nums",
-               .handler = &bcm2835gpio_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 = &bcm2835gpio_handle_jtag_gpionum_tck,
-               .mode = COMMAND_CONFIG,
-               .help = "gpio number for tck.",
-               .usage = "[tck]",
-       },
-       {
-               .name = "tms_num",
-               .handler = &bcm2835gpio_handle_jtag_gpionum_tms,
-               .mode = COMMAND_CONFIG,
-               .help = "gpio number for tms.",
-               .usage = "[tms]",
-       },
-       {
-               .name = "tdo_num",
-               .handler = &bcm2835gpio_handle_jtag_gpionum_tdo,
-               .mode = COMMAND_CONFIG,
-               .help = "gpio number for tdo.",
-               .usage = "[tdo]",
-       },
-       {
-               .name = "tdi_num",
-               .handler = &bcm2835gpio_handle_jtag_gpionum_tdi,
-               .mode = COMMAND_CONFIG,
-               .help = "gpio number for tdi.",
-               .usage = "[tdi]",
-       },
-       {
-               .name = "swd_nums",
-               .handler = &bcm2835gpio_handle_swd_gpionums,
-               .mode = COMMAND_CONFIG,
-               .help = "gpio numbers for swclk, swdio. (in that order)",
-               .usage = "[swclk swdio]",
-       },
-       {
-               .name = "swclk_num",
-               .handler = &bcm2835gpio_handle_swd_gpionum_swclk,
-               .mode = COMMAND_CONFIG,
-               .help = "gpio number for swclk.",
-               .usage = "[swclk]",
-       },
-       {
-               .name = "swdio_num",
-               .handler = &bcm2835gpio_handle_swd_gpionum_swdio,
-               .mode = COMMAND_CONFIG,
-               .help = "gpio number for swdio.",
-               .usage = "[swdio]",
-       },
-       {
-               .name = "swdio_dir_num",
-               .handler = &bcm2835gpio_handle_swd_dir_gpionum_swdio,
-               .mode = COMMAND_CONFIG,
-               .help = "gpio number for swdio direction control pin (set=output mode, clear=input mode)",
-               .usage = "[swdio_dir]",
-       },
-       {
-               .name = "srst_num",
-               .handler = &bcm2835gpio_handle_jtag_gpionum_srst,
-               .mode = COMMAND_CONFIG,
-               .help = "gpio number for srst.",
-               .usage = "[srst]",
-       },
-       {
-               .name = "trst_num",
-               .handler = &bcm2835gpio_handle_jtag_gpionum_trst,
-               .mode = COMMAND_CONFIG,
-               .help = "gpio number for trst.",
-               .usage = "[trst]",
-       },
        {
                .name = "speed_coeffs",
                .handler = &bcm2835gpio_handle_speed_coeffs,
        {
                .name = "speed_coeffs",
                .handler = &bcm2835gpio_handle_speed_coeffs,
@@ -435,49 +306,26 @@ static const struct command_registration bcm2835gpio_command_handlers[] = {
        COMMAND_REGISTRATION_DONE
 };
 
        COMMAND_REGISTRATION_DONE
 };
 
-static const char * const bcm2835_transports[] = { "jtag", "swd", NULL };
-
-static struct jtag_interface bcm2835gpio_interface = {
-       .supported = DEBUG_CAP_TMS_SEQ,
-       .execute_queue = bitbang_execute_queue,
-};
-
-struct adapter_driver bcm2835gpio_adapter_driver = {
-       .name = "bcm2835gpio",
-       .transports = bcm2835_transports,
-       .commands = bcm2835gpio_command_handlers,
-
-       .init = bcm2835gpio_init,
-       .quit = bcm2835gpio_quit,
-       .reset = bcm2835gpio_reset,
-       .speed = bcm2835gpio_speed,
-       .khz = bcm2835gpio_khz,
-       .speed_div = bcm2835gpio_speed_div,
-
-       .jtag_ops = &bcm2835gpio_interface,
-       .swd_ops = &bitbang_swd,
-};
-
 static bool bcm2835gpio_jtag_mode_possible(void)
 {
 static bool bcm2835gpio_jtag_mode_possible(void)
 {
-       if (!is_gpio_valid(tck_gpio))
-               return 0;
-       if (!is_gpio_valid(tms_gpio))
-               return 0;
-       if (!is_gpio_valid(tdi_gpio))
-               return 0;
-       if (!is_gpio_valid(tdo_gpio))
-               return 0;
-       return 1;
+       if (!is_gpio_config_valid(ADAPTER_GPIO_IDX_TCK))
+               return false;
+       if (!is_gpio_config_valid(ADAPTER_GPIO_IDX_TMS))
+               return false;
+       if (!is_gpio_config_valid(ADAPTER_GPIO_IDX_TDI))
+               return false;
+       if (!is_gpio_config_valid(ADAPTER_GPIO_IDX_TDO))
+               return false;
+       return true;
 }
 
 static bool bcm2835gpio_swd_mode_possible(void)
 {
 }
 
 static bool bcm2835gpio_swd_mode_possible(void)
 {
-       if (!is_gpio_valid(swclk_gpio))
-               return 0;
-       if (!is_gpio_valid(swdio_gpio))
-               return 0;
-       return 1;
+       if (!is_gpio_config_valid(ADAPTER_GPIO_IDX_SWCLK))
+               return false;
+       if (!is_gpio_config_valid(ADAPTER_GPIO_IDX_SWDIO))
+               return false;
+       return true;
 }
 
 static void bcm2835gpio_munmap(void)
 }
 
 static void bcm2835gpio_munmap(void)
@@ -493,12 +341,22 @@ static void bcm2835gpio_munmap(void)
        }
 }
 
        }
 }
 
+static struct bitbang_interface bcm2835gpio_bitbang = {
+       .read = bcm2835gpio_read,
+       .write = bcm2835gpio_write,
+       .swdio_read = bcm2835_swdio_read,
+       .swdio_drive = bcm2835_swdio_drive,
+       .swd_write = bcm2835gpio_swd_write_generic,
+       .blink = NULL
+};
+
 static int bcm2835gpio_init(void)
 {
 static int bcm2835gpio_init(void)
 {
-       bitbang_interface = &bcm2835gpio_bitbang;
-
        LOG_INFO("BCM2835 GPIO JTAG/SWD bitbang driver");
 
        LOG_INFO("BCM2835 GPIO JTAG/SWD bitbang driver");
 
+       bitbang_interface = &bcm2835gpio_bitbang;
+       adapter_gpio_config = adapter_gpio_get_config();
+
        if (transport_is_jtag() && !bcm2835gpio_jtag_mode_possible()) {
                LOG_ERROR("Require tck, tms, tdi and tdo gpios for JTAG mode");
                return ERROR_JTAG_INIT_FAILED;
        if (transport_is_jtag() && !bcm2835gpio_jtag_mode_possible()) {
                LOG_ERROR("Require tck, tms, tdi and tdo gpios for JTAG mode");
                return ERROR_JTAG_INIT_FAILED;
@@ -543,58 +401,45 @@ static int bcm2835gpio_init(void)
        /* set 4mA drive strength, slew rate limited, hysteresis on */
        pads_base[BCM2835_PADS_GPIO_0_27_OFFSET] = 0x5a000008 + 1;
 
        /* set 4mA drive strength, slew rate limited, hysteresis on */
        pads_base[BCM2835_PADS_GPIO_0_27_OFFSET] = 0x5a000008 + 1;
 
-       /*
-        * Configure TDO as an input, and TDI, TCK, TMS, TRST, SRST
-        * as outputs.  Drive TDI and TCK low, and TMS/TRST/SRST high.
+       /* Configure JTAG/SWD signals. Default directions and initial states are handled
+        * by adapter.c and "adapter gpio" command.
         */
        if (transport_is_jtag()) {
         */
        if (transport_is_jtag()) {
-               tdo_gpio_mode = MODE_GPIO(tdo_gpio);
-               tdi_gpio_mode = MODE_GPIO(tdi_gpio);
-               tck_gpio_mode = MODE_GPIO(tck_gpio);
-               tms_gpio_mode = MODE_GPIO(tms_gpio);
-
-               INP_GPIO(tdo_gpio);
-
-               GPIO_CLR = 1<<tdi_gpio | 1<<tck_gpio;
-               GPIO_SET = 1<<tms_gpio;
-
-               OUT_GPIO(tdi_gpio);
-               OUT_GPIO(tck_gpio);
-               OUT_GPIO(tms_gpio);
-
-               if (is_gpio_valid(trst_gpio)) {
-                       trst_gpio_mode = MODE_GPIO(trst_gpio);
-                       GPIO_SET = 1 << trst_gpio;
-                       OUT_GPIO(trst_gpio);
-               }
+               initialize_gpio(ADAPTER_GPIO_IDX_TDO);
+               initialize_gpio(ADAPTER_GPIO_IDX_TDI);
+               initialize_gpio(ADAPTER_GPIO_IDX_TMS);
+               initialize_gpio(ADAPTER_GPIO_IDX_TCK);
+               initialize_gpio(ADAPTER_GPIO_IDX_TRST);
        }
 
        if (transport_is_swd()) {
        }
 
        if (transport_is_swd()) {
-               /* Make buffer an output before the GPIO connected to it */
-               if (is_gpio_valid(swdio_dir_gpio)) {
-                       swdio_dir_gpio_mode = MODE_GPIO(swdio_dir_gpio);
-                       GPIO_SET = 1 << swdio_dir_gpio;
-                       OUT_GPIO(swdio_dir_gpio);
+               /* swdio and its buffer should be initialized in the order that prevents
+                * two outputs from being connected together. This will occur if the
+                * swdio GPIO of the AM335x is configured as an output while its
+                * external buffer is configured to send the swdio signal from the
+                * target to the AM335x.
+                */
+               if (adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO].init_state == ADAPTER_GPIO_INIT_STATE_INPUT) {
+                       initialize_gpio(ADAPTER_GPIO_IDX_SWDIO);
+                       initialize_gpio(ADAPTER_GPIO_IDX_SWDIO_DIR);
+               } else {
+                       initialize_gpio(ADAPTER_GPIO_IDX_SWDIO_DIR);
+                       initialize_gpio(ADAPTER_GPIO_IDX_SWDIO);
                }
 
                }
 
-               swclk_gpio_mode = MODE_GPIO(swclk_gpio);
-               swdio_gpio_mode = MODE_GPIO(swdio_gpio);
-
-               GPIO_CLR = 1<<swdio_gpio | 1<<swclk_gpio;
+               initialize_gpio(ADAPTER_GPIO_IDX_SWCLK);
 
 
-               OUT_GPIO(swclk_gpio);
-               OUT_GPIO(swdio_gpio);
-       }
-
-       if (is_gpio_valid(srst_gpio)) {
-               srst_gpio_mode = MODE_GPIO(srst_gpio);
-               GPIO_SET = 1 << srst_gpio;
-               OUT_GPIO(srst_gpio);
+               if (adapter_gpio_config[ADAPTER_GPIO_IDX_SWCLK].drive == ADAPTER_GPIO_DRIVE_MODE_PUSH_PULL &&
+                               adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO].drive == ADAPTER_GPIO_DRIVE_MODE_PUSH_PULL) {
+                       LOG_DEBUG("BCM2835 GPIO using fast mode for SWD write");
+                       bcm2835gpio_bitbang.swd_write = bcm2835gpio_swd_write_fast;
+               } else {
+                       LOG_DEBUG("BCM2835 GPIO using generic mode for SWD write");
+                       bcm2835gpio_bitbang.swd_write = bcm2835gpio_swd_write_generic;
+               }
        }
 
        }
 
-       LOG_DEBUG("saved pinmux settings: tck %d tms %d tdi %d "
-                 "tdo %d trst %d srst %d", tck_gpio_mode, tms_gpio_mode,
-                 tdi_gpio_mode, tdo_gpio_mode, trst_gpio_mode, srst_gpio_mode);
+       initialize_gpio(ADAPTER_GPIO_IDX_SRST);
 
        return ERROR_OK;
 }
 
        return ERROR_OK;
 }
@@ -602,26 +447,51 @@ static int bcm2835gpio_init(void)
 static int bcm2835gpio_quit(void)
 {
        if (transport_is_jtag()) {
 static int bcm2835gpio_quit(void)
 {
        if (transport_is_jtag()) {
-               SET_MODE_GPIO(tdo_gpio, tdo_gpio_mode);
-               SET_MODE_GPIO(tdi_gpio, tdi_gpio_mode);
-               SET_MODE_GPIO(tck_gpio, tck_gpio_mode);
-               SET_MODE_GPIO(tms_gpio, tms_gpio_mode);
-               if (is_gpio_valid(trst_gpio))
-                       SET_MODE_GPIO(trst_gpio, trst_gpio_mode);
+               restore_gpio(ADAPTER_GPIO_IDX_TDO);
+               restore_gpio(ADAPTER_GPIO_IDX_TDI);
+               restore_gpio(ADAPTER_GPIO_IDX_TCK);
+               restore_gpio(ADAPTER_GPIO_IDX_TMS);
+               restore_gpio(ADAPTER_GPIO_IDX_TRST);
        }
 
        if (transport_is_swd()) {
        }
 
        if (transport_is_swd()) {
-               SET_MODE_GPIO(swclk_gpio, swclk_gpio_mode);
-               SET_MODE_GPIO(swdio_gpio, swdio_gpio_mode);
+               /* Restore swdio/swdio_dir to their initial modes, even if that means
+                * connecting two outputs. Begin by making swdio an input so that the
+                * current and final states of swdio and swdio_dir do not have to be
+                * considered to calculate the safe restoration order.
+                */
+               INP_GPIO(adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO].gpio_num);
+               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))
-               SET_MODE_GPIO(srst_gpio, srst_gpio_mode);
-
-       if (is_gpio_valid(swdio_dir_gpio))
-               SET_MODE_GPIO(swdio_dir_gpio, swdio_dir_gpio_mode);
+       restore_gpio(ADAPTER_GPIO_IDX_SRST);
 
        bcm2835gpio_munmap();
 
        return ERROR_OK;
 }
 
        bcm2835gpio_munmap();
 
        return ERROR_OK;
 }
+
+
+static const char * const bcm2835_transports[] = { "jtag", "swd", NULL };
+
+static struct jtag_interface bcm2835gpio_interface = {
+       .supported = DEBUG_CAP_TMS_SEQ,
+       .execute_queue = bitbang_execute_queue,
+};
+struct adapter_driver bcm2835gpio_adapter_driver = {
+       .name = "bcm2835gpio",
+       .transports = bcm2835_transports,
+       .commands = bcm2835gpio_command_handlers,
+
+       .init = bcm2835gpio_init,
+       .quit = bcm2835gpio_quit,
+       .reset = bcm2835gpio_reset,
+       .speed = bcm2835gpio_speed,
+       .khz = bcm2835gpio_khz,
+       .speed_div = bcm2835gpio_speed_div,
+
+       .jtag_ops = &bcm2835gpio_interface,
+       .swd_ops = &bitbang_swd,
+};
index 1a638a30f8f9c8b042113daee06ddf021b69dd16..aeb42ed4f33a0e5a3319b0c64fc62959a090aa52 100644 (file)
@@ -455,70 +455,140 @@ proc vsllink_usb_interface args {
        eval vsllink usb_interface $args
 }
 
        eval vsllink usb_interface $args
 }
 
+
+lappend _telnet_autocomplete_skip bcm2835_gpio_helper
+proc bcm2835_gpio_helper {sig_name args} {
+       set caller [lindex [info level -1] 0]
+       echo "DEPRECATED! use 'adapter gpio $sig_name' not '$caller'"
+       switch [llength $args] {
+               0 {}
+               1 {eval adapter gpio $sig_name $args -chip 0}
+               2 {eval adapter gpio $sig_name [lindex $args 1] -chip [lindex $args 0]}
+               default {return -code 1 -level 1 "$caller: syntax error"}
+       }
+       eval adapter gpio $sig_name
+}
+
 lappend _telnet_autocomplete_skip bcm2835gpio_jtag_nums
 lappend _telnet_autocomplete_skip bcm2835gpio_jtag_nums
-proc bcm2835gpio_jtag_nums args {
-       echo "DEPRECATED! use 'bcm2835gpio jtag_nums' not 'bcm2835gpio_jtag_nums'"
-       eval bcm2835gpio jtag_nums $args
+proc bcm2835gpio_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 'bcm2835gpio_jtag_nums'"
+       eval adapter gpio tck $tck_num -chip 0
+       eval adapter gpio tms $tms_num -chip 0
+       eval adapter gpio tdi $tdi_num -chip 0
+       eval adapter gpio tdo $tdo_num -chip 0
 }
 
 lappend _telnet_autocomplete_skip bcm2835gpio_tck_num
 proc bcm2835gpio_tck_num args {
 }
 
 lappend _telnet_autocomplete_skip bcm2835gpio_tck_num
 proc bcm2835gpio_tck_num args {
-       echo "DEPRECATED! use 'bcm2835gpio tck_num' not 'bcm2835gpio_tck_num'"
-       eval bcm2835gpio tck_num $args
+       eval bcm2835_gpio_helper tck $args
 }
 
 lappend _telnet_autocomplete_skip bcm2835gpio_tms_num
 proc bcm2835gpio_tms_num args {
 }
 
 lappend _telnet_autocomplete_skip bcm2835gpio_tms_num
 proc bcm2835gpio_tms_num args {
-       echo "DEPRECATED! use 'bcm2835gpio tms_num' not 'bcm2835gpio_tms_num'"
-       eval bcm2835gpio tms_num $args
+       eval bcm2835_gpio_helper tms $args
 }
 
 lappend _telnet_autocomplete_skip bcm2835gpio_tdo_num
 proc bcm2835gpio_tdo_num args {
 }
 
 lappend _telnet_autocomplete_skip bcm2835gpio_tdo_num
 proc bcm2835gpio_tdo_num args {
-       echo "DEPRECATED! use 'bcm2835gpio tdo_num' not 'bcm2835gpio_tdo_num'"
-       eval bcm2835gpio tdo_num $args
+       eval bcm2835_gpio_helper tdo $args
 }
 
 lappend _telnet_autocomplete_skip bcm2835gpio_tdi_num
 proc bcm2835gpio_tdi_num args {
 }
 
 lappend _telnet_autocomplete_skip bcm2835gpio_tdi_num
 proc bcm2835gpio_tdi_num args {
-       echo "DEPRECATED! use 'bcm2835gpio tdi_num' not 'bcm2835gpio_tdi_num'"
-       eval bcm2835gpio tdi_num $args
+       eval bcm2835_gpio_helper tdi $args
 }
 
 lappend _telnet_autocomplete_skip bcm2835gpio_swd_nums
 }
 
 lappend _telnet_autocomplete_skip bcm2835gpio_swd_nums
-proc bcm2835gpio_swd_nums args {
-       echo "DEPRECATED! use 'bcm2835gpio swd_nums' not 'bcm2835gpio_swd_nums'"
-       eval bcm2835gpio swd_nums $args
+proc bcm2835gpio_swd_nums {swclk_num swdio_num} {
+       echo "DEPRECATED! use 'adapter gpio swclk; adapter gpio swdio' not 'bcm2835gpio_swd_nums'"
+       eval adapter gpio swclk $swclk_num -chip 0
+       eval adapter gpio swdio $swdio_num -chip 0
 }
 
 lappend _telnet_autocomplete_skip bcm2835gpio_swclk_num
 proc bcm2835gpio_swclk_num args {
 }
 
 lappend _telnet_autocomplete_skip bcm2835gpio_swclk_num
 proc bcm2835gpio_swclk_num args {
-       echo "DEPRECATED! use 'bcm2835gpio swclk_num' not 'bcm2835gpio_swclk_num'"
-       eval bcm2835gpio swclk_num $args
+       eval bcm2835_gpio_helper swclk $args
 }
 
 lappend _telnet_autocomplete_skip bcm2835gpio_swdio_num
 proc bcm2835gpio_swdio_num args {
 }
 
 lappend _telnet_autocomplete_skip bcm2835gpio_swdio_num
 proc bcm2835gpio_swdio_num args {
-       echo "DEPRECATED! use 'bcm2835gpio swdio_num' not 'bcm2835gpio_swdio_num'"
-       eval bcm2835gpio swdio_num $args
+       eval bcm2835_gpio_helper swdio $args
 }
 
 lappend _telnet_autocomplete_skip bcm2835gpio_swdio_dir_num
 proc bcm2835gpio_swdio_dir_num args {
 }
 
 lappend _telnet_autocomplete_skip bcm2835gpio_swdio_dir_num
 proc bcm2835gpio_swdio_dir_num args {
-       echo "DEPRECATED! use 'bcm2835gpio swdio_dir_num' not 'bcm2835gpio_swdio_dir_num'"
-       eval bcm2835gpio swdio_dir_num $args
+       eval bcm2835_gpio_helper swdio_dir $args
 }
 
 lappend _telnet_autocomplete_skip bcm2835gpio_srst_num
 proc bcm2835gpio_srst_num args {
 }
 
 lappend _telnet_autocomplete_skip bcm2835gpio_srst_num
 proc bcm2835gpio_srst_num args {
-       echo "DEPRECATED! use 'bcm2835gpio srst_num' not 'bcm2835gpio_srst_num'"
-       eval bcm2835gpio srst_num $args
+       eval bcm2835_gpio_helper srst $args
 }
 
 lappend _telnet_autocomplete_skip bcm2835gpio_trst_num
 proc bcm2835gpio_trst_num args {
 }
 
 lappend _telnet_autocomplete_skip bcm2835gpio_trst_num
 proc bcm2835gpio_trst_num args {
-       echo "DEPRECATED! use 'bcm2835gpio trst_num' not 'bcm2835gpio_trst_num'"
-       eval bcm2835gpio trst_num $args
+       eval bcm2835_gpio_helper trst $args
+}
+
+lappend _telnet_autocomplete_skip "bcm2835gpio jtag_nums"
+proc "bcm2835gpio 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 'bcm2835gpio jtag_nums'"
+       eval adapter gpio tck $tck_num -chip 0
+       eval adapter gpio tms $tms_num -chip 0
+       eval adapter gpio tdi $tdi_num -chip 0
+       eval adapter gpio tdo $tdo_num -chip 0
+}
+
+lappend _telnet_autocomplete_skip "bcm2835gpio tck_num"
+proc "bcm2835gpio tck_num" args {
+       eval bcm2835_gpio_helper tck $args
+}
+
+lappend _telnet_autocomplete_skip "bcm2835gpio tms_num"
+proc "bcm2835gpio tms_num" args {
+       eval bcm2835_gpio_helper tms $args
+}
+
+lappend _telnet_autocomplete_skip "bcm2835gpio tdo_num"
+proc "bcm2835gpio tdo_num" args {
+       eval bcm2835_gpio_helper tdo $args
+}
+
+lappend _telnet_autocomplete_skip "bcm2835gpio tdi_num"
+proc "bcm2835gpio tdi_num" args {
+       eval bcm2835_gpio_helper tdi $args
+}
+
+lappend _telnet_autocomplete_skip "bcm2835gpio swd_nums"
+proc "bcm2835gpio swd_nums" {swclk_num swdio_num} {
+       echo "DEPRECATED! use 'adapter gpio swclk; adapter gpio swdio' not 'bcm2835gpio swd_nums'"
+       eval adapter gpio swclk $swclk_num -chip 0
+       eval adapter gpio swdio $swdio_num -chip 0
+}
+
+lappend _telnet_autocomplete_skip "bcm2835gpio swclk_num"
+proc "bcm2835gpio swclk_num" args {
+       eval bcm2835_gpio_helper swclk $args
+}
+
+lappend _telnet_autocomplete_skip "bcm2835gpio swdio_num"
+proc "bcm2835gpio swdio_num" args {
+       eval bcm2835_gpio_helper swdio $args
+}
+
+lappend _telnet_autocomplete_skip "bcm2835gpio swdio_dir_num"
+proc "bcm2835gpio swdio_dir_num" args {
+       eval bcm2835_gpio_helper swdio_dir $args
+}
+
+lappend _telnet_autocomplete_skip "bcm2835gpio srst_num"
+proc "bcm2835gpio srst_num" args {
+       eval bcm2835_gpio_helper srst $args
+}
+
+lappend _telnet_autocomplete_skip "bcm2835gpio trst_num"
+proc "bcm2835gpio trst_num" args {
+       eval bcm2835_gpio_helper trst $args
 }
 
 lappend _telnet_autocomplete_skip bcm2835gpio_speed_coeffs
 }
 
 lappend _telnet_autocomplete_skip bcm2835gpio_speed_coeffs
index 495ff0f042da09fc122a7d0d84cd46e1f6ebd3a9..cd1cbfb8af1ab533749713ec40a13627f88dcac1 100644 (file)
@@ -7,31 +7,35 @@
 
 adapter driver bcm2835gpio
 
 
 adapter driver bcm2835gpio
 
-bcm2835gpio_peripheral_base 0x3F000000
+bcm2835gpio peripheral_base 0x3F000000
 
 # Transition delay calculation: SPEED_COEFF/khz - SPEED_OFFSET
 # These depend on system clock, calibrated for stock 700MHz
 # bcm2835gpio_speed SPEED_COEFF SPEED_OFFSET
 
 # Transition delay calculation: SPEED_COEFF/khz - SPEED_OFFSET
 # These depend on system clock, calibrated for stock 700MHz
 # bcm2835gpio_speed SPEED_COEFF SPEED_OFFSET
-bcm2835gpio_speed_coeffs 146203 36
+bcm2835gpio speed_coeffs 146203 36
 
 # Each of the JTAG lines need a gpio number set: tck tms tdi tdo
 # Header pin numbers: 23 22 19 21
 
 # Each of the JTAG lines need a gpio number set: tck tms tdi tdo
 # Header pin numbers: 23 22 19 21
-bcm2835gpio_jtag_nums 11 25 10 9
+adapter gpio tck -chip 0 11
+adapter gpio tms -chip 0 25
+adapter gpio tdi -chip 0 10
+adapter gpio tdo -chip 0 9
 
 # Each of the SWD lines need a gpio number set: swclk swdio
 # Header pin numbers: 23 22
 
 # Each of the SWD lines need a gpio number set: swclk swdio
 # Header pin numbers: 23 22
-bcm2835gpio_swd_nums 11 25
+adapter gpio swclk -chip 0 11
+adapter gpio swdio -chip 0 25
 
 # Direction pin for SWDIO level shifting buffer
 
 # Direction pin for SWDIO level shifting buffer
-bcm2835gpio_swdio_dir_num 6
+adapter gpio swdio_dir -chip 0 6
 
 # If you define trst or srst, use appropriate reset_config
 # Header pin numbers: TRST - 26, SRST - 18
 
 
 # If you define trst or srst, use appropriate reset_config
 # Header pin numbers: TRST - 26, SRST - 18
 
-bcm2835gpio_trst_num 7
+adapter gpio trst -chip 0 7
 #reset_config trst_only
 
 #reset_config trst_only
 
-bcm2835gpio_srst_num 24
+adapter gpio srst -chip 0 24
 #reset_config srst_only
 
 # or if you have both connected
 #reset_config srst_only
 
 # or if you have both connected
index 6d5c3bfd4936c9eeffb33d3f80a5a3d28cc007c7..02a35635006063561ead1f12dd9d944c07d530a3 100644 (file)
@@ -21,19 +21,23 @@ bcm2835gpio speed_coeffs 113714 28
 
 # Each of the JTAG lines need a gpio number set: tck tms tdi tdo
 # Header pin numbers: 23 22 19 21
 
 # Each of the JTAG lines need a gpio number set: tck tms tdi tdo
 # Header pin numbers: 23 22 19 21
-bcm2835gpio jtag_nums 11 25 10 9
+adapter gpio tck -chip 0 11
+adapter gpio tms -chip 0 25
+adapter gpio tdi -chip 0 10
+adapter gpio tdo -chip 0 9
 
 # Each of the SWD lines need a gpio number set: swclk swdio
 # Header pin numbers: 23 22
 
 # Each of the SWD lines need a gpio number set: swclk swdio
 # Header pin numbers: 23 22
-bcm2835gpio swd_nums 11 25
+adapter gpio swclk -chip 0 11
+adapter gpio swdio -chip 0 25
 
 # If you define trst or srst, use appropriate reset_config
 # Header pin numbers: TRST - 26, SRST - 18
 
 
 # If you define trst or srst, use appropriate reset_config
 # Header pin numbers: TRST - 26, SRST - 18
 
-# bcm2835gpio trst_num 7
+# adapter gpio trst -chip 0 7
 # reset_config trst_only
 
 # reset_config trst_only
 
-# bcm2835gpio srst_num 24
+# adapter gpio srst -chip 0 24
 # reset_config srst_only srst_push_pull
 
 # or if you have both connected,
 # reset_config srst_only srst_push_pull
 
 # or if you have both connected,
index 547df0872f311af6c5e0374702cdff88c0756b72..5faabed9decc6299785a8fce85516cf4f34dbb94 100644 (file)
@@ -21,19 +21,23 @@ bcm2835gpio speed_coeffs 146203 36
 
 # Each of the JTAG lines need a gpio number set: tck tms tdi tdo
 # Header pin numbers: 23 22 19 21
 
 # Each of the JTAG lines need a gpio number set: tck tms tdi tdo
 # Header pin numbers: 23 22 19 21
-bcm2835gpio jtag_nums 11 25 10 9
+adapter gpio tck -chip 0 11
+adapter gpio tms -chip 0 25
+adapter gpio tdi -chip 0 10
+adapter gpio tdo -chip 0 9
 
 # Each of the SWD lines need a gpio number set: swclk swdio
 # Header pin numbers: 23 22
 
 # Each of the SWD lines need a gpio number set: swclk swdio
 # Header pin numbers: 23 22
-bcm2835gpio swd_nums 11 25
+adapter gpio swclk -chip 0 11
+adapter gpio swdio -chip 0 25
 
 # If you define trst or srst, use appropriate reset_config
 # Header pin numbers: TRST - 26, SRST - 18
 
 
 # If you define trst or srst, use appropriate reset_config
 # Header pin numbers: TRST - 26, SRST - 18
 
-# bcm2835gpio trst_num 7
+# adapter gpio trst -chip 0 7
 # reset_config trst_only
 
 # reset_config trst_only
 
-# bcm2835gpio srst_num 24
+# adapter gpio srst -chip 0 24
 # reset_config srst_only srst_push_pull
 
 # or if you have both connected,
 # reset_config srst_only srst_push_pull
 
 # or if you have both connected,
diff --git a/testing/test-bcm2835gpio-deprecated-commands.cfg b/testing/test-bcm2835gpio-deprecated-commands.cfg
new file mode 100644 (file)
index 0000000..b34eb36
--- /dev/null
@@ -0,0 +1,105 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+# OpenOCD script to test that the deprecated "bcm2835gpio *" and "bcm2835gpio_*"
+# commands produce the expected results. Run this command as:
+# openocd -f <path>/test-bcm2835gpio-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}'"]
+       }
+}
+
+set supported_signals {tdo tdi tms tck trst swdio swdio_dir swclk srst}
+
+adapter speed 100
+adapter driver bcm2835gpio
+puts "Driver is '[adapter name]'"
+expected_value "bcm2835gpio" [adapter name]
+echo [adapter gpio]
+
+#####################################
+# Test the "bcm2835gpio *" commands
+
+# Change the GPIO chip for all signals. Don't check directly here, do so when
+# each signal command is tested.
+# bcm2835gpio gpiochip 0
+
+bcm2835gpio 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]
+
+bcm2835gpio 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]
+
+bcm2835gpio 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]
+
+bcm2835gpio 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]
+
+bcm2835gpio tdo_num 8
+expected_value "adapter gpio tdo (input): num 8, chip 0, active-high, pull-none, init-state input" [eval adapter gpio tdo]
+
+bcm2835gpio 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]
+
+bcm2835gpio 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]
+
+bcm2835gpio 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]
+
+bcm2835gpio 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]
+
+bcm2835gpio srst_num 14
+expected_value "adapter gpio srst (output): num 14, chip 0, active-low, pull-none, init-state inactive" [eval adapter gpio srst]
+
+bcm2835gpio trst_num 15
+expected_value "adapter gpio trst (output): num 15, chip 0, active-low, pull-none, init-state inactive" [eval adapter gpio trst]
+
+
+#####################################
+# Test the old bcm2835gpio_* commands
+
+# Reset the GPIO chip for all signals. Don't check directly here, do so when
+# each signal command is tested.
+foreach sig_name $supported_signals {
+       eval adapter gpio $sig_name -chip -1
+}
+
+bcm2835gpio_jtag_nums 17 18 19 20
+expected_value "adapter gpio tck (output): num 17, chip 0, active-high, push-pull, pull-none, init-state inactive" [eval adapter gpio tck]
+expected_value "adapter gpio tms (output): num 18, chip 0, active-high, push-pull, pull-none, init-state active" [eval adapter gpio tms]
+expected_value "adapter gpio tdi (output): num 19, chip 0, active-high, push-pull, pull-none, init-state inactive" [eval adapter gpio tdi]
+expected_value "adapter gpio tdo (input): num 20, chip 0, active-high, pull-none, init-state input" [eval adapter gpio tdo]
+
+bcm2835gpio_tck_num 21
+expected_value "adapter gpio tck (output): num 21, chip 0, active-high, push-pull, pull-none, init-state inactive" [eval adapter gpio tck]
+
+bcm2835gpio_tms_num 22
+expected_value "adapter gpio tms (output): num 22, chip 0, active-high, push-pull, pull-none, init-state active" [eval adapter gpio tms]
+
+bcm2835gpio_tdi_num 23
+expected_value "adapter gpio tdi (output): num 23, chip 0, active-high, push-pull, pull-none, init-state inactive" [eval adapter gpio tdi]
+
+bcm2835gpio_tdo_num 24
+expected_value "adapter gpio tdo (input): num 24, chip 0, active-high, pull-none, init-state input" [eval adapter gpio tdo]
+
+bcm2835gpio_swd_nums 25 26
+expected_value "adapter gpio swclk (output): num 25, chip 0, active-high, push-pull, pull-none, init-state inactive" [eval adapter gpio swclk]
+expected_value "adapter gpio swdio (bidirectional): num 26, chip 0, active-high, push-pull, pull-none, init-state inactive" [eval adapter gpio swdio]
+
+bcm2835gpio_swclk_num 27
+expected_value "adapter gpio swclk (output): num 27, chip 0, active-high, push-pull, pull-none, init-state inactive" [eval adapter gpio swclk]
+
+bcm2835gpio_swdio_num 28
+expected_value "adapter gpio swdio (bidirectional): num 28, chip 0, active-high, push-pull, pull-none, init-state inactive" [eval adapter gpio swdio]
+
+puts "SUCCESS"