This is an automated email from Gerrit. "Tomas Vanek <van...@fbl.cz>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/8743
-- gerrit commit a1d1ea0446248672ee0237892ca593528397fa46 Author: Tomas Vanek <van...@fbl.cz> 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. Signed-off-by: Tomas Vanek <van...@fbl.cz> Change-Id: I5a990a43dcd7a6d73c71b795283a9fbdff489bf4 diff --git a/src/jtag/drivers/ch347.c b/src/jtag/drivers/ch347.c index e7d59f3206..23fd13f225 100644 --- a/src/jtag/drivers/ch347.c +++ b/src/jtag/drivers/ch347.c @@ -1585,16 +1585,41 @@ static int ch347_adapter_set_speed(uint8_t clock_index) return ch347_adapter_init(clock_index, &unused); } +/** + * @brief swd init function + * + * @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 result %02" PRIx8, 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) { @@ -1638,6 +1663,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 = (1000 + speed_idx / 2) / speed_idx; + else + *khz = 100; + return ERROR_OK; + } + int retval = ch347_init_pack_size(); if (retval != ERROR_OK) return retval; @@ -1662,6 +1695,11 @@ static int ch347_speed_get_index(int khz, int *speed_idx) return ERROR_FAIL; } + if (swd_mode) { + *speed_idx = MIN(DIV_ROUND_UP(1000, khz), 20); + 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) @@ -1792,29 +1830,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 * @@ -1849,7 +1864,7 @@ static int ch347_init(void) if (retval != ERROR_OK) return retval; - retval = ch347_swd_init_cmd(); + retval = ch347_swd_init_cmd(0); } return retval; --