1 /***************************************************************************
2 * Copyright (C) 2011 by Mathias Kuester *
5 * Copyright (C) 2011 sleep(5) ltd *
6 * tomas@sleepfive.com *
8 * Copyright (C) 2012 by Christopher D. Kilgour *
9 * techie at whiterocker.com *
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. *
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. *
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 ***************************************************************************/
32 #include "helper/binarybuffer.h"
35 * Implementation Notes
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.
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
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
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.
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
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.
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.
88 unsigned pflash_sector_size_bytes
;
89 unsigned nvm_sector_size_bytes
;
91 } kinetis_flash_params
[4] = {
99 #define FLEXRAM 0x14000000
100 #define FTFx_FSTAT 0x40020000
101 #define FTFx_FCNFG 0x40020001
102 #define FTFx_FCCOB3 0x40020004
103 #define FTFx_FPROT3 0x40020010
104 #define SIM_SDID 0x40048024
105 #define SIM_FCFG1 0x4004804c
106 #define SIM_FCFG2 0x40048050
109 #define FTFx_CMD_BLOCKSTAT 0x00
110 #define FTFx_CMD_SECTSTAT 0x01
111 #define FTFx_CMD_LWORDPROG 0x06
112 #define FTFx_CMD_SECTERASE 0x09
113 #define FTFx_CMD_SECTWRITE 0x0b
114 #define FTFx_CMD_SETFLEXRAM 0x81
116 struct kinetis_flash_bank
{
117 unsigned granularity
;
118 unsigned bank_ordinal
;
119 uint32_t sector_size
;
120 uint32_t protection_size
;
134 FLASH_BANK_COMMAND_HANDLER(kinetis_flash_bank_command
)
136 struct kinetis_flash_bank
*bank_info
;
139 return ERROR_COMMAND_SYNTAX_ERROR
;
141 LOG_INFO("add flash_bank kinetis %s", bank
->name
);
143 bank_info
= malloc(sizeof(struct kinetis_flash_bank
));
145 memset(bank_info
, 0, sizeof(struct kinetis_flash_bank
));
147 bank
->driver_priv
= bank_info
;
152 static int kinetis_protect(struct flash_bank
*bank
, int set
, int first
,
155 LOG_WARNING("kinetis_protect not supported yet");
158 if (bank
->target
->state
!= TARGET_HALTED
) {
159 LOG_ERROR("Target not halted");
160 return ERROR_TARGET_NOT_HALTED
;
163 return ERROR_FLASH_BANK_INVALID
;
166 static int kinetis_protect_check(struct flash_bank
*bank
)
168 struct kinetis_flash_bank
*kinfo
= bank
->driver_priv
;
170 if (bank
->target
->state
!= TARGET_HALTED
) {
171 LOG_ERROR("Target not halted");
172 return ERROR_TARGET_NOT_HALTED
;
175 if (kinfo
->flash_class
== FC_PFLASH
) {
178 uint32_t fprot
, psec
;
181 /* read protection register */
182 result
= target_read_memory(bank
->target
, FTFx_FPROT3
, 1, 4, buffer
);
184 if (result
!= ERROR_OK
)
187 fprot
= target_buffer_get_u32(bank
->target
, buffer
);
190 * Every bit protects 1/32 of the full flash (not necessarily
191 * just this bank), but we enforce the bank ordinals for
192 * PFlash to start at zero.
194 b
= kinfo
->bank_ordinal
* (bank
->size
/ kinfo
->protection_size
);
195 for (psec
= 0, i
= 0; i
< bank
->num_sectors
; i
++) {
196 if ((fprot
>> b
) & 1)
197 bank
->sectors
[i
].is_protected
= 0;
199 bank
->sectors
[i
].is_protected
= 1;
201 psec
+= bank
->sectors
[i
].size
;
203 if (psec
>= kinfo
->protection_size
) {
209 LOG_ERROR("Protection checks for FlexNVM not yet supported");
210 return ERROR_FLASH_BANK_INVALID
;
216 static int kinetis_ftfx_command(struct flash_bank
*bank
, uint32_t w0
,
217 uint32_t w1
, uint32_t w2
, uint8_t *ftfx_fstat
)
223 for (i
= 0; i
< 50; i
++) {
225 target_read_memory(bank
->target
, FTFx_FSTAT
, 1, 1, buffer
);
227 if (result
!= ERROR_OK
)
230 if (buffer
[0] & 0x80)
236 if (buffer
[0] != 0x80) {
237 /* reset error flags */
240 target_write_memory(bank
->target
, FTFx_FSTAT
, 1, 1, buffer
);
241 if (result
!= ERROR_OK
)
245 target_buffer_set_u32(bank
->target
, buffer
, w0
);
246 target_buffer_set_u32(bank
->target
, buffer
+ 4, w1
);
247 target_buffer_set_u32(bank
->target
, buffer
+ 8, w2
);
249 result
= target_write_memory(bank
->target
, FTFx_FCCOB3
, 4, 3, buffer
);
251 if (result
!= ERROR_OK
)
256 result
= target_write_memory(bank
->target
, FTFx_FSTAT
, 1, 1, buffer
);
257 if (result
!= ERROR_OK
)
261 for (i
= 0; i
< 50; i
++) {
263 target_read_memory(bank
->target
, FTFx_FSTAT
, 1, 1, ftfx_fstat
);
265 if (result
!= ERROR_OK
)
268 if (*ftfx_fstat
& 0x80)
272 if ((*ftfx_fstat
& 0xf0) != 0x80) {
274 ("ftfx command failed FSTAT: %02X W0: %08X W1: %08X W2: %08X",
275 *ftfx_fstat
, w0
, w1
, w2
);
277 return ERROR_FLASH_OPERATION_FAILED
;
283 static int kinetis_erase(struct flash_bank
*bank
, int first
, int last
)
286 uint32_t w0
= 0, w1
= 0, w2
= 0;
288 if (bank
->target
->state
!= TARGET_HALTED
) {
289 LOG_ERROR("Target not halted");
290 return ERROR_TARGET_NOT_HALTED
;
293 if ((first
> bank
->num_sectors
) || (last
> bank
->num_sectors
))
294 return ERROR_FLASH_OPERATION_FAILED
;
297 * FIXME: TODO: use the 'Erase Flash Block' command if the
298 * requested erase is PFlash or NVM and encompasses the entire
299 * block. Should be quicker.
301 for (i
= first
; i
<= last
; i
++) {
303 /* set command and sector address */
304 w0
= (FTFx_CMD_SECTERASE
<< 24) | (bank
->base
+ bank
->sectors
[i
].offset
);
306 result
= kinetis_ftfx_command(bank
, w0
, w1
, w2
, &ftfx_fstat
);
308 if (result
!= ERROR_OK
) {
309 LOG_WARNING("erase sector %d failed", i
);
310 return ERROR_FLASH_OPERATION_FAILED
;
313 bank
->sectors
[i
].is_erased
= 1;
318 ("flash configuration field erased, please reset the device");
324 static int kinetis_write(struct flash_bank
*bank
, uint8_t *buffer
,
325 uint32_t offset
, uint32_t count
)
327 unsigned int i
, result
, fallback
= 0;
329 uint32_t wc
, w0
= 0, w1
= 0, w2
= 0;
330 struct kinetis_flash_bank
*kinfo
= bank
->driver_priv
;
332 if (bank
->target
->state
!= TARGET_HALTED
) {
333 LOG_ERROR("Target not halted");
334 return ERROR_TARGET_NOT_HALTED
;
337 if (kinfo
->flash_class
== FC_FLEX_NVM
) {
340 LOG_DEBUG("flash write into FlexNVM @%08X", offset
);
342 /* make flex ram available */
343 w0
= (FTFx_CMD_SETFLEXRAM
<< 24) | 0x00ff0000;
345 result
= kinetis_ftfx_command(bank
, w0
, w1
, w2
, &ftfx_fstat
);
347 if (result
!= ERROR_OK
)
348 return ERROR_FLASH_OPERATION_FAILED
;
350 /* check if ram ready */
351 result
= target_read_memory(bank
->target
, FTFx_FCNFG
, 1, 1, buf
);
353 if (result
!= ERROR_OK
)
356 if (!(buf
[0] & (1 << 1))) {
357 /* fallback to longword write */
360 LOG_WARNING("ram not ready, fallback to slow longword write (FCNFG: %02X)",
364 LOG_DEBUG("flash write into PFLASH @08%X", offset
);
368 /* program section command */
370 unsigned prog_section_bytes
= kinfo
->sector_size
>> 8;
371 for (i
= 0; i
< count
; i
+= kinfo
->sector_size
) {
373 * The largest possible Kinetis "section" is
374 * 16 bytes. A full Kinetis sector is always
377 uint8_t residual_buffer
[16];
379 uint32_t section_count
= 256;
380 uint32_t residual_wc
= 0;
383 * Assume the word count covers an entire
386 wc
= kinfo
->sector_size
/ 4;
389 * If bytes to be programmed are less than the
390 * full sector, then determine the number of
391 * full-words to program, and put together the
392 * residual buffer so that a full "section"
393 * may always be programmed.
395 if ((count
- i
) < kinfo
->sector_size
) {
396 /* number of bytes to program beyond full section */
397 unsigned residual_bc
= (count
-i
) % prog_section_bytes
;
399 /* number of complete words to copy directly from buffer */
400 wc
= (count
- i
) / 4;
402 /* number of total sections to write, including residual */
403 section_count
= DIV_ROUND_UP((count
-i
), prog_section_bytes
);
405 /* any residual bytes delivers a whole residual section */
406 residual_wc
= (residual_bc
? prog_section_bytes
: 0)/4;
408 /* clear residual buffer then populate residual bytes */
409 (void) memset(residual_buffer
, 0xff, prog_section_bytes
);
410 (void) memcpy(residual_buffer
, &buffer
[i
+4*wc
], residual_bc
);
413 LOG_DEBUG("write section @ %08X with length %d bytes",
414 offset
+ i
, (count
- i
));
416 /* write data to flexram as whole-words */
417 result
= target_write_memory(bank
->target
, FLEXRAM
, 4, wc
,
420 if (result
!= ERROR_OK
) {
421 LOG_ERROR("target_write_memory failed");
425 /* write the residual words to the flexram */
427 result
= target_write_memory(bank
->target
,
432 if (result
!= ERROR_OK
) {
433 LOG_ERROR("target_write_memory failed");
438 /* execute section-write command */
439 w0
= (FTFx_CMD_SECTWRITE
<< 24) | (bank
->base
+ offset
+ i
);
440 w1
= section_count
<< 16;
442 result
= kinetis_ftfx_command(bank
, w0
, w1
, w2
, &ftfx_fstat
);
444 if (result
!= ERROR_OK
)
445 return ERROR_FLASH_OPERATION_FAILED
;
448 /* program longword command, not supported in "SF3" devices */
449 else if (kinfo
->granularity
!= 3) {
450 for (i
= 0; i
< count
; i
+= 4) {
453 LOG_DEBUG("write longword @ %08X", offset
+ i
);
455 w0
= (FTFx_CMD_LWORDPROG
<< 24) | (bank
->base
+ offset
+ i
);
457 uint32_t padding
= 0xffffffff;
458 memcpy(&padding
, buffer
+ i
, count
- i
);
459 w1
= buf_get_u32(&padding
, 0, 32);
461 w1
= buf_get_u32(buffer
+ i
, 0, 32);
464 result
= kinetis_ftfx_command(bank
, w0
, w1
, w2
, &ftfx_fstat
);
466 if (result
!= ERROR_OK
)
467 return ERROR_FLASH_OPERATION_FAILED
;
470 LOG_ERROR("Flash write strategy not implemented");
471 return ERROR_FLASH_OPERATION_FAILED
;
477 static int kinetis_read_part_info(struct flash_bank
*bank
)
482 uint8_t fcfg1_nvmsize
, fcfg1_pfsize
, fcfg1_eesize
, fcfg2_pflsh
;
483 uint32_t nvm_size
= 0, pf_size
= 0, ee_size
= 0;
484 unsigned granularity
, num_blocks
= 0, num_pflash_blocks
= 0, num_nvm_blocks
= 0,
485 first_nvm_bank
= 0, reassign
= 0;
486 struct kinetis_flash_bank
*kinfo
= bank
->driver_priv
;
488 result
= target_read_memory(bank
->target
, SIM_SDID
, 1, 4, buf
);
489 if (result
!= ERROR_OK
)
491 kinfo
->sim_sdid
= target_buffer_get_u32(bank
->target
, buf
);
492 granularity
= (kinfo
->sim_sdid
>> 7) & 0x03;
494 result
= target_read_memory(bank
->target
, SIM_FCFG1
, 1, 4, buf
);
495 if (result
!= ERROR_OK
)
497 kinfo
->sim_fcfg1
= target_buffer_get_u32(bank
->target
, buf
);
499 result
= target_read_memory(bank
->target
, SIM_FCFG2
, 1, 4, buf
);
500 if (result
!= ERROR_OK
)
502 kinfo
->sim_fcfg2
= target_buffer_get_u32(bank
->target
, buf
);
503 fcfg2_pflsh
= (kinfo
->sim_fcfg2
>> 23) & 0x01;
505 LOG_DEBUG("SDID: %08X FCFG1: %08X FCFG2: %08X", kinfo
->sim_sdid
,
506 kinfo
->sim_fcfg1
, kinfo
->sim_fcfg2
);
508 fcfg1_nvmsize
= (uint8_t)((kinfo
->sim_fcfg1
>> 28) & 0x0f);
509 fcfg1_pfsize
= (uint8_t)((kinfo
->sim_fcfg1
>> 24) & 0x0f);
510 fcfg1_eesize
= (uint8_t)((kinfo
->sim_fcfg1
>> 16) & 0x0f);
512 /* when the PFLSH bit is set, there is no FlexNVM/FlexRAM */
514 switch (fcfg1_nvmsize
) {
519 nvm_size
= 1 << (14 + (fcfg1_nvmsize
>> 1));
522 if (granularity
== 3)
532 switch (fcfg1_eesize
) {
543 ee_size
= (16 << (10 - fcfg1_eesize
));
551 switch (fcfg1_pfsize
) {
558 pf_size
= 1 << (14 + (fcfg1_pfsize
>> 1));
561 if (granularity
== 3)
563 else if (fcfg2_pflsh
)
573 LOG_DEBUG("FlexNVM: %d PFlash: %d FlexRAM: %d PFLSH: %d",
574 nvm_size
, pf_size
, ee_size
, fcfg2_pflsh
);
576 num_blocks
= kinetis_flash_params
[granularity
].num_blocks
;
577 num_pflash_blocks
= num_blocks
/ (2 - fcfg2_pflsh
);
578 first_nvm_bank
= num_pflash_blocks
;
579 num_nvm_blocks
= num_blocks
- num_pflash_blocks
;
581 LOG_DEBUG("%d blocks total: %d PFlash, %d FlexNVM",
582 num_blocks
, num_pflash_blocks
, num_nvm_blocks
);
585 * If the flash class is already assigned, verify the
588 if (kinfo
->flash_class
!= FC_AUTO
) {
589 if (kinfo
->bank_ordinal
!= (unsigned) bank
->bank_number
) {
590 LOG_WARNING("Flash ordinal/bank number mismatch");
592 } else if (kinfo
->granularity
!= granularity
) {
593 LOG_WARNING("Flash granularity mismatch");
596 switch (kinfo
->flash_class
) {
598 if (kinfo
->bank_ordinal
>= first_nvm_bank
) {
599 LOG_WARNING("Class mismatch, bank %d is not PFlash",
602 } else if (bank
->size
!= (pf_size
/ num_pflash_blocks
)) {
603 LOG_WARNING("PFlash size mismatch");
605 } else if (bank
->base
!=
606 (0x00000000 + bank
->size
* kinfo
->bank_ordinal
)) {
607 LOG_WARNING("PFlash address range mismatch");
609 } else if (kinfo
->sector_size
!=
610 kinetis_flash_params
[granularity
].pflash_sector_size_bytes
) {
611 LOG_WARNING("PFlash sector size mismatch");
614 LOG_DEBUG("PFlash bank %d already configured okay",
615 kinfo
->bank_ordinal
);
619 if ((kinfo
->bank_ordinal
>= num_blocks
) ||
620 (kinfo
->bank_ordinal
< first_nvm_bank
)) {
621 LOG_WARNING("Class mismatch, bank %d is not FlexNVM",
624 } else if (bank
->size
!= (nvm_size
/ num_nvm_blocks
)) {
625 LOG_WARNING("FlexNVM size mismatch");
627 } else if (bank
->base
!=
628 (0x10000000 + bank
->size
* kinfo
->bank_ordinal
)) {
629 LOG_WARNING("FlexNVM address range mismatch");
631 } else if (kinfo
->sector_size
!=
632 kinetis_flash_params
[granularity
].nvm_sector_size_bytes
) {
633 LOG_WARNING("FlexNVM sector size mismatch");
636 LOG_DEBUG("FlexNVM bank %d already configured okay",
637 kinfo
->bank_ordinal
);
641 if (kinfo
->bank_ordinal
!= num_blocks
) {
642 LOG_WARNING("Class mismatch, bank %d is not FlexRAM",
645 } else if (bank
->size
!= ee_size
) {
646 LOG_WARNING("FlexRAM size mismatch");
648 } else if (bank
->base
!= FLEXRAM
) {
649 LOG_WARNING("FlexRAM address mismatch");
651 } else if (kinfo
->sector_size
!=
652 kinetis_flash_params
[granularity
].nvm_sector_size_bytes
) {
653 LOG_WARNING("FlexRAM sector size mismatch");
656 LOG_DEBUG("FlexRAM bank %d already configured okay",
657 kinfo
->bank_ordinal
);
662 LOG_WARNING("Unknown or inconsistent flash class");
668 LOG_INFO("Probing flash info for bank %d", bank
->bank_number
);
675 kinfo
->granularity
= granularity
;
677 if ((unsigned)bank
->bank_number
< num_pflash_blocks
) {
678 /* pflash, banks start at address zero */
679 kinfo
->flash_class
= FC_PFLASH
;
680 bank
->size
= (pf_size
/ num_pflash_blocks
);
681 bank
->base
= 0x00000000 + bank
->size
* bank
->bank_number
;
682 kinfo
->sector_size
= kinetis_flash_params
[granularity
].pflash_sector_size_bytes
;
683 kinfo
->protection_size
= pf_size
/ 32;
684 } else if ((unsigned)bank
->bank_number
< num_blocks
) {
685 /* nvm, banks start at address 0x10000000 */
686 kinfo
->flash_class
= FC_FLEX_NVM
;
687 bank
->size
= (nvm_size
/ num_nvm_blocks
);
688 bank
->base
= 0x10000000 + bank
->size
* (bank
->bank_number
- first_nvm_bank
);
689 kinfo
->sector_size
= kinetis_flash_params
[granularity
].nvm_sector_size_bytes
;
690 kinfo
->protection_size
= 0; /* FIXME: TODO: depends on DEPART bits, chip */
691 } else if ((unsigned)bank
->bank_number
== num_blocks
) {
692 LOG_ERROR("FlexRAM support not yet implemented");
693 return ERROR_FLASH_OPER_UNSUPPORTED
;
695 LOG_ERROR("Cannot determine parameters for bank %d, only %d banks on device",
696 bank
->bank_number
, num_blocks
);
697 return ERROR_FLASH_BANK_INVALID
;
702 bank
->sectors
= NULL
;
705 bank
->num_sectors
= bank
->size
/ kinfo
->sector_size
;
706 assert(bank
->num_sectors
> 0);
707 bank
->sectors
= malloc(sizeof(struct flash_sector
) * bank
->num_sectors
);
709 for (i
= 0; i
< bank
->num_sectors
; i
++) {
710 bank
->sectors
[i
].offset
= offset
;
711 bank
->sectors
[i
].size
= kinfo
->sector_size
;
712 offset
+= kinfo
->sector_size
;
713 bank
->sectors
[i
].is_erased
= -1;
714 bank
->sectors
[i
].is_protected
= 1;
720 static int kinetis_probe(struct flash_bank
*bank
)
722 if (bank
->target
->state
!= TARGET_HALTED
) {
723 LOG_WARNING("Cannot communicate... target not halted.");
724 return ERROR_TARGET_NOT_HALTED
;
727 return kinetis_read_part_info(bank
);
730 static int kinetis_auto_probe(struct flash_bank
*bank
)
732 struct kinetis_flash_bank
*kinfo
= bank
->driver_priv
;
737 return kinetis_probe(bank
);
740 static int kinetis_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
742 const char *bank_class_names
[] = {
743 "(ANY)", "PFlash", "FlexNVM", "FlexRAM"
746 struct kinetis_flash_bank
*kinfo
= bank
->driver_priv
;
748 (void) snprintf(buf
, buf_size
,
749 "%s driver for %s flash bank %s at 0x%8.8" PRIx32
"",
750 bank
->driver
->name
, bank_class_names
[kinfo
->flash_class
],
751 bank
->name
, bank
->base
);
756 static int kinetis_blank_check(struct flash_bank
*bank
)
758 struct kinetis_flash_bank
*kinfo
= bank
->driver_priv
;
760 if (bank
->target
->state
!= TARGET_HALTED
) {
761 LOG_ERROR("Target not halted");
762 return ERROR_TARGET_NOT_HALTED
;
765 if (kinfo
->flash_class
== FC_PFLASH
) {
767 uint32_t w0
= 0, w1
= 0, w2
= 0;
770 /* check if whole bank is blank */
771 w0
= (FTFx_CMD_BLOCKSTAT
<< 24) | bank
->base
;
772 w1
= 0; /* "normal margin" */
774 result
= kinetis_ftfx_command(bank
, w0
, w1
, w2
, &ftfx_fstat
);
776 if (result
!= ERROR_OK
)
779 if (ftfx_fstat
& 0x01) {
780 /* the whole bank is not erased, check sector-by-sector */
782 for (i
= 0; i
< bank
->num_sectors
; i
++) {
783 w0
= (FTFx_CMD_SECTSTAT
<< 24) | (bank
->base
+ bank
->sectors
[i
].offset
);
784 w1
= (0x100 << 16) | 0; /* normal margin */
786 result
= kinetis_ftfx_command(bank
, w0
, w1
, w2
, &ftfx_fstat
);
788 if (result
== ERROR_OK
) {
789 bank
->sectors
[i
].is_erased
= !(ftfx_fstat
& 0x01);
791 LOG_DEBUG("Ignoring errored PFlash sector blank-check");
792 bank
->sectors
[i
].is_erased
= -1;
796 /* the whole bank is erased, update all sectors */
798 for (i
= 0; i
< bank
->num_sectors
; i
++)
799 bank
->sectors
[i
].is_erased
= 1;
802 LOG_WARNING("kinetis_blank_check not supported yet for FlexNVM");
803 return ERROR_FLASH_OPERATION_FAILED
;
809 static int kinetis_flash_read(struct flash_bank
*bank
,
810 uint8_t *buffer
, uint32_t offset
, uint32_t count
)
812 LOG_WARNING("kinetis_flash_read not supported yet");
814 if (bank
->target
->state
!= TARGET_HALTED
) {
815 LOG_ERROR("Target not halted");
816 return ERROR_TARGET_NOT_HALTED
;
819 return ERROR_FLASH_OPERATION_FAILED
;
822 struct flash_driver kinetis_flash
= {
824 .flash_bank_command
= kinetis_flash_bank_command
,
825 .erase
= kinetis_erase
,
826 .protect
= kinetis_protect
,
827 .write
= kinetis_write
,
828 .read
= kinetis_flash_read
,
829 .probe
= kinetis_probe
,
830 .auto_probe
= kinetis_auto_probe
,
831 .erase_check
= kinetis_blank_check
,
832 .protect_check
= kinetis_protect_check
,
833 .info
= kinetis_info
,
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)