Kaitav
I don't have experience with the two drivers that you mentioned so can't saw which would be more suitable or easiest to use. It is also quite simple to develop a Flash driver based on the details in the user's manual.
Below I have copied the complete low level Flash driver code from the uTasker project (used as lowest level driver for Program Once, parameter and file system). This is compiler independent and is also used with Keil. You can probably work out the details to use it for storing your data. As noted above, the operation is described in the user's manual and I expect that all implementations will be more or less the same.
Regards
Mark
// This routine runs from SRAM - the reason why the pointer is passed is to avoid the routine taking it from a const value in FLASH, which is then not code location dependent
//
static unsigned short fnFlashRoutine[] = { // to avoid potential compiler in-lining of the routine (removing position independency) the machine code is used directly
0x2180, // MOVS r1,#0x80 load the value 0x80 (command complete interrupt flag) to register r1
0x7001, // STRB r1,[r0,#0x00] write r1 (0x80) to the passed pointer location (r0)
0x7801, // LDRB r1,[r0,#0x00] read back from the same location to r1
0x0609, // LSLS r1,r1,#24 shift the register content by 24 bits to the left so that the command complete interrupt flag is at bit 31
0xd5fc, // BPL -4 if the command complete interrupt flag bit is '0' (register content is not negative value) branch back to read its value again
0x4770 // BX lr return from sub-routine
};
static int fnFlashNow(unsigned char ucCommand, unsigned long *ptrWord, unsigned long *ptr_ulWord)
{
static void (*fnRAM_code)(volatile unsigned char *) = 0;
if (!fnRAM_code) { // the first time this is used it will load the program to SRAM
#define PROG_WORD_SIZE 30 // adequate space for the small program
int i = 0;
unsigned char *ptrThumb2 = (unsigned char *)fnFlashRoutine;
static unsigned short usProgSpace[PROG_WORD_SIZE]; // make space for the routine on stack (this will have an even boundary)
ptrThumb2 = (unsigned char *)(((CAST_POINTER_ARITHMETIC)ptrThumb2) & ~0x1); // thumb 2 address
while (i < PROG_WORD_SIZE) { // copy program to SRAM
usProgSpace[i++] = *(unsigned short *)ptrThumb2;
ptrThumb2 += sizeof (unsigned short);
}
ptrThumb2 = (unsigned char *)usProgSpace;
ptrThumb2++; // create a thumb 2 call
fnRAM_code = (void(*)(volatile unsigned char *))(ptrThumb2);
}
while (!(FTFL_FSTAT & FTFL_STAT_CCIF)) {} // wait for previous commands to complete
if (FTFL_FSTAT & (FTFL_STAT_ACCERR | FTFL_STAT_FPVIOL)) { // check for errors in previous command
FTFL_FSTAT = (FTFL_STAT_ACCERR | FTFL_STAT_FPVIOL); // clear old errors
}
switch (FTFL_FCCOB0 = ucCommand) { // enter the command sequence
case FCMD_ERASE_FLASH_SECTOR:
case FCMD_PROGRAM:
FTFL_FCCOB1 = (unsigned char)(((CAST_POINTER_ARITHMETIC)ptrWord) >> 16); // set address in flash
FTFL_FCCOB2 = (unsigned char)(((CAST_POINTER_ARITHMETIC)ptrWord) >> 8);
FTFL_FCCOB3 = (unsigned char)((CAST_POINTER_ARITHMETIC)ptrWord);
if (ucCommand == FCMD_PROGRAM) { // program long-word aligned value
FTFL_FCCOB4 = (unsigned char)(*ptr_ulWord >> 24); // enter the long word to be programmed
FTFL_FCCOB5 = (unsigned char)(*ptr_ulWord >> 16);
FTFL_FCCOB6 = (unsigned char)(*ptr_ulWord >> 8);
FTFL_FCCOB7 = (unsigned char)(*ptr_ulWord);
#if defined KINETIS_K_FPU // write second long word
ptr_ulWord++;
FTFL_FCCOB8 = (unsigned char)(*ptr_ulWord >> 24); // enter the second long word to be programmed
FTFL_FCCOB9 = (unsigned char)(*ptr_ulWord >> 16);
FTFL_FCCOBA = (unsigned char)(*ptr_ulWord >> 8);
FTFL_FCCOBB = (unsigned char)(*ptr_ulWord);
#endif
}
break;
#if defined SUPPORT_PROGRAM_ONCE
case FCMD_READ_ONCE:
FTFL_FCCOB1 = (unsigned char)(*ptrWord); // record index (0..7) for FPU types or (0..15)
break;
case FCMD_PROGRAM_ONCE:
FTFL_FCCOB1 = (unsigned char)(*ptrWord); // record index (0..7) for FPU types or (0..15)
FTFL_FCCOB4 = (unsigned char)(*ptr_ulWord >> 24);
FTFL_FCCOB5 = (unsigned char)(*ptr_ulWord >> 16);
FTFL_FCCOB6 = (unsigned char)(*ptr_ulWord >> 8);
FTFL_FCCOB7 = (unsigned char)(*ptr_ulWord);
#if defined KINETIS_K_FPU
ptr_ulWord++;
FTFL_FCCOB8 = (unsigned char)(*ptr_ulWord >> 24);
FTFL_FCCOB9 = (unsigned char)(*ptr_ulWord >> 16);
FTFL_FCCOBA = (unsigned char)(*ptr_ulWord >> 8);
FTFL_FCCOBB = (unsigned char)(*ptr_ulWord);
#endif
break;
#endif
}
uDisable_Interrupt(); // protect this region from interrupts
fnRAM_code((volatile unsigned char *)FTFL_BLOCK); // execute the command from SRAM
uEnable_Interrupt(); // safe to accept interrupts again
#if defined SUPPORT_PROGRAM_ONCE
if (FCMD_READ_ONCE == ucCommand) { // the result (8 bytes) is in FTFL_FCCOB2/FTFL_FCCOB3
*ptr_ulWord++ = ((FTFL_FCCOB4 << 24) | (FTFL_FCCOB5 << 16) | (FTFL_FCCOB6 << 8) | FTFL_FCCOB7);
#if defined KINETIS_K_FPU
*ptr_ulWord = ((FTFL_FCCOB8 << 24) | (FTFL_FCCOB9 << 16) | (FTFL_FCCOBA << 8) | FTFL_FCCOBB);
#endif
}
#endif
return (FTFL_FSTAT & (FTFL_STAT_ACCERR | FTFL_STAT_FPVIOL | FTFL_STAT_MGSTAT0)); // if there was an error this will be non-zero
}