Amit
I checked your project annd think that the Flash erase is OK at the lowest level.
However the generated code can't work without some additional user manipulation. Basically it has a number of land-mines which are waiting to go off when user's don't tread carefully (and in fact understand the underlying code and operation).
1. Much is based on the variable uint8_t OpStatus who's pointer is passed to the flash initialisation FLASH_Init(&OpStatus);
In the process it is inserted into the internal flash management struct.
2. The Flash driver is interrupt driven which makes its operation a little tricky to follow and the code rather complicated. Depending on how you configure the project the actual flash operation will be put in a protected region (eg. the original demo has it put in EnterCritical()/ExitCritical() regions but your generated code doesn't have this - either it doesn't need it or it may fail later when it should be protected).
2.a. In addition the internal implementation is blocking, which defeats any potential benefits of interrupt driven operation (that is it spins internally on the same interrupt flag)
2.b. I do wonder whether there are different Flash drivers that can be chosen from since the one used looks more suitable for a multiple-plane flash design (at least if it wasn't blocking)
3. The user code is in fact spinning on the state of flash struct state (controlled by the Flash interrupt which has however already been processed when the code arrives), accessed by *OpStatus. It is waiting for it to become TRUE.
Unfortunately the state of the variable after successful flash programming is never TRUE but LDD_FLASH_IDLE (what value this actually is depends on some unrelated enum).
The first fix (and probably generally best) is to wait on the flash state. That is, rather than
while(*OpStatus != TRUE); /* Wait while operation done */
do
while(*OpStatus != LDD_FLASH_IDLE); /* Wait while operation done */
This would have to be changed in all flash routines (EraseFlash() etc.)
The reference project has a user cludge in it which makes it work.
In Events.c someone has added
void FLASH_OnOperationComplete(LDD_TUserData *UserDataPtr)
{
uint8_t *OpStatus = (LDD_TUserData*) UserDataPtr;
*OpStatus = TRUE;
}
This actively overwites the state with the TRUE value and so allows it to work,
but in a freshly generated project it is
void FLASH1_OnOperationComplete(LDD_TUserData *UserDataPtr)
{
/* Write your code here ... */
}
(it maybe should be - "add code here if you need it to work" ;-)
That means that a freshly generated project probably can't work unless you are lucky that the TRUE and LDD_FLASH_IDLE defines happen to match up (they are in fact only one out so maybe some times you do get lucky).
In fact I am still not sure exactly how this status is operating (whether it is pointing to the internal state or has its own variable somewhere (tricky to see with CW's debugger)) but it is certainly weird and not very maintainable.
Regards
Mark