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%08" PRIx32
, 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%" PRIx32
, 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%" PRIx32
, 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
), efm32x_flash_write_code
);
586 while (target_alloc_working_area_try(target
, buffer_size
, &source
) != ERROR_OK
) {
588 buffer_size
&= ~3UL; /* Make sure it's 4 byte aligned */
589 if (buffer_size
<= 256) {
590 /* we already allocated the writing code, but failed to get a
591 * buffer, free the algorithm */
592 target_free_working_area(target
, write_algorithm
);
594 LOG_WARNING("no large enough working area available, can't do block memory writes");
595 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
599 init_reg_param(®_params
[0], "r0", 32, PARAM_IN_OUT
); /* flash base (in), status (out) */
600 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
); /* count (word-32bit) */
601 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
); /* buffer start */
602 init_reg_param(®_params
[3], "r3", 32, PARAM_OUT
); /* buffer end */
603 init_reg_param(®_params
[4], "r4", 32, PARAM_IN_OUT
); /* target address */
605 buf_set_u32(reg_params
[0].value
, 0, 32, EFM32_MSC_REGBASE
);
606 buf_set_u32(reg_params
[1].value
, 0, 32, count
);
607 buf_set_u32(reg_params
[2].value
, 0, 32, source
->address
);
608 buf_set_u32(reg_params
[3].value
, 0, 32, source
->address
+ source
->size
);
609 buf_set_u32(reg_params
[4].value
, 0, 32, address
);
611 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
612 armv7m_info
.core_mode
= ARM_MODE_THREAD
;
614 ret
= target_run_flash_async_algorithm(target
, buf
, count
, 4,
617 source
->address
, source
->size
,
618 write_algorithm
->address
, 0,
621 if (ret
== ERROR_FLASH_OPERATION_FAILED
) {
622 LOG_ERROR("flash write failed at address 0x%"PRIx32
,
623 buf_get_u32(reg_params
[4].value
, 0, 32));
625 if (buf_get_u32(reg_params
[0].value
, 0, 32) &
626 EFM32_MSC_STATUS_LOCKED_MASK
) {
627 LOG_ERROR("flash memory write protected");
630 if (buf_get_u32(reg_params
[0].value
, 0, 32) &
631 EFM32_MSC_STATUS_INVADDR_MASK
) {
632 LOG_ERROR("invalid flash memory write address");
636 target_free_working_area(target
, source
);
637 target_free_working_area(target
, write_algorithm
);
639 destroy_reg_param(®_params
[0]);
640 destroy_reg_param(®_params
[1]);
641 destroy_reg_param(®_params
[2]);
642 destroy_reg_param(®_params
[3]);
643 destroy_reg_param(®_params
[4]);
648 static int efm32x_write_word(struct flash_bank
*bank
, uint32_t addr
,
651 /* this function DOES NOT set WREN; must be set already */
652 /* 1. write address to ADDRB
654 3. check status (INVADDR, LOCKED)
655 4. wait for WDATAREADY
656 5. write data to WDATA
657 6. write WRITECMD_WRITEONCE to WRITECMD
658 7. wait until !STATUS_BUSY
661 /* FIXME: EFM32G ref states (7.3.2) that writes should be
662 * performed twice per dword */
667 /* if not called, GDB errors will be reported during large writes */
670 ret
= target_write_u32(bank
->target
, EFM32_MSC_ADDRB
, addr
);
674 ret
= efm32x_set_reg_bits(bank
, EFM32_MSC_WRITECMD
,
675 EFM32_MSC_WRITECMD_LADDRIM_MASK
, 1);
679 ret
= target_read_u32(bank
->target
, EFM32_MSC_STATUS
, &status
);
683 LOG_DEBUG("status 0x%" PRIx32
, status
);
685 if (status
& EFM32_MSC_STATUS_LOCKED_MASK
) {
686 LOG_ERROR("Page is locked");
688 } else if (status
& EFM32_MSC_STATUS_INVADDR_MASK
) {
689 LOG_ERROR("Invalid address 0x%" PRIx32
, addr
);
693 ret
= efm32x_wait_status(bank
, EFM32_FLASH_WDATAREADY_TMO
,
694 EFM32_MSC_STATUS_WDATAREADY_MASK
, 1);
695 if (ERROR_OK
!= ret
) {
696 LOG_ERROR("Wait for WDATAREADY failed");
700 ret
= target_write_u32(bank
->target
, EFM32_MSC_WDATA
, val
);
701 if (ERROR_OK
!= ret
) {
702 LOG_ERROR("WDATA write failed");
706 ret
= target_write_u32(bank
->target
, EFM32_MSC_WRITECMD
,
707 EFM32_MSC_WRITECMD_WRITEONCE_MASK
);
708 if (ERROR_OK
!= ret
) {
709 LOG_ERROR("WRITECMD write failed");
713 ret
= efm32x_wait_status(bank
, EFM32_FLASH_WRITE_TMO
,
714 EFM32_MSC_STATUS_BUSY_MASK
, 0);
715 if (ERROR_OK
!= ret
) {
716 LOG_ERROR("Wait for BUSY failed");
723 static int efm32x_write(struct flash_bank
*bank
, uint8_t *buffer
,
724 uint32_t offset
, uint32_t count
)
726 struct target
*target
= bank
->target
;
727 uint8_t *new_buffer
= NULL
;
729 if (target
->state
!= TARGET_HALTED
) {
730 LOG_ERROR("Target not halted");
731 return ERROR_TARGET_NOT_HALTED
;
735 LOG_ERROR("offset 0x%" PRIx32
" breaks required 4-byte "
736 "alignment", offset
);
737 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
741 uint32_t old_count
= count
;
742 count
= (old_count
| 3) + 1;
743 new_buffer
= malloc(count
);
744 if (new_buffer
== NULL
) {
745 LOG_ERROR("odd number of bytes to write and no memory "
746 "for padding buffer");
749 LOG_INFO("odd number of bytes to write (%" PRIu32
"), extending to %" PRIu32
" "
750 "and padding with 0xff", old_count
, count
);
751 memset(buffer
, 0xff, count
);
752 buffer
= memcpy(new_buffer
, buffer
, old_count
);
755 uint32_t words_remaining
= count
/ 4;
758 /* unlock flash registers */
759 efm32x_msc_lock(bank
, 0);
760 retval
= efm32x_set_wren(bank
, 1);
761 if (retval
!= ERROR_OK
)
764 /* try using a block write */
765 retval
= efm32x_write_block(bank
, buffer
, offset
, words_remaining
);
767 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
) {
768 /* if block write failed (no sufficient working area),
769 * we use normal (slow) single word accesses */
770 LOG_WARNING("couldn't use block writes, falling back to single "
773 while (words_remaining
> 0) {
775 memcpy(&value
, buffer
, sizeof(uint32_t));
777 retval
= efm32x_write_word(bank
, offset
, value
);
778 if (retval
!= ERROR_OK
)
779 goto reset_pg_and_lock
;
788 retval2
= efm32x_set_wren(bank
, 0);
789 efm32x_msc_lock(bank
, 1);
790 if (retval
== ERROR_OK
)
800 static int efm32x_probe(struct flash_bank
*bank
)
802 struct efm32x_flash_bank
*efm32x_info
= bank
->driver_priv
;
803 struct efm32_info efm32_mcu_info
;
806 uint32_t base_address
= 0x00000000;
808 efm32x_info
->probed
= 0;
809 memset(efm32x_info
->lb_page
, 0xff, LOCKBITS_PAGE_SZ
);
811 ret
= efm32x_read_info(bank
, &efm32_mcu_info
);
815 switch (efm32_mcu_info
.part_family
) {
816 case EFM_FAMILY_ID_GECKO
:
817 LOG_INFO("Gecko MCU detected");
819 case EFM_FAMILY_ID_GIANT_GECKO
:
820 LOG_INFO("Giant Gecko MCU detected");
822 case EFM_FAMILY_ID_TINY_GECKO
:
823 LOG_INFO("Tiny Gecko MCU detected");
825 case EFM_FAMILY_ID_LEOPARD_GECKO
:
826 LOG_INFO("Leopard Gecko MCU detected");
829 LOG_ERROR("Unsupported MCU family %d",
830 efm32_mcu_info
.part_family
);
834 LOG_INFO("flash size = %dkbytes", efm32_mcu_info
.flash_sz_kib
);
835 LOG_INFO("flash page size = %dbytes", efm32_mcu_info
.page_size
);
837 assert(0 != efm32_mcu_info
.page_size
);
839 int num_pages
= efm32_mcu_info
.flash_sz_kib
* 1024 /
840 efm32_mcu_info
.page_size
;
842 assert(num_pages
> 0);
846 bank
->sectors
= NULL
;
849 bank
->base
= base_address
;
850 bank
->size
= (num_pages
* efm32_mcu_info
.page_size
);
851 bank
->num_sectors
= num_pages
;
853 ret
= efm32x_read_lock_data(bank
);
854 if (ERROR_OK
!= ret
) {
855 LOG_ERROR("Failed to read LB data");
859 bank
->sectors
= malloc(sizeof(struct flash_sector
) * num_pages
);
861 for (i
= 0; i
< num_pages
; i
++) {
862 bank
->sectors
[i
].offset
= i
* efm32_mcu_info
.page_size
;
863 bank
->sectors
[i
].size
= efm32_mcu_info
.page_size
;
864 bank
->sectors
[i
].is_erased
= -1;
865 bank
->sectors
[i
].is_protected
= 1;
868 efm32x_info
->probed
= 1;
873 static int efm32x_auto_probe(struct flash_bank
*bank
)
875 struct efm32x_flash_bank
*efm32x_info
= bank
->driver_priv
;
876 if (efm32x_info
->probed
)
878 return efm32x_probe(bank
);
881 static int efm32x_protect_check(struct flash_bank
*bank
)
883 struct target
*target
= bank
->target
;
887 if (target
->state
!= TARGET_HALTED
) {
888 LOG_ERROR("Target not halted");
889 return ERROR_TARGET_NOT_HALTED
;
892 ret
= efm32x_read_lock_data(bank
);
893 if (ERROR_OK
!= ret
) {
894 LOG_ERROR("Failed to read LB data");
898 assert(NULL
!= bank
->sectors
);
900 for (i
= 0; i
< bank
->num_sectors
; i
++)
901 bank
->sectors
[i
].is_protected
= efm32x_get_page_lock(bank
, i
);
906 static int get_efm32x_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
908 struct efm32_info info
;
912 ret
= efm32x_read_info(bank
, &info
);
913 if (ERROR_OK
!= ret
) {
914 LOG_ERROR("Failed to read EFM32 info");
918 printed
= snprintf(buf
, buf_size
, "EFM32 ");
923 return ERROR_BUF_TOO_SMALL
;
925 switch (info
.part_family
) {
926 case EFM_FAMILY_ID_GECKO
:
927 printed
= snprintf(buf
, buf_size
, "Gecko");
929 case EFM_FAMILY_ID_GIANT_GECKO
:
930 printed
= snprintf(buf
, buf_size
, "Giant Gecko");
932 case EFM_FAMILY_ID_TINY_GECKO
:
933 printed
= snprintf(buf
, buf_size
, "Tiny Gecko");
935 case EFM_FAMILY_ID_LEOPARD_GECKO
:
936 printed
= snprintf(buf
, buf_size
, "Leopard Gecko");
944 return ERROR_BUF_TOO_SMALL
;
946 printed
= snprintf(buf
, buf_size
, " - Rev: %d", info
.prod_rev
);
951 return ERROR_BUF_TOO_SMALL
;
956 static const struct command_registration efm32x_exec_command_handlers
[] = {
957 COMMAND_REGISTRATION_DONE
960 static const struct command_registration efm32x_command_handlers
[] = {
964 .help
= "efm32 flash command group",
966 .chain
= efm32x_exec_command_handlers
,
968 COMMAND_REGISTRATION_DONE
971 struct flash_driver efm32_flash
= {
973 .commands
= efm32x_command_handlers
,
974 .flash_bank_command
= efm32x_flash_bank_command
,
975 .erase
= efm32x_erase
,
976 .protect
= efm32x_protect
,
977 .write
= efm32x_write
,
978 .read
= default_flash_read
,
979 .probe
= efm32x_probe
,
980 .auto_probe
= efm32x_auto_probe
,
981 .erase_check
= default_flash_blank_check
,
982 .protect_check
= efm32x_protect_check
,
983 .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)