nrf51: recognize hwid 0084
[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 = 0x0084,
319 .variant = "QFAC",
320 .build_code = "A1",
321 .flash_size_kb = 256,
322 },
323 {
324 .hwid = 0x0085,
325 .variant = "QFAC",
326 .build_code = "A0",
327 .flash_size_kb = 256,
328 },
329 {
330 .hwid = 0x0086,
331 .variant = "QFAC",
332 .build_code = "A1",
333 .flash_size_kb = 256,
334 },
335 {
336 .hwid = 0x007E,
337 .variant = "CDAB",
338 .build_code = "A0",
339 .flash_size_kb = 128,
340 },
341 {
342 .hwid = 0x007A,
343 .variant = "CEAA",
344 .build_code = "C0",
345 .flash_size_kb = 256,
346 },
347 {
348 .hwid = 0x0088,
349 .variant = "CFAC",
350 .build_code = "A0",
351 .flash_size_kb = 256,
352 },
353
354 /* Some early nRF51-DK (PCA10028) & nRF51-Dongle (PCA10031) boards
355 with built-in jlink seem to use engineering samples not listed
356 in the nRF51 Series Compatibility Matrix V1.0. */
357 {
358 .hwid = 0x0071,
359 .variant = "QFAC",
360 .build_code = "AB",
361 .flash_size_kb = 256,
362 },
363 };
364
365 static int nrf51_bank_is_probed(struct flash_bank *bank)
366 {
367 struct nrf51_info *chip = bank->driver_priv;
368
369 assert(chip != NULL);
370
371 return chip->bank[bank->bank_number].probed;
372 }
373 static int nrf51_probe(struct flash_bank *bank);
374
375 static int nrf51_get_probed_chip_if_halted(struct flash_bank *bank, struct nrf51_info **chip)
376 {
377 if (bank->target->state != TARGET_HALTED) {
378 LOG_ERROR("Target not halted");
379 return ERROR_TARGET_NOT_HALTED;
380 }
381
382 *chip = bank->driver_priv;
383
384 int probed = nrf51_bank_is_probed(bank);
385 if (probed < 0)
386 return probed;
387 else if (!probed)
388 return nrf51_probe(bank);
389 else
390 return ERROR_OK;
391 }
392
393 static int nrf51_wait_for_nvmc(struct nrf51_info *chip)
394 {
395 uint32_t ready;
396 int res;
397 int timeout = 100;
398
399 do {
400 res = target_read_u32(chip->target, NRF51_NVMC_READY, &ready);
401 if (res != ERROR_OK) {
402 LOG_ERROR("Couldn't read NVMC_READY register");
403 return res;
404 }
405
406 if (ready == 0x00000001)
407 return ERROR_OK;
408
409 alive_sleep(1);
410 } while (timeout--);
411
412 LOG_DEBUG("Timed out waiting for NVMC_READY");
413 return ERROR_FLASH_BUSY;
414 }
415
416 static int nrf51_nvmc_erase_enable(struct nrf51_info *chip)
417 {
418 int res;
419 res = target_write_u32(chip->target,
420 NRF51_NVMC_CONFIG,
421 NRF51_NVMC_CONFIG_EEN);
422
423 if (res != ERROR_OK) {
424 LOG_ERROR("Failed to enable erase operation");
425 return res;
426 }
427
428 /*
429 According to NVMC examples in Nordic SDK busy status must be
430 checked after writing to NVMC_CONFIG
431 */
432 res = nrf51_wait_for_nvmc(chip);
433 if (res != ERROR_OK)
434 LOG_ERROR("Erase enable did not complete");
435
436 return res;
437 }
438
439 static int nrf51_nvmc_write_enable(struct nrf51_info *chip)
440 {
441 int res;
442 res = target_write_u32(chip->target,
443 NRF51_NVMC_CONFIG,
444 NRF51_NVMC_CONFIG_WEN);
445
446 if (res != ERROR_OK) {
447 LOG_ERROR("Failed to enable write operation");
448 return res;
449 }
450
451 /*
452 According to NVMC examples in Nordic SDK busy status must be
453 checked after writing to NVMC_CONFIG
454 */
455 res = nrf51_wait_for_nvmc(chip);
456 if (res != ERROR_OK)
457 LOG_ERROR("Write enable did not complete");
458
459 return res;
460 }
461
462 static int nrf51_nvmc_read_only(struct nrf51_info *chip)
463 {
464 int res;
465 res = target_write_u32(chip->target,
466 NRF51_NVMC_CONFIG,
467 NRF51_NVMC_CONFIG_REN);
468
469 if (res != ERROR_OK) {
470 LOG_ERROR("Failed to enable read-only operation");
471 return res;
472 }
473 /*
474 According to NVMC examples in Nordic SDK busy status must be
475 checked after writing to NVMC_CONFIG
476 */
477 res = nrf51_wait_for_nvmc(chip);
478 if (res != ERROR_OK)
479 LOG_ERROR("Read only enable did not complete");
480
481 return res;
482 }
483
484 static int nrf51_nvmc_generic_erase(struct nrf51_info *chip,
485 uint32_t erase_register, uint32_t erase_value)
486 {
487 int res;
488
489 res = nrf51_nvmc_erase_enable(chip);
490 if (res != ERROR_OK)
491 goto error;
492
493 res = target_write_u32(chip->target,
494 erase_register,
495 erase_value);
496 if (res != ERROR_OK)
497 goto set_read_only;
498
499 res = nrf51_wait_for_nvmc(chip);
500 if (res != ERROR_OK)
501 goto set_read_only;
502
503 return nrf51_nvmc_read_only(chip);
504
505 set_read_only:
506 nrf51_nvmc_read_only(chip);
507 error:
508 LOG_ERROR("Failed to erase reg: 0x%08"PRIx32" val: 0x%08"PRIx32,
509 erase_register, erase_value);
510 return ERROR_FAIL;
511 }
512
513 static int nrf51_protect_check(struct flash_bank *bank)
514 {
515 int res;
516 uint32_t clenr0;
517
518 /* UICR cannot be write protected so just return early */
519 if (bank->base == NRF51_UICR_BASE)
520 return ERROR_OK;
521
522 struct nrf51_info *chip = bank->driver_priv;
523
524 assert(chip != NULL);
525
526 res = target_read_u32(chip->target, NRF51_FICR_CLENR0,
527 &clenr0);
528 if (res != ERROR_OK) {
529 LOG_ERROR("Couldn't read code region 0 size[FICR]");
530 return res;
531 }
532
533 if (clenr0 == 0xFFFFFFFF) {
534 res = target_read_u32(chip->target, NRF51_UICR_CLENR0,
535 &clenr0);
536 if (res != ERROR_OK) {
537 LOG_ERROR("Couldn't read code region 0 size[UICR]");
538 return res;
539 }
540 }
541
542 for (int i = 0; i < bank->num_sectors; i++)
543 bank->sectors[i].is_protected =
544 clenr0 != 0xFFFFFFFF && bank->sectors[i].offset < clenr0;
545
546 return ERROR_OK;
547 }
548
549 static int nrf51_protect(struct flash_bank *bank, int set, int first, int last)
550 {
551 int res;
552 uint32_t clenr0, ppfc;
553 struct nrf51_info *chip;
554
555 /* UICR cannot be write protected so just bail out early */
556 if (bank->base == NRF51_UICR_BASE)
557 return ERROR_FAIL;
558
559 res = nrf51_get_probed_chip_if_halted(bank, &chip);
560 if (res != ERROR_OK)
561 return res;
562
563 if (first != 0) {
564 LOG_ERROR("Code region 0 must start at the begining of the bank");
565 return ERROR_FAIL;
566 }
567
568 res = target_read_u32(chip->target, NRF51_FICR_PPFC,
569 &ppfc);
570 if (res != ERROR_OK) {
571 LOG_ERROR("Couldn't read PPFC register");
572 return res;
573 }
574
575 if ((ppfc & 0xFF) == 0x00) {
576 LOG_ERROR("Code region 0 size was pre-programmed at the factory, can't change flash protection settings");
577 return ERROR_FAIL;
578 };
579
580 res = target_read_u32(chip->target, NRF51_UICR_CLENR0,
581 &clenr0);
582 if (res != ERROR_OK) {
583 LOG_ERROR("Couldn't read code region 0 size[UICR]");
584 return res;
585 }
586
587 if (clenr0 == 0xFFFFFFFF) {
588 res = target_write_u32(chip->target, NRF51_UICR_CLENR0,
589 clenr0);
590 if (res != ERROR_OK) {
591 LOG_ERROR("Couldn't write code region 0 size[UICR]");
592 return res;
593 }
594
595 } else {
596 LOG_ERROR("You need to perform chip erase before changing the protection settings");
597 }
598
599 nrf51_protect_check(bank);
600
601 return ERROR_OK;
602 }
603
604 static int nrf51_probe(struct flash_bank *bank)
605 {
606 uint32_t hwid;
607 int res;
608 struct nrf51_info *chip = bank->driver_priv;
609
610 res = target_read_u32(chip->target, NRF51_FICR_CONFIGID, &hwid);
611 if (res != ERROR_OK) {
612 LOG_ERROR("Couldn't read CONFIGID register");
613 return res;
614 }
615
616 hwid &= 0xFFFF; /* HWID is stored in the lower two
617 * bytes of the CONFIGID register */
618
619 const struct nrf51_device_spec *spec = NULL;
620 for (size_t i = 0; i < ARRAY_SIZE(nrf51_known_devices_table); i++)
621 if (hwid == nrf51_known_devices_table[i].hwid) {
622 spec = &nrf51_known_devices_table[i];
623 break;
624 }
625
626 if (!chip->bank[0].probed && !chip->bank[1].probed) {
627 if (spec)
628 LOG_INFO("nRF51822-%s(build code: %s) %ukB Flash",
629 spec->variant, spec->build_code, spec->flash_size_kb);
630 else
631 LOG_WARNING("Unknown device (HWID 0x%08" PRIx32 ")", hwid);
632 }
633
634
635 if (bank->base == NRF51_FLASH_BASE) {
636 res = target_read_u32(chip->target, NRF51_FICR_CODEPAGESIZE,
637 &chip->code_page_size);
638 if (res != ERROR_OK) {
639 LOG_ERROR("Couldn't read code page size");
640 return res;
641 }
642
643 res = target_read_u32(chip->target, NRF51_FICR_CODESIZE,
644 &chip->code_memory_size);
645 if (res != ERROR_OK) {
646 LOG_ERROR("Couldn't read code memory size");
647 return res;
648 }
649
650 if (spec && chip->code_memory_size != spec->flash_size_kb) {
651 LOG_ERROR("Chip's reported Flash capacity does not match expected one");
652 return ERROR_FAIL;
653 }
654
655 bank->size = chip->code_memory_size * 1024;
656 bank->num_sectors = bank->size / chip->code_page_size;
657 bank->sectors = calloc(bank->num_sectors,
658 sizeof((bank->sectors)[0]));
659 if (!bank->sectors)
660 return ERROR_FLASH_BANK_NOT_PROBED;
661
662 /* Fill out the sector information: all NRF51 sectors are the same size and
663 * there is always a fixed number of them. */
664 for (int i = 0; i < bank->num_sectors; i++) {
665 bank->sectors[i].size = chip->code_page_size;
666 bank->sectors[i].offset = i * chip->code_page_size;
667
668 /* mark as unknown */
669 bank->sectors[i].is_erased = -1;
670 bank->sectors[i].is_protected = -1;
671 }
672
673 nrf51_protect_check(bank);
674
675 chip->bank[0].probed = true;
676 } else {
677 bank->size = NRF51_UICR_SIZE;
678 bank->num_sectors = 1;
679 bank->sectors = calloc(bank->num_sectors,
680 sizeof((bank->sectors)[0]));
681 if (!bank->sectors)
682 return ERROR_FLASH_BANK_NOT_PROBED;
683
684 bank->sectors[0].size = bank->size;
685 bank->sectors[0].offset = 0;
686
687 /* mark as unknown */
688 bank->sectors[0].is_erased = 0;
689 bank->sectors[0].is_protected = 0;
690
691 chip->bank[1].probed = true;
692 }
693
694 return ERROR_OK;
695 }
696
697 static int nrf51_auto_probe(struct flash_bank *bank)
698 {
699 int probed = nrf51_bank_is_probed(bank);
700
701 if (probed < 0)
702 return probed;
703 else if (probed)
704 return ERROR_OK;
705 else
706 return nrf51_probe(bank);
707 }
708
709 static struct flash_sector *nrf51_find_sector_by_address(struct flash_bank *bank, uint32_t address)
710 {
711 struct nrf51_info *chip = bank->driver_priv;
712
713 for (int i = 0; i < bank->num_sectors; i++)
714 if (bank->sectors[i].offset <= address &&
715 address < (bank->sectors[i].offset + chip->code_page_size))
716 return &bank->sectors[i];
717 return NULL;
718 }
719
720 static int nrf51_erase_all(struct nrf51_info *chip)
721 {
722 LOG_DEBUG("Erasing all non-volatile memory");
723 return nrf51_nvmc_generic_erase(chip,
724 NRF51_NVMC_ERASEALL,
725 0x00000001);
726 }
727
728 static int nrf51_erase_page(struct flash_bank *bank,
729 struct nrf51_info *chip,
730 struct flash_sector *sector)
731 {
732 int res;
733
734 LOG_DEBUG("Erasing page at 0x%"PRIx32, sector->offset);
735 if (sector->is_protected) {
736 LOG_ERROR("Cannot erase protected sector at 0x%" PRIx32, sector->offset);
737 return ERROR_FAIL;
738 }
739
740 if (bank->base == NRF51_UICR_BASE) {
741 uint32_t ppfc;
742 res = target_read_u32(chip->target, NRF51_FICR_PPFC,
743 &ppfc);
744 if (res != ERROR_OK) {
745 LOG_ERROR("Couldn't read PPFC register");
746 return res;
747 }
748
749 if ((ppfc & 0xFF) == 0xFF) {
750 /* We can't erase the UICR. Double-check to
751 see if it's already erased before complaining. */
752 default_flash_blank_check(bank);
753 if (sector->is_erased == 1)
754 return ERROR_OK;
755
756 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");
757 return ERROR_FAIL;
758 };
759
760 res = nrf51_nvmc_generic_erase(chip,
761 NRF51_NVMC_ERASEUICR,
762 0x00000001);
763
764
765 } else {
766 res = nrf51_nvmc_generic_erase(chip,
767 NRF51_NVMC_ERASEPAGE,
768 sector->offset);
769 }
770
771 if (res == ERROR_OK)
772 sector->is_erased = 1;
773
774 return res;
775 }
776
777 static const uint8_t nrf51_flash_write_code[] = {
778 /* See contrib/loaders/flash/cortex-m0.S */
779 /* <wait_fifo>: */
780 0x0d, 0x68, /* ldr r5, [r1, #0] */
781 0x00, 0x2d, /* cmp r5, #0 */
782 0x0b, 0xd0, /* beq.n 1e <exit> */
783 0x4c, 0x68, /* ldr r4, [r1, #4] */
784 0xac, 0x42, /* cmp r4, r5 */
785 0xf9, 0xd0, /* beq.n 0 <wait_fifo> */
786 0x20, 0xcc, /* ldmia r4!, {r5} */
787 0x20, 0xc3, /* stmia r3!, {r5} */
788 0x94, 0x42, /* cmp r4, r2 */
789 0x01, 0xd3, /* bcc.n 18 <no_wrap> */
790 0x0c, 0x46, /* mov r4, r1 */
791 0x08, 0x34, /* adds r4, #8 */
792 /* <no_wrap>: */
793 0x4c, 0x60, /* str r4, [r1, #4] */
794 0x04, 0x38, /* subs r0, #4 */
795 0xf0, 0xd1, /* bne.n 0 <wait_fifo> */
796 /* <exit>: */
797 0x00, 0xbe /* bkpt 0x0000 */
798 };
799
800
801 /* Start a low level flash write for the specified region */
802 static int nrf51_ll_flash_write(struct nrf51_info *chip, uint32_t offset, const uint8_t *buffer, uint32_t bytes)
803 {
804 struct target *target = chip->target;
805 uint32_t buffer_size = 8192;
806 struct working_area *write_algorithm;
807 struct working_area *source;
808 uint32_t address = NRF51_FLASH_BASE + offset;
809 struct reg_param reg_params[4];
810 struct armv7m_algorithm armv7m_info;
811 int retval = ERROR_OK;
812
813
814 LOG_DEBUG("Writing buffer to flash offset=0x%"PRIx32" bytes=0x%"PRIx32, offset, bytes);
815 assert(bytes % 4 == 0);
816
817 /* allocate working area with flash programming code */
818 if (target_alloc_working_area(target, sizeof(nrf51_flash_write_code),
819 &write_algorithm) != ERROR_OK) {
820 LOG_WARNING("no working area available, falling back to slow memory writes");
821
822 for (; bytes > 0; bytes -= 4) {
823 retval = target_write_memory(chip->target, offset, 4, 1, buffer);
824 if (retval != ERROR_OK)
825 return retval;
826
827 retval = nrf51_wait_for_nvmc(chip);
828 if (retval != ERROR_OK)
829 return retval;
830
831 offset += 4;
832 buffer += 4;
833 }
834
835 return ERROR_OK;
836 }
837
838 LOG_WARNING("using fast async flash loader. This is currently supported");
839 LOG_WARNING("only with ST-Link and CMSIS-DAP. If you have issues, add");
840 LOG_WARNING("\"set WORKAREASIZE 0\" before sourcing nrf51.cfg to disable it");
841
842 retval = target_write_buffer(target, write_algorithm->address,
843 sizeof(nrf51_flash_write_code),
844 nrf51_flash_write_code);
845 if (retval != ERROR_OK)
846 return retval;
847
848 /* memory buffer */
849 while (target_alloc_working_area(target, buffer_size, &source) != ERROR_OK) {
850 buffer_size /= 2;
851 buffer_size &= ~3UL; /* Make sure it's 4 byte aligned */
852 if (buffer_size <= 256) {
853 /* free working area, write algorithm already allocated */
854 target_free_working_area(target, write_algorithm);
855
856 LOG_WARNING("No large enough working area available, can't do block memory writes");
857 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
858 }
859 }
860
861 armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
862 armv7m_info.core_mode = ARM_MODE_THREAD;
863
864 init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT); /* byte count */
865 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT); /* buffer start */
866 init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT); /* buffer end */
867 init_reg_param(&reg_params[3], "r3", 32, PARAM_IN_OUT); /* target address */
868
869 buf_set_u32(reg_params[0].value, 0, 32, bytes);
870 buf_set_u32(reg_params[1].value, 0, 32, source->address);
871 buf_set_u32(reg_params[2].value, 0, 32, source->address + source->size);
872 buf_set_u32(reg_params[3].value, 0, 32, address);
873
874 retval = target_run_flash_async_algorithm(target, buffer, bytes/4, 4,
875 0, NULL,
876 4, reg_params,
877 source->address, source->size,
878 write_algorithm->address, 0,
879 &armv7m_info);
880
881 target_free_working_area(target, source);
882 target_free_working_area(target, write_algorithm);
883
884 destroy_reg_param(&reg_params[0]);
885 destroy_reg_param(&reg_params[1]);
886 destroy_reg_param(&reg_params[2]);
887 destroy_reg_param(&reg_params[3]);
888
889 return retval;
890 }
891
892 /* Check and erase flash sectors in specified range then start a low level page write.
893 start/end must be sector aligned.
894 */
895 static int nrf51_write_pages(struct flash_bank *bank, uint32_t start, uint32_t end, const uint8_t *buffer)
896 {
897 int res = ERROR_FAIL;
898 struct nrf51_info *chip = bank->driver_priv;
899 struct flash_sector *sector;
900 uint32_t offset;
901
902 assert(start % chip->code_page_size == 0);
903 assert(end % chip->code_page_size == 0);
904
905 /* Erase all sectors */
906 for (offset = start; offset < end; offset += chip->code_page_size) {
907 sector = nrf51_find_sector_by_address(bank, offset);
908 if (!sector) {
909 LOG_ERROR("Invalid sector @ 0x%08"PRIx32, offset);
910 return ERROR_FLASH_SECTOR_INVALID;
911 }
912
913 if (sector->is_protected) {
914 LOG_ERROR("Can't erase protected sector @ 0x%08"PRIx32, offset);
915 goto error;
916 }
917
918 if (sector->is_erased != 1) { /* 1 = erased, 0= not erased, -1 = unknown */
919 res = nrf51_erase_page(bank, chip, sector);
920 if (res != ERROR_OK) {
921 LOG_ERROR("Failed to erase sector @ 0x%08"PRIx32, sector->offset);
922 goto error;
923 }
924 }
925 sector->is_erased = 0;
926 }
927
928 res = nrf51_nvmc_write_enable(chip);
929 if (res != ERROR_OK)
930 goto error;
931
932 res = nrf51_ll_flash_write(chip, start, buffer, (end - start));
933 if (res != ERROR_OK)
934 goto set_read_only;
935
936 return nrf51_nvmc_read_only(chip);
937
938 set_read_only:
939 nrf51_nvmc_read_only(chip);
940 error:
941 LOG_ERROR("Failed to write to nrf51 flash");
942 return res;
943 }
944
945 static int nrf51_erase(struct flash_bank *bank, int first, int last)
946 {
947 int res;
948 struct nrf51_info *chip;
949
950 res = nrf51_get_probed_chip_if_halted(bank, &chip);
951 if (res != ERROR_OK)
952 return res;
953
954 /* For each sector to be erased */
955 for (int s = first; s <= last && res == ERROR_OK; s++)
956 res = nrf51_erase_page(bank, chip, &bank->sectors[s]);
957
958 return res;
959 }
960
961 static int nrf51_code_flash_write(struct flash_bank *bank,
962 struct nrf51_info *chip,
963 const uint8_t *buffer, uint32_t offset, uint32_t count)
964 {
965
966 int res;
967 /* Need to perform reads to fill any gaps we need to preserve in the first page,
968 before the start of buffer, or in the last page, after the end of buffer */
969 uint32_t first_page = offset/chip->code_page_size;
970 uint32_t last_page = DIV_ROUND_UP(offset+count, chip->code_page_size);
971
972 uint32_t first_page_offset = first_page * chip->code_page_size;
973 uint32_t last_page_offset = last_page * chip->code_page_size;
974
975 LOG_DEBUG("Padding write from 0x%08"PRIx32"-0x%08"PRIx32" as 0x%08"PRIx32"-0x%08"PRIx32,
976 offset, offset+count, first_page_offset, last_page_offset);
977
978 uint32_t page_cnt = last_page - first_page;
979 uint8_t buffer_to_flash[page_cnt*chip->code_page_size];
980
981 /* Fill in any space between start of first page and start of buffer */
982 uint32_t pre = offset - first_page_offset;
983 if (pre > 0) {
984 res = target_read_memory(bank->target,
985 first_page_offset,
986 1,
987 pre,
988 buffer_to_flash);
989 if (res != ERROR_OK)
990 return res;
991 }
992
993 /* Fill in main contents of buffer */
994 memcpy(buffer_to_flash+pre, buffer, count);
995
996 /* Fill in any space between end of buffer and end of last page */
997 uint32_t post = last_page_offset - (offset+count);
998 if (post > 0) {
999 /* Retrieve the full row contents from Flash */
1000 res = target_read_memory(bank->target,
1001 offset + count,
1002 1,
1003 post,
1004 buffer_to_flash+pre+count);
1005 if (res != ERROR_OK)
1006 return res;
1007 }
1008
1009 return nrf51_write_pages(bank, first_page_offset, last_page_offset, buffer_to_flash);
1010 }
1011
1012 static int nrf51_uicr_flash_write(struct flash_bank *bank,
1013 struct nrf51_info *chip,
1014 const uint8_t *buffer, uint32_t offset, uint32_t count)
1015 {
1016 int res;
1017 uint8_t uicr[NRF51_UICR_SIZE];
1018 struct flash_sector *sector = &bank->sectors[0];
1019
1020 if ((offset + count) > NRF51_UICR_SIZE)
1021 return ERROR_FAIL;
1022
1023 res = target_read_memory(bank->target,
1024 NRF51_UICR_BASE,
1025 1,
1026 NRF51_UICR_SIZE,
1027 uicr);
1028
1029 if (res != ERROR_OK)
1030 return res;
1031
1032 if (sector->is_erased != 1) {
1033 res = nrf51_erase_page(bank, chip, sector);
1034 if (res != ERROR_OK)
1035 return res;
1036 }
1037
1038 res = nrf51_nvmc_write_enable(chip);
1039 if (res != ERROR_OK)
1040 return res;
1041
1042 memcpy(&uicr[offset], buffer, count);
1043
1044 res = nrf51_ll_flash_write(chip, NRF51_UICR_BASE, uicr, NRF51_UICR_SIZE);
1045 if (res != ERROR_OK) {
1046 nrf51_nvmc_read_only(chip);
1047 return res;
1048 }
1049
1050 return nrf51_nvmc_read_only(chip);
1051 }
1052
1053
1054 static int nrf51_write(struct flash_bank *bank, const uint8_t *buffer,
1055 uint32_t offset, uint32_t count)
1056 {
1057 int res;
1058 struct nrf51_info *chip;
1059
1060 res = nrf51_get_probed_chip_if_halted(bank, &chip);
1061 if (res != ERROR_OK)
1062 return res;
1063
1064 return chip->bank[bank->bank_number].write(bank, chip, buffer, offset, count);
1065 }
1066
1067
1068 FLASH_BANK_COMMAND_HANDLER(nrf51_flash_bank_command)
1069 {
1070 static struct nrf51_info *chip;
1071
1072 switch (bank->base) {
1073 case NRF51_FLASH_BASE:
1074 bank->bank_number = 0;
1075 break;
1076 case NRF51_UICR_BASE:
1077 bank->bank_number = 1;
1078 break;
1079 default:
1080 LOG_ERROR("Invalid bank address 0x%08" PRIx32, bank->base);
1081 return ERROR_FAIL;
1082 }
1083
1084 if (!chip) {
1085 /* Create a new chip */
1086 chip = calloc(1, sizeof(*chip));
1087 if (!chip)
1088 return ERROR_FAIL;
1089
1090 chip->target = bank->target;
1091 }
1092
1093 switch (bank->base) {
1094 case NRF51_FLASH_BASE:
1095 chip->bank[bank->bank_number].write = nrf51_code_flash_write;
1096 break;
1097 case NRF51_UICR_BASE:
1098 chip->bank[bank->bank_number].write = nrf51_uicr_flash_write;
1099 break;
1100 }
1101
1102 chip->bank[bank->bank_number].probed = false;
1103 bank->driver_priv = chip;
1104
1105 return ERROR_OK;
1106 }
1107
1108 COMMAND_HANDLER(nrf51_handle_mass_erase_command)
1109 {
1110 int res;
1111 struct flash_bank *bank = NULL;
1112 struct target *target = get_current_target(CMD_CTX);
1113
1114 res = get_flash_bank_by_addr(target, NRF51_FLASH_BASE, true, &bank);
1115 if (res != ERROR_OK)
1116 return res;
1117
1118 assert(bank != NULL);
1119
1120 struct nrf51_info *chip;
1121
1122 res = nrf51_get_probed_chip_if_halted(bank, &chip);
1123 if (res != ERROR_OK)
1124 return res;
1125
1126 uint32_t ppfc;
1127
1128 res = target_read_u32(target, NRF51_FICR_PPFC,
1129 &ppfc);
1130 if (res != ERROR_OK) {
1131 LOG_ERROR("Couldn't read PPFC register");
1132 return res;
1133 }
1134
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.");
1138 return ERROR_FAIL;
1139 };
1140
1141 res = nrf51_erase_all(chip);
1142 if (res != ERROR_OK) {
1143 LOG_ERROR("Failed to erase the chip");
1144 nrf51_protect_check(bank);
1145 return res;
1146 }
1147
1148 for (int i = 0; i < bank->num_sectors; i++)
1149 bank->sectors[i].is_erased = 1;
1150
1151 res = nrf51_protect_check(bank);
1152 if (res != ERROR_OK) {
1153 LOG_ERROR("Failed to check chip's write protection");
1154 return res;
1155 }
1156
1157 res = get_flash_bank_by_addr(target, NRF51_UICR_BASE, true, &bank);
1158 if (res != ERROR_OK)
1159 return res;
1160
1161 bank->sectors[0].is_erased = 1;
1162
1163 return ERROR_OK;
1164 }
1165
1166 static int nrf51_info(struct flash_bank *bank, char *buf, int buf_size)
1167 {
1168 int res;
1169
1170 struct nrf51_info *chip;
1171
1172 res = nrf51_get_probed_chip_if_halted(bank, &chip);
1173 if (res != ERROR_OK)
1174 return res;
1175
1176 static struct {
1177 const uint32_t address;
1178 uint32_t value;
1179 } ficr[] = {
1180 { .address = NRF51_FICR_CODEPAGESIZE },
1181 { .address = NRF51_FICR_CODESIZE },
1182 { .address = NRF51_FICR_CLENR0 },
1183 { .address = NRF51_FICR_PPFC },
1184 { .address = NRF51_FICR_NUMRAMBLOCK },
1185 { .address = NRF51_FICR_SIZERAMBLOCK0 },
1186 { .address = NRF51_FICR_SIZERAMBLOCK1 },
1187 { .address = NRF51_FICR_SIZERAMBLOCK2 },
1188 { .address = NRF51_FICR_SIZERAMBLOCK3 },
1189 { .address = NRF51_FICR_CONFIGID },
1190 { .address = NRF51_FICR_DEVICEID0 },
1191 { .address = NRF51_FICR_DEVICEID1 },
1192 { .address = NRF51_FICR_ER0 },
1193 { .address = NRF51_FICR_ER1 },
1194 { .address = NRF51_FICR_ER2 },
1195 { .address = NRF51_FICR_ER3 },
1196 { .address = NRF51_FICR_IR0 },
1197 { .address = NRF51_FICR_IR1 },
1198 { .address = NRF51_FICR_IR2 },
1199 { .address = NRF51_FICR_IR3 },
1200 { .address = NRF51_FICR_DEVICEADDRTYPE },
1201 { .address = NRF51_FICR_DEVICEADDR0 },
1202 { .address = NRF51_FICR_DEVICEADDR1 },
1203 { .address = NRF51_FICR_OVERRIDEN },
1204 { .address = NRF51_FICR_NRF_1MBIT0 },
1205 { .address = NRF51_FICR_NRF_1MBIT1 },
1206 { .address = NRF51_FICR_NRF_1MBIT2 },
1207 { .address = NRF51_FICR_NRF_1MBIT3 },
1208 { .address = NRF51_FICR_NRF_1MBIT4 },
1209 { .address = NRF51_FICR_BLE_1MBIT0 },
1210 { .address = NRF51_FICR_BLE_1MBIT1 },
1211 { .address = NRF51_FICR_BLE_1MBIT2 },
1212 { .address = NRF51_FICR_BLE_1MBIT3 },
1213 { .address = NRF51_FICR_BLE_1MBIT4 },
1214 }, uicr[] = {
1215 { .address = NRF51_UICR_CLENR0, },
1216 { .address = NRF51_UICR_RBPCONF },
1217 { .address = NRF51_UICR_XTALFREQ },
1218 { .address = NRF51_UICR_FWID },
1219 };
1220
1221 for (size_t i = 0; i < ARRAY_SIZE(ficr); i++) {
1222 res = target_read_u32(chip->target, ficr[i].address,
1223 &ficr[i].value);
1224 if (res != ERROR_OK) {
1225 LOG_ERROR("Couldn't read %" PRIx32, ficr[i].address);
1226 return res;
1227 }
1228 }
1229
1230 for (size_t i = 0; i < ARRAY_SIZE(uicr); i++) {
1231 res = target_read_u32(chip->target, uicr[i].address,
1232 &uicr[i].value);
1233 if (res != ERROR_OK) {
1234 LOG_ERROR("Couldn't read %" PRIx32, uicr[i].address);
1235 return res;
1236 }
1237 }
1238
1239 snprintf(buf, buf_size,
1240 "\n[factory information control block]\n\n"
1241 "code page size: %"PRIu32"B\n"
1242 "code memory size: %"PRIu32"kB\n"
1243 "code region 0 size: %"PRIu32"kB\n"
1244 "pre-programmed code: %s\n"
1245 "number of ram blocks: %"PRIu32"\n"
1246 "ram block 0 size: %"PRIu32"B\n"
1247 "ram block 1 size: %"PRIu32"B\n"
1248 "ram block 2 size: %"PRIu32"B\n"
1249 "ram block 3 size: %"PRIu32 "B\n"
1250 "config id: %" PRIx32 "\n"
1251 "device id: 0x%"PRIx32"%08"PRIx32"\n"
1252 "encryption root: 0x%08"PRIx32"%08"PRIx32"%08"PRIx32"%08"PRIx32"\n"
1253 "identity root: 0x%08"PRIx32"%08"PRIx32"%08"PRIx32"%08"PRIx32"\n"
1254 "device address type: 0x%"PRIx32"\n"
1255 "device address: 0x%"PRIx32"%08"PRIx32"\n"
1256 "override enable: %"PRIx32"\n"
1257 "NRF_1MBIT values: %"PRIx32" %"PRIx32" %"PRIx32" %"PRIx32" %"PRIx32"\n"
1258 "BLE_1MBIT values: %"PRIx32" %"PRIx32" %"PRIx32" %"PRIx32" %"PRIx32"\n"
1259 "\n[user information control block]\n\n"
1260 "code region 0 size: %"PRIu32"kB\n"
1261 "read back protection configuration: %"PRIx32"\n"
1262 "reset value for XTALFREQ: %"PRIx32"\n"
1263 "firmware id: 0x%04"PRIx32,
1264 ficr[0].value,
1265 ficr[1].value,
1266 (ficr[2].value == 0xFFFFFFFF) ? 0 : ficr[2].value / 1024,
1267 ((ficr[3].value & 0xFF) == 0x00) ? "present" : "not present",
1268 ficr[4].value,
1269 ficr[5].value,
1270 (ficr[6].value == 0xFFFFFFFF) ? 0 : ficr[6].value,
1271 (ficr[7].value == 0xFFFFFFFF) ? 0 : ficr[7].value,
1272 (ficr[8].value == 0xFFFFFFFF) ? 0 : ficr[8].value,
1273 ficr[9].value,
1274 ficr[10].value, ficr[11].value,
1275 ficr[12].value, ficr[13].value, ficr[14].value, ficr[15].value,
1276 ficr[16].value, ficr[17].value, ficr[18].value, ficr[19].value,
1277 ficr[20].value,
1278 ficr[21].value, ficr[22].value,
1279 ficr[23].value,
1280 ficr[24].value, ficr[25].value, ficr[26].value, ficr[27].value, ficr[28].value,
1281 ficr[29].value, ficr[30].value, ficr[31].value, ficr[32].value, ficr[33].value,
1282 (uicr[0].value == 0xFFFFFFFF) ? 0 : uicr[0].value / 1024,
1283 uicr[1].value & 0xFFFF,
1284 uicr[2].value & 0xFF,
1285 uicr[3].value & 0xFFFF);
1286
1287 return ERROR_OK;
1288 }
1289
1290 static const struct command_registration nrf51_exec_command_handlers[] = {
1291 {
1292 .name = "mass_erase",
1293 .handler = nrf51_handle_mass_erase_command,
1294 .mode = COMMAND_EXEC,
1295 .help = "Erase all flash contents of the chip.",
1296 },
1297 COMMAND_REGISTRATION_DONE
1298 };
1299
1300 static const struct command_registration nrf51_command_handlers[] = {
1301 {
1302 .name = "nrf51",
1303 .mode = COMMAND_ANY,
1304 .help = "nrf51 flash command group",
1305 .usage = "",
1306 .chain = nrf51_exec_command_handlers,
1307 },
1308 COMMAND_REGISTRATION_DONE
1309 };
1310
1311 struct flash_driver nrf51_flash = {
1312 .name = "nrf51",
1313 .commands = nrf51_command_handlers,
1314 .flash_bank_command = nrf51_flash_bank_command,
1315 .info = nrf51_info,
1316 .erase = nrf51_erase,
1317 .protect = nrf51_protect,
1318 .write = nrf51_write,
1319 .read = default_flash_read,
1320 .probe = nrf51_probe,
1321 .auto_probe = nrf51_auto_probe,
1322 .erase_check = default_flash_blank_check,
1323 .protect_check = nrf51_protect_check,
1324 };

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)