In July, 2010, I had the freescale support about how to save data in SE8 Flash Memory. OK.
Actually, I have an application (temperature controller), which has 8 x 4 parameters (a const signed int vector in C language) to be saved in Flash Memory.
When I program the hardware and enter the "save parameters mode" the first time, it works okay (I'm able to save the data in the memory).
However, when I turn it off and turn it on again (the hardware), I'm not able anymore to save the data.
I tried to debug the application, but it has been very difficult to find the problem.
#include "FLASH.h"
/*
*
*/
#pragma CODE_SEG DEFAULT
void flash_init(void)
{
if(!(FCDIV & 0x80))
{
if(FSTAT & 0x30) //Check to see if FACCERR is set
{
FSTAT |= 0x30; //write a 1 to FACCERR to clear
}
FCDIV = FLASH_CLOCK;
}
}
/*
*
*/
#pragma CODE_SEG FLASH_ROUTINES
unsigned char flash_cmd(unsigned int flashAddress, unsigned int flashDataCounter, unsigned char* pFlashDataPtr, unsigned char flashCommand)
{
/* Clear Flags if set*/
FSTAT = 0x30;
do
{
/* Wait for the Last Busrt Command to complete */
while(!(FSTAT&0x80));
/* Write Data into Flash*/
(*((volatile unsigned char *)(flashAddress++))) = *pFlashDataPtr;
pFlashDataPtr++;
/* Write Command */
FCMD = flashCommand;
_asm NOP;
_asm NOP;
_asm NOP;
_asm NOP;
/* Put FCBEF at 1 */
FSTAT = 0x80;
/* Check if Flash Access Error or Protection Violation Error are Set */
if(FSTAT & 0x30)
{
/* If so, finish the function returning 1 to indicate error */
return (1);
}
}while (--flashDataCounter);
/* wait for the last command to complete */
while((FSTAT & 0x40)==0);
/* Return zero to indicate that the function executed Ok */
return (0);
}
#pragma CODE_SEG DEFAULT
/******************************************************************************************************/
/******************************************************************************************************/
/******************************************************************************************************/
/* This is the implementation to copy a function to RAM; Read Technical Note 228 for more information */
extern char __SEG_START_FLASH_ROUTINES[];
extern char __SEG_SIZE_FLASH_ROUTINES[];
/*
* Start_Copy_In_RAM refers to the begining of the segment
* ToCopyToRAM. This segment contains the functions after
* they have been copied to RAM.
*/
#define START_COPY_IN_RAM __SEG_START_FLASH_ROUTINES
#define SIZE_COPY_IN_RAM __SEG_SIZE_FLASH_ROUTINES
/*
* Start_In_ROM refers to the begining of the segment
* ToCopyToRAM. This segment contains the functions in ROM.
*/
void flash_copyInRAM(void)
{
char *srcPtr;
char *dstPtr;
int count;
srcPtr = (char *)START_COPY_IN_RAM;
dstPtr = (char *)&flash_cmd;
for (count = 0; count < (int) SIZE_COPY_IN_RAM; count++, dstPtr++, srcPtr++)
{
*dstPtr = *srcPtr;
}
}
/*
*
*/
void memoryManager_enableMemory(unsigned char status)
{
if(status == MEMORY_ENABLED)
{
RTCSC_RTIE = 0; //Disable Timer Interrupt
DisableInterrupts;
SOPT1_COPT = 0;
}
else if(status == MEMORY_DISABLED)
{
SOPT1_COPT = 1;
__RESET_WATCHDOG();
RTCSC_RTIE = 1; //Enable Timer Interrupt
EnableInterrupts;
}
}
Please, could anyone help me?
Thank you in advance.
Hi Celso,
I'm erasing the flash page. Please, see below some lines of my routine. I did some tests today morning, and I got the problem in two scenarios:
Scenario 1:
- Program the hardware
- Save/change two or three parameters (OK)
- Turn the hardware off and on
- Save/change one parameter (Not OK). All the other features of my software works fine, but I'm not able to save the parameters anymore
Scenario 2:
- Program the hardware
- Save/change two or three parameters (OK)
- Continue saving more and more parameters (Not OK). I had problems to save the 8th or 9th parameters. The microcontroller was reseted once. After, the memory and the software were completely erased.
Conclusion:
If I don't use the memory, all is okay. However, if I use the memory (erase and program) some times, the software is lost or completely erased.
Thank you, in advance.
Cremonezi
I forgot to post some lines of my routine. Sorry.
RTCSC_RTIE = 0; //Disable Timer Interrupt
DisableInterrupts; //Disable global interrupts
SOPT1_COPT = 0; //Disable WDT
if(flash_erase(MEMORY_PAGE) == 0) //If there is no problem during erase process, enter program mode.
{
for(i = 1; i <= PARAMETERS_NUMBER; i++)
memoryManager_saveParamValue(i, menu_parameterNumber, menu_data[PARAM_VALUE]);
}
SOPT1_COPT = 1; //Enable WDT
__RESET_WATCHDOG(); //Reset WDT
RTCSC_RTIE = 1; //Enable Timer Interrupt
EnableInterrupts; //Enable global interrupts
//*********************************************************
void memoryManager_saveParamValue(unsigned char index, unsigned char paramIndex, signed int value)
{
unsigned char address;
unsigned char addressAdjust;
addressAdjust = ((index-1)*4);
address = ((index-1)*8) + PARAM_VALUE_INDEX;
if(index == paramIndex)
{
memoryManager_writeData(address,value);
memoryManager_bufferData[index-1] = value;
}
else
memoryManager_writeData(address,memoryManager_bufferData[index-1]);
address += 2;
memoryManager_writeData(address,memoryManager_parameters[addressAdjust+1]);
address += 2;
memoryManager_writeData(address,memoryManager_parameters[addressAdjust+2]);
address += 2;
memoryManager_writeData(address,memoryManager_parameters[addressAdjust+3]);
}
void memoryManager_writeData(unsigned char address, signed int singleInt16)
{
unsigned char index;
unsigned char memData;
index = address;
memData = getByte16Bits(singleInt16,1);
memoryManager_writeByte(index, memData);
index++;
memData = getByte16Bits(singleInt16,2);
memoryManager_writeByte(index, memData);
}
void memoryManager_writeByte(unsigned char address, unsigned char singleByte)
{
unsigned char dataToWrite;
dataToWrite = singleByte;
memoryAddress = MEMORY_INIT_ADDRESS + (unsigned int)address;
if(flash_program(memoryAddress, dataToWrite))
{
memoryErrorCode = MEMORY_WRITE_ERROR;
}
}