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 EZR_FAMILY_ID_WONDER_GECKO 120
51 #define EZR_FAMILY_ID_LEOPARD_GECKO 121
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 M0plus device(ZERO GECKO) */
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 efm32_info
->page_size
= 1024;
183 else if (EFM_FAMILY_ID_GIANT_GECKO
== efm32_info
->part_family
||
184 EFM_FAMILY_ID_LEOPARD_GECKO
== efm32_info
->part_family
) {
185 if (efm32_info
->prod_rev
>= 18) {
187 ret
= target_read_u8(bank
->target
, EFM32_MSC_DI_PAGE_SIZE
,
192 efm32_info
->page_size
= (1 << ((pg_size
+10) & 0xff));
194 /* EFM32 GG/LG errata: MEM_INFO_PAGE_SIZE is invalid
195 for MCUs with PROD_REV < 18 */
196 if (efm32_info
->flash_sz_kib
< 512)
197 efm32_info
->page_size
= 2048;
199 efm32_info
->page_size
= 4096;
202 if ((2048 != efm32_info
->page_size
) &&
203 (4096 != efm32_info
->page_size
)) {
204 LOG_ERROR("Invalid page size %u", efm32_info
->page_size
);
207 } else if (EFM_FAMILY_ID_WONDER_GECKO
== efm32_info
->part_family
||
208 EZR_FAMILY_ID_WONDER_GECKO
== efm32_info
->part_family
||
209 EZR_FAMILY_ID_LEOPARD_GECKO
== efm32_info
->part_family
) {
211 ret
= target_read_u8(bank
->target
, EFM32_MSC_DI_PAGE_SIZE
,
216 efm32_info
->page_size
= (1 << ((pg_size
+10) & 0xff));
217 if (2048 != efm32_info
->page_size
) {
218 LOG_ERROR("Invalid page size %u", efm32_info
->page_size
);
222 LOG_ERROR("Unknown MCU family %d", efm32_info
->part_family
);
229 /* flash bank efm32 <base> <size> 0 0 <target#>
231 FLASH_BANK_COMMAND_HANDLER(efm32x_flash_bank_command
)
233 struct efm32x_flash_bank
*efm32x_info
;
236 return ERROR_COMMAND_SYNTAX_ERROR
;
238 efm32x_info
= malloc(sizeof(struct efm32x_flash_bank
));
240 bank
->driver_priv
= efm32x_info
;
241 efm32x_info
->probed
= 0;
242 memset(efm32x_info
->lb_page
, 0xff, LOCKBITS_PAGE_SZ
);
247 /* set or reset given bits in a register */
248 static int efm32x_set_reg_bits(struct flash_bank
*bank
, uint32_t reg
,
249 uint32_t bitmask
, int set
)
252 uint32_t reg_val
= 0;
254 ret
= target_read_u32(bank
->target
, reg
, ®_val
);
263 return target_write_u32(bank
->target
, reg
, reg_val
);
266 static int efm32x_set_wren(struct flash_bank
*bank
, int write_enable
)
268 return efm32x_set_reg_bits(bank
, EFM32_MSC_WRITECTRL
,
269 EFM32_MSC_WRITECTRL_WREN_MASK
, write_enable
);
272 static int efm32x_msc_lock(struct flash_bank
*bank
, int lock
)
274 return target_write_u32(bank
->target
, EFM32_MSC_LOCK
,
275 (lock
? 0 : EFM32_MSC_LOCK_LOCKKEY
));
278 static int efm32x_wait_status(struct flash_bank
*bank
, int timeout
,
279 uint32_t wait_mask
, int wait_for_set
)
285 ret
= target_read_u32(bank
->target
, EFM32_MSC_STATUS
, &status
);
289 LOG_DEBUG("status: 0x%" PRIx32
"", status
);
291 if (((status
& wait_mask
) == 0) && (0 == wait_for_set
))
293 else if (((status
& wait_mask
) != 0) && wait_for_set
)
296 if (timeout
-- <= 0) {
297 LOG_ERROR("timed out waiting for MSC status");
304 if (status
& EFM32_MSC_STATUS_ERASEABORTED_MASK
)
305 LOG_WARNING("page erase was aborted");
310 static int efm32x_erase_page(struct flash_bank
*bank
, uint32_t addr
)
312 /* this function DOES NOT set WREN; must be set already */
313 /* 1. write address to ADDRB
315 3. check status (INVADDR, LOCKED)
317 5. wait until !STATUS_BUSY
322 LOG_DEBUG("erasing flash page at 0x%08" PRIx32
, addr
);
324 ret
= target_write_u32(bank
->target
, EFM32_MSC_ADDRB
, addr
);
328 ret
= efm32x_set_reg_bits(bank
, EFM32_MSC_WRITECMD
,
329 EFM32_MSC_WRITECMD_LADDRIM_MASK
, 1);
333 ret
= target_read_u32(bank
->target
, EFM32_MSC_STATUS
, &status
);
337 LOG_DEBUG("status 0x%" PRIx32
, status
);
339 if (status
& EFM32_MSC_STATUS_LOCKED_MASK
) {
340 LOG_ERROR("Page is locked");
342 } else if (status
& EFM32_MSC_STATUS_INVADDR_MASK
) {
343 LOG_ERROR("Invalid address 0x%" PRIx32
, addr
);
347 ret
= efm32x_set_reg_bits(bank
, EFM32_MSC_WRITECMD
,
348 EFM32_MSC_WRITECMD_ERASEPAGE_MASK
, 1);
352 return efm32x_wait_status(bank
, EFM32_FLASH_ERASE_TMO
,
353 EFM32_MSC_STATUS_BUSY_MASK
, 0);
356 static int efm32x_erase(struct flash_bank
*bank
, int first
, int last
)
358 struct target
*target
= bank
->target
;
362 if (TARGET_HALTED
!= target
->state
) {
363 LOG_ERROR("Target not halted");
364 return ERROR_TARGET_NOT_HALTED
;
367 efm32x_msc_lock(bank
, 0);
368 ret
= efm32x_set_wren(bank
, 1);
369 if (ERROR_OK
!= ret
) {
370 LOG_ERROR("Failed to enable MSC write");
374 for (i
= first
; i
<= last
; i
++) {
375 ret
= efm32x_erase_page(bank
, bank
->sectors
[i
].offset
);
377 LOG_ERROR("Failed to erase page %d", i
);
380 ret
= efm32x_set_wren(bank
, 0);
381 efm32x_msc_lock(bank
, 1);
386 static int efm32x_read_lock_data(struct flash_bank
*bank
)
388 struct efm32x_flash_bank
*efm32x_info
= bank
->driver_priv
;
389 struct target
*target
= bank
->target
;
392 uint32_t *ptr
= NULL
;
395 assert(!(bank
->num_sectors
& 0x1f));
397 data_size
= bank
->num_sectors
/ 8; /* number of data bytes */
398 data_size
/= 4; /* ...and data dwords */
400 ptr
= efm32x_info
->lb_page
;
402 for (i
= 0; i
< data_size
; i
++, ptr
++) {
403 ret
= target_read_u32(target
, EFM32_MSC_LOCK_BITS
+i
*4, ptr
);
404 if (ERROR_OK
!= ret
) {
405 LOG_ERROR("Failed to read PLW %d", i
);
410 /* also, read ULW, DLW and MLW */
413 ptr
= efm32x_info
->lb_page
+ 126;
414 ret
= target_read_u32(target
, EFM32_MSC_LOCK_BITS
+126*4, ptr
);
415 if (ERROR_OK
!= ret
) {
416 LOG_ERROR("Failed to read ULW");
421 ptr
= efm32x_info
->lb_page
+ 127;
422 ret
= target_read_u32(target
, EFM32_MSC_LOCK_BITS
+127*4, ptr
);
423 if (ERROR_OK
!= ret
) {
424 LOG_ERROR("Failed to read DLW");
428 /* MLW, word 125, present in GG and LG */
429 ptr
= efm32x_info
->lb_page
+ 125;
430 ret
= target_read_u32(target
, EFM32_MSC_LOCK_BITS
+125*4, ptr
);
431 if (ERROR_OK
!= ret
) {
432 LOG_ERROR("Failed to read MLW");
439 static int efm32x_write_lock_data(struct flash_bank
*bank
)
441 struct efm32x_flash_bank
*efm32x_info
= bank
->driver_priv
;
444 ret
= efm32x_erase_page(bank
, EFM32_MSC_LOCK_BITS
);
445 if (ERROR_OK
!= ret
) {
446 LOG_ERROR("Failed to erase LB page");
450 return efm32x_write(bank
, (uint8_t *)efm32x_info
->lb_page
, EFM32_MSC_LOCK_BITS
,
454 static int efm32x_get_page_lock(struct flash_bank
*bank
, size_t page
)
456 struct efm32x_flash_bank
*efm32x_info
= bank
->driver_priv
;
457 uint32_t dw
= efm32x_info
->lb_page
[page
>> 5];
460 mask
= 1 << (page
& 0x1f);
462 return (dw
& mask
) ? 0 : 1;
465 static int efm32x_set_page_lock(struct flash_bank
*bank
, size_t page
, int set
)
467 struct efm32x_flash_bank
*efm32x_info
= bank
->driver_priv
;
468 uint32_t *dw
= &efm32x_info
->lb_page
[page
>> 5];
471 mask
= 1 << (page
& 0x1f);
481 static int efm32x_protect(struct flash_bank
*bank
, int set
, int first
, int last
)
483 struct target
*target
= bank
->target
;
488 LOG_ERROR("Erase device data to reset page locks");
492 if (target
->state
!= TARGET_HALTED
) {
493 LOG_ERROR("Target not halted");
494 return ERROR_TARGET_NOT_HALTED
;
497 for (i
= first
; i
<= last
; i
++) {
498 ret
= efm32x_set_page_lock(bank
, i
, set
);
499 if (ERROR_OK
!= ret
) {
500 LOG_ERROR("Failed to set lock on page %d", i
);
505 ret
= efm32x_write_lock_data(bank
);
506 if (ERROR_OK
!= ret
) {
507 LOG_ERROR("Failed to write LB page");
514 static int efm32x_write_block(struct flash_bank
*bank
, const uint8_t *buf
,
515 uint32_t offset
, uint32_t count
)
517 struct target
*target
= bank
->target
;
518 uint32_t buffer_size
= 16384;
519 struct working_area
*write_algorithm
;
520 struct working_area
*source
;
521 uint32_t address
= bank
->base
+ offset
;
522 struct reg_param reg_params
[5];
523 struct armv7m_algorithm armv7m_info
;
526 /* see contrib/loaders/flash/efm32.S for src */
527 static const uint8_t efm32x_flash_write_code
[] = {
528 /* #define EFM32_MSC_WRITECTRL_OFFSET 0x008 */
529 /* #define EFM32_MSC_WRITECMD_OFFSET 0x00c */
530 /* #define EFM32_MSC_ADDRB_OFFSET 0x010 */
531 /* #define EFM32_MSC_WDATA_OFFSET 0x018 */
532 /* #define EFM32_MSC_STATUS_OFFSET 0x01c */
533 /* #define EFM32_MSC_LOCK_OFFSET 0x03c */
535 0x15, 0x4e, /* ldr r6, =#0x1b71 */
536 0xc6, 0x63, /* str r6, [r0, #EFM32_MSC_LOCK_OFFSET] */
537 0x01, 0x26, /* movs r6, #1 */
538 0x86, 0x60, /* str r6, [r0, #EFM32_MSC_WRITECTRL_OFFSET] */
541 0x16, 0x68, /* ldr r6, [r2, #0] */
542 0x00, 0x2e, /* cmp r6, #0 */
543 0x22, 0xd0, /* beq exit */
544 0x55, 0x68, /* ldr r5, [r2, #4] */
545 0xb5, 0x42, /* cmp r5, r6 */
546 0xf9, 0xd0, /* beq wait_fifo */
548 0x04, 0x61, /* str r4, [r0, #EFM32_MSC_ADDRB_OFFSET] */
549 0x01, 0x26, /* movs r6, #1 */
550 0xc6, 0x60, /* str r6, [r0, #EFM32_MSC_WRITECMD_OFFSET] */
551 0xc6, 0x69, /* ldr r6, [r0, #EFM32_MSC_STATUS_OFFSET] */
552 0x06, 0x27, /* movs r7, #6 */
553 0x3e, 0x42, /* tst r6, r7 */
554 0x16, 0xd1, /* bne error */
556 /* wait_wdataready: */
557 0xc6, 0x69, /* ldr r6, [r0, #EFM32_MSC_STATUS_OFFSET] */
558 0x08, 0x27, /* movs r7, #8 */
559 0x3e, 0x42, /* tst r6, r7 */
560 0xfb, 0xd0, /* beq wait_wdataready */
562 0x2e, 0x68, /* ldr r6, [r5] */
563 0x86, 0x61, /* str r6, [r0, #EFM32_MSC_WDATA_OFFSET] */
564 0x08, 0x26, /* movs r6, #8 */
565 0xc6, 0x60, /* str r6, [r0, #EFM32_MSC_WRITECMD_OFFSET] */
567 0x04, 0x35, /* adds r5, #4 */
568 0x04, 0x34, /* adds r4, #4 */
571 0xc6, 0x69, /* ldr r6, [r0, #EFM32_MSC_STATUS_OFFSET] */
572 0x01, 0x27, /* movs r7, #1 */
573 0x3e, 0x42, /* tst r6, r7 */
574 0xfb, 0xd1, /* bne busy */
576 0x9d, 0x42, /* cmp r5, r3 */
577 0x01, 0xd3, /* bcc no_wrap */
578 0x15, 0x46, /* mov r5, r2 */
579 0x08, 0x35, /* adds r5, #8 */
582 0x55, 0x60, /* str r5, [r2, #4] */
583 0x01, 0x39, /* subs r1, r1, #1 */
584 0x00, 0x29, /* cmp r1, #0 */
585 0x02, 0xd0, /* beq exit */
586 0xdb, 0xe7, /* b wait_fifo */
589 0x00, 0x20, /* movs r0, #0 */
590 0x50, 0x60, /* str r0, [r2, #4] */
593 0x30, 0x46, /* mov r0, r6 */
594 0x00, 0xbe, /* bkpt #0 */
597 0x71, 0x1b, 0x00, 0x00
600 /* flash write code */
601 if (target_alloc_working_area(target
, sizeof(efm32x_flash_write_code
),
602 &write_algorithm
) != ERROR_OK
) {
603 LOG_WARNING("no working area available, can't do block memory writes");
604 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
607 ret
= target_write_buffer(target
, write_algorithm
->address
,
608 sizeof(efm32x_flash_write_code
), efm32x_flash_write_code
);
613 while (target_alloc_working_area_try(target
, buffer_size
, &source
) != ERROR_OK
) {
615 buffer_size
&= ~3UL; /* Make sure it's 4 byte aligned */
616 if (buffer_size
<= 256) {
617 /* we already allocated the writing code, but failed to get a
618 * buffer, free the algorithm */
619 target_free_working_area(target
, write_algorithm
);
621 LOG_WARNING("no large enough working area available, can't do block memory writes");
622 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
626 init_reg_param(®_params
[0], "r0", 32, PARAM_IN_OUT
); /* flash base (in), status (out) */
627 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
); /* count (word-32bit) */
628 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
); /* buffer start */
629 init_reg_param(®_params
[3], "r3", 32, PARAM_OUT
); /* buffer end */
630 init_reg_param(®_params
[4], "r4", 32, PARAM_IN_OUT
); /* target address */
632 buf_set_u32(reg_params
[0].value
, 0, 32, EFM32_MSC_REGBASE
);
633 buf_set_u32(reg_params
[1].value
, 0, 32, count
);
634 buf_set_u32(reg_params
[2].value
, 0, 32, source
->address
);
635 buf_set_u32(reg_params
[3].value
, 0, 32, source
->address
+ source
->size
);
636 buf_set_u32(reg_params
[4].value
, 0, 32, address
);
638 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
639 armv7m_info
.core_mode
= ARM_MODE_THREAD
;
641 ret
= target_run_flash_async_algorithm(target
, buf
, count
, 4,
644 source
->address
, source
->size
,
645 write_algorithm
->address
, 0,
648 if (ret
== ERROR_FLASH_OPERATION_FAILED
) {
649 LOG_ERROR("flash write failed at address 0x%"PRIx32
,
650 buf_get_u32(reg_params
[4].value
, 0, 32));
652 if (buf_get_u32(reg_params
[0].value
, 0, 32) &
653 EFM32_MSC_STATUS_LOCKED_MASK
) {
654 LOG_ERROR("flash memory write protected");
657 if (buf_get_u32(reg_params
[0].value
, 0, 32) &
658 EFM32_MSC_STATUS_INVADDR_MASK
) {
659 LOG_ERROR("invalid flash memory write address");
663 target_free_working_area(target
, source
);
664 target_free_working_area(target
, write_algorithm
);
666 destroy_reg_param(®_params
[0]);
667 destroy_reg_param(®_params
[1]);
668 destroy_reg_param(®_params
[2]);
669 destroy_reg_param(®_params
[3]);
670 destroy_reg_param(®_params
[4]);
675 static int efm32x_write_word(struct flash_bank
*bank
, uint32_t addr
,
678 /* this function DOES NOT set WREN; must be set already */
679 /* 1. write address to ADDRB
681 3. check status (INVADDR, LOCKED)
682 4. wait for WDATAREADY
683 5. write data to WDATA
684 6. write WRITECMD_WRITEONCE to WRITECMD
685 7. wait until !STATUS_BUSY
688 /* FIXME: EFM32G ref states (7.3.2) that writes should be
689 * performed twice per dword */
694 /* if not called, GDB errors will be reported during large writes */
697 ret
= target_write_u32(bank
->target
, EFM32_MSC_ADDRB
, addr
);
701 ret
= efm32x_set_reg_bits(bank
, EFM32_MSC_WRITECMD
,
702 EFM32_MSC_WRITECMD_LADDRIM_MASK
, 1);
706 ret
= target_read_u32(bank
->target
, EFM32_MSC_STATUS
, &status
);
710 LOG_DEBUG("status 0x%" PRIx32
, status
);
712 if (status
& EFM32_MSC_STATUS_LOCKED_MASK
) {
713 LOG_ERROR("Page is locked");
715 } else if (status
& EFM32_MSC_STATUS_INVADDR_MASK
) {
716 LOG_ERROR("Invalid address 0x%" PRIx32
, addr
);
720 ret
= efm32x_wait_status(bank
, EFM32_FLASH_WDATAREADY_TMO
,
721 EFM32_MSC_STATUS_WDATAREADY_MASK
, 1);
722 if (ERROR_OK
!= ret
) {
723 LOG_ERROR("Wait for WDATAREADY failed");
727 ret
= target_write_u32(bank
->target
, EFM32_MSC_WDATA
, val
);
728 if (ERROR_OK
!= ret
) {
729 LOG_ERROR("WDATA write failed");
733 ret
= target_write_u32(bank
->target
, EFM32_MSC_WRITECMD
,
734 EFM32_MSC_WRITECMD_WRITEONCE_MASK
);
735 if (ERROR_OK
!= ret
) {
736 LOG_ERROR("WRITECMD write failed");
740 ret
= efm32x_wait_status(bank
, EFM32_FLASH_WRITE_TMO
,
741 EFM32_MSC_STATUS_BUSY_MASK
, 0);
742 if (ERROR_OK
!= ret
) {
743 LOG_ERROR("Wait for BUSY failed");
750 static int efm32x_write(struct flash_bank
*bank
, const uint8_t *buffer
,
751 uint32_t offset
, uint32_t count
)
753 struct target
*target
= bank
->target
;
754 uint8_t *new_buffer
= NULL
;
756 if (target
->state
!= TARGET_HALTED
) {
757 LOG_ERROR("Target not halted");
758 return ERROR_TARGET_NOT_HALTED
;
762 LOG_ERROR("offset 0x%" PRIx32
" breaks required 4-byte "
763 "alignment", offset
);
764 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
768 uint32_t old_count
= count
;
769 count
= (old_count
| 3) + 1;
770 new_buffer
= malloc(count
);
771 if (new_buffer
== NULL
) {
772 LOG_ERROR("odd number of bytes to write and no memory "
773 "for padding buffer");
776 LOG_INFO("odd number of bytes to write (%" PRIu32
"), extending to %" PRIu32
" "
777 "and padding with 0xff", old_count
, count
);
778 memset(new_buffer
, 0xff, count
);
779 buffer
= memcpy(new_buffer
, buffer
, old_count
);
782 uint32_t words_remaining
= count
/ 4;
785 /* unlock flash registers */
786 efm32x_msc_lock(bank
, 0);
787 retval
= efm32x_set_wren(bank
, 1);
788 if (retval
!= ERROR_OK
)
791 /* try using a block write */
792 retval
= efm32x_write_block(bank
, buffer
, offset
, words_remaining
);
794 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
) {
795 /* if block write failed (no sufficient working area),
796 * we use normal (slow) single word accesses */
797 LOG_WARNING("couldn't use block writes, falling back to single "
800 while (words_remaining
> 0) {
802 memcpy(&value
, buffer
, sizeof(uint32_t));
804 retval
= efm32x_write_word(bank
, offset
, value
);
805 if (retval
!= ERROR_OK
)
806 goto reset_pg_and_lock
;
815 retval2
= efm32x_set_wren(bank
, 0);
816 efm32x_msc_lock(bank
, 1);
817 if (retval
== ERROR_OK
)
827 static int efm32x_probe(struct flash_bank
*bank
)
829 struct efm32x_flash_bank
*efm32x_info
= bank
->driver_priv
;
830 struct efm32_info efm32_mcu_info
;
833 uint32_t base_address
= 0x00000000;
835 efm32x_info
->probed
= 0;
836 memset(efm32x_info
->lb_page
, 0xff, LOCKBITS_PAGE_SZ
);
838 ret
= efm32x_read_info(bank
, &efm32_mcu_info
);
842 switch (efm32_mcu_info
.part_family
) {
843 case EFM_FAMILY_ID_GECKO
:
844 LOG_INFO("Gecko MCU detected");
846 case EFM_FAMILY_ID_GIANT_GECKO
:
847 LOG_INFO("Giant Gecko MCU detected");
849 case EFM_FAMILY_ID_TINY_GECKO
:
850 LOG_INFO("Tiny Gecko MCU detected");
852 case EFM_FAMILY_ID_LEOPARD_GECKO
:
853 case EZR_FAMILY_ID_LEOPARD_GECKO
:
854 LOG_INFO("Leopard Gecko MCU detected");
856 case EFM_FAMILY_ID_WONDER_GECKO
:
857 case EZR_FAMILY_ID_WONDER_GECKO
:
858 LOG_INFO("Wonder Gecko MCU detected");
860 case EFM_FAMILY_ID_ZERO_GECKO
:
861 LOG_INFO("Zero Gecko MCU detected");
864 LOG_ERROR("Unsupported MCU family %d",
865 efm32_mcu_info
.part_family
);
869 LOG_INFO("flash size = %dkbytes", efm32_mcu_info
.flash_sz_kib
);
870 LOG_INFO("flash page size = %dbytes", efm32_mcu_info
.page_size
);
872 assert(0 != efm32_mcu_info
.page_size
);
874 int num_pages
= efm32_mcu_info
.flash_sz_kib
* 1024 /
875 efm32_mcu_info
.page_size
;
877 assert(num_pages
> 0);
881 bank
->sectors
= NULL
;
884 bank
->base
= base_address
;
885 bank
->size
= (num_pages
* efm32_mcu_info
.page_size
);
886 bank
->num_sectors
= num_pages
;
888 ret
= efm32x_read_lock_data(bank
);
889 if (ERROR_OK
!= ret
) {
890 LOG_ERROR("Failed to read LB data");
894 bank
->sectors
= malloc(sizeof(struct flash_sector
) * num_pages
);
896 for (i
= 0; i
< num_pages
; i
++) {
897 bank
->sectors
[i
].offset
= i
* efm32_mcu_info
.page_size
;
898 bank
->sectors
[i
].size
= efm32_mcu_info
.page_size
;
899 bank
->sectors
[i
].is_erased
= -1;
900 bank
->sectors
[i
].is_protected
= 1;
903 efm32x_info
->probed
= 1;
908 static int efm32x_auto_probe(struct flash_bank
*bank
)
910 struct efm32x_flash_bank
*efm32x_info
= bank
->driver_priv
;
911 if (efm32x_info
->probed
)
913 return efm32x_probe(bank
);
916 static int efm32x_protect_check(struct flash_bank
*bank
)
918 struct target
*target
= bank
->target
;
922 if (target
->state
!= TARGET_HALTED
) {
923 LOG_ERROR("Target not halted");
924 return ERROR_TARGET_NOT_HALTED
;
927 ret
= efm32x_read_lock_data(bank
);
928 if (ERROR_OK
!= ret
) {
929 LOG_ERROR("Failed to read LB data");
933 assert(NULL
!= bank
->sectors
);
935 for (i
= 0; i
< bank
->num_sectors
; i
++)
936 bank
->sectors
[i
].is_protected
= efm32x_get_page_lock(bank
, i
);
941 static int get_efm32x_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
943 struct efm32_info info
;
947 ret
= efm32x_read_info(bank
, &info
);
948 if (ERROR_OK
!= ret
) {
949 LOG_ERROR("Failed to read EFM32 info");
953 switch (info
.part_family
) {
954 case EZR_FAMILY_ID_WONDER_GECKO
:
955 case EZR_FAMILY_ID_LEOPARD_GECKO
:
956 printed
= snprintf(buf
, buf_size
, "EZR32 ");
959 printed
= snprintf(buf
, buf_size
, "EFM32 ");
966 return ERROR_BUF_TOO_SMALL
;
968 switch (info
.part_family
) {
969 case EFM_FAMILY_ID_GECKO
:
970 printed
= snprintf(buf
, buf_size
, "Gecko");
972 case EFM_FAMILY_ID_GIANT_GECKO
:
973 printed
= snprintf(buf
, buf_size
, "Giant Gecko");
975 case EFM_FAMILY_ID_TINY_GECKO
:
976 printed
= snprintf(buf
, buf_size
, "Tiny Gecko");
978 case EFM_FAMILY_ID_LEOPARD_GECKO
:
979 case EZR_FAMILY_ID_LEOPARD_GECKO
:
980 printed
= snprintf(buf
, buf_size
, "Leopard Gecko");
982 case EFM_FAMILY_ID_WONDER_GECKO
:
983 case EZR_FAMILY_ID_WONDER_GECKO
:
984 printed
= snprintf(buf
, buf_size
, "Wonder Gecko");
986 case EFM_FAMILY_ID_ZERO_GECKO
:
987 printed
= snprintf(buf
, buf_size
, "Zero Gecko");
995 return ERROR_BUF_TOO_SMALL
;
997 printed
= snprintf(buf
, buf_size
, " - Rev: %d", info
.prod_rev
);
1002 return ERROR_BUF_TOO_SMALL
;
1007 static const struct command_registration efm32x_exec_command_handlers
[] = {
1008 COMMAND_REGISTRATION_DONE
1011 static const struct command_registration efm32x_command_handlers
[] = {
1014 .mode
= COMMAND_ANY
,
1015 .help
= "efm32 flash command group",
1017 .chain
= efm32x_exec_command_handlers
,
1019 COMMAND_REGISTRATION_DONE
1022 struct flash_driver efm32_flash
= {
1024 .commands
= efm32x_command_handlers
,
1025 .flash_bank_command
= efm32x_flash_bank_command
,
1026 .erase
= efm32x_erase
,
1027 .protect
= efm32x_protect
,
1028 .write
= efm32x_write
,
1029 .read
= default_flash_read
,
1030 .probe
= efm32x_probe
,
1031 .auto_probe
= efm32x_auto_probe
,
1032 .erase_check
= default_flash_blank_check
,
1033 .protect_check
= efm32x_protect_check
,
1034 .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)