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, write to the *
29 * Free Software Foundation, Inc., *
30 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
31 ***************************************************************************/
38 #include <helper/binarybuffer.h>
39 #include <target/algorithm.h>
40 #include <target/armv7m.h>
41 #include <target/cortex_m.h>
43 /* keep family IDs in decimal */
44 #define EFM_FAMILY_ID_GECKO 71
45 #define EFM_FAMILY_ID_GIANT_GECKO 72
46 #define EFM_FAMILY_ID_TINY_GECKO 73
47 #define EFM_FAMILY_ID_LEOPARD_GECKO 74
48 #define EFM_FAMILY_ID_WONDER_GECKO 75
49 #define EFM_FAMILY_ID_ZERO_GECKO 76
50 #define EFM_FAMILY_ID_HAPPY_GECKO 77
51 #define EZR_FAMILY_ID_WONDER_GECKO 120
52 #define EZR_FAMILY_ID_LEOPARD_GECKO 121
54 #define EFM32_FLASH_ERASE_TMO 100
55 #define EFM32_FLASH_WDATAREADY_TMO 100
56 #define EFM32_FLASH_WRITE_TMO 100
58 /* size in bytes, not words; must fit all Gecko devices */
59 #define LOCKBITS_PAGE_SZ 512
61 #define EFM32_MSC_INFO_BASE 0x0fe00000
63 #define EFM32_MSC_USER_DATA EFM32_MSC_INFO_BASE
64 #define EFM32_MSC_LOCK_BITS (EFM32_MSC_INFO_BASE+0x4000)
65 #define EFM32_MSC_DEV_INFO (EFM32_MSC_INFO_BASE+0x8000)
67 /* PAGE_SIZE is only present in Leopard, Giant and Wonder Gecko MCUs */
68 #define EFM32_MSC_DI_PAGE_SIZE (EFM32_MSC_DEV_INFO+0x1e7)
69 #define EFM32_MSC_DI_FLASH_SZ (EFM32_MSC_DEV_INFO+0x1f8)
70 #define EFM32_MSC_DI_RAM_SZ (EFM32_MSC_DEV_INFO+0x1fa)
71 #define EFM32_MSC_DI_PART_NUM (EFM32_MSC_DEV_INFO+0x1fc)
72 #define EFM32_MSC_DI_PART_FAMILY (EFM32_MSC_DEV_INFO+0x1fe)
73 #define EFM32_MSC_DI_PROD_REV (EFM32_MSC_DEV_INFO+0x1ff)
75 #define EFM32_MSC_REGBASE 0x400c0000
76 #define EFM32_MSC_WRITECTRL (EFM32_MSC_REGBASE+0x008)
77 #define EFM32_MSC_WRITECTRL_WREN_MASK 0x1
78 #define EFM32_MSC_WRITECMD (EFM32_MSC_REGBASE+0x00c)
79 #define EFM32_MSC_WRITECMD_LADDRIM_MASK 0x1
80 #define EFM32_MSC_WRITECMD_ERASEPAGE_MASK 0x2
81 #define EFM32_MSC_WRITECMD_WRITEONCE_MASK 0x8
82 #define EFM32_MSC_ADDRB (EFM32_MSC_REGBASE+0x010)
83 #define EFM32_MSC_WDATA (EFM32_MSC_REGBASE+0x018)
84 #define EFM32_MSC_STATUS (EFM32_MSC_REGBASE+0x01c)
85 #define EFM32_MSC_STATUS_BUSY_MASK 0x1
86 #define EFM32_MSC_STATUS_LOCKED_MASK 0x2
87 #define EFM32_MSC_STATUS_INVADDR_MASK 0x4
88 #define EFM32_MSC_STATUS_WDATAREADY_MASK 0x8
89 #define EFM32_MSC_STATUS_WORDTIMEOUT_MASK 0x10
90 #define EFM32_MSC_STATUS_ERASEABORTED_MASK 0x20
91 #define EFM32_MSC_LOCK (EFM32_MSC_REGBASE+0x03c)
92 #define EFM32_MSC_LOCK_LOCKKEY 0x1b71
94 struct efm32x_flash_bank
{
96 uint32_t lb_page
[LOCKBITS_PAGE_SZ
/4];
100 uint16_t flash_sz_kib
;
108 static int efm32x_write(struct flash_bank
*bank
, const uint8_t *buffer
,
109 uint32_t offset
, uint32_t count
);
111 static int efm32x_get_flash_size(struct flash_bank
*bank
, uint16_t *flash_sz
)
113 return target_read_u16(bank
->target
, EFM32_MSC_DI_FLASH_SZ
, flash_sz
);
116 static int efm32x_get_ram_size(struct flash_bank
*bank
, uint16_t *ram_sz
)
118 return target_read_u16(bank
->target
, EFM32_MSC_DI_RAM_SZ
, ram_sz
);
121 static int efm32x_get_part_num(struct flash_bank
*bank
, uint16_t *pnum
)
123 return target_read_u16(bank
->target
, EFM32_MSC_DI_PART_NUM
, pnum
);
126 static int efm32x_get_part_family(struct flash_bank
*bank
, uint8_t *pfamily
)
128 return target_read_u8(bank
->target
, EFM32_MSC_DI_PART_FAMILY
, pfamily
);
131 static int efm32x_get_prod_rev(struct flash_bank
*bank
, uint8_t *prev
)
133 return target_read_u8(bank
->target
, EFM32_MSC_DI_PROD_REV
, prev
);
136 static int efm32x_read_info(struct flash_bank
*bank
,
137 struct efm32_info
*efm32_info
)
142 memset(efm32_info
, 0, sizeof(struct efm32_info
));
144 ret
= target_read_u32(bank
->target
, CPUID
, &cpuid
);
148 if (((cpuid
>> 4) & 0xfff) == 0xc23) {
149 /* Cortex M3 device */
150 } else if (((cpuid
>> 4) & 0xfff) == 0xc24) {
151 /* Cortex M4 device(WONDER GECKO) */
152 } else if (((cpuid
>> 4) & 0xfff) == 0xc60) {
153 /* Cortex M0plus device */
155 LOG_ERROR("Target is not Cortex-Mx Device");
159 ret
= efm32x_get_flash_size(bank
, &(efm32_info
->flash_sz_kib
));
163 ret
= efm32x_get_ram_size(bank
, &(efm32_info
->ram_sz_kib
));
167 ret
= efm32x_get_part_num(bank
, &(efm32_info
->part_num
));
171 ret
= efm32x_get_part_family(bank
, &(efm32_info
->part_family
));
175 ret
= efm32x_get_prod_rev(bank
, &(efm32_info
->prod_rev
));
179 if (EFM_FAMILY_ID_GECKO
== efm32_info
->part_family
||
180 EFM_FAMILY_ID_TINY_GECKO
== efm32_info
->part_family
)
181 efm32_info
->page_size
= 512;
182 else if (EFM_FAMILY_ID_ZERO_GECKO
== efm32_info
->part_family
||
183 EFM_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
);
231 /* flash bank efm32 <base> <size> 0 0 <target#>
233 FLASH_BANK_COMMAND_HANDLER(efm32x_flash_bank_command
)
235 struct efm32x_flash_bank
*efm32x_info
;
238 return ERROR_COMMAND_SYNTAX_ERROR
;
240 efm32x_info
= malloc(sizeof(struct efm32x_flash_bank
));
242 bank
->driver_priv
= efm32x_info
;
243 efm32x_info
->probed
= 0;
244 memset(efm32x_info
->lb_page
, 0xff, LOCKBITS_PAGE_SZ
);
249 /* set or reset given bits in a register */
250 static int efm32x_set_reg_bits(struct flash_bank
*bank
, uint32_t reg
,
251 uint32_t bitmask
, int set
)
254 uint32_t reg_val
= 0;
256 ret
= target_read_u32(bank
->target
, reg
, ®_val
);
265 return target_write_u32(bank
->target
, reg
, reg_val
);
268 static int efm32x_set_wren(struct flash_bank
*bank
, int write_enable
)
270 return efm32x_set_reg_bits(bank
, EFM32_MSC_WRITECTRL
,
271 EFM32_MSC_WRITECTRL_WREN_MASK
, write_enable
);
274 static int efm32x_msc_lock(struct flash_bank
*bank
, int lock
)
276 return target_write_u32(bank
->target
, EFM32_MSC_LOCK
,
277 (lock
? 0 : EFM32_MSC_LOCK_LOCKKEY
));
280 static int efm32x_wait_status(struct flash_bank
*bank
, int timeout
,
281 uint32_t wait_mask
, int wait_for_set
)
287 ret
= target_read_u32(bank
->target
, EFM32_MSC_STATUS
, &status
);
291 LOG_DEBUG("status: 0x%" PRIx32
"", status
);
293 if (((status
& wait_mask
) == 0) && (0 == wait_for_set
))
295 else if (((status
& wait_mask
) != 0) && wait_for_set
)
298 if (timeout
-- <= 0) {
299 LOG_ERROR("timed out waiting for MSC status");
306 if (status
& EFM32_MSC_STATUS_ERASEABORTED_MASK
)
307 LOG_WARNING("page erase was aborted");
312 static int efm32x_erase_page(struct flash_bank
*bank
, uint32_t addr
)
314 /* this function DOES NOT set WREN; must be set already */
315 /* 1. write address to ADDRB
317 3. check status (INVADDR, LOCKED)
319 5. wait until !STATUS_BUSY
324 LOG_DEBUG("erasing flash page at 0x%08" PRIx32
, addr
);
326 ret
= target_write_u32(bank
->target
, EFM32_MSC_ADDRB
, addr
);
330 ret
= efm32x_set_reg_bits(bank
, EFM32_MSC_WRITECMD
,
331 EFM32_MSC_WRITECMD_LADDRIM_MASK
, 1);
335 ret
= target_read_u32(bank
->target
, EFM32_MSC_STATUS
, &status
);
339 LOG_DEBUG("status 0x%" PRIx32
, status
);
341 if (status
& EFM32_MSC_STATUS_LOCKED_MASK
) {
342 LOG_ERROR("Page is locked");
344 } else if (status
& EFM32_MSC_STATUS_INVADDR_MASK
) {
345 LOG_ERROR("Invalid address 0x%" PRIx32
, addr
);
349 ret
= efm32x_set_reg_bits(bank
, EFM32_MSC_WRITECMD
,
350 EFM32_MSC_WRITECMD_ERASEPAGE_MASK
, 1);
354 return efm32x_wait_status(bank
, EFM32_FLASH_ERASE_TMO
,
355 EFM32_MSC_STATUS_BUSY_MASK
, 0);
358 static int efm32x_erase(struct flash_bank
*bank
, int first
, int last
)
360 struct target
*target
= bank
->target
;
364 if (TARGET_HALTED
!= target
->state
) {
365 LOG_ERROR("Target not halted");
366 return ERROR_TARGET_NOT_HALTED
;
369 efm32x_msc_lock(bank
, 0);
370 ret
= efm32x_set_wren(bank
, 1);
371 if (ERROR_OK
!= ret
) {
372 LOG_ERROR("Failed to enable MSC write");
376 for (i
= first
; i
<= last
; i
++) {
377 ret
= efm32x_erase_page(bank
, bank
->sectors
[i
].offset
);
379 LOG_ERROR("Failed to erase page %d", i
);
382 ret
= efm32x_set_wren(bank
, 0);
383 efm32x_msc_lock(bank
, 1);
388 static int efm32x_read_lock_data(struct flash_bank
*bank
)
390 struct efm32x_flash_bank
*efm32x_info
= bank
->driver_priv
;
391 struct target
*target
= bank
->target
;
394 uint32_t *ptr
= NULL
;
397 assert(!(bank
->num_sectors
& 0x1f));
399 data_size
= bank
->num_sectors
/ 8; /* number of data bytes */
400 data_size
/= 4; /* ...and data dwords */
402 ptr
= efm32x_info
->lb_page
;
404 for (i
= 0; i
< data_size
; i
++, ptr
++) {
405 ret
= target_read_u32(target
, EFM32_MSC_LOCK_BITS
+i
*4, ptr
);
406 if (ERROR_OK
!= ret
) {
407 LOG_ERROR("Failed to read PLW %d", i
);
412 /* also, read ULW, DLW and MLW */
415 ptr
= efm32x_info
->lb_page
+ 126;
416 ret
= target_read_u32(target
, EFM32_MSC_LOCK_BITS
+126*4, ptr
);
417 if (ERROR_OK
!= ret
) {
418 LOG_ERROR("Failed to read ULW");
423 ptr
= efm32x_info
->lb_page
+ 127;
424 ret
= target_read_u32(target
, EFM32_MSC_LOCK_BITS
+127*4, ptr
);
425 if (ERROR_OK
!= ret
) {
426 LOG_ERROR("Failed to read DLW");
430 /* MLW, word 125, present in GG and LG */
431 ptr
= efm32x_info
->lb_page
+ 125;
432 ret
= target_read_u32(target
, EFM32_MSC_LOCK_BITS
+125*4, ptr
);
433 if (ERROR_OK
!= ret
) {
434 LOG_ERROR("Failed to read MLW");
441 static int efm32x_write_lock_data(struct flash_bank
*bank
)
443 struct efm32x_flash_bank
*efm32x_info
= bank
->driver_priv
;
446 ret
= efm32x_erase_page(bank
, EFM32_MSC_LOCK_BITS
);
447 if (ERROR_OK
!= ret
) {
448 LOG_ERROR("Failed to erase LB page");
452 return efm32x_write(bank
, (uint8_t *)efm32x_info
->lb_page
, EFM32_MSC_LOCK_BITS
,
456 static int efm32x_get_page_lock(struct flash_bank
*bank
, size_t page
)
458 struct efm32x_flash_bank
*efm32x_info
= bank
->driver_priv
;
459 uint32_t dw
= efm32x_info
->lb_page
[page
>> 5];
462 mask
= 1 << (page
& 0x1f);
464 return (dw
& mask
) ? 0 : 1;
467 static int efm32x_set_page_lock(struct flash_bank
*bank
, size_t page
, int set
)
469 struct efm32x_flash_bank
*efm32x_info
= bank
->driver_priv
;
470 uint32_t *dw
= &efm32x_info
->lb_page
[page
>> 5];
473 mask
= 1 << (page
& 0x1f);
483 static int efm32x_protect(struct flash_bank
*bank
, int set
, int first
, int last
)
485 struct target
*target
= bank
->target
;
490 LOG_ERROR("Erase device data to reset page locks");
494 if (target
->state
!= TARGET_HALTED
) {
495 LOG_ERROR("Target not halted");
496 return ERROR_TARGET_NOT_HALTED
;
499 for (i
= first
; i
<= last
; i
++) {
500 ret
= efm32x_set_page_lock(bank
, i
, set
);
501 if (ERROR_OK
!= ret
) {
502 LOG_ERROR("Failed to set lock on page %d", i
);
507 ret
= efm32x_write_lock_data(bank
);
508 if (ERROR_OK
!= ret
) {
509 LOG_ERROR("Failed to write LB page");
516 static int efm32x_write_block(struct flash_bank
*bank
, const uint8_t *buf
,
517 uint32_t offset
, uint32_t count
)
519 struct target
*target
= bank
->target
;
520 uint32_t buffer_size
= 16384;
521 struct working_area
*write_algorithm
;
522 struct working_area
*source
;
523 uint32_t address
= bank
->base
+ offset
;
524 struct reg_param reg_params
[5];
525 struct armv7m_algorithm armv7m_info
;
528 /* see contrib/loaders/flash/efm32.S for src */
529 static const uint8_t efm32x_flash_write_code
[] = {
530 /* #define EFM32_MSC_WRITECTRL_OFFSET 0x008 */
531 /* #define EFM32_MSC_WRITECMD_OFFSET 0x00c */
532 /* #define EFM32_MSC_ADDRB_OFFSET 0x010 */
533 /* #define EFM32_MSC_WDATA_OFFSET 0x018 */
534 /* #define EFM32_MSC_STATUS_OFFSET 0x01c */
535 /* #define EFM32_MSC_LOCK_OFFSET 0x03c */
537 0x15, 0x4e, /* ldr r6, =#0x1b71 */
538 0xc6, 0x63, /* str r6, [r0, #EFM32_MSC_LOCK_OFFSET] */
539 0x01, 0x26, /* movs r6, #1 */
540 0x86, 0x60, /* str r6, [r0, #EFM32_MSC_WRITECTRL_OFFSET] */
543 0x16, 0x68, /* ldr r6, [r2, #0] */
544 0x00, 0x2e, /* cmp r6, #0 */
545 0x22, 0xd0, /* beq exit */
546 0x55, 0x68, /* ldr r5, [r2, #4] */
547 0xb5, 0x42, /* cmp r5, r6 */
548 0xf9, 0xd0, /* beq wait_fifo */
550 0x04, 0x61, /* str r4, [r0, #EFM32_MSC_ADDRB_OFFSET] */
551 0x01, 0x26, /* movs r6, #1 */
552 0xc6, 0x60, /* str r6, [r0, #EFM32_MSC_WRITECMD_OFFSET] */
553 0xc6, 0x69, /* ldr r6, [r0, #EFM32_MSC_STATUS_OFFSET] */
554 0x06, 0x27, /* movs r7, #6 */
555 0x3e, 0x42, /* tst r6, r7 */
556 0x16, 0xd1, /* bne error */
558 /* wait_wdataready: */
559 0xc6, 0x69, /* ldr r6, [r0, #EFM32_MSC_STATUS_OFFSET] */
560 0x08, 0x27, /* movs r7, #8 */
561 0x3e, 0x42, /* tst r6, r7 */
562 0xfb, 0xd0, /* beq wait_wdataready */
564 0x2e, 0x68, /* ldr r6, [r5] */
565 0x86, 0x61, /* str r6, [r0, #EFM32_MSC_WDATA_OFFSET] */
566 0x08, 0x26, /* movs r6, #8 */
567 0xc6, 0x60, /* str r6, [r0, #EFM32_MSC_WRITECMD_OFFSET] */
569 0x04, 0x35, /* adds r5, #4 */
570 0x04, 0x34, /* adds r4, #4 */
573 0xc6, 0x69, /* ldr r6, [r0, #EFM32_MSC_STATUS_OFFSET] */
574 0x01, 0x27, /* movs r7, #1 */
575 0x3e, 0x42, /* tst r6, r7 */
576 0xfb, 0xd1, /* bne busy */
578 0x9d, 0x42, /* cmp r5, r3 */
579 0x01, 0xd3, /* bcc no_wrap */
580 0x15, 0x46, /* mov r5, r2 */
581 0x08, 0x35, /* adds r5, #8 */
584 0x55, 0x60, /* str r5, [r2, #4] */
585 0x01, 0x39, /* subs r1, r1, #1 */
586 0x00, 0x29, /* cmp r1, #0 */
587 0x02, 0xd0, /* beq exit */
588 0xdb, 0xe7, /* b wait_fifo */
591 0x00, 0x20, /* movs r0, #0 */
592 0x50, 0x60, /* str r0, [r2, #4] */
595 0x30, 0x46, /* mov r0, r6 */
596 0x00, 0xbe, /* bkpt #0 */
599 0x71, 0x1b, 0x00, 0x00
602 /* flash write code */
603 if (target_alloc_working_area(target
, sizeof(efm32x_flash_write_code
),
604 &write_algorithm
) != ERROR_OK
) {
605 LOG_WARNING("no working area available, can't do block memory writes");
606 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
609 ret
= target_write_buffer(target
, write_algorithm
->address
,
610 sizeof(efm32x_flash_write_code
), efm32x_flash_write_code
);
615 while (target_alloc_working_area_try(target
, buffer_size
, &source
) != ERROR_OK
) {
617 buffer_size
&= ~3UL; /* Make sure it's 4 byte aligned */
618 if (buffer_size
<= 256) {
619 /* we already allocated the writing code, but failed to get a
620 * buffer, free the algorithm */
621 target_free_working_area(target
, write_algorithm
);
623 LOG_WARNING("no large enough working area available, can't do block memory writes");
624 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
628 init_reg_param(®_params
[0], "r0", 32, PARAM_IN_OUT
); /* flash base (in), status (out) */
629 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
); /* count (word-32bit) */
630 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
); /* buffer start */
631 init_reg_param(®_params
[3], "r3", 32, PARAM_OUT
); /* buffer end */
632 init_reg_param(®_params
[4], "r4", 32, PARAM_IN_OUT
); /* target address */
634 buf_set_u32(reg_params
[0].value
, 0, 32, EFM32_MSC_REGBASE
);
635 buf_set_u32(reg_params
[1].value
, 0, 32, count
);
636 buf_set_u32(reg_params
[2].value
, 0, 32, source
->address
);
637 buf_set_u32(reg_params
[3].value
, 0, 32, source
->address
+ source
->size
);
638 buf_set_u32(reg_params
[4].value
, 0, 32, address
);
640 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
641 armv7m_info
.core_mode
= ARM_MODE_THREAD
;
643 ret
= target_run_flash_async_algorithm(target
, buf
, count
, 4,
646 source
->address
, source
->size
,
647 write_algorithm
->address
, 0,
650 if (ret
== ERROR_FLASH_OPERATION_FAILED
) {
651 LOG_ERROR("flash write failed at address 0x%"PRIx32
,
652 buf_get_u32(reg_params
[4].value
, 0, 32));
654 if (buf_get_u32(reg_params
[0].value
, 0, 32) &
655 EFM32_MSC_STATUS_LOCKED_MASK
) {
656 LOG_ERROR("flash memory write protected");
659 if (buf_get_u32(reg_params
[0].value
, 0, 32) &
660 EFM32_MSC_STATUS_INVADDR_MASK
) {
661 LOG_ERROR("invalid flash memory write address");
665 target_free_working_area(target
, source
);
666 target_free_working_area(target
, write_algorithm
);
668 destroy_reg_param(®_params
[0]);
669 destroy_reg_param(®_params
[1]);
670 destroy_reg_param(®_params
[2]);
671 destroy_reg_param(®_params
[3]);
672 destroy_reg_param(®_params
[4]);
677 static int efm32x_write_word(struct flash_bank
*bank
, uint32_t addr
,
680 /* this function DOES NOT set WREN; must be set already */
681 /* 1. write address to ADDRB
683 3. check status (INVADDR, LOCKED)
684 4. wait for WDATAREADY
685 5. write data to WDATA
686 6. write WRITECMD_WRITEONCE to WRITECMD
687 7. wait until !STATUS_BUSY
690 /* FIXME: EFM32G ref states (7.3.2) that writes should be
691 * performed twice per dword */
696 /* if not called, GDB errors will be reported during large writes */
699 ret
= target_write_u32(bank
->target
, EFM32_MSC_ADDRB
, addr
);
703 ret
= efm32x_set_reg_bits(bank
, EFM32_MSC_WRITECMD
,
704 EFM32_MSC_WRITECMD_LADDRIM_MASK
, 1);
708 ret
= target_read_u32(bank
->target
, EFM32_MSC_STATUS
, &status
);
712 LOG_DEBUG("status 0x%" PRIx32
, status
);
714 if (status
& EFM32_MSC_STATUS_LOCKED_MASK
) {
715 LOG_ERROR("Page is locked");
717 } else if (status
& EFM32_MSC_STATUS_INVADDR_MASK
) {
718 LOG_ERROR("Invalid address 0x%" PRIx32
, addr
);
722 ret
= efm32x_wait_status(bank
, EFM32_FLASH_WDATAREADY_TMO
,
723 EFM32_MSC_STATUS_WDATAREADY_MASK
, 1);
724 if (ERROR_OK
!= ret
) {
725 LOG_ERROR("Wait for WDATAREADY failed");
729 ret
= target_write_u32(bank
->target
, EFM32_MSC_WDATA
, val
);
730 if (ERROR_OK
!= ret
) {
731 LOG_ERROR("WDATA write failed");
735 ret
= target_write_u32(bank
->target
, EFM32_MSC_WRITECMD
,
736 EFM32_MSC_WRITECMD_WRITEONCE_MASK
);
737 if (ERROR_OK
!= ret
) {
738 LOG_ERROR("WRITECMD write failed");
742 ret
= efm32x_wait_status(bank
, EFM32_FLASH_WRITE_TMO
,
743 EFM32_MSC_STATUS_BUSY_MASK
, 0);
744 if (ERROR_OK
!= ret
) {
745 LOG_ERROR("Wait for BUSY failed");
752 static int efm32x_write(struct flash_bank
*bank
, const uint8_t *buffer
,
753 uint32_t offset
, uint32_t count
)
755 struct target
*target
= bank
->target
;
756 uint8_t *new_buffer
= NULL
;
758 if (target
->state
!= TARGET_HALTED
) {
759 LOG_ERROR("Target not halted");
760 return ERROR_TARGET_NOT_HALTED
;
764 LOG_ERROR("offset 0x%" PRIx32
" breaks required 4-byte "
765 "alignment", offset
);
766 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
770 uint32_t old_count
= count
;
771 count
= (old_count
| 3) + 1;
772 new_buffer
= malloc(count
);
773 if (new_buffer
== NULL
) {
774 LOG_ERROR("odd number of bytes to write and no memory "
775 "for padding buffer");
778 LOG_INFO("odd number of bytes to write (%" PRIu32
"), extending to %" PRIu32
" "
779 "and padding with 0xff", old_count
, count
);
780 memset(new_buffer
, 0xff, count
);
781 buffer
= memcpy(new_buffer
, buffer
, old_count
);
784 uint32_t words_remaining
= count
/ 4;
787 /* unlock flash registers */
788 efm32x_msc_lock(bank
, 0);
789 retval
= efm32x_set_wren(bank
, 1);
790 if (retval
!= ERROR_OK
)
793 /* try using a block write */
794 retval
= efm32x_write_block(bank
, buffer
, offset
, words_remaining
);
796 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
) {
797 /* if block write failed (no sufficient working area),
798 * we use normal (slow) single word accesses */
799 LOG_WARNING("couldn't use block writes, falling back to single "
802 while (words_remaining
> 0) {
804 memcpy(&value
, buffer
, sizeof(uint32_t));
806 retval
= efm32x_write_word(bank
, offset
, value
);
807 if (retval
!= ERROR_OK
)
808 goto reset_pg_and_lock
;
817 retval2
= efm32x_set_wren(bank
, 0);
818 efm32x_msc_lock(bank
, 1);
819 if (retval
== ERROR_OK
)
829 static int efm32x_probe(struct flash_bank
*bank
)
831 struct efm32x_flash_bank
*efm32x_info
= bank
->driver_priv
;
832 struct efm32_info efm32_mcu_info
;
835 uint32_t base_address
= 0x00000000;
837 efm32x_info
->probed
= 0;
838 memset(efm32x_info
->lb_page
, 0xff, LOCKBITS_PAGE_SZ
);
840 ret
= efm32x_read_info(bank
, &efm32_mcu_info
);
844 switch (efm32_mcu_info
.part_family
) {
845 case EFM_FAMILY_ID_GECKO
:
846 LOG_INFO("Gecko MCU detected");
848 case EFM_FAMILY_ID_GIANT_GECKO
:
849 LOG_INFO("Giant Gecko MCU detected");
851 case EFM_FAMILY_ID_TINY_GECKO
:
852 LOG_INFO("Tiny Gecko MCU detected");
854 case EFM_FAMILY_ID_LEOPARD_GECKO
:
855 case EZR_FAMILY_ID_LEOPARD_GECKO
:
856 LOG_INFO("Leopard Gecko MCU detected");
858 case EFM_FAMILY_ID_WONDER_GECKO
:
859 case EZR_FAMILY_ID_WONDER_GECKO
:
860 LOG_INFO("Wonder Gecko MCU detected");
862 case EFM_FAMILY_ID_ZERO_GECKO
:
863 LOG_INFO("Zero Gecko MCU detected");
865 case EFM_FAMILY_ID_HAPPY_GECKO
:
866 LOG_INFO("Happy Gecko MCU detected");
869 LOG_ERROR("Unsupported MCU family %d",
870 efm32_mcu_info
.part_family
);
874 LOG_INFO("flash size = %dkbytes", efm32_mcu_info
.flash_sz_kib
);
875 LOG_INFO("flash page size = %dbytes", efm32_mcu_info
.page_size
);
877 assert(0 != efm32_mcu_info
.page_size
);
879 int num_pages
= efm32_mcu_info
.flash_sz_kib
* 1024 /
880 efm32_mcu_info
.page_size
;
882 assert(num_pages
> 0);
886 bank
->sectors
= NULL
;
889 bank
->base
= base_address
;
890 bank
->size
= (num_pages
* efm32_mcu_info
.page_size
);
891 bank
->num_sectors
= num_pages
;
893 ret
= efm32x_read_lock_data(bank
);
894 if (ERROR_OK
!= ret
) {
895 LOG_ERROR("Failed to read LB data");
899 bank
->sectors
= malloc(sizeof(struct flash_sector
) * num_pages
);
901 for (i
= 0; i
< num_pages
; i
++) {
902 bank
->sectors
[i
].offset
= i
* efm32_mcu_info
.page_size
;
903 bank
->sectors
[i
].size
= efm32_mcu_info
.page_size
;
904 bank
->sectors
[i
].is_erased
= -1;
905 bank
->sectors
[i
].is_protected
= 1;
908 efm32x_info
->probed
= 1;
913 static int efm32x_auto_probe(struct flash_bank
*bank
)
915 struct efm32x_flash_bank
*efm32x_info
= bank
->driver_priv
;
916 if (efm32x_info
->probed
)
918 return efm32x_probe(bank
);
921 static int efm32x_protect_check(struct flash_bank
*bank
)
923 struct target
*target
= bank
->target
;
927 if (target
->state
!= TARGET_HALTED
) {
928 LOG_ERROR("Target not halted");
929 return ERROR_TARGET_NOT_HALTED
;
932 ret
= efm32x_read_lock_data(bank
);
933 if (ERROR_OK
!= ret
) {
934 LOG_ERROR("Failed to read LB data");
938 assert(NULL
!= bank
->sectors
);
940 for (i
= 0; i
< bank
->num_sectors
; i
++)
941 bank
->sectors
[i
].is_protected
= efm32x_get_page_lock(bank
, i
);
946 static int get_efm32x_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
948 struct efm32_info info
;
952 ret
= efm32x_read_info(bank
, &info
);
953 if (ERROR_OK
!= ret
) {
954 LOG_ERROR("Failed to read EFM32 info");
958 switch (info
.part_family
) {
959 case EZR_FAMILY_ID_WONDER_GECKO
:
960 case EZR_FAMILY_ID_LEOPARD_GECKO
:
961 printed
= snprintf(buf
, buf_size
, "EZR32 ");
964 printed
= snprintf(buf
, buf_size
, "EFM32 ");
971 return ERROR_BUF_TOO_SMALL
;
973 switch (info
.part_family
) {
974 case EFM_FAMILY_ID_GECKO
:
975 printed
= snprintf(buf
, buf_size
, "Gecko");
977 case EFM_FAMILY_ID_GIANT_GECKO
:
978 printed
= snprintf(buf
, buf_size
, "Giant Gecko");
980 case EFM_FAMILY_ID_TINY_GECKO
:
981 printed
= snprintf(buf
, buf_size
, "Tiny Gecko");
983 case EFM_FAMILY_ID_LEOPARD_GECKO
:
984 case EZR_FAMILY_ID_LEOPARD_GECKO
:
985 printed
= snprintf(buf
, buf_size
, "Leopard Gecko");
987 case EFM_FAMILY_ID_WONDER_GECKO
:
988 case EZR_FAMILY_ID_WONDER_GECKO
:
989 printed
= snprintf(buf
, buf_size
, "Wonder Gecko");
991 case EFM_FAMILY_ID_ZERO_GECKO
:
992 printed
= snprintf(buf
, buf_size
, "Zero Gecko");
994 case EFM_FAMILY_ID_HAPPY_GECKO
:
995 printed
= snprintf(buf
, buf_size
, "Happy Gecko");
1000 buf_size
-= printed
;
1003 return ERROR_BUF_TOO_SMALL
;
1005 printed
= snprintf(buf
, buf_size
, " - Rev: %d", info
.prod_rev
);
1007 buf_size
-= printed
;
1010 return ERROR_BUF_TOO_SMALL
;
1015 static const struct command_registration efm32x_exec_command_handlers
[] = {
1016 COMMAND_REGISTRATION_DONE
1019 static const struct command_registration efm32x_command_handlers
[] = {
1022 .mode
= COMMAND_ANY
,
1023 .help
= "efm32 flash command group",
1025 .chain
= efm32x_exec_command_handlers
,
1027 COMMAND_REGISTRATION_DONE
1030 struct flash_driver efm32_flash
= {
1032 .commands
= efm32x_command_handlers
,
1033 .flash_bank_command
= efm32x_flash_bank_command
,
1034 .erase
= efm32x_erase
,
1035 .protect
= efm32x_protect
,
1036 .write
= efm32x_write
,
1037 .read
= default_flash_read
,
1038 .probe
= efm32x_probe
,
1039 .auto_probe
= efm32x_auto_probe
,
1040 .erase_check
= default_flash_blank_check
,
1041 .protect_check
= efm32x_protect_check
,
1042 .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)