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

📄 flash.c

📁 EX44B0开发板BootLoader
💻 C
字号:
/***********************************************************************/
/* Copyright Silicon Storage Technology, Inc. (SST), 1994-2001         */
/* Example "C" language Driver of 39VF160 16 Mbit Multi-Purpose Flash  */
/* Nelson Wang, Silicon Storage Technology, Inc.                       */
/*                                                                     */
/* Revision 1.0, Sept. 12, 2001                                        */
/*                                                                     */
/***********************************************************************/

#include "Flash.h"

#define FALSE			0
#define TRUE			1

// 数据线引脚映射
#define FLASH_DATA(n)	( (n) >> 15 & 0x0001 /* D15 -> D0  */ \
						| (n) >> 12 & 0x0004 /* D14 -> D2  */ \
						| (n) >> 9  & 0x0010 /* D13 -> D4  */ \
						| (n) >> 6  & 0x0040 /* D12 -> D6  */ \
						| (n) >> 3  & 0x0100 /* D11 -> D8  */ \
						| (n) >> 0  & 0x0400 /* D10 -> D10 */ \
						| (n) << 3  & 0x1000 /* D9  -> D12 */ \
						| (n) << 6  & 0x4000 /* D8  -> D14 */ \
						| (n) >> 6  & 0x0002 /* D7  -> D1  */ \
						| (n) >> 3  & 0x0008 /* D6  -> D3  */ \
						| (n) >> 0  & 0x0020 /* D5  -> D5  */ \
						| (n) << 3  & 0x0080 /* D4  -> D7  */ \
						| (n) << 6  & 0x0200 /* D3  -> D9  */ \
						| (n) << 9  & 0x0800 /* D2  -> D11 */ \
						| (n) << 12 & 0x2000 /* D1  -> D13 */ \
						| (n) << 15 & 0x8000 /* D0  -> D15 */ )

#define FLASH_ADDR(a)	((volatile WORD *)((a) << 1))

#define FLASH_WRITE(addr, word) (*FLASH_ADDR(addr) = FLASH_DATA(word))

#define SST_ID			0xBF	/* SST Manufacturer's ID code   */
#define SST_39VF160		0x2782	/* SST 39VF160 device code      */

/************************************************************************/
/* PROCEDURE:   Check_SST_39VF160                                       */
/*                                                                      */
/* This procedure decides whether a physical hardware device has a      */
/* SST39VF160 16 Mbit Multi-Purpose Flash installed or not.             */
/*                                                                      */
/* Input:                                                               */
/*          None                                                        */
/*                                                                      */
/* Output:                                                              */
/*          return TRUE:  indicates a SST39VF160                        */
/*          return FALSE: indicates not a SST39VF160                    */
/************************************************************************/

int Check_SST_39VF160(void)
{
	unsigned SST_id1, SST_id2;
	int ReturnStatus;

	/*  Issue the Software Product ID code to 39VF160   */

	FLASH_WRITE(0x5555, 0xaaaa);
	FLASH_WRITE(0x2aaa, 0x5555);
	FLASH_WRITE(0x5555, 0x9090);

//	Delay_150_Nano_Seconds();

	/* Read the product ID from 39VF160 */

	SST_id1 = *FLASH_ADDR(0) & FLASH_DATA(255);	/* get first ID word               */
	SST_id2 = *FLASH_ADDR(1);					/* get second ID word              */

	/* Determine whether there is a SST39VF160 installed or not */

	ReturnStatus = SST_id1 == FLASH_DATA(SST_ID)
				&& SST_id2 == FLASH_DATA(SST_39VF160);

	/* Issue the Soffware Product ID Exit code thus returning the 39VF160 */
	/* to the read operating mode                                         */

	FLASH_WRITE(0x5555, 0xaaaa);
	FLASH_WRITE(0x2aaa, 0x5555);
	FLASH_WRITE(0x5555, 0xF0F0);

//	Delay_150_Nano_Seconds();

	return(ReturnStatus);
}

/************************************************************************/
/* PROCEDURE:   Erase_Entire_Chip                                       */
/*                                                                      */
/* This procedure can be used to erase the entire chip.                 */
/*                                                                      */
/* Input:                                                               */
/*      NONE                                                            */
/*                                                                      */
/* Output:                                                              */
/*      NONE                                                            */
/************************************************************************/

void Erase_Entire_Chip(void)
{
	/*  Issue the Chip Erase command to 39VF160  */

	FLASH_WRITE(0x5555, 0xaaaa);
	FLASH_WRITE(0x2aaa, 0x5555);
	FLASH_WRITE(0x5555, 0x8080);

	FLASH_WRITE(0x5555, 0xaaaa);
	FLASH_WRITE(0x2aaa, 0x5555);
	FLASH_WRITE(0x5555, 0x1010);

//	Delay_100_Milli_Seconds();		/* Delay Tsce time                  */
	Check_Toggle_Ready((WORD *)0);	/* wait for TOGGLE bit to get ready */
}

/************************************************************************/
/* PROCEDURE:   Erase_One_Sector                                        */
/*                                                                      */
/* This procedure can be used to erase a total of 2048 words.           */
/*                                                                      */
/* Input:                                                               */
/*      dst     DESTINATION address which the erase operation starts    */
/*                                                                      */
/* Output:                                                              */
/*      NONE                                                            */
/************************************************************************/

