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 static int nrf5_bank_is_probed(struct flash_bank
*bank
)
288 struct nrf5_bank
*nbank
= bank
->driver_priv
;
290 assert(nbank
!= NULL
);
292 return nbank
->probed
;
294 static int nrf5_probe(struct flash_bank
*bank
);
296 static int nrf5_get_probed_chip_if_halted(struct flash_bank
*bank
, struct nrf5_info
**chip
)
298 if (bank
->target
->state
!= TARGET_HALTED
) {
299 LOG_ERROR("Target not halted");
300 return ERROR_TARGET_NOT_HALTED
;
303 struct nrf5_bank
*nbank
= bank
->driver_priv
;
306 int probed
= nrf5_bank_is_probed(bank
);
310 return nrf5_probe(bank
);
315 static int nrf5_wait_for_nvmc(struct nrf5_info
*chip
)
319 int timeout_ms
= 340;
320 int64_t ts_start
= timeval_ms();
323 res
= target_read_u32(chip
->target
, NRF5_NVMC_READY
, &ready
);
324 if (res
!= ERROR_OK
) {
325 LOG_ERROR("Couldn't read NVMC_READY register");
329 if (ready
== 0x00000001)
334 } while ((timeval_ms()-ts_start
) < timeout_ms
);
336 LOG_DEBUG("Timed out waiting for NVMC_READY");
337 return ERROR_FLASH_BUSY
;
340 static int nrf5_nvmc_erase_enable(struct nrf5_info
*chip
)
343 res
= target_write_u32(chip
->target
,
345 NRF5_NVMC_CONFIG_EEN
);
347 if (res
!= ERROR_OK
) {
348 LOG_ERROR("Failed to enable erase operation");
353 According to NVMC examples in Nordic SDK busy status must be
354 checked after writing to NVMC_CONFIG
356 res
= nrf5_wait_for_nvmc(chip
);
358 LOG_ERROR("Erase enable did not complete");
363 static int nrf5_nvmc_write_enable(struct nrf5_info
*chip
)
366 res
= target_write_u32(chip
->target
,
368 NRF5_NVMC_CONFIG_WEN
);
370 if (res
!= ERROR_OK
) {
371 LOG_ERROR("Failed to enable write operation");
376 According to NVMC examples in Nordic SDK busy status must be
377 checked after writing to NVMC_CONFIG
379 res
= nrf5_wait_for_nvmc(chip
);
381 LOG_ERROR("Write enable did not complete");
386 static int nrf5_nvmc_read_only(struct nrf5_info
*chip
)
389 res
= target_write_u32(chip
->target
,
391 NRF5_NVMC_CONFIG_REN
);
393 if (res
!= ERROR_OK
) {
394 LOG_ERROR("Failed to enable read-only operation");
398 According to NVMC examples in Nordic SDK busy status must be
399 checked after writing to NVMC_CONFIG
401 res
= nrf5_wait_for_nvmc(chip
);
403 LOG_ERROR("Read only enable did not complete");
408 static int nrf5_nvmc_generic_erase(struct nrf5_info
*chip
,
409 uint32_t erase_register
, uint32_t erase_value
)
413 res
= nrf5_nvmc_erase_enable(chip
);
417 res
= target_write_u32(chip
->target
,
423 res
= nrf5_wait_for_nvmc(chip
);
427 return nrf5_nvmc_read_only(chip
);
430 nrf5_nvmc_read_only(chip
);
432 LOG_ERROR("Failed to erase reg: 0x%08"PRIx32
" val: 0x%08"PRIx32
,
433 erase_register
, erase_value
);
437 static int nrf5_protect_check_bprot(struct flash_bank
*bank
)
439 struct nrf5_bank
*nbank
= bank
->driver_priv
;
440 struct nrf5_info
*chip
= nbank
->chip
;
442 assert(chip
!= NULL
);
444 static uint32_t nrf5_bprot_offsets
[4] = { 0x600, 0x604, 0x610, 0x614 };
445 uint32_t bprot_reg
= 0;
448 for (int i
= 0; i
< bank
->num_sectors
; i
++) {
449 unsigned int bit
= i
% 32;
451 unsigned int n_reg
= i
/ 32;
452 if (n_reg
>= ARRAY_SIZE(nrf5_bprot_offsets
))
455 res
= target_read_u32(chip
->target
, NRF5_BPROT_BASE
+ nrf5_bprot_offsets
[n_reg
], &bprot_reg
);
459 bank
->sectors
[i
].is_protected
= (bprot_reg
& (1 << bit
)) ? 1 : 0;
464 static int nrf5_protect_check(struct flash_bank
*bank
)
469 /* UICR cannot be write protected so just return early */
470 if (bank
->base
== NRF5_UICR_BASE
)
473 struct nrf5_bank
*nbank
= bank
->driver_priv
;
474 struct nrf5_info
*chip
= nbank
->chip
;
476 assert(chip
!= NULL
);
478 if (chip
->features
& NRF5_FEATURE_BPROT
)
479 return nrf5_protect_check_bprot(bank
);
481 if (!(chip
->features
& NRF5_FEATURE_SERIES_51
)) {
482 LOG_WARNING("Flash protection of this nRF device is not supported");
483 return ERROR_FLASH_OPER_UNSUPPORTED
;
486 res
= target_read_u32(chip
->target
, NRF51_FICR_CLENR0
,
488 if (res
!= ERROR_OK
) {
489 LOG_ERROR("Couldn't read code region 0 size[FICR]");
493 if (clenr0
== 0xFFFFFFFF) {
494 res
= target_read_u32(chip
->target
, NRF51_UICR_CLENR0
,
496 if (res
!= ERROR_OK
) {
497 LOG_ERROR("Couldn't read code region 0 size[UICR]");
502 for (int i
= 0; i
< bank
->num_sectors
; i
++)
503 bank
->sectors
[i
].is_protected
=
504 clenr0
!= 0xFFFFFFFF && bank
->sectors
[i
].offset
< clenr0
;
509 static int nrf5_protect(struct flash_bank
*bank
, int set
, int first
, int last
)
512 uint32_t clenr0
, ppfc
;
513 struct nrf5_info
*chip
;
515 /* UICR cannot be write protected so just bail out early */
516 if (bank
->base
== NRF5_UICR_BASE
)
519 res
= nrf5_get_probed_chip_if_halted(bank
, &chip
);
523 if (!(chip
->features
& NRF5_FEATURE_SERIES_51
)) {
524 LOG_ERROR("Flash protection setting of this nRF device is not supported");
525 return ERROR_FLASH_OPER_UNSUPPORTED
;
529 LOG_ERROR("Code region 0 must start at the begining of the bank");
533 res
= target_read_u32(chip
->target
, NRF51_FICR_PPFC
,
535 if (res
!= ERROR_OK
) {
536 LOG_ERROR("Couldn't read PPFC register");
540 if ((ppfc
& 0xFF) == 0x00) {
541 LOG_ERROR("Code region 0 size was pre-programmed at the factory, can't change flash protection settings");
545 res
= target_read_u32(chip
->target
, NRF51_UICR_CLENR0
,
547 if (res
!= ERROR_OK
) {
548 LOG_ERROR("Couldn't read code region 0 size[UICR]");
552 if (clenr0
== 0xFFFFFFFF) {
553 res
= target_write_u32(chip
->target
, NRF51_UICR_CLENR0
,
555 if (res
!= ERROR_OK
) {
556 LOG_ERROR("Couldn't write code region 0 size[UICR]");
561 LOG_ERROR("You need to perform chip erase before changing the protection settings");
564 nrf5_protect_check(bank
);
569 static bool nrf5_info_variant_to_str(uint32_t variant
, char *bf
)
571 h_u32_to_be((uint8_t *)bf
, variant
);
573 if (isalnum(bf
[0]) && isalnum(bf
[1]) && isalnum(bf
[2]) && isalnum(bf
[3]))
580 static const char *nrf5_decode_info_package(uint32_t package
)
582 for (size_t i
= 0; i
< ARRAY_SIZE(nrf5_packages_table
); i
++) {
583 if (nrf5_packages_table
[i
].package
== package
)
584 return nrf5_packages_table
[i
].code
;
589 static int nrf5_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
591 struct nrf5_bank
*nbank
= bank
->driver_priv
;
592 struct nrf5_info
*chip
= nbank
->chip
;
596 res
= snprintf(buf
, buf_size
,
597 "nRF%s-%s(build code: %s)",
598 chip
->spec
->part
, chip
->spec
->variant
, chip
->spec
->build_code
);
600 } else if (chip
->ficr_info_valid
) {
602 nrf5_info_variant_to_str(chip
->ficr_info
.variant
, variant
);
603 res
= snprintf(buf
, buf_size
,
604 "nRF%" PRIx32
"-%s%.2s(build code: %s)",
605 chip
->ficr_info
.part
,
606 nrf5_decode_info_package(chip
->ficr_info
.package
),
607 variant
, &variant
[2]);
610 res
= snprintf(buf
, buf_size
, "nRF51xxx (HWID 0x%04" PRIx16
")",
616 snprintf(buf
+ res
, buf_size
- res
, " %ukB Flash, %ukB RAM",
617 chip
->flash_size_kb
, chip
->ram_size_kb
);
621 static int nrf5_read_ficr_info(struct nrf5_info
*chip
)
624 struct target
*target
= chip
->target
;
626 chip
->ficr_info_valid
= false;
628 res
= target_read_u32(target
, NRF5_FICR_INFO_PART
, &chip
->ficr_info
.part
);
629 if (res
!= ERROR_OK
) {
630 LOG_DEBUG("Couldn't read FICR INFO.PART register");
634 uint32_t series
= chip
->ficr_info
.part
& 0xfffff000;
637 chip
->features
= NRF5_FEATURE_SERIES_51
;
641 chip
->features
= NRF5_FEATURE_SERIES_52
;
643 switch (chip
->ficr_info
.part
) {
646 chip
->features
|= NRF5_FEATURE_BPROT
;
650 chip
->features
|= NRF5_FEATURE_ACL_PROT
;
656 LOG_DEBUG("FICR INFO likely not implemented. Invalid PART value 0x%08"
657 PRIx32
, chip
->ficr_info
.part
);
658 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
661 /* Now we know the device has FICR INFO filled by something relevant:
662 * Although it is not documented, the tested nRF51 rev 3 devices
663 * have FICR INFO.PART, RAM and FLASH of the same format as nRF52.
664 * VARIANT and PACKAGE coding is unknown for a nRF51 device.
665 * nRF52 devices have FICR INFO documented and always filled. */
667 res
= target_read_u32(target
, NRF5_FICR_INFO_VARIANT
, &chip
->ficr_info
.variant
);
671 res
= target_read_u32(target
, NRF5_FICR_INFO_PACKAGE
, &chip
->ficr_info
.package
);
675 res
= target_read_u32(target
, NRF5_FICR_INFO_RAM
, &chip
->ficr_info
.ram
);
679 res
= target_read_u32(target
, NRF5_FICR_INFO_FLASH
, &chip
->ficr_info
.flash
);
683 chip
->ficr_info_valid
= true;
687 static int nrf5_get_ram_size(struct target
*target
, uint32_t *ram_size
)
693 uint32_t numramblock
;
694 res
= target_read_u32(target
, NRF51_FICR_NUMRAMBLOCK
, &numramblock
);
695 if (res
!= ERROR_OK
) {
696 LOG_DEBUG("Couldn't read FICR NUMRAMBLOCK register");
700 if (numramblock
< 1 || numramblock
> 4) {
701 LOG_DEBUG("FICR NUMRAMBLOCK strange value %" PRIx32
, numramblock
);
702 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
705 for (unsigned int i
= 0; i
< numramblock
; i
++) {
706 uint32_t sizeramblock
;
707 res
= target_read_u32(target
, NRF51_FICR_SIZERAMBLOCK0
+ sizeof(uint32_t)*i
, &sizeramblock
);
708 if (res
!= ERROR_OK
) {
709 LOG_DEBUG("Couldn't read FICR NUMRAMBLOCK register");
712 if (sizeramblock
< 1024 || sizeramblock
> 65536)
713 LOG_DEBUG("FICR SIZERAMBLOCK strange value %" PRIx32
, sizeramblock
);
715 *ram_size
+= sizeramblock
;
720 static int nrf5_probe(struct flash_bank
*bank
)
723 struct nrf5_bank
*nbank
= bank
->driver_priv
;
724 struct nrf5_info
*chip
= nbank
->chip
;
725 struct target
*target
= chip
->target
;
727 res
= target_read_u32(target
, NRF5_FICR_CONFIGID
, &chip
->hwid
);
728 if (res
!= ERROR_OK
) {
729 LOG_ERROR("Couldn't read CONFIGID register");
733 chip
->hwid
&= 0xFFFF; /* HWID is stored in the lower two
734 * bytes of the CONFIGID register */
736 /* guess a nRF51 series if the device has no FICR INFO and we don't know HWID */
737 chip
->features
= NRF5_FEATURE_SERIES_51
;
739 /* Don't bail out on error for the case that some old engineering
740 * sample has FICR INFO registers unreadable. We can proceed anyway. */
741 (void)nrf5_read_ficr_info(chip
);
744 for (size_t i
= 0; i
< ARRAY_SIZE(nrf5_known_devices_table
); i
++) {
745 if (chip
->hwid
== nrf5_known_devices_table
[i
].hwid
) {
746 chip
->spec
= &nrf5_known_devices_table
[i
];
747 chip
->features
= chip
->spec
->features
;
752 if (chip
->spec
&& chip
->ficr_info_valid
) {
753 /* check if HWID table gives the same part as FICR INFO */
754 if (chip
->ficr_info
.part
!= strtoul(chip
->spec
->part
, NULL
, 16))
755 LOG_WARNING("HWID 0x%04" PRIx32
" mismatch: FICR INFO.PART %"
756 PRIx32
, chip
->hwid
, chip
->ficr_info
.part
);
759 if (chip
->ficr_info_valid
) {
760 chip
->ram_size_kb
= chip
->ficr_info
.ram
;
763 nrf5_get_ram_size(target
, &ram_size
);
764 chip
->ram_size_kb
= ram_size
/ 1024;
767 /* The value stored in NRF5_FICR_CODEPAGESIZE is the number of bytes in one page of FLASH. */
768 uint32_t flash_page_size
;
769 res
= target_read_u32(chip
->target
, NRF5_FICR_CODEPAGESIZE
,
771 if (res
!= ERROR_OK
) {
772 LOG_ERROR("Couldn't read code page size");
776 /* Note the register name is misleading,
777 * NRF5_FICR_CODESIZE is the number of pages in flash memory, not the number of bytes! */
778 uint32_t num_sectors
;
779 res
= target_read_u32(chip
->target
, NRF5_FICR_CODESIZE
, &num_sectors
);
780 if (res
!= ERROR_OK
) {
781 LOG_ERROR("Couldn't read code memory size");
785 chip
->flash_size_kb
= num_sectors
* flash_page_size
/ 1024;
787 if (!chip
->bank
[0].probed
&& !chip
->bank
[1].probed
) {
789 nrf5_info(bank
, buf
, sizeof(buf
));
790 if (!chip
->spec
&& !chip
->ficr_info_valid
) {
791 LOG_INFO("Unknown device: %s", buf
);
797 if (bank
->base
== NRF5_FLASH_BASE
) {
799 if (chip
->spec
&& chip
->flash_size_kb
!= chip
->spec
->flash_size_kb
)
800 LOG_WARNING("Chip's reported Flash capacity does not match expected one");
801 if (chip
->ficr_info_valid
&& chip
->flash_size_kb
!= chip
->ficr_info
.flash
)
802 LOG_WARNING("Chip's reported Flash capacity does not match FICR INFO.FLASH");
804 bank
->num_sectors
= num_sectors
;
805 bank
->size
= num_sectors
* flash_page_size
;
807 bank
->sectors
= alloc_block_array(0, flash_page_size
, num_sectors
);
811 nrf5_protect_check(bank
);
813 chip
->bank
[0].probed
= true;
816 bank
->num_sectors
= 1;
817 bank
->size
= flash_page_size
;
819 bank
->sectors
= alloc_block_array(0, flash_page_size
, num_sectors
);
823 bank
->sectors
[0].is_protected
= 0;
825 chip
->bank
[1].probed
= true;
831 static int nrf5_auto_probe(struct flash_bank
*bank
)
833 int probed
= nrf5_bank_is_probed(bank
);
840 return nrf5_probe(bank
);
843 static int nrf5_erase_all(struct nrf5_info
*chip
)
845 LOG_DEBUG("Erasing all non-volatile memory");
846 return nrf5_nvmc_generic_erase(chip
,
851 static int nrf5_erase_page(struct flash_bank
*bank
,
852 struct nrf5_info
*chip
,
853 struct flash_sector
*sector
)
857 LOG_DEBUG("Erasing page at 0x%"PRIx32
, sector
->offset
);
858 if (sector
->is_protected
) {
859 LOG_ERROR("Cannot erase protected sector 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 FLASH_BANK_COMMAND_HANDLER(nrf5_flash_bank_command
)
1068 static struct nrf5_info
*chip
;
1069 struct nrf5_bank
*nbank
= NULL
;
1071 switch (bank
->base
) {
1072 case NRF5_FLASH_BASE
:
1073 case NRF5_UICR_BASE
:
1076 LOG_ERROR("Invalid bank address " TARGET_ADDR_FMT
, bank
->base
);
1081 /* Create a new chip */
1082 chip
= calloc(1, sizeof(*chip
));
1086 chip
->target
= bank
->target
;
1089 switch (bank
->base
) {
1090 case NRF5_FLASH_BASE
:
1091 nbank
= &chip
->bank
[0];
1093 case NRF5_UICR_BASE
:
1094 nbank
= &chip
->bank
[1];
1097 assert(nbank
!= NULL
);
1101 nbank
->probed
= false;
1102 bank
->driver_priv
= nbank
;
1103 bank
->write_start_alignment
= bank
->write_end_alignment
= 4;
1108 COMMAND_HANDLER(nrf5_handle_mass_erase_command
)
1111 struct flash_bank
*bank
= NULL
;
1112 struct target
*target
= get_current_target(CMD_CTX
);
1114 res
= get_flash_bank_by_addr(target
, NRF5_FLASH_BASE
, true, &bank
);
1115 if (res
!= ERROR_OK
)
1118 assert(bank
!= NULL
);
1120 struct nrf5_info
*chip
;
1122 res
= nrf5_get_probed_chip_if_halted(bank
, &chip
);
1123 if (res
!= ERROR_OK
)
1126 if (chip
->features
& NRF5_FEATURE_SERIES_51
) {
1128 res
= target_read_u32(target
, NRF51_FICR_PPFC
,
1130 if (res
!= ERROR_OK
) {
1131 LOG_ERROR("Couldn't read PPFC register");
1135 if ((ppfc
& 0xFF) == 0x00) {
1136 LOG_ERROR("Code region 0 size was pre-programmed at the factory, "
1137 "mass erase command won't work.");
1142 res
= nrf5_erase_all(chip
);
1143 if (res
!= ERROR_OK
) {
1144 LOG_ERROR("Failed to erase the chip");
1145 nrf5_protect_check(bank
);
1149 res
= nrf5_protect_check(bank
);
1150 if (res
!= ERROR_OK
) {
1151 LOG_ERROR("Failed to check chip's write protection");
1155 res
= get_flash_bank_by_addr(target
, NRF5_UICR_BASE
, true, &bank
);
1156 if (res
!= ERROR_OK
)
1162 COMMAND_HANDLER(nrf5_handle_info_command
)
1165 struct flash_bank
*bank
= NULL
;
1166 struct target
*target
= get_current_target(CMD_CTX
);
1168 res
= get_flash_bank_by_addr(target
, NRF5_FLASH_BASE
, true, &bank
);
1169 if (res
!= ERROR_OK
)
1172 assert(bank
!= NULL
);
1174 struct nrf5_info
*chip
;
1176 res
= nrf5_get_probed_chip_if_halted(bank
, &chip
);
1177 if (res
!= ERROR_OK
)
1181 const uint32_t address
;
1184 { .address
= NRF5_FICR_CODEPAGESIZE
},
1185 { .address
= NRF5_FICR_CODESIZE
},
1186 { .address
= NRF51_FICR_CLENR0
},
1187 { .address
= NRF51_FICR_PPFC
},
1188 { .address
= NRF51_FICR_NUMRAMBLOCK
},
1189 { .address
= NRF51_FICR_SIZERAMBLOCK0
},
1190 { .address
= NRF51_FICR_SIZERAMBLOCK1
},
1191 { .address
= NRF51_FICR_SIZERAMBLOCK2
},
1192 { .address
= NRF51_FICR_SIZERAMBLOCK3
},
1193 { .address
= NRF5_FICR_CONFIGID
},
1194 { .address
= NRF5_FICR_DEVICEID0
},
1195 { .address
= NRF5_FICR_DEVICEID1
},
1196 { .address
= NRF5_FICR_ER0
},
1197 { .address
= NRF5_FICR_ER1
},
1198 { .address
= NRF5_FICR_ER2
},
1199 { .address
= NRF5_FICR_ER3
},
1200 { .address
= NRF5_FICR_IR0
},
1201 { .address
= NRF5_FICR_IR1
},
1202 { .address
= NRF5_FICR_IR2
},
1203 { .address
= NRF5_FICR_IR3
},
1204 { .address
= NRF5_FICR_DEVICEADDRTYPE
},
1205 { .address
= NRF5_FICR_DEVICEADDR0
},
1206 { .address
= NRF5_FICR_DEVICEADDR1
},
1207 { .address
= NRF51_FICR_OVERRIDEN
},
1208 { .address
= NRF51_FICR_NRF_1MBIT0
},
1209 { .address
= NRF51_FICR_NRF_1MBIT1
},
1210 { .address
= NRF51_FICR_NRF_1MBIT2
},
1211 { .address
= NRF51_FICR_NRF_1MBIT3
},
1212 { .address
= NRF51_FICR_NRF_1MBIT4
},
1213 { .address
= NRF51_FICR_BLE_1MBIT0
},
1214 { .address
= NRF51_FICR_BLE_1MBIT1
},
1215 { .address
= NRF51_FICR_BLE_1MBIT2
},
1216 { .address
= NRF51_FICR_BLE_1MBIT3
},
1217 { .address
= NRF51_FICR_BLE_1MBIT4
},
1219 { .address
= NRF51_UICR_CLENR0
, },
1220 { .address
= NRF51_UICR_RBPCONF
},
1221 { .address
= NRF51_UICR_XTALFREQ
},
1222 { .address
= NRF51_UICR_FWID
},
1225 for (size_t i
= 0; i
< ARRAY_SIZE(ficr
); i
++) {
1226 res
= target_read_u32(chip
->target
, ficr
[i
].address
,
1228 if (res
!= ERROR_OK
) {
1229 LOG_ERROR("Couldn't read %" PRIx32
, ficr
[i
].address
);
1234 for (size_t i
= 0; i
< ARRAY_SIZE(uicr
); i
++) {
1235 res
= target_read_u32(chip
->target
, uicr
[i
].address
,
1237 if (res
!= ERROR_OK
) {
1238 LOG_ERROR("Couldn't read %" PRIx32
, uicr
[i
].address
);
1244 "\n[factory information control block]\n\n"
1245 "code page size: %"PRIu32
"B\n"
1246 "code memory size: %"PRIu32
"kB\n"
1247 "code region 0 size: %"PRIu32
"kB\n"
1248 "pre-programmed code: %s\n"
1249 "number of ram blocks: %"PRIu32
"\n"
1250 "ram block 0 size: %"PRIu32
"B\n"
1251 "ram block 1 size: %"PRIu32
"B\n"
1252 "ram block 2 size: %"PRIu32
"B\n"
1253 "ram block 3 size: %"PRIu32
"B\n"
1254 "config id: %" PRIx32
"\n"
1255 "device id: 0x%"PRIx32
"%08"PRIx32
"\n"
1256 "encryption root: 0x%08"PRIx32
"%08"PRIx32
"%08"PRIx32
"%08"PRIx32
"\n"
1257 "identity root: 0x%08"PRIx32
"%08"PRIx32
"%08"PRIx32
"%08"PRIx32
"\n"
1258 "device address type: 0x%"PRIx32
"\n"
1259 "device address: 0x%"PRIx32
"%08"PRIx32
"\n"
1260 "override enable: %"PRIx32
"\n"
1261 "NRF_1MBIT values: %"PRIx32
" %"PRIx32
" %"PRIx32
" %"PRIx32
" %"PRIx32
"\n"
1262 "BLE_1MBIT values: %"PRIx32
" %"PRIx32
" %"PRIx32
" %"PRIx32
" %"PRIx32
"\n"
1263 "\n[user information control block]\n\n"
1264 "code region 0 size: %"PRIu32
"kB\n"
1265 "read back protection configuration: %"PRIx32
"\n"
1266 "reset value for XTALFREQ: %"PRIx32
"\n"
1267 "firmware id: 0x%04"PRIx32
,
1269 (ficr
[1].value
* ficr
[0].value
) / 1024,
1270 (ficr
[2].value
== 0xFFFFFFFF) ? 0 : ficr
[2].value
/ 1024,
1271 ((ficr
[3].value
& 0xFF) == 0x00) ? "present" : "not present",
1274 (ficr
[6].value
== 0xFFFFFFFF) ? 0 : ficr
[6].value
,
1275 (ficr
[7].value
== 0xFFFFFFFF) ? 0 : ficr
[7].value
,
1276 (ficr
[8].value
== 0xFFFFFFFF) ? 0 : ficr
[8].value
,
1278 ficr
[10].value
, ficr
[11].value
,
1279 ficr
[12].value
, ficr
[13].value
, ficr
[14].value
, ficr
[15].value
,
1280 ficr
[16].value
, ficr
[17].value
, ficr
[18].value
, ficr
[19].value
,
1282 ficr
[21].value
, ficr
[22].value
,
1284 ficr
[24].value
, ficr
[25].value
, ficr
[26].value
, ficr
[27].value
, ficr
[28].value
,
1285 ficr
[29].value
, ficr
[30].value
, ficr
[31].value
, ficr
[32].value
, ficr
[33].value
,
1286 (uicr
[0].value
== 0xFFFFFFFF) ? 0 : uicr
[0].value
/ 1024,
1287 uicr
[1].value
& 0xFFFF,
1288 uicr
[2].value
& 0xFF,
1289 uicr
[3].value
& 0xFFFF);
1294 static const struct command_registration nrf5_exec_command_handlers
[] = {
1296 .name
= "mass_erase",
1297 .handler
= nrf5_handle_mass_erase_command
,
1298 .mode
= COMMAND_EXEC
,
1299 .help
= "Erase all flash contents of the chip.",
1304 .handler
= nrf5_handle_info_command
,
1305 .mode
= COMMAND_EXEC
,
1306 .help
= "Show FICR and UICR info.",
1309 COMMAND_REGISTRATION_DONE
1312 static const struct command_registration nrf5_command_handlers
[] = {
1315 .mode
= COMMAND_ANY
,
1316 .help
= "nrf5 flash command group",
1318 .chain
= nrf5_exec_command_handlers
,
1322 .mode
= COMMAND_ANY
,
1323 .help
= "nrf51 flash command group",
1325 .chain
= nrf5_exec_command_handlers
,
1327 COMMAND_REGISTRATION_DONE
1330 const struct flash_driver nrf5_flash
= {
1332 .commands
= nrf5_command_handlers
,
1333 .flash_bank_command
= nrf5_flash_bank_command
,
1335 .erase
= nrf5_erase
,
1336 .protect
= nrf5_protect
,
1337 .write
= nrf5_write
,
1338 .read
= default_flash_read
,
1339 .probe
= nrf5_probe
,
1340 .auto_probe
= nrf5_auto_probe
,
1341 .erase_check
= default_flash_blank_check
,
1342 .protect_check
= nrf5_protect_check
,
1343 .free_driver_priv
= nrf5_free_driver_priv
,
1346 /* We need to retain the flash-driver name as well as the commands
1347 * for backwards compatability */
1348 const struct flash_driver nrf51_flash
= {
1350 .commands
= nrf5_command_handlers
,
1351 .flash_bank_command
= nrf5_flash_bank_command
,
1353 .erase
= nrf5_erase
,
1354 .protect
= nrf5_protect
,
1355 .write
= nrf5_write
,
1356 .read
= default_flash_read
,
1357 .probe
= nrf5_probe
,
1358 .auto_probe
= nrf5_auto_probe
,
1359 .erase_check
= default_flash_blank_check
,
1360 .protect_check
= nrf5_protect_check
,
1361 .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)