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