1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
24 #include "replacements.h"
31 #include "algorithm.h"
32 #include "binarybuffer.h"
37 int stm32x_register_commands(struct command_context_s
*cmd_ctx
);
38 int stm32x_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct flash_bank_s
*bank
);
39 int stm32x_erase(struct flash_bank_s
*bank
, int first
, int last
);
40 int stm32x_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
);
41 int stm32x_write(struct flash_bank_s
*bank
, u8
*buffer
, u32 offset
, u32 count
);
42 int stm32x_probe(struct flash_bank_s
*bank
);
43 int stm32x_handle_part_id_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
44 int stm32x_protect_check(struct flash_bank_s
*bank
);
45 int stm32x_erase_check(struct flash_bank_s
*bank
);
46 int stm32x_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
);
48 int stm32x_handle_lock_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
49 int stm32x_handle_unlock_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
50 int stm32x_handle_options_read_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
51 int stm32x_handle_options_write_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
52 int stm32x_handle_mass_erase_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
54 flash_driver_t stm32x_flash
=
57 .register_commands
= stm32x_register_commands
,
58 .flash_bank_command
= stm32x_flash_bank_command
,
59 .erase
= stm32x_erase
,
60 .protect
= stm32x_protect
,
61 .write
= stm32x_write
,
62 .probe
= stm32x_probe
,
63 .erase_check
= stm32x_erase_check
,
64 .protect_check
= stm32x_protect_check
,
68 int stm32x_register_commands(struct command_context_s
*cmd_ctx
)
70 command_t
*stm32x_cmd
= register_command(cmd_ctx
, NULL
, "stm32x", NULL
, COMMAND_ANY
, "stm32x flash specific commands");
72 register_command(cmd_ctx
, stm32x_cmd
, "lock", stm32x_handle_lock_command
, COMMAND_EXEC
,
74 register_command(cmd_ctx
, stm32x_cmd
, "unlock", stm32x_handle_unlock_command
, COMMAND_EXEC
,
75 "unlock protected device");
76 register_command(cmd_ctx
, stm32x_cmd
, "mass_erase", stm32x_handle_mass_erase_command
, COMMAND_EXEC
,
78 register_command(cmd_ctx
, stm32x_cmd
, "options_read", stm32x_handle_options_read_command
, COMMAND_EXEC
,
79 "read device option bytes");
80 register_command(cmd_ctx
, stm32x_cmd
, "options_write", stm32x_handle_options_write_command
, COMMAND_EXEC
,
81 "write device option bytes");
85 int stm32x_build_block_list(struct flash_bank_s
*bank
)
102 ERROR("BUG: unknown bank->size encountered");
106 bank
->num_sectors
= num_sectors
;
107 bank
->sectors
= malloc(sizeof(flash_sector_t
) * num_sectors
);
109 for (i
= 0; i
< num_sectors
; i
++)
111 bank
->sectors
[i
].offset
= i
* 1024;
112 bank
->sectors
[i
].size
= 1024;
113 bank
->sectors
[i
].is_erased
= -1;
114 bank
->sectors
[i
].is_protected
= 1;
120 /* flash bank stm32x <base> <size> 0 0 <target#>
122 int stm32x_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct flash_bank_s
*bank
)
124 stm32x_flash_bank_t
*stm32x_info
;
128 WARNING("incomplete flash_bank stm32x configuration");
129 return ERROR_FLASH_BANK_INVALID
;
132 stm32x_info
= malloc(sizeof(stm32x_flash_bank_t
));
133 bank
->driver_priv
= stm32x_info
;
135 if (bank
->base
!= 0x08000000)
137 WARNING("overriding flash base address for STM32x device with 0x08000000");
138 bank
->base
= 0x08000000;
141 stm32x_build_block_list(bank
);
143 stm32x_info
->write_algorithm
= NULL
;
148 u32
stm32x_get_flash_status(flash_bank_t
*bank
)
150 target_t
*target
= bank
->target
;
153 target_read_u32(target
, STM32_FLASH_SR
, &status
);
158 u32
stm32x_wait_status_busy(flash_bank_t
*bank
, int timeout
)
162 /* wait for busy to clear */
163 while (((status
= stm32x_get_flash_status(bank
)) & FLASH_BSY
) && (timeout
-- > 0))
165 DEBUG("status: 0x%x", status
);
172 int stm32x_blank_check(struct flash_bank_s
*bank
, int first
, int last
)
174 target_t
*target
= bank
->target
;
179 if ((first
< 0) || (last
> bank
->num_sectors
))
180 return ERROR_FLASH_SECTOR_INVALID
;
182 if (target
->state
!= TARGET_HALTED
)
184 return ERROR_TARGET_NOT_HALTED
;
187 buffer
= malloc(256);
189 for (i
= first
; i
<= last
; i
++)
191 bank
->sectors
[i
].is_erased
= 1;
193 target
->type
->read_memory(target
, bank
->base
+ bank
->sectors
[i
].offset
, 4, 256/4, buffer
);
195 for (nBytes
= 0; nBytes
< 256; nBytes
++)
197 if (buffer
[nBytes
] != 0xFF)
199 bank
->sectors
[i
].is_erased
= 0;
210 int stm32x_protect_check(struct flash_bank_s
*bank
)
212 target_t
*target
= bank
->target
;
217 if (target
->state
!= TARGET_HALTED
)
219 return ERROR_TARGET_NOT_HALTED
;
222 /* each bit refers to a 4bank protection */
223 target_read_u32(target
, STM32_FLASH_WRPR
, &protection
);
225 for (i
= 0; i
< 32; i
++)
229 if( protection
& (1 << i
))
232 for (s
= 0; s
< 4; s
++)
233 bank
->sectors
[(i
* 4) + s
].is_protected
= set
;
239 int stm32x_erase(struct flash_bank_s
*bank
, int first
, int last
)
241 target_t
*target
= bank
->target
;
246 /* unlock flash registers */
247 target_write_u32(target
, STM32_FLASH_KEYR
, KEY1
);
248 target_write_u32(target
, STM32_FLASH_KEYR
, KEY2
);
250 if (target
->state
!= TARGET_HALTED
)
252 return ERROR_TARGET_NOT_HALTED
;
255 for (i
= first
; i
<= last
; i
++)
257 target_write_u32(target
, STM32_FLASH_CR
, FLASH_PER
);
258 target_write_u32(target
, STM32_FLASH_AR
, bank
->base
+ bank
->sectors
[i
].offset
);
259 target_write_u32(target
, STM32_FLASH_CR
, FLASH_PER
|FLASH_STRT
);
261 status
= stm32x_wait_status_busy(bank
, 10);
263 if( status
& FLASH_WRPRTERR
)
264 return ERROR_FLASH_OPERATION_FAILED
;
265 if( status
& FLASH_PGERR
)
266 return ERROR_FLASH_OPERATION_FAILED
;
267 bank
->sectors
[i
].is_erased
= 1;
270 target_write_u32(target
, STM32_FLASH_CR
, FLASH_LOCK
);
275 int stm32x_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
)
277 target_t
*target
= bank
->target
;
279 if (target
->state
!= TARGET_HALTED
)
281 return ERROR_TARGET_NOT_HALTED
;
287 int stm32x_write_block(struct flash_bank_s
*bank
, u8
*buffer
, u32 offset
, u32 count
)
289 stm32x_flash_bank_t
*stm32x_info
= bank
->driver_priv
;
290 target_t
*target
= bank
->target
;
291 u32 buffer_size
= 8192;
292 working_area_t
*source
;
293 u32 address
= bank
->base
+ offset
;
294 reg_param_t reg_params
[6];
295 armv7m_algorithm_t armv7m_info
;
296 int retval
= ERROR_OK
;
298 u8 stm32x_flash_write_code
[] = {
300 0xDF, 0xF8, 0x24, 0x40, /* ldr r4, STM32_FLASH_CR */
301 0x09, 0x4D, /* ldr r5, STM32_FLASH_SR */
302 0x4F, 0xF0, 0x01, 0x03, /* mov r3, #1 */
303 0x23, 0x60, /* str r3, [r4, #0] */
304 0x30, 0xF8, 0x02, 0x3B, /* ldrh r3, [r0], #2 */
305 0x21, 0xF8, 0x02, 0x3B, /* strh r3, [r1], #2 */
307 0x2B, 0x68, /* ldr r3, [r5, #0] */
308 0x13, 0xF0, 0x01, 0x0F, /* tst r3, #0x01 */
309 0xFB, 0xD0, /* beq busy */
310 0x13, 0xF0, 0x14, 0x0F, /* tst r3, #0x14 */
311 0x01, 0xD1, /* bne exit */
312 0x01, 0x3A, /* subs r2, r2, #1 */
313 0xED, 0xD1, /* bne write */
315 0xFE, 0xE7, /* b exit */
316 0x10, 0x20, 0x02, 0x40, /* STM32_FLASH_CR: .word 0x40022010 */
317 0x0C, 0x20, 0x02, 0x40 /* STM32_FLASH_SR: .word 0x4002200C */
320 /* flash write code */
321 if (!stm32x_info
->write_algorithm
)
323 if (target_alloc_working_area(target
, sizeof(stm32x_flash_write_code
), &stm32x_info
->write_algorithm
) != ERROR_OK
)
325 WARNING("no working area available, can't do block memory writes");
326 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
329 target_write_buffer(target
, stm32x_info
->write_algorithm
->address
, sizeof(stm32x_flash_write_code
), stm32x_flash_write_code
);
333 while (target_alloc_working_area(target
, buffer_size
, &source
) != ERROR_OK
)
336 if (buffer_size
<= 256)
338 /* if we already allocated the writing code, but failed to get a buffer, free the algorithm */
339 if (stm32x_info
->write_algorithm
)
340 target_free_working_area(target
, stm32x_info
->write_algorithm
);
342 WARNING("no large enough working area available, can't do block memory writes");
343 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
347 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
348 armv7m_info
.core_mode
= ARMV7M_MODE_ANY
;
349 armv7m_info
.core_state
= ARMV7M_STATE_THUMB
;
351 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
);
352 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
353 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
);
354 init_reg_param(®_params
[3], "r3", 32, PARAM_IN
);
355 init_reg_param(®_params
[4], "r4", 32, PARAM_IN
);
356 init_reg_param(®_params
[5], "r5", 32, PARAM_IN
);
360 u32 thisrun_count
= (count
> (buffer_size
/ 2)) ? (buffer_size
/ 2) : count
;
362 target_write_buffer(target
, source
->address
, thisrun_count
* 2, buffer
);
364 buf_set_u32(reg_params
[0].value
, 0, 32, source
->address
);
365 buf_set_u32(reg_params
[1].value
, 0, 32, address
);
366 buf_set_u32(reg_params
[2].value
, 0, 32, thisrun_count
);
368 if ((retval
= target
->type
->run_algorithm(target
, 0, NULL
, 6, reg_params
, stm32x_info
->write_algorithm
->address
, \
369 stm32x_info
->write_algorithm
->address
+ (sizeof(stm32x_flash_write_code
) - 10), 10000, &armv7m_info
)) != ERROR_OK
)
371 ERROR("error executing str7x flash write algorithm");
375 if (buf_get_u32(reg_params
[3].value
, 0, 32) & 0x14)
377 retval
= ERROR_FLASH_OPERATION_FAILED
;
381 buffer
+= thisrun_count
* 2;
382 address
+= thisrun_count
* 2;
383 count
-= thisrun_count
;
386 target_free_working_area(target
, source
);
388 destroy_reg_param(®_params
[0]);
389 destroy_reg_param(®_params
[1]);
390 destroy_reg_param(®_params
[2]);
391 destroy_reg_param(®_params
[3]);
392 destroy_reg_param(®_params
[4]);
393 destroy_reg_param(®_params
[5]);
398 int stm32x_write(struct flash_bank_s
*bank
, u8
*buffer
, u32 offset
, u32 count
)
400 target_t
*target
= bank
->target
;
401 u32 words_remaining
= (count
/ 2);
402 u32 bytes_remaining
= (count
& 0x00000001);
403 u32 address
= bank
->base
+ offset
;
404 u32 bytes_written
= 0;
408 if (target
->state
!= TARGET_HALTED
)
410 return ERROR_TARGET_NOT_HALTED
;
415 WARNING("offset 0x%x breaks required 2-byte alignment", offset
);
416 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
419 /* unlock flash registers */
420 target_write_u32(target
, STM32_FLASH_KEYR
, KEY1
);
421 target_write_u32(target
, STM32_FLASH_KEYR
, KEY2
);
423 /* multiple half words (2-byte) to be programmed? */
424 if (words_remaining
> 0)
426 /* try using a block write */
427 if ((retval
= stm32x_write_block(bank
, buffer
, offset
, words_remaining
)) != ERROR_OK
)
429 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
)
431 /* if block write failed (no sufficient working area),
432 * we use normal (slow) single dword accesses */
433 WARNING("couldn't use block writes, falling back to single memory accesses");
435 else if (retval
== ERROR_FLASH_OPERATION_FAILED
)
437 ERROR("flash writing failed with error code: 0x%x", retval
);
438 return ERROR_FLASH_OPERATION_FAILED
;
443 buffer
+= words_remaining
* 2;
444 address
+= words_remaining
* 2;
449 while (words_remaining
> 0)
451 target_write_u32(target
, STM32_FLASH_CR
, FLASH_PG
);
452 target_write_u16(target
, address
, *(u16
*)(buffer
+ bytes_written
));
454 status
= stm32x_wait_status_busy(bank
, 5);
456 if( status
& FLASH_WRPRTERR
)
457 return ERROR_FLASH_OPERATION_FAILED
;
458 if( status
& FLASH_PGERR
)
459 return ERROR_FLASH_OPERATION_FAILED
;
468 u8 last_halfword
[2] = {0xff, 0xff};
471 while(bytes_remaining
> 0)
473 last_halfword
[i
++] = *(buffer
+ bytes_written
);
478 target_write_u32(target
, STM32_FLASH_CR
, FLASH_PG
);
479 target_write_u16(target
, address
, *(u16
*)last_halfword
);
481 status
= stm32x_wait_status_busy(bank
, 5);
483 if( status
& FLASH_WRPRTERR
)
484 return ERROR_FLASH_OPERATION_FAILED
;
485 if( status
& FLASH_PGERR
)
486 return ERROR_FLASH_OPERATION_FAILED
;
489 target_write_u32(target
, STM32_FLASH_CR
, FLASH_LOCK
);
494 int stm32x_probe(struct flash_bank_s
*bank
)
499 int stm32x_handle_part_id_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
504 int stm32x_erase_check(struct flash_bank_s
*bank
)
506 return stm32x_blank_check(bank
, 0, bank
->num_sectors
- 1);
509 int stm32x_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
)
511 snprintf(buf
, buf_size
, "stm32x flash driver info" );
515 int stm32x_handle_lock_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
519 target_t
*target
= NULL
;
520 stm32x_flash_bank_t
*stm32x_info
= NULL
;
524 command_print(cmd_ctx
, "stm32x lock <bank>");
528 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
531 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
535 stm32x_info
= bank
->driver_priv
;
537 target
= bank
->target
;
539 if (target
->state
!= TARGET_HALTED
)
541 return ERROR_TARGET_NOT_HALTED
;
544 /* unlock flash registers */
545 target_write_u32(target
, STM32_FLASH_KEYR
, KEY1
);
546 target_write_u32(target
, STM32_FLASH_KEYR
, KEY2
);
548 /* unlock option flash registers */
549 target_write_u32(target
, STM32_FLASH_OPTKEYR
, KEY1
);
550 target_write_u32(target
, STM32_FLASH_OPTKEYR
, KEY2
);
552 /* erase option bytes */
553 target_write_u32(target
, STM32_FLASH_CR
, FLASH_OPTER
|FLASH_OPTWRE
);
554 target_write_u32(target
, STM32_FLASH_CR
, FLASH_OPTER
|FLASH_STRT
|FLASH_OPTWRE
);
556 status
= stm32x_wait_status_busy(bank
, 10);
558 if( status
& FLASH_WRPRTERR
)
559 return ERROR_FLASH_OPERATION_FAILED
;
560 if( status
& FLASH_PGERR
)
561 return ERROR_FLASH_OPERATION_FAILED
;
563 /* program option bytes */
564 target_write_u32(target
, STM32_FLASH_CR
, FLASH_OPTPG
|FLASH_OPTWRE
);
566 /* set readout protection */
567 target_write_u16(target
, STM32_OB_ADR
, 0);
569 status
= stm32x_wait_status_busy(bank
, 10);
571 if( status
& FLASH_WRPRTERR
)
572 return ERROR_FLASH_OPERATION_FAILED
;
573 if( status
& FLASH_PGERR
)
574 return ERROR_FLASH_OPERATION_FAILED
;
576 target_write_u32(target
, STM32_FLASH_CR
, FLASH_LOCK
);
577 command_print(cmd_ctx
, "stm32x locked");
582 int stm32x_handle_unlock_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
586 target_t
*target
= NULL
;
587 stm32x_flash_bank_t
*stm32x_info
= NULL
;
591 command_print(cmd_ctx
, "stm32x unlock <bank>");
595 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
598 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
602 stm32x_info
= bank
->driver_priv
;
604 target
= bank
->target
;
606 if (target
->state
!= TARGET_HALTED
)
608 return ERROR_TARGET_NOT_HALTED
;
611 /* unlock flash registers */
612 target_write_u32(target
, STM32_FLASH_KEYR
, KEY1
);
613 target_write_u32(target
, STM32_FLASH_KEYR
, KEY2
);
615 /* unlock option flash registers */
616 target_write_u32(target
, STM32_FLASH_OPTKEYR
, KEY1
);
617 target_write_u32(target
, STM32_FLASH_OPTKEYR
, KEY2
);
619 /* erase option bytes */
620 target_write_u32(target
, STM32_FLASH_CR
, FLASH_OPTER
|FLASH_OPTWRE
);
621 target_write_u32(target
, STM32_FLASH_CR
, FLASH_OPTER
|FLASH_STRT
|FLASH_OPTWRE
);
623 status
= stm32x_wait_status_busy(bank
, 10);
625 if( status
& FLASH_WRPRTERR
)
626 return ERROR_FLASH_OPERATION_FAILED
;
627 if( status
& FLASH_PGERR
)
628 return ERROR_FLASH_OPERATION_FAILED
;
630 /* program option bytes */
631 target_write_u32(target
, STM32_FLASH_CR
, FLASH_OPTPG
|FLASH_OPTWRE
);
633 /* clear readout protection and complementary option bytes */
634 target_write_u16(target
, STM32_OB_ADR
, 0x5AA5);
636 status
= stm32x_wait_status_busy(bank
, 10);
638 if( status
& FLASH_WRPRTERR
)
639 return ERROR_FLASH_OPERATION_FAILED
;
640 if( status
& FLASH_PGERR
)
641 return ERROR_FLASH_OPERATION_FAILED
;
643 target_write_u32(target
, STM32_FLASH_CR
, FLASH_LOCK
);
644 command_print(cmd_ctx
, "stm32x unlocked");
649 int stm32x_handle_options_read_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
653 target_t
*target
= NULL
;
654 stm32x_flash_bank_t
*stm32x_info
= NULL
;
658 command_print(cmd_ctx
, "stm32x options_read <bank>");
662 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
665 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
669 stm32x_info
= bank
->driver_priv
;
671 target
= bank
->target
;
673 if (target
->state
!= TARGET_HALTED
)
675 return ERROR_TARGET_NOT_HALTED
;
678 //target_read_u32(target, STM32_OB_ADR, &optionbyte);
679 //command_print(cmd_ctx, "Option Byte 0: 0x%x", optionbyte);
680 //target_read_u32(target, STM32_OB_ADR+4, &optionbyte);
681 //command_print(cmd_ctx, "Option Byte 1: 0x%x", optionbyte);
682 //target_read_u32(target, STM32_OB_ADR+8, &optionbyte);
683 //command_print(cmd_ctx, "Option Byte 2: 0x%x", optionbyte);
684 //target_read_u32(target, STM32_OB_ADR+12, &optionbyte);
685 //command_print(cmd_ctx, "Option Byte 3: 0x%x", optionbyte);
687 target_read_u32(target
, STM32_FLASH_OBR
, &optionbyte
);
688 command_print(cmd_ctx
, "Option Byte: 0x%x", optionbyte
);
690 if (buf_get_u32((u8
*)&optionbyte
, OPT_ERROR
, 1))
691 command_print(cmd_ctx
, "Option Byte Complement Error");
693 if (buf_get_u32((u8
*)&optionbyte
, OPT_READOUT
, 1))
694 command_print(cmd_ctx
, "Readout Protection On");
696 command_print(cmd_ctx
, "Readout Protection Off");
698 if (buf_get_u32((u8
*)&optionbyte
, OPT_RDWDGSW
, 1))
699 command_print(cmd_ctx
, "Software Watchdog");
701 command_print(cmd_ctx
, "Hardware Watchdog");
703 if (buf_get_u32((u8
*)&optionbyte
, OPT_RDRSTSTOP
, 1))
704 command_print(cmd_ctx
, "Stop: No reset generated");
706 command_print(cmd_ctx
, "Stop: Reset generated");
708 if (buf_get_u32((u8
*)&optionbyte
, OPT_RDRSTSTDBY
, 1))
709 command_print(cmd_ctx
, "Standby: No reset generated");
711 command_print(cmd_ctx
, "Standby: Reset generated");
716 int stm32x_handle_options_write_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
719 target_t
*target
= NULL
;
720 stm32x_flash_bank_t
*stm32x_info
= NULL
;
721 u16 optionbyte
= 0xF8;
726 command_print(cmd_ctx
, "stm32x options_write <bank> <SWWDG|HWWDG> <RSTSTNDBY|NORSTSTNDBY> <RSTSTOP|NORSTSTOP>");
730 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
733 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
737 stm32x_info
= bank
->driver_priv
;
739 target
= bank
->target
;
741 if (target
->state
!= TARGET_HALTED
)
743 return ERROR_TARGET_NOT_HALTED
;
746 if (strcmp(args
[1], "SWWDG") == 0)
748 optionbyte
|= (1<<0);
752 optionbyte
&= ~(1<<0);
755 if (strcmp(args
[2], "NORSTSTNDBY") == 0)
757 optionbyte
|= (1<<1);
761 optionbyte
&= ~(1<<1);
764 if (strcmp(args
[3], "NORSTSTOP") == 0)
766 optionbyte
|= (1<<2);
770 optionbyte
&= ~(1<<2);
773 /* unlock flash registers */
774 target_write_u32(target
, STM32_FLASH_KEYR
, KEY1
);
775 target_write_u32(target
, STM32_FLASH_KEYR
, KEY2
);
777 /* unlock option flash registers */
778 target_write_u32(target
, STM32_FLASH_OPTKEYR
, KEY1
);
779 target_write_u32(target
, STM32_FLASH_OPTKEYR
, KEY2
);
781 /* program option bytes */
782 target_write_u32(target
, STM32_FLASH_CR
, FLASH_OPTPG
|FLASH_OPTWRE
);
784 /* write option byte */
785 target_write_u16(target
, STM32_OB_ADR
+ 2, optionbyte
);
787 status
= stm32x_wait_status_busy(bank
, 10);
789 if( status
& FLASH_WRPRTERR
)
790 return ERROR_FLASH_OPERATION_FAILED
;
791 if( status
& FLASH_PGERR
)
792 return ERROR_FLASH_OPERATION_FAILED
;
794 target_write_u32(target
, STM32_FLASH_CR
, FLASH_LOCK
);
799 int stm32x_handle_mass_erase_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
803 target_t
*target
= NULL
;
804 stm32x_flash_bank_t
*stm32x_info
= NULL
;
808 command_print(cmd_ctx
, "stm32x mass_erase <bank>");
812 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
815 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
819 stm32x_info
= bank
->driver_priv
;
821 target
= bank
->target
;
823 if (target
->state
!= TARGET_HALTED
)
825 return ERROR_TARGET_NOT_HALTED
;
828 /* unlock option flash registers */
829 target_write_u32(target
, STM32_FLASH_KEYR
, KEY1
);
830 target_write_u32(target
, STM32_FLASH_KEYR
, KEY2
);
832 /* mass erase flash memory */
833 target_write_u32(target
, STM32_FLASH_CR
, FLASH_MER
);
834 target_write_u32(target
, STM32_FLASH_CR
, FLASH_MER
|FLASH_STRT
);
836 status
= stm32x_wait_status_busy(bank
, 10);
838 if( status
& FLASH_WRPRTERR
)
839 return ERROR_FLASH_OPERATION_FAILED
;
840 if( status
& FLASH_PGERR
)
841 return ERROR_FLASH_OPERATION_FAILED
;
843 target_write_u32(target
, STM32_FLASH_CR
, FLASH_LOCK
);
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)