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.

Problem with Fapi_doVerifyByByte()

Other Parts Discussed in Thread: TMS570LS3137, HALCOGEN

Hello TI Community,

I have a problem with the Flash API on TMS570LS3137 (the HDK kit). I am using the example code from the F021 Flash API (SPNU501G) for a single byte flash record and I try to verify whether it has been written correctly. For that purpose I used Fapi_doVerifyByByte(). 

Unfortunately, when I add the source code after the example code or before the FSM registers re-lock function, something really strange happens - my code cannot reach even the beginning - the Bank0 initialization.

Here is my code, after I have commented the problematic pieces with "////":

void main(void)
{

sciInit();

PutText(scilinREG, "\rPutText is working!\n");
sciDisplayText(scilinREG, (uint8_t *)"\rReally working\n", sizeof("\rReally working\n"));

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;

////Fapi_FlashStatusWordType oVerifyByByte;

////uint8_t cmp_buffer[3] = { 0xA5, 0xA5, 0xA5 };

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(160); /* Example code is assuming operating
frequency of 180 MHz */
if((oReturnCheck == Fapi_Status_Success) && (FLASH_CONTROL_REGISTER->FmStat.FMSTAT_BITS.BUSY != Fapi_Status_FsmBusy))
{
oReturnCheck = Fapi_setActiveFlashBank(Fapi_FlashBank0);
/* Place specific example code here */
PutText(scilinREG, "\rFlashBank0 set active\n");
/* Wait for FSM to finish */

while(FLASH_CONTROL_REGISTER->FmStat.FMSTAT_BITS.BUSY == 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 */
PutText(scilinREG, "\r\nFlash init ERROR\n");
}

else
{
PutText(scilinREG, "\r\nSeems like working\n");
}
}

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 = 0x0100U;

/* 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;

////oReturnCheck = Fapi_Error_Fail;
////oReturnCheck = Fapi_doVerifyByByte((uint8_t *)0x102U, 1, cmp_buffer, &oVerifyByByte);

////if(oReturnCheck == Fapi_Status_Success)
////{
//// PutText(scilinREG, "Byte written correctly");
////}
////else {PutText(scilinREG, "Byte NOT written correctly");}

/* re-lock FSM registers to prevent writing */
FLASH_CONTROL_REGISTER->FsmWrEna.u32Register = 0x2U;

while(1);
/* USER CODE END */
}

As I mentioned, I also tried to invoke the Fapi_doVerifyByByte() function after the whole example code, after the FSM lock - I did it with initialized Fapi_FlashStatusWordType, different cmp_buffer sizes  but the result was just the same.

My end goal is to write a byte, verify it, read it and erase it.

Thank you in advance.

Kind regards,

Varban

  • Hi Varban,

    Would it be possible to get your whole project - so I can run it and debug it? Would be better that way rather than having me maybe miss something in how you have the device initialization setup.
  • Hello Anthony,

    Thank you for you fast answer. I am using the Ethernet example project to which I have added a "Flash" folder with the FlashAPI.

    I am also attaching the whole Ethernet "master directory".
  • Oops, the file cannot be attached because of the size... I am sharing the link -  the "main" project is: Version 00.03.00

    from http://processors.wiki.ti.com/index.php/HALCoGen_Ethernet_Driver_and_lwIP_Integration_Demonstration

  • Thanks Varban,

    Sorry I didn't get to this post today. Will proiritize it for tomorrow though.
  • Okay, Anthony, no problem.

  • Hi Varbhan,

    I downloaded the .zip file above and it unzips to a TMS570LS31x folder with subdirectories Build-TMS570LS31x, Demo Executable, and HalCoGen-TMS570LS31x. It *looks* complete, is the project that you are having trouble with the one in the Build-TMS570LS31x folder?
  • Hi Varbhan,

    Ok so I kept going at it, and was able to rebuild the project and start a debug session after adjusting the include paths to point to my install directory for lwIP.

    I'm seeing a undefined instruction exception occur somewhere during this function call (to the library code which is not available in source form) ... Does that match what you see?

  • Hi Varbhan,

    Not sure if this will solve all your problems but at least it should get you to the 'next' problem ;)

    The issue with the call to Fapi_setActiveFlashBank(Fapi_FlashBank0) is that this call does more than just set a variable somewhere for use in later function calls - it operates on the flash bank putting it in another mode. In that mode, you can't execute from the flash - so this is one of the functions that cannot be executed from the same bank that it is operating on.

    If you just try changing the function call to Fapi_setActiveFlashBank(Fapi_FlashBank7) - you'll see that the call succeeds because you're then executing code from bank 0 but operating on bank 7 (different banks).

    If you want to operate from bank 0 you'll need to run from RAM as the F021 Flash API documentation discusses.

    I'm going to file a ticket though on the library documentation - it should be more clear about which functions cannot be called if you are executing from the same bank. It's a bit misleading in the flowchart too where it tells you to call this function for the 'current bank' - some people might think that current bank means the bank that you are currently executing from instead of the bank you currently want to operate on.

    EDIT:  For reference the ticket # filed on the flash API is SDOCM00114339

  • Hello Anthony,

    I will read the F021 documentation once again and apply your suggestions on the code.... after that I will get back to you with the results.

    Thank you very much for the detailed explanation.

    Best regards,

    Varban

  • Hello again,

    I have tested with  Fapi_setActiveFlashBank(Fapi_FlashBank7) - now I can properly work with Bank1 - that is fairly enough for our project.

    However, I still do not get the idea of the Fapi_setActiveFlashBank function. What do you mean by running bank 0 from RAM (this is also mentioned in the F021 API documentation but is not clear at all)?

    And what is happening in my case so that the Bank1 is operational, where is that Bank1 run from? I mean... what is the relationship between the RAM, the initialized Bank and the operational Bank(s)?

    Thanks again for your help!

    Best Regards,

    Varban

  • Hi Varban,

    If I said 'running bank 0 from RAM' this was incorrect.

    The accurate statement is that you cannot simultaneously execute from, and perform certain (most) F021 API functions on the same flash bank. Most of these operations will put the flash bank in a state that prevents normal program reads.

    So to operate on bank 0, you must copy the F021 Flash API into RAM and execute the API from RAM while the operations on bank 0 are underway.

    This is actually why we go to the expense of having a separate bank (bank 7) for EEPROM emulation. While the main flash bank would typically only be programmed in the production line or during a service call ... the EEPROM emulation area typically needs to be programmed while the application is running.

    Because we have a separate bank (bank 7) for EEPROM emulation - operating on this bank does not affect your ability to properly read from bank 0, avoiding the problems associated with relocating only critical areas of code to RAM for execution.