| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216 |
- # script for Cypress PSoC 4 devices
- #
- # 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
- dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu
- set _TARGETNAME $_CHIPNAME.cpu
- target create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap
- $_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 speed 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.
- # As a workaround the TEST_MODE flag is set before reset instead.
- # It worked for the oldest family PSoC4100/4200 even though it is not guaranteed
- # by specification.
- #
- # Newer families like PSoC 4000, 4100M, 4200M, 4100L, 4200L and PSoC 4 BLE
- # clear TEST_MODE flag during device reset so workaround is not possible.
- # Use a KitProg adapter for these devices or "reset halt" will not stop
- # before executing user code.
- #
- # 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 psoc4_get_family_id {} {
- set err [catch "mem2array romtable_pid 32 0xF0000FE0 3"]
- if { $err } {
- return 0
- }
- if { [expr {$romtable_pid(0) & 0xffffff00 }]
- || [expr {$romtable_pid(1) & 0xffffff00 }]
- || [expr {$romtable_pid(2) & 0xffffff00 }] } {
- echo "Unexpected data in ROMTABLE"
- return 0
- }
- set designer_id [expr {(( $romtable_pid(1) & 0xf0 ) >> 4) | (( $romtable_pid(2) & 0xf ) << 4 ) }]
- if { $designer_id != 0xb4 } {
- echo [format "ROMTABLE Designer ID 0x%02x is not Cypress" $designer_id]
- return 0
- }
- set family_id [expr {( $romtable_pid(0) & 0xff ) | (( $romtable_pid(1) & 0xf ) << 8 ) }]
- return $family_id
- }
- proc ocd_process_reset_inner { MODE } {
- global PSOC4_USE_ACQUIRE PSOC4_TEST_MODE_WORKAROUND
- global _TARGETNAME
- if { 0 != [string compare $_TARGETNAME [target names]] } {
- return -code error "PSoC 4 reset can handle only one $_TARGETNAME target";
- }
- set t $_TARGETNAME
- # 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";
- }
- if { ! [info exists PSOC4_USE_ACQUIRE] } {
- if { 0 == [string compare [adapter name] kitprog ] } {
- set PSOC4_USE_ACQUIRE 1
- } else {
- set PSOC4_USE_ACQUIRE 0
- }
- }
- if { $PSOC4_USE_ACQUIRE } {
- set PSOC4_TEST_MODE_WORKAROUND 0
- } elseif { ! [info exists PSOC4_TEST_MODE_WORKAROUND] } {
- if { [psoc4_get_family_id] == 0x93 } {
- set PSOC4_TEST_MODE_WORKAROUND 1
- } else {
- set PSOC4_TEST_MODE_WORKAROUND 0
- }
- }
- #$t invoke-event reset-start
- $t invoke-event reset-assert-pre
- if { $halt && $PSOC4_USE_ACQUIRE } {
- catch { [adapter name] acquire_psoc }
- $t arp_examine
- } else {
- if { $PSOC4_TEST_MODE_WORKAROUND } {
- set TEST_MODE 0x40030014
- if { $halt == 1 } {
- catch { mww $TEST_MODE 0x80000000 }
- } else {
- catch { 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 [reg pc]
- regsub {pc[^:]*: } $pc "" pc
- if { $pc < 0x10000000 || $pc > 0x1000ffff } {
- set hint ""
- set family_id [psoc4_get_family_id]
- if { $family_id == 0x93 } {
- set hint ", use 'reset_config none'"
- } elseif { $family_id > 0x93 } {
- set hint ", use a KitProg adapter"
- }
- return -code error [format "TARGET: %s - Not halted in system ROM%s" $t $hint]
- }
- # Set registers to reset vector values
- mem2array value 32 0 2
- reg pc [expr {$value(1) & 0xfffffffe} ]
- reg msp $value(0)
- if { $PSOC4_TEST_MODE_WORKAROUND } {
- catch { 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
- }
|