linuxgpiod: add SWDIO buffer 36/6936/4
authorSteve Marple <stevemarple@googlemail.com>
Tue, 12 Apr 2022 17:25:40 +0000 (18:25 +0100)
committerAntonio Borneo <borneo.antonio@gmail.com>
Sat, 30 Apr 2022 17:47:38 +0000 (17:47 +0000)
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>
src/jtag/drivers/linuxgpiod.c

index 9f9f27a9f24102777d079c176f96c1ec4a9843f4..288035f2e077edb885b0bd1a4f075c730e3c010a 100644 (file)
@@ -27,6 +27,7 @@ static int trst_gpio = -1;
 static int srst_gpio = -1;
 static int swclk_gpio = -1;
 static int swdio_gpio = -1;
+static int swdio_dir_gpio = -1;
 static int led_gpio = -1;
 static int gpiochip = -1;
 static int tck_gpiochip = -1;
@@ -37,6 +38,7 @@ static int trst_gpiochip = -1;
 static int srst_gpiochip = -1;
 static int swclk_gpiochip = -1;
 static int swdio_gpiochip = -1;
+static int swdio_dir_gpiochip = -1;
 static int led_gpiochip = -1;
 
 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_swclk;
 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_line *gpiod_tck;
@@ -56,6 +59,7 @@ static struct gpiod_line *gpiod_tdo;
 static struct gpiod_line *gpiod_trst;
 static struct gpiod_line *gpiod_swclk;
 static struct gpiod_line *gpiod_swdio;
+static struct gpiod_line *gpiod_swdio_dir;
 static struct gpiod_line *gpiod_srst;
 static struct gpiod_line *gpiod_led;
 
@@ -63,6 +67,7 @@ static int last_swclk;
 static int last_swdio;
 static bool last_stored;
 static bool swdio_input;
+static bool swdio_dir_is_active_high = true;
 
 /* Bitbang interface read of TDO */
 static bb_value_t linuxgpiod_read(void)
@@ -152,6 +157,11 @@ static void linuxgpiod_swdio_drive(bool is_output)
        gpiod_line_release(gpiod_swdio);
 
        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);
                if (retval < 0)
                        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");
                if (retval < 0)
                        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;
@@ -297,6 +312,8 @@ static int linuxgpiod_quit(void)
                gpiod_chip_close(gpiod_chip_srst);
        if (gpiod_chip_swdio != NULL)
                gpiod_chip_close(gpiod_chip_swdio);
+       if (gpiod_chip_swdio_dir != NULL)
+               gpiod_chip_close(gpiod_chip_swdio_dir);
        if (gpiod_chip_swclk != NULL)
                gpiod_chip_close(gpiod_chip_swclk);
        if (gpiod_chip_trst != NULL)
@@ -451,10 +468,26 @@ static int linuxgpiod_init(void)
                        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);
                if (!gpiod_swclk)
                        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);
                if (!gpiod_swdio)
                        goto out_error;
@@ -593,6 +626,12 @@ COMMAND_HANDLER(linuxgpiod_handle_swd_gpionum_swdio)
                        &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)
 {
        return CALL_COMMAND_HANDLER(linuxgpiod_helper_gpionum, "led", &led_gpiochip,
@@ -611,6 +650,7 @@ COMMAND_HANDLER(linuxgpiod_handle_gpiochip)
                srst_gpiochip = gpiochip;
                swclk_gpiochip = gpiochip;
                swdio_gpiochip = gpiochip;
+               swdio_dir_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.",
                .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",
                .handler = linuxgpiod_handle_gpionum_led,

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)