From 6b3b55839eeac82bfc81226c082054b62984fec2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?King=20K=C3=A9vin?= Date: Wed, 10 Mar 2021 14:24:52 +0100 Subject: [PATCH] swd: use variables for pins (for later dynamic change) --- lib/swd.c | 44 +++++++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/lib/swd.c b/lib/swd.c index 273de57..da78f74 100644 --- a/lib/swd.c +++ b/lib/swd.c @@ -28,8 +28,14 @@ /** @defgroup swd_gpio GPIO used for SWDIO and SWCLK * @{ */ -#define SWD_SWCLK_PIN PB10 /**< GPIO pin for clock signal */ -#define SWD_SWDIO_PIN PB2 /**< GPIO pin for data input/output signal */ +#define SWD_SWCLK_PIN PB10 /**< default GPIO pin for clock signal */ +#define SWD_SWDIO_PIN PB2 /**< default GPIO pin for data input/output signal */ +static uint32_t swd_swclk_rcc = GPIO_RCC(SWD_SWCLK_PIN); +static uint32_t swd_swclk_port = GPIO_PORT(SWD_SWCLK_PIN); +static uint32_t swd_swclk_pin = GPIO_PIN(SWD_SWCLK_PIN); +static uint32_t swd_swdio_rcc = GPIO_RCC(SWD_SWDIO_PIN); +static uint32_t swd_swdio_port = GPIO_PORT(SWD_SWDIO_PIN); +static uint32_t swd_swdio_pin = GPIO_PIN(SWD_SWDIO_PIN); /** @} */ /** @defgroup swd_timer timer used to generate a periodic clock @@ -47,14 +53,14 @@ static volatile uint8_t swd_bits_i = 0; /** transaction bit index */ void swd_setup(uint32_t freq) { // setup GPIO for clock and data signals - rcc_periph_clock_enable(GPIO_RCC(SWD_SWCLK_PIN)); // enable clock for GPIO peripheral for clock signal - gpio_set(GPIO_PORT(SWD_SWCLK_PIN), GPIO_PIN(SWD_SWCLK_PIN)); // inactive clock is high - gpio_mode_setup(GPIO_PORT(SWD_SWCLK_PIN), GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN(SWD_SWCLK_PIN)); // the host controls the clock - gpio_set_output_options(GPIO_PORT(SWD_SWCLK_PIN), GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN(SWD_SWCLK_PIN)); // set SWCLK pin output as push-pull - rcc_periph_clock_enable(GPIO_RCC(SWD_SWDIO_PIN)); // enable clock for GPIO peripheral for data signal - gpio_set(GPIO_PORT(SWD_SWDIO_PIN), GPIO_PIN(SWD_SWDIO_PIN)); // inactive data is high (resetting the target when clock is active) - gpio_mode_setup(GPIO_PORT(SWD_SWDIO_PIN), GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN(SWD_SWDIO_PIN)); // the data signal is half duplex, with the host controlling who is driving the data signal when - gpio_set_output_options(GPIO_PORT(SWD_SWDIO_PIN), GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN(SWD_SWDIO_PIN)); // set SWDIO pin output as push-pull + rcc_periph_clock_enable(swd_swclk_rcc); // enable clock for GPIO peripheral for clock signal + gpio_set(swd_swclk_port, swd_swclk_pin); // inactive clock is high + gpio_mode_setup(swd_swclk_port, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, swd_swclk_pin); // the host controls the clock + gpio_set_output_options(swd_swclk_port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, swd_swclk_pin); // set SWCLK pin output as push-pull + rcc_periph_clock_enable(swd_swdio_rcc); // enable clock for GPIO peripheral for data signal + gpio_set(swd_swdio_port, swd_swdio_pin); // inactive data is high (resetting the target when clock is active) + gpio_mode_setup(swd_swdio_port, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, swd_swdio_pin); // the data signal is half duplex, with the host controlling who is driving the data signal when + gpio_set_output_options(swd_swdio_port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, swd_swdio_pin); // set SWDIO pin output as push-pull // setup timer to generate periodic clock rcc_periph_clock_enable(RCC_TIM(SWD_TIMER)); // enable clock for timer peripheral @@ -86,8 +92,8 @@ void swd_release(void) rcc_periph_clock_disable(RCC_TIM(SWD_TIMER)); // disable clock for timer peripheral // release GPIO - gpio_mode_setup(GPIO_PORT(SWD_SWCLK_PIN), GPIO_MODE_INPUT, GPIO_PUPD_NONE, GPIO_PIN(SWD_SWCLK_PIN)); // put clock signal pin back to input floating - gpio_mode_setup(GPIO_PORT(SWD_SWDIO_PIN), GPIO_MODE_INPUT, GPIO_PUPD_NONE, GPIO_PIN(SWD_SWDIO_PIN)); // put data signal pin back to input floating + gpio_mode_setup(swd_swclk_port, GPIO_MODE_INPUT, GPIO_PUPD_NONE, swd_swclk_pin); // put clock signal pin back to input floating + gpio_mode_setup(swd_swdio_port, GPIO_MODE_INPUT, GPIO_PUPD_NONE, swd_swdio_pin); // put data signal pin back to input floating } /** perform SWD transaction (one sequence of bits read or write) @@ -104,10 +110,10 @@ uint64_t swd_transaction(uint64_t output, uint8_t bit_count, bool write) } // initialize read/write if (write) { - gpio_mode_setup(GPIO_PORT(SWD_SWDIO_PIN), GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN(SWD_SWDIO_PIN)); // we drive the data signal to output data + gpio_mode_setup(swd_swdio_port, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, swd_swdio_pin); // we drive the data signal to output data swd_bits_out = output; // set data to output } else { - gpio_mode_setup(GPIO_PORT(SWD_SWDIO_PIN), GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, GPIO_PIN(SWD_SWDIO_PIN)); // the target will drive the data signal, we just pull it up + gpio_mode_setup(swd_swdio_port, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, swd_swdio_pin); // the target will drive the data signal, we just pull it up swd_bits_out = ~0ULL; // set the value so we pull up } swd_bits_in = 0; // reset input buffer @@ -303,19 +309,19 @@ void TIM_ISR(SWD_TIMER)(void) } if (edge_falling) { // falling edge: we output data if (swd_bits_out & (1ULL << swd_bits_i)) { // output data, LSb first - gpio_set(GPIO_PORT(SWD_SWDIO_PIN), GPIO_PIN(SWD_SWDIO_PIN)); // output high + gpio_set(swd_swdio_port, swd_swdio_pin); // output high } else { - gpio_clear(GPIO_PORT(SWD_SWDIO_PIN), GPIO_PIN(SWD_SWDIO_PIN)); // output low + gpio_clear(swd_swdio_port, swd_swdio_pin); // output low } - gpio_clear(GPIO_PORT(SWD_SWCLK_PIN), GPIO_PIN(SWD_SWCLK_PIN)); // output falling clock edge + gpio_clear(swd_swclk_port, swd_swclk_pin); // output falling clock edge } else { // rising edge: read data - if (gpio_get(GPIO_PORT(SWD_SWDIO_PIN), GPIO_PIN(SWD_SWDIO_PIN))) { // read data + if (gpio_get(swd_swdio_port, swd_swdio_pin)) { // read data swd_bits_out |= (1ULL << swd_bits_i); // set bit } else { swd_bits_out &= ~(1ULL << swd_bits_i); // clear bit } swd_bits_i++; - gpio_set(GPIO_PORT(SWD_SWCLK_PIN), GPIO_PIN(SWD_SWCLK_PIN)); // output rising clock edge + gpio_set(swd_swclk_port, swd_swclk_pin); // output rising clock edge } edge_falling = !edge_falling; // remember opposite upcoming edge } else { // no other interrupt should occur