]> git.sur5r.net Git - openocd/blob - src/flash/nor/stm32f2x.c
flash: cleanup stm32f2x loader
[openocd] / 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 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29
30 #include "imp.h"
31 #include <helper/binarybuffer.h>
32 #include <target/algorithm.h>
33 #include <target/armv7m.h>
34
35 /* Regarding performance:
36  *
37  * Short story - it might be best to leave the performance at
38  * current levels.
39  *
40  * You may see a jump in speed if you change to using
41  * 32bit words for the block programming.
42  *
43  * Its a shame you cannot use the double word as its
44  * even faster - but you require external VPP for that mode.
45  *
46  * Having said all that 16bit writes give us the widest vdd
47  * operating range, so may be worth adding a note to that effect.
48  *
49  */
50
51 /* Danger!!!! The STM32F1x and STM32F2x series actually have
52  * quite different flash controllers.
53  *
54  * What's more scary is that the names of the registers and their
55  * addresses are the same, but the actual bits and what they do are
56  * can be very different.
57  *
58  * To reduce testing complexity and dangers of regressions,
59  * a seperate file is used for stm32fx2x.
60  *
61  * 1mByte part with 4 x 16, 1 x 64, 7 x 128kBytes sectors
62  *
63  * What's the protection page size???
64  *
65  * Tested with STM3220F-EVAL board.
66  *
67  * STM32F21xx series for reference.
68  *
69  * RM0033
70  * http://www.st.com/internet/mcu/product/250192.jsp
71  *
72  * PM0059
73  * www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/PROGRAMMING_MANUAL/CD00233952.pdf
74  *
75  * STM32F1x series - notice that this code was copy, pasted and knocked
76  * into a stm32f2x driver, so in case something has been converted or
77  * bugs haven't been fixed, here are the original manuals:
78  *
79  * RM0008 - Reference manual
80  *
81  * RM0042, the Flash programming manual for low-, medium- high-density and
82  * connectivity line STM32F10x devices
83  *
84  * PM0068, the Flash programming manual for XL-density STM32F10x devices.
85  *
86  */
87
88  // Erase time can be as high as 1000ms, 10x this and it's toast...
89 #define FLASH_ERASE_TIMEOUT 10000
90 #define FLASH_WRITE_TIMEOUT 5
91
92
93 #define STM32_FLASH_BASE        0x40023c00
94 #define STM32_FLASH_ACR         0x40023c00
95 #define STM32_FLASH_KEYR        0x40023c04
96 #define STM32_FLASH_OPTKEYR     0x40023c08
97 #define STM32_FLASH_SR          0x40023c0C
98 #define STM32_FLASH_CR          0x40023c10
99 #define STM32_FLASH_OPTCR       0x40023c14
100 #define STM32_FLASH_OBR         0x40023c1C
101
102
103
104 /* option byte location */
105
106 #define STM32_OB_RDP            0x1FFFF800
107 #define STM32_OB_USER           0x1FFFF802
108 #define STM32_OB_DATA0          0x1FFFF804
109 #define STM32_OB_DATA1          0x1FFFF806
110 #define STM32_OB_WRP0           0x1FFFF808
111 #define STM32_OB_WRP1           0x1FFFF80A
112 #define STM32_OB_WRP2           0x1FFFF80C
113 #define STM32_OB_WRP3           0x1FFFF80E
114
115 /* FLASH_CR register bits */
116
117 #define FLASH_PG                (1 << 0)
118 #define FLASH_SER               (1 << 1)
119 #define FLASH_MER               (1 << 2)
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 {
155         struct working_area *write_algorithm;
156         int probed;
157 };
158
159
160 /* flash bank stm32x <base> <size> 0 0 <target#>
161  */
162 FLASH_BANK_COMMAND_HANDLER(stm32x_flash_bank_command)
163 {
164         struct stm32x_flash_bank *stm32x_info;
165
166         if (CMD_ARGC < 6)
167         {
168                 LOG_WARNING("incomplete flash_bank stm32x configuration");
169                 return ERROR_FLASH_BANK_INVALID;
170         }
171
172         stm32x_info = malloc(sizeof(struct stm32x_flash_bank));
173         bank->driver_priv = stm32x_info;
174
175         stm32x_info->write_algorithm = NULL;
176         stm32x_info->probed = 0;
177
178         return ERROR_OK;
179 }
180
181 static inline int stm32x_get_flash_reg(struct flash_bank *bank, uint32_t reg)
182 {
183         return reg;
184 }
185
186 static inline int stm32x_get_flash_status(struct flash_bank *bank, uint32_t *status)
187 {
188         struct target *target = bank->target;
189         return target_read_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_SR), status);
190 }
191
192 static int stm32x_wait_status_busy(struct flash_bank *bank, int timeout)
193 {
194         struct target *target = bank->target;
195         uint32_t status;
196         int retval = ERROR_OK;
197
198         /* wait for busy to clear */
199         for (;;)
200         {
201                 retval = stm32x_get_flash_status(bank, &status);
202                 if (retval != ERROR_OK)
203                         return retval;
204                 LOG_DEBUG("status: 0x%" PRIx32 "", status);
205                 if ((status & FLASH_BSY) == 0)
206                         break;
207                 if (timeout-- <= 0)
208                 {
209                         LOG_ERROR("timed out waiting for flash");
210                         return ERROR_FAIL;
211                 }
212                 alive_sleep(1);
213         }
214
215
216         if (status & FLASH_WRPERR)
217         {
218                 LOG_ERROR("stm32x device protected");
219                 retval = ERROR_FAIL;
220         }
221
222         /* Clear but report errors */
223         if (status & FLASH_ERROR)
224         {
225                 /* If this operation fails, we ignore it and report the original
226                  * retval
227                  */
228                 target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_SR),
229                                 status & FLASH_ERROR);
230         }
231         return retval;
232 }
233
234 static int stm32x_unlock_reg(struct target *target)
235 {
236         /* unlock flash registers */
237         int retval = target_write_u32(target, STM32_FLASH_KEYR, KEY1);
238         if (retval != ERROR_OK)
239                 return retval;
240
241         retval = target_write_u32(target, STM32_FLASH_KEYR, KEY2);
242         if (retval != ERROR_OK)
243                 return retval;
244         return ERROR_OK;
245 }
246
247 static int stm32x_protect_check(struct flash_bank *bank)
248 {
249         return ERROR_OK;
250 }
251
252 static int stm32x_erase(struct flash_bank *bank, int first, int last)
253 {
254         struct target *target = bank->target;
255         int i;
256
257         if (bank->target->state != TARGET_HALTED)
258         {
259                 LOG_ERROR("Target not halted");
260                 return ERROR_TARGET_NOT_HALTED;
261         }
262
263         int retval;
264         retval = stm32x_unlock_reg(target);
265         if (retval != ERROR_OK)
266                 return retval;
267
268         /*
269         Sector Erase
270         To erase a sector, follow the procedure below:
271         1. Check that no Flash memory operation is ongoing by checking the BSY bit in the
272           FLASH_SR register
273         2. Set the SER bit and select the sector (out of the 12 sectors in the main memory block)
274           you wish to erase (SNB) in the FLASH_CR register
275         3. Set the STRT bit in the FLASH_CR register
276         4. Wait for the BSY bit to be cleared
277          */
278
279         for (i = first; i <= last; i++)
280         {
281                 retval = target_write_u32(target,
282                                 stm32x_get_flash_reg(bank, STM32_FLASH_CR), FLASH_SER | FLASH_SNB(i) | FLASH_STRT);
283                 if (retval != ERROR_OK)
284                         return retval;
285
286                 retval = stm32x_wait_status_busy(bank, FLASH_ERASE_TIMEOUT);
287                 if (retval != ERROR_OK)
288                         return retval;
289
290                 bank->sectors[i].is_erased = 1;
291         }
292
293         retval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_CR), FLASH_LOCK);
294         if (retval != ERROR_OK)
295                 return retval;
296
297         return ERROR_OK;
298 }
299
300 static int stm32x_protect(struct flash_bank *bank, int set, int first, int last)
301 {
302         return ERROR_OK;
303 }
304
305 static int stm32x_write_block(struct flash_bank *bank, uint8_t *buffer,
306                 uint32_t offset, uint32_t count)
307 {
308         struct stm32x_flash_bank *stm32x_info = bank->driver_priv;
309         struct target *target = bank->target;
310         uint32_t buffer_size = 16384;
311         struct working_area *source;
312         uint32_t address = bank->base + offset;
313         struct reg_param reg_params[5];
314         struct armv7m_algorithm armv7m_info;
315         int retval = ERROR_OK;
316
317         /* see contrib/loaders/flash/stm32f2x.S for src */
318
319         static const uint16_t stm32x_flash_write_code_16[] = {
320                 /* 00000000 <write>: */
321                 0x4b07,                         /* ldr          r3, [pc, #28] (20 <STM32_PROG16>) */
322                 0x6123,                         /* str          r3, [r4, #16] */
323                 0xf830, 0x3b02,         /* ldrh.w       r3, [r0], #2 */
324                 0xf821, 0x3b02,         /* strh.w       r3, [r1], #2 */
325
326                 /* 0000000c <busy>: */
327                 0x68e3,                         /* ldr          r3, [r4, #12] */
328                 0xf413, 0x3f80,         /* tst.w        r3, #65536      ; 0x10000 */
329                 0xd0fb,                         /* beq.n        c <busy> */
330                 0xf013, 0x0ff0,         /* tst.w        r3, #240        ; 0xf0 */
331                 0xd101,                         /* bne.n        1e <exit> */
332                 0x3a01,                         /* subs         r2, #1 */
333                 0xd1f0,                         /* bne.n        0 <write> */
334                                                         /* 0000001e <exit>: */
335                 0xbe00,                         /* bkpt         0x0000 */
336
337                 /* 00000020 <STM32_PROG16>: */
338                 0x0101, 0x0000,         /* .word        0x00000101 */
339         };
340
341         /* Flip endian */
342         uint8_t stm32x_flash_write_code[sizeof(stm32x_flash_write_code_16)*2];
343         for (unsigned i = 0; i < sizeof(stm32x_flash_write_code_16) / 2; i++)
344         {
345                 stm32x_flash_write_code[i*2 + 0] = stm32x_flash_write_code_16[i] & 0xff;
346                 stm32x_flash_write_code[i*2 + 1] = (stm32x_flash_write_code_16[i] >> 8) & 0xff;
347         }
348
349         if (target_alloc_working_area(target, sizeof(stm32x_flash_write_code),
350                         &stm32x_info->write_algorithm) != ERROR_OK)
351         {
352                 LOG_WARNING("no working area available, can't do block memory writes");
353                 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
354         };
355
356         if ((retval = target_write_buffer(target, stm32x_info->write_algorithm->address,
357                         sizeof(stm32x_flash_write_code),
358                         (uint8_t*)stm32x_flash_write_code)) != ERROR_OK)
359                 return retval;
360
361         /* memory buffer */
362         while (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK)
363         {
364                 buffer_size /= 2;
365                 if (buffer_size <= 256)
366                 {
367                         /* if we already allocated the writing code, but failed to get a
368                          * buffer, free the algorithm */
369                         if (stm32x_info->write_algorithm)
370                                 target_free_working_area(target, stm32x_info->write_algorithm);
371
372                         LOG_WARNING("no large enough working area available, can't do block memory writes");
373                         return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
374                 }
375         };
376
377         armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
378         armv7m_info.core_mode = ARMV7M_MODE_ANY;
379
380         init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
381         init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
382         init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT);
383         init_reg_param(&reg_params[3], "r3", 32, PARAM_IN_OUT);
384         init_reg_param(&reg_params[4], "r4", 32, PARAM_OUT);
385
386         while (count > 0)
387         {
388                 uint32_t thisrun_count = (count > (buffer_size / 2)) ?
389                                 (buffer_size / 2) : count;
390
391                 if ((retval = target_write_buffer(target, source->address,
392                                 thisrun_count * 2, buffer)) != ERROR_OK)
393                         break;
394
395                 buf_set_u32(reg_params[0].value, 0, 32, source->address);
396                 buf_set_u32(reg_params[1].value, 0, 32, address);
397                 buf_set_u32(reg_params[2].value, 0, 32, thisrun_count);
398                 // R3 is a return value only
399                 buf_set_u32(reg_params[4].value, 0, 32, STM32_FLASH_BASE);
400
401                 if ((retval = target_run_algorithm(target, 0, NULL,
402                                 sizeof(reg_params) / sizeof(*reg_params),
403                                 reg_params,
404                                 stm32x_info->write_algorithm->address,
405                                 0,
406                                 10000, &armv7m_info)) != ERROR_OK)
407                 {
408                         LOG_ERROR("error executing stm32x flash write algorithm");
409                         break;
410                 }
411
412                 uint32_t error = buf_get_u32(reg_params[3].value, 0, 32) & FLASH_ERROR;
413
414                 if (error & FLASH_WRPERR)
415                 {
416                         LOG_ERROR("flash memory write protected");
417                 }
418
419                 if (error != 0)
420                 {
421                         LOG_ERROR("flash write failed = %08x", error);
422                         /* Clear but report errors */
423                         target_write_u32(target, STM32_FLASH_SR, error);
424                         retval = ERROR_FAIL;
425                         break;
426                 }
427
428                 buffer += thisrun_count * 2;
429                 address += thisrun_count * 2;
430                 count -= thisrun_count;
431         }
432
433         target_free_working_area(target, source);
434         target_free_working_area(target, stm32x_info->write_algorithm);
435
436         destroy_reg_param(&reg_params[0]);
437         destroy_reg_param(&reg_params[1]);
438         destroy_reg_param(&reg_params[2]);
439         destroy_reg_param(&reg_params[3]);
440         destroy_reg_param(&reg_params[4]);
441
442         return retval;
443 }
444
445 static int stm32x_write(struct flash_bank *bank, uint8_t *buffer,
446                 uint32_t offset, uint32_t count)
447 {
448         struct target *target = bank->target;
449         uint32_t words_remaining = (count / 2);
450         uint32_t bytes_remaining = (count & 0x00000001);
451         uint32_t address = bank->base + offset;
452         uint32_t bytes_written = 0;
453         int retval;
454
455         if (bank->target->state != TARGET_HALTED)
456         {
457                 LOG_ERROR("Target not halted");
458                 return ERROR_TARGET_NOT_HALTED;
459         }
460
461         if (offset & 0x1)
462         {
463                 LOG_WARNING("offset 0x%" PRIx32 " breaks required 2-byte alignment", offset);
464                 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
465         }
466
467         retval = stm32x_unlock_reg(target);
468         if (retval != ERROR_OK)
469                 return retval;
470
471         /* multiple half words (2-byte) to be programmed? */
472         if (words_remaining > 0)
473         {
474                 /* try using a block write */
475                 if ((retval = stm32x_write_block(bank, buffer, offset, words_remaining)) != ERROR_OK)
476                 {
477                         if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE)
478                         {
479                                 /* if block write failed (no sufficient working area),
480                                  * we use normal (slow) single dword accesses */
481                                 LOG_WARNING("couldn't use block writes, falling back to single memory accesses");
482                         }
483                 }
484                 else
485                 {
486                         buffer += words_remaining * 2;
487                         address += words_remaining * 2;
488                         words_remaining = 0;
489                 }
490         }
491
492         if ((retval != ERROR_OK) && (retval != ERROR_TARGET_RESOURCE_NOT_AVAILABLE))
493                 return retval;
494
495         /*
496         Standard programming
497         The Flash memory programming sequence is as follows:
498         1. Check that no main Flash memory operation is ongoing by checking the BSY bit in the
499           FLASH_SR register.
500         2. Set the PG bit in the FLASH_CR register
501         3. Perform the data write operation(s) to the desired memory address (inside main
502           memory block or OTP area):
503         – – Half-word access in case of x16 parallelism
504         – Word access in case of x32 parallelism
505         –
506         4.
507         Byte access in case of x8 parallelism
508         Double word access in case of x64 parallelism
509         Wait for the BSY bit to be cleared
510         */
511         while (words_remaining > 0)
512         {
513                 uint16_t value;
514                 memcpy(&value, buffer + bytes_written, sizeof(uint16_t));
515
516                 retval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_CR),
517                                 FLASH_PG | FLASH_PSIZE_16);
518                 if (retval != ERROR_OK)
519                         return retval;
520
521                 retval = target_write_u16(target, address, value);
522                 if (retval != ERROR_OK)
523                         return retval;
524
525                 retval = stm32x_wait_status_busy(bank, FLASH_WRITE_TIMEOUT);
526                 if (retval != ERROR_OK)
527                         return retval;
528
529                 bytes_written += 2;
530                 words_remaining--;
531                 address += 2;
532         }
533
534         if (bytes_remaining)
535         {
536                 retval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_CR),
537                                 FLASH_PG | FLASH_PSIZE_8);
538                 if (retval != ERROR_OK)
539                         return retval;
540                 retval = target_write_u8(target, address, buffer[bytes_written]);
541                 if (retval != ERROR_OK)
542                         return retval;
543
544                 retval = stm32x_wait_status_busy(bank, FLASH_WRITE_TIMEOUT);
545                 if (retval != ERROR_OK)
546                         return retval;
547         }
548
549         return target_write_u32(target, STM32_FLASH_CR, FLASH_LOCK);
550 }
551
552 static void setup_sector(struct flash_bank *bank, int start, int num, int size)
553 {
554         for (int i = start; i < (start + num) ; i++)
555         {
556                 bank->sectors[i].offset = bank->size;
557                 bank->sectors[i].size = size;
558                 bank->size += bank->sectors[i].size;
559         }
560 }
561
562 static int stm32x_probe(struct flash_bank *bank)
563 {
564         struct target *target = bank->target;
565         struct stm32x_flash_bank *stm32x_info = bank->driver_priv;
566         int i;
567         uint16_t num_pages;
568         uint32_t device_id;
569         uint32_t base_address = 0x08000000;
570
571         stm32x_info->probed = 0;
572
573         /* read stm32 device id register */
574         int retval = target_read_u32(target, 0xE0042000, &device_id);
575         if (retval != ERROR_OK)
576                 return retval;
577         LOG_INFO("device id = 0x%08" PRIx32 "", device_id);
578
579         if ((device_id & 0x7ff) != 0x411)
580         {
581                 LOG_WARNING("Cannot identify target as a STM32 family, try the other STM32 drivers.");
582                 return ERROR_FAIL;
583         }
584
585         /* sectors sizes vary, handle this in a different code path
586          * than the rest.
587          */
588         // Uhhh.... what to use here?
589
590         /* calculate numbers of pages*/
591         num_pages = 4 + 1 + 7;
592
593         if (bank->sectors)
594         {
595                 free(bank->sectors);
596                 bank->sectors = NULL;
597         }
598
599         bank->base = base_address;
600         bank->num_sectors = num_pages;
601         bank->sectors = malloc(sizeof(struct flash_sector) * num_pages);
602
603         bank->size = 0;
604         setup_sector(bank, 0, 4, 16 * 1024);
605         setup_sector(bank, 4, 1, 64 * 1024);
606         setup_sector(bank, 4+1, 7, 128 * 1024);
607
608         for (i = 0; i < num_pages; i++)
609         {
610                 bank->sectors[i].is_erased = -1;
611                 bank->sectors[i].is_protected = 0;
612         }
613
614         LOG_INFO("flash size = %dkBytes", bank->size / 1024);
615
616         stm32x_info->probed = 1;
617
618         return ERROR_OK;
619 }
620
621 static int stm32x_auto_probe(struct flash_bank *bank)
622 {
623         struct stm32x_flash_bank *stm32x_info = bank->driver_priv;
624         if (stm32x_info->probed)
625                 return ERROR_OK;
626         return stm32x_probe(bank);
627 }
628
629 static int get_stm32x_info(struct flash_bank *bank, char *buf, int buf_size)
630 {
631         struct target *target = bank->target;
632         uint32_t device_id;
633         int printed;
634
635         /* read stm32 device id register */
636         int retval = target_read_u32(target, 0xE0042000, &device_id);
637         if (retval != ERROR_OK)
638                 return retval;
639
640         if ((device_id & 0x7ff) == 0x411)
641         {
642                 printed = snprintf(buf, buf_size, "stm32x (1mByte part) - Rev: ");
643                 buf += printed;
644                 buf_size -= printed;
645
646                 switch (device_id >> 16)
647                 {
648                         case 0x1000:
649                                 snprintf(buf, buf_size, "A");
650                                 break;
651
652                         case 0x2000:
653                                 snprintf(buf, buf_size, "B");
654                                 break;
655
656                         case 0x1001:
657                                 snprintf(buf, buf_size, "Z");
658                                 break;
659
660                         case 0x2001:
661                                 snprintf(buf, buf_size, "Y");
662                                 break;
663
664                         default:
665                                 snprintf(buf, buf_size, "unknown");
666                                 break;
667                 }
668         }
669         else
670         {
671                 snprintf(buf, buf_size, "Cannot identify target as a stm32x\n");
672                 return ERROR_FAIL;
673         }
674
675         return ERROR_OK;
676 }
677
678 static const struct command_registration stm32x_exec_command_handlers[] = {
679         COMMAND_REGISTRATION_DONE
680 };
681
682 static const struct command_registration stm32x_command_handlers[] = {
683         {
684                 .name = "stm32f2x",
685                 .mode = COMMAND_ANY,
686                 .help = "stm32f2x flash command group",
687                 .chain = stm32x_exec_command_handlers,
688         },
689         COMMAND_REGISTRATION_DONE
690 };
691
692 struct flash_driver stm32f2x_flash = {
693         .name = "stm32f2x",
694         .commands = stm32x_command_handlers,
695         .flash_bank_command = stm32x_flash_bank_command,
696         .erase = stm32x_erase,
697         .protect = stm32x_protect,
698         .write = stm32x_write,
699         .read = default_flash_read,
700         .probe = stm32x_probe,
701         .auto_probe = stm32x_auto_probe,
702         .erase_check = default_flash_mem_blank_check,
703         .protect_check = stm32x_protect_check,
704         .info = get_stm32x_info,
705 };