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.

RM42: F021 trouble, Flash_BlockProgram

Hi guys,

I'm running a setup where an RM42 configured as SPI-slave gets a firmware image from the SPI-master. I'm writing the bootloader for the slave, and I'm using the F021 Flash API v. 1.51 on an RM42L43 platform. I've made some code that transfers an image through SPI and tries to write it to flash. I've used the bootloader examples from the wiki as my starting poing.

Sometimes however, what I try to write is not what ends up on the flash chip. When I receive a firmware-image, my program flow is like this:

1) Erase the area containing application code (only done once and for all relevant sectors)

2) Check that the erased area is all 1-bits

3) Write the transferred payload to the flash chip 16 bytes at a time

4) Read the written data from the flash 16 bytes at a time, compare the read-buffer to the write-buffer

Now what I see is, sporadically the write will go awry. What ends up on the flash chip is not what was in the buffer passed to Fapi_BlockProgram - I will typically see this error after a couple of writes and I see the first error quicker if I write to the chip with shorter intervals (transfer smaller chunks through SPI).

I'm using the API like QJ Wang describes in this post: http://e2e.ti.com/support/microcontrollers/hercules/f/312/t/277379.aspx

For Flash Erase:

Fapi_initializeAPI((Fapi_FmcRegistersType *)F021_CPU0_REGISTER_ADDRESS, Freq_In_MHz);

Fapi_setActiveFlashBank((Fapi_FlashBankType)ucBank);

Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector, eraseStartAddr);

status = Fapi_getFsmStatus();

status = Flash_Erase_Check((uint32_t)eraseStartAddr0, Size_In_Bytes);

For flash program:

Fapi_initializeAPI((Fapi_FmcRegistersType *)F021_CPU0_REGISTER_ADDRESS, Freq_In_MHz);

Fapi_setActiveFlashBank((Fapi_FlashBankType)Bank);

Fapi_issueProgrammingCommand((uint32_t *)dst,

status = Flash_Program_Check(Flash_Start_Address, Data_Start_Address, Size_In_Bytes);

 


I've sprinkled my code with assertions and error checks to narrow in on the source of the error. I am always succesful in erasing the chip and it is only the writing part that fails.

I'm running the code without an OS, in privilege mode, interrupts are disabled while writing/erasing and I'm running the Fapi-object code and the code that calls it from SRAM. System clock frequency is 100MHz (Freq_In_MHz) and I'm writing to flash address 0x10000 and forward (bank 0, sectors 8-14).

Any more info I should provide ?

Kind regards

/Mikkel

  • Mikkel,

    I do not see the following in your given examples:

    1)  A check to see if the Flash is busy (FMSTAT register busy bit) before continuing on to the next step. 

    2)  Checking the return values from the Flash API to see if they return an error.

    Also, the latest version of the F021 Flash API is v2.0.1 and is the recommended API version to use.  Please read the API reference guide version revision history to see differences between v1.51 and v2.0.1.

  • Hi John, and thanks for the very quick answer :)

    1) I've tried sprinkling a wait statement in between every API function call, like this:

    while( Fapi_checkFsmForReady() != Fapi_Status_FsmReady );

    ... but to no avail.

    2) I do check the return values, but the API functions return 0/Fapi_Status_Success - but when I do a manual read and compare of the data written, there are inconsistencies. 

    I think it may be related to some timing issues, as I see the first programming a lot earlier if I transfer small blocks at a time before writing (16 byte chunks instead of 256 bytes, for instance). But I can't imagine what could be wrong with the timing, since interrupts are turned off and I explicitly check for the FSM status (as you suggested 2) before continuing.

    If you think the issue could be resolved by switching to using version 2.0.1 instead of 1.51, I can try that :)

  • Hi Mikkel,

    I don't think v2.0.1 will solve the problem you are seeing, but all my examples nowadays are geared towards its interface.

    Another question, are your 16 byte writes aligned on 16byte address boundaries?

    One thing not mentioned in your original post is if you are pogramming the ECC, either by supplying the data or using AutoECC generation.

    Are you using the API blank and verify functions?  If not, you need to make sure you do a pipeline flush after programming and before reading the data locations in Flash.

    I would expect your flow to program say a 1kB buffer to be something like this (written generically for both versions of the API):

    At device power up:

       Initialize API/FlashBanks

    At program time:

       Set the Flash Bank to be written as active

       Enable sector(s) for programming/erase (required the first time.  v1.51 does this through user defined callback functions)

        Erase sectors/bank for data to be programmed to if needed (In your first post, you state you are erasing sectors 8-14 in bank 0.  This can be done with a single bank erase by enabling only those sectors leaving sectors 0-7 disabled)

        Wait for erase to finish

        Verify the erase sectors/bank are blank.

        Loop over the 1kB buffer, incrementing address for each pass by 16 bytes

        {

            Issue programming command for 16 bytes at current 16byte aligned address

            Wait for programming to finish

            Verify the 16bytes

        }

  • Thanks for the help John - I've got the flashing part working now. Flushing the pipeline before reading back the written data, did all the difference :)

    Thanks a bunch!