Skip to content
Open
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
20 changes: 19 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ 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/ws2812.pio)

target_include_directories(debugprobe PRIVATE src)

Expand All @@ -52,16 +53,33 @@ target_compile_definitions (debugprobe PRIVATE
option (DEBUG_ON_PICO "Compile firmware for the Pico instead of Debug Probe" OFF)
if (DEBUG_ON_PICO)
target_compile_definitions (debugprobe PRIVATE
DEBUG_ON_PICO=1
DEBUG_ON_PICO=1
)
if (PICO_BOARD STREQUAL "pico")
set_target_properties(debugprobe PROPERTIES
OUTPUT_NAME "debugprobe_on_pico"
)
target_compile_definitions (debugprobe PRIVATE
PICO_BOARD_PICO=1
)

elseif (PICO_BOARD STREQUAL "pico2")
set_target_properties(debugprobe PROPERTIES
OUTPUT_NAME "debugprobe_on_pico2"
)
target_compile_definitions (debugprobe PRIVATE
PICO_BOARD_PICO2=1
)
elseif (PICO_BOARD STREQUAL "waveshare_rp2040_zero")
set_target_properties(debugprobe PROPERTIES
OUTPUT_NAME "debugprobe_on_zero"
)
target_compile_definitions (debugprobe PRIVATE
PICO_BOARD_PICO_ZERO=1
)
target_sources(debugprobe PRIVATE
${CMAKE_CURRENT_LIST_DIR}/src/ws2812.c
)
else ()
message(SEND_ERROR "Unsupported board ${PICO_BOARD}")
endif ()
Expand Down
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,21 @@ cd build-pico2
cmake -DDEBUG_ON_PICO=1 -DPICO_BOARD=pico2 -DPICO_PLATFORM=rp2350 ../
```

# Building for Waveshare RP2040 Zero

To build for the Waveshare RP2040 Zero, configure CMake with the DEBUG_ON_PICO option and set the target board:

- Requires Pico SDK v2.0.0 or newer (PICO_SDK_PATH must be set).
- The output file will be named debugprobe_on_zero.uf2 (default build produces debugprobe.uf2).

```
git submodule sync
git submodule update --init --recursive
mkdir build-zero
cd build-zero
cmake .. -DDEBUG_ON_PICO=1 -DPICO_BOARD=waveshare_rp2040_zero
```

# TODO
- AutoBaud selection, as PIO is a capable frequency counter
- Possibly include RTT support
12 changes: 12 additions & 0 deletions include/DAP_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,11 @@ This information includes:
#include <hardware/gpio.h>

#include "cmsis_compiler.h"

#include "probe_config.h"
#ifdef PROBE_WS2812_LED
#include "ws2812.h"
#endif
#include "probe.h"

/// Processor Clock of the Cortex-M MCU used in the Debug Unit.
Expand Down Expand Up @@ -505,6 +509,10 @@ It is recommended to provide the following LEDs for status indication:
__STATIC_INLINE void LED_CONNECTED_OUT (uint32_t bit) {
#ifdef PROBE_DAP_CONNECTED_LED
gpio_put(PROBE_DAP_CONNECTED_LED, bit);
#else
#ifdef PROBE_WS2812_DAP_CONNECTED
PROBE_WS2812_DAP_CONNECTED(bit);
#endif
#endif
}

Expand All @@ -516,6 +524,10 @@ __STATIC_INLINE void LED_CONNECTED_OUT (uint32_t bit) {
__STATIC_INLINE void LED_RUNNING_OUT (uint32_t bit) {
#ifdef PROBE_DAP_RUNNING_LED
gpio_put(PROBE_DAP_RUNNING_LED, bit);
#else
#ifdef PROBE_WS2812_DAP_RUNNING
PROBE_WS2812_DAP_RUNNING(bit);
#endif
#endif
}

Expand Down
66 changes: 66 additions & 0 deletions include/board_pico_zero_config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2025 KUNYI CHEN <[email protected]>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
#pragma once
#ifndef BOARD_PICO_ZERO_H_
#define BOARD_PICO_ZERO_H_

#define PROBE_IO_RAW
#define PROBE_CDC_UART

// PIO config
#define PROBE_SM 0
#define PROBE_PIN_OFFSET 2
#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
#define PROBE_UART_RX 5
#define PROBE_UART_INTERFACE uart1
#define PROBE_UART_BAUDRATE 115200

/* LED config - some or all of these can be omitted if not used */
#define PROBE_WS2812_LED
#define SM_WS2812 0
#define WS2812_PIN 16
#define PROBE_WS2812_USB_CONNECTED put_blueLED
#define PROBE_WS2812_DAP_CONNECTED put_greenLED
#define PROBE_WS2812_DAP_RUNNING put_redLED
/*
#define PROBE_USB_CONNECTED_LED 2
#define PROBE_DAP_CONNECTED_LED 15
#define PROBE_DAP_RUNNING_LED 16
#define PROBE_UART_RX_LED 7
#define PROBE_UART_TX_LED 8
*/

#define PROBE_PRODUCT_STRING "DebugProbe on Pico Zero (CMSIS-DAP/SWD)"

#endif
31 changes: 27 additions & 4 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
#include "tusb_edpt_handler.h"
#include "DAP.h"
#include "hardware/structs/usb.h"
#include "ws2812.h"

// UART0 for debugprobe debug
// UART1 for debugprobe to target device
Expand All @@ -54,14 +55,27 @@ static uint8_t RxDataBuffer[CFG_TUD_HID_EP_BUFSIZE];

#define THREADED 1

#define UART_TASK_PRIO (tskIDLE_PRIORITY + 3)
#define TUD_TASK_PRIO (tskIDLE_PRIORITY + 2)
#define DAP_TASK_PRIO (tskIDLE_PRIORITY + 1)
#define UART_TASK_PRIO (tskIDLE_PRIORITY + 4)
#define TUD_TASK_PRIO (tskIDLE_PRIORITY + 3)
#define DAP_TASK_PRIO (tskIDLE_PRIORITY + 2)
#define LED_TASK_PRIO (tskIDLE_PRIORITY + 1)

TaskHandle_t dap_taskhandle, tud_taskhandle, mon_taskhandle;
TaskHandle_t dap_taskhandle, tud_taskhandle, mon_taskhandle, led_taskhandle;

static int was_configured;

void led_thread(void *ptr)
{
TickType_t wake;

ws2812_init();
wake = xTaskGetTickCount();
do {
refresh_led();
xTaskDelayUntil(&wake, pdMS_TO_TICKS(20));
} while (true);
}

void dev_mon(void *ptr)
{
uint32_t sof[3];
Expand Down Expand Up @@ -106,7 +120,12 @@ void usb_thread(void *ptr)
gpio_put(PROBE_USB_CONNECTED_LED, 1);
else
gpio_put(PROBE_USB_CONNECTED_LED, 0);
#else
#ifdef PROBE_WS2812_USB_CONNECTED
PROBE_WS2812_USB_CONNECTED(tud_ready());
#endif
#endif

// If suspended or disconnected, delay for 1ms (20 ticks)
if (tud_suspended() || !tud_connected())
xTaskDelayUntil(&wake, 20);
Expand Down Expand Up @@ -139,6 +158,10 @@ int main(void) {
xTaskCreate(usb_thread, "TUD", configMINIMAL_STACK_SIZE, NULL, TUD_TASK_PRIO, &tud_taskhandle);
#if PICO_RP2040
xTaskCreate(dev_mon, "WDOG", configMINIMAL_STACK_SIZE, NULL, TUD_TASK_PRIO, &mon_taskhandle);
#endif
#ifdef PROBE_WS2812_LED
// #pragma message("WS2812 support enabled")
xTaskCreate(led_thread, "LED", configMINIMAL_STACK_SIZE, NULL, LED_TASK_PRIO, &led_taskhandle);
#endif
vTaskStartScheduler();
}
Expand Down
10 changes: 8 additions & 2 deletions src/probe_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,14 @@ do { \

// TODO tie this up with PICO_BOARD defines in the main SDK

#ifdef DEBUG_ON_PICO
#include "board_pico_config.h"
#ifdef DEBUG_ON_PICO
#if (PICO_BOARD_PICO)
#include "board_pico_config.h"
#elif (PICO_BOARD_PICO2)
#include "board_pico_config.h"
#elif (PICO_BOARD_PICO_ZERO)
#include "board_pico_zero_config.h"
#endif
#else
#include "board_debug_probe_config.h"
#endif
Expand Down
5 changes: 3 additions & 2 deletions src/usb_descriptors.c
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ char const* string_desc_arr [] =
"CDC-ACM UART Interface", // 6: Interface descriptor for CDC
};

static uint16_t _desc_str[32];
static uint16_t _desc_str[64];

// Invoked when received GET STRING DESCRIPTOR request
// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete
Expand All @@ -166,7 +166,8 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid)

// Cap at max char
chr_count = strlen(str);
if ( chr_count > 31 ) chr_count = 31;
if ( chr_count > (sizeof(_desc_str)/sizeof(_desc_str[0]) - 1) )
chr_count = sizeof(_desc_str)/sizeof(_desc_str[0]) - 1;

for(uint8_t i=0; i<chr_count; i++)
{
Expand Down
96 changes: 96 additions & 0 deletions src/ws2812.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
#include <stdio.h>
#include <stdlib.h>

#include <pico/stdlib.h>
#include <hardware/clocks.h>
#include <hardware/gpio.h>

#include "probe_config.h"
#include "ws2812.pio.h"

#define RED_MASK 0x01
#define GREEN_MASK 0x02
#define BLUE_MASK 0x04
struct _ws2812 {
uint initted;
uint offset;
uint led;
};

static struct _ws2812 ws2812 = {0};

#ifndef SM_WS2812
#define SM_WS2812 2
#endif

#ifndef WS2812_PIN
#define WS2812_PIN 16
#endif

static inline void put_pixel(uint32_t pixel_grb) {
pio_sm_put_blocking(pio1, SM_WS2812, pixel_grb << 8u);
}

void put_rgb(uint8_t red, uint8_t green, uint8_t blue)
{
uint32_t mask = (green << 16) | (red << 8) | (blue << 0);
put_pixel(mask);
}

void refresh_led(void)
{
uint val = 0;
if (ws2812.led & RED_MASK)
val |= 10 << 8;
if (ws2812.led & GREEN_MASK)
val |= 10 << 16;
if (ws2812.led & BLUE_MASK)
val |= 10;

put_pixel(val);
}

void put_redLED(bool on)
{
if (on)
ws2812.led |= RED_MASK;
else
ws2812.led &= ~RED_MASK;
}

void put_greenLED(bool on)
{
if (on)
ws2812.led |= GREEN_MASK;
else
ws2812.led &= ~GREEN_MASK;
}

void put_blueLED(bool on)
{
if (on)
ws2812.led |= BLUE_MASK;
else
ws2812.led &= ~BLUE_MASK;
}

void ws2812_init(void)
{
if (ws2812.initted)
return;

ws2812.initted = 1;
ws2812.led = 0;
ws2812.offset = pio_add_program(pio1, &ws2812_program);
ws2812_program_init(pio1, SM_WS2812, ws2812.offset, WS2812_PIN, 800000, false);
}

void ws2812_deinit(void)
{
if (!ws2812.initted)
return;

pio_sm_set_enabled(pio1, SM_WS2812, 0);
pio_remove_program(pio1, &ws2812_program, ws2812.offset);
ws2812.initted = 0;
}
Loading