AnsweredAssumed Answered

FRDM K27 flash managment

Question asked by Claudio Brunelli on Aug 9, 2019

I'd like to share my code, to understand what is abnormal about flash managment that I do.

The code you can see below, is taken from sdk library and modified by me, because I would just like to include in the project what I really need.

In the linker file I centralized several areas of flash destined for eeprom use because 
the final purpose I want to achieve is to have more flash zones destined to eeprom to be able
to randomly choose one or the other. But without having all the sdk libraries installed. The reproduced code works correctly except for the cancellation of the flash sectors
which is always total. I mean that if I launch WriteToEeprom (0) the segment that should not be managed is also deleted. And viceversa. For information: the first segment is located at 0x9000 and has a size of 0x100. The second is located at 0x9100 and also a size of 0x100.
It statrs from
WriteToEeprom(...) function.
I hope I have clarified myself.
It seems that everything works correctly but the deletion is always total and not
relative to the segment that I want to manage at that moment. Thank you.


/*!
***********************************************************************************************************************************************************************************
*** @details: Inclued files                                                                                                                                                        ***
***********************************************************************************************************************************************************************************
*/
#include    "custom_def.h"
#include    "global_vars.h"
#include    "flash.h"
#include     "SSD_FTFx_Common.h"
#include     "SSD_FTFx_Internal.h"

#include     "SSD_Types.h"
#include     "SSD_FTFx.h"
#include     "SSD_FTFx_Internal.h"

/*!
***********************************************************************************************************************************************************************************
*** @details: Defines                                                                                                                                                            ***
***********************************************************************************************************************************************************************************
*/
#define FLASH_REGISTERS_BASE           0x40020000
#define DEFLASH_BLOCK_BASE           0xFFFFFFFF
#define EERAM_BLOCK_BASE            0x14000000

#define EERAM_BLOCK_SIZE              0x00000000
#define DEBUGENABLE                   0x00
#define    INIT_STRUCT_FLAG              FALSE


/*********************************************************************************************************************************************************************************/
/* EEprom (flash) segments                                                                                                                                                         */
/*********************************************************************************************************************************************************************************/

/* USER BACKUP EEPROM */
extern  UINT8    EEP_UserBackUp_Start[];                                    // eeprom user backup start
extern  UINT8    EEP_UserBackUp_Stop[];                                    // eeprom user backup stop

extern  UINT8    EEP_UserBackUp_Size[];                                    // eeprom user backup size (treaty as array)
#define            EEP_UserBackUpSize        (UINT32)EEP_UserBackUp_Size        // eeprom user backup size

extern    UINT32    EEP_UserBackUp_Sector[];
#define            EEP_UserBackUpSector    (UINT32)EEP_UserBackUp_Sector



/* DATA USER EEPROM */
extern  UINT8    EEP_DataUser_Start[];                                    // eeprom user data start
extern  UINT8    EEP_DataUser_Stop[];                                    // eeprom user data stop

extern  UINT8    EEP_DataUser_Size[];                                    // eeprom user data size (treaty as array)
#define            EEP_DataUserSize     (UINT32)EEP_DataUser_Size            // eeprom user data size

extern    UINT32    EEP_DataUser_Sector[];
#define            EEP_DataUserSector    (UINT32)EEP_DataUser_Sector


UINT8                    Ram_For_CommandSequences[0x400];
pFLASHCOMMANDSEQUENCE     pFlashCommandSequence;

UINT8                     RAM_UserBackUp[24];

/*!
***********************************************************************************************************************************************************************************
*** @details: Eeprom segments structure                                                                                                                                            ***
***********************************************************************************************************************************************************************************
*/
typedef struct
{
    UINT8    *dst;
    UINT8    *src;
    UINT32    size;
    UINT32  sector_size;
}eepromstru;


eepromstru    EepromStruct[] =
{
    {EEP_UserBackUp_Start, (UINT8*)RAM_UserBackUp, EEP_UserBackUpSize, EEP_UserBackUpSector},
    {EEP_DataUser_Start,   (UINT8*)RAM_UserBackUp, EEP_DataUserSize,   EEP_DataUserSector  },

};

// STRUCTURE DATA
/*
 The data in the structure coming from linker file. Neverthless they are:
 -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
 EEP_UserBackUp_Start     = 0x9000            the destination
 RAM_UserBackUp           = 0x18                the data source (for now)
 EEP_UserBackUpSize       = 0x100                flash size
 EEP_UserBackUpSector     = 0x100                flash sector
 -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
 EEP_DataUser_Start        = 0x9100            the destination
 RAM_UserBackUp           = 0x18                the data source (for now)
 EEP_DataUserSize         = 0x100                flash size
 EEP_DataUserSector        = 0x100            flash sector
*/


