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
|
/** @defgroup swd_gpio GPIO used for SWDIO and SWCLK
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
#define SWD_SWCLK_PIN PB10 /**< GPIO pin for clock signal */
|
#define SWD_SWCLK_PIN PB10 /**< default GPIO pin for clock signal */
|
||||||
#define SWD_SWDIO_PIN PB2 /**< GPIO pin for data input/output 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
|
/** @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)
|
void swd_setup(uint32_t freq)
|
||||||
{
|
{
|
||||||
// setup GPIO for clock and data signals
|
// setup GPIO for clock and data signals
|
||||||
rcc_periph_clock_enable(GPIO_RCC(SWD_SWCLK_PIN)); // enable clock for GPIO peripheral for clock signal
|
rcc_periph_clock_enable(swd_swclk_rcc); // 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_set(swd_swclk_port, 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_mode_setup(swd_swclk_port, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, 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
|
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(GPIO_RCC(SWD_SWDIO_PIN)); // enable clock for GPIO peripheral for data signal
|
rcc_periph_clock_enable(swd_swdio_rcc); // 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_set(swd_swdio_port, 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_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(GPIO_PORT(SWD_SWDIO_PIN), GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN(SWD_SWDIO_PIN)); // set SWDIO pin output as push-pull
|
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
|
// setup timer to generate periodic clock
|
||||||
rcc_periph_clock_enable(RCC_TIM(SWD_TIMER)); // enable clock for timer peripheral
|
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
|
rcc_periph_clock_disable(RCC_TIM(SWD_TIMER)); // disable clock for timer peripheral
|
||||||
|
|
||||||
// release GPIO
|
// 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(swd_swclk_port, GPIO_MODE_INPUT, GPIO_PUPD_NONE, 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_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)
|
/** 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
|
// initialize read/write
|
||||||
if (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
|
swd_bits_out = output; // set data to output
|
||||||
} else {
|
} 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_out = ~0ULL; // set the value so we pull up
|
||||||
}
|
}
|
||||||
swd_bits_in = 0; // reset input buffer
|
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 (edge_falling) { // falling edge: we output data
|
||||||
if (swd_bits_out & (1ULL << swd_bits_i)) { // output data, LSb first
|
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 {
|
} 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
|
} 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
|
swd_bits_out |= (1ULL << swd_bits_i); // set bit
|
||||||
} else {
|
} else {
|
||||||
swd_bits_out &= ~(1ULL << swd_bits_i); // clear bit
|
swd_bits_out &= ~(1ULL << swd_bits_i); // clear bit
|
||||||
}
|
}
|
||||||
swd_bits_i++;
|
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
|
edge_falling = !edge_falling; // remember opposite upcoming edge
|
||||||
} else { // no other interrupt should occur
|
} else { // no other interrupt should occur
|
||||||
|
|
Loading…
Reference in New Issue