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.

TI Hercules RM48L952ZWT On-chip Flash

Other Parts Discussed in Thread: RM48L952, HALCOGEN, TMDSRM48HDK, CCSTUDIO, F021FLASHAPI

Hi,

  We are using the TI Hercules board with RM48L952ZWT. This board has 3MB of on-chip Flash.  We use  a lot of the Flash for our drivers, application etc. However, we wanted to either use the an internal flash bank dedicated for data storage, or reserve the last sector for our own data to be stored 3MB. We know that there is a 1000 cycle write/erase limit on the 3MB -- what about the other Flash bank mentioned (64KB?) how many erase/write cycles can we get?  How do we access this flash bank? HaCoGen 4.3.00 does not generate any functions to access the RM48 flash part. We downloaded the attacheduploaded here from TI, but there are some extern functions used that are missing. i.e., extern Fapi_StatusType Fapi_initializeFlashBanks(uint32_t u32HclkFrequency);

Was there are another zip file we should download from TI for reading/writing/erasing to flash we can incoroporate into our HalCoGen driver directory for the RM48L952?  Hereis the file we downloaded first: 3362.spna189.zip

Thank you

  • Hello:

    Data Flash (Bank 7) has a lifespan of 100,000 write/erase cycles and is intended to be used as an emulated EEPROM (FEE). HALCoGen does generate code to handle FEE, you can find the configuration under the FEE tab.

    Regards,

    Enrique
  • Hi Tammy,

    To perform any of the following In-System flash operations, Erase, Program and Verify you need to get and use the F021 Flash API: www.ti.com/.../f021flashapi

    Best Regards,
    Christian
  • Hi Enrique (and Christian). Thank you. I included the FEE drivers, and HalCoGen autogenerated a bunch of files (ti_fee....) including a file called Fapi_UserDefinedFunctions.c But it will not build in CCS because it is missing a file that HalCoGen did not autogenerate called F021.h. Is this the API that Christian is referring to that I must including the the CCS project with the missing code that HalCoGen did not autogenerate?
  • Hello:

    That file is part of Flash API mentioned by Christian. The FEE driver resides on top of F021 Flash API.

    Regards,

    Enrique
  • Hi Enrique and Christian. Thank you. We have extracted the F021 library now. We are using the RM48L952ZWT processor. There were a bunch of lib files installed (18 lib files): i.e.,

    F021_API_CortexR4_BE_..., F021_API_CortexR4_LE_...

    what do we actually need to be included in our CCS project for the TI processor we are using? Thank you again.
  • Hi Tammy,

    The library and source files are described in the flash API reference guide on page 8 and 9: 

    The RM48 you are using is a ARM Cortex-R4F, with a TCM flash interface, device using the Little Endian byte ordering.

    So, depending on your requirements, you got the choice of the following Libs:

    • F021_API_CortexR4_LE.lib
    • F021_API_CortexR4_LE_v3D16.lib
    • F021_API_CortexR4_LE_NDS.lib
    • F021_API_CortexR4_LE_v3D16_NDS.lib

    If you like to use the FPU of the CPU you should consider to use a Lib with v3D16 support.

    Best Regards,
    Christian

  • Hi Thank you Again. We included the  F021_API_CortexR4_LE_v3D16.lib.

    1. What is the difference between the F021_API_CortexR4_LE_v3D16.lib and the F021_API_CortexR4_LE_v3D16_NDS.lib?

    2. We started with the examples in SPNA148.pdf and copy pasted below for reading, writing and erasing a test byte to the Bank 7 64K Flash. In CCS debugger we can see in the memory browser and reading that after writing the byte it is in the memory location. But when we recycyle power, and read from the same Flash region, it is back to 0xFFFFFFFF, so it does not look like we actually wrote anything to Flash because after power cycle on Hercules board it should still be there as non-volatile memory.  Are we using the wrong example code in this pdf to test out reading/writing/erasing from flash? The pdf that came with the library is uplodaded here: 6320.SPNA148.pdf

    /* Local Functions Functions */

    void Flash_BSPEraseByte(void)

    {

    Fapi_StatusType oReturnCheck = Fapi_Status_Success;

    FwpWriteByteAccessorType * oFwpWriteByteAccessor = FWPWRITE_BYTE_ACCESSOR_ADDRESS;

    FwpWriteByteAccessorType * oFwpWriteEccByteAccessor = FWPWRITE_ECC_BYTE_ACCESSOR_ADDRESS;

    FwpWriteDWordAccessorType * oFwpWriteDWordAccessor = FWPWRITE_DWORD_ACCESSOR_ADDRESS;

    uint8 au8MainDataBuffer[16] = {0x78, 0x17, 0x19, 0x2E, 0x0A, 0xB9, 0x11, 0x70,

    0x5F, 0xC1, 0x9C, 0xFD, 0x54, 0x51, 0xED, 0x86};

    uint32 u32Index;

    /*

    For proper initialization of the device prior to any Flash

    operations,

    see the device-specific initialization document.

    Assumes, unless otherwise noted, device has 144bit wide Flash Banks.

    */

    oReturnCheck = Fapi_initializeFlashBanks(180); /* Example code is assuming operating

    frequency of 180 MHz */

    if((oReturnCheck == Fapi_Status_Success) && (Fapi_checkFsmForReady()!= Fapi_Status_FsmBusy))

    {

    oReturnCheck = Fapi_setActiveFlashBank(Fapi_FlashBank7);

    /* Place specific example code here */

    FLASH_CONTROL_REGISTER->Fbprot.u32Register = 1U; /* Disable Level 1 Protection */

    /* Enable all sectors of current bank for erase and program. For EEPROM banks with more

    than 16 sectors, this must be 0xFFFF */

    FLASH_CONTROL_REGISTER->Fbse.u32Register = 0xFFFF;

    FLASH_CONTROL_REGISTER->Fbprot.u32Register = 0U; /* Enable Level 1 Protection */

    /*Unlock FSM registers for writing */

    FLASH_CONTROL_REGISTER->FsmWrEna.u32Register = 0x5U;

    /* Set command to "Clear the Status Register" */

    FLASH_CONTROL_REGISTER->FsmCommand.FSM_COMMAND_BITS.FSMCMD = Fapi_ClearStatus;

    /* Execute the Clear Status command */

    FLASH_CONTROL_REGISTER->FsmExecute.FSM_EXECUTE_BITS.FSMEXECUTE = 0x15U;

    /* Write address to FADDR register. This address must be within the bank to be erased */

    FLASH_CONTROL_REGISTER->Faddr.u32Register = 0xF0200000U;

    /* Set command to "Program" */

    FLASH_CONTROL_REGISTER->FsmCommand.FSM_COMMAND_BITS.FSMCMD = Fapi_EraseSector;

    /* Execute the Program command */

    FLASH_CONTROL_REGISTER->FsmExecute.FSM_EXECUTE_BITS.FSMEXECUTE = 0x15U;

    /* re-lock FSM registers to prevent writing */

    FLASH_CONTROL_REGISTER->FsmWrEna.u32Register = 0x2U;

    /* Wait for FSM to finish */

    while(Fapi_checkFsmForReady() == Fapi_Status_FsmBusy);

    /* Check the FSM Status to see if there were no errors */

    if (FLASH_CONTROL_REGISTER->FmStat.u32Register != 0)

    {

    /* Put Error handling code here */

    sciSend (sciREG, 24, (unsigned char *) "\r\nERROR Erase FSM Status\r\n");

    }

    }

    }

    void Flash_BSPWriteByte(void)

    {

    volatile uint32_t u32ReadValue=0, u32Error=0;

    Fapi_StatusType oReturnCheck = Fapi_Status_Success;

    FwpWriteByteAccessorType * oFwpWriteByteAccessor = FWPWRITE_BYTE_ACCESSOR_ADDRESS;

    FwpWriteByteAccessorType * oFwpWriteEccByteAccessor = FWPWRITE_ECC_BYTE_ACCESSOR_ADDRESS;

    FwpWriteDWordAccessorType * oFwpWriteDWordAccessor = FWPWRITE_DWORD_ACCESSOR_ADDRESS;

    uint8 au8MainDataBuffer[16] = {0x78, 0x17, 0x19, 0x2E, 0x0A, 0xB9, 0x11, 0x70,

    0x5F, 0xC1, 0x9C, 0xFD, 0x54, 0x51, 0xED, 0x86};

    uint32 u32Index;

    /*

    For proper initialization of the device prior to any Flash

    operations,

    see the device-specific initialization document.

    Assumes, unless otherwise noted, device has 144bit wide Flash Banks.

    */

    oReturnCheck = Fapi_initializeFlashBanks(200); /* Example code is assuming operating frequency */

    if((oReturnCheck == Fapi_Status_Success) && (Fapi_checkFsmForReady() != Fapi_Status_FsmBusy))

    {

    oReturnCheck = Fapi_setActiveFlashBank(Fapi_FlashBank7);

    FLASH_CONTROL_REGISTER->Fbprot.u32Register = 1U; /* Disable Level 1 Protection */

    /* Enable all sectors of current bank for erase and program. For EEPROM banks with more

    than 16 sectors, this must be 0xFFFF */

    FLASH_CONTROL_REGISTER->Fbse.u32Register = 0xFFFF;

    FLASH_CONTROL_REGISTER->Fbprot.u32Register = 0U; /* Enable Level 1 Protection */

    /*Unlock FSM registers for writing */

    FLASH_CONTROL_REGISTER->FsmWrEna.u32Register = 0x5U;

    /* Set command to "Clear the Status Register" */

    FLASH_CONTROL_REGISTER->FsmCommand.FSM_COMMAND_BITS.FSMCMD = Fapi_ClearStatus;

    /* Execute the Clear Status command */

    FLASH_CONTROL_REGISTER->FsmExecute.FSM_EXECUTE_BITS.FSMEXECUTE = 0x15U;

    /* Write address to FADDR register */

    FLASH_CONTROL_REGISTER->Faddr.u32Register = 0xF0200000U;

    /* Placing byte at address 0x0102 */

    oFwpWriteByteAccessor[2] = 0xA5;

    /* Set command to "Program" */

    FLASH_CONTROL_REGISTER->FsmCommand.FSM_COMMAND_BITS.FSMCMD = Fapi_ProgramData;

    /* Execute the Program command */

    FLASH_CONTROL_REGISTER->FsmExecute.FSM_EXECUTE_BITS.FSMEXECUTE = 0x15U;

    /* re-lock FSM registers to prevent writing */

    FLASH_CONTROL_REGISTER->FsmWrEna.u32Register = 0x2U;

     

    /* Wait for FSM to finish */

    while(Fapi_checkFsmForReady() == Fapi_Status_FsmBusy);

    /* Check the FSM Status to see if there were no errors */

    if (FLASH_CONTROL_REGISTER->FmStat.u32Register != 0)

    {

    /* Put Error handling code here */

    sciSend (sciREG, 24, (unsigned char *) "\r\nERROR WRITE FSM Status\r\n");

    }

    }

    }

     

    void Flash_BSPReadByte(void)

    {

    uint32_t* pu32CurrentAddress=(uint32_t *)(0xF0200000);

    pu32CurrentAddress=(uint32_t *)(0xF0200000);

    if(*pu32CurrentAddress !=0xFFA5FFFF)

    {

    sciSend (sciREG, 15, (unsigned char *) "\r\nERROR FLASH READ\r\n");

    }

    }

  • Hi Enrique, Is there any update to my question?
  • Hi Tammy,

    The App Note SPNA148 you are referring to is for advanced F021 Flash programming. I would strongly recommend to start with the plain F021 Flash API instead and only go with the Advanced Programming if you figure that the plain API isn't sufficient for your needs.

    The usage of the API is described in the Reference Guide SPNU510 starting at chapter 5, the different library files are described in section 2.3.3.2.

    Best Regards,
    Christian
  • Hi Thank you. When we used the sample code that I had posted further up from SPNA148, it looked like it did something over the CCS debugger to the address 0xF02000000 (what we assumed to be the start of the EEPROM bank 7 of 64K), when we rebooted it was not the case. We could see in the debugger memory browser something changed.

    When we just wrote the write function from the SPNU510 (there was no test code example only) flow chart example, we get nothing happening even in the debugger. Is there any example code from TI at all for the use of these functions in SPNU510 we can start with to see that we can manipulate bank 7 via the FEE drivers?

    (see above for code from SPNA148 - which actually was in the app note in addition to flow charts)

    (no sample code from flowchart SPNU510, followed flow chart below but it did nothing)
    ..
    uint8_t au8MainDataBuffer[16] = {0x78, 0x17, 0x19, 0x2E, 0x0A, 0xB9, 0x11, 0x70, 0x5F, 0xC1, 0x9C, 0xFD, 0x54, 0x51, 0xED, 0x86};
    uint8_t au8EccDataBuffer[16];
    uint32_t pu32StartAddress;
    uint8_t *p1;
    uint8_t *eccp1;
    p1 = au8MainDataBuffer;
    eccp1 = au8EccDataBuffer;
    pu32StartAddress = 0xF0200000U;

    oReturnCheck = Fapi_initializeFlashBanks(200); /* Example code is assuming operating frequency */

    if((oReturnCheck == Fapi_Status_Success) && (Fapi_checkFsmForReady() != Fapi_Status_FsmBusy))
    {
    oReturnCheck = Fapi_setActiveFlashBank(Fapi_FlashBank7);
    oReturnCheck = Fapi_enableEepromBankSectors (0xF,0);
    while(Fapi_checkFsmForReady() == Fapi_Status_FsmBusy);

    if((oReturnCheck == Fapi_Status_Success) && (Fapi_checkFsmForReady() != Fapi_Status_FsmBusy))
    {
    oReturnCheck = Fapi_issueProgrammingCommand(&pu32StartAddress,
    p1,
    16,
    eccp1,
    16,
    Fapi_DataOnly);
    /* Wait for FSM to finish */
    while(Fapi_checkFsmForReady() == Fapi_Status_FsmBusy);

    if((oReturnCheck == Fapi_Status_Success) && (Fapi_checkFsmForReady() != Fapi_Status_FsmBusy))
    {
    /* Check the FSM Status to see if there were no errors */
    if (FLASH_CONTROL_REGISTER->FmStat.u32Register != 0)
    {
    /* Put Error handling code here */
    sciSend (sciREG, 24, (unsigned char *) "\r\nERROR Erase FSM Status\r\n");
    }
    }
    }
  • Hi Tammy,

    I don't have a example for the EEPROM Bank 7, I only have way over complicated examples for other aspects which aren't valid here.

    Your code looks ok to me, the flow seems to be correct, except one issue:

    uint32_t pu32StartAddress; --> Note, this isn't a pointer this is a normal variable, which will most likely be on the stack.

    ...

    pu32StartAddress = 0xF0200000U; --> Correct address.

    ...

    oReturnCheck = Fapi_issueProgrammingCommand(&pu32StartAddress, --> This will lead for the function to try to flash something to the eSRAM, which of course is not what you want.

    so correct should be:

    uint32_t *pu32StartAddress = (uint32_t *)(0xF0200000);

    ...

    oReturnCheck = Fapi_issueProgrammingCommand(&pu32StartAddress,
    p1,
    16,
    NULL,
    0,
    Fapi_AutoEccGeneration);

    Please note, that if you like to program the ECC bits separately, the size of the ECC vs. Data is one-eighth, or in other words 16 data Bytes do have two ECC Bytes associated.

    At this point in time I realized, that I could use and modify one of my existing F021 Flash API Projects to demonstrate this:

    8054.RM48 F021 API EEPROM 2015-04-01v2.zip

    Please note, that this is only an example and I can't guarantee for its correctness!

    The example was built and tested with: HALCoGen 4.02.00, F021FLASHAPI v2.01.01, CCSTUDIO 6.1.0, TI ARM CGT 5.2.3, TMDSRM48HDK, RM48L952 Rev. C

    Best Regards,
    Christian

    EDIT: Uploaded correct ZIP file

  • Hi Christian. Thank you. I just saw you updated to new code examples. So, the function works and during runtime in CCS memory browser I can see the flash location at 0xF0200000 is updated. But if I recycle power on the board, restart the debugger -- it is back to 0xFFFFFFFF (the changes were not permanent), which they should have been for non-volatile memory. So same behavior. Is there a missing step?

  • Hi Enrique, I was not sure if you or Christian is answering this. Christian posted new code examples with the APIs he recommended from the other pdf in the installation zip. So, his function works and during runtime in CCS memory browser I can see the flash location at 0xF0200000 is updated. But if I recycle power on the board, restart the debugger -- it is back to 0xFFFFFFFF (the changes were not permanent), which they should have been for non-volatile memory. So same behavior we we recycle power on the board, the data is not saved into Flash according to CCS memory browser. Is there a missing step?
  • Hi Christian. When we are using TI's CCS to start a debug session (and then our code is flashed onto the board). Is it possible that CCS is erasing Bank 7 in addition to the 3MB bank our code is in?
  • Hi Tammy,

    Yes, this is exactly what happens, by default CCS will erase the entire flash memory as soon as you load a new code to the target.

    To change this you have to go to the Project Settings --> Debug --> Flash Settings.

    The following screenshot show the dialog I'm referring to:

    You can see that I checked the Necessary Sectors Only option, by default Entire Flash is checked.
    So you have to either change this to Necessary Sectors Only or Selected Sectors Only (and choose the right sectors) to prevent CCS erasing Bank 7.

    Best Regards,
    Christian