void Erase_One_Sector(WORD *dst)
{
	/*  Issue the Sector Erase command to 39VF160  */

	FLASH_WRITE(0x5555, 0xaaaa);
	FLASH_WRITE(0x2aaa, 0x5555);
	FLASH_WRITE(0x5555, 0x8080);

	FLASH_WRITE(0x5555, 0xaaaa);
	FLASH_WRITE(0x2aaa, 0x5555);
	FLASH_WRITE((unsigned)dst >> 1, 0x3030);

//	Delay_25_Milli_Seconds();		/* Delay time = Tse                 */
	Check_Toggle_Ready(dst);		/* wait for TOGGLE bit to get ready */
}

/************************************************************************/
/* PROCEDURE:   Erase_One_Block                                         */
/*                                                                      */
/* This procedure can be used to erase a total of 32K words.            */
/*                                                                      */
/* Input:                                                               */
/*      dst     DESTINATION address which the erase operation starts    */
/*                                                                      */
/* Output:                                                              */
/*      NONE                                                            */
/************************************************************************/

void Erase_One_Block(WORD *dst)
{
	/*  Issue the Sector Erase command to 39VF160  */

	FLASH_WRITE(0x5555, 0xaaaa);
	FLASH_WRITE(0x2aaa, 0x5555);
	FLASH_WRITE(0x5555, 0x8080);

	FLASH_WRITE(0x5555, 0xaaaa);
	FLASH_WRITE(0x2aaa, 0x5555);
	FLASH_WRITE((unsigned)dst >> 1, 0x5050);

//	Delay_25_Milli_Seconds();		/* Delay time = Tbe                 */
	Check_Toggle_Ready(dst);		/* wait for TOGGLE bit to get ready */
}

/************************************************************************/
/* PROCEDURE:   Program_One_Word                                        */
/*                                                                      */
/* This procedure can be used to program ONE word of date to the        */
/* 39VF160.                                                             */
/*                                                                      */
/* NOTE:  It is VERY important the sector containing the word to be     */
/*        programmed was ERASED first.                                  */
/*                                                                      */
/* Input:                                                               */
/*           dst     DESTINATION address which will be written with the */
/*                   data passed in from Src                            */
/*           data    The WORD which will be written to the 39VF160      */
/*                                                                      */
/* Output:                                                              */
/*           None                                                       */
/************************************************************************/

void Program_One_Word(WORD *dst, WORD data)
{
	FLASH_WRITE(0x5555, 0xaaaa);
	FLASH_WRITE(0x2aaa, 0x5555);
	FLASH_WRITE(0x5555, 0xa0a0);

	*dst = data;					/* transfer the word to destination */

	Check_Toggle_Ready(dst);		/* wait for TOGGLE bit to get ready */
}

/************************************************************************/
/* PROCEDURE:    Check_Toggle_Ready                                     */
/*                                                                      */
/* During the internal program cycle, any consecutive read operation    */
/* on DQ6 will produce alternating 0's and 1's (i.e. toggling between   */
/* 0 and 1). When the program cycle is completed, DQ6 of the data will  */
/* stop toggling. After the DQ6 data bit stops toggling, the device is  */
/* ready for next operation.                                            */
/*                                                                      */
/* Input:                                                               */
/*           dst        must already set-up by the caller               */
/*                                                                      */
/* Output:                                                              */
/*           None                                                       */
/************************************************************************/

void Check_Toggle_Ready(WORD *dst)
{
	int Loop = TRUE;
	unsigned TimeOut = 0;

	int PreData = *(volatile WORD *)dst & FLASH_DATA(0x0040);
	while(TimeOut < 0x07FFFFFF && Loop)
	{
		int CurrData = *(volatile WORD *)dst & FLASH_DATA(0x0040);
		if(PreData == CurrData)
			Loop = FALSE;				/* ready to exit the while loop */
		PreData = CurrData;
		TimeOut++;
	}
}

/************************************************************************/
/* PROCEDURE:   Check_Data_Polling                                      */
/*                                                                      */
/* During the internal program cycle, any attempt to read DQ7 of the    */
/* last byte loaded during the page/byte-load cycle will receive the    */
/* complement of the true data.  Once the program cycle is completed,   */
/* DQ7 will show true data.                                             */
/*                                                                      */
/* Input:                                                               */
/*           dst        must already set-up by the caller               */
/*           TrueData   Data is the original (true) data                */
/*                                                                      */
/* Output:                                                              */
/*           None                                                       */
/************************************************************************/

void Check_Data_Polling(WORD *dst, WORD TrueData)
{
	int Loop = TRUE;
	unsigned long TimeOut = 0;

	TrueData &= FLASH_DATA(0x8080);
	while ((TimeOut< 0x07FFFFFF) && (Loop))
	{
		int CurrData = *(volatile WORD *)dst & FLASH_DATA(0x8080);
		if (TrueData == CurrData)
			Loop = FALSE;   /* ready to exit the while loop  */
		TimeOut++;
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -