probe: fix SWDIO line idle state and export low-level functions

Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
This commit is contained in:
Jonathan Bell
2022-07-04 15:04:55 +01:00
parent 908bfbd4fb
commit 02b31998d5
3 changed files with 34 additions and 12 deletions

View File

@@ -63,6 +63,8 @@ struct _probe {
// PIO offset
uint offset;
uint cached_freq_khz;
};
static struct _probe probe;
@@ -87,20 +89,23 @@ struct __attribute__((__packed__)) probe_pkt_hdr {
};
void probe_set_swclk_freq(uint freq_khz) {
picoprobe_info("Set swclk freq %dKHz\n", freq_khz);
uint clk_sys_freq_khz = clock_get_hz(clk_sys) / 1000;
// 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);
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;
}
}
static inline void probe_assert_reset(bool state)
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) {
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);
pio_sm_put_blocking(pio0, PROBE_SM, data_byte);
@@ -112,7 +117,7 @@ static inline void probe_write_bits(uint bit_count, uint8_t data_byte) {
DEBUG_PINS_CLR(probe_timing, DBG_PIN_WRITE);
}
static inline uint8_t probe_read_bits(uint bit_count) {
uint8_t probe_read_bits(uint bit_count) {
DEBUG_PINS_SET(probe_timing, DBG_PIN_READ);
pio_sm_put_blocking(pio0, PROBE_SM, bit_count - 1);
uint32_t data = pio_sm_get_blocking(pio0, PROBE_SM);
@@ -127,12 +132,12 @@ static inline uint8_t probe_read_bits(uint bit_count) {
return data_shifted;
}
static void probe_read_mode(void) {
void probe_read_mode(void) {
pio_sm_exec(pio0, PROBE_SM, pio_encode_jmp(probe.offset + probe_offset_in_posedge));
while(pio0->dbg_padoe & (1 << PROBE_PIN_SWDIO));
}
static void probe_write_mode(void) {
void probe_write_mode(void) {
pio_sm_exec(pio0, PROBE_SM, pio_encode_jmp(probe.offset + probe_offset_out_negedge));
while(!(pio0->dbg_padoe & (1 << PROBE_PIN_SWDIO)));
}
@@ -183,6 +188,13 @@ void probe_init() {
probe_write_mode();
}
void probe_deinit(void)
{
probe_read_mode();
pio_sm_set_enabled(pio0, PROBE_SM, 0);
pio_remove_program(pio0, &probe_program, probe.offset);
}
void probe_handle_read(uint total_bits) {
picoprobe_debug("Read %d bits\n", total_bits);
probe_read_mode();

View File

@@ -26,7 +26,17 @@
#ifndef PROBE_H_
#define PROBE_H_
void probe_set_swclk_freq(uint freq_khz);
void probe_write_bits(uint bit_count, uint8_t data_byte);
uint8_t probe_read_bits(uint bit_count);
void probe_read_mode(void);
void probe_write_mode(void);
void probe_handle_read(uint total_bits);
void probe_handle_write(uint8_t *data, uint total_bits);
void probe_task(void);
void probe_init(void);
void probe_deinit(void);
#endif

View File

@@ -34,7 +34,7 @@ public out_negedge:
out_negedge_bitloop:
out pins, 1 side 0x0 ; clock data out on falling edge
jmp x-- out_negedge_bitloop side 0x1 ; data is present for posedge
set pins, 0 side 0x0 ; Drive data low
set pins, 1 side 0x0 ; Drive data high (idle bus state)
push ; Push to rx fifo just so processor knows when done
jmp out_negedge ; Wait for next transaction