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

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)