psoc4.cfg 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. # script for Cypress PSoC 4 devices
  2. #
  3. # PSoC 4 devices support SWD transports only.
  4. #
  5. source [find target/swj-dp.tcl]
  6. if { [info exists CHIPNAME] } {
  7. set _CHIPNAME $CHIPNAME
  8. } else {
  9. set _CHIPNAME psoc4
  10. }
  11. # Work-area is a space in RAM used for flash programming
  12. # By default use 4kB
  13. if { [info exists WORKAREASIZE] } {
  14. set _WORKAREASIZE $WORKAREASIZE
  15. } else {
  16. set _WORKAREASIZE 0x1000
  17. }
  18. if { [info exists CPUTAPID] } {
  19. set _CPUTAPID $CPUTAPID
  20. } else {
  21. set _CPUTAPID 0x0bb11477
  22. }
  23. swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID
  24. dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu
  25. set _TARGETNAME $_CHIPNAME.cpu
  26. target create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap
  27. $_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0
  28. set _FLASHNAME $_CHIPNAME.flash
  29. flash bank $_FLASHNAME psoc4 0 0 0 0 $_TARGETNAME
  30. adapter speed 1500
  31. # Reset, bloody PSoC 4 reset
  32. #
  33. # 1) XRES (nSRST) resets also SWD DP so SWD line reset and DP reinit is needed.
  34. # High level adapter stops working after SRST and needs OpenOCD restart.
  35. # If your hw does not use SRST for other circuits, use sysresetreq instead
  36. #
  37. # 2) PSoC 4 executes initialization code from system ROM after reset.
  38. # This code subsequently jumps to user flash reset vector address.
  39. # Unfortunately the system ROM code is protected from reading and debugging.
  40. # Protection breaks vector catch VC_CORERESET used for "reset halt" by cortex_m.
  41. #
  42. # Cypress uses TEST_MODE flag to loop CPU in system ROM before executing code
  43. # from user flash. Programming specifications states that TEST_MODE flag must be
  44. # set in time frame 400 usec delayed about 1 msec from reset.
  45. #
  46. # OpenOCD have no standard way how to set TEST_MODE in specified time frame.
  47. # As a workaround the TEST_MODE flag is set before reset instead.
  48. # It worked for the oldest family PSoC4100/4200 even though it is not guaranteed
  49. # by specification.
  50. #
  51. # Newer families like PSoC 4000, 4100M, 4200M, 4100L, 4200L and PSoC 4 BLE
  52. # clear TEST_MODE flag during device reset so workaround is not possible.
  53. # Use a KitProg adapter for these devices or "reset halt" will not stop
  54. # before executing user code.
  55. #
  56. # 3) SWD cannot be connected during system initialization after reset.
  57. # This might be a reason for unconnecting ST-Link v2 when deasserting reset.
  58. # As a workaround arp_reset deassert is not called for hla
  59. if {![using_hla]} {
  60. # if srst is not fitted use SYSRESETREQ to
  61. # perform a soft reset
  62. cortex_m reset_config sysresetreq
  63. }
  64. proc psoc4_get_family_id {} {
  65. set err [catch "mem2array romtable_pid 32 0xF0000FE0 3"]
  66. if { $err } {
  67. return 0
  68. }
  69. if { [expr {$romtable_pid(0) & 0xffffff00 }]
  70. || [expr {$romtable_pid(1) & 0xffffff00 }]
  71. || [expr {$romtable_pid(2) & 0xffffff00 }] } {
  72. echo "Unexpected data in ROMTABLE"
  73. return 0
  74. }
  75. set designer_id [expr {(( $romtable_pid(1) & 0xf0 ) >> 4) | (( $romtable_pid(2) & 0xf ) << 4 ) }]
  76. if { $designer_id != 0xb4 } {
  77. echo [format "ROMTABLE Designer ID 0x%02x is not Cypress" $designer_id]
  78. return 0
  79. }
  80. set family_id [expr {( $romtable_pid(0) & 0xff ) | (( $romtable_pid(1) & 0xf ) << 8 ) }]
  81. return $family_id
  82. }
  83. proc ocd_process_reset_inner { MODE } {
  84. global PSOC4_USE_ACQUIRE PSOC4_TEST_MODE_WORKAROUND
  85. global _TARGETNAME
  86. if { 0 != [string compare $_TARGETNAME [target names]] } {
  87. return -code error "PSoC 4 reset can handle only one $_TARGETNAME target";
  88. }
  89. set t $_TARGETNAME
  90. # If this target must be halted...
  91. set halt -1
  92. if { 0 == [string compare $MODE halt] } {
  93. set halt 1
  94. }
  95. if { 0 == [string compare $MODE init] } {
  96. set halt 1;
  97. }
  98. if { 0 == [string compare $MODE run ] } {
  99. set halt 0;
  100. }
  101. if { $halt < 0 } {
  102. return -code error "Invalid mode: $MODE, must be one of: halt, init, or run";
  103. }
  104. if { ! [info exists PSOC4_USE_ACQUIRE] } {
  105. if { 0 == [string compare [adapter name] kitprog ] } {
  106. set PSOC4_USE_ACQUIRE 1
  107. } else {
  108. set PSOC4_USE_ACQUIRE 0
  109. }
  110. }
  111. if { $PSOC4_USE_ACQUIRE } {
  112. set PSOC4_TEST_MODE_WORKAROUND 0
  113. } elseif { ! [info exists PSOC4_TEST_MODE_WORKAROUND] } {
  114. if { [psoc4_get_family_id] == 0x93 } {
  115. set PSOC4_TEST_MODE_WORKAROUND 1
  116. } else {
  117. set PSOC4_TEST_MODE_WORKAROUND 0
  118. }
  119. }
  120. #$t invoke-event reset-start
  121. $t invoke-event reset-assert-pre
  122. if { $halt && $PSOC4_USE_ACQUIRE } {
  123. catch { [adapter name] acquire_psoc }
  124. $t arp_examine
  125. } else {
  126. if { $PSOC4_TEST_MODE_WORKAROUND } {
  127. set TEST_MODE 0x40030014
  128. if { $halt == 1 } {
  129. catch { mww $TEST_MODE 0x80000000 }
  130. } else {
  131. catch { mww $TEST_MODE 0 }
  132. }
  133. }
  134. $t arp_reset assert 0
  135. }
  136. $t invoke-event reset-assert-post
  137. $t invoke-event reset-deassert-pre
  138. if {![using_hla]} { # workaround ST-Link v2 fails and forcing reconnect
  139. $t arp_reset deassert 0
  140. }
  141. $t invoke-event reset-deassert-post
  142. # Pass 1 - Now wait for any halt (requested as part of reset
  143. # assert/deassert) to happen. Ideally it takes effect without
  144. # first executing any instructions.
  145. if { $halt } {
  146. # Now PSoC CPU should loop in system ROM
  147. $t arp_waitstate running 200
  148. $t arp_halt
  149. # Catch, but ignore any errors.
  150. catch { $t arp_waitstate halted 1000 }
  151. # Did we succeed?
  152. set s [$t curstate]
  153. if { 0 != [string compare $s "halted" ] } {
  154. return -code error [format "TARGET: %s - Not halted" $t]
  155. }
  156. # Check if PSoC CPU is stopped in system ROM
  157. set pc [reg pc]
  158. regsub {pc[^:]*: } $pc "" pc
  159. if { $pc < 0x10000000 || $pc > 0x1000ffff } {
  160. set hint ""
  161. set family_id [psoc4_get_family_id]
  162. if { $family_id == 0x93 } {
  163. set hint ", use 'reset_config none'"
  164. } elseif { $family_id > 0x93 } {
  165. set hint ", use a KitProg adapter"
  166. }
  167. return -code error [format "TARGET: %s - Not halted in system ROM%s" $t $hint]
  168. }
  169. # Set registers to reset vector values
  170. mem2array value 32 0 2
  171. reg pc [expr {$value(1) & 0xfffffffe} ]
  172. reg msp $value(0)
  173. if { $PSOC4_TEST_MODE_WORKAROUND } {
  174. catch { mww $TEST_MODE 0 }
  175. }
  176. }
  177. #Pass 2 - if needed "init"
  178. if { 0 == [string compare init $MODE] } {
  179. set err [catch "$t arp_waitstate halted 5000"]
  180. # Did it halt?
  181. if { $err == 0 } {
  182. $t invoke-event reset-init
  183. }
  184. }
  185. $t invoke-event reset-end
  186. }