d72efed6808f19d658c053804f9b7db5dc7e9d25
[openocd.git] / contrib / loaders / flash / msp432 / main_msp432p411x.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 #define INFO_FLASH_START __INFO_FLASH_A_TECH_START__
41 #define INFO_FLASH_MIDDLE __INFO_FLASH_A_TECH_MIDDLE__
42 #define BSL_FLASH_START BSL_API_TABLE_ADDR
43
44 /* Main with trampoline */
45 int main(void)
46 {
47 /* Halt watchdog */
48 MAP_WDT_A_HOLD_TIMER();
49
50 /* Disable interrupts */
51 cpu_cpsid();
52
53 while (1) {
54 switch (FLASH_LOADER->FLASH_FUNCTION) {
55 case FLASH_INIT:
56 FLASH_LOADER->RETURN_CODE = FLASH_BUSY;
57 msp432_flash_init();
58 FLASH_LOADER->FLASH_FUNCTION = 0;
59 break;
60 case FLASH_MASS_ERASE:
61 FLASH_LOADER->RETURN_CODE = FLASH_BUSY;
62 msp432_flash_mass_erase();
63 FLASH_LOADER->FLASH_FUNCTION = 0;
64 break;
65 case FLASH_SECTOR_ERASE:
66 FLASH_LOADER->RETURN_CODE = FLASH_BUSY;
67 msp432_flash_sector_erase();
68 FLASH_LOADER->FLASH_FUNCTION = 0;
69 break;
70 case FLASH_PROGRAM:
71 FLASH_LOADER->RETURN_CODE = FLASH_BUSY;
72 msp432_flash_write();
73 FLASH_LOADER->FLASH_FUNCTION = 0;
74 break;
75 case FLASH_CONTINUOUS_PROGRAM:
76 FLASH_LOADER->RETURN_CODE = FLASH_BUSY;
77 msp432_flash_continous_write();
78 FLASH_LOADER->FLASH_FUNCTION = 0;
79 break;
80 case FLASH_EXIT:
81 FLASH_LOADER->RETURN_CODE = FLASH_BUSY;
82 msp432_flash_exit();
83 FLASH_LOADER->FLASH_FUNCTION = 0;
84 break;
85 case FLASH_NO_COMMAND:
86 break;
87 default:
88 FLASH_LOADER->RETURN_CODE = FLASH_WRONG_COMMAND;
89 break;
90 }
91 }
92 }
93
94 /* Initialize flash */
95 void msp432_flash_init(void)
96 {
97 bool success = false;
98
99 /* Point to vector table in RAM */
100 SCB->VTOR = (uint32_t)0x01000000;
101
102 /* backup system parameters */
103 BACKUP_PARAMS->BANK0_WAIT_RESTORE =
104 MAP_FLASH_CTL_A_GET_WAIT_STATE(FLASH_A_BANK0);
105 BACKUP_PARAMS->BANK1_WAIT_RESTORE =
106 MAP_FLASH_CTL_A_GET_WAIT_STATE(FLASH_A_BANK1);
107 BACKUP_PARAMS->VCORE_LEVEL_RESTORE = MAP_PCM_GET_CORE_VOLTAGE_LEVEL();
108 BACKUP_PARAMS->PCM_VCORE_LEVEL_RESTORE = MAP_PCM_GET_POWER_STATE();
109 BACKUP_PARAMS->CS_DC0_FREQ_RESTORE = CS->CTL0 & CS_CTL0_DCORSEL_MASK;
110
111 /* set parameters for flashing */
112 success = MAP_PCM_SET_POWER_STATE(PCM_AM_LDO_VCORE0);
113
114 /* Set Flash wait states to 2 */
115 MAP_FLASH_CTL_A_SET_WAIT_STATE(FLASH_A_BANK0, 2);
116 MAP_FLASH_CTL_A_SET_WAIT_STATE(FLASH_A_BANK1, 2);
117
118 /* Set CPU speed to 24MHz */
119 __cs_set_dco_frequency_range(CS_DCO_FREQUENCY_24);
120
121 if (!success) {
122 /* Indicate failed power switch */
123 FLASH_LOADER->RETURN_CODE = FLASH_POWER_ERROR;
124 } else
125 FLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;
126 }
127
128 /* Erase entire flash */
129 void msp432_flash_mass_erase(void)
130 {
131 bool success = false;
132
133 /* Allow flash writes */
134 unlock_flash_sectors();
135
136 /* Allow some mass erase repeats before timeout with error */
137 int erase_repeats = FLASH_MAX_REPEATS;
138 while (!success && (erase_repeats > 0)) {
139 /* Mass erase with post-verify */
140 success = ROM_FLASH_CTL_A_PERFORM_MASS_ERASE();
141 erase_repeats--;
142 }
143
144 if (erase_repeats == 0)
145 FLASH_LOADER->RETURN_CODE = FLASH_VERIFY_ERROR;
146 else
147 FLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;
148
149 /* Block flash writes */
150 lock_all_flash_sectors();
151 }
152
153 /* Erase one flash sector */
154 void msp432_flash_sector_erase(void)
155 {
156 bool success = false;
157
158 /* Allow flash writes */
159 unlock_all_flash_sectors();
160
161 /* Allow some sector erase repeats before timeout with error */
162 int erase_repeats = FLASH_MAX_REPEATS;
163 while (!success && (erase_repeats > 0)) {
164 /* Sector erase with post-verify */
165 success = MAP_FLASH_CTL_A_ERASE_SECTOR(FLASH_LOADER->DST_ADDRESS);
166 erase_repeats--;
167 }
168
169 if (erase_repeats == 0)
170 FLASH_LOADER->RETURN_CODE = FLASH_ERROR;
171 else
172 FLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;
173
174 /* Block flash writes */
175 lock_all_flash_sectors();
176 }
177
178 /* Write data to flash with the help of DriverLib */
179 void msp432_flash_write(void)
180 {
181 bool success = false;
182
183 /* Allow flash writes */
184 unlock_all_flash_sectors();
185
186 while (!(FLASH_LOADER->BUFFER1_STATUS_REGISTER & BUFFER_DATA_READY))
187 ;
188
189 FLASH_LOADER->BUFFER1_STATUS_REGISTER |= BUFFER_ACTIVE;
190
191 /* Program memory */
192 success = program_device((uint32_t *)RAM_LOADER_BUFFER1,
193 (void *)FLASH_LOADER->DST_ADDRESS, FLASH_LOADER->SRC_LENGTH);
194
195 FLASH_LOADER->BUFFER1_STATUS_REGISTER &=
196 ~(BUFFER_ACTIVE | BUFFER_DATA_READY);
197
198 /* Block flash writes */
199 lock_all_flash_sectors();
200
201 if (!success)
202 FLASH_LOADER->RETURN_CODE = FLASH_ERROR;
203 else
204 FLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;
205 }
206
207 /* Write data to flash with the help of DriverLib with auto-increment */
208 void msp432_flash_continous_write(void)
209 {
210 bool buffer1_in_use = false;
211 bool buffer2_in_use = false;
212 uint32_t *src_address = NULL;
213 bool success = false;
214
215 uint32_t bytes_to_write = FLASH_LOADER->SRC_LENGTH;
216 uint32_t write_package = 0;
217 uint32_t start_addr = FLASH_LOADER->DST_ADDRESS;
218
219 while (bytes_to_write > 0) {
220 if (bytes_to_write > SRC_LENGTH_MAX) {
221 write_package = SRC_LENGTH_MAX;
222 bytes_to_write -= write_package;
223 } else {
224 write_package = bytes_to_write;
225 bytes_to_write -= write_package;
226 }
227 unlock_all_flash_sectors();
228 while (!(FLASH_LOADER->BUFFER1_STATUS_REGISTER & BUFFER_DATA_READY) &&
229 !(FLASH_LOADER->BUFFER2_STATUS_REGISTER & BUFFER_DATA_READY))
230 ;
231
232 if (FLASH_LOADER->BUFFER1_STATUS_REGISTER & BUFFER_DATA_READY) {
233 FLASH_LOADER->BUFFER1_STATUS_REGISTER |= BUFFER_ACTIVE;
234 src_address = (uint32_t *) RAM_LOADER_BUFFER1;
235 buffer1_in_use = true;
236 } else if (FLASH_LOADER->BUFFER2_STATUS_REGISTER & BUFFER_DATA_READY) {
237 FLASH_LOADER->BUFFER2_STATUS_REGISTER |= BUFFER_ACTIVE;
238 src_address = (uint32_t *) RAM_LOADER_BUFFER2;
239 buffer2_in_use = true;
240 }
241 if (buffer1_in_use || buffer2_in_use) {
242 success = program_device(src_address, (void *) start_addr, write_package);
243 start_addr += write_package;
244 }
245 if (buffer1_in_use) {
246 FLASH_LOADER->BUFFER1_STATUS_REGISTER &= ~(BUFFER_ACTIVE | BUFFER_DATA_READY);
247 buffer1_in_use = false;
248 } else if (buffer2_in_use) {
249 FLASH_LOADER->BUFFER2_STATUS_REGISTER &= ~(BUFFER_ACTIVE | BUFFER_DATA_READY);
250 buffer2_in_use = false;
251 }
252 /* Block flash writes */
253 lock_all_flash_sectors();
254
255 if (!success) {
256 FLASH_LOADER->RETURN_CODE = FLASH_ERROR;
257 break;
258 }
259 }
260 if (success)
261 FLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;
262 }
263
264 /* Unlock Main/Info Flash sectors */
265 void unlock_flash_sectors(void)
266 {
267 if (FLASH_LOADER->ERASE_PARAM & ERASE_MAIN)
268 MAP_FLASH_CTL_A_UNPROTECT_MEMORY(FLASH_BASE, FLASH_BASE +
269 MAP_SYS_CTL_A_GET_FLASH_SIZE() - 1);
270
271 if (FLASH_LOADER->ERASE_PARAM & ERASE_INFO) {
272 MAP_FLASH_CTL_A_UNPROTECT_MEMORY(INFO_FLASH_START, TLV_BASE - 1);
273 if (FLASH_LOADER->UNLOCK_BSL == UNLOCK_BSL_KEY)
274 MAP_FLASH_CTL_A_UNPROTECT_MEMORY(BSL_FLASH_START,
275 INFO_FLASH_MIDDLE - 1);
276 MAP_FLASH_CTL_A_UNPROTECT_MEMORY(INFO_FLASH_MIDDLE, INFO_FLASH_MIDDLE +
277 MAP_SYS_CTL_A_GET_INFO_FLASH_SIZE() - 1);
278 }
279 }
280
281 /* Unlock All Flash sectors */
282 void unlock_all_flash_sectors(void)
283 {
284 MAP_FLASH_CTL_A_UNPROTECT_MEMORY(FLASH_BASE, FLASH_BASE +
285 MAP_SYS_CTL_A_GET_FLASH_SIZE() - 1);
286 MAP_FLASH_CTL_A_UNPROTECT_MEMORY(INFO_FLASH_START, TLV_BASE - 1);
287 if (FLASH_LOADER->UNLOCK_BSL == UNLOCK_BSL_KEY)
288 MAP_FLASH_CTL_A_UNPROTECT_MEMORY(BSL_FLASH_START,
289 INFO_FLASH_MIDDLE - 1);
290 MAP_FLASH_CTL_A_UNPROTECT_MEMORY(INFO_FLASH_MIDDLE, INFO_FLASH_MIDDLE +
291 MAP_SYS_CTL_A_GET_INFO_FLASH_SIZE() - 1);
292 }
293
294 /* Lock all Flash sectors */
295 void lock_all_flash_sectors(void)
296 {
297 MAP_FLASH_CTL_A_PROTECT_MEMORY(FLASH_BASE, FLASH_BASE +
298 MAP_SYS_CTL_A_GET_FLASH_SIZE() - 1);
299 MAP_FLASH_CTL_A_PROTECT_MEMORY(INFO_FLASH_START, INFO_FLASH_START +
300 MAP_SYS_CTL_A_GET_INFO_FLASH_SIZE() - 1);
301 }
302
303 /* Force DCO frequency range */
304 void __cs_set_dco_frequency_range(uint32_t dco_freq)
305 {
306 /* Unlocking the CS Module */
307 CS->KEY = CS_KEY_VAL;
308
309 /* Resetting Tuning Parameters and Setting the frequency */
310 CS->CTL0 = (CS->CTL0 & ~CS_CTL0_DCORSEL_MASK) | dco_freq;
311
312 /* Locking the CS Module */
313 CS->KEY = 0;
314 }
315
316 /* Exit flash programming */
317 void msp432_flash_exit(void)
318 {
319 bool success = false;
320
321 /* Restore modified registers, in reverse order */
322 __cs_set_dco_frequency_range(CS_DCO_FREQUENCY_3);
323
324 MAP_FLASH_CTL_A_SET_WAIT_STATE(FLASH_A_BANK0,
325 BACKUP_PARAMS->BANK0_WAIT_RESTORE);
326 MAP_FLASH_CTL_A_SET_WAIT_STATE(FLASH_A_BANK1,
327 BACKUP_PARAMS->BANK1_WAIT_RESTORE);
328
329 success = MAP_PCM_SET_POWER_STATE(BACKUP_PARAMS->PCM_VCORE_LEVEL_RESTORE);
330
331 success &= MAP_PCM_SET_CORE_VOLTAGE_LEVEL(
332 BACKUP_PARAMS->VCORE_LEVEL_RESTORE);
333
334 __cs_set_dco_frequency_range(BACKUP_PARAMS->CS_DC0_FREQ_RESTORE);
335
336 /* Point to vector table in Flash */
337 SCB->VTOR = (uint32_t)0x00000000;
338
339 if (!success)
340 FLASH_LOADER->RETURN_CODE = FLASH_ERROR;
341 else
342 FLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;
343 }
344
345 static bool program_device(void *src, void *dest, uint32_t length)
346 {
347 uint32_t dst_address = (uint32_t)dest;
348
349 /* Flash main memory first, then information memory */
350 if ((dst_address < INFO_FLASH_START) && ((dst_address + length) >
351 INFO_FLASH_START)) {
352 uint32_t block_length = INFO_FLASH_START - dst_address;
353 uint32_t src_address = (uint32_t)src;
354 /* Main memory block */
355 bool success = MAP_FLASH_CTL_A_PROGRAM_MEMORY(src, dest, block_length);
356
357 src_address = src_address + block_length;
358 block_length = length - block_length;
359 /* Information memory block */
360 success &= MAP_FLASH_CTL_A_PROGRAM_MEMORY((void *)src_address,
361 (void *)INFO_FLASH_START, block_length);
362 return success;
363 } else
364 return MAP_FLASH_CTL_A_PROGRAM_MEMORY(src, dest, length);
365 }

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)