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

Feature/wch link support #2061

Draft
wants to merge 14 commits into
base: main
Choose a base branch
from
Draft
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
6 changes: 6 additions & 0 deletions meson_options.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ option(
'apollo3',
'at32f4',
'ch32',
'ch32v',
'ch579',
'efm',
'gd32',
Expand Down Expand Up @@ -148,3 +149,8 @@ option(
value: false,
description: 'Enable firmware-side protocol acceleration of RISC-V Debug'
)
option(
'rvswd_support',
type: 'boolean',
value: 'false'
)
64 changes: 63 additions & 1 deletion src/command.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ static bool cmd_help(target_s *target, int argc, const char **argv);

static bool cmd_jtag_scan(target_s *target, int argc, const char **argv);
static bool cmd_swd_scan(target_s *target, int argc, const char **argv);
#if defined(ENABLE_RVSWD) && defined(PLATFORM_HAS_RVSWD)
static bool cmd_rvswd_scan(target_s *target, int argc, const char **argv);
#endif
static bool cmd_auto_scan(target_s *target, int argc, const char **argv);
static bool cmd_frequency(target_s *target, int argc, const char **argv);
static bool cmd_targets(target_s *target, int argc, const char **argv);
Expand Down Expand Up @@ -94,6 +97,9 @@ const command_s cmd_list[] = {
{"jtag_scan", cmd_jtag_scan, "Scan JTAG chain for devices"},
{"swd_scan", cmd_swd_scan, "Scan SWD interface for devices: [TARGET_ID]"},
{"swdp_scan", cmd_swd_scan, "Deprecated: use swd_scan instead"},
#if defined(ENABLE_RVSWD) && defined(PLATFORM_HAS_RVSWD)
{"rvswd_scan", cmd_rvswd_scan, "Scan RVSWD for devices"},
#endif
{"auto_scan", cmd_auto_scan, "Automatically scan all chain types for devices"},
{"frequency", cmd_frequency, "set minimum high and low times: [FREQ]"},
{"targets", cmd_targets, "Display list of available targets"},
Expand Down Expand Up @@ -316,6 +322,52 @@ bool cmd_swd_scan(target_s *target, int argc, const char **argv)
return true;
}

#if defined(ENABLE_RVSWD) && defined(PLATFORM_HAS_RVSWD)
bool cmd_rvswd_scan(target_s *target, int argc, const char **argv)
{
(void)target;
(void)argc;
(void)argv;

if (platform_target_voltage())
gdb_outf("Target voltage: %s\n", platform_target_voltage());

if (connect_assert_nrst)
platform_nrst_set_val(true); /* will be deasserted after attach */

bool scan_result = false;
TRY (EXCEPTION_ALL) {
#if CONFIG_BMDA == 1
scan_result = bmda_rvswd_scan();
#else
scan_result = false;
#endif
}
CATCH () {
case EXCEPTION_TIMEOUT:
gdb_outf("Timeout during scan. Is target stuck in WFI?\n");
break;
case EXCEPTION_ERROR:
gdb_outf("Exception: %s\n", exception_frame.msg);
break;
default:
break;
}

if (!scan_result) {
platform_target_clk_output_enable(false);
Copy link
Member

Choose a reason for hiding this comment

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

This line and its identical counterpart below can be lifted out together just above the check for the scan result. That reduces repetition.

platform_nrst_set_val(false);
gdb_out("RVSWD scan failed!\n");
return false;
}

cmd_targets(NULL, 0, NULL);
platform_target_clk_output_enable(false);
morse(NULL, false);
return true;
}
#endif

bool cmd_auto_scan(target_s *target, int argc, const char **argv)
{
(void)target;
Expand All @@ -342,8 +394,18 @@ bool cmd_auto_scan(target_s *target, int argc, const char **argv)
#else
scan_result = adiv5_swd_scan(0);
#endif
if (!scan_result)
if (!scan_result) {
gdb_out("SWD scan found no devices.\n");
#if defined(ENABLE_RVSWD) && defined(PLATFORM_HAS_RVSWD)
#if CONFIG_BMDA == 1
scan_result = bmda_rvswd_scan();
#else
scan_result = false;
#endif
if (!scan_result)
gdb_out("RVSWD scan found no devices.\n");
#endif
}
Comment on lines -345 to +408
Copy link
Member

Choose a reason for hiding this comment

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

Given how nested this is getting, perhaps lets invert this logic by extracting the post-scan actions into their own function (this allows all scan routines to stop duplicating those same actions) so we can check if (scan_result) and then return via that post-scan routine?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have some ideas to help with that and make it more future proof too, but for now some minor refactor in that direction wouldn't hurt

}
}
CATCH () {
Expand Down
3 changes: 3 additions & 0 deletions src/include/target.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ typedef struct target_controller target_controller_s;
#if CONFIG_BMDA == 1
bool bmda_swd_scan(uint32_t targetid);
bool bmda_jtag_scan(void);
#if defined(ENABLE_RVSWD) && defined(PLATFORM_HAS_RVSWD)
bool bmda_rvswd_scan(void);
#endif
#endif
bool adiv5_swd_scan(uint32_t targetid);
bool jtag_scan(void);
Expand Down
8 changes: 8 additions & 0 deletions src/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,13 @@ if rtt_support
endif
endif

# RVSWD support handling
rvswd_support = get_option('rvswd_support')
if rtt_support
libbmd_core_args += ['-DENABLE_RVSWD=1']
bmd_core_args += ['-DENABLE_RVSWD=1']
Comment on lines +85 to +86
Copy link
Member

Choose a reason for hiding this comment

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

We suggest making this CONFIG_RVSWD to be consistent with the revamped macro naming style. The if just above needs checking as we think the condition is wrong - think it should be checking rvswd_support, not rtt_support.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You are correct, I noticed after pushing

endif

# Advertise QStartNoAckMode
advertise_noackmode = get_option('advertise_noackmode')
if advertise_noackmode
Expand Down Expand Up @@ -117,6 +124,7 @@ summary(
{
'Debug output': debug_output,
'RTT support': rtt_support,
'RVSWD support': rvswd_support,
'Advertise QStartNoAckMode': advertise_noackmode,
},
bool_yn: true,
Expand Down
3 changes: 2 additions & 1 deletion src/platforms/hosted/bmp_libusb.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ static const debugger_device_s debugger_devices[] = {
{VENDOR_ID_STLINK, PRODUCT_ID_STLINKV3, PROBE_TYPE_STLINK_V2, NULL, "ST-Link v3"},
{VENDOR_ID_STLINK, PRODUCT_ID_STLINKV3E, PROBE_TYPE_STLINK_V2, NULL, "ST-Link v3E"},
{VENDOR_ID_SEGGER, PRODUCT_ID_ANY, PROBE_TYPE_JLINK, NULL, "Segger J-Link"},
{VENDOR_ID_WCH, PRODUCT_ID_WCHLINK_RV, PROBE_TYPE_WCHLINK, NULL, "WCH-Link"},
{VENDOR_ID_FTDI, PRODUCT_ID_FTDI_FT2232, PROBE_TYPE_FTDI, NULL, "FTDI FT2232"},
{VENDOR_ID_FTDI, PRODUCT_ID_FTDI_FT4232, PROBE_TYPE_FTDI, NULL, "FTDI FT4232"},
{VENDOR_ID_FTDI, PRODUCT_ID_FTDI_FT232, PROBE_TYPE_FTDI, NULL, "FTDI FT232"},
Expand Down Expand Up @@ -118,7 +119,7 @@ const debugger_device_s *get_debugger_device_from_vid_pid(const uint16_t probe_v
void bmp_ident(bmda_probe_s *info)
{
DEBUG_INFO("Black Magic Debug App " FIRMWARE_VERSION "\n for Black Magic Probe, ST-Link v2 and v3, CMSIS-DAP, "
"J-Link and FTDI (MPSSE)\n");
"J-Link, FTDI (MPSSE) and WCH-Link\n");
if (info && info->vid && info->pid) {
DEBUG_INFO("Using %04x:%04x %s %s\n %s %s\n", info->vid, info->pid,
(info->serial[0]) ? info->serial : NO_SERIAL_NUMBER, info->manufacturer, info->product, info->version);
Expand Down
3 changes: 3 additions & 0 deletions src/platforms/hosted/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ bmda_sources = files(
'jlink.c',
'jlink_jtag.c',
'jlink_swd.c',
'wchlink.c',
'wchlink_rvswd.c',
'wchlink_riscv_dtm.c',
)
subdir('remote')

Expand Down
24 changes: 24 additions & 0 deletions src/platforms/hosted/platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
#include "stlinkv2.h"
#include "ftdi_bmp.h"
#include "jlink.h"
#include "wchlink.h"
#include "cmsis_dap.h"
#endif

Expand Down Expand Up @@ -163,6 +164,11 @@ void platform_init(int argc, char **argv)
if (!jlink_init())
exit(1);
break;

case PROBE_TYPE_WCHLINK:
if (!wchlink_init())
exit(-1);
break;
#endif

#ifdef ENABLE_GPIOD
Expand Down Expand Up @@ -309,6 +315,21 @@ bool bmda_jtag_init(void)
}
}

bool bmda_rvswd_scan()
{
bmda_probe_info.is_jtag = false;

switch (bmda_probe_info.type) {
#if HOSTED_BMP_ONLY == 0
case PROBE_TYPE_WCHLINK:
return wchlink_rvswd_scan();
#endif

default:
return false;
}
}

void bmda_adiv5_dp_init(adiv5_debug_port_s *const dp)
{
switch (bmda_probe_info.type) {
Expand Down Expand Up @@ -411,6 +432,9 @@ char *bmda_adaptor_ident(void)
case PROBE_TYPE_JLINK:
return "J-Link";

case PROBE_TYPE_WCHLINK:
return "WCH-Link";

case PROBE_TYPE_GPIOD:
return "GPIOD";

Expand Down
7 changes: 7 additions & 0 deletions src/platforms/hosted/platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ void platform_buffer_flush(void);
do { \
} while (0)
#define PLATFORM_HAS_POWER_SWITCH
#define PLATFORM_HAS_RVSWD

#define PRODUCT_ID_ANY 0xffffU

Expand Down Expand Up @@ -77,13 +78,19 @@ void platform_buffer_flush(void);
#define VENDOR_ID_ORBCODE 0x1209U
#define PRODUCT_ID_ORBTRACE 0x3443U

#define VENDOR_ID_WCH 0x1a86U
#define PRODUCT_ID_WCHLINK_RV 0x8010U /* WCH-Link and WCH-LinkE in mode RV */
#define PRODUCT_ID_WCHLINK_DAP 0x8011U /* WCH-Link in mode DAP */
#define PRODUCT_ID_WCHLINKE_DAP 0x8012U /* WCH-LinkE in mode DAP */

typedef enum probe_type {
PROBE_TYPE_NONE = 0,
PROBE_TYPE_BMP,
PROBE_TYPE_STLINK_V2,
PROBE_TYPE_FTDI,
PROBE_TYPE_CMSIS_DAP,
PROBE_TYPE_JLINK,
PROBE_TYPE_WCHLINK,
PROBE_TYPE_GPIOD,
} probe_type_e;

Expand Down
Loading
Loading