jtag/drivers: Add support for CH347-based JTAG adapters

This adds general support for JTAG adapters based on the WCH CH347T and
CH347F chips.

The CH347T must be configured in mode 3 to provide both UART and JTAG
interfaces. The CH347F exposes UART and JTAG directly. Similar to FTDI
FT2232-based devices, the CH347T/F can be used for simultaneous UART and
JTAG communication.

The ch347 driver code is based on:
  https://github.com/WCHSoftGroup/ch347

Bug fixes and adjustments were made to align the code with OpenOCD style
and ensure compatibility. The driver was integrated into the OpenOCD
build system.

The USB packet format was identified using public GitHub sources and
documented here:
  https://www.easydevkits.com/wch-ch347-jtag-interface/

Change-Id: I5fca9dd015111e4410fea029611fdeedbb228fdb
Signed-off-by: EasyDevKits <info@easydevkits.com>
Reviewed-on: https://review.openocd.org/c/openocd/+/7937
Tested-by: jenkins
Reviewed-by: ZhiYuanNJ <871238103@qq.com>
Reviewed-by: Tomas Vanek <vanekt@fbl.cz>
This commit is contained in:
EasyDevKits
2023-10-14 16:28:59 +02:00
committed by Tomas Vanek
parent 68b6d3ad47
commit 7d0e125896
8 changed files with 2424 additions and 1 deletions

View File

