@@ -262,6 +262,7 @@ static const ARM_STORAGE_INFO info = {
262
262
* This is the command code written into the first FCCOB register, FCCOB0.
263
263
*/
264
264
enum FlashCommandOps {
265
+ RD1SEC = (uint8_t )0x01 , /* read 1s section */
265
266
PGM8 = (uint8_t )0x07 , /* program phrase */
266
267
ERSBLK = (uint8_t )0x08 , /* erase block */
267
268
ERSSCR = (uint8_t )0x09 , /* erase flash sector */
@@ -433,6 +434,34 @@ static inline void setupAddressInCCOB123(uint64_t addr)
433
434
}
434
435
#endif /* ifndef USING_KSDK2 */
435
436
437
+ static inline void setupRead1sSection (uint64_t addr , size_t cnt )
438
+ {
439
+ #ifdef USING_KSDK2
440
+ kFCCOBx [0 ] = BYTES_JOIN_TO_WORD_1_3 (RD1SEC , addr );
441
+ kFCCOBx [1 ] = BYTES_JOIN_TO_WORD_2_1_1 (cnt >> 4 , 0 /* normal read level */ , 0 );
442
+ #else
443
+ BW_FTFE_FCCOB0_CCOBn ((uintptr_t )FTFE , RD1SEC );
444
+ setupAddressInCCOB123 (addr );
445
+ BW_FTFE_FCCOB4_CCOBn ((uintptr_t )FTFE , ((cnt >> 4 ) >> 8 ) & 0xFFUL ); /* bits [15:8] of cnt in units of 128-bits. */
446
+ BW_FTFE_FCCOB5_CCOBn ((uintptr_t )FTFE , ((cnt >> 4 ) >> 0 ) & 0xFFUL ); /* bits [7:0] of cnt in units of 128-bits. */
447
+ BW_FTFE_FCCOB6_CCOBn ((uintptr_t )FTFE , 0 ); /* use normal read level for 1s. */
448
+ #endif
449
+ }
450
+
451
+ static inline bool currentCommandByteIsRD1SEC (void )
452
+ {
453
+ #ifdef USING_KSDK2
454
+ return ((kFCCOBx [0 ] >> 24 ) == RD1SEC );
455
+ #else
456
+ return (BR_FTFE_FCCOB0_CCOBn ((uintptr_t )FTFE ) == RD1SEC );
457
+ #endif
458
+ }
459
+
460
+ static inline bool currentCommandSetupIsAnEraseCheck (const struct mtd_k64f_data * context )
461
+ {
462
+ return ((context -> currentCommand == ARM_STORAGE_OPERATION_ERASE ) && currentCommandByteIsRD1SEC ());
463
+ }
464
+
436
465
static inline void setupEraseSector (uint64_t addr )
437
466
{
438
467
#ifdef USING_KSDK2
@@ -547,16 +576,33 @@ static inline void setupNextProgramData(struct mtd_k64f_data *context)
547
576
}
548
577
}
549
578
579
+ /* Setup a command to determine if erase is needed for the range
580
+ * [context->currentOperatingStorageAddress, context->currentOperatingStorageAddress + ERASE_UNIT).
581
+ * If any byte within the range isn't 0xFF, this command results in a run-time
582
+ * error.
583
+ *
584
+ * Upon launch, if any byte within the given range isn't 0xFF then this command
585
+ * will terminate in a run-time error.
586
+ */
587
+ static inline void setupNextEraseCheck (const struct mtd_k64f_data * context )
588
+ {
589
+ setupRead1sSection (context -> currentOperatingStorageAddress , ERASE_UNIT ); /* setup check for erased */
590
+ }
591
+
592
+ static inline void progressEraseContextByEraseUnit (struct mtd_k64f_data * context )
593
+ {
594
+ context -> amountLeftToOperate -= ERASE_UNIT ;
595
+ context -> currentOperatingStorageAddress += ERASE_UNIT ;
596
+ }
597
+
550
598
/**
551
599
* Advance the state machine for erase. This function is called only if
552
600
* amountLeftToOperate is non-zero.
553
601
*/
554
602
static inline void setupNextErase (struct mtd_k64f_data * context )
555
603
{
556
604
setupEraseSector (context -> currentOperatingStorageAddress ); /* Program FCCOB to load the required command parameters. */
557
-
558
- context -> amountLeftToOperate -= ERASE_UNIT ;
559
- context -> currentOperatingStorageAddress += ERASE_UNIT ;
605
+ progressEraseContextByEraseUnit (context );
560
606
}
561
607
562
608
static int32_t executeCommand (struct mtd_k64f_data * context )
@@ -591,7 +637,10 @@ static int32_t executeCommand(struct mtd_k64f_data *context)
591
637
return ARM_DRIVER_ERROR_PARAMETER ;
592
638
}
593
639
if (failedWithRunTimeError ()) {
594
- return ARM_STORAGE_ERROR_RUNTIME_OR_INTEGRITY_FAILURE ;
640
+ /* filter away run-time errors which may legitimately arise from an erase-check operation. */
641
+ if (!currentCommandSetupIsAnEraseCheck (context )) {
642
+ return ARM_STORAGE_ERROR_RUNTIME_OR_INTEGRITY_FAILURE ;
643
+ }
595
644
}
596
645
597
646
/* signal synchronous completion. */
@@ -607,11 +656,22 @@ static int32_t executeCommand(struct mtd_k64f_data *context)
607
656
break ;
608
657
609
658
case ARM_STORAGE_OPERATION_ERASE :
659
+ if (currentCommandSetupIsAnEraseCheck (context )) {
660
+ if (failedWithRunTimeError ()) {
661
+ /* a run-time failure from an erase-check indicates at an erase operation is necessary */
662
+ setupNextErase (context );
663
+ /* continue on to the next iteration of the parent loop */
664
+ break ;
665
+ } else {
666
+ /* erase can be skipped since this sector is already erased. */
667
+ progressEraseContextByEraseUnit (context );
668
+ }
669
+ }
610
670
if (context -> amountLeftToOperate == 0 ) {
611
671
return context -> sizeofCurrentOperation ;
612
672
}
613
673
614
- setupNextErase (context ); /* start the successive erase operation */
674
+ setupNextEraseCheck (context ); /* start the erase check on the successive erase sector */
615
675
/* continue on to the next iteration of the parent loop */
616
676
break ;
617
677
@@ -653,10 +713,13 @@ static void ftfe_ccie_irq_handler(void)
653
713
return ;
654
714
}
655
715
if (failedWithRunTimeError ()) {
656
- if (context -> commandCompletionCallback ) {
657
- context -> commandCompletionCallback (ARM_STORAGE_ERROR_RUNTIME_OR_INTEGRITY_FAILURE , context -> currentCommand );
716
+ /* filter away run-time errors which may legitimately arise from an erase-check operation. */
717
+ if (!currentCommandSetupIsAnEraseCheck (context )) {
718
+ if (context -> commandCompletionCallback ) {
719
+ context -> commandCompletionCallback (ARM_STORAGE_ERROR_RUNTIME_OR_INTEGRITY_FAILURE , context -> currentCommand );
720
+ }
721
+ return ;
658
722
}
659
- return ;
660
723
}
661
724
662
725
switch (context -> currentCommand ) {
@@ -674,14 +737,25 @@ static void ftfe_ccie_irq_handler(void)
674
737
break ;
675
738
676
739
case ARM_STORAGE_OPERATION_ERASE :
740
+ if (currentCommandSetupIsAnEraseCheck (context )) {
741
+ if (failedWithRunTimeError ()) {
742
+ /* a run-time failure from an erase-check indicates at an erase operation is necessary */
743
+ setupNextErase (context );
744
+ launchCommandFromIRQ (context );
745
+ break ;
746
+ } else {
747
+ /* erase can be skipped since this sector is already erased. */
748
+ progressEraseContextByEraseUnit (context );
749
+ }
750
+ }
677
751
if (context -> amountLeftToOperate == 0 ) {
678
752
if (context -> commandCompletionCallback ) {
679
753
context -> commandCompletionCallback (context -> sizeofCurrentOperation , ARM_STORAGE_OPERATION_ERASE );
680
754
}
681
755
return ;
682
756
}
683
757
684
- setupNextErase (context );
758
+ setupNextEraseCheck (context ); /* start the erase check on the successive erase sector */
685
759
launchCommandFromIRQ (context );
686
760
break ;
687
761
@@ -915,7 +989,7 @@ static int32_t erase(uint64_t addr, uint32_t size)
915
989
context -> amountLeftToOperate = size ;
916
990
917
991
clearErrorStatusBits ();
918
- setupNextErase (context );
992
+ setupNextEraseCheck (context );
919
993
return executeCommand (context );
920
994
}
921
995
0 commit comments