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