swd: use variables for pins (for later dynamic change)
This commit is contained in:
parent
6bed3ab0fb
commit
6b3b55839e
44
lib/swd.c
44
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
|
||||
|
Loading…
Reference in New Issue
Block a user