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] = {
98 struct kinetis_flash_bank
{
100 unsigned bank_ordinal
;
101 uint32_t sector_size
;
102 uint32_t protection_size
;
116 FLASH_BANK_COMMAND_HANDLER(kinetis_flash_bank_command
)
118 struct kinetis_flash_bank
*bank_info
;
121 return ERROR_COMMAND_SYNTAX_ERROR
;
123 LOG_INFO("add flash_bank kinetis %s", bank
->name
);
125 bank_info
= malloc(sizeof(struct kinetis_flash_bank
));
127 memset(bank_info
, 0, sizeof(struct kinetis_flash_bank
));
129 bank
->driver_priv
= bank_info
;
134 static int kinetis_protect(struct flash_bank
*bank
, int set
, int first
,
137 LOG_WARNING("kinetis_protect not supported yet");
140 if (bank
->target
->state
!= TARGET_HALTED
) {
141 LOG_ERROR("Target not halted");
142 return ERROR_TARGET_NOT_HALTED
;
145 return ERROR_FLASH_BANK_INVALID
;
148 static int kinetis_protect_check(struct flash_bank
*bank
)
150 struct kinetis_flash_bank
*kinfo
= bank
->driver_priv
;
152 if (bank
->target
->state
!= TARGET_HALTED
) {
153 LOG_ERROR("Target not halted");
154 return ERROR_TARGET_NOT_HALTED
;
157 if (kinfo
->flash_class
== FC_PFLASH
) {
160 uint32_t fprot
, psec
;
163 /* read protection register FTFx_FPROT */
164 result
= target_read_memory(bank
->target
, 0x40020010, 1, 4, buffer
);
166 if (result
!= ERROR_OK
)
169 fprot
= target_buffer_get_u32(bank
->target
, buffer
);
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.
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;
181 bank
->sectors
[i
].is_protected
= 1;
183 psec
+= bank
->sectors
[i
].size
;
185 if (psec
>= kinfo
->protection_size
) {
191 LOG_ERROR("Protection checks for FlexNVM not yet supported");
192 return ERROR_FLASH_BANK_INVALID
;
198 static int kinetis_ftfx_command(struct flash_bank
*bank
, uint32_t w0
,
199 uint32_t w1
, uint32_t w2
, uint8_t *ftfx_fstat
)
205 for (i
= 0; i
< 50; i
++) {
207 target_read_memory(bank
->target
, 0x40020000, 1, 1, buffer
);
209 if (result
!= ERROR_OK
)
212 if (buffer
[0] & 0x80)
218 if (buffer
[0] != 0x80) {
219 /* reset error flags */
222 target_write_memory(bank
->target
, 0x40020000, 1, 1, buffer
);
223 if (result
!= ERROR_OK
)
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
);
231 result
= target_write_memory(bank
->target
, 0x40020004, 4, 3, buffer
);
233 if (result
!= ERROR_OK
)
238 result
= target_write_memory(bank
->target
, 0x40020000, 1, 1, buffer
);
239 if (result
!= ERROR_OK
)
243 for (i
= 0; i
< 50; i
++) {
245 target_read_memory(bank
->target
, 0x40020000, 1, 1, ftfx_fstat
);
247 if (result
!= ERROR_OK
)
250 if (*ftfx_fstat
& 0x80)
254 if ((*ftfx_fstat
& 0xf0) != 0x80) {
256 ("ftfx command failed FSTAT: %02X W0: %08X W1: %08X W2: %08X",
257 *ftfx_fstat
, w0
, w1
, w2
);
259 return ERROR_FLASH_OPERATION_FAILED
;
265 static int kinetis_erase(struct flash_bank
*bank
, int first
, int last
)
268 uint32_t w0
= 0, w1
= 0, w2
= 0;
270 if (bank
->target
->state
!= TARGET_HALTED
) {
271 LOG_ERROR("Target not halted");
272 return ERROR_TARGET_NOT_HALTED
;
275 if ((first
> bank
->num_sectors
) || (last
> bank
->num_sectors
))
276 return ERROR_FLASH_OPERATION_FAILED
;
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.
283 for (i
= first
; i
<= last
; i
++) {
285 /* set command and sector address */
286 w0
= (0x09 << 24) | (bank
->base
+ bank
->sectors
[i
].offset
);
288 result
= kinetis_ftfx_command(bank
, w0
, w1
, w2
, &ftfx_fstat
);
290 if (result
!= ERROR_OK
) {
291 LOG_WARNING("erase sector %d failed", i
);
292 return ERROR_FLASH_OPERATION_FAILED
;
295 bank
->sectors
[i
].is_erased
= 1;
300 ("flash configuration field erased, please reset the device");
306 static int kinetis_write(struct flash_bank
*bank
, uint8_t *buffer
,
307 uint32_t offset
, uint32_t count
)
309 unsigned int i
, result
, fallback
= 0;
311 uint32_t wc
, w0
= 0, w1
= 0, w2
= 0;
312 struct kinetis_flash_bank
*kinfo
= bank
->driver_priv
;
314 if (bank
->target
->state
!= TARGET_HALTED
) {
315 LOG_ERROR("Target not halted");
316 return ERROR_TARGET_NOT_HALTED
;
319 if (kinfo
->flash_class
== FC_FLEX_NVM
) {
322 LOG_DEBUG("flash write into FlexNVM @%08X", offset
);
324 /* make flex ram available */
325 w0
= (0x81 << 24) | 0x00ff0000;
327 result
= kinetis_ftfx_command(bank
, w0
, w1
, w2
, &ftfx_fstat
);
329 if (result
!= ERROR_OK
)
330 return ERROR_FLASH_OPERATION_FAILED
;
332 /* check if ram ready */
333 result
= target_read_memory(bank
->target
, 0x40020001, 1, 1, buf
);
335 if (result
!= ERROR_OK
)
338 if (!(buf
[0] & (1 << 1))) {
339 /* fallback to longword write */
342 LOG_WARNING("ram not ready, fallback to slow longword write (FCNFG: %02X)",
346 LOG_DEBUG("flash write into PFLASH @08%X", offset
);
350 /* program section command */
352 unsigned prog_section_bytes
= kinfo
->sector_size
>> 8;
353 for (i
= 0; i
< count
; i
+= kinfo
->sector_size
) {
355 * The largest possible Kinetis "section" is
356 * 16 bytes. A full Kinetis sector is always
359 uint8_t residual_buffer
[16];
361 uint32_t section_count
= 256;
362 uint32_t residual_wc
= 0;
365 * Assume the word count covers an entire
368 wc
= kinfo
->sector_size
/ 4;
371 * If bytes to be programmed are less than the
372 * full sector, then determine the number of
373 * full-words to program, and put together the
374 * residual buffer so that a full "section"
375 * may always be programmed.
377 if ((count
- i
) < kinfo
->sector_size
) {
378 /* number of bytes to program beyond full section */
379 unsigned residual_bc
= (count
-i
) % prog_section_bytes
;
381 /* number of complete words to copy directly from buffer */
382 wc
= (count
- i
) / 4;
384 /* number of total sections to write, including residual */
385 section_count
= DIV_ROUND_UP((count
-i
), prog_section_bytes
);
387 /* any residual bytes delivers a whole residual section */
388 residual_wc
= (residual_bc
? prog_section_bytes
: 0)/4;
390 /* clear residual buffer then populate residual bytes */
391 (void) memset(residual_buffer
, 0xff, prog_section_bytes
);
392 (void) memcpy(residual_buffer
, &buffer
[i
+4*wc
], residual_bc
);
395 LOG_DEBUG("write section @ %08X with length %d bytes",
396 offset
+ i
, (count
- i
));
398 /* write data to flexram as whole-words */
399 result
= target_write_memory(bank
->target
, 0x14000000, 4, wc
,
402 if (result
!= ERROR_OK
) {
403 LOG_ERROR("target_write_memory failed");
407 /* write the residual words to the flexram */
409 result
= target_write_memory(bank
->target
,
414 if (result
!= ERROR_OK
) {
415 LOG_ERROR("target_write_memory failed");
420 /* execute section-write command */
421 w0
= (0x0b << 24) | (bank
->base
+ offset
+ i
);
422 w1
= section_count
<< 16;
424 result
= kinetis_ftfx_command(bank
, w0
, w1
, w2
, &ftfx_fstat
);
426 if (result
!= ERROR_OK
)
427 return ERROR_FLASH_OPERATION_FAILED
;
430 /* program longword command, not supported in "SF3" devices */
431 else if (kinfo
->granularity
!= 3) {
432 for (i
= 0; i
< count
; i
+= 4) {
435 LOG_DEBUG("write longword @ %08X", offset
+ i
);
437 w0
= (0x06 << 24) | (bank
->base
+ offset
+ i
);
438 w1
= buf_get_u32(buffer
+ offset
+ i
, 0, 32);
440 result
= kinetis_ftfx_command(bank
, w0
, w1
, w2
, &ftfx_fstat
);
442 if (result
!= ERROR_OK
)
443 return ERROR_FLASH_OPERATION_FAILED
;
446 LOG_ERROR("Flash write strategy not implemented");
447 return ERROR_FLASH_OPERATION_FAILED
;
453 static int kinetis_read_part_info(struct flash_bank
*bank
)
458 uint8_t fcfg1_nvmsize
, fcfg1_pfsize
, fcfg1_eesize
, fcfg2_pflsh
;
459 uint32_t nvm_size
= 0, pf_size
= 0, ee_size
= 0;
460 unsigned granularity
, num_blocks
= 0, num_pflash_blocks
= 0, num_nvm_blocks
= 0,
461 first_nvm_bank
= 0, reassign
= 0;
462 struct kinetis_flash_bank
*kinfo
= bank
->driver_priv
;
464 result
= target_read_memory(bank
->target
, 0x40048024, 1, 4, buf
);
465 if (result
!= ERROR_OK
)
467 kinfo
->sim_sdid
= target_buffer_get_u32(bank
->target
, buf
);
468 granularity
= (kinfo
->sim_sdid
>> 7) & 0x03;
469 result
= target_read_memory(bank
->target
, 0x4004804c, 1, 4, buf
);
470 if (result
!= ERROR_OK
)
472 kinfo
->sim_fcfg1
= target_buffer_get_u32(bank
->target
, buf
);
473 result
= target_read_memory(bank
->target
, 0x40048050, 1, 4, buf
);
474 if (result
!= ERROR_OK
)
476 kinfo
->sim_fcfg2
= target_buffer_get_u32(bank
->target
, buf
);
477 fcfg2_pflsh
= (kinfo
->sim_fcfg2
>> 23) & 0x01;
479 LOG_DEBUG("SDID: %08X FCFG1: %08X FCFG2: %08X", kinfo
->sim_sdid
,
480 kinfo
->sim_fcfg1
, kinfo
->sim_fcfg2
);
482 fcfg1_nvmsize
= (uint8_t)((kinfo
->sim_fcfg1
>> 28) & 0x0f);
483 fcfg1_pfsize
= (uint8_t)((kinfo
->sim_fcfg1
>> 24) & 0x0f);
484 fcfg1_eesize
= (uint8_t)((kinfo
->sim_fcfg1
>> 16) & 0x0f);
486 /* when the PFLSH bit is set, there is no FlexNVM/FlexRAM */
488 switch (fcfg1_nvmsize
) {
493 nvm_size
= 1 << (14 + (fcfg1_nvmsize
>> 1));
496 if (granularity
== 3)
506 switch (fcfg1_eesize
) {
517 ee_size
= (16 << (10 - fcfg1_eesize
));
525 switch (fcfg1_pfsize
) {
532 pf_size
= 1 << (14 + (fcfg1_pfsize
>> 1));
535 if (granularity
== 3)
537 else if (fcfg2_pflsh
)
547 LOG_DEBUG("FlexNVM: %d PFlash: %d FlexRAM: %d PFLSH: %d",
548 nvm_size
, pf_size
, ee_size
, fcfg2_pflsh
);
550 num_blocks
= kinetis_flash_params
[granularity
].num_blocks
;
551 num_pflash_blocks
= num_blocks
/ (2 - fcfg2_pflsh
);
552 first_nvm_bank
= num_pflash_blocks
;
553 num_nvm_blocks
= num_blocks
- num_pflash_blocks
;
555 LOG_DEBUG("%d blocks total: %d PFlash, %d FlexNVM",
556 num_blocks
, num_pflash_blocks
, num_nvm_blocks
);
559 * If the flash class is already assigned, verify the
562 if (kinfo
->flash_class
!= FC_AUTO
) {
563 if (kinfo
->bank_ordinal
!= (unsigned) bank
->bank_number
) {
564 LOG_WARNING("Flash ordinal/bank number mismatch");
566 } else if (kinfo
->granularity
!= granularity
) {
567 LOG_WARNING("Flash granularity mismatch");
570 switch (kinfo
->flash_class
) {
572 if (kinfo
->bank_ordinal
>= first_nvm_bank
) {
573 LOG_WARNING("Class mismatch, bank %d is not PFlash",
576 } else if (bank
->size
!= (pf_size
/ num_pflash_blocks
)) {
577 LOG_WARNING("PFlash size mismatch");
579 } else if (bank
->base
!=
580 (0x00000000 + bank
->size
* kinfo
->bank_ordinal
)) {
581 LOG_WARNING("PFlash address range mismatch");
583 } else if (kinfo
->sector_size
!=
584 kinetis_flash_params
[granularity
].pflash_sector_size_bytes
) {
585 LOG_WARNING("PFlash sector size mismatch");
588 LOG_DEBUG("PFlash bank %d already configured okay",
589 kinfo
->bank_ordinal
);
593 if ((kinfo
->bank_ordinal
>= num_blocks
) ||
594 (kinfo
->bank_ordinal
< first_nvm_bank
)) {
595 LOG_WARNING("Class mismatch, bank %d is not FlexNVM",
598 } else if (bank
->size
!= (nvm_size
/ num_nvm_blocks
)) {
599 LOG_WARNING("FlexNVM size mismatch");
601 } else if (bank
->base
!=
602 (0x10000000 + bank
->size
* kinfo
->bank_ordinal
)) {
603 LOG_WARNING("FlexNVM address range mismatch");
605 } else if (kinfo
->sector_size
!=
606 kinetis_flash_params
[granularity
].nvm_sector_size_bytes
) {
607 LOG_WARNING("FlexNVM sector size mismatch");
610 LOG_DEBUG("FlexNVM bank %d already configured okay",
611 kinfo
->bank_ordinal
);
615 if (kinfo
->bank_ordinal
!= num_blocks
) {
616 LOG_WARNING("Class mismatch, bank %d is not FlexRAM",
619 } else if (bank
->size
!= ee_size
) {
620 LOG_WARNING("FlexRAM size mismatch");
622 } else if (bank
->base
!= 0x14000000) {
623 LOG_WARNING("FlexRAM address mismatch");
625 } else if (kinfo
->sector_size
!=
626 kinetis_flash_params
[granularity
].nvm_sector_size_bytes
) {
627 LOG_WARNING("FlexRAM sector size mismatch");
630 LOG_DEBUG("FlexRAM bank %d already configured okay",
631 kinfo
->bank_ordinal
);
636 LOG_WARNING("Unknown or inconsistent flash class");
642 LOG_INFO("Probing flash info for bank %d", bank
->bank_number
);
649 kinfo
->granularity
= granularity
;
651 if ((unsigned)bank
->bank_number
< num_pflash_blocks
) {
652 /* pflash, banks start at address zero */
653 kinfo
->flash_class
= FC_PFLASH
;
654 bank
->size
= (pf_size
/ num_pflash_blocks
);
655 bank
->base
= 0x00000000 + bank
->size
* bank
->bank_number
;
656 kinfo
->sector_size
= kinetis_flash_params
[granularity
].pflash_sector_size_bytes
;
657 kinfo
->protection_size
= pf_size
/ 32;
658 } else if ((unsigned)bank
->bank_number
< num_blocks
) {
659 /* nvm, banks start at address 0x10000000 */
660 kinfo
->flash_class
= FC_FLEX_NVM
;
661 bank
->size
= (nvm_size
/ num_nvm_blocks
);
662 bank
->base
= 0x10000000 + bank
->size
* (bank
->bank_number
- first_nvm_bank
);
663 kinfo
->sector_size
= kinetis_flash_params
[granularity
].nvm_sector_size_bytes
;
664 kinfo
->protection_size
= 0; /* FIXME: TODO: depends on DEPART bits, chip */
665 } else if ((unsigned)bank
->bank_number
== num_blocks
) {
666 LOG_ERROR("FlexRAM support not yet implemented");
667 return ERROR_FLASH_OPER_UNSUPPORTED
;
669 LOG_ERROR("Cannot determine parameters for bank %d, only %d banks on device",
670 bank
->bank_number
, num_blocks
);
671 return ERROR_FLASH_BANK_INVALID
;
676 bank
->sectors
= NULL
;
679 bank
->num_sectors
= bank
->size
/ kinfo
->sector_size
;
680 assert(bank
->num_sectors
> 0);
681 bank
->sectors
= malloc(sizeof(struct flash_sector
) * bank
->num_sectors
);
683 for (i
= 0; i
< bank
->num_sectors
; i
++) {
684 bank
->sectors
[i
].offset
= offset
;
685 bank
->sectors
[i
].size
= kinfo
->sector_size
;
686 offset
+= kinfo
->sector_size
;
687 bank
->sectors
[i
].is_erased
= -1;
688 bank
->sectors
[i
].is_protected
= 1;
694 static int kinetis_probe(struct flash_bank
*bank
)
696 if (bank
->target
->state
!= TARGET_HALTED
) {
697 LOG_WARNING("Cannot communicate... target not halted.");
698 return ERROR_TARGET_NOT_HALTED
;
701 return kinetis_read_part_info(bank
);
704 static int kinetis_auto_probe(struct flash_bank
*bank
)
706 struct kinetis_flash_bank
*kinfo
= bank
->driver_priv
;
711 return kinetis_probe(bank
);
714 static int kinetis_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
716 const char *bank_class_names
[] = {
717 "(ANY)", "PFlash", "FlexNVM", "FlexRAM"
720 struct kinetis_flash_bank
*kinfo
= bank
->driver_priv
;
722 (void) snprintf(buf
, buf_size
,
723 "%s driver for %s flash bank %s at 0x%8.8" PRIx32
"",
724 bank
->driver
->name
, bank_class_names
[kinfo
->flash_class
],
725 bank
->name
, bank
->base
);
730 static int kinetis_blank_check(struct flash_bank
*bank
)
732 struct kinetis_flash_bank
*kinfo
= bank
->driver_priv
;
734 if (bank
->target
->state
!= TARGET_HALTED
) {
735 LOG_ERROR("Target not halted");
736 return ERROR_TARGET_NOT_HALTED
;
739 if (kinfo
->flash_class
== FC_PFLASH
) {
741 uint32_t w0
= 0, w1
= 0, w2
= 0;
744 /* check if whole bank is blank */
745 w0
= (0x00 << 24) | bank
->base
;
746 w1
= 0; /* "normal margin" */
748 result
= kinetis_ftfx_command(bank
, w0
, w1
, w2
, &ftfx_fstat
);
750 if (result
!= ERROR_OK
)
753 if (ftfx_fstat
& 0x01) {
754 /* the whole bank is not erased, check sector-by-sector */
756 for (i
= 0; i
< bank
->num_sectors
; i
++) {
757 w0
= (0x01 << 24) | (bank
->base
+ bank
->sectors
[i
].offset
);
758 w1
= (0x100 << 16) | 0; /* normal margin */
760 result
= kinetis_ftfx_command(bank
, w0
, w1
, w2
, &ftfx_fstat
);
762 if (result
== ERROR_OK
) {
763 bank
->sectors
[i
].is_erased
= !(ftfx_fstat
& 0x01);
765 LOG_DEBUG("Ignoring errored PFlash sector blank-check");
766 bank
->sectors
[i
].is_erased
= -1;
770 /* the whole bank is erased, update all sectors */
772 for (i
= 0; i
< bank
->num_sectors
; i
++)
773 bank
->sectors
[i
].is_erased
= 1;
776 LOG_WARNING("kinetis_blank_check not supported yet for FlexNVM");
777 return ERROR_FLASH_OPERATION_FAILED
;
783 static int kinetis_flash_read(struct flash_bank
*bank
,
784 uint8_t *buffer
, uint32_t offset
, uint32_t count
)
786 LOG_WARNING("kinetis_flash_read not supported yet");
788 if (bank
->target
->state
!= TARGET_HALTED
) {
789 LOG_ERROR("Target not halted");
790 return ERROR_TARGET_NOT_HALTED
;
793 return ERROR_FLASH_OPERATION_FAILED
;
796 struct flash_driver kinetis_flash
= {
798 .flash_bank_command
= kinetis_flash_bank_command
,
799 .erase
= kinetis_erase
,
800 .protect
= kinetis_protect
,
801 .write
= kinetis_write
,
802 .read
= kinetis_flash_read
,
803 .probe
= kinetis_probe
,
804 .auto_probe
= kinetis_auto_probe
,
805 .erase_check
= kinetis_blank_check
,
806 .protect_check
= kinetis_protect_check
,
807 .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)