@@ -129,6 +129,7 @@ m4_define([ADAPTER_OPT], [m4_translit(ADAPTER_ARG($1), [_], [-])])
m4_define([USB1_ADAPTERS],
[[[ftdi], [MPSSE mode of FTDI based devices], [FTDI]],
[[ch347], [Mode 3 of CH347 based devices], [CH347]],
[[stlink], [ST-Link Programmer], [HLADAPTER_STLINK]],
[[ti_icdi], [TI ICDI JTAG Programmer], [HLADAPTER_ICDI]],
[[ulink], [Keil ULINK JTAG Programmer], [ULINK]],
@@ -724,6 +725,7 @@ AM_CONDITIONAL([INTERNAL_JIMTCL], [test "x$use_internal_jimtcl" = "xyes"])
AM_CONDITIONAL([HAVE_JIMTCL_PKG_CONFIG], [test "x$have_jimtcl_pkg_config" = "xyes"])
AM_CONDITIONAL([INTERNAL_LIBJAYLINK], [test "x$use_internal_libjaylink" = "xyes"])
AM_CONDITIONAL([USE_GCOV], [test "x$enable_gcov" = "xyes"])
# Look for environ alternatives. Possibility #1: is environ in unistd.h or stdlib.h?

View File

@@ -220,6 +220,11 @@ ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="06ad", MODE="660", GROUP="plugdev",
# USBprog with OpenOCD firmware
ATTRS{idVendor}=="1781", ATTRS{idProduct}=="0c63", MODE="660", GROUP="plugdev", TAG+="uaccess"
# WCH CH347T chip in mode 3
ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="55dd", MODE="660", GROUP="plugdev", TAG+="uaccess"
# WCH CH347F chip
ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="55de", MODE="660", GROUP="plugdev", TAG+="uaccess"
# TI/Luminary Stellaris In-Circuit Debug Interface (ICDI) Board
ATTRS{idVendor}=="1cbe", ATTRS{idProduct}=="00fd", MODE="660", GROUP="plugdev", TAG+="uaccess"

View File

@@ -633,6 +633,10 @@ This is deprecated from Linux v5.3; prefer using @b{linuxgpiod}.
@item @b{esp_usb_jtag}
@* A JTAG driver to communicate with builtin debug modules of Espressif ESP32-C3 and ESP32-S3 chips using OpenOCD.
@item @b{ch347}
@* A JTAG driver that works with the WCH CH347F and CH347T chips.
When using the CH347T, it must be configured to operate in mode 3 (UART + JTAG).
@end itemize
@node About Jim Tcl
@@ -2554,6 +2558,41 @@ and a specific set of GPIOs is used.
@c chooses among list of bit configs ... only one option
@end deffn
@deffn {Interface Driver} {ch347}
Driver for WCH CH347F and CH347T chips.
When using the CH347T, it must be configured to operate in mode 3 (UART + JTAG).
This driver has these driver-specific command:
@deffn {Config Command} {ch347 vid_pid} [vid pid]+
The vendor ID and product ID of the CH347F or CH347T device in mode 3. If not specified
the driver will use vendor ID 0x1a86 and product ID 0x55dd.
Currently, up to four [@var{vid}, @var{pid}] pairs may be given, e.g.
@example
ch347 vid_pid 0x1a86 0x55dd 0x1a86 0x55de
@end example
@end deffn
@deffn {Config Command} {ch347 device_desc} description
If specified connect to a device which exactly has this product description
string. If not specified the first found device with the correct vendor
and product ID will be connected.
@example
ch347 device_desc "EasyDevKit"
@end example
@end deffn
@deffn {Config Command} {ch347 activity_led} [n]gpio_number
If specified the drive let an activity LED blink during JTAG operations.
The number is the GPIO number of the CH347T chip. If prefixed with "n",
then this GPIO should be low active. The example configures GPIO4 as
low active activity LED. For the CH347T chip only GPIO3 (Pin11 / SCL),
GPIO4 (Pin15 / ACT), GPIO5 (Pin9 / TRST) and GPIO6 (Pin2 / CTS1) are possible.
@example
ch347 activity_led n4
@end example
@end deffn
@end deffn
@deffn {Interface Driver} {cmsis-dap}
ARM CMSIS-DAP compliant based adapter v1 (USB HID based)
or v2 (USB bulk).

View File

@@ -0,0 +1,146 @@
# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later
# Link: https://www.easydevkits.com
# PCB: ESP32-WROVER-E WCH JTAG DevKit v0.1
# Chip: CH347T in mode 3 (UART+JTAG mode)
# Product id of 0x55dd is only valid if the chip is started in mode 3
# These are the other product ids: mode 0 = 0x55da, mode 1 = 0x55db, mode 2 = 0x55dc
# The similar chip CH347F has no modes and always product id 0x55de
Bus 001 Device 013: ID 1a86:55dd QinHeng Electronics EasyDevKit
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 0
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor 0x1a86 QinHeng Electronics
idProduct 0x55dd
bcdDevice 4.41
iManufacturer 1 EasyDevKits
iProduct 2 EasyDevKit
iSerial 3 ACBACJGAAB
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 0x0062
bNumInterfaces 3
bConfigurationValue 1
iConfiguration 0
bmAttributes 0x80
(Bus Powered)
MaxPower 500mA
Interface Association:
bLength 8
bDescriptorType 11
bFirstInterface 0
bInterfaceCount 2
bFunctionClass 2 Communications
bFunctionSubClass 2 Abstract (modem)
bFunctionProtocol 1 AT-commands (v.25ter)
iFunction 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 2 Communications
bInterfaceSubClass 2 Abstract (modem)
bInterfaceProtocol 1 AT-commands (v.25ter)
iInterface 0
CDC Header:
bcdCDC 1.10
CDC Call Management:
bmCapabilities 0x00
bDataInterface 1
CDC ACM:
bmCapabilities 0x02
line coding and serial state
CDC Union:
bMasterInterface 0
bSlaveInterface 1
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x83 EP 3 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 1
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 10 CDC Data
bInterfaceSubClass 0
bInterfaceProtocol 0
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x04 EP 4 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x84 EP 4 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 2
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 0
bInterfaceProtocol 0
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x06 EP 6 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x86 EP 6 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Device Qualifier (for other device speed):
bLength 10
bDescriptorType 6
bcdUSB 2.00
bDeviceClass 255 Vendor Specific Class
bDeviceSubClass 0
bDeviceProtocol 255
bMaxPacketSize0 64
bNumConfigurations 1
Device Status: 0x0000
(Bus Powered)

View File

@@ -208,6 +208,9 @@ endif
if AM335XGPIO
DRIVERFILES += %D%/am335xgpio.c
endif
if CH347
DRIVERFILES += %D%/ch347.c
endif
DRIVERHEADERS = \
%D%/bitbang.h \

2225
src/jtag/drivers/ch347.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -379,6 +379,7 @@ extern struct adapter_driver armjtagew_adapter_driver;
extern struct adapter_driver at91rm9200_adapter_driver;
extern struct adapter_driver bcm2835gpio_adapter_driver;
extern struct adapter_driver buspirate_adapter_driver;
extern struct adapter_driver ch347_adapter_driver;
extern struct adapter_driver cmsis_dap_adapter_driver;
extern struct adapter_driver dmem_dap_adapter_driver;
extern struct adapter_driver dummy_adapter_driver;

View File

@@ -159,6 +159,8 @@ struct adapter_driver *adapter_drivers[] = {
&xlnx_pcie_xvc_adapter_driver,
&xlnx_axi_xvc_adapter_driver,
#endif
#if BUILD_CH347 == 1
&ch347_adapter_driver,
#endif
NULL,
};