e0bb5c20ba59784c1faf5c221ce8069bdf0b2025
[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 break;
591
592 default:
593 LOG_WARNING("Unknown or inconsistent flash class");
594 reassign = 1;
595 break;
596 }
597 }
598 } else {
599 LOG_INFO("Probing flash info for bank %d", bank->bank_number);
600 reassign = 1;
601 }
602
603 if (!reassign)
604 return ERROR_OK;
605
606 kinfo->granularity = granularity;
607
608 if ((unsigned)bank->bank_number < num_pflash_blocks) {
609 /* pflash, banks start at address zero */
610 kinfo->flash_class = FC_PFLASH;
611 bank->size = (pf_size / num_pflash_blocks);
612 bank->base = 0x00000000 + bank->size * bank->bank_number;
613 kinfo->sector_size = kinetis_flash_params[granularity].pflash_sector_size_bytes;
614 kinfo->protection_size = pf_size / 32;
615 } else if ((unsigned)bank->bank_number < num_blocks) {
616 /* nvm, banks start at address 0x10000000 */
617 kinfo->flash_class = FC_FLEX_NVM;
618 bank->size = (nvm_size / num_nvm_blocks);
619 bank->base = 0x10000000 + bank->size * (bank->bank_number - first_nvm_bank);
620 kinfo->sector_size = kinetis_flash_params[granularity].nvm_sector_size_bytes;
621 kinfo->protection_size = 0; /* FIXME: TODO: depends on DEPART bits, chip */
622 } else if ((unsigned)bank->bank_number == num_blocks) {
623 LOG_ERROR("FlexRAM support not yet implemented");
624 return ERROR_FLASH_OPER_UNSUPPORTED;
625 } else {
626 LOG_ERROR("Cannot determine parameters for bank %d, only %d banks on device",
627 bank->bank_number, num_blocks);
628 return ERROR_FLASH_BANK_INVALID;
629 }
630
631 if (bank->sectors) {
632 free(bank->sectors);
633 bank->sectors = NULL;
634 }
635
636 bank->num_sectors = bank->size / kinfo->sector_size;
637 assert(bank->num_sectors > 0);
638 bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
639
640 for (i = 0; i < bank->num_sectors; i++) {
641 bank->sectors[i].offset = offset;
642 bank->sectors[i].size = kinfo->sector_size;
643 offset += kinfo->sector_size;
644 bank->sectors[i].is_erased = -1;
645 bank->sectors[i].is_protected = 1;
646 }
647
648 return ERROR_OK;
649 }
650
651 static int kinetis_probe(struct flash_bank *bank)
652 {
653 if (bank->target->state != TARGET_HALTED) {
654 LOG_WARNING("Cannot communicate... target not halted.");
655 return ERROR_TARGET_NOT_HALTED;
656 }
657
658 return kinetis_read_part_info(bank);
659 }
660
661 static int kinetis_auto_probe(struct flash_bank *bank)
662 {
663 struct kinetis_flash_bank *kinfo = bank->driver_priv;
664
665 if (kinfo->sim_sdid)
666 return ERROR_OK;
667
668 return kinetis_probe(bank);
669 }
670
671 static int kinetis_info(struct flash_bank *bank, char *buf, int buf_size)
672 {
673 const char *bank_class_names[] = {
674 "(ANY)", "PFlash", "FlexNVM", "FlexRAM"
675 };
676
677 struct kinetis_flash_bank *kinfo = bank->driver_priv;
678
679 (void) snprintf(buf, buf_size,
680 "%s driver for %s flash bank %s at 0x%8.8" PRIx32 "",
681 bank->driver->name, bank_class_names[kinfo->flash_class],
682 bank->name, bank->base);
683
684 return ERROR_OK;
685 }
686
687 static int kinetis_blank_check(struct flash_bank *bank)
688 {
689 struct kinetis_flash_bank *kinfo = bank->driver_priv;
690
691 if (bank->target->state != TARGET_HALTED) {
692 LOG_ERROR("Target not halted");
693 return ERROR_TARGET_NOT_HALTED;
694 }
695
696 if (kinfo->flash_class == FC_PFLASH) {
697 int result;
698 uint32_t w0 = 0, w1 = 0, w2 = 0;
699 uint8_t ftfx_fstat;
700
701 /* check if whole bank is blank */
702 w0 = (0x00 << 24) | bank->base;
703 w1 = 0; /* "normal margin" */
704
705 result = kinetis_ftfx_command(bank, w0, w1, w2, &ftfx_fstat);
706
707 if (result != ERROR_OK)
708 return result;
709
710 if (ftfx_fstat & 0x01) {
711 /* the whole bank is not erased, check sector-by-sector */
712 int i;
713 for (i = 0; i < bank->num_sectors; i++) {
714 w0 = (0x01 << 24) | (bank->base + bank->sectors[i].offset);
715 w1 = (0x100 << 16) | 0; /* normal margin */
716
717 result = kinetis_ftfx_command(bank, w0, w1, w2, &ftfx_fstat);
718
719 if (result == ERROR_OK) {
720 bank->sectors[i].is_erased = !(ftfx_fstat & 0x01);
721 } else {
722 LOG_DEBUG("Ignoring errored PFlash sector blank-check");
723 bank->sectors[i].is_erased = -1;
724 }
725 }
726 } else {
727 /* the whole bank is erased, update all sectors */
728 int i;
729 for (i = 0; i < bank->num_sectors; i++)
730 bank->sectors[i].is_erased = 1;
731 }
732 } else {
733 LOG_WARNING("kinetis_blank_check not supported yet for FlexNVM");
734 return ERROR_FLASH_OPERATION_FAILED;
735 }
736
737 return ERROR_OK;
738 }
739
740 static int kinetis_flash_read(struct flash_bank *bank,
741 uint8_t *buffer, uint32_t offset, uint32_t count)
742 {
743 LOG_WARNING("kinetis_flash_read not supported yet");
744
745 if (bank->target->state != TARGET_HALTED) {
746 LOG_ERROR("Target not halted");
747 return ERROR_TARGET_NOT_HALTED;
748 }
749
750 return ERROR_FLASH_OPERATION_FAILED;
751 }
752
753 struct flash_driver kinetis_flash = {
754 .name = "kinetis",
755 .flash_bank_command = kinetis_flash_bank_command,
756 .erase = kinetis_erase,
757 .protect = kinetis_protect,
758 .write = kinetis_write,
759 .read = kinetis_flash_read,
760 .probe = kinetis_probe,
761 .auto_probe = kinetis_auto_probe,
762 .erase_check = kinetis_blank_check,
763 .protect_check = kinetis_protect_check,
764 .info = kinetis_info,
765 };

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)