1 /***************************************************************************
2 * Copyright (C) 2013 Synapse Product Development *
3 * Andrey Smirnov <andrew.smironv@gmail.com> *
4 * Angus Gratton <gus@projectgus.com> *
5 * Erdem U. Altunyurt <spamjunkeater@gmail.com> *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
19 ***************************************************************************/
26 #include <target/algorithm.h>
27 #include <target/armv7m.h>
28 #include <helper/types.h>
29 #include <helper/time_support.h>
32 NRF5_FLASH_BASE
= 0x00000000,
35 enum nrf5_ficr_registers
{
36 NRF5_FICR_BASE
= 0x10000000, /* Factory Information Configuration Registers */
38 #define NRF5_FICR_REG(offset) (NRF5_FICR_BASE + offset)
40 NRF5_FICR_CODEPAGESIZE
= NRF5_FICR_REG(0x010),
41 NRF5_FICR_CODESIZE
= NRF5_FICR_REG(0x014),
43 NRF51_FICR_CLENR0
= NRF5_FICR_REG(0x028),
44 NRF51_FICR_PPFC
= NRF5_FICR_REG(0x02C),
45 NRF51_FICR_NUMRAMBLOCK
= NRF5_FICR_REG(0x034),
46 NRF51_FICR_SIZERAMBLOCK0
= NRF5_FICR_REG(0x038),
47 NRF51_FICR_SIZERAMBLOCK1
= NRF5_FICR_REG(0x03C),
48 NRF51_FICR_SIZERAMBLOCK2
= NRF5_FICR_REG(0x040),
49 NRF51_FICR_SIZERAMBLOCK3
= NRF5_FICR_REG(0x044),
51 NRF5_FICR_CONFIGID
= NRF5_FICR_REG(0x05C),
52 NRF5_FICR_DEVICEID0
= NRF5_FICR_REG(0x060),
53 NRF5_FICR_DEVICEID1
= NRF5_FICR_REG(0x064),
54 NRF5_FICR_ER0
= NRF5_FICR_REG(0x080),
55 NRF5_FICR_ER1
= NRF5_FICR_REG(0x084),
56 NRF5_FICR_ER2
= NRF5_FICR_REG(0x088),
57 NRF5_FICR_ER3
= NRF5_FICR_REG(0x08C),
58 NRF5_FICR_IR0
= NRF5_FICR_REG(0x090),
59 NRF5_FICR_IR1
= NRF5_FICR_REG(0x094),
60 NRF5_FICR_IR2
= NRF5_FICR_REG(0x098),
61 NRF5_FICR_IR3
= NRF5_FICR_REG(0x09C),
62 NRF5_FICR_DEVICEADDRTYPE
= NRF5_FICR_REG(0x0A0),
63 NRF5_FICR_DEVICEADDR0
= NRF5_FICR_REG(0x0A4),
64 NRF5_FICR_DEVICEADDR1
= NRF5_FICR_REG(0x0A8),
66 NRF51_FICR_OVERRIDEN
= NRF5_FICR_REG(0x0AC),
67 NRF51_FICR_NRF_1MBIT0
= NRF5_FICR_REG(0x0B0),
68 NRF51_FICR_NRF_1MBIT1
= NRF5_FICR_REG(0x0B4),
69 NRF51_FICR_NRF_1MBIT2
= NRF5_FICR_REG(0x0B8),
70 NRF51_FICR_NRF_1MBIT3
= NRF5_FICR_REG(0x0BC),
71 NRF51_FICR_NRF_1MBIT4
= NRF5_FICR_REG(0x0C0),
72 NRF51_FICR_BLE_1MBIT0
= NRF5_FICR_REG(0x0EC),
73 NRF51_FICR_BLE_1MBIT1
= NRF5_FICR_REG(0x0F0),
74 NRF51_FICR_BLE_1MBIT2
= NRF5_FICR_REG(0x0F4),
75 NRF51_FICR_BLE_1MBIT3
= NRF5_FICR_REG(0x0F8),
76 NRF51_FICR_BLE_1MBIT4
= NRF5_FICR_REG(0x0FC),
78 /* Following registers are available on nRF52 and on nRF51 since rev 3 */
79 NRF5_FICR_INFO_PART
= NRF5_FICR_REG(0x100),
80 NRF5_FICR_INFO_VARIANT
= NRF5_FICR_REG(0x104),
81 NRF5_FICR_INFO_PACKAGE
= NRF5_FICR_REG(0x108),
82 NRF5_FICR_INFO_RAM
= NRF5_FICR_REG(0x10C),
83 NRF5_FICR_INFO_FLASH
= NRF5_FICR_REG(0x110),
86 enum nrf5_uicr_registers
{
87 NRF5_UICR_BASE
= 0x10001000, /* User Information
88 * Configuration Regsters */
90 #define NRF5_UICR_REG(offset) (NRF5_UICR_BASE + offset)
92 NRF51_UICR_CLENR0
= NRF5_UICR_REG(0x000),
93 NRF51_UICR_RBPCONF
= NRF5_UICR_REG(0x004),
94 NRF51_UICR_XTALFREQ
= NRF5_UICR_REG(0x008),
95 NRF51_UICR_FWID
= NRF5_UICR_REG(0x010),
98 enum nrf5_nvmc_registers
{
99 NRF5_NVMC_BASE
= 0x4001E000, /* Non-Volatile Memory
100 * Controller Registers */
102 #define NRF5_NVMC_REG(offset) (NRF5_NVMC_BASE + offset)
104 NRF5_NVMC_READY
= NRF5_NVMC_REG(0x400),
105 NRF5_NVMC_CONFIG
= NRF5_NVMC_REG(0x504),
106 NRF5_NVMC_ERASEPAGE
= NRF5_NVMC_REG(0x508),
107 NRF5_NVMC_ERASEALL
= NRF5_NVMC_REG(0x50C),
108 NRF5_NVMC_ERASEUICR
= NRF5_NVMC_REG(0x514),
110 NRF5_BPROT_BASE
= 0x40000000,
113 enum nrf5_nvmc_config_bits
{
114 NRF5_NVMC_CONFIG_REN
= 0x00,
115 NRF5_NVMC_CONFIG_WEN
= 0x01,
116 NRF5_NVMC_CONFIG_EEN
= 0x02,
120 struct nrf52_ficr_info
{
129 NRF5_FEATURE_SERIES_51
= 1 << 0,
130 NRF5_FEATURE_SERIES_52
= 1 << 1,
131 NRF5_FEATURE_BPROT
= 1 << 2,
132 NRF5_FEATURE_ACL_PROT
= 1 << 3,
135 struct nrf5_device_spec
{
139 const char *build_code
;
140 unsigned int flash_size_kb
;
141 enum nrf5_features features
;
148 struct nrf5_info
*chip
;
151 struct target
*target
;
153 /* chip identification stored in nrf5_probe() for use in nrf5_info() */
154 bool ficr_info_valid
;
155 struct nrf52_ficr_info ficr_info
;
156 const struct nrf5_device_spec
*spec
;
158 enum nrf5_features features
;
159 unsigned int flash_size_kb
;
160 unsigned int ram_size_kb
;
163 #define NRF51_DEVICE_DEF(id, pt, var, bcode, fsize) \
168 .build_code = bcode, \
169 .flash_size_kb = (fsize), \
170 .features = NRF5_FEATURE_SERIES_51, \
173 #define NRF5_DEVICE_DEF(id, pt, var, bcode, fsize, features) \
178 .build_code = bcode, \
179 .flash_size_kb = (fsize), \
180 .features = features, \
183 /* The known devices table below is derived from the "nRF5x series
184 * compatibility matrix" documents, which can be found in the "DocLib" of
187 * https://www.nordicsemi.com/DocLib/Content/Comp_Matrix/nRF51/latest/COMP/nrf51/nRF51422_ic_revision_overview
188 * https://www.nordicsemi.com/DocLib/Content/Comp_Matrix/nRF51/latest/COMP/nrf51/nRF51822_ic_revision_overview
189 * https://www.nordicsemi.com/DocLib/Content/Comp_Matrix/nRF51/latest/COMP/nrf51/nRF51824_ic_revision_overview
190 * https://www.nordicsemi.com/DocLib/Content/Comp_Matrix/nRF52810/latest/COMP/nrf52810/nRF52810_ic_revision_overview
191 * https://www.nordicsemi.com/DocLib/Content/Comp_Matrix/nRF52832/latest/COMP/nrf52832/ic_revision_overview
192 * https://www.nordicsemi.com/DocLib/Content/Comp_Matrix/nRF52840/latest/COMP/nrf52840/nRF52840_ic_revision_overview
194 * Up to date with Matrix v2.0, plus some additional HWIDs.
196 * The additional HWIDs apply where the build code in the matrix is
197 * shown as Gx0, Bx0, etc. In these cases the HWID in the matrix is
198 * for x==0, x!=0 means different (unspecified) HWIDs.
200 static const struct nrf5_device_spec nrf5_known_devices_table
[] = {
201 /* nRF51822 Devices (IC rev 1). */
202 NRF51_DEVICE_DEF(0x001D, "51822", "QFAA", "CA/C0", 256),
203 NRF51_DEVICE_DEF(0x0026, "51822", "QFAB", "AA", 128),
204 NRF51_DEVICE_DEF(0x0027, "51822", "QFAB", "A0", 128),
205 NRF51_DEVICE_DEF(0x0020, "51822", "CEAA", "BA", 256),
206 NRF51_DEVICE_DEF(0x002F, "51822", "CEAA", "B0", 256),
208 /* Some early nRF51-DK (PCA10028) & nRF51-Dongle (PCA10031) boards
209 with built-in jlink seem to use engineering samples not listed
210 in the nRF51 Series Compatibility Matrix V1.0. */
211 NRF51_DEVICE_DEF(0x0071, "51822", "QFAC", "AB", 256),
213 /* nRF51822 Devices (IC rev 2). */
214 NRF51_DEVICE_DEF(0x002A, "51822", "QFAA", "FA0", 256),
215 NRF51_DEVICE_DEF(0x0044, "51822", "QFAA", "GC0", 256),
216 NRF51_DEVICE_DEF(0x003C, "51822", "QFAA", "G0", 256),
217 NRF51_DEVICE_DEF(0x0057, "51822", "QFAA", "G2", 256),
218 NRF51_DEVICE_DEF(0x0058, "51822", "QFAA", "G3", 256),
219 NRF51_DEVICE_DEF(0x004C, "51822", "QFAB", "B0", 128),
220 NRF51_DEVICE_DEF(0x0040, "51822", "CEAA", "CA0", 256),
221 NRF51_DEVICE_DEF(0x0047, "51822", "CEAA", "DA0", 256),
222 NRF51_DEVICE_DEF(0x004D, "51822", "CEAA", "D00", 256),
224 /* nRF51822 Devices (IC rev 3). */
225 NRF51_DEVICE_DEF(0x0072, "51822", "QFAA", "H0", 256),
226 NRF51_DEVICE_DEF(0x00D1, "51822", "QFAA", "H2", 256),
227 NRF51_DEVICE_DEF(0x007B, "51822", "QFAB", "C0", 128),
228 NRF51_DEVICE_DEF(0x0083, "51822", "QFAC", "A0", 256),
229 NRF51_DEVICE_DEF(0x0084, "51822", "QFAC", "A1", 256),
230 NRF51_DEVICE_DEF(0x007D, "51822", "CDAB", "A0", 128),
231 NRF51_DEVICE_DEF(0x0079, "51822", "CEAA", "E0", 256),
232 NRF51_DEVICE_DEF(0x0087, "51822", "CFAC", "A0", 256),
233 NRF51_DEVICE_DEF(0x008F, "51822", "QFAA", "H1", 256),
235 /* nRF51422 Devices (IC rev 1). */
236 NRF51_DEVICE_DEF(0x001E, "51422", "QFAA", "CA", 256),
237 NRF51_DEVICE_DEF(0x0024, "51422", "QFAA", "C0", 256),
238 NRF51_DEVICE_DEF(0x0031, "51422", "CEAA", "A0A", 256),
240 /* nRF51422 Devices (IC rev 2). */
241 NRF51_DEVICE_DEF(0x002D, "51422", "QFAA", "DAA", 256),
242 NRF51_DEVICE_DEF(0x002E, "51422", "QFAA", "E0", 256),
243 NRF51_DEVICE_DEF(0x0061, "51422", "QFAB", "A00", 128),
244 NRF51_DEVICE_DEF(0x0050, "51422", "CEAA", "B0", 256),
246 /* nRF51422 Devices (IC rev 3). */
247 NRF51_DEVICE_DEF(0x0073, "51422", "QFAA", "F0", 256),
248 NRF51_DEVICE_DEF(0x007C, "51422", "QFAB", "B0", 128),
249 NRF51_DEVICE_DEF(0x0085, "51422", "QFAC", "A0", 256),
250 NRF51_DEVICE_DEF(0x0086, "51422", "QFAC", "A1", 256),
251 NRF51_DEVICE_DEF(0x007E, "51422", "CDAB", "A0", 128),
252 NRF51_DEVICE_DEF(0x007A, "51422", "CEAA", "C0", 256),
253 NRF51_DEVICE_DEF(0x0088, "51422", "CFAC", "A0", 256),
255 /* The driver fully autodects nRF52 series devices by FICR INFO,
256 * no need for nRF52xxx HWIDs in this table */
258 /* nRF52810 Devices */
259 NRF5_DEVICE_DEF(0x0142, "52810", "QFAA", "B0", 192, NRF5_FEATURE_SERIES_52
| NRF5_FEATURE_BPROT
),
260 NRF5_DEVICE_DEF(0x0143, "52810", "QCAA", "C0", 192, NRF5_FEATURE_SERIES_52
| NRF5_FEATURE_BPROT
),
262 /* nRF52832 Devices */
263 NRF5_DEVICE_DEF(0x00C7, "52832", "QFAA", "B0", 512, NRF5_FEATURE_SERIES_52
| NRF5_FEATURE_BPROT
),
264 NRF5_DEVICE_DEF(0x0139, "52832", "QFAA", "E0", 512, NRF5_FEATURE_SERIES_52
| NRF5_FEATURE_BPROT
),
265 NRF5_DEVICE_DEF(0x00E3, "52832", "CIAA", "B0", 512, NRF5_FEATURE_SERIES_52
| NRF5_FEATURE_BPROT
),
267 /* nRF52840 Devices */
268 NRF5_DEVICE_DEF(0x0150, "52840", "QIAA", "C0", 1024, NRF5_FEATURE_SERIES_52
| NRF5_FEATURE_ACL_PROT
),
272 struct nrf5_device_package
{
277 /* Newer devices have FICR INFO.PACKAGE.
278 * This table converts its value to two character code */
279 static const struct nrf5_device_package nrf5_packages_table
[] = {
286 const struct flash_driver nrf5_flash
, nrf51_flash
;
288 static int nrf5_bank_is_probed(struct flash_bank
*bank
)
290 struct nrf5_bank
*nbank
= bank
->driver_priv
;
292 assert(nbank
!= NULL
);
294 return nbank
->probed
;
296 static int nrf5_probe(struct flash_bank
*bank
);
298 static int nrf5_get_probed_chip_if_halted(struct flash_bank
*bank
, struct nrf5_info
**chip
)
300 if (bank
->target
->state
!= TARGET_HALTED
) {
301 LOG_ERROR("Target not halted");
302 return ERROR_TARGET_NOT_HALTED
;
305 struct nrf5_bank
*nbank
= bank
->driver_priv
;
308 int probed
= nrf5_bank_is_probed(bank
);
312 return nrf5_probe(bank
);
317 static int nrf5_wait_for_nvmc(struct nrf5_info
*chip
)
321 int timeout_ms
= 340;
322 int64_t ts_start
= timeval_ms();
325 res
= target_read_u32(chip
->target
, NRF5_NVMC_READY
, &ready
);
326 if (res
!= ERROR_OK
) {
327 LOG_ERROR("Couldn't read NVMC_READY register");
331 if (ready
== 0x00000001)
336 } while ((timeval_ms()-ts_start
) < timeout_ms
);
338 LOG_DEBUG("Timed out waiting for NVMC_READY");
339 return ERROR_FLASH_BUSY
;
342 static int nrf5_nvmc_erase_enable(struct nrf5_info
*chip
)
345 res
= target_write_u32(chip
->target
,
347 NRF5_NVMC_CONFIG_EEN
);
349 if (res
!= ERROR_OK
) {
350 LOG_ERROR("Failed to enable erase operation");
355 According to NVMC examples in Nordic SDK busy status must be
356 checked after writing to NVMC_CONFIG
358 res
= nrf5_wait_for_nvmc(chip
);
360 LOG_ERROR("Erase enable did not complete");
365 static int nrf5_nvmc_write_enable(struct nrf5_info
*chip
)
368 res
= target_write_u32(chip
->target
,
370 NRF5_NVMC_CONFIG_WEN
);
372 if (res
!= ERROR_OK
) {
373 LOG_ERROR("Failed to enable write operation");
378 According to NVMC examples in Nordic SDK busy status must be
379 checked after writing to NVMC_CONFIG
381 res
= nrf5_wait_for_nvmc(chip
);
383 LOG_ERROR("Write enable did not complete");
388 static int nrf5_nvmc_read_only(struct nrf5_info
*chip
)
391 res
= target_write_u32(chip
->target
,
393 NRF5_NVMC_CONFIG_REN
);
395 if (res
!= ERROR_OK
) {
396 LOG_ERROR("Failed to enable read-only operation");
400 According to NVMC examples in Nordic SDK busy status must be
401 checked after writing to NVMC_CONFIG
403 res
= nrf5_wait_for_nvmc(chip
);
405 LOG_ERROR("Read only enable did not complete");
410 static int nrf5_nvmc_generic_erase(struct nrf5_info
*chip
,
411 uint32_t erase_register
, uint32_t erase_value
)
415 res
= nrf5_nvmc_erase_enable(chip
);
419 res
= target_write_u32(chip
->target
,
425 res
= nrf5_wait_for_nvmc(chip
);
429 return nrf5_nvmc_read_only(chip
);
432 nrf5_nvmc_read_only(chip
);
434 LOG_ERROR("Failed to erase reg: 0x%08"PRIx32
" val: 0x%08"PRIx32
,
435 erase_register
, erase_value
);
439 static int nrf5_protect_check_bprot(struct flash_bank
*bank
)
441 struct nrf5_bank
*nbank
= bank
->driver_priv
;
442 struct nrf5_info
*chip
= nbank
->chip
;
444 assert(chip
!= NULL
);
446 static uint32_t nrf5_bprot_offsets
[4] = { 0x600, 0x604, 0x610, 0x614 };
447 uint32_t bprot_reg
= 0;
450 for (int i
= 0; i
< bank
->num_sectors
; i
++) {
451 unsigned int bit
= i
% 32;
453 unsigned int n_reg
= i
/ 32;
454 if (n_reg
>= ARRAY_SIZE(nrf5_bprot_offsets
))
457 res
= target_read_u32(chip
->target
, NRF5_BPROT_BASE
+ nrf5_bprot_offsets
[n_reg
], &bprot_reg
);
461 bank
->sectors
[i
].is_protected
= (bprot_reg
& (1 << bit
)) ? 1 : 0;
466 static int nrf5_protect_check(struct flash_bank
*bank
)
471 /* UICR cannot be write protected so just return early */
472 if (bank
->base
== NRF5_UICR_BASE
)
475 struct nrf5_bank
*nbank
= bank
->driver_priv
;
476 struct nrf5_info
*chip
= nbank
->chip
;
478 assert(chip
!= NULL
);
480 if (chip
->features
& NRF5_FEATURE_BPROT
)
481 return nrf5_protect_check_bprot(bank
);
483 if (!(chip
->features
& NRF5_FEATURE_SERIES_51
)) {
484 LOG_WARNING("Flash protection of this nRF device is not supported");
485 return ERROR_FLASH_OPER_UNSUPPORTED
;
488 res
= target_read_u32(chip
->target
, NRF51_FICR_CLENR0
,
490 if (res
!= ERROR_OK
) {
491 LOG_ERROR("Couldn't read code region 0 size[FICR]");
495 if (clenr0
== 0xFFFFFFFF) {
496 res
= target_read_u32(chip
->target
, NRF51_UICR_CLENR0
,
498 if (res
!= ERROR_OK
) {
499 LOG_ERROR("Couldn't read code region 0 size[UICR]");
504 for (int i
= 0; i
< bank
->num_sectors
; i
++)
505 bank
->sectors
[i
].is_protected
=
506 clenr0
!= 0xFFFFFFFF && bank
->sectors
[i
].offset
< clenr0
;
511 static int nrf5_protect(struct flash_bank
*bank
, int set
, int first
, int last
)
514 uint32_t clenr0
, ppfc
;
515 struct nrf5_info
*chip
;
517 /* UICR cannot be write protected so just bail out early */
518 if (bank
->base
== NRF5_UICR_BASE
)
521 res
= nrf5_get_probed_chip_if_halted(bank
, &chip
);
525 if (!(chip
->features
& NRF5_FEATURE_SERIES_51
)) {
526 LOG_ERROR("Flash protection setting of this nRF device is not supported");
527 return ERROR_FLASH_OPER_UNSUPPORTED
;
531 LOG_ERROR("Code region 0 must start at the begining of the bank");
535 res
= target_read_u32(chip
->target
, NRF51_FICR_PPFC
,
537 if (res
!= ERROR_OK
) {
538 LOG_ERROR("Couldn't read PPFC register");
542 if ((ppfc
& 0xFF) == 0x00) {
543 LOG_ERROR("Code region 0 size was pre-programmed at the factory, can't change flash protection settings");
547 res
= target_read_u32(chip
->target
, NRF51_UICR_CLENR0
,
549 if (res
!= ERROR_OK
) {
550 LOG_ERROR("Couldn't read code region 0 size[UICR]");
554 if (clenr0
== 0xFFFFFFFF) {
555 res
= target_write_u32(chip
->target
, NRF51_UICR_CLENR0
,
557 if (res
!= ERROR_OK
) {
558 LOG_ERROR("Couldn't write code region 0 size[UICR]");
563 LOG_ERROR("You need to perform chip erase before changing the protection settings");
566 nrf5_protect_check(bank
);
571 static bool nrf5_info_variant_to_str(uint32_t variant
, char *bf
)
573 h_u32_to_be((uint8_t *)bf
, variant
);
575 if (isalnum(bf
[0]) && isalnum(bf
[1]) && isalnum(bf
[2]) && isalnum(bf
[3]))
582 static const char *nrf5_decode_info_package(uint32_t package
)
584 for (size_t i
= 0; i
< ARRAY_SIZE(nrf5_packages_table
); i
++) {
585 if (nrf5_packages_table
[i
].package
== package
)
586 return nrf5_packages_table
[i
].code
;
591 static int nrf5_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
593 struct nrf5_bank
*nbank
= bank
->driver_priv
;
594 struct nrf5_info
*chip
= nbank
->chip
;
598 res
= snprintf(buf
, buf_size
,
599 "nRF%s-%s(build code: %s)",
600 chip
->spec
->part
, chip
->spec
->variant
, chip
->spec
->build_code
);
602 } else if (chip
->ficr_info_valid
) {
604 nrf5_info_variant_to_str(chip
->ficr_info
.variant
, variant
);
605 res
= snprintf(buf
, buf_size
,
606 "nRF%" PRIx32
"-%s%.2s(build code: %s)",
607 chip
->ficr_info
.part
,
608 nrf5_decode_info_package(chip
->ficr_info
.package
),
609 variant
, &variant
[2]);
612 res
= snprintf(buf
, buf_size
, "nRF51xxx (HWID 0x%08" PRIx32
")",
618 snprintf(buf
+ res
, buf_size
- res
, " %ukB Flash, %ukB RAM",
619 chip
->flash_size_kb
, chip
->ram_size_kb
);
623 static int nrf5_read_ficr_info(struct nrf5_info
*chip
)
626 struct target
*target
= chip
->target
;
628 chip
->ficr_info_valid
= false;
630 res
= target_read_u32(target
, NRF5_FICR_INFO_PART
, &chip
->ficr_info
.part
);
631 if (res
!= ERROR_OK
) {
632 LOG_DEBUG("Couldn't read FICR INFO.PART register");
636 uint32_t series
= chip
->ficr_info
.part
& 0xfffff000;
639 chip
->features
= NRF5_FEATURE_SERIES_51
;
643 chip
->features
= NRF5_FEATURE_SERIES_52
;
645 switch (chip
->ficr_info
.part
) {
648 chip
->features
|= NRF5_FEATURE_BPROT
;
652 chip
->features
|= NRF5_FEATURE_ACL_PROT
;
658 LOG_DEBUG("FICR INFO likely not implemented. Invalid PART value 0x%08"
659 PRIx32
, chip
->ficr_info
.part
);
660 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
663 /* Now we know the device has FICR INFO filled by something relevant:
664 * Although it is not documented, the tested nRF51 rev 3 devices
665 * have FICR INFO.PART, RAM and FLASH of the same format as nRF52.
666 * VARIANT and PACKAGE coding is unknown for a nRF51 device.
667 * nRF52 devices have FICR INFO documented and always filled. */
669 res
= target_read_u32(target
, NRF5_FICR_INFO_VARIANT
, &chip
->ficr_info
.variant
);
673 res
= target_read_u32(target
, NRF5_FICR_INFO_PACKAGE
, &chip
->ficr_info
.package
);
677 res
= target_read_u32(target
, NRF5_FICR_INFO_RAM
, &chip
->ficr_info
.ram
);
681 res
= target_read_u32(target
, NRF5_FICR_INFO_FLASH
, &chip
->ficr_info
.flash
);
685 chip
->ficr_info_valid
= true;
689 static int nrf5_get_ram_size(struct target
*target
, uint32_t *ram_size
)
695 uint32_t numramblock
;
696 res
= target_read_u32(target
, NRF51_FICR_NUMRAMBLOCK
, &numramblock
);
697 if (res
!= ERROR_OK
) {
698 LOG_DEBUG("Couldn't read FICR NUMRAMBLOCK register");
702 if (numramblock
< 1 || numramblock
> 4) {
703 LOG_DEBUG("FICR NUMRAMBLOCK strange value %" PRIx32
, numramblock
);
704 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
707 for (unsigned int i
= 0; i
< numramblock
; i
++) {
708 uint32_t sizeramblock
;
709 res
= target_read_u32(target
, NRF51_FICR_SIZERAMBLOCK0
+ sizeof(uint32_t)*i
, &sizeramblock
);
710 if (res
!= ERROR_OK
) {
711 LOG_DEBUG("Couldn't read FICR NUMRAMBLOCK register");
714 if (sizeramblock
< 1024 || sizeramblock
> 65536)
715 LOG_DEBUG("FICR SIZERAMBLOCK strange value %" PRIx32
, sizeramblock
);
717 *ram_size
+= sizeramblock
;
722 static int nrf5_probe(struct flash_bank
*bank
)
725 struct nrf5_bank
*nbank
= bank
->driver_priv
;
726 struct nrf5_info
*chip
= nbank
->chip
;
727 struct target
*target
= chip
->target
;
729 res
= target_read_u32(target
, NRF5_FICR_CONFIGID
, &chip
->hwid
);
730 if (res
!= ERROR_OK
) {
731 LOG_ERROR("Couldn't read CONFIGID register");
735 chip
->hwid
&= 0xFFFF; /* HWID is stored in the lower two
736 * bytes of the CONFIGID register */
738 /* guess a nRF51 series if the device has no FICR INFO and we don't know HWID */
739 chip
->features
= NRF5_FEATURE_SERIES_51
;
741 /* Don't bail out on error for the case that some old engineering
742 * sample has FICR INFO registers unreadable. We can proceed anyway. */
743 (void)nrf5_read_ficr_info(chip
);
746 for (size_t i
= 0; i
< ARRAY_SIZE(nrf5_known_devices_table
); i
++) {
747 if (chip
->hwid
== nrf5_known_devices_table
[i
].hwid
) {
748 chip
->spec
= &nrf5_known_devices_table
[i
];
749 chip
->features
= chip
->spec
->features
;
754 if (chip
->spec
&& chip
->ficr_info_valid
) {
755 /* check if HWID table gives the same part as FICR INFO */
756 if (chip
->ficr_info
.part
!= strtoul(chip
->spec
->part
, NULL
, 16))
757 LOG_WARNING("HWID 0x%04" PRIx32
" mismatch: FICR INFO.PART %"
758 PRIx32
, chip
->hwid
, chip
->ficr_info
.part
);
761 if (chip
->ficr_info_valid
) {
762 chip
->ram_size_kb
= chip
->ficr_info
.ram
;
765 nrf5_get_ram_size(target
, &ram_size
);
766 chip
->ram_size_kb
= ram_size
/ 1024;
769 /* The value stored in NRF5_FICR_CODEPAGESIZE is the number of bytes in one page of FLASH. */
770 uint32_t flash_page_size
;
771 res
= target_read_u32(chip
->target
, NRF5_FICR_CODEPAGESIZE
,
773 if (res
!= ERROR_OK
) {
774 LOG_ERROR("Couldn't read code page size");
778 /* Note the register name is misleading,
779 * NRF5_FICR_CODESIZE is the number of pages in flash memory, not the number of bytes! */
780 uint32_t num_sectors
;
781 res
= target_read_u32(chip
->target
, NRF5_FICR_CODESIZE
, &num_sectors
);
782 if (res
!= ERROR_OK
) {
783 LOG_ERROR("Couldn't read code memory size");
787 chip
->flash_size_kb
= num_sectors
* flash_page_size
/ 1024;
789 if (!chip
->bank
[0].probed
&& !chip
->bank
[1].probed
) {
791 nrf5_info(bank
, buf
, sizeof(buf
));
792 if (!chip
->spec
&& !chip
->ficr_info_valid
) {
793 LOG_INFO("Unknown device: %s", buf
);
801 if (bank
->base
== NRF5_FLASH_BASE
) {
803 if (chip
->spec
&& chip
->flash_size_kb
!= chip
->spec
->flash_size_kb
)
804 LOG_WARNING("Chip's reported Flash capacity does not match expected one");
805 if (chip
->ficr_info_valid
&& chip
->flash_size_kb
!= chip
->ficr_info
.flash
)
806 LOG_WARNING("Chip's reported Flash capacity does not match FICR INFO.FLASH");
808 bank
->num_sectors
= num_sectors
;
809 bank
->size
= num_sectors
* flash_page_size
;
811 bank
->sectors
= alloc_block_array(0, flash_page_size
, num_sectors
);
815 nrf5_protect_check(bank
);
817 chip
->bank
[0].probed
= true;
820 bank
->num_sectors
= 1;
821 bank
->size
= flash_page_size
;
823 bank
->sectors
= alloc_block_array(0, flash_page_size
, num_sectors
);
827 bank
->sectors
[0].is_protected
= 0;
829 chip
->bank
[1].probed
= true;
835 static int nrf5_auto_probe(struct flash_bank
*bank
)
837 int probed
= nrf5_bank_is_probed(bank
);
844 return nrf5_probe(bank
);
847 static int nrf5_erase_all(struct nrf5_info
*chip
)
849 LOG_DEBUG("Erasing all non-volatile memory");
850 return nrf5_nvmc_generic_erase(chip
,
855 static int nrf5_erase_page(struct flash_bank
*bank
,
856 struct nrf5_info
*chip
,
857 struct flash_sector
*sector
)
861 LOG_DEBUG("Erasing page at 0x%"PRIx32
, sector
->offset
);
863 if (bank
->base
== NRF5_UICR_BASE
) {
864 if (chip
->features
& NRF5_FEATURE_SERIES_51
) {
866 res
= target_read_u32(chip
->target
, NRF51_FICR_PPFC
,
868 if (res
!= ERROR_OK
) {
869 LOG_ERROR("Couldn't read PPFC register");
873 if ((ppfc
& 0xFF) == 0xFF) {
874 /* We can't erase the UICR. Double-check to
875 see if it's already erased before complaining. */
876 default_flash_blank_check(bank
);
877 if (sector
->is_erased
== 1)
880 LOG_ERROR("The chip was not pre-programmed with SoftDevice stack and UICR cannot be erased separately. Please issue mass erase before trying to write to this region");
885 res
= nrf5_nvmc_generic_erase(chip
,
891 res
= nrf5_nvmc_generic_erase(chip
,
899 static const uint8_t nrf5_flash_write_code
[] = {
900 /* See contrib/loaders/flash/cortex-m0.S */
902 0x0d, 0x68, /* ldr r5, [r1, #0] */
903 0x00, 0x2d, /* cmp r5, #0 */
904 0x0b, 0xd0, /* beq.n 1e <exit> */
905 0x4c, 0x68, /* ldr r4, [r1, #4] */
906 0xac, 0x42, /* cmp r4, r5 */
907 0xf9, 0xd0, /* beq.n 0 <wait_fifo> */
908 0x20, 0xcc, /* ldmia r4!, {r5} */
909 0x20, 0xc3, /* stmia r3!, {r5} */
910 0x94, 0x42, /* cmp r4, r2 */
911 0x01, 0xd3, /* bcc.n 18 <no_wrap> */
912 0x0c, 0x46, /* mov r4, r1 */
913 0x08, 0x34, /* adds r4, #8 */
915 0x4c, 0x60, /* str r4, [r1, #4] */
916 0x04, 0x38, /* subs r0, #4 */
917 0xf0, 0xd1, /* bne.n 0 <wait_fifo> */
919 0x00, 0xbe /* bkpt 0x0000 */
923 /* Start a low level flash write for the specified region */
924 static int nrf5_ll_flash_write(struct nrf5_info
*chip
, uint32_t address
, const uint8_t *buffer
, uint32_t bytes
)
926 struct target
*target
= chip
->target
;
927 uint32_t buffer_size
= 8192;
928 struct working_area
*write_algorithm
;
929 struct working_area
*source
;
930 struct reg_param reg_params
[4];
931 struct armv7m_algorithm armv7m_info
;
932 int retval
= ERROR_OK
;
934 LOG_DEBUG("Writing buffer to flash address=0x%"PRIx32
" bytes=0x%"PRIx32
, address
, bytes
);
935 assert(bytes
% 4 == 0);
937 /* allocate working area with flash programming code */
938 if (target_alloc_working_area(target
, sizeof(nrf5_flash_write_code
),
939 &write_algorithm
) != ERROR_OK
) {
940 LOG_WARNING("no working area available, falling back to slow memory writes");
942 for (; bytes
> 0; bytes
-= 4) {
943 retval
= target_write_memory(target
, address
, 4, 1, buffer
);
944 if (retval
!= ERROR_OK
)
947 retval
= nrf5_wait_for_nvmc(chip
);
948 if (retval
!= ERROR_OK
)
958 retval
= target_write_buffer(target
, write_algorithm
->address
,
959 sizeof(nrf5_flash_write_code
),
960 nrf5_flash_write_code
);
961 if (retval
!= ERROR_OK
)
965 while (target_alloc_working_area(target
, buffer_size
, &source
) != ERROR_OK
) {
967 buffer_size
&= ~3UL; /* Make sure it's 4 byte aligned */
968 if (buffer_size
<= 256) {
969 /* free working area, write algorithm already allocated */
970 target_free_working_area(target
, write_algorithm
);
972 LOG_WARNING("No large enough working area available, can't do block memory writes");
973 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
977 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
978 armv7m_info
.core_mode
= ARM_MODE_THREAD
;
980 init_reg_param(®_params
[0], "r0", 32, PARAM_IN_OUT
); /* byte count */
981 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
); /* buffer start */
982 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
); /* buffer end */
983 init_reg_param(®_params
[3], "r3", 32, PARAM_IN_OUT
); /* target address */
985 buf_set_u32(reg_params
[0].value
, 0, 32, bytes
);
986 buf_set_u32(reg_params
[1].value
, 0, 32, source
->address
);
987 buf_set_u32(reg_params
[2].value
, 0, 32, source
->address
+ source
->size
);
988 buf_set_u32(reg_params
[3].value
, 0, 32, address
);
990 retval
= target_run_flash_async_algorithm(target
, buffer
, bytes
/4, 4,
993 source
->address
, source
->size
,
994 write_algorithm
->address
, 0,
997 target_free_working_area(target
, source
);
998 target_free_working_area(target
, write_algorithm
);
1000 destroy_reg_param(®_params
[0]);
1001 destroy_reg_param(®_params
[1]);
1002 destroy_reg_param(®_params
[2]);
1003 destroy_reg_param(®_params
[3]);
1008 static int nrf5_write(struct flash_bank
*bank
, const uint8_t *buffer
,
1009 uint32_t offset
, uint32_t count
)
1011 struct nrf5_info
*chip
;
1013 int res
= nrf5_get_probed_chip_if_halted(bank
, &chip
);
1014 if (res
!= ERROR_OK
)
1017 assert(offset
% 4 == 0);
1018 assert(count
% 4 == 0);
1020 res
= nrf5_nvmc_write_enable(chip
);
1021 if (res
!= ERROR_OK
)
1024 res
= nrf5_ll_flash_write(chip
, bank
->base
+ offset
, buffer
, count
);
1025 if (res
!= ERROR_OK
)
1028 return nrf5_nvmc_read_only(chip
);
1031 nrf5_nvmc_read_only(chip
);
1032 LOG_ERROR("Failed to write to nrf5 flash");
1036 static int nrf5_erase(struct flash_bank
*bank
, int first
, int last
)
1039 struct nrf5_info
*chip
;
1041 res
= nrf5_get_probed_chip_if_halted(bank
, &chip
);
1042 if (res
!= ERROR_OK
)
1045 /* For each sector to be erased */
1046 for (int s
= first
; s
<= last
&& res
== ERROR_OK
; s
++)
1047 res
= nrf5_erase_page(bank
, chip
, &bank
->sectors
[s
]);
1052 static void nrf5_free_driver_priv(struct flash_bank
*bank
)
1054 struct nrf5_bank
*nbank
= bank
->driver_priv
;
1055 struct nrf5_info
*chip
= nbank
->chip
;
1060 if (chip
->refcount
== 0) {
1062 bank
->driver_priv
= NULL
;
1066 static struct nrf5_info
*nrf5_get_chip(struct target
*target
)
1068 struct flash_bank
*bank_iter
;
1070 /* iterate over nrf5 banks of same target */
1071 for (bank_iter
= flash_bank_list(); bank_iter
; bank_iter
= bank_iter
->next
) {
1072 if (bank_iter
->driver
!= &nrf5_flash
&& bank_iter
->driver
!= &nrf51_flash
)
1075 if (bank_iter
->target
!= target
)
1078 struct nrf5_bank
*nbank
= bank_iter
->driver_priv
;
1088 FLASH_BANK_COMMAND_HANDLER(nrf5_flash_bank_command
)
1090 struct nrf5_info
*chip
;
1091 struct nrf5_bank
*nbank
= NULL
;
1093 switch (bank
->base
) {
1094 case NRF5_FLASH_BASE
:
1095 case NRF5_UICR_BASE
:
1098 LOG_ERROR("Invalid bank address " TARGET_ADDR_FMT
, bank
->base
);
1102 chip
= nrf5_get_chip(bank
->target
);
1104 /* Create a new chip */
1105 chip
= calloc(1, sizeof(*chip
));
1109 chip
->target
= bank
->target
;
1112 switch (bank
->base
) {
1113 case NRF5_FLASH_BASE
:
1114 nbank
= &chip
->bank
[0];
1116 case NRF5_UICR_BASE
:
1117 nbank
= &chip
->bank
[1];
1120 assert(nbank
!= NULL
);
1124 nbank
->probed
= false;
1125 bank
->driver_priv
= nbank
;
1126 bank
->write_start_alignment
= bank
->write_end_alignment
= 4;
1131 COMMAND_HANDLER(nrf5_handle_mass_erase_command
)
1134 struct flash_bank
*bank
= NULL
;
1135 struct target
*target
= get_current_target(CMD_CTX
);
1137 res
= get_flash_bank_by_addr(target
, NRF5_FLASH_BASE
, true, &bank
);
1138 if (res
!= ERROR_OK
)
1141 assert(bank
!= NULL
);
1143 struct nrf5_info
*chip
;
1145 res
= nrf5_get_probed_chip_if_halted(bank
, &chip
);
1146 if (res
!= ERROR_OK
)
1149 if (chip
->features
& NRF5_FEATURE_SERIES_51
) {
1151 res
= target_read_u32(target
, NRF51_FICR_PPFC
,
1153 if (res
!= ERROR_OK
) {
1154 LOG_ERROR("Couldn't read PPFC register");
1158 if ((ppfc
& 0xFF) == 0x00) {
1159 LOG_ERROR("Code region 0 size was pre-programmed at the factory, "
1160 "mass erase command won't work.");
1165 res
= nrf5_erase_all(chip
);
1166 if (res
!= ERROR_OK
) {
1167 LOG_ERROR("Failed to erase the chip");
1168 nrf5_protect_check(bank
);
1172 res
= nrf5_protect_check(bank
);
1173 if (res
!= ERROR_OK
) {
1174 LOG_ERROR("Failed to check chip's write protection");
1178 res
= get_flash_bank_by_addr(target
, NRF5_UICR_BASE
, true, &bank
);
1179 if (res
!= ERROR_OK
)
1185 COMMAND_HANDLER(nrf5_handle_info_command
)
1188 struct flash_bank
*bank
= NULL
;
1189 struct target
*target
= get_current_target(CMD_CTX
);
1191 res
= get_flash_bank_by_addr(target
, NRF5_FLASH_BASE
, true, &bank
);
1192 if (res
!= ERROR_OK
)
1195 assert(bank
!= NULL
);
1197 struct nrf5_info
*chip
;
1199 res
= nrf5_get_probed_chip_if_halted(bank
, &chip
);
1200 if (res
!= ERROR_OK
)
1204 const uint32_t address
;
1207 { .address
= NRF5_FICR_CODEPAGESIZE
},
1208 { .address
= NRF5_FICR_CODESIZE
},
1209 { .address
= NRF51_FICR_CLENR0
},
1210 { .address
= NRF51_FICR_PPFC
},
1211 { .address
= NRF51_FICR_NUMRAMBLOCK
},
1212 { .address
= NRF51_FICR_SIZERAMBLOCK0
},
1213 { .address
= NRF51_FICR_SIZERAMBLOCK1
},
1214 { .address
= NRF51_FICR_SIZERAMBLOCK2
},
1215 { .address
= NRF51_FICR_SIZERAMBLOCK3
},
1216 { .address
= NRF5_FICR_CONFIGID
},
1217 { .address
= NRF5_FICR_DEVICEID0
},
1218 { .address
= NRF5_FICR_DEVICEID1
},
1219 { .address
= NRF5_FICR_ER0
},
1220 { .address
= NRF5_FICR_ER1
},
1221 { .address
= NRF5_FICR_ER2
},
1222 { .address
= NRF5_FICR_ER3
},
1223 { .address
= NRF5_FICR_IR0
},
1224 { .address
= NRF5_FICR_IR1
},
1225 { .address
= NRF5_FICR_IR2
},
1226 { .address
= NRF5_FICR_IR3
},
1227 { .address
= NRF5_FICR_DEVICEADDRTYPE
},
1228 { .address
= NRF5_FICR_DEVICEADDR0
},
1229 { .address
= NRF5_FICR_DEVICEADDR1
},
1230 { .address
= NRF51_FICR_OVERRIDEN
},
1231 { .address
= NRF51_FICR_NRF_1MBIT0
},
1232 { .address
= NRF51_FICR_NRF_1MBIT1
},
1233 { .address
= NRF51_FICR_NRF_1MBIT2
},
1234 { .address
= NRF51_FICR_NRF_1MBIT3
},
1235 { .address
= NRF51_FICR_NRF_1MBIT4
},
1236 { .address
= NRF51_FICR_BLE_1MBIT0
},
1237 { .address
= NRF51_FICR_BLE_1MBIT1
},
1238 { .address
= NRF51_FICR_BLE_1MBIT2
},
1239 { .address
= NRF51_FICR_BLE_1MBIT3
},
1240 { .address
= NRF51_FICR_BLE_1MBIT4
},
1242 { .address
= NRF51_UICR_CLENR0
, },
1243 { .address
= NRF51_UICR_RBPCONF
},
1244 { .address
= NRF51_UICR_XTALFREQ
},
1245 { .address
= NRF51_UICR_FWID
},
1248 for (size_t i
= 0; i
< ARRAY_SIZE(ficr
); i
++) {
1249 res
= target_read_u32(chip
->target
, ficr
[i
].address
,
1251 if (res
!= ERROR_OK
) {
1252 LOG_ERROR("Couldn't read %" PRIx32
, ficr
[i
].address
);
1257 for (size_t i
= 0; i
< ARRAY_SIZE(uicr
); i
++) {
1258 res
= target_read_u32(chip
->target
, uicr
[i
].address
,
1260 if (res
!= ERROR_OK
) {
1261 LOG_ERROR("Couldn't read %" PRIx32
, uicr
[i
].address
);
1267 "\n[factory information control block]\n\n"
1268 "code page size: %"PRIu32
"B\n"
1269 "code memory size: %"PRIu32
"kB\n"
1270 "code region 0 size: %"PRIu32
"kB\n"
1271 "pre-programmed code: %s\n"
1272 "number of ram blocks: %"PRIu32
"\n"
1273 "ram block 0 size: %"PRIu32
"B\n"
1274 "ram block 1 size: %"PRIu32
"B\n"
1275 "ram block 2 size: %"PRIu32
"B\n"
1276 "ram block 3 size: %"PRIu32
"B\n"
1277 "config id: %" PRIx32
"\n"
1278 "device id: 0x%"PRIx32
"%08"PRIx32
"\n"
1279 "encryption root: 0x%08"PRIx32
"%08"PRIx32
"%08"PRIx32
"%08"PRIx32
"\n"
1280 "identity root: 0x%08"PRIx32
"%08"PRIx32
"%08"PRIx32
"%08"PRIx32
"\n"
1281 "device address type: 0x%"PRIx32
"\n"
1282 "device address: 0x%"PRIx32
"%08"PRIx32
"\n"
1283 "override enable: %"PRIx32
"\n"
1284 "NRF_1MBIT values: %"PRIx32
" %"PRIx32
" %"PRIx32
" %"PRIx32
" %"PRIx32
"\n"
1285 "BLE_1MBIT values: %"PRIx32
" %"PRIx32
" %"PRIx32
" %"PRIx32
" %"PRIx32
"\n"
1286 "\n[user information control block]\n\n"
1287 "code region 0 size: %"PRIu32
"kB\n"
1288 "read back protection configuration: %"PRIx32
"\n"
1289 "reset value for XTALFREQ: %"PRIx32
"\n"
1290 "firmware id: 0x%04"PRIx32
,
1292 (ficr
[1].value
* ficr
[0].value
) / 1024,
1293 (ficr
[2].value
== 0xFFFFFFFF) ? 0 : ficr
[2].value
/ 1024,
1294 ((ficr
[3].value
& 0xFF) == 0x00) ? "present" : "not present",
1297 (ficr
[6].value
== 0xFFFFFFFF) ? 0 : ficr
[6].value
,
1298 (ficr
[7].value
== 0xFFFFFFFF) ? 0 : ficr
[7].value
,
1299 (ficr
[8].value
== 0xFFFFFFFF) ? 0 : ficr
[8].value
,
1301 ficr
[10].value
, ficr
[11].value
,
1302 ficr
[12].value
, ficr
[13].value
, ficr
[14].value
, ficr
[15].value
,
1303 ficr
[16].value
, ficr
[17].value
, ficr
[18].value
, ficr
[19].value
,
1305 ficr
[21].value
, ficr
[22].value
,
1307 ficr
[24].value
, ficr
[25].value
, ficr
[26].value
, ficr
[27].value
, ficr
[28].value
,
1308 ficr
[29].value
, ficr
[30].value
, ficr
[31].value
, ficr
[32].value
, ficr
[33].value
,
1309 (uicr
[0].value
== 0xFFFFFFFF) ? 0 : uicr
[0].value
/ 1024,
1310 uicr
[1].value
& 0xFFFF,
1311 uicr
[2].value
& 0xFF,
1312 uicr
[3].value
& 0xFFFF);
1317 static const struct command_registration nrf5_exec_command_handlers
[] = {
1319 .name
= "mass_erase",
1320 .handler
= nrf5_handle_mass_erase_command
,
1321 .mode
= COMMAND_EXEC
,
1322 .help
= "Erase all flash contents of the chip.",
1327 .handler
= nrf5_handle_info_command
,
1328 .mode
= COMMAND_EXEC
,
1329 .help
= "Show FICR and UICR info.",
1332 COMMAND_REGISTRATION_DONE
1335 static const struct command_registration nrf5_command_handlers
[] = {
1338 .mode
= COMMAND_ANY
,
1339 .help
= "nrf5 flash command group",
1341 .chain
= nrf5_exec_command_handlers
,
1345 .mode
= COMMAND_ANY
,
1346 .help
= "nrf51 flash command group",
1348 .chain
= nrf5_exec_command_handlers
,
1350 COMMAND_REGISTRATION_DONE
1353 const struct flash_driver nrf5_flash
= {
1355 .commands
= nrf5_command_handlers
,
1356 .flash_bank_command
= nrf5_flash_bank_command
,
1358 .erase
= nrf5_erase
,
1359 .protect
= nrf5_protect
,
1360 .write
= nrf5_write
,
1361 .read
= default_flash_read
,
1362 .probe
= nrf5_probe
,
1363 .auto_probe
= nrf5_auto_probe
,
1364 .erase_check
= default_flash_blank_check
,
1365 .protect_check
= nrf5_protect_check
,
1366 .free_driver_priv
= nrf5_free_driver_priv
,
1369 /* We need to retain the flash-driver name as well as the commands
1370 * for backwards compatability */
1371 const struct flash_driver nrf51_flash
= {
1373 .commands
= nrf5_command_handlers
,
1374 .flash_bank_command
= nrf5_flash_bank_command
,
1376 .erase
= nrf5_erase
,
1377 .protect
= nrf5_protect
,
1378 .write
= nrf5_write
,
1379 .read
= default_flash_read
,
1380 .probe
= nrf5_probe
,
1381 .auto_probe
= nrf5_auto_probe
,
1382 .erase_check
= default_flash_blank_check
,
1383 .protect_check
= nrf5_protect_check
,
1384 .free_driver_priv
= nrf5_free_driver_priv
,
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)