Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support resetting Picoprobe board using USB RESET interface (RP2040) #108

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
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
3 changes: 3 additions & 0 deletions include/board_pico_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,7 @@

#define PROBE_PRODUCT_STRING "Picoprobe (CMSIS-DAP)"

// Host Reset Config
#define PICOPROBE_RESET_CAPABLE 1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer disabled by default. I would guess that for other users the feature would aid remote development of the probe firmware itself, but the vast majority will be doing uf2 drag-and-drop with a Pico or a Debug Probe and a standard release.

So, please move this definition to include/board_example_config.h with a suitable description.


#endif
21 changes: 21 additions & 0 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@
#include "tusb_edpt_handler.h"
#include "DAP.h"

#include "usb_reset_interface.h"
#include "pico/bootrom.h"
#include "hardware/watchdog.h"




// UART0 for Picoprobe debug
// UART1 for picoprobe to target device

Expand Down Expand Up @@ -153,6 +160,20 @@ bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_requ
// nothing to with DATA & ACK stage
if (stage != CONTROL_STAGE_SETUP) return true;

#if PICOPROBE_RESET_CAPABLE
if (request->wIndex == 3) {
if (request->bRequest == RESET_REQUEST_BOOTSEL) {
reset_usb_boot(0, (request->wValue & 0x7f) | 0);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Superfluous bitwise OR with zero

return true;
}
if (request->bRequest == RESET_REQUEST_FLASH) {
watchdog_reboot(0, 0, 100);
return true;
}
return false;
}
#endif

switch (request->bmRequestType_bit.type)
{
case TUSB_REQ_TYPE_VENDOR:
Expand Down
7 changes: 7 additions & 0 deletions src/tusb_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
#ifndef _TUSB_CONFIG_H_
#define _TUSB_CONFIG_H_

#include "picoprobe_config.h"

#ifdef __cplusplus
extern "C" {
#endif
Expand Down Expand Up @@ -66,7 +68,12 @@
#define CFG_TUD_CDC 1
#define CFG_TUD_MSC 0
#define CFG_TUD_MIDI 0

#if PICOPROBE_RESET_CAPABLE
#define CFG_TUD_VENDOR 2
#else
#define CFG_TUD_VENDOR 1
#endif

/*
* TX bufsize (actually UART RX) is oversized because the Windows CDC-ACM
Expand Down
25 changes: 25 additions & 0 deletions src/usb_descriptors.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
#include "get_serial.h"
#include "picoprobe_config.h"

#include "usb_reset_interface.h"

//--------------------------------------------------------------------+
// Device Descriptors
//--------------------------------------------------------------------+
Expand Down Expand Up @@ -71,6 +73,9 @@ enum
ITF_NUM_PROBE, // Old versions of Keil MDK only look at interface 0
ITF_NUM_CDC_COM,
ITF_NUM_CDC_DATA,
#if PICOPROBE_RESET_CAPABLE
ITF_NUM_RPI_RESET,
#endif
ITF_NUM_TOTAL
};

Expand All @@ -80,11 +85,24 @@ enum
#define PROBE_OUT_EP_NUM 0x04
#define PROBE_IN_EP_NUM 0x85


#if PICOPROBE_RESET_CAPABLE
#define TUD_RPI_RESET_DESCRIPTOR_LEN 9

#define TUD_RPI_RESET_DESCRIPTOR(_itfnum, _stridx) \
/* Interface */\
9, TUSB_DESC_INTERFACE, _itfnum, 0, 0, TUSB_CLASS_VENDOR_SPECIFIC, RESET_INTERFACE_SUBCLASS, RESET_INTERFACE_PROTOCOL, _stridx
#endif

#if (PICOPROBE_DEBUG_PROTOCOL == PROTO_DAP_V1)
#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_DESC_LEN + TUD_HID_INOUT_DESC_LEN)
#else
#if PICOPROBE_RESET_CAPABLE
#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_DESC_LEN + TUD_VENDOR_DESC_LEN + TUD_RPI_RESET_DESCRIPTOR_LEN)
#else
#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_DESC_LEN + TUD_VENDOR_DESC_LEN)
#endif
#endif

static uint8_t const desc_hid_report[] =
{
Expand Down Expand Up @@ -113,6 +131,10 @@ uint8_t const desc_configuration[] =
#endif
// Interface 1 + 2
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_COM, 6, CDC_NOTIFICATION_EP_NUM, 64, CDC_DATA_OUT_EP_NUM, CDC_DATA_IN_EP_NUM, 64),
#if PICOPROBE_RESET_CAPABLE
// Picotool compatible reset descriptor.
TUD_RPI_RESET_DESCRIPTOR(ITF_NUM_RPI_RESET, 7),
#endif
};

// Invoked when received GET CONFIGURATION DESCRIPTOR
Expand All @@ -138,6 +160,9 @@ char const* string_desc_arr [] =
"CMSIS-DAP v1 Interface", // 4: Interface descriptor for HID transport
"CMSIS-DAP v2 Interface", // 5: Interface descriptor for Bulk transport
"CDC-ACM UART Interface", // 6: Interface descriptor for CDC
#if PICOPROBE_RESET_CAPABLE
"Reset", // 7: RPI Reset.
#endif
};

static uint16_t _desc_str[32];
Expand Down
28 changes: 28 additions & 0 deletions src/usb_reset_interface.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can the reset interface definitions be included with a Cmake library linkage instead of a repeat inclusion of the sdk header?

* Copyright (c) 2021 Raspberry Pi (Trading) Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
*/

#ifndef _PICO_USB_RESET_INTERFACE_H
#define _PICO_USB_RESET_INTERFACE_H

/** \file usb_reset_interface.h
* \defgroup pico_usb_reset_interface pico_usb_reset_interface
*
* Definition for the reset interface that may be exposed by the pico_stdio_usb library
*/

// VENDOR sub-class for the reset interface
#define RESET_INTERFACE_SUBCLASS 0x00
// VENDOR protocol for the reset interface
#define RESET_INTERFACE_PROTOCOL 0x01

// CONTROL requests:

// reset to BOOTSEL
#define RESET_REQUEST_BOOTSEL 0x01
// regular flash boot
#define RESET_REQUEST_FLASH 0x02

#endif