drivers/bcm2835gpio: Migrate to adapter gpio commands

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>
This commit is contained in:
Steve Marple 2022-06-25 23:45:18 +01:00 committed by Antonio Borneo
parent e643a494d4
commit 0dd969d83b
7 changed files with 460 additions and 457 deletions

View File

@ -3292,66 +3292,12 @@ able to coexist nicely with both sysfs bitbanging and various
peripherals' kernel drivers. The driver restores the previous peripherals' kernel drivers. The driver restores the previous
configuration on exit. 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 See @file{interface/raspberrypi-native.cfg} for a sample config and
pinout. 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} @deffn {Config Command} {bcm2835gpio 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 113714, and speed_offset defaults to 28. speed_coeff defaults to 113714, and speed_offset defaults to 28.

View File

@ -12,6 +12,7 @@
#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"
@ -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 (bcm2835_peri_base + 0x100000)
#define BCM2835_PADS_GPIO_0_27_OFFSET (0x2c / 4) #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 */ /* GPIO setup macros */
#define MODE_GPIO(g) (*(pio_base+((g)/10))>>(((g)%10)*3) & 7) #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 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 */ \ #define SET_MODE_GPIO(g, m) do { /* clear the mode bits first, then set as necessary */ \
INP_GPIO(g); \ INP_GPIO(g); \
*(pio_base+((g)/10)) |= ((m)<<(((g)%10)*3)); } while (0) *(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_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_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 *pio_base = MAP_FAILED;
static volatile uint32_t *pads_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 */ /* Transition delay coefficients */
static int speed_coeff = 113714; static int speed_coeff = 113714;
static int speed_offset = 28; static int speed_offset = 28;
static unsigned int jtag_delay; 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 set = tck << adapter_gpio_config[ADAPTER_GPIO_IDX_TCK].gpio_num |
uint32_t clear = !tck<<tck_gpio | !tms<<tms_gpio | !tdi<<tdi_gpio; 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_SET = set;
GPIO_CLR = clear; 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; swclk = swclk ^ (adapter_gpio_config[ADAPTER_GPIO_IDX_SWCLK].active_low ? 1 : 0);
uint32_t clear = !swclk << swclk_gpio | !swdio << swdio_gpio; 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_SET = set;
GPIO_CLR = clear; GPIO_CLR = clear;
@ -122,55 +178,62 @@ static int bcm2835gpio_swd_write(int swclk, int swdio)
return ERROR_OK; return ERROR_OK;
} }
/* Generic mode that works for open-drain/open-source drive modes, but slower */
static int bcm2835gpio_swd_write_generic(int swclk, int swdio)
{
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 */
for (unsigned int i = 0; i < jtag_delay; ++i)
asm volatile ("");
return ERROR_OK;
}
/* (1) assert or (0) deassert reset lines */ /* (1) assert or (0) deassert reset lines */
static int bcm2835gpio_reset(int trst, int srst) static int bcm2835gpio_reset(int trst, int srst)
{ {
uint32_t set = 0; /* As the "adapter reset_config" command keeps the srst and trst gpio drive
uint32_t clear = 0; * 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_valid(trst_gpio)) { if (is_gpio_config_valid(ADAPTER_GPIO_IDX_TRST))
set |= !trst<<trst_gpio; set_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_TRST], trst);
clear |= trst<<trst_gpio;
}
if (is_gpio_valid(srst_gpio)) {
set |= !srst<<srst_gpio;
clear |= srst<<srst_gpio;
}
GPIO_SET = set;
GPIO_CLR = clear;
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; return ERROR_OK;
} }
static void bcm2835_swdio_drive(bool is_output) static void bcm2835_swdio_drive(bool is_output)
{ {
if (is_gpio_valid(swdio_dir_gpio)) { if (is_output) {
if (is_output) { if (is_gpio_config_valid(ADAPTER_GPIO_IDX_SWDIO_DIR))
GPIO_SET = 1 << swdio_dir_gpio; set_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO_DIR], 1);
OUT_GPIO(swdio_gpio); OUT_GPIO(adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO].gpio_num);
} else {
INP_GPIO(swdio_gpio);
GPIO_CLR = 1 << swdio_dir_gpio;
}
} else { } else {
if (is_output) INP_GPIO(adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO].gpio_num);
OUT_GPIO(swdio_gpio); if (is_gpio_config_valid(ADAPTER_GPIO_IDX_SWDIO_DIR))
else set_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO_DIR], 0);
INP_GPIO(swdio_gpio);
} }
} }
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) static int bcm2835gpio_khz(int khz, int *jtag_speed)
{ {
if (!khz) { if (!khz) {
LOG_DEBUG("RCLK not supported"); LOG_DEBUG("BCM2835 GPIO: RCLK not supported");
return ERROR_FAIL; return ERROR_FAIL;
} }
*jtag_speed = speed_coeff/khz - speed_offset; *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) COMMAND_HANDLER(bcm2835gpio_handle_speed_coeffs)
{ {
if (CMD_ARGC == 2) { 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", .name = "speed_coeffs",
.handler = &bcm2835gpio_handle_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)) if (!is_gpio_config_valid(ADAPTER_GPIO_IDX_TCK))
return 0; return false;
if (!is_gpio_valid(tms_gpio)) if (!is_gpio_config_valid(ADAPTER_GPIO_IDX_TMS))
return 0; return false;
if (!is_gpio_valid(tdi_gpio)) if (!is_gpio_config_valid(ADAPTER_GPIO_IDX_TDI))
return 0; return false;
if (!is_gpio_valid(tdo_gpio)) if (!is_gpio_config_valid(ADAPTER_GPIO_IDX_TDO))
return 0; return false;
return 1; return true;
} }
static bool bcm2835gpio_swd_mode_possible(void) static bool bcm2835gpio_swd_mode_possible(void)
{ {
if (!is_gpio_valid(swclk_gpio)) if (!is_gpio_config_valid(ADAPTER_GPIO_IDX_SWCLK))
return 0; return false;
if (!is_gpio_valid(swdio_gpio)) if (!is_gpio_config_valid(ADAPTER_GPIO_IDX_SWDIO))
return 0; return false;
return 1; 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()) { if (transport_is_jtag() && !bcm2835gpio_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;
@ -543,58 +401,45 @@ static int bcm2835gpio_init(void)
/* set 4mA drive strength, slew rate limited, hysteresis on */ /* set 4mA drive strength, slew rate limited, hysteresis on */
pads_base[BCM2835_PADS_GPIO_0_27_OFFSET] = 0x5a000008 + 1; pads_base[BCM2835_PADS_GPIO_0_27_OFFSET] = 0x5a000008 + 1;
/* /* Configure JTAG/SWD signals. Default directions and initial states are handled
* Configure TDO as an input, and TDI, TCK, TMS, TRST, SRST * by adapter.c and "adapter gpio" command.
* as outputs. Drive TDI and TCK low, and TMS/TRST/SRST high.
*/ */
if (transport_is_jtag()) { if (transport_is_jtag()) {
tdo_gpio_mode = MODE_GPIO(tdo_gpio); initialize_gpio(ADAPTER_GPIO_IDX_TDO);
tdi_gpio_mode = MODE_GPIO(tdi_gpio); initialize_gpio(ADAPTER_GPIO_IDX_TDI);
tck_gpio_mode = MODE_GPIO(tck_gpio); initialize_gpio(ADAPTER_GPIO_IDX_TMS);
tms_gpio_mode = MODE_GPIO(tms_gpio); initialize_gpio(ADAPTER_GPIO_IDX_TCK);
initialize_gpio(ADAPTER_GPIO_IDX_TRST);
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);
}
} }
if (transport_is_swd()) { if (transport_is_swd()) {
/* Make buffer an output before the GPIO connected to it */ /* swdio and its buffer should be initialized in the order that prevents
if (is_gpio_valid(swdio_dir_gpio)) { * two outputs from being connected together. This will occur if the
swdio_dir_gpio_mode = MODE_GPIO(swdio_dir_gpio); * swdio GPIO of the AM335x is configured as an output while its
GPIO_SET = 1 << swdio_dir_gpio; * external buffer is configured to send the swdio signal from the
OUT_GPIO(swdio_dir_gpio); * 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); initialize_gpio(ADAPTER_GPIO_IDX_SWCLK);
swdio_gpio_mode = MODE_GPIO(swdio_gpio);
GPIO_CLR = 1<<swdio_gpio | 1<<swclk_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) {
OUT_GPIO(swclk_gpio); LOG_DEBUG("BCM2835 GPIO using fast mode for SWD write");
OUT_GPIO(swdio_gpio); 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;
}
} }
if (is_gpio_valid(srst_gpio)) { initialize_gpio(ADAPTER_GPIO_IDX_SRST);
srst_gpio_mode = MODE_GPIO(srst_gpio);
GPIO_SET = 1 << srst_gpio;
OUT_GPIO(srst_gpio);
}
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);
return ERROR_OK; return ERROR_OK;
} }
@ -602,26 +447,51 @@ static int bcm2835gpio_init(void)
static int bcm2835gpio_quit(void) static int bcm2835gpio_quit(void)
{ {
if (transport_is_jtag()) { if (transport_is_jtag()) {
SET_MODE_GPIO(tdo_gpio, tdo_gpio_mode); restore_gpio(ADAPTER_GPIO_IDX_TDO);
SET_MODE_GPIO(tdi_gpio, tdi_gpio_mode); restore_gpio(ADAPTER_GPIO_IDX_TDI);
SET_MODE_GPIO(tck_gpio, tck_gpio_mode); restore_gpio(ADAPTER_GPIO_IDX_TCK);
SET_MODE_GPIO(tms_gpio, tms_gpio_mode); restore_gpio(ADAPTER_GPIO_IDX_TMS);
if (is_gpio_valid(trst_gpio)) restore_gpio(ADAPTER_GPIO_IDX_TRST);
SET_MODE_GPIO(trst_gpio, trst_gpio_mode);
} }
if (transport_is_swd()) { if (transport_is_swd()) {
SET_MODE_GPIO(swclk_gpio, swclk_gpio_mode); /* Restore swdio/swdio_dir to their initial modes, even if that means
SET_MODE_GPIO(swdio_gpio, swdio_gpio_mode); * 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)) restore_gpio(ADAPTER_GPIO_IDX_SRST);
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);
bcm2835gpio_munmap(); bcm2835gpio_munmap();
return ERROR_OK; 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,
};

View 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 { proc bcm2835gpio_jtag_nums {tck_num tms_num tdi_num tdo_num} {
echo "DEPRECATED! use 'bcm2835gpio jtag_nums' not 'bcm2835gpio_jtag_nums'" echo "DEPRECATED! use 'adapter gpio tck; adapter gpio tms; adapter gpio tdi; adapter gpio tdo' not 'bcm2835gpio_jtag_nums'"
eval bcm2835gpio jtag_nums $args 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 lappend _telnet_autocomplete_skip bcm2835gpio_tck_num
proc bcm2835gpio_tck_num args { proc bcm2835gpio_tck_num args {
echo "DEPRECATED! use 'bcm2835gpio tck_num' not 'bcm2835gpio_tck_num'" eval bcm2835_gpio_helper tck $args
eval bcm2835gpio tck_num $args
} }
lappend _telnet_autocomplete_skip bcm2835gpio_tms_num lappend _telnet_autocomplete_skip bcm2835gpio_tms_num
proc bcm2835gpio_tms_num args { proc bcm2835gpio_tms_num args {
echo "DEPRECATED! use 'bcm2835gpio tms_num' not 'bcm2835gpio_tms_num'" eval bcm2835_gpio_helper tms $args
eval bcm2835gpio tms_num $args
} }
lappend _telnet_autocomplete_skip bcm2835gpio_tdo_num lappend _telnet_autocomplete_skip bcm2835gpio_tdo_num
proc bcm2835gpio_tdo_num args { proc bcm2835gpio_tdo_num args {
echo "DEPRECATED! use 'bcm2835gpio tdo_num' not 'bcm2835gpio_tdo_num'" eval bcm2835_gpio_helper tdo $args
eval bcm2835gpio tdo_num $args
} }
lappend _telnet_autocomplete_skip bcm2835gpio_tdi_num lappend _telnet_autocomplete_skip bcm2835gpio_tdi_num
proc bcm2835gpio_tdi_num args { proc bcm2835gpio_tdi_num args {
echo "DEPRECATED! use 'bcm2835gpio tdi_num' not 'bcm2835gpio_tdi_num'" eval bcm2835_gpio_helper tdi $args
eval bcm2835gpio tdi_num $args
} }
lappend _telnet_autocomplete_skip bcm2835gpio_swd_nums lappend _telnet_autocomplete_skip bcm2835gpio_swd_nums
proc bcm2835gpio_swd_nums args { proc bcm2835gpio_swd_nums {swclk_num swdio_num} {
echo "DEPRECATED! use 'bcm2835gpio swd_nums' not 'bcm2835gpio_swd_nums'" echo "DEPRECATED! use 'adapter gpio swclk; adapter gpio swdio' not 'bcm2835gpio_swd_nums'"
eval bcm2835gpio swd_nums $args eval adapter gpio swclk $swclk_num -chip 0
eval adapter gpio swdio $swdio_num -chip 0
} }
lappend _telnet_autocomplete_skip bcm2835gpio_swclk_num lappend _telnet_autocomplete_skip bcm2835gpio_swclk_num
proc bcm2835gpio_swclk_num args { proc bcm2835gpio_swclk_num args {
echo "DEPRECATED! use 'bcm2835gpio swclk_num' not 'bcm2835gpio_swclk_num'" eval bcm2835_gpio_helper swclk $args
eval bcm2835gpio swclk_num $args
} }
lappend _telnet_autocomplete_skip bcm2835gpio_swdio_num lappend _telnet_autocomplete_skip bcm2835gpio_swdio_num
proc bcm2835gpio_swdio_num args { proc bcm2835gpio_swdio_num args {
echo "DEPRECATED! use 'bcm2835gpio swdio_num' not 'bcm2835gpio_swdio_num'" eval bcm2835_gpio_helper swdio $args
eval bcm2835gpio swdio_num $args
} }
lappend _telnet_autocomplete_skip bcm2835gpio_swdio_dir_num lappend _telnet_autocomplete_skip bcm2835gpio_swdio_dir_num
proc bcm2835gpio_swdio_dir_num args { proc bcm2835gpio_swdio_dir_num args {
echo "DEPRECATED! use 'bcm2835gpio swdio_dir_num' not 'bcm2835gpio_swdio_dir_num'" eval bcm2835_gpio_helper swdio_dir $args
eval bcm2835gpio swdio_dir_num $args
} }
lappend _telnet_autocomplete_skip bcm2835gpio_srst_num lappend _telnet_autocomplete_skip bcm2835gpio_srst_num
proc bcm2835gpio_srst_num args { proc bcm2835gpio_srst_num args {
echo "DEPRECATED! use 'bcm2835gpio srst_num' not 'bcm2835gpio_srst_num'" eval bcm2835_gpio_helper srst $args
eval bcm2835gpio srst_num $args
} }
lappend _telnet_autocomplete_skip bcm2835gpio_trst_num lappend _telnet_autocomplete_skip bcm2835gpio_trst_num
proc bcm2835gpio_trst_num args { proc bcm2835gpio_trst_num args {
echo "DEPRECATED! use 'bcm2835gpio trst_num' not 'bcm2835gpio_trst_num'" eval bcm2835_gpio_helper trst $args
eval bcm2835gpio trst_num $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

View 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 # Transition delay calculation: SPEED_COEFF/khz - SPEED_OFFSET
# These depend on system clock, calibrated for stock 700MHz # These depend on system clock, calibrated for stock 700MHz
# bcm2835gpio_speed SPEED_COEFF SPEED_OFFSET # 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 # Each of the JTAG lines need a gpio number set: tck tms tdi tdo
# Header pin numbers: 23 22 19 21 # 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 # Each of the SWD lines need a gpio number set: swclk swdio
# Header pin numbers: 23 22 # 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 # If you define trst or srst, use appropriate reset_config
# Header pin numbers: TRST - 26, SRST - 18 # 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 #reset_config srst_only
# or if you have both connected # or if you have both connected

View File

@ -21,19 +21,23 @@ bcm2835gpio speed_coeffs 113714 28
# Each of the JTAG lines need a gpio number set: tck tms tdi tdo # Each of the JTAG lines need a gpio number set: tck tms tdi tdo
# Header pin numbers: 23 22 19 21 # 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 # Each of the SWD lines need a gpio number set: swclk swdio
# Header pin numbers: 23 22 # 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 # If you define trst or srst, use appropriate reset_config
# Header pin numbers: TRST - 26, SRST - 18 # 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 # reset_config srst_only srst_push_pull
# or if you have both connected, # or if you have both connected,

View File

@ -21,19 +21,23 @@ bcm2835gpio speed_coeffs 146203 36
# Each of the JTAG lines need a gpio number set: tck tms tdi tdo # Each of the JTAG lines need a gpio number set: tck tms tdi tdo
# Header pin numbers: 23 22 19 21 # 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 # Each of the SWD lines need a gpio number set: swclk swdio
# Header pin numbers: 23 22 # 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 # If you define trst or srst, use appropriate reset_config
# Header pin numbers: TRST - 26, SRST - 18 # 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 # reset_config srst_only srst_push_pull
# or if you have both connected, # or if you have both connected,

View File

@ -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"