|
From: openocd-gerrit <ope...@us...> - 2025-08-24 05:03:49
|
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Main OpenOCD repository".
The branch, master has been updated
via 87f78286794f6d8fbf885715b01b685f98885d9d (commit)
via c7aaaac809ebb71b20dee4bacad22a56533e85f5 (commit)
from 99cb670becdb1e00fc75997383325550b02accdd (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 87f78286794f6d8fbf885715b01b685f98885d9d
Author: Tomas Vanek <va...@fb...>
Date: Sun Nov 5 06:49:18 2023 +0100
drivers/ch347: add SWD speed settings
SWD has completely different speed setting than JTAG.
There is no official chip documentation. The trial and error
method on SWD init USB packet discovered a byte parameter used
as a divisor from 1 MHz maximal clock.
Prevent setting too low clocks as it may trigger USB disconnects.
CH347T/F versions 5.44/1.1 add 5 MHz SWD speed at divisor/index 0.
CH347F related parts co-authored by ZhiYuanNJ <871...@qq...>
Signed-off-by: Tomas Vanek <va...@fb...>
Change-Id: I5a990a43dcd7a6d73c71b795283a9fbdff489bf4
Reviewed-on: https://review.openocd.org/c/openocd/+/8743
Reviewed-by: ZhiYuanNJ <871...@qq...>
Tested-by: jenkins
diff --git a/src/jtag/drivers/ch347.c b/src/jtag/drivers/ch347.c
index f4f013a79..ecec155f7 100644
--- a/src/jtag/drivers/ch347.c
+++ b/src/jtag/drivers/ch347.c
@@ -119,6 +119,9 @@
#define CH347_MAX_SEND_BUF 0X200
#define CH347_MAX_RECV_BUF 0X200
#define CH347_MAX_CMD_BUF 128
+#define CH347_SWD_CLOCK_MAX 5000
+#define CH347_SWD_CLOCK_BASE 1000
+#define CH347_SWD_CLOCK_MAX_DIVISOR 8
#define CH347_EPOUT 0x06u // the usb endpoint number for writing
#define CH347_EPIN 0x86u // the usb endpoint number for reading
@@ -205,6 +208,7 @@ struct ch347_info {
bool use_bitwise_mode;
enum pack_size pack_size; // see: pack_size for explanation
int max_len; // in STANDARD_PACK or bitwise mode we can send only one USBC_PACKET_USBHS sized package
+ bool swclk_5mhz_supported;
// a "scratchpad" where we record all bytes for one command
uint8_t scratchpad_cmd_type; // command type
@@ -1506,6 +1510,8 @@ static int ch347_open_device(void)
if (ch347.chip_variant == CH347T) {
if (swd_mode) {
+ ch347.swclk_5mhz_supported = ch347_device_descriptor.bcdDevice >= 0x544;
+
if (ch347_device_descriptor.bcdDevice < 0x441)
LOG_WARNING("CH347T version older than 4.41 probably does not support SWD transport");
@@ -1520,6 +1526,8 @@ static int ch347_open_device(void)
LOG_INFO("Please upgrade CH347T firmware to a production version >= 5.44");
} else if (ch347.chip_variant == CH347F) {
+ ch347.swclk_5mhz_supported = ch347_device_descriptor.bcdDevice >= 0x101;
+
if (ch347_device_descriptor.bcdDevice < 0x101)
LOG_INFO("Please upgrade CH347F firmware to a production version >= 1.1");
}
@@ -1608,16 +1616,44 @@ static int ch347_adapter_set_speed(uint8_t clock_index)
return ch347_adapter_init(clock_index, &unused);
}
+/**
+ * @brief swd init function
+ * @param clock_divisor Divisor of base SWD frequency 1 MHz or 0 for fast 5 MHz clock
+ *
+ * @return ERROR_OK on success
+ */
+static int ch347_swd_init_cmd(uint8_t clock_divisor)
+{
+ int retval = ch347_cmd_start_next(CH347_CMD_SWD_INIT);
+ if (retval != ERROR_OK)
+ return retval;
+
+ uint8_t cmd_data[] = {0x40, 0x42, 0x0f, 0x00, clock_divisor, 0x00, 0x00, 0x00 };
+ retval = ch347_scratchpad_add_bytes(cmd_data, ARRAY_SIZE(cmd_data));
+ if (retval != ERROR_OK)
+ return retval;
+
+ /* TODO: CH347_CMD_SWD_INIT reads one data byte.
+ But how can we decide if SWD init was successfully executed?
+ Return an error code if init was failed */
+ uint8_t init_result = 0;
+ retval = ch347_single_read_get_byte(0, &init_result);
+ LOG_DEBUG("SWD init clk div %" PRIu8 ", result %02" PRIx8,
+ clock_divisor, init_result);
+ return retval;
+}
+
/**
* @brief Initializes the JTAG interface and set CH347 TCK frequency
*
* @param speed_index speed index for JTAG_INIT command
- * @return Success returns ERROR_OKï¼failed returns ERROR_FAIL
+ * @return Success returns ERROR_OK, failed returns ERROR_FAIL
*/
static int ch347_speed_set(int speed_index)
{
if (swd_mode)
- return ERROR_OK;
+ return ch347_swd_init_cmd(speed_index);
+
int retval = ch347_adapter_set_speed(speed_index);
if (retval != ERROR_OK) {
LOG_ERROR("Couldn't set CH347 speed");
@@ -1660,6 +1696,14 @@ static int ch347_init_pack_size(void)
*/
static int ch347_speed_get(int speed_idx, int *khz)
{
+ if (swd_mode) {
+ if (speed_idx)
+ *khz = DIV_ROUND_UP(CH347_SWD_CLOCK_BASE, speed_idx);
+ else
+ *khz = CH347_SWD_CLOCK_MAX;
+ return ERROR_OK;
+ }
+
int retval = ch347_init_pack_size();
if (retval != ERROR_OK)
return retval;
@@ -1682,6 +1726,19 @@ static int ch347_speed_get_index(int khz, int *speed_idx)
LOG_ERROR("Adaptive clocking not supported");
return ERROR_FAIL;
}
+
+ if (swd_mode) {
+ if (khz >= CH347_SWD_CLOCK_MAX && ch347.swclk_5mhz_supported) {
+ *speed_idx = 0;
+ } else {
+ // Don't allow too low clk speeds: packet processing is limited to ~8 msec
+ // or triggers host USB disconnect
+ *speed_idx = MIN(DIV_ROUND_UP(CH347_SWD_CLOCK_BASE, khz),
+ CH347_SWD_CLOCK_MAX_DIVISOR);
+ }
+ return ERROR_OK;
+ }
+
// when checking with speed index 9 we can see if the device supports STANDARD_PACK or LARGER_PACK mode
int retval = ch347_init_pack_size();
if (retval != ERROR_OK)
@@ -1809,27 +1866,6 @@ static const struct command_registration ch347_command_handlers[] = {
COMMAND_REGISTRATION_DONE
};
-/**
- * @brief swd init function
- *
- * @return ERROR_OK on success
- */
-static int ch347_swd_init_cmd(void)
-{
- int retval = ch347_cmd_start_next(CH347_CMD_SWD_INIT);
- if (retval != ERROR_OK)
- return retval;
- uint8_t cmd_data[] = {0x40, 0x42, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00 };
- retval = ch347_scratchpad_add_bytes(cmd_data, ARRAY_SIZE(cmd_data));
- if (retval != ERROR_OK)
- return retval;
- /* TODO: CH347_CMD_SWD_INIT reads one data byte.
- But how can we decide if SWD init was successfully executed?
- Return an error code if init was failed */
- uint8_t unused;
- return ch347_single_read_get_byte(0, &unused);
-}
-
/**
* @brief CH347 Initialization function
*
@@ -1862,7 +1898,8 @@ static int ch347_init(void)
retval = ch347_init_pack_size();
if (retval != ERROR_OK)
return retval;
- retval = ch347_swd_init_cmd();
+
+ retval = ch347_swd_init_cmd(1);
}
return retval;
}
commit c7aaaac809ebb71b20dee4bacad22a56533e85f5
Author: Tomas Vanek <va...@fb...>
Date: Sun Nov 5 06:42:25 2023 +0100
drivers/ch347: detailed packet logging
Split USB data packet logs by CH347 protocol commands
Signed-off-by: Tomas Vanek <va...@fb...>
Change-Id: I0f61529755f007ab13f42643676199790c5be2d4
Reviewed-on: https://review.openocd.org/c/openocd/+/8742
Reviewed-by: ZhiYuanNJ <871...@qq...>
Tested-by: jenkins
diff --git a/src/jtag/drivers/ch347.c b/src/jtag/drivers/ch347.c
index 8c9c784cd..f4f013a79 100644
--- a/src/jtag/drivers/ch347.c
+++ b/src/jtag/drivers/ch347.c
@@ -261,6 +261,102 @@ static inline bool ch347_is_single_cmd_type(uint8_t type)
return type == CH347_CMD_GPIO || type == CH347_CMD_JTAG_INIT || type == CH347_CMD_SWD_INIT;
}
+static void log_buf_dump(const uint8_t *data, unsigned int size, bool recv)
+{
+ unsigned int i = 0, j = 0;
+ unsigned int n = size * 3 + 1;
+ char *str = malloc(n);
+ if (!str)
+ return;
+
+ while (i < size && j < n) {
+ uint8_t cmd = data[i++];
+ hexify(str + j, &cmd, 1, n - j);
+ j += 2;
+ str[j++] = ' ';
+
+ unsigned int cmd_payload_size = le_to_h_u16(data + i);
+ if (i + 2 <= size && j + 4 < n) {
+ hexify(str + j, data + i, 2, n - j);
+ i += 2;
+ j += 4;
+ str[j++] = ' ';
+ }
+
+ if (cmd == CH347_CMD_SWD) {
+ // nested SWD commands
+ str[j] = '\0';
+ if (i + cmd_payload_size > size) {
+ LOG_DEBUG_IO("%s - bad size", str);
+ cmd_payload_size = size - i;
+ } else {
+ LOG_DEBUG_IO("%s", str);
+ }
+ j = 0;
+ unsigned int swd_base_i = i;
+
+ while (i < swd_base_i + cmd_payload_size) {
+ uint8_t swd_cmd = data[i++];
+ hexify(str + j, &swd_cmd, 1, n - j);
+ j += 2;
+ str[j++] = ' ';
+
+ unsigned int swd_bits = 0;
+ unsigned int swd_payload_size = 0;
+ if (!recv) {
+ if (i + 2 <= size) {
+ swd_bits = le_to_h_u16(data + i);
+ hexify(str + j, data + i, 2, n - j);
+ i += 2;
+ j += 4;
+ str[j++] = ' ';
+ }
+ }
+
+ switch (swd_cmd) {
+ case CH347_CMD_SWD_REG_W:
+ if (recv)
+ swd_payload_size = 1;
+ else
+ swd_payload_size = DIV_ROUND_UP(swd_bits, 8);
+ break;
+ case CH347_CMD_SWD_SEQ_W:
+ if (!recv)
+ swd_payload_size = DIV_ROUND_UP(swd_bits, 8);
+ break;
+ case CH347_CMD_SWD_REG_R:
+ if (recv)
+ swd_payload_size = 1 + 4 + 1;
+ else
+ swd_payload_size = 1;
+ break;
+ }
+
+ hexify(str + j, data + i, MIN(swd_payload_size, size - i), n - j);
+ i += swd_payload_size;
+ j += 2 * swd_payload_size;
+ str[j] = '\0';
+ if (i > size)
+ LOG_DEBUG_IO(" %s - bad size", str);
+ else
+ LOG_DEBUG_IO(" %s", str);
+ j = 0;
+ }
+ } else {
+ hexify(str + j, data + i, MIN(cmd_payload_size, size - i), n - j);
+ i += cmd_payload_size;
+ j += 2 * cmd_payload_size;
+ str[j] = '\0';
+ if (i > size)
+ LOG_DEBUG_IO("%s - bad size", str);
+ else
+ LOG_DEBUG_IO("%s", str);
+ j = 0;
+ }
+ }
+ free(str);
+}
+
/**
* @brief writes data to the CH347 via libusb driver
*
@@ -289,9 +385,8 @@ static int ch347_write_data(uint8_t *data, int *length)
}
if (LOG_LEVEL_IS(LOG_LVL_DEBUG_IO)) {
- char *str = buf_to_hex_str(data, i * 8);
- LOG_DEBUG_IO("size=%d, buf=[%s]", i, str);
- free(str);
+ LOG_DEBUG_IO("size=%d, buf=", i);
+ log_buf_dump(data, i, false);
}
*length = i;
@@ -327,9 +422,8 @@ static int ch347_read_data(uint8_t *data, int *length)
}
if (LOG_LEVEL_IS(LOG_LVL_DEBUG_IO)) {
- char *str = buf_to_hex_str(data, i * 8);
- LOG_DEBUG_IO("size=%d, buf=[%s]", i, str);
- free(str);
+ LOG_DEBUG_IO("size=%d, buf=", i);
+ log_buf_dump(data, i, true);
}
*length = i;
-----------------------------------------------------------------------
Summary of changes:
src/jtag/drivers/ch347.c | 191 +++++++++++++++++++++++++++++++++++++++--------
1 file changed, 161 insertions(+), 30 deletions(-)
hooks/post-receive
--
Main OpenOCD repository
|