/*!
***********************************************************************************************************************************************************************************
*** @fn        : UINT32 CustomFlashProgramLongword(PFLASH_SSD_CONFIG PSSDConfig, UINT32 destination, UINT32 size, pFLASHCOMMANDSEQUENCE FlashCommandSequence)                        ***
*** @brief    : erase flash sector                                                                                                                                                   ***
*** @param    : flash structure, destination flash addr, size of flash, command sequences                                                                                            ***
***                                                                                                                                                                             ***
*** @ return: operation result                                                                                                                                                    ***
***                                                                                                                                                                             ***
*** @details: flash writinf (long word type !)                                                                                                                                    ***
***                                                                                                                                                                             ***
***********************************************************************************************************************************************************************************
*/
UINT32 CustomFlashProgramLongword(PFLASH_SSD_CONFIG PSSDConfig, UINT32 destination, UINT32 size, UINT32 source)
{
    UINT8     pCommandArray[8];                                                                     /* command sequence array */
    UINT32    returnCode;                                                                          /* return code variable */
    UINT32     endAddress;                                                                          /* storing end address */


    returnCode = FTFx_OK;                                                                        /* set the default return code as FTFx_OK */
    endAddress = destination + BYTE2WORD(size);                                                    /* calculating Flash end address */

    if (destination & (BYTE2WORD(FTFx_LONGWORD_SIZE)-1))                                        /* check if the destination is Longword aligned or not */
        return FTFx_ERR_ADDR;

    if(size & (FTFx_LONGWORD_SIZE-1))                                                            /* check if the size is Longword alignment or not */
        return FTFx_ERR_SIZE;

    /* check for valid range of the target addresses */
    if((destination < PSSDConfig->PFlashBlockBase) || (endAddress  > (PSSDConfig->PFlashBlockBase + BYTE2WORD(PSSDConfig->PFlashBlockSize))))
        return FTFx_ERR_RANGE;

    if(FTFx_OK == returnCode)
    {
        while(size > 0)
        {
            pCommandArray[0] = FTFx_PROGRAM_LONGWORD;
            pCommandArray[1] = (UINT8)( destination >> 16);
            pCommandArray[2] = (UINT8)((destination >> 8) & 0xFF);
            pCommandArray[3] = (UINT8)( destination & 0xFF);

            pCommandArray[4] = READ8(source + 3);
            pCommandArray[5] = READ8(source + 2);
            pCommandArray[6] = READ8(source + 1);
            pCommandArray[7] = READ8(source);

            returnCode = pFlashCommandSequence(PSSDConfig, 7, pCommandArray);

            if(returnCode == FTFx_OK)
            {
                destination += FTFx_LONGWORD_SIZE;
                size        -= FTFx_LONGWORD_SIZE;
                source      += FTFx_LONGWORD_SIZE;
            }
            else
                break;
        }
    }
    return(returnCode);
}


/*!
***********************************************************************************************************************************************************************************
*** @fn        : UINT32 CustomFlashEraseSector(PFLASH_SSD_CONFIG PSSDConfig, UINT32 destination, UINT32 size, pFLASHCOMMANDSEQUENCE FlashCommandSequence)                            ***
*** @brief    : erase flash sector                                                                                                                                                   ***
*** @param    : flash structure, destination flash addr, size of flash, command sequences                                                                                            ***
***                                                                                                                                                                             ***
*** @ return: operation result                                                                                                                                                    ***
***                                                                                                                                                                             ***
*** @details: flash clearing                                                                                                                                                    ***
***                                                                                                                                                                             ***
***********************************************************************************************************************************************************************************
*/
UINT32 CustomFlashEraseSector(PFLASH_SSD_CONFIG PSSDConfig, UINT32 destination, UINT32 size, UINT32 sector_size)
{
    UINT8     pCommandArray[4];                         /* command sequence array */
    UINT32     returnCode;                              /* return code variable */
    UINT32     endAddress;                              /* storing end address */

    returnCode = FTFx_OK;                            /* set the default return code as FTFx_OK */
    endAddress = destination + BYTE2WORD(size);        // calculating Flash end address

    if(destination < PSSDConfig->PFlashBlockBase)
        return FTFx_ERR_RANGE;

    if(endAddress > (PSSDConfig->PFlashBlockBase + BYTE2WORD(PSSDConfig->PFlashBlockSize)))
            return FTFx_ERR_RANGE;

    if(destination & (sector_size-1)) return FTFx_ERR_ADDR;                    // check if the destination is sector aligned or not
    if(size        & (sector_size-1)) return FTFx_ERR_SIZE;                    // check if the size is sector alignment or not

    while(size > 0)
    {
        pCommandArray[0] = FTFx_ERASE_SECTOR;
        pCommandArray[1] = (UINT8)(destination  >> 16);
        pCommandArray[2] = (UINT8)((destination >>  8) & 0xFF);
        pCommandArray[3] = (UINT8)(destination & 0xFF);
        returnCode = pFlashCommandSequence(PSSDConfig, 3, pCommandArray);    // calling flash command sequence function to execute the command */

        if(returnCode != FTFx_OK)
            break;
        else
        {
            /* update size and destination address */
            size        = size - sector_size;
            destination = destination + sector_size;
        }
    }
    return(returnCode);
}

