?? flash.c
字號:
// ----------------------------------------------------------------------------
// ATMEL Microcontroller Software Support - ROUSSET -
// ----------------------------------------------------------------------------
// DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
// DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ----------------------------------------------------------------------------
//* File Name : Flash.c
//* Object : Flash routine
//* Creation : JPP 30/Jun/2004
//* Modif : JPM 16/Nov/2004 Flash write status
//*----------------------------------------------------------------------------
#include "Board.h"
#include "Flash.h"
#include "trace.h"
#include "po_types.h"
#include "po_kernel.h"
#include "dbgu.h"
#if defined(AT91SAM7A3) ||defined(AT91SAM7S32) || defined(AT91SAM7S64) || defined(AT91SAM7S128) || defined(AT91SAM7S256) || defined(AT91SAM9265) || defined(NANDFLASH) || defined (AT91SAM7X256) || defined (AT91SAM7X128)
#else
#error PROBLEM DEFINE !!!
#endif
#ifdef AT91SAM9265
//*----------------------------------------------------------------------------
//* \fn AT91F_Flash_Init
//* \brief Flash init
//*----------------------------------------------------------------------------
void AT91F_Flash_Init (void)
{
}
//*----------------------------------------------------------------------------
//* \fn AT91F_Flash_Unlock
//* \brief Clear the lock bit and set at 1 FSR bit=0
//* \input page number (0-1023)
//* \output Region
//*----------------------------------------------------------------------------
#ifdef ADS_COMPIL
int AT91F_Flash_Unlock(unsigned int Flash_Lock_Page)
#else
__ramfunc int AT91F_Flash_Unlock(unsigned int Flash_Lock_Page)
#endif
{
return TRUE;
}
//*----------------------------------------------------------------------------
//* \fn AT91F_Flash_Write
//* \brief Write in one Flash page located in AT91C_IFLASH, size in 32 bits
//* \input Flash_Address: start at 0x0010 0000 size: in byte
//*----------------------------------------------------------------------------
#ifdef ADS_COMPIL
int AT91F_Flash_Write( unsigned int Flash_Address ,int size ,unsigned int * buff, unsigned char Memset)
#else
__ramfunc int AT91F_Flash_Write( unsigned int Flash_Address ,int size ,unsigned int * buff, unsigned char Memset)
#endif
{
unsigned int i; //, page, status;
unsigned int * Flash;
//* init flash pointer
Flash = (unsigned int *) Flash_Address;
TRACE_DEBUG_H( "FL Ad(0x%X) ", (int)Flash);
TRACE_DEBUG_H( "FL Ad(0x%X) ", (int)Flash_Address);
TRACE_DEBUG_H( " Lg(%d)\n\r", size);
po_lock();
#ifdef USE_LED
AT91F_LED_blinkSpeed(0);
#endif
for (i=0; (i < FLASH_PAGE_SIZE_BYTE) & (size > 0) ;i++, Flash++,buff++,size-=4 )
{
//* copy the flash to the write buffer ensuring code generation
if( FALSE == Memset )
{
*Flash=*buff;
}
else
{
*Flash=buff[0];
buff--;
}
}
po_unlock();
return true;
}
#endif // AT91SAM9265
#if defined(AT91SAM7A3) || defined(AT91SAM7S32) || defined(AT91SAM7S64) || defined(AT91SAM7S128) || defined(AT91SAM7S256) || defined (AT91SAM7X256) || defined (AT91SAM7X128)
// Prototype:
#ifdef ADS_COMPIL
int AT91F_Flash_Ready (void);
#else
__ramfunc int AT91F_Flash_Ready (void);
#endif
//*----------------------------------------------------------------------------
//* \fn AT91F_Flash_Init
//* \brief Flash init
//*----------------------------------------------------------------------------
void AT91F_Flash_Init (void)
{
//* Set Flash Waite sate
// Single Cycle Access at Up to 30 MHz, or 40
// if AT91C_MASTER_CLOCK = 47923200 I have 48 Cycle for 1 usecond ( flied MC_FMR->FMCN )
// 48 x 1,5 = 72
AT91F_MC_EFC_CfgModeReg( AT91C_BASE_MC, ((AT91C_MC_FMCN)&(72 <<16)) | AT91C_MC_FWS_1FWS );
}
#ifdef AT91SAM7A3
//*----------------------------------------------------------------------------
//* \fn AT91F_Flash_Status
//* \brief Wait the flash ready
//*----------------------------------------------------------------------------
#ifdef ADS_COMPIL
int AT91F_Flash_Status( unsigned int Mask )
#else
__ramfunc int AT91F_Flash_Status( unsigned int Mask )
#endif
{
unsigned int status;
status = 0;
//* Wait the end of command
while( (status & Mask) != Mask )
{
status = AT91C_BASE_MC->MC_FSR;
}
return status;
}
#endif
//*----------------------------------------------------------------------------
//* \fn AT91F_Flash_Lock_Status
//* \brief Get the Lock bits field status
//*----------------------------------------------------------------------------
#ifdef ADS_COMPIL
int AT91F_Flash_Lock_Status(void)
#else
__ramfunc int AT91F_Flash_Lock_Status(void)
#endif
{
return( AT91F_MC_EFC_GetStatus( AT91C_BASE_MC ) & AT91C_MC_FSR_LOCK );
}
//*----------------------------------------------------------------------------
//* \fn AT91F_Flash_Lock
//* \brief Write the lock bit and set at 0 FSR Bit = 1
//* \input page number (0-1023)
//* \output Region
//*----------------------------------------------------------------------------
#ifdef ADS_COMPIL
int AT91F_Flash_Lock (unsigned int Flash_Lock_Page)
#else
__ramfunc int AT91F_Flash_Lock (unsigned int Flash_Lock_Page)
#endif
{
//* write the flash
//* Write the Set Lock Bit command
AT91F_MC_EFC_PerformCmd( AT91C_BASE_MC, AT91C_MC_CORRECT_KEY | AT91C_MC_FCMD_LOCK | (AT91C_MC_PAGEN & (Flash_Lock_Page << 8) ) );
#ifdef AT91SAM7A3
//* Wait the end of command
return AT91F_Flash_Status(AT91C_MC_EOL);
#else
//* Wait the end of command
AT91F_Flash_Ready();
return (AT91F_Flash_Lock_Status());
#endif
}
//*----------------------------------------------------------------------------
//* \fn AT91F_Flash_Check_Erase
//* \brief Check the memory at 0xFF in 32 bits access
//*----------------------------------------------------------------------------
#ifdef ADS_COMPIL
int AT91F_Flash_Check_Erase (unsigned int * start, unsigned int size)
#else
__ramfunc int AT91F_Flash_Check_Erase (unsigned int * start, unsigned int size)
#endif
{
unsigned int i;
//* Check if flash is erased
for (i=0; i < (size/4) ; i++ )
{
if ( start[i] != ERASE_VALUE )
{
return false;
}
}
return true ;
}
//*----------------------------------------------------------------------------
//* \fn AT91F_Flash_Erase_All
//* \brief Send command erase all flash
//*----------------------------------------------------------------------------
#ifdef ADS_COMPIL
int AT91F_Flash_Erase_All(void)
#else
__ramfunc int AT91F_Flash_Erase_All(void)
#endif
{
//* Write the Erase All command
AT91F_MC_EFC_PerformCmd( AT91C_BASE_MC, AT91C_MC_CORRECT_KEY | AT91C_MC_FCMD_ERASE_ALL );
#ifdef AT91SAM7A3
//* Wait the end of command
return AT91F_Flash_Status(AT91C_MC_EOP);;
#else
//* Wait the end of command
AT91F_Flash_Ready();
//* Check the result
return( ( AT91F_MC_EFC_GetStatus( AT91C_BASE_MC ) & ( AT91C_MC_PROGE | AT91C_MC_LOCKE ))==0) ;
#endif
}
//*----------------------------------------------------------------------------
//* \fn AT91F_Flash_Unlock
//* \brief Clear the lock bit and set at 1 FSR bit=0
//* \input page number (0-1023)
//* \output Region
//*----------------------------------------------------------------------------
#ifdef ADS_COMPIL
int AT91F_Flash_Unlock(unsigned int Flash_Lock_Page)
#else
__ramfunc int AT91F_Flash_Unlock(unsigned int Flash_Lock_Page)
#endif
{
//* Write the Clear Lock Bit command
AT91F_MC_EFC_PerformCmd( AT91C_BASE_MC, AT91C_MC_CORRECT_KEY | AT91C_MC_FCMD_UNLOCK | (AT91C_MC_PAGEN & (Flash_Lock_Page << 8) ) );
#ifdef AT91SAM7A3
//* Wait the end of command
return( AT91F_Flash_Status(AT91C_MC_EOL) );
#else
//* Wait the end of command
AT91F_Flash_Ready();
return( AT91F_Flash_Lock_Status() );
#endif
}
//*----------------------------------------------------------------------------
//* \fn AT91F_Flash_Write
//* \brief Write in one Flash page located in AT91C_IFLASH, size in 32 bits
//* \input Flash_Address: start at 0x0010 0000 size: in byte
//*----------------------------------------------------------------------------
#ifdef ADS_COMPIL
int AT91F_Flash_Write( unsigned int Flash_Address ,int size ,unsigned int * buff, unsigned char Memset)
#else
__ramfunc int AT91F_Flash_Write( unsigned int Flash_Address ,int size ,unsigned int * buff, unsigned char Memset)
#endif
{
unsigned int i, page, status;
unsigned int * Flash;
//* init flash pointer
Flash = (unsigned int *) Flash_Address;
//* Get the Flash page number
page = ((Flash_Address - (unsigned int)AT91C_IFLASH ) /FLASH_PAGE_SIZE_BYTE);
TRACE_DEBUG_H( "FL Ad(0x%X) ", Flash);
TRACE_DEBUG_H( "FL Ad(0x%X) ", Flash_Address);
TRACE_DEBUG_H( "Lg(%d)\n\r", size);
po_lock();
#ifdef USE_LED
AT91F_LED_blinkSpeed(0);
#endif
//* copy the new value
for (i=0; (i < FLASH_PAGE_SIZE_BYTE) & (size > 0); i++,Flash++,buff++,size-=4 )
{
//* copy the flash to the write buffer ensuring code generation
if( FALSE == Memset )
{
*Flash=*buff;
}
else
{
*Flash=buff[0];
buff--;
}
}
//* Write the write page command
AT91F_MC_EFC_PerformCmd( AT91C_BASE_MC, AT91C_MC_CORRECT_KEY | AT91C_MC_FCMD_START_PROG | (AT91C_MC_PAGEN & (page <<8)) );
//* Wait the end of command
#ifdef AT91SAM7A3
status = AT91F_Flash_Status(AT91C_MC_EOP);
#else
status = AT91F_Flash_Ready();
#endif
po_unlock();
//* Check the result
if ( (status & ( AT91C_MC_PROGE | AT91C_MC_LOCKE )) != 0)
{
return false;
}
return true;
}
//*----------------------------------------------------------------------------
//* \fn AT91F_Flash_Write_all
//* \brief Write in one Flash page located in AT91C_IFLASH, size in byte
//* \input Start address (base=AT91C_IFLASH) size (in byte ) and buff address
//*----------------------------------------------------------------------------
#ifdef ADS_COMPIL
int AT91F_Flash_Write_all( unsigned int Flash_Address ,int size ,unsigned int * buff)
#else
__ramfunc int AT91F_Flash_Write_all( unsigned int Flash_Address ,int size ,unsigned int * buff)
#endif
{
int next, status;
unsigned int dest;
unsigned int * src;
dest = Flash_Address;
src = buff;
status = true;
while( (status == true) & (size > 0) )
{
//* Check the size
if (size <= FLASH_PAGE_SIZE_BYTE)
next = size;
else
next = FLASH_PAGE_SIZE_BYTE;
#ifdef AT91SAM7A3
//* Unlock current sector base address - current address by sector size
if ( !AT91F_Flash_Unlock((dest - (unsigned int)AT91C_IFLASH ) /FLASH_PAGE_SIZE_BYTE))
{
return false;
}
#endif
//* Write page and get status
status = AT91F_Flash_Write( dest ,next ,src, FALSE);
// * get next page param
size -= next;
src += FLASH_PAGE_SIZE_BYTE/4;
dest += FLASH_PAGE_SIZE_BYTE;
}
return status;
}
#ifdef ADS_COMPIL
#pragma arm section code = "ramfunc"
#endif
#ifndef AT91SAM7A3
//*----------------------------------------------------------------------------
//* \fn AT91F_Flash_Ready
//* \brief Wait the flash ready
//*----------------------------------------------------------------------------
#ifdef ADS_COMPIL
int AT91F_Flash_Ready (void)
#else
__ramfunc int AT91F_Flash_Ready (void)
#endif
{
unsigned int status;
status = 0;
//* Wait the end of command
while ((status & AT91C_MC_FRDY) != AT91C_MC_FRDY )
{
status = AT91F_MC_EFC_GetStatus( AT91C_BASE_MC );
}
return status;
}
#endif
#endif // AT91SAM7A3 AT91SAM7S32 AT91SAM7S64 AT91SAM7S128 AT91SAM7S256
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -