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

📄 sst39f080.c

📁 名厂车载GPS通信终端
💻 C
字号:
/***********************************************************************/
/* Copyright Silicon Storage Technology, Inc. (SST), 1994-2001         */
/* Example "C" language Driver of 39VF080 4 Mbit Multi-Purpose Flash   */
/* Chi Chung Yin, Silicon Storage Technology, Inc.                     */
/*                                                                     */
/* Revision 1.0, Sept. 12, 2001                                        */
/*                                                                     */
/***********************************************************************/
#define _39F080
#include "includes.h"

#define SECTOR_SIZE             256     /* Must be 128 bytes for       */
#define SECTOR_BYTES			    4096
#define	BLOCKSIZE				  16

#define SST_ID                  0xBF    /* SST Manufacturer's ID code   */
#define SST_39VF080             0xd8    /* SST 39VF080 device code      */

#define	FIRST_ADDR_IDENTIFY	0x05555
#define	SECOND_ADDR_IDENTIFY	0x02AAA
#define  MANUFACTURERIDADDR	0x00000
#define	DEVICEID				   0x00001



/*************************************************************************/
/* PROCEDURE:   Check_SST_39VF080                                       */
/*                                                                      */
/* This procedure  decides whether a  physical hardware device has a    */
/* SST 39VF080 8 Mbit Multi-Purpose Flash installed or not.             */
/*                                                                      */
/* Input:                                                               */
/*          None                                                        */
/*                                                                      */
/* Output:                                                              */
/*          return TRUE:  indicates a SST 39VF080                       */
/*          return FALSE: indicates not a SST 39VF080                   */
/************************************************************************/

void Change_Bank(DWORD addr)
{
	static uchar Bank_Status = 0; 
	
	if(Bank_Status)
	{
		if(addr<BANK_DIFFER_ADDR)
		{
			Bank_Status = 0;
			bsr0        = 0;
		}
	}
	else 
	{
		if(addr>=BANK_DIFFER_ADDR)
		{
			Bank_Status = 1;
			bsr0        = 1;
		}
	}
}

int Check_SST_39VF080(void)
{
	UCHAR SST_id1;
	UCHAR SST_id2;
	
	/*  Issue the Software Product ID code to 39VF080   */
	asm("fclr I");
	Addressing_One_Byte(FIRST_ADDR_IDENTIFY,0XAA); 	/* set up address to be 5555h      */
	Addressing_One_Byte(SECOND_ADDR_IDENTIFY,0X55);
	Addressing_One_Byte(FIRST_ADDR_IDENTIFY,0X90);
	asm("fset I");
	Delay10ms(1);       							/* check DATABOOK for the most  */
	/* accurate value -- Tida       */
	/* Read the product ID from 39VF080 */
	SST_id1  =  Read_One_Byte(MANUFACTURERIDADDR);              /* get first ID byte                    */
	SST_id2  =  Read_One_Byte(DEVICEID);              /* get first ID byte                    */
	
	/* Determine whether there is a SST 39VF080 installed or not */
	
	if ((SST_id1 == SST_ID) && (SST_id2 ==SST_39VF080))
		FlashState = TRUE;
	else
		FlashState = FALSE;
	
	/* Issue the Soffware Product ID Exit code thus returning the 39VF080   */
	/* to the read operating mode                                           */
	asm("fclr I");
	Addressing_One_Byte(FIRST_ADDR_IDENTIFY,0XAA); 	/* set up address to be 5555h      */
	Addressing_One_Byte(SECOND_ADDR_IDENTIFY,0X55);
	Addressing_One_Byte(FIRST_ADDR_IDENTIFY,0XF0);	
	asm("fset I");
	Delay10ms(1);       					/* check DATABOOK for the most  */
	/* accurate value -- Tida       */
	
	return(FlashState);
}


/*************************************************************************/
/* PROCEDURE:   Erase_Entire_Chip                                       */
/*                                                                      */
/* This procedure can be used to erase the entire chip.                 */
/*                                                                      */
/* Input:                                                               */
/*      Src     SOURCE address which the erase operation will start     */
/*                                                                      */
/* Output:                                                              */
/*      NONE                                                            */
/************************************************************************/

void Erase_Entire_Chip(void)
{
	
	/*  Issue the Sector Erase command to 39VF080   */
	asm("fclr I");
	Addressing_One_Byte(FIRST_ADDR_IDENTIFY,0XAA); 	/* set up address to be 5555h      */
	Addressing_One_Byte(SECOND_ADDR_IDENTIFY,0X55);
	Addressing_One_Byte(FIRST_ADDR_IDENTIFY,0X80);
	Addressing_One_Byte(FIRST_ADDR_IDENTIFY,0XAA); 	/* set up address to be 5555h      */
	Addressing_One_Byte(SECOND_ADDR_IDENTIFY,0X55);
	Addressing_One_Byte(FIRST_ADDR_IDENTIFY,0X10);	
	asm("fset I");
	Delay10ms(11);      		/* check DATABOOK for the most  */
	/* accurate value -- Tsce       */
}

/*************************************************************************/
/* PROCEDURE:   Erase_One_Sector                                        */
/*                                                                      */
/* This procedure can be used to erase a total of 4096 bytes.           */
/*                                                                      */
/* Input:                                                               */
/*      Src     SOURCE address which the erase operation will start     */
/*                                                                      */
/* Output:                                                              */
/*      NONE                                                            */
/************************************************************************/

void Erase_One_Sector(WORD  block)
{
	/*  Issue the Sector Erase command to 39VF080   */
	clr_watchdog();
	asm("fclr I");
	Addressing_One_Byte(FIRST_ADDR_IDENTIFY,0XAA); 	/* set up address to be 5555h      */
	Addressing_One_Byte(SECOND_ADDR_IDENTIFY,0X55);
	Addressing_One_Byte(FIRST_ADDR_IDENTIFY,0X80);
	Addressing_One_Byte(FIRST_ADDR_IDENTIFY,0XAA); 	/* set up address to be 5555h      */
	Addressing_One_Byte(SECOND_ADDR_IDENTIFY,0X55);
	Addressing_One_Byte((DWORD)block*SECTOR_BYTES,0X30);
	asm("fset I");
	Delay10ms(3);		      					/* check DATABOOK for the most  */
	/* accurate value -- Tse        */
}

void Write_Bytes(DWORD addr,LPBYTE pSrc,WORD SrcLen)
{
	WORD i;
	if(addr%SECTOR_BYTES==0)
	{
		Erase_One_Sector((WORD)(addr/SECTOR_BYTES));
	}
	for(i=0;i<SrcLen;i++)
	{
		Program_One_Byte(pSrc+i,addr+i);
	}
	//Uart1TxString("\r\nWrite bytes ok\r\n",20);
}

void Write_One_Byte(LPBYTE SrcByte, DWORD DstAddr,WORD sector)
{
	Program_One_Byte(SrcByte,(DWORD)(DstAddr+(DWORD)((DWORD)sector*(DWORD)SECTOR_BYTES)));
}

void Addressing_One_Byte(DWORD addr,UCHAR Dst)
{
	UCHAR far *pointer;
	
	Change_Bank(addr);
	addr &= BANK_MASK_ADDR;
	pointer=(UCHAR far*)(addr+FALSH_OFFER_ADDR);
	*pointer=Dst;
}

UCHAR Read_One_Byte(DWORD addr)
{
	UCHAR far *temp;
	asm("fclr I");
	Change_Bank(addr);
	addr &= BANK_MASK_ADDR;
	temp=(UCHAR far*)(addr+FALSH_OFFER_ADDR);
	asm("fset I");
	//asm("NOP");
	return(*temp);
}

uchar Read_Sector_Byte(WORD sector,DWORD addr)
{
	DWORD darr;
	
	darr   = sector;
	darr <<= 12;
	darr  += addr;
	return Read_One_Byte(darr);
}
/************************************************************************/
/* PROCEDURE:   Program_One_Byte                                        */
/*                                                                      */
/* This procedure can be used to program ONE byte of date to the        */
/* 39VF080.                                                             */
/*                                                                      */
/* NOTE:  It is VERY important the sector containing the byte to be     */
/*        programmed was ERASED first.                                  */
/*                                                                      */
/* Input:                                                               */
/*           Src     The BYTE which will be written to the 39VF080.     */
/*           Dst     DESTINATION address which will be written with the */
/*                   data passed in from Src                            */
/*                                                                      */
/* Output:                                                              */
/*           None                                                       */
/************************************************************************/

void Program_One_Byte (LPBYTE SrcByte, DWORD DstAddr)
{
	asm("fclr I");
	Addressing_One_Byte(FIRST_ADDR_IDENTIFY,0XAA); 	/* set up address to be 5555h      */
	Addressing_One_Byte(SECOND_ADDR_IDENTIFY,0X55);
	Addressing_One_Byte(FIRST_ADDR_IDENTIFY,0XA0);
	Addressing_One_Byte(DstAddr,SrcByte[0]); 			/* transfer the byte to destination */
    asm("fset I");
	Check_Toggle_Ready(DstAddr,SrcByte[0]);  			/* 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 (DWORD addr,UCHAR src)
{
	UCHAR Loop = TRUE;
	UCHAR PreData;
	UCHAR CurrData;
	
	PreData = src;
	PreData = PreData & 0x40;
	asm("fclr I");
	TenMsecCount=0;	
	asm("fset I");
	while((TenMsecCount< 1000) && (Loop))
	{
		clr_watchdog();
		CurrData =Read_One_Byte(addr);
		CurrData = CurrData & 0x40;
		if (PreData == CurrData)
			Loop = FALSE;   /* ready to exit the while loop */
		PreData = CurrData;
	}
}

/************************************************************************/
/* 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               */
/*           True       Datathis is the original (true) data            */
/*                                                                      */
/* Output:                                                              */
/*           None                                                       */
/************************************************************************/

void Check_Data_Polling (DWORD addr,UCHAR TrueData)
{
    UCHAR Loop = TRUE;
    UCHAR CurrData;
	
    TrueData = TrueData &  0x80;
	asm("fclr I");
	TenMsecCount=0;	
	asm("fset I");
    while ((TenMsecCount< 500) && (Loop))
    {
		clr_watchdog();
        CurrData = Read_One_Byte(addr);
        CurrData = CurrData & 0x80;
        if (TrueData == CurrData)
		{
			Loop = FALSE;   /* ready to exit the while loop  */
		}
    }
}

⌨️ 快捷键说明

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