1 /***************************************************************************
2 * Copyright (C) 2013 Synapse Product Development *
3 * Andrey Smirnov <andrew.smironv@gmail.com> *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
19 ***************************************************************************/
28 NRF51_FLASH_BASE
= 0x00000000,
31 enum nrf51_ficr_registers
{
32 NRF51_FICR_BASE
= 0x10000000, /* Factory Information Configuration Registers */
34 #define NRF51_FICR_REG(offset) (NRF51_FICR_BASE + offset)
36 NRF51_FICR_CODEPAGESIZE
= NRF51_FICR_REG(0x010),
37 NRF51_FICR_CODESIZE
= NRF51_FICR_REG(0x014),
38 NRF51_FICR_CLENR0
= NRF51_FICR_REG(0x028),
39 NRF51_FICR_PPFC
= NRF51_FICR_REG(0x02C),
40 NRF51_FICR_NUMRAMBLOCK
= NRF51_FICR_REG(0x034),
41 NRF51_FICR_SIZERAMBLOCK0
= NRF51_FICR_REG(0x038),
42 NRF51_FICR_SIZERAMBLOCK1
= NRF51_FICR_REG(0x03C),
43 NRF51_FICR_SIZERAMBLOCK2
= NRF51_FICR_REG(0x040),
44 NRF51_FICR_SIZERAMBLOCK3
= NRF51_FICR_REG(0x044),
45 NRF51_FICR_CONFIGID
= NRF51_FICR_REG(0x05C),
46 NRF51_FICR_DEVICEID0
= NRF51_FICR_REG(0x060),
47 NRF51_FICR_DEVICEID1
= NRF51_FICR_REG(0x064),
48 NRF51_FICR_ER0
= NRF51_FICR_REG(0x080),
49 NRF51_FICR_ER1
= NRF51_FICR_REG(0x084),
50 NRF51_FICR_ER2
= NRF51_FICR_REG(0x088),
51 NRF51_FICR_ER3
= NRF51_FICR_REG(0x08C),
52 NRF51_FICR_IR0
= NRF51_FICR_REG(0x090),
53 NRF51_FICR_IR1
= NRF51_FICR_REG(0x094),
54 NRF51_FICR_IR2
= NRF51_FICR_REG(0x098),
55 NRF51_FICR_IR3
= NRF51_FICR_REG(0x09C),
56 NRF51_FICR_DEVICEADDRTYPE
= NRF51_FICR_REG(0x0A0),
57 NRF51_FICR_DEVICEADDR0
= NRF51_FICR_REG(0x0A4),
58 NRF51_FICR_DEVICEADDR1
= NRF51_FICR_REG(0x0A8),
59 NRF51_FICR_OVERRIDEN
= NRF51_FICR_REG(0x0AC),
60 NRF51_FICR_NRF_1MBIT0
= NRF51_FICR_REG(0x0B0),
61 NRF51_FICR_NRF_1MBIT1
= NRF51_FICR_REG(0x0B4),
62 NRF51_FICR_NRF_1MBIT2
= NRF51_FICR_REG(0x0B8),
63 NRF51_FICR_NRF_1MBIT3
= NRF51_FICR_REG(0x0BC),
64 NRF51_FICR_NRF_1MBIT4
= NRF51_FICR_REG(0x0C0),
65 NRF51_FICR_BLE_1MBIT0
= NRF51_FICR_REG(0x0EC),
66 NRF51_FICR_BLE_1MBIT1
= NRF51_FICR_REG(0x0F0),
67 NRF51_FICR_BLE_1MBIT2
= NRF51_FICR_REG(0x0F4),
68 NRF51_FICR_BLE_1MBIT3
= NRF51_FICR_REG(0x0F8),
69 NRF51_FICR_BLE_1MBIT4
= NRF51_FICR_REG(0x0FC),
72 enum nrf51_uicr_registers
{
73 NRF51_UICR_BASE
= 0x10001000, /* User Information
74 * Configuration Regsters */
76 #define NRF51_UICR_REG(offset) (NRF51_UICR_BASE + offset)
78 NRF51_UICR_CLENR0
= NRF51_UICR_REG(0x000),
79 NRF51_UICR_RBPCONF
= NRF51_UICR_REG(0x004),
80 NRF51_UICR_XTALFREQ
= NRF51_UICR_REG(0x008),
81 NRF51_UICR_FWID
= NRF51_UICR_REG(0x010),
84 enum nrf51_nvmc_registers
{
85 NRF51_NVMC_BASE
= 0x4001E000, /* Non-Volatile Memory
86 * Controller Regsters */
88 #define NRF51_NVMC_REG(offset) (NRF51_NVMC_BASE + offset)
90 NRF51_NVMC_READY
= NRF51_NVMC_REG(0x400),
91 NRF51_NVMC_CONFIG
= NRF51_NVMC_REG(0x504),
92 NRF51_NVMC_ERASEPAGE
= NRF51_NVMC_REG(0x508),
93 NRF51_NVMC_ERASEALL
= NRF51_NVMC_REG(0x50C),
94 NRF51_NVMC_ERASEUICR
= NRF51_NVMC_REG(0x514),
97 enum nrf51_nvmc_config_bits
{
98 NRF51_NVMC_CONFIG_REN
= 0x00,
99 NRF51_NVMC_CONFIG_WEN
= 0x01,
100 NRF51_NVMC_CONFIG_EEN
= 0x02,
105 uint32_t code_page_size
;
106 uint32_t code_memory_size
;
109 struct target
*target
;
112 static int nrf51_probe(struct flash_bank
*bank
);
114 static int nrf51_get_probed_chip_if_halted(struct flash_bank
*bank
, struct nrf51_info
**chip
)
116 if (bank
->target
->state
!= TARGET_HALTED
) {
117 LOG_ERROR("Target not halted");
118 return ERROR_TARGET_NOT_HALTED
;
121 *chip
= (struct nrf51_info
*)bank
->driver_priv
;
123 if (!(*chip
)->probed
)
124 return nrf51_probe(bank
);
129 static int nrf51_wait_for_nvmc(struct nrf51_info
*chip
)
136 res
= target_read_u32(chip
->target
, NRF51_NVMC_READY
, &ready
);
137 if (res
!= ERROR_OK
) {
138 LOG_ERROR("Couldn't read NVMC_READY register");
142 if (ready
== 0x00000001)
148 return ERROR_FLASH_BUSY
;
151 static int nrf51_nvmc_erase_enable(struct nrf51_info
*chip
)
154 res
= target_write_u32(chip
->target
,
156 NRF51_NVMC_CONFIG_EEN
);
158 if (res
!= ERROR_OK
) {
159 LOG_ERROR("Failed to enable erase operation");
164 According to NVMC examples in Nordic SDK busy status must be
165 checked after writing to NVMC_CONFIG
167 res
= nrf51_wait_for_nvmc(chip
);
169 LOG_ERROR("Erase enable did not complete");
174 static int nrf51_nvmc_write_enable(struct nrf51_info
*chip
)
177 res
= target_write_u32(chip
->target
,
179 NRF51_NVMC_CONFIG_WEN
);
181 if (res
!= ERROR_OK
) {
182 LOG_ERROR("Failed to enable write operation");
187 According to NVMC examples in Nordic SDK busy status must be
188 checked after writing to NVMC_CONFIG
190 res
= nrf51_wait_for_nvmc(chip
);
192 LOG_ERROR("Write enable did not complete");
197 static int nrf51_nvmc_read_only(struct nrf51_info
*chip
)
200 res
= target_write_u32(chip
->target
,
202 NRF51_NVMC_CONFIG_REN
);
204 if (res
!= ERROR_OK
) {
205 LOG_ERROR("Failed to enable read-only operation");
209 According to NVMC examples in Nordic SDK busy status must be
210 checked after writing to NVMC_CONFIG
212 res
= nrf51_wait_for_nvmc(chip
);
214 LOG_ERROR("Read only enable did not complete");
219 static int nrf51_nvmc_generic_erase(struct nrf51_info
*chip
,
220 uint32_t erase_register
, uint32_t erase_value
)
224 res
= nrf51_nvmc_erase_enable(chip
);
228 res
= target_write_u32(chip
->target
,
234 res
= nrf51_wait_for_nvmc(chip
);
238 return nrf51_nvmc_read_only(chip
);
241 nrf51_nvmc_read_only(chip
);
243 LOG_ERROR("Failed to erase reg: 0x%08"PRIx32
" val: 0x%08"PRIx32
,
244 erase_register
, erase_value
);
248 static int nrf51_protect_check(struct flash_bank
*bank
)
253 struct nrf51_info
*chip
= (struct nrf51_info
*)bank
->driver_priv
;
255 assert(chip
!= NULL
);
257 res
= target_read_u32(chip
->target
, NRF51_FICR_CLENR0
,
259 if (res
!= ERROR_OK
) {
260 LOG_ERROR("Couldn't read code region 0 size[FICR]");
264 if (clenr0
== 0xFFFFFFFF) {
265 res
= target_read_u32(chip
->target
, NRF51_UICR_CLENR0
,
267 if (res
!= ERROR_OK
) {
268 LOG_ERROR("Couldn't read code region 0 size[UICR]");
273 for (int i
= 0; i
< bank
->num_sectors
; i
++)
274 bank
->sectors
[i
].is_protected
=
275 clenr0
!= 0xFFFFFFFF && bank
->sectors
[i
].offset
< clenr0
;
280 static int nrf51_protect(struct flash_bank
*bank
, int set
, int first
, int last
)
283 uint32_t clenr0
, ppfc
;
284 struct nrf51_info
*chip
;
286 res
= nrf51_get_probed_chip_if_halted(bank
, &chip
);
291 LOG_ERROR("Code region 0 must start at the begining of the bank");
295 res
= target_read_u32(chip
->target
, NRF51_FICR_PPFC
,
297 if (res
!= ERROR_OK
) {
298 LOG_ERROR("Couldn't read PPFC register");
302 if ((ppfc
& 0xFF) == 0x00) {
303 LOG_ERROR("Code region 0 size was pre-programmed at the factory, can't change flash protection settings");
307 res
= target_read_u32(chip
->target
, NRF51_UICR_CLENR0
,
309 if (res
!= ERROR_OK
) {
310 LOG_ERROR("Couldn't read code region 0 size[UICR]");
314 if (clenr0
== 0xFFFFFFFF) {
315 res
= target_write_u32(chip
->target
, NRF51_UICR_CLENR0
,
317 if (res
!= ERROR_OK
) {
318 LOG_ERROR("Couldn't write code region 0 size[UICR]");
323 LOG_ERROR("You need to perform chip erase before changing the protection settings");
326 nrf51_protect_check(bank
);
331 static int nrf51_probe(struct flash_bank
*bank
)
335 struct nrf51_info
*chip
= (struct nrf51_info
*)bank
->driver_priv
;
337 res
= target_read_u32(chip
->target
, NRF51_FICR_DEVICEID0
, &id
);
338 if (res
!= ERROR_OK
) {
339 LOG_ERROR("Couldn't read Device ID 0 register");
343 res
= target_read_u32(chip
->target
, NRF51_FICR_DEVICEID1
, &id
);
344 if (res
!= ERROR_OK
) {
345 LOG_ERROR("Couldn't read Device ID 1 register");
349 res
= target_read_u32(chip
->target
, NRF51_FICR_CODEPAGESIZE
,
350 &chip
->code_page_size
);
351 if (res
!= ERROR_OK
) {
352 LOG_ERROR("Couldn't read code page size");
356 res
= target_read_u32(chip
->target
, NRF51_FICR_CODESIZE
,
357 &chip
->code_memory_size
);
358 if (res
!= ERROR_OK
) {
359 LOG_ERROR("Couldn't read code memory size");
363 bank
->size
= chip
->code_memory_size
* 1024;
364 bank
->num_sectors
= bank
->size
/ chip
->code_page_size
;
365 bank
->sectors
= calloc(bank
->num_sectors
,
366 sizeof((bank
->sectors
)[0]));
368 return ERROR_FLASH_BANK_NOT_PROBED
;
370 /* Fill out the sector information: all NRF51 sectors are the same size and
371 * there is always a fixed number of them. */
372 for (int i
= 0; i
< bank
->num_sectors
; i
++) {
373 bank
->sectors
[i
].size
= chip
->code_page_size
;
374 bank
->sectors
[i
].offset
= i
* chip
->code_page_size
;
376 /* mark as unknown */
377 bank
->sectors
[i
].is_erased
= -1;
378 bank
->sectors
[i
].is_protected
= -1;
381 nrf51_protect_check(bank
);
388 static int nrf51_auto_probe(struct flash_bank
*bank
)
390 struct nrf51_info
*chip
= (struct nrf51_info
*)bank
->driver_priv
;
395 return nrf51_probe(bank
);
398 static struct flash_sector
*nrf51_find_sector_by_address(struct flash_bank
*bank
, uint32_t address
)
400 struct nrf51_info
*chip
= (struct nrf51_info
*)bank
->driver_priv
;
402 for (int i
= 0; i
< bank
->num_sectors
; i
++)
403 if (bank
->sectors
[i
].offset
<= address
&&
404 address
< (bank
->sectors
[i
].offset
+ chip
->code_page_size
))
405 return &bank
->sectors
[i
];
409 static int nrf51_erase_all(struct nrf51_info
*chip
)
411 return nrf51_nvmc_generic_erase(chip
,
416 static int nrf51_erase_page(struct nrf51_info
*chip
, struct flash_sector
*sector
)
420 if (sector
->is_protected
)
423 res
= nrf51_nvmc_generic_erase(chip
,
424 NRF51_NVMC_ERASEPAGE
,
427 sector
->is_erased
= 1;
432 static int nrf51_write_page(struct flash_bank
*bank
, uint32_t offset
, uint8_t *buffer
)
434 assert(offset
% 4 == 0);
436 int res
= ERROR_FAIL
;
437 struct nrf51_info
*chip
= (struct nrf51_info
*)bank
->driver_priv
;
438 struct flash_sector
*sector
= nrf51_find_sector_by_address(bank
, offset
);
443 if (sector
->is_protected
)
446 if (!sector
->is_erased
) {
447 res
= nrf51_erase_page(chip
, sector
);
452 res
= nrf51_nvmc_write_enable(chip
);
456 sector
->is_erased
= 0;
457 res
= target_write_memory(bank
->target
, offset
, 4,
458 chip
->code_page_size
/ 4, buffer
);
462 return nrf51_nvmc_read_only(chip
);
465 nrf51_nvmc_read_only(chip
);
467 LOG_ERROR("Failed to write sector @ 0x%08"PRIx32
, sector
->offset
);
471 static int nrf51_erase(struct flash_bank
*bank
, int first
, int last
)
474 struct nrf51_info
*chip
;
476 res
= nrf51_get_probed_chip_if_halted(bank
, &chip
);
480 /* For each sector to be erased */
481 for (int s
= first
; s
<= last
&& res
== ERROR_OK
; s
++)
482 res
= nrf51_erase_page(chip
, &bank
->sectors
[s
]);
487 static int nrf51_write(struct flash_bank
*bank
, uint8_t *buffer
,
488 uint32_t offset
, uint32_t count
)
494 struct nrf51_info
*chip
;
496 res
= nrf51_get_probed_chip_if_halted(bank
, &chip
);
500 region
.start
= offset
;
501 region
.end
= offset
+ count
;
506 } start_extra
, end_extra
;
508 start_extra
.length
= region
.start
% chip
->code_page_size
;
509 start_extra
.buffer
= buffer
;
510 end_extra
.length
= region
.end
% chip
->code_page_size
;
511 end_extra
.buffer
= buffer
+ count
- end_extra
.length
;
513 if (start_extra
.length
) {
514 uint8_t page
[chip
->code_page_size
];
516 res
= target_read_memory(bank
->target
,
517 region
.start
- start_extra
.length
,
518 1, start_extra
.length
, page
);
522 memcpy(page
+ start_extra
.length
,
524 chip
->code_page_size
- start_extra
.length
);
526 res
= nrf51_write_page(bank
,
527 region
.start
- start_extra
.length
,
533 if (end_extra
.length
) {
534 uint8_t page
[chip
->code_page_size
];
536 /* Retrieve the full row contents from Flash */
537 res
= target_read_memory(bank
->target
,
540 (chip
->code_page_size
- end_extra
.length
),
541 page
+ end_extra
.length
);
545 memcpy(page
, end_extra
.buffer
, end_extra
.length
);
547 res
= nrf51_write_page(bank
,
548 region
.end
- end_extra
.length
,
555 region
.start
+= start_extra
.length
;
556 region
.end
-= end_extra
.length
;
558 for (uint32_t address
= region
.start
; address
< region
.end
;
559 address
+= chip
->code_page_size
) {
560 res
= nrf51_write_page(bank
, address
, &buffer
[address
- region
.start
]);
570 FLASH_BANK_COMMAND_HANDLER(nrf51_flash_bank_command
)
572 struct nrf51_info
*chip
;
574 /* Create a new chip */
575 chip
= calloc(1, sizeof(*chip
));
579 chip
->target
= bank
->target
;
580 chip
->probed
= false;
582 bank
->driver_priv
= chip
;
584 if (bank
->base
!= NRF51_FLASH_BASE
) {
585 LOG_ERROR("Address 0x%08" PRIx32
" invalid bank address (try 0x%08" PRIx32
587 bank
->base
, NRF51_FLASH_BASE
);
594 COMMAND_HANDLER(nrf51_handle_mass_erase_command
)
597 struct flash_bank
*bank
;
599 res
= get_flash_bank_by_num(0, &bank
);
603 struct nrf51_info
*chip
;
605 res
= nrf51_get_probed_chip_if_halted(bank
, &chip
);
611 res
= target_read_u32(chip
->target
, NRF51_FICR_PPFC
,
613 if (res
!= ERROR_OK
) {
614 LOG_ERROR("Couldn't read PPFC register");
618 if ((ppfc
& 0xFF) == 0x00) {
619 LOG_ERROR("Code region 0 size was pre-programmed at the factory, "
620 "mass erase command won't work.");
624 res
= nrf51_erase_all(chip
);
625 if (res
!= ERROR_OK
) {
626 LOG_ERROR("Failed to erase the chip");
627 nrf51_protect_check(bank
);
631 for (int i
= 0; i
< bank
->num_sectors
; i
++)
632 bank
->sectors
[i
].is_erased
= 1;
634 return nrf51_protect_check(bank
);
637 static int nrf51_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
641 struct nrf51_info
*chip
;
643 res
= nrf51_get_probed_chip_if_halted(bank
, &chip
);
648 uint32_t address
, value
;
650 { .address
= NRF51_FICR_CODEPAGESIZE
},
651 { .address
= NRF51_FICR_CODESIZE
},
652 { .address
= NRF51_FICR_CLENR0
},
653 { .address
= NRF51_FICR_PPFC
},
654 { .address
= NRF51_FICR_NUMRAMBLOCK
},
655 { .address
= NRF51_FICR_SIZERAMBLOCK0
},
656 { .address
= NRF51_FICR_SIZERAMBLOCK1
},
657 { .address
= NRF51_FICR_SIZERAMBLOCK2
},
658 { .address
= NRF51_FICR_SIZERAMBLOCK3
},
659 { .address
= NRF51_FICR_CONFIGID
},
660 { .address
= NRF51_FICR_DEVICEID0
},
661 { .address
= NRF51_FICR_DEVICEID1
},
662 { .address
= NRF51_FICR_ER0
},
663 { .address
= NRF51_FICR_ER1
},
664 { .address
= NRF51_FICR_ER2
},
665 { .address
= NRF51_FICR_ER3
},
666 { .address
= NRF51_FICR_IR0
},
667 { .address
= NRF51_FICR_IR1
},
668 { .address
= NRF51_FICR_IR2
},
669 { .address
= NRF51_FICR_IR3
},
670 { .address
= NRF51_FICR_DEVICEADDRTYPE
},
671 { .address
= NRF51_FICR_DEVICEADDR0
},
672 { .address
= NRF51_FICR_DEVICEADDR1
},
673 { .address
= NRF51_FICR_OVERRIDEN
},
674 { .address
= NRF51_FICR_NRF_1MBIT0
},
675 { .address
= NRF51_FICR_NRF_1MBIT1
},
676 { .address
= NRF51_FICR_NRF_1MBIT2
},
677 { .address
= NRF51_FICR_NRF_1MBIT3
},
678 { .address
= NRF51_FICR_NRF_1MBIT4
},
679 { .address
= NRF51_FICR_BLE_1MBIT0
},
680 { .address
= NRF51_FICR_BLE_1MBIT1
},
681 { .address
= NRF51_FICR_BLE_1MBIT2
},
682 { .address
= NRF51_FICR_BLE_1MBIT3
},
683 { .address
= NRF51_FICR_BLE_1MBIT4
},
685 { .address
= NRF51_UICR_CLENR0
, },
686 { .address
= NRF51_UICR_RBPCONF
},
687 { .address
= NRF51_UICR_XTALFREQ
},
688 { .address
= NRF51_UICR_FWID
},
691 for (size_t i
= 0; i
< ARRAY_SIZE(ficr
); i
++) {
692 res
= target_read_u32(chip
->target
, ficr
[i
].address
,
694 if (res
!= ERROR_OK
) {
695 LOG_ERROR("Couldn't read %" PRIx32
, ficr
[i
].address
);
700 for (size_t i
= 0; i
< ARRAY_SIZE(uicr
); i
++) {
701 res
= target_read_u32(chip
->target
, uicr
[i
].address
,
703 if (res
!= ERROR_OK
) {
704 LOG_ERROR("Couldn't read %" PRIx32
, uicr
[i
].address
);
709 snprintf(buf
, buf_size
,
710 "\n[factory information control block]\n\n"
711 "code page size: %"PRIu32
"B\n"
712 "code memory size: %"PRIu32
"kB\n"
713 "code region 0 size: %"PRIu32
"kB\n"
714 "pre-programmed code: %s\n"
715 "number of ram blocks: %"PRIu32
"\n"
716 "ram block 0 size: %"PRIu32
"B\n"
717 "ram block 1 size: %"PRIu32
"B\n"
718 "ram block 2 size: %"PRIu32
"B\n"
719 "ram block 3 size: %"PRIu32
"B\n"
720 "config id: %" PRIx32
"\n"
721 "device id: 0x%"PRIx32
"%08"PRIx32
"\n"
722 "encryption root: 0x%08"PRIx32
"%08"PRIx32
"%08"PRIx32
"%08"PRIx32
"\n"
723 "identity root: 0x%08"PRIx32
"%08"PRIx32
"%08"PRIx32
"%08"PRIx32
"\n"
724 "device address type: 0x%"PRIx32
"\n"
725 "device address: 0x%"PRIx32
"%08"PRIx32
"\n"
726 "override enable: %"PRIx32
"\n"
727 "NRF_1MBIT values: %"PRIx32
" %"PRIx32
" %"PRIx32
" %"PRIx32
" %"PRIx32
"\n"
728 "BLE_1MBIT values: %"PRIx32
" %"PRIx32
" %"PRIx32
" %"PRIx32
" %"PRIx32
"\n"
729 "\n[user information control block]\n\n"
730 "code region 0 size: %"PRIu32
"kB\n"
731 "read back protection configuration: %"PRIx32
"\n"
732 "reset value for XTALFREQ: %"PRIx32
"\n"
733 "firmware id: 0x%04"PRIx32
,
736 (ficr
[2].value
== 0xFFFFFFFF) ? 0 : ficr
[2].value
/ 1024,
737 ((ficr
[3].value
& 0xFF) == 0x00) ? "present" : "not present",
740 (ficr
[6].value
== 0xFFFFFFFF) ? 0 : ficr
[6].value
,
741 (ficr
[7].value
== 0xFFFFFFFF) ? 0 : ficr
[7].value
,
742 (ficr
[8].value
== 0xFFFFFFFF) ? 0 : ficr
[8].value
,
744 ficr
[10].value
, ficr
[11].value
,
745 ficr
[12].value
, ficr
[13].value
, ficr
[14].value
, ficr
[15].value
,
746 ficr
[16].value
, ficr
[17].value
, ficr
[18].value
, ficr
[19].value
,
748 ficr
[21].value
, ficr
[22].value
,
750 ficr
[24].value
, ficr
[25].value
, ficr
[26].value
, ficr
[27].value
, ficr
[28].value
,
751 ficr
[29].value
, ficr
[30].value
, ficr
[31].value
, ficr
[32].value
, ficr
[33].value
,
752 (uicr
[0].value
== 0xFFFFFFFF) ? 0 : uicr
[0].value
/ 1024,
753 uicr
[1].value
& 0xFFFF,
754 uicr
[2].value
& 0xFF,
755 uicr
[3].value
& 0xFFFF);
760 static const struct command_registration nrf51_exec_command_handlers
[] = {
762 .name
= "mass_erase",
763 .handler
= nrf51_handle_mass_erase_command
,
764 .mode
= COMMAND_EXEC
,
765 .help
= "Erase all flash contents of the chip.",
767 COMMAND_REGISTRATION_DONE
770 static const struct command_registration nrf51_command_handlers
[] = {
774 .help
= "nrf51 flash command group",
776 .chain
= nrf51_exec_command_handlers
,
778 COMMAND_REGISTRATION_DONE
781 struct flash_driver nrf51_flash
= {
783 .commands
= nrf51_command_handlers
,
784 .flash_bank_command
= nrf51_flash_bank_command
,
786 .erase
= nrf51_erase
,
787 .protect
= nrf51_protect
,
788 .write
= nrf51_write
,
789 .read
= default_flash_read
,
790 .probe
= nrf51_probe
,
791 .auto_probe
= nrf51_auto_probe
,
792 .erase_check
= default_flash_blank_check
,
793 .protect_check
= nrf51_protect_check
,
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)