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
46 #define EFM32_FLASH_ERASE_TMO 100
47 #define EFM32_FLASH_WDATAREADY_TMO 100
48 #define EFM32_FLASH_WRITE_TMO 100
50 /* size in bytes, not words; must fit all Gecko devices */
51 #define LOCKBITS_PAGE_SZ 512
53 #define EFM32_MSC_INFO_BASE 0x0fe00000
55 #define EFM32_MSC_USER_DATA EFM32_MSC_INFO_BASE
56 #define EFM32_MSC_LOCK_BITS (EFM32_MSC_INFO_BASE+0x4000)
57 #define EFM32_MSC_DEV_INFO (EFM32_MSC_INFO_BASE+0x8000)
59 /* PAGE_SIZE is only present in Leopard and Giant Gecko MCUs */
60 #define EFM32_MSC_DI_PAGE_SIZE (EFM32_MSC_DEV_INFO+0x1e7)
61 #define EFM32_MSC_DI_FLASH_SZ (EFM32_MSC_DEV_INFO+0x1f8)
62 #define EFM32_MSC_DI_RAM_SZ (EFM32_MSC_DEV_INFO+0x1fa)
63 #define EFM32_MSC_DI_PART_NUM (EFM32_MSC_DEV_INFO+0x1fc)
64 #define EFM32_MSC_DI_PART_FAMILY (EFM32_MSC_DEV_INFO+0x1fe)
65 #define EFM32_MSC_DI_PROD_REV (EFM32_MSC_DEV_INFO+0x1ff)
67 #define EFM32_MSC_REGBASE 0x400c0000
68 #define EFM32_MSC_WRITECTRL (EFM32_MSC_REGBASE+0x008)
69 #define EFM32_MSC_WRITECTRL_WREN_MASK 0x1
70 #define EFM32_MSC_WRITECMD (EFM32_MSC_REGBASE+0x00c)
71 #define EFM32_MSC_WRITECMD_LADDRIM_MASK 0x1
72 #define EFM32_MSC_WRITECMD_ERASEPAGE_MASK 0x2
73 #define EFM32_MSC_WRITECMD_WRITEONCE_MASK 0x8
74 #define EFM32_MSC_ADDRB (EFM32_MSC_REGBASE+0x010)
75 #define EFM32_MSC_WDATA (EFM32_MSC_REGBASE+0x018)
76 #define EFM32_MSC_STATUS (EFM32_MSC_REGBASE+0x01c)
77 #define EFM32_MSC_STATUS_BUSY_MASK 0x1
78 #define EFM32_MSC_STATUS_LOCKED_MASK 0x2
79 #define EFM32_MSC_STATUS_INVADDR_MASK 0x4
80 #define EFM32_MSC_STATUS_WDATAREADY_MASK 0x8
81 #define EFM32_MSC_STATUS_WORDTIMEOUT_MASK 0x10
82 #define EFM32_MSC_STATUS_ERASEABORTED_MASK 0x20
83 #define EFM32_MSC_LOCK (EFM32_MSC_REGBASE+0x03c)
84 #define EFM32_MSC_LOCK_LOCKKEY 0x1b71
86 struct efm32x_flash_bank
{
88 uint32_t lb_page
[LOCKBITS_PAGE_SZ
/4];
92 uint16_t flash_sz_kib
;
100 static int efm32x_write(struct flash_bank
*bank
, uint8_t *buffer
,
101 uint32_t offset
, uint32_t count
);
103 static int efm32x_get_flash_size(struct flash_bank
*bank
, uint16_t *flash_sz
)
105 return target_read_u16(bank
->target
, EFM32_MSC_DI_FLASH_SZ
, flash_sz
);
108 static int efm32x_get_ram_size(struct flash_bank
*bank
, uint16_t *ram_sz
)
110 return target_read_u16(bank
->target
, EFM32_MSC_DI_RAM_SZ
, ram_sz
);
113 static int efm32x_get_part_num(struct flash_bank
*bank
, uint16_t *pnum
)
115 return target_read_u16(bank
->target
, EFM32_MSC_DI_PART_NUM
, pnum
);
118 static int efm32x_get_part_family(struct flash_bank
*bank
, uint8_t *pfamily
)
120 return target_read_u8(bank
->target
, EFM32_MSC_DI_PART_FAMILY
, pfamily
);
123 static int efm32x_get_prod_rev(struct flash_bank
*bank
, uint8_t *prev
)
125 return target_read_u8(bank
->target
, EFM32_MSC_DI_PROD_REV
, prev
);
128 static int efm32x_read_info(struct flash_bank
*bank
,
129 struct efm32_info
*efm32_info
)
134 memset(efm32_info
, 0, sizeof(struct efm32_info
));
136 ret
= target_read_u32(bank
->target
, CPUID
, &cpuid
);
140 if (((cpuid
>> 4) & 0xfff) == 0xc23) {
141 /* Cortex M3 device */
143 LOG_ERROR("Target is not CortexM3");
147 ret
= efm32x_get_flash_size(bank
, &(efm32_info
->flash_sz_kib
));
151 ret
= efm32x_get_ram_size(bank
, &(efm32_info
->ram_sz_kib
));
155 ret
= efm32x_get_part_num(bank
, &(efm32_info
->part_num
));
159 ret
= efm32x_get_part_family(bank
, &(efm32_info
->part_family
));
163 ret
= efm32x_get_prod_rev(bank
, &(efm32_info
->prod_rev
));
167 if (EFM_FAMILY_ID_GECKO
== efm32_info
->part_family
||
168 EFM_FAMILY_ID_TINY_GECKO
== efm32_info
->part_family
)
169 efm32_info
->page_size
= 512;
170 else if (EFM_FAMILY_ID_GIANT_GECKO
== efm32_info
->part_family
||
171 EFM_FAMILY_ID_LEOPARD_GECKO
== efm32_info
->part_family
) {
172 if (efm32_info
->prod_rev
>= 18) {
174 ret
= target_read_u8(bank
->target
, EFM32_MSC_DI_PAGE_SIZE
,
179 efm32_info
->page_size
= (1 << ((pg_size
+10) & 0xff));
181 /* EFM32 GG/LG errata: MEM_INFO_PAGE_SIZE is invalid
182 for MCUs with PROD_REV < 18 */
183 if (efm32_info
->flash_sz_kib
< 512)
184 efm32_info
->page_size
= 2048;
186 efm32_info
->page_size
= 4096;
189 if ((2048 != efm32_info
->page_size
) &&
190 (4096 != efm32_info
->page_size
)) {
191 LOG_ERROR("Invalid page size %u", efm32_info
->page_size
);
195 LOG_ERROR("Unknown MCU family %d", efm32_info
->part_family
);
202 /* flash bank efm32 <base> <size> 0 0 <target#>
204 FLASH_BANK_COMMAND_HANDLER(efm32x_flash_bank_command
)
206 struct efm32x_flash_bank
*efm32x_info
;
209 return ERROR_COMMAND_SYNTAX_ERROR
;
211 efm32x_info
= malloc(sizeof(struct efm32x_flash_bank
));
213 bank
->driver_priv
= efm32x_info
;
214 efm32x_info
->probed
= 0;
215 memset(efm32x_info
->lb_page
, 0xff, LOCKBITS_PAGE_SZ
);
220 /* set or reset given bits in a register */
221 static int efm32x_set_reg_bits(struct flash_bank
*bank
, uint32_t reg
,
222 uint32_t bitmask
, int set
)
225 uint32_t reg_val
= 0;
227 ret
= target_read_u32(bank
->target
, reg
, ®_val
);
236 return target_write_u32(bank
->target
, reg
, reg_val
);
239 static int efm32x_set_wren(struct flash_bank
*bank
, int write_enable
)
241 return efm32x_set_reg_bits(bank
, EFM32_MSC_WRITECTRL
,
242 EFM32_MSC_WRITECTRL_WREN_MASK
, write_enable
);
245 static int efm32x_msc_lock(struct flash_bank
*bank
, int lock
)
247 return target_write_u32(bank
->target
, EFM32_MSC_LOCK
,
248 (lock
? 0 : EFM32_MSC_LOCK_LOCKKEY
));
251 static int efm32x_wait_status(struct flash_bank
*bank
, int timeout
,
252 uint32_t wait_mask
, int wait_for_set
)
258 ret
= target_read_u32(bank
->target
, EFM32_MSC_STATUS
, &status
);
262 LOG_DEBUG("status: 0x%" PRIx32
"", status
);
264 if (((status
& wait_mask
) == 0) && (0 == wait_for_set
))
266 else if (((status
& wait_mask
) != 0) && wait_for_set
)
269 if (timeout
-- <= 0) {
270 LOG_ERROR("timed out waiting for MSC status");
277 if (status
& EFM32_MSC_STATUS_ERASEABORTED_MASK
)
278 LOG_WARNING("page erase was aborted");
283 static int efm32x_erase_page(struct flash_bank
*bank
, uint32_t addr
)
285 /* this function DOES NOT set WREN; must be set already */
286 /* 1. write address to ADDRB
288 3. check status (INVADDR, LOCKED)
290 5. wait until !STATUS_BUSY
295 LOG_DEBUG("erasing flash page at 0x%08x", addr
);
297 ret
= target_write_u32(bank
->target
, EFM32_MSC_ADDRB
, addr
);
301 ret
= efm32x_set_reg_bits(bank
, EFM32_MSC_WRITECMD
,
302 EFM32_MSC_WRITECMD_LADDRIM_MASK
, 1);
306 ret
= target_read_u32(bank
->target
, EFM32_MSC_STATUS
, &status
);
310 LOG_DEBUG("status 0x%x", status
);
312 if (status
& EFM32_MSC_STATUS_LOCKED_MASK
) {
313 LOG_ERROR("Page is locked");
315 } else if (status
& EFM32_MSC_STATUS_INVADDR_MASK
) {
316 LOG_ERROR("Invalid address 0x%x", addr
);
320 ret
= efm32x_set_reg_bits(bank
, EFM32_MSC_WRITECMD
,
321 EFM32_MSC_WRITECMD_ERASEPAGE_MASK
, 1);
325 return efm32x_wait_status(bank
, EFM32_FLASH_ERASE_TMO
,
326 EFM32_MSC_STATUS_BUSY_MASK
, 0);
329 static int efm32x_erase(struct flash_bank
*bank
, int first
, int last
)
331 struct target
*target
= bank
->target
;
335 if (TARGET_HALTED
!= target
->state
) {
336 LOG_ERROR("Target not halted");
337 return ERROR_TARGET_NOT_HALTED
;
340 efm32x_msc_lock(bank
, 0);
341 ret
= efm32x_set_wren(bank
, 1);
342 if (ERROR_OK
!= ret
) {
343 LOG_ERROR("Failed to enable MSC write");
347 for (i
= first
; i
<= last
; i
++) {
348 ret
= efm32x_erase_page(bank
, bank
->sectors
[i
].offset
);
350 LOG_ERROR("Failed to erase page %d", i
);
353 ret
= efm32x_set_wren(bank
, 0);
354 efm32x_msc_lock(bank
, 1);
359 static int efm32x_read_lock_data(struct flash_bank
*bank
)
361 struct efm32x_flash_bank
*efm32x_info
= bank
->driver_priv
;
362 struct target
*target
= bank
->target
;
365 uint32_t *ptr
= NULL
;
368 assert(!(bank
->num_sectors
& 0x1f));
370 data_size
= bank
->num_sectors
/ 8; /* number of data bytes */
371 data_size
/= 4; /* ...and data dwords */
373 ptr
= efm32x_info
->lb_page
;
375 for (i
= 0; i
< data_size
; i
++, ptr
++) {
376 ret
= target_read_u32(target
, EFM32_MSC_LOCK_BITS
+i
*4, ptr
);
377 if (ERROR_OK
!= ret
) {
378 LOG_ERROR("Failed to read PLW %d", i
);
383 /* also, read ULW, DLW and MLW */
386 ptr
= efm32x_info
->lb_page
+ 126;
387 ret
= target_read_u32(target
, EFM32_MSC_LOCK_BITS
+126*4, ptr
);
388 if (ERROR_OK
!= ret
) {
389 LOG_ERROR("Failed to read ULW");
394 ptr
= efm32x_info
->lb_page
+ 127;
395 ret
= target_read_u32(target
, EFM32_MSC_LOCK_BITS
+127*4, ptr
);
396 if (ERROR_OK
!= ret
) {
397 LOG_ERROR("Failed to read DLW");
401 /* MLW, word 125, present in GG and LG */
402 ptr
= efm32x_info
->lb_page
+ 125;
403 ret
= target_read_u32(target
, EFM32_MSC_LOCK_BITS
+125*4, ptr
);
404 if (ERROR_OK
!= ret
) {
405 LOG_ERROR("Failed to read MLW");
412 static int efm32x_write_lock_data(struct flash_bank
*bank
)
414 struct efm32x_flash_bank
*efm32x_info
= bank
->driver_priv
;
417 ret
= efm32x_erase_page(bank
, EFM32_MSC_LOCK_BITS
);
418 if (ERROR_OK
!= ret
) {
419 LOG_ERROR("Failed to erase LB page");
423 return efm32x_write(bank
, (uint8_t *)efm32x_info
->lb_page
, EFM32_MSC_LOCK_BITS
,
427 static int efm32x_get_page_lock(struct flash_bank
*bank
, size_t page
)
429 struct efm32x_flash_bank
*efm32x_info
= bank
->driver_priv
;
430 uint32_t dw
= efm32x_info
->lb_page
[page
>> 5];
433 mask
= 1 << (page
& 0x1f);
435 return (dw
& mask
) ? 0 : 1;
438 static int efm32x_set_page_lock(struct flash_bank
*bank
, size_t page
, int set
)
440 struct efm32x_flash_bank
*efm32x_info
= bank
->driver_priv
;
441 uint32_t *dw
= &efm32x_info
->lb_page
[page
>> 5];
444 mask
= 1 << (page
& 0x1f);
454 static int efm32x_protect(struct flash_bank
*bank
, int set
, int first
, int last
)
456 struct target
*target
= bank
->target
;
461 LOG_ERROR("Erase device data to reset page locks");
465 if (target
->state
!= TARGET_HALTED
) {
466 LOG_ERROR("Target not halted");
467 return ERROR_TARGET_NOT_HALTED
;
470 for (i
= first
; i
<= last
; i
++) {
471 ret
= efm32x_set_page_lock(bank
, i
, set
);
472 if (ERROR_OK
!= ret
) {
473 LOG_ERROR("Failed to set lock on page %d", i
);
478 ret
= efm32x_write_lock_data(bank
);
479 if (ERROR_OK
!= ret
) {
480 LOG_ERROR("Failed to write LB page");
487 static int efm32x_write_block(struct flash_bank
*bank
, uint8_t *buf
,
488 uint32_t offset
, uint32_t count
)
490 struct target
*target
= bank
->target
;
491 uint32_t buffer_size
= 16384;
492 struct working_area
*write_algorithm
;
493 struct working_area
*source
;
494 uint32_t address
= bank
->base
+ offset
;
495 struct reg_param reg_params
[5];
496 struct armv7m_algorithm armv7m_info
;
499 /* see contrib/loaders/flash/efm32.S for src */
500 static const uint8_t efm32x_flash_write_code
[] = {
501 /* #define EFM32_MSC_WRITECTRL_OFFSET 0x008 */
502 /* #define EFM32_MSC_WRITECMD_OFFSET 0x00c */
503 /* #define EFM32_MSC_ADDRB_OFFSET 0x010 */
504 /* #define EFM32_MSC_WDATA_OFFSET 0x018 */
505 /* #define EFM32_MSC_STATUS_OFFSET 0x01c */
506 /* #define EFM32_MSC_LOCK_OFFSET 0x03c */
508 0x15, 0x4e, /* ldr r6, =#0x1b71 */
509 0xc6, 0x63, /* str r6, [r0, #EFM32_MSC_LOCK_OFFSET] */
510 0x01, 0x26, /* movs r6, #1 */
511 0x86, 0x60, /* str r6, [r0, #EFM32_MSC_WRITECTRL_OFFSET] */
514 0x16, 0x68, /* ldr r6, [r2, #0] */
515 0x00, 0x2e, /* cmp r6, #0 */
516 0x22, 0xd0, /* beq exit */
517 0x55, 0x68, /* ldr r5, [r2, #4] */
518 0xb5, 0x42, /* cmp r5, r6 */
519 0xf9, 0xd0, /* beq wait_fifo */
521 0x04, 0x61, /* str r4, [r0, #EFM32_MSC_ADDRB_OFFSET] */
522 0x01, 0x26, /* movs r6, #1 */
523 0xc6, 0x60, /* str r6, [r0, #EFM32_MSC_WRITECMD_OFFSET] */
524 0xc6, 0x69, /* ldr r6, [r0, #EFM32_MSC_STATUS_OFFSET] */
525 0x06, 0x27, /* movs r7, #6 */
526 0x3e, 0x42, /* tst r6, r7 */
527 0x16, 0xd1, /* bne error */
529 /* wait_wdataready: */
530 0xc6, 0x69, /* ldr r6, [r0, #EFM32_MSC_STATUS_OFFSET] */
531 0x08, 0x27, /* movs r7, #8 */
532 0x3e, 0x42, /* tst r6, r7 */
533 0xfb, 0xd0, /* beq wait_wdataready */
535 0x2e, 0x68, /* ldr r6, [r5] */
536 0x86, 0x61, /* str r6, [r0, #EFM32_MSC_WDATA_OFFSET] */
537 0x08, 0x26, /* movs r6, #8 */
538 0xc6, 0x60, /* str r6, [r0, #EFM32_MSC_WRITECMD_OFFSET] */
540 0x04, 0x35, /* adds r5, #4 */
541 0x04, 0x34, /* adds r4, #4 */
544 0xc6, 0x69, /* ldr r6, [r0, #EFM32_MSC_STATUS_OFFSET] */
545 0x01, 0x27, /* movs r7, #1 */
546 0x3e, 0x42, /* tst r6, r7 */
547 0xfb, 0xd1, /* bne busy */
549 0x9d, 0x42, /* cmp r5, r3 */
550 0x01, 0xd3, /* bcc no_wrap */
551 0x15, 0x46, /* mov r5, r2 */
552 0x08, 0x35, /* adds r5, #8 */
555 0x55, 0x60, /* str r5, [r2, #4] */
556 0x01, 0x39, /* subs r1, r1, #1 */
557 0x00, 0x29, /* cmp r1, #0 */
558 0x02, 0xd0, /* beq exit */
559 0xdb, 0xe7, /* b wait_fifo */
562 0x00, 0x20, /* movs r0, #0 */
563 0x50, 0x60, /* str r0, [r2, #4] */
566 0x30, 0x46, /* mov r0, r6 */
567 0x00, 0xbe, /* bkpt #0 */
570 0x71, 0x1b, 0x00, 0x00
573 /* flash write code */
574 if (target_alloc_working_area(target
, sizeof(efm32x_flash_write_code
),
575 &write_algorithm
) != ERROR_OK
) {
576 LOG_WARNING("no working area available, can't do block memory writes");
577 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
580 ret
= target_write_buffer(target
, write_algorithm
->address
,
581 sizeof(efm32x_flash_write_code
),
582 (uint8_t *)efm32x_flash_write_code
);
587 while (target_alloc_working_area_try(target
, buffer_size
, &source
) != ERROR_OK
) {
589 buffer_size
&= ~3UL; /* Make sure it's 4 byte aligned */
590 if (buffer_size
<= 256) {
591 /* we already allocated the writing code, but failed to get a
592 * buffer, free the algorithm */
593 target_free_working_area(target
, write_algorithm
);
595 LOG_WARNING("no large enough working area available, can't do block memory writes");
596 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
600 init_reg_param(®_params
[0], "r0", 32, PARAM_IN_OUT
); /* flash base (in), status (out) */
601 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
); /* count (word-32bit) */
602 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
); /* buffer start */
603 init_reg_param(®_params
[3], "r3", 32, PARAM_OUT
); /* buffer end */
604 init_reg_param(®_params
[4], "r4", 32, PARAM_IN_OUT
); /* target address */
606 buf_set_u32(reg_params
[0].value
, 0, 32, EFM32_MSC_REGBASE
);
607 buf_set_u32(reg_params
[1].value
, 0, 32, count
);
608 buf_set_u32(reg_params
[2].value
, 0, 32, source
->address
);
609 buf_set_u32(reg_params
[3].value
, 0, 32, source
->address
+ source
->size
);
610 buf_set_u32(reg_params
[4].value
, 0, 32, address
);
612 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
613 armv7m_info
.core_mode
= ARM_MODE_THREAD
;
615 ret
= target_run_flash_async_algorithm(target
, buf
, count
, 4,
618 source
->address
, source
->size
,
619 write_algorithm
->address
, 0,
622 if (ret
== ERROR_FLASH_OPERATION_FAILED
) {
623 LOG_ERROR("flash write failed at address 0x%"PRIx32
,
624 buf_get_u32(reg_params
[4].value
, 0, 32));
626 if (buf_get_u32(reg_params
[0].value
, 0, 32) &
627 EFM32_MSC_STATUS_LOCKED_MASK
) {
628 LOG_ERROR("flash memory write protected");
631 if (buf_get_u32(reg_params
[0].value
, 0, 32) &
632 EFM32_MSC_STATUS_INVADDR_MASK
) {
633 LOG_ERROR("invalid flash memory write address");
637 target_free_working_area(target
, source
);
638 target_free_working_area(target
, write_algorithm
);
640 destroy_reg_param(®_params
[0]);
641 destroy_reg_param(®_params
[1]);
642 destroy_reg_param(®_params
[2]);
643 destroy_reg_param(®_params
[3]);
644 destroy_reg_param(®_params
[4]);
649 static int efm32x_write_word(struct flash_bank
*bank
, uint32_t addr
,
652 /* this function DOES NOT set WREN; must be set already */
653 /* 1. write address to ADDRB
655 3. check status (INVADDR, LOCKED)
656 4. wait for WDATAREADY
657 5. write data to WDATA
658 6. write WRITECMD_WRITEONCE to WRITECMD
659 7. wait until !STATUS_BUSY
662 /* FIXME: EFM32G ref states (7.3.2) that writes should be
663 * performed twice per dword */
668 /* if not called, GDB errors will be reported during large writes */
671 ret
= target_write_u32(bank
->target
, EFM32_MSC_ADDRB
, addr
);
675 ret
= efm32x_set_reg_bits(bank
, EFM32_MSC_WRITECMD
,
676 EFM32_MSC_WRITECMD_LADDRIM_MASK
, 1);
680 ret
= target_read_u32(bank
->target
, EFM32_MSC_STATUS
, &status
);
684 LOG_DEBUG("status 0x%x", status
);
686 if (status
& EFM32_MSC_STATUS_LOCKED_MASK
) {
687 LOG_ERROR("Page is locked");
689 } else if (status
& EFM32_MSC_STATUS_INVADDR_MASK
) {
690 LOG_ERROR("Invalid address 0x%x", addr
);
694 ret
= efm32x_wait_status(bank
, EFM32_FLASH_WDATAREADY_TMO
,
695 EFM32_MSC_STATUS_WDATAREADY_MASK
, 1);
696 if (ERROR_OK
!= ret
) {
697 LOG_ERROR("Wait for WDATAREADY failed");
701 ret
= target_write_u32(bank
->target
, EFM32_MSC_WDATA
, val
);
702 if (ERROR_OK
!= ret
) {
703 LOG_ERROR("WDATA write failed");
707 ret
= target_write_u32(bank
->target
, EFM32_MSC_WRITECMD
,
708 EFM32_MSC_WRITECMD_WRITEONCE_MASK
);
709 if (ERROR_OK
!= ret
) {
710 LOG_ERROR("WRITECMD write failed");
714 ret
= efm32x_wait_status(bank
, EFM32_FLASH_WRITE_TMO
,
715 EFM32_MSC_STATUS_BUSY_MASK
, 0);
716 if (ERROR_OK
!= ret
) {
717 LOG_ERROR("Wait for BUSY failed");
724 static int efm32x_write(struct flash_bank
*bank
, uint8_t *buffer
,
725 uint32_t offset
, uint32_t count
)
727 struct target
*target
= bank
->target
;
728 uint8_t *new_buffer
= NULL
;
730 if (target
->state
!= TARGET_HALTED
) {
731 LOG_ERROR("Target not halted");
732 return ERROR_TARGET_NOT_HALTED
;
736 LOG_ERROR("offset 0x%" PRIx32
" breaks required 4-byte "
737 "alignment", offset
);
738 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
742 uint32_t old_count
= count
;
743 count
= (old_count
| 3) + 1;
744 new_buffer
= malloc(count
);
745 if (new_buffer
== NULL
) {
746 LOG_ERROR("odd number of bytes to write and no memory "
747 "for padding buffer");
750 LOG_INFO("odd number of bytes to write (%d), extending to %d "
751 "and padding with 0xff", old_count
, count
);
752 memset(buffer
, 0xff, count
);
753 buffer
= memcpy(new_buffer
, buffer
, old_count
);
756 uint32_t words_remaining
= count
/ 4;
759 /* unlock flash registers */
760 efm32x_msc_lock(bank
, 0);
761 retval
= efm32x_set_wren(bank
, 1);
762 if (retval
!= ERROR_OK
)
765 /* try using a block write */
766 retval
= efm32x_write_block(bank
, buffer
, offset
, words_remaining
);
768 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
) {
769 /* if block write failed (no sufficient working area),
770 * we use normal (slow) single word accesses */
771 LOG_WARNING("couldn't use block writes, falling back to single "
774 while (words_remaining
> 0) {
776 memcpy(&value
, buffer
, sizeof(uint32_t));
778 retval
= efm32x_write_word(bank
, offset
, value
);
779 if (retval
!= ERROR_OK
)
780 goto reset_pg_and_lock
;
789 retval2
= efm32x_set_wren(bank
, 0);
790 efm32x_msc_lock(bank
, 1);
791 if (retval
== ERROR_OK
)
801 static int efm32x_probe(struct flash_bank
*bank
)
803 struct efm32x_flash_bank
*efm32x_info
= bank
->driver_priv
;
804 struct efm32_info efm32_mcu_info
;
807 uint32_t base_address
= 0x00000000;
809 efm32x_info
->probed
= 0;
810 memset(efm32x_info
->lb_page
, 0xff, LOCKBITS_PAGE_SZ
);
812 ret
= efm32x_read_info(bank
, &efm32_mcu_info
);
816 switch (efm32_mcu_info
.part_family
) {
817 case EFM_FAMILY_ID_GECKO
:
818 LOG_INFO("Gecko MCU detected");
820 case EFM_FAMILY_ID_GIANT_GECKO
:
821 LOG_INFO("Giant Gecko MCU detected");
823 case EFM_FAMILY_ID_TINY_GECKO
:
824 LOG_INFO("Tiny Gecko MCU detected");
826 case EFM_FAMILY_ID_LEOPARD_GECKO
:
827 LOG_INFO("Leopard Gecko MCU detected");
830 LOG_ERROR("Unsupported MCU family %d",
831 efm32_mcu_info
.part_family
);
835 LOG_INFO("flash size = %dkbytes", efm32_mcu_info
.flash_sz_kib
);
836 LOG_INFO("flash page size = %dbytes", efm32_mcu_info
.page_size
);
838 assert(0 != efm32_mcu_info
.page_size
);
840 int num_pages
= efm32_mcu_info
.flash_sz_kib
* 1024 /
841 efm32_mcu_info
.page_size
;
843 assert(num_pages
> 0);
847 bank
->sectors
= NULL
;
850 bank
->base
= base_address
;
851 bank
->size
= (num_pages
* efm32_mcu_info
.page_size
);
852 bank
->num_sectors
= num_pages
;
854 ret
= efm32x_read_lock_data(bank
);
855 if (ERROR_OK
!= ret
) {
856 LOG_ERROR("Failed to read LB data");
860 bank
->sectors
= malloc(sizeof(struct flash_sector
) * num_pages
);
862 for (i
= 0; i
< num_pages
; i
++) {
863 bank
->sectors
[i
].offset
= i
* efm32_mcu_info
.page_size
;
864 bank
->sectors
[i
].size
= efm32_mcu_info
.page_size
;
865 bank
->sectors
[i
].is_erased
= -1;
866 bank
->sectors
[i
].is_protected
= 1;
869 efm32x_info
->probed
= 1;
874 static int efm32x_auto_probe(struct flash_bank
*bank
)
876 struct efm32x_flash_bank
*efm32x_info
= bank
->driver_priv
;
877 if (efm32x_info
->probed
)
879 return efm32x_probe(bank
);
882 static int efm32x_protect_check(struct flash_bank
*bank
)
884 struct target
*target
= bank
->target
;
888 if (target
->state
!= TARGET_HALTED
) {
889 LOG_ERROR("Target not halted");
890 return ERROR_TARGET_NOT_HALTED
;
893 ret
= efm32x_read_lock_data(bank
);
894 if (ERROR_OK
!= ret
) {
895 LOG_ERROR("Failed to read LB data");
899 assert(NULL
!= bank
->sectors
);
901 for (i
= 0; i
< bank
->num_sectors
; i
++)
902 bank
->sectors
[i
].is_protected
= efm32x_get_page_lock(bank
, i
);
907 static int get_efm32x_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
909 struct efm32_info info
;
913 ret
= efm32x_read_info(bank
, &info
);
914 if (ERROR_OK
!= ret
) {
915 LOG_ERROR("Failed to read EFM32 info");
919 printed
= snprintf(buf
, buf_size
, "EFM32 ");
924 return ERROR_BUF_TOO_SMALL
;
926 switch (info
.part_family
) {
927 case EFM_FAMILY_ID_GECKO
:
928 printed
= snprintf(buf
, buf_size
, "Gecko");
930 case EFM_FAMILY_ID_GIANT_GECKO
:
931 printed
= snprintf(buf
, buf_size
, "Giant Gecko");
933 case EFM_FAMILY_ID_TINY_GECKO
:
934 printed
= snprintf(buf
, buf_size
, "Tiny Gecko");
936 case EFM_FAMILY_ID_LEOPARD_GECKO
:
937 printed
= snprintf(buf
, buf_size
, "Leopard Gecko");
945 return ERROR_BUF_TOO_SMALL
;
947 printed
= snprintf(buf
, buf_size
, " - Rev: %d", info
.prod_rev
);
952 return ERROR_BUF_TOO_SMALL
;
957 static const struct command_registration efm32x_exec_command_handlers
[] = {
958 COMMAND_REGISTRATION_DONE
961 static const struct command_registration efm32x_command_handlers
[] = {
965 .help
= "efm32 flash command group",
967 .chain
= efm32x_exec_command_handlers
,
969 COMMAND_REGISTRATION_DONE
972 struct flash_driver efm32_flash
= {
974 .commands
= efm32x_command_handlers
,
975 .flash_bank_command
= efm32x_flash_bank_command
,
976 .erase
= efm32x_erase
,
977 .protect
= efm32x_protect
,
978 .write
= efm32x_write
,
979 .read
= default_flash_read
,
980 .probe
= efm32x_probe
,
981 .auto_probe
= efm32x_auto_probe
,
982 .erase_check
= default_flash_blank_check
,
983 .protect_check
= efm32x_protect_check
,
984 .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)