probe: resolve a bug in init/deinit handling

OpenOCD is fond of calling PORT_OFF and PORT_SWD_SETUP frequently, which
played havoc with caching both adapter khz and the DAP delay.

Revert to caching just the DAP delay and reset it when PORT_OFF is called.

Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
This commit is contained in:
Jonathan Bell
2022-07-13 17:01:36 +01:00
parent e698ea5d5c
commit 8737a06202
5 changed files with 13 additions and 9 deletions

View File

@@ -315,8 +315,11 @@ Configures the DAP Hardware I/O pins for Serial Wire Debug (SWD) mode:
- SWCLK, SWDIO, nRESET to output mode and set to default high level.
- TDI, nTRST to HighZ mode (pins are unused in SWD mode).
*/
// hack - zap our "stop doing divides everywhere" cache
extern volatile uint32_t cached_delay;
__STATIC_INLINE void PORT_SWD_SETUP (void) {
probe_init();
cached_delay = 0;
}
/** Disable JTAG/SWD I/O Pins.
@@ -542,7 +545,7 @@ Status LEDs. In detail the operation of Hardware I/O and LED pins are enabled an
- LED output pins are enabled and LEDs are turned off.
*/
__STATIC_INLINE void DAP_SETUP (void) {
;
probe_gpio_init();
}
/** Reset Target Device with custom specific I/O pin or command sequence.

View File

@@ -87,6 +87,7 @@ int main(void) {
cdc_uart_init();
tusb_init();
#if (PICOPROBE_DEBUG_PROTOCOL == PROTO_OPENOCD_CUSTOM)
probe_gpio_init();
probe_init();
#else
DAP_Setup();

View File

@@ -63,8 +63,6 @@ struct _probe {
// PIO offset
uint offset;
uint cached_freq_khz;
};
static struct _probe probe;
@@ -89,14 +87,11 @@ struct __attribute__((__packed__)) probe_pkt_hdr {
};
void probe_set_swclk_freq(uint freq_khz) {
if (freq_khz != probe.cached_freq_khz) {
uint clk_sys_freq_khz = clock_get_hz(clk_sys) / 1000;
picoprobe_info("Set swclk freq %dKHz sysclk %dkHz\n", freq_khz, clk_sys_freq_khz);
// Worked out with saleae
uint32_t divider = clk_sys_freq_khz / freq_khz / 2;
pio_sm_set_clkdiv_int_frac(pio0, PROBE_SM, divider, 0);
probe.cached_freq_khz = freq_khz;
}
}
void probe_assert_reset(bool state)
@@ -141,13 +136,16 @@ void probe_write_mode(void) {
while(!(pio0->dbg_padoe & (1 << PROBE_PIN_SWDIO)));
}
void probe_init() {
void probe_gpio_init()
{
// Funcsel pins
pio_gpio_init(pio0, PROBE_PIN_SWCLK);
pio_gpio_init(pio0, PROBE_PIN_SWDIO);
// Make sure SWDIO has a pullup on it. Idle state is high
gpio_pull_up(PROBE_PIN_SWDIO);
}
void probe_init() {
// 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

View File

@@ -37,6 +37,8 @@ void probe_handle_read(uint total_bits);
void probe_handle_write(uint8_t *data, uint total_bits);
void probe_task(void);
void probe_gpio_init(void);
void probe_init(void);
void probe_deinit(void);
#endif
#endif

View File

@@ -32,7 +32,7 @@
/* Slight hack - we're not bitbashing so we need to set baudrate off the DAP's delay cycles.
* Ideally we don't want calls to udiv everywhere... */
#define MAKE_KHZ(x) (CPU_CLOCK / (2000 * ((x) + 1)))
static uint32_t cached_delay;
volatile uint32_t cached_delay = 0;
// Generate SWJ Sequence
// count: sequence bit count