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
51 #define EFM32_FLASH_ERASE_TMO 100
52 #define EFM32_FLASH_WDATAREADY_TMO 100
53 #define EFM32_FLASH_WRITE_TMO 100
55 /* size in bytes, not words; must fit all Gecko devices */
56 #define LOCKBITS_PAGE_SZ 512
58 #define EFM32_MSC_INFO_BASE 0x0fe00000
60 #define EFM32_MSC_USER_DATA EFM32_MSC_INFO_BASE
61 #define EFM32_MSC_LOCK_BITS (EFM32_MSC_INFO_BASE+0x4000)
62 #define EFM32_MSC_DEV_INFO (EFM32_MSC_INFO_BASE+0x8000)
64 /* PAGE_SIZE is only present in Leopard and Giant Gecko MCUs */
65 #define EFM32_MSC_DI_PAGE_SIZE (EFM32_MSC_DEV_INFO+0x1e7)
66 #define EFM32_MSC_DI_FLASH_SZ (EFM32_MSC_DEV_INFO+0x1f8)
67 #define EFM32_MSC_DI_RAM_SZ (EFM32_MSC_DEV_INFO+0x1fa)
68 #define EFM32_MSC_DI_PART_NUM (EFM32_MSC_DEV_INFO+0x1fc)
69 #define EFM32_MSC_DI_PART_FAMILY (EFM32_MSC_DEV_INFO+0x1fe)
70 #define EFM32_MSC_DI_PROD_REV (EFM32_MSC_DEV_INFO+0x1ff)
72 #define EFM32_MSC_REGBASE 0x400c0000
73 #define EFM32_MSC_WRITECTRL (EFM32_MSC_REGBASE+0x008)
74 #define EFM32_MSC_WRITECTRL_WREN_MASK 0x1
75 #define EFM32_MSC_WRITECMD (EFM32_MSC_REGBASE+0x00c)
76 #define EFM32_MSC_WRITECMD_LADDRIM_MASK 0x1
77 #define EFM32_MSC_WRITECMD_ERASEPAGE_MASK 0x2
78 #define EFM32_MSC_WRITECMD_WRITEONCE_MASK 0x8
79 #define EFM32_MSC_ADDRB (EFM32_MSC_REGBASE+0x010)
80 #define EFM32_MSC_WDATA (EFM32_MSC_REGBASE+0x018)
81 #define EFM32_MSC_STATUS (EFM32_MSC_REGBASE+0x01c)
82 #define EFM32_MSC_STATUS_BUSY_MASK 0x1
83 #define EFM32_MSC_STATUS_LOCKED_MASK 0x2
84 #define EFM32_MSC_STATUS_INVADDR_MASK 0x4
85 #define EFM32_MSC_STATUS_WDATAREADY_MASK 0x8
86 #define EFM32_MSC_STATUS_WORDTIMEOUT_MASK 0x10
87 #define EFM32_MSC_STATUS_ERASEABORTED_MASK 0x20
88 #define EFM32_MSC_LOCK (EFM32_MSC_REGBASE+0x03c)
89 #define EFM32_MSC_LOCK_LOCKKEY 0x1b71
91 struct efm32x_flash_bank
{
93 uint32_t lb_page
[LOCKBITS_PAGE_SZ
/4];
97 uint16_t flash_sz_kib
;
105 static int efm32x_write(struct flash_bank
*bank
, const uint8_t *buffer
,
106 uint32_t offset
, uint32_t count
);
108 static int efm32x_get_flash_size(struct flash_bank
*bank
, uint16_t *flash_sz
)
110 return target_read_u16(bank
->target
, EFM32_MSC_DI_FLASH_SZ
, flash_sz
);
113 static int efm32x_get_ram_size(struct flash_bank
*bank
, uint16_t *ram_sz
)
115 return target_read_u16(bank
->target
, EFM32_MSC_DI_RAM_SZ
, ram_sz
);
118 static int efm32x_get_part_num(struct flash_bank
*bank
, uint16_t *pnum
)
120 return target_read_u16(bank
->target
, EFM32_MSC_DI_PART_NUM
, pnum
);
123 static int efm32x_get_part_family(struct flash_bank
*bank
, uint8_t *pfamily
)
125 return target_read_u8(bank
->target
, EFM32_MSC_DI_PART_FAMILY
, pfamily
);
128 static int efm32x_get_prod_rev(struct flash_bank
*bank
, uint8_t *prev
)
130 return target_read_u8(bank
->target
, EFM32_MSC_DI_PROD_REV
, prev
);
133 static int efm32x_read_info(struct flash_bank
*bank
,
134 struct efm32_info
*efm32_info
)
139 memset(efm32_info
, 0, sizeof(struct efm32_info
));
141 ret
= target_read_u32(bank
->target
, CPUID
, &cpuid
);
145 if (((cpuid
>> 4) & 0xfff) == 0xc23) {
146 /* Cortex M3 device */
147 } else if (((cpuid
>> 4) & 0xfff) == 0xc24) {
148 /* Cortex M4 device(WONDER GECKO) */
149 } else if (((cpuid
>> 4) & 0xfff) == 0xc60) {
150 /* Cortex M0plus device(ZERO GECKO) */
152 LOG_ERROR("Target is not Cortex-Mx Device");
156 ret
= efm32x_get_flash_size(bank
, &(efm32_info
->flash_sz_kib
));
160 ret
= efm32x_get_ram_size(bank
, &(efm32_info
->ram_sz_kib
));
164 ret
= efm32x_get_part_num(bank
, &(efm32_info
->part_num
));
168 ret
= efm32x_get_part_family(bank
, &(efm32_info
->part_family
));
172 ret
= efm32x_get_prod_rev(bank
, &(efm32_info
->prod_rev
));
176 if (EFM_FAMILY_ID_GECKO
== efm32_info
->part_family
||
177 EFM_FAMILY_ID_TINY_GECKO
== efm32_info
->part_family
)
178 efm32_info
->page_size
= 512;
179 else if (EFM_FAMILY_ID_ZERO_GECKO
== efm32_info
->part_family
)
180 efm32_info
->page_size
= 1024;
181 else if (EFM_FAMILY_ID_GIANT_GECKO
== efm32_info
->part_family
||
182 EFM_FAMILY_ID_LEOPARD_GECKO
== efm32_info
->part_family
) {
183 if (efm32_info
->prod_rev
>= 18) {
185 ret
= target_read_u8(bank
->target
, EFM32_MSC_DI_PAGE_SIZE
,
190 efm32_info
->page_size
= (1 << ((pg_size
+10) & 0xff));
192 /* EFM32 GG/LG errata: MEM_INFO_PAGE_SIZE is invalid
193 for MCUs with PROD_REV < 18 */
194 if (efm32_info
->flash_sz_kib
< 512)
195 efm32_info
->page_size
= 2048;
197 efm32_info
->page_size
= 4096;
200 if ((2048 != efm32_info
->page_size
) &&
201 (4096 != efm32_info
->page_size
)) {
202 LOG_ERROR("Invalid page size %u", efm32_info
->page_size
);
205 } else if (EFM_FAMILY_ID_WONDER_GECKO
== efm32_info
->part_family
) {
207 ret
= target_read_u8(bank
->target
, EFM32_MSC_DI_PAGE_SIZE
,
212 efm32_info
->page_size
= (1 << ((pg_size
+10) & 0xff));
213 if (2048 != efm32_info
->page_size
) {
214 LOG_ERROR("Invalid page size %u", efm32_info
->page_size
);
218 LOG_ERROR("Unknown MCU family %d", efm32_info
->part_family
);
225 /* flash bank efm32 <base> <size> 0 0 <target#>
227 FLASH_BANK_COMMAND_HANDLER(efm32x_flash_bank_command
)
229 struct efm32x_flash_bank
*efm32x_info
;
232 return ERROR_COMMAND_SYNTAX_ERROR
;
234 efm32x_info
= malloc(sizeof(struct efm32x_flash_bank
));
236 bank
->driver_priv
= efm32x_info
;
237 efm32x_info
->probed
= 0;
238 memset(efm32x_info
->lb_page
, 0xff, LOCKBITS_PAGE_SZ
);
243 /* set or reset given bits in a register */
244 static int efm32x_set_reg_bits(struct flash_bank
*bank
, uint32_t reg
,
245 uint32_t bitmask
, int set
)
248 uint32_t reg_val
= 0;
250 ret
= target_read_u32(bank
->target
, reg
, ®_val
);
259 return target_write_u32(bank
->target
, reg
, reg_val
);
262 static int efm32x_set_wren(struct flash_bank
*bank
, int write_enable
)
264 return efm32x_set_reg_bits(bank
, EFM32_MSC_WRITECTRL
,
265 EFM32_MSC_WRITECTRL_WREN_MASK
, write_enable
);
268 static int efm32x_msc_lock(struct flash_bank
*bank
, int lock
)
270 return target_write_u32(bank
->target
, EFM32_MSC_LOCK
,
271 (lock
? 0 : EFM32_MSC_LOCK_LOCKKEY
));
274 static int efm32x_wait_status(struct flash_bank
*bank
, int timeout
,
275 uint32_t wait_mask
, int wait_for_set
)
281 ret
= target_read_u32(bank
->target
, EFM32_MSC_STATUS
, &status
);
285 LOG_DEBUG("status: 0x%" PRIx32
"", status
);
287 if (((status
& wait_mask
) == 0) && (0 == wait_for_set
))
289 else if (((status
& wait_mask
) != 0) && wait_for_set
)
292 if (timeout
-- <= 0) {
293 LOG_ERROR("timed out waiting for MSC status");
300 if (status
& EFM32_MSC_STATUS_ERASEABORTED_MASK
)
301 LOG_WARNING("page erase was aborted");
306 static int efm32x_erase_page(struct flash_bank
*bank
, uint32_t addr
)
308 /* this function DOES NOT set WREN; must be set already */
309 /* 1. write address to ADDRB
311 3. check status (INVADDR, LOCKED)
313 5. wait until !STATUS_BUSY
318 LOG_DEBUG("erasing flash page at 0x%08" PRIx32
, addr
);
320 ret
= target_write_u32(bank
->target
, EFM32_MSC_ADDRB
, addr
);
324 ret
= efm32x_set_reg_bits(bank
, EFM32_MSC_WRITECMD
,
325 EFM32_MSC_WRITECMD_LADDRIM_MASK
, 1);
329 ret
= target_read_u32(bank
->target
, EFM32_MSC_STATUS
, &status
);
333 LOG_DEBUG("status 0x%" PRIx32
, status
);
335 if (status
& EFM32_MSC_STATUS_LOCKED_MASK
) {
336 LOG_ERROR("Page is locked");
338 } else if (status
& EFM32_MSC_STATUS_INVADDR_MASK
) {
339 LOG_ERROR("Invalid address 0x%" PRIx32
, addr
);
343 ret
= efm32x_set_reg_bits(bank
, EFM32_MSC_WRITECMD
,
344 EFM32_MSC_WRITECMD_ERASEPAGE_MASK
, 1);
348 return efm32x_wait_status(bank
, EFM32_FLASH_ERASE_TMO
,
349 EFM32_MSC_STATUS_BUSY_MASK
, 0);
352 static int efm32x_erase(struct flash_bank
*bank
, int first
, int last
)
354 struct target
*target
= bank
->target
;
358 if (TARGET_HALTED
!= target
->state
) {
359 LOG_ERROR("Target not halted");
360 return ERROR_TARGET_NOT_HALTED
;
363 efm32x_msc_lock(bank
, 0);
364 ret
= efm32x_set_wren(bank
, 1);
365 if (ERROR_OK
!= ret
) {
366 LOG_ERROR("Failed to enable MSC write");
370 for (i
= first
; i
<= last
; i
++) {
371 ret
= efm32x_erase_page(bank
, bank
->sectors
[i
].offset
);
373 LOG_ERROR("Failed to erase page %d", i
);
376 ret
= efm32x_set_wren(bank
, 0);
377 efm32x_msc_lock(bank
, 1);
382 static int efm32x_read_lock_data(struct flash_bank
*bank
)
384 struct efm32x_flash_bank
*efm32x_info
= bank
->driver_priv
;
385 struct target
*target
= bank
->target
;
388 uint32_t *ptr
= NULL
;
391 assert(!(bank
->num_sectors
& 0x1f));
393 data_size
= bank
->num_sectors
/ 8; /* number of data bytes */
394 data_size
/= 4; /* ...and data dwords */
396 ptr
= efm32x_info
->lb_page
;
398 for (i
= 0; i
< data_size
; i
++, ptr
++) {
399 ret
= target_read_u32(target
, EFM32_MSC_LOCK_BITS
+i
*4, ptr
);
400 if (ERROR_OK
!= ret
) {
401 LOG_ERROR("Failed to read PLW %d", i
);
406 /* also, read ULW, DLW and MLW */
409 ptr
= efm32x_info
->lb_page
+ 126;
410 ret
= target_read_u32(target
, EFM32_MSC_LOCK_BITS
+126*4, ptr
);
411 if (ERROR_OK
!= ret
) {
412 LOG_ERROR("Failed to read ULW");
417 ptr
= efm32x_info
->lb_page
+ 127;
418 ret
= target_read_u32(target
, EFM32_MSC_LOCK_BITS
+127*4, ptr
);
419 if (ERROR_OK
!= ret
) {
420 LOG_ERROR("Failed to read DLW");
424 /* MLW, word 125, present in GG and LG */
425 ptr
= efm32x_info
->lb_page
+ 125;
426 ret
= target_read_u32(target
, EFM32_MSC_LOCK_BITS
+125*4, ptr
);
427 if (ERROR_OK
!= ret
) {
428 LOG_ERROR("Failed to read MLW");
435 static int efm32x_write_lock_data(struct flash_bank
*bank
)
437 struct efm32x_flash_bank
*efm32x_info
= bank
->driver_priv
;
440 ret
= efm32x_erase_page(bank
, EFM32_MSC_LOCK_BITS
);
441 if (ERROR_OK
!= ret
) {
442 LOG_ERROR("Failed to erase LB page");
446 return efm32x_write(bank
, (uint8_t *)efm32x_info
->lb_page
, EFM32_MSC_LOCK_BITS
,
450 static int efm32x_get_page_lock(struct flash_bank
*bank
, size_t page
)
452 struct efm32x_flash_bank
*efm32x_info
= bank
->driver_priv
;
453 uint32_t dw
= efm32x_info
->lb_page
[page
>> 5];
456 mask
= 1 << (page
& 0x1f);
458 return (dw
& mask
) ? 0 : 1;
461 static int efm32x_set_page_lock(struct flash_bank
*bank
, size_t page
, int set
)
463 struct efm32x_flash_bank
*efm32x_info
= bank
->driver_priv
;
464 uint32_t *dw
= &efm32x_info
->lb_page
[page
>> 5];
467 mask
= 1 << (page
& 0x1f);
477 static int efm32x_protect(struct flash_bank
*bank
, int set
, int first
, int last
)
479 struct target
*target
= bank
->target
;
484 LOG_ERROR("Erase device data to reset page locks");
488 if (target
->state
!= TARGET_HALTED
) {
489 LOG_ERROR("Target not halted");
490 return ERROR_TARGET_NOT_HALTED
;
493 for (i
= first
; i
<= last
; i
++) {
494 ret
= efm32x_set_page_lock(bank
, i
, set
);
495 if (ERROR_OK
!= ret
) {
496 LOG_ERROR("Failed to set lock on page %d", i
);
501 ret
= efm32x_write_lock_data(bank
);
502 if (ERROR_OK
!= ret
) {
503 LOG_ERROR("Failed to write LB page");
510 static int efm32x_write_block(struct flash_bank
*bank
, const uint8_t *buf
,
511 uint32_t offset
, uint32_t count
)
513 struct target
*target
= bank
->target
;
514 uint32_t buffer_size
= 16384;
515 struct working_area
*write_algorithm
;
516 struct working_area
*source
;
517 uint32_t address
= bank
->base
+ offset
;
518 struct reg_param reg_params
[5];
519 struct armv7m_algorithm armv7m_info
;
522 /* see contrib/loaders/flash/efm32.S for src */
523 static const uint8_t efm32x_flash_write_code
[] = {
524 /* #define EFM32_MSC_WRITECTRL_OFFSET 0x008 */
525 /* #define EFM32_MSC_WRITECMD_OFFSET 0x00c */
526 /* #define EFM32_MSC_ADDRB_OFFSET 0x010 */
527 /* #define EFM32_MSC_WDATA_OFFSET 0x018 */
528 /* #define EFM32_MSC_STATUS_OFFSET 0x01c */
529 /* #define EFM32_MSC_LOCK_OFFSET 0x03c */
531 0x15, 0x4e, /* ldr r6, =#0x1b71 */
532 0xc6, 0x63, /* str r6, [r0, #EFM32_MSC_LOCK_OFFSET] */
533 0x01, 0x26, /* movs r6, #1 */
534 0x86, 0x60, /* str r6, [r0, #EFM32_MSC_WRITECTRL_OFFSET] */
537 0x16, 0x68, /* ldr r6, [r2, #0] */
538 0x00, 0x2e, /* cmp r6, #0 */
539 0x22, 0xd0, /* beq exit */
540 0x55, 0x68, /* ldr r5, [r2, #4] */
541 0xb5, 0x42, /* cmp r5, r6 */
542 0xf9, 0xd0, /* beq wait_fifo */
544 0x04, 0x61, /* str r4, [r0, #EFM32_MSC_ADDRB_OFFSET] */
545 0x01, 0x26, /* movs r6, #1 */
546 0xc6, 0x60, /* str r6, [r0, #EFM32_MSC_WRITECMD_OFFSET] */
547 0xc6, 0x69, /* ldr r6, [r0, #EFM32_MSC_STATUS_OFFSET] */
548 0x06, 0x27, /* movs r7, #6 */
549 0x3e, 0x42, /* tst r6, r7 */
550 0x16, 0xd1, /* bne error */
552 /* wait_wdataready: */
553 0xc6, 0x69, /* ldr r6, [r0, #EFM32_MSC_STATUS_OFFSET] */
554 0x08, 0x27, /* movs r7, #8 */
555 0x3e, 0x42, /* tst r6, r7 */
556 0xfb, 0xd0, /* beq wait_wdataready */
558 0x2e, 0x68, /* ldr r6, [r5] */
559 0x86, 0x61, /* str r6, [r0, #EFM32_MSC_WDATA_OFFSET] */
560 0x08, 0x26, /* movs r6, #8 */
561 0xc6, 0x60, /* str r6, [r0, #EFM32_MSC_WRITECMD_OFFSET] */
563 0x04, 0x35, /* adds r5, #4 */
564 0x04, 0x34, /* adds r4, #4 */
567 0xc6, 0x69, /* ldr r6, [r0, #EFM32_MSC_STATUS_OFFSET] */
568 0x01, 0x27, /* movs r7, #1 */
569 0x3e, 0x42, /* tst r6, r7 */
570 0xfb, 0xd1, /* bne busy */
572 0x9d, 0x42, /* cmp r5, r3 */
573 0x01, 0xd3, /* bcc no_wrap */
574 0x15, 0x46, /* mov r5, r2 */
575 0x08, 0x35, /* adds r5, #8 */
578 0x55, 0x60, /* str r5, [r2, #4] */
579 0x01, 0x39, /* subs r1, r1, #1 */
580 0x00, 0x29, /* cmp r1, #0 */
581 0x02, 0xd0, /* beq exit */
582 0xdb, 0xe7, /* b wait_fifo */
585 0x00, 0x20, /* movs r0, #0 */
586 0x50, 0x60, /* str r0, [r2, #4] */
589 0x30, 0x46, /* mov r0, r6 */
590 0x00, 0xbe, /* bkpt #0 */
593 0x71, 0x1b, 0x00, 0x00
596 /* flash write code */
597 if (target_alloc_working_area(target
, sizeof(efm32x_flash_write_code
),
598 &write_algorithm
) != ERROR_OK
) {
599 LOG_WARNING("no working area available, can't do block memory writes");
600 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
603 ret
= target_write_buffer(target
, write_algorithm
->address
,
604 sizeof(efm32x_flash_write_code
), efm32x_flash_write_code
);
609 while (target_alloc_working_area_try(target
, buffer_size
, &source
) != ERROR_OK
) {
611 buffer_size
&= ~3UL; /* Make sure it's 4 byte aligned */
612 if (buffer_size
<= 256) {
613 /* we already allocated the writing code, but failed to get a
614 * buffer, free the algorithm */
615 target_free_working_area(target
, write_algorithm
);
617 LOG_WARNING("no large enough working area available, can't do block memory writes");
618 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
622 init_reg_param(®_params
[0], "r0", 32, PARAM_IN_OUT
); /* flash base (in), status (out) */
623 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
); /* count (word-32bit) */
624 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
); /* buffer start */
625 init_reg_param(®_params
[3], "r3", 32, PARAM_OUT
); /* buffer end */
626 init_reg_param(®_params
[4], "r4", 32, PARAM_IN_OUT
); /* target address */
628 buf_set_u32(reg_params
[0].value
, 0, 32, EFM32_MSC_REGBASE
);
629 buf_set_u32(reg_params
[1].value
, 0, 32, count
);
630 buf_set_u32(reg_params
[2].value
, 0, 32, source
->address
);
631 buf_set_u32(reg_params
[3].value
, 0, 32, source
->address
+ source
->size
);
632 buf_set_u32(reg_params
[4].value
, 0, 32, address
);
634 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
635 armv7m_info
.core_mode
= ARM_MODE_THREAD
;
637 ret
= target_run_flash_async_algorithm(target
, buf
, count
, 4,
640 source
->address
, source
->size
,
641 write_algorithm
->address
, 0,
644 if (ret
== ERROR_FLASH_OPERATION_FAILED
) {
645 LOG_ERROR("flash write failed at address 0x%"PRIx32
,
646 buf_get_u32(reg_params
[4].value
, 0, 32));
648 if (buf_get_u32(reg_params
[0].value
, 0, 32) &
649 EFM32_MSC_STATUS_LOCKED_MASK
) {
650 LOG_ERROR("flash memory write protected");
653 if (buf_get_u32(reg_params
[0].value
, 0, 32) &
654 EFM32_MSC_STATUS_INVADDR_MASK
) {
655 LOG_ERROR("invalid flash memory write address");
659 target_free_working_area(target
, source
);
660 target_free_working_area(target
, write_algorithm
);
662 destroy_reg_param(®_params
[0]);
663 destroy_reg_param(®_params
[1]);
664 destroy_reg_param(®_params
[2]);
665 destroy_reg_param(®_params
[3]);
666 destroy_reg_param(®_params
[4]);
671 static int efm32x_write_word(struct flash_bank
*bank
, uint32_t addr
,
674 /* this function DOES NOT set WREN; must be set already */
675 /* 1. write address to ADDRB
677 3. check status (INVADDR, LOCKED)
678 4. wait for WDATAREADY
679 5. write data to WDATA
680 6. write WRITECMD_WRITEONCE to WRITECMD
681 7. wait until !STATUS_BUSY
684 /* FIXME: EFM32G ref states (7.3.2) that writes should be
685 * performed twice per dword */
690 /* if not called, GDB errors will be reported during large writes */
693 ret
= target_write_u32(bank
->target
, EFM32_MSC_ADDRB
, addr
);
697 ret
= efm32x_set_reg_bits(bank
, EFM32_MSC_WRITECMD
,
698 EFM32_MSC_WRITECMD_LADDRIM_MASK
, 1);
702 ret
= target_read_u32(bank
->target
, EFM32_MSC_STATUS
, &status
);
706 LOG_DEBUG("status 0x%" PRIx32
, status
);
708 if (status
& EFM32_MSC_STATUS_LOCKED_MASK
) {
709 LOG_ERROR("Page is locked");
711 } else if (status
& EFM32_MSC_STATUS_INVADDR_MASK
) {
712 LOG_ERROR("Invalid address 0x%" PRIx32
, addr
);
716 ret
= efm32x_wait_status(bank
, EFM32_FLASH_WDATAREADY_TMO
,
717 EFM32_MSC_STATUS_WDATAREADY_MASK
, 1);
718 if (ERROR_OK
!= ret
) {
719 LOG_ERROR("Wait for WDATAREADY failed");
723 ret
= target_write_u32(bank
->target
, EFM32_MSC_WDATA
, val
);
724 if (ERROR_OK
!= ret
) {
725 LOG_ERROR("WDATA write failed");
729 ret
= target_write_u32(bank
->target
, EFM32_MSC_WRITECMD
,
730 EFM32_MSC_WRITECMD_WRITEONCE_MASK
);
731 if (ERROR_OK
!= ret
) {
732 LOG_ERROR("WRITECMD write failed");
736 ret
= efm32x_wait_status(bank
, EFM32_FLASH_WRITE_TMO
,
737 EFM32_MSC_STATUS_BUSY_MASK
, 0);
738 if (ERROR_OK
!= ret
) {
739 LOG_ERROR("Wait for BUSY failed");
746 static int efm32x_write(struct flash_bank
*bank
, const uint8_t *buffer
,
747 uint32_t offset
, uint32_t count
)
749 struct target
*target
= bank
->target
;
750 uint8_t *new_buffer
= NULL
;
752 if (target
->state
!= TARGET_HALTED
) {
753 LOG_ERROR("Target not halted");
754 return ERROR_TARGET_NOT_HALTED
;
758 LOG_ERROR("offset 0x%" PRIx32
" breaks required 4-byte "
759 "alignment", offset
);
760 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
764 uint32_t old_count
= count
;
765 count
= (old_count
| 3) + 1;
766 new_buffer
= malloc(count
);
767 if (new_buffer
== NULL
) {
768 LOG_ERROR("odd number of bytes to write and no memory "
769 "for padding buffer");
772 LOG_INFO("odd number of bytes to write (%" PRIu32
"), extending to %" PRIu32
" "
773 "and padding with 0xff", old_count
, count
);
774 memset(new_buffer
, 0xff, count
);
775 buffer
= memcpy(new_buffer
, buffer
, old_count
);
778 uint32_t words_remaining
= count
/ 4;
781 /* unlock flash registers */
782 efm32x_msc_lock(bank
, 0);
783 retval
= efm32x_set_wren(bank
, 1);
784 if (retval
!= ERROR_OK
)
787 /* try using a block write */
788 retval
= efm32x_write_block(bank
, buffer
, offset
, words_remaining
);
790 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
) {
791 /* if block write failed (no sufficient working area),
792 * we use normal (slow) single word accesses */
793 LOG_WARNING("couldn't use block writes, falling back to single "
796 while (words_remaining
> 0) {
798 memcpy(&value
, buffer
, sizeof(uint32_t));
800 retval
= efm32x_write_word(bank
, offset
, value
);
801 if (retval
!= ERROR_OK
)
802 goto reset_pg_and_lock
;
811 retval2
= efm32x_set_wren(bank
, 0);
812 efm32x_msc_lock(bank
, 1);
813 if (retval
== ERROR_OK
)
823 static int efm32x_probe(struct flash_bank
*bank
)
825 struct efm32x_flash_bank
*efm32x_info
= bank
->driver_priv
;
826 struct efm32_info efm32_mcu_info
;
829 uint32_t base_address
= 0x00000000;
831 efm32x_info
->probed
= 0;
832 memset(efm32x_info
->lb_page
, 0xff, LOCKBITS_PAGE_SZ
);
834 ret
= efm32x_read_info(bank
, &efm32_mcu_info
);
838 switch (efm32_mcu_info
.part_family
) {
839 case EFM_FAMILY_ID_GECKO
:
840 LOG_INFO("Gecko MCU detected");
842 case EFM_FAMILY_ID_GIANT_GECKO
:
843 LOG_INFO("Giant Gecko MCU detected");
845 case EFM_FAMILY_ID_TINY_GECKO
:
846 LOG_INFO("Tiny Gecko MCU detected");
848 case EFM_FAMILY_ID_LEOPARD_GECKO
:
849 LOG_INFO("Leopard Gecko MCU detected");
851 case EFM_FAMILY_ID_WONDER_GECKO
:
852 LOG_INFO("Wonder Gecko MCU detected");
854 case EFM_FAMILY_ID_ZERO_GECKO
:
855 LOG_INFO("Zero Gecko MCU detected");
858 LOG_ERROR("Unsupported MCU family %d",
859 efm32_mcu_info
.part_family
);
863 LOG_INFO("flash size = %dkbytes", efm32_mcu_info
.flash_sz_kib
);
864 LOG_INFO("flash page size = %dbytes", efm32_mcu_info
.page_size
);
866 assert(0 != efm32_mcu_info
.page_size
);
868 int num_pages
= efm32_mcu_info
.flash_sz_kib
* 1024 /
869 efm32_mcu_info
.page_size
;
871 assert(num_pages
> 0);
875 bank
->sectors
= NULL
;
878 bank
->base
= base_address
;
879 bank
->size
= (num_pages
* efm32_mcu_info
.page_size
);
880 bank
->num_sectors
= num_pages
;
882 ret
= efm32x_read_lock_data(bank
);
883 if (ERROR_OK
!= ret
) {
884 LOG_ERROR("Failed to read LB data");
888 bank
->sectors
= malloc(sizeof(struct flash_sector
) * num_pages
);
890 for (i
= 0; i
< num_pages
; i
++) {
891 bank
->sectors
[i
].offset
= i
* efm32_mcu_info
.page_size
;
892 bank
->sectors
[i
].size
= efm32_mcu_info
.page_size
;
893 bank
->sectors
[i
].is_erased
= -1;
894 bank
->sectors
[i
].is_protected
= 1;
897 efm32x_info
->probed
= 1;
902 static int efm32x_auto_probe(struct flash_bank
*bank
)
904 struct efm32x_flash_bank
*efm32x_info
= bank
->driver_priv
;
905 if (efm32x_info
->probed
)
907 return efm32x_probe(bank
);
910 static int efm32x_protect_check(struct flash_bank
*bank
)
912 struct target
*target
= bank
->target
;
916 if (target
->state
!= TARGET_HALTED
) {
917 LOG_ERROR("Target not halted");
918 return ERROR_TARGET_NOT_HALTED
;
921 ret
= efm32x_read_lock_data(bank
);
922 if (ERROR_OK
!= ret
) {
923 LOG_ERROR("Failed to read LB data");
927 assert(NULL
!= bank
->sectors
);
929 for (i
= 0; i
< bank
->num_sectors
; i
++)
930 bank
->sectors
[i
].is_protected
= efm32x_get_page_lock(bank
, i
);
935 static int get_efm32x_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
937 struct efm32_info info
;
941 ret
= efm32x_read_info(bank
, &info
);
942 if (ERROR_OK
!= ret
) {
943 LOG_ERROR("Failed to read EFM32 info");
947 printed
= snprintf(buf
, buf_size
, "EFM32 ");
952 return ERROR_BUF_TOO_SMALL
;
954 switch (info
.part_family
) {
955 case EFM_FAMILY_ID_GECKO
:
956 printed
= snprintf(buf
, buf_size
, "Gecko");
958 case EFM_FAMILY_ID_GIANT_GECKO
:
959 printed
= snprintf(buf
, buf_size
, "Giant Gecko");
961 case EFM_FAMILY_ID_TINY_GECKO
:
962 printed
= snprintf(buf
, buf_size
, "Tiny Gecko");
964 case EFM_FAMILY_ID_LEOPARD_GECKO
:
965 printed
= snprintf(buf
, buf_size
, "Leopard Gecko");
967 case EFM_FAMILY_ID_WONDER_GECKO
:
968 printed
= snprintf(buf
, buf_size
, "Wonder Gecko");
970 case EFM_FAMILY_ID_ZERO_GECKO
:
971 printed
= snprintf(buf
, buf_size
, "Zero Gecko");
979 return ERROR_BUF_TOO_SMALL
;
981 printed
= snprintf(buf
, buf_size
, " - Rev: %d", info
.prod_rev
);
986 return ERROR_BUF_TOO_SMALL
;
991 static const struct command_registration efm32x_exec_command_handlers
[] = {
992 COMMAND_REGISTRATION_DONE
995 static const struct command_registration efm32x_command_handlers
[] = {
999 .help
= "efm32 flash command group",
1001 .chain
= efm32x_exec_command_handlers
,
1003 COMMAND_REGISTRATION_DONE
1006 struct flash_driver efm32_flash
= {
1008 .commands
= efm32x_command_handlers
,
1009 .flash_bank_command
= efm32x_flash_bank_command
,
1010 .erase
= efm32x_erase
,
1011 .protect
= efm32x_protect
,
1012 .write
= efm32x_write
,
1013 .read
= default_flash_read
,
1014 .probe
= efm32x_probe
,
1015 .auto_probe
= efm32x_auto_probe
,
1016 .erase_check
= default_flash_blank_check
,
1017 .protect_check
= efm32x_protect_check
,
1018 .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)