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.

RM48L530: FEE driver not writing to Flash after Software Reset

Part Number: RM48L530
Other Parts Discussed in Thread: HALCOGEN

Hi,

The TI FEE driver seems to not be able to write to the flash after a software reset.

We are using the TI FEE driver provided with HalcoGen v4.06 and using F021 Flash API v2.01.01. The FEE is setup in Halcogen for 1 block of 64 bytes, 2 virtual sectors.

Our bootloader uses the FEE to backup data from the RAM before the PBIST selftest and memoryInit is run. This takes place during startup (_c_int00() ) in our bootloader. The data is then read from FEE back into RAM before the real application is started by the bootloader.

If a fatal error occurs during the execution of our application, we write the error info to a no_init section of the RAM and cause a software reset (systemREG1->SYSECR |= 0x00008000).

The bootloader then starts up and runs the following after reset:

void _c_int00(void)
{
    SL_Init_R4Registers();

    SL_Init_StackPointers();

    ApplyErrata();

    // Initialize System - Clock, Flash settings with Efuse self check
    systemInit();

    // Workaround for Errata PBIST#4
    errata_PBIST_4();

// Init the FEE driver

 TI_Fee_Init();
 do
 {
  TI_Fee_MainFunction();
  Delay();
  Status=TI_Fee_GetStatus(0 );
 }
 while((Status != IDLE));

// Backup the RAM to the FEE

TI_Fee_WriteAsync( 1 , (uint8*) u32_pRamBackupDataStartAddress);
 do
 {
  TI_Fee_MainFunction();
  Delay();
  Status=TI_Fee_GetStatus(0 );
 }
 while((Status != IDLE));

////////////// Run Selftests Including PBIST ////////////////

///////////// Do memoryInit for RAM and Peripherals ///////////////////

// Init the FEE driver again because memoryInit erased all RAM

 TI_Fee_Init();
 do
 {
  TI_Fee_MainFunction();
  Delay();
  Status=TI_Fee_GetStatus(0 );
 }
 while((Status != IDLE));

// Restore the RAM from the FEE

TI_Fee_Read( 1, 0, (uint8*) u08_pDataBufferToRead, 64);
 do
 {
  TI_Fee_MainFunction();
  Delay();
  Status=TI_Fee_GetStatus(0 );
 }
 while((Status != IDLE));

///////////////////////////// Start Application /////////////////////////////////////////

When I do a cold start, or start via the debugger, I can see that the FEE is written correctly (by viewing the flash7 bank in the debugger). But if I cause a software reset, the RAM data is NOT written to the FEE. I also tried not using the TI FEE driver and just writing to the FLASH7 bank using the F021 Library  - this also gave issues ((FAPI_GET_FSM_STATUS != Fapi_Status_Success) is always false) when doing a software reset from the application.

Is there something I can do to prepare the flash driver properly to the same state as when a External reset/ Debuuger Reset / Poweron reset was the cause of reset? We really must backup the RAM data after a SWRST so that we can diagnose the cause in our application AFTER the PBIST and memoryInit was done in the bootloader.

Regards,

Chris

  • Hello Chris,

    When did you issue the SW reset? Did you get the correct data back using TI_Fee_Read(...) before issuing the SW reset?
  • Hi QJ

    The sequence is as follows:

    1. Bootloader Starts -> goto _c_int00
    2. Init FEE
    3. Write to FEE
    4. Selftests (PBIST etc.)
    5. Init FEE
    6. Read FEE
    7. Goto Real Application
    8. Real Application cause SW reset (Back to bootloader start)

    At step no.6 I read the contents of the FEE and they did not change (the contents of the RAM written to the FEE in step 3 is different than before, so a write must take place).

    As an experiment, I also tried the following:

    1. Bootloader Starts -> goto _c_int00
    2. Init FEE
    3. Write to FEE
    4. Selftests (PBIST etc.)
    5. Init FEE
    6. Read FEE
    8. Bootloader cause SW reset (Back to bootloader start)

    Now the FEE is written and the correct data is read. It seems like if my application causes the SW Reset, the state of the CPU is not the same (perhaps because the application sets up different values for clocks and peripherals) as when the Bootloader causes the SW reset (without ever starting the application).

    Is there something I can do after a SW reset to ensure the same state of the CPU/Flash module in both cases?

    Chris
  • Chris,

    I replied this post this morning, but it lost. Any way, can you please dry:

    1. after data write, call TI_Fee_GetJobResult(0);
    2. use TI_Fee_WriteSyn(..) instead of TI_Fee_WriteAsun(..)

    Since data is not written successfully in your first experiment code, I don't think this problem is related to SW reset.
  • Hi,

    I made the changes as you suggest, but still no data appears in the flash, but the JobResult = JOB_OK.

    If I step through the writing it appears to think that everything is fine and actually sends the data to the FAPI, but nothing is actually stored in the flash.

    I will dig deeper into the differences between the application configuration settings for the Flash and clocks vs. the Bootloader.

    for now I can see these differences (this setup is done the moment the real application starts):

      /*
      ** setup flash wait-states
      */
      flashWREG->FRDCNTL =((2U << 8U) /////////////// for bootloader this is (0 << 8)
                        | (1U << 4U) /////////////// for bootloader this is (0 << 4)
                        | 1U);   /* pipeline mode */ /////////////// for bootloader this is (0)

      /*
      ** Setup flash bank power modes
      */
      flashWREG->FBFALLBACK = ((SYS_SLEEP << 14U) /////////////// for bootloader this is (SYS_ACTIVE << 14U)
                            | (SYS_SLEEP << 12U)
                            | (SYS_SLEEP << 10U)
                            | (SYS_SLEEP << 8U)
                            | (SYS_ACTIVE << 6U) /////////////// for bootloader this is (SYS_SLEEP << 6U)
                            | (SYS_ACTIVE << 4U) /////////////// for bootloader this is (SYS_SLEEP << 4U)
                            | (SYS_ACTIVE << 2U)
                            |  SYS_ACTIVE);
      /*
      ** setup PLL
      */
      /** - Setup pll control register 1:
       *     - Setup reset on oscillator slip
       *     - Setup bypass on pll slip
       *     - Setup Pll output clock divider
       *     - Setup reset on oscillator fail
       *     - Setup reference clock divider
       *     - Setup Pll multiplier
       */
      systemREG1->PLLCTL1 = ( 0
                            | 0x20000000U
                            | ((1-1) << 24U) /////////////// for bootloader this is (1 << 24)
                            | ((8-1) << 16U)
                            | ((100-1) << 8U));

      /** - Setup pll control register 1
       *     - Enable/Disable frequency modulation
       *     - Setup spreading rate
       *     - Setup bandwidth adjustment
       *     - Setup internal Pll output divider
       *     - Setup spreading amount
       */
     systemREG1->PLLCTL2 = ( 0
                            | (255U << 22U)
                            | (0U << 12U) ////////////////for bootloader this is (7 << 12)
                            | ((4-1) << 9U) ////////////////for bootloader this is (2 - 1 << 9)
                            |  61U);

      /** @b Initialize @b Secondary Pll: */

      systemREG2->PLLCTL3 = (((4-1)<<29) |    //////////////for bootloader this is (2U - 1U) << 29U)
                           ((1-1)<<24)  |   /////////////// for bootloader this is (1 << 24)
                           ((8-1)<<16) |
                           ((100-1)<<8));

    Chris

  • Also alothough the jobResult is JOB_OK, in FMSTAT register the CSTAT and PGV bits are set.
  • Hi Chris,

    I will do a test later, then come back to you.