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 * This program is free software; you can redistribute it and/or modify *
15 * it under the terms of the GNU General Public License as published by *
16 * the Free Software Foundation; either version 2 of the License, or *
17 * (at your option) any later version. *
19 * This program is distributed in the hope that it will be useful, *
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
22 * GNU General Public License for more details. *
24 * You should have received a copy of the GNU General Public License *
25 * along with this program; if not, write to the *
26 * Free Software Foundation, Inc., *
27 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
28 ***************************************************************************/
35 #include <helper/binarybuffer.h>
36 #include <target/algorithm.h>
37 #include <target/armv7m.h>
38 #include <target/cortex_m.h>
40 /* keep family IDs in decimal */
41 #define EFM_FAMILY_ID_GECKO 71
42 #define EFM_FAMILY_ID_GIANT_GECKO 72
43 #define EFM_FAMILY_ID_TINY_GECKO 73
44 #define EFM_FAMILY_ID_LEOPARD_GECKO 74
45 #define EFM_FAMILY_ID_WONDER_GECKO 75
47 #define EFM32_FLASH_ERASE_TMO 100
48 #define EFM32_FLASH_WDATAREADY_TMO 100
49 #define EFM32_FLASH_WRITE_TMO 100
51 /* size in bytes, not words; must fit all Gecko devices */
52 #define LOCKBITS_PAGE_SZ 512
54 #define EFM32_MSC_INFO_BASE 0x0fe00000
56 #define EFM32_MSC_USER_DATA EFM32_MSC_INFO_BASE
57 #define EFM32_MSC_LOCK_BITS (EFM32_MSC_INFO_BASE+0x4000)
58 #define EFM32_MSC_DEV_INFO (EFM32_MSC_INFO_BASE+0x8000)
60 /* PAGE_SIZE is only present in Leopard and Giant Gecko MCUs */
61 #define EFM32_MSC_DI_PAGE_SIZE (EFM32_MSC_DEV_INFO+0x1e7)
62 #define EFM32_MSC_DI_FLASH_SZ (EFM32_MSC_DEV_INFO+0x1f8)
63 #define EFM32_MSC_DI_RAM_SZ (EFM32_MSC_DEV_INFO+0x1fa)
64 #define EFM32_MSC_DI_PART_NUM (EFM32_MSC_DEV_INFO+0x1fc)
65 #define EFM32_MSC_DI_PART_FAMILY (EFM32_MSC_DEV_INFO+0x1fe)
66 #define EFM32_MSC_DI_PROD_REV (EFM32_MSC_DEV_INFO+0x1ff)
68 #define EFM32_MSC_REGBASE 0x400c0000
69 #define EFM32_MSC_WRITECTRL (EFM32_MSC_REGBASE+0x008)
70 #define EFM32_MSC_WRITECTRL_WREN_MASK 0x1
71 #define EFM32_MSC_WRITECMD (EFM32_MSC_REGBASE+0x00c)
72 #define EFM32_MSC_WRITECMD_LADDRIM_MASK 0x1
73 #define EFM32_MSC_WRITECMD_ERASEPAGE_MASK 0x2
74 #define EFM32_MSC_WRITECMD_WRITEONCE_MASK 0x8
75 #define EFM32_MSC_ADDRB (EFM32_MSC_REGBASE+0x010)
76 #define EFM32_MSC_WDATA (EFM32_MSC_REGBASE+0x018)
77 #define EFM32_MSC_STATUS (EFM32_MSC_REGBASE+0x01c)
78 #define EFM32_MSC_STATUS_BUSY_MASK 0x1
79 #define EFM32_MSC_STATUS_LOCKED_MASK 0x2
80 #define EFM32_MSC_STATUS_INVADDR_MASK 0x4
81 #define EFM32_MSC_STATUS_WDATAREADY_MASK 0x8
82 #define EFM32_MSC_STATUS_WORDTIMEOUT_MASK 0x10
83 #define EFM32_MSC_STATUS_ERASEABORTED_MASK 0x20
84 #define EFM32_MSC_LOCK (EFM32_MSC_REGBASE+0x03c)
85 #define EFM32_MSC_LOCK_LOCKKEY 0x1b71
87 struct efm32x_flash_bank
{
89 uint32_t lb_page
[LOCKBITS_PAGE_SZ
/4];
93 uint16_t flash_sz_kib
;
101 static int efm32x_write(struct flash_bank
*bank
, uint8_t *buffer
,
102 uint32_t offset
, uint32_t count
);
104 static int efm32x_get_flash_size(struct flash_bank
*bank
, uint16_t *flash_sz
)
106 return target_read_u16(bank
->target
, EFM32_MSC_DI_FLASH_SZ
, flash_sz
);
109 static int efm32x_get_ram_size(struct flash_bank
*bank
, uint16_t *ram_sz
)
111 return target_read_u16(bank
->target
, EFM32_MSC_DI_RAM_SZ
, ram_sz
);
114 static int efm32x_get_part_num(struct flash_bank
*bank
, uint16_t *pnum
)
116 return target_read_u16(bank
->target
, EFM32_MSC_DI_PART_NUM
, pnum
);
119 static int efm32x_get_part_family(struct flash_bank
*bank
, uint8_t *pfamily
)
121 return target_read_u8(bank
->target
, EFM32_MSC_DI_PART_FAMILY
, pfamily
);
124 static int efm32x_get_prod_rev(struct flash_bank
*bank
, uint8_t *prev
)
126 return target_read_u8(bank
->target
, EFM32_MSC_DI_PROD_REV
, prev
);
129 static int efm32x_read_info(struct flash_bank
*bank
,
130 struct efm32_info
*efm32_info
)
135 memset(efm32_info
, 0, sizeof(struct efm32_info
));
137 ret
= target_read_u32(bank
->target
, CPUID
, &cpuid
);
141 if (((cpuid
>> 4) & 0xfff) == 0xc23) {
142 /* Cortex M3 device */
143 } else if (((cpuid
>> 4) & 0xfff) == 0xc24) {
144 /* Cortex M4 device */
146 LOG_ERROR("Target is not CortexM3 or M4");
150 ret
= efm32x_get_flash_size(bank
, &(efm32_info
->flash_sz_kib
));
154 ret
= efm32x_get_ram_size(bank
, &(efm32_info
->ram_sz_kib
));
158 ret
= efm32x_get_part_num(bank
, &(efm32_info
->part_num
));
162 ret
= efm32x_get_part_family(bank
, &(efm32_info
->part_family
));
166 ret
= efm32x_get_prod_rev(bank
, &(efm32_info
->prod_rev
));
170 if (EFM_FAMILY_ID_GECKO
== efm32_info
->part_family
||
171 EFM_FAMILY_ID_TINY_GECKO
== efm32_info
->part_family
)
172 efm32_info
->page_size
= 512;
173 else if (EFM_FAMILY_ID_GIANT_GECKO
== efm32_info
->part_family
||
174 EFM_FAMILY_ID_LEOPARD_GECKO
== efm32_info
->part_family
) {
175 if (efm32_info
->prod_rev
>= 18) {
177 ret
= target_read_u8(bank
->target
, EFM32_MSC_DI_PAGE_SIZE
,
182 efm32_info
->page_size
= (1 << ((pg_size
+10) & 0xff));
184 /* EFM32 GG/LG errata: MEM_INFO_PAGE_SIZE is invalid
185 for MCUs with PROD_REV < 18 */
186 if (efm32_info
->flash_sz_kib
< 512)
187 efm32_info
->page_size
= 2048;
189 efm32_info
->page_size
= 4096;
192 if ((2048 != efm32_info
->page_size
) &&
193 (4096 != efm32_info
->page_size
)) {
194 LOG_ERROR("Invalid page size %u", efm32_info
->page_size
);
197 } else if (EFM_FAMILY_ID_WONDER_GECKO
== efm32_info
->part_family
) {
199 ret
= target_read_u8(bank
->target
, EFM32_MSC_DI_PAGE_SIZE
,
204 efm32_info
->page_size
= (1 << ((pg_size
+10) & 0xff));
205 if (2048 != efm32_info
->page_size
) {
206 LOG_ERROR("Invalid page size %u", efm32_info
->page_size
);
210 LOG_ERROR("Unknown MCU family %d", efm32_info
->part_family
);
217 /* flash bank efm32 <base> <size> 0 0 <target#>
219 FLASH_BANK_COMMAND_HANDLER(efm32x_flash_bank_command
)
221 struct efm32x_flash_bank
*efm32x_info
;
224 return ERROR_COMMAND_SYNTAX_ERROR
;
226 efm32x_info
= malloc(sizeof(struct efm32x_flash_bank
));
228 bank
->driver_priv
= efm32x_info
;
229 efm32x_info
->probed
= 0;
230 memset(efm32x_info
->lb_page
, 0xff, LOCKBITS_PAGE_SZ
);
235 /* set or reset given bits in a register */
236 static int efm32x_set_reg_bits(struct flash_bank
*bank
, uint32_t reg
,
237 uint32_t bitmask
, int set
)
240 uint32_t reg_val
= 0;
242 ret
= target_read_u32(bank
->target
, reg
, ®_val
);
251 return target_write_u32(bank
->target
, reg
, reg_val
);
254 static int efm32x_set_wren(struct flash_bank
*bank
, int write_enable
)
256 return efm32x_set_reg_bits(bank
, EFM32_MSC_WRITECTRL
,
257 EFM32_MSC_WRITECTRL_WREN_MASK
, write_enable
);
260 static int efm32x_msc_lock(struct flash_bank
*bank
, int lock
)
262 return target_write_u32(bank
->target
, EFM32_MSC_LOCK
,
263 (lock
? 0 : EFM32_MSC_LOCK_LOCKKEY
));
266 static int efm32x_wait_status(struct flash_bank
*bank
, int timeout
,
267 uint32_t wait_mask
, int wait_for_set
)
273 ret
= target_read_u32(bank
->target
, EFM32_MSC_STATUS
, &status
);
277 LOG_DEBUG("status: 0x%" PRIx32
"", status
);
279 if (((status
& wait_mask
) == 0) && (0 == wait_for_set
))
281 else if (((status
& wait_mask
) != 0) && wait_for_set
)
284 if (timeout
-- <= 0) {
285 LOG_ERROR("timed out waiting for MSC status");
292 if (status
& EFM32_MSC_STATUS_ERASEABORTED_MASK
)
293 LOG_WARNING("page erase was aborted");
298 static int efm32x_erase_page(struct flash_bank
*bank
, uint32_t addr
)
300 /* this function DOES NOT set WREN; must be set already */
301 /* 1. write address to ADDRB
303 3. check status (INVADDR, LOCKED)
305 5. wait until !STATUS_BUSY
310 LOG_DEBUG("erasing flash page at 0x%08" PRIx32
, addr
);
312 ret
= target_write_u32(bank
->target
, EFM32_MSC_ADDRB
, addr
);
316 ret
= efm32x_set_reg_bits(bank
, EFM32_MSC_WRITECMD
,
317 EFM32_MSC_WRITECMD_LADDRIM_MASK
, 1);
321 ret
= target_read_u32(bank
->target
, EFM32_MSC_STATUS
, &status
);
325 LOG_DEBUG("status 0x%" PRIx32
, status
);
327 if (status
& EFM32_MSC_STATUS_LOCKED_MASK
) {
328 LOG_ERROR("Page is locked");
330 } else if (status
& EFM32_MSC_STATUS_INVADDR_MASK
) {
331 LOG_ERROR("Invalid address 0x%" PRIx32
, addr
);
335 ret
= efm32x_set_reg_bits(bank
, EFM32_MSC_WRITECMD
,
336 EFM32_MSC_WRITECMD_ERASEPAGE_MASK
, 1);
340 return efm32x_wait_status(bank
, EFM32_FLASH_ERASE_TMO
,
341 EFM32_MSC_STATUS_BUSY_MASK
, 0);
344 static int efm32x_erase(struct flash_bank
*bank
, int first
, int last
)
346 struct target
*target
= bank
->target
;
350 if (TARGET_HALTED
!= target
->state
) {
351 LOG_ERROR("Target not halted");
352 return ERROR_TARGET_NOT_HALTED
;
355 efm32x_msc_lock(bank
, 0);
356 ret
= efm32x_set_wren(bank
, 1);
357 if (ERROR_OK
!= ret
) {
358 LOG_ERROR("Failed to enable MSC write");
362 for (i
= first
; i
<= last
; i
++) {
363 ret
= efm32x_erase_page(bank
, bank
->sectors
[i
].offset
);
365 LOG_ERROR("Failed to erase page %d", i
);
368 ret
= efm32x_set_wren(bank
, 0);
369 efm32x_msc_lock(bank
, 1);
374 static int efm32x_read_lock_data(struct flash_bank
*bank
)
376 struct efm32x_flash_bank
*efm32x_info
= bank
->driver_priv
;
377 struct target
*target
= bank
->target
;
380 uint32_t *ptr
= NULL
;
383 assert(!(bank
->num_sectors
& 0x1f));
385 data_size
= bank
->num_sectors
/ 8; /* number of data bytes */
386 data_size
/= 4; /* ...and data dwords */
388 ptr
= efm32x_info
->lb_page
;
390 for (i
= 0; i
< data_size
; i
++, ptr
++) {
391 ret
= target_read_u32(target
, EFM32_MSC_LOCK_BITS
+i
*4, ptr
);
392 if (ERROR_OK
!= ret
) {
393 LOG_ERROR("Failed to read PLW %d", i
);
398 /* also, read ULW, DLW and MLW */
401 ptr
= efm32x_info
->lb_page
+ 126;
402 ret
= target_read_u32(target
, EFM32_MSC_LOCK_BITS
+126*4, ptr
);
403 if (ERROR_OK
!= ret
) {
404 LOG_ERROR("Failed to read ULW");
409 ptr
= efm32x_info
->lb_page
+ 127;
410 ret
= target_read_u32(target
, EFM32_MSC_LOCK_BITS
+127*4, ptr
);
411 if (ERROR_OK
!= ret
) {
412 LOG_ERROR("Failed to read DLW");
416 /* MLW, word 125, present in GG and LG */
417 ptr
= efm32x_info
->lb_page
+ 125;
418 ret
= target_read_u32(target
, EFM32_MSC_LOCK_BITS
+125*4, ptr
);
419 if (ERROR_OK
!= ret
) {
420 LOG_ERROR("Failed to read MLW");
427 static int efm32x_write_lock_data(struct flash_bank
*bank
)
429 struct efm32x_flash_bank
*efm32x_info
= bank
->driver_priv
;
432 ret
= efm32x_erase_page(bank
, EFM32_MSC_LOCK_BITS
);
433 if (ERROR_OK
!= ret
) {
434 LOG_ERROR("Failed to erase LB page");
438 return efm32x_write(bank
, (uint8_t *)efm32x_info
->lb_page
, EFM32_MSC_LOCK_BITS
,
442 static int efm32x_get_page_lock(struct flash_bank
*bank
, size_t page
)
444 struct efm32x_flash_bank
*efm32x_info
= bank
->driver_priv
;
445 uint32_t dw
= efm32x_info
->lb_page
[page
>> 5];
448 mask
= 1 << (page
& 0x1f);
450 return (dw
& mask
) ? 0 : 1;
453 static int efm32x_set_page_lock(struct flash_bank
*bank
, size_t page
, int set
)
455 struct efm32x_flash_bank
*efm32x_info
= bank
->driver_priv
;
456 uint32_t *dw
= &efm32x_info
->lb_page
[page
>> 5];
459 mask
= 1 << (page
& 0x1f);
469 static int efm32x_protect(struct flash_bank
*bank
, int set
, int first
, int last
)
471 struct target
*target
= bank
->target
;
476 LOG_ERROR("Erase device data to reset page locks");
480 if (target
->state
!= TARGET_HALTED
) {
481 LOG_ERROR("Target not halted");
482 return ERROR_TARGET_NOT_HALTED
;
485 for (i
= first
; i
<= last
; i
++) {
486 ret
= efm32x_set_page_lock(bank
, i
, set
);
487 if (ERROR_OK
!= ret
) {
488 LOG_ERROR("Failed to set lock on page %d", i
);
493 ret
= efm32x_write_lock_data(bank
);
494 if (ERROR_OK
!= ret
) {
495 LOG_ERROR("Failed to write LB page");
502 static int efm32x_write_block(struct flash_bank
*bank
, uint8_t *buf
,
503 uint32_t offset
, uint32_t count
)
505 struct target
*target
= bank
->target
;
506 uint32_t buffer_size
= 16384;
507 struct working_area
*write_algorithm
;
508 struct working_area
*source
;
509 uint32_t address
= bank
->base
+ offset
;
510 struct reg_param reg_params
[5];
511 struct armv7m_algorithm armv7m_info
;
514 /* see contrib/loaders/flash/efm32.S for src */
515 static const uint8_t efm32x_flash_write_code
[] = {
516 /* #define EFM32_MSC_WRITECTRL_OFFSET 0x008 */
517 /* #define EFM32_MSC_WRITECMD_OFFSET 0x00c */
518 /* #define EFM32_MSC_ADDRB_OFFSET 0x010 */
519 /* #define EFM32_MSC_WDATA_OFFSET 0x018 */
520 /* #define EFM32_MSC_STATUS_OFFSET 0x01c */
521 /* #define EFM32_MSC_LOCK_OFFSET 0x03c */
523 0x15, 0x4e, /* ldr r6, =#0x1b71 */
524 0xc6, 0x63, /* str r6, [r0, #EFM32_MSC_LOCK_OFFSET] */
525 0x01, 0x26, /* movs r6, #1 */
526 0x86, 0x60, /* str r6, [r0, #EFM32_MSC_WRITECTRL_OFFSET] */
529 0x16, 0x68, /* ldr r6, [r2, #0] */
530 0x00, 0x2e, /* cmp r6, #0 */
531 0x22, 0xd0, /* beq exit */
532 0x55, 0x68, /* ldr r5, [r2, #4] */
533 0xb5, 0x42, /* cmp r5, r6 */
534 0xf9, 0xd0, /* beq wait_fifo */
536 0x04, 0x61, /* str r4, [r0, #EFM32_MSC_ADDRB_OFFSET] */
537 0x01, 0x26, /* movs r6, #1 */
538 0xc6, 0x60, /* str r6, [r0, #EFM32_MSC_WRITECMD_OFFSET] */
539 0xc6, 0x69, /* ldr r6, [r0, #EFM32_MSC_STATUS_OFFSET] */
540 0x06, 0x27, /* movs r7, #6 */
541 0x3e, 0x42, /* tst r6, r7 */
542 0x16, 0xd1, /* bne error */
544 /* wait_wdataready: */
545 0xc6, 0x69, /* ldr r6, [r0, #EFM32_MSC_STATUS_OFFSET] */
546 0x08, 0x27, /* movs r7, #8 */
547 0x3e, 0x42, /* tst r6, r7 */
548 0xfb, 0xd0, /* beq wait_wdataready */
550 0x2e, 0x68, /* ldr r6, [r5] */
551 0x86, 0x61, /* str r6, [r0, #EFM32_MSC_WDATA_OFFSET] */
552 0x08, 0x26, /* movs r6, #8 */
553 0xc6, 0x60, /* str r6, [r0, #EFM32_MSC_WRITECMD_OFFSET] */
555 0x04, 0x35, /* adds r5, #4 */
556 0x04, 0x34, /* adds r4, #4 */
559 0xc6, 0x69, /* ldr r6, [r0, #EFM32_MSC_STATUS_OFFSET] */
560 0x01, 0x27, /* movs r7, #1 */
561 0x3e, 0x42, /* tst r6, r7 */
562 0xfb, 0xd1, /* bne busy */
564 0x9d, 0x42, /* cmp r5, r3 */
565 0x01, 0xd3, /* bcc no_wrap */
566 0x15, 0x46, /* mov r5, r2 */
567 0x08, 0x35, /* adds r5, #8 */
570 0x55, 0x60, /* str r5, [r2, #4] */
571 0x01, 0x39, /* subs r1, r1, #1 */
572 0x00, 0x29, /* cmp r1, #0 */
573 0x02, 0xd0, /* beq exit */
574 0xdb, 0xe7, /* b wait_fifo */
577 0x00, 0x20, /* movs r0, #0 */
578 0x50, 0x60, /* str r0, [r2, #4] */
581 0x30, 0x46, /* mov r0, r6 */
582 0x00, 0xbe, /* bkpt #0 */
585 0x71, 0x1b, 0x00, 0x00
588 /* flash write code */
589 if (target_alloc_working_area(target
, sizeof(efm32x_flash_write_code
),
590 &write_algorithm
) != ERROR_OK
) {
591 LOG_WARNING("no working area available, can't do block memory writes");
592 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
595 ret
= target_write_buffer(target
, write_algorithm
->address
,
596 sizeof(efm32x_flash_write_code
), efm32x_flash_write_code
);
601 while (target_alloc_working_area_try(target
, buffer_size
, &source
) != ERROR_OK
) {
603 buffer_size
&= ~3UL; /* Make sure it's 4 byte aligned */
604 if (buffer_size
<= 256) {
605 /* we already allocated the writing code, but failed to get a
606 * buffer, free the algorithm */
607 target_free_working_area(target
, write_algorithm
);
609 LOG_WARNING("no large enough working area available, can't do block memory writes");
610 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
614 init_reg_param(®_params
[0], "r0", 32, PARAM_IN_OUT
); /* flash base (in), status (out) */
615 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
); /* count (word-32bit) */
616 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
); /* buffer start */
617 init_reg_param(®_params
[3], "r3", 32, PARAM_OUT
); /* buffer end */
618 init_reg_param(®_params
[4], "r4", 32, PARAM_IN_OUT
); /* target address */
620 buf_set_u32(reg_params
[0].value
, 0, 32, EFM32_MSC_REGBASE
);
621 buf_set_u32(reg_params
[1].value
, 0, 32, count
);
622 buf_set_u32(reg_params
[2].value
, 0, 32, source
->address
);
623 buf_set_u32(reg_params
[3].value
, 0, 32, source
->address
+ source
->size
);
624 buf_set_u32(reg_params
[4].value
, 0, 32, address
);
626 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
627 armv7m_info
.core_mode
= ARM_MODE_THREAD
;
629 ret
= target_run_flash_async_algorithm(target
, buf
, count
, 4,
632 source
->address
, source
->size
,
633 write_algorithm
->address
, 0,
636 if (ret
== ERROR_FLASH_OPERATION_FAILED
) {
637 LOG_ERROR("flash write failed at address 0x%"PRIx32
,
638 buf_get_u32(reg_params
[4].value
, 0, 32));
640 if (buf_get_u32(reg_params
[0].value
, 0, 32) &
641 EFM32_MSC_STATUS_LOCKED_MASK
) {
642 LOG_ERROR("flash memory write protected");
645 if (buf_get_u32(reg_params
[0].value
, 0, 32) &
646 EFM32_MSC_STATUS_INVADDR_MASK
) {
647 LOG_ERROR("invalid flash memory write address");
651 target_free_working_area(target
, source
);
652 target_free_working_area(target
, write_algorithm
);
654 destroy_reg_param(®_params
[0]);
655 destroy_reg_param(®_params
[1]);
656 destroy_reg_param(®_params
[2]);
657 destroy_reg_param(®_params
[3]);
658 destroy_reg_param(®_params
[4]);
663 static int efm32x_write_word(struct flash_bank
*bank
, uint32_t addr
,
666 /* this function DOES NOT set WREN; must be set already */
667 /* 1. write address to ADDRB
669 3. check status (INVADDR, LOCKED)
670 4. wait for WDATAREADY
671 5. write data to WDATA
672 6. write WRITECMD_WRITEONCE to WRITECMD
673 7. wait until !STATUS_BUSY
676 /* FIXME: EFM32G ref states (7.3.2) that writes should be
677 * performed twice per dword */
682 /* if not called, GDB errors will be reported during large writes */
685 ret
= target_write_u32(bank
->target
, EFM32_MSC_ADDRB
, addr
);
689 ret
= efm32x_set_reg_bits(bank
, EFM32_MSC_WRITECMD
,
690 EFM32_MSC_WRITECMD_LADDRIM_MASK
, 1);
694 ret
= target_read_u32(bank
->target
, EFM32_MSC_STATUS
, &status
);
698 LOG_DEBUG("status 0x%" PRIx32
, status
);
700 if (status
& EFM32_MSC_STATUS_LOCKED_MASK
) {
701 LOG_ERROR("Page is locked");
703 } else if (status
& EFM32_MSC_STATUS_INVADDR_MASK
) {
704 LOG_ERROR("Invalid address 0x%" PRIx32
, addr
);
708 ret
= efm32x_wait_status(bank
, EFM32_FLASH_WDATAREADY_TMO
,
709 EFM32_MSC_STATUS_WDATAREADY_MASK
, 1);
710 if (ERROR_OK
!= ret
) {
711 LOG_ERROR("Wait for WDATAREADY failed");
715 ret
= target_write_u32(bank
->target
, EFM32_MSC_WDATA
, val
);
716 if (ERROR_OK
!= ret
) {
717 LOG_ERROR("WDATA write failed");
721 ret
= target_write_u32(bank
->target
, EFM32_MSC_WRITECMD
,
722 EFM32_MSC_WRITECMD_WRITEONCE_MASK
);
723 if (ERROR_OK
!= ret
) {
724 LOG_ERROR("WRITECMD write failed");
728 ret
= efm32x_wait_status(bank
, EFM32_FLASH_WRITE_TMO
,
729 EFM32_MSC_STATUS_BUSY_MASK
, 0);
730 if (ERROR_OK
!= ret
) {
731 LOG_ERROR("Wait for BUSY failed");
738 static int efm32x_write(struct flash_bank
*bank
, uint8_t *buffer
,
739 uint32_t offset
, uint32_t count
)
741 struct target
*target
= bank
->target
;
742 uint8_t *new_buffer
= NULL
;
744 if (target
->state
!= TARGET_HALTED
) {
745 LOG_ERROR("Target not halted");
746 return ERROR_TARGET_NOT_HALTED
;
750 LOG_ERROR("offset 0x%" PRIx32
" breaks required 4-byte "
751 "alignment", offset
);
752 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
756 uint32_t old_count
= count
;
757 count
= (old_count
| 3) + 1;
758 new_buffer
= malloc(count
);
759 if (new_buffer
== NULL
) {
760 LOG_ERROR("odd number of bytes to write and no memory "
761 "for padding buffer");
764 LOG_INFO("odd number of bytes to write (%" PRIu32
"), extending to %" PRIu32
" "
765 "and padding with 0xff", old_count
, count
);
766 memset(buffer
, 0xff, count
);
767 buffer
= memcpy(new_buffer
, buffer
, old_count
);
770 uint32_t words_remaining
= count
/ 4;
773 /* unlock flash registers */
774 efm32x_msc_lock(bank
, 0);
775 retval
= efm32x_set_wren(bank
, 1);
776 if (retval
!= ERROR_OK
)
779 /* try using a block write */
780 retval
= efm32x_write_block(bank
, buffer
, offset
, words_remaining
);
782 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
) {
783 /* if block write failed (no sufficient working area),
784 * we use normal (slow) single word accesses */
785 LOG_WARNING("couldn't use block writes, falling back to single "
788 while (words_remaining
> 0) {
790 memcpy(&value
, buffer
, sizeof(uint32_t));
792 retval
= efm32x_write_word(bank
, offset
, value
);
793 if (retval
!= ERROR_OK
)
794 goto reset_pg_and_lock
;
803 retval2
= efm32x_set_wren(bank
, 0);
804 efm32x_msc_lock(bank
, 1);
805 if (retval
== ERROR_OK
)
815 static int efm32x_probe(struct flash_bank
*bank
)
817 struct efm32x_flash_bank
*efm32x_info
= bank
->driver_priv
;
818 struct efm32_info efm32_mcu_info
;
821 uint32_t base_address
= 0x00000000;
823 efm32x_info
->probed
= 0;
824 memset(efm32x_info
->lb_page
, 0xff, LOCKBITS_PAGE_SZ
);
826 ret
= efm32x_read_info(bank
, &efm32_mcu_info
);
830 switch (efm32_mcu_info
.part_family
) {
831 case EFM_FAMILY_ID_GECKO
:
832 LOG_INFO("Gecko MCU detected");
834 case EFM_FAMILY_ID_GIANT_GECKO
:
835 LOG_INFO("Giant Gecko MCU detected");
837 case EFM_FAMILY_ID_TINY_GECKO
:
838 LOG_INFO("Tiny Gecko MCU detected");
840 case EFM_FAMILY_ID_LEOPARD_GECKO
:
841 LOG_INFO("Leopard Gecko MCU detected");
843 case EFM_FAMILY_ID_WONDER_GECKO
:
844 LOG_INFO("Wonder Gecko MCU detected");
847 LOG_ERROR("Unsupported MCU family %d",
848 efm32_mcu_info
.part_family
);
852 LOG_INFO("flash size = %dkbytes", efm32_mcu_info
.flash_sz_kib
);
853 LOG_INFO("flash page size = %dbytes", efm32_mcu_info
.page_size
);
855 assert(0 != efm32_mcu_info
.page_size
);
857 int num_pages
= efm32_mcu_info
.flash_sz_kib
* 1024 /
858 efm32_mcu_info
.page_size
;
860 assert(num_pages
> 0);
864 bank
->sectors
= NULL
;
867 bank
->base
= base_address
;
868 bank
->size
= (num_pages
* efm32_mcu_info
.page_size
);
869 bank
->num_sectors
= num_pages
;
871 ret
= efm32x_read_lock_data(bank
);
872 if (ERROR_OK
!= ret
) {
873 LOG_ERROR("Failed to read LB data");
877 bank
->sectors
= malloc(sizeof(struct flash_sector
) * num_pages
);
879 for (i
= 0; i
< num_pages
; i
++) {
880 bank
->sectors
[i
].offset
= i
* efm32_mcu_info
.page_size
;
881 bank
->sectors
[i
].size
= efm32_mcu_info
.page_size
;
882 bank
->sectors
[i
].is_erased
= -1;
883 bank
->sectors
[i
].is_protected
= 1;
886 efm32x_info
->probed
= 1;
891 static int efm32x_auto_probe(struct flash_bank
*bank
)
893 struct efm32x_flash_bank
*efm32x_info
= bank
->driver_priv
;
894 if (efm32x_info
->probed
)
896 return efm32x_probe(bank
);
899 static int efm32x_protect_check(struct flash_bank
*bank
)
901 struct target
*target
= bank
->target
;
905 if (target
->state
!= TARGET_HALTED
) {
906 LOG_ERROR("Target not halted");
907 return ERROR_TARGET_NOT_HALTED
;
910 ret
= efm32x_read_lock_data(bank
);
911 if (ERROR_OK
!= ret
) {
912 LOG_ERROR("Failed to read LB data");
916 assert(NULL
!= bank
->sectors
);
918 for (i
= 0; i
< bank
->num_sectors
; i
++)
919 bank
->sectors
[i
].is_protected
= efm32x_get_page_lock(bank
, i
);
924 static int get_efm32x_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
926 struct efm32_info info
;
930 ret
= efm32x_read_info(bank
, &info
);
931 if (ERROR_OK
!= ret
) {
932 LOG_ERROR("Failed to read EFM32 info");
936 printed
= snprintf(buf
, buf_size
, "EFM32 ");
941 return ERROR_BUF_TOO_SMALL
;
943 switch (info
.part_family
) {
944 case EFM_FAMILY_ID_GECKO
:
945 printed
= snprintf(buf
, buf_size
, "Gecko");
947 case EFM_FAMILY_ID_GIANT_GECKO
:
948 printed
= snprintf(buf
, buf_size
, "Giant Gecko");
950 case EFM_FAMILY_ID_TINY_GECKO
:
951 printed
= snprintf(buf
, buf_size
, "Tiny Gecko");
953 case EFM_FAMILY_ID_LEOPARD_GECKO
:
954 printed
= snprintf(buf
, buf_size
, "Leopard Gecko");
956 case EFM_FAMILY_ID_WONDER_GECKO
:
957 printed
= snprintf(buf
, buf_size
, "Wonder Gecko");
965 return ERROR_BUF_TOO_SMALL
;
967 printed
= snprintf(buf
, buf_size
, " - Rev: %d", info
.prod_rev
);
972 return ERROR_BUF_TOO_SMALL
;
977 static const struct command_registration efm32x_exec_command_handlers
[] = {
978 COMMAND_REGISTRATION_DONE
981 static const struct command_registration efm32x_command_handlers
[] = {
985 .help
= "efm32 flash command group",
987 .chain
= efm32x_exec_command_handlers
,
989 COMMAND_REGISTRATION_DONE
992 struct flash_driver efm32_flash
= {
994 .commands
= efm32x_command_handlers
,
995 .flash_bank_command
= efm32x_flash_bank_command
,
996 .erase
= efm32x_erase
,
997 .protect
= efm32x_protect
,
998 .write
= efm32x_write
,
999 .read
= default_flash_read
,
1000 .probe
= efm32x_probe
,
1001 .auto_probe
= efm32x_auto_probe
,
1002 .erase_check
= default_flash_blank_check
,
1003 .protect_check
= efm32x_protect_check
,
1004 .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)