X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=tcl%2Ftarget%2Fpsoc4.cfg;fp=tcl%2Ftarget%2Fpsoc4.cfg;h=2416dbe90c8a954196ed561eb25665cccd15edc1;hp=0000000000000000000000000000000000000000;hb=1d7176f50bc7d5971a82977ac2baa79eef521c21;hpb=a9c90a0f8f9080d185233e4037e9c88075366fcb;ds=sidebyside diff --git a/tcl/target/psoc4.cfg b/tcl/target/psoc4.cfg new file mode 100644 index 0000000000..2416dbe90c --- /dev/null +++ b/tcl/target/psoc4.cfg @@ -0,0 +1,152 @@ +# 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 +}