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
;
54 struct working_area
*working_area
;
55 struct armv7m_algorithm armv7m_info
;
58 static int msp432_auto_probe(struct flash_bank
*bank
);
60 static int msp432_device_type(uint32_t family_type
, uint32_t device_id
,
61 uint32_t hardware_rev
)
63 int device_type
= MSP432_NO_TYPE
;
65 if (MSP432E4
== family_type
) {
66 /* MSP432E4 device family */
68 if (device_id
== 0x180C0002) {
69 if (hardware_rev
== 0x102DC06E) {
71 device_type
= MSP432E401Y
;
72 } else if (hardware_rev
== 0x1032E076) {
74 device_type
= MSP432E411Y
;
76 /* Reasonable guess that this is a new variant */
77 device_type
= MSP432E4X_GUESS
;
80 /* Wild guess that this is an MSP432E4 */
81 device_type
= MSP432E4X_GUESS
;
84 /* MSP432P4 device family */
86 /* Examine the device ID and hardware revision to get the device type */
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
;
102 /* Unknown or unanticipated hardware revision */
103 device_type
= MSP432P401X_GUESS
;
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
;
121 /* Unknown or unanticipated hardware revision */
122 device_type
= MSP432P411X_GUESS
;
126 /* Device is very early silicon that has been deprecated */
127 device_type
= MSP432P401X_DEPR
;
130 if (device_id
< 0xA010) {
131 /* Wild guess that this is an MSP432P401x */
132 device_type
= MSP432P401X_GUESS
;
134 /* Reasonable guess that this is a new variant */
135 device_type
= MSP432P411X_GUESS
;
144 static const char *msp432_return_text(uint32_t return_code
)
146 switch (return_code
) {
150 return "FLASH_SUCCESS";
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";
162 return "UNDEFINED_RETURN_CODE";
166 static void msp432_init_params(struct msp432_algo_params
*algo_params
)
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
);
179 static int msp432_exec_cmd(struct target
*target
, struct msp432_algo_params
180 *algo_params
, uint32_t command
)
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
);
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
)
196 /* Write out command to target memory */
197 retval
= target_write_buffer(target
, ALGO_FLASH_COMMAND_ADDR
,
198 sizeof(command
), (uint8_t *)&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_buffer(target
, ALGO_RETURN_CODE_ADDR
,
214 sizeof(return_code
), (uint8_t *)&return_code
);
215 if (ERROR_OK
!= retval
)
218 elapsed_ms
= timeval_ms() - start_ms
;
219 if (elapsed_ms
> 500)
221 if (elapsed_ms
> FLASH_TIMEOUT
)
225 if (FLASH_SUCCESS
!= return_code
) {
226 LOG_ERROR("msp432: Flash operation failed: %s",
227 msp432_return_text(return_code
));
234 static int msp432_wait_inactive(struct target
*target
, uint32_t buffer
)
236 uint32_t status_code
= BUFFER_ACTIVE
;
237 uint32_t status_addr
;
239 long long elapsed_ms
;
244 case 1: /* Buffer 1 */
245 status_addr
= ALGO_BUFFER1_STATUS_ADDR
;
247 case 2: /* Buffer 2 */
248 status_addr
= ALGO_BUFFER2_STATUS_ADDR
;
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
)
261 elapsed_ms
= timeval_ms() - start_ms
;
262 if (elapsed_ms
> 500)
264 if (elapsed_ms
> FLASH_TIMEOUT
)
268 if (BUFFER_INACTIVE
!= status_code
) {
270 "msp432: Flash operation failed: buffer not written to flash");
277 static int msp432_init(struct flash_bank
*bank
)
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];
284 const uint8_t *loader_code
;
285 uint32_t loader_size
;
286 uint32_t algo_entry_addr
;
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
)
294 /* Choose appropriate flash helper algorithm */
295 switch (msp432_bank
->device_type
) {
297 case MSP432P401X_DEPR
:
298 case MSP432P401X_GUESS
:
300 loader_code
= msp432p401x_algo
;
301 loader_size
= sizeof(msp432p401x_algo
);
302 algo_entry_addr
= P4_ALGO_ENTRY_ADDR
;
305 case MSP432P411X_GUESS
:
306 loader_code
= msp432p411x_algo
;
307 loader_size
= sizeof(msp432p411x_algo
);
308 algo_entry_addr
= P4_ALGO_ENTRY_ADDR
;
312 case MSP432E4X_GUESS
:
313 loader_code
= msp432e4x_algo
;
314 loader_size
= sizeof(msp432e4x_algo
);
315 algo_entry_addr
= E4_ALGO_ENTRY_ADDR
;
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. */
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
) {
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. */
334 "msp432: Unrecognized MSP432E4 DID0 and DID1 values "
335 "(%08X, %08X)", msp432_bank
->device_id
,
336 msp432_bank
->hardware_rev
);
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
)
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
;
351 /* Write flash helper algorithm into target memory */
352 retval
= target_write_buffer(target
, ALGO_BASE_ADDR
, loader_size
,
354 if (ERROR_OK
!= retval
)
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
;
361 /* Initialize algorithm parameters to default values */
362 msp432_init_params(&algo_params
);
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
)
370 /* Initialize stack pointer for flash helper algorithm */
371 init_reg_param(®_params
[0], "sp", 32, PARAM_OUT
);
372 buf_set_u32(reg_params
[0].value
, 0, 32, ALGO_STACK_POINTER_ADDR
);
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(®_params
[0]);
378 if (ERROR_OK
!= retval
) {
379 LOG_ERROR("msp432: Failed to start flash helper algorithm");
384 * At this point, the algorithm is running on the target and
385 * ready to receive commands and data to flash the target
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
)
393 retval
= msp432_wait_return_code(target
);
398 static int msp432_quit(struct flash_bank
*bank
)
400 struct target
*target
= bank
->target
;
401 struct msp432_bank
*msp432_bank
= bank
->driver_priv
;
402 struct msp432_algo_params algo_params
;
406 /* Initialize algorithm parameters to default values */
407 msp432_init_params(&algo_params
);
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
)
414 (void)msp432_wait_return_code(target
);
416 /* Regardless of the return code, attempt to halt the target */
417 (void)target_halt(target
);
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
);
423 target_free_working_area(target
, msp432_bank
->working_area
);
424 msp432_bank
->working_area
= NULL
;
429 static int msp432_mass_erase(struct flash_bank
*bank
, bool all
)
431 struct target
*target
= bank
->target
;
432 struct msp432_bank
*msp432_bank
= bank
->driver_priv
;
433 struct msp432_algo_params algo_params
;
437 if (TARGET_HALTED
!= target
->state
) {
438 LOG_ERROR("Target not halted");
439 return ERROR_TARGET_NOT_HALTED
;
442 retval
= msp432_init(bank
);
443 if (ERROR_OK
!= retval
)
446 /* Initialize algorithm parameters to default values */
447 msp432_init_params(&algo_params
);
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
);
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
);
462 retval
= msp432_wait_return_code(target
);
463 if (ERROR_OK
!= retval
) {
464 (void)msp432_quit(bank
);
468 retval
= msp432_quit(bank
);
469 if (ERROR_OK
!= retval
)
475 COMMAND_HANDLER(msp432_mass_erase_command
)
477 struct flash_bank
*bank
;
478 struct msp432_bank
*msp432_bank
;
484 } else if (1 == CMD_ARGC
) {
485 /* Check argument for how much to erase */
486 if (0 == strcmp(CMD_ARGV
[0], "main"))
488 else if (0 == strcmp(CMD_ARGV
[0], "all"))
491 return ERROR_COMMAND_SYNTAX_ERROR
;
493 return ERROR_COMMAND_SYNTAX_ERROR
;
496 retval
= get_flash_bank_by_num(0, &bank
);
497 if (ERROR_OK
!= retval
)
500 msp432_bank
= bank
->driver_priv
;
502 if (MSP432E4
== msp432_bank
->family_type
) {
503 /* MSP432E4 does not have main vs info regions, ignore "all" */
507 retval
= msp432_mass_erase(bank
, all
);
508 if (ERROR_OK
!= retval
)
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");
515 LOG_INFO("msp432: Mass erase of %s is complete",
516 all
? "main + info flash" : "main flash");
522 COMMAND_HANDLER(msp432_bsl_command
)
524 struct flash_bank
*bank
;
525 struct msp432_bank
*msp432_bank
;
529 return ERROR_COMMAND_SYNTAX_ERROR
;
531 retval
= get_flash_bank_by_num(0, &bank
);
532 if (ERROR_OK
!= retval
)
535 msp432_bank
= bank
->driver_priv
;
537 if (MSP432E4
== msp432_bank
->family_type
) {
538 LOG_WARNING("msp432: MSP432E4 does not have a BSL region");
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;
548 return ERROR_COMMAND_SYNTAX_ERROR
;
551 LOG_INFO("msp432: BSL flash region is currently %slocked",
552 msp432_bank
->unlock_bsl
? "un" : "");
557 FLASH_BANK_COMMAND_HANDLER(msp432_flash_bank_command
)
559 struct msp432_bank
*msp432_bank
;
562 return ERROR_COMMAND_SYNTAX_ERROR
;
564 msp432_bank
= malloc(sizeof(struct msp432_bank
));
565 if (NULL
== msp432_bank
)
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
;
579 /* Finish initialization of bank 0 (main flash) */
580 bank
->driver_priv
= msp432_bank
;
586 static int msp432_erase(struct flash_bank
*bank
, int first
, int last
)
588 struct target
*target
= bank
->target
;
589 struct msp432_bank
*msp432_bank
= bank
->driver_priv
;
590 struct msp432_algo_params algo_params
;
594 if (TARGET_HALTED
!= target
->state
) {
595 LOG_ERROR("Target not halted");
596 return ERROR_TARGET_NOT_HALTED
;
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);
606 retval
= msp432_init(bank
);
607 if (ERROR_OK
!= retval
)
610 /* Initialize algorithm parameters to default values */
611 msp432_init_params(&algo_params
);
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
);
621 /* Erase requested sectors one by one */
622 for (int i
= first
; i
<= last
; i
++) {
624 /* Skip TVL (read-only) sector of the info bank */
625 if (1 == bank
->bank_number
&& 1 == i
)
628 /* Skip BSL sectors of info bank if locked */
629 if (1 == bank
->bank_number
&& (2 == i
|| 3 == i
) &&
630 !msp432_bank
->unlock_bsl
)
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
));
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
);
644 retval
= msp432_wait_return_code(target
);
645 if (ERROR_OK
!= retval
) {
646 (void)msp432_quit(bank
);
651 retval
= msp432_quit(bank
);
652 if (ERROR_OK
!= retval
)
658 static int msp432_write(struct flash_bank
*bank
, const uint8_t *buffer
,
659 uint32_t offset
, uint32_t count
)
661 struct target
*target
= bank
->target
;
662 struct msp432_bank
*msp432_bank
= bank
->driver_priv
;
663 struct msp432_algo_params algo_params
;
665 uint32_t data_ready
= BUFFER_DATA_READY
;
667 long long elapsed_ms
;
671 if (TARGET_HALTED
!= target
->state
) {
672 LOG_ERROR("Target not halted");
673 return ERROR_TARGET_NOT_HALTED
;
677 * Block attempts to write to read-only sectors of flash
678 * The TVL region in sector 1 of the info flash is always read-only
679 * The BSL region in sectors 2 and 3 of the info flash may be unlocked
680 * The helper algorithm will hang on attempts to write to TVL
682 if (1 == bank
->bank_number
) {
683 /* Set read-only start to TVL sector */
684 uint32_t start
= 0x1000;
685 /* Set read-only end after BSL region if locked */
686 uint32_t end
= (msp432_bank
->unlock_bsl
) ? 0x2000 : 0x4000;
687 /* Check if request includes anything in read-only sectors */
688 if ((offset
+ count
- 1) < start
|| offset
>= end
) {
689 /* The request includes no bytes in read-only sectors */
690 /* Fall out and process the request normally */
692 /* Send a request for anything before read-only sectors */
693 if (offset
< start
) {
694 uint32_t start_count
= MIN(start
- offset
, count
);
695 retval
= msp432_write(bank
, buffer
, offset
, start_count
);
696 if (ERROR_OK
!= retval
)
699 /* Send a request for anything after read-only sectors */
700 if ((offset
+ count
- 1) >= end
) {
701 uint32_t skip
= end
- offset
;
705 return msp432_write(bank
, buffer
, offset
, count
);
707 /* Request is entirely in read-only sectors */
713 retval
= msp432_init(bank
);
714 if (ERROR_OK
!= retval
)
717 /* Initialize algorithm parameters to default values */
718 msp432_init_params(&algo_params
);
720 /* Set up parameters for requested flash write operation */
721 buf_set_u32(algo_params
.address
, 0, 32, bank
->base
+ offset
);
722 buf_set_u32(algo_params
.length
, 0, 32, count
);
724 /* Check if this is the info bank */
725 if (1 == bank
->bank_number
) {
726 /* And flag if BSL is unlocked */
727 if (msp432_bank
->unlock_bsl
)
728 buf_set_u32(algo_params
.unlock_bsl
, 0, 32, FLASH_UNLOCK_BSL
);
731 /* Set up flash helper algorithm to continuous flash mode */
732 retval
= msp432_exec_cmd(target
, &algo_params
, FLASH_CONTINUOUS
);
733 if (ERROR_OK
!= retval
) {
734 (void)msp432_quit(bank
);
738 /* Write requested data, one buffer at a time */
739 start_ms
= timeval_ms();
742 if (count
> ALGO_BUFFER_SIZE
)
743 size
= ALGO_BUFFER_SIZE
;
747 /* Put next block of data to flash into buffer */
748 retval
= target_write_buffer(target
, ALGO_BUFFER1_ADDR
, size
, buffer
);
749 if (ERROR_OK
!= retval
) {
750 LOG_ERROR("Unable to write data to target memory");
751 (void)msp432_quit(bank
);
752 return ERROR_FLASH_OPERATION_FAILED
;
755 /* Signal the flash helper algorithm that data is ready to flash */
756 retval
= target_write_buffer(target
, ALGO_BUFFER1_STATUS_ADDR
,
757 sizeof(data_ready
), (uint8_t *)&data_ready
);
758 if (ERROR_OK
!= retval
) {
759 (void)msp432_quit(bank
);
760 return ERROR_FLASH_OPERATION_FAILED
;
763 retval
= msp432_wait_inactive(target
, 1);
764 if (ERROR_OK
!= retval
) {
765 (void)msp432_quit(bank
);
772 elapsed_ms
= timeval_ms() - start_ms
;
773 if (elapsed_ms
> 500)
777 /* Confirm that the flash helper algorithm is finished */
778 retval
= msp432_wait_return_code(target
);
779 if (ERROR_OK
!= retval
) {
780 (void)msp432_quit(bank
);
784 retval
= msp432_quit(bank
);
785 if (ERROR_OK
!= retval
)
791 static int msp432_probe(struct flash_bank
*bank
)
793 struct target
*target
= bank
->target
;
794 struct msp432_bank
*msp432_bank
= bank
->driver_priv
;
799 uint32_t hardware_rev
;
802 uint32_t sector_length
;
809 bank_id
= bank
->bank_number
;
811 /* Read the flash size register to determine this is a P4 or not */
812 /* MSP432P4s will return the size of flash. MSP432E4s will return zero */
813 retval
= target_read_u32(target
, P4_FLASH_MAIN_SIZE_REG
, &size
);
814 if (ERROR_OK
!= retval
)
818 /* This is likely an MSP432E4 */
819 msp432_bank
->family_type
= MSP432E4
;
821 retval
= target_read_u32(target
, E4_DID0_REG
, &device_id
);
822 if (ERROR_OK
!= retval
)
825 msp432_bank
->device_id
= device_id
;
827 retval
= target_read_u32(target
, E4_DID1_REG
, &hardware_rev
);
828 if (ERROR_OK
!= retval
)
831 msp432_bank
->hardware_rev
= hardware_rev
;
833 /* This is likely an MSP432P4 */
834 msp432_bank
->family_type
= MSP432P4
;
836 retval
= target_read_u32(target
, P4_DEVICE_ID_REG
, &device_id
);
837 if (ERROR_OK
!= retval
)
840 msp432_bank
->device_id
= device_id
& 0xFFFF;
842 retval
= target_read_u32(target
, P4_HARDWARE_REV_REG
, &hardware_rev
);
843 if (ERROR_OK
!= retval
)
846 msp432_bank
->hardware_rev
= hardware_rev
& 0xFF;
849 msp432_bank
->device_type
= msp432_device_type(msp432_bank
->family_type
,
850 msp432_bank
->device_id
, msp432_bank
->hardware_rev
);
852 /* If not already allocated, create the info bank for MSP432P4 */
853 /* We could not determine it was needed until device was probed */
854 if (MSP432P4
== msp432_bank
->family_type
) {
855 /* If we've been given bank 1, then this was already done */
857 /* And only allocate it if it doesn't exist yet */
858 if (NULL
== bank
->next
) {
859 struct flash_bank
*info_bank
;
860 info_bank
= malloc(sizeof(struct flash_bank
));
861 if (NULL
== info_bank
)
864 name
= malloc(strlen(bank
->name
)+1);
869 strcpy(name
, bank
->name
);
871 /* Initialize bank 1 (info region) */
872 info_bank
->name
= name
;
873 info_bank
->target
= bank
->target
;
874 info_bank
->driver
= bank
->driver
;
875 info_bank
->driver_priv
= bank
->driver_priv
;
876 info_bank
->bank_number
= 1;
877 info_bank
->base
= 0x00200000;
879 info_bank
->chip_width
= 0;
880 info_bank
->bus_width
= 0;
881 info_bank
->erased_value
= 0xff;
882 info_bank
->default_padded_value
= 0xff;
883 info_bank
->write_start_alignment
= 0;
884 info_bank
->write_end_alignment
= 0;
885 info_bank
->minimal_write_gap
= FLASH_WRITE_GAP_SECTOR
;
886 info_bank
->num_sectors
= 0;
887 info_bank
->sectors
= NULL
;
888 info_bank
->num_prot_blocks
= 0;
889 info_bank
->prot_blocks
= NULL
;
890 info_bank
->next
= NULL
;
892 /* Enable the new bank */
893 bank
->next
= info_bank
;
898 if (MSP432P4
== msp432_bank
->family_type
) {
899 /* Set up MSP432P4 specific flash parameters */
901 retval
= target_read_u32(target
, P4_FLASH_MAIN_SIZE_REG
, &size
);
902 if (ERROR_OK
!= retval
)
905 base
= P4_FLASH_MAIN_BASE
;
906 sector_length
= P4_SECTOR_LENGTH
;
907 num_sectors
= size
/ sector_length
;
908 } else if (1 == bank_id
) {
909 if (msp432_bank
->device_type
== MSP432P411X
||
910 msp432_bank
->device_type
== MSP432P411X_GUESS
) {
911 /* MSP432P411x has an info size register, use that for size */
912 retval
= target_read_u32(target
, P4_FLASH_INFO_SIZE_REG
, &size
);
913 if (ERROR_OK
!= retval
)
916 /* All other MSP432P401x devices have fixed info region size */
917 size
= 0x4000; /* 16 KB info region */
919 base
= P4_FLASH_INFO_BASE
;
920 sector_length
= P4_SECTOR_LENGTH
;
921 num_sectors
= size
/ sector_length
;
923 /* Invalid bank number somehow */
927 /* Set up MSP432E4 specific flash parameters */
928 base
= E4_FLASH_BASE
;
929 size
= E4_FLASH_SIZE
;
930 sector_length
= E4_SECTOR_LENGTH
;
931 num_sectors
= size
/ sector_length
;
934 if (NULL
!= bank
->sectors
) {
936 bank
->sectors
= NULL
;
939 bank
->sectors
= malloc(sizeof(struct flash_sector
) * num_sectors
);
940 if (NULL
== bank
->sectors
)
945 bank
->write_start_alignment
= 0;
946 bank
->write_end_alignment
= 0;
947 bank
->num_sectors
= num_sectors
;
948 msp432_bank
->sector_length
= sector_length
;
950 for (int i
= 0; i
< num_sectors
; i
++) {
951 bank
->sectors
[i
].offset
= i
* sector_length
;
952 bank
->sectors
[i
].size
= sector_length
;
953 bank
->sectors
[i
].is_erased
= -1;
954 bank
->sectors
[i
].is_protected
= 0;
957 /* We've successfully determined the stats on this flash bank */
958 msp432_bank
->probed
[bank_id
] = true;
960 /* If we fall through to here, then all went well */
965 static int msp432_auto_probe(struct flash_bank
*bank
)
967 struct msp432_bank
*msp432_bank
= bank
->driver_priv
;
969 int retval
= ERROR_OK
;
971 if (bank
->bank_number
< 0 || bank
->bank_number
> 1) {
972 /* Invalid bank number somehow */
976 if (!msp432_bank
->probed
[bank
->bank_number
])
977 retval
= msp432_probe(bank
);
982 static int msp432_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
984 struct msp432_bank
*msp432_bank
= bank
->driver_priv
;
987 switch (msp432_bank
->device_type
) {
988 case MSP432P401X_DEPR
:
989 if (0xFFFF == msp432_bank
->device_id
) {
990 /* Very early pre-production silicon currently deprecated */
991 printed
= snprintf(buf
, buf_size
,
992 "MSP432P401x pre-production device (deprecated silicon)\n"
995 /* Revision A or B silicon, also deprecated */
996 printed
= snprintf(buf
, buf_size
,
997 "MSP432P401x Device Rev %c (deprecated silicon)\n"
998 SUPPORT_MESSAGE
, (char)msp432_bank
->hardware_rev
);
1002 printed
= snprintf(buf
, buf_size
,
1003 "MSP432P401x Device Rev %c\n",
1004 (char)msp432_bank
->hardware_rev
);
1007 printed
= snprintf(buf
, buf_size
,
1008 "MSP432P411x Device Rev %c\n",
1009 (char)msp432_bank
->hardware_rev
);
1012 printed
= snprintf(buf
, buf_size
, "MSP432E401Y Device\n");
1015 printed
= snprintf(buf
, buf_size
, "MSP432E411Y Device\n");
1017 case MSP432E4X_GUESS
:
1018 printed
= snprintf(buf
, buf_size
,
1019 "Unrecognized MSP432E4 DID0 and DID1 IDs (%08X, %08X)",
1020 msp432_bank
->device_id
, msp432_bank
->hardware_rev
);
1022 case MSP432P401X_GUESS
:
1023 case MSP432P411X_GUESS
:
1025 printed
= snprintf(buf
, buf_size
,
1026 "Unrecognized MSP432P4 Device ID and Hardware Rev (%04X, %02X)",
1027 msp432_bank
->device_id
, msp432_bank
->hardware_rev
);
1031 buf_size
-= printed
;
1034 return ERROR_BUF_TOO_SMALL
;
1039 static void msp432_flash_free_driver_priv(struct flash_bank
*bank
)
1041 /* A single private struct is shared between main and info banks */
1042 /* Only free it on the call for main bank (#0) */
1043 if ((0 == bank
->bank_number
) && (NULL
!= bank
->driver_priv
))
1044 free(bank
->driver_priv
);
1045 /* Forget about the private struct on both main and info banks */
1046 bank
->driver_priv
= NULL
;
1049 static const struct command_registration msp432_exec_command_handlers
[] = {
1051 .name
= "mass_erase",
1052 .handler
= msp432_mass_erase_command
,
1053 .mode
= COMMAND_EXEC
,
1054 .help
= "Erase entire flash memory on device.",
1055 .usage
= "['main' | 'all']",
1059 .handler
= msp432_bsl_command
,
1060 .mode
= COMMAND_EXEC
,
1061 .help
= "Allow BSL to be erased or written by flash commands.",
1062 .usage
= "['unlock' | 'lock']",
1064 COMMAND_REGISTRATION_DONE
1067 static const struct command_registration msp432_command_handlers
[] = {
1070 .mode
= COMMAND_EXEC
,
1071 .help
= "MSP432 flash command group",
1073 .chain
= msp432_exec_command_handlers
,
1075 COMMAND_REGISTRATION_DONE
1078 struct flash_driver msp432_flash
= {
1080 .commands
= msp432_command_handlers
,
1081 .flash_bank_command
= msp432_flash_bank_command
,
1082 .erase
= msp432_erase
,
1083 .write
= msp432_write
,
1084 .read
= default_flash_read
,
1085 .probe
= msp432_probe
,
1086 .auto_probe
= msp432_auto_probe
,
1087 .erase_check
= default_flash_blank_check
,
1088 .info
= msp432_info
,
1089 .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)