openocd: fix SPDX tag format for files .c
[openocd.git] / contrib / loaders / flash / msp432 / main_msp432p401x.c
1 // SPDX-License-Identifier: BSD-3-Clause
2
3 /******************************************************************************
4 *
5 * Copyright (C) 2013-2018 Texas Instruments Incorporated - http://www.ti.com/
6 *
7 ******************************************************************************/
8
9 #include <stdint.h>
10 #include <stdbool.h>
11 #include "driverlib.h"
12
13 #include "MSP432P4_FlashLibIf.h"
14
15 /* Number of erase repeats until timeout */
16 #define FLASH_MAX_REPEATS 5
17
18 /* Local prototypes */
19 void msp432_flash_init(void);
20 void msp432_flash_mass_erase(void);
21 void msp432_flash_sector_erase(void);
22 void msp432_flash_write(void);
23 void msp432_flash_continous_write(void);
24 void msp432_flash_exit(void);
25 void unlock_flash_sectors(void);
26 void unlock_all_flash_sectors(void);
27 void lock_all_flash_sectors(void);
28 void __cs_set_dco_frequency_range(uint32_t dco_freq);
29 static bool program_device(void *src, void *dest, uint32_t length);
30
31 struct backup_params {
32 uint32_t BANK0_WAIT_RESTORE;
33 uint32_t BANK1_WAIT_RESTORE;
34 uint32_t CS_DC0_FREQ_RESTORE;
35 uint8_t VCORE_LEVEL_RESTORE;
36 uint8_t PCM_VCORE_LEVEL_RESTORE;
37 };
38
39 #define BACKUP_PARAMS ((struct backup_params *) 0x20000180)
40
41 /* Main with trampoline */
42 int main(void)
43 {
44 /* Halt watchdog */
45 MAP_WDT_A_HOLD_TIMER();
46
47 /* Disable interrupts */
48 cpu_cpsid();
49
50 while (1) {
51 switch (FLASH_LOADER->FLASH_FUNCTION) {
52 case FLASH_INIT:
53 FLASH_LOADER->RETURN_CODE = FLASH_BUSY;
54 msp432_flash_init();
55 FLASH_LOADER->FLASH_FUNCTION = 0;
56 break;
57 case FLASH_MASS_ERASE:
58 FLASH_LOADER->RETURN_CODE = FLASH_BUSY;
59 msp432_flash_mass_erase();
60 FLASH_LOADER->FLASH_FUNCTION = 0;
61 break;
62 case FLASH_SECTOR_ERASE:
63 FLASH_LOADER->RETURN_CODE = FLASH_BUSY;
64 msp432_flash_sector_erase();
65 FLASH_LOADER->FLASH_FUNCTION = 0;
66 break;
67 case FLASH_PROGRAM:
68 FLASH_LOADER->RETURN_CODE = FLASH_BUSY;
69 msp432_flash_write();
70 FLASH_LOADER->FLASH_FUNCTION = 0;
71 break;
72 case FLASH_CONTINUOUS_PROGRAM:
73 FLASH_LOADER->RETURN_CODE = FLASH_BUSY;
74 msp432_flash_continous_write();
75 FLASH_LOADER->FLASH_FUNCTION = 0;
76 break;
77 case FLASH_EXIT:
78 FLASH_LOADER->RETURN_CODE = FLASH_BUSY;
79 msp432_flash_exit();
80 FLASH_LOADER->FLASH_FUNCTION = 0;
81 break;
82 case FLASH_NO_COMMAND:
83 break;
84 default:
85 FLASH_LOADER->RETURN_CODE = FLASH_WRONG_COMMAND;
86 break;
87 }
88 }
89 }
90
91 /* Initialize flash */
92 void msp432_flash_init(void)
93 {
94 bool success = false;
95
96 /* Point to vector table in RAM */
97 SCB->VTOR = (uint32_t)0x01000000;
98
99 /* backup system parameters */
100 BACKUP_PARAMS->BANK0_WAIT_RESTORE =
101 MAP_FLASH_CTL_GET_WAIT_STATE(FLASH_BANK0);
102 BACKUP_PARAMS->BANK1_WAIT_RESTORE =
103 MAP_FLASH_CTL_GET_WAIT_STATE(FLASH_BANK1);
104 BACKUP_PARAMS->VCORE_LEVEL_RESTORE = MAP_PCM_GET_CORE_VOLTAGE_LEVEL();
105 BACKUP_PARAMS->PCM_VCORE_LEVEL_RESTORE = MAP_PCM_GET_POWER_STATE();
106 BACKUP_PARAMS->CS_DC0_FREQ_RESTORE = CS->CTL0 & CS_CTL0_DCORSEL_MASK;
107
108 /* set parameters for flashing */
109 success = MAP_PCM_SET_POWER_STATE(PCM_AM_LDO_VCORE0);
110
111 /* Set Flash wait states to 2 */
112 MAP_FLASH_CTL_SET_WAIT_STATE(FLASH_BANK0, 2);
113 MAP_FLASH_CTL_SET_WAIT_STATE(FLASH_BANK1, 2);
114
115 /* Set CPU speed to 24MHz */
116 __cs_set_dco_frequency_range(CS_DCO_FREQUENCY_24);
117
118 if (!success) {
119 /* Indicate failed power switch */
120 FLASH_LOADER->RETURN_CODE = FLASH_POWER_ERROR;
121 } else
122 FLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;
123 }
124
125 /* Erase entire flash */
126 void msp432_flash_mass_erase(void)
127 {
128 bool success = false;
129
130 /* Allow flash writes */
131 unlock_flash_sectors();
132
133 /* Allow some mass erase repeats before timeout with error */
134 int erase_repeats = FLASH_MAX_REPEATS;
135 while (!success && (erase_repeats > 0)) {
136 /* Mass erase with post-verify */
137 success = MAP_FLASH_CTL_PERFORM_MASS_ERASE();
138 erase_repeats--;
139 }
140
141 if (erase_repeats == 0)
142 FLASH_LOADER->RETURN_CODE = FLASH_VERIFY_ERROR;
143 else
144 FLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;
145
146 /* Block flash writes */
147 lock_all_flash_sectors();
148 }
149
150 /* Erase one flash sector */
151 void msp432_flash_sector_erase(void)
152 {
153 bool success = false;
154
155 /* Allow flash writes */
156 unlock_all_flash_sectors();
157
158 /* Allow some sector erase repeats before timeout with error */
159 int erase_repeats = FLASH_MAX_REPEATS;
160 while (!success && (erase_repeats > 0)) {
161 /* Sector erase with post-verify */
162 success = MAP_FLASH_CTL_ERASE_SECTOR(FLASH_LOADER->DST_ADDRESS);
163 erase_repeats--;
164 }
165
166 if (erase_repeats == 0)
167 FLASH_LOADER->RETURN_CODE = FLASH_ERROR;
168 else
169 FLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;
170
171 /* Block flash writes */
172 lock_all_flash_sectors();
173 }
174
175 /* Write data to flash with the help of DriverLib */
176 void msp432_flash_write(void)
177 {
178 bool success = false;
179
180 /* Allow flash writes */
181 unlock_all_flash_sectors();
182
183 while (!(FLASH_LOADER->BUFFER1_STATUS_REGISTER & BUFFER_DATA_READY))
184 ;
185
186 FLASH_LOADER->BUFFER1_STATUS_REGISTER |= BUFFER_ACTIVE;
187
188 /* Program memory */
189 success = program_device((uint32_t *)RAM_LOADER_BUFFER1,
190 (void *)FLASH_LOADER->DST_ADDRESS, FLASH_LOADER->SRC_LENGTH);
191
192 FLASH_LOADER->BUFFER1_STATUS_REGISTER &=
193 ~(BUFFER_ACTIVE | BUFFER_DATA_READY);
194
195 /* Block flash writes */
196 lock_all_flash_sectors();
197
198 if (!success)
199 FLASH_LOADER->RETURN_CODE = FLASH_ERROR;
200 else
201 FLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;
202 }
203
204 /* Write data to flash with the help of DriverLib with auto-increment */
205 void msp432_flash_continous_write(void)
206 {
207 bool buffer1_in_use = false;
208 bool buffer2_in_use = false;
209 uint32_t *src_address = NULL;
210 bool success = false;
211
212 uint32_t bytes_to_write = FLASH_LOADER->SRC_LENGTH;
213 uint32_t write_package = 0;
214 uint32_t start_addr = FLASH_LOADER->DST_ADDRESS;
215
216 while (bytes_to_write > 0) {
217 if (bytes_to_write > SRC_LENGTH_MAX) {
218 write_package = SRC_LENGTH_MAX;
219 bytes_to_write -= write_package;
220 } else {
221 write_package = bytes_to_write;
222 bytes_to_write -= write_package;
223 }
224 unlock_all_flash_sectors();
225
226 while (!(FLASH_LOADER->BUFFER1_STATUS_REGISTER & BUFFER_DATA_READY) &&
227 !(FLASH_LOADER->BUFFER2_STATUS_REGISTER & BUFFER_DATA_READY))
228 ;
229
230 if (FLASH_LOADER->BUFFER1_STATUS_REGISTER & BUFFER_DATA_READY) {
231 FLASH_LOADER->BUFFER1_STATUS_REGISTER |= BUFFER_ACTIVE;
232 src_address = (uint32_t *)RAM_LOADER_BUFFER1;
233 buffer1_in_use = true;
234 } else if (FLASH_LOADER->BUFFER2_STATUS_REGISTER & BUFFER_DATA_READY) {
235 FLASH_LOADER->BUFFER2_STATUS_REGISTER |= BUFFER_ACTIVE;
236 src_address = (uint32_t *)RAM_LOADER_BUFFER2;
237 buffer2_in_use = true;
238 }
239 if (buffer1_in_use || buffer2_in_use) {
240 success = program_device(src_address,
241 (void *)start_addr, write_package);
242
243 if (buffer1_in_use)
244 P6->OUT &= ~BIT4; /* Program from B1 */
245 else if (buffer2_in_use)
246 P3->OUT &= ~BIT6; /* Program from B1 */
247
248 start_addr += write_package;
249 }
250 if (buffer1_in_use) {
251 FLASH_LOADER->BUFFER1_STATUS_REGISTER &=
252 ~(BUFFER_ACTIVE | BUFFER_DATA_READY);
253 buffer1_in_use = false;
254 } else if (buffer2_in_use) {
255 FLASH_LOADER->BUFFER2_STATUS_REGISTER &=
256 ~(BUFFER_ACTIVE | BUFFER_DATA_READY);
257 buffer2_in_use = false;
258 }
259 /* Block flash writes */
260 lock_all_flash_sectors();
261
262 if (!success) {
263 FLASH_LOADER->RETURN_CODE = FLASH_ERROR;
264 break;
265 }
266 }
267 if (success)
268 FLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;
269 }
270
271 /* Unlock Main/Info Flash sectors */
272 void unlock_flash_sectors(void)
273 {
274 if (FLASH_LOADER->ERASE_PARAM & ERASE_MAIN) {
275 MAP_FLASH_CTL_UNPROTECT_SECTOR(FLASH_MAIN_MEMORY_SPACE_BANK0,
276 0xFFFFFFFF);
277 MAP_FLASH_CTL_UNPROTECT_SECTOR(FLASH_MAIN_MEMORY_SPACE_BANK1,
278 0xFFFFFFFF);
279 }
280 if (FLASH_LOADER->ERASE_PARAM & ERASE_INFO) {
281 MAP_FLASH_CTL_UNPROTECT_SECTOR(FLASH_INFO_MEMORY_SPACE_BANK0,
282 FLASH_SECTOR0 | FLASH_SECTOR1);
283 if (FLASH_LOADER->UNLOCK_BSL == UNLOCK_BSL_KEY)
284 MAP_FLASH_CTL_UNPROTECT_SECTOR(FLASH_INFO_MEMORY_SPACE_BANK1,
285 FLASH_SECTOR0 | FLASH_SECTOR1);
286 }
287 }
288
289 /* Unlock All Flash sectors */
290 void unlock_all_flash_sectors(void)
291 {
292 MAP_FLASH_CTL_UNPROTECT_SECTOR(FLASH_MAIN_MEMORY_SPACE_BANK0, 0xFFFFFFFF);
293 MAP_FLASH_CTL_UNPROTECT_SECTOR(FLASH_MAIN_MEMORY_SPACE_BANK1, 0xFFFFFFFF);
294 MAP_FLASH_CTL_UNPROTECT_SECTOR(FLASH_INFO_MEMORY_SPACE_BANK0,
295 FLASH_SECTOR0 | FLASH_SECTOR1);
296 if (FLASH_LOADER->UNLOCK_BSL == UNLOCK_BSL_KEY)
297 MAP_FLASH_CTL_UNPROTECT_SECTOR(FLASH_INFO_MEMORY_SPACE_BANK1,
298 FLASH_SECTOR0 | FLASH_SECTOR1);
299 }
300
301
302 /* Lock all Flash sectors */
303 void lock_all_flash_sectors(void)
304 {
305 MAP_FLASH_CTL_PROTECT_SECTOR(FLASH_MAIN_MEMORY_SPACE_BANK0, 0xFFFFFFFF);
306 MAP_FLASH_CTL_PROTECT_SECTOR(FLASH_MAIN_MEMORY_SPACE_BANK1, 0xFFFFFFFF);
307 MAP_FLASH_CTL_PROTECT_SECTOR(FLASH_INFO_MEMORY_SPACE_BANK0,
308 FLASH_SECTOR0 | FLASH_SECTOR1);
309 MAP_FLASH_CTL_PROTECT_SECTOR(FLASH_INFO_MEMORY_SPACE_BANK1,
310 FLASH_SECTOR0 | FLASH_SECTOR1);
311 }
312
313
314 /* Force DCO frequency range */
315 void __cs_set_dco_frequency_range(uint32_t dco_freq)
316 {
317 /* Unlocking the CS Module */
318 CS->KEY = CS_KEY_VAL;
319
320 /* Resetting Tuning Parameters and Setting the frequency */
321 CS->CTL0 = (CS->CTL0 & ~CS_CTL0_DCORSEL_MASK) | dco_freq;
322
323 /* Locking the CS Module */
324 CS->KEY = 0;
325 }
326
327 /* Exit flash programming */
328 void msp432_flash_exit(void)
329 {
330 bool success = false;
331
332 /* Restore modified registers, in reverse order */
333 __cs_set_dco_frequency_range(CS_DCO_FREQUENCY_3);
334
335 MAP_FLASH_CTL_SET_WAIT_STATE(FLASH_BANK0,
336 BACKUP_PARAMS->BANK0_WAIT_RESTORE);
337 MAP_FLASH_CTL_SET_WAIT_STATE(FLASH_BANK1,
338 BACKUP_PARAMS->BANK1_WAIT_RESTORE);
339
340 success = MAP_PCM_SET_POWER_STATE(BACKUP_PARAMS->PCM_VCORE_LEVEL_RESTORE);
341
342 success &= MAP_PCM_SET_CORE_VOLTAGE_LEVEL(
343 BACKUP_PARAMS->VCORE_LEVEL_RESTORE);
344
345 __cs_set_dco_frequency_range(BACKUP_PARAMS->CS_DC0_FREQ_RESTORE);
346
347 /* Point to vector table in Flash */
348 SCB->VTOR = (uint32_t)0x00000000;
349
350 if (!success)
351 FLASH_LOADER->RETURN_CODE = FLASH_ERROR;
352 else
353 FLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;
354 }
355
356 static bool program_device(void *src, void *dest, uint32_t length)
357 {
358 return MAP_FLASH_CTL_PROGRAM_MEMORY(src, dest, length);
359 }

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)