Browse Source

driver: swdp_bitbang: rework pin configurations

Move low-level GPIO functions to a separate file and use GPIO driver
API if low-level GPIO support is not available for the platform.
Allows alternative pin configuration using only two pins, clk and dio.
Improve binding description.

Signed-off-by: Maximilian Deubel <maximilian.deubel@nordicsemi.no>
Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
pull/74303/head
Maximilian Deubel 2 years ago committed by Alberto Escolar
parent
commit
3ef2c66a8a
  1. 1
      drivers/dp/Kconfig
  2. 340
      drivers/dp/swdp_bitbang.c
  3. 84
      drivers/dp/swdp_ll_pin.h
  4. 84
      dts/bindings/misc/zephyr,swdp-gpio.yaml

1
drivers/dp/Kconfig

@ -24,6 +24,7 @@ config SWDP_BITBANG_DRIVER @@ -24,6 +24,7 @@ config SWDP_BITBANG_DRIVER
bool "Serial Wire Debug Port bit-bang driver"
default y
depends on DT_HAS_ZEPHYR_SWDP_GPIO_ENABLED
depends on GPIO
help
Serial Wire Debug Port bit-bang driver.

340
drivers/dp/swdp_bitbang.c

@ -21,15 +21,11 @@ @@ -21,15 +21,11 @@
#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/swdp.h>
#include "swdp_ll_pin.h"
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(swdp, CONFIG_DP_DRIVER_LOG_LEVEL);
#if defined(CONFIG_SOC_SERIES_NRF52X)
#define CPU_CLOCK 64000000U
#else
#define CPU_CLOCK CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC
#endif
#define CLOCK_DELAY(swclk_freq, port_write_cycles) \
((CPU_CLOCK / 2 / swclk_freq) - port_write_cycles)
@ -44,15 +40,15 @@ LOG_MODULE_REGISTER(swdp, CONFIG_DP_DRIVER_LOG_LEVEL); @@ -44,15 +40,15 @@ LOG_MODULE_REGISTER(swdp, CONFIG_DP_DRIVER_LOG_LEVEL);
struct sw_config {
struct gpio_dt_spec clk;
struct gpio_dt_spec dout;
struct gpio_dt_spec din;
struct gpio_dt_spec dio;
struct gpio_dt_spec dnoe;
void *dout_reg;
void *dio_reg;
void *dnoe_reg;
struct gpio_dt_spec noe;
struct gpio_dt_spec reset;
uint32_t port_write_cycles;
void *clk_reg;
void *dout_reg;
void *din_reg;
void *dnoe_reg;
};
struct sw_cfg_data {
@ -98,102 +94,78 @@ static ALWAYS_INLINE uint32_t sw_get32bit_parity(uint32_t data) @@ -98,102 +94,78 @@ static ALWAYS_INLINE uint32_t sw_get32bit_parity(uint32_t data)
return data & 1U;
}
static ALWAYS_INLINE void pin_delay_asm(uint32_t delay)
{
#if defined(CONFIG_SOC_SERIES_NRF52X)
__asm volatile ("movs r3, %[p]\n"
".start_%=:\n"
"subs r3, #1\n"
"bne .start_%=\n"
:
: [p] "r" (delay)
: "r3", "cc"
);
#else
#error "Not defined for this SoC family"
#endif
}
static ALWAYS_INLINE void pin_platform_set(void *base, uint8_t pin)
{
#if defined(CONFIG_SOC_SERIES_NRF52X)
NRF_GPIO_Type * reg = base;
reg->OUTSET = BIT(pin);
#else
#error "Not defined for this SoC family"
#endif
}
static ALWAYS_INLINE void pin_platform_clr(void *base, uint8_t pin)
{
#if defined(CONFIG_SOC_SERIES_NRF52X)
NRF_GPIO_Type * reg = base;
reg->OUTCLR = BIT(pin);
#else
#error "Not defined for this SoC family"
#endif
}
static ALWAYS_INLINE uint32_t pin_platform_get(void *base, uint8_t pin)
{
#if defined(CONFIG_SOC_SERIES_NRF52X)
NRF_GPIO_Type * reg = base;
return ((reg->IN >> pin) & 1);
#else
#error "Not defined for this SoC family"
#endif
}
/* Set SWCLK DAP hardware output pin to high level */
static ALWAYS_INLINE void pin_swclk_set(const struct device *dev)
{
const struct sw_config *config = dev->config;
const struct gpio_dt_spec *dt_spec = &config->clk;
pin_platform_set(config->clk_reg, dt_spec->pin);
if (FAST_BITBANG_HW_SUPPORT) {
swdp_ll_pin_set(config->clk_reg, config->clk.pin);
} else {
gpio_pin_set_dt(&config->clk, 1);
}
}
/* Set SWCLK DAP hardware output pin to low level */
static ALWAYS_INLINE void pin_swclk_clr(const struct device *dev)
{
const struct sw_config *config = dev->config;
const struct gpio_dt_spec *dt_spec = &config->clk;
pin_platform_clr(config->clk_reg, dt_spec->pin);
if (FAST_BITBANG_HW_SUPPORT) {
swdp_ll_pin_clr(config->clk_reg, config->clk.pin);
} else {
gpio_pin_set_dt(&config->clk, 0);
}
}
/* Set the SWDIO DAP hardware output pin to high level */
static ALWAYS_INLINE void pin_swdio_set(const struct device *dev)
{
const struct sw_config *config = dev->config;
const struct gpio_dt_spec *dt_spec = &config->dout;
pin_platform_set(config->dout_reg, dt_spec->pin);
if (config->dout.port) {
if (FAST_BITBANG_HW_SUPPORT) {
swdp_ll_pin_set(config->dout_reg, config->dout.pin);
} else {
gpio_pin_set_dt(&config->dout, 1);
}
} else {
if (FAST_BITBANG_HW_SUPPORT) {
swdp_ll_pin_set(config->dio_reg, config->dio.pin);
} else {
gpio_pin_set_dt(&config->dio, 1);
}
}
}
/* Set the SWDIO DAP hardware output pin to low level */
static ALWAYS_INLINE void pin_swdio_clr(const struct device *dev)
{
const struct sw_config *config = dev->config;
const struct gpio_dt_spec *dt_spec = &config->dout;
pin_platform_clr(config->dout_reg, dt_spec->pin);
if (config->dout.port) {
if (FAST_BITBANG_HW_SUPPORT) {
swdp_ll_pin_clr(config->dout_reg, config->dout.pin);
} else {
gpio_pin_set_dt(&config->dout, 0);
}
} else {
if (FAST_BITBANG_HW_SUPPORT) {
swdp_ll_pin_clr(config->dio_reg, config->dio.pin);
} else {
gpio_pin_set_dt(&config->dio, 0);
}
}
}
/* Set the SWDIO DAP hardware output pin to bit level */
static ALWAYS_INLINE void pin_swdio_out(const struct device *dev,
const uint32_t bit)
{
const struct sw_config *config = dev->config;
const struct gpio_dt_spec *dt_spec = &config->dout;
if (bit & 1U) {
pin_platform_set(config->dout_reg, dt_spec->pin);
pin_swdio_set(dev);
} else {
pin_platform_clr(config->dout_reg, dt_spec->pin);
pin_swdio_clr(dev);
}
}
@ -201,9 +173,12 @@ static ALWAYS_INLINE void pin_swdio_out(const struct device *dev, @@ -201,9 +173,12 @@ static ALWAYS_INLINE void pin_swdio_out(const struct device *dev,
static ALWAYS_INLINE uint32_t pin_swdio_in(const struct device *dev)
{
const struct sw_config *config = dev->config;
const struct gpio_dt_spec *dt_spec = &config->din;
return pin_platform_get(config->din_reg, dt_spec->pin);
if (FAST_BITBANG_HW_SUPPORT) {
return swdp_ll_pin_get(config->dio_reg, config->dio.pin);
} else {
return gpio_pin_get_dt(&config->dio);
}
}
/*
@ -213,9 +188,20 @@ static ALWAYS_INLINE uint32_t pin_swdio_in(const struct device *dev) @@ -213,9 +188,20 @@ static ALWAYS_INLINE uint32_t pin_swdio_in(const struct device *dev)
static ALWAYS_INLINE void pin_swdio_out_enable(const struct device *dev)
{
const struct sw_config *config = dev->config;
const struct gpio_dt_spec *dt_spec = &config->dnoe;
pin_platform_set(config->dnoe_reg, dt_spec->pin);
if (config->dnoe.port) {
if (FAST_BITBANG_HW_SUPPORT) {
swdp_ll_pin_set(config->dnoe_reg, config->dnoe.pin);
} else {
gpio_pin_set_dt(&config->dnoe, 1);
}
} else {
if (FAST_BITBANG_HW_SUPPORT) {
swdp_ll_pin_output(config->dio_reg, config->dio.pin);
} else {
gpio_pin_configure_dt(&config->dio, GPIO_OUTPUT_ACTIVE);
}
}
}
/*
@ -224,9 +210,20 @@ static ALWAYS_INLINE void pin_swdio_out_enable(const struct device *dev) @@ -224,9 +210,20 @@ static ALWAYS_INLINE void pin_swdio_out_enable(const struct device *dev)
static ALWAYS_INLINE void pin_swdio_out_disable(const struct device *dev)
{
const struct sw_config *config = dev->config;
const struct gpio_dt_spec *dt_spec = &config->dnoe;
pin_platform_clr(config->dnoe_reg, dt_spec->pin);
if (config->dnoe.port) {
if (FAST_BITBANG_HW_SUPPORT) {
swdp_ll_pin_clr(config->dnoe_reg, config->dnoe.pin);
} else {
gpio_pin_set_dt(&config->dnoe, 0);
}
} else {
if (FAST_BITBANG_HW_SUPPORT) {
swdp_ll_pin_input(config->dio_reg, config->dio.pin);
} else {
gpio_pin_configure_dt(&config->dio, GPIO_INPUT);
}
}
}
#define SW_CLOCK_CYCLE(dev, delay) \
@ -260,13 +257,14 @@ static int sw_sequence(const struct device *dev, uint32_t count, @@ -260,13 +257,14 @@ static int sw_sequence(const struct device *dev, uint32_t count,
{
struct sw_cfg_data *sw_data = dev->data;
unsigned int key;
uint32_t val = 0;
uint32_t n = 0;
uint32_t val = 0; /* current byte */
uint32_t n = 0; /* bit counter */
LOG_DBG("count %u", count);
LOG_DBG("writing %u bits", count);
LOG_HEXDUMP_DBG(data, count, "sequence bit data");
key = irq_lock();
pin_swdio_out_enable(dev);
while (count--) {
if (n == 0U) {
val = *data++;
@ -309,6 +307,8 @@ static int sw_transfer(const struct device *dev, @@ -309,6 +307,8 @@ static int sw_transfer(const struct device *dev,
uint32_t parity = 0;
uint32_t n;
pin_swdio_out_enable(dev);
LOG_DBG("request 0x%02x idle %u", request, idle_cycles);
if (!(request & SWDP_REQUEST_RnW)) {
LOG_DBG("write data 0x%08x", *data);
@ -449,19 +449,31 @@ static int sw_set_pins(const struct device *dev, @@ -449,19 +449,31 @@ static int sw_set_pins(const struct device *dev,
}
}
if (pins & BIT(SWDP_SWDIO_PIN)) {
if (value & BIT(SWDP_SWDIO_PIN)) {
gpio_pin_set_dt(&config->dout, 1);
} else {
gpio_pin_set_dt(&config->dout, 0);
if (config->dout_reg != NULL) {
if (pins & BIT(SWDP_SWDIO_PIN)) {
if (value & BIT(SWDP_SWDIO_PIN)) {
gpio_pin_set_dt(&config->dout, 1);
} else {
gpio_pin_set_dt(&config->dout, 0);
}
}
} else {
if (pins & BIT(SWDP_SWDIO_PIN)) {
if (value & BIT(SWDP_SWDIO_PIN)) {
gpio_pin_set_dt(&config->dio, 1);
} else {
gpio_pin_set_dt(&config->dio, 0);
}
}
}
if (pins & BIT(SWDP_nRESET_PIN)) {
if (value & BIT(SWDP_nRESET_PIN)) {
gpio_pin_set_dt(&config->reset, 1);
} else {
gpio_pin_set_dt(&config->reset, 0);
if (config->reset.port) {
if (pins & BIT(SWDP_nRESET_PIN)) {
if (value & BIT(SWDP_nRESET_PIN)) {
gpio_pin_set_dt(&config->reset, 1);
} else {
gpio_pin_set_dt(&config->reset, 0);
}
}
}
@ -473,10 +485,12 @@ static int sw_get_pins(const struct device *dev, uint8_t *const state) @@ -473,10 +485,12 @@ static int sw_get_pins(const struct device *dev, uint8_t *const state)
const struct sw_config *config = dev->config;
uint32_t val;
val = gpio_pin_get_dt(&config->reset);
*state = val ? BIT(SWDP_nRESET_PIN) : 0;
if (config->reset.port) {
val = gpio_pin_get_dt(&config->reset);
*state = val ? BIT(SWDP_nRESET_PIN) : 0;
}
val = gpio_pin_get_dt(&config->din);
val = gpio_pin_get_dt(&config->dio);
*state |= val ? BIT(SWDP_SWDIO_PIN) : 0;
val = gpio_pin_get_dt(&config->clk);
@ -529,10 +543,28 @@ static int sw_port_on(const struct device *dev) @@ -529,10 +543,28 @@ static int sw_port_on(const struct device *dev)
const struct sw_config *config = dev->config;
gpio_pin_set_dt(&config->clk, 1);
gpio_pin_set_dt(&config->dout, 1);
gpio_pin_set_dt(&config->dnoe, 1);
gpio_pin_set_dt(&config->noe, 1);
gpio_pin_set_dt(&config->reset, 1);
if (config->dnoe.port) {
gpio_pin_set_dt(&config->dnoe, 1);
}
if (config->dout.port) {
gpio_pin_set_dt(&config->dout, 1);
} else {
int ret;
ret = gpio_pin_configure_dt(&config->dio, GPIO_OUTPUT_ACTIVE);
if (ret) {
return ret;
}
}
if (config->noe.port) {
gpio_pin_set_dt(&config->noe, 1);
}
if (config->reset.port) {
gpio_pin_set_dt(&config->reset, 1);
}
return 0;
}
@ -541,9 +573,27 @@ static int sw_port_off(const struct device *dev) @@ -541,9 +573,27 @@ static int sw_port_off(const struct device *dev)
{
const struct sw_config *config = dev->config;
gpio_pin_set_dt(&config->dnoe, 0);
gpio_pin_set_dt(&config->noe, 0);
gpio_pin_set_dt(&config->reset, 1);
if (config->dnoe.port) {
gpio_pin_set_dt(&config->dnoe, 0);
}
if (config->dout.port) {
gpio_pin_set_dt(&config->dout, 0);
} else {
int ret;
ret = gpio_pin_configure_dt(&config->dio, GPIO_INPUT);
if (ret) {
return ret;
}
}
if (config->noe.port) {
gpio_pin_set_dt(&config->noe, 0);
}
if (config->reset.port) {
gpio_pin_set_dt(&config->reset, 1);
}
return 0;
}
@ -559,29 +609,37 @@ static int sw_gpio_init(const struct device *dev) @@ -559,29 +609,37 @@ static int sw_gpio_init(const struct device *dev)
return ret;
}
ret = gpio_pin_configure_dt(&config->dout, GPIO_OUTPUT_ACTIVE);
ret = gpio_pin_configure_dt(&config->dio, GPIO_INPUT);
if (ret) {
return ret;
}
ret = gpio_pin_configure_dt(&config->din, GPIO_INPUT);
if (ret) {
return ret;
if (config->dout.port) {
ret = gpio_pin_configure_dt(&config->dout, GPIO_OUTPUT_ACTIVE);
if (ret) {
return ret;
}
}
ret = gpio_pin_configure_dt(&config->dnoe, GPIO_OUTPUT_INACTIVE);
if (ret) {
return ret;
if (config->dnoe.port) {
ret = gpio_pin_configure_dt(&config->dnoe, GPIO_OUTPUT_INACTIVE);
if (ret) {
return ret;
}
}
ret = gpio_pin_configure_dt(&config->noe, GPIO_OUTPUT_INACTIVE);
if (ret) {
return ret;
if (config->noe.port) {
ret = gpio_pin_configure_dt(&config->noe, GPIO_OUTPUT_INACTIVE);
if (ret) {
return ret;
}
}
ret = gpio_pin_configure_dt(&config->reset, GPIO_OUTPUT_INACTIVE);
if (ret) {
return ret;
if (config->reset.port) {
ret = gpio_pin_configure_dt(&config->reset, GPIO_OUTPUT_ACTIVE);
if (ret) {
return ret;
}
}
sw_data->turnaround = 1U;
@ -605,29 +663,35 @@ static struct swdp_api swdp_bitbang_api = { @@ -605,29 +663,35 @@ static struct swdp_api swdp_bitbang_api = {
.swdp_port_off = sw_port_off,
};
#define SW_GPIOS_GET_REG(n, gpios) \
INT_TO_POINTER(DT_REG_ADDR(DT_PHANDLE(DT_DRV_INST(n), gpios)))
#define SW_DEVICE_DEFINE(n) \
static const struct sw_config sw_cfg_##n = { \
.clk = GPIO_DT_SPEC_INST_GET(n, clk_gpios), \
.dout = GPIO_DT_SPEC_INST_GET(n, dout_gpios), \
.din = GPIO_DT_SPEC_INST_GET(n, din_gpios), \
.dnoe = GPIO_DT_SPEC_INST_GET(n, dnoe_gpios), \
.noe = GPIO_DT_SPEC_INST_GET(n, noe_gpios), \
.reset = GPIO_DT_SPEC_INST_GET(n, reset_gpios), \
.port_write_cycles = DT_INST_PROP(n, port_write_cycles), \
.clk_reg = SW_GPIOS_GET_REG(n, clk_gpios), \
.dout_reg = SW_GPIOS_GET_REG(n, dout_gpios), \
.din_reg = SW_GPIOS_GET_REG(n, din_gpios), \
.dnoe_reg = SW_GPIOS_GET_REG(n, dnoe_gpios), \
}; \
\
static struct sw_cfg_data sw_data_##n; \
\
DEVICE_DT_INST_DEFINE(n, sw_gpio_init, NULL, \
&sw_data_##n, &sw_cfg_##n, \
POST_KERNEL, CONFIG_DP_DRIVER_INIT_PRIO, \
&swdp_bitbang_api); \
#define SW_GPIOS_GET_REG(n, gpios) \
COND_CODE_1(DT_INST_NODE_HAS_PROP(n, gpios), \
(INT_TO_POINTER(DT_REG_ADDR(DT_PHANDLE(DT_DRV_INST(n), gpios)))), \
(NULL))
#define SW_DEVICE_DEFINE(n) \
BUILD_ASSERT((DT_INST_NODE_HAS_PROP(n, dout_gpios)) == \
(DT_INST_NODE_HAS_PROP(n, dnoe_gpios)), \
"Either the dout-gpios or dnoe-gpios property is missing."); \
\
static const struct sw_config sw_cfg_##n = { \
.clk = GPIO_DT_SPEC_INST_GET(n, clk_gpios), \
.clk_reg = SW_GPIOS_GET_REG(n, clk_gpios), \
.dio = GPIO_DT_SPEC_INST_GET(n, dio_gpios), \
.dio_reg = SW_GPIOS_GET_REG(n, dio_gpios), \
.dout = GPIO_DT_SPEC_INST_GET_OR(n, dout_gpios, {0}), \
.dout_reg = SW_GPIOS_GET_REG(n, dout_gpios), \
.dnoe = GPIO_DT_SPEC_INST_GET_OR(n, dnoe_gpios, {0}), \
.dnoe_reg = SW_GPIOS_GET_REG(n, dnoe_gpios), \
.noe = GPIO_DT_SPEC_INST_GET_OR(n, noe_gpios, {0}), \
.reset = GPIO_DT_SPEC_INST_GET_OR(n, reset_gpios, {0}), \
.port_write_cycles = DT_INST_PROP(n, port_write_cycles), \
}; \
\
static struct sw_cfg_data sw_data_##n; \
\
DEVICE_DT_INST_DEFINE(n, sw_gpio_init, NULL, \
&sw_data_##n, &sw_cfg_##n, \
POST_KERNEL, CONFIG_DP_DRIVER_INIT_PRIO, \
&swdp_bitbang_api);
DT_INST_FOREACH_STATUS_OKAY(SW_DEVICE_DEFINE)

84
drivers/dp/swdp_ll_pin.h

@ -0,0 +1,84 @@ @@ -0,0 +1,84 @@
/*
* Copyright (c) 2023 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/kernel.h>
#include <zephyr/drivers/gpio.h>
#if defined(CONFIG_SOC_SERIES_NRF52X)
#define CPU_CLOCK 64000000U
#else
#define CPU_CLOCK CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC
#endif
#if defined(CONFIG_SOC_SERIES_NRF52X) || defined(CONFIG_SOC_SERIES_NRF53X)
#define FAST_BITBANG_HW_SUPPORT 1
#else
#define FAST_BITBANG_HW_SUPPORT 0
#endif
static ALWAYS_INLINE void pin_delay_asm(uint32_t delay)
{
#if defined(CONFIG_CPU_CORTEX_M)
__asm volatile ("movs r3, %[p]\n"
".start_%=:\n"
"subs r3, #1\n"
"bne .start_%=\n"
:
: [p] "r" (delay)
: "r3", "cc"
);
#else
#warning "Pin delay is not defined"
#endif
}
static ALWAYS_INLINE void swdp_ll_pin_input(void *const base, uint8_t pin)
{
#if defined(CONFIG_SOC_SERIES_NRF52X) || defined(CONFIG_SOC_SERIES_NRF53X)
NRF_GPIO_Type * reg = base;
reg->PIN_CNF[pin] = 0b0000;
#endif
}
static ALWAYS_INLINE void swdp_ll_pin_output(void *const base, uint8_t pin)
{
#if defined(CONFIG_SOC_SERIES_NRF52X) || defined(CONFIG_SOC_SERIES_NRF53X)
NRF_GPIO_Type * reg = base;
reg->PIN_CNF[pin] = 0b0001;
#endif
}
static ALWAYS_INLINE void swdp_ll_pin_set(void *const base, uint8_t pin)
{
#if defined(CONFIG_SOC_SERIES_NRF52X) || defined(CONFIG_SOC_SERIES_NRF53X)
NRF_GPIO_Type * reg = base;
reg->OUTSET = BIT(pin);
#endif
}
static ALWAYS_INLINE void swdp_ll_pin_clr(void *const base, uint8_t pin)
{
#if defined(CONFIG_SOC_SERIES_NRF52X) || defined(CONFIG_SOC_SERIES_NRF53X)
NRF_GPIO_Type * reg = base;
reg->OUTCLR = BIT(pin);
#endif
}
static ALWAYS_INLINE uint32_t swdp_ll_pin_get(void *const base, uint8_t pin)
{
#if defined(CONFIG_SOC_SERIES_NRF52X) || defined(CONFIG_SOC_SERIES_NRF53X)
NRF_GPIO_Type * reg = base;
return ((reg->IN >> pin) & 1);
#else
return 0UL;
#endif
}

84
dts/bindings/misc/zephyr,swdp-gpio.yaml

@ -1,10 +1,60 @@ @@ -1,10 +1,60 @@
# Copyright (c) 2019, Phytec Messtechnik GmbH
# Copyright (c) 2019 Phytec Messtechnik GmbH
# Copyright (c) 2023 Nordic Semiconductor ASA
# SPDX-License-Identifier: Apache-2.0
description: >
description: |
This is a representation of the Serial Wire Debug Port interface
implementation by GPIO bit-banging.
Schematic using dual-supply bus transceiver and separate dout and dnoe pins
VCC_3V3 VCC_REF
^ ^
| +-------------+ |
+-------|vcca vccb|-----+
| |
clk-gpios -------|a b|-------------- SWD CLK
| |
noe-gpios -------|dir gnd|-----+
+-------------+ |
74LVC1T45 v
GND
VCC_3V3 VCC_REF
^ ^
| +-------------+ |
+-------|vcca vccb|-----+
| |
dio-gpios -------|a b|------------*- SWD DIO
| | |
+-------|dir gnd|-----+ |
| +-------------+ | |
v 74LVC1T45 v |
GND GND |
|
|
VCC_3V3 VCC_REF |
^ ^ |
| +-------------+ | |
+-------|vcca vccb|-----+ |
| | |
dout-gpios -------|a b|------------+
| |
dnoe-gpios -------|dir gnd|-----+
+-------------+ |
74LVC1T45 v
GND
Direct connection using only dio pin for SWD DIO.
clk-gpios ------------------------------------ SWD CLK
dio-gpios ------------------------------------ SWD DIO
Of course, bidirectional bus transceiver between dio and SWD DIO can also be
used together with noe pin to enable/disable transceivers.
compatible: "zephyr,swdp-gpio"
include: base.yaml
@ -15,32 +65,38 @@ properties: @@ -15,32 +65,38 @@ properties:
required: true
description: GPIO pin used for SWCLK output
dout-gpios:
dio-gpios:
type: phandle-array
required: true
description: GPIO pin used for SWDIO output
description: |
GPIO pin used for SWDIO input. This pin is also used for the SWDIO output
if separate output pin is not defined.
din-gpios:
dout-gpios:
type: phandle-array
required: true
description: GPIO pin used for SWDIO input
description: |
Optional GPIO pin used for SWDIO output.
dnoe-gpios:
type: phandle-array
required: true
description: GPIO pin used for SWDIO NOE output
description: |
GPIO pin used to disable the SWDIO output buffer behind optional
pin dout-gpios.
noe-gpios:
type: phandle-array
required: true
description: GPIO pin used for SWD NOE output
description: |
Optional pin to disable all bus transceivers if any are present.
reset-gpios:
type: phandle-array
required: true
description: GPIO pin used for RESET output
description: |
Optional GPIO pin used for RESET output.
port-write-cycles:
type: int
required: true
description: Number of processor cycles for I/O Port write operations
description: |
Number of processor cycles for I/O Port write operations.For example, the
GPIO clock may be different from the CPU clock. This can usually be
found in the SoC documentation.

Loading…
Cancel
Save