Very critical problem to save data in SE8 Flash Memory!!!

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

Very critical problem to save data in SE8 Flash Memory!!!

1,508件の閲覧回数
cremonezi
Contributor I

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.

ラベル(1)
0 件の賞賛
返信
5 返答(返信)

890件の閲覧回数
celsoken
Contributor V

It seems you forgot to erase the flash page.

Before writing to flash it is mandatory that you erase the whole page you're going to write data.

 

I hope it helps,

 

Celso

0 件の賞賛
返信

889件の閲覧回数
cremonezi
Contributor I

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

 

 

 

0 件の賞賛
返信

890件の閲覧回数
cremonezi
Contributor I

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;
    }
}

0 件の賞賛
返信

890件の閲覧回数
cremonezi
Contributor I

Should I use the burst command instead of using a normal program command, byte to byte?

0 件の賞賛
返信

890件の閲覧回数
kef
Specialist I

COPT bits are write once. You can't turn COP off then on. First write to SOPT1 register (setting/clearing any SOPT1 bit) will lock COPT setting.

 

 

0 件の賞賛
返信