AnsweredAssumed Answered

How to use fsl_flash.c to implement flex nvm with flash EEPROM

Question asked by Ed Ablan on Dec 4, 2017
Latest reply on Dec 7, 2017 by Ed Ablan

All,

 

I am using the K64 FRDM board for some proof concept regarding the flex nvm setup for flash EEPROM and DFLASH. I couldn't find any demos or application notes on how to leverage this library code, but essentially started playing with it to get a working solution. I was finally able to get it to work, however have noticed some intermittent behavior for settings this up using the partition command. If i let the code run on its own, the flash EEPROM does not get properly setup, and stays at the default of no E-flash and only D-flash is used. However if I manually step through the FLASH_ProgramPartition() function, specifically into the flash_command_sequence(), and the callFlashRunCommand() function it E-flash and D-flash or properly partitioned and works as expected. Not sure what is going on here. I have intentionally turned off all interrupts during this just to make sure nothing will pull the rug from underneath the fsl_flash.c functions. Any help or even and app note that specifically details how to actually use this fsl_flash.c library with E-FLASH and D-FLASH.

 

It should be important to note, that I am using mbed cli to create the project and export to IAR.

 

Below is the code that shows what I've done:

 

 

 

#include "mbed.h"

#include "intrinsics.h"

#include "fsl_flash.h"

#include <stdio.h>
#include <errno.h>

#define MAX_STRING_SIZE    20

#define TEST_VALUE    0xB00B3 //721075

#define CALC_ADDR_END( start, var ) (start + sizeof( var ))

#define EEPROM_START    FSL_FEATURE_FLASH_FLEX_RAM_START_ADDRESS

typedef struct

{
   uint32_t test_var1;

   uint16_t test_var2;

   bool test_var3;

   uint8_t test_var4;

   uint16_t test_var5;

}

TestStruct1_t;

typedef struct

{

   uint8_t test_var1;

   char test_string1[MAX_STRING_SIZE];

   uint8_t test_var3;

}

TestStruct2_t; // Create global variable that is tied to flex_nvm memory space

__no_init uint32_t eeprom1_uint32          @ EEPROM_START;

#define E_UINT32_2               CALC_ADDR_END(EEPROM_START, eeprom1_uint32)

__no_init uint32_t eeprom2_uint32          @ E_UINT32_2;

#define E_TEST_STRUCT_1          CALC_ADDR_END(E_UINT32_2, eeprom2_uint32)

__no_init TestStruct1_t e_test_struct1     @ E_TEST_STRUCT_1;

#define E_TEST_STRUCT_2          CALC_ADDR_END(E_TEST_STRUCT_1, e_test_struct1)

__no_init TestStruct2_t e_test_struct2     @  E_TEST_STRUCT_2;

#pragma location="__flash"

const uint32_t test_var = 0;

flash_config_t flash_config;

template <class T, class U>

static status_t Copy_Mem_To_EEPROM(T *start, U *src, uint32_t num_bytes)

{

   return FLASH_EepromWrite(&flash_config, (uint32_t)start, (uint8_t*)src, num_bytes);

}

template <class T, class U>

static status_t Copy_Value_To_EEPROM(uint32_t *start, T src, uint32_t num_bytes)

{

   return FLASH_EepromWrite(&flash_config, (uint32_t)start, (uint8_t*)&src, num_bytes);

}

void flex_mem_demo(void)

{

   __disable_interrupt();

   TestStruct1_t p1;

   TestStruct2_t p2;

   // manually break and set the eeprom1_uint32 = 0 using the debugger

   // this allows the one time program partition to be run. Every other restart

   // instance from this point forward will only initialize and increment the

   // eeprom1_uint32 , but not repartition the Flex NVM. Enjoy

   if(eeprom1_uint32 == 0xFFFFFFFF)

   {

      FLASH_Init(&flash_config);

      FLASH_ProgramPartition(&flash_config,                kFLASH_PartitionFlexramLoadOptionLoadedWithValidEepromData, 0x32, 0x0B);

      FLASH_Init(&flash_config);

      Copy_Value_To_EEPROM(&eeprom1_uint32, TEST_VALUE, sizeof(eeprom1_uint32));

      p1.test_var1 = 1; //modify local parameter //now store in eeprom       Copy_Mem_To_EEPROM(&e_test_struct1.test_var1, &p1.test_var1,                            sizeof(e_test_struct1.test_var1));

   }

   else

   {

      FLASH_Init(&flash_config); p1.test_var1 =    e_test_struct1.test_var1 + 1;       Copy_Mem_To_EEPROM(&e_test_struct1.test_var1, &p1.test_var1,       sizeof(e_test_struct1.test_var1));

      Copy_Value_To_EEPROM(&eeprom1_uint32, (eeprom1_uint32 +    1), sizeof(eeprom1_uint32));

   }

   __enable_interrupt();

}

int main(void)

{

   device.baud(115200);

   flex_mem_demo();

   dflash_mem_demo();

   while(1);

}

Outcomes