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.

RM48L952: Unable to write to bank 7

Part Number: RM48L952
Other Parts Discussed in Thread: HALCOGEN

Hello,

Here is exactly same problem without solution
https://e2e.ti.com/support/microcontrollers/hercules/f/312/t/323571?tisearch=e2e-quicksearch&keymatch=PGV

So I get same PGV & CSTAT bits as mark of an error.

Erase to bank 7 looks to work (does not return error, cannot say anything else since bank is already erased so data does not change).

Bank0 & 1 erase & write works so flashAPI usage logic should be ok.

According to SPNU501G.pdf chapter 5.3 the only difference in bank7 should be using the different "enable bank function".

But then I looked how FEE driver has done it, and was surprised that for write command the FlashAPI is not used, FlashAPI is used only for Erase operation... Why it would not use FlashAPI since for other operations it uses it?


About EWAIT: tried also that FlashAPI macro, same results (also no register changes), and system.c sets correct EWAIT value (3) (using halcogen generated files) so there should not be any reason to call that macro if understood correctly...

Also tried 'Fapi_DataOnly' and also tried to write 0xFF, 0xFF data and all these fails.

I am trying to write 0xF0200000 address, (verified this from R0 register inside ram-function) so that should be valid EEPROM address (sector 0)

=========== CODE ================
#define USED_EEPROM_SECTORS 0x1  // TRIED ALSO 0xFFFF
        FAPI_RET_ON_ERROR( Fapi_initializeFlashBanks( HAL_u32SystemClockMHz() ) ); /* used for API Rev2.01 */
        FAPI_RET_ON_ERROR( Fapi_enableEepromBankSectors( USED_EEPROM_SECTORS, 0U ) );

        while( FAPI_CHECK_FSM_READY_BUSY == Fapi_Status_FsmBusy );
        FSM_STATUS_RET_ON_ERROR( FAPI_GET_FSM_STATUS );
        // this is in RAM
        FAPI_RET_ON_ERROR( tFapi_Program( (uint32*)u32Dst, (uint8*)u32Src, (uint32)u32Bytes) );

where tFapi_Program-function is:
// This code needs to be in RAM
#pragma location = "RAMCODE"
static Fapi_StatusType tFapi_Program( uint32* pu32dst, uint8* pu8src, uint32 u32bytes )
{
    FAPI_RET_ON_ERROR( Fapi_issueProgrammingCommand( pu32dst, pu8src, u32bytes, 0, 0, Fapi_AutoEccGeneration) );

    while( FAPI_CHECK_FSM_READY_BUSY == Fapi_Status_FsmBusy );
    FSM_STATUS_RET_ON_ERROR( FAPI_GET_FSM_STATUS ); ////// CODE GOES THIS FAR so API interface returns OK

    return Fapi_Status_Success;
}
========= END OF CODE ==========

