📄 flash16x4.c
字号:
//*----------------------------------------------------------------------------
//* ATMEL Microcontroller Software Support - ROUSSET -
//*----------------------------------------------------------------------------
//* The software is delivered "AS IS" without warranty or condition of any
//* kind, either express, implied or statutory. This includes without
//* limitation any warranty or condition with respect to merchantability or
//* fitness for any particular purpose, or against the infringements of
//* intellectual property rights of others.
//*----------------------------------------------------------------------------
//* File Name : AT91F_FLASH16x4.c
//* Object : Basic functions to erase and write a FLASH
//*
//* 1.0 Jul 15 2002 : HIi Creation
//*----------------------------------------------------------------------------
#include "FLASH16x4.h"
/* Define Flash Codes */
#define FLASH_SEQ_ADD1 (0x5555)
#define FLASH_SEQ_ADD2 (0xAAAA)
#define FLASH_CODE1 ((unsigned short)(0x00AA))
#define FLASH_CODE2 ((unsigned short)(0x0055))
#define ID_IN_CODE ((unsigned short)(0x0090))
#define ID_OUT_CODE ((unsigned short)(0x00F0))
#define WRITE_CODE ((unsigned short)(0x00A0))
#define ERASE_SECTOR_CODE1 ((unsigned short)(0x0080))
#define CHIP_SECTOR_CODE1 ((unsigned short)(0x0010))
#define ERASE_SECTOR_CODE2 ((unsigned short)(0x0030))
#define ERASE_SUSPEND ((unsigned short)(0x00B0))
#define ERASE_RESUME ((unsigned short)(0x0030))
//* This function is used for the flash timeout
extern unsigned int AT91F_GetTickCount(void);
//*----------------------------------------------------------------------------
//* \fn AT91F_FLASH16x4Open
//* \brief This function initialise the AT91S_FLASH16x4 structure
//*----------------------------------------------------------------------------
AT91PS_FLASH16x4 AT91F_FLASH16x4Open(
AT91PS_FLASH16x4 pFlash, // \arg Pointer to the FLASH service
AT91PS_FLASH_INFO pFlashInfo,
unsigned short *baseAddress)
{
pFlash->baseAddress = baseAddress;
pFlash->pFlashInfo = pFlashInfo;
pFlash->ProductId = AT91F_FLASH16x4ProductId;
pFlash->SectorErase = AT91F_FLASH16x4SectorErase;
pFlash->IsSectorErased = AT91F_FLASH16x4IsSectorErased;
pFlash->ChipErase = AT91F_FLASH16x4ChipErase;
pFlash->EraseSuspend = AT91F_FLASH16x4EraseSuspend;
pFlash->EraseResume = AT91F_FLASH16x4EraseResume;
pFlash->Program = AT91F_FLASH16x4Program;
pFlash->IsProgramed = AT91F_FLASH16x4IsProgramed;
pFlash->BypassUnlock = AT91F_FLASH16x4BypassUnlock;
pFlash->SectorLockout = AT91F_FLASH16x4SectorLockout;
return pFlash;
}
//*----------------------------------------------------------------------------
//* \fn AT91F_Init16x4Flash
//* \brief This function initialize the flashinfo structure for a AT49BV1614
//*----------------------------------------------------------------------------
unsigned int AT91F_Init16x4Flash(AT91PS_FLASH_INFO pFlashInfo, unsigned int baseAddress)
{
int j;
unsigned int flashbase;
pFlashInfo->sector_count = CFG_MAX_FLASH_SECT;
pFlashInfo->size = FLASH_BANK_SIZE;;
flashbase = baseAddress;
for (j = 0; j < pFlashInfo->sector_count; j++)
{
if (j <= 9)
{
//* The 8 eight first sectors are 8 KB
if (j <= 7)
pFlashInfo->start[j] = flashbase + j*0x2000;
//* 9th and 10th are both 32 KB
if ((j == 8) || (j == 9))
pFlashInfo->start[j] = flashbase + 0x10000 + (j-8)*0x8000;
}
else
pFlashInfo->start[j] = flashbase + (j-8)*MAIN_SECT_SIZE;
}
return 1;
}
//*----------------------------------------------------------------------------
//* \fn AT91F_SVC_FLASH16x4ProductId
//* \brief This function returns Manufacturer and Device code
//*----------------------------------------------------------------------------
unsigned int AT91F_FLASH16x4ProductId(
AT91PS_FLASH16x4 pFlash) // \arg Pointer to the FLASH service
{
volatile unsigned short *baseAddress = pFlash->baseAddress;
unsigned int id;
//* Enter Software Product Identification Mode
*(baseAddress + FLASH_SEQ_ADD1) = FLASH_CODE1;
*(baseAddress + FLASH_SEQ_ADD2) = FLASH_CODE2;
*(baseAddress + FLASH_SEQ_ADD1) = ID_IN_CODE;
//* Read Manufacturer and device code from the device
id = (short) *baseAddress ;
id |= *(baseAddress + 1) << 16;
//* Exit Software Product Identification Mode
*(baseAddress + FLASH_SEQ_ADD1) = FLASH_CODE1;
*(baseAddress + FLASH_SEQ_ADD2) = FLASH_CODE2;
*(baseAddress + FLASH_SEQ_ADD1) = ID_OUT_CODE;
return id;
}
//*----------------------------------------------------------------------------
//* \fn AT91F_SVC_FLASH16x4SectorErase
//* \brief This function erases sectors
//*----------------------------------------------------------------------------
unsigned int AT91F_FLASH16x4SectorErase(
AT91PS_FLASH16x4 pFlash, // \arg Pointer to the FLASH service
unsigned int FirstSector,
unsigned int LastSector,
void *address)
{
unsigned int sect;
volatile unsigned short *SectAddr;
volatile unsigned short *baseAddress = (volatile unsigned short *)pFlash->baseAddress;
unsigned int TimeOut;
unsigned int IsFlashReady;
if ((FirstSector >= pFlash->pFlashInfo->sector_count) || (LastSector >= pFlash->pFlashInfo->sector_count))
return AT91C_FLASH_ERR_SECTOR;
/* Start erase on unprotected sectors */
for (sect = FirstSector; sect <= LastSector; sect++)
{
SectAddr= (volatile unsigned short *)(pFlash->pFlashInfo->start[sect]);
//* Enter Sector Erase Sequence codes
*(baseAddress + FLASH_SEQ_ADD1) = FLASH_CODE1;
*(baseAddress + FLASH_SEQ_ADD2) = FLASH_CODE2;
*(baseAddress + FLASH_SEQ_ADD1) = ERASE_SECTOR_CODE1;
*(baseAddress + FLASH_SEQ_ADD1) = FLASH_CODE1;
*(baseAddress + FLASH_SEQ_ADD2) = FLASH_CODE2;
*((volatile unsigned short *) SectAddr) = ERASE_SECTOR_CODE2 ;
/* wait until flash is ready */
IsFlashReady = AT91C_FLASH_BUSY;
TimeOut = AT91F_GetTickCount()+ AT91C_FLASH_TIMEOUT;
do
{
/* check timeout */
if (AT91F_GetTickCount() > TimeOut)
{
*(baseAddress + FLASH_SEQ_ADD1) = ID_OUT_CODE;
IsFlashReady = AT91C_FLASH_ERR_TIMEOUT;
break;
}
if ((*SectAddr & 0xFFFF) & AT91C_BIT_RDY_MASK)
IsFlashReady = AT91C_FLASH_READY;
}
while (IsFlashReady == AT91C_FLASH_BUSY);
*(baseAddress + FLASH_SEQ_ADD1) = ID_OUT_CODE;
if(IsFlashReady != AT91C_FLASH_READY)
return IsFlashReady;
}
return IsFlashReady;
}
//*----------------------------------------------------------------------------
//* \fn AT91F_SVC_FLASH16x4IsSectorErased
//* \brief This function return 1 if the sector has been erased
//*----------------------------------------------------------------------------
int AT91F_FLASH16x4IsSectorErased(
AT91PS_FLASH16x4 pFlash, // \arg Pointer to the FLASH service
void *address)
{
return (*(unsigned short *)address == (unsigned short) -1);
}
//*----------------------------------------------------------------------------
//* \fn AT91F_SVC_FLASH16x4ChipErase
//* \brief This function erase a sector
//*----------------------------------------------------------------------------
void AT91F_FLASH16x4ChipErase(
AT91PS_FLASH16x4 pFlash) // \arg Pointer to the FLASH service
{
//* TBD
}
//*----------------------------------------------------------------------------
//* \fn AT91F_SVC_FLASH16x4EraseSuspend
//* \brief This function erase a sector
//*----------------------------------------------------------------------------
void AT91F_FLASH16x4EraseSuspend(
AT91PS_FLASH16x4 pFlash) // \arg Pointer to the FLASH service
{
//TBD
}
//*----------------------------------------------------------------------------
//* \fn AT91F_SVC_FLASH16x4EraseResume
//* \brief This function erase a sector
//*----------------------------------------------------------------------------
void AT91F_FLASH16x4EraseResume(
AT91PS_FLASH16x4 pFlash, // \arg Pointer to the FLASH service
void *address)
{
//TBD
}
//*----------------------------------------------------------------------------
//* \fn AT91F_SVC_FLASH16x4Program
//* \brief This function erase a sector
//*----------------------------------------------------------------------------
unsigned int AT91F_FLASH16x4Program(
AT91PS_FLASH16x4 pFlash, // \arg Pointer to the FLASH service
void *address,
unsigned short value)
{
volatile unsigned short *baseAddress = pFlash->baseAddress;
unsigned int TimeOut;
unsigned int IsFlashReady;
if ((unsigned int)address > (unsigned int)(baseAddress + pFlash->pFlashInfo->size))
return AT91C_FLASH_ERR_ADDRESS;
//* Enter Chip Erase Sequence codes
*(baseAddress + FLASH_SEQ_ADD1) = FLASH_CODE1;
*(baseAddress + FLASH_SEQ_ADD2) = FLASH_CODE2;
*(baseAddress + FLASH_SEQ_ADD1) = WRITE_CODE;
if (((unsigned int)address) & 0x1)
*((char *) address) = (char) value;
else
*((short *) address) = value;
//* wait until flash is ready
IsFlashReady = AT91C_FLASH_BUSY;
TimeOut = AT91F_GetTickCount()+ AT91C_FLASH_TIMEOUT;
do
{
//* check timeout
if (AT91F_GetTickCount() > TimeOut)
{
*(baseAddress + FLASH_SEQ_ADD1) = ID_OUT_CODE;
IsFlashReady = AT91C_FLASH_ERR_TIMEOUT;
break;
}
if ((*(unsigned short *)address & 0xFFFF) & AT91C_BIT_RDY_MASK)
IsFlashReady = AT91C_FLASH_READY;
}
while (IsFlashReady == AT91C_FLASH_BUSY);
*(baseAddress + FLASH_SEQ_ADD1) = ID_OUT_CODE;
if((IsFlashReady != AT91C_FLASH_READY) || (*((unsigned short *)address) !=value))
IsFlashReady = AT91C_FLASH_ERR_PROGRAM;
return IsFlashReady;
}
//*----------------------------------------------------------------------------
//* \fn AT91F_SVC_FLASH16x4IsProgramed
//* \brief This function test if a byte/word has been programed
//*----------------------------------------------------------------------------
int AT91F_FLASH16x4IsProgramed(
AT91PS_FLASH16x4 pFlash, // \arg Pointer to the FLASH service
void *address,
unsigned short value)
{
if (((unsigned int) address) & 0x1)
return (*((char *) address) == (char) value);
else
return (*((short *) address) == value);
}
//*----------------------------------------------------------------------------
//* \fn AT91F_SVC_FLASH16x4BypassUnlock
//* \brief This function erase a sector
//*----------------------------------------------------------------------------
void AT91F_FLASH16x4BypassUnlock(
AT91PS_FLASH16x4 pFlash)
{
//TBD
}
//*----------------------------------------------------------------------------
//* \fn AT91F_SVC_FLASH16x4SectorLockout
//* \brief This function erase a sector
//*----------------------------------------------------------------------------
void AT91F_FLASH16x4SectorLockout(
AT91PS_FLASH16x4 pFlash,
void *address)
{
//TBD
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -