Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5ab8c86465 | ||
|
|
2a6f9911db | ||
|
|
5b6eb3e427 | ||
|
|
6473166494 | ||
|
|
3a1887ff06 | ||
|
|
13b420d34c | ||
|
|
eb494103d4 | ||
|
|
7de418cce3 | ||
|
|
0746b5a844 | ||
|
|
d04ff3b472 | ||
|
|
57f5569894 | ||
|
|
ae5bdb082d | ||
|
|
491b96c1d4 |
@@ -44,6 +44,17 @@ target_compile_definitions (picoprobe PRIVATE
|
||||
PICO_RP2040_USB_DEVICE_ENUMERATION_FIX=1
|
||||
)
|
||||
|
||||
option (DEBUGPROBE "compile for the debugprobe" OFF)
|
||||
if (DEBUGPROBE)
|
||||
target_compile_definitions (picoprobe PRIVATE
|
||||
DEBUGPROBE=1
|
||||
)
|
||||
set_target_properties(picoprobe PROPERTIES
|
||||
OUTPUT_NAME "debugprobe"
|
||||
)
|
||||
endif ()
|
||||
|
||||
|
||||
target_link_libraries(picoprobe PRIVATE
|
||||
pico_multicore
|
||||
pico_stdlib
|
||||
|
||||
30
README.md
30
README.md
@@ -4,6 +4,36 @@ Picoprobe allows a Pico / RP2040 to be used as USB -> SWD and UART bridge. This
|
||||
# Documentation
|
||||
Picoprobe documentation can be found in the [Pico Getting Started Guide](https://datasheets.raspberrypi.com/pico/getting-started-with-pico.pdf). See "Appendix A: Using Picoprobe".
|
||||
|
||||
# Hacking
|
||||
|
||||
For the purpose of making changes or studying of the code, you may want to compile the code yourself.
|
||||
|
||||
To compile this project firstly initialize and update the submodules:
|
||||
```
|
||||
git submodule update --init
|
||||
```
|
||||
then create and switch to the build directory:
|
||||
```
|
||||
mkdir build
|
||||
cd build
|
||||
```
|
||||
then run cmake and build the code:
|
||||
```
|
||||
cmake ..
|
||||
make
|
||||
```
|
||||
Done! You should now have a `picoprobe.uf2` that you can upload to your Pico in the normal way.
|
||||
|
||||
If you want to create the version that runs on the Raspberry Pi Debug Probe, then you need to invoke `cmake` in the sequence above with the `DEBUGPROBE=ON` option:
|
||||
```
|
||||
cmake -DDEBUGPROBE=ON ..
|
||||
```
|
||||
|
||||
This will build with the configuration for the Debug Probe and call the output program `debugprobe.uf2`, as opposed to `picoprobe.uf2` for the vanilla version.
|
||||
|
||||
Note that if you first ran through the whole sequence to compile for the Pico, then you don't need to start back at the top. You can just go back to the `cmake` step and start from there.
|
||||
|
||||
|
||||
# TODO
|
||||
- TinyUSB's vendor interface is FIFO-based and not packet-based. Using raw tx/rx callbacks is preferable as this stops DAP command batches from being concatenated, which confused openOCD.
|
||||
- Instead of polling, move the DAP thread to an asynchronously started/stopped one-shot operation to reduce CPU wakeups
|
||||
|
||||
@@ -460,7 +460,11 @@ __STATIC_FORCEINLINE void PIN_nTRST_OUT (uint32_t bit) {
|
||||
\return Current status of the nRESET DAP hardware I/O pin.
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t PIN_nRESET_IN (void) {
|
||||
#ifdef PROBE_PIN_RESET
|
||||
return probe_reset_level();
|
||||
#else
|
||||
return (0U);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** nRESET I/O pin: Set Output.
|
||||
@@ -469,7 +473,11 @@ __STATIC_FORCEINLINE uint32_t PIN_nRESET_IN (void) {
|
||||
- 1: release device hardware reset.
|
||||
*/
|
||||
__STATIC_FORCEINLINE void PIN_nRESET_OUT (uint32_t bit) {
|
||||
;
|
||||
#ifdef PROBE_PIN_RESET
|
||||
probe_assert_reset(!!bit);
|
||||
#else
|
||||
(void) bit;
|
||||
#endif
|
||||
}
|
||||
|
||||
///@}
|
||||
|
||||
@@ -52,4 +52,4 @@
|
||||
|
||||
#define PROBE_PRODUCT_STRING "Debug Probe (CMSIS-DAP)"
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
/* Include CDC interface to bridge to target UART. Omit if not used. */
|
||||
#define PROBE_CDC_UART
|
||||
/* Target reset GPIO (active-low). Omit if not used.*/
|
||||
#define PROBE_PIN_RESET 0
|
||||
#define PROBE_PIN_RESET 1
|
||||
|
||||
#define PROBE_SM 0
|
||||
#define PROBE_PIN_OFFSET 12
|
||||
|
||||
@@ -35,7 +35,9 @@
|
||||
#define PROBE_PIN_SWCLK (PROBE_PIN_OFFSET + 0) // 2
|
||||
#define PROBE_PIN_SWDIO (PROBE_PIN_OFFSET + 1) // 3
|
||||
// Target reset config
|
||||
#if false
|
||||
#define PROBE_PIN_RESET 1
|
||||
#endif
|
||||
|
||||
// UART config
|
||||
#define PICOPROBE_UART_TX 4
|
||||
|
||||
@@ -65,8 +65,11 @@ do { \
|
||||
|
||||
// TODO tie this up with PICO_BOARD defines in the main SDK
|
||||
|
||||
#ifndef DEBUGPROBE
|
||||
#include "board_pico_config.h"
|
||||
//#include "board_debugprobe_config.h"
|
||||
#else
|
||||
#include "board_debugprobe_config.h"
|
||||
#endif
|
||||
//#include "board_example_config.h"
|
||||
|
||||
|
||||
|
||||
66
src/probe.c
66
src/probe.c
@@ -62,8 +62,9 @@ static struct _probe probe;
|
||||
void probe_set_swclk_freq(uint 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;
|
||||
uint32_t divider = clk_sys_freq_khz / freq_khz / 4;
|
||||
if (divider == 0)
|
||||
divider = 1;
|
||||
pio_sm_set_clkdiv_int_frac(pio0, PROBE_SM, divider, 0);
|
||||
}
|
||||
|
||||
@@ -75,21 +76,48 @@ void probe_assert_reset(bool state)
|
||||
#endif
|
||||
}
|
||||
|
||||
int probe_reset_level(void)
|
||||
{
|
||||
#if defined(PROBE_PIN_RESET)
|
||||
return gpio_get(PROBE_PIN_RESET);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
typedef enum probe_pio_command {
|
||||
CMD_WRITE = 0,
|
||||
CMD_SKIP,
|
||||
CMD_TURNAROUND,
|
||||
CMD_READ
|
||||
} probe_pio_command_t;
|
||||
|
||||
static inline uint32_t fmt_probe_command(uint bit_count, bool out_en, probe_pio_command_t cmd) {
|
||||
uint cmd_addr =
|
||||
cmd == CMD_WRITE ? probe.offset + probe_offset_write_cmd :
|
||||
cmd == CMD_SKIP ? probe.offset + probe_offset_get_next_cmd :
|
||||
cmd == CMD_TURNAROUND ? probe.offset + probe_offset_turnaround_cmd :
|
||||
probe.offset + probe_offset_read_cmd;
|
||||
return ((bit_count - 1) & 0xff) | ((uint)out_en << 8) | (cmd_addr << 9);
|
||||
}
|
||||
|
||||
void probe_write_bits(uint bit_count, uint32_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, fmt_probe_command(bit_count, true, CMD_WRITE));
|
||||
pio_sm_put_blocking(pio0, PROBE_SM, data_byte);
|
||||
DEBUG_PINS_SET(probe_timing, DBG_PIN_WRITE_WAIT);
|
||||
picoprobe_dump("Write %d bits 0x%x\n", bit_count, data_byte);
|
||||
// Wait for pio to push garbage to rx fifo so we know it has finished sending
|
||||
pio_sm_get_blocking(pio0, PROBE_SM);
|
||||
DEBUG_PINS_CLR(probe_timing, DBG_PIN_WRITE_WAIT);
|
||||
// Return immediately so we can cue up the next command whilst this one runs
|
||||
DEBUG_PINS_CLR(probe_timing, DBG_PIN_WRITE);
|
||||
}
|
||||
|
||||
void probe_hiz_clocks(uint bit_count) {
|
||||
pio_sm_put_blocking(pio0, PROBE_SM, fmt_probe_command(bit_count, false, CMD_TURNAROUND));
|
||||
pio_sm_put_blocking(pio0, PROBE_SM, 0);
|
||||
}
|
||||
|
||||
uint32_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);
|
||||
pio_sm_put_blocking(pio0, PROBE_SM, fmt_probe_command(bit_count, false, CMD_READ));
|
||||
uint32_t data = pio_sm_get_blocking(pio0, PROBE_SM);
|
||||
uint32_t data_shifted = data;
|
||||
if (bit_count < 32) {
|
||||
@@ -101,14 +129,20 @@ uint32_t probe_read_bits(uint bit_count) {
|
||||
return data_shifted;
|
||||
}
|
||||
|
||||
static void probe_wait_idle() {
|
||||
pio0->fdebug = 1u << (PIO_FDEBUG_TXSTALL_LSB + PROBE_SM);
|
||||
while (!(pio0->fdebug & (1u << (PIO_FDEBUG_TXSTALL_LSB + PROBE_SM))))
|
||||
;
|
||||
}
|
||||
|
||||
void probe_read_mode(void) {
|
||||
pio_sm_exec(pio0, PROBE_SM, pio_encode_jmp(probe.offset + probe_offset_in_posedge));
|
||||
while(pio_sm_get_pc(pio0, PROBE_SM) != probe.offset + probe_offset_in_idle);
|
||||
pio_sm_put_blocking(pio0, PROBE_SM, fmt_probe_command(0, false, CMD_SKIP));
|
||||
probe_wait_idle();
|
||||
}
|
||||
|
||||
void probe_write_mode(void) {
|
||||
pio_sm_exec(pio0, PROBE_SM, pio_encode_jmp(probe.offset + probe_offset_out_negedge));
|
||||
while(pio_sm_get_pc(pio0, PROBE_SM) != probe.offset + probe_offset_out_idle);
|
||||
pio_sm_put_blocking(pio0, PROBE_SM, fmt_probe_command(0, true, CMD_SKIP));
|
||||
probe_wait_idle();
|
||||
}
|
||||
|
||||
void probe_init() {
|
||||
@@ -123,19 +157,17 @@ void probe_init() {
|
||||
// Set up divisor
|
||||
probe_set_swclk_freq(1000);
|
||||
|
||||
// Enable SM
|
||||
// Jump SM to command dispatch routine, and enable it
|
||||
pio_sm_exec(pio0, PROBE_SM, offset + probe_offset_get_next_cmd);
|
||||
pio_sm_set_enabled(pio0, PROBE_SM, 1);
|
||||
probe.initted = 1;
|
||||
}
|
||||
|
||||
// Jump to write program
|
||||
probe_write_mode();
|
||||
}
|
||||
|
||||
void probe_deinit(void)
|
||||
{
|
||||
probe_read_mode();
|
||||
if (probe.initted) {
|
||||
probe_read_mode();
|
||||
pio_sm_set_enabled(pio0, PROBE_SM, 0);
|
||||
pio_remove_program(pio0, &probe_program, probe.offset);
|
||||
probe.initted = 0;
|
||||
|
||||
@@ -35,13 +35,18 @@
|
||||
#endif
|
||||
|
||||
void probe_set_swclk_freq(uint freq_khz);
|
||||
|
||||
// Bit counts in the range 1..256
|
||||
void probe_write_bits(uint bit_count, uint32_t data_byte);
|
||||
uint32_t probe_read_bits(uint bit_count);
|
||||
void probe_hiz_clocks(uint bit_count);
|
||||
|
||||
void probe_read_mode(void);
|
||||
void probe_write_mode(void);
|
||||
|
||||
void probe_init(void);
|
||||
void probe_deinit(void);
|
||||
void probe_assert_reset(bool state);
|
||||
int probe_reset_level(void);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2021 Raspberry Pi (Trading) Ltd.
|
||||
* Copyright (c) 2021-2023 Raspberry Pi (Trading) Ltd.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -23,32 +23,50 @@
|
||||
*
|
||||
*/
|
||||
|
||||
// Every TX FIFO entry is either a command, or up to 32 bits of data.
|
||||
// Command format:
|
||||
//
|
||||
// | 13:9 | 8 | 7:0 |
|
||||
// | Cmd | Dir | Count |
|
||||
//
|
||||
// Count is the number of bits to be transferred by this command, minus 1.
|
||||
// Dir is the output enable for the SWDIO pin.
|
||||
// Cmd is the address of the write_cmd, read_cmd or get_next_cmd label.
|
||||
//
|
||||
// write_cmd expects a FIFO data entry, but read_cmd does not.
|
||||
//
|
||||
// read_cmd pushes data to the FIFO, but write_cmd does not. (The lack of RX
|
||||
// garbage on writes allows the interface code to return early after pushing a
|
||||
// write command, as there is no need in general to poll for a command's
|
||||
// completion as long as all commands are executed in order.)
|
||||
//
|
||||
// The SWCLK period is 4 PIO SM execution cycles.
|
||||
|
||||
.program probe
|
||||
.side_set 1 opt
|
||||
|
||||
public out_negedge:
|
||||
set pindirs, 1 side 0x0 ; Init OE clock 0
|
||||
public out_idle:
|
||||
pull ; Pull number of bits to shift -1 from tx fifo and put into output shift register
|
||||
mov x, osr ; mov bits to shift -1 from output shift register into x
|
||||
pull ; Pull data to shift out
|
||||
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, 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
|
||||
public write_cmd:
|
||||
public turnaround_cmd: ; Alias of write, used for probe_oen.pio
|
||||
pull
|
||||
write_bitloop:
|
||||
out pins, 1 [1] side 0x0 ; Data is output by host on negedge
|
||||
jmp x-- write_bitloop [1] side 0x1 ; ...and captured by target on posedge
|
||||
; Fall through to next command
|
||||
.wrap_target
|
||||
public get_next_cmd:
|
||||
pull side 0x0 ; SWCLK is initially low
|
||||
out x, 8 ; Get bit count
|
||||
out pindirs, 1 ; Set SWDIO direction
|
||||
out pc, 5 ; Go to command routine
|
||||
|
||||
read_bitloop:
|
||||
nop ; Additional delay on taken loop branch
|
||||
public read_cmd:
|
||||
in pins, 1 [1] side 0x1 ; Data is captured by host on posedge
|
||||
jmp x-- read_bitloop side 0x0
|
||||
push
|
||||
.wrap ; Wrap to next command
|
||||
|
||||
public in_posedge:
|
||||
set pindirs, 0 side 0x0 ; INIT IE clock 0
|
||||
public in_idle:
|
||||
pull ; Pull number of bits to shift -1 from tx fifo and put into output shift register
|
||||
mov x, osr ; mov bits to shift -1 from output shift register into x into x
|
||||
in_posedge_bitloop:
|
||||
in pins, 1 side 0x1 ; Generate posedge and read data
|
||||
jmp x-- in_posedge_bitloop side 0x0 ;
|
||||
push ; Push to rx fifo when done
|
||||
jmp in_posedge ; Jump back to start
|
||||
|
||||
; Implement probe_gpio_init() and probe_sm_init() methods here - set pins, offsets, sidesets etc
|
||||
% c-sdk {
|
||||
|
||||
@@ -1,39 +1,48 @@
|
||||
; Output-enable active-low variant of the SWD probe
|
||||
|
||||
; This program is very similar to the one in probe.pio. The only difference is
|
||||
; that here write_cmd and turnaround_cmd are split into two separate routines,
|
||||
; whose difference is OEn being high/low.
|
||||
|
||||
; SWDIO_OEn is pin 0, SWCLK pin 1, SWDIO (out) pin 2, SWDI (in) pin 3.
|
||||
; Pin 0 and 1 are sideset pins
|
||||
|
||||
.program probe
|
||||
.side_set 2 opt
|
||||
|
||||
; SWDIO_OEN is pin 0, SWCLK pin 1, SWDIO (out) pin 2, SWDI (in) pin 3.
|
||||
; Pin 0 and 1 are sideset pins
|
||||
public out_negedge:
|
||||
set pindirs, 0x1 side 0x0 ; OE_N 0, data high, clock 0
|
||||
public out_idle:
|
||||
pull ; pull nbits - 1
|
||||
mov x, osr
|
||||
pull ; pull data
|
||||
public out_negedge_bitloop:
|
||||
out pins, 1 side 0x0
|
||||
jmp x-- out_negedge_bitloop side 0x2 ; OE_N 0, clock high
|
||||
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
|
||||
public turnaround_cmd:
|
||||
pull
|
||||
turnaround_bitloop:
|
||||
nop [1] side 0x1
|
||||
jmp x-- turnaround_bitloop [1] side 0x3
|
||||
jmp get_next_cmd
|
||||
|
||||
public in_posedge:
|
||||
set pindirs, 0x0 side 0x1 ; OE_N 1, data high, clock 0
|
||||
public in_idle:
|
||||
pull
|
||||
mov x, osr
|
||||
in_posedge_bitloop:
|
||||
in pins, 1 side 0x1 ; OE_N 1, clock 0
|
||||
jmp x-- in_posedge_bitloop side 0x3 ; OE_N 1, clock 1
|
||||
push
|
||||
jmp in_posedge
|
||||
public write_cmd:
|
||||
pull
|
||||
write_bitloop:
|
||||
out pins, 1 [1] side 0x0 ; Data is output by host on negedge
|
||||
jmp x-- write_bitloop [1] side 0x2 ; ...and captured by target on posedge
|
||||
; Fall through to next command
|
||||
.wrap_target
|
||||
public get_next_cmd:
|
||||
pull side 0x1 ; SWCLK initially low, OEn disabled
|
||||
out x, 8 ; Get bit count
|
||||
out pindirs, 1 ; Set SWDIO direction
|
||||
out pc, 5 ; Go to command routine
|
||||
|
||||
read_bitloop:
|
||||
nop ; Additional delay on taken loop branch
|
||||
public read_cmd:
|
||||
in pins, 1 [1] side 0x3 ; Data is captured by host on posedge
|
||||
jmp x-- read_bitloop side 0x1
|
||||
push
|
||||
.wrap ; Wrap to next command
|
||||
|
||||
|
||||
; Implement probe_gpio_init() and probe_sm_init() methods here - set pins, offsets, sidesets etc
|
||||
% c-sdk {
|
||||
|
||||
void probe_gpio_init()
|
||||
static inline void probe_gpio_init()
|
||||
{
|
||||
#if defined(PROBE_PIN_RESET)
|
||||
// Target reset pin: pull up, input to emulate open drain pin
|
||||
@@ -51,10 +60,10 @@ void probe_gpio_init()
|
||||
gpio_pull_up(PROBE_PIN_SWDIOEN);
|
||||
}
|
||||
|
||||
void probe_sm_init(pio_sm_config* sm_config) {
|
||||
static inline void probe_sm_init(pio_sm_config* sm_config) {
|
||||
|
||||
// Set SWDIOEN and SWCLK as sideset pins
|
||||
sm_config_set_sideset_pins(&sm_config, PROBE_PIN_SWDIOEN);
|
||||
sm_config_set_sideset_pins(sm_config, PROBE_PIN_SWDIOEN);
|
||||
|
||||
// Set SWDIO offset
|
||||
sm_config_set_out_pins(sm_config, PROBE_PIN_SWDIO, 1);
|
||||
@@ -70,4 +79,4 @@ void probe_sm_init(pio_sm_config* sm_config) {
|
||||
sm_config_set_in_shift(sm_config, true, false, 0);
|
||||
}
|
||||
|
||||
%}
|
||||
%}
|
||||
|
||||
@@ -133,8 +133,6 @@ uint8_t SWD_Transfer (uint32_t request, uint32_t *data) {
|
||||
probe_write_bits(8, prq);
|
||||
|
||||
/* Turnaround (ignore read bits) */
|
||||
probe_read_mode();
|
||||
|
||||
ack = probe_read_bits(DAP_Data.swd_conf.turnaround + 3);
|
||||
ack >>= DAP_Data.swd_conf.turnaround;
|
||||
|
||||
@@ -154,12 +152,10 @@ uint8_t SWD_Transfer (uint32_t request, uint32_t *data) {
|
||||
picoprobe_debug("Read %02x ack %02x 0x%08x parity %01x\n",
|
||||
prq, ack, val, bit);
|
||||
/* Turnaround for line idle */
|
||||
probe_read_bits(DAP_Data.swd_conf.turnaround);
|
||||
probe_write_mode();
|
||||
probe_hiz_clocks(DAP_Data.swd_conf.turnaround);
|
||||
} else {
|
||||
/* Turnaround for write */
|
||||
probe_read_bits(DAP_Data.swd_conf.turnaround);
|
||||
probe_write_mode();
|
||||
probe_hiz_clocks(DAP_Data.swd_conf.turnaround);
|
||||
|
||||
/* Write WDATA[0:31] */
|
||||
val = *data;
|
||||
@@ -178,9 +174,9 @@ uint8_t SWD_Transfer (uint32_t request, uint32_t *data) {
|
||||
/* Idle cycles - drive 0 for N clocks */
|
||||
if (DAP_Data.transfer.idle_cycles) {
|
||||
for (n = DAP_Data.transfer.idle_cycles; n; ) {
|
||||
if (n > 32) {
|
||||
probe_write_bits(32, 0);
|
||||
n -= 32;
|
||||
if (n > 256) {
|
||||
probe_write_bits(256, 0);
|
||||
n -= 256;
|
||||
} else {
|
||||
probe_write_bits(n, 0);
|
||||
n -= n;
|
||||
@@ -195,8 +191,7 @@ uint8_t SWD_Transfer (uint32_t request, uint32_t *data) {
|
||||
/* Dummy Read RDATA[0:31] + Parity */
|
||||
probe_read_bits(33);
|
||||
}
|
||||
probe_read_bits(DAP_Data.swd_conf.turnaround);
|
||||
probe_write_mode();
|
||||
probe_hiz_clocks(DAP_Data.swd_conf.turnaround);
|
||||
if (DAP_Data.swd_conf.data_phase && ((request & DAP_TRANSFER_RnW) == 0U)) {
|
||||
/* Dummy Write WDATA[0:31] + Parity */
|
||||
probe_write_bits(32, 0);
|
||||
@@ -209,7 +204,6 @@ uint8_t SWD_Transfer (uint32_t request, uint32_t *data) {
|
||||
n = DAP_Data.swd_conf.turnaround + 32U + 1U;
|
||||
/* Back off data phase */
|
||||
probe_read_bits(n);
|
||||
probe_write_mode();
|
||||
return ((uint8_t)ack);
|
||||
}
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ tusb_desc_device_t const desc_device =
|
||||
|
||||
.idVendor = 0x2E8A, // Pi
|
||||
.idProduct = 0x000c, // CMSIS-DAP Debug Probe
|
||||
.bcdDevice = 0x0101, // Version 01.01
|
||||
.bcdDevice = 0x0103, // Version 01.03
|
||||
.iManufacturer = 0x01,
|
||||
.iProduct = 0x02,
|
||||
.iSerialNumber = 0x03,
|
||||
@@ -99,7 +99,7 @@ uint8_t const * tud_hid_descriptor_report_cb(uint8_t itf)
|
||||
|
||||
uint8_t const desc_configuration[] =
|
||||
{
|
||||
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
|
||||
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0, 100),
|
||||
// Interface 0
|
||||
#if (PICOPROBE_DEBUG_PROTOCOL == PROTO_DAP_V1)
|
||||
// HID (named interface)
|
||||
|
||||
Reference in New Issue
Block a user