# script for Cypress PSoC 41xx/42xx family # # PSoC 4 devices support SWD transports only. # source [find target/swj-dp.tcl] if { [info exists CHIPNAME] } { set _CHIPNAME $CHIPNAME } else { set _CHIPNAME psoc4 } # Work-area is a space in RAM used for flash programming # By default use 4kB if { [info exists WORKAREASIZE] } { set _WORKAREASIZE $WORKAREASIZE } else { set _WORKAREASIZE 0x1000 } if { [info exists CPUTAPID] } { set _CPUTAPID $CPUTAPID } else { set _CPUTAPID 0x0bb11477 } swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID set _TARGETNAME $_CHIPNAME.cpu target create $_TARGETNAME cortex_m -chain-position $_TARGETNAME $_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 set _FLASHNAME $_CHIPNAME.flash flash bank $_FLASHNAME psoc4 0 0 0 0 $_TARGETNAME adapter_khz 1500 # Reset, bloody PSoC 4 reset # # 1) XRES (nSRST) resets also SWD DP so SWD line reset and DP reinit is needed. # High level adapter stops working after SRST and needs OpenOCD restart. # If your hw does not use SRST for other circuits, use sysresetreq instead # # 2) PSoC 4 executes initialization code from system ROM after reset. # This code subsequently jumps to user flash reset vector address. # Unfortunately the system ROM code is protected from reading and debugging. # Protection breaks vector catch VC_CORERESET used for "reset halt" by cortex_m. # # Cypress uses TEST_MODE flag to loop CPU in system ROM before executing code # from user flash. Programming specifications states that TEST_MODE flag must be # set in time frame 400 usec delayed about 1 msec from reset. # # OpenOCD have no standard way how to set TEST_MODE in specified time frame. # TEST_MODE flag is set before reset instead. It worked for tested chips # despite it is not guaranteed by specification. # # 3) SWD cannot be connected during system initialization after reset. # This might be a reason for unconnecting ST-Link v2 when deasserting reset. # As a workaround arp_reset deassert is not called for hla if {![using_hla]} { # if srst is not fitted use SYSRESETREQ to # perform a soft reset cortex_m reset_config sysresetreq } proc ocd_process_reset_inner { MODE } { if { 0 != [string compare psoc4.cpu [target names]] } { return -code error "PSoC 4 reset can handle only one psoc4.cpu target"; } set t psoc4.cpu # If this target must be halted... set halt -1 if { 0 == [string compare $MODE halt] } { set halt 1 } if { 0 == [string compare $MODE init] } { set halt 1; } if { 0 == [string compare $MODE run ] } { set halt 0; } if { $halt < 0 } { return -code error "Invalid mode: $MODE, must be one of: halt, init, or run"; } #$t invoke-event reset-start $t invoke-event reset-assert-pre set TEST_MODE 0x40030014 if { $halt == 1 } { mww $TEST_MODE 0x80000000 } else { mww $TEST_MODE 0 } $t arp_reset assert 0 $t invoke-event reset-assert-post $t invoke-event reset-deassert-pre if {![using_hla]} { # workaround ST-Link v2 fails and forcing reconnect $t arp_reset deassert 0 } $t invoke-event reset-deassert-post # Pass 1 - Now wait for any halt (requested as part of reset # assert/deassert) to happen. Ideally it takes effect without # first executing any instructions. if { $halt } { # Now PSoC CPU should loop in system ROM $t arp_waitstate running 200 $t arp_halt # Catch, but ignore any errors. catch { $t arp_waitstate halted 1000 } # Did we succeed? set s [$t curstate] if { 0 != [string compare $s "halted" ] } { return -code error [format "TARGET: %s - Not halted" $t] } # Check if PSoC CPU is stopped in system ROM set pc [ocd_reg pc] regsub {pc[^:]*: } $pc "" pc if { $pc < 0x10000000 || $pc > 0x1000ffff } { return -code error [format "TARGET: %s - Not halted is system ROM" $t] } # Set registers to reset vector values mem2array value 32 0 2 reg pc [expr $value(1) & 0xfffffffe ] reg msp $value(0) mww $TEST_MODE 0 } #Pass 2 - if needed "init" if { 0 == [string compare init $MODE] } { set err [catch "$t arp_waitstate halted 5000"] # Did it halt? if { $err == 0 } { $t invoke-event reset-init } } $t invoke-event reset-end }