1
+ # pyOCD debugger
2
+ # Copyright (c) 2023 Brian Pugh
3
+ # Copyright (c) 2024 Uwe Strempel
4
+ # SPDX-License-Identifier: Apache-2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+
18
+ import time
19
+
20
+ from ...core .memory_map import FlashRegion , MemoryMap , RamRegion
21
+ from ...coresight .coresight_target import CoreSightTarget
22
+ from ...coresight .cortex_m import CortexM
23
+ from ...coresight .minimal_mem_ap import MinimalMemAP as MiniAP
24
+
25
+
26
+ class DBGMCU :
27
+ CR = 0xE00E1004
28
+ CR_VALUE = 0x7 # DBG_STANDBY | DBG_STOP | DBG_SLEEP
29
+
30
+ # addapted from keil pack
31
+ # see also H7B3 documentation
32
+ CR_VALUE_ALL_ENABLE_ALL_DEBUG_CLOCKS = 0x00670000 # set preset values (enable all debug clocks by default)
33
+ # DBGMCU_CR[18] CKDBGD3EN, [17] CKDBGD2EN, [16] CKDBGD1EN
34
+ # DBGMCU_CR[22] D3DBGCKEN, [21] D1DBGCKEN
35
+ APB3 = 0xE00E1034
36
+ APB3_FZ1_VALUE = 0x00000000 # DBGMCU_APB3FZ1: DBGMCU APB3 peripheral freeze register
37
+ APB1L = 0xE00E103C
38
+ APB1L_FZ1_VALUE = 0x00000000 # DBGMCU_APB1LFZ1: DBGMCU APB1L peripheral freeze register
39
+ APB2 = 0xE00E104C
40
+ APB2_FZ1_VALUE = 0x00000000 # DBGMCU_APB2FZ1: DBGMCU APB2 peripheral freeze register
41
+ APB4 = 0xE00E1054
42
+ APB4_FZ1_VALUE = 0x00000000 # DBGMCU_APB4FZ1: DBGMCU APB4 peripheral freeze register
43
+
44
+
45
+ FLASH_ALGO = {
46
+ 'load_address' : 0x20000000 ,
47
+
48
+ # Flash algorithm as a hex string
49
+ 'instructions' : [
50
+ 0xe7fdbe00 ,
51
+ 0x4770ba40 , 0x4770bac0 , 0x0030ea4f , 0x00004770 , 0x8f4ff3bf , 0xb5104770 , 0x48ea4603 , 0x61604cea ,
52
+ 0x48e9bf00 , 0xf0006900 , 0x28000001 , 0x48e7d1f9 , 0x60604ce5 , 0x606048e6 , 0x4ce648e2 , 0xbf006020 ,
53
+ 0x1f0048e4 , 0xf0006800 , 0x28000001 , 0x48dfd1f8 , 0x3c104ce0 , 0x48de6020 , 0xf8c44cdb , 0x46200104 ,
54
+ 0x200069c0 , 0x4601bd10 , 0x68c048d7 , 0x0001f040 , 0x60d04ad5 , 0x380848d7 , 0xf0406800 , 0xf8c20001 ,
55
+ 0x2000010c , 0xbf004770 , 0x690048cf , 0x0001f000 , 0xd1f92800 , 0x49cc48cb , 0x46086148 , 0xf02068c0 ,
56
+ 0x60c80001 , 0x68c04608 , 0x0008f040 , 0x460860c8 , 0xf04068c0 , 0x60c80020 , 0x48c3bf00 , 0xf0006900 ,
57
+ 0x28000001 , 0x48c0d1f9 , 0xf02068c0 , 0x49be0008 , 0xbf0060c8 , 0x1f0048bf , 0xf0006800 , 0x28000001 ,
58
+ 0x48b8d1f8 , 0x600849bb , 0xf8d048b7 , 0xf020010c , 0x49b50001 , 0x010cf8c1 , 0xf8d04608 , 0xf040010c ,
59
+ 0xf8c10008 , 0x4608010c , 0x010cf8d0 , 0x0020f040 , 0x390849b0 , 0xbf006008 , 0x1f0048ae , 0xf0006800 ,
60
+ 0x28000001 , 0x48abd1f8 , 0x68003808 , 0x0008f020 , 0xf8c149a5 , 0x2000010c , 0xb5104770 , 0xf3c14601 ,
61
+ 0xf1b13247 , 0xd3366f00 , 0x6f01f1b1 , 0x489ed233 , 0x4ba16940 , 0x4b9c4318 , 0xbf006158 , 0x6900489a ,
62
+ 0x0004f000 , 0xd1f92800 , 0x68c04897 , 0x50fef420 , 0x60d84b95 , 0x68c04618 , 0xea432304 , 0x43181382 ,
63
+ 0x60d84b91 , 0x68c04618 , 0x0020f040 , 0xbf0060d8 , 0x6900488d , 0x0004f000 , 0xd1f92800 , 0x68c0488a ,
64
+ 0x0004f020 , 0x60d84b88 , 0x69004618 , 0x0001f000 , 0x2001b3f0 , 0x4887bd10 , 0x4b876800 , 0x4b824318 ,
65
+ 0x0114f8c3 , 0x4883bf00 , 0x68001f00 , 0x0004f000 , 0xd1f82800 , 0x3808487f , 0xf4206800 , 0x4b7a50fe ,
66
+ 0x010cf8c3 , 0x3808487b , 0xf1a26800 , 0x24040380 , 0x1383ea44 , 0x4b744318 , 0x010cf8c3 , 0xf8d04618 ,
67
+ 0xf040010c , 0xf8c30020 , 0xbf00010c , 0x1f004871 , 0xf0006800 , 0x28000004 , 0x486ed1f8 , 0x68003808 ,
68
+ 0x0004f020 , 0xf8c34b68 , 0x486a010c , 0xe0001f00 , 0x6800e005 , 0x0001f000 , 0x2001b108 , 0xf7ffe7ba ,
69
+ 0x2000fee7 , 0xb5f0e7b6 , 0x46164603 , 0x4635461a , 0xbf002400 , 0x6 pyocd / target / builtin / target_STM32H7B2xx .py900485c , 0x0001f000 , 0xd1f92800 ,
70
+ 0x4f594858 , 0xbf006178 , 0x1f00485a , 0xf0006800 , 0x28000001 , 0x4853d1f8 , 0x60384f56 , 0x4852e09c ,
71
+ 0xf02068c0 , 0x4f500001 , 0x463860f8 , 0xf04068c0 , 0x60f80002 , 0x3808484f , 0xf0206800 , 0xf8c70001 ,
72
+ 0x4638010c , 0x010cf8d0 , 0x0002f040 , 0x010cf8c7 , 0xd30c2910 , 0xe0062400 , 0x6868682f , 0x60506017 ,
73
+ 0x32083508 , 0x2c021c64 , 0x3910dbf6 , 0x2400e028 , 0xf815e004 , 0xf8020b01 , 0x1c640b01 , 0xd3f8428c ,
74
+ 0xe0032400 , 0xf80220ff , 0x1c640b01 , 0x0010f1c1 , 0xd8f742a0 , 0x6f00f1b3 , 0xf1b3d309 , 0xd2066f01 ,
75
+ 0x68c04831 , 0x0040f040 , 0x60f84f2f , 0x4831e007 , 0x68003808 , 0x0040f040 , 0xf8c74f2b , 0x2100010c ,
76
+ 0xfe76f7ff , 0x6f00f1b3 , 0xf1b3d30a , 0xd2076f01 , 0x4825bf00 , 0xf0006900 , 0x28000001 , 0xe007d1f9 ,
77
+ 0x4824bf00 , 0x68001f00 , 0x0001f000 , 0xd1f82800 , 0x6900481d , 0x4f1f2000 , 0x683f1f3f , 0xb1b04300 ,
78
+ 0x6f00f1b3 , 0xf1b3d309 , 0xd2066f01 , 0x68c04816 , 0x0002f020 , 0x60f84f14 , 0x4816e007 , 0x68003808 ,
79
+ 0x0002f020 , 0xf8c74f10 , 0x2001010c , 0xf1b3bdf0 , 0xd3096f00 , 0x6f01f1b3 , 0x480bd206 , 0xf02068c0 ,
80
+ 0x4f090002 , 0xe00760f8 , 0x3808480a , 0xf0206800 , 0x4f050002 , 0x010cf8c7 , 0xf47f2900 , 0x2000af60 ,
81
+ 0x0000e7e4 , 0x0faf0000 , 0x52002000 , 0x45670123 , 0xcdef89ab , 0x52002114 , 0x0fef0000 , 0x00000000
82
+ ],
83
+
84
+ # Relative function addresses
85
+ 'pc_init' : 0x2000001b ,
86
+ 'pc_unInit' : 0x2000006b ,
87
+ 'pc_program_page' : 0x2000024b ,
88
+ 'pc_erase_sector' : 0x2000013f ,
89
+ 'pc_eraseAll' : 0x2000008b ,
90
+
91
+ 'static_base' : 0x20000000 + 0x00000004 + 0x000003dc ,
92
+ 'begin_stack' : 0x200113f0 ,
93
+ 'end_stack' : 0x200103f0 ,
94
+ 'begin_data' : 0x20000000 + 0x1000 ,
95
+ 'page_size' : 0x2000 ,
96
+ 'analyzer_supported' : False ,
97
+ 'analyzer_address' : 0x00000000 ,
98
+ # Enable double buffering
99
+ 'page_buffers' : [
100
+ 0x200003f0 ,
101
+ 0x200083f0
102
+ ],
103
+ 'min_program_length' : 0x2000 ,
104
+
105
+ # Relative region addresses and sizes
106
+ 'ro_start' : 0x4 ,
107
+ 'ro_size' : 0x3dc ,
108
+ 'rw_start' : 0x3e0 ,
109
+ 'rw_size' : 0x4 ,
110
+ 'zi_start' : 0x3e4 ,
111
+ 'zi_size' : 0x0 ,
112
+
113
+ # Flash information
114
+ 'flash_start' : 0x8000000 ,
115
+ 'flash_size' : 0x00200000 ,
116
+ 'sector_sizes' : (
117
+ (0x0 , 0x2000 ),
118
+ )
119
+ }
120
+
121
+ class STM32H7B3xx (CoreSightTarget ):
122
+
123
+ VENDOR = "STMicroelectronics"
124
+ MEMORY_MAP = MemoryMap (
125
+ # Datasheet says there's 1MB
126
+ FlashRegion ( start = 0x08000000 , length = 0x00100000 , sector_size = 0x2000 ,
127
+ page_size = 0x2000 ,
128
+ is_boot_memory = True ,
129
+ algo = FLASH_ALGO ,
130
+ name = "bank_1" ),
131
+ # Datasheet does not reference a flash bank 2,
132
+ # but there's an additional 1M here, as well.
133
+ FlashRegion ( start = 0x08100000 , length = 0x00100000 , sector_size = 0x2000 ,
134
+ page_size = 0x2000 ,
135
+ is_boot_memory = True ,
136
+ algo = FLASH_ALGO ,
137
+ name = "bank_2" ),
138
+ RamRegion ( start = 0x20000000 , length = 0x20000 , name = "dtcm" ),
139
+ RamRegion ( start = 0x24000000 , length = 0x40000 , name = "axi_sram_1" ),
140
+ RamRegion ( start = 0x24040000 , length = 0x60000 , name = "axi_sram_2" ),
141
+ RamRegion ( start = 0x240A0000 , length = 0x60000 , name = "axi_sram_3" ),
142
+ RamRegion ( start = 0x30000000 , length = 0x10000 , name = "ahb_sram_1" ),
143
+ RamRegion ( start = 0x30010000 , length = 0x10000 , name = "ahb_sram_2" ),
144
+ RamRegion ( start = 0x38000000 , length = 0x8000 , name = "sdr_sram" ),
145
+ RamRegion ( start = 0x38800000 , length = 0x1000 , name = "backup_sram" ),
146
+ )
147
+
148
+ def __init__ (self , session ):
149
+ super ().__init__ (session , self .MEMORY_MAP )
150
+
151
+ def assert_reset_for_connect (self ):
152
+ self .dp .assert_reset (True )
153
+
154
+ def safe_reset_and_halt (self ):
155
+ assert self .dp .is_reset_asserted ()
156
+
157
+ # At this point we can't access full AP as it is not initialized yet.
158
+ # Let's create a minimalistic AP and use it.
159
+ ap = MiniAP (self .dp )
160
+ ap .init ()
161
+
162
+ DEMCR_value = ap .read32 (CortexM .DEMCR )
163
+
164
+ # Halt on reset.
165
+ ap .write32 (CortexM .DEMCR , CortexM .DEMCR_VC_CORERESET )
166
+ ap .write32 (CortexM .DHCSR , CortexM .DBGKEY | CortexM .C_DEBUGEN )
167
+
168
+ # Prevent disabling bus clock/power in low power modes.
169
+ ap .write32 (DBGMCU .CR , DBGMCU .CR_VALUE )
170
+ self .dp .assert_reset (False )
171
+ time .sleep (0.01 )
172
+
173
+ # Restore DEMCR original value.
174
+ ap .write32 (CortexM .DEMCR , DEMCR_value )
175
+
176
+ def create_init_sequence (self ):
177
+ # STM32 under some low power/broken clock states doesn't allow AHP communication.
178
+ # Low power modes are quite popular on stm32 (including MBed OS defaults).
179
+ # 'attach' mode is broken by default, as STM32 can't be connected on low-power mode
180
+ # successfully without previous DBGMCU setup (It is not possible to write DBGMCU).
181
+ # It is also not possible to run full pyOCD discovery code under-reset.
182
+ #
183
+ # As a solution we can setup DBGMCU under reset, halt core and release reset.
184
+ # Unfortunately this code has to be executed _before_ discovery stage
185
+ # and without discovery stage we don't have access to AP/Core.
186
+ # As a solution we can create minimalistic AP implementation and use it
187
+ # to setup core halt.
188
+ # So the sequence for 'halt' connect mode will look like
189
+ # -> Assert reset
190
+ # -> Connect DebugPort
191
+ # -> Setup MiniAp
192
+ # -> Setup halt on reset
193
+ # -> Enable support for debugging in low-power modes
194
+ # -> Release reset
195
+ # -> [Core is halted and reset is released]
196
+ # -> Continue [discovery, create cores, etc]
197
+ seq = super ().create_init_sequence ()
198
+ if self .session .options .get ('connect_mode' ) in ('halt' , 'under-reset' ):
199
+ seq .insert_before ('dp_init' , ('assert_reset_for_connect' , self .assert_reset_for_connect ))
200
+ seq .insert_after ('dp_init' , ('safe_reset_and_halt' , self .safe_reset_and_halt ))
201
+
202
+ return seq
203
+
204
+ def post_connect_hook (self ):
205
+ self .write32 (DBGMCU .CR , DBGMCU .CR_VALUE | DBGMCU .CR_VALUE_ALL_ENABLE_ALL_DEBUG_CLOCKS )
206
+ self .write32 (DBGMCU .CR , DBGMCU .CR_VALUE )
207
+ self .write32 (DBGMCU .APB3 , DBGMCU .APB3_FZ1_VALUE )
208
+ self .write32 (DBGMCU .APB1L , DBGMCU .APB1L_FZ1_VALUE )
209
+ self .write32 (DBGMCU .APB2 , DBGMCU .APB2_FZ1_VALUE )
210
+ self .write32 (DBGMCU .APB4 , DBGMCU .APB4_FZ1_VALUE )
0 commit comments