@@ -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+
554632static 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