Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
145 changes: 84 additions & 61 deletions drivers/dp/swdp_bitbang.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,17 @@
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(swdp, CONFIG_DP_DRIVER_LOG_LEVEL);

#define CLOCK_DELAY(swclk_freq, port_write_cycles) \
((CPU_CLOCK / 2 / swclk_freq) - port_write_cycles)
#define MAX_SWJ_CLOCK(delay_cycles, port_write_cycles) \
((CPU_CLOCK / 2U) / (port_write_cycles + delay_cycles))

Check notice on line 30 in drivers/dp/swdp_bitbang.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

drivers/dp/swdp_bitbang.c:30 -#define MAX_SWJ_CLOCK(delay_cycles, port_write_cycles) \ +#define MAX_SWJ_CLOCK(delay_cycles, port_write_cycles) \

/*
* Default SWCLK frequency in Hz.
* sw_clock can be used to overwrite this default value.
*/
#define SWDP_DEFAULT_SWCLK_FREQUENCY 1000000U

#define DELAY_FAST_CYCLES 2U
#define DELAY_SLOW_CYCLES 3U

Check notice on line 39 in drivers/dp/swdp_bitbang.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

drivers/dp/swdp_bitbang.c:39 -#define DELAY_FAST_CYCLES 2U +#define DELAY_FAST_CYCLES 2U

