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>
31 /* Both those values are constant across the current spectrum ofr nRF5 devices */
32 #define WATCHDOG_REFRESH_REGISTER 0x40010600
33 #define WATCHDOG_REFRESH_VALUE 0x6e524635
36 NRF5_FLASH_BASE
= 0x00000000,
39 enum nrf5_ficr_registers
{
40 NRF5_FICR_BASE
= 0x10000000, /* Factory Information Configuration Registers */
42 #define NRF5_FICR_REG(offset) (NRF5_FICR_BASE + offset)
44 NRF5_FICR_CODEPAGESIZE
= NRF5_FICR_REG(0x010),
45 NRF5_FICR_CODESIZE
= NRF5_FICR_REG(0x014),
47 NRF51_FICR_CLENR0
= NRF5_FICR_REG(0x028),
48 NRF51_FICR_PPFC
= NRF5_FICR_REG(0x02C),
49 NRF51_FICR_NUMRAMBLOCK
= NRF5_FICR_REG(0x034),
50 NRF51_FICR_SIZERAMBLOCK0
= NRF5_FICR_REG(0x038),
51 NRF51_FICR_SIZERAMBLOCK1
= NRF5_FICR_REG(0x03C),
52 NRF51_FICR_SIZERAMBLOCK2
= NRF5_FICR_REG(0x040),
53 NRF51_FICR_SIZERAMBLOCK3
= NRF5_FICR_REG(0x044),
55 NRF5_FICR_CONFIGID
= NRF5_FICR_REG(0x05C),
56 NRF5_FICR_DEVICEID0
= NRF5_FICR_REG(0x060),
57 NRF5_FICR_DEVICEID1
= NRF5_FICR_REG(0x064),
58 NRF5_FICR_ER0
= NRF5_FICR_REG(0x080),
59 NRF5_FICR_ER1
= NRF5_FICR_REG(0x084),
60 NRF5_FICR_ER2
= NRF5_FICR_REG(0x088),
61 NRF5_FICR_ER3
= NRF5_FICR_REG(0x08C),
62 NRF5_FICR_IR0
= NRF5_FICR_REG(0x090),
63 NRF5_FICR_IR1
= NRF5_FICR_REG(0x094),
64 NRF5_FICR_IR2
= NRF5_FICR_REG(0x098),
65 NRF5_FICR_IR3
= NRF5_FICR_REG(0x09C),
66 NRF5_FICR_DEVICEADDRTYPE
= NRF5_FICR_REG(0x0A0),
67 NRF5_FICR_DEVICEADDR0
= NRF5_FICR_REG(0x0A4),
68 NRF5_FICR_DEVICEADDR1
= NRF5_FICR_REG(0x0A8),
70 NRF51_FICR_OVERRIDEN
= NRF5_FICR_REG(0x0AC),
71 NRF51_FICR_NRF_1MBIT0
= NRF5_FICR_REG(0x0B0),
72 NRF51_FICR_NRF_1MBIT1
= NRF5_FICR_REG(0x0B4),
73 NRF51_FICR_NRF_1MBIT2
= NRF5_FICR_REG(0x0B8),
74 NRF51_FICR_NRF_1MBIT3
= NRF5_FICR_REG(0x0BC),
75 NRF51_FICR_NRF_1MBIT4
= NRF5_FICR_REG(0x0C0),
76 NRF51_FICR_BLE_1MBIT0
= NRF5_FICR_REG(0x0EC),
77 NRF51_FICR_BLE_1MBIT1
= NRF5_FICR_REG(0x0F0),
78 NRF51_FICR_BLE_1MBIT2
= NRF5_FICR_REG(0x0F4),
79 NRF51_FICR_BLE_1MBIT3
= NRF5_FICR_REG(0x0F8),
80 NRF51_FICR_BLE_1MBIT4
= NRF5_FICR_REG(0x0FC),
82 /* Following registers are available on nRF52 and on nRF51 since rev 3 */
83 NRF5_FICR_INFO_PART
= NRF5_FICR_REG(0x100),
84 NRF5_FICR_INFO_VARIANT
= NRF5_FICR_REG(0x104),
85 NRF5_FICR_INFO_PACKAGE
= NRF5_FICR_REG(0x108),
86 NRF5_FICR_INFO_RAM
= NRF5_FICR_REG(0x10C),
87 NRF5_FICR_INFO_FLASH
= NRF5_FICR_REG(0x110),
90 enum nrf5_uicr_registers
{
91 NRF5_UICR_BASE
= 0x10001000, /* User Information
92 * Configuration Regsters */
94 #define NRF5_UICR_REG(offset) (NRF5_UICR_BASE + offset)
96 NRF51_UICR_CLENR0
= NRF5_UICR_REG(0x000),
97 NRF51_UICR_RBPCONF
= NRF5_UICR_REG(0x004),
98 NRF51_UICR_XTALFREQ
= NRF5_UICR_REG(0x008),
99 NRF51_UICR_FWID
= NRF5_UICR_REG(0x010),
102 enum nrf5_nvmc_registers
{
103 NRF5_NVMC_BASE
= 0x4001E000, /* Non-Volatile Memory
104 * Controller Registers */
106 #define NRF5_NVMC_REG(offset) (NRF5_NVMC_BASE + offset)
108 NRF5_NVMC_READY
= NRF5_NVMC_REG(0x400),
109 NRF5_NVMC_CONFIG
= NRF5_NVMC_REG(0x504),
110 NRF5_NVMC_ERASEPAGE
= NRF5_NVMC_REG(0x508),
111 NRF5_NVMC_ERASEALL
= NRF5_NVMC_REG(0x50C),
112 NRF5_NVMC_ERASEUICR
= NRF5_NVMC_REG(0x514),
114 NRF5_BPROT_BASE
= 0x40000000,
117 enum nrf5_nvmc_config_bits
{
118 NRF5_NVMC_CONFIG_REN
= 0x00,
119 NRF5_NVMC_CONFIG_WEN
= 0x01,
120 NRF5_NVMC_CONFIG_EEN
= 0x02,
124 struct nrf52_ficr_info
{
133 NRF5_FEATURE_SERIES_51
= 1 << 0,
134 NRF5_FEATURE_SERIES_52
= 1 << 1,
135 NRF5_FEATURE_BPROT
= 1 << 2,
136 NRF5_FEATURE_ACL_PROT
= 1 << 3,
139 struct nrf5_device_spec
{
143 const char *build_code
;
144 unsigned int flash_size_kb
;
145 enum nrf5_features features
;
152 struct nrf5_info
*chip
;
155 struct target
*target
;
157 /* chip identification stored in nrf5_probe() for use in nrf5_info() */
158 bool ficr_info_valid
;
159 struct nrf52_ficr_info ficr_info
;
160 const struct nrf5_device_spec
*spec
;
162 enum nrf5_features features
;
163 unsigned int flash_size_kb
;
164 unsigned int ram_size_kb
;
167 #define NRF51_DEVICE_DEF(id, pt, var, bcode, fsize) \
172 .build_code = bcode, \
173 .flash_size_kb = (fsize), \
174 .features = NRF5_FEATURE_SERIES_51, \
177 #define NRF5_DEVICE_DEF(id, pt, var, bcode, fsize, features) \
182 .build_code = bcode, \
183 .flash_size_kb = (fsize), \
184 .features = features, \
187 /* The known devices table below is derived from the "nRF5x series
188 * compatibility matrix" documents, which can be found in the "DocLib" of
191 * https://www.nordicsemi.com/DocLib/Content/Comp_Matrix/nRF51/latest/COMP/nrf51/nRF51422_ic_revision_overview
192 * https://www.nordicsemi.com/DocLib/Content/Comp_Matrix/nRF51/latest/COMP/nrf51/nRF51822_ic_revision_overview
193 * https://www.nordicsemi.com/DocLib/Content/Comp_Matrix/nRF51/latest/COMP/nrf51/nRF51824_ic_revision_overview
194 * https://www.nordicsemi.com/DocLib/Content/Comp_Matrix/nRF52810/latest/COMP/nrf52810/nRF52810_ic_revision_overview
195 * https://www.nordicsemi.com/DocLib/Content/Comp_Matrix/nRF52832/latest/COMP/nrf52832/ic_revision_overview
196 * https://www.nordicsemi.com/DocLib/Content/Comp_Matrix/nRF52840/latest/COMP/nrf52840/nRF52840_ic_revision_overview
198 * Up to date with Matrix v2.0, plus some additional HWIDs.
200 * The additional HWIDs apply where the build code in the matrix is
201 * shown as Gx0, Bx0, etc. In these cases the HWID in the matrix is
202 * for x==0, x!=0 means different (unspecified) HWIDs.
204 static const struct nrf5_device_spec nrf5_known_devices_table
[] = {
205 /* nRF51822 Devices (IC rev 1). */
206 NRF51_DEVICE_DEF(0x001D, "51822", "QFAA", "CA/C0", 256),
207 NRF51_DEVICE_DEF(0x0026, "51822", "QFAB", "AA", 128),
208 NRF51_DEVICE_DEF(0x0027, "51822", "QFAB", "A0", 128),
209 NRF51_DEVICE_DEF(0x0020, "51822", "CEAA", "BA", 256),
210 NRF51_DEVICE_DEF(0x002F, "51822", "CEAA", "B0", 256),
212 /* Some early nRF51-DK (PCA10028) & nRF51-Dongle (PCA10031) boards
213 with built-in jlink seem to use engineering samples not listed
214 in the nRF51 Series Compatibility Matrix V1.0. */
215 NRF51_DEVICE_DEF(0x0071, "51822", "QFAC", "AB", 256),
217 /* nRF51822 Devices (IC rev 2). */
218 NRF51_DEVICE_DEF(0x002A, "51822", "QFAA", "FA0", 256),
219 NRF51_DEVICE_DEF(0x0044, "51822", "QFAA", "GC0", 256),
220 NRF51_DEVICE_DEF(0x003C, "51822", "QFAA", "G0", 256),
221 NRF51_DEVICE_DEF(0x0057, "51822", "QFAA", "G2", 256),
222 NRF51_DEVICE_DEF(0x0058, "51822", "QFAA", "G3", 256),
223 NRF51_DEVICE_DEF(0x004C, "51822", "QFAB", "B0", 128),
224 NRF51_DEVICE_DEF(0x0040, "51822", "CEAA", "CA0", 256),
225 NRF51_DEVICE_DEF(0x0047, "51822", "CEAA", "DA0", 256),
226 NRF51_DEVICE_DEF(0x004D, "51822", "CEAA", "D00", 256),
228 /* nRF51822 Devices (IC rev 3). */
229 NRF51_DEVICE_DEF(0x0072, "51822", "QFAA", "H0", 256),
230 NRF51_DEVICE_DEF(0x00D1, "51822", "QFAA", "H2", 256),
231 NRF51_DEVICE_DEF(0x007B, "51822", "QFAB", "C0", 128),
232 NRF51_DEVICE_DEF(0x0083, "51822", "QFAC", "A0", 256),
233 NRF51_DEVICE_DEF(0x0084, "51822", "QFAC", "A1", 256),
234 NRF51_DEVICE_DEF(0x007D, "51822", "CDAB", "A0", 128),
235 NRF51_DEVICE_DEF(0x0079, "51822", "CEAA", "E0", 256),
236 NRF51_DEVICE_DEF(0x0087, "51822", "CFAC", "A0", 256),
237 NRF51_DEVICE_DEF(0x008F, "51822", "QFAA", "H1", 256),
239 /* nRF51422 Devices (IC rev 1). */
240 NRF51_DEVICE_DEF(0x001E, "51422", "QFAA", "CA", 256),
241 NRF51_DEVICE_DEF(0x0024, "51422", "QFAA", "C0", 256),
242 NRF51_DEVICE_DEF(0x0031, "51422", "CEAA", "A0A", 256),
244 /* nRF51422 Devices (IC rev 2). */
245 NRF51_DEVICE_DEF(0x002D, "51422", "QFAA", "DAA", 256),
246 NRF51_DEVICE_DEF(0x002E, "51422", "QFAA", "E0", 256),
247 NRF51_DEVICE_DEF(0x0061, "51422", "QFAB", "A00", 128),
248 NRF51_DEVICE_DEF(0x0050, "51422", "CEAA", "B0", 256),
250 /* nRF51422 Devices (IC rev 3). */
251 NRF51_DEVICE_DEF(0x0073, "51422", "QFAA", "F0", 256),
252 NRF51_DEVICE_DEF(0x007C, "51422", "QFAB", "B0", 128),
253 NRF51_DEVICE_DEF(0x0085, "51422", "QFAC", "A0", 256),
254 NRF51_DEVICE_DEF(0x0086, "51422", "QFAC", "A1", 256),
255 NRF51_DEVICE_DEF(0x007E, "51422", "CDAB", "A0", 128),
256 NRF51_DEVICE_DEF(0x007A, "51422", "CEAA", "C0", 256),
257 NRF51_DEVICE_DEF(0x0088, "51422", "CFAC", "A0", 256),
259 /* The driver fully autodects nRF52 series devices by FICR INFO,
260 * no need for nRF52xxx HWIDs in this table */
262 /* nRF52810 Devices */
263 NRF5_DEVICE_DEF(0x0142, "52810", "QFAA", "B0", 192, NRF5_FEATURE_SERIES_52
| NRF5_FEATURE_BPROT
),
264 NRF5_DEVICE_DEF(0x0143, "52810", "QCAA", "C0", 192, NRF5_FEATURE_SERIES_52
| NRF5_FEATURE_BPROT
),
266 /* nRF52832 Devices */
267 NRF5_DEVICE_DEF(0x00C7, "52832", "QFAA", "B0", 512, NRF5_FEATURE_SERIES_52
| NRF5_FEATURE_BPROT
),
268 NRF5_DEVICE_DEF(0x0139, "52832", "QFAA", "E0", 512, NRF5_FEATURE_SERIES_52
| NRF5_FEATURE_BPROT
),
269 NRF5_DEVICE_DEF(0x00E3, "52832", "CIAA", "B0", 512, NRF5_FEATURE_SERIES_52
| NRF5_FEATURE_BPROT
),
271 /* nRF52840 Devices */
272 NRF5_DEVICE_DEF(0x0150, "52840", "QIAA", "C0", 1024, NRF5_FEATURE_SERIES_52
| NRF5_FEATURE_ACL_PROT
),
276 struct nrf5_device_package
{
281 /* Newer devices have FICR INFO.PACKAGE.
282 * This table converts its value to two character code */
283 static const struct nrf5_device_package nrf5_packages_table
[] = {
290 const struct flash_driver nrf5_flash
, nrf51_flash
;
292 static int nrf5_bank_is_probed(struct flash_bank
*bank
)
294 struct nrf5_bank
*nbank
= bank
->driver_priv
;
296 assert(nbank
!= NULL
);
298 return nbank
->probed
;
300 static int nrf5_probe(struct flash_bank
*bank
);
302 static int nrf5_get_probed_chip_if_halted(struct flash_bank
*bank
, struct nrf5_info
**chip
)
304 if (bank
->target
->state
!= TARGET_HALTED
) {
305 LOG_ERROR("Target not halted");
306 return ERROR_TARGET_NOT_HALTED
;
309 struct nrf5_bank
*nbank
= bank
->driver_priv
;
312 int probed
= nrf5_bank_is_probed(bank
);
316 return nrf5_probe(bank
);
321 static int nrf5_wait_for_nvmc(struct nrf5_info
*chip
)
325 int timeout_ms
= 340;
326 int64_t ts_start
= timeval_ms();
329 res
= target_read_u32(chip
->target
, NRF5_NVMC_READY
, &ready
);
330 if (res
!= ERROR_OK
) {
331 LOG_ERROR("Couldn't read NVMC_READY register");
335 if (ready
== 0x00000001)
340 } while ((timeval_ms()-ts_start
) < timeout_ms
);
342 LOG_DEBUG("Timed out waiting for NVMC_READY");
343 return ERROR_FLASH_BUSY
;
346 static int nrf5_nvmc_erase_enable(struct nrf5_info
*chip
)
349 res
= target_write_u32(chip
->target
,
351 NRF5_NVMC_CONFIG_EEN
);
353 if (res
!= ERROR_OK
) {
354 LOG_ERROR("Failed to enable erase operation");
359 According to NVMC examples in Nordic SDK busy status must be
360 checked after writing to NVMC_CONFIG
362 res
= nrf5_wait_for_nvmc(chip
);
364 LOG_ERROR("Erase enable did not complete");
369 static int nrf5_nvmc_write_enable(struct nrf5_info
*chip
)
372 res
= target_write_u32(chip
->target
,
374 NRF5_NVMC_CONFIG_WEN
);
376 if (res
!= ERROR_OK
) {
377 LOG_ERROR("Failed to enable write operation");
382 According to NVMC examples in Nordic SDK busy status must be
383 checked after writing to NVMC_CONFIG
385 res
= nrf5_wait_for_nvmc(chip
);
387 LOG_ERROR("Write enable did not complete");
392 static int nrf5_nvmc_read_only(struct nrf5_info
*chip
)
395 res
= target_write_u32(chip
->target
,
397 NRF5_NVMC_CONFIG_REN
);
399 if (res
!= ERROR_OK
) {
400 LOG_ERROR("Failed to enable read-only operation");
404 According to NVMC examples in Nordic SDK busy status must be
405 checked after writing to NVMC_CONFIG
407 res
= nrf5_wait_for_nvmc(chip
);
409 LOG_ERROR("Read only enable did not complete");
414 static int nrf5_nvmc_generic_erase(struct nrf5_info
*chip
,
415 uint32_t erase_register
, uint32_t erase_value
)
419 res
= nrf5_nvmc_erase_enable(chip
);
423 res
= target_write_u32(chip
->target
,
429 res
= nrf5_wait_for_nvmc(chip
);
433 return nrf5_nvmc_read_only(chip
);
436 nrf5_nvmc_read_only(chip
);
438 LOG_ERROR("Failed to erase reg: 0x%08"PRIx32
" val: 0x%08"PRIx32
,
439 erase_register
, erase_value
);
443 static int nrf5_protect_check_bprot(struct flash_bank
*bank
)
445 struct nrf5_bank
*nbank
= bank
->driver_priv
;
446 struct nrf5_info
*chip
= nbank
->chip
;
448 assert(chip
!= NULL
);
450 static uint32_t nrf5_bprot_offsets
[4] = { 0x600, 0x604, 0x610, 0x614 };
451 uint32_t bprot_reg
= 0;
454 for (int i
= 0; i
< bank
->num_sectors
; i
++) {
455 unsigned int bit
= i
% 32;
457 unsigned int n_reg
= i
/ 32;
458 if (n_reg
>= ARRAY_SIZE(nrf5_bprot_offsets
))
461 res
= target_read_u32(chip
->target
, NRF5_BPROT_BASE
+ nrf5_bprot_offsets
[n_reg
], &bprot_reg
);
465 bank
->sectors
[i
].is_protected
= (bprot_reg
& (1 << bit
)) ? 1 : 0;
470 static int nrf5_protect_check(struct flash_bank
*bank
)
475 /* UICR cannot be write protected so just return early */
476 if (bank
->base
== NRF5_UICR_BASE
)
479 struct nrf5_bank
*nbank
= bank
->driver_priv
;
480 struct nrf5_info
*chip
= nbank
->chip
;
482 assert(chip
!= NULL
);
484 if (chip
->features
& NRF5_FEATURE_BPROT
)
485 return nrf5_protect_check_bprot(bank
);
487 if (!(chip
->features
& NRF5_FEATURE_SERIES_51
)) {
488 LOG_WARNING("Flash protection of this nRF device is not supported");
489 return ERROR_FLASH_OPER_UNSUPPORTED
;
492 res
= target_read_u32(chip
->target
, NRF51_FICR_CLENR0
,
494 if (res
!= ERROR_OK
) {
495 LOG_ERROR("Couldn't read code region 0 size[FICR]");
499 if (clenr0
== 0xFFFFFFFF) {
500 res
= target_read_u32(chip
->target
, NRF51_UICR_CLENR0
,
502 if (res
!= ERROR_OK
) {
503 LOG_ERROR("Couldn't read code region 0 size[UICR]");
508 for (int i
= 0; i
< bank
->num_sectors
; i
++)
509 bank
->sectors
[i
].is_protected
=
510 clenr0
!= 0xFFFFFFFF && bank
->sectors
[i
].offset
< clenr0
;
515 static int nrf5_protect(struct flash_bank
*bank
, int set
, int first
, int last
)
518 uint32_t clenr0
, ppfc
;
519 struct nrf5_info
*chip
;
521 /* UICR cannot be write protected so just bail out early */
522 if (bank
->base
== NRF5_UICR_BASE
)
525 res
= nrf5_get_probed_chip_if_halted(bank
, &chip
);
529 if (!(chip
->features
& NRF5_FEATURE_SERIES_51
)) {
530 LOG_ERROR("Flash protection setting of this nRF device is not supported");
531 return ERROR_FLASH_OPER_UNSUPPORTED
;
535 LOG_ERROR("Code region 0 must start at the begining of the bank");
539 res
= target_read_u32(chip
->target
, NRF51_FICR_PPFC
,
541 if (res
!= ERROR_OK
) {
542 LOG_ERROR("Couldn't read PPFC register");
546 if ((ppfc
& 0xFF) == 0x00) {
547 LOG_ERROR("Code region 0 size was pre-programmed at the factory, can't change flash protection settings");
551 res
= target_read_u32(chip
->target
, NRF51_UICR_CLENR0
,
553 if (res
!= ERROR_OK
) {
554 LOG_ERROR("Couldn't read code region 0 size[UICR]");
558 if (clenr0
== 0xFFFFFFFF) {
559 res
= target_write_u32(chip
->target
, NRF51_UICR_CLENR0
,
561 if (res
!= ERROR_OK
) {
562 LOG_ERROR("Couldn't write code region 0 size[UICR]");
567 LOG_ERROR("You need to perform chip erase before changing the protection settings");
570 nrf5_protect_check(bank
);
575 static bool nrf5_info_variant_to_str(uint32_t variant
, char *bf
)
579 h_u32_to_be(b
, variant
);
580 if (isalnum(b
[0]) && isalnum(b
[1]) && isalnum(b
[2]) && isalnum(b
[3])) {
590 static const char *nrf5_decode_info_package(uint32_t package
)
592 for (size_t i
= 0; i
< ARRAY_SIZE(nrf5_packages_table
); i
++) {
593 if (nrf5_packages_table
[i
].package
== package
)
594 return nrf5_packages_table
[i
].code
;
599 static int nrf5_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
601 struct nrf5_bank
*nbank
= bank
->driver_priv
;
602 struct nrf5_info
*chip
= nbank
->chip
;
606 res
= snprintf(buf
, buf_size
,
607 "nRF%s-%s(build code: %s)",
608 chip
->spec
->part
, chip
->spec
->variant
, chip
->spec
->build_code
);
610 } else if (chip
->ficr_info_valid
) {
612 nrf5_info_variant_to_str(chip
->ficr_info
.variant
, variant
);
613 res
= snprintf(buf
, buf_size
,
614 "nRF%" PRIx32
"-%s%.2s(build code: %s)",
615 chip
->ficr_info
.part
,
616 nrf5_decode_info_package(chip
->ficr_info
.package
),
617 variant
, &variant
[2]);
620 res
= snprintf(buf
, buf_size
, "nRF51xxx (HWID 0x%08" PRIx32
")",
626 snprintf(buf
+ res
, buf_size
- res
, " %ukB Flash, %ukB RAM",
627 chip
->flash_size_kb
, chip
->ram_size_kb
);
631 static int nrf5_read_ficr_info(struct nrf5_info
*chip
)
634 struct target
*target
= chip
->target
;
636 chip
->ficr_info_valid
= false;
638 res
= target_read_u32(target
, NRF5_FICR_INFO_PART
, &chip
->ficr_info
.part
);
639 if (res
!= ERROR_OK
) {
640 LOG_DEBUG("Couldn't read FICR INFO.PART register");
644 uint32_t series
= chip
->ficr_info
.part
& 0xfffff000;
647 chip
->features
= NRF5_FEATURE_SERIES_51
;
651 chip
->features
= NRF5_FEATURE_SERIES_52
;
653 switch (chip
->ficr_info
.part
) {
656 chip
->features
|= NRF5_FEATURE_BPROT
;
660 chip
->features
|= NRF5_FEATURE_ACL_PROT
;
666 LOG_DEBUG("FICR INFO likely not implemented. Invalid PART value 0x%08"
667 PRIx32
, chip
->ficr_info
.part
);
668 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
671 /* Now we know the device has FICR INFO filled by something relevant:
672 * Although it is not documented, the tested nRF51 rev 3 devices
673 * have FICR INFO.PART, RAM and FLASH of the same format as nRF52.
674 * VARIANT and PACKAGE coding is unknown for a nRF51 device.
675 * nRF52 devices have FICR INFO documented and always filled. */
677 res
= target_read_u32(target
, NRF5_FICR_INFO_VARIANT
, &chip
->ficr_info
.variant
);
681 res
= target_read_u32(target
, NRF5_FICR_INFO_PACKAGE
, &chip
->ficr_info
.package
);
685 res
= target_read_u32(target
, NRF5_FICR_INFO_RAM
, &chip
->ficr_info
.ram
);
689 res
= target_read_u32(target
, NRF5_FICR_INFO_FLASH
, &chip
->ficr_info
.flash
);
693 chip
->ficr_info_valid
= true;
697 static int nrf5_get_ram_size(struct target
*target
, uint32_t *ram_size
)
703 uint32_t numramblock
;
704 res
= target_read_u32(target
, NRF51_FICR_NUMRAMBLOCK
, &numramblock
);
705 if (res
!= ERROR_OK
) {
706 LOG_DEBUG("Couldn't read FICR NUMRAMBLOCK register");
710 if (numramblock
< 1 || numramblock
> 4) {
711 LOG_DEBUG("FICR NUMRAMBLOCK strange value %" PRIx32
, numramblock
);
712 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
715 for (unsigned int i
= 0; i
< numramblock
; i
++) {
716 uint32_t sizeramblock
;
717 res
= target_read_u32(target
, NRF51_FICR_SIZERAMBLOCK0
+ sizeof(uint32_t)*i
, &sizeramblock
);
718 if (res
!= ERROR_OK
) {
719 LOG_DEBUG("Couldn't read FICR NUMRAMBLOCK register");
722 if (sizeramblock
< 1024 || sizeramblock
> 65536)
723 LOG_DEBUG("FICR SIZERAMBLOCK strange value %" PRIx32
, sizeramblock
);
725 *ram_size
+= sizeramblock
;
730 static int nrf5_probe(struct flash_bank
*bank
)
733 struct nrf5_bank
*nbank
= bank
->driver_priv
;
734 struct nrf5_info
*chip
= nbank
->chip
;
735 struct target
*target
= chip
->target
;
737 res
= target_read_u32(target
, NRF5_FICR_CONFIGID
, &chip
->hwid
);
738 if (res
!= ERROR_OK
) {
739 LOG_ERROR("Couldn't read CONFIGID register");
743 chip
->hwid
&= 0xFFFF; /* HWID is stored in the lower two
744 * bytes of the CONFIGID register */
746 /* guess a nRF51 series if the device has no FICR INFO and we don't know HWID */
747 chip
->features
= NRF5_FEATURE_SERIES_51
;
749 /* Don't bail out on error for the case that some old engineering
750 * sample has FICR INFO registers unreadable. We can proceed anyway. */
751 (void)nrf5_read_ficr_info(chip
);
754 for (size_t i
= 0; i
< ARRAY_SIZE(nrf5_known_devices_table
); i
++) {
755 if (chip
->hwid
== nrf5_known_devices_table
[i
].hwid
) {
756 chip
->spec
= &nrf5_known_devices_table
[i
];
757 chip
->features
= chip
->spec
->features
;
762 if (chip
->spec
&& chip
->ficr_info_valid
) {
763 /* check if HWID table gives the same part as FICR INFO */
764 if (chip
->ficr_info
.part
!= strtoul(chip
->spec
->part
, NULL
, 16))
765 LOG_WARNING("HWID 0x%04" PRIx32
" mismatch: FICR INFO.PART %"
766 PRIx32
, chip
->hwid
, chip
->ficr_info
.part
);
769 if (chip
->ficr_info_valid
) {
770 chip
->ram_size_kb
= chip
->ficr_info
.ram
;
773 nrf5_get_ram_size(target
, &ram_size
);
774 chip
->ram_size_kb
= ram_size
/ 1024;
777 /* The value stored in NRF5_FICR_CODEPAGESIZE is the number of bytes in one page of FLASH. */
778 uint32_t flash_page_size
;
779 res
= target_read_u32(chip
->target
, NRF5_FICR_CODEPAGESIZE
,
781 if (res
!= ERROR_OK
) {
782 LOG_ERROR("Couldn't read code page size");
786 /* Note the register name is misleading,
787 * NRF5_FICR_CODESIZE is the number of pages in flash memory, not the number of bytes! */
788 uint32_t num_sectors
;
789 res
= target_read_u32(chip
->target
, NRF5_FICR_CODESIZE
, &num_sectors
);
790 if (res
!= ERROR_OK
) {
791 LOG_ERROR("Couldn't read code memory size");
795 chip
->flash_size_kb
= num_sectors
* flash_page_size
/ 1024;
797 if (!chip
->bank
[0].probed
&& !chip
->bank
[1].probed
) {
799 nrf5_info(bank
, buf
, sizeof(buf
));
800 if (!chip
->spec
&& !chip
->ficr_info_valid
) {
801 LOG_INFO("Unknown device: %s", buf
);
809 if (bank
->base
== NRF5_FLASH_BASE
) {
811 if (chip
->spec
&& chip
->flash_size_kb
!= chip
->spec
->flash_size_kb
)
812 LOG_WARNING("Chip's reported Flash capacity does not match expected one");
813 if (chip
->ficr_info_valid
&& chip
->flash_size_kb
!= chip
->ficr_info
.flash
)
814 LOG_WARNING("Chip's reported Flash capacity does not match FICR INFO.FLASH");
816 bank
->num_sectors
= num_sectors
;
817 bank
->size
= num_sectors
* flash_page_size
;
819 bank
->sectors
= alloc_block_array(0, flash_page_size
, num_sectors
);
823 nrf5_protect_check(bank
);
825 chip
->bank
[0].probed
= true;
828 bank
->num_sectors
= 1;
829 bank
->size
= flash_page_size
;
831 bank
->sectors
= alloc_block_array(0, flash_page_size
, num_sectors
);
835 bank
->sectors
[0].is_protected
= 0;
837 chip
->bank
[1].probed
= true;
843 static int nrf5_auto_probe(struct flash_bank
*bank
)
845 int probed
= nrf5_bank_is_probed(bank
);
852 return nrf5_probe(bank
);
855 static int nrf5_erase_all(struct nrf5_info
*chip
)
857 LOG_DEBUG("Erasing all non-volatile memory");
858 return nrf5_nvmc_generic_erase(chip
,
863 static int nrf5_erase_page(struct flash_bank
*bank
,
864 struct nrf5_info
*chip
,
865 struct flash_sector
*sector
)
869 LOG_DEBUG("Erasing page at 0x%"PRIx32
, sector
->offset
);
871 if (bank
->base
== NRF5_UICR_BASE
) {
872 if (chip
->features
& NRF5_FEATURE_SERIES_51
) {
874 res
= target_read_u32(chip
->target
, NRF51_FICR_PPFC
,
876 if (res
!= ERROR_OK
) {
877 LOG_ERROR("Couldn't read PPFC register");
881 if ((ppfc
& 0xFF) == 0xFF) {
882 /* We can't erase the UICR. Double-check to
883 see if it's already erased before complaining. */
884 default_flash_blank_check(bank
);
885 if (sector
->is_erased
== 1)
888 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");
893 res
= nrf5_nvmc_generic_erase(chip
,
899 res
= nrf5_nvmc_generic_erase(chip
,
907 /* Start a low level flash write for the specified region */
908 static int nrf5_ll_flash_write(struct nrf5_info
*chip
, uint32_t address
, const uint8_t *buffer
, uint32_t bytes
)
910 struct target
*target
= chip
->target
;
911 uint32_t buffer_size
= 8192;
912 struct working_area
*write_algorithm
;
913 struct working_area
*source
;
914 struct reg_param reg_params
[6];
915 struct armv7m_algorithm armv7m_info
;
916 int retval
= ERROR_OK
;
918 static const uint8_t nrf5_flash_write_code
[] = {
919 #include "../../../contrib/loaders/flash/nrf5/nrf5.inc"
922 LOG_DEBUG("Writing buffer to flash address=0x%"PRIx32
" bytes=0x%"PRIx32
, address
, bytes
);
923 assert(bytes
% 4 == 0);
925 /* allocate working area with flash programming code */
926 if (target_alloc_working_area(target
, sizeof(nrf5_flash_write_code
),
927 &write_algorithm
) != ERROR_OK
) {
928 LOG_WARNING("no working area available, falling back to slow memory writes");
930 for (; bytes
> 0; bytes
-= 4) {
931 retval
= target_write_memory(target
, address
, 4, 1, buffer
);
932 if (retval
!= ERROR_OK
)
935 retval
= nrf5_wait_for_nvmc(chip
);
936 if (retval
!= ERROR_OK
)
946 retval
= target_write_buffer(target
, write_algorithm
->address
,
947 sizeof(nrf5_flash_write_code
),
948 nrf5_flash_write_code
);
949 if (retval
!= ERROR_OK
)
953 while (target_alloc_working_area(target
, buffer_size
, &source
) != ERROR_OK
) {
955 buffer_size
&= ~3UL; /* Make sure it's 4 byte aligned */
956 if (buffer_size
<= 256) {
957 /* free working area, write algorithm already allocated */
958 target_free_working_area(target
, write_algorithm
);
960 LOG_WARNING("No large enough working area available, can't do block memory writes");
961 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
965 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
966 armv7m_info
.core_mode
= ARM_MODE_THREAD
;
968 init_reg_param(®_params
[0], "r0", 32, PARAM_IN_OUT
); /* byte count */
969 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
); /* buffer start */
970 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
); /* buffer end */
971 init_reg_param(®_params
[3], "r3", 32, PARAM_IN_OUT
); /* target address */
972 init_reg_param(®_params
[4], "r6", 32, PARAM_OUT
); /* watchdog refresh value */
973 init_reg_param(®_params
[5], "r7", 32, PARAM_OUT
); /* watchdog refresh register address */
975 buf_set_u32(reg_params
[0].value
, 0, 32, bytes
);
976 buf_set_u32(reg_params
[1].value
, 0, 32, source
->address
);
977 buf_set_u32(reg_params
[2].value
, 0, 32, source
->address
+ source
->size
);
978 buf_set_u32(reg_params
[3].value
, 0, 32, address
);
979 buf_set_u32(reg_params
[4].value
, 0, 32, WATCHDOG_REFRESH_VALUE
);
980 buf_set_u32(reg_params
[5].value
, 0, 32, WATCHDOG_REFRESH_REGISTER
);
982 retval
= target_run_flash_async_algorithm(target
, buffer
, bytes
/4, 4,
984 ARRAY_SIZE(reg_params
), reg_params
,
985 source
->address
, source
->size
,
986 write_algorithm
->address
, 0,
989 target_free_working_area(target
, source
);
990 target_free_working_area(target
, write_algorithm
);
992 destroy_reg_param(®_params
[0]);
993 destroy_reg_param(®_params
[1]);
994 destroy_reg_param(®_params
[2]);
995 destroy_reg_param(®_params
[3]);
996 destroy_reg_param(®_params
[4]);
997 destroy_reg_param(®_params
[5]);
1002 static int nrf5_write(struct flash_bank
*bank
, const uint8_t *buffer
,
1003 uint32_t offset
, uint32_t count
)
1005 struct nrf5_info
*chip
;
1007 int res
= nrf5_get_probed_chip_if_halted(bank
, &chip
);
1008 if (res
!= ERROR_OK
)
1011 assert(offset
% 4 == 0);
1012 assert(count
% 4 == 0);
1014 res
= nrf5_nvmc_write_enable(chip
);
1015 if (res
!= ERROR_OK
)
1018 res
= nrf5_ll_flash_write(chip
, bank
->base
+ offset
, buffer
, count
);
1019 if (res
!= ERROR_OK
)
1022 return nrf5_nvmc_read_only(chip
);
1025 nrf5_nvmc_read_only(chip
);
1026 LOG_ERROR("Failed to write to nrf5 flash");
1030 static int nrf5_erase(struct flash_bank
*bank
, int first
, int last
)
1033 struct nrf5_info
*chip
;
1035 res
= nrf5_get_probed_chip_if_halted(bank
, &chip
);
1036 if (res
!= ERROR_OK
)
1039 /* For each sector to be erased */
1040 for (int s
= first
; s
<= last
&& res
== ERROR_OK
; s
++)
1041 res
= nrf5_erase_page(bank
, chip
, &bank
->sectors
[s
]);
1046 static void nrf5_free_driver_priv(struct flash_bank
*bank
)
1048 struct nrf5_bank
*nbank
= bank
->driver_priv
;
1049 struct nrf5_info
*chip
= nbank
->chip
;
1054 if (chip
->refcount
== 0) {
1056 bank
->driver_priv
= NULL
;
1060 static struct nrf5_info
*nrf5_get_chip(struct target
*target
)
1062 struct flash_bank
*bank_iter
;
1064 /* iterate over nrf5 banks of same target */
1065 for (bank_iter
= flash_bank_list(); bank_iter
; bank_iter
= bank_iter
->next
) {
1066 if (bank_iter
->driver
!= &nrf5_flash
&& bank_iter
->driver
!= &nrf51_flash
)
1069 if (bank_iter
->target
!= target
)
1072 struct nrf5_bank
*nbank
= bank_iter
->driver_priv
;
1082 FLASH_BANK_COMMAND_HANDLER(nrf5_flash_bank_command
)
1084 struct nrf5_info
*chip
;
1085 struct nrf5_bank
*nbank
= NULL
;
1087 switch (bank
->base
) {
1088 case NRF5_FLASH_BASE
:
1089 case NRF5_UICR_BASE
:
1092 LOG_ERROR("Invalid bank address " TARGET_ADDR_FMT
, bank
->base
);
1096 chip
= nrf5_get_chip(bank
->target
);
1098 /* Create a new chip */
1099 chip
= calloc(1, sizeof(*chip
));
1103 chip
->target
= bank
->target
;
1106 switch (bank
->base
) {
1107 case NRF5_FLASH_BASE
:
1108 nbank
= &chip
->bank
[0];
1110 case NRF5_UICR_BASE
:
1111 nbank
= &chip
->bank
[1];
1114 assert(nbank
!= NULL
);
1118 nbank
->probed
= false;
1119 bank
->driver_priv
= nbank
;
1120 bank
->write_start_alignment
= bank
->write_end_alignment
= 4;
1125 COMMAND_HANDLER(nrf5_handle_mass_erase_command
)
1128 struct flash_bank
*bank
= NULL
;
1129 struct target
*target
= get_current_target(CMD_CTX
);
1131 res
= get_flash_bank_by_addr(target
, NRF5_FLASH_BASE
, true, &bank
);
1132 if (res
!= ERROR_OK
)
1135 assert(bank
!= NULL
);
1137 struct nrf5_info
*chip
;
1139 res
= nrf5_get_probed_chip_if_halted(bank
, &chip
);
1140 if (res
!= ERROR_OK
)
1143 if (chip
->features
& NRF5_FEATURE_SERIES_51
) {
1145 res
= target_read_u32(target
, NRF51_FICR_PPFC
,
1147 if (res
!= ERROR_OK
) {
1148 LOG_ERROR("Couldn't read PPFC register");
1152 if ((ppfc
& 0xFF) == 0x00) {
1153 LOG_ERROR("Code region 0 size was pre-programmed at the factory, "
1154 "mass erase command won't work.");
1159 res
= nrf5_erase_all(chip
);
1160 if (res
!= ERROR_OK
) {
1161 LOG_ERROR("Failed to erase the chip");
1162 nrf5_protect_check(bank
);
1166 res
= nrf5_protect_check(bank
);
1167 if (res
!= ERROR_OK
) {
1168 LOG_ERROR("Failed to check chip's write protection");
1172 res
= get_flash_bank_by_addr(target
, NRF5_UICR_BASE
, true, &bank
);
1173 if (res
!= ERROR_OK
)
1179 COMMAND_HANDLER(nrf5_handle_info_command
)
1182 struct flash_bank
*bank
= NULL
;
1183 struct target
*target
= get_current_target(CMD_CTX
);
1185 res
= get_flash_bank_by_addr(target
, NRF5_FLASH_BASE
, true, &bank
);
1186 if (res
!= ERROR_OK
)
1189 assert(bank
!= NULL
);
1191 struct nrf5_info
*chip
;
1193 res
= nrf5_get_probed_chip_if_halted(bank
, &chip
);
1194 if (res
!= ERROR_OK
)
1198 const uint32_t address
;
1201 { .address
= NRF5_FICR_CODEPAGESIZE
},
1202 { .address
= NRF5_FICR_CODESIZE
},
1203 { .address
= NRF51_FICR_CLENR0
},
1204 { .address
= NRF51_FICR_PPFC
},
1205 { .address
= NRF51_FICR_NUMRAMBLOCK
},
1206 { .address
= NRF51_FICR_SIZERAMBLOCK0
},
1207 { .address
= NRF51_FICR_SIZERAMBLOCK1
},
1208 { .address
= NRF51_FICR_SIZERAMBLOCK2
},
1209 { .address
= NRF51_FICR_SIZERAMBLOCK3
},
1210 { .address
= NRF5_FICR_CONFIGID
},
1211 { .address
= NRF5_FICR_DEVICEID0
},
1212 { .address
= NRF5_FICR_DEVICEID1
},
1213 { .address
= NRF5_FICR_ER0
},
1214 { .address
= NRF5_FICR_ER1
},
1215 { .address
= NRF5_FICR_ER2
},
1216 { .address
= NRF5_FICR_ER3
},
1217 { .address
= NRF5_FICR_IR0
},
1218 { .address
= NRF5_FICR_IR1
},
1219 { .address
= NRF5_FICR_IR2
},
1220 { .address
= NRF5_FICR_IR3
},
1221 { .address
= NRF5_FICR_DEVICEADDRTYPE
},
1222 { .address
= NRF5_FICR_DEVICEADDR0
},
1223 { .address
= NRF5_FICR_DEVICEADDR1
},
1224 { .address
= NRF51_FICR_OVERRIDEN
},
1225 { .address
= NRF51_FICR_NRF_1MBIT0
},
1226 { .address
= NRF51_FICR_NRF_1MBIT1
},
1227 { .address
= NRF51_FICR_NRF_1MBIT2
},
1228 { .address
= NRF51_FICR_NRF_1MBIT3
},
1229 { .address
= NRF51_FICR_NRF_1MBIT4
},
1230 { .address
= NRF51_FICR_BLE_1MBIT0
},
1231 { .address
= NRF51_FICR_BLE_1MBIT1
},
1232 { .address
= NRF51_FICR_BLE_1MBIT2
},
1233 { .address
= NRF51_FICR_BLE_1MBIT3
},
1234 { .address
= NRF51_FICR_BLE_1MBIT4
},
1236 { .address
= NRF51_UICR_CLENR0
, },
1237 { .address
= NRF51_UICR_RBPCONF
},
1238 { .address
= NRF51_UICR_XTALFREQ
},
1239 { .address
= NRF51_UICR_FWID
},
1242 for (size_t i
= 0; i
< ARRAY_SIZE(ficr
); i
++) {
1243 res
= target_read_u32(chip
->target
, ficr
[i
].address
,
1245 if (res
!= ERROR_OK
) {
1246 LOG_ERROR("Couldn't read %" PRIx32
, ficr
[i
].address
);
1251 for (size_t i
= 0; i
< ARRAY_SIZE(uicr
); i
++) {
1252 res
= target_read_u32(chip
->target
, uicr
[i
].address
,
1254 if (res
!= ERROR_OK
) {
1255 LOG_ERROR("Couldn't read %" PRIx32
, uicr
[i
].address
);
1261 "\n[factory information control block]\n\n"
1262 "code page size: %"PRIu32
"B\n"
1263 "code memory size: %"PRIu32
"kB\n"
1264 "code region 0 size: %"PRIu32
"kB\n"
1265 "pre-programmed code: %s\n"
1266 "number of ram blocks: %"PRIu32
"\n"
1267 "ram block 0 size: %"PRIu32
"B\n"
1268 "ram block 1 size: %"PRIu32
"B\n"
1269 "ram block 2 size: %"PRIu32
"B\n"
1270 "ram block 3 size: %"PRIu32
"B\n"
1271 "config id: %" PRIx32
"\n"
1272 "device id: 0x%"PRIx32
"%08"PRIx32
"\n"
1273 "encryption root: 0x%08"PRIx32
"%08"PRIx32
"%08"PRIx32
"%08"PRIx32
"\n"
1274 "identity root: 0x%08"PRIx32
"%08"PRIx32
"%08"PRIx32
"%08"PRIx32
"\n"
1275 "device address type: 0x%"PRIx32
"\n"
1276 "device address: 0x%"PRIx32
"%08"PRIx32
"\n"
1277 "override enable: %"PRIx32
"\n"
1278 "NRF_1MBIT values: %"PRIx32
" %"PRIx32
" %"PRIx32
" %"PRIx32
" %"PRIx32
"\n"
1279 "BLE_1MBIT values: %"PRIx32
" %"PRIx32
" %"PRIx32
" %"PRIx32
" %"PRIx32
"\n"
1280 "\n[user information control block]\n\n"
1281 "code region 0 size: %"PRIu32
"kB\n"
1282 "read back protection configuration: %"PRIx32
"\n"
1283 "reset value for XTALFREQ: %"PRIx32
"\n"
1284 "firmware id: 0x%04"PRIx32
,
1286 (ficr
[1].value
* ficr
[0].value
) / 1024,
1287 (ficr
[2].value
== 0xFFFFFFFF) ? 0 : ficr
[2].value
/ 1024,
1288 ((ficr
[3].value
& 0xFF) == 0x00) ? "present" : "not present",
1291 (ficr
[6].value
== 0xFFFFFFFF) ? 0 : ficr
[6].value
,
1292 (ficr
[7].value
== 0xFFFFFFFF) ? 0 : ficr
[7].value
,
1293 (ficr
[8].value
== 0xFFFFFFFF) ? 0 : ficr
[8].value
,
1295 ficr
[10].value
, ficr
[11].value
,
1296 ficr
[12].value
, ficr
[13].value
, ficr
[14].value
, ficr
[15].value
,
1297 ficr
[16].value
, ficr
[17].value
, ficr
[18].value
, ficr
[19].value
,
1299 ficr
[21].value
, ficr
[22].value
,
1301 ficr
[24].value
, ficr
[25].value
, ficr
[26].value
, ficr
[27].value
, ficr
[28].value
,
1302 ficr
[29].value
, ficr
[30].value
, ficr
[31].value
, ficr
[32].value
, ficr
[33].value
,
1303 (uicr
[0].value
== 0xFFFFFFFF) ? 0 : uicr
[0].value
/ 1024,
1304 uicr
[1].value
& 0xFFFF,
1305 uicr
[2].value
& 0xFF,
1306 uicr
[3].value
& 0xFFFF);
1311 static const struct command_registration nrf5_exec_command_handlers
[] = {
1313 .name
= "mass_erase",
1314 .handler
= nrf5_handle_mass_erase_command
,
1315 .mode
= COMMAND_EXEC
,
1316 .help
= "Erase all flash contents of the chip.",
1321 .handler
= nrf5_handle_info_command
,
1322 .mode
= COMMAND_EXEC
,
1323 .help
= "Show FICR and UICR info.",
1326 COMMAND_REGISTRATION_DONE
1329 static const struct command_registration nrf5_command_handlers
[] = {
1332 .mode
= COMMAND_ANY
,
1333 .help
= "nrf5 flash command group",
1335 .chain
= nrf5_exec_command_handlers
,
1339 .mode
= COMMAND_ANY
,
1340 .help
= "nrf51 flash command group",
1342 .chain
= nrf5_exec_command_handlers
,
1344 COMMAND_REGISTRATION_DONE
1347 const struct flash_driver nrf5_flash
= {
1349 .commands
= nrf5_command_handlers
,
1350 .flash_bank_command
= nrf5_flash_bank_command
,
1352 .erase
= nrf5_erase
,
1353 .protect
= nrf5_protect
,
1354 .write
= nrf5_write
,
1355 .read
= default_flash_read
,
1356 .probe
= nrf5_probe
,
1357 .auto_probe
= nrf5_auto_probe
,
1358 .erase_check
= default_flash_blank_check
,
1359 .protect_check
= nrf5_protect_check
,
1360 .free_driver_priv
= nrf5_free_driver_priv
,
1363 /* We need to retain the flash-driver name as well as the commands
1364 * for backwards compatability */
1365 const struct flash_driver nrf51_flash
= {
1367 .commands
= nrf5_command_handlers
,
1368 .flash_bank_command
= nrf5_flash_bank_command
,
1370 .erase
= nrf5_erase
,
1371 .protect
= nrf5_protect
,
1372 .write
= nrf5_write
,
1373 .read
= default_flash_read
,
1374 .probe
= nrf5_probe
,
1375 .auto_probe
= nrf5_auto_probe
,
1376 .erase_check
= default_flash_blank_check
,
1377 .protect_check
= nrf5_protect_check
,
1378 .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)