hudson2009 wrote on Thursday, October 23, 2008:
Hi Chaalar,
Thanks for your reply.
1) i am using the portDISABLE_INTERRUPTS(); (not sure it is appropriate)
2) use (.fast) to put into the SRAM as below:
e_FLASH_Result Flash_Command(e_FLASH_Cmd cmd, const int page)__attribute__ ((section (".fast")));
//*****************************************************************************
// Function: Flash_Command
//
// Description:
// Perform a flash command on the specified page number.
// This function does not take a data as a parameter - eg. flash write buffer must be
// setup already if required.
//
// Parameters:
// - cmd : flash command to perform,
// - page : page number.
//
// Return Value:
// - e_FLASH_Result
//
//*****************************************************************************
e_FLASH_Result Flash_Command(e_FLASH_Cmd cmd, const int page)
{
e_FLASH_Result ret_val = FLASH_FAIL;
unsigned int fcr_val = 0x0; //Value to be placed in MC_FCR.
unsigned int fsr_val; //FSR reg content.
AT91S_EFC *pEfc; //pointer to EFC.
pEfc = AT91C_BASE_EFC0; // Base address of EFC0 registers.
switch(cmd)
{
case FLASH_LOCK_PAGE: // Lock a page.
fcr_val = (0x5A << 24) | (page << 8) | 0x2;
break;
case FLASH_UNLOCK_PAGE: // Unlock a page.
fcr_val = (0x5A << 24) | (page << 8) | 0x4;
break;
case FLASH_ERASE_PAGE: // Erase a page of data - write all zeroes (not 0xff)!
case FLASH_WRITE_PAGE: // Write data to a page (which should be unlocked already).
fcr_val = (0x5A << 24) | (page << 8) | 0x1;
break;
default:
return ret_val;
break;
}
// Disable interrupts
portDISABLE_INTERRUPTS();
//AT91C_BASE_AIC->AIC_IDCR = 0xFFFFFFFF;
// Wait for flash to be ready.
do
{
fsr_val = pEfc->EFC_FSR;
}
while ((fsr_val & AT91C_MC_FRDY) == 0);
// Now send command.
pEfc->EFC_FCR = fcr_val;
// Wait for flash to be ready.
do
{
fsr_val = pEfc->EFC_FSR;
}
while ((fsr_val & AT91C_MC_FRDY) == 0);
//Check for errors and return.
if((fsr_val = pEfc->EFC_FSR) & (AT91C_MC_PROGE | AT91C_MC_LOCKE))
{
return ret_val; // Error shown in PROGE or LOCKE bits.
}
// Restore interrupts
portENABLE_INTERRUPTS();
return FLASH_OK;
}