Skip to content

Commit 4cb8013

Browse files
committed
at32f43x: Implement read unprotect over SWD transport
1 parent 00e2311 commit 4cb8013

File tree

1 file changed

+82
-1
lines changed

1 file changed

+82
-1
lines changed

src/target/at32f43x.c

Lines changed: 82 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -551,6 +551,84 @@ static bool at32f43_mass_erase(target_s *target)
551551
return true;
552552
}
553553

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

0 commit comments

Comments
 (0)