/******************************************************************************
******************************************************************************
*
* [url=home.php?mod=space&uid=288409]@file[/url] flash.c
*
* [url=home.php?mod=space&uid=247401]@brief[/url] application entry point which performs application specific tasks.
*
*******************************************************************************
*
* provide a demo for how to initialize the NV32, output messages via SCI,
* flash operations, etc.
* NOTE:
* printf call may occupy a lot of memory (around 1924 bytes), so please
* consider your code size before using printf.
******************************************************************************
*
* provide FLASH driver
*
******************************************************************************/
#include "flash.h"
/******************************************************************************
* Global variables
******************************************************************************/
/******************************************************************************
* Constants and macros
******************************************************************************/
/******************************************************************************
* Local types
******************************************************************************/
/******************************************************************************
* Local function prototypes
******************************************************************************/
/******************************************************************************
* Local variables
******************************************************************************/
/******************************************************************************
* Local functions
******************************************************************************/
/******************************************************************************
* Global functions
******************************************************************************/
/*****************************************************************************//*!
+FUNCTION----------------------------------------------------------------
* [url=home.php?mod=space&uid=42490]@function[/url] name: Flash_CopyInRAM
*
* @brief This section of the code is the one that copies the routine into RAM.
* It is following the steps documented in Technical Note 228
*
* @param
*
* [url=home.php?mod=space&uid=266161]@return[/url] none
*
* [url=home.php?mod=space&uid=72445]@[/url] Pass/ Fail criteria: none
*****************************************************************************/
#define FLASH_ENABLE_STALLING_FLASH_CONTROLLER
/*****************************************************************************//*!
+FUNCTION----------------------------------------------------------------
* @function name: Flash_Init
*
* @brief initialize flash driver
*
* @param
*
* @return none
*
* @ Pass/ Fail criteria: none
*****************************************************************************/
uint16_t Flash_Init(void)
{
uint16_t err = FLASH_ERR_SUCCESS;
uint32_t clkDIV = BUS_CLK_HZ/1000000L - 1;
uint32_t Tpgs =(285 *(BUS_CLK_HZ/100))/1000000L; //update 2016.8.4 by 光脚板のGG
uint32_t Tprog =(675*(BUS_CLK_HZ/100))/1000000L; //by 光脚板のGG
// printf("Tpgs= %x \n" , Tpgs);
// printf("Tprog= %x \n" , Tprog);
EFMCR=(clkDIV<<24) + 0x00000001; //divide to 1M hz
EFMETM0=(Tpgs<<16) + 0x00001194; //0x00281194; //
EFMETM1=(Tprog<<16) + 0x000088B8; //
// printf("EFMCR= %x \n" , EFMCR);
// printf("EFMETM0= %x \n" , EFMETM0);
// printf("EFMETM1= %x \n" , EFMETM1);
return(err);
}
/*****************************************************************************//*!
+FUNCTION----------------------------------------------------------------
* @function name: FlashProgram
*
* @brief program flash routine, each program operation supports up to 2 longwords
* programming
*
* @param
*
* @return none
*
* @ Pass/ Fail criteria: none
*****************************************************************************/
uint16_t Flash_Program(uint32_t wNVMTargetAddress, uint8_t *pData, uint16_t sizeBytes)
{
uint16_t err = FLASH_ERR_SUCCESS;
uint16_t w2LongWordCount = sizeBytes>>3;
uint8_t wLeftBytes = (sizeBytes & 0x07);
uint16_t wLeftLongWords = wLeftBytes>>2;
uint32_t wTargetAddress = wNVMTargetAddress;
uint32_t dwData0,dwData1;
uint32_t *pdwData = (uint32_t*)pData;
int i;
//printf("\n adr : 0x%x ,data = 0x%x\n",w2LongWordCount,wLeftLongWords );
// Check address to see if it is aligned to 4 bytes
// Global address [1:0] must be 00.
if(wNVMTargetAddress & 0x03)
{
err = FLASH_ERR_INVALID_PARAM;
return (err);
}
// Loop for the two longwords (8 bytes) programming
for(i = 0; i < w2LongWordCount; i++)
{
dwData0 = *pdwData++;
dwData1 = *pdwData++;
err = Flash_Program2LongWords(wTargetAddress, dwData0, dwData1);
if(err)
{
goto EndP;
//break;
}
wTargetAddress += 8;
}
// Loop for the single longword (4 bytes) programming
for(i = 0; i < wLeftLongWords; i++)
{
dwData0 = *pdwData++;
//printf("\n adr : 0x%x ,data = 0x%x\n",i,dwData0 );
err = Flash_Program1LongWord(wTargetAddress, dwData0);
//printf("\n adr : 0x%x ,data = 0x%x\n",i,dwData0 );
if(err)
{
goto EndP;
//break;
}
wTargetAddress += 4;
}
wLeftBytes = (wLeftBytes-(wLeftLongWords<<2)); // calculate the # of bytes that are not programmed
if(!wLeftBytes){
return (err);
}
#if defined(BIG_ENDIAN)
dwData0 = 0;
pData = (uint8_t*)pdwData; // pointer to the left bytes
for(i = wLeftBytes; i >0; i--)
{
dwData0 <<= 8;
dwData0 |= *pData++; // MSB byte first
}
// Calculate how many bytes need to be filled with 0xFFs
// in order to form a single longword for the left bytes of data
wLeftBytes = 4 - wLeftBytes;
//
for(i = wLeftBytes; i >0; i--)
{
dwData0 <<= 8;
dwData0 |= 0xFF; // MSB byte first
}
#else
dwData0 = 0xFFFFFFFFL;
pData = (uint8_t*)pdwData+wLeftBytes-1; // pointer to the left bytes
for(i = wLeftBytes; i >0; i--)
{
dwData0 <<= 8;
dwData0 |= *pData--; // MSB byte first
}
#endif
// Now program the last longword
err = Flash_Program1LongWord(wTargetAddress, dwData0);
EndP:
return (err);
}
uint16_t Flash_Program1LongWord(uint32_t wNVMTargetAddress, uint32_t dwData)
{
uint16_t err = FLASH_ERR_SUCCESS;
// Check address to see if it is aligned to 4 bytes
// Global address [1:0] must be 00.
if(wNVMTargetAddress & 0x03)
{
err = FLASH_ERR_INVALID_PARAM;
return (err);
}
// Clear error flags
EFMCMD = FLASH_CMD_CLEAR;
// Write index to specify the command code to be loaded
M32(wNVMTargetAddress) = dwData;
// Write command code and memory address bits[23:16]
EFM_LaunchCMD(FLASH_CMD_PROGRAM);
return (err);
}
uint16_t Flash_Program2LongWords(uint32_t wNVMTargetAddress, uint32_t dwData0, uint32_t dwData1)
{
uint16_t err = FLASH_ERR_SUCCESS;
// Check address to see if it is aligned to 4 bytes
// Global address [1:0] must be 00.
if(wNVMTargetAddress & 0x03)
{
err = FLASH_ERR_INVALID_PARAM;
return (err);
}
// Clear error flags
EFMCMD = FLASH_CMD_CLEAR;
// printf("\n write data adr : 0x%x ,data = 0x%x\n",dwData0,dwData1 );
// Write index to specify the command code to be loaded
M32(wNVMTargetAddress) = dwData0;
// Write command code and memory address bits[23:16]
EFM_LaunchCMD(FLASH_CMD_PROGRAM);
wNVMTargetAddress = wNVMTargetAddress +4;
// printf("\n write data adr : 0x%x ,data = 0x%x\n",wNVMTargetAddress,dwData1 );
// Clear error flags
EFMCMD = FLASH_CMD_CLEAR;
// Write index to specify the command code to be loaded
M32(wNVMTargetAddress) = dwData1;
// Write command code and memory address bits[23:16]
EFM_LaunchCMD(FLASH_CMD_PROGRAM);
// printf("\n write data adr : 0x%x ,data = 0x%x\n",wNVMTargetAddress,dwData1 );
return (err);
}
/*****************************************************************************//*!
+FUNCTION----------------------------------------------------------------
* @function name: Flash_EraseSector
*
* @brief erase flash sector, each flash sector is of 512 bytes long,
* global address [1:0] = 00.
*
* @param
*
* @return none
*
* @ Pass/ Fail criteria: none
*****************************************************************************/
uint16_t Flash_EraseSector(uint32_t wNVMTargetAddress)
{
uint16_t err = FLASH_ERR_SUCCESS;
// Check address to see if it is aligned to 4 bytes
// Global address [1:0] must be 00.
if(wNVMTargetAddress & 0x03)
{
err = FLASH_ERR_INVALID_PARAM;
return (err);
}
// Clear error flags
EFMCMD = FLASH_CMD_CLEAR;
M32(wNVMTargetAddress) = 0xffffffff;
EFM_LaunchCMD(FLASH_CMD_ERASE_SECTOR);
return (err);
}
uint16_t Flash_VerifyBackdoorKey()
{
uint16_t err = FLASH_ERR_SUCCESS;
// int i;
// Clear error flags
EFMCMD = FLASH_CMD_CLEAR;
// Write index to specify the command code to be loaded
Custombkd = FLASH_FACTORY_KEY;
return (err);
}
/*****************************************************************************//*!
+FUNCTION----------------------------------------------------------------
* @function name: NVM_EraseAll
*
* @brief erase all block,both flash and EEPROM
*
* @param
*
* @return none
*
* @ Pass/ Fail criteria: none
*****************************************************************************/
uint16_t NVM_EraseAll(void)
{
uint16_t err = FLASH_ERR_SUCCESS;
EFMCMD = FLASH_CMD_CLEAR;
EFM_LaunchCMD(FLASH_CMD_ERASE_ALL);
// Clear error flags
return err;
}
/*****************************************************************************//*!
+FUNCTION----------------------------------------------------------------
* @function name: NVM_Unsecure
*
* @brief unsecure
*
* @param
*
* @return none
*
* @ Pass/ Fail criteria: none
*****************************************************************************/
uint16_t NVM_Unsecure(void)
{
uint16_t err = FLASH_ERR_SUCCESS;
return err;
}
#ifdef IAR
void __ramfunc EFM_LaunchCMD(uint32_t EFM_CMD)
#else
void EFM_LaunchCMD(uint32_t EFM_CMD)
#endif
{
DisableInterrupts;
if((EFMCMD&EFM_DONE_MASK)== EFM_STATUS_READY)
{
EFMCMD = EFM_CMD;
}
while(1)
{
if((EFMCMD&EFM_DONE_MASK) == EFM_STATUS_DONE) break;
}
EnableInterrupts;
}