f007ad758a51ca0c5602431ce481331601197eb0
[openocd.git] / src / flash / nor / stm32f2x.c
1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
5 * Copyright (C) 2008 by Spencer Oliver *
6 * spen@spen-soft.co.uk *
7 * *
8 * Copyright (C) 2011 Øyvind Harboe *
9 * oyvind.harboe@zylin.com *
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * GNU General Public License for more details. *
20 * *
21 * You should have received a copy of the GNU General Public License *
22 * along with this program; if not, write to the *
23 * Free Software Foundation, Inc., *
24 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
25 ***************************************************************************/
26
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"
29 #endif
30
31 #include "imp.h"
32 #include <helper/binarybuffer.h>
33 #include <target/algorithm.h>
34 #include <target/armv7m.h>
35
36 /* Regarding performance:
37 *
38 * Short story - it might be best to leave the performance at
39 * current levels.
40 *
41 * You may see a jump in speed if you change to using
42 * 32bit words for the block programming.
43 *
44 * Its a shame you cannot use the double word as its
45 * even faster - but you require external VPP for that mode.
46 *
47 * Having said all that 16bit writes give us the widest vdd
48 * operating range, so may be worth adding a note to that effect.
49 *
50 */
51
52 /* Danger!!!! The STM32F1x and STM32F2x series actually have
53 * quite different flash controllers.
54 *
55 * What's more scary is that the names of the registers and their
56 * addresses are the same, but the actual bits and what they do are
57 * can be very different.
58 *
59 * To reduce testing complexity and dangers of regressions,
60 * a seperate file is used for stm32fx2x.
61 *
62 * 1mByte part with 4 x 16, 1 x 64, 7 x 128kBytes sectors
63 *
64 * What's the protection page size???
65 *
66 * Tested with STM3220F-EVAL board.
67 *
68 * STM32F21xx series for reference.
69 *
70 * RM0033
71 * http://www.st.com/internet/mcu/product/250192.jsp
72 *
73 * PM0059
74 * www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/
75 * PROGRAMMING_MANUAL/CD00233952.pdf
76 *
77 * STM32F1x series - notice that this code was copy, pasted and knocked
78 * into a stm32f2x driver, so in case something has been converted or
79 * bugs haven't been fixed, here are the original manuals:
80 *
81 * RM0008 - Reference manual
82 *
83 * RM0042, the Flash programming manual for low-, medium- high-density and
84 * connectivity line STM32F10x devices
85 *
86 * PM0068, the Flash programming manual for XL-density STM32F10x devices.
87 *
88 */
89
90 /* Erase time can be as high as 1000ms, 10x this and it's toast... */
91 #define FLASH_ERASE_TIMEOUT 10000
92 #define FLASH_WRITE_TIMEOUT 5
93
94 #define STM32_FLASH_BASE 0x40023c00
95 #define STM32_FLASH_ACR 0x40023c00
96 #define STM32_FLASH_KEYR 0x40023c04
97 #define STM32_FLASH_OPTKEYR 0x40023c08
98 #define STM32_FLASH_SR 0x40023c0C
99 #define STM32_FLASH_CR 0x40023c10
100 #define STM32_FLASH_OPTCR 0x40023c14
101 #define STM32_FLASH_OBR 0x40023c1C
102
103 /* option byte location */
104
105 #define STM32_OB_RDP 0x1FFFF800
106 #define STM32_OB_USER 0x1FFFF802
107 #define STM32_OB_DATA0 0x1FFFF804
108 #define STM32_OB_DATA1 0x1FFFF806
109 #define STM32_OB_WRP0 0x1FFFF808
110 #define STM32_OB_WRP1 0x1FFFF80A
111 #define STM32_OB_WRP2 0x1FFFF80C
112 #define STM32_OB_WRP3 0x1FFFF80E
113
114 /* FLASH_CR register bits */
115
116 #define FLASH_PG (1 << 0)
117 #define FLASH_SER (1 << 1)
118 #define FLASH_MER (1 << 2)
119 #define FLASH_MER1 (1 << 15)
120 #define FLASH_STRT (1 << 16)
121 #define FLASH_PSIZE_8 (0 << 8)
122 #define FLASH_PSIZE_16 (1 << 8)
123 #define FLASH_PSIZE_32 (2 << 8)
124 #define FLASH_PSIZE_64 (3 << 8)
125 #define FLASH_SNB(a) ((a) << 3)
126 #define FLASH_LOCK (1 << 31)
127
128 /* FLASH_SR register bits */
129
130 #define FLASH_BSY (1 << 16)
131 #define FLASH_PGSERR (1 << 7) /* Programming sequence error */
132 #define FLASH_PGPERR (1 << 6) /* Programming parallelism error */
133 #define FLASH_PGAERR (1 << 5) /* Programming alignment error */
134 #define FLASH_WRPERR (1 << 4) /* Write protection error */
135 #define FLASH_OPERR (1 << 1) /* Operation error */
136
137 #define FLASH_ERROR (FLASH_PGSERR | FLASH_PGPERR | FLASH_PGAERR | FLASH_WRPERR | FLASH_OPERR)
138
139 /* STM32_FLASH_OBR bit definitions (reading) */
140
141 #define OPT_ERROR 0
142 #define OPT_READOUT 1
143 #define OPT_RDWDGSW 2
144 #define OPT_RDRSTSTOP 3
145 #define OPT_RDRSTSTDBY 4
146 #define OPT_BFB2 5 /* dual flash bank only */
147
148 /* register unlock keys */
149
150 #define KEY1 0x45670123
151 #define KEY2 0xCDEF89AB
152
153 struct stm32x_flash_bank {
154 int probed;
155 };
156
157
158 /* flash bank stm32x <base> <size> 0 0 <target#>
159 */
160 FLASH_BANK_COMMAND_HANDLER(stm32x_flash_bank_command)
161 {
162 struct stm32x_flash_bank *stm32x_info;
163
164 if (CMD_ARGC < 6)
165 return ERROR_COMMAND_SYNTAX_ERROR;
166
167 stm32x_info = malloc(sizeof(struct stm32x_flash_bank));
168 bank->driver_priv = stm32x_info;
169
170 stm32x_info->probed = 0;
171
172 return ERROR_OK;
173 }
174
175 static inline int stm32x_get_flash_reg(struct flash_bank *bank, uint32_t reg)
176 {
177 return reg;
178 }
179
180 static inline int stm32x_get_flash_status(struct flash_bank *bank, uint32_t *status)
181 {
182 struct target *target = bank->target;
183 return target_read_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_SR), status);
184 }
185
186 static int stm32x_wait_status_busy(struct flash_bank *bank, int timeout)
187 {
188 struct target *target = bank->target;
189 uint32_t status;
190 int retval = ERROR_OK;
191
192 /* wait for busy to clear */
193 for (;;) {
194 retval = stm32x_get_flash_status(bank, &status);
195 if (retval != ERROR_OK)
196 return retval;
197 LOG_DEBUG("status: 0x%" PRIx32 "", status);
198 if ((status & FLASH_BSY) == 0)
199 break;
200 if (timeout-- <= 0) {
201 LOG_ERROR("timed out waiting for flash");
202 return ERROR_FAIL;
203 }
204 alive_sleep(1);
205 }
206
207
208 if (status & FLASH_WRPERR) {
209 LOG_ERROR("stm32x device protected");
210 retval = ERROR_FAIL;
211 }
212
213 /* Clear but report errors */
214 if (status & FLASH_ERROR) {
215 /* If this operation fails, we ignore it and report the original
216 * retval
217 */
218 target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_SR),
219 status & FLASH_ERROR);
220 }
221 return retval;
222 }
223
224 static int stm32x_unlock_reg(struct target *target)
225 {
226 uint32_t ctrl;
227
228 /* first check if not already unlocked
229 * otherwise writing on STM32_FLASH_KEYR will fail
230 */
231 int retval = target_read_u32(target, STM32_FLASH_CR, &ctrl);
232 if (retval != ERROR_OK)
233 return retval;
234
235 if ((ctrl & FLASH_LOCK) == 0)
236 return ERROR_OK;
237
238 /* unlock flash registers */
239 retval = target_write_u32(target, STM32_FLASH_KEYR, KEY1);
240 if (retval != ERROR_OK)
241 return retval;
242
243 retval = target_write_u32(target, STM32_FLASH_KEYR, KEY2);
244 if (retval != ERROR_OK)
245 return retval;
246
247 retval = target_read_u32(target, STM32_FLASH_CR, &ctrl);
248 if (retval != ERROR_OK)
249 return retval;
250
251 if (ctrl & FLASH_LOCK) {
252 LOG_ERROR("flash not unlocked STM32_FLASH_CR: %x", ctrl);
253 return ERROR_TARGET_FAILURE;
254 }
255
256 return ERROR_OK;
257 }
258
259 static int stm32x_protect_check(struct flash_bank *bank)
260 {
261 return ERROR_OK;
262 }
263
264 static int stm32x_erase(struct flash_bank *bank, int first, int last)
265 {
266 struct target *target = bank->target;
267 int i;
268
269 if (bank->target->state != TARGET_HALTED) {
270 LOG_ERROR("Target not halted");
271 return ERROR_TARGET_NOT_HALTED;
272 }
273
274 int retval;
275 retval = stm32x_unlock_reg(target);
276 if (retval != ERROR_OK)
277 return retval;
278
279 /*
280 Sector Erase
281 To erase a sector, follow the procedure below:
282 1. Check that no Flash memory operation is ongoing by checking the BSY bit in the
283 FLASH_SR register
284 2. Set the SER bit and select the sector (out of the 12 sectors in the main memory block)
285 you wish to erase (SNB) in the FLASH_CR register
286 3. Set the STRT bit in the FLASH_CR register
287 4. Wait for the BSY bit to be cleared
288 */
289
290 for (i = first; i <= last; i++) {
291 retval = target_write_u32(target,
292 stm32x_get_flash_reg(bank, STM32_FLASH_CR), FLASH_SER | FLASH_SNB(i) | FLASH_STRT);
293 if (retval != ERROR_OK)
294 return retval;
295
296 retval = stm32x_wait_status_busy(bank, FLASH_ERASE_TIMEOUT);
297 if (retval != ERROR_OK)
298 return retval;
299
300 bank->sectors[i].is_erased = 1;
301 }
302
303 retval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_CR), FLASH_LOCK);
304 if (retval != ERROR_OK)
305 return retval;
306
307 return ERROR_OK;
308 }
309
310 static int stm32x_protect(struct flash_bank *bank, int set, int first, int last)
311 {
312 return ERROR_OK;
313 }
314
315 static int stm32x_write_block(struct flash_bank *bank, uint8_t *buffer,
316 uint32_t offset, uint32_t count)
317 {
318 struct target *target = bank->target;
319 uint32_t buffer_size = 16384;
320 struct working_area *write_algorithm;
321 struct working_area *source;
322 uint32_t address = bank->base + offset;
323 struct reg_param reg_params[5];
324 struct armv7m_algorithm armv7m_info;
325 int retval = ERROR_OK;
326
327 /* see contrib/loaders/flash/stm32f2x.S for src */
328
329 static const uint8_t stm32x_flash_write_code[] = {
330 /* wait_fifo: */
331 0xD0, 0xF8, 0x00, 0x80, /* ldr r8, [r0, #0] */
332 0xB8, 0xF1, 0x00, 0x0F, /* cmp r8, #0 */
333 0x1A, 0xD0, /* beq exit */
334 0x47, 0x68, /* ldr r7, [r0, #4] */
335 0x47, 0x45, /* cmp r7, r8 */
336 0xF7, 0xD0, /* beq wait_fifo */
337
338 0xDF, 0xF8, 0x30, 0x60, /* ldr r6, STM32_PROG16 */
339 0x26, 0x61, /* str r6, [r4, #STM32_FLASH_CR_OFFSET] */
340 0x37, 0xF8, 0x02, 0x6B, /* ldrh r6, [r7], #0x02 */
341 0x22, 0xF8, 0x02, 0x6B, /* strh r6, [r2], #0x02 */
342 /* busy: */
343 0xE6, 0x68, /* ldr r6, [r4, #STM32_FLASH_SR_OFFSET] */
344 0x16, 0xF4, 0x80, 0x3F, /* tst r6, #0x10000 */
345 0xFB, 0xD1, /* bne busy */
346 0x16, 0xF0, 0xF0, 0x0F, /* tst r6, #0xf0 */
347 0x07, 0xD1, /* bne error */
348
349 0x8F, 0x42, /* cmp r7, r1 */
350 0x28, 0xBF, /* it cs */
351 0x00, 0xF1, 0x08, 0x07, /* addcs r7, r0, #8 */
352 0x47, 0x60, /* str r7, [r0, #4] */
353 0x01, 0x3B, /* subs r3, r3, #1 */
354 0x13, 0xB1, /* cbz r3, exit */
355 0xE1, 0xE7, /* b wait_fifo */
356 /* error: */
357 0x00, 0x21, /* movs r1, #0 */
358 0x41, 0x60, /* str r1, [r0, #4] */
359 /* exit: */
360 0x30, 0x46, /* mov r0, r6 */
361 0x00, 0xBE, /* bkpt #0x00 */
362
363 /* <STM32_PROG16>: */
364 0x01, 0x01, 0x00, 0x00, /* .word 0x00000101 */
365 };
366
367 if (target_alloc_working_area(target, sizeof(stm32x_flash_write_code),
368 &write_algorithm) != ERROR_OK) {
369 LOG_WARNING("no working area available, can't do block memory writes");
370 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
371 };
372
373 retval = target_write_buffer(target, write_algorithm->address,
374 sizeof(stm32x_flash_write_code),
375 (uint8_t *)stm32x_flash_write_code);
376 if (retval != ERROR_OK)
377 return retval;
378
379 /* memory buffer */
380 while (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) {
381 buffer_size /= 2;
382 if (buffer_size <= 256) {
383 /* we already allocated the writing code, but failed to get a
384 * buffer, free the algorithm */
385 target_free_working_area(target, write_algorithm);
386
387 LOG_WARNING("no large enough working area available, can't do block memory writes");
388 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
389 }
390 };
391
392 armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
393 armv7m_info.core_mode = ARMV7M_MODE_ANY;
394
395 init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT); /* buffer start, status (out) */
396 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT); /* buffer end */
397 init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT); /* target address */
398 init_reg_param(&reg_params[3], "r3", 32, PARAM_OUT); /* count (halfword-16bit) */
399 init_reg_param(&reg_params[4], "r4", 32, PARAM_OUT); /* flash base */
400
401 buf_set_u32(reg_params[0].value, 0, 32, source->address);
402 buf_set_u32(reg_params[1].value, 0, 32, source->address + source->size);
403 buf_set_u32(reg_params[2].value, 0, 32, address);
404 buf_set_u32(reg_params[3].value, 0, 32, count);
405 buf_set_u32(reg_params[4].value, 0, 32, STM32_FLASH_BASE);
406
407 retval = target_run_flash_async_algorithm(target, buffer, count, 2,
408 0, NULL,
409 5, reg_params,
410 source->address, source->size,
411 write_algorithm->address, 0,
412 &armv7m_info);
413
414 if (retval == ERROR_FLASH_OPERATION_FAILED) {
415 LOG_ERROR("error executing stm32x flash write algorithm");
416
417 uint32_t error = buf_get_u32(reg_params[0].value, 0, 32) & FLASH_ERROR;
418
419 if (error & FLASH_WRPERR)
420 LOG_ERROR("flash memory write protected");
421
422 if (error != 0) {
423 LOG_ERROR("flash write failed = %08x", error);
424 /* Clear but report errors */
425 target_write_u32(target, STM32_FLASH_SR, error);
426 retval = ERROR_FAIL;
427 }
428 }
429
430 target_free_working_area(target, source);
431 target_free_working_area(target, write_algorithm);
432
433 destroy_reg_param(&reg_params[0]);
434 destroy_reg_param(&reg_params[1]);
435 destroy_reg_param(&reg_params[2]);
436 destroy_reg_param(&reg_params[3]);
437 destroy_reg_param(&reg_params[4]);
438
439 return retval;
440 }
441
442 static int stm32x_write(struct flash_bank *bank, uint8_t *buffer,
443 uint32_t offset, uint32_t count)
444 {
445 struct target *target = bank->target;
446 uint32_t words_remaining = (count / 2);
447 uint32_t bytes_remaining = (count & 0x00000001);
448 uint32_t address = bank->base + offset;
449 uint32_t bytes_written = 0;
450 int retval;
451
452 if (bank->target->state != TARGET_HALTED) {
453 LOG_ERROR("Target not halted");
454 return ERROR_TARGET_NOT_HALTED;
455 }
456
457 if (offset & 0x1) {
458 LOG_WARNING("offset 0x%" PRIx32 " breaks required 2-byte alignment", offset);
459 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
460 }
461
462 retval = stm32x_unlock_reg(target);
463 if (retval != ERROR_OK)
464 return retval;
465
466 /* multiple half words (2-byte) to be programmed? */
467 if (words_remaining > 0) {
468 /* try using a block write */
469 retval = stm32x_write_block(bank, buffer, offset, words_remaining);
470 if (retval != ERROR_OK) {
471 if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) {
472 /* if block write failed (no sufficient working area),
473 * we use normal (slow) single dword accesses */
474 LOG_WARNING("couldn't use block writes, falling back to single memory accesses");
475 }
476 } else {
477 buffer += words_remaining * 2;
478 address += words_remaining * 2;
479 words_remaining = 0;
480 }
481 }
482
483 if ((retval != ERROR_OK) && (retval != ERROR_TARGET_RESOURCE_NOT_AVAILABLE))
484 return retval;
485
486 /*
487 Standard programming
488 The Flash memory programming sequence is as follows:
489 1. Check that no main Flash memory operation is ongoing by checking the BSY bit in the
490 FLASH_SR register.
491 2. Set the PG bit in the FLASH_CR register
492 3. Perform the data write operation(s) to the desired memory address (inside main
493 memory block or OTP area):
494 – – Half-word access in case of x16 parallelism
495 – Word access in case of x32 parallelism
496 –
497 4.
498 Byte access in case of x8 parallelism
499 Double word access in case of x64 parallelism
500 Wait for the BSY bit to be cleared
501 */
502 while (words_remaining > 0) {
503 uint16_t value;
504 memcpy(&value, buffer + bytes_written, sizeof(uint16_t));
505
506 retval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_CR),
507 FLASH_PG | FLASH_PSIZE_16);
508 if (retval != ERROR_OK)
509 return retval;
510
511 retval = target_write_u16(target, address, value);
512 if (retval != ERROR_OK)
513 return retval;
514
515 retval = stm32x_wait_status_busy(bank, FLASH_WRITE_TIMEOUT);
516 if (retval != ERROR_OK)
517 return retval;
518
519 bytes_written += 2;
520 words_remaining--;
521 address += 2;
522 }
523
524 if (bytes_remaining) {
525 retval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_CR),
526 FLASH_PG | FLASH_PSIZE_8);
527 if (retval != ERROR_OK)
528 return retval;
529 retval = target_write_u8(target, address, buffer[bytes_written]);
530 if (retval != ERROR_OK)
531 return retval;
532
533 retval = stm32x_wait_status_busy(bank, FLASH_WRITE_TIMEOUT);
534 if (retval != ERROR_OK)
535 return retval;
536 }
537
538 return target_write_u32(target, STM32_FLASH_CR, FLASH_LOCK);
539 }
540
541 static void setup_sector(struct flash_bank *bank, int start, int num, int size)
542 {
543 for (int i = start; i < (start + num) ; i++) {
544 bank->sectors[i].offset = bank->size;
545 bank->sectors[i].size = size;
546 bank->size += bank->sectors[i].size;
547 }
548 }
549
550 static int stm32x_get_device_id(struct flash_bank *bank, uint32_t *device_id)
551 {
552 /* this checks for a stm32f4x errata issue where a
553 * stm32f2x DBGMCU_IDCODE is incorrectly returned.
554 * If the issue is detected target is forced to stm32f4x Rev A.
555 * Only effects Rev A silicon */
556
557 struct target *target = bank->target;
558 uint32_t cpuid;
559
560 /* read stm32 device id register */
561 int retval = target_read_u32(target, 0xE0042000, device_id);
562 if (retval != ERROR_OK)
563 return retval;
564
565 if ((*device_id & 0xfff) == 0x411) {
566 /* read CPUID reg to check core type */
567 retval = target_read_u32(target, 0xE000ED00, &cpuid);
568 if (retval != ERROR_OK)
569 return retval;
570
571 /* check for cortex_m4 */
572 if (((cpuid >> 4) & 0xFFF) == 0xC24) {
573 *device_id &= ~((0xFFFF << 16) | 0xfff);
574 *device_id |= (0x1000 << 16) | 0x413;
575 LOG_INFO("stm32f4x errata detected - fixing incorrect MCU_IDCODE");
576 }
577 }
578 return retval;
579 }
580
581 static int stm32x_probe(struct flash_bank *bank)
582 {
583 struct target *target = bank->target;
584 struct stm32x_flash_bank *stm32x_info = bank->driver_priv;
585 int i;
586 uint16_t flash_size_in_kb;
587 uint16_t max_flash_size_in_kb;
588 uint32_t device_id;
589 uint32_t base_address = 0x08000000;
590
591 stm32x_info->probed = 0;
592
593 /* read stm32 device id register */
594 int retval = stm32x_get_device_id(bank, &device_id);
595 if (retval != ERROR_OK)
596 return retval;
597 LOG_INFO("device id = 0x%08" PRIx32 "", device_id);
598
599 /* set max flash size depending on family */
600 switch (device_id & 0xfff) {
601 case 0x411:
602 case 0x413:
603 max_flash_size_in_kb = 1024;
604 break;
605 case 0x419:
606 max_flash_size_in_kb = 2048;
607 break;
608 default:
609 LOG_WARNING("Cannot identify target as a STM32 family.");
610 return ERROR_FAIL;
611 }
612
613 /* get flash size from target. */
614 retval = target_read_u16(target, 0x1FFF7A22, &flash_size_in_kb);
615
616 /* failed reading flash size or flash size invalid (early silicon),
617 * default to max target family */
618 if (retval != ERROR_OK || flash_size_in_kb == 0xffff || flash_size_in_kb == 0) {
619 LOG_WARNING("STM32 flash size failed, probe inaccurate - assuming %dk flash",
620 max_flash_size_in_kb);
621 flash_size_in_kb = max_flash_size_in_kb;
622 }
623
624 LOG_INFO("flash size = %dkbytes", flash_size_in_kb);
625
626 /* did we assign flash size? */
627 assert(flash_size_in_kb != 0xffff);
628
629 /* calculate numbers of pages */
630 int num_pages = (flash_size_in_kb / 128) + 4;
631
632 /* check for larger 2048 bytes devices */
633 if (flash_size_in_kb > 1024)
634 num_pages += 4;
635
636 /* check that calculation result makes sense */
637 assert(num_pages > 0);
638
639 if (bank->sectors) {
640 free(bank->sectors);
641 bank->sectors = NULL;
642 }
643
644 bank->base = base_address;
645 bank->num_sectors = num_pages;
646 bank->sectors = malloc(sizeof(struct flash_sector) * num_pages);
647 bank->size = 0;
648
649 /* fixed memory */
650 setup_sector(bank, 0, 4, 16 * 1024);
651 setup_sector(bank, 4, 1, 64 * 1024);
652
653 /* dynamic memory */
654 setup_sector(bank, 4 + 1, MAX(12, num_pages) - 5, 128 * 1024);
655
656 if (num_pages > 12) {
657
658 /* fixed memory for larger devices */
659 setup_sector(bank, 12, 4, 16 * 1024);
660 setup_sector(bank, 16, 1, 64 * 1024);
661
662 /* dynamic memory for larger devices */
663 setup_sector(bank, 16 + 1, num_pages - 5 - 12, 128 * 1024);
664 }
665
666 for (i = 0; i < num_pages; i++) {
667 bank->sectors[i].is_erased = -1;
668 bank->sectors[i].is_protected = 0;
669 }
670
671 stm32x_info->probed = 1;
672
673 return ERROR_OK;
674 }
675
676 static int stm32x_auto_probe(struct flash_bank *bank)
677 {
678 struct stm32x_flash_bank *stm32x_info = bank->driver_priv;
679 if (stm32x_info->probed)
680 return ERROR_OK;
681 return stm32x_probe(bank);
682 }
683
684 static int get_stm32x_info(struct flash_bank *bank, char *buf, int buf_size)
685 {
686 uint32_t device_id;
687 int printed;
688
689 /* read stm32 device id register */
690 int retval = stm32x_get_device_id(bank, &device_id);
691 if (retval != ERROR_OK)
692 return retval;
693
694 if ((device_id & 0xfff) == 0x411) {
695 printed = snprintf(buf, buf_size, "stm32f2x - Rev: ");
696 buf += printed;
697 buf_size -= printed;
698
699 switch (device_id >> 16) {
700 case 0x1000:
701 snprintf(buf, buf_size, "A");
702 break;
703
704 case 0x2000:
705 snprintf(buf, buf_size, "B");
706 break;
707
708 case 0x1001:
709 snprintf(buf, buf_size, "Z");
710 break;
711
712 case 0x2001:
713 snprintf(buf, buf_size, "Y");
714 break;
715
716 default:
717 snprintf(buf, buf_size, "unknown");
718 break;
719 }
720 } else if (((device_id & 0xfff) == 0x413) ||
721 ((device_id & 0xfff) == 0x419)) {
722 printed = snprintf(buf, buf_size, "stm32f4x - Rev: ");
723 buf += printed;
724 buf_size -= printed;
725
726 switch (device_id >> 16) {
727 case 0x1000:
728 snprintf(buf, buf_size, "A");
729 break;
730
731 case 0x1001:
732 snprintf(buf, buf_size, "Z");
733 break;
734
735 default:
736 snprintf(buf, buf_size, "unknown");
737 break;
738 }
739 } else {
740 snprintf(buf, buf_size, "Cannot identify target as a stm32x\n");
741 return ERROR_FAIL;
742 }
743
744 return ERROR_OK;
745 }
746
747 static int stm32x_mass_erase(struct flash_bank *bank)
748 {
749 int retval;
750 struct target *target = bank->target;
751
752 if (target->state != TARGET_HALTED) {
753 LOG_ERROR("Target not halted");
754 return ERROR_TARGET_NOT_HALTED;
755 }
756
757 retval = stm32x_unlock_reg(target);
758 if (retval != ERROR_OK)
759 return retval;
760
761 /* mass erase flash memory */
762 if (bank->num_sectors > 12)
763 retval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_CR), FLASH_MER | FLASH_MER1);
764 else
765 retval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_CR), FLASH_MER);
766 if (retval != ERROR_OK)
767 return retval;
768 retval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_CR),
769 FLASH_MER | FLASH_STRT);
770 if (retval != ERROR_OK)
771 return retval;
772
773 retval = stm32x_wait_status_busy(bank, 30000);
774 if (retval != ERROR_OK)
775 return retval;
776
777 retval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_CR), FLASH_LOCK);
778 if (retval != ERROR_OK)
779 return retval;
780
781 return ERROR_OK;
782 }
783
784 COMMAND_HANDLER(stm32x_handle_mass_erase_command)
785 {
786 int i;
787
788 if (CMD_ARGC < 1) {
789 command_print(CMD_CTX, "stm32x mass_erase <bank>");
790 return ERROR_COMMAND_SYNTAX_ERROR;
791 }
792
793 struct flash_bank *bank;
794 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
795 if (ERROR_OK != retval)
796 return retval;
797
798 retval = stm32x_mass_erase(bank);
799 if (retval == ERROR_OK) {
800 /* set all sectors as erased */
801 for (i = 0; i < bank->num_sectors; i++)
802 bank->sectors[i].is_erased = 1;
803
804 command_print(CMD_CTX, "stm32x mass erase complete");
805 } else {
806 command_print(CMD_CTX, "stm32x mass erase failed");
807 }
808
809 return retval;
810 }
811
812 static const struct command_registration stm32x_exec_command_handlers[] = {
813 {
814 .name = "mass_erase",
815 .handler = stm32x_handle_mass_erase_command,
816 .mode = COMMAND_EXEC,
817 .usage = "bank_id",
818 .help = "Erase entire flash device.",
819 },
820 COMMAND_REGISTRATION_DONE
821 };
822
823 static const struct command_registration stm32x_command_handlers[] = {
824 {
825 .name = "stm32f2x",
826 .mode = COMMAND_ANY,
827 .help = "stm32f2x flash command group",
828 .usage = "",
829 .chain = stm32x_exec_command_handlers,
830 },
831 COMMAND_REGISTRATION_DONE
832 };
833
834 struct flash_driver stm32f2x_flash = {
835 .name = "stm32f2x",
836 .commands = stm32x_command_handlers,
837 .flash_bank_command = stm32x_flash_bank_command,
838 .erase = stm32x_erase,
839 .protect = stm32x_protect,
840 .write = stm32x_write,
841 .read = default_flash_read,
842 .probe = stm32x_probe,
843 .auto_probe = stm32x_auto_probe,
844 .erase_check = default_flash_blank_check,
845 .protect_check = stm32x_protect_check,
846 .info = get_stm32x_info,
847 };

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)