Compare commits

..

3 Commits

Author SHA1 Message Date
Jonathan Bell
2eeef92b89 submodules: delete CMSIS_5 from the repository
See https://github.com/raspberrypi/pico-setup/issues/57

Clones of debugprobe or invocations of pico-setup.sh frequently
encounter errors relating to bandwidth budgets. These sporadic errors
are due to the large size of the CMSIS_5 repo clone exhausting the
bandwidth quotas on Github, so drop this in favour of a downstream copy
of the relevant CMSIS-DAP firmware files.

Users are advised to delete and regenerate the build directory.

Optionally, reclaim filesystem space by removing .git/modules/CMSIS_5
and all subdirectories.
2025-07-07 11:52:26 +01:00
Jonathan Bell
8a0c487df3 CMakelists.txt: use downstream copies of CMSIS_5 files
This change will require re-running cmake in the build directory.
2025-07-07 11:52:26 +01:00
Jonathan Bell
2a421d1648 Add downstream copies of CMSIS_5 files relevant to CMSIS-DAP firmware
From tag v2.0.0. Not used in the project yet.
2025-07-07 11:52:08 +01:00
12 changed files with 31 additions and 580 deletions

View File

@@ -22,7 +22,6 @@ add_executable(debugprobe
src/get_serial.c
src/sw_dp_pio.c
src/tusb_edpt_handler.c
src/autobaud.c
)
target_sources(debugprobe PRIVATE
@@ -43,22 +42,9 @@ target_compile_options(debugprobe PRIVATE -Wall)
pico_generate_pio_header(debugprobe ${CMAKE_CURRENT_LIST_DIR}/src/probe.pio)
pico_generate_pio_header(debugprobe ${CMAKE_CURRENT_LIST_DIR}/src/probe_oen.pio)
pico_generate_pio_header(debugprobe ${CMAKE_CURRENT_LIST_DIR}/src/autobaud.pio)
target_include_directories(debugprobe PRIVATE src)
# add version
add_custom_target(version
${CMAKE_SOURCE_DIR}/get-version.sh
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
)
target_include_directories(debugprobe PRIVATE
${CMAKE_BINARY_DIR}/generated
)
add_dependencies(debugprobe version)
target_compile_definitions (debugprobe PRIVATE
PICO_RP2040_USB_DEVICE_ENUMERATION_FIX=1
)
@@ -89,9 +75,6 @@ target_link_libraries(debugprobe PRIVATE
tinyusb_device
tinyusb_board
hardware_pio
hardware_dma
hardware_irq
hardware_clocks
FreeRTOS-Kernel
FreeRTOS-Kernel-Heap1
)

View File

@@ -1,12 +1,11 @@
# Debugprobe
Firmware source for the Raspberry Pi Debug Probe SWD/UART accessory. Can also be run on a Raspberry Pi Pico or Pico 2.
Firmware source for the Raspberry Pi Debug Probe SWD/UART accessory. Can also be run on a Raspberry Pi Pico.
[Raspberry Pi Debug Probe product page](https://www.raspberrypi.com/products/debug-probe/)
[Raspberry Pi Pico product page](https://www.raspberrypi.com/products/raspberry-pi-pico/)
[Raspberry Pi Pico 2 product page](https://www.raspberrypi.com/products/raspberry-pi-pico-2/)
# Documentation
@@ -30,7 +29,7 @@ Then create and switch to the build directory:
mkdir build
cd build
```
If your environment doesn't contain `PICO_SDK_PATH`, then either add it to your environment variables with `export PICO_SDK_PATH=/path/to/sdk` or add `-DPICO_SDK_PATH=/path/to/sdk` to the arguments to CMake below.
If your environment doesn't contain `PICO_SDK_PATH`, then either add it to your environment variables with `export PICO_SDK_PATH=/path/to/sdk` or add `PICO_SDK_PATH=/path/to/sdk` to the arguments to CMake below.
Run cmake and build the code:
```
@@ -39,41 +38,31 @@ Run cmake and build the code:
```
Done! You should now have a `debugprobe.uf2` that you can upload to your Debug Probe via the UF2 bootloader.
## Building for the Pico 1
If you want to create the version that runs on the Pico, then you need to invoke `cmake` in the sequence above with the `DEBUG_ON_PICO=ON` option:
```
cmake -DDEBUG_ON_PICO=ON ..
```
This will build with the configuration for the Pico and call the output program `debugprobe_on_pico.uf2`, as opposed to `debugprobe.uf2` for the accessory hardware.
Note that if you first ran through the whole sequence to compile for the Debug Probe, then you don't need to start back at the top. You can just go back to the `cmake` step and start from there.
## Building for the Pico 2
# Building for the Pico 2
If using an existing debugprobe clone:
- You must completely regenerate your build directory, or use a different one.
- You must also sync and update submodules.
- You must also sync and update submodules as rp2350 needs a downstream FreeRTOS port for now.
- `PICO_SDK_PATH` must point to a version 2.0.0 or greater install.
```
git submodule sync
git submodule update --init --recursive
git submodule update --init
mkdir build-pico2
cd build-pico2
cmake -DDEBUG_ON_PICO=1 -DPICO_BOARD=pico2 ../
cmake -DDEBUG_ON_PICO=1 -DPICO_BOARD=pico2 -DPICO_PLATFORM=rp2350 ../
```
This will build with the configuration for the Pico 2 and call the output program `debugprobe_on_pico2.uf2`.
# AutoBaud
Mode which automatically detects and sets the UART baud rate as data arrives.
To enable AutoBaud, configure the USB CDC port to the following custom baud rate:
```
9728 (0x2600)
```
> **Note:** Some Linux serial tools cannot set custom baud values. PuTTY on Windows and any terminal that supports arbitrary baud rates works.
Changing the baud rate to any other value disables AutoBaud.
# TODO
- AutoBaud selection, as PIO is a capable frequency counter
- Possibly include RTT support

View File

@@ -1,21 +0,0 @@
#!/bin/sh
if command -v git &>/dev/null
then
VERSION=$(git describe --exact-match --tags 2> /dev/null || git rev-parse --short HEAD)
else
VERSION="unknown"
fi
if [ ! -e generated/probe ]
then
mkdir -p generated/probe
fi
cat > generated/probe/version.h << EOF
#ifndef _PROBE_VERSION_H
#define _PROBE_VERSION_H
#define PROBE_VERSION "${VERSION}"
#endif
EOF

View File

@@ -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 PROBE_UART_TX 4

View File

@@ -102,11 +102,9 @@
*/
/* SMP port only */
#define configNUMBER_OF_CORES 2
#define configTICK_CORE 0
#define configUSE_CORE_AFFINITY 1
#define configNUM_CORES 1
#define configTICK_CORE 1
#define configRUN_MULTIPLE_PRIORITIES 1
#define configUSE_PASSIVE_IDLE_HOOK 0
/* RP2040 specific */
#define configSUPPORT_PICO_SYNC_INTEROP 1

View File

@@ -1,387 +0,0 @@
#include <pico/stdlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <hardware/pio.h>
#include <hardware/dma.h>
#include <hardware/irq.h>
#include <hardware/clocks.h>
#include "autobaud.h"
#include "probe_config.h"
#include "autobaud.pio.h"
// DMA buffer size
#define BUF_SIZE 1024
// Size of hash table for sample occurrence counts
#define HASH_TBL_SIZE 500
// Minimum sample occurrence ratio to consider a baud rate value valid
#define MIN_FREQUENCY 0.05f
// PIO clock frequency in Hz
#define PIO_CLOCK_FREQUENCY 125000000
// DMA IRQ for autobaud
#define DMA_AUTOBAUD_IRQ 0
// Priority for DMA IRQ handler
#define DMA_AUTOBAUD_IRQ_PRIORITY PICO_SHARED_IRQ_HANDLER_DEFAULT_ORDER_PRIORITY
typedef struct {
int key;
int count;
} Entry;
typedef struct {
Entry *entries;
size_t size;
} HashTable;
// PIO instance
static PIO pio;
// PIO state machine
static int sm = -1;
// PIO program offset
static int offset = -1;
// UART RX GPIO 1 pin
static const uint rx_pin = PROBE_UART_RX;
// Frequency hash table to store samples occurance
static HashTable *freq_table;
// Estimated baud rate and validity
static float baud;
static float validity;
// shortest bit duration in PIO cycles
static uint32_t min_cycles_count = UINT32_MAX;
// longest bit duration in PIO cycles
static uint32_t max_cycles_count = 0;
static uint32_t total_samples; // total samples seen
static uint32_t bit_time_sum; // sum of 1-bit times
static uint32_t bit_time_count; // total 1-bit times
static uint32_t outlier_count; // total of 1-bit times outliers
// DMA channels to read RX PIO line
static int ctrl_chan = -1;
static int data_chan = -1;
// DMA ring buffer storing PIO RX FIFO data
static uint32_t rx_buffer[BUF_SIZE] __attribute__((aligned(4096)));
// DMA control channel reads this value to reload transfer count
static const uint32_t dma_reload_count = BUF_SIZE;
static uintptr_t last_write_addr = (uintptr_t)rx_buffer;
static uintptr_t curr_write_addr = (uintptr_t)rx_buffer;
volatile bool autobaud_running = false;
volatile bool autobaud_stopped = true;
// Queue to hold new baud rate estimates
QueueHandle_t baudQueue;
TaskHandle_t autobaud_taskhandle;
uint32_t hash(uint32_t x, size_t size) {
x = ((x >> 16) ^ x) * 0x45d9f3bu;
x = ((x >> 16) ^ x) * 0x45d9f3bu;
x = (x >> 16) ^ x;
return x % size;
}
HashTable *create_table(size_t size) {
HashTable *table = malloc(sizeof(HashTable));
if (!table) return NULL;
table->size = size;
table->entries = calloc(size, sizeof(Entry));
if (!table->entries) {
free(table);
return NULL;
}
return table;
}
void insert(HashTable *table, int key) {
uint32_t idx = hash(key, table->size);
while (table->entries[idx].key != 0) {
if (table->entries[idx].key == key) {
table->entries[idx].count++;
return;
}
idx = (idx + 1) % table->size;
}
table->entries[idx].key = key;
table->entries[idx].count = 1;
}
int get_count(HashTable *table, int key) {
uint32_t idx = hash(key, table->size);
while (table->entries[idx].key != 0) {
if (table->entries[idx].key == key) {
return table->entries[idx].count;
}
idx = (idx + 1) % table->size;
}
return 0;
}
void free_table(HashTable *table) {
free(table->entries);
free(table);
}
void __isr dma_handler() {
// Clear DMA interrupt
if ((data_chan >= 0) && dma_irqn_get_channel_status(DMA_AUTOBAUD_IRQ, data_chan)) {
dma_irqn_acknowledge_channel(DMA_AUTOBAUD_IRQ, data_chan);
}
}
bool dma_configure(PIO pio, uint sm) {
// Configure two DMA channels for continuous RX FIFO monitoring:
// - data_chan: Continuously reads from PIO RX FIFO into circular buffer
// - ctrl_chan: Triggers data_chan to restart when it completes a transfer
ctrl_chan = dma_claim_unused_channel(true);
if (ctrl_chan < 0) return false;
data_chan = dma_claim_unused_channel(true);
if (data_chan < 0) return false;
dma_channel_config data_cfg = dma_channel_get_default_config(data_chan);
channel_config_set_transfer_data_size(&data_cfg, DMA_SIZE_32);
channel_config_set_read_increment(&data_cfg, false);
channel_config_set_write_increment(&data_cfg, true);
channel_config_set_dreq(&data_cfg, pio_get_dreq(pio, sm, false)); // Trigger when PIO RX FIFO has data to read
channel_config_set_chain_to(&data_cfg, ctrl_chan); // Chain to control channel when transfer completes
channel_config_set_ring(&data_cfg, true, 12); // Ring buffer size 2^12 = 4096 bytes (1024 uint32_t)
dma_channel_configure(
data_chan,
&data_cfg,
rx_buffer,
&pio->rxf[sm],
BUF_SIZE,
false
);
dma_channel_config ctrl_cfg = dma_channel_get_default_config(ctrl_chan);
channel_config_set_transfer_data_size(&ctrl_cfg, DMA_SIZE_32);
channel_config_set_read_increment(&ctrl_cfg, false);
channel_config_set_write_increment(&ctrl_cfg, false);
dma_channel_configure(
ctrl_chan,
&ctrl_cfg,
&(dma_hw->ch[data_chan].al1_transfer_count_trig), // Destination: data channel's transfer count register
&dma_reload_count, // Source: reload transfer count value (BUF_SIZE)
1,
false
);
// Enable DMA interrupt on data channel completion
irq_add_shared_handler(dma_get_irq_num(DMA_AUTOBAUD_IRQ), dma_handler, DMA_AUTOBAUD_IRQ_PRIORITY);
irq_set_enabled(dma_get_irq_num(DMA_AUTOBAUD_IRQ), true);
dma_irqn_set_channel_enabled(DMA_AUTOBAUD_IRQ, data_chan, true);
dma_channel_start(data_chan);
return true;
}
// Compare rounded integer parts of baud rates
// Tolerance of 0.5% in detected versus set
static inline bool baud_changed(float new_baud, float baud) {
uint32_t hi = (uint32_t)(baud * 1.005f);
uint32_t lo = (uint32_t)(baud * 0.995f);
uint32_t new = (uint32_t)new_baud;
return (new > hi || new < lo);
}
// Processes new DMA samples read from the PIO RX FIFO. Each DMA sample
// represents a timestamp (or cycle count) between edges on the input signal.
// Accumulates these durations, filters noise, and estimates baud rate.
uint estimate_baud_rate() {
uint old_progress = total_samples;
// Get current DMA write address
curr_write_addr = dma_hw->ch[data_chan].write_addr;
// Convert absolute addresses to buffer indices
size_t curr_index = ((curr_write_addr) - (uintptr_t)rx_buffer) / sizeof(rx_buffer[0]);
size_t last_index = (last_write_addr - (uintptr_t)rx_buffer) / sizeof(rx_buffer[0]);
for (size_t i = last_index; i != curr_index; i = (i + 1) % BUF_SIZE) {
uint32_t raw = rx_buffer[i];
uint32_t curr_cycles_count = (UINT32_MAX - raw) * 2;
insert(freq_table, curr_cycles_count);
total_samples++;
if (curr_cycles_count > max_cycles_count)
max_cycles_count = curr_cycles_count;
float freq = (float) get_count(freq_table, curr_cycles_count) / (float) total_samples;
// if sample is seen at least 5% of all samples,
// it is assumed it's not a noisy value
if (freq < MIN_FREQUENCY) continue;
if (curr_cycles_count < min_cycles_count) {
min_cycles_count = curr_cycles_count;
bit_time_sum = 0;
bit_time_count = 0;
outlier_count = 0;
continue;
}
// If current duration is within +10% of min_cycles, treat it as a "1-bit period"
if ((curr_cycles_count - min_cycles_count) < ((float)min_cycles_count * 0.1f)) {
bit_time_sum += curr_cycles_count;
bit_time_count++;
// 1-bit period should not be less than 1/9th of the longest period
if (curr_cycles_count < (max_cycles_count / 9))
outlier_count++;
// Calculate baud from average of 1-bit times
float avg_bit_time = (float) bit_time_sum / (float) bit_time_count;
float new_baud = PIO_CLOCK_FREQUENCY / avg_bit_time;
// If baud has changed, send updated baud information to cdc_thread
if (baud_changed(new_baud, baud)) {
float completeness = 1.0f - expf(-(float) total_samples / 40.0f);
float noise_ratio = (float) outlier_count / (float) bit_time_count;
float consistency = 1.0f - fminf(noise_ratio * 2.0f, 1.0f);
float validity = completeness * consistency;
if (validity > 0.6f) {
baud = new_baud;
BaudInfo_t new_baud_info;
new_baud_info.baud = (uint32_t)roundf(baud);
new_baud_info.validity = validity;
xQueueOverwrite(baudQueue, &new_baud_info);
}
}
}
}
last_write_addr = curr_write_addr;
return total_samples - old_progress;
}
void autobaud_deinit() {
// Disable DMA IRQ and channels
if (data_chan >= 0) {
dma_irqn_set_channel_enabled(DMA_AUTOBAUD_IRQ, data_chan, false);
dma_irqn_acknowledge_channel(DMA_AUTOBAUD_IRQ, data_chan);
dma_channel_unclaim(data_chan);
data_chan = -1;
}
if (ctrl_chan >= 0) {
dma_channel_unclaim(ctrl_chan);
ctrl_chan = -1;
}
irq_remove_handler(dma_get_irq_num(DMA_AUTOBAUD_IRQ), dma_handler);
if (!irq_has_shared_handler(dma_get_irq_num(DMA_AUTOBAUD_IRQ))) {
irq_set_enabled(dma_get_irq_num(DMA_AUTOBAUD_IRQ), false);
}
// Remove PIO program
if (pio && (sm >= 0)) {
pio_sm_set_enabled(pio, sm, false);
pio_sm_unclaim(pio, sm);
}
if (pio && (offset >= 0)) {
pio_remove_program(pio, &autobaud_program, offset);
}
if (freq_table) {
free_table(freq_table);
freq_table = NULL;
}
if (baudQueue) {
vQueueDelete(baudQueue);
baudQueue = NULL;
}
// Reset state
pio = NULL;
sm = offset = -1;
baud = validity = 0.0f;
min_cycles_count = UINT32_MAX;
max_cycles_count = 0;
total_samples = bit_time_sum = bit_time_count = outlier_count = 0;
last_write_addr = (uintptr_t)rx_buffer;
curr_write_addr = (uintptr_t)rx_buffer;
}
bool autobaud_init() {
pio = pio0;
// Claim a free PIO state machine
sm = pio_claim_unused_sm(pio, true);
if (sm < 0)
return false;
// Add PIO program
offset = pio_add_program(pio, &autobaud_program);
if (offset < 0) {
autobaud_deinit();
return false;
}
float div = (float)clock_get_hz(clk_sys) / PIO_CLOCK_FREQUENCY;
autobaud_program_init(pio, sm, offset, rx_pin, div);
pio_sm_set_enabled(pio, sm, true);
// Create hash table to keep count of sample occurance
freq_table = create_table(HASH_TBL_SIZE);
if (!freq_table) {
autobaud_deinit();
return false;
}
// Create queue to send baud information to cdc_thread
baudQueue = xQueueCreate(1, sizeof(BaudInfo_t));
if (!baudQueue) {
autobaud_deinit();
return false;
}
// Set up DMA to continuously write PIO RX data into RAM
if (!dma_configure(pio, sm)) {
autobaud_deinit();
return false;
}
return true;
}
void autobaud_start() {
xTaskNotify(autobaud_taskhandle, AUTOBAUD_CMD_START, eSetValueWithOverwrite);
}
void autobaud_wait_stop() {
while (!autobaud_stopped)
xTaskNotify(autobaud_taskhandle, AUTOBAUD_CMD_STOP, eSetValueWithOverwrite);
}
// FreeRTOS thread running if MAGIC_BAUD was set by host
void autobaud_thread(void * param) {
TickType_t wake = xTaskGetTickCount();
uint32_t cmd = AUTOBAUD_CMD_NONE;
uint processed;
while (true) {
if (!autobaud_running) {
// Idle state: thread is blocked here until start command is received
xTaskNotifyWait(0, 0xFFFFFFFFu, &cmd, portMAX_DELAY);
if (cmd == AUTOBAUD_CMD_START) {
if (autobaud_init()) {
autobaud_running = true;
autobaud_stopped = false;
}
}
} else {
// Check if host requested autobaud termination
if (xTaskNotifyWait(0, 0xFFFFFFFFu, &cmd, 0) == pdTRUE) {
if (cmd == AUTOBAUD_CMD_STOP) {
autobaud_running = false;
autobaud_deinit();
autobaud_stopped = true;
continue;
}
}
processed = estimate_baud_rate();
if (!processed)
xTaskDelayUntil(&wake, 1);
}
}
}

View File

@@ -1,30 +0,0 @@
#ifndef AUTOBAUD_H
#define AUTOBAUD_H
#include "FreeRTOS.h"
#include "queue.h"
#include "semphr.h"
#define MAGIC_BAUD 9728 // 0x2600
typedef enum {
AUTOBAUD_CMD_NONE = 0,
AUTOBAUD_CMD_START = 1,
AUTOBAUD_CMD_STOP = 2,
} autobaud_cmd_t;
typedef struct {
uint32_t baud; // Estimated baud rate
float validity; // Validity of the estimated baud rate
} BaudInfo_t;
extern volatile bool autobaud_running;
extern volatile bool autobaud_stopped;
extern QueueHandle_t baudQueue;
extern TaskHandle_t autobaud_taskhandle;
void autobaud_start(void);
void autobaud_wait_stop(void);
void autobaud_thread(void * param);
#endif

View File

@@ -1,42 +0,0 @@
.program autobaud
.wrap_target
falling_edge:
wait 0 pin 0 ; falling edge detected
set x, 0 ; set cycle counter to 0
mov x, ~x ; x = 0xFFFFFFFF, to decrement x
count_cycles:
jmp pin rising_edge ; if line went high, save current cycle count
jmp x-- count_cycles ; otherwise, decrement and enter loop again
rising_edge:
mov isr, x ; save elapsed cycle count in ISR
push noblock ; nonblocking push of the ISR content
jmp falling_edge ; repeat sampling process
.wrap
% c-sdk {
// Helper function (for use in C program) to initialize this PIO program
void autobaud_program_init(PIO pio, uint sm, uint offset, uint rx_pin, float div) {
// Sets up state machine and wrap target. This function is automatically
// generated in autobaud.pio.h.
pio_sm_config c = autobaud_program_get_default_config(offset);
// No need to set PIO funcsel, as this program is receive-only
sm_config_set_in_pins(&c, rx_pin);
sm_config_set_jmp_pin(&c, rx_pin);
pio_sm_set_consecutive_pindirs(pio, sm, rx_pin, 1, false);
// Set the clock divider for the state machine
sm_config_set_clkdiv(&c, div);
// Load configuration and jump to start of the program
pio_sm_init(pio, sm, offset, &c);
}
%}

View File

@@ -27,7 +27,6 @@
#include "FreeRTOS.h"
#include "task.h"
#include "tusb.h"
#include "autobaud.h"
#include "probe_config.h"
@@ -51,8 +50,6 @@ static volatile uint tx_led_debounce;
static uint rx_led_debounce;
#endif
static BaudInfo_t baud_info;
void cdc_uart_init(void) {
gpio_set_function(PROBE_UART_TX, GPIO_FUNC_UART);
gpio_set_function(PROBE_UART_RX, GPIO_FUNC_UART);
@@ -179,22 +176,6 @@ bool cdc_task(void)
return keep_alive;
}
void cdc_uart_set_baudrate(uint32_t baudrate) {
/* Set the tick thread interval to the amount of time it takes to
* fill up half a FIFO. Millis is too coarse for integer divide.
*/
uint32_t micros = (1000 * 1000 * 16 * 10) / MAX(baudrate, 1);
interval = MAX(1, micros / ((1000 * 1000) / configTICK_RATE_HZ));
debounce_ticks = MAX(1, configTICK_RATE_HZ / (interval * DEBOUNCE_MS));
probe_info("New baud rate %ld micros %ld interval %lu\n",
baudrate, micros, interval);
uart_deinit(PROBE_UART_INTERFACE);
tud_cdc_write_clear();
tud_cdc_read_flush();
uart_init(PROBE_UART_INTERFACE, baudrate);
}
void cdc_thread(void *ptr)
{
BaseType_t delayed;
@@ -205,38 +186,31 @@ void cdc_thread(void *ptr)
keep_alive = cdc_task();
if (!keep_alive) {
delayed = xTaskDelayUntil(&last_wake, interval);
if (delayed == pdFALSE)
last_wake = xTaskGetTickCount();
if (autobaud_running) {
// Receive baud information from autobaud thread
if (xQueueReceive(baudQueue, &baud_info, 0) == pdTRUE) {
cdc_uart_set_baudrate(baud_info.baud);
// Assume 8N1
uart_set_format(PROBE_UART_INTERFACE, 8, 1, UART_PARITY_NONE);
}
}
if (delayed == pdFALSE)
last_wake = xTaskGetTickCount();
}
}
}
void tud_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const* line_coding)
{
if (line_coding->bit_rate == MAGIC_BAUD) {
if (!autobaud_running)
autobaud_start();
return;
}
else if (autobaud_running) {
autobaud_wait_stop();
}
uart_parity_t parity;
uint data_bits, stop_bits;
/* Set the tick thread interval to the amount of time it takes to
* fill up half a FIFO. Millis is too coarse for integer divide.
*/
uint32_t micros = (1000 * 1000 * 16 * 10) / MAX(line_coding->bit_rate, 1);
/* Modifying state, so park the thread before changing it. */
if (tud_cdc_connected())
vTaskSuspend(uart_taskhandle);
cdc_uart_set_baudrate(line_coding->bit_rate);
interval = MAX(1, micros / ((1000 * 1000) / configTICK_RATE_HZ));
debounce_ticks = MAX(1, configTICK_RATE_HZ / (interval * DEBOUNCE_MS));
probe_info("New baud rate %ld micros %ld interval %lu\n",
line_coding->bit_rate, micros, interval);
uart_deinit(PROBE_UART_INTERFACE);
tud_cdc_write_clear();
tud_cdc_read_flush();
uart_init(PROBE_UART_INTERFACE, line_coding->bit_rate);
switch (line_coding->parity) {
case CDC_LINE_CODING_PARITY_ODD:

View File

@@ -41,7 +41,6 @@
#include "probe_config.h"
#include "probe.h"
#include "cdc_uart.h"
#include "autobaud.h"
#include "get_serial.h"
#include "tusb_edpt_handler.h"
#include "DAP.h"
@@ -59,8 +58,6 @@ static uint8_t RxDataBuffer[CFG_TUD_HID_EP_BUFSIZE];
#define TUD_TASK_PRIO (tskIDLE_PRIORITY + 2)
#define DAP_TASK_PRIO (tskIDLE_PRIORITY + 1)
#define AUTOBAUD_TASK_PRIO (tskIDLE_PRIORITY + 1)
TaskHandle_t dap_taskhandle, tud_taskhandle, mon_taskhandle;
static int was_configured;
@@ -233,9 +230,6 @@ void tud_suspend_cb(bool remote_wakeup_en)
if (was_configured) {
vTaskSuspend(uart_taskhandle);
vTaskSuspend(dap_taskhandle);
if (autobaud_running)
autobaud_wait_stop();
vTaskSuspend(autobaud_taskhandle);
}
/* slow down clk_sys for power saving ? */
}
@@ -246,7 +240,6 @@ void tud_resume_cb(void)
if (was_configured) {
vTaskResume(uart_taskhandle);
vTaskResume(dap_taskhandle);
vTaskResume(autobaud_taskhandle);
}
}
@@ -257,10 +250,6 @@ void tud_unmount_cb(void)
vTaskSuspend(dap_taskhandle);
vTaskDelete(uart_taskhandle);
vTaskDelete(dap_taskhandle);
if (autobaud_running)
autobaud_wait_stop();
vTaskSuspend(autobaud_taskhandle);
vTaskDelete(autobaud_taskhandle);
was_configured = 0;
}
@@ -272,9 +261,6 @@ void tud_mount_cb(void)
xTaskCreate(cdc_thread, "UART", configMINIMAL_STACK_SIZE, NULL, UART_TASK_PRIO, &uart_taskhandle);
/* Lowest priority thread is debug - need to shuffle buffers before we can toggle swd... */
xTaskCreate(dap_thread, "DAP", configMINIMAL_STACK_SIZE, NULL, DAP_TASK_PRIO, &dap_taskhandle);
/* Autobaud detection using PIO as a frequency counter */
xTaskCreate(autobaud_thread, "ABR", configMINIMAL_STACK_SIZE, NULL, AUTOBAUD_TASK_PRIO, &autobaud_taskhandle);
vTaskCoreAffinitySet(autobaud_taskhandle, (1 << 1));
was_configured = 1;
}
}

View File

@@ -1,6 +1,6 @@
#include "probe_config.h"
#include "pico/binary_info.h"
#include "probe/version.h"
#define STR_HELPER(x) #x
#define STR(x) STR_HELPER(x)
@@ -8,7 +8,6 @@
void bi_decl_config()
{
bi_decl(bi_program_version_string(PROBE_VERSION));
#ifdef PROBE_PIN_RESET
bi_decl(bi_1pin_with_name(PROBE_PIN_RESET, "PROBE RESET"));
#endif

View File

@@ -48,7 +48,7 @@ tusb_desc_device_t const desc_device =
.idVendor = 0x2E8A, // Pi
.idProduct = 0x000c, // CMSIS-DAP Debug Probe
.bcdDevice = 0x0223, // Version 02.23
.bcdDevice = 0x0222, // Version 02.22
.iManufacturer = 0x01,
.iProduct = 0x02,
.iSerialNumber = 0x03,