Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hardware target reset support #10

Merged
merged 1 commit into from
Feb 23, 2021
Merged
Show file tree
Hide file tree
Changes from all 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
3 changes: 3 additions & 0 deletions src/picoprobe_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@
#define PROBE_PIN_SWCLK PROBE_PIN_OFFSET + 0 // 2
#define PROBE_PIN_SWDIO PROBE_PIN_OFFSET + 1 // 3

// Target reset config
#define PROBE_PIN_RESET 6

// UART config
#define PICOPROBE_UART_TX 4
#define PICOPROBE_UART_RX 5
Expand Down
32 changes: 23 additions & 9 deletions src/probe.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,12 @@ struct _probe {
static struct _probe probe;

enum PROBE_CMDS {
PROBE_INVALID = 0, // Invalid command
PROBE_WRITE_BITS = 1, // Host wants us to write bits
PROBE_READ_BITS = 2, // Host wants us to read bits
PROBE_SET_FREQ = 3, // Set TCK
PROBE_RESET = 4, // Reset all state
PROBE_INVALID = 0, // Invalid command
PROBE_WRITE_BITS = 1, // Host wants us to write bits
PROBE_READ_BITS = 2, // Host wants us to read bits
PROBE_SET_FREQ = 3, // Set TCK
PROBE_RESET = 4, // Reset all state
PROBE_TARGET_RESET = 5, // Reset target
};

struct __attribute__((__packed__)) probe_cmd_hdr {
Expand All @@ -93,6 +94,12 @@ void probe_set_swclk_freq(uint freq_khz) {
pio_sm_set_clkdiv_int_frac(pio0, PROBE_SM, divider, 0);
}

static inline void probe_assert_reset(bool state)
{
/* Change the direction to out to drive pin to 0 or to in to emulate open drain */
gpio_set_dir(PROBE_PIN_RESET, state);
}

static inline void probe_write_bits(uint bit_count, uint8_t data_byte) {
DEBUG_PINS_SET(probe_timing, DBG_PIN_WRITE);
pio_sm_put_blocking(pio0, PROBE_SM, bit_count - 1);
Expand Down Expand Up @@ -137,11 +144,16 @@ void probe_init() {
// Make sure SWDIO has a pullup on it. Idle state is high
gpio_pull_up(PROBE_PIN_SWDIO);

// Target reset pin: pull up, input to emulate open drain pin
gpio_pull_up(PROBE_PIN_RESET);
// gpio_init will leave the pin cleared and set as input
gpio_init(PROBE_PIN_RESET);

uint offset = pio_add_program(pio0, &probe_program);
probe.offset = offset;

pio_sm_config sm_config = probe_program_get_default_config(offset);

// Set SWCLK as a sideset pin
sm_config_set_sideset_pins(&sm_config, PROBE_PIN_SWCLK);

Expand Down Expand Up @@ -225,7 +237,7 @@ void probe_prepare_read_header(struct probe_cmd_hdr *hdr) {
void probe_handle_pkt(void) {
uint8_t *pkt = &probe.rx_buf[0] + sizeof(struct probe_pkt_hdr);
uint remaining = probe.rx_len - sizeof(struct probe_pkt_hdr);

DEBUG_PINS_SET(probe_timing, DBG_PIN_PKT);

picoprobe_debug("Processing packet of length %d\n", probe.rx_len);
Expand All @@ -236,7 +248,7 @@ void probe_handle_pkt(void) {
uint data_bytes = DIV_ROUND_UP(hdr->bits, 8);
pkt += sizeof(struct probe_cmd_hdr);
remaining -= sizeof(struct probe_cmd_hdr);

if (hdr->cmd == PROBE_WRITE_BITS) {
uint8_t *data = pkt;
probe_handle_write(data, hdr->bits);
Expand All @@ -251,6 +263,8 @@ void probe_handle_pkt(void) {
// TODO: Is there anything to do after a reset?
// tx len and rx len should already be 0
;
} else if (hdr->cmd == PROBE_TARGET_RESET) {
probe_assert_reset(hdr->bits);
}
}
probe.rx_len = 0;
Expand All @@ -275,7 +289,7 @@ void probe_task(void) {
return;
}
probe.rx_len += count;
}
}

if (probe.rx_len >= sizeof(struct probe_pkt_hdr)) {
struct probe_pkt_hdr *pkt_hdr = (struct probe_pkt_hdr*)&probe.rx_buf[0];
Expand Down