nrf51: Add new HWID 0x008F
[openocd.git] / src / flash / nor / nrf51.c
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> *
6 * *
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. *
11 * *
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. *
16 * *
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 ***************************************************************************/
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #include "imp.h"
26 #include <target/algorithm.h>
27 #include <target/armv7m.h>
28 #include <helper/types.h>
29
30 enum {
31 NRF51_FLASH_BASE = 0x00000000,
32 };
33
34 enum nrf51_ficr_registers {
35 NRF51_FICR_BASE = 0x10000000, /* Factory Information Configuration Registers */
36
37 #define NRF51_FICR_REG(offset) (NRF51_FICR_BASE + offset)
38
39 NRF51_FICR_CODEPAGESIZE = NRF51_FICR_REG(0x010),
40 NRF51_FICR_CODESIZE = NRF51_FICR_REG(0x014),
41 NRF51_FICR_CLENR0 = NRF51_FICR_REG(0x028),
42 NRF51_FICR_PPFC = NRF51_FICR_REG(0x02C),
43 NRF51_FICR_NUMRAMBLOCK = NRF51_FICR_REG(0x034),
44 NRF51_FICR_SIZERAMBLOCK0 = NRF51_FICR_REG(0x038),
45 NRF51_FICR_SIZERAMBLOCK1 = NRF51_FICR_REG(0x03C),
46 NRF51_FICR_SIZERAMBLOCK2 = NRF51_FICR_REG(0x040),
47 NRF51_FICR_SIZERAMBLOCK3 = NRF51_FICR_REG(0x044),
48 NRF51_FICR_CONFIGID = NRF51_FICR_REG(0x05C),
49 NRF51_FICR_DEVICEID0 = NRF51_FICR_REG(0x060),
50 NRF51_FICR_DEVICEID1 = NRF51_FICR_REG(0x064),
51 NRF51_FICR_ER0 = NRF51_FICR_REG(0x080),
52 NRF51_FICR_ER1 = NRF51_FICR_REG(0x084),
53 NRF51_FICR_ER2 = NRF51_FICR_REG(0x088),
54 NRF51_FICR_ER3 = NRF51_FICR_REG(0x08C),
55 NRF51_FICR_IR0 = NRF51_FICR_REG(0x090),
56 NRF51_FICR_IR1 = NRF51_FICR_REG(0x094),
57 NRF51_FICR_IR2 = NRF51_FICR_REG(0x098),
58 NRF51_FICR_IR3 = NRF51_FICR_REG(0x09C),
59 NRF51_FICR_DEVICEADDRTYPE = NRF51_FICR_REG(0x0A0),
60 NRF51_FICR_DEVICEADDR0 = NRF51_FICR_REG(0x0A4),
61 NRF51_FICR_DEVICEADDR1 = NRF51_FICR_REG(0x0A8),
62 NRF51_FICR_OVERRIDEN = NRF51_FICR_REG(0x0AC),
63 NRF51_FICR_NRF_1MBIT0 = NRF51_FICR_REG(0x0B0),
64 NRF51_FICR_NRF_1MBIT1 = NRF51_FICR_REG(0x0B4),
65 NRF51_FICR_NRF_1MBIT2 = NRF51_FICR_REG(0x0B8),
66 NRF51_FICR_NRF_1MBIT3 = NRF51_FICR_REG(0x0BC),
67 NRF51_FICR_NRF_1MBIT4 = NRF51_FICR_REG(0x0C0),
68 NRF51_FICR_BLE_1MBIT0 = NRF51_FICR_REG(0x0EC),
69 NRF51_FICR_BLE_1MBIT1 = NRF51_FICR_REG(0x0F0),
70 NRF51_FICR_BLE_1MBIT2 = NRF51_FICR_REG(0x0F4),
71 NRF51_FICR_BLE_1MBIT3 = NRF51_FICR_REG(0x0F8),
72 NRF51_FICR_BLE_1MBIT4 = NRF51_FICR_REG(0x0FC),
73 };
74
75 enum nrf51_uicr_registers {
76 NRF51_UICR_BASE = 0x10001000, /* User Information
77 * Configuration Regsters */
78
79 NRF51_UICR_SIZE = 0x100,
80
81 #define NRF51_UICR_REG(offset) (NRF51_UICR_BASE + offset)
82
83 NRF51_UICR_CLENR0 = NRF51_UICR_REG(0x000),
84 NRF51_UICR_RBPCONF = NRF51_UICR_REG(0x004),
85 NRF51_UICR_XTALFREQ = NRF51_UICR_REG(0x008),
86 NRF51_UICR_FWID = NRF51_UICR_REG(0x010),
87 };
88
89 enum nrf51_nvmc_registers {
90 NRF51_NVMC_BASE = 0x4001E000, /* Non-Volatile Memory
91 * Controller Regsters */
92
93 #define NRF51_NVMC_REG(offset) (NRF51_NVMC_BASE + offset)
94
95 NRF51_NVMC_READY = NRF51_NVMC_REG(0x400),
96 NRF51_NVMC_CONFIG = NRF51_NVMC_REG(0x504),
97 NRF51_NVMC_ERASEPAGE = NRF51_NVMC_REG(0x508),
98 NRF51_NVMC_ERASEALL = NRF51_NVMC_REG(0x50C),
99 NRF51_NVMC_ERASEUICR = NRF51_NVMC_REG(0x514),
100 };
101
102 enum nrf51_nvmc_config_bits {
103 NRF51_NVMC_CONFIG_REN = 0x00,
104 NRF51_NVMC_CONFIG_WEN = 0x01,
105 NRF51_NVMC_CONFIG_EEN = 0x02,
106
107 };
108
109 struct nrf51_info {
110 uint32_t code_page_size;
111
112 struct {
113 bool probed;
114 int (*write) (struct flash_bank *bank,
115 struct nrf51_info *chip,
116 const uint8_t *buffer, uint32_t offset, uint32_t count);
117 } bank[2];
118 struct target *target;
119 };
120
121 struct nrf51_device_spec {
122 uint16_t hwid;
123 const char *part;
124 const char *variant;
125 const char *build_code;
126 unsigned int flash_size_kb;
127 };
128
129 /* The known devices table below is derived from the "nRF51 Series
130 * Compatibility Matrix" document, which can be found by searching for
131 * ATTN-51 on the Nordic Semi website:
132 *
133 * http://www.nordicsemi.com/eng/content/search?SearchText=ATTN-51
134 *
135 * Up to date with Matrix v2.0, plus some additional HWIDs.
136 *
137 * The additional HWIDs apply where the build code in the matrix is
138 * shown as Gx0, Bx0, etc. In these cases the HWID in the matrix is
139 * for x==0, x!=0 means different (unspecified) HWIDs.
140 */
141 static const struct nrf51_device_spec nrf51_known_devices_table[] = {
142 /* nRF51822 Devices (IC rev 1). */
143 {
144 .hwid = 0x001D,
145 .part = "51822",
146 .variant = "QFAA",
147 .build_code = "CA/C0",
148 .flash_size_kb = 256,
149 },
150 {
151 .hwid = 0x0026,
152 .part = "51822",
153 .variant = "QFAB",
154 .build_code = "AA",
155 .flash_size_kb = 128,
156 },
157 {
158 .hwid = 0x0027,
159 .part = "51822",
160 .variant = "QFAB",
161 .build_code = "A0",
162 .flash_size_kb = 128,
163 },
164 {
165 .hwid = 0x0020,
166 .part = "51822",
167 .variant = "CEAA",
168 .build_code = "BA",
169 .flash_size_kb = 256,
170 },
171 {
172 .hwid = 0x002F,
173 .part = "51822",
174 .variant = "CEAA",
175 .build_code = "B0",
176 .flash_size_kb = 256,
177 },
178
179 /* nRF51822 Devices (IC rev 2). */
180 {
181 .hwid = 0x002A,
182 .part = "51822",
183 .variant = "QFAA",
184 .build_code = "FA0",
185 .flash_size_kb = 256,
186 },
187 {
188 .hwid = 0x0044,
189 .part = "51822",
190 .variant = "QFAA",
191 .build_code = "GC0",
192 .flash_size_kb = 256,
193 },
194 {
195 .hwid = 0x003C,
196 .part = "51822",
197 .variant = "QFAA",
198 .build_code = "G0",
199 .flash_size_kb = 256,
200 },
201 {
202 .hwid = 0x0057,
203 .part = "51822",
204 .variant = "QFAA",
205 .build_code = "G2",
206 .flash_size_kb = 256,
207 },
208 {
209 .hwid = 0x0058,
210 .part = "51822",
211 .variant = "QFAA",
212 .build_code = "G3",
213 .flash_size_kb = 256,
214 },
215 {
216 .hwid = 0x004C,
217 .part = "51822",
218 .variant = "QFAB",
219 .build_code = "B0",
220 .flash_size_kb = 128,
221 },
222 {
223 .hwid = 0x0040,
224 .part = "51822",
225 .variant = "CEAA",
226 .build_code = "CA0",
227 .flash_size_kb = 256,
228 },
229 {
230 .hwid = 0x0047,
231 .part = "51822",
232 .variant = "CEAA",
233 .build_code = "DA0",
234 .flash_size_kb = 256,
235 },
236 {
237 .hwid = 0x004D,
238 .part = "51822",
239 .variant = "CEAA",
240 .build_code = "D00",
241 .flash_size_kb = 256,
242 },
243
244 /* nRF51822 Devices (IC rev 3). */
245 {
246 .hwid = 0x0072,
247 .part = "51822",
248 .variant = "QFAA",
249 .build_code = "H0",
250 .flash_size_kb = 256,
251 },
252 {
253 .hwid = 0x007B,
254 .part = "51822",
255 .variant = "QFAB",
256 .build_code = "C0",
257 .flash_size_kb = 128,
258 },
259 {
260 .hwid = 0x0083,
261 .part = "51822",
262 .variant = "QFAC",
263 .build_code = "A0",
264 .flash_size_kb = 256,
265 },
266 {
267 .hwid = 0x0084,
268 .part = "51822",
269 .variant = "QFAC",
270 .build_code = "A1",
271 .flash_size_kb = 256,
272 },
273 {
274 .hwid = 0x007D,
275 .part = "51822",
276 .variant = "CDAB",
277 .build_code = "A0",
278 .flash_size_kb = 128,
279 },
280 {
281 .hwid = 0x0079,
282 .part = "51822",
283 .variant = "CEAA",
284 .build_code = "E0",
285 .flash_size_kb = 256,
286 },
287 {
288 .hwid = 0x0087,
289 .part = "51822",
290 .variant = "CFAC",
291 .build_code = "A0",
292 .flash_size_kb = 256,
293 },
294 {
295 .hwid = 0x008F,
296 .part = "51822",
297 .variant = "QFAA",
298 .build_code = "H1",
299 .flash_size_kb = 256,
300 },
301
302 /* nRF51422 Devices (IC rev 1). */
303 {
304 .hwid = 0x001E,
305 .part = "51422",
306 .variant = "QFAA",
307 .build_code = "CA",
308 .flash_size_kb = 256,
309 },
310 {
311 .hwid = 0x0024,
312 .part = "51422",
313 .variant = "QFAA",
314 .build_code = "C0",
315 .flash_size_kb = 256,
316 },
317 {
318 .hwid = 0x0031,
319 .part = "51422",
320 .variant = "CEAA",
321 .build_code = "A0A",
322 .flash_size_kb = 256,
323 },
324
325 /* nRF51422 Devices (IC rev 2). */
326 {
327 .hwid = 0x002D,
328 .part = "51422",
329 .variant = "QFAA",
330 .build_code = "DAA",
331 .flash_size_kb = 256,
332 },
333 {
334 .hwid = 0x002E,
335 .part = "51422",
336 .variant = "QFAA",
337 .build_code = "E0",
338 .flash_size_kb = 256,
339 },
340 {
341 .hwid = 0x0061,
342 .part = "51422",
343 .variant = "QFAB",
344 .build_code = "A00",
345 .flash_size_kb = 128,
346 },
347 {
348 .hwid = 0x0050,
349 .part = "51422",
350 .variant = "CEAA",
351 .build_code = "B0",
352 .flash_size_kb = 256,
353 },
354
355 /* nRF51422 Devices (IC rev 3). */
356 {
357 .hwid = 0x0073,
358 .part = "51422",
359 .variant = "QFAA",
360 .build_code = "F0",
361 .flash_size_kb = 256,
362 },
363 {
364 .hwid = 0x007C,
365 .part = "51422",
366 .variant = "QFAB",
367 .build_code = "B0",
368 .flash_size_kb = 128,
369 },
370 {
371 .hwid = 0x0085,
372 .part = "51422",
373 .variant = "QFAC",
374 .build_code = "A0",
375 .flash_size_kb = 256,
376 },
377 {
378 .hwid = 0x0086,
379 .part = "51422",
380 .variant = "QFAC",
381 .build_code = "A1",
382 .flash_size_kb = 256,
383 },
384 {
385 .hwid = 0x007E,
386 .part = "51422",
387 .variant = "CDAB",
388 .build_code = "A0",
389 .flash_size_kb = 128,
390 },
391 {
392 .hwid = 0x007A,
393 .part = "51422",
394 .variant = "CEAA",
395 .build_code = "C0",
396 .flash_size_kb = 256,
397 },
398 {
399 .hwid = 0x0088,
400 .part = "51422",
401 .variant = "CFAC",
402 .build_code = "A0",
403 .flash_size_kb = 256,
404 },
405
406 /* Some early nRF51-DK (PCA10028) & nRF51-Dongle (PCA10031) boards
407 with built-in jlink seem to use engineering samples not listed
408 in the nRF51 Series Compatibility Matrix V1.0. */
409 {
410 .hwid = 0x0071,
411 .part = "51822",
412 .variant = "QFAC",
413 .build_code = "AB",
414 .flash_size_kb = 256,
415 },
416 };
417
418 static int nrf51_bank_is_probed(struct flash_bank *bank)
419 {
420 struct nrf51_info *chip = bank->driver_priv;
421
422 assert(chip != NULL);
423
424 return chip->bank[bank->bank_number].probed;
425 }
426 static int nrf51_probe(struct flash_bank *bank);
427
428 static int nrf51_get_probed_chip_if_halted(struct flash_bank *bank, struct nrf51_info **chip)
429 {
430 if (bank->target->state != TARGET_HALTED) {
431 LOG_ERROR("Target not halted");
432 return ERROR_TARGET_NOT_HALTED;
433 }
434
435 *chip = bank->driver_priv;
436
437 int probed = nrf51_bank_is_probed(bank);
438 if (probed < 0)
439 return probed;
440 else if (!probed)
441 return nrf51_probe(bank);
442 else
443 return ERROR_OK;
444 }
445
446 static int nrf51_wait_for_nvmc(struct nrf51_info *chip)
447 {
448 uint32_t ready;
449 int res;
450 int timeout = 100;
451
452 do {
453 res = target_read_u32(chip->target, NRF51_NVMC_READY, &ready);
454 if (res != ERROR_OK) {
455 LOG_ERROR("Couldn't read NVMC_READY register");
456 return res;
457 }
458
459 if (ready == 0x00000001)
460 return ERROR_OK;
461
462 alive_sleep(1);
463 } while (timeout--);
464
465 LOG_DEBUG("Timed out waiting for NVMC_READY");
466 return ERROR_FLASH_BUSY;
467 }
468
469 static int nrf51_nvmc_erase_enable(struct nrf51_info *chip)
470 {
471 int res;
472 res = target_write_u32(chip->target,
473 NRF51_NVMC_CONFIG,
474 NRF51_NVMC_CONFIG_EEN);
475
476 if (res != ERROR_OK) {
477 LOG_ERROR("Failed to enable erase operation");
478 return res;
479 }
480
481 /*
482 According to NVMC examples in Nordic SDK busy status must be
483 checked after writing to NVMC_CONFIG
484 */
485 res = nrf51_wait_for_nvmc(chip);
486 if (res != ERROR_OK)
487 LOG_ERROR("Erase enable did not complete");
488
489 return res;
490 }
491
492 static int nrf51_nvmc_write_enable(struct nrf51_info *chip)
493 {
494 int res;
495 res = target_write_u32(chip->target,
496 NRF51_NVMC_CONFIG,
497 NRF51_NVMC_CONFIG_WEN);
498
499 if (res != ERROR_OK) {
500 LOG_ERROR("Failed to enable write operation");
501 return res;
502 }
503
504 /*
505 According to NVMC examples in Nordic SDK busy status must be
506 checked after writing to NVMC_CONFIG
507 */
508 res = nrf51_wait_for_nvmc(chip);
509 if (res != ERROR_OK)
510 LOG_ERROR("Write enable did not complete");
511
512 return res;
513 }
514
515 static int nrf51_nvmc_read_only(struct nrf51_info *chip)
516 {
517 int res;
518 res = target_write_u32(chip->target,
519 NRF51_NVMC_CONFIG,
520 NRF51_NVMC_CONFIG_REN);
521
522 if (res != ERROR_OK) {
523 LOG_ERROR("Failed to enable read-only operation");
524 return res;
525 }
526 /*
527 According to NVMC examples in Nordic SDK busy status must be
528 checked after writing to NVMC_CONFIG
529 */
530 res = nrf51_wait_for_nvmc(chip);
531 if (res != ERROR_OK)
532 LOG_ERROR("Read only enable did not complete");
533
534 return res;
535 }
536
537 static int nrf51_nvmc_generic_erase(struct nrf51_info *chip,
538 uint32_t erase_register, uint32_t erase_value)
539 {
540 int res;
541
542 res = nrf51_nvmc_erase_enable(chip);
543 if (res != ERROR_OK)
544 goto error;
545
546 res = target_write_u32(chip->target,
547 erase_register,
548 erase_value);
549 if (res != ERROR_OK)
550 goto set_read_only;
551
552 res = nrf51_wait_for_nvmc(chip);
553 if (res != ERROR_OK)
554 goto set_read_only;
555
556 return nrf51_nvmc_read_only(chip);
557
558 set_read_only:
559 nrf51_nvmc_read_only(chip);
560 error:
561 LOG_ERROR("Failed to erase reg: 0x%08"PRIx32" val: 0x%08"PRIx32,
562 erase_register, erase_value);
563 return ERROR_FAIL;
564 }
565
566 static int nrf51_protect_check(struct flash_bank *bank)
567 {
568 int res;
569 uint32_t clenr0;
570
571 /* UICR cannot be write protected so just return early */
572 if (bank->base == NRF51_UICR_BASE)
573 return ERROR_OK;
574
575 struct nrf51_info *chip = bank->driver_priv;
576
577 assert(chip != NULL);
578
579 res = target_read_u32(chip->target, NRF51_FICR_CLENR0,
580 &clenr0);
581 if (res != ERROR_OK) {
582 LOG_ERROR("Couldn't read code region 0 size[FICR]");
583 return res;
584 }
585
586 if (clenr0 == 0xFFFFFFFF) {
587 res = target_read_u32(chip->target, NRF51_UICR_CLENR0,
588 &clenr0);
589 if (res != ERROR_OK) {
590 LOG_ERROR("Couldn't read code region 0 size[UICR]");
591 return res;
592 }
593 }
594
595 for (int i = 0; i < bank->num_sectors; i++)
596 bank->sectors[i].is_protected =
597 clenr0 != 0xFFFFFFFF && bank->sectors[i].offset < clenr0;
598
599 return ERROR_OK;
600 }
601
602 static int nrf51_protect(struct flash_bank *bank, int set, int first, int last)
603 {
604 int res;
605 uint32_t clenr0, ppfc;
606 struct nrf51_info *chip;
607
608 /* UICR cannot be write protected so just bail out early */
609 if (bank->base == NRF51_UICR_BASE)
610 return ERROR_FAIL;
611
612 res = nrf51_get_probed_chip_if_halted(bank, &chip);
613 if (res != ERROR_OK)
614 return res;
615
616 if (first != 0) {
617 LOG_ERROR("Code region 0 must start at the begining of the bank");
618 return ERROR_FAIL;
619 }
620
621 res = target_read_u32(chip->target, NRF51_FICR_PPFC,
622 &ppfc);
623 if (res != ERROR_OK) {
624 LOG_ERROR("Couldn't read PPFC register");
625 return res;
626 }
627
628 if ((ppfc & 0xFF) == 0x00) {
629 LOG_ERROR("Code region 0 size was pre-programmed at the factory, can't change flash protection settings");
630 return ERROR_FAIL;
631 }
632
633 res = target_read_u32(chip->target, NRF51_UICR_CLENR0,
634 &clenr0);
635 if (res != ERROR_OK) {
636 LOG_ERROR("Couldn't read code region 0 size[UICR]");
637 return res;
638 }
639
640 if (clenr0 == 0xFFFFFFFF) {
641 res = target_write_u32(chip->target, NRF51_UICR_CLENR0,
642 clenr0);
643 if (res != ERROR_OK) {
644 LOG_ERROR("Couldn't write code region 0 size[UICR]");
645 return res;
646 }
647
648 } else {
649 LOG_ERROR("You need to perform chip erase before changing the protection settings");
650 }
651
652 nrf51_protect_check(bank);
653
654 return ERROR_OK;
655 }
656
657 static int nrf51_probe(struct flash_bank *bank)
658 {
659 uint32_t hwid;
660 int res;
661 struct nrf51_info *chip = bank->driver_priv;
662
663 res = target_read_u32(chip->target, NRF51_FICR_CONFIGID, &hwid);
664 if (res != ERROR_OK) {
665 LOG_ERROR("Couldn't read CONFIGID register");
666 return res;
667 }
668
669 hwid &= 0xFFFF; /* HWID is stored in the lower two
670 * bytes of the CONFIGID register */
671
672 const struct nrf51_device_spec *spec = NULL;
673 for (size_t i = 0; i < ARRAY_SIZE(nrf51_known_devices_table); i++) {
674 if (hwid == nrf51_known_devices_table[i].hwid) {
675 spec = &nrf51_known_devices_table[i];
676 break;
677 }
678 }
679
680 if (!chip->bank[0].probed && !chip->bank[1].probed) {
681 if (spec)
682 LOG_INFO("nRF%s-%s(build code: %s) %ukB Flash",
683 spec->part, spec->variant, spec->build_code,
684 spec->flash_size_kb);
685 else
686 LOG_WARNING("Unknown device (HWID 0x%08" PRIx32 ")", hwid);
687 }
688
689 if (bank->base == NRF51_FLASH_BASE) {
690 /* The value stored in NRF51_FICR_CODEPAGESIZE is the number of bytes in one page of FLASH. */
691 res = target_read_u32(chip->target, NRF51_FICR_CODEPAGESIZE,
692 &chip->code_page_size);
693 if (res != ERROR_OK) {
694 LOG_ERROR("Couldn't read code page size");
695 return res;
696 }
697
698 /* Note the register name is misleading,
699 * NRF51_FICR_CODESIZE is the number of pages in flash memory, not the number of bytes! */
700 uint32_t num_sectors;
701 res = target_read_u32(chip->target, NRF51_FICR_CODESIZE, &num_sectors);
702 if (res != ERROR_OK) {
703 LOG_ERROR("Couldn't read code memory size");
704 return res;
705 }
706
707 bank->num_sectors = num_sectors;
708 bank->size = num_sectors * chip->code_page_size;
709
710 if (spec && bank->size / 1024 != spec->flash_size_kb)
711 LOG_WARNING("Chip's reported Flash capacity does not match expected one");
712
713 bank->sectors = calloc(bank->num_sectors,
714 sizeof((bank->sectors)[0]));
715 if (!bank->sectors)
716 return ERROR_FLASH_BANK_NOT_PROBED;
717
718 /* Fill out the sector information: all NRF51 sectors are the same size and
719 * there is always a fixed number of them. */
720 for (int i = 0; i < bank->num_sectors; i++) {
721 bank->sectors[i].size = chip->code_page_size;
722 bank->sectors[i].offset = i * chip->code_page_size;
723
724 /* mark as unknown */
725 bank->sectors[i].is_erased = -1;
726 bank->sectors[i].is_protected = -1;
727 }
728
729 nrf51_protect_check(bank);
730
731 chip->bank[0].probed = true;
732 } else {
733 bank->size = NRF51_UICR_SIZE;
734 bank->num_sectors = 1;
735 bank->sectors = calloc(bank->num_sectors,
736 sizeof((bank->sectors)[0]));
737 if (!bank->sectors)
738 return ERROR_FLASH_BANK_NOT_PROBED;
739
740 bank->sectors[0].size = bank->size;
741 bank->sectors[0].offset = 0;
742
743 /* mark as unknown */
744 bank->sectors[0].is_erased = 0;
745 bank->sectors[0].is_protected = 0;
746
747 chip->bank[1].probed = true;
748 }
749
750 return ERROR_OK;
751 }
752
753 static int nrf51_auto_probe(struct flash_bank *bank)
754 {
755 int probed = nrf51_bank_is_probed(bank);
756
757 if (probed < 0)
758 return probed;
759 else if (probed)
760 return ERROR_OK;
761 else
762 return nrf51_probe(bank);
763 }
764
765 static struct flash_sector *nrf51_find_sector_by_address(struct flash_bank *bank, uint32_t address)
766 {
767 struct nrf51_info *chip = bank->driver_priv;
768
769 for (int i = 0; i < bank->num_sectors; i++)
770 if (bank->sectors[i].offset <= address &&
771 address < (bank->sectors[i].offset + chip->code_page_size))
772 return &bank->sectors[i];
773 return NULL;
774 }
775
776 static int nrf51_erase_all(struct nrf51_info *chip)
777 {
778 LOG_DEBUG("Erasing all non-volatile memory");
779 return nrf51_nvmc_generic_erase(chip,
780 NRF51_NVMC_ERASEALL,
781 0x00000001);
782 }
783
784 static int nrf51_erase_page(struct flash_bank *bank,
785 struct nrf51_info *chip,
786 struct flash_sector *sector)
787 {
788 int res;
789
790 LOG_DEBUG("Erasing page at 0x%"PRIx32, sector->offset);
791 if (sector->is_protected) {
792 LOG_ERROR("Cannot erase protected sector at 0x%" PRIx32, sector->offset);
793 return ERROR_FAIL;
794 }
795
796 if (bank->base == NRF51_UICR_BASE) {
797 uint32_t ppfc;
798 res = target_read_u32(chip->target, NRF51_FICR_PPFC,
799 &ppfc);
800 if (res != ERROR_OK) {
801 LOG_ERROR("Couldn't read PPFC register");
802 return res;
803 }
804
805 if ((ppfc & 0xFF) == 0xFF) {
806 /* We can't erase the UICR. Double-check to
807 see if it's already erased before complaining. */
808 default_flash_blank_check(bank);
809 if (sector->is_erased == 1)
810 return ERROR_OK;
811
812 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");
813 return ERROR_FAIL;
814 }
815
816 res = nrf51_nvmc_generic_erase(chip,
817 NRF51_NVMC_ERASEUICR,
818 0x00000001);
819
820
821 } else {
822 res = nrf51_nvmc_generic_erase(chip,
823 NRF51_NVMC_ERASEPAGE,
824 sector->offset);
825 }
826
827 if (res == ERROR_OK)
828 sector->is_erased = 1;
829
830 return res;
831 }
832
833 static const uint8_t nrf51_flash_write_code[] = {
834 /* See contrib/loaders/flash/cortex-m0.S */
835 /* <wait_fifo>: */
836 0x0d, 0x68, /* ldr r5, [r1, #0] */
837 0x00, 0x2d, /* cmp r5, #0 */
838 0x0b, 0xd0, /* beq.n 1e <exit> */
839 0x4c, 0x68, /* ldr r4, [r1, #4] */
840 0xac, 0x42, /* cmp r4, r5 */
841 0xf9, 0xd0, /* beq.n 0 <wait_fifo> */
842 0x20, 0xcc, /* ldmia r4!, {r5} */
843 0x20, 0xc3, /* stmia r3!, {r5} */
844 0x94, 0x42, /* cmp r4, r2 */
845 0x01, 0xd3, /* bcc.n 18 <no_wrap> */
846 0x0c, 0x46, /* mov r4, r1 */
847 0x08, 0x34, /* adds r4, #8 */
848 /* <no_wrap>: */
849 0x4c, 0x60, /* str r4, [r1, #4] */
850 0x04, 0x38, /* subs r0, #4 */
851 0xf0, 0xd1, /* bne.n 0 <wait_fifo> */
852 /* <exit>: */
853 0x00, 0xbe /* bkpt 0x0000 */
854 };
855
856
857 /* Start a low level flash write for the specified region */
858 static int nrf51_ll_flash_write(struct nrf51_info *chip, uint32_t offset, const uint8_t *buffer, uint32_t bytes)
859 {
860 struct target *target = chip->target;
861 uint32_t buffer_size = 8192;
862 struct working_area *write_algorithm;
863 struct working_area *source;
864 uint32_t address = NRF51_FLASH_BASE + offset;
865 struct reg_param reg_params[4];
866 struct armv7m_algorithm armv7m_info;
867 int retval = ERROR_OK;
868
869
870 LOG_DEBUG("Writing buffer to flash offset=0x%"PRIx32" bytes=0x%"PRIx32, offset, bytes);
871 assert(bytes % 4 == 0);
872
873 /* allocate working area with flash programming code */
874 if (target_alloc_working_area(target, sizeof(nrf51_flash_write_code),
875 &write_algorithm) != ERROR_OK) {
876 LOG_WARNING("no working area available, falling back to slow memory writes");
877
878 for (; bytes > 0; bytes -= 4) {
879 retval = target_write_memory(chip->target, offset, 4, 1, buffer);
880 if (retval != ERROR_OK)
881 return retval;
882
883 retval = nrf51_wait_for_nvmc(chip);
884 if (retval != ERROR_OK)
885 return retval;
886
887 offset += 4;
888 buffer += 4;
889 }
890
891 return ERROR_OK;
892 }
893
894 LOG_WARNING("using fast async flash loader. This is currently supported");
895 LOG_WARNING("only with ST-Link and CMSIS-DAP. If you have issues, add");
896 LOG_WARNING("\"set WORKAREASIZE 0\" before sourcing nrf51.cfg to disable it");
897
898 retval = target_write_buffer(target, write_algorithm->address,
899 sizeof(nrf51_flash_write_code),
900 nrf51_flash_write_code);
901 if (retval != ERROR_OK)
902 return retval;
903
904 /* memory buffer */
905 while (target_alloc_working_area(target, buffer_size, &source) != ERROR_OK) {
906 buffer_size /= 2;
907 buffer_size &= ~3UL; /* Make sure it's 4 byte aligned */
908 if (buffer_size <= 256) {
909 /* free working area, write algorithm already allocated */
910 target_free_working_area(target, write_algorithm);
911
912 LOG_WARNING("No large enough working area available, can't do block memory writes");
913 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
914 }
915 }
916
917 armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
918 armv7m_info.core_mode = ARM_MODE_THREAD;
919
920 init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT); /* byte count */
921 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT); /* buffer start */
922 init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT); /* buffer end */
923 init_reg_param(&reg_params[3], "r3", 32, PARAM_IN_OUT); /* target address */
924
925 buf_set_u32(reg_params[0].value, 0, 32, bytes);
926 buf_set_u32(reg_params[1].value, 0, 32, source->address);
927 buf_set_u32(reg_params[2].value, 0, 32, source->address + source->size);
928 buf_set_u32(reg_params[3].value, 0, 32, address);
929
930 retval = target_run_flash_async_algorithm(target, buffer, bytes/4, 4,
931 0, NULL,
932 4, reg_params,
933 source->address, source->size,
934 write_algorithm->address, 0,
935 &armv7m_info);
936
937 target_free_working_area(target, source);
938 target_free_working_area(target, write_algorithm);
939
940 destroy_reg_param(&reg_params[0]);
941 destroy_reg_param(&reg_params[1]);
942 destroy_reg_param(&reg_params[2]);
943 destroy_reg_param(&reg_params[3]);
944
945 return retval;
946 }
947
948 /* Check and erase flash sectors in specified range then start a low level page write.
949 start/end must be sector aligned.
950 */
951 static int nrf51_write_pages(struct flash_bank *bank, uint32_t start, uint32_t end, const uint8_t *buffer)
952 {
953 int res = ERROR_FAIL;
954 struct nrf51_info *chip = bank->driver_priv;
955 struct flash_sector *sector;
956 uint32_t offset;
957
958 assert(start % chip->code_page_size == 0);
959 assert(end % chip->code_page_size == 0);
960
961 /* Erase all sectors */
962 for (offset = start; offset < end; offset += chip->code_page_size) {
963 sector = nrf51_find_sector_by_address(bank, offset);
964 if (!sector) {
965 LOG_ERROR("Invalid sector @ 0x%08"PRIx32, offset);
966 return ERROR_FLASH_SECTOR_INVALID;
967 }
968
969 if (sector->is_protected) {
970 LOG_ERROR("Can't erase protected sector @ 0x%08"PRIx32, offset);
971 goto error;
972 }
973
974 if (sector->is_erased != 1) { /* 1 = erased, 0= not erased, -1 = unknown */
975 res = nrf51_erase_page(bank, chip, sector);
976 if (res != ERROR_OK) {
977 LOG_ERROR("Failed to erase sector @ 0x%08"PRIx32, sector->offset);
978 goto error;
979 }
980 }
981 sector->is_erased = 0;
982 }
983
984 res = nrf51_nvmc_write_enable(chip);
985 if (res != ERROR_OK)
986 goto error;
987
988 res = nrf51_ll_flash_write(chip, start, buffer, (end - start));
989 if (res != ERROR_OK)
990 goto set_read_only;
991
992 return nrf51_nvmc_read_only(chip);
993
994 set_read_only:
995 nrf51_nvmc_read_only(chip);
996 error:
997 LOG_ERROR("Failed to write to nrf51 flash");
998 return res;
999 }
1000
1001 static int nrf51_erase(struct flash_bank *bank, int first, int last)
1002 {
1003 int res;
1004 struct nrf51_info *chip;
1005
1006 res = nrf51_get_probed_chip_if_halted(bank, &chip);
1007 if (res != ERROR_OK)
1008 return res;
1009
1010 /* For each sector to be erased */
1011 for (int s = first; s <= last && res == ERROR_OK; s++)
1012 res = nrf51_erase_page(bank, chip, &bank->sectors[s]);
1013
1014 return res;
1015 }
1016
1017 static int nrf51_code_flash_write(struct flash_bank *bank,
1018 struct nrf51_info *chip,
1019 const uint8_t *buffer, uint32_t offset, uint32_t count)
1020 {
1021
1022 int res;
1023 /* Need to perform reads to fill any gaps we need to preserve in the first page,
1024 before the start of buffer, or in the last page, after the end of buffer */
1025 uint32_t first_page = offset/chip->code_page_size;
1026 uint32_t last_page = DIV_ROUND_UP(offset+count, chip->code_page_size);
1027
1028 uint32_t first_page_offset = first_page * chip->code_page_size;
1029 uint32_t last_page_offset = last_page * chip->code_page_size;
1030
1031 LOG_DEBUG("Padding write from 0x%08"PRIx32"-0x%08"PRIx32" as 0x%08"PRIx32"-0x%08"PRIx32,
1032 offset, offset+count, first_page_offset, last_page_offset);
1033
1034 uint32_t page_cnt = last_page - first_page;
1035 uint8_t buffer_to_flash[page_cnt*chip->code_page_size];
1036
1037 /* Fill in any space between start of first page and start of buffer */
1038 uint32_t pre = offset - first_page_offset;
1039 if (pre > 0) {
1040 res = target_read_memory(bank->target,
1041 first_page_offset,
1042 1,
1043 pre,
1044 buffer_to_flash);
1045 if (res != ERROR_OK)
1046 return res;
1047 }
1048
1049 /* Fill in main contents of buffer */
1050 memcpy(buffer_to_flash+pre, buffer, count);
1051
1052 /* Fill in any space between end of buffer and end of last page */
1053 uint32_t post = last_page_offset - (offset+count);
1054 if (post > 0) {
1055 /* Retrieve the full row contents from Flash */
1056 res = target_read_memory(bank->target,
1057 offset + count,
1058 1,
1059 post,
1060 buffer_to_flash+pre+count);
1061 if (res != ERROR_OK)
1062 return res;
1063 }
1064
1065 return nrf51_write_pages(bank, first_page_offset, last_page_offset, buffer_to_flash);
1066 }
1067
1068 static int nrf51_uicr_flash_write(struct flash_bank *bank,
1069 struct nrf51_info *chip,
1070 const uint8_t *buffer, uint32_t offset, uint32_t count)
1071 {
1072 int res;
1073 uint8_t uicr[NRF51_UICR_SIZE];
1074 struct flash_sector *sector = &bank->sectors[0];
1075
1076 if ((offset + count) > NRF51_UICR_SIZE)
1077 return ERROR_FAIL;
1078
1079 res = target_read_memory(bank->target,
1080 NRF51_UICR_BASE,
1081 1,
1082 NRF51_UICR_SIZE,
1083 uicr);
1084
1085 if (res != ERROR_OK)
1086 return res;
1087
1088 if (sector->is_erased != 1) {
1089 res = nrf51_erase_page(bank, chip, sector);
1090 if (res != ERROR_OK)
1091 return res;
1092 }
1093
1094 res = nrf51_nvmc_write_enable(chip);
1095 if (res != ERROR_OK)
1096 return res;
1097
1098 memcpy(&uicr[offset], buffer, count);
1099
1100 res = nrf51_ll_flash_write(chip, NRF51_UICR_BASE, uicr, NRF51_UICR_SIZE);
1101 if (res != ERROR_OK) {
1102 nrf51_nvmc_read_only(chip);
1103 return res;
1104 }
1105
1106 return nrf51_nvmc_read_only(chip);
1107 }
1108
1109
1110 static int nrf51_write(struct flash_bank *bank, const uint8_t *buffer,
1111 uint32_t offset, uint32_t count)
1112 {
1113 int res;
1114 struct nrf51_info *chip;
1115
1116 res = nrf51_get_probed_chip_if_halted(bank, &chip);
1117 if (res != ERROR_OK)
1118 return res;
1119
1120 return chip->bank[bank->bank_number].write(bank, chip, buffer, offset, count);
1121 }
1122
1123
1124 FLASH_BANK_COMMAND_HANDLER(nrf51_flash_bank_command)
1125 {
1126 static struct nrf51_info *chip;
1127
1128 switch (bank->base) {
1129 case NRF51_FLASH_BASE:
1130 bank->bank_number = 0;
1131 break;
1132 case NRF51_UICR_BASE:
1133 bank->bank_number = 1;
1134 break;
1135 default:
1136 LOG_ERROR("Invalid bank address 0x%08" PRIx32, bank->base);
1137 return ERROR_FAIL;
1138 }
1139
1140 if (!chip) {
1141 /* Create a new chip */
1142 chip = calloc(1, sizeof(*chip));
1143 if (!chip)
1144 return ERROR_FAIL;
1145
1146 chip->target = bank->target;
1147 }
1148
1149 switch (bank->base) {
1150 case NRF51_FLASH_BASE:
1151 chip->bank[bank->bank_number].write = nrf51_code_flash_write;
1152 break;
1153 case NRF51_UICR_BASE:
1154 chip->bank[bank->bank_number].write = nrf51_uicr_flash_write;
1155 break;
1156 }
1157
1158 chip->bank[bank->bank_number].probed = false;
1159 bank->driver_priv = chip;
1160
1161 return ERROR_OK;
1162 }
1163
1164 COMMAND_HANDLER(nrf51_handle_mass_erase_command)
1165 {
1166 int res;
1167 struct flash_bank *bank = NULL;
1168 struct target *target = get_current_target(CMD_CTX);
1169
1170 res = get_flash_bank_by_addr(target, NRF51_FLASH_BASE, true, &bank);
1171 if (res != ERROR_OK)
1172 return res;
1173
1174 assert(bank != NULL);
1175
1176 struct nrf51_info *chip;
1177
1178 res = nrf51_get_probed_chip_if_halted(bank, &chip);
1179 if (res != ERROR_OK)
1180 return res;
1181
1182 uint32_t ppfc;
1183
1184 res = target_read_u32(target, NRF51_FICR_PPFC,
1185 &ppfc);
1186 if (res != ERROR_OK) {
1187 LOG_ERROR("Couldn't read PPFC register");
1188 return res;
1189 }
1190
1191 if ((ppfc & 0xFF) == 0x00) {
1192 LOG_ERROR("Code region 0 size was pre-programmed at the factory, "
1193 "mass erase command won't work.");
1194 return ERROR_FAIL;
1195 }
1196
1197 res = nrf51_erase_all(chip);
1198 if (res != ERROR_OK) {
1199 LOG_ERROR("Failed to erase the chip");
1200 nrf51_protect_check(bank);
1201 return res;
1202 }
1203
1204 for (int i = 0; i < bank->num_sectors; i++)
1205 bank->sectors[i].is_erased = 1;
1206
1207 res = nrf51_protect_check(bank);
1208 if (res != ERROR_OK) {
1209 LOG_ERROR("Failed to check chip's write protection");
1210 return res;
1211 }
1212
1213 res = get_flash_bank_by_addr(target, NRF51_UICR_BASE, true, &bank);
1214 if (res != ERROR_OK)
1215 return res;
1216
1217 bank->sectors[0].is_erased = 1;
1218
1219 return ERROR_OK;
1220 }
1221
1222 static int nrf51_info(struct flash_bank *bank, char *buf, int buf_size)
1223 {
1224 int res;
1225
1226 struct nrf51_info *chip;
1227
1228 res = nrf51_get_probed_chip_if_halted(bank, &chip);
1229 if (res != ERROR_OK)
1230 return res;
1231
1232 static struct {
1233 const uint32_t address;
1234 uint32_t value;
1235 } ficr[] = {
1236 { .address = NRF51_FICR_CODEPAGESIZE },
1237 { .address = NRF51_FICR_CODESIZE },
1238 { .address = NRF51_FICR_CLENR0 },
1239 { .address = NRF51_FICR_PPFC },
1240 { .address = NRF51_FICR_NUMRAMBLOCK },
1241 { .address = NRF51_FICR_SIZERAMBLOCK0 },
1242 { .address = NRF51_FICR_SIZERAMBLOCK1 },
1243 { .address = NRF51_FICR_SIZERAMBLOCK2 },
1244 { .address = NRF51_FICR_SIZERAMBLOCK3 },
1245 { .address = NRF51_FICR_CONFIGID },
1246 { .address = NRF51_FICR_DEVICEID0 },
1247 { .address = NRF51_FICR_DEVICEID1 },
1248 { .address = NRF51_FICR_ER0 },
1249 { .address = NRF51_FICR_ER1 },
1250 { .address = NRF51_FICR_ER2 },
1251 { .address = NRF51_FICR_ER3 },
1252 { .address = NRF51_FICR_IR0 },
1253 { .address = NRF51_FICR_IR1 },
1254 { .address = NRF51_FICR_IR2 },
1255 { .address = NRF51_FICR_IR3 },
1256 { .address = NRF51_FICR_DEVICEADDRTYPE },
1257 { .address = NRF51_FICR_DEVICEADDR0 },
1258 { .address = NRF51_FICR_DEVICEADDR1 },
1259 { .address = NRF51_FICR_OVERRIDEN },
1260 { .address = NRF51_FICR_NRF_1MBIT0 },
1261 { .address = NRF51_FICR_NRF_1MBIT1 },
1262 { .address = NRF51_FICR_NRF_1MBIT2 },
1263 { .address = NRF51_FICR_NRF_1MBIT3 },
1264 { .address = NRF51_FICR_NRF_1MBIT4 },
1265 { .address = NRF51_FICR_BLE_1MBIT0 },
1266 { .address = NRF51_FICR_BLE_1MBIT1 },
1267 { .address = NRF51_FICR_BLE_1MBIT2 },
1268 { .address = NRF51_FICR_BLE_1MBIT3 },
1269 { .address = NRF51_FICR_BLE_1MBIT4 },
1270 }, uicr[] = {
1271 { .address = NRF51_UICR_CLENR0, },
1272 { .address = NRF51_UICR_RBPCONF },
1273 { .address = NRF51_UICR_XTALFREQ },
1274 { .address = NRF51_UICR_FWID },
1275 };
1276
1277 for (size_t i = 0; i < ARRAY_SIZE(ficr); i++) {
1278 res = target_read_u32(chip->target, ficr[i].address,
1279 &ficr[i].value);
1280 if (res != ERROR_OK) {
1281 LOG_ERROR("Couldn't read %" PRIx32, ficr[i].address);
1282 return res;
1283 }
1284 }
1285
1286 for (size_t i = 0; i < ARRAY_SIZE(uicr); i++) {
1287 res = target_read_u32(chip->target, uicr[i].address,
1288 &uicr[i].value);
1289 if (res != ERROR_OK) {
1290 LOG_ERROR("Couldn't read %" PRIx32, uicr[i].address);
1291 return res;
1292 }
1293 }
1294
1295 snprintf(buf, buf_size,
1296 "\n[factory information control block]\n\n"
1297 "code page size: %"PRIu32"B\n"
1298 "code memory size: %"PRIu32"kB\n"
1299 "code region 0 size: %"PRIu32"kB\n"
1300 "pre-programmed code: %s\n"
1301 "number of ram blocks: %"PRIu32"\n"
1302 "ram block 0 size: %"PRIu32"B\n"
1303 "ram block 1 size: %"PRIu32"B\n"
1304 "ram block 2 size: %"PRIu32"B\n"
1305 "ram block 3 size: %"PRIu32 "B\n"
1306 "config id: %" PRIx32 "\n"
1307 "device id: 0x%"PRIx32"%08"PRIx32"\n"
1308 "encryption root: 0x%08"PRIx32"%08"PRIx32"%08"PRIx32"%08"PRIx32"\n"
1309 "identity root: 0x%08"PRIx32"%08"PRIx32"%08"PRIx32"%08"PRIx32"\n"
1310 "device address type: 0x%"PRIx32"\n"
1311 "device address: 0x%"PRIx32"%08"PRIx32"\n"
1312 "override enable: %"PRIx32"\n"
1313 "NRF_1MBIT values: %"PRIx32" %"PRIx32" %"PRIx32" %"PRIx32" %"PRIx32"\n"
1314 "BLE_1MBIT values: %"PRIx32" %"PRIx32" %"PRIx32" %"PRIx32" %"PRIx32"\n"
1315 "\n[user information control block]\n\n"
1316 "code region 0 size: %"PRIu32"kB\n"
1317 "read back protection configuration: %"PRIx32"\n"
1318 "reset value for XTALFREQ: %"PRIx32"\n"
1319 "firmware id: 0x%04"PRIx32,
1320 ficr[0].value,
1321 (ficr[1].value * ficr[0].value) / 1024,
1322 (ficr[2].value == 0xFFFFFFFF) ? 0 : ficr[2].value / 1024,
1323 ((ficr[3].value & 0xFF) == 0x00) ? "present" : "not present",
1324 ficr[4].value,
1325 ficr[5].value,
1326 (ficr[6].value == 0xFFFFFFFF) ? 0 : ficr[6].value,
1327 (ficr[7].value == 0xFFFFFFFF) ? 0 : ficr[7].value,
1328 (ficr[8].value == 0xFFFFFFFF) ? 0 : ficr[8].value,
1329 ficr[9].value,
1330 ficr[10].value, ficr[11].value,
1331 ficr[12].value, ficr[13].value, ficr[14].value, ficr[15].value,
1332 ficr[16].value, ficr[17].value, ficr[18].value, ficr[19].value,
1333 ficr[20].value,
1334 ficr[21].value, ficr[22].value,
1335 ficr[23].value,
1336 ficr[24].value, ficr[25].value, ficr[26].value, ficr[27].value, ficr[28].value,
1337 ficr[29].value, ficr[30].value, ficr[31].value, ficr[32].value, ficr[33].value,
1338 (uicr[0].value == 0xFFFFFFFF) ? 0 : uicr[0].value / 1024,
1339 uicr[1].value & 0xFFFF,
1340 uicr[2].value & 0xFF,
1341 uicr[3].value & 0xFFFF);
1342
1343 return ERROR_OK;
1344 }
1345
1346 static const struct command_registration nrf51_exec_command_handlers[] = {
1347 {
1348 .name = "mass_erase",
1349 .handler = nrf51_handle_mass_erase_command,
1350 .mode = COMMAND_EXEC,
1351 .help = "Erase all flash contents of the chip.",
1352 },
1353 COMMAND_REGISTRATION_DONE
1354 };
1355
1356 static const struct command_registration nrf51_command_handlers[] = {
1357 {
1358 .name = "nrf51",
1359 .mode = COMMAND_ANY,
1360 .help = "nrf51 flash command group",
1361 .usage = "",
1362 .chain = nrf51_exec_command_handlers,
1363 },
1364 COMMAND_REGISTRATION_DONE
1365 };
1366
1367 struct flash_driver nrf51_flash = {
1368 .name = "nrf51",
1369 .commands = nrf51_command_handlers,
1370 .flash_bank_command = nrf51_flash_bank_command,
1371 .info = nrf51_info,
1372 .erase = nrf51_erase,
1373 .protect = nrf51_protect,
1374 .write = nrf51_write,
1375 .read = default_flash_read,
1376 .probe = nrf51_probe,
1377 .auto_probe = nrf51_auto_probe,
1378 .erase_check = default_flash_blank_check,
1379 .protect_check = nrf51_protect_check,
1380 };

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)