1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * Copyright (C) 2008 by Spencer Oliver *
6 * spen@spen-soft.co.uk *
8 * Copyright (C) 2011 by Andreas Fritiofson *
9 * andreas.fritiofson@gmail.com *
11 * Copyright (C) 2013 by Roman Dmitrienko *
14 * Copyright (C) 2014 Nemui Trinomius *
15 * nemuisan_kawausogasuki@live.jp *
17 * This program is free software; you can redistribute it and/or modify *
18 * it under the terms of the GNU General Public License as published by *
19 * the Free Software Foundation; either version 2 of the License, or *
20 * (at your option) any later version. *
22 * This program is distributed in the hope that it will be useful, *
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
25 * GNU General Public License for more details. *
27 * You should have received a copy of the GNU General Public License *
28 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
29 ***************************************************************************/
36 #include <helper/binarybuffer.h>
37 #include <target/algorithm.h>
38 #include <target/armv7m.h>
39 #include <target/cortex_m.h>
41 /* keep family IDs in decimal */
42 #define EFM_FAMILY_ID_GECKO 71
43 #define EFM_FAMILY_ID_GIANT_GECKO 72
44 #define EFM_FAMILY_ID_TINY_GECKO 73
45 #define EFM_FAMILY_ID_LEOPARD_GECKO 74
46 #define EFM_FAMILY_ID_WONDER_GECKO 75
47 #define EFM_FAMILY_ID_ZERO_GECKO 76
48 #define EFM_FAMILY_ID_HAPPY_GECKO 77
49 #define EZR_FAMILY_ID_WONDER_GECKO 120
50 #define EZR_FAMILY_ID_LEOPARD_GECKO 121
51 #define EZR_FAMILY_ID_HAPPY_GECKO 122
53 #define EFM32_FLASH_ERASE_TMO 100
54 #define EFM32_FLASH_WDATAREADY_TMO 100
55 #define EFM32_FLASH_WRITE_TMO 100
57 /* size in bytes, not words; must fit all Gecko devices */
58 #define LOCKBITS_PAGE_SZ 512
60 #define EFM32_MSC_INFO_BASE 0x0fe00000
62 #define EFM32_MSC_USER_DATA EFM32_MSC_INFO_BASE
63 #define EFM32_MSC_LOCK_BITS (EFM32_MSC_INFO_BASE+0x4000)
64 #define EFM32_MSC_DEV_INFO (EFM32_MSC_INFO_BASE+0x8000)
66 /* PAGE_SIZE is only present in Leopard, Giant and Wonder Gecko MCUs */
67 #define EFM32_MSC_DI_PAGE_SIZE (EFM32_MSC_DEV_INFO+0x1e7)
68 #define EFM32_MSC_DI_FLASH_SZ (EFM32_MSC_DEV_INFO+0x1f8)
69 #define EFM32_MSC_DI_RAM_SZ (EFM32_MSC_DEV_INFO+0x1fa)
70 #define EFM32_MSC_DI_PART_NUM (EFM32_MSC_DEV_INFO+0x1fc)
71 #define EFM32_MSC_DI_PART_FAMILY (EFM32_MSC_DEV_INFO+0x1fe)
72 #define EFM32_MSC_DI_PROD_REV (EFM32_MSC_DEV_INFO+0x1ff)
74 #define EFM32_MSC_REGBASE 0x400c0000
75 #define EFM32_MSC_WRITECTRL (EFM32_MSC_REGBASE+0x008)
76 #define EFM32_MSC_WRITECTRL_WREN_MASK 0x1
77 #define EFM32_MSC_WRITECMD (EFM32_MSC_REGBASE+0x00c)
78 #define EFM32_MSC_WRITECMD_LADDRIM_MASK 0x1
79 #define EFM32_MSC_WRITECMD_ERASEPAGE_MASK 0x2
80 #define EFM32_MSC_WRITECMD_WRITEONCE_MASK 0x8
81 #define EFM32_MSC_ADDRB (EFM32_MSC_REGBASE+0x010)
82 #define EFM32_MSC_WDATA (EFM32_MSC_REGBASE+0x018)
83 #define EFM32_MSC_STATUS (EFM32_MSC_REGBASE+0x01c)
84 #define EFM32_MSC_STATUS_BUSY_MASK 0x1
85 #define EFM32_MSC_STATUS_LOCKED_MASK 0x2
86 #define EFM32_MSC_STATUS_INVADDR_MASK 0x4
87 #define EFM32_MSC_STATUS_WDATAREADY_MASK 0x8
88 #define EFM32_MSC_STATUS_WORDTIMEOUT_MASK 0x10
89 #define EFM32_MSC_STATUS_ERASEABORTED_MASK 0x20
90 #define EFM32_MSC_LOCK (EFM32_MSC_REGBASE+0x03c)
91 #define EFM32_MSC_LOCK_LOCKKEY 0x1b71
93 struct efm32x_flash_bank
{
95 uint32_t lb_page
[LOCKBITS_PAGE_SZ
/4];
99 uint16_t flash_sz_kib
;
107 static int efm32x_write(struct flash_bank
*bank
, const uint8_t *buffer
,
108 uint32_t offset
, uint32_t count
);
110 static int efm32x_get_flash_size(struct flash_bank
*bank
, uint16_t *flash_sz
)
112 return target_read_u16(bank
->target
, EFM32_MSC_DI_FLASH_SZ
, flash_sz
);
115 static int efm32x_get_ram_size(struct flash_bank
*bank
, uint16_t *ram_sz
)
117 return target_read_u16(bank
->target
, EFM32_MSC_DI_RAM_SZ
, ram_sz
);
120 static int efm32x_get_part_num(struct flash_bank
*bank
, uint16_t *pnum
)
122 return target_read_u16(bank
->target
, EFM32_MSC_DI_PART_NUM
, pnum
);
125 static int efm32x_get_part_family(struct flash_bank
*bank
, uint8_t *pfamily
)
127 return target_read_u8(bank
->target
, EFM32_MSC_DI_PART_FAMILY
, pfamily
);
130 static int efm32x_get_prod_rev(struct flash_bank
*bank
, uint8_t *prev
)
132 return target_read_u8(bank
->target
, EFM32_MSC_DI_PROD_REV
, prev
);
135 static int efm32x_read_info(struct flash_bank
*bank
,
136 struct efm32_info
*efm32_info
)
141 memset(efm32_info
, 0, sizeof(struct efm32_info
));
143 ret
= target_read_u32(bank
->target
, CPUID
, &cpuid
);
147 if (((cpuid
>> 4) & 0xfff) == 0xc23) {
148 /* Cortex-M3 device */
149 } else if (((cpuid
>> 4) & 0xfff) == 0xc24) {
150 /* Cortex-M4 device (WONDER GECKO) */
151 } else if (((cpuid
>> 4) & 0xfff) == 0xc60) {
152 /* Cortex-M0+ device */
154 LOG_ERROR("Target is not Cortex-Mx Device");
158 ret
= efm32x_get_flash_size(bank
, &(efm32_info
->flash_sz_kib
));
162 ret
= efm32x_get_ram_size(bank
, &(efm32_info
->ram_sz_kib
));
166 ret
= efm32x_get_part_num(bank
, &(efm32_info
->part_num
));
170 ret
= efm32x_get_part_family(bank
, &(efm32_info
->part_family
));
174 ret
= efm32x_get_prod_rev(bank
, &(efm32_info
->prod_rev
));
178 if (EFM_FAMILY_ID_GECKO
== efm32_info
->part_family
||
179 EFM_FAMILY_ID_TINY_GECKO
== efm32_info
->part_family
)
180 efm32_info
->page_size
= 512;
181 else if (EFM_FAMILY_ID_ZERO_GECKO
== efm32_info
->part_family
||
182 EFM_FAMILY_ID_HAPPY_GECKO
== efm32_info
->part_family
||
183 EZR_FAMILY_ID_HAPPY_GECKO
== efm32_info
->part_family
)
184 efm32_info
->page_size
= 1024;
185 else if (EFM_FAMILY_ID_GIANT_GECKO
== efm32_info
->part_family
||
186 EFM_FAMILY_ID_LEOPARD_GECKO
== efm32_info
->part_family
) {
187 if (efm32_info
->prod_rev
>= 18) {
189 ret
= target_read_u8(bank
->target
, EFM32_MSC_DI_PAGE_SIZE
,
194 efm32_info
->page_size
= (1 << ((pg_size
+10) & 0xff));
196 /* EFM32 GG/LG errata: MEM_INFO_PAGE_SIZE is invalid
197 for MCUs with PROD_REV < 18 */
198 if (efm32_info
->flash_sz_kib
< 512)
199 efm32_info
->page_size
= 2048;
201 efm32_info
->page_size
= 4096;
204 if ((2048 != efm32_info
->page_size
) &&
205 (4096 != efm32_info
->page_size
)) {
206 LOG_ERROR("Invalid page size %u", efm32_info
->page_size
);
209 } else if (EFM_FAMILY_ID_WONDER_GECKO
== efm32_info
->part_family
||
210 EZR_FAMILY_ID_WONDER_GECKO
== efm32_info
->part_family
||
211 EZR_FAMILY_ID_LEOPARD_GECKO
== efm32_info
->part_family
) {
213 ret
= target_read_u8(bank
->target
, EFM32_MSC_DI_PAGE_SIZE
,
218 efm32_info
->page_size
= (1 << ((pg_size
+10) & 0xff));
219 if (2048 != efm32_info
->page_size
) {
220 LOG_ERROR("Invalid page size %u", efm32_info
->page_size
);
224 LOG_ERROR("Unknown MCU family %d", efm32_info
->part_family
);
232 * Helper to create a human friendly string describing a part
234 static int efm32x_decode_info(struct efm32_info
*info
, char *buf
, int buf_size
)
238 switch (info
->part_family
) {
239 case EZR_FAMILY_ID_WONDER_GECKO
:
240 case EZR_FAMILY_ID_LEOPARD_GECKO
:
241 case EZR_FAMILY_ID_HAPPY_GECKO
:
242 printed
= snprintf(buf
, buf_size
, "EZR32 ");
245 printed
= snprintf(buf
, buf_size
, "EFM32 ");
252 return ERROR_BUF_TOO_SMALL
;
254 switch (info
->part_family
) {
255 case EFM_FAMILY_ID_GECKO
:
256 printed
= snprintf(buf
, buf_size
, "Gecko");
258 case EFM_FAMILY_ID_GIANT_GECKO
:
259 printed
= snprintf(buf
, buf_size
, "Giant Gecko");
261 case EFM_FAMILY_ID_TINY_GECKO
:
262 printed
= snprintf(buf
, buf_size
, "Tiny Gecko");
264 case EFM_FAMILY_ID_LEOPARD_GECKO
:
265 case EZR_FAMILY_ID_LEOPARD_GECKO
:
266 printed
= snprintf(buf
, buf_size
, "Leopard Gecko");
268 case EFM_FAMILY_ID_WONDER_GECKO
:
269 case EZR_FAMILY_ID_WONDER_GECKO
:
270 printed
= snprintf(buf
, buf_size
, "Wonder Gecko");
272 case EFM_FAMILY_ID_ZERO_GECKO
:
273 printed
= snprintf(buf
, buf_size
, "Zero Gecko");
275 case EFM_FAMILY_ID_HAPPY_GECKO
:
276 case EZR_FAMILY_ID_HAPPY_GECKO
:
277 printed
= snprintf(buf
, buf_size
, "Happy Gecko");
285 return ERROR_BUF_TOO_SMALL
;
287 printed
= snprintf(buf
, buf_size
, " - Rev: %d", info
->prod_rev
);
292 return ERROR_BUF_TOO_SMALL
;
297 /* flash bank efm32 <base> <size> 0 0 <target#>
299 FLASH_BANK_COMMAND_HANDLER(efm32x_flash_bank_command
)
301 struct efm32x_flash_bank
*efm32x_info
;
304 return ERROR_COMMAND_SYNTAX_ERROR
;
306 efm32x_info
= malloc(sizeof(struct efm32x_flash_bank
));
308 bank
->driver_priv
= efm32x_info
;
309 efm32x_info
->probed
= 0;
310 memset(efm32x_info
->lb_page
, 0xff, LOCKBITS_PAGE_SZ
);
315 /* set or reset given bits in a register */
316 static int efm32x_set_reg_bits(struct flash_bank
*bank
, uint32_t reg
,
317 uint32_t bitmask
, int set
)
320 uint32_t reg_val
= 0;
322 ret
= target_read_u32(bank
->target
, reg
, ®_val
);
331 return target_write_u32(bank
->target
, reg
, reg_val
);
334 static int efm32x_set_wren(struct flash_bank
*bank
, int write_enable
)
336 return efm32x_set_reg_bits(bank
, EFM32_MSC_WRITECTRL
,
337 EFM32_MSC_WRITECTRL_WREN_MASK
, write_enable
);
340 static int efm32x_msc_lock(struct flash_bank
*bank
, int lock
)
342 return target_write_u32(bank
->target
, EFM32_MSC_LOCK
,
343 (lock
? 0 : EFM32_MSC_LOCK_LOCKKEY
));
346 static int efm32x_wait_status(struct flash_bank
*bank
, int timeout
,
347 uint32_t wait_mask
, int wait_for_set
)
353 ret
= target_read_u32(bank
->target
, EFM32_MSC_STATUS
, &status
);
357 LOG_DEBUG("status: 0x%" PRIx32
"", status
);
359 if (((status
& wait_mask
) == 0) && (0 == wait_for_set
))
361 else if (((status
& wait_mask
) != 0) && wait_for_set
)
364 if (timeout
-- <= 0) {
365 LOG_ERROR("timed out waiting for MSC status");
372 if (status
& EFM32_MSC_STATUS_ERASEABORTED_MASK
)
373 LOG_WARNING("page erase was aborted");
378 static int efm32x_erase_page(struct flash_bank
*bank
, uint32_t addr
)
380 /* this function DOES NOT set WREN; must be set already */
381 /* 1. write address to ADDRB
383 3. check status (INVADDR, LOCKED)
385 5. wait until !STATUS_BUSY
390 LOG_DEBUG("erasing flash page at 0x%08" PRIx32
, addr
);
392 ret
= target_write_u32(bank
->target
, EFM32_MSC_ADDRB
, addr
);
396 ret
= efm32x_set_reg_bits(bank
, EFM32_MSC_WRITECMD
,
397 EFM32_MSC_WRITECMD_LADDRIM_MASK
, 1);
401 ret
= target_read_u32(bank
->target
, EFM32_MSC_STATUS
, &status
);
405 LOG_DEBUG("status 0x%" PRIx32
, status
);
407 if (status
& EFM32_MSC_STATUS_LOCKED_MASK
) {
408 LOG_ERROR("Page is locked");
410 } else if (status
& EFM32_MSC_STATUS_INVADDR_MASK
) {
411 LOG_ERROR("Invalid address 0x%" PRIx32
, addr
);
415 ret
= efm32x_set_reg_bits(bank
, EFM32_MSC_WRITECMD
,
416 EFM32_MSC_WRITECMD_ERASEPAGE_MASK
, 1);
420 return efm32x_wait_status(bank
, EFM32_FLASH_ERASE_TMO
,
421 EFM32_MSC_STATUS_BUSY_MASK
, 0);
424 static int efm32x_erase(struct flash_bank
*bank
, int first
, int last
)
426 struct target
*target
= bank
->target
;
430 if (TARGET_HALTED
!= target
->state
) {
431 LOG_ERROR("Target not halted");
432 return ERROR_TARGET_NOT_HALTED
;
435 efm32x_msc_lock(bank
, 0);
436 ret
= efm32x_set_wren(bank
, 1);
437 if (ERROR_OK
!= ret
) {
438 LOG_ERROR("Failed to enable MSC write");
442 for (i
= first
; i
<= last
; i
++) {
443 ret
= efm32x_erase_page(bank
, bank
->sectors
[i
].offset
);
445 LOG_ERROR("Failed to erase page %d", i
);
448 ret
= efm32x_set_wren(bank
, 0);
449 efm32x_msc_lock(bank
, 1);
454 static int efm32x_read_lock_data(struct flash_bank
*bank
)
456 struct efm32x_flash_bank
*efm32x_info
= bank
->driver_priv
;
457 struct target
*target
= bank
->target
;
460 uint32_t *ptr
= NULL
;
463 assert(bank
->num_sectors
> 0);
465 /* calculate the number of 32-bit words to read (one lock bit per sector) */
466 data_size
= (bank
->num_sectors
+ 31) / 32;
468 ptr
= efm32x_info
->lb_page
;
470 for (i
= 0; i
< data_size
; i
++, ptr
++) {
471 ret
= target_read_u32(target
, EFM32_MSC_LOCK_BITS
+i
*4, ptr
);
472 if (ERROR_OK
!= ret
) {
473 LOG_ERROR("Failed to read PLW %d", i
);
478 /* also, read ULW, DLW and MLW */
481 ptr
= efm32x_info
->lb_page
+ 126;
482 ret
= target_read_u32(target
, EFM32_MSC_LOCK_BITS
+126*4, ptr
);
483 if (ERROR_OK
!= ret
) {
484 LOG_ERROR("Failed to read ULW");
489 ptr
= efm32x_info
->lb_page
+ 127;
490 ret
= target_read_u32(target
, EFM32_MSC_LOCK_BITS
+127*4, ptr
);
491 if (ERROR_OK
!= ret
) {
492 LOG_ERROR("Failed to read DLW");
496 /* MLW, word 125, present in GG and LG */
497 ptr
= efm32x_info
->lb_page
+ 125;
498 ret
= target_read_u32(target
, EFM32_MSC_LOCK_BITS
+125*4, ptr
);
499 if (ERROR_OK
!= ret
) {
500 LOG_ERROR("Failed to read MLW");
507 static int efm32x_write_lock_data(struct flash_bank
*bank
)
509 struct efm32x_flash_bank
*efm32x_info
= bank
->driver_priv
;
512 ret
= efm32x_erase_page(bank
, EFM32_MSC_LOCK_BITS
);
513 if (ERROR_OK
!= ret
) {
514 LOG_ERROR("Failed to erase LB page");
518 return efm32x_write(bank
, (uint8_t *)efm32x_info
->lb_page
, EFM32_MSC_LOCK_BITS
,
522 static int efm32x_get_page_lock(struct flash_bank
*bank
, size_t page
)
524 struct efm32x_flash_bank
*efm32x_info
= bank
->driver_priv
;
525 uint32_t dw
= efm32x_info
->lb_page
[page
>> 5];
528 mask
= 1 << (page
& 0x1f);
530 return (dw
& mask
) ? 0 : 1;
533 static int efm32x_set_page_lock(struct flash_bank
*bank
, size_t page
, int set
)
535 struct efm32x_flash_bank
*efm32x_info
= bank
->driver_priv
;
536 uint32_t *dw
= &efm32x_info
->lb_page
[page
>> 5];
539 mask
= 1 << (page
& 0x1f);
549 static int efm32x_protect(struct flash_bank
*bank
, int set
, int first
, int last
)
551 struct target
*target
= bank
->target
;
556 LOG_ERROR("Erase device data to reset page locks");
560 if (target
->state
!= TARGET_HALTED
) {
561 LOG_ERROR("Target not halted");
562 return ERROR_TARGET_NOT_HALTED
;
565 for (i
= first
; i
<= last
; i
++) {
566 ret
= efm32x_set_page_lock(bank
, i
, set
);
567 if (ERROR_OK
!= ret
) {
568 LOG_ERROR("Failed to set lock on page %d", i
);
573 ret
= efm32x_write_lock_data(bank
);
574 if (ERROR_OK
!= ret
) {
575 LOG_ERROR("Failed to write LB page");
582 static int efm32x_write_block(struct flash_bank
*bank
, const uint8_t *buf
,
583 uint32_t offset
, uint32_t count
)
585 struct target
*target
= bank
->target
;
586 uint32_t buffer_size
= 16384;
587 struct working_area
*write_algorithm
;
588 struct working_area
*source
;
589 uint32_t address
= bank
->base
+ offset
;
590 struct reg_param reg_params
[5];
591 struct armv7m_algorithm armv7m_info
;
594 /* see contrib/loaders/flash/efm32.S for src */
595 static const uint8_t efm32x_flash_write_code
[] = {
596 /* #define EFM32_MSC_WRITECTRL_OFFSET 0x008 */
597 /* #define EFM32_MSC_WRITECMD_OFFSET 0x00c */
598 /* #define EFM32_MSC_ADDRB_OFFSET 0x010 */
599 /* #define EFM32_MSC_WDATA_OFFSET 0x018 */
600 /* #define EFM32_MSC_STATUS_OFFSET 0x01c */
601 /* #define EFM32_MSC_LOCK_OFFSET 0x03c */
603 0x15, 0x4e, /* ldr r6, =#0x1b71 */
604 0xc6, 0x63, /* str r6, [r0, #EFM32_MSC_LOCK_OFFSET] */
605 0x01, 0x26, /* movs r6, #1 */
606 0x86, 0x60, /* str r6, [r0, #EFM32_MSC_WRITECTRL_OFFSET] */
609 0x16, 0x68, /* ldr r6, [r2, #0] */
610 0x00, 0x2e, /* cmp r6, #0 */
611 0x22, 0xd0, /* beq exit */
612 0x55, 0x68, /* ldr r5, [r2, #4] */
613 0xb5, 0x42, /* cmp r5, r6 */
614 0xf9, 0xd0, /* beq wait_fifo */
616 0x04, 0x61, /* str r4, [r0, #EFM32_MSC_ADDRB_OFFSET] */
617 0x01, 0x26, /* movs r6, #1 */
618 0xc6, 0x60, /* str r6, [r0, #EFM32_MSC_WRITECMD_OFFSET] */
619 0xc6, 0x69, /* ldr r6, [r0, #EFM32_MSC_STATUS_OFFSET] */
620 0x06, 0x27, /* movs r7, #6 */
621 0x3e, 0x42, /* tst r6, r7 */
622 0x16, 0xd1, /* bne error */
624 /* wait_wdataready: */
625 0xc6, 0x69, /* ldr r6, [r0, #EFM32_MSC_STATUS_OFFSET] */
626 0x08, 0x27, /* movs r7, #8 */
627 0x3e, 0x42, /* tst r6, r7 */
628 0xfb, 0xd0, /* beq wait_wdataready */
630 0x2e, 0x68, /* ldr r6, [r5] */
631 0x86, 0x61, /* str r6, [r0, #EFM32_MSC_WDATA_OFFSET] */
632 0x08, 0x26, /* movs r6, #8 */
633 0xc6, 0x60, /* str r6, [r0, #EFM32_MSC_WRITECMD_OFFSET] */
635 0x04, 0x35, /* adds r5, #4 */
636 0x04, 0x34, /* adds r4, #4 */
639 0xc6, 0x69, /* ldr r6, [r0, #EFM32_MSC_STATUS_OFFSET] */
640 0x01, 0x27, /* movs r7, #1 */
641 0x3e, 0x42, /* tst r6, r7 */
642 0xfb, 0xd1, /* bne busy */
644 0x9d, 0x42, /* cmp r5, r3 */
645 0x01, 0xd3, /* bcc no_wrap */
646 0x15, 0x46, /* mov r5, r2 */
647 0x08, 0x35, /* adds r5, #8 */
650 0x55, 0x60, /* str r5, [r2, #4] */
651 0x01, 0x39, /* subs r1, r1, #1 */
652 0x00, 0x29, /* cmp r1, #0 */
653 0x02, 0xd0, /* beq exit */
654 0xdb, 0xe7, /* b wait_fifo */
657 0x00, 0x20, /* movs r0, #0 */
658 0x50, 0x60, /* str r0, [r2, #4] */
661 0x30, 0x46, /* mov r0, r6 */
662 0x00, 0xbe, /* bkpt #0 */
665 0x71, 0x1b, 0x00, 0x00
668 /* flash write code */
669 if (target_alloc_working_area(target
, sizeof(efm32x_flash_write_code
),
670 &write_algorithm
) != ERROR_OK
) {
671 LOG_WARNING("no working area available, can't do block memory writes");
672 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
675 ret
= target_write_buffer(target
, write_algorithm
->address
,
676 sizeof(efm32x_flash_write_code
), efm32x_flash_write_code
);
681 while (target_alloc_working_area_try(target
, buffer_size
, &source
) != ERROR_OK
) {
683 buffer_size
&= ~3UL; /* Make sure it's 4 byte aligned */
684 if (buffer_size
<= 256) {
685 /* we already allocated the writing code, but failed to get a
686 * buffer, free the algorithm */
687 target_free_working_area(target
, write_algorithm
);
689 LOG_WARNING("no large enough working area available, can't do block memory writes");
690 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
694 init_reg_param(®_params
[0], "r0", 32, PARAM_IN_OUT
); /* flash base (in), status (out) */
695 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
); /* count (word-32bit) */
696 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
); /* buffer start */
697 init_reg_param(®_params
[3], "r3", 32, PARAM_OUT
); /* buffer end */
698 init_reg_param(®_params
[4], "r4", 32, PARAM_IN_OUT
); /* target address */
700 buf_set_u32(reg_params
[0].value
, 0, 32, EFM32_MSC_REGBASE
);
701 buf_set_u32(reg_params
[1].value
, 0, 32, count
);
702 buf_set_u32(reg_params
[2].value
, 0, 32, source
->address
);
703 buf_set_u32(reg_params
[3].value
, 0, 32, source
->address
+ source
->size
);
704 buf_set_u32(reg_params
[4].value
, 0, 32, address
);
706 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
707 armv7m_info
.core_mode
= ARM_MODE_THREAD
;
709 ret
= target_run_flash_async_algorithm(target
, buf
, count
, 4,
712 source
->address
, source
->size
,
713 write_algorithm
->address
, 0,
716 if (ret
== ERROR_FLASH_OPERATION_FAILED
) {
717 LOG_ERROR("flash write failed at address 0x%"PRIx32
,
718 buf_get_u32(reg_params
[4].value
, 0, 32));
720 if (buf_get_u32(reg_params
[0].value
, 0, 32) &
721 EFM32_MSC_STATUS_LOCKED_MASK
) {
722 LOG_ERROR("flash memory write protected");
725 if (buf_get_u32(reg_params
[0].value
, 0, 32) &
726 EFM32_MSC_STATUS_INVADDR_MASK
) {
727 LOG_ERROR("invalid flash memory write address");
731 target_free_working_area(target
, source
);
732 target_free_working_area(target
, write_algorithm
);
734 destroy_reg_param(®_params
[0]);
735 destroy_reg_param(®_params
[1]);
736 destroy_reg_param(®_params
[2]);
737 destroy_reg_param(®_params
[3]);
738 destroy_reg_param(®_params
[4]);
743 static int efm32x_write_word(struct flash_bank
*bank
, uint32_t addr
,
746 /* this function DOES NOT set WREN; must be set already */
747 /* 1. write address to ADDRB
749 3. check status (INVADDR, LOCKED)
750 4. wait for WDATAREADY
751 5. write data to WDATA
752 6. write WRITECMD_WRITEONCE to WRITECMD
753 7. wait until !STATUS_BUSY
756 /* FIXME: EFM32G ref states (7.3.2) that writes should be
757 * performed twice per dword */
762 /* if not called, GDB errors will be reported during large writes */
765 ret
= target_write_u32(bank
->target
, EFM32_MSC_ADDRB
, addr
);
769 ret
= efm32x_set_reg_bits(bank
, EFM32_MSC_WRITECMD
,
770 EFM32_MSC_WRITECMD_LADDRIM_MASK
, 1);
774 ret
= target_read_u32(bank
->target
, EFM32_MSC_STATUS
, &status
);
778 LOG_DEBUG("status 0x%" PRIx32
, status
);
780 if (status
& EFM32_MSC_STATUS_LOCKED_MASK
) {
781 LOG_ERROR("Page is locked");
783 } else if (status
& EFM32_MSC_STATUS_INVADDR_MASK
) {
784 LOG_ERROR("Invalid address 0x%" PRIx32
, addr
);
788 ret
= efm32x_wait_status(bank
, EFM32_FLASH_WDATAREADY_TMO
,
789 EFM32_MSC_STATUS_WDATAREADY_MASK
, 1);
790 if (ERROR_OK
!= ret
) {
791 LOG_ERROR("Wait for WDATAREADY failed");
795 ret
= target_write_u32(bank
->target
, EFM32_MSC_WDATA
, val
);
796 if (ERROR_OK
!= ret
) {
797 LOG_ERROR("WDATA write failed");
801 ret
= target_write_u32(bank
->target
, EFM32_MSC_WRITECMD
,
802 EFM32_MSC_WRITECMD_WRITEONCE_MASK
);
803 if (ERROR_OK
!= ret
) {
804 LOG_ERROR("WRITECMD write failed");
808 ret
= efm32x_wait_status(bank
, EFM32_FLASH_WRITE_TMO
,
809 EFM32_MSC_STATUS_BUSY_MASK
, 0);
810 if (ERROR_OK
!= ret
) {
811 LOG_ERROR("Wait for BUSY failed");
818 static int efm32x_write(struct flash_bank
*bank
, const uint8_t *buffer
,
819 uint32_t offset
, uint32_t count
)
821 struct target
*target
= bank
->target
;
822 uint8_t *new_buffer
= NULL
;
824 if (target
->state
!= TARGET_HALTED
) {
825 LOG_ERROR("Target not halted");
826 return ERROR_TARGET_NOT_HALTED
;
830 LOG_ERROR("offset 0x%" PRIx32
" breaks required 4-byte "
831 "alignment", offset
);
832 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
836 uint32_t old_count
= count
;
837 count
= (old_count
| 3) + 1;
838 new_buffer
= malloc(count
);
839 if (new_buffer
== NULL
) {
840 LOG_ERROR("odd number of bytes to write and no memory "
841 "for padding buffer");
844 LOG_INFO("odd number of bytes to write (%" PRIu32
"), extending to %" PRIu32
" "
845 "and padding with 0xff", old_count
, count
);
846 memset(new_buffer
, 0xff, count
);
847 buffer
= memcpy(new_buffer
, buffer
, old_count
);
850 uint32_t words_remaining
= count
/ 4;
853 /* unlock flash registers */
854 efm32x_msc_lock(bank
, 0);
855 retval
= efm32x_set_wren(bank
, 1);
856 if (retval
!= ERROR_OK
)
859 /* try using a block write */
860 retval
= efm32x_write_block(bank
, buffer
, offset
, words_remaining
);
862 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
) {
863 /* if block write failed (no sufficient working area),
864 * we use normal (slow) single word accesses */
865 LOG_WARNING("couldn't use block writes, falling back to single "
868 while (words_remaining
> 0) {
870 memcpy(&value
, buffer
, sizeof(uint32_t));
872 retval
= efm32x_write_word(bank
, offset
, value
);
873 if (retval
!= ERROR_OK
)
874 goto reset_pg_and_lock
;
883 retval2
= efm32x_set_wren(bank
, 0);
884 efm32x_msc_lock(bank
, 1);
885 if (retval
== ERROR_OK
)
895 static int efm32x_probe(struct flash_bank
*bank
)
897 struct efm32x_flash_bank
*efm32x_info
= bank
->driver_priv
;
898 struct efm32_info efm32_mcu_info
;
901 uint32_t base_address
= 0x00000000;
904 efm32x_info
->probed
= 0;
905 memset(efm32x_info
->lb_page
, 0xff, LOCKBITS_PAGE_SZ
);
907 ret
= efm32x_read_info(bank
, &efm32_mcu_info
);
911 ret
= efm32x_decode_info(&efm32_mcu_info
, buf
, sizeof(buf
));
915 LOG_INFO("detected part: %s", buf
);
916 LOG_INFO("flash size = %dkbytes", efm32_mcu_info
.flash_sz_kib
);
917 LOG_INFO("flash page size = %dbytes", efm32_mcu_info
.page_size
);
919 assert(0 != efm32_mcu_info
.page_size
);
921 int num_pages
= efm32_mcu_info
.flash_sz_kib
* 1024 /
922 efm32_mcu_info
.page_size
;
924 assert(num_pages
> 0);
928 bank
->sectors
= NULL
;
931 bank
->base
= base_address
;
932 bank
->size
= (num_pages
* efm32_mcu_info
.page_size
);
933 bank
->num_sectors
= num_pages
;
935 ret
= efm32x_read_lock_data(bank
);
936 if (ERROR_OK
!= ret
) {
937 LOG_ERROR("Failed to read LB data");
941 bank
->sectors
= malloc(sizeof(struct flash_sector
) * num_pages
);
943 for (i
= 0; i
< num_pages
; i
++) {
944 bank
->sectors
[i
].offset
= i
* efm32_mcu_info
.page_size
;
945 bank
->sectors
[i
].size
= efm32_mcu_info
.page_size
;
946 bank
->sectors
[i
].is_erased
= -1;
947 bank
->sectors
[i
].is_protected
= 1;
950 efm32x_info
->probed
= 1;
955 static int efm32x_auto_probe(struct flash_bank
*bank
)
957 struct efm32x_flash_bank
*efm32x_info
= bank
->driver_priv
;
958 if (efm32x_info
->probed
)
960 return efm32x_probe(bank
);
963 static int efm32x_protect_check(struct flash_bank
*bank
)
965 struct target
*target
= bank
->target
;
969 if (target
->state
!= TARGET_HALTED
) {
970 LOG_ERROR("Target not halted");
971 return ERROR_TARGET_NOT_HALTED
;
974 ret
= efm32x_read_lock_data(bank
);
975 if (ERROR_OK
!= ret
) {
976 LOG_ERROR("Failed to read LB data");
980 assert(NULL
!= bank
->sectors
);
982 for (i
= 0; i
< bank
->num_sectors
; i
++)
983 bank
->sectors
[i
].is_protected
= efm32x_get_page_lock(bank
, i
);
988 static int get_efm32x_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
990 struct efm32_info info
;
993 ret
= efm32x_read_info(bank
, &info
);
994 if (ERROR_OK
!= ret
) {
995 LOG_ERROR("Failed to read EFM32 info");
999 return efm32x_decode_info(&info
, buf
, buf_size
);
1002 COMMAND_HANDLER(efm32x_handle_debuglock_command
)
1004 struct target
*target
= NULL
;
1007 return ERROR_COMMAND_SYNTAX_ERROR
;
1009 struct flash_bank
*bank
;
1010 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
1011 if (ERROR_OK
!= retval
)
1014 struct efm32x_flash_bank
*efm32x_info
= bank
->driver_priv
;
1016 target
= bank
->target
;
1018 if (target
->state
!= TARGET_HALTED
) {
1019 LOG_ERROR("Target not halted");
1020 return ERROR_TARGET_NOT_HALTED
;
1024 ptr
= efm32x_info
->lb_page
+ 127;
1027 retval
= efm32x_write_lock_data(bank
);
1028 if (ERROR_OK
!= retval
) {
1029 LOG_ERROR("Failed to write LB page");
1033 command_print(CMD_CTX
, "efm32x debug interface locked, reset the device to apply");
1038 static const struct command_registration efm32x_exec_command_handlers
[] = {
1040 .name
= "debuglock",
1041 .handler
= efm32x_handle_debuglock_command
,
1042 .mode
= COMMAND_EXEC
,
1044 .help
= "Lock the debug interface of the device.",
1046 COMMAND_REGISTRATION_DONE
1049 static const struct command_registration efm32x_command_handlers
[] = {
1052 .mode
= COMMAND_ANY
,
1053 .help
= "efm32 flash command group",
1055 .chain
= efm32x_exec_command_handlers
,
1057 COMMAND_REGISTRATION_DONE
1060 struct flash_driver efm32_flash
= {
1062 .commands
= efm32x_command_handlers
,
1063 .flash_bank_command
= efm32x_flash_bank_command
,
1064 .erase
= efm32x_erase
,
1065 .protect
= efm32x_protect
,
1066 .write
= efm32x_write
,
1067 .read
= default_flash_read
,
1068 .probe
= efm32x_probe
,
1069 .auto_probe
= efm32x_auto_probe
,
1070 .erase_check
= default_flash_blank_check
,
1071 .protect_check
= efm32x_protect_check
,
1072 .info
= get_efm32x_info
,
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)