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.

TMS320F28075: Flash cannot erase programming after power-up

Part Number: TMS320F28075
Other Parts Discussed in Thread: C2000WARE

Hi team,

Here's some questions from the customer may need your help:

The F021 library version is 1.54 and has the capability to erase and reprogram certain sectors in the firmware for parameter saving, firmware upgrades, etc.

The current phenomenon is that using CCS to load the .out file and run it directly, FLASH erase programming is fine.

The same engineering of the same cmd and out files, once loaded using CCS and then powered back on by unplugging the emulator, the FLASH state becomes either unerasable or unprogrammable.

Check the return value of Fapi_getFsmStatus after erase, erase empty Sector returns 0x0810, erase unless empty Sector returns 0x0C10 according to FMSTAT Register Description: Spruhm9f document section 3.15.21.6

Three bits involving FMSTAT:

  • bit11 is reserved in documents A
  • bit10 EV indicates an error with the erase
  • Bit4 CSTAT indicates an error executing the command

The FLASH register in two cases:

```
#The FLASH control register is not erased when the FLASH is not erased by power-up again 
0x05F800 0200 0000 0000 0000 0000 0000 0000 0000
0x05F808 0000 0000 0000 0000 0000 0000 0000 0000
0x05F810 0000 0000 0000 0000 0000 0000 0000 0000
0x05F818 0000 0000 0000 0000 0000 0000 000F 0000
0x05F820 0003 0000 8001 0000 0001 0860 0000 0000
0x05F828 0000 0000 0000 0000 0000 0000 0000 0000
0x05F830 00FC 0000 55AA 0000 0000 0000 0000 0000
0x05F838 0000 0000 0000 0000 0000 0000 0000 0000
0x05F840 000B 0000 0055 00EB 0000 00DB 0000 000F
0x05F848 0716 0000 A000 0000 0004 0000 010A 0700
#Flash control register when CCS loads normal erase 
0x05F800 0200 0000 0000 0000 0000 0000 0000 0000
0x05F808 0000 0000 0000 0000 0000 0000 0000 0000
0x05F810 0000 0000 0000 0000 0000 0000 0000 0000
0x05F818 0000 0000 0000 0000 0000 0000 000F 0000
0x05F820 0003 0000 8001 0000 0001 0860 0000 0000
0x05F828 0000 0000 0000 0000 0000 0000 0000 0000
0x05F830 00FC 0000 0000 0000 0000 0000 0000 0000
0x05F838 0000 0000 0000 0000 0000 0000 0000 0000
0x05F840 000B 0000 008C 01E9 0000 01BE 0000 0000
0x05F848 071B 0000 9000 0000 0004 0000 010A 0700
```

The registers listed in the document do not have any obvious errors, but there are some different addresses that are not described in the document. The customer would like to know how to further diagnose this problem?

FlashAPI and other FLASH-related code are in SRAM, only FLASH does not erase programming properly after power-up, and other firmware functions are fine, including FLASH reads. Before using F28075, the same code was used on the F280049 without any problems. This time just replaced the FlashAPI, which is very similar but not exactly the same.

Could you help check this case? Thanks.

Best Regards,

