flash/nor: add support for TI MSP432 devices
[openocd.git] / src / flash / nor / msp432.c
1 /***************************************************************************
2 * Copyright (C) 2018 by Texas Instruments, Inc. *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
16 ***************************************************************************/
17
18 #ifdef HAVE_CONFIG_H
19 #include "config.h"
20 #endif
21
22 #include "imp.h"
23 #include "msp432.h"
24 #include <helper/binarybuffer.h>
25 #include <helper/time_support.h>
26 #include <target/algorithm.h>
27 #include <target/armv7m.h>
28 #include <target/image.h>
29
30 /* MSP432P4 hardware registers */
31 #define P4_FLASH_MAIN_SIZE_REG 0xE0043020
32 #define P4_FLASH_INFO_SIZE_REG 0xE0043024
33 #define P4_DEVICE_ID_REG 0x0020100C
34 #define P4_HARDWARE_REV_REG 0x00201010
35
36 /* MSP432E4 hardware registers */
37 #define E4_DID0_REG 0x400FE000
38 #define E4_DID1_REG 0x400FE004
39
40 #define FLASH_TIMEOUT 8000
41
42 #define SUPPORT_MESSAGE \
43 "Your pre-production MSP432P401x silicon is not fully supported\n" \
44 "You can find more information at www.ti.com/product/MSP432P401R"
45
46 struct msp432_bank {
47 uint32_t device_id;
48 uint32_t hardware_rev;
49 int family_type;
50 int device_type;
51 uint32_t sector_length;
52 bool probed[2];
53 bool unlock_bsl;
54 struct working_area *working_area;
55 struct armv7m_algorithm armv7m_info;
56 };
57
58 static int msp432_auto_probe(struct flash_bank *bank);
59
60 static int msp432_device_type(uint32_t family_type, uint32_t device_id,
61 uint32_t hardware_rev)
62 {
63 int device_type = MSP432_NO_TYPE;
64
65 if (MSP432E4 == family_type) {
66 /* MSP432E4 device family */
67
68 if (device_id == 0x180C0002) {
69 if (hardware_rev == 0x102DC06E) {
70 /* The 01Y variant */
71 device_type = MSP432E401Y;
72 } else if (hardware_rev == 0x1032E076) {
73 /* The 11Y variant */
74 device_type = MSP432E411Y;
75 } else {
76 /* Reasonable guess that this is a new variant */
77 device_type = MSP432E4X_GUESS;
78 }
79 } else {
80 /* Wild guess that this is an MSP432E4 */
81 device_type = MSP432E4X_GUESS;
82 }
83 } else {
84 /* MSP432P4 device family */
85
86 /* Examine the device ID and hardware revision to get the device type */
87 switch (device_id) {
88 case 0xA000:
89 case 0xA001:
90 case 0xA002:
91 case 0xA003:
92 case 0xA004:
93 case 0xA005:
94 /* Device is definitely MSP432P401x, check hardware revision */
95 if (hardware_rev == 0x41 || hardware_rev == 0x42) {
96 /* Rev A or B of the silicon has been deprecated */
97 device_type = MSP432P401X_DEPR;
98 } else if (hardware_rev >= 0x43 && hardware_rev <= 0x49) {
99 /* Current and future revisions of the MSP432P401x device */
100 device_type = MSP432P401X;
101 } else {
102 /* Unknown or unanticipated hardware revision */
103 device_type = MSP432P401X_GUESS;
104 }
105 break;
106 case 0xA010:
107 case 0xA012:
108 case 0xA016:
109 case 0xA019:
110 case 0xA01F:
111 case 0xA020:
112 case 0xA022:
113 case 0xA026:
114 case 0xA029:
115 case 0xA02F:
116 /* Device is definitely MSP432P411x, check hardware revision */
117 if (hardware_rev >= 0x41 && hardware_rev <= 0x49) {
118 /* Current and future revisions of the MSP432P411x device */
119 device_type = MSP432P411X;
120 } else {
121 /* Unknown or unanticipated hardware revision */
122 device_type = MSP432P411X_GUESS;
123 }
124 break;
125 case 0xFFFF:
126 /* Device is very early silicon that has been deprecated */
127 device_type = MSP432P401X_DEPR;
128 break;
129 default:
130 if (device_id < 0xA010) {
131 /* Wild guess that this is an MSP432P401x */
132 device_type = MSP432P401X_GUESS;
133 } else {
134 /* Reasonable guess that this is a new variant */
135 device_type = MSP432P411X_GUESS;
136 }
137 break;
138 }
139 }
140
141 return device_type;
142 }
143
144 static const char *msp432_return_text(uint32_t return_code)
145 {
146 switch (return_code) {
147 case FLASH_BUSY:
148 return "FLASH_BUSY";
149 case FLASH_SUCCESS:
150 return "FLASH_SUCCESS";
151 case FLASH_ERROR:
152 return "FLASH_ERROR";
153 case FLASH_TIMEOUT_ERROR:
154 return "FLASH_TIMEOUT_ERROR";
155 case FLASH_VERIFY_ERROR:
156 return "FLASH_VERIFY_WRONG";
157 case FLASH_WRONG_COMMAND:
158 return "FLASH_WRONG_COMMAND";
159 case FLASH_POWER_ERROR:
160 return "FLASH_POWER_ERROR";
161 default:
162 return "UNDEFINED_RETURN_CODE";
163 }
164 }
165
166 static void msp432_init_params(struct msp432_algo_params *algo_params)
167 {
168 buf_set_u32(algo_params->flash_command, 0, 32, FLASH_NO_COMMAND);
169 buf_set_u32(algo_params->return_code, 0, 32, 0);
170 buf_set_u32(algo_params->_reserved0, 0, 32, 0);
171 buf_set_u32(algo_params->address, 0, 32, 0);
172 buf_set_u32(algo_params->length, 0, 32, 0);
173 buf_set_u32(algo_params->buffer1_status, 0, 32, BUFFER_INACTIVE);
174 buf_set_u32(algo_params->buffer2_status, 0, 32, BUFFER_INACTIVE);
175 buf_set_u32(algo_params->erase_param, 0, 32, FLASH_ERASE_MAIN);
176 buf_set_u32(algo_params->unlock_bsl, 0, 32, FLASH_LOCK_BSL);
177 }
178
179 static int msp432_exec_cmd(struct target *target, struct msp432_algo_params
180 *algo_params, uint32_t command)
181 {
182 int retval;
183
184 /* Make sure the given params do not include the command */
185 buf_set_u32(algo_params->flash_command, 0, 32, FLASH_NO_COMMAND);
186 buf_set_u32(algo_params->return_code, 0, 32, 0);
187 buf_set_u32(algo_params->buffer1_status, 0, 32, BUFFER_INACTIVE);
188 buf_set_u32(algo_params->buffer2_status, 0, 32, BUFFER_INACTIVE);
189
190 /* Write out parameters to target memory */
191 retval = target_write_buffer(target, ALGO_PARAMS_BASE_ADDR,
192 sizeof(struct msp432_algo_params), (uint8_t *)algo_params);
193 if (ERROR_OK != retval)
194 return retval;
195
196 /* Write out command to target memory */
197 retval = target_write_buffer(target, ALGO_FLASH_COMMAND_ADDR,
198 sizeof(command), (uint8_t *)&command);
199
200 return retval;
201 }
202
203 static int msp432_wait_return_code(struct target *target)
204 {
205 uint32_t return_code = 0;
206 long long start_ms;
207 long long elapsed_ms;
208
209 int retval = ERROR_OK;
210
211 start_ms = timeval_ms();
212 while ((0 == return_code) || (FLASH_BUSY == return_code)) {
213 retval = target_read_buffer(target, ALGO_RETURN_CODE_ADDR,
214 sizeof(return_code), (uint8_t *)&return_code);
215 if (ERROR_OK != retval)
216 return retval;
217
218 elapsed_ms = timeval_ms() - start_ms;
219 if (elapsed_ms > 500)
220 keep_alive();
221 if (elapsed_ms > FLASH_TIMEOUT)
222 break;
223 };
224
225 if (FLASH_SUCCESS != return_code) {
226 LOG_ERROR("msp432: Flash operation failed: %s",
227 msp432_return_text(return_code));
228 return ERROR_FAIL;
229 }
230
231 return ERROR_OK;
232 }
233
234 static int msp432_wait_inactive(struct target *target, uint32_t buffer)
235 {
236 uint32_t status_code = BUFFER_ACTIVE;
237 uint32_t status_addr;
238 long long start_ms;
239 long long elapsed_ms;
240
241 int retval;
242
243 switch (buffer) {
244 case 1: /* Buffer 1 */
245 status_addr = ALGO_BUFFER1_STATUS_ADDR;
246 break;
247 case 2: /* Buffer 2 */
248 status_addr = ALGO_BUFFER2_STATUS_ADDR;
249 break;
250 default:
251 return ERROR_FAIL;
252 }
253
254 start_ms = timeval_ms();
255 while (BUFFER_INACTIVE != status_code) {
256 retval = target_read_buffer(target, status_addr, sizeof(status_code),
257 (uint8_t *)&status_code);
258 if (ERROR_OK != retval)
259 return retval;
260
261 elapsed_ms = timeval_ms() - start_ms;
262 if (elapsed_ms > 500)
263 keep_alive();
264 if (elapsed_ms > FLASH_TIMEOUT)
265 break;
266 };
267
268 if (BUFFER_INACTIVE != status_code) {
269 LOG_ERROR(
270 "msp432: Flash operation failed: buffer not written to flash");
271 return ERROR_FAIL;
272 }
273
274 return ERROR_OK;
275 }
276
277 static int msp432_init(struct flash_bank *bank)
278 {
279 struct target *target = bank->target;
280 struct msp432_bank *msp432_bank = bank->driver_priv;
281 struct msp432_algo_params algo_params;
282 struct reg_param reg_params[1];
283
284 const uint8_t *loader_code;
285 uint32_t loader_size;
286 uint32_t algo_entry_addr;
287 int retval;
288
289 /* Make sure we've probed the flash to get the device and size */
290 retval = msp432_auto_probe(bank);
291 if (ERROR_OK != retval)
292 return retval;
293
294 /* Choose appropriate flash helper algorithm */
295 switch (msp432_bank->device_type) {
296 case MSP432P401X:
297 case MSP432P401X_DEPR:
298 case MSP432P401X_GUESS:
299 default:
300 loader_code = msp432p401x_algo;
301 loader_size = sizeof(msp432p401x_algo);
302 algo_entry_addr = P4_ALGO_ENTRY_ADDR;
303 break;
304 case MSP432P411X:
305 case MSP432P411X_GUESS:
306 loader_code = msp432p411x_algo;
307 loader_size = sizeof(msp432p411x_algo);
308 algo_entry_addr = P4_ALGO_ENTRY_ADDR;
309 break;
310 case MSP432E401Y:
311 case MSP432E411Y:
312 case MSP432E4X_GUESS:
313 loader_code = msp432e4x_algo;
314 loader_size = sizeof(msp432e4x_algo);
315 algo_entry_addr = E4_ALGO_ENTRY_ADDR;
316 break;
317 }
318
319 /* Issue warnings if this is a device we may not be able to flash */
320 if (MSP432P401X_GUESS == msp432_bank->device_type ||
321 MSP432P411X_GUESS == msp432_bank->device_type) {
322 /* Explicit device type check failed. Report this. */
323 LOG_WARNING(
324 "msp432: Unrecognized MSP432P4 Device ID and Hardware "
325 "Rev (%04X, %02X)", msp432_bank->device_id,
326 msp432_bank->hardware_rev);
327 } else if (MSP432P401X_DEPR == msp432_bank->device_type) {
328 LOG_WARNING(
329 "msp432: MSP432P401x pre-production device (deprecated "
330 "silicon)\n" SUPPORT_MESSAGE);
331 } else if (MSP432E4X_GUESS == msp432_bank->device_type) {
332 /* Explicit device type check failed. Report this. */
333 LOG_WARNING(
334 "msp432: Unrecognized MSP432E4 DID0 and DID1 values "
335 "(%08X, %08X)", msp432_bank->device_id,
336 msp432_bank->hardware_rev);
337 }
338
339 /* Check for working area to use for flash helper algorithm */
340 if (NULL != msp432_bank->working_area)
341 target_free_working_area(target, msp432_bank->working_area);
342 retval = target_alloc_working_area(target, ALGO_WORKING_SIZE,
343 &msp432_bank->working_area);
344 if (ERROR_OK != retval)
345 return retval;
346
347 /* Confirm the defined working address is the area we need to use */
348 if (ALGO_BASE_ADDR != msp432_bank->working_area->address)
349 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
350
351 /* Write flash helper algorithm into target memory */
352 retval = target_write_buffer(target, ALGO_BASE_ADDR, loader_size,
353 loader_code);
354 if (ERROR_OK != retval)
355 return retval;
356
357 /* Initialize the ARMv7 specific info to run the algorithm */
358 msp432_bank->armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
359 msp432_bank->armv7m_info.core_mode = ARM_MODE_THREAD;
360
361 /* Initialize algorithm parameters to default values */
362 msp432_init_params(&algo_params);
363
364 /* Write out parameters to target memory */
365 retval = target_write_buffer(target, ALGO_PARAMS_BASE_ADDR,
366 sizeof(algo_params), (uint8_t *)&algo_params);
367 if (ERROR_OK != retval)
368 return retval;
369
370 /* Initialize stack pointer for flash helper algorithm */
371 init_reg_param(&reg_params[0], "sp", 32, PARAM_OUT);
372 buf_set_u32(reg_params[0].value, 0, 32, ALGO_STACK_POINTER_ADDR);
373
374 /* Begin executing the flash helper algorithm */
375 retval = target_start_algorithm(target, 0, 0, 1, reg_params,
376 algo_entry_addr, 0, &msp432_bank->armv7m_info);
377 destroy_reg_param(&reg_params[0]);
378 if (ERROR_OK != retval) {
379 LOG_ERROR("msp432: Failed to start flash helper algorithm");
380 return retval;
381 }
382
383 /*
384 * At this point, the algorithm is running on the target and
385 * ready to receive commands and data to flash the target
386 */
387
388 /* Issue the init command to the flash helper algorithm */
389 retval = msp432_exec_cmd(target, &algo_params, FLASH_INIT);
390 if (ERROR_OK != retval)
391 return retval;
392
393 retval = msp432_wait_return_code(target);
394
395 return retval;
396 }
397
398 static int msp432_quit(struct flash_bank *bank)
399 {
400 struct target *target = bank->target;
401 struct msp432_bank *msp432_bank = bank->driver_priv;
402 struct msp432_algo_params algo_params;
403
404 int retval;
405
406 /* Initialize algorithm parameters to default values */
407 msp432_init_params(&algo_params);
408
409 /* Issue the exit command to the flash helper algorithm */
410 retval = msp432_exec_cmd(target, &algo_params, FLASH_EXIT);
411 if (ERROR_OK != retval)
412 return retval;
413
414 (void)msp432_wait_return_code(target);
415
416 /* Regardless of the return code, attempt to halt the target */
417 (void)target_halt(target);
418
419 /* Now confirm target halted and clean up from flash helper algorithm */
420 retval = target_wait_algorithm(target, 0, NULL, 0, NULL, 0, FLASH_TIMEOUT,
421 &msp432_bank->armv7m_info);
422
423 target_free_working_area(target, msp432_bank->working_area);
424 msp432_bank->working_area = NULL;
425
426 return retval;
427 }
428
429 static int msp432_mass_erase(struct flash_bank *bank, bool all)
430 {
431 struct target *target = bank->target;
432 struct msp432_bank *msp432_bank = bank->driver_priv;
433 struct msp432_algo_params algo_params;
434
435 int retval;
436
437 if (TARGET_HALTED != target->state) {
438 LOG_ERROR("Target not halted");
439 return ERROR_TARGET_NOT_HALTED;
440 }
441
442 retval = msp432_init(bank);
443 if (ERROR_OK != retval)
444 return retval;
445
446 /* Initialize algorithm parameters to default values */
447 msp432_init_params(&algo_params);
448 if (all) {
449 buf_set_u32(algo_params.erase_param, 0, 32,
450 FLASH_ERASE_MAIN | FLASH_ERASE_INFO);
451 if (msp432_bank->unlock_bsl)
452 buf_set_u32(algo_params.unlock_bsl, 0, 32, FLASH_UNLOCK_BSL);
453 }
454
455 /* Issue the mass erase command to the flash helper algorithm */
456 retval = msp432_exec_cmd(target, &algo_params, FLASH_MASS_ERASE);
457 if (ERROR_OK != retval) {
458 (void)msp432_quit(bank);
459 return retval;
460 }
461
462 retval = msp432_wait_return_code(target);
463 if (ERROR_OK != retval) {
464 (void)msp432_quit(bank);
465 return retval;
466 }
467
468 retval = msp432_quit(bank);
469 if (ERROR_OK != retval)
470 return retval;
471
472 return retval;
473 }
474
475 COMMAND_HANDLER(msp432_mass_erase_command)
476 {
477 struct flash_bank *bank;
478 struct msp432_bank *msp432_bank;
479 bool all;
480 int retval;
481
482 if (0 == CMD_ARGC) {
483 all = false;
484 } else if (1 == CMD_ARGC) {
485 /* Check argument for how much to erase */
486 if (0 == strcmp(CMD_ARGV[0], "main"))
487 all = false;
488 else if (0 == strcmp(CMD_ARGV[0], "all"))
489 all = true;
490 else
491 return ERROR_COMMAND_SYNTAX_ERROR;
492 } else {
493 return ERROR_COMMAND_SYNTAX_ERROR;
494 }
495
496 retval = get_flash_bank_by_num(0, &bank);
497 if (ERROR_OK != retval)
498 return retval;
499
500 msp432_bank = bank->driver_priv;
501
502 if (MSP432E4 == msp432_bank->family_type) {
503 /* MSP432E4 does not have main vs info regions, ignore "all" */
504 all = false;
505 }
506
507 retval = msp432_mass_erase(bank, all);
508 if (ERROR_OK != retval)
509 return retval;
510
511 if (MSP432E4 == msp432_bank->family_type) {
512 /* MSP432E4 does not have main vs info regions */
513 LOG_INFO("msp432: Mass erase of flash is complete");
514 } else {
515 LOG_INFO("msp432: Mass erase of %s is complete",
516 all ? "main + info flash" : "main flash");
517 }
518
519 return ERROR_OK;
520 }
521
522 COMMAND_HANDLER(msp432_bsl_command)
523 {
524 struct flash_bank *bank;
525 struct msp432_bank *msp432_bank;
526 int retval;
527
528 if (1 < CMD_ARGC)
529 return ERROR_COMMAND_SYNTAX_ERROR;
530
531 retval = get_flash_bank_by_num(0, &bank);
532 if (ERROR_OK != retval)
533 return retval;
534
535 msp432_bank = bank->driver_priv;
536
537 if (MSP432E4 == msp432_bank->family_type) {
538 LOG_WARNING("msp432: MSP432E4 does not have a BSL region");
539 return ERROR_OK;
540 }
541
542 if (1 == CMD_ARGC) {
543 if (0 == strcmp(CMD_ARGV[0], "lock"))
544 msp432_bank->unlock_bsl = false;
545 else if (0 == strcmp(CMD_ARGV[0], "unlock"))
546 msp432_bank->unlock_bsl = true;
547 else
548 return ERROR_COMMAND_SYNTAX_ERROR;
549 }
550
551 LOG_INFO("msp432: BSL flash region is currently %slocked",
552 msp432_bank->unlock_bsl ? "un" : "");
553
554 return ERROR_OK;
555 }
556
557 FLASH_BANK_COMMAND_HANDLER(msp432_flash_bank_command)
558 {
559 struct msp432_bank *msp432_bank;
560
561 if (CMD_ARGC < 6)
562 return ERROR_COMMAND_SYNTAX_ERROR;
563
564 msp432_bank = malloc(sizeof(struct msp432_bank));
565 if (NULL == msp432_bank)
566 return ERROR_FAIL;
567
568 /* Initialize private flash information */
569 msp432_bank->device_id = 0;
570 msp432_bank->hardware_rev = 0;
571 msp432_bank->family_type = MSP432_NO_FAMILY;
572 msp432_bank->device_type = MSP432_NO_TYPE;
573 msp432_bank->sector_length = 0x1000;
574 msp432_bank->probed[0] = false;
575 msp432_bank->probed[1] = false;
576 msp432_bank->unlock_bsl = false;
577 msp432_bank->working_area = NULL;
578
579 /* Finish initialization of bank 0 (main flash) */
580 bank->driver_priv = msp432_bank;
581 bank->next = NULL;
582
583 return ERROR_OK;
584 }
585
586 static int msp432_erase(struct flash_bank *bank, int first, int last)
587 {
588 struct target *target = bank->target;
589 struct msp432_bank *msp432_bank = bank->driver_priv;
590 struct msp432_algo_params algo_params;
591
592 int retval;
593
594 if (TARGET_HALTED != target->state) {
595 LOG_ERROR("Target not halted");
596 return ERROR_TARGET_NOT_HALTED;
597 }
598
599 /* Do a mass erase if user requested all sectors of main flash */
600 if ((0 == bank->bank_number) && (first == 0) &&
601 (last == (bank->num_sectors - 1))) {
602 /* Request mass erase of main flash */
603 return msp432_mass_erase(bank, false);
604 }
605
606 retval = msp432_init(bank);
607 if (ERROR_OK != retval)
608 return retval;
609
610 /* Initialize algorithm parameters to default values */
611 msp432_init_params(&algo_params);
612
613 /* Adjust params if this is the info bank */
614 if (1 == bank->bank_number) {
615 buf_set_u32(algo_params.erase_param, 0, 32, FLASH_ERASE_INFO);
616 /* And flag if BSL is unlocked */
617 if (msp432_bank->unlock_bsl)
618 buf_set_u32(algo_params.unlock_bsl, 0, 32, FLASH_UNLOCK_BSL);
619 }
620
621 /* Erase requested sectors one by one */
622 for (int i = first; i <= last; i++) {
623
624 /* Skip TVL (read-only) sector of the info bank */
625 if (1 == bank->bank_number && 1 == i)
626 continue;
627
628 /* Skip BSL sectors of info bank if locked */
629 if (1 == bank->bank_number && (2 == i || 3 == i) &&
630 !msp432_bank->unlock_bsl)
631 continue;
632
633 /* Convert sector number to starting address of sector */
634 buf_set_u32(algo_params.address, 0, 32, bank->base +
635 (i * msp432_bank->sector_length));
636
637 /* Issue the sector erase command to the flash helper algorithm */
638 retval = msp432_exec_cmd(target, &algo_params, FLASH_SECTOR_ERASE);
639 if (ERROR_OK != retval) {
640 (void)msp432_quit(bank);
641 return retval;
642 }
643
644 retval = msp432_wait_return_code(target);
645 if (ERROR_OK != retval) {
646 (void)msp432_quit(bank);
647 return retval;
648 }
649 }
650
651 retval = msp432_quit(bank);
652 if (ERROR_OK != retval)
653 return retval;
654
655 return retval;
656 }
657
658 static int msp432_protect(struct flash_bank *bank, int set, int first,
659 int last)
660 {
661 return ERROR_OK;
662 }
663
664 static int msp432_write(struct flash_bank *bank, const uint8_t *buffer,
665 uint32_t offset, uint32_t count)
666 {
667 struct target *target = bank->target;
668 struct msp432_bank *msp432_bank = bank->driver_priv;
669 struct msp432_algo_params algo_params;
670 uint32_t size;
671 uint32_t data_ready = BUFFER_DATA_READY;
672 long long start_ms;
673 long long elapsed_ms;
674
675 int retval;
676
677 if (TARGET_HALTED != target->state) {
678 LOG_ERROR("Target not halted");
679 return ERROR_TARGET_NOT_HALTED;
680 }
681
682 /*
683 * Block attempts to write to read-only sectors of flash
684 * The TVL region in sector 1 of the info flash is always read-only
685 * The BSL region in sectors 2 and 3 of the info flash may be unlocked
686 * The helper algorithm will hang on attempts to write to TVL
687 */
688 if (1 == bank->bank_number) {
689 /* Set read-only start to TVL sector */
690 uint32_t start = 0x1000;
691 /* Set read-only end after BSL region if locked */
692 uint32_t end = (msp432_bank->unlock_bsl) ? 0x2000 : 0x4000;
693 /* Check if request includes anything in read-only sectors */
694 if ((offset + count - 1) < start || offset >= end) {
695 /* The request includes no bytes in read-only sectors */
696 /* Fall out and process the request normally */
697 } else {
698 /* Send a request for anything before read-only sectors */
699 if (offset < start) {
700 uint32_t start_count = MIN(start - offset, count);
701 retval = msp432_write(bank, buffer, offset, start_count);
702 if (ERROR_OK != retval)
703 return retval;
704 }
705 /* Send a request for anything after read-only sectors */
706 if ((offset + count - 1) >= end) {
707 uint32_t skip = end - offset;
708 count -= skip;
709 offset += skip;
710 buffer += skip;
711 return msp432_write(bank, buffer, offset, count);
712 } else {
713 /* Request is entirely in read-only sectors */
714 return ERROR_OK;
715 }
716 }
717 }
718
719 retval = msp432_init(bank);
720 if (ERROR_OK != retval)
721 return retval;
722
723 /* Initialize algorithm parameters to default values */
724 msp432_init_params(&algo_params);
725
726 /* Set up parameters for requested flash write operation */
727 buf_set_u32(algo_params.address, 0, 32, bank->base + offset);
728 buf_set_u32(algo_params.length, 0, 32, count);
729
730 /* Check if this is the info bank */
731 if (1 == bank->bank_number) {
732 /* And flag if BSL is unlocked */
733 if (msp432_bank->unlock_bsl)
734 buf_set_u32(algo_params.unlock_bsl, 0, 32, FLASH_UNLOCK_BSL);
735 }
736
737 /* Set up flash helper algorithm to continuous flash mode */
738 retval = msp432_exec_cmd(target, &algo_params, FLASH_CONTINUOUS);
739 if (ERROR_OK != retval) {
740 (void)msp432_quit(bank);
741 return retval;
742 }
743
744 /* Write requested data, one buffer at a time */
745 start_ms = timeval_ms();
746 while (count > 0) {
747
748 if (count > ALGO_BUFFER_SIZE)
749 size = ALGO_BUFFER_SIZE;
750 else
751 size = count;
752
753 /* Put next block of data to flash into buffer */
754 retval = target_write_buffer(target, ALGO_BUFFER1_ADDR, size, buffer);
755 if (ERROR_OK != retval) {
756 LOG_ERROR("Unable to write data to target memory");
757 (void)msp432_quit(bank);
758 return ERROR_FLASH_OPERATION_FAILED;
759 }
760
761 /* Signal the flash helper algorithm that data is ready to flash */
762 retval = target_write_buffer(target, ALGO_BUFFER1_STATUS_ADDR,
763 sizeof(data_ready), (uint8_t *)&data_ready);
764 if (ERROR_OK != retval) {
765 (void)msp432_quit(bank);
766 return ERROR_FLASH_OPERATION_FAILED;
767 }
768
769 retval = msp432_wait_inactive(target, 1);
770 if (ERROR_OK != retval) {
771 (void)msp432_quit(bank);
772 return retval;
773 }
774
775 count -= size;
776 buffer += size;
777
778 elapsed_ms = timeval_ms() - start_ms;
779 if (elapsed_ms > 500)
780 keep_alive();
781 }
782
783 /* Confirm that the flash helper algorithm is finished */
784 retval = msp432_wait_return_code(target);
785 if (ERROR_OK != retval) {
786 (void)msp432_quit(bank);
787 return retval;
788 }
789
790 retval = msp432_quit(bank);
791 if (ERROR_OK != retval)
792 return retval;
793
794 return retval;
795 }
796
797 static int msp432_probe(struct flash_bank *bank)
798 {
799 struct target *target = bank->target;
800 struct msp432_bank *msp432_bank = bank->driver_priv;
801
802 char *name;
803
804 uint32_t device_id;
805 uint32_t hardware_rev;
806
807 uint32_t base;
808 uint32_t sector_length;
809 uint32_t size;
810 int num_sectors;
811 int bank_id;
812
813 int retval;
814
815 bank_id = bank->bank_number;
816
817 /* Read the flash size register to determine this is a P4 or not */
818 /* MSP432P4s will return the size of flash. MSP432E4s will return zero */
819 retval = target_read_u32(target, P4_FLASH_MAIN_SIZE_REG, &size);
820 if (ERROR_OK != retval)
821 return retval;
822
823 if (0 == size) {
824 /* This is likely an MSP432E4 */
825 msp432_bank->family_type = MSP432E4;
826
827 retval = target_read_u32(target, E4_DID0_REG, &device_id);
828 if (ERROR_OK != retval)
829 return retval;
830
831 msp432_bank->device_id = device_id;
832
833 retval = target_read_u32(target, E4_DID1_REG, &hardware_rev);
834 if (ERROR_OK != retval)
835 return retval;
836
837 msp432_bank->hardware_rev = hardware_rev;
838 } else {
839 /* This is likely an MSP432P4 */
840 msp432_bank->family_type = MSP432P4;
841
842 retval = target_read_u32(target, P4_DEVICE_ID_REG, &device_id);
843 if (ERROR_OK != retval)
844 return retval;
845
846 msp432_bank->device_id = device_id & 0xFFFF;
847
848 retval = target_read_u32(target, P4_HARDWARE_REV_REG, &hardware_rev);
849 if (ERROR_OK != retval)
850 return retval;
851
852 msp432_bank->hardware_rev = hardware_rev & 0xFF;
853 }
854
855 msp432_bank->device_type = msp432_device_type(msp432_bank->family_type,
856 msp432_bank->device_id, msp432_bank->hardware_rev);
857
858 /* If not already allocated, create the info bank for MSP432P4 */
859 /* We could not determine it was needed until device was probed */
860 if (MSP432P4 == msp432_bank->family_type) {
861 /* If we've been given bank 1, then this was already done */
862 if (0 == bank_id) {
863 /* And only allocate it if it doesn't exist yet */
864 if (NULL == bank->next) {
865 struct flash_bank *info_bank;
866 info_bank = malloc(sizeof(struct flash_bank));
867 if (NULL == info_bank)
868 return ERROR_FAIL;
869
870 name = malloc(strlen(bank->name)+1);
871 if (NULL == name) {
872 free(info_bank);
873 return ERROR_FAIL;
874 }
875 strcpy(name, bank->name);
876
877 /* Initialize bank 1 (info region) */
878 info_bank->name = name;
879 info_bank->target = bank->target;
880 info_bank->driver = bank->driver;
881 info_bank->driver_priv = bank->driver_priv;
882 info_bank->bank_number = 1;
883 info_bank->base = 0x00200000;
884 info_bank->size = 0;
885 info_bank->chip_width = 0;
886 info_bank->bus_width = 0;
887 info_bank->erased_value = 0xff;
888 info_bank->default_padded_value = 0xff;
889 info_bank->write_start_alignment = 0;
890 info_bank->write_end_alignment = 0;
891 info_bank->minimal_write_gap = FLASH_WRITE_GAP_SECTOR;
892 info_bank->num_sectors = 0;
893 info_bank->sectors = NULL;
894 info_bank->num_prot_blocks = 0;
895 info_bank->prot_blocks = NULL;
896 info_bank->next = NULL;
897
898 /* Enable the new bank */
899 bank->next = info_bank;
900 }
901 }
902 }
903
904 if (MSP432P4 == msp432_bank->family_type) {
905 /* Set up MSP432P4 specific flash parameters */
906 if (0 == bank_id) {
907 retval = target_read_u32(target, P4_FLASH_MAIN_SIZE_REG, &size);
908 if (ERROR_OK != retval)
909 return retval;
910
911 base = P4_FLASH_MAIN_BASE;
912 sector_length = P4_SECTOR_LENGTH;
913 num_sectors = size / sector_length;
914 } else if (1 == bank_id) {
915 if (msp432_bank->device_type == MSP432P411X ||
916 msp432_bank->device_type == MSP432P411X_GUESS) {
917 /* MSP432P411x has an info size register, use that for size */
918 retval = target_read_u32(target, P4_FLASH_INFO_SIZE_REG, &size);
919 if (ERROR_OK != retval)
920 return retval;
921 } else {
922 /* All other MSP432P401x devices have fixed info region size */
923 size = 0x4000; /* 16 KB info region */
924 }
925 base = P4_FLASH_INFO_BASE;
926 sector_length = P4_SECTOR_LENGTH;
927 num_sectors = size / sector_length;
928 } else {
929 /* Invalid bank number somehow */
930 return ERROR_FAIL;
931 }
932 } else {
933 /* Set up MSP432E4 specific flash parameters */
934 base = E4_FLASH_BASE;
935 size = E4_FLASH_SIZE;
936 sector_length = E4_SECTOR_LENGTH;
937 num_sectors = size / sector_length;
938 }
939
940 if (NULL != bank->sectors) {
941 free(bank->sectors);
942 bank->sectors = NULL;
943 }
944
945 bank->sectors = malloc(sizeof(struct flash_sector) * num_sectors);
946 if (NULL == bank->sectors)
947 return ERROR_FAIL;
948
949 bank->base = base;
950 bank->size = size;
951 bank->write_start_alignment = 0;
952 bank->write_end_alignment = 0;
953 bank->num_sectors = num_sectors;
954 msp432_bank->sector_length = sector_length;
955
956 for (int i = 0; i < num_sectors; i++) {
957 bank->sectors[i].offset = i * sector_length;
958 bank->sectors[i].size = sector_length;
959 bank->sectors[i].is_erased = -1;
960 bank->sectors[i].is_protected = 0;
961 }
962
963 /* We've successfully determined the stats on this flash bank */
964 msp432_bank->probed[bank_id] = true;
965
966 /* If we fall through to here, then all went well */
967
968 return ERROR_OK;
969 }
970
971 static int msp432_auto_probe(struct flash_bank *bank)
972 {
973 struct msp432_bank *msp432_bank = bank->driver_priv;
974
975 int retval = ERROR_OK;
976
977 if (bank->bank_number < 0 || bank->bank_number > 1) {
978 /* Invalid bank number somehow */
979 return ERROR_FAIL;
980 }
981
982 if (!msp432_bank->probed[bank->bank_number])
983 retval = msp432_probe(bank);
984
985 return retval;
986 }
987
988 static int msp432_protect_check(struct flash_bank *bank)
989 {
990 return ERROR_OK;
991 }
992
993 static int msp432_info(struct flash_bank *bank, char *buf, int buf_size)
994 {
995 struct msp432_bank *msp432_bank = bank->driver_priv;
996 int printed = 0;
997
998 switch (msp432_bank->device_type) {
999 case MSP432P401X_DEPR:
1000 if (0xFFFF == msp432_bank->device_id) {
1001 /* Very early pre-production silicon currently deprecated */
1002 printed = snprintf(buf, buf_size,
1003 "MSP432P401x pre-production device (deprecated silicon)\n"
1004 SUPPORT_MESSAGE);
1005 } else {
1006 /* Revision A or B silicon, also deprecated */
1007 printed = snprintf(buf, buf_size,
1008 "MSP432P401x Device Rev %c (deprecated silicon)\n"
1009 SUPPORT_MESSAGE, (char)msp432_bank->hardware_rev);
1010 }
1011 break;
1012 case MSP432P401X:
1013 printed = snprintf(buf, buf_size,
1014 "MSP432P401x Device Rev %c\n",
1015 (char)msp432_bank->hardware_rev);
1016 break;
1017 case MSP432P411X:
1018 printed = snprintf(buf, buf_size,
1019 "MSP432P411x Device Rev %c\n",
1020 (char)msp432_bank->hardware_rev);
1021 break;
1022 case MSP432E401Y:
1023 printed = snprintf(buf, buf_size, "MSP432E401Y Device\n");
1024 break;
1025 case MSP432E411Y:
1026 printed = snprintf(buf, buf_size, "MSP432E411Y Device\n");
1027 break;
1028 case MSP432E4X_GUESS:
1029 printed = snprintf(buf, buf_size,
1030 "Unrecognized MSP432E4 DID0 and DID1 IDs (%08X, %08X)",
1031 msp432_bank->device_id, msp432_bank->hardware_rev);
1032 break;
1033 case MSP432P401X_GUESS:
1034 case MSP432P411X_GUESS:
1035 default:
1036 printed = snprintf(buf, buf_size,
1037 "Unrecognized MSP432P4 Device ID and Hardware Rev (%04X, %02X)",
1038 msp432_bank->device_id, msp432_bank->hardware_rev);
1039 break;
1040 }
1041
1042 buf_size -= printed;
1043
1044 if (0 > buf_size)
1045 return ERROR_BUF_TOO_SMALL;
1046
1047 return ERROR_OK;
1048 }
1049
1050 static void msp432_flash_free_driver_priv(struct flash_bank *bank)
1051 {
1052 /* A single private struct is shared between main and info banks */
1053 /* Only free it on the call for main bank (#0) */
1054 if ((0 == bank->bank_number) && (NULL != bank->driver_priv))
1055 free(bank->driver_priv);
1056 /* Forget about the private struct on both main and info banks */
1057 bank->driver_priv = NULL;
1058 }
1059
1060 static const struct command_registration msp432_exec_command_handlers[] = {
1061 {
1062 .name = "mass_erase",
1063 .handler = msp432_mass_erase_command,
1064 .mode = COMMAND_EXEC,
1065 .help = "Erase entire flash memory on device.",
1066 .usage = "['main' | 'all']",
1067 },
1068 {
1069 .name = "bsl",
1070 .handler = msp432_bsl_command,
1071 .mode = COMMAND_EXEC,
1072 .help = "Allow BSL to be erased or written by flash commands.",
1073 .usage = "['unlock' | 'lock']",
1074 },
1075 COMMAND_REGISTRATION_DONE
1076 };
1077
1078 static const struct command_registration msp432_command_handlers[] = {
1079 {
1080 .name = "msp432",
1081 .mode = COMMAND_EXEC,
1082 .help = "MSP432 flash command group",
1083 .usage = "",
1084 .chain = msp432_exec_command_handlers,
1085 },
1086 COMMAND_REGISTRATION_DONE
1087 };
1088
1089 struct flash_driver msp432_flash = {
1090 .name = "msp432",
1091 .commands = msp432_command_handlers,
1092 .flash_bank_command = msp432_flash_bank_command,
1093 .erase = msp432_erase,
1094 .protect = msp432_protect,
1095 .write = msp432_write,
1096 .read = default_flash_read,
1097 .probe = msp432_probe,
1098 .auto_probe = msp432_auto_probe,
1099 .erase_check = default_flash_blank_check,
1100 .protect_check = msp432_protect_check,
1101 .info = msp432_info,
1102 .free_driver_priv = msp432_flash_free_driver_priv,
1103 };

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)