1 /***************************************************************************
2 * Copyright (C) 2015 by Uwe Bonnes *
3 * bon@elektron.ikp.physik.tu-darmstadt.de *
5 * Copyright (C) 2019 by Tarek Bochkati for STMicroelectronics *
6 * tarek.bouchkati@gmail.com *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
20 ***************************************************************************/
27 #include <helper/binarybuffer.h>
28 #include <target/algorithm.h>
29 #include <target/armv7m.h>
33 /* STM32L4xxx series for reference.
35 * RM0351 (STM32L4x5/STM32L4x6)
36 * http://www.st.com/resource/en/reference_manual/dm00083560.pdf
38 * RM0394 (STM32L43x/44x/45x/46x)
39 * http://www.st.com/resource/en/reference_manual/dm00151940.pdf
41 * RM0432 (STM32L4R/4Sxx)
42 * http://www.st.com/resource/en/reference_manual/dm00310109.pdf
44 * STM32L476RG Datasheet (for erase timing)
45 * http://www.st.com/resource/en/datasheet/stm32l476rg.pdf
47 * The RM0351 devices have normally two banks, but on 512 and 256 kiB devices
48 * an option byte is available to map all sectors to the first bank.
49 * Both STM32 banks are treated as one OpenOCD bank, as other STM32 devices
52 * RM0394 devices have a single bank only.
54 * RM0432 devices have single and dual bank operating modes.
55 * - for STM32L4R/Sxx the FLASH size is 2Mbyte or 1Mbyte.
56 * - for STM32L4P/Q5x the FLASH size is 1Mbyte or 512Kbyte.
57 * Bank page (sector) size is 4Kbyte (dual mode) or 8Kbyte (single mode).
59 * Bank mode is controlled by two different bits in option bytes register.
61 * In 2M FLASH devices bit 22 (DBANK) controls Dual Bank mode.
62 * In 1M FLASH devices bit 21 (DB1M) controls Dual Bank mode.
64 * In 1M FLASH devices bit 22 (DBANK) controls Dual Bank mode.
65 * In 512K FLASH devices bit 21 (DB512K) controls Dual Bank mode.
69 /* STM32WBxxx series for reference.
72 * http://www.st.com/resource/en/reference_manual/dm00318631.pdf
75 * http://www.st.com/resource/en/reference_manual/dm00622834.pdf
79 * STM32G0xxx series for reference.
82 * http://www.st.com/resource/en/reference_manual/dm00371828.pdf
85 * http://www.st.com/resource/en/reference_manual/dm00463896.pdf
89 * STM32G4xxx series for reference.
91 * RM0440 (STM32G43x/44x/47x/48x)
92 * http://www.st.com/resource/en/reference_manual/dm00355726.pdf
94 * Cat. 2 devices have single bank only, page size is 2kByte.
96 * Cat. 3 devices have single and dual bank operating modes,
97 * Page size is 2kByte (dual mode) or 4kByte (single mode).
99 * Bank mode is controlled by bit 22 (DBANK) in option bytes register.
100 * Both banks are treated as a single OpenOCD bank.
103 /* Erase time can be as high as 25ms, 10x this and assume it's toast... */
105 #define FLASH_ERASE_TIMEOUT 250
112 struct stm32l4_part_info
{
114 const char *device_str
;
115 const struct stm32l4_rev
*revs
;
116 const size_t num_revs
;
117 const uint16_t max_flash_size_kb
;
118 const bool has_dual_bank
;
119 const uint32_t flash_regs_base
;
120 const uint32_t fsize_addr
;
123 struct stm32l4_flash_bank
{
129 uint32_t user_bank_size
;
130 uint32_t wrpxxr_mask
;
131 const struct stm32l4_part_info
*part_info
;
134 /* human readable list of families this drivers supports */
135 static const char *device_families
= "STM32L4/L4+/WB/G4/G0";
137 static const struct stm32l4_rev stm32_415_revs
[] = {
138 { 0x1000, "1" }, { 0x1001, "2" }, { 0x1003, "3" }, { 0x1007, "4" }
141 static const struct stm32l4_rev stm32_435_revs
[] = {
142 { 0x1000, "A" }, { 0x1001, "Z" }, { 0x2001, "Y" },
145 static const struct stm32l4_rev stm32_460_revs
[] = {
146 { 0x1000, "A/Z" } /* A and Z, no typo in RM! */, { 0x2000, "B" },
149 static const struct stm32l4_rev stm32_461_revs
[] = {
150 { 0x1000, "A" }, { 0x2000, "B" },
153 static const struct stm32l4_rev stm32_462_revs
[] = {
154 { 0x1000, "A" }, { 0x1001, "Z" }, { 0x2001, "Y" },
157 static const struct stm32l4_rev stm32_464_revs
[] = {
158 { 0x1000, "A" }, { 0x1001, "Z" }, { 0x2001, "Y" },
161 static const struct stm32l4_rev stm32_466_revs
[] = {
162 { 0x1000, "A" }, { 0x1001, "Z" }, { 0x2000, "B" },
165 static const struct stm32l4_rev stm32_468_revs
[] = {
166 { 0x1000, "A" }, { 0x2000, "B" }, { 0x2001, "Z" },
169 static const struct stm32l4_rev stm32_469_revs
[] = {
170 { 0x1000, "A" }, { 0x2000, "B" }, { 0x2001, "Z" },
173 static const struct stm32l4_rev stm32_470_revs
[] = {
174 { 0x1000, "A" }, { 0x1001, "Z" }, { 0x1003, "Y" }, { 0x100F, "W" },
177 static const struct stm32l4_rev stm32_471_revs
[] = {
181 static const struct stm32l4_rev stm32_495_revs
[] = {
185 static const struct stm32l4_part_info stm32l4_parts
[] = {
188 .revs
= stm32_415_revs
,
189 .num_revs
= ARRAY_SIZE(stm32_415_revs
),
190 .device_str
= "STM32L47/L48xx",
191 .max_flash_size_kb
= 1024,
192 .has_dual_bank
= true,
193 .flash_regs_base
= 0x40022000,
194 .fsize_addr
= 0x1FFF75E0,
198 .revs
= stm32_435_revs
,
199 .num_revs
= ARRAY_SIZE(stm32_435_revs
),
200 .device_str
= "STM32L43/L44xx",
201 .max_flash_size_kb
= 256,
202 .has_dual_bank
= false,
203 .flash_regs_base
= 0x40022000,
204 .fsize_addr
= 0x1FFF75E0,
208 .revs
= stm32_460_revs
,
209 .num_revs
= ARRAY_SIZE(stm32_460_revs
),
210 .device_str
= "STM32G07/G08xx",
211 .max_flash_size_kb
= 128,
212 .has_dual_bank
= false,
213 .flash_regs_base
= 0x40022000,
214 .fsize_addr
= 0x1FFF75E0,
218 .revs
= stm32_461_revs
,
219 .num_revs
= ARRAY_SIZE(stm32_461_revs
),
220 .device_str
= "STM32L49/L4Axx",
221 .max_flash_size_kb
= 1024,
222 .has_dual_bank
= true,
223 .flash_regs_base
= 0x40022000,
224 .fsize_addr
= 0x1FFF75E0,
228 .revs
= stm32_462_revs
,
229 .num_revs
= ARRAY_SIZE(stm32_462_revs
),
230 .device_str
= "STM32L45/L46xx",
231 .max_flash_size_kb
= 512,
232 .has_dual_bank
= false,
233 .flash_regs_base
= 0x40022000,
234 .fsize_addr
= 0x1FFF75E0,
238 .revs
= stm32_464_revs
,
239 .num_revs
= ARRAY_SIZE(stm32_464_revs
),
240 .device_str
= "STM32L41/L42xx",
241 .max_flash_size_kb
= 128,
242 .has_dual_bank
= false,
243 .flash_regs_base
= 0x40022000,
244 .fsize_addr
= 0x1FFF75E0,
248 .revs
= stm32_466_revs
,
249 .num_revs
= ARRAY_SIZE(stm32_466_revs
),
250 .device_str
= "STM32G03/G04xx",
251 .max_flash_size_kb
= 64,
252 .has_dual_bank
= false,
253 .flash_regs_base
= 0x40022000,
254 .fsize_addr
= 0x1FFF75E0,
258 .revs
= stm32_468_revs
,
259 .num_revs
= ARRAY_SIZE(stm32_468_revs
),
260 .device_str
= "STM32G43/G44xx",
261 .max_flash_size_kb
= 128,
262 .has_dual_bank
= false,
263 .flash_regs_base
= 0x40022000,
264 .fsize_addr
= 0x1FFF75E0,
268 .revs
= stm32_469_revs
,
269 .num_revs
= ARRAY_SIZE(stm32_469_revs
),
270 .device_str
= "STM32G47/G48xx",
271 .max_flash_size_kb
= 512,
272 .has_dual_bank
= true,
273 .flash_regs_base
= 0x40022000,
274 .fsize_addr
= 0x1FFF75E0,
278 .revs
= stm32_470_revs
,
279 .num_revs
= ARRAY_SIZE(stm32_470_revs
),
280 .device_str
= "STM32L4R/L4Sxx",
281 .max_flash_size_kb
= 2048,
282 .has_dual_bank
= true,
283 .flash_regs_base
= 0x40022000,
284 .fsize_addr
= 0x1FFF75E0,
288 .revs
= stm32_471_revs
,
289 .num_revs
= ARRAY_SIZE(stm32_471_revs
),
290 .device_str
= "STM32L4P5/L4Q5x",
291 .max_flash_size_kb
= 1024,
292 .has_dual_bank
= true,
293 .flash_regs_base
= 0x40022000,
294 .fsize_addr
= 0x1FFF75E0,
298 .revs
= stm32_495_revs
,
299 .num_revs
= ARRAY_SIZE(stm32_495_revs
),
300 .device_str
= "STM32WB5x",
301 .max_flash_size_kb
= 1024,
302 .has_dual_bank
= false,
303 .flash_regs_base
= 0x58004000,
304 .fsize_addr
= 0x1FFF75E0,
308 /* flash bank stm32l4x <base> <size> 0 0 <target#> */
309 FLASH_BANK_COMMAND_HANDLER(stm32l4_flash_bank_command
)
311 struct stm32l4_flash_bank
*stm32l4_info
;
314 return ERROR_COMMAND_SYNTAX_ERROR
;
316 stm32l4_info
= malloc(sizeof(struct stm32l4_flash_bank
));
318 return ERROR_FAIL
; /* Checkme: What better error to use?*/
319 bank
->driver_priv
= stm32l4_info
;
321 /* The flash write must be aligned to a double word (8-bytes) boundary.
322 * Ask the flash infrastructure to ensure required alignment */
323 bank
->write_start_alignment
= bank
->write_end_alignment
= 8;
325 stm32l4_info
->probed
= false;
326 stm32l4_info
->user_bank_size
= bank
->size
;
331 static inline uint32_t stm32l4_get_flash_reg(struct flash_bank
*bank
, uint32_t reg_offset
)
333 struct stm32l4_flash_bank
*stm32l4_info
= bank
->driver_priv
;
334 return stm32l4_info
->part_info
->flash_regs_base
+ reg_offset
;
337 static inline int stm32l4_read_flash_reg(struct flash_bank
*bank
, uint32_t reg_offset
, uint32_t *value
)
339 return target_read_u32(bank
->target
, stm32l4_get_flash_reg(bank
, reg_offset
), value
);
342 static inline int stm32l4_write_flash_reg(struct flash_bank
*bank
, uint32_t reg_offset
, uint32_t value
)
344 return target_write_u32(bank
->target
, stm32l4_get_flash_reg(bank
, reg_offset
), value
);
347 static int stm32l4_wait_status_busy(struct flash_bank
*bank
, int timeout
)
350 int retval
= ERROR_OK
;
352 /* wait for busy to clear */
354 retval
= stm32l4_read_flash_reg(bank
, STM32_FLASH_SR
, &status
);
355 if (retval
!= ERROR_OK
)
357 LOG_DEBUG("status: 0x%" PRIx32
"", status
);
358 if ((status
& FLASH_BSY
) == 0)
360 if (timeout
-- <= 0) {
361 LOG_ERROR("timed out waiting for flash");
368 if (status
& FLASH_WRPERR
) {
369 LOG_ERROR("stm32x device protected");
373 /* Clear but report errors */
374 if (status
& FLASH_ERROR
) {
375 if (retval
== ERROR_OK
)
377 /* If this operation fails, we ignore it and report the original
380 stm32l4_write_flash_reg(bank
, STM32_FLASH_SR
, status
& FLASH_ERROR
);
386 static int stm32l4_unlock_reg(struct flash_bank
*bank
)
390 /* first check if not already unlocked
391 * otherwise writing on STM32_FLASH_KEYR will fail
393 int retval
= stm32l4_read_flash_reg(bank
, STM32_FLASH_CR
, &ctrl
);
394 if (retval
!= ERROR_OK
)
397 if ((ctrl
& FLASH_LOCK
) == 0)
400 /* unlock flash registers */
401 retval
= stm32l4_write_flash_reg(bank
, STM32_FLASH_KEYR
, KEY1
);
402 if (retval
!= ERROR_OK
)
405 retval
= stm32l4_write_flash_reg(bank
, STM32_FLASH_KEYR
, KEY2
);
406 if (retval
!= ERROR_OK
)
409 retval
= stm32l4_read_flash_reg(bank
, STM32_FLASH_CR
, &ctrl
);
410 if (retval
!= ERROR_OK
)
413 if (ctrl
& FLASH_LOCK
) {
414 LOG_ERROR("flash not unlocked STM32_FLASH_CR: %" PRIx32
, ctrl
);
415 return ERROR_TARGET_FAILURE
;
421 static int stm32l4_unlock_option_reg(struct flash_bank
*bank
)
425 int retval
= stm32l4_read_flash_reg(bank
, STM32_FLASH_CR
, &ctrl
);
426 if (retval
!= ERROR_OK
)
429 if ((ctrl
& FLASH_OPTLOCK
) == 0)
432 /* unlock option registers */
433 retval
= stm32l4_write_flash_reg(bank
, STM32_FLASH_OPTKEYR
, OPTKEY1
);
434 if (retval
!= ERROR_OK
)
437 retval
= stm32l4_write_flash_reg(bank
, STM32_FLASH_OPTKEYR
, OPTKEY2
);
438 if (retval
!= ERROR_OK
)
441 retval
= stm32l4_read_flash_reg(bank
, STM32_FLASH_CR
, &ctrl
);
442 if (retval
!= ERROR_OK
)
445 if (ctrl
& FLASH_OPTLOCK
) {
446 LOG_ERROR("options not unlocked STM32_FLASH_CR: %" PRIx32
, ctrl
);
447 return ERROR_TARGET_FAILURE
;
453 static int stm32l4_write_option(struct flash_bank
*bank
, uint32_t reg_offset
,
454 uint32_t value
, uint32_t mask
)
459 retval
= stm32l4_read_flash_reg(bank
, reg_offset
, &optiondata
);
460 if (retval
!= ERROR_OK
)
463 retval
= stm32l4_unlock_reg(bank
);
464 if (retval
!= ERROR_OK
)
467 retval
= stm32l4_unlock_option_reg(bank
);
468 if (retval
!= ERROR_OK
)
471 optiondata
= (optiondata
& ~mask
) | (value
& mask
);
473 retval
= stm32l4_write_flash_reg(bank
, reg_offset
, optiondata
);
474 if (retval
!= ERROR_OK
)
477 retval
= stm32l4_write_flash_reg(bank
, STM32_FLASH_CR
, FLASH_OPTSTRT
);
478 if (retval
!= ERROR_OK
)
481 retval
= stm32l4_wait_status_busy(bank
, FLASH_ERASE_TIMEOUT
);
484 retval2
= stm32l4_write_flash_reg(bank
, STM32_FLASH_CR
, FLASH_LOCK
| FLASH_OPTLOCK
);
486 if (retval
!= ERROR_OK
)
492 static int stm32l4_protect_check(struct flash_bank
*bank
)
494 struct stm32l4_flash_bank
*stm32l4_info
= bank
->driver_priv
;
496 uint32_t wrp1ar
, wrp1br
, wrp2ar
, wrp2br
;
497 stm32l4_read_flash_reg(bank
, STM32_FLASH_WRP1AR
, &wrp1ar
);
498 stm32l4_read_flash_reg(bank
, STM32_FLASH_WRP1BR
, &wrp1br
);
499 if (stm32l4_info
->part_info
->has_dual_bank
) {
500 stm32l4_read_flash_reg(bank
, STM32_FLASH_WRP2AR
, &wrp2ar
);
501 stm32l4_read_flash_reg(bank
, STM32_FLASH_WRP2BR
, &wrp2br
);
503 /* prevent unintialized errors */
508 const uint8_t wrp1a_start
= wrp1ar
& stm32l4_info
->wrpxxr_mask
;
509 const uint8_t wrp1a_end
= (wrp1ar
>> 16) & stm32l4_info
->wrpxxr_mask
;
510 const uint8_t wrp1b_start
= wrp1br
& stm32l4_info
->wrpxxr_mask
;
511 const uint8_t wrp1b_end
= (wrp1br
>> 16) & stm32l4_info
->wrpxxr_mask
;
512 const uint8_t wrp2a_start
= wrp2ar
& stm32l4_info
->wrpxxr_mask
;
513 const uint8_t wrp2a_end
= (wrp2ar
>> 16) & stm32l4_info
->wrpxxr_mask
;
514 const uint8_t wrp2b_start
= wrp2br
& stm32l4_info
->wrpxxr_mask
;
515 const uint8_t wrp2b_end
= (wrp2br
>> 16) & stm32l4_info
->wrpxxr_mask
;
517 for (int i
= 0; i
< bank
->num_sectors
; i
++) {
518 if (i
< stm32l4_info
->bank1_sectors
) {
519 if (((i
>= wrp1a_start
) &&
521 ((i
>= wrp1b_start
) &&
523 bank
->sectors
[i
].is_protected
= 1;
525 bank
->sectors
[i
].is_protected
= 0;
527 assert(stm32l4_info
->part_info
->has_dual_bank
== true);
529 snb
= i
- stm32l4_info
->bank1_sectors
;
530 if (((snb
>= wrp2a_start
) &&
531 (snb
<= wrp2a_end
)) ||
532 ((snb
>= wrp2b_start
) &&
534 bank
->sectors
[i
].is_protected
= 1;
536 bank
->sectors
[i
].is_protected
= 0;
542 static int stm32l4_erase(struct flash_bank
*bank
, int first
, int last
)
544 struct stm32l4_flash_bank
*stm32l4_info
= bank
->driver_priv
;
548 assert((0 <= first
) && (first
<= last
) && (last
< bank
->num_sectors
));
550 if (bank
->target
->state
!= TARGET_HALTED
) {
551 LOG_ERROR("Target not halted");
552 return ERROR_TARGET_NOT_HALTED
;
555 retval
= stm32l4_unlock_reg(bank
);
556 if (retval
!= ERROR_OK
)
561 To erase a sector, follow the procedure below:
562 1. Check that no Flash memory operation is ongoing by
563 checking the BSY bit in the FLASH_SR register
564 2. Set the PER bit and select the page and bank
565 you wish to erase in the FLASH_CR register
566 3. Set the STRT bit in the FLASH_CR register
567 4. Wait for the BSY bit to be cleared
570 for (i
= first
; i
<= last
; i
++) {
571 uint32_t erase_flags
;
572 erase_flags
= FLASH_PER
| FLASH_STRT
;
574 if (i
>= stm32l4_info
->bank1_sectors
) {
576 snb
= i
- stm32l4_info
->bank1_sectors
;
577 erase_flags
|= snb
<< FLASH_PAGE_SHIFT
| FLASH_CR_BKER
;
579 erase_flags
|= i
<< FLASH_PAGE_SHIFT
;
580 retval
= stm32l4_write_flash_reg(bank
, STM32_FLASH_CR
, erase_flags
);
581 if (retval
!= ERROR_OK
)
584 retval
= stm32l4_wait_status_busy(bank
, FLASH_ERASE_TIMEOUT
);
585 if (retval
!= ERROR_OK
)
588 bank
->sectors
[i
].is_erased
= 1;
592 retval2
= stm32l4_write_flash_reg(bank
, STM32_FLASH_CR
, FLASH_LOCK
);
594 if (retval
!= ERROR_OK
)
600 static int stm32l4_protect(struct flash_bank
*bank
, int set
, int first
, int last
)
602 struct target
*target
= bank
->target
;
603 struct stm32l4_flash_bank
*stm32l4_info
= bank
->driver_priv
;
605 if (target
->state
!= TARGET_HALTED
) {
606 LOG_ERROR("Target not halted");
607 return ERROR_TARGET_NOT_HALTED
;
612 uint32_t reg_value
= 0xFF; /* Default to bank un-protected */
613 if (last
>= stm32l4_info
->bank1_sectors
) {
615 uint8_t begin
= first
> stm32l4_info
->bank1_sectors
? first
: 0x00;
616 reg_value
= ((last
& 0xFF) << 16) | begin
;
619 ret
= stm32l4_write_option(bank
, STM32_FLASH_WRP2AR
, reg_value
, 0xffffffff);
622 reg_value
= 0xFF; /* Default to bank un-protected */
623 if (first
< stm32l4_info
->bank1_sectors
) {
625 uint8_t end
= last
>= stm32l4_info
->bank1_sectors
? 0xFF : last
;
626 reg_value
= (end
<< 16) | (first
& 0xFF);
629 ret
= stm32l4_write_option(bank
, STM32_FLASH_WRP1AR
, reg_value
, 0xffffffff);
635 /* Count is in double-words */
636 static int stm32l4_write_block(struct flash_bank
*bank
, const uint8_t *buffer
,
637 uint32_t offset
, uint32_t count
)
639 struct target
*target
= bank
->target
;
640 struct stm32l4_flash_bank
*stm32l4_info
= bank
->driver_priv
;
641 uint32_t buffer_size
;
642 struct working_area
*write_algorithm
;
643 struct working_area
*source
;
644 uint32_t address
= bank
->base
+ offset
;
645 struct reg_param reg_params
[6];
646 struct armv7m_algorithm armv7m_info
;
647 int retval
= ERROR_OK
;
649 static const uint8_t stm32l4_flash_write_code
[] = {
650 #include "../../../contrib/loaders/flash/stm32/stm32l4x.inc"
653 if (target_alloc_working_area(target
, sizeof(stm32l4_flash_write_code
),
654 &write_algorithm
) != ERROR_OK
) {
655 LOG_WARNING("no working area available, can't do block memory writes");
656 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
659 retval
= target_write_buffer(target
, write_algorithm
->address
,
660 sizeof(stm32l4_flash_write_code
),
661 stm32l4_flash_write_code
);
662 if (retval
!= ERROR_OK
) {
663 target_free_working_area(target
, write_algorithm
);
667 /* memory buffer, size *must* be multiple of dword plus one dword for rp and one for wp */
668 buffer_size
= target_get_working_area_avail(target
) & ~(2 * sizeof(uint32_t) - 1);
669 if (buffer_size
< 256) {
670 LOG_WARNING("large enough working area not available, can't do block memory writes");
671 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
672 } else if (buffer_size
> 16384) {
673 /* probably won't benefit from more than 16k ... */
677 if (target_alloc_working_area_try(target
, buffer_size
, &source
) != ERROR_OK
) {
678 LOG_ERROR("allocating working area failed");
679 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
682 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
683 armv7m_info
.core_mode
= ARM_MODE_THREAD
;
685 init_reg_param(®_params
[0], "r0", 32, PARAM_IN_OUT
); /* buffer start, status (out) */
686 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
); /* buffer end */
687 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
); /* target address */
688 init_reg_param(®_params
[3], "r3", 32, PARAM_OUT
); /* count (double word-64bit) */
689 init_reg_param(®_params
[4], "r4", 32, PARAM_OUT
); /* flash status register */
690 init_reg_param(®_params
[5], "r5", 32, PARAM_OUT
); /* flash control register */
692 buf_set_u32(reg_params
[0].value
, 0, 32, source
->address
);
693 buf_set_u32(reg_params
[1].value
, 0, 32, source
->address
+ source
->size
);
694 buf_set_u32(reg_params
[2].value
, 0, 32, address
);
695 buf_set_u32(reg_params
[3].value
, 0, 32, count
);
696 buf_set_u32(reg_params
[4].value
, 0, 32, stm32l4_info
->part_info
->flash_regs_base
+ STM32_FLASH_SR
);
697 buf_set_u32(reg_params
[5].value
, 0, 32, stm32l4_info
->part_info
->flash_regs_base
+ STM32_FLASH_CR
);
699 retval
= target_run_flash_async_algorithm(target
, buffer
, count
, 8,
701 ARRAY_SIZE(reg_params
), reg_params
,
702 source
->address
, source
->size
,
703 write_algorithm
->address
, 0,
706 if (retval
== ERROR_FLASH_OPERATION_FAILED
) {
707 LOG_ERROR("error executing stm32l4 flash write algorithm");
709 uint32_t error
= buf_get_u32(reg_params
[0].value
, 0, 32) & FLASH_ERROR
;
711 if (error
& FLASH_WRPERR
)
712 LOG_ERROR("flash memory write protected");
715 LOG_ERROR("flash write failed = %08" PRIx32
, error
);
716 /* Clear but report errors */
717 stm32l4_write_flash_reg(bank
, STM32_FLASH_SR
, error
);
722 target_free_working_area(target
, source
);
723 target_free_working_area(target
, write_algorithm
);
725 destroy_reg_param(®_params
[0]);
726 destroy_reg_param(®_params
[1]);
727 destroy_reg_param(®_params
[2]);
728 destroy_reg_param(®_params
[3]);
729 destroy_reg_param(®_params
[4]);
730 destroy_reg_param(®_params
[5]);
735 static int stm32l4_write(struct flash_bank
*bank
, const uint8_t *buffer
,
736 uint32_t offset
, uint32_t count
)
738 int retval
= ERROR_OK
, retval2
;
740 if (bank
->target
->state
!= TARGET_HALTED
) {
741 LOG_ERROR("Target not halted");
742 return ERROR_TARGET_NOT_HALTED
;
745 /* The flash write must be aligned to a double word (8-bytes) boundary.
746 * The flash infrastructure ensures it, do just a security check */
747 assert(offset
% 8 == 0);
748 assert(count
% 8 == 0);
750 /* STM32G4xxx Cat. 3 devices may have gaps between banks, check whether
751 * data to be written does not go into a gap:
752 * suppose buffer is fully contained in bank from sector 0 to sector
753 * num->sectors - 1 and sectors are ordered according to offset
755 struct flash_sector
*head
= &bank
->sectors
[0];
756 struct flash_sector
*tail
= &bank
->sectors
[bank
->num_sectors
- 1];
758 while ((head
< tail
) && (offset
>= (head
+ 1)->offset
)) {
759 /* buffer does not intersect head nor gap behind head */
763 while ((head
< tail
) && (offset
+ count
<= (tail
- 1)->offset
+ (tail
- 1)->size
)) {
764 /* buffer does not intersect tail nor gap before tail */
768 LOG_DEBUG("data: 0x%08" PRIx32
" - 0x%08" PRIx32
", sectors: 0x%08" PRIx32
" - 0x%08" PRIx32
,
769 offset
, offset
+ count
- 1, head
->offset
, tail
->offset
+ tail
->size
- 1);
771 /* Now check that there is no gap from head to tail, this should work
772 * even for multiple or non-symmetric gaps
774 while (head
< tail
) {
775 if (head
->offset
+ head
->size
!= (head
+ 1)->offset
) {
776 LOG_ERROR("write into gap from " TARGET_ADDR_FMT
" to " TARGET_ADDR_FMT
,
777 bank
->base
+ head
->offset
+ head
->size
,
778 bank
->base
+ (head
+ 1)->offset
- 1);
779 retval
= ERROR_FLASH_DST_OUT_OF_BANK
;
784 if (retval
!= ERROR_OK
)
787 retval
= stm32l4_unlock_reg(bank
);
788 if (retval
!= ERROR_OK
)
791 retval
= stm32l4_write_block(bank
, buffer
, offset
, count
/ 8);
794 retval2
= stm32l4_write_flash_reg(bank
, STM32_FLASH_CR
, FLASH_LOCK
);
796 if (retval
!= ERROR_OK
) {
797 LOG_ERROR("block write failed");
803 static int stm32l4_read_idcode(struct flash_bank
*bank
, uint32_t *id
)
807 /* try stm32l4/l4+/wb/g4 id register first, then stm32g0 id register */
808 retval
= target_read_u32(bank
->target
, DBGMCU_IDCODE_L4_G4
, id
);
809 if ((retval
!= ERROR_OK
) || ((*id
& 0xfff) == 0) || ((*id
& 0xfff) == 0xfff)) {
810 retval
= target_read_u32(bank
->target
, DBGMCU_IDCODE_G0
, id
);
811 if ((retval
!= ERROR_OK
) || ((*id
& 0xfff) == 0) || ((*id
& 0xfff) == 0xfff)) {
812 LOG_ERROR("can't get device id");
813 return (retval
== ERROR_OK
) ? ERROR_FAIL
: retval
;
820 static int stm32l4_probe(struct flash_bank
*bank
)
822 struct target
*target
= bank
->target
;
823 struct stm32l4_flash_bank
*stm32l4_info
= bank
->driver_priv
;
824 const struct stm32l4_part_info
*part_info
;
825 uint16_t flash_size_kb
= 0xffff;
829 stm32l4_info
->probed
= false;
831 /* read stm32 device id registers */
832 int retval
= stm32l4_read_idcode(bank
, &stm32l4_info
->idcode
);
833 if (retval
!= ERROR_OK
)
836 device_id
= stm32l4_info
->idcode
& 0xFFF;
838 for (unsigned int n
= 0; n
< ARRAY_SIZE(stm32l4_parts
); n
++) {
839 if (device_id
== stm32l4_parts
[n
].id
)
840 stm32l4_info
->part_info
= &stm32l4_parts
[n
];
843 if (!stm32l4_info
->part_info
) {
844 LOG_WARNING("Cannot identify target as an %s family device.", device_families
);
848 part_info
= stm32l4_info
->part_info
;
850 char device_info
[1024];
851 retval
= bank
->driver
->info(bank
, device_info
, sizeof(device_info
));
852 if (retval
!= ERROR_OK
)
855 LOG_INFO("device idcode = 0x%08" PRIx32
" (%s)", stm32l4_info
->idcode
, device_info
);
857 /* get flash size from target. */
858 retval
= target_read_u16(target
, part_info
->fsize_addr
, &flash_size_kb
);
860 /* failed reading flash size or flash size invalid (early silicon),
861 * default to max target family */
862 if (retval
!= ERROR_OK
|| flash_size_kb
== 0xffff || flash_size_kb
== 0
863 || flash_size_kb
> part_info
->max_flash_size_kb
) {
864 LOG_WARNING("STM32 flash size failed, probe inaccurate - assuming %dk flash",
865 part_info
->max_flash_size_kb
);
866 flash_size_kb
= part_info
->max_flash_size_kb
;
869 /* if the user sets the size manually then ignore the probed value
870 * this allows us to work around devices that have a invalid flash size register value */
871 if (stm32l4_info
->user_bank_size
) {
872 LOG_WARNING("overriding size register by configured bank size - MAY CAUSE TROUBLE");
873 flash_size_kb
= stm32l4_info
->user_bank_size
/ 1024;
876 LOG_INFO("flash size = %dkbytes", flash_size_kb
);
878 /* did we assign a flash size? */
879 assert((flash_size_kb
!= 0xffff) && flash_size_kb
);
881 /* read flash option register */
882 retval
= stm32l4_read_flash_reg(bank
, STM32_FLASH_OPTR
, &options
);
883 if (retval
!= ERROR_OK
)
886 stm32l4_info
->bank1_sectors
= 0;
887 stm32l4_info
->hole_sectors
= 0;
890 int page_size_kb
= 0;
892 stm32l4_info
->dual_bank_mode
= false;
895 case 0x415: /* STM32L47/L48xx */
896 case 0x461: /* STM32L49/L4Axx */
897 /* if flash size is max (1M) the device is always dual bank
898 * 0x415: has variants with 512K
899 * 0x461: has variants with 512 and 256
900 * for these variants:
901 * if DUAL_BANK = 0 -> single bank
902 * else -> dual bank without gap
903 * note: the page size is invariant
906 num_pages
= flash_size_kb
/ page_size_kb
;
907 stm32l4_info
->bank1_sectors
= num_pages
;
909 /* check DUAL_BANK bit[21] if the flash is less than 1M */
910 if (flash_size_kb
== 1024 || (options
& BIT(21))) {
911 stm32l4_info
->dual_bank_mode
= true;
912 stm32l4_info
->bank1_sectors
= num_pages
/ 2;
915 case 0x435: /* STM32L43/L44xx */
916 case 0x460: /* STM32G07/G08xx */
917 case 0x462: /* STM32L45/L46xx */
918 case 0x464: /* STM32L41/L42xx */
919 case 0x466: /* STM32G03/G04xx */
920 case 0x468: /* STM32G43/G44xx */
921 /* single bank flash */
923 num_pages
= flash_size_kb
/ page_size_kb
;
924 stm32l4_info
->bank1_sectors
= num_pages
;
926 case 0x469: /* STM32G47/G48xx */
927 /* STM32G47/8 can be single/dual bank:
928 * if DUAL_BANK = 0 -> single bank
929 * else -> dual bank WITH gap
932 num_pages
= flash_size_kb
/ page_size_kb
;
933 stm32l4_info
->bank1_sectors
= num_pages
;
934 if (options
& BIT(22)) {
935 stm32l4_info
->dual_bank_mode
= true;
937 num_pages
= flash_size_kb
/ page_size_kb
;
938 stm32l4_info
->bank1_sectors
= num_pages
/ 2;
940 /* for devices with trimmed flash, there is a gap between both banks */
941 stm32l4_info
->hole_sectors
=
942 (part_info
->max_flash_size_kb
- flash_size_kb
) / (2 * page_size_kb
);
945 case 0x470: /* STM32L4R/L4Sxx */
946 case 0x471: /* STM32L4P5/L4Q5x */
947 /* STM32L4R/S can be single/dual bank:
948 * if size = 2M check DBANK bit(22)
949 * if size = 1M check DB1M bit(21)
950 * STM32L4P/Q can be single/dual bank
951 * if size = 1M check DBANK bit(22)
952 * if size = 512K check DB512K bit(21)
955 num_pages
= flash_size_kb
/ page_size_kb
;
956 stm32l4_info
->bank1_sectors
= num_pages
;
957 const bool use_dbank_bit
= flash_size_kb
== part_info
->max_flash_size_kb
;
958 if ((use_dbank_bit
&& (options
& BIT(22))) ||
959 (!use_dbank_bit
&& (options
& BIT(21)))) {
960 stm32l4_info
->dual_bank_mode
= true;
962 num_pages
= flash_size_kb
/ page_size_kb
;
963 stm32l4_info
->bank1_sectors
= num_pages
/ 2;
966 case 0x495: /* STM32WB5x */
967 /* single bank flash */
969 num_pages
= flash_size_kb
/ page_size_kb
;
970 stm32l4_info
->bank1_sectors
= num_pages
;
973 LOG_ERROR("unsupported device");
977 LOG_INFO("flash mode : %s-bank", stm32l4_info
->dual_bank_mode
? "dual" : "single");
979 const int gap_size_kb
= stm32l4_info
->hole_sectors
* page_size_kb
;
981 if (gap_size_kb
!= 0) {
982 LOG_INFO("gap detected from 0x%08" PRIx32
" to 0x%08" PRIx32
,
983 STM32_FLASH_BANK_BASE
+ stm32l4_info
->bank1_sectors
984 * page_size_kb
* 1024,
985 STM32_FLASH_BANK_BASE
+ (stm32l4_info
->bank1_sectors
986 * page_size_kb
+ gap_size_kb
) * 1024 - 1);
989 /* number of significant bits in WRPxxR differs per device,
990 * always right adjusted, on some devices non-implemented
991 * bits read as '0', on others as '1' ...
992 * notably G4 Cat. 2 implement only 6 bits, contradicting the RM
995 /* use *max_flash_size* instead of actual size as the trimmed versions
996 * certainly use the same number of bits
997 * max_flash_size is always power of two, so max_pages too
999 uint32_t max_pages
= stm32l4_info
->part_info
->max_flash_size_kb
/ page_size_kb
;
1000 assert((max_pages
& (max_pages
- 1)) == 0);
1002 /* in dual bank mode number of pages is doubled, but extra bit is bank selection */
1003 stm32l4_info
->wrpxxr_mask
= ((max_pages
>> (stm32l4_info
->dual_bank_mode
? 1 : 0)) - 1);
1004 assert((stm32l4_info
->wrpxxr_mask
& 0xFFFF0000) == 0);
1005 LOG_DEBUG("WRPxxR mask 0x%04" PRIx16
, stm32l4_info
->wrpxxr_mask
);
1007 if (bank
->sectors
) {
1008 free(bank
->sectors
);
1009 bank
->sectors
= NULL
;
1012 bank
->size
= (flash_size_kb
+ gap_size_kb
) * 1024;
1013 bank
->base
= STM32_FLASH_BANK_BASE
;
1014 bank
->num_sectors
= num_pages
;
1015 bank
->sectors
= malloc(sizeof(struct flash_sector
) * bank
->num_sectors
);
1016 if (bank
->sectors
== NULL
) {
1017 LOG_ERROR("failed to allocate bank sectors");
1021 for (int i
= 0; i
< bank
->num_sectors
; i
++) {
1022 bank
->sectors
[i
].offset
= i
* page_size_kb
* 1024;
1023 /* in dual bank configuration, if there is a gap between banks
1024 * we fix up the sector offset to consider this gap */
1025 if (i
>= stm32l4_info
->bank1_sectors
&& stm32l4_info
->hole_sectors
)
1026 bank
->sectors
[i
].offset
+= gap_size_kb
* 1024;
1027 bank
->sectors
[i
].size
= page_size_kb
* 1024;
1028 bank
->sectors
[i
].is_erased
= -1;
1029 bank
->sectors
[i
].is_protected
= 1;
1032 stm32l4_info
->probed
= true;
1036 static int stm32l4_auto_probe(struct flash_bank
*bank
)
1038 struct stm32l4_flash_bank
*stm32l4_info
= bank
->driver_priv
;
1039 if (stm32l4_info
->probed
)
1042 return stm32l4_probe(bank
);
1045 static int get_stm32l4_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
1047 struct stm32l4_flash_bank
*stm32l4_info
= bank
->driver_priv
;
1048 const struct stm32l4_part_info
*part_info
= stm32l4_info
->part_info
;
1051 const char *rev_str
= NULL
;
1052 uint16_t rev_id
= stm32l4_info
->idcode
>> 16;
1053 for (unsigned int i
= 0; i
< part_info
->num_revs
; i
++) {
1054 if (rev_id
== part_info
->revs
[i
].rev
) {
1055 rev_str
= part_info
->revs
[i
].str
;
1057 if (rev_str
!= NULL
) {
1058 snprintf(buf
, buf_size
, "%s - Rev: %s%s",
1059 part_info
->device_str
, rev_str
, stm32l4_info
->probed
?
1060 (stm32l4_info
->dual_bank_mode
? " dual-bank" : " single-bank") : "");
1066 snprintf(buf
, buf_size
, "%s - Rev: unknown (0x%04x)%s",
1067 part_info
->device_str
, rev_id
, stm32l4_info
->probed
?
1068 (stm32l4_info
->dual_bank_mode
? " dual-bank" : " single-bank") : "");
1071 snprintf(buf
, buf_size
, "Cannot identify target as an %s device", device_families
);
1078 static int stm32l4_mass_erase(struct flash_bank
*bank
)
1080 int retval
, retval2
;
1081 struct target
*target
= bank
->target
;
1082 struct stm32l4_flash_bank
*stm32l4_info
= bank
->driver_priv
;
1084 uint32_t action
= FLASH_MER1
;
1086 if (stm32l4_info
->part_info
->has_dual_bank
)
1087 action
|= FLASH_MER2
;
1089 if (target
->state
!= TARGET_HALTED
) {
1090 LOG_ERROR("Target not halted");
1091 return ERROR_TARGET_NOT_HALTED
;
1094 retval
= stm32l4_unlock_reg(bank
);
1095 if (retval
!= ERROR_OK
)
1098 /* mass erase flash memory */
1099 retval
= stm32l4_wait_status_busy(bank
, FLASH_ERASE_TIMEOUT
/ 10);
1100 if (retval
!= ERROR_OK
)
1103 retval
= stm32l4_write_flash_reg(bank
, STM32_FLASH_CR
, action
);
1104 if (retval
!= ERROR_OK
)
1107 retval
= stm32l4_write_flash_reg(bank
, STM32_FLASH_CR
, action
| FLASH_STRT
);
1108 if (retval
!= ERROR_OK
)
1111 retval
= stm32l4_wait_status_busy(bank
, FLASH_ERASE_TIMEOUT
);
1114 retval2
= stm32l4_write_flash_reg(bank
, STM32_FLASH_CR
, FLASH_LOCK
);
1116 if (retval
!= ERROR_OK
)
1122 COMMAND_HANDLER(stm32l4_handle_mass_erase_command
)
1125 command_print(CMD
, "stm32l4x mass_erase <STM32L4 bank>");
1126 return ERROR_COMMAND_SYNTAX_ERROR
;
1129 struct flash_bank
*bank
;
1130 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
1131 if (ERROR_OK
!= retval
)
1134 retval
= stm32l4_mass_erase(bank
);
1135 if (retval
== ERROR_OK
) {
1136 /* set all sectors as erased */
1137 for (int i
= 0; i
< bank
->num_sectors
; i
++)
1138 bank
->sectors
[i
].is_erased
= 1;
1140 command_print(CMD
, "stm32l4x mass erase complete");
1142 command_print(CMD
, "stm32l4x mass erase failed");
1148 COMMAND_HANDLER(stm32l4_handle_option_read_command
)
1151 command_print(CMD
, "stm32l4x option_read <STM32L4 bank> <option_reg offset>");
1152 return ERROR_COMMAND_SYNTAX_ERROR
;
1155 struct flash_bank
*bank
;
1156 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
1157 if (ERROR_OK
!= retval
)
1160 uint32_t reg_offset
, reg_addr
;
1163 reg_offset
= strtoul(CMD_ARGV
[1], NULL
, 16);
1164 reg_addr
= stm32l4_get_flash_reg(bank
, reg_offset
);
1166 retval
= stm32l4_read_flash_reg(bank
, reg_offset
, &value
);
1167 if (ERROR_OK
!= retval
)
1170 command_print(CMD
, "Option Register: <0x%" PRIx32
"> = 0x%" PRIx32
"", reg_addr
, value
);
1175 COMMAND_HANDLER(stm32l4_handle_option_write_command
)
1178 command_print(CMD
, "stm32l4x option_write <STM32L4 bank> <option_reg offset> <value> [mask]");
1179 return ERROR_COMMAND_SYNTAX_ERROR
;
1182 struct flash_bank
*bank
;
1183 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
1184 if (ERROR_OK
!= retval
)
1187 uint32_t reg_offset
;
1189 uint32_t mask
= 0xFFFFFFFF;
1191 reg_offset
= strtoul(CMD_ARGV
[1], NULL
, 16);
1192 value
= strtoul(CMD_ARGV
[2], NULL
, 16);
1194 mask
= strtoul(CMD_ARGV
[3], NULL
, 16);
1196 command_print(CMD
, "%s Option written.\n"
1197 "INFO: a reset or power cycle is required "
1198 "for the new settings to take effect.", bank
->driver
->name
);
1200 retval
= stm32l4_write_option(bank
, reg_offset
, value
, mask
);
1204 COMMAND_HANDLER(stm32l4_handle_option_load_command
)
1207 return ERROR_COMMAND_SYNTAX_ERROR
;
1209 struct flash_bank
*bank
;
1210 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
1211 if (ERROR_OK
!= retval
)
1214 retval
= stm32l4_unlock_reg(bank
);
1215 if (ERROR_OK
!= retval
)
1218 retval
= stm32l4_unlock_option_reg(bank
);
1219 if (ERROR_OK
!= retval
)
1222 /* Set OBL_LAUNCH bit in CR -> system reset and option bytes reload,
1223 * but the RMs explicitly do *NOT* list this as power-on reset cause, and:
1224 * "Note: If the read protection is set while the debugger is still
1225 * connected through JTAG/SWD, apply a POR (power-on reset) instead of a system reset."
1227 retval
= stm32l4_write_flash_reg(bank
, STM32_FLASH_CR
, FLASH_OBL_LAUNCH
);
1229 command_print(CMD
, "stm32l4x option load completed. Power-on reset might be required");
1231 /* Need to re-probe after change */
1232 struct stm32l4_flash_bank
*stm32l4_info
= bank
->driver_priv
;
1233 stm32l4_info
->probed
= false;
1238 COMMAND_HANDLER(stm32l4_handle_lock_command
)
1240 struct target
*target
= NULL
;
1243 return ERROR_COMMAND_SYNTAX_ERROR
;
1245 struct flash_bank
*bank
;
1246 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
1247 if (ERROR_OK
!= retval
)
1250 target
= bank
->target
;
1252 if (target
->state
!= TARGET_HALTED
) {
1253 LOG_ERROR("Target not halted");
1254 return ERROR_TARGET_NOT_HALTED
;
1257 /* set readout protection level 1 by erasing the RDP option byte */
1258 if (stm32l4_write_option(bank
, STM32_FLASH_OPTR
, 0, 0x000000FF) != ERROR_OK
) {
1259 command_print(CMD
, "%s failed to lock device", bank
->driver
->name
);
1266 COMMAND_HANDLER(stm32l4_handle_unlock_command
)
1268 struct target
*target
= NULL
;
1271 return ERROR_COMMAND_SYNTAX_ERROR
;
1273 struct flash_bank
*bank
;
1274 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
1275 if (ERROR_OK
!= retval
)
1278 target
= bank
->target
;
1280 if (target
->state
!= TARGET_HALTED
) {
1281 LOG_ERROR("Target not halted");
1282 return ERROR_TARGET_NOT_HALTED
;
1285 if (stm32l4_write_option(bank
, STM32_FLASH_OPTR
, RDP_LEVEL_0
, 0x000000FF) != ERROR_OK
) {
1286 command_print(CMD
, "%s failed to unlock device", bank
->driver
->name
);
1293 static const struct command_registration stm32l4_exec_command_handlers
[] = {
1296 .handler
= stm32l4_handle_lock_command
,
1297 .mode
= COMMAND_EXEC
,
1299 .help
= "Lock entire flash device.",
1303 .handler
= stm32l4_handle_unlock_command
,
1304 .mode
= COMMAND_EXEC
,
1306 .help
= "Unlock entire protected flash device.",
1309 .name
= "mass_erase",
1310 .handler
= stm32l4_handle_mass_erase_command
,
1311 .mode
= COMMAND_EXEC
,
1313 .help
= "Erase entire flash device.",
1316 .name
= "option_read",
1317 .handler
= stm32l4_handle_option_read_command
,
1318 .mode
= COMMAND_EXEC
,
1319 .usage
= "bank_id reg_offset",
1320 .help
= "Read & Display device option bytes.",
1323 .name
= "option_write",
1324 .handler
= stm32l4_handle_option_write_command
,
1325 .mode
= COMMAND_EXEC
,
1326 .usage
= "bank_id reg_offset value mask",
1327 .help
= "Write device option bit fields with provided value.",
1330 .name
= "option_load",
1331 .handler
= stm32l4_handle_option_load_command
,
1332 .mode
= COMMAND_EXEC
,
1334 .help
= "Force re-load of device options (will cause device reset).",
1336 COMMAND_REGISTRATION_DONE
1339 static const struct command_registration stm32l4_command_handlers
[] = {
1342 .mode
= COMMAND_ANY
,
1343 .help
= "stm32l4x flash command group",
1345 .chain
= stm32l4_exec_command_handlers
,
1347 COMMAND_REGISTRATION_DONE
1350 const struct flash_driver stm32l4x_flash
= {
1352 .commands
= stm32l4_command_handlers
,
1353 .flash_bank_command
= stm32l4_flash_bank_command
,
1354 .erase
= stm32l4_erase
,
1355 .protect
= stm32l4_protect
,
1356 .write
= stm32l4_write
,
1357 .read
= default_flash_read
,
1358 .probe
= stm32l4_probe
,
1359 .auto_probe
= stm32l4_auto_probe
,
1360 .erase_check
= default_flash_blank_check
,
1361 .protect_check
= stm32l4_protect_check
,
1362 .info
= get_stm32l4_info
,
1363 .free_driver_priv
= default_flash_free_driver_priv
,
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)