1 # script for Cypress PSoC 4 devices
4 # PSoC 4 devices support SWD transports only.
6 source [find target/swj-dp.tcl]
8 if { [info exists CHIPNAME] } {
9 set _CHIPNAME $CHIPNAME
14 # Work-area is a space in RAM used for flash programming
16 if { [info exists WORKAREASIZE] } {
17 set _WORKAREASIZE $WORKAREASIZE
19 set _WORKAREASIZE 0x1000
22 if { [info exists CPUTAPID] } {
23 set _CPUTAPID $CPUTAPID
25 set _CPUTAPID 0x0bb11477
28 swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID
30 set _TARGETNAME $_CHIPNAME.cpu
31 target create $_TARGETNAME cortex_m -chain-position $_TARGETNAME
33 $_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0
35 set _FLASHNAME $_CHIPNAME.flash
36 flash bank $_FLASHNAME psoc4 0 0 0 0 $_TARGETNAME
40 # Reset, bloody PSoC 4 reset
42 # 1) XRES (nSRST) resets also SWD DP so SWD line reset and DP reinit is needed.
43 # High level adapter stops working after SRST and needs OpenOCD restart.
44 # If your hw does not use SRST for other circuits, use sysresetreq instead
46 # 2) PSoC 4 executes initialization code from system ROM after reset.
47 # This code subsequently jumps to user flash reset vector address.
48 # Unfortunately the system ROM code is protected from reading and debugging.
49 # Protection breaks vector catch VC_CORERESET used for "reset halt" by cortex_m.
51 # Cypress uses TEST_MODE flag to loop CPU in system ROM before executing code
52 # from user flash. Programming specifications states that TEST_MODE flag must be
53 # set in time frame 400 usec delayed about 1 msec from reset.
55 # OpenOCD have no standard way how to set TEST_MODE in specified time frame.
56 # As a workaround the TEST_MODE flag is set before reset instead.
57 # It worked for the oldest family PSoC4100/4200 even though it is not guaranteed
60 # Newer families like PSoC 4000, 4100M, 4200M, 4100L, 4200L and PSoC 4 BLE
61 # clear TEST_MODE flag during device reset so workaround is not possible.
62 # Use a KitProg adapter for theese devices or "reset halt" will not stop
63 # before executing user code.
65 # 3) SWD cannot be connected during system initialization after reset.
66 # This might be a reason for unconnecting ST-Link v2 when deasserting reset.
67 # As a workaround arp_reset deassert is not called for hla
70 # if srst is not fitted use SYSRESETREQ to
71 # perform a soft reset
72 cortex_m reset_config sysresetreq
75 proc psoc4_get_family_id {} {
76 set err [catch "mem2array romtable_pid 32 0xF0000FE0 3"]
80 if { [expr $romtable_pid(0) & 0xffffff00 ]
81 || [expr $romtable_pid(1) & 0xffffff00 ]
82 || [expr $romtable_pid(2) & 0xffffff00 ] } {
83 echo "Unexpected data in ROMTABLE"
86 set designer_id [expr (( $romtable_pid(1) & 0xf0 ) >> 4) | (( $romtable_pid(2) & 0xf ) << 4 ) ]
87 if { $designer_id != 0xb4 } {
88 echo [format "ROMTABLE Designer ID 0x%02x is not Cypress" $designer_id]
91 set family_id [expr ( $romtable_pid(0) & 0xff ) | (( $romtable_pid(1) & 0xf ) << 8 ) ]
95 proc ocd_process_reset_inner { MODE } {
96 global PSOC4_USE_ACQUIRE PSOC4_TEST_MODE_WORKAROUND
99 if { 0 != [string compare $_TARGETNAME [target names]] } {
100 return -code error "PSoC 4 reset can handle only one $_TARGETNAME target";
104 # If this target must be halted...
106 if { 0 == [string compare $MODE halt] } {
109 if { 0 == [string compare $MODE init] } {
112 if { 0 == [string compare $MODE run ] } {
116 return -code error "Invalid mode: $MODE, must be one of: halt, init, or run";
119 if { ! [info exists PSOC4_USE_ACQUIRE] } {
120 if { 0 == [string compare [adapter_name] kitprog ] } {
121 set PSOC4_USE_ACQUIRE 1
123 set PSOC4_USE_ACQUIRE 0
126 if { $PSOC4_USE_ACQUIRE } {
127 set PSOC4_TEST_MODE_WORKAROUND 0
128 } elseif { ! [info exists PSOC4_TEST_MODE_WORKAROUND] } {
129 if { [psoc4_get_family_id] == 0x93 } {
130 set PSOC4_TEST_MODE_WORKAROUND 1
132 set PSOC4_TEST_MODE_WORKAROUND 0
136 #$t invoke-event reset-start
137 $t invoke-event reset-assert-pre
139 if { $halt && $PSOC4_USE_ACQUIRE } {
140 catch { [adapter_name] acquire_psoc }
143 if { $PSOC4_TEST_MODE_WORKAROUND } {
144 set TEST_MODE 0x40030014
146 catch { mww $TEST_MODE 0x80000000 }
148 catch { mww $TEST_MODE 0 }
152 $t arp_reset assert 0
155 $t invoke-event reset-assert-post
156 $t invoke-event reset-deassert-pre
157 if {![using_hla]} { # workaround ST-Link v2 fails and forcing reconnect
158 $t arp_reset deassert 0
160 $t invoke-event reset-deassert-post
162 # Pass 1 - Now wait for any halt (requested as part of reset
163 # assert/deassert) to happen. Ideally it takes effect without
164 # first executing any instructions.
166 # Now PSoC CPU should loop in system ROM
167 $t arp_waitstate running 200
170 # Catch, but ignore any errors.
171 catch { $t arp_waitstate halted 1000 }
176 if { 0 != [string compare $s "halted" ] } {
177 return -code error [format "TARGET: %s - Not halted" $t]
180 # Check if PSoC CPU is stopped in system ROM
182 regsub {pc[^:]*: } $pc "" pc
183 if { $pc < 0x10000000 || $pc > 0x1000ffff } {
185 set family_id [psoc4_get_family_id]
186 if { $family_id == 0x93 } {
187 set hint ", use 'reset_config none'"
188 } elseif { $family_id > 0x93 } {
189 set hint ", use a KitProg adapter"
191 return -code error [format "TARGET: %s - Not halted in system ROM%s" $t $hint]
194 # Set registers to reset vector values
195 mem2array value 32 0 2
196 reg pc [expr $value(1) & 0xfffffffe ]
199 if { $PSOC4_TEST_MODE_WORKAROUND } {
200 catch { mww $TEST_MODE 0 }
204 #Pass 2 - if needed "init"
205 if { 0 == [string compare init $MODE] } {
206 set err [catch "$t arp_waitstate halted 5000"]
210 $t invoke-event reset-init
214 $t invoke-event reset-end