1 /***************************************************************************
2 * Copyright (C) 2018 by Texas Instruments, Inc. *
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. *
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. *
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 ***************************************************************************/
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>
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
36 /* MSP432E4 hardware registers */
37 #define E4_DID0_REG 0x400FE000
38 #define E4_DID1_REG 0x400FE004
40 #define FLASH_TIMEOUT 8000
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"
48 uint32_t hardware_rev
;
51 uint32_t sector_length
;
55 struct working_area
*working_area
;
56 struct armv7m_algorithm armv7m_info
;
59 static int msp432_auto_probe(struct flash_bank
*bank
);
61 static int msp432_device_type(uint32_t family_type
, uint32_t device_id
,
62 uint32_t hardware_rev
)
64 int device_type
= MSP432_NO_TYPE
;
66 if (MSP432E4
== family_type
) {
67 /* MSP432E4 device family */
69 if (device_id
== 0x180C0002) {
70 if (hardware_rev
== 0x102DC06E) {
72 device_type
= MSP432E401Y
;
73 } else if (hardware_rev
== 0x1032E076) {
75 device_type
= MSP432E411Y
;
77 /* Reasonable guess that this is a new variant */
78 device_type
= MSP432E4X_GUESS
;
81 /* Wild guess that this is an MSP432E4 */
82 device_type
= MSP432E4X_GUESS
;
85 /* MSP432P4 device family */
87 /* Examine the device ID and hardware revision to get the device type */
95 /* Device is definitely MSP432P401x, check hardware revision */
96 if (hardware_rev
== 0x41 || hardware_rev
== 0x42) {
97 /* Rev A or B of the silicon has been deprecated */
98 device_type
= MSP432P401X_DEPR
;
99 } else if (hardware_rev
>= 0x43 && hardware_rev
<= 0x49) {
100 /* Current and future revisions of the MSP432P401x device */
101 device_type
= MSP432P401X
;
103 /* Unknown or unanticipated hardware revision */
104 device_type
= MSP432P401X_GUESS
;
117 /* Device is definitely MSP432P411x, check hardware revision */
118 if (hardware_rev
>= 0x41 && hardware_rev
<= 0x49) {
119 /* Current and future revisions of the MSP432P411x device */
120 device_type
= MSP432P411X
;
122 /* Unknown or unanticipated hardware revision */
123 device_type
= MSP432P411X_GUESS
;
127 /* Device is very early silicon that has been deprecated */
128 device_type
= MSP432P401X_DEPR
;
131 if (device_id
< 0xA010) {
132 /* Wild guess that this is an MSP432P401x */
133 device_type
= MSP432P401X_GUESS
;
135 /* Reasonable guess that this is a new variant */
136 device_type
= MSP432P411X_GUESS
;
145 static const char *msp432_return_text(uint32_t return_code
)
147 switch (return_code
) {
151 return "FLASH_SUCCESS";
153 return "FLASH_ERROR";
154 case FLASH_TIMEOUT_ERROR
:
155 return "FLASH_TIMEOUT_ERROR";
156 case FLASH_VERIFY_ERROR
:
157 return "FLASH_VERIFY_WRONG";
158 case FLASH_WRONG_COMMAND
:
159 return "FLASH_WRONG_COMMAND";
160 case FLASH_POWER_ERROR
:
161 return "FLASH_POWER_ERROR";
163 return "UNDEFINED_RETURN_CODE";
167 static void msp432_init_params(struct msp432_algo_params
*algo_params
)
169 buf_set_u32(algo_params
->flash_command
, 0, 32, FLASH_NO_COMMAND
);
170 buf_set_u32(algo_params
->return_code
, 0, 32, 0);
171 buf_set_u32(algo_params
->_reserved0
, 0, 32, 0);
172 buf_set_u32(algo_params
->address
, 0, 32, 0);
173 buf_set_u32(algo_params
->length
, 0, 32, 0);
174 buf_set_u32(algo_params
->buffer1_status
, 0, 32, BUFFER_INACTIVE
);
175 buf_set_u32(algo_params
->buffer2_status
, 0, 32, BUFFER_INACTIVE
);
176 buf_set_u32(algo_params
->erase_param
, 0, 32, FLASH_ERASE_MAIN
);
177 buf_set_u32(algo_params
->unlock_bsl
, 0, 32, FLASH_LOCK_BSL
);
180 static int msp432_exec_cmd(struct target
*target
, struct msp432_algo_params
181 *algo_params
, uint32_t command
)
185 /* Make sure the given params do not include the command */
186 buf_set_u32(algo_params
->flash_command
, 0, 32, FLASH_NO_COMMAND
);
187 buf_set_u32(algo_params
->return_code
, 0, 32, 0);
188 buf_set_u32(algo_params
->buffer1_status
, 0, 32, BUFFER_INACTIVE
);
189 buf_set_u32(algo_params
->buffer2_status
, 0, 32, BUFFER_INACTIVE
);
191 /* Write out parameters to target memory */
192 retval
= target_write_buffer(target
, ALGO_PARAMS_BASE_ADDR
,
193 sizeof(struct msp432_algo_params
), (uint8_t *)algo_params
);
194 if (ERROR_OK
!= retval
)
197 /* Write out command to target memory */
198 retval
= target_write_u32(target
, ALGO_FLASH_COMMAND_ADDR
, command
);
203 static int msp432_wait_return_code(struct target
*target
)
205 uint32_t return_code
= 0;
207 long long elapsed_ms
;
209 int retval
= ERROR_OK
;
211 start_ms
= timeval_ms();
212 while ((0 == return_code
) || (FLASH_BUSY
== return_code
)) {
213 retval
= target_read_u32(target
, ALGO_RETURN_CODE_ADDR
, &return_code
);
214 if (ERROR_OK
!= retval
)
217 elapsed_ms
= timeval_ms() - start_ms
;
218 if (elapsed_ms
> 500)
220 if (elapsed_ms
> FLASH_TIMEOUT
)
224 if (FLASH_SUCCESS
!= return_code
) {
225 LOG_ERROR("msp432: Flash operation failed: %s",
226 msp432_return_text(return_code
));
233 static int msp432_wait_inactive(struct target
*target
, uint32_t buffer
)
235 uint32_t status_code
= BUFFER_ACTIVE
;
236 uint32_t status_addr
;
238 long long elapsed_ms
;
243 case 1: /* Buffer 1 */
244 status_addr
= ALGO_BUFFER1_STATUS_ADDR
;
246 case 2: /* Buffer 2 */
247 status_addr
= ALGO_BUFFER2_STATUS_ADDR
;
253 start_ms
= timeval_ms();
254 while (BUFFER_INACTIVE
!= status_code
) {
255 retval
= target_read_u32(target
, status_addr
, &status_code
);
256 if (ERROR_OK
!= retval
)
259 elapsed_ms
= timeval_ms() - start_ms
;
260 if (elapsed_ms
> 500)
262 if (elapsed_ms
> FLASH_TIMEOUT
)
266 if (BUFFER_INACTIVE
!= status_code
) {
268 "msp432: Flash operation failed: buffer not written to flash");
275 static int msp432_init(struct flash_bank
*bank
)
277 struct target
*target
= bank
->target
;
278 struct msp432_bank
*msp432_bank
= bank
->driver_priv
;
279 struct msp432_algo_params algo_params
;
280 struct reg_param reg_params
[1];
282 const uint8_t *loader_code
;
283 uint32_t loader_size
;
284 uint32_t algo_entry_addr
;
287 /* Make sure we've probed the flash to get the device and size */
288 retval
= msp432_auto_probe(bank
);
289 if (ERROR_OK
!= retval
)
292 /* Choose appropriate flash helper algorithm */
293 switch (msp432_bank
->device_type
) {
295 case MSP432P401X_DEPR
:
296 case MSP432P401X_GUESS
:
298 loader_code
= msp432p401x_algo
;
299 loader_size
= sizeof(msp432p401x_algo
);
300 algo_entry_addr
= P4_ALGO_ENTRY_ADDR
;
303 case MSP432P411X_GUESS
:
304 loader_code
= msp432p411x_algo
;
305 loader_size
= sizeof(msp432p411x_algo
);
306 algo_entry_addr
= P4_ALGO_ENTRY_ADDR
;
310 case MSP432E4X_GUESS
:
311 loader_code
= msp432e4x_algo
;
312 loader_size
= sizeof(msp432e4x_algo
);
313 algo_entry_addr
= E4_ALGO_ENTRY_ADDR
;
317 /* Issue warnings if this is a device we may not be able to flash */
318 if (MSP432P401X_GUESS
== msp432_bank
->device_type
||
319 MSP432P411X_GUESS
== msp432_bank
->device_type
) {
320 /* Explicit device type check failed. Report this. */
322 "msp432: Unrecognized MSP432P4 Device ID and Hardware "
323 "Rev (%04X, %02X)", msp432_bank
->device_id
,
324 msp432_bank
->hardware_rev
);
325 } else if (MSP432P401X_DEPR
== msp432_bank
->device_type
) {
327 "msp432: MSP432P401x pre-production device (deprecated "
328 "silicon)\n" SUPPORT_MESSAGE
);
329 } else if (MSP432E4X_GUESS
== msp432_bank
->device_type
) {
330 /* Explicit device type check failed. Report this. */
332 "msp432: Unrecognized MSP432E4 DID0 and DID1 values "
333 "(%08X, %08X)", msp432_bank
->device_id
,
334 msp432_bank
->hardware_rev
);
337 /* Check for working area to use for flash helper algorithm */
338 if (NULL
!= msp432_bank
->working_area
)
339 target_free_working_area(target
, msp432_bank
->working_area
);
340 retval
= target_alloc_working_area(target
, ALGO_WORKING_SIZE
,
341 &msp432_bank
->working_area
);
342 if (ERROR_OK
!= retval
)
345 /* Confirm the defined working address is the area we need to use */
346 if (ALGO_BASE_ADDR
!= msp432_bank
->working_area
->address
)
347 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
349 /* Write flash helper algorithm into target memory */
350 retval
= target_write_buffer(target
, ALGO_BASE_ADDR
, loader_size
,
352 if (ERROR_OK
!= retval
)
355 /* Initialize the ARMv7 specific info to run the algorithm */
356 msp432_bank
->armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
357 msp432_bank
->armv7m_info
.core_mode
= ARM_MODE_THREAD
;
359 /* Initialize algorithm parameters to default values */
360 msp432_init_params(&algo_params
);
362 /* Write out parameters to target memory */
363 retval
= target_write_buffer(target
, ALGO_PARAMS_BASE_ADDR
,
364 sizeof(algo_params
), (uint8_t *)&algo_params
);
365 if (ERROR_OK
!= retval
)
368 /* Initialize stack pointer for flash helper algorithm */
369 init_reg_param(®_params
[0], "sp", 32, PARAM_OUT
);
370 buf_set_u32(reg_params
[0].value
, 0, 32, ALGO_STACK_POINTER_ADDR
);
372 /* Begin executing the flash helper algorithm */
373 retval
= target_start_algorithm(target
, 0, 0, 1, reg_params
,
374 algo_entry_addr
, 0, &msp432_bank
->armv7m_info
);
375 destroy_reg_param(®_params
[0]);
376 if (ERROR_OK
!= retval
) {
377 LOG_ERROR("msp432: Failed to start flash helper algorithm");
382 * At this point, the algorithm is running on the target and
383 * ready to receive commands and data to flash the target
386 /* Issue the init command to the flash helper algorithm */
387 retval
= msp432_exec_cmd(target
, &algo_params
, FLASH_INIT
);
388 if (ERROR_OK
!= retval
)
391 retval
= msp432_wait_return_code(target
);
396 static int msp432_quit(struct flash_bank
*bank
)
398 struct target
*target
= bank
->target
;
399 struct msp432_bank
*msp432_bank
= bank
->driver_priv
;
400 struct msp432_algo_params algo_params
;
404 /* Initialize algorithm parameters to default values */
405 msp432_init_params(&algo_params
);
407 /* Issue the exit command to the flash helper algorithm */
408 retval
= msp432_exec_cmd(target
, &algo_params
, FLASH_EXIT
);
409 if (ERROR_OK
!= retval
)
412 (void)msp432_wait_return_code(target
);
414 /* Regardless of the return code, attempt to halt the target */
415 (void)target_halt(target
);
417 /* Now confirm target halted and clean up from flash helper algorithm */
418 retval
= target_wait_algorithm(target
, 0, NULL
, 0, NULL
, 0, FLASH_TIMEOUT
,
419 &msp432_bank
->armv7m_info
);
421 target_free_working_area(target
, msp432_bank
->working_area
);
422 msp432_bank
->working_area
= NULL
;
427 static int msp432_mass_erase(struct flash_bank
*bank
, bool all
)
429 struct target
*target
= bank
->target
;
430 struct msp432_bank
*msp432_bank
= bank
->driver_priv
;
431 struct msp432_algo_params algo_params
;
435 if (TARGET_HALTED
!= target
->state
) {
436 LOG_ERROR("Target not halted");
437 return ERROR_TARGET_NOT_HALTED
;
440 retval
= msp432_init(bank
);
441 if (ERROR_OK
!= retval
)
444 /* Initialize algorithm parameters to default values */
445 msp432_init_params(&algo_params
);
447 buf_set_u32(algo_params
.erase_param
, 0, 32,
448 FLASH_ERASE_MAIN
| FLASH_ERASE_INFO
);
449 if (msp432_bank
->unlock_bsl
)
450 buf_set_u32(algo_params
.unlock_bsl
, 0, 32, FLASH_UNLOCK_BSL
);
453 /* Issue the mass erase command to the flash helper algorithm */
454 retval
= msp432_exec_cmd(target
, &algo_params
, FLASH_MASS_ERASE
);
455 if (ERROR_OK
!= retval
) {
456 (void)msp432_quit(bank
);
460 retval
= msp432_wait_return_code(target
);
461 if (ERROR_OK
!= retval
) {
462 (void)msp432_quit(bank
);
466 retval
= msp432_quit(bank
);
467 if (ERROR_OK
!= retval
)
473 COMMAND_HANDLER(msp432_mass_erase_command
)
475 struct flash_bank
*bank
;
476 struct msp432_bank
*msp432_bank
;
482 return ERROR_COMMAND_SYNTAX_ERROR
;
484 retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
485 if (retval
!= ERROR_OK
)
490 } else if (2 == CMD_ARGC
) {
491 /* Check argument for how much to erase */
492 if (0 == strcmp(CMD_ARGV
[1], "main"))
494 else if (0 == strcmp(CMD_ARGV
[1], "all"))
497 return ERROR_COMMAND_SYNTAX_ERROR
;
499 return ERROR_COMMAND_SYNTAX_ERROR
;
502 msp432_bank
= bank
->driver_priv
;
504 if (MSP432E4
== msp432_bank
->family_type
) {
505 /* MSP432E4 does not have main vs info regions, ignore "all" */
509 retval
= msp432_mass_erase(bank
, all
);
510 if (ERROR_OK
!= retval
)
513 if (MSP432E4
== msp432_bank
->family_type
) {
514 /* MSP432E4 does not have main vs info regions */
515 LOG_INFO("msp432: Mass erase of flash is complete");
517 LOG_INFO("msp432: Mass erase of %s is complete",
518 all
? "main + information flash" : "main flash");
524 COMMAND_HANDLER(msp432_bsl_command
)
526 struct flash_bank
*bank
;
527 struct msp432_bank
*msp432_bank
;
532 return ERROR_COMMAND_SYNTAX_ERROR
;
534 retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
535 if (retval
!= ERROR_OK
)
538 msp432_bank
= bank
->driver_priv
;
540 if (MSP432E4
== msp432_bank
->family_type
) {
541 LOG_WARNING("msp432: MSP432E4 does not have a BSL region");
546 if (0 == strcmp(CMD_ARGV
[1], "lock"))
547 msp432_bank
->unlock_bsl
= false;
548 else if (0 == strcmp(CMD_ARGV
[1], "unlock"))
549 msp432_bank
->unlock_bsl
= true;
551 return ERROR_COMMAND_SYNTAX_ERROR
;
552 } else if (1 != CMD_ARGC
) {
553 /* Extra, unknown argument passed in */
554 return ERROR_COMMAND_SYNTAX_ERROR
;
557 LOG_INFO("msp432: BSL flash region is currently %slocked",
558 msp432_bank
->unlock_bsl
? "un" : "");
563 FLASH_BANK_COMMAND_HANDLER(msp432_flash_bank_command
)
565 struct msp432_bank
*msp432_bank
;
568 return ERROR_COMMAND_SYNTAX_ERROR
;
570 /* Create shared private struct for flash banks */
571 msp432_bank
= malloc(sizeof(struct msp432_bank
));
572 if (NULL
== msp432_bank
)
575 /* Initialize private flash information */
576 msp432_bank
->device_id
= 0;
577 msp432_bank
->hardware_rev
= 0;
578 msp432_bank
->family_type
= MSP432_NO_FAMILY
;
579 msp432_bank
->device_type
= MSP432_NO_TYPE
;
580 msp432_bank
->sector_length
= 0x1000;
581 msp432_bank
->probed_main
= false;
582 msp432_bank
->probed_info
= false;
583 msp432_bank
->unlock_bsl
= false;
584 msp432_bank
->working_area
= NULL
;
586 /* Finish up initial settings here */
587 bank
->driver_priv
= msp432_bank
;
588 bank
->base
= FLASH_BASE
;
593 static int msp432_erase(struct flash_bank
*bank
, unsigned int first
,
596 struct target
*target
= bank
->target
;
597 struct msp432_bank
*msp432_bank
= bank
->driver_priv
;
598 struct msp432_algo_params algo_params
;
600 bool is_main
= FLASH_BASE
== bank
->base
;
601 bool is_info
= P4_FLASH_INFO_BASE
== bank
->base
;
605 if (TARGET_HALTED
!= target
->state
) {
606 LOG_ERROR("Target not halted");
607 return ERROR_TARGET_NOT_HALTED
;
610 /* Do a mass erase if user requested all sectors of main flash */
611 if (is_main
&& (first
== 0) && (last
== (bank
->num_sectors
- 1))) {
612 /* Request mass erase of main flash */
613 return msp432_mass_erase(bank
, false);
616 retval
= msp432_init(bank
);
617 if (ERROR_OK
!= retval
)
620 /* Initialize algorithm parameters to default values */
621 msp432_init_params(&algo_params
);
623 /* Adjust params if this is the info bank */
625 buf_set_u32(algo_params
.erase_param
, 0, 32, FLASH_ERASE_INFO
);
626 /* And flag if BSL is unlocked */
627 if (msp432_bank
->unlock_bsl
)
628 buf_set_u32(algo_params
.unlock_bsl
, 0, 32, FLASH_UNLOCK_BSL
);
631 /* Erase requested sectors one by one */
632 for (unsigned int i
= first
; i
<= last
; i
++) {
634 /* Skip TVL (read-only) sector of the info bank */
635 if (is_info
&& 1 == i
)
638 /* Skip BSL sectors of info bank if locked */
639 if (is_info
&& (2 == i
|| 3 == i
) &&
640 !msp432_bank
->unlock_bsl
)
643 /* Convert sector number to starting address of sector */
644 buf_set_u32(algo_params
.address
, 0, 32, bank
->base
+
645 (i
* msp432_bank
->sector_length
));
647 /* Issue the sector erase command to the flash helper algorithm */
648 retval
= msp432_exec_cmd(target
, &algo_params
, FLASH_SECTOR_ERASE
);
649 if (ERROR_OK
!= retval
) {
650 (void)msp432_quit(bank
);
654 retval
= msp432_wait_return_code(target
);
655 if (ERROR_OK
!= retval
) {
656 (void)msp432_quit(bank
);
661 retval
= msp432_quit(bank
);
662 if (ERROR_OK
!= retval
)
668 static int msp432_write(struct flash_bank
*bank
, const uint8_t *buffer
,
669 uint32_t offset
, uint32_t count
)
671 struct target
*target
= bank
->target
;
672 struct msp432_bank
*msp432_bank
= bank
->driver_priv
;
673 struct msp432_algo_params algo_params
;
675 uint32_t data_ready
= BUFFER_DATA_READY
;
677 long long elapsed_ms
;
679 bool is_info
= P4_FLASH_INFO_BASE
== bank
->base
;
683 if (TARGET_HALTED
!= target
->state
) {
684 LOG_ERROR("Target not halted");
685 return ERROR_TARGET_NOT_HALTED
;
689 * Block attempts to write to read-only sectors of flash
690 * The TVL region in sector 1 of the info flash is always read-only
691 * The BSL region in sectors 2 and 3 of the info flash may be unlocked
692 * The helper algorithm will hang on attempts to write to TVL
695 /* Set read-only start to TVL sector */
696 uint32_t start
= 0x1000;
697 /* Set read-only end after BSL region if locked */
698 uint32_t end
= (msp432_bank
->unlock_bsl
) ? 0x2000 : 0x4000;
699 /* Check if request includes anything in read-only sectors */
700 if ((offset
+ count
- 1) < start
|| offset
>= end
) {
701 /* The request includes no bytes in read-only sectors */
702 /* Fall out and process the request normally */
704 /* Send a request for anything before read-only sectors */
705 if (offset
< start
) {
706 uint32_t start_count
= MIN(start
- offset
, count
);
707 retval
= msp432_write(bank
, buffer
, offset
, start_count
);
708 if (ERROR_OK
!= retval
)
711 /* Send a request for anything after read-only sectors */
712 if ((offset
+ count
- 1) >= end
) {
713 uint32_t skip
= end
- offset
;
717 return msp432_write(bank
, buffer
, offset
, count
);
719 /* Request is entirely in read-only sectors */
725 retval
= msp432_init(bank
);
726 if (ERROR_OK
!= retval
)
729 /* Initialize algorithm parameters to default values */
730 msp432_init_params(&algo_params
);
732 /* Set up parameters for requested flash write operation */
733 buf_set_u32(algo_params
.address
, 0, 32, bank
->base
+ offset
);
734 buf_set_u32(algo_params
.length
, 0, 32, count
);
736 /* Check if this is the info bank */
738 /* And flag if BSL is unlocked */
739 if (msp432_bank
->unlock_bsl
)
740 buf_set_u32(algo_params
.unlock_bsl
, 0, 32, FLASH_UNLOCK_BSL
);
743 /* Set up flash helper algorithm to continuous flash mode */
744 retval
= msp432_exec_cmd(target
, &algo_params
, FLASH_CONTINUOUS
);
745 if (ERROR_OK
!= retval
) {
746 (void)msp432_quit(bank
);
750 /* Write requested data, one buffer at a time */
751 start_ms
= timeval_ms();
754 if (count
> ALGO_BUFFER_SIZE
)
755 size
= ALGO_BUFFER_SIZE
;
759 /* Put next block of data to flash into buffer */
760 retval
= target_write_buffer(target
, ALGO_BUFFER1_ADDR
, size
, buffer
);
761 if (ERROR_OK
!= retval
) {
762 LOG_ERROR("Unable to write data to target memory");
763 (void)msp432_quit(bank
);
764 return ERROR_FLASH_OPERATION_FAILED
;
767 /* Signal the flash helper algorithm that data is ready to flash */
768 retval
= target_write_u32(target
, ALGO_BUFFER1_STATUS_ADDR
,
770 if (ERROR_OK
!= retval
) {
771 (void)msp432_quit(bank
);
772 return ERROR_FLASH_OPERATION_FAILED
;
775 retval
= msp432_wait_inactive(target
, 1);
776 if (ERROR_OK
!= retval
) {
777 (void)msp432_quit(bank
);
784 elapsed_ms
= timeval_ms() - start_ms
;
785 if (elapsed_ms
> 500)
789 /* Confirm that the flash helper algorithm is finished */
790 retval
= msp432_wait_return_code(target
);
791 if (ERROR_OK
!= retval
) {
792 (void)msp432_quit(bank
);
796 retval
= msp432_quit(bank
);
797 if (ERROR_OK
!= retval
)
803 static int msp432_probe(struct flash_bank
*bank
)
805 struct target
*target
= bank
->target
;
806 struct msp432_bank
*msp432_bank
= bank
->driver_priv
;
809 uint32_t hardware_rev
;
811 uint32_t sector_length
;
813 unsigned int num_sectors
;
815 bool is_main
= FLASH_BASE
== bank
->base
;
816 bool is_info
= P4_FLASH_INFO_BASE
== bank
->base
;
820 /* Check if this bank has already been successfully probed */
821 if (is_main
&& msp432_bank
->probed_main
)
823 if (is_info
&& msp432_bank
->probed_info
)
826 /* Read the flash size register to determine this is a P4 or not */
827 /* MSP432P4s will return the size of flash. MSP432E4s will return zero */
828 retval
= target_read_u32(target
, P4_FLASH_MAIN_SIZE_REG
, &size
);
829 if (ERROR_OK
!= retval
)
833 /* This is likely an MSP432E4 */
834 msp432_bank
->family_type
= MSP432E4
;
836 retval
= target_read_u32(target
, E4_DID0_REG
, &device_id
);
837 if (ERROR_OK
!= retval
)
840 msp432_bank
->device_id
= device_id
;
842 retval
= target_read_u32(target
, E4_DID1_REG
, &hardware_rev
);
843 if (ERROR_OK
!= retval
)
846 msp432_bank
->hardware_rev
= hardware_rev
;
848 /* This is likely an MSP432P4 */
849 msp432_bank
->family_type
= MSP432P4
;
851 retval
= target_read_u32(target
, P4_DEVICE_ID_REG
, &device_id
);
852 if (ERROR_OK
!= retval
)
855 msp432_bank
->device_id
= device_id
& 0xFFFF;
857 retval
= target_read_u32(target
, P4_HARDWARE_REV_REG
, &hardware_rev
);
858 if (ERROR_OK
!= retval
)
861 msp432_bank
->hardware_rev
= hardware_rev
& 0xFF;
864 msp432_bank
->device_type
= msp432_device_type(msp432_bank
->family_type
,
865 msp432_bank
->device_id
, msp432_bank
->hardware_rev
);
867 if (MSP432P4
== msp432_bank
->family_type
) {
868 /* Set up MSP432P4 specific flash parameters */
870 retval
= target_read_u32(target
, P4_FLASH_MAIN_SIZE_REG
, &size
);
871 if (ERROR_OK
!= retval
)
874 sector_length
= P4_SECTOR_LENGTH
;
875 num_sectors
= size
/ sector_length
;
876 } else if (is_info
) {
877 if (msp432_bank
->device_type
== MSP432P411X
||
878 msp432_bank
->device_type
== MSP432P411X_GUESS
) {
879 /* MSP432P411x has an info size register, use that for size */
880 retval
= target_read_u32(target
, P4_FLASH_INFO_SIZE_REG
, &size
);
881 if (ERROR_OK
!= retval
)
884 /* All other MSP432P401x devices have fixed info region size */
885 size
= 0x4000; /* 16 KB info region */
887 sector_length
= P4_SECTOR_LENGTH
;
888 num_sectors
= size
/ sector_length
;
890 /* Invalid bank somehow */
894 /* Set up MSP432E4 specific flash parameters */
896 size
= E4_FLASH_SIZE
;
897 sector_length
= E4_SECTOR_LENGTH
;
898 num_sectors
= size
/ sector_length
;
900 /* Invalid bank somehow */
905 if (NULL
!= bank
->sectors
) {
907 bank
->sectors
= NULL
;
910 if (num_sectors
> 0) {
911 bank
->sectors
= malloc(sizeof(struct flash_sector
) * num_sectors
);
912 if (NULL
== bank
->sectors
)
917 bank
->write_start_alignment
= 0;
918 bank
->write_end_alignment
= 0;
919 bank
->num_sectors
= num_sectors
;
920 msp432_bank
->sector_length
= sector_length
;
922 for (unsigned int i
= 0; i
< num_sectors
; i
++) {
923 bank
->sectors
[i
].offset
= i
* sector_length
;
924 bank
->sectors
[i
].size
= sector_length
;
925 bank
->sectors
[i
].is_erased
= -1;
926 bank
->sectors
[i
].is_protected
= 0;
929 /* We've successfully determined the stats on this flash bank */
931 msp432_bank
->probed_main
= true;
933 msp432_bank
->probed_info
= true;
935 if (is_main
&& MSP432P4
== msp432_bank
->family_type
) {
936 /* Create the info flash bank needed by MSP432P4 variants */
937 struct flash_bank
*info
= calloc(sizeof(struct flash_bank
), 1);
941 /* Create a name for the info bank, append "_1" to main name */
942 char *name
= malloc(strlen(bank
->name
) + 3);
943 strcpy(name
, bank
->name
);
946 /* Initialize info bank */
948 info
->target
= bank
->target
;
949 info
->driver
= bank
->driver
;
950 info
->driver_priv
= msp432_bank
;
951 info
->base
= P4_FLASH_INFO_BASE
;
953 flash_bank_add(info
);
956 /* If we fall through to here, then all went well */
961 static int msp432_auto_probe(struct flash_bank
*bank
)
963 struct msp432_bank
*msp432_bank
= bank
->driver_priv
;
965 bool is_main
= FLASH_BASE
== bank
->base
;
966 bool is_info
= P4_FLASH_INFO_BASE
== bank
->base
;
968 int retval
= ERROR_OK
;
971 if (!msp432_bank
->probed_main
)
972 retval
= msp432_probe(bank
);
974 if (!msp432_bank
->probed_info
)
975 retval
= msp432_probe(bank
);
980 static int msp432_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
982 struct msp432_bank
*msp432_bank
= bank
->driver_priv
;
985 switch (msp432_bank
->device_type
) {
986 case MSP432P401X_DEPR
:
987 if (0xFFFF == msp432_bank
->device_id
) {
988 /* Very early pre-production silicon currently deprecated */
989 printed
= snprintf(buf
, buf_size
,
990 "MSP432P401x pre-production device (deprecated silicon)\n"
993 /* Revision A or B silicon, also deprecated */
994 printed
= snprintf(buf
, buf_size
,
995 "MSP432P401x Device Rev %c (deprecated silicon)\n"
996 SUPPORT_MESSAGE
, (char)msp432_bank
->hardware_rev
);
1000 printed
= snprintf(buf
, buf_size
,
1001 "MSP432P401x Device Rev %c\n",
1002 (char)msp432_bank
->hardware_rev
);
1005 printed
= snprintf(buf
, buf_size
,
1006 "MSP432P411x Device Rev %c\n",
1007 (char)msp432_bank
->hardware_rev
);
1010 printed
= snprintf(buf
, buf_size
, "MSP432E401Y Device\n");
1013 printed
= snprintf(buf
, buf_size
, "MSP432E411Y Device\n");
1015 case MSP432E4X_GUESS
:
1016 printed
= snprintf(buf
, buf_size
,
1017 "Unrecognized MSP432E4 DID0 and DID1 IDs (%08X, %08X)",
1018 msp432_bank
->device_id
, msp432_bank
->hardware_rev
);
1020 case MSP432P401X_GUESS
:
1021 case MSP432P411X_GUESS
:
1023 printed
= snprintf(buf
, buf_size
,
1024 "Unrecognized MSP432P4 Device ID and Hardware Rev (%04X, %02X)",
1025 msp432_bank
->device_id
, msp432_bank
->hardware_rev
);
1029 buf_size
-= printed
;
1032 return ERROR_BUF_TOO_SMALL
;
1037 static int msp432_protect_check(struct flash_bank
*bank
)
1039 /* Added to suppress warning, not needed for MSP432 flash */
1043 static void msp432_flash_free_driver_priv(struct flash_bank
*bank
)
1045 bool is_main
= FLASH_BASE
== bank
->base
;
1047 /* A single private struct is shared between main and info banks */
1048 /* Only free it on the call for main bank */
1049 if (is_main
&& (NULL
!= bank
->driver_priv
))
1050 free(bank
->driver_priv
);
1052 /* Forget about the private struct on both main and info banks */
1053 bank
->driver_priv
= NULL
;
1056 static const struct command_registration msp432_exec_command_handlers
[] = {
1058 .name
= "mass_erase",
1059 .handler
= msp432_mass_erase_command
,
1060 .mode
= COMMAND_EXEC
,
1061 .help
= "Erase entire flash memory on device.",
1062 .usage
= "bank_id ['main' | 'all']",
1066 .handler
= msp432_bsl_command
,
1067 .mode
= COMMAND_EXEC
,
1068 .help
= "Allow BSL to be erased or written by flash commands.",
1069 .usage
= "bank_id ['unlock' | 'lock']",
1071 COMMAND_REGISTRATION_DONE
1074 static const struct command_registration msp432_command_handlers
[] = {
1077 .mode
= COMMAND_EXEC
,
1078 .help
= "MSP432 flash command group",
1080 .chain
= msp432_exec_command_handlers
,
1082 COMMAND_REGISTRATION_DONE
1085 const struct flash_driver msp432_flash
= {
1087 .commands
= msp432_command_handlers
,
1088 .flash_bank_command
= msp432_flash_bank_command
,
1089 .erase
= msp432_erase
,
1090 .write
= msp432_write
,
1091 .read
= default_flash_read
,
1092 .probe
= msp432_probe
,
1093 .auto_probe
= msp432_auto_probe
,
1094 .erase_check
= default_flash_blank_check
,
1095 .protect_check
= msp432_protect_check
,
1096 .info
= msp432_info
,
1097 .free_driver_priv
= msp432_flash_free_driver_priv
,
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)