/*!
***********************************************************************************************************************************************************************************
*** @fn        : UINT32 xFlashInit(UINT32 flash_to_manage)                                                                                                                            ***
*** @brief    : inizialize flash segment                                                                                                                                            ***
*** @param    : flash to manage                                                                                                                                                    ***
***                                                                                                                                                                             ***
*** @ return: operation result                                                                                                                                                    ***
***                                                                                                                                                                             ***
*** @details: flash inizialization                                                                                                                                                ***
***                                                                                                                                                                             ***
***********************************************************************************************************************************************************************************
*/
UINT32 CustomFlashInit(UINT32 flash_to_manage, UINT32 sector_size, FLASH_SSD_CONFIG *flash_config_stru)
{
    UINT32    flashCmdFr, flashCmdTo, i;
    UINT8     value;

    flashCmdFr = (UINT32)FlashCommandSequence - 1;
    flashCmdTo = (UINT32)Ram_For_CommandSequences;
    for(i = 0; i < sector_size; i++)
    {
       value = READ8(flashCmdFr++);
       WRITE8(flashCmdTo++, value);
    }
    pFlashCommandSequence = (pFLASHCOMMANDSEQUENCE)((UINT8 *)Ram_For_CommandSequences + 1);


    flash_config_stru->ftfxRegBase     = FLASH_REGISTERS_BASE;

    flash_config_stru->PFlashBlockBase = flash_to_manage;
    flash_config_stru->PFlashBlockSize = sector_size;

    flash_config_stru->DFlashBlockBase = DEFLASH_BLOCK_BASE;
    flash_config_stru->DFlashBlockSize = 0;

    flash_config_stru->EERAMBlockBase  = EERAM_BLOCK_BASE;
    flash_config_stru->EERAMBlockSize  = EERAM_BLOCK_SIZE;

    flash_config_stru->EEEBlockSize    = 0;
    flash_config_stru->InitStructFlag  = TRUE;

    flash_config_stru->CallBack           = (PCALLBACK)0xFFFFFFFF;
    flash_config_stru->DebugEnable     = 0x00;

    return FTFx_OK;
}


/*!
***********************************************************************************************************************************************************************************
*** @fn        : void WriteToEeprom(UINT8 eep_section)                                                                                                                                ***
*** @brief    : Write to eeprom (flash)                                                                                                                                            ***
*** @param    : on input eeprom segment (see related structure EepromStruct                                                                                                        ***
***                                                                                                                                                                             ***
*** @ return: none                                                                                                                                                                ***
***                                                                                                                                                                             ***
*** @details:                                                                                                                                                                     ***
***                                                                                                                                                                             ***
***********************************************************************************************************************************************************************************
*/
void WriteToEeprom(UINT8 eep_section)
{
    UINT32                i, return_code;
    FLASH_SSD_CONFIG    flash_config_stru;


    if(eep_section > sizeof(EepromStruct) / sizeof(eepromstru))
        return;

    // just to write something on segment 0 (later erase)
    if(eep_section == 0)
    {
        for(i = 0; i < sizeof(RAM_UserBackUp) / sizeof(UINT8); i++)
            RAM_UserBackUp[i] = '0';
    }

    // just to write something on segment 1 (later erase)
    if(eep_section == 1)
    {
        for(i = 0; i < sizeof(RAM_UserBackUp) / sizeof(UINT8); i++)
            RAM_UserBackUp[i] = '1';
    }




    // init flash
    return_code = CustomFlashInit((UINT32)EepromStruct[eep_section].dst,
                                          EepromStruct[eep_section].size,
                                          &flash_config_stru);
    if(return_code != FTFx_OK) return;


    // erase flash
    return_code = CustomFlashEraseSector(&flash_config_stru,
                                         (UINT32)EepromStruct[eep_section].dst,
                                         (UINT32)EepromStruct[eep_section].size,
                                         (UINT32)EepromStruct[eep_section].sector_size);
    if(return_code != FTFx_OK) return;




    // write flash
    return_code =  CustomFlashProgramLongword(&flash_config_stru,
                                              (UINT32)EepromStruct[eep_section].dst,
                                              (UINT32)sizeof(RAM_UserBackUp) / sizeof(UINT8),
                                              (UINT32)RAM_UserBackUp);

}

Outcomes