summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
5765a0c)
Some MCUs (e.g. the STM32F3) directly expose the internal reset line to
an external pin. When this signal is driven by a push/pull line, it can
actually be inhibited by the external driver. This results in a setup
where the MCU cannot reset itself, for example, by a watchdog timeout or
a sysreset request. To fix this condition, support for open drain output
on the SRST line is required.
Note that because `reset_config srst_open_drain` is the default, all
users of this adapter will switch over to an open drain output unless
explicitly configured otherwise.
Signed-off-by: Alex Crawford <openocd@code.acrawford.com>
Change-Id: I89b39b03aa03f826ed3c45793412780448940bcc
Reviewed-on: https://review.openocd.org/c/openocd/+/6559
Tested-by: jenkins
Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com>
-static struct gpiod_line *helper_get_input_line(const char *label, unsigned int offset)
+static struct gpiod_line *helper_get_line(const char *label, unsigned int offset, int val, int dir, int flags)
{
struct gpiod_line *line;
int retval;
{
struct gpiod_line *line;
int retval;
- retval = gpiod_line_request_input(line, "OpenOCD");
+ struct gpiod_line_request_config config = {
+ .consumer = "OpenOCD",
+ .request_type = dir,
+ .flags = flags,
+ };
+
+ retval = gpiod_line_request(line, &config, val);
- LOG_ERROR("Error request_input line %s", label);
+ LOG_ERROR("Error requesting gpio line %s", label);
return NULL;
}
return line;
}
return NULL;
}
return line;
}
-static struct gpiod_line *helper_get_output_line(const char *label, unsigned int offset, int val)
+static struct gpiod_line *helper_get_input_line(const char *label, unsigned int offset)
- struct gpiod_line *line;
- int retval;
-
- line = gpiod_chip_get_line(gpiod_chip, offset);
- if (!line) {
- LOG_ERROR("Error get line %s", label);
- return NULL;
- }
+ return helper_get_line(label, offset, 0, GPIOD_LINE_REQUEST_DIRECTION_INPUT, 0);
+}
- retval = gpiod_line_request_output(line, "OpenOCD", val);
- if (retval < 0) {
- LOG_ERROR("Error request_output line %s", label);
- return NULL;
- }
+static struct gpiod_line *helper_get_output_line(const char *label, unsigned int offset, int val)
+{
+ return helper_get_line(label, offset, val, GPIOD_LINE_REQUEST_DIRECTION_OUTPUT, 0);
+}
+static struct gpiod_line *helper_get_open_drain_output_line(const char *label, unsigned int offset, int val)
+{
+ return helper_get_line(label, offset, val, GPIOD_LINE_REQUEST_DIRECTION_OUTPUT, GPIOD_LINE_REQUEST_FLAG_OPEN_DRAIN);
}
static int linuxgpiod_init(void)
}
static int linuxgpiod_init(void)
}
if (is_gpio_valid(srst_gpio)) {
}
if (is_gpio_valid(srst_gpio)) {
- gpiod_srst = helper_get_output_line("srst", srst_gpio, 1);
+ if (jtag_get_reset_config() & RESET_SRST_PUSH_PULL)
+ gpiod_srst = helper_get_output_line("srst", srst_gpio, 1);
+ else
+ gpiod_srst = helper_get_open_drain_output_line("srst", srst_gpio, 1);
+
if (!gpiod_srst)
goto out_error;
}
if (!gpiod_srst)
goto out_error;
}