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

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)