Cherry

  • I'm the customer, please give me some hints, thanks.

  • Hi Xiao,

    Sorry for the delay in response.  This is assigned to me today.  

    Can you check whether EALLOW is enabled before the flash API function calls or not?  F2807x API V1.54 needs the application to call EALLOW/EDIS as needed. F280049 does not need EALLOW to be called. 

    Thanks and regards,

    Vamsi

  • Hi Vamsi,

    Thanks for your support here! Due to some limitations, they cannot go on here directly, so I will keep on updating here.

    Can you check whether EALLOW is enabled before the flash API function calls or not?

    Yes, they do enable the EALLOW.

    As we mentioned before, they load the .out file with CCS and run it directly, FLASH erase programming is all working well. Without EALLOW/EDIS, CCS should not load directly, is that right?

    Thanks and Best Regards,

    Cherry

  • Cherry,

    CCS flash load happens due to the CCS flash plugin (it is developed by us).

    I am asking about the user application's usage of the flash API.  Please check and let me know.

    Thanks and regards,
    Vamsi

  • Hi Vamsi,

    Thanks for your clarification, I will check with the customer and please expect the modified updates.

    Thanks and regards,

    Cherry

  • Hi Vamsi,

    Here's some clarification:

    Erase flash is when the program is run after the ccs has loaded the program, and then the SCIA is connected to the chip, and a command is entered to erase it. This erase command is executed when the ccs is already loaded. However, the scs are finished loading the same .out firmware, and the erase command cannot be executed after power-up is re-applied. The application adds EALLOW and EDIS to flash API access.

    The following functions are used to initialize the FlashAPI and erase sectors, with EALLOW and EDIS added:

    #pragma CODE_SECTION(InitFlashAPI,".TI.ramfunc");
    Fapi_StatusType InitFlashAPI(void)
    {
    	Fapi_StatusType st = Fapi_Status_Success;
    
    	EALLOW;
    
    	// using INTOSC2,PLL clock frequency 120M,120*1.03 = 123.6,take 124
    	st = Fapi_initializeAPI(F021_CPU0_BASE_ADDRESS, 124);
    	if (st != Fapi_Status_Success)
    	{
    		return st;
    	}
    
    	st = Fapi_setActiveFlashBank(Fapi_FlashBank0);
    	if (st != Fapi_Status_Success)
    	{
    		return st;
    	}
    
    	EDIS;
    
    	return st;
    }
    
    
    #pragma CODE_SECTION(eraseFlashSector,".TI.ramfunc");
    Uint32 eraseFlashSector(Uint16 sector)
    {
    	Fapi_StatusType st;
    	Fapi_FlashStatusType fst;
    	Uint32 addr = 0;
    
    	if(sector < 'a' || sector > 'n')
    	{
    		return 0;
    	}
    
    	addr = flashSectorStart[sector - 'a'];
    
    	EALLOW;
    	st = Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector, (uint32*)addr);
    	while (Fapi_checkFsmForReady() != Fapi_Status_FsmReady)
    	{
    		KickDog();
    	}
    	// FLASH0CTRL_BASE = 0x05F800 FMSTAT Offset 0x2A 
    	//FMSTAT Register Description: Section 3.15.21.6 of the spruhm9f document 
    	// Erasing empty Sector returns 0x0810, erasing non-empty Sector returns 0x0C10 
    	fst = Fapi_getFsmStatus();
    	EDIS;
    
    	if(st != Fapi_Status_Success || fst != 0)
    	{
    		addr = 0;
    		printx("st=0x____ ", st);
    		printx("fst=0x________\r\n", fst);
    	}
    
    	return addr;
    }

    Please let e know if these info helps. Thanks.

    Best Regards,

    Cherry

  • Cherry,

    I will review and get back to you in a day.

    Thanks and regards,

    Vamsi

  • Cherry,

    Is the device secured before the erase operation?

    When it fails to erase from the above code, you mentioned CCS flash plugin is able to erase successfully - correct?

    Thanks and regards,

    Vamsi

  • Hi Vamsi,

    Is the device secured before the erase operation?

    No, the device is not secured.

    When it fails to erase from the above code, you mentioned CCS flash plugin is able to erase successfully - correct?

    Correct.

    Thanks and regards,

    Cherry

  • Cherry,

    Thank you for the info.

    Can customer try the flash programming example from C2000Ware and see whether it is able to erase the flash successfully or not?  This helps us to know whether it is code problem or something else.

    Thanks and regards,

    Vamsi

  • Hi Vamsi,

    Can customer try the flash programming example from C2000Ware and see whether it is able to erase the flash successfully or not? 

    Yes, they have tried and it's working well.(C2000Ware_4_00_00_00\device_support\f2807x\examples\cpu1\flash_programming\cpu01)

    Thanks and regards,

    Cherry

  • Cherry,

    In that case, I feel it is their code issue.  

    Can you send a project that I can build and run on my side?  Please remove all the proprietary info.

    Thanks and regards,
    Vamsi

  • Hello Vamsi,

    Thanks for your help again. But feel sorry that due to some reasons, they can not provide the project. Can we find other ways?

    And here's some feedback from the customer: the 280049 and 28075 chips are the third generation C28x, FLASH is both NAND and both have ECC, and the FlashAPI is both the F021 library. However one is  the library to manage EALLOW/EDIS, while the other one is to let the customer to manage EALLOW/EDIS. For customer this may not so convenience. 

    Thanks and regards,

    Cherry

  • Cherry,

    We used to share our code with other non-C2000 teams that use the same flash wrapper.  And those teams requested us to not include core-specific content in the flash API.  Hence, we did not include EALLOW/EDIS previously.  Later, we decided to include EALLOW/EDIS during F28004x timeframe to reduce that extra work for the users.

    Regarding the project sharing: Ok, if they are not able to share it, may be they can compare their application to that of our flash API programming example in the C2000Ware?

    Also, search for "What are the common debug tips that we can consider when Flash API fails to erase or program?" in this FAQ: https://e2e.ti.com/support/microcontrollers/c2000/f/171/t/951668 

    Thanks and regards,
    Vamsi

  • Hello Vamsi,

    Thanks! 

    The same .out target file, run directly with ccs load in, erases FLASH normally, but cannot be erased after power-up again. And if burn the .out file with a third-party tool like C2Prog, and run it directly after the burn is complete without powering down,  can't erase FLASH either. So it's obvious that the ccs did some extra work when the target file was loaded. The customer would like to know what extra work it does to erase FLASH.

    The OnReset() function in F28075.gel has a SetupDCSM() to configure cryptographic module DCSM which may relate to encryption, and the ccs load can still be erased properly after removal, which means that the DCSM is not very relevant.

    Is there additional work required to ensure FLASH erasable in cases where the customer's engineering is not encrypted using DCSM?

    If DCSM is not used for encryption, is it necessary to call DCSM_unlockZone1CSM() to decrypt with full FF password during initialization?

    Regarding the project sharing

    Here's the HAL.c file, which includes the initialization of the function:

    #include <hal.h>
    
    //*****************************************************************************
    //
    // Function to initialize the device. Primarily initializes system control to a
    // known state by disabling the watchdog, setting up the SYSCLKOUT frequency,
    // and enabling the clocks to the peripherals.
    //
    //*****************************************************************************
    void Device_init(void)
    {
    	SysCtl_disableWatchdog();
    
    #ifdef _FLASH
    	//
    	// Copy time critical code and flash setup code to RAM. This includes the
    	// following functions: InitFlash();
    	//
    	// The RamfuncsLoadStart, RamfuncsLoadSize, and RamfuncsRunStart symbols
    	// are created by the linker. Refer to the device .cmd file.
    	//
    	//memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t) &RamfuncsLoadSize);
    #endif
    
    	//
    	// Set up PLL control and clock dividers
    	//
    	SysCtl_setClock(DEVICE_SETCLOCK_CFG);
    
    	//
    	// Make sure the LSPCLK divider is set to the default (divide by 4)
    	//
    	SysCtl_setLowSpeedClock(SYSCTL_LSPCLK_PRESCALE_4);
    
    	//
    	// These asserts will check that the #defines for the clock rates in
    	// device.h match the actual rates that have been configured. If they do
    	// not match, check that the calculations of DEVICE_SYSCLK_FREQ and
    	// DEVICE_LSPCLK_FREQ are accurate. Some examples will not perform as
    	// expected if these are not correct.
    	//
    	ASSERT(SysCtl_getClock(DEVICE_OSCSRC_FREQ) == DEVICE_SYSCLK_FREQ);
    	ASSERT(SysCtl_getLowSpeedClock(DEVICE_OSCSRC_FREQ) == DEVICE_LSPCLK_FREQ);
    
    	//
    	// Call Flash Initialization to setup flash waitstates. This function must
    	// reside in RAM.
    	//
    	Flash_initModule(FLASH0CTRL_BASE, FLASH0ECC_BASE, DEVICE_FLASH_WAITSTATES);
    
    	//
    	// Turn on all peripherals
    	//
    	Device_enableAllPeripherals();
    }
    
    //*****************************************************************************
    //
    // Function to turn on all peripherals, enabling reads and writes to the
    // peripherals' registers.
    //
    // Note that to reduce power, unused peripherals should be disabled.
    //
    //*****************************************************************************
    void Device_enableAllPeripherals(void)
    {
    #if 1
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TIMER0);
    
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SCIA);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SCIB);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SCIC);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SCID);
    #else
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CLA1);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_DMA);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TIMER0);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TIMER1);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TIMER2);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_HRPWM);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
    
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EMIF1);
    
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM1);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM2);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM3);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM4);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM5);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM6);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM7);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM8);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM9);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM10);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM11);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM12);
    
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_ECAP1);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_ECAP2);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_ECAP3);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_ECAP4);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_ECAP5);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_ECAP6);
    
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EQEP1);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EQEP2);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EQEP3);
    
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SD1);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SD2);
    
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SCIA);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SCIB);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SCIC);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SCID);
    
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SPIA);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SPIB);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SPIC);
    
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_I2CA);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_I2CB);
    
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CANA);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CANB);
    
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_MCBSPA);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_MCBSPB);
    
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_USBA);
    
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_ADCA);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_ADCB);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_ADCD);
    
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CMPSS1);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CMPSS2);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CMPSS3);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CMPSS4);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CMPSS5);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CMPSS6);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CMPSS7);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CMPSS8);
    
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_DACA);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_DACB);
    #endif
    }
    
    //*****************************************************************************
    //
    // Function to disable pin locks and enable pullups on GPIOs.
    //
    //*****************************************************************************
    void Device_initGPIO(void)
    {
    
    }
    
    #pragma CODE_SECTION(InitFlashAPI,".TI.ramfunc");
    Fapi_StatusType InitFlashAPI(void)
    {
    	Fapi_StatusType st = Fapi_Status_Success;
    
    	EALLOW;
    
    	// 使用INTOSC2,PLL主频120M,120*1.03 = 123.6,取124
    	st = Fapi_initializeAPI(F021_CPU0_BASE_ADDRESS, 124);
    	if (st != Fapi_Status_Success)
    	{
    		return st;
    	}
    
    	st = Fapi_setActiveFlashBank(Fapi_FlashBank0);
    	if (st != Fapi_Status_Success)
    	{
    		return st;
    	}
    
    	EDIS;
    
    	return st;
    }
    
    // sector = a-n
    #pragma CODE_SECTION(eraseFlashSector,".TI.ramfunc");
    Uint32 eraseFlashSector(Uint16 sector)
    {
    	Fapi_StatusType st;
    	Fapi_FlashStatusType fst;
    	Uint32 addr = 0;
    
    	if(sector < 'a' || sector > 'n')
    	{
    		return 0;
    	}
    
    	addr = flashSectorStart[sector - 'a'];
    
    	EALLOW;
    	st = Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector, (uint32*)addr);
    	while (Fapi_checkFsmForReady() != Fapi_Status_FsmReady)
    	{
    		KickDog();
    	}
    	// FLASH0CTRL_BASE = 0x05F800 FMSTAT偏移量0x2A
    	// FMSTAT寄存器描述:spruhm9f文档的3.15.21.6节
    	// 擦除空Sector返回0x0810,擦除非空Sector返回0x0C10
    	fst = Fapi_getFsmStatus();
    	EDIS;
    
    	if(st != Fapi_Status_Success || fst != 0)
    	{
    		addr = 0;
    		printx("st=0x____ ", st);
    		printx("fst=0x________\r\n", fst);
    	}
    
    	return addr;
    }
    
    //*****************************************************************************
    //
    // Error handling function to be called when an ASSERT is violated
    //
    //*****************************************************************************
    #pragma CODE_SECTION(__error__,".TI.ramfunc");
    void __error__(char *filename, uint32_t line)
    {
    	//
    	// An ASSERT condition was evaluated as false. You can use the filename and
    	// line parameters to determine what went wrong.
    	//
    	ESTOP0;
    }
    
    // initCPUTimers - This function initializes all three CPU timers
    // to a known state.
    void initCPUTimers(void)
    {
    	//
    	// Initialize timer period to maximum
    	//
    	CPUTimer_setPeriod(CPUTIMER0_BASE, 0xFFFFFFFF);
    	CPUTimer_setPeriod(CPUTIMER1_BASE, 0xFFFFFFFF);
    	CPUTimer_setPeriod(CPUTIMER2_BASE, 0xFFFFFFFF);
    
    	//
    	// Initialize pre-scale counter to divide by 1 (SYSCLKOUT)
    	//
    	CPUTimer_setPreScaler(CPUTIMER0_BASE, 0);
    	CPUTimer_setPreScaler(CPUTIMER1_BASE, 0);
    	CPUTimer_setPreScaler(CPUTIMER2_BASE, 0);
    
    	//
    	// Make sure timer is stopped
    	//
    	CPUTimer_stopTimer(CPUTIMER0_BASE);
    	CPUTimer_stopTimer(CPUTIMER1_BASE);
    	CPUTimer_stopTimer(CPUTIMER2_BASE);
    
    	//
    	// Reload all counter register with period value
    	//
    	CPUTimer_reloadTimerCounter(CPUTIMER0_BASE);
    	CPUTimer_reloadTimerCounter(CPUTIMER1_BASE);
    	CPUTimer_reloadTimerCounter(CPUTIMER2_BASE);
    }
    
    // configCPUTimer - This function initializes the selected timer to the
    // period specified by the "freq" and "period" parameters. The "freq" is
    // entered as Hz and the period in uSeconds. The timer is held in the stopped
    // state after configuration.
    void configCPUTimer(uint32_t cpuTimer, float freq, float period)
    {
    	uint32_t temp;
    
    	//
    	// Initialize timer period:
    	//
    	temp = (uint32_t) (freq / 1000000 * period);
    	CPUTimer_setPeriod(cpuTimer, temp);
    
    	//
    	// Set pre-scale counter to divide by 1 (SYSCLKOUT):
    	//
    	CPUTimer_setPreScaler(cpuTimer, 0);
    
    	//
    	// Initializes timer control register. The timer is stopped, reloaded,
    	// free run disabled, and interrupt enabled.
    	// Additionally, the free and soft bits are set
    	//
    	CPUTimer_stopTimer(cpuTimer);
    	CPUTimer_reloadTimerCounter(cpuTimer);
    	CPUTimer_setEmulationMode(cpuTimer,
    			CPUTIMER_EMULATIONMODE_STOPAFTERNEXTDECREMENT);
    	CPUTimer_enableInterrupt(cpuTimer);
    }
    
    
    #pragma CODE_SECTION(DELAY_MS,".TI.ramfunc");
    void DELAY_MS(Uint16 n)
    {
    	while(n--)
    	{
    		KickDog();
    		DEVICE_DELAY_US(500);
    		KickDog();
    		DEVICE_DELAY_US(500);
    	}
    }
    
    #pragma CODE_SECTION(SystemReset,".TI.ramfunc");
    void SystemReset(void)
    {
    	SysCtl_resetDevice();
    }
    
    const Uint32 flashSectorStart[14] =
    {
    	0x080000, 0x082000, 0x084000, 0x086000,
    	0x088000, 0x090000, 0x098000, 0x0A0000, 0x0A8000, 0x0B0000,
    	0x0B8000, 0x0BA000, 0x0BC000, 0x0BE000
    };
    const Uint32 flashSectorSize[14] =
    {
    	0x2000, 0x2000, 0x2000, 0x2000,
    	0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
    	0x2000, 0x2000, 0x2000, 0x2000,
    };
    
    #pragma CODE_SECTION(isFlashEmpty,".TI.ramfunc");
    Uint32 isFlashEmpty(Uint32 start, Uint32 len)
    {
    	Fapi_FlashStatusWordType fswt;
    	Fapi_StatusType st;
    
    	EALLOW;
    	st = Fapi_doBlankCheck((Uint32 *)start, len>>1, &fswt);
    	EDIS;
    
    	if(Fapi_Status_Success == st)
    	{
    		return 0;
    	}
    	else
    	{
    		return fswt.au32StatusWord[0];
    	}
    }
    
    //
    // Fapi_serviceWatchdogTimer - Watchdog servicing function
    //
    #pragma CODE_SECTION(Fapi_serviceWatchdogTimer,".TI.ramfunc");
    Fapi_StatusType Fapi_serviceWatchdogTimer(void)
    {
       //
       // User to add their own watchdog servicing code here
       //
       KickDog();
       return(Fapi_Status_Success);
    }
    
    //
    // Fapi_setupEepromSectorEnable - Enables EEPROM sectors for bank and sector
    //                                erase
    //
    #pragma CODE_SECTION(Fapi_setupEepromSectorEnable,".TI.ramfunc");
    Fapi_StatusType Fapi_setupEepromSectorEnable(void)
    {
       //
       // Value must be 0xFFFF to enable erase and programming of the
       // EEPROM bank, 0 to disable
       //
       Fapi_GlobalInit.m_poFlashControlRegisters->Fbse.u32Register = 0xFFFF;
    
       //
       // Enables sectors 32-63 for bank and sector erase
       //
       FAPI_WRITE_LOCKED_FSM_REGISTER(Fapi_GlobalInit.m_poFlashControlRegisters->FsmSector.u32Register,
                                      0x0U);
    
       //
       // Enables sectors 0-31 for bank and sector erase
       //
       FAPI_WRITE_LOCKED_FSM_REGISTER(Fapi_GlobalInit.m_poFlashControlRegisters->FsmSector1.u32Register,
                                      0x0U);
    
       //
       // Enables sectors 32-63 for bank and sector erase
       //
       FAPI_WRITE_LOCKED_FSM_REGISTER(Fapi_GlobalInit.m_poFlashControlRegisters->FsmSector2.u32Register,
                                      0x0U);
    
       return(Fapi_Status_Success);
    }
    
    //
    // Fapi_setupBankSectorEnable - Setup and enable bank sectors 0-15
    //
    #pragma CODE_SECTION(Fapi_setupBankSectorEnable,".TI.ramfunc");
    Fapi_StatusType Fapi_setupBankSectorEnable(void)
    {
       //
       // Enable sectors 0-15 for erase and programming
       //
       Fapi_GlobalInit.m_poFlashControlRegisters->Fbse.u32Register = 0xFFFF;
       FAPI_WRITE_LOCKED_FSM_REGISTER(Fapi_GlobalInit.m_poFlashControlRegisters->FsmSector.u32Register,
                                      0x0U);
    
       return(Fapi_Status_Success);
    }

    Main.c operation logic:

    #include <hal.h>
    #include <string.h>
    #include <stdlib.h>
    #include <stdint.h>
    #include <stdio.h>
    #include "main.h"
    #include "syscall.h"
    #include "util.h"
    
    
    void main(void)
    {
    //	CopyLibrary();
    	Device_init();
    	Device_initGPIO();
    	InitFlashAPI();
    	EEPROM_Init();
    	EEPROM_Load();
    	initCPUTimers();
    	configCPUTimer(CPUTIMER0_BASE, DEVICE_SYSCLK_FREQ, 10000);	// 10ms sysTick
    	Interrupt_initModule();
    	Interrupt_initVectorTable();
    	InitSystem();
    	Run();
    }
    
    void InitSystem(void)
    {
    	BOOL isSave = FALSE;
    
    	Interrupt_register(INT_TIMER0,  &cpuTimer0ISR);
    	Interrupt_enable(INT_TIMER0);
    
    	Interrupt_enableInCPU(INTERRUPT_CPU_INT1);
    	Interrupt_enableInCPU(INTERRUPT_CPU_INT8);
    	Interrupt_enableInCPU(INTERRUPT_CPU_INT9);
    
    	EINT;
    	ERTM;
    
    	if(isSave)
    	{
    		EEPROM_Save();
    	}
    }
    
    #pragma CODE_SECTION(CleanUp,".TI.ramfunc");
    void CleanUp(void)
    {
    //	DeInitECana();
    	CPUTimer_stopTimer(CPUTIMER0_BASE);
    	__disable_interrupts();
    	SysCtl_disableWatchdog();
    }
    
    #pragma CODE_SECTION(Run,".TI.ramfunc");
    void Run(void)
    {
    	BOOL isRunUserApp = TRUE;
    
    	LED_ON();
    	CPUTimer_startTimer(CPUTIMER0_BASE);
    
    	SysCtl_setWatchdogPrescaler(SYSCTL_WD_PRESCALE_64);
    	SysCtl_enableWatchdog();
    
    	while(TRUE)
    	{
    		tskSyscall(&scia);
    		tskSyscall(&scib);
    		tskSyscall(&scic);
    		KickDog();
    	}
    }
    
    #pragma CODE_SECTION(cpuTimer0ISR,".TI.ramfunc");
    __interrupt void cpuTimer0ISR(void)
    {
    	ymodem.timeout++;
    	sysTickTimer++;
    	if(sysTickTimer > 50)
    	{
    		LED_SET(sysTickTimer&0x40);
    	}
    	Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1);
    }
    
    // SCIA
    #pragma CODE_SECTION(sciaRxISR,".TI.ramfunc");
    __interrupt void sciaRxISR(void)
    {
    	CONSOLE_REGS *sci = &scia;
    	if(UART_SCIA == (consoleMask & UART_SCIA))
    	{
    		if((HWREGH(sci->iface.sci + SCI_O_RXST) & SCI_RXST_RXRDY) == SCI_RXST_RXRDY)
    		{
    			consoleUsed = UART_SCIA;
    		}
    		tskRecvSciData(sci);
    	}
    	Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
    }
    
    // SCIB
    #pragma CODE_SECTION(scibRxISR,".TI.ramfunc");
    __interrupt void scibRxISR(void)
    {
    	CONSOLE_REGS *sci = &scib;
    
    	if(UART_SCIB == (consoleMask & UART_SCIB))
    	{
    		if((HWREGH(sci->iface.sci + SCI_O_RXST) & SCI_RXST_RXRDY) == SCI_RXST_RXRDY)
    		{
    			consoleUsed = UART_SCIB;
    		}
    		tskRecvSciData(sci);
    	}
    	Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
    }
    
    // SCIC
    #pragma CODE_SECTION(scicRxISR,".TI.ramfunc");
    __interrupt void scicRxISR(void)
    {
    	CONSOLE_REGS *sci = &scic;
    
    	if(UART_SCIC == (consoleMask & UART_SCIC))
    	{
    		if((HWREGH(sci->iface.sci + SCI_O_RXST) & SCI_RXST_RXRDY) == SCI_RXST_RXRDY)
    		{
    			consoleUsed = UART_SCIC;
    		}
    		tskRecvSciData(sci);
    	}
    	Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP8);
    }

    And regarding the FLASH operation registers, is there any further description? The erase reports error, the bit4 and bit10 actually returned do not tell the user exactly what the error was. 

    Thanks and Best Regards,

    Cherry

  • Cherry,

    1) What is the flash wait state value used?

    2) For Fapi_initializeAPI(), instead of 124Mhz, can they try 120MHz.  I understand why they are using this 3% more value - but it is not required.  We are updating the guide to remove that requirement.  I don't think this has anything to do with the current debug, but just want to notify.

    3) Flash plugin does not do anything extra - it follows the same steps as we outlined in the flash API example.

    4) FMSTAT value is simply saying that erase verify is not successful - meaning erase is not successful.  Reserved bits does not offer any extra info - hence not documented.

    5) Regarding the DCSM question:  Please see below snippet from the TRM.  Take a look at Case 2 and the note below that.

    6) When you say the flash erase is not successful after the power up, are they running it standalone (in flash boot mode) OR are they running it with JTAG connected?

    Thanks and regards,
    Vamsi

  • Hello Vamsi,

    Thank you so much for your support and effort!

    This issue has been resolved by removing the kick operation from the watchdog callback function Fapi_serviceWatchdog Timer() in FlashAPI. The function is as below:

    //
    // Fapi_serviceWatchdogTimer - Watchdog servicing function
    //
    #pragma CODE_SECTION(Fapi_serviceWatchdogTimer,".TI.ramfunc");
    Fapi_StatusType Fapi_serviceWatchdogTimer(void)
    {
       //
       // User to add their own watchdog servicing code here
       //
    
       return(Fapi_Status_Success);
    }

    In the note: it asks the customer to add their own kick dog action and then plus SyscCtl_serviceWatchdog(), which finally results in this issue. Maybe we can figure out some ways to avoid this bug. 

    Thanks again!

    Best Regards,

    Cherry