This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TM4C129ENCPDT: FlashPBSave fails after 8 times

Part Number: TM4C129ENCPDT

With this code i am able to save to flash 8 times. 

#define FLASH_PB_START 0x000FF000

#define FLASH_PB_END 0x00100000

#define FLASH_PB_SIZE 512

FlashPBInit(FLASH_PB_START, FLASH_PB_END, FLASH_PB_SIZE);

After that the FlashPBSave returns on this line. 

// If every possible location has been checked and none are valid, then
// it will not be possible to write this parameter block. Simply
// return without writing it.
//
if((g_pui8FlashPBCurrent && (pui8New == g_pui8FlashPBCurrent)) ||
(!g_pui8FlashPBCurrent && (pui8New == g_pui8FlashPBStart)))
{
return;
}

I found this forum thread which describes my situation. I don't see a resolution.

Also, my code came from a working stellaris project that we ported to the new TIVA part. The only thing we changed were these 2 defines

#define FLASH_PB_START 0x000FF000

#define FLASH_PB_END 0x00100000

Anyone got any helpful hints where to go from here?

Also

  • To allow continuous updates of the parameter block, the FLASH_PB_START to FLASH_PB_END must span at least 2 erase blocks. On this device an erase block is 16KB. You only allocated 4KB, you need 32KB.
  • May we ask the "magic" - by which the "9th such effort" - meanders into "continuous updates?"      (that's a rather "naked" stretch - is it not?)

    We "get" the (8 x 512 = 4KB) - it is the (word choice) "continuous" which confounds...      

  • This is how it is done in the tivaware examples for the TMC129

    C:\ti\TivaWare_C_Series-2.1.4.178\examples\boards\dk-tm4c129x\qs_weather

    //*****************************************************************************
    //
    // Define the size of the flash program blocks for saving configuration data.
    //
    //*****************************************************************************
    #define FLASH_PB_START 0x40000
    #define FLASH_PB_END FLASH_PB_START + 0x4000

    My experiments after posting seem to work by moving FLASH_PB_START and FLASH_PB_END  away from the actual end of flash more like this example.

    I assume this TI example works with only 1 erase page.. 

  • Hi John,

    It does work with a single erase sector, however you run the risk that if power is lost (or the device is otherwise reset) while that page is being erased, then the data is lost. If you define the program block to cover at least two erase sectors, it will write the new data into the second sector before it erases the first sector.

  • I have your suggestion implemented as well as backing from the end of flash by 1 entire block.

    #define FLASH_BLOCK_SIZE 0x8000 // 32,768
    #define END_OF_FLASH 0x100000 // 1,048,576
    #define FLASH_PB_SIZE 512 // Our parameter block size
    #define FLASH_PB_END (END_OF_FLASH - FLASH_BLOCK_SIZE) // 1 Block buffer between the space we use and the actual end of flash
    #define FLASH_PB_START (FLASH_PB_END - FLASH_BLOCK_SIZE) // 1 Block buffer used for read/write parameters. 32,768/512 = 64
    #define NUM_WRITES_BEFORE_BLOCK_RESUED (FLASH_BLOCK_SIZE/FLASH_PB_SIZE) // 32,768/512 = 64


    I also wrote a test method to play with all this;

    #ifdef DEVELOPER

    static tConfigParameters g_TestParameters;
    tConfigParameters *g_pTestParameters = 0;

    void PerformFlashTest()
    {
    uint16_t i = 0;
    uint16_t numWriteFails = 0;
    uint16_t numReadFails = 0;
    uint8_t *pui8FlashPBBefore;
    uint8_t *pui8FlashPBAfter;
    g_TestParameters = g_sWorkingDefaultParameters;
    // Write all blocks
    for (i = 0; i < NUM_WRITES_BEFORE_BLOCK_RESUED*2; i++)
    {
    pui8FlashPBBefore = FlashPBGet();
    g_TestParameters.usLocationURLPort = i;
    FlashPBSave((uint8_t *)&g_TestParameters);
    pui8FlashPBAfter= FlashPBGet();
    if (pui8FlashPBBefore == pui8FlashPBAfter || pui8FlashPBAfter == 0)
    {
    numWriteFails++;
    }
    }
    // Read all blocks
    for (i = 0; i < NUM_WRITES_BEFORE_BLOCK_RESUED*2; i++)
    {
    g_pTestParameters = (tConfigParameters *)FlashPBGet();
    if(g_pTestParameters == 0)
    {
    numReadFails++;
    }
    }

    ConfigInit();
    }
    #endif

    This test passes now . Thanks for the quick and accurate answers.