kinetis: update support for all program flash granularities
[openocd.git] / src / flash / nor / kinetis.c
1 /***************************************************************************
2 * Copyright (C) 2011 by Mathias Kuester *
3 * kesmtp@freenet.de *
4 * *
5 * Copyright (C) 2011 sleep(5) ltd *
6 * tomas@sleepfive.com *
7 * *
8 * Copyright (C) 2012 by Christopher D. Kilgour *
9 * techie at whiterocker.com *
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * GNU General Public License for more details. *
20 * *
21 * You should have received a copy of the GNU General Public License *
22 * along with this program; if not, write to the *
23 * Free Software Foundation, Inc., *
24 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
25 ***************************************************************************/
26
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"
29 #endif
30
31 #include "imp.h"
32 #include "helper/binarybuffer.h"
33
34 /*
35 * Implementation Notes
36 *
37 * The persistent memories in the Kinetis chip families K10 through
38 * K70 are all manipulated with the Flash Memory Module. Some
39 * variants call this module the FTFE, others call it the FTFL. To
40 * indicate that both are considered here, we use FTFX.
41 *
42 * Within the module, according to the chip variant, the persistent
43 * memory is divided into what Freescale terms Program Flash, FlexNVM,
44 * and FlexRAM. All chip variants have Program Flash. Some chip
45 * variants also have FlexNVM and FlexRAM, which always appear
46 * together.
47 *
48 * A given Kinetis chip may have 2 or 4 blocks of flash. Here we map
49 * each block to a separate bank. Each block size varies by chip and
50 * may be determined by the read-only SIM_FCFG1 register. The sector
51 * size within each bank/block varies by the chip granularity as
52 * described below.
53 *
54 * Kinetis offers four different of flash granularities applicable
55 * across the chip families. The granularity is apparently reflected
56 * by at least the reference manual suffix. For example, for chip
57 * MK60FN1M0VLQ12, reference manual K60P144M150SF3RM ends in "SF3RM",
58 * where the "3" indicates there are four flash blocks with 4kiB
59 * sectors. All possible granularities are indicated below.
60 *
61 * The first half of the flash (1 or 2 blocks, depending on the
62 * granularity) is always Program Flash and always starts at address
63 * 0x00000000. The "PFLSH" flag, bit 23 of the read-only SIM_FCFG2
64 * register, determines whether the second half of the flash is also
65 * Program Flash or FlexNVM+FlexRAM. When PFLSH is set, the second
66 * half of flash is Program Flash and is contiguous in the memory map
67 * from the first half. When PFLSH is clear, the second half of flash
68 * is FlexNVM and always starts at address 0x10000000. FlexRAM, which
69 * is also present when PFLSH is clear, always starts at address
70 * 0x14000000.
71 *
72 * The Flash Memory Module provides a register set where flash
73 * commands are loaded to perform flash operations like erase and
74 * program. Different commands are available depending on whether
75 * Program Flash or FlexNVM/FlexRAM is being manipulated. Although
76 * the commands used are quite consistent between flash blocks, the
77 * parameters they accept differ according to the flash granularity.
78 * Some Kinetis chips have different granularity between Program Flash
79 * and FlexNVM/FlexRAM, so flash command arguments may differ between
80 * blocks in the same chip.
81 *
82 * Although not documented as such by Freescale, it appears that bits
83 * 8:7 of the read-only SIM_SDID register reflect the granularity
84 * settings 0..3, so sector sizes and block counts are applicable
85 * according to the following table.
86 */
87 const struct {
88 unsigned pflash_sector_size_bytes;
89 unsigned nvm_sector_size_bytes;
90 unsigned num_blocks;
91 } kinetis_flash_params[4] = {
92 { 1<<10, 1<<10, 2 },
93 { 2<<10, 1<<10, 2 },
94 { 2<<10, 2<<10, 2 },
95 { 4<<10, 4<<10, 4 }
96 };
97
98 struct kinetis_flash_bank {
99 unsigned granularity;
100 unsigned bank_ordinal;
101 uint32_t sector_size;
102 uint32_t protection_size;
103
104 uint32_t sim_sdid;
105 uint32_t sim_fcfg1;
106 uint32_t sim_fcfg2;
107
108 enum {
109 FC_AUTO = 0,
110 FC_PFLASH,
111 FC_FLEX_NVM,
112 FC_FLEX_RAM,
113 } flash_class;
114 };
115
116 FLASH_BANK_COMMAND_HANDLER(kinetis_flash_bank_command)
117 {
118 struct kinetis_flash_bank *bank_info;
119
120 if (CMD_ARGC < 6)
121 return ERROR_COMMAND_SYNTAX_ERROR;
122
123 LOG_INFO("add flash_bank kinetis %s", bank->name);
124
125 bank_info = malloc(sizeof(struct kinetis_flash_bank));
126
127 memset(bank_info, 0, sizeof(struct kinetis_flash_bank));
128
129 bank->driver_priv = bank_info;
130
131 return ERROR_OK;
132 }
133
134 static int kinetis_protect(struct flash_bank *bank, int set, int first,
135 int last)
136 {
137 LOG_WARNING("kinetis_protect not supported yet");
138 /* FIXME: TODO */
139
140 if (bank->target->state != TARGET_HALTED) {
141 LOG_ERROR("Target not halted");
142 return ERROR_TARGET_NOT_HALTED;
143 }
144
145 return ERROR_FLASH_BANK_INVALID;
146 }
147
148 static int kinetis_protect_check(struct flash_bank *bank)
149 {
150 struct kinetis_flash_bank *kinfo = bank->driver_priv;
151
152 if (bank->target->state != TARGET_HALTED) {
153 LOG_ERROR("Target not halted");
154 return ERROR_TARGET_NOT_HALTED;
155 }
156
157 if (kinfo->flash_class == FC_PFLASH) {
158 int result;
159 uint8_t buffer[4];
160 uint32_t fprot, psec;
161 int i, b;
162
163 /* read protection register FTFx_FPROT */
164 result = target_read_memory(bank->target, 0x40020010, 1, 4, buffer);
165
166 if (result != ERROR_OK)
167 return result;
168
169 fprot = target_buffer_get_u32(bank->target, buffer);
170
171 /*
172 * Every bit protects 1/32 of the full flash (not necessarily
173 * just this bank), but we enforce the bank ordinals for
174 * PFlash to start at zero.
175 */
176 b = kinfo->bank_ordinal * (bank->size / kinfo->protection_size);
177 for (psec = 0, i = 0; i < bank->num_sectors; i++) {
178 if ((fprot >> b) & 1)
179 bank->sectors[i].is_protected = 0;
180 else
181 bank->sectors[i].is_protected = 1;
182
183 psec += bank->sectors[i].size;
184
185 if (psec >= kinfo->protection_size) {
186 psec = 0;
187 b++;
188 }
189 }
190 } else {
191 LOG_ERROR("Protection checks for FlexNVM not yet supported");
192 return ERROR_FLASH_BANK_INVALID;
193 }
194
195 return ERROR_OK;
196 }
197
198 static int kinetis_ftfx_command(struct flash_bank *bank, uint32_t w0,
199 uint32_t w1, uint32_t w2, uint8_t *ftfx_fstat)
200 {
201 uint8_t buffer[12];
202 int result, i;
203
204 /* wait for done */
205 for (i = 0; i < 50; i++) {
206 result =
207 target_read_memory(bank->target, 0x40020000, 1, 1, buffer);
208
209 if (result != ERROR_OK)
210 return result;
211
212 if (buffer[0] & 0x80)
213 break;
214
215 buffer[0] = 0x00;
216 }
217
218 if (buffer[0] != 0x80) {
219 /* reset error flags */
220 buffer[0] = 0x30;
221 result =
222 target_write_memory(bank->target, 0x40020000, 1, 1, buffer);
223 if (result != ERROR_OK)
224 return result;
225 }
226
227 target_buffer_set_u32(bank->target, buffer, w0);
228 target_buffer_set_u32(bank->target, buffer + 4, w1);
229 target_buffer_set_u32(bank->target, buffer + 8, w2);
230
231 result = target_write_memory(bank->target, 0x40020004, 4, 3, buffer);
232
233 if (result != ERROR_OK)
234 return result;
235
236 /* start command */
237 buffer[0] = 0x80;
238 result = target_write_memory(bank->target, 0x40020000, 1, 1, buffer);
239 if (result != ERROR_OK)
240 return result;
241
242 /* wait for done */
243 for (i = 0; i < 50; i++) {
244 result =
245 target_read_memory(bank->target, 0x40020000, 1, 1, ftfx_fstat);
246
247 if (result != ERROR_OK)
248 return result;
249
250 if (*ftfx_fstat & 0x80)
251 break;
252 }
253
254 if ((*ftfx_fstat & 0xf0) != 0x80) {
255 LOG_ERROR
256 ("ftfx command failed FSTAT: %02X W0: %08X W1: %08X W2: %08X",
257 *ftfx_fstat, w0, w1, w2);
258
259 return ERROR_FLASH_OPERATION_FAILED;
260 }
261
262 return ERROR_OK;
263 }
264
265 static int kinetis_erase(struct flash_bank *bank, int first, int last)
266 {
267 int result, i;
268 uint32_t w0 = 0, w1 = 0, w2 = 0;
269
270 if (bank->target->state != TARGET_HALTED) {
271 LOG_ERROR("Target not halted");
272 return ERROR_TARGET_NOT_HALTED;
273 }
274
275 if ((first > bank->num_sectors) || (last > bank->num_sectors))
276 return ERROR_FLASH_OPERATION_FAILED;
277
278 /*
279 * FIXME: TODO: use the 'Erase Flash Block' command if the
280 * requested erase is PFlash or NVM and encompasses the entire
281 * block. Should be quicker.
282 */
283 for (i = first; i <= last; i++) {
284 uint8_t ftfx_fstat;
285 /* set command and sector address */
286 w0 = (0x09 << 24) | (bank->base + bank->sectors[i].offset);
287
288 result = kinetis_ftfx_command(bank, w0, w1, w2, &ftfx_fstat);
289
290 if (result != ERROR_OK) {
291 LOG_WARNING("erase sector %d failed", i);
292 return ERROR_FLASH_OPERATION_FAILED;
293 }
294
295 bank->sectors[i].is_erased = 1;
296 }
297
298 if (first == 0) {
299 LOG_WARNING
300 ("flash configuration field erased, please reset the device");
301 }
302
303 return ERROR_OK;
304 }
305
306 static int kinetis_write(struct flash_bank *bank, uint8_t *buffer,
307 uint32_t offset, uint32_t count)
308 {
309 unsigned int i, result, fallback = 0;
310 uint8_t buf[8];
311 uint32_t wc, w0 = 0, w1 = 0, w2 = 0;
312 struct kinetis_flash_bank *kinfo = bank->driver_priv;
313
314 if (bank->target->state != TARGET_HALTED) {
315 LOG_ERROR("Target not halted");
316 return ERROR_TARGET_NOT_HALTED;
317 }
318
319 if (kinfo->flash_class == FC_FLEX_NVM) {
320 uint8_t ftfx_fstat;
321
322 LOG_DEBUG("flash write into FlexNVM @%08X", offset);
323
324 /* make flex ram available */
325 w0 = (0x81 << 24) | 0x00ff0000;
326
327 result = kinetis_ftfx_command(bank, w0, w1, w2, &ftfx_fstat);
328
329 if (result != ERROR_OK)
330 return ERROR_FLASH_OPERATION_FAILED;
331
332 /* check if ram ready */
333 result = target_read_memory(bank->target, 0x40020001, 1, 1, buf);
334
335 if (result != ERROR_OK)
336 return result;
337
338 if (!(buf[0] & (1 << 1))) {
339 /* fallback to longword write */
340 fallback = 1;
341
342 LOG_WARNING("ram not ready, fallback to slow longword write (FCNFG: %02X)",
343 buf[0]);
344 }
345 } else {
346 LOG_DEBUG("flash write into PFLASH @08%X", offset);
347 }
348
349
350 /* program section command */
351 if (fallback == 0) {
352 unsigned prog_section_bytes = kinfo->sector_size >> 8;
353 for (i = 0; i < count; i += kinfo->sector_size) {
354 uint8_t ftfx_fstat;
355
356 wc = kinfo->sector_size / 4;
357
358 if ((count - i) < kinfo->sector_size) {
359 wc = count - i;
360 wc /= 4;
361 }
362
363 LOG_DEBUG("write section @ %08X with length %d",
364 offset + i, wc * 4);
365
366 /* write data to flexram */
367 result =
368 target_write_memory(bank->target, 0x14000000, 4, wc,
369 buffer + i);
370
371 if (result != ERROR_OK) {
372 LOG_ERROR("target_write_memory failed");
373
374 return result;
375 }
376
377 /* execute section command */
378 w0 = (0x0b << 24) | (bank->base + offset + i);
379 w1 = ((wc * 4 / prog_section_bytes) << 16);
380
381 result = kinetis_ftfx_command(bank, w0, w1, w2, &ftfx_fstat);
382
383 if (result != ERROR_OK)
384 return ERROR_FLASH_OPERATION_FAILED;
385 }
386 }
387 /* program longword command, not supported in "SF3" devices */
388 else if (kinfo->granularity != 3) {
389 for (i = 0; i < count; i += 4) {
390 uint8_t ftfx_fstat;
391
392 LOG_DEBUG("write longword @ %08X", offset + i);
393
394 w0 = (0x06 << 24) | (bank->base + offset + i);
395 w1 = buf_get_u32(buffer + offset + i, 0, 32);
396
397 result = kinetis_ftfx_command(bank, w0, w1, w2, &ftfx_fstat);
398
399 if (result != ERROR_OK)
400 return ERROR_FLASH_OPERATION_FAILED;
401 }
402 } else {
403 LOG_ERROR("Flash write strategy not implemented");
404 return ERROR_FLASH_OPERATION_FAILED;
405 }
406
407 return ERROR_OK;
408 }
409
410 static int kinetis_read_part_info(struct flash_bank *bank)
411 {
412 int result, i;
413 uint8_t buf[4];
414 uint32_t offset = 0;
415 uint8_t fcfg1_nvmsize, fcfg1_pfsize, fcfg1_eesize, fcfg2_pflsh;
416 uint32_t nvm_size = 0, pf_size = 0, ee_size = 0;
417 unsigned granularity, num_blocks = 0, num_pflash_blocks = 0, num_nvm_blocks = 0,
418 first_nvm_bank = 0, reassign = 0;
419 struct kinetis_flash_bank *kinfo = bank->driver_priv;
420
421 result = target_read_memory(bank->target, 0x40048024, 1, 4, buf);
422 if (result != ERROR_OK)
423 return result;
424 kinfo->sim_sdid = target_buffer_get_u32(bank->target, buf);
425 granularity = (kinfo->sim_sdid >> 7) & 0x03;
426 result = target_read_memory(bank->target, 0x4004804c, 1, 4, buf);
427 if (result != ERROR_OK)
428 return result;
429 kinfo->sim_fcfg1 = target_buffer_get_u32(bank->target, buf);
430 result = target_read_memory(bank->target, 0x40048050, 1, 4, buf);
431 if (result != ERROR_OK)
432 return result;
433 kinfo->sim_fcfg2 = target_buffer_get_u32(bank->target, buf);
434 fcfg2_pflsh = (kinfo->sim_fcfg2 >> 23) & 0x01;
435
436 LOG_DEBUG("SDID: %08X FCFG1: %08X FCFG2: %08X", kinfo->sim_sdid,
437 kinfo->sim_fcfg1, kinfo->sim_fcfg2);
438
439 fcfg1_nvmsize = (uint8_t)((kinfo->sim_fcfg1 >> 28) & 0x0f);
440 fcfg1_pfsize = (uint8_t)((kinfo->sim_fcfg1 >> 24) & 0x0f);
441 fcfg1_eesize = (uint8_t)((kinfo->sim_fcfg1 >> 16) & 0x0f);
442
443 /* when the PFLSH bit is set, there is no FlexNVM/FlexRAM */
444 if (!fcfg2_pflsh) {
445 switch (fcfg1_nvmsize) {
446 case 0x03:
447 case 0x07:
448 case 0x09:
449 case 0x0b:
450 nvm_size = 1 << (14 + (fcfg1_nvmsize >> 1));
451 break;
452 case 0x0f:
453 if (granularity == 3)
454 nvm_size = 512<<10;
455 else
456 nvm_size = 256<<10;
457 break;
458 default:
459 nvm_size = 0;
460 break;
461 }
462
463 switch (fcfg1_eesize) {
464 case 0x00:
465 case 0x01:
466 case 0x02:
467 case 0x03:
468 case 0x04:
469 case 0x05:
470 case 0x06:
471 case 0x07:
472 case 0x08:
473 case 0x09:
474 ee_size = (16 << (10 - fcfg1_eesize));
475 break;
476 default:
477 ee_size = 0;
478 break;
479 }
480 }
481
482 switch (fcfg1_pfsize) {
483 case 0x03:
484 case 0x05:
485 case 0x07:
486 case 0x09:
487 case 0x0b:
488 case 0x0d:
489 pf_size = 1 << (14 + (fcfg1_pfsize >> 1));
490 break;
491 case 0x0f:
492 if (granularity == 3)
493 pf_size = 1024<<10;
494 else if (fcfg2_pflsh)
495 pf_size = 512<<10;
496 else
497 pf_size = 256<<10;
498 break;
499 default:
500 pf_size = 0;
501 break;
502 }
503
504 LOG_DEBUG("FlexNVM: %d PFlash: %d FlexRAM: %d PFLSH: %d",
505 nvm_size, pf_size, ee_size, fcfg2_pflsh);
506
507 num_blocks = kinetis_flash_params[granularity].num_blocks;
508 num_pflash_blocks = num_blocks / (2 - fcfg2_pflsh);
509 first_nvm_bank = num_pflash_blocks;
510 num_nvm_blocks = num_blocks - num_pflash_blocks;
511
512 LOG_DEBUG("%d blocks total: %d PFlash, %d FlexNVM",
513 num_blocks, num_pflash_blocks, num_nvm_blocks);
514
515 /*
516 * If the flash class is already assigned, verify the
517 * parameters.
518 */
519 if (kinfo->flash_class != FC_AUTO) {
520 if (kinfo->bank_ordinal != (unsigned) bank->bank_number) {
521 LOG_WARNING("Flash ordinal/bank number mismatch");
522 reassign = 1;
523 } else if (kinfo->granularity != granularity) {
524 LOG_WARNING("Flash granularity mismatch");
525 reassign = 1;
526 } else {
527 switch (kinfo->flash_class) {
528 case FC_PFLASH:
529 if (kinfo->bank_ordinal >= first_nvm_bank) {
530 LOG_WARNING("Class mismatch, bank %d is not PFlash",
531 bank->bank_number);
532 reassign = 1;
533 } else if (bank->size != (pf_size / num_pflash_blocks)) {
534 LOG_WARNING("PFlash size mismatch");
535 reassign = 1;
536 } else if (bank->base !=
537 (0x00000000 + bank->size * kinfo->bank_ordinal)) {
538 LOG_WARNING("PFlash address range mismatch");
539 reassign = 1;
540 } else if (kinfo->sector_size !=
541 kinetis_flash_params[granularity].pflash_sector_size_bytes) {
542 LOG_WARNING("PFlash sector size mismatch");
543 reassign = 1;
544 } else {
545 LOG_DEBUG("PFlash bank %d already configured okay",
546 kinfo->bank_ordinal);
547 }
548 break;
549 case FC_FLEX_NVM:
550 if ((kinfo->bank_ordinal >= num_blocks) ||
551 (kinfo->bank_ordinal < first_nvm_bank)) {
552 LOG_WARNING("Class mismatch, bank %d is not FlexNVM",
553 bank->bank_number);
554 reassign = 1;
555 } else if (bank->size != (nvm_size / num_nvm_blocks)) {
556 LOG_WARNING("FlexNVM size mismatch");
557 reassign = 1;
558 } else if (bank->base !=
559 (0x10000000 + bank->size * kinfo->bank_ordinal)) {
560 LOG_WARNING("FlexNVM address range mismatch");
561 reassign = 1;
562 } else if (kinfo->sector_size !=
563 kinetis_flash_params[granularity].nvm_sector_size_bytes) {
564 LOG_WARNING("FlexNVM sector size mismatch");
565 reassign = 1;
566 } else {
567 LOG_DEBUG("FlexNVM bank %d already configured okay",
568 kinfo->bank_ordinal);
569 }
570 break;
571 case FC_FLEX_RAM:
572 if (kinfo->bank_ordinal != num_blocks) {
573 LOG_WARNING("Class mismatch, bank %d is not FlexRAM",
574 bank->bank_number);
575 reassign = 1;
576 } else if (bank->size != ee_size) {
577 LOG_WARNING("FlexRAM size mismatch");
578 reassign = 1;
579 } else if (bank->base != 0x14000000) {
580 LOG_WARNING("FlexRAM address mismatch");
581 reassign = 1;
582 } else if (kinfo->sector_size !=
583 kinetis_flash_params[granularity].nvm_sector_size_bytes) {
584 LOG_WARNING("FlexRAM sector size mismatch");
585 reassign = 1;
586 } else {
587 LOG_DEBUG("FlexRAM bank %d already configured okay",
588 kinfo->bank_ordinal);
589 }
590 default:
591 LOG_WARNING("Unknown or inconsistent flash class");
592 reassign = 1;
593 break;
594 }
595 }
596 } else {
597 LOG_INFO("Probing flash info for bank %d", bank->bank_number);
598 reassign = 1;
599 }
600
601 if (!reassign)
602 return ERROR_OK;
603
604 kinfo->granularity = granularity;
605
606 if ((unsigned)bank->bank_number < num_pflash_blocks) {
607 /* pflash, banks start at address zero */
608 kinfo->flash_class = FC_PFLASH;
609 bank->size = (pf_size / num_pflash_blocks);
610 bank->base = 0x00000000 + bank->size * bank->bank_number;
611 kinfo->sector_size = kinetis_flash_params[granularity].pflash_sector_size_bytes;
612 kinfo->protection_size = pf_size / 32;
613 } else if ((unsigned)bank->bank_number < num_blocks) {
614 /* nvm, banks start at address 0x10000000 */
615 kinfo->flash_class = FC_FLEX_NVM;
616 bank->size = (nvm_size / num_nvm_blocks);
617 bank->base = 0x10000000 + bank->size * (bank->bank_number - first_nvm_bank);
618 kinfo->sector_size = kinetis_flash_params[granularity].nvm_sector_size_bytes;
619 kinfo->protection_size = 0; /* FIXME: TODO: depends on DEPART bits, chip */
620 } else if ((unsigned)bank->bank_number == num_blocks) {
621 LOG_ERROR("FlexRAM support not yet implemented");
622 return ERROR_FLASH_OPER_UNSUPPORTED;
623 } else {
624 LOG_ERROR("Cannot determine parameters for bank %d, only %d banks on device",
625 bank->bank_number, num_blocks);
626 return ERROR_FLASH_BANK_INVALID;
627 }
628
629 if (bank->sectors) {
630 free(bank->sectors);
631 bank->sectors = NULL;
632 }
633
634 bank->num_sectors = bank->size / kinfo->sector_size;
635 assert(bank->num_sectors > 0);
636 bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
637
638 for (i = 0; i < bank->num_sectors; i++) {
639 bank->sectors[i].offset = offset;
640 bank->sectors[i].size = kinfo->sector_size;
641 offset += kinfo->sector_size;
642 bank->sectors[i].is_erased = -1;
643 bank->sectors[i].is_protected = 1;
644 }
645
646 return ERROR_OK;
647 }
648
649 static int kinetis_probe(struct flash_bank *bank)
650 {
651 if (bank->target->state != TARGET_HALTED) {
652 LOG_WARNING("Cannot communicate... target not halted.");
653 return ERROR_TARGET_NOT_HALTED;
654 }
655
656 return kinetis_read_part_info(bank);
657 }
658
659 static int kinetis_auto_probe(struct flash_bank *bank)
660 {
661 struct kinetis_flash_bank *kinfo = bank->driver_priv;
662
663 if (kinfo->sim_sdid)
664 return ERROR_OK;
665
666 return kinetis_probe(bank);
667 }
668
669 static int kinetis_info(struct flash_bank *bank, char *buf, int buf_size)
670 {
671 const char *bank_class_names[] = {
672 "(ANY)", "PFlash", "FlexNVM", "FlexRAM"
673 };
674
675 struct kinetis_flash_bank *kinfo = bank->driver_priv;
676
677 (void) snprintf(buf, buf_size,
678 "%s driver for %s flash bank %s at 0x%8.8" PRIx32 "",
679 bank->driver->name, bank_class_names[kinfo->flash_class],
680 bank->name, bank->base);
681
682 return ERROR_OK;
683 }
684
685 static int kinetis_blank_check(struct flash_bank *bank)
686 {
687 struct kinetis_flash_bank *kinfo = bank->driver_priv;
688
689 if (bank->target->state != TARGET_HALTED) {
690 LOG_ERROR("Target not halted");
691 return ERROR_TARGET_NOT_HALTED;
692 }
693
694 if (kinfo->flash_class == FC_PFLASH) {
695 int result;
696 uint32_t w0 = 0, w1 = 0, w2 = 0;
697 uint8_t ftfx_fstat;
698
699 /* check if whole bank is blank */
700 w0 = (0x00 << 24) | bank->base;
701 w1 = 0; /* "normal margin" */
702
703 result = kinetis_ftfx_command(bank, w0, w1, w2, &ftfx_fstat);
704
705 if (result != ERROR_OK)
706 return result;
707
708 if (ftfx_fstat & 0x01) {
709 /* the whole bank is not erased, check sector-by-sector */
710 int i;
711 for (i = 0; i < bank->num_sectors; i++) {
712 w0 = (0x01 << 24) | (bank->base + bank->sectors[i].offset);
713 w1 = (0x100 << 16) | 0; /* normal margin */
714
715 result = kinetis_ftfx_command(bank, w0, w1, w2, &ftfx_fstat);
716
717 if (result == ERROR_OK) {
718 bank->sectors[i].is_erased = !(ftfx_fstat & 0x01);
719 } else {
720 LOG_DEBUG("Ignoring errored PFlash sector blank-check");
721 bank->sectors[i].is_erased = -1;
722 }
723 }
724 } else {
725 /* the whole bank is erased, update all sectors */
726 int i;
727 for (i = 0; i < bank->num_sectors; i++)
728 bank->sectors[i].is_erased = 1;
729 }
730 } else {
731 LOG_WARNING("kinetis_blank_check not supported yet for FlexNVM");
732 return ERROR_FLASH_OPERATION_FAILED;
733 }
734
735 return ERROR_OK;
736 }
737
738 static int kinetis_flash_read(struct flash_bank *bank,
739 uint8_t *buffer, uint32_t offset, uint32_t count)
740 {
741 LOG_WARNING("kinetis_flash_read not supported yet");
742
743 if (bank->target->state != TARGET_HALTED) {
744 LOG_ERROR("Target not halted");
745 return ERROR_TARGET_NOT_HALTED;
746 }
747
748 return ERROR_FLASH_OPERATION_FAILED;
749 }
750
751 struct flash_driver kinetis_flash = {
752 .name = "kinetis",
753 .flash_bank_command = kinetis_flash_bank_command,
754 .erase = kinetis_erase,
755 .protect = kinetis_protect,
756 .write = kinetis_write,
757 .read = kinetis_flash_read,
758 .probe = kinetis_probe,
759 .auto_probe = kinetis_auto_probe,
760 .erase_check = kinetis_blank_check,
761 .protect_check = kinetis_protect_check,
762 .info = kinetis_info,
763 };

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)