- corrected stm32x_handle_options_write_command, incorrect options printed
[openocd.git] / src / flash / stm32x.c
1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
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. *
9 * *
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. *
14 * *
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 ***************************************************************************/
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include "replacements.h"
25
26 #include "stm32x.h"
27 #include "flash.h"
28 #include "target.h"
29 #include "log.h"
30 #include "armv7m.h"
31 #include "algorithm.h"
32 #include "binarybuffer.h"
33
34 #include <stdlib.h>
35 #include <string.h>
36
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);
47
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);
53
54 flash_driver_t stm32x_flash =
55 {
56 .name = "stm32x",
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,
65 .info = stm32x_info
66 };
67
68 int stm32x_register_commands(struct command_context_s *cmd_ctx)
69 {
70 command_t *stm32x_cmd = register_command(cmd_ctx, NULL, "stm32x", NULL, COMMAND_ANY, "stm32x flash specific commands");
71
72 register_command(cmd_ctx, stm32x_cmd, "lock", stm32x_handle_lock_command, COMMAND_EXEC,
73 "lock device");
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,
77 "mass erase device");
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");
82 return ERROR_OK;
83 }
84
85 int stm32x_build_block_list(struct flash_bank_s *bank)
86 {
87 int i;
88 int num_sectors = 0;
89
90 switch (bank->size)
91 {
92 case 32 * 1024:
93 num_sectors = 32;
94 break;
95 case 64 * 1024:
96 num_sectors = 64;
97 break;
98 case 128 * 1024:
99 num_sectors = 128;
100 break;
101 default:
102 ERROR("BUG: unknown bank->size encountered");
103 exit(-1);
104 }
105
106 bank->num_sectors = num_sectors;
107 bank->sectors = malloc(sizeof(flash_sector_t) * num_sectors);
108
109 for (i = 0; i < num_sectors; i++)
110 {
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;
115 }
116
117 return ERROR_OK;
118 }
119
120 /* flash bank stm32x <base> <size> 0 0 <target#>
121 */
122 int stm32x_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank)
123 {
124 stm32x_flash_bank_t *stm32x_info;
125
126 if (argc < 6)
127 {
128 WARNING("incomplete flash_bank stm32x configuration");
129 return ERROR_FLASH_BANK_INVALID;
130 }
131
132 stm32x_info = malloc(sizeof(stm32x_flash_bank_t));
133 bank->driver_priv = stm32x_info;
134
135 if (bank->base != 0x08000000)
136 {
137 WARNING("overriding flash base address for STM32x device with 0x08000000");
138 bank->base = 0x08000000;
139 }
140
141 stm32x_info->target = get_target_by_num(strtoul(args[5], NULL, 0));
142 if (!stm32x_info->target)
143 {
144 ERROR("no target '%s' configured", args[5]);
145 exit(-1);
146 }
147
148 stm32x_build_block_list(bank);
149
150 stm32x_info->write_algorithm = NULL;
151
152 return ERROR_OK;
153 }
154
155 u32 stm32x_get_flash_status(flash_bank_t *bank)
156 {
157 stm32x_flash_bank_t *stm32x_info = bank->driver_priv;
158 target_t *target = stm32x_info->target;
159 u32 status;
160
161 target_read_u32(target, STM32_FLASH_SR, &status);
162
163 return status;
164 }
165
166 u32 stm32x_wait_status_busy(flash_bank_t *bank, int timeout)
167 {
168 u32 status;
169
170 /* wait for busy to clear */
171 while (((status = stm32x_get_flash_status(bank)) & FLASH_BSY) && (timeout-- > 0))
172 {
173 DEBUG("status: 0x%x", status);
174 usleep(1000);
175 }
176
177 return status;
178 }
179
180 int stm32x_blank_check(struct flash_bank_s *bank, int first, int last)
181 {
182 stm32x_flash_bank_t *stm32x_info = bank->driver_priv;
183 target_t *target = stm32x_info->target;
184 u8 *buffer;
185 int i;
186 int nBytes;
187
188 if ((first < 0) || (last > bank->num_sectors))
189 return ERROR_FLASH_SECTOR_INVALID;
190
191 if (target->state != TARGET_HALTED)
192 {
193 return ERROR_TARGET_NOT_HALTED;
194 }
195
196 buffer = malloc(256);
197
198 for (i = first; i <= last; i++)
199 {
200 bank->sectors[i].is_erased = 1;
201
202 target->type->read_memory(target, bank->base + bank->sectors[i].offset, 4, 256/4, buffer);
203
204 for (nBytes = 0; nBytes < 256; nBytes++)
205 {
206 if (buffer[nBytes] != 0xFF)
207 {
208 bank->sectors[i].is_erased = 0;
209 break;
210 }
211 }
212 }
213
214 free(buffer);
215
216 return ERROR_OK;
217 }
218
219 int stm32x_protect_check(struct flash_bank_s *bank)
220 {
221 stm32x_flash_bank_t *stm32x_info = bank->driver_priv;
222 target_t *target = stm32x_info->target;
223
224 u32 protection;
225 int i, s;
226
227 if (target->state != TARGET_HALTED)
228 {
229 return ERROR_TARGET_NOT_HALTED;
230 }
231
232 /* each bit refers to a 4bank protection */
233 target_read_u32(target, STM32_FLASH_WRPR, &protection);
234
235 for (i = 0; i < 32; i++)
236 {
237 int set = 1;
238
239 if( protection & (1 << i))
240 set = 0;
241
242 for (s = 0; s < 4; s++)
243 bank->sectors[(i * 4) + s].is_protected = set;
244 }
245
246 return ERROR_OK;
247 }
248
249 int stm32x_erase(struct flash_bank_s *bank, int first, int last)
250 {
251 stm32x_flash_bank_t *stm32x_info = bank->driver_priv;
252 target_t *target = stm32x_info->target;
253
254 int i;
255 u32 status;
256
257 /* unlock flash registers */
258 target_write_u32(target, STM32_FLASH_KEYR, KEY1);
259 target_write_u32(target, STM32_FLASH_KEYR, KEY2);
260
261 if (target->state != TARGET_HALTED)
262 {
263 return ERROR_TARGET_NOT_HALTED;
264 }
265
266 for (i = first; i <= last; i++)
267 {
268 target_write_u32(target, STM32_FLASH_CR, FLASH_PER);
269 target_write_u32(target, STM32_FLASH_AR, bank->base + bank->sectors[i].offset);
270 target_write_u32(target, STM32_FLASH_CR, FLASH_PER|FLASH_STRT);
271
272 status = stm32x_wait_status_busy(bank, 10);
273
274 if( status & FLASH_WRPRTERR )
275 return ERROR_FLASH_OPERATION_FAILED;
276 if( status & FLASH_PGERR )
277 return ERROR_FLASH_OPERATION_FAILED;
278 bank->sectors[i].is_erased = 1;
279 }
280
281 target_write_u32(target, STM32_FLASH_CR, FLASH_LOCK);
282
283 return ERROR_OK;
284 }
285
286 int stm32x_protect(struct flash_bank_s *bank, int set, int first, int last)
287 {
288 stm32x_flash_bank_t *stm32x_info = bank->driver_priv;
289 target_t *target = stm32x_info->target;
290
291 if (target->state != TARGET_HALTED)
292 {
293 return ERROR_TARGET_NOT_HALTED;
294 }
295
296 return ERROR_OK;
297 }
298
299 int stm32x_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
300 {
301 stm32x_flash_bank_t *stm32x_info = bank->driver_priv;
302 target_t *target = stm32x_info->target;
303 u32 buffer_size = 8192;
304 working_area_t *source;
305 u32 address = bank->base + offset;
306 reg_param_t reg_params[6];
307 armv7m_algorithm_t armv7m_info;
308 int retval = ERROR_OK;
309
310 u8 stm32x_flash_write_code[] = {
311 /* write: */
312 0xDF, 0xF8, 0x24, 0x40, /* ldr r4, STM32_FLASH_CR */
313 0x09, 0x4D, /* ldr r5, STM32_FLASH_SR */
314 0x4F, 0xF0, 0x01, 0x03, /* mov r3, #1 */
315 0x23, 0x60, /* str r3, [r4, #0] */
316 0x30, 0xF8, 0x02, 0x3B, /* ldrh r3, [r0], #2 */
317 0x21, 0xF8, 0x02, 0x3B, /* strh r3, [r1], #2 */
318 /* busy: */
319 0x2B, 0x68, /* ldr r3, [r5, #0] */
320 0x13, 0xF0, 0x01, 0x0F, /* tst r3, #0x01 */
321 0xFB, 0xD0, /* beq busy */
322 0x13, 0xF0, 0x14, 0x0F, /* tst r3, #0x14 */
323 0x01, 0xD1, /* bne exit */
324 0x01, 0x3A, /* subs r2, r2, #1 */
325 0xED, 0xD1, /* bne write */
326 /* exit: */
327 0xFE, 0xE7, /* b exit */
328 0x10, 0x20, 0x02, 0x40, /* STM32_FLASH_CR: .word 0x40022010 */
329 0x0C, 0x20, 0x02, 0x40 /* STM32_FLASH_SR: .word 0x4002200C */
330 };
331
332 /* flash write code */
333 if (!stm32x_info->write_algorithm)
334 {
335 if (target_alloc_working_area(target, sizeof(stm32x_flash_write_code), &stm32x_info->write_algorithm) != ERROR_OK)
336 {
337 WARNING("no working area available, can't do block memory writes");
338 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
339 };
340
341 target_write_buffer(target, stm32x_info->write_algorithm->address, sizeof(stm32x_flash_write_code), stm32x_flash_write_code);
342 }
343
344 /* memory buffer */
345 while (target_alloc_working_area(target, buffer_size, &source) != ERROR_OK)
346 {
347 buffer_size /= 2;
348 if (buffer_size <= 256)
349 {
350 /* if we already allocated the writing code, but failed to get a buffer, free the algorithm */
351 if (stm32x_info->write_algorithm)
352 target_free_working_area(target, stm32x_info->write_algorithm);
353
354 WARNING("no large enough working area available, can't do block memory writes");
355 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
356 }
357 };
358
359 armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
360 armv7m_info.core_mode = ARMV7M_MODE_ANY;
361 armv7m_info.core_state = ARMV7M_STATE_THUMB;
362
363 init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
364 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
365 init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT);
366 init_reg_param(&reg_params[3], "r3", 32, PARAM_IN);
367 init_reg_param(&reg_params[4], "r4", 32, PARAM_IN);
368 init_reg_param(&reg_params[5], "r5", 32, PARAM_IN);
369
370 while (count > 0)
371 {
372 u32 thisrun_count = (count > (buffer_size / 2)) ? (buffer_size / 2) : count;
373
374 target_write_buffer(target, source->address, thisrun_count * 2, buffer);
375
376 buf_set_u32(reg_params[0].value, 0, 32, source->address);
377 buf_set_u32(reg_params[1].value, 0, 32, address);
378 buf_set_u32(reg_params[2].value, 0, 32, thisrun_count);
379
380 if ((retval = target->type->run_algorithm(target, 0, NULL, 6, reg_params, stm32x_info->write_algorithm->address, \
381 stm32x_info->write_algorithm->address + (sizeof(stm32x_flash_write_code) - 10), 10000, &armv7m_info)) != ERROR_OK)
382 {
383 ERROR("error executing str7x flash write algorithm");
384 break;
385 }
386
387 if (buf_get_u32(reg_params[3].value, 0, 32) & 0x14)
388 {
389 retval = ERROR_FLASH_OPERATION_FAILED;
390 break;
391 }
392
393 buffer += thisrun_count * 2;
394 address += thisrun_count * 2;
395 count -= thisrun_count;
396 }
397
398 target_free_working_area(target, source);
399
400 destroy_reg_param(&reg_params[0]);
401 destroy_reg_param(&reg_params[1]);
402 destroy_reg_param(&reg_params[2]);
403 destroy_reg_param(&reg_params[3]);
404 destroy_reg_param(&reg_params[4]);
405 destroy_reg_param(&reg_params[5]);
406
407 return retval;
408 }
409
410 int stm32x_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
411 {
412 stm32x_flash_bank_t *stm32x_info = bank->driver_priv;
413 target_t *target = stm32x_info->target;
414 u32 words_remaining = (count / 2);
415 u32 bytes_remaining = (count & 0x00000001);
416 u32 address = bank->base + offset;
417 u32 bytes_written = 0;
418 u8 status;
419 u32 retval;
420
421 if (target->state != TARGET_HALTED)
422 {
423 return ERROR_TARGET_NOT_HALTED;
424 }
425
426 if (offset & 0x1)
427 {
428 WARNING("offset 0x%x breaks required 2-byte alignment", offset);
429 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
430 }
431
432 /* unlock flash registers */
433 target_write_u32(target, STM32_FLASH_KEYR, KEY1);
434 target_write_u32(target, STM32_FLASH_KEYR, KEY2);
435
436 /* multiple half words (2-byte) to be programmed? */
437 if (words_remaining > 0)
438 {
439 /* try using a block write */
440 if ((retval = stm32x_write_block(bank, buffer, offset, words_remaining)) != ERROR_OK)
441 {
442 if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE)
443 {
444 /* if block write failed (no sufficient working area),
445 * we use normal (slow) single dword accesses */
446 WARNING("couldn't use block writes, falling back to single memory accesses");
447 }
448 else if (retval == ERROR_FLASH_OPERATION_FAILED)
449 {
450 ERROR("flash writing failed with error code: 0x%x", retval);
451 return ERROR_FLASH_OPERATION_FAILED;
452 }
453 }
454 else
455 {
456 buffer += words_remaining * 2;
457 address += words_remaining * 2;
458 words_remaining = 0;
459 }
460 }
461
462 while (words_remaining > 0)
463 {
464 target_write_u32(target, STM32_FLASH_CR, FLASH_PG);
465 target_write_u16(target, address, *(u16*)(buffer + bytes_written));
466
467 status = stm32x_wait_status_busy(bank, 5);
468
469 if( status & FLASH_WRPRTERR )
470 return ERROR_FLASH_OPERATION_FAILED;
471 if( status & FLASH_PGERR )
472 return ERROR_FLASH_OPERATION_FAILED;
473
474 bytes_written += 2;
475 words_remaining--;
476 address += 2;
477 }
478
479 if (bytes_remaining)
480 {
481 u8 last_halfword[2] = {0xff, 0xff};
482 int i = 0;
483
484 while(bytes_remaining > 0)
485 {
486 last_halfword[i++] = *(buffer + bytes_written);
487 bytes_remaining--;
488 bytes_written++;
489 }
490
491 target_write_u32(target, STM32_FLASH_CR, FLASH_PG);
492 target_write_u16(target, address, *(u16*)last_halfword);
493
494 status = stm32x_wait_status_busy(bank, 5);
495
496 if( status & FLASH_WRPRTERR )
497 return ERROR_FLASH_OPERATION_FAILED;
498 if( status & FLASH_PGERR )
499 return ERROR_FLASH_OPERATION_FAILED;
500 }
501
502 target_write_u32(target, STM32_FLASH_CR, FLASH_LOCK);
503
504 return ERROR_OK;
505 }
506
507 int stm32x_probe(struct flash_bank_s *bank)
508 {
509 return ERROR_OK;
510 }
511
512 int stm32x_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
513 {
514 return ERROR_OK;
515 }
516
517 int stm32x_erase_check(struct flash_bank_s *bank)
518 {
519 return stm32x_blank_check(bank, 0, bank->num_sectors - 1);
520 }
521
522 int stm32x_info(struct flash_bank_s *bank, char *buf, int buf_size)
523 {
524 snprintf(buf, buf_size, "stm32x flash driver info" );
525 return ERROR_OK;
526 }
527
528 int stm32x_handle_lock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
529 {
530 flash_bank_t *bank;
531 u32 status;
532 target_t *target = NULL;
533 stm32x_flash_bank_t *stm32x_info = NULL;
534
535 if (argc < 1)
536 {
537 command_print(cmd_ctx, "stm32x lock <bank>");
538 return ERROR_OK;
539 }
540
541 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
542 if (!bank)
543 {
544 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
545 return ERROR_OK;
546 }
547
548 stm32x_info = bank->driver_priv;
549
550 target = stm32x_info->target;
551
552 if (target->state != TARGET_HALTED)
553 {
554 return ERROR_TARGET_NOT_HALTED;
555 }
556
557 /* unlock flash registers */
558 target_write_u32(target, STM32_FLASH_KEYR, KEY1);
559 target_write_u32(target, STM32_FLASH_KEYR, KEY2);
560
561 /* unlock option flash registers */
562 target_write_u32(target, STM32_FLASH_OPTKEYR, KEY1);
563 target_write_u32(target, STM32_FLASH_OPTKEYR, KEY2);
564
565 /* erase option bytes */
566 target_write_u32(target, STM32_FLASH_CR, FLASH_OPTER|FLASH_OPTWRE);
567 target_write_u32(target, STM32_FLASH_CR, FLASH_OPTER|FLASH_STRT|FLASH_OPTWRE);
568
569 status = stm32x_wait_status_busy(bank, 10);
570
571 if( status & FLASH_WRPRTERR )
572 return ERROR_FLASH_OPERATION_FAILED;
573 if( status & FLASH_PGERR )
574 return ERROR_FLASH_OPERATION_FAILED;
575
576 /* program option bytes */
577 target_write_u32(target, STM32_FLASH_CR, FLASH_OPTPG|FLASH_OPTWRE);
578
579 /* set readout protection */
580 target_write_u16(target, STM32_OB_ADR, 0);
581
582 status = stm32x_wait_status_busy(bank, 10);
583
584 if( status & FLASH_WRPRTERR )
585 return ERROR_FLASH_OPERATION_FAILED;
586 if( status & FLASH_PGERR )
587 return ERROR_FLASH_OPERATION_FAILED;
588
589 target_write_u32(target, STM32_FLASH_CR, FLASH_LOCK);
590 command_print(cmd_ctx, "stm32x locked");
591
592 return ERROR_OK;
593 }
594
595 int stm32x_handle_unlock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
596 {
597 flash_bank_t *bank;
598 u32 status;
599 target_t *target = NULL;
600 stm32x_flash_bank_t *stm32x_info = NULL;
601
602 if (argc < 1)
603 {
604 command_print(cmd_ctx, "stm32x unlock <bank>");
605 return ERROR_OK;
606 }
607
608 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
609 if (!bank)
610 {
611 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
612 return ERROR_OK;
613 }
614
615 stm32x_info = bank->driver_priv;
616
617 target = stm32x_info->target;
618
619 if (target->state != TARGET_HALTED)
620 {
621 return ERROR_TARGET_NOT_HALTED;
622 }
623
624 /* unlock flash registers */
625 target_write_u32(target, STM32_FLASH_KEYR, KEY1);
626 target_write_u32(target, STM32_FLASH_KEYR, KEY2);
627
628 /* unlock option flash registers */
629 target_write_u32(target, STM32_FLASH_OPTKEYR, KEY1);
630 target_write_u32(target, STM32_FLASH_OPTKEYR, KEY2);
631
632 /* erase option bytes */
633 target_write_u32(target, STM32_FLASH_CR, FLASH_OPTER|FLASH_OPTWRE);
634 target_write_u32(target, STM32_FLASH_CR, FLASH_OPTER|FLASH_STRT|FLASH_OPTWRE);
635
636 status = stm32x_wait_status_busy(bank, 10);
637
638 if( status & FLASH_WRPRTERR )
639 return ERROR_FLASH_OPERATION_FAILED;
640 if( status & FLASH_PGERR )
641 return ERROR_FLASH_OPERATION_FAILED;
642
643 /* program option bytes */
644 target_write_u32(target, STM32_FLASH_CR, FLASH_OPTPG|FLASH_OPTWRE);
645
646 /* clear readout protection and complementary option bytes */
647 target_write_u16(target, STM32_OB_ADR, 0x5AA5);
648
649 status = stm32x_wait_status_busy(bank, 10);
650
651 if( status & FLASH_WRPRTERR )
652 return ERROR_FLASH_OPERATION_FAILED;
653 if( status & FLASH_PGERR )
654 return ERROR_FLASH_OPERATION_FAILED;
655
656 target_write_u32(target, STM32_FLASH_CR, FLASH_LOCK);
657 command_print(cmd_ctx, "stm32x unlocked");
658
659 return ERROR_OK;
660 }
661
662 int stm32x_handle_options_read_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
663 {
664 flash_bank_t *bank;
665 u32 optionbyte;
666 target_t *target = NULL;
667 stm32x_flash_bank_t *stm32x_info = NULL;
668
669 if (argc < 1)
670 {
671 command_print(cmd_ctx, "stm32x options_read <bank>");
672 return ERROR_OK;
673 }
674
675 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
676 if (!bank)
677 {
678 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
679 return ERROR_OK;
680 }
681
682 stm32x_info = bank->driver_priv;
683
684 target = stm32x_info->target;
685
686 if (target->state != TARGET_HALTED)
687 {
688 return ERROR_TARGET_NOT_HALTED;
689 }
690
691 //target_read_u32(target, STM32_OB_ADR, &optionbyte);
692 //command_print(cmd_ctx, "Option Byte 0: 0x%x", optionbyte);
693 //target_read_u32(target, STM32_OB_ADR+4, &optionbyte);
694 //command_print(cmd_ctx, "Option Byte 1: 0x%x", optionbyte);
695 //target_read_u32(target, STM32_OB_ADR+8, &optionbyte);
696 //command_print(cmd_ctx, "Option Byte 2: 0x%x", optionbyte);
697 //target_read_u32(target, STM32_OB_ADR+12, &optionbyte);
698 //command_print(cmd_ctx, "Option Byte 3: 0x%x", optionbyte);
699
700 target_read_u32(target, STM32_FLASH_OBR, &optionbyte);
701 command_print(cmd_ctx, "Option Byte: 0x%x", optionbyte);
702
703 if (buf_get_u32((u8*)&optionbyte, OPT_ERROR, 1))
704 command_print(cmd_ctx, "Option Byte Complement Error");
705
706 if (buf_get_u32((u8*)&optionbyte, OPT_READOUT, 1))
707 command_print(cmd_ctx, "Readout Protection On");
708 else
709 command_print(cmd_ctx, "Readout Protection Off");
710
711 if (buf_get_u32((u8*)&optionbyte, OPT_RDWDGSW, 1))
712 command_print(cmd_ctx, "Software Watchdog");
713 else
714 command_print(cmd_ctx, "Hardware Watchdog");
715
716 if (buf_get_u32((u8*)&optionbyte, OPT_RDRSTSTOP, 1))
717 command_print(cmd_ctx, "Stop: No reset generated");
718 else
719 command_print(cmd_ctx, "Stop: Reset generated");
720
721 if (buf_get_u32((u8*)&optionbyte, OPT_RDRSTSTDBY, 1))
722 command_print(cmd_ctx, "Standby: No reset generated");
723 else
724 command_print(cmd_ctx, "Standby: Reset generated");
725
726 return ERROR_OK;
727 }
728
729 int stm32x_handle_options_write_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
730 {
731 flash_bank_t *bank;
732 target_t *target = NULL;
733 stm32x_flash_bank_t *stm32x_info = NULL;
734 u16 optionbyte = 0xF8;
735 u32 status;
736
737 if (argc < 4)
738 {
739 command_print(cmd_ctx, "stm32x options_write <bank> <SWWDG|HWWDG> <RSTSTNDBY|NORSTSTNDBY> <RSTSTOP|NORSTSTOP>");
740 return ERROR_OK;
741 }
742
743 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
744 if (!bank)
745 {
746 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
747 return ERROR_OK;
748 }
749
750 stm32x_info = bank->driver_priv;
751
752 target = stm32x_info->target;
753
754 if (target->state != TARGET_HALTED)
755 {
756 return ERROR_TARGET_NOT_HALTED;
757 }
758
759 if (strcmp(args[1], "SWWDG") == 0)
760 {
761 optionbyte |= (1<<0);
762 }
763 else
764 {
765 optionbyte &= ~(1<<0);
766 }
767
768 if (strcmp(args[2], "NORSTSTNDBY") == 0)
769 {
770 optionbyte |= (1<<1);
771 }
772 else
773 {
774 optionbyte &= ~(1<<1);
775 }
776
777 if (strcmp(args[3], "NORSTSTOP") == 0)
778 {
779 optionbyte |= (1<<2);
780 }
781 else
782 {
783 optionbyte &= ~(1<<2);
784 }
785
786 /* unlock flash registers */
787 target_write_u32(target, STM32_FLASH_KEYR, KEY1);
788 target_write_u32(target, STM32_FLASH_KEYR, KEY2);
789
790 /* unlock option flash registers */
791 target_write_u32(target, STM32_FLASH_OPTKEYR, KEY1);
792 target_write_u32(target, STM32_FLASH_OPTKEYR, KEY2);
793
794 /* program option bytes */
795 target_write_u32(target, STM32_FLASH_CR, FLASH_OPTPG|FLASH_OPTWRE);
796
797 /* write option byte */
798 target_write_u16(target, STM32_OB_ADR + 2, optionbyte);
799
800 status = stm32x_wait_status_busy(bank, 10);
801
802 if( status & FLASH_WRPRTERR )
803 return ERROR_FLASH_OPERATION_FAILED;
804 if( status & FLASH_PGERR )
805 return ERROR_FLASH_OPERATION_FAILED;
806
807 target_write_u32(target, STM32_FLASH_CR, FLASH_LOCK);
808
809 return ERROR_OK;
810 }
811
812 int stm32x_handle_mass_erase_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
813 {
814 flash_bank_t *bank;
815 u32 status;
816 target_t *target = NULL;
817 stm32x_flash_bank_t *stm32x_info = NULL;
818
819 if (argc < 1)
820 {
821 command_print(cmd_ctx, "stm32x mass_erase <bank>");
822 return ERROR_OK;
823 }
824
825 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
826 if (!bank)
827 {
828 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
829 return ERROR_OK;
830 }
831
832 stm32x_info = bank->driver_priv;
833
834 target = stm32x_info->target;
835
836 if (target->state != TARGET_HALTED)
837 {
838 return ERROR_TARGET_NOT_HALTED;
839 }
840
841 /* unlock option flash registers */
842 target_write_u32(target, STM32_FLASH_KEYR, KEY1);
843 target_write_u32(target, STM32_FLASH_KEYR, KEY2);
844
845 /* mass erase flash memory */
846 target_write_u32(target, STM32_FLASH_CR, FLASH_MER);
847 target_write_u32(target, STM32_FLASH_CR, FLASH_MER|FLASH_STRT);
848
849 status = stm32x_wait_status_busy(bank, 10);
850
851 if( status & FLASH_WRPRTERR )
852 return ERROR_FLASH_OPERATION_FAILED;
853 if( status & FLASH_PGERR )
854 return ERROR_FLASH_OPERATION_FAILED;
855
856 target_write_u32(target, STM32_FLASH_CR, FLASH_LOCK);
857
858 return ERROR_OK;
859 }

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)