linuxgpiod: add SWDIO buffer
The SWDIO buffer requires a direction pin to select input or output direction. Output is selected by a high logic level (matches bcm2835gpio driver). Change-Id: I240cb99a5dfea08121bb33d4b5e2108ce7597468 Signed-off-by: Steve Marple <stevemarple@googlemail.com> Reviewed-on: https://review.openocd.org/c/openocd/+/6936 Tested-by: jenkins Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com>
This commit is contained in:
parent
9de084e006
commit
20adf85f34
|
@ -27,6 +27,7 @@ static int trst_gpio = -1;
|
||||||
static int srst_gpio = -1;
|
static int srst_gpio = -1;
|
||||||
static int swclk_gpio = -1;
|
static int swclk_gpio = -1;
|
||||||
static int swdio_gpio = -1;
|
static int swdio_gpio = -1;
|
||||||
|
static int swdio_dir_gpio = -1;
|
||||||
static int led_gpio = -1;
|
static int led_gpio = -1;
|
||||||
static int gpiochip = -1;
|
static int gpiochip = -1;
|
||||||
static int tck_gpiochip = -1;
|
static int tck_gpiochip = -1;
|
||||||
|
@ -37,6 +38,7 @@ static int trst_gpiochip = -1;
|
||||||
static int srst_gpiochip = -1;
|
static int srst_gpiochip = -1;
|
||||||
static int swclk_gpiochip = -1;
|
static int swclk_gpiochip = -1;
|
||||||
static int swdio_gpiochip = -1;
|
static int swdio_gpiochip = -1;
|
||||||
|
static int swdio_dir_gpiochip = -1;
|
||||||
static int led_gpiochip = -1;
|
static int led_gpiochip = -1;
|
||||||
|
|
||||||
static struct gpiod_chip *gpiod_chip_tck;
|
static struct gpiod_chip *gpiod_chip_tck;
|
||||||
|
@ -47,6 +49,7 @@ static struct gpiod_chip *gpiod_chip_trst;
|
||||||
static struct gpiod_chip *gpiod_chip_srst;
|
static struct gpiod_chip *gpiod_chip_srst;
|
||||||
static struct gpiod_chip *gpiod_chip_swclk;
|
static struct gpiod_chip *gpiod_chip_swclk;
|
||||||
static struct gpiod_chip *gpiod_chip_swdio;
|
static struct gpiod_chip *gpiod_chip_swdio;
|
||||||
|
static struct gpiod_chip *gpiod_chip_swdio_dir;
|
||||||
static struct gpiod_chip *gpiod_chip_led;
|
static struct gpiod_chip *gpiod_chip_led;
|
||||||
|
|
||||||
static struct gpiod_line *gpiod_tck;
|
static struct gpiod_line *gpiod_tck;
|
||||||
|
@ -56,6 +59,7 @@ static struct gpiod_line *gpiod_tdo;
|
||||||
static struct gpiod_line *gpiod_trst;
|
static struct gpiod_line *gpiod_trst;
|
||||||
static struct gpiod_line *gpiod_swclk;
|
static struct gpiod_line *gpiod_swclk;
|
||||||
static struct gpiod_line *gpiod_swdio;
|
static struct gpiod_line *gpiod_swdio;
|
||||||
|
static struct gpiod_line *gpiod_swdio_dir;
|
||||||
static struct gpiod_line *gpiod_srst;
|
static struct gpiod_line *gpiod_srst;
|
||||||
static struct gpiod_line *gpiod_led;
|
static struct gpiod_line *gpiod_led;
|
||||||
|
|
||||||
|
@ -63,6 +67,7 @@ static int last_swclk;
|
||||||
static int last_swdio;
|
static int last_swdio;
|
||||||
static bool last_stored;
|
static bool last_stored;
|
||||||
static bool swdio_input;
|
static bool swdio_input;
|
||||||
|
static bool swdio_dir_is_active_high = true;
|
||||||
|
|
||||||
/* Bitbang interface read of TDO */
|
/* Bitbang interface read of TDO */
|
||||||
static bb_value_t linuxgpiod_read(void)
|
static bb_value_t linuxgpiod_read(void)
|
||||||
|
@ -152,6 +157,11 @@ static void linuxgpiod_swdio_drive(bool is_output)
|
||||||
gpiod_line_release(gpiod_swdio);
|
gpiod_line_release(gpiod_swdio);
|
||||||
|
|
||||||
if (is_output) {
|
if (is_output) {
|
||||||
|
if (gpiod_swdio_dir) {
|
||||||
|
retval = gpiod_line_set_value(gpiod_swdio_dir, swdio_dir_is_active_high ? 1 : 0);
|
||||||
|
if (retval < 0)
|
||||||
|
LOG_WARNING("Fail set swdio_dir");
|
||||||
|
}
|
||||||
retval = gpiod_line_request_output(gpiod_swdio, "OpenOCD", 1);
|
retval = gpiod_line_request_output(gpiod_swdio, "OpenOCD", 1);
|
||||||
if (retval < 0)
|
if (retval < 0)
|
||||||
LOG_WARNING("Fail request_output line swdio");
|
LOG_WARNING("Fail request_output line swdio");
|
||||||
|
@ -159,6 +169,11 @@ static void linuxgpiod_swdio_drive(bool is_output)
|
||||||
retval = gpiod_line_request_input(gpiod_swdio, "OpenOCD");
|
retval = gpiod_line_request_input(gpiod_swdio, "OpenOCD");
|
||||||
if (retval < 0)
|
if (retval < 0)
|
||||||
LOG_WARNING("Fail request_input line swdio");
|
LOG_WARNING("Fail request_input line swdio");
|
||||||
|
if (gpiod_swdio_dir) {
|
||||||
|
retval = gpiod_line_set_value(gpiod_swdio_dir, swdio_dir_is_active_high ? 0 : 1);
|
||||||
|
if (retval < 0)
|
||||||
|
LOG_WARNING("Fail set swdio_dir");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
last_stored = false;
|
last_stored = false;
|
||||||
|
@ -297,6 +312,8 @@ static int linuxgpiod_quit(void)
|
||||||
gpiod_chip_close(gpiod_chip_srst);
|
gpiod_chip_close(gpiod_chip_srst);
|
||||||
if (gpiod_chip_swdio != NULL)
|
if (gpiod_chip_swdio != NULL)
|
||||||
gpiod_chip_close(gpiod_chip_swdio);
|
gpiod_chip_close(gpiod_chip_swdio);
|
||||||
|
if (gpiod_chip_swdio_dir != NULL)
|
||||||
|
gpiod_chip_close(gpiod_chip_swdio_dir);
|
||||||
if (gpiod_chip_swclk != NULL)
|
if (gpiod_chip_swclk != NULL)
|
||||||
gpiod_chip_close(gpiod_chip_swclk);
|
gpiod_chip_close(gpiod_chip_swclk);
|
||||||
if (gpiod_chip_trst != NULL)
|
if (gpiod_chip_trst != NULL)
|
||||||
|
@ -451,10 +468,26 @@ static int linuxgpiod_init(void)
|
||||||
goto out_error;
|
goto out_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_gpio_valid(swdio_dir_gpio)) {
|
||||||
|
gpiod_chip_swdio_dir = gpiod_chip_open_by_number(swdio_dir_gpiochip);
|
||||||
|
if (!gpiod_chip_swdio_dir) {
|
||||||
|
LOG_ERROR("Cannot open LinuxGPIOD swdio_dir_gpiochip %d", swdio_dir_gpiochip);
|
||||||
|
goto out_error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
gpiod_swclk = helper_get_output_line("swclk", gpiod_chip_swclk, swclk_gpio, 1);
|
gpiod_swclk = helper_get_output_line("swclk", gpiod_chip_swclk, swclk_gpio, 1);
|
||||||
if (!gpiod_swclk)
|
if (!gpiod_swclk)
|
||||||
goto out_error;
|
goto out_error;
|
||||||
|
|
||||||
|
/* Set buffer direction before making SWDIO an output */
|
||||||
|
if (is_gpio_valid(swdio_dir_gpio)) {
|
||||||
|
gpiod_swdio_dir = helper_get_output_line("swdio_dir", gpiod_chip_swdio_dir, swdio_dir_gpio,
|
||||||
|
swdio_dir_is_active_high ? 1 : 0);
|
||||||
|
if (!gpiod_swdio_dir)
|
||||||
|
goto out_error;
|
||||||
|
}
|
||||||
|
|
||||||
gpiod_swdio = helper_get_output_line("swdio", gpiod_chip_swdio, swdio_gpio, 1);
|
gpiod_swdio = helper_get_output_line("swdio", gpiod_chip_swdio, swdio_gpio, 1);
|
||||||
if (!gpiod_swdio)
|
if (!gpiod_swdio)
|
||||||
goto out_error;
|
goto out_error;
|
||||||
|
@ -593,6 +626,12 @@ COMMAND_HANDLER(linuxgpiod_handle_swd_gpionum_swdio)
|
||||||
&swdio_gpio);
|
&swdio_gpio);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
COMMAND_HANDLER(linuxgpiod_handle_swd_gpionum_swdio_dir)
|
||||||
|
{
|
||||||
|
return CALL_COMMAND_HANDLER(linuxgpiod_helper_gpionum, "swdio_dir", &swdio_dir_gpiochip,
|
||||||
|
&swdio_dir_gpio);
|
||||||
|
}
|
||||||
|
|
||||||
COMMAND_HANDLER(linuxgpiod_handle_gpionum_led)
|
COMMAND_HANDLER(linuxgpiod_handle_gpionum_led)
|
||||||
{
|
{
|
||||||
return CALL_COMMAND_HANDLER(linuxgpiod_helper_gpionum, "led", &led_gpiochip,
|
return CALL_COMMAND_HANDLER(linuxgpiod_helper_gpionum, "led", &led_gpiochip,
|
||||||
|
@ -611,6 +650,7 @@ COMMAND_HANDLER(linuxgpiod_handle_gpiochip)
|
||||||
srst_gpiochip = gpiochip;
|
srst_gpiochip = gpiochip;
|
||||||
swclk_gpiochip = gpiochip;
|
swclk_gpiochip = gpiochip;
|
||||||
swdio_gpiochip = gpiochip;
|
swdio_gpiochip = gpiochip;
|
||||||
|
swdio_dir_gpiochip = gpiochip;
|
||||||
led_gpiochip = gpiochip;
|
led_gpiochip = gpiochip;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -689,6 +729,13 @@ static const struct command_registration linuxgpiod_subcommand_handlers[] = {
|
||||||
.help = "gpio chip number (optional) and gpio number for swdio.",
|
.help = "gpio chip number (optional) and gpio number for swdio.",
|
||||||
.usage = "[chip] swdio",
|
.usage = "[chip] swdio",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.name = "swdio_dir_num",
|
||||||
|
.handler = linuxgpiod_handle_swd_gpionum_swdio_dir,
|
||||||
|
.mode = COMMAND_CONFIG,
|
||||||
|
.help = "gpio chip number (optional) and gpio number for swdio_dir.",
|
||||||
|
.usage = "[chip] swdio_dir",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
.name = "led_num",
|
.name = "led_num",
|
||||||
.handler = linuxgpiod_handle_gpionum_led,
|
.handler = linuxgpiod_handle_gpionum_led,
|
||||||
|
|
Loading…
Reference in New Issue