⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 flash16x4.c

📁 ATMEL公司AT91RM9200的BasicFlash烧写程序
💻 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 + -