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.

RM48 F021 V2.00.01 API Fapi_CheckFsmForReady() and Fapi_getFSMStatus issue.

Other Parts Discussed in Thread: RM48L950

Hi,

Wondering if someone can please help me.

I am writing to Bank 7 on the RM48L950 device.  I have followed the F021 V2.00.01 API exactly to the letter, however after issuing an ERASE SECTOR command and waiting for the FSM to become ready I get status bits = 0x0180 from the Fapi_getFsmStatus();

The two bits in question are "Busy" (bit 8) and "Erase Active" (bit 7).  Technically this is correct, but Fapi_CheckFsmForReady() should stay busy if the register Busy bit is set.

If I re-check the Fapi_getFsmStatus() a second later the bits are cleared and status = 0.

Can anyone suggest how to ensure the Fapi_CheckFsmForReady() should be used, and why it is not busy when the registers are busy.

For completeness my code is posted below.

Thanks

Stomp

Lint16 s16RM4_FLASH__SectorErase(Luint32 u32Bank, Luint32 u32Flash_Start_Address, Luint32 u32Size_In_Bytes, Luint32 u32Freq_In_MHz)
{
	Lint16 s16Status;
	Luint32 u32Status;
	Fapi_StatusType stReturn1;
	Fapi_StatusType stReturn1A;
	Fapi_StatusType stReturn2;
	Fapi_StatusType stReturn3;

	//set our status up early
	s16Status =  C_LCCM135__RETURN_TYPE__ERROR_GENERIC;

	stReturn1 = Fapi_initializeAPI((Fapi_FmcRegistersType *)0xfff87000, u32Freq_In_MHz);
	if(stReturn1 != Fapi_Status_Success)
	{
		//error
		s16Status = s16RM4_FLASH__F021ErorCode(stReturn1);

	}//if(stReturn1 != Fapi_Status_Success)
	else
	{
		//good to continue
		stReturn1A = Fapi_initializeFlashBanks(u32Freq_In_MHz);
		if(stReturn1A != Fapi_Status_Success)
		{
			//error
			s16Status = s16RM4_FLASH__F021ErorCode(stReturn1A);

		}//if(stReturn1A != Fapi_Status_Success)
		else
		{

			stReturn2 = Fapi_setActiveFlashBank((Fapi_FlashBankType)u32Bank);
			if(stReturn2 != Fapi_Status_Success)
			{
				//error
				s16Status = s16RM4_FLASH__F021ErorCode(stReturn2);

			}//if(stReturn2 != Fapi_Status_Success)
			else
			{
				//determine which sectors to enable
				if(u32Bank == 7)
				{
					/*This function sets up the sectors in the EEPROM banks that are available for erase and programming
					operations. This function must be called with the EEPROM bank (Flash Bank 7) as the active bank.
					Additionally, the function must be called once before performing program and sector erase operations and
					always before a bank erase operation. Each bit refers to a single sector with Sector 0 is bit 0 in
					u32SectorEnables_31_0 to Sector 31 is bit 31 in u32SectorEnables_31_0 and Sector 32 is bit 0 in
					u32SectorEnables_63_32 to Sector 63 is bit 31 in u32SectorEnables_63_32*/
					Fapi_enableEepromBankSectors(0xFFFFFFFF, 0xFFFFFFFF);
				}
				else
				{
					/*This function sets up the sectors in the non-EEPROM banks that are available for erase and programming
					operations. This function must be called with the bank intended for the erase or program operation as the
					active bank. Additionally, the function must be called once before performing program and sector erase
					operations and always before a bank erase operation. Each bit refers to a single sector where Sector 0 is
					bit 0 to Sector 15 is bit 15 in u16SectorEnables.*/
					Fapi_enableMainBankSectors(0xFFFF);
				}

				//wait ready before we issue the programming command
				while(Fapi_checkFsmForReady() == Fapi_Status_FsmBusy)
				{
				}

				//success
				stReturn3 = Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector, (Luint32 *)u32Flash_Start_Address);

				while(Fapi_checkFsmForReady() == Fapi_Status_FsmBusy)
				{
					//allowed to execute other code here
				}

				u32Status = Fapi_getFsmStatus();
				if(u32Status != 0)
				{
					//the device has simply failed
					s16Status = C_LCCM135__RETURN_TYPE__ERROR_DUT_FAILED;

				}//if(u32Status != 0)
				else
				{
					s16Status = s16RM4_FLASH__EraseCheck(u32Flash_Start_Address, u32Size_In_Bytes);

				}//else if(u32Status != 0)

			}//else if(stReturn2 != Fapi_Status_Success)

		}//else if(stReturn1A != Fapi_Status_Success)

	}//else if(stReturn1 != Fapi_Status_Success)

	//return with the status
	return s16Status;
}

  • Hello Stomp,

    I have couple of questions for you,

    1. Can you pls re-check if the right header files/compiler options are fed (_LITTLE_ENDIAN/_BIG_ENDIAN)

    2. Can you pls place a counter as shown below and let me know the count value as well ?

    				testCount = 0;
    				while(Fapi_checkFsmForReady() == Fapi_Status_FsmBusy)
    				{
    					testCount ++;
    				}
    
    				u32Status = Fapi_getFsmStatus();
    
    
    Best Regards,
    karthik.
  • Hi Karthik,

    I have never used any other mode than little endian, I am certain that the compiler option is set:

    And  looking into F021/registers.h and I find:

    Now if I use the Dump Pre-Processor defines to a text file  I get is

    #define __little_endian__ 1	/* Predefined */
    #define _LITTLE_ENDIAN

    Therefore confirming the device is in LE mode

    Thanks

  • Hi Stomp,

    Were you able to get the testcount as I suggested in previous post ?.

    That will give us a better idea. Thanks.

    Best Regards,

    Karthik.

  • Hi Karthik,

    Sorry it was approaching midnight last night.. :(

    Here is the results of the test.

    Below is my source code with the break-point set:

    And the results of the watch values.

    You can see that I modified the code to poll the status register.  It takes quite some time to return to zero.  Most interestingly tho, between the erase sector command and the wait for busy, there is NO incrementing.!

    Thanks

    Stomp!

  • Hello Stomp,

    Not sure if you have solved this already, but with the counter values you have given above, its very clear the register reads are not happening properly as expected in software.

    Since you are very sure about the little endian configuration, can you Pls send a snap shot of the dis-assembly code of the below snapshot, It should be mainly pertaining to the red-box shown below.

  • Hello,

    Sorry for the very late reply, I have been on another project.

    We still have the same problem as detailed above.

    Below is a screenshot of the dissam.  I am not sure why the "while (Fapi_checkFsmForReady() == Fapi_Status_FsmBusy)" appears twice, some compiler error?

    Any suggestions would be great as this is quite urgent now.

  • Hello Stomp,

    I see several issues with your usage of the F021 Flash API v2.0.1.

    1)  Fapi_initializeAPI() is not a v2.x function, but I do include a macro to provide backwards compatibility to v1.x API.  It has been replaced by Fapi_initializeFlashBanks().  Therefore you should not be calling both.

    2) Fapi_initializeFlashBanks() should only be called once in your application unless you change System frequency or RWAIT/EWAIT values.  It should not be called every time you are issuing an erase command.

    One question I have for you is what include file are you using in your code for the API?  You code snippet does not show this.

  • Hi John,

    Thanks very much for your information.

    I have now only used Fapi_initializeFlashBanks() in our routines.

    I have also tracked down the error we were seeing.  It is related to the file "registers.h" where at the top (line38) you include either the big or little endian includes based on the define "_LITTLE_ENDIAN".  In our setup "_LITTLE_ENDIAN" does not get included until way late in the compile process, maybe even in the linking step.

    I confirmed this by deleting the file "registers_fmc_be.h", which caused an include missing error.  It looks like this is a silent problem we were unaware of until our indepth verification.

    Whilst I appreciate your experience, a much better way to handle such things (if using defines) is to explicitly set defines such as :

    #if LITTLE_ENDIAN == 1

    #elif LITTLE_ENDIAN == 0

    #else

    #error

    #endif

    This way if something like this happens we won't get caught out.  In this instance our firmware was skipping the busy check because of the byte ordering of the defines of the registers.  Could have been much worse in production.

    Cheers

    Stomp.

  • Hello Stomp,

    You never answered the question on which API header file(s) you are specifically including in your code.  Based on your description of the problem, you are either using pre 2.x header file names or including multiple API head files directly.  In the 2.x version of the API, "F021.h" is the only header file that is directly included in user's code.   "F021.h" will determine which compiler is being used (CCS, IAR, GHS, ARM, gcc).  Once it has determined the compiler, it will then look at the compiler option defined macros to see if the code is being compiled in BE or LE and set the appropriate API macro (_BIG_ENDIAN, _LITTLE_ENDIAN).  After this is done, it will then choose the appropriate include file for the register definitions.

    It will error out if it cannot determine which compiler is being used, otherwise, the correct endianess macro by definition will always be set before any other API include files are called by the preprocesser.  If any other API header files are included in addition to/ or instead of "F021.h", you could see the issue you witnessed.