Also generic question about Fapi_issueProgrammingCommand(), if it used as Fap_AutoEccGeneration, can only say 5 bytes to be given to API and inside api that will be 'filled' to 8 bytes or do I need give 8/16/32 byte array into where I copy 5 byte payload (leave other fields any data I want say 0xFF) and give length as 8/16/32? Understood  from 3.3.1 that most likely the autofill' is performed inside API (or least whole 8 bytes is automatically used in ECC calculation so only that 5 bytes can given to API meaning simultaneously that this residual data cannot be tried to write again since ECC has been already calculated over it.

  • Hello Jarrko,

    I am forwarding your question to Prathap so he can address it from the SW side. He should be able to narrow the reasons why it is not working and why it is done differently within the FEE driver.
  • Hi Jarkko,

    Attached is a simple program I did for Bank7 Erase and program. Hope this helps. I have the HALCoGen project too for reference.

    I assumed RM48x device. The code works fine in my bench board. I do not have the RM48 HDK board. 

    I tried to program 5byte payload as you asked in to Bank7 - Sector0.

    /cfs-file/__key/communityserver-discussions-components-files/312/1768.RM48_5F00_Bank7.zip

  • Hi,

    That indeed helped (made me confident that you will not need to enable FEE driver from HALCoGen since I disabled that from your project and your code still worked). Still took a while to spot such an obvious mistake in own code or maybe just because the mistake was so stupid.

    I missed 1 function call from bank7 handling (since I did that bank a bit differently than main banks handling)...
    FAPI_RET_ON_ERROR( Fapi_setActiveFlashBank( Fapi_FlashBank7 ) );

    --> with this change it works
            FAPI_RET_ON_ERROR( Fapi_initializeFlashBanks( HAL_u32SystemClockMHz() ) ); /* used for API Rev2.01 */
            FAPI_RET_ON_ERROR( Fapi_setActiveFlashBank( Fapi_FlashBank7 ) );
            FAPI_RET_ON_ERROR( Fapi_enableEepromBankSectors( USED_EEPROM_SECTORS, 0U ) );

    So Bank7 now works!

    Just now wondering what the broken erase command made or didn't made since after it FSM_STATUS was 0, most likely it didn't do anything but also didn't flag any errors...



  • Hi

    I do not have the source code of the library, but I they do not check for the Bank being active before issuing the command.
    So if you have called Erase without Bank7 being Active, the API will return success since it's a Async, it initiates a Erase command and comes out, but if you check "FAPI_GET_FSM_STATUS" it would have returned Erase Failure ( 0x00000400 in FMSTAT register)...
    I do have that check in my code I sent...
  • Will it show that erase failure if/when the bank is in "factory condition" (ie. already erased when giving that command)? Just asking to be sure that I do not have other bug in my code regarding FSM status checking...

    Since this was my erase code for bank7 (without that set bank line which I now added) - similar as programming version

    static uint8 u8Fapi_EepromBlockErase( uint32 u32Address )
    {
    uint8 u8Status = FLASH_EEPROM_ILLEGAL_SECTOR;

    if( bEepromValidArea( u32Address ) )
    {
    FAPI_RET_ON_ERROR( Fapi_initializeFlashBanks( HAL_u32SystemClockMHz() ) ); /* used for API Rev2.01 */
    ////FAPI_RET_ON_ERROR( Fapi_setActiveFlashBank( Fapi_FlashBank7 ) ); // missed from code
    FAPI_RET_ON_ERROR( Fapi_enableEepromBankSectors( USED_EEPROM_SECTORS, 0U ) );

    while( FAPI_CHECK_FSM_READY_BUSY == Fapi_Status_FsmBusy );
    FSM_STATUS_RET_ON_ERROR( FAPI_GET_FSM_STATUS );

    // this is in RAM
    FAPI_RET_ON_ERROR( tFapi_Erase( (uint32*)u32Address ) );

    u8Status = FLASH_OPER_OK;
    }

    return u8Status;
    }

    #pragma location = "RAMCODE"
    static Fapi_StatusType tFapi_Erase( uint32* pu32Sector )
    {
    FAPI_RET_ON_ERROR( Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector, pu32Sector) );

    while( FAPI_CHECK_FSM_READY_BUSY == Fapi_Status_FsmBusy );
    FSM_STATUS_RET_ON_ERROR( FAPI_GET_FSM_STATUS );

    return Fapi_Status_Success;
    }

    where
    #define FSM_STATUS_RET_ON_ERROR( status ) if( (status) != 0U ){ return (Fapi_Error_Fail); }
    and
    FLASH_OPER_OK = 0, // same as Fapi_Status_Success

    So this code return 0 and I also checked FSM_STATUS with debugger before exiting that erase function and it was 0...
  • Hi

    factory condition doesn't matter. The above code will work same way.

    Just curious, why are you executing Erase out of RAM? If it is only Bank7 you erasing you can do it from Bank 0.
    I understand logic of executing from RAM if you want to maintain common code and your application requires Bank0 and Bank7 sectors erases...
  • Sorry but cannot get your code either into that "erase fail" branch.

    First run original code so that sector0 was reseted then made small experiment

    After system reset tried to jump over that Fapi_setActiveFlashBank()-func by manipulating PC so that jumping from ...d8 to ..e0

    Tried to manipulate this code so that jumping PC from ...d8 to ...e0, then stopping code to ..e8 and writing r0=1, r1=0 (just to be s
    00004fd4: FA000206 blx Fapi_initializeFlashBanks
    00004fd8: E3A00007 mov r0, #7
    00004fdc: FA00029C blx Fapi_setActiveFlashBank
    00004fe0: E3E00000 mvn r0, #0
    00004fe4: E3E01000 mvn r1, #0
    00004fe8: FA000432 blx Fapi_enableEepromBankSectors

    Then stepped over and after erase command "FMdlStat" register == 0, meaning code does not enter into erase fail branch

    Then run code here
    program_status = Fapi_issueProgrammingCommand((uint32_t *)(0xf0200000U),
    &write_data[0],(0x5),0,0,Fapi_AutoEccGeneration);
    if(program_status != Fapi_Status_Success)

    And after that program command the content of 0xf0200000 does not change and "FMdlStat" register has value 0x00001010 meaning CSTAT & PGV == same as I got in my code


    With this experiment I would like to say that error is not flagged, at least your code behaved exactly like mine when skipping that bank selection.

    I'll think that this is enough for me the FSM status will not react in that use case thus most likely my error checking code is also ok...

    For curious question: yes, our bootloader is beginning of bank0 and it writes to bank0, bank1&bank7 that's why couple of (common) ram-functions (and API lib is also in ram).