Skip to content
This repository was archived by the owner on Mar 7, 2026. It is now read-only.

Commit 61d6092

Browse files
committed
at32f43x: Implement read unprotect over SWD transport
1 parent 24e36ec commit 61d6092

1 file changed

Lines changed: 82 additions & 1 deletion

File tree

src/target/at32f43x.c

Lines changed: 82 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,84 @@ static bool at32f43_mass_erase(target_s *const target, platform_timeout_s *const
546546
return true;
547547
}
548548

549+
static bool at32f43x_swd_raw_access_noabort(adiv5_debug_port_s *dp, uint8_t rnw, uint16_t addr, uint32_t value)
550+
{
551+
const uint8_t request = make_packet_request(rnw, addr);
552+
uint32_t response = 0;
553+
uint8_t ack = SWD_ACK_WAIT;
554+
platform_timeout_s timeout_progressbar;
555+
platform_timeout_set(&timeout_progressbar, 500U);
556+
platform_timeout_s timeout_erase;
557+
platform_timeout_set(&timeout_erase, 15000U);
558+
while ((ack == SWD_ACK_WAIT) && !platform_timeout_is_expired(&timeout_erase)) {
559+
swd_proc.seq_out(request, 8U);
560+
ack = swd_proc.seq_in(3U);
561+
/* No data phase */
562+
platform_delay(5U);
563+
target_print_progress(&timeout_progressbar);
564+
}
565+
566+
if (ack != SWD_ACK_OK) {
567+
DEBUG_ERROR("SWD access has invalid ack %x\n", ack);
568+
raise_exception(EXCEPTION_ERROR, "SWD invalid ACK");
569+
}
570+
571+
if (platform_timeout_is_expired(&timeout_erase)) {
572+
DEBUG_ERROR("%s timed out after %u ms\n", __func__, 15000U);
573+
raise_exception(EXCEPTION_TIMEOUT, "SWD WAIT");
574+
}
575+
576+
if (rnw) {
577+
if (!swd_proc.seq_in_parity(&response, 32U)) {
578+
dp->fault = 1U;
579+
DEBUG_ERROR("SWD access resulted in parity error\n");
580+
raise_exception(EXCEPTION_ERROR, "SWD parity error");
581+
}
582+
} else
583+
swd_proc.seq_out_parity(value, 32U);
584+
/* Idle cycles */
585+
swd_proc.seq_out(0, 8U);
586+
return response;
587+
}
588+
589+
static bool at32f43x_mem_write_noabort(target_s *target, target_addr32_t dest, uint16_t val)
590+
{
591+
const uint32_t src_bytes = val;
592+
const void *src = &src_bytes;
593+
const align_e align = ALIGN_16BIT;
594+
adiv5_access_port_s *ap = cortex_ap(target);
595+
596+
//adi_ap_mem_access_setup(ap, dest, align);
597+
uint32_t csw = ap->csw | ADIV5_AP_CSW_ADDRINC_SINGLE | ADIV5_AP_CSW_SIZE_HALFWORD;
598+
adiv5_ap_write(ap, ADIV5_AP_CSW, csw);
599+
adiv5_dp_write(ap->dp, ADIV5_AP_TAR_LOW, (uint32_t)dest);
600+
601+
uint32_t value = 0;
602+
adiv5_pack_data(dest, src, &value, align);
603+
/* Submit the memory write */
604+
adiv5_dp_write(ap->dp, ADIV5_AP_DRW, value);
605+
606+
/* Poll for completion (RDBUFF will be responding with WAITs) */
607+
volatile uint32_t rdbuff = 0;
608+
TRY (EXCEPTION_ALL) {
609+
//ack = ap->dp->low_access(dp, rnw, addr, value)
610+
rdbuff = at32f43x_swd_raw_access_noabort(ap->dp, ADIV5_LOW_READ, ADIV5_DP_RDBUFF, 0);
611+
}
612+
CATCH () {
613+
case EXCEPTION_TIMEOUT:
614+
DEBUG_TARGET("Timeout during scan. Is target stuck in WFI?\n");
615+
break;
616+
case EXCEPTION_ERROR:
617+
DEBUG_TARGET("Exception: %s\n", exception_frame.msg);
618+
break;
619+
default:
620+
return false;
621+
}
622+
(void)rdbuff;
623+
624+
return true;
625+
}
626+
549627
static bool at32f43_option_erase(target_s *const target)
550628
{
551629
/* bank_reg_offset is 0, option bytes belong to first bank */
@@ -675,8 +753,11 @@ static bool at32f43_cmd_option(target_s *const target, const int argc, const cha
675753
* FIXME: this transaction only completes after typ. 15 seconds (mass erase of both banks of 4032 KiB chip)
676754
* and if BMD ABORTs it after 250 ms, then chip considers erase as incomplete and stays read-protected.
677755
*/
678-
if (!at32f43_option_write_erased(target, 0U, AT32F43x_USD_RDP_KEY))
756+
at32f43_flash_clear_eop(target, 0);
757+
target_mem32_write32(target, AT32F43x_FLASH_CTRL, AT32F43x_FLASH_CTRL_USDPRGM | AT32F43x_FLASH_CTRL_USDULKS);
758+
if (!at32f43x_mem_write_noabort(target, AT32F43x_USD_BASE, AT32F43x_USD_RDP_KEY))
679759
return false;
760+
680761
/* Set EOPB0 to default 0b010 for 384 KB SRAM */
681762
if (!at32f43_option_write_erased(target, 8U, AT32F43x_USD_EOPB0_DEFAULT))
682763
return false;

0 commit comments

Comments
 (0)