struct sw_config {
struct gpio_dt_spec clk;
Expand Down Expand Up @@ -528,14 +529,19 @@
struct sw_cfg_data *sw_data = dev->data;
uint32_t delay;

sw_data->fast_clock = false;
delay = ((CPU_CLOCK / 2U) + (clock - 1U)) / clock;

if (delay > config->port_write_cycles) {
delay -= config->port_write_cycles;
delay = (delay + (DELAY_SLOW_CYCLES - 1U)) / DELAY_SLOW_CYCLES;
} else {
if (clock >= MAX_SWJ_CLOCK(DELAY_FAST_CYCLES, config->port_write_cycles)) {
sw_data->fast_clock = true;
delay = 1U;
} else {
sw_data->fast_clock = false;

delay = ((CPU_CLOCK / 2U) + (clock - 1U)) / clock;
if (delay > config->port_write_cycles) {
delay -= config->port_write_cycles;
delay = (delay + (DELAY_SLOW_CYCLES - 1U)) / DELAY_SLOW_CYCLES;
} else {
delay = 1U;
}
}

sw_data->clock_delay = delay;
Expand All @@ -562,112 +568,129 @@
static int sw_port_on(const struct device *dev)
{
const struct sw_config *config = dev->config;

gpio_pin_set_dt(&config->clk, 1);
int ret;

if (config->dnoe.port) {
gpio_pin_set_dt(&config->dnoe, 1);
ret = gpio_pin_configure_dt(&config->dnoe, GPIO_OUTPUT_ACTIVE);
if (ret) {
return ret;
}
}

if (config->dout.port) {
gpio_pin_set_dt(&config->dout, 1);
} else {
int ret;

ret = gpio_pin_configure_dt(&config->dio, GPIO_OUTPUT_ACTIVE);
ret = gpio_pin_configure_dt(&config->dout, 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;
}

static int sw_port_off(const struct device *dev)
{
const struct sw_config *config = dev->config;

if (config->dnoe.port) {
gpio_pin_set_dt(&config->dnoe, 0);
ret = gpio_pin_configure_dt(&config->dio, GPIO_INPUT);
if (ret) {
return ret;
}

if (config->dout.port) {
gpio_pin_set_dt(&config->dout, 0);
} else {
int ret;

ret = gpio_pin_configure_dt(&config->dio, GPIO_INPUT);
if (config->noe.port) {
ret = gpio_pin_configure_dt(&config->noe, GPIO_OUTPUT_ACTIVE);
if (ret) {
return ret;
}
}

if (config->noe.port) {
gpio_pin_set_dt(&config->noe, 0);
ret = gpio_pin_configure_dt(&config->clk, GPIO_OUTPUT_ACTIVE);
if (ret) {
return ret;
}
if (config->reset.port) {
gpio_pin_set_dt(&config->reset, 1);

ret = gpio_pin_configure_dt(&config->reset, GPIO_OUTPUT_ACTIVE);
if (ret) {
return ret;
}

return 0;
}

static int sw_gpio_init(const struct device *dev)
static int sw_port_off(const struct device *dev)
{
const struct sw_config *config = dev->config;
struct sw_cfg_data *sw_data = dev->data;
int ret;

ret = gpio_pin_configure_dt(&config->clk, GPIO_OUTPUT_ACTIVE);
if (ret) {
return ret;
}
/* If there is a transceiver connected to IO, pins should always be driven. */
if (config->dnoe.port) {
ret = gpio_pin_configure_dt(&config->dnoe, GPIO_OUTPUT_INACTIVE);
if (ret) {
return ret;
}

ret = gpio_pin_configure_dt(&config->dio, GPIO_INPUT);
if (ret) {
return ret;
}
if (config->dout.port) {
ret = gpio_pin_configure_dt(&config->dout, GPIO_OUTPUT_ACTIVE);
if (ret) {
return ret;
}
}

if (config->dout.port) {
ret = gpio_pin_configure_dt(&config->dout, GPIO_OUTPUT_ACTIVE);
ret = gpio_pin_configure_dt(&config->dio, GPIO_INPUT);
if (ret) {
return ret;
}
}
} else {
if (config->dout.port) {
ret = gpio_pin_configure_dt(&config->dout, GPIO_DISCONNECTED);
if (ret) {
return ret;
}
}

if (config->dnoe.port) {
ret = gpio_pin_configure_dt(&config->dnoe, GPIO_OUTPUT_INACTIVE);
ret = gpio_pin_configure_dt(&config->dio, GPIO_DISCONNECTED);
if (ret) {
return ret;
}
}

/* If there is a transceiver connected to CLK, pins should always be driven. */
if (config->noe.port) {
ret = gpio_pin_configure_dt(&config->noe, GPIO_OUTPUT_INACTIVE);
if (ret) {
return ret;
}

ret = gpio_pin_configure_dt(&config->clk, GPIO_OUTPUT_ACTIVE);
if (ret) {
return ret;
}

} else {
ret = gpio_pin_configure_dt(&config->clk, GPIO_DISCONNECTED);
if (ret) {
return ret;
}
}

if (config->reset.port) {
ret = gpio_pin_configure_dt(&config->reset, GPIO_OUTPUT_ACTIVE);
ret = gpio_pin_configure_dt(&config->reset, GPIO_DISCONNECTED);
if (ret) {
return ret;
}
}

return 0;
}

static int sw_gpio_init(const struct device *dev)
{
const struct sw_config *config = dev->config;
struct sw_cfg_data *sw_data = dev->data;
int ret;

/* start with the port turned off */
ret = sw_port_off(dev);
if (ret) {
return ret;
}

sw_data->turnaround = 1U;
sw_data->data_phase = false;
sw_data->fast_clock = false;
sw_data->clock_delay = CLOCK_DELAY(SWDP_DEFAULT_SWCLK_FREQUENCY,
config->port_write_cycles);
sw_set_clock(dev, SWDP_DEFAULT_SWCLK_FREQUENCY);

return 0;
}
Expand Down
3 changes: 2 additions & 1 deletion drivers/dp/swdp_ll_pin.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@

#include <zephyr/kernel.h>
#include <zephyr/drivers/gpio.h>
#include <soc.h>

#if defined(CONFIG_SOC_SERIES_NRF52X)
#if defined(CONFIG_SOC_SERIES_NRF52X) || defined(CONFIG_SOC_SERIES_NRF53X)
#define CPU_CLOCK 64000000U
#else
#define CPU_CLOCK CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC
Expand Down
Loading