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

📄 sst28f040_zly_driver.c

📁 烧写falsh。为单片机支持升级程序使用
💻 C
字号:
#pragma large
#include "w77e58.h"
#include "flash.h"

 #include <stdlib.h>
#include <intrins.h>
#include "math.h"


#define FLASH_BASE_ADDR  0x8000

#define FALSE			0
#define TRUE			1

#define ROW_SIZE		256	        /* Must be 256  unsigned char xdatas for 28SF040 */

#define SST_ID			0xBF		/* SST Manufacturer抯 ID code */
#define SST_28SF040		0x04		/* SST 28SF040 device code */

#define AUTO_PG_ERASE1		0x20
#define AUTO_PG_ERASE2		0xD0
#define AUTO_PGRM		0x10
#define RESET			0xFF
#define READ_ID			0x90

void Enable_Chip_Data_Protection();
void Disable_Chip_Data_Protection();
void Check_Data_Polling (unsigned char *Dst,	unsigned char TrueData);
int Check_Toggle_Ready (unsigned char *Dst);


/*****************************************************************************************************/
/* PROCEDURE:			Write_28SF040				                             */
/*                                                                                                   */
/* This procedure can be used to write a total of 256 bytes at one write cycle to the	             */
/* SST抯 28SF040 4 Mbit SuperFlash EEPROM.                                                           */
/*                                                                                                   */
/* Input:                                                                                            */
/*           SRC     SOURCE address containing the data which will be                                */
/*                   written into the 28SF040.                                                       */
/*           Dst     DESTINATION address which will be written with the                              */
/*                   data passed in from ds:si                                                       */
/*                                                                                                   */
/* Output:                                                                                           */
/*            return - 1 : indicates an error in programming the 28SF040                             */
/*            return - 0 : indicates no error in programming the 28SF040                             */
/*****************************************************************************************************/

int Write_28SF040 (unsigned char *Src,    unsigned int Dst)
{
	   unsigned char *SourceBuf;
	   unsigned char *DestBuf;
	   int Index;
	   int Count;
	   unsigned char SourceByte;
	   unsigned char ProgrammedByte;
	   unsigned char Continue;
       char tmp1;
       char tmp2;
       unsigned long TimeOut ;
       char Loop;
       Loop=TRUE;
       TimeOut=0;
	   /*和本次设计有关,详细情况参考透明modem原理图*/
       if(Dst>=0x8000)
        {
            P1_4 = 1;
            ;
        }
        else
        {
            P1_4 = 0;
            Dst=Dst+FLASH_BASE_ADDR;
        }
        
       Disable_Chip_Data_Protection();
	   SourceBuf = Src;
	   DestBuf = (unsigned char *)Dst;

	   /************************************************************************************/
	   /*                                      ERASE OPERATION                             */
	   /*                                                                                  */ 
	   /************************************************************************************/

	  *DestBuf = AUTO_PG_ERASE1;                      
	  *DestBuf = AUTO_PG_ERASE2;              
	  Check_Toggle_Ready((unsigned char *)Dst);

	  Count = 0;
	  Continue = TRUE;
	  while ((Count < ROW_SIZE) && (Continue))
	  {
	               SourceByte = * DestBuf++;
	                if (SourceByte == 0xFF)
	                        Count++;
	                else
	                         Continue =  FALSE;
	  }
	  if (!Continue)
	  {     
	 	 Enable_Chip_Data_Protection();             
	 	 return (FALSE);                                   
	  }
	/**********************************************************************************************************/
	/*                                   PROGRAM  OPERATION                                                   */
	/*                                                                                                        */
	/**********************************************************************************************************/

	SourceBuf = Src;
	DestBuf = (unsigned char *)Dst;

	for (Index = 0; Index < ROW_SIZE; Index++)
	{
	SourceByte = *SourceBuf++;
	if (SourceByte != 0xFF)	        
	{

	   *DestBuf = AUTO_PGRM;	            
	   *DestBuf = SourceByte;	            
	   if(FALSE==Check_Toggle_Ready((unsigned char*)Dst))
       {
            //如果通过检查,数据出错,就通过进一步的读取数据进一步确认
            while ((TimeOut< 0x07FFFFFF) && (Loop)) 
            {
               tmp1 = *(DestBuf);
               tmp2 = *(DestBuf);
               if(tmp1==tmp2)
                   Loop=FALSE;
               TimeOut++;
            }
            if (Loop==FALSE) Continue = TRUE;
            else Continue = FALSE;
        }
        
	    ProgrammedByte = *DestBuf; 
	    //检查写入的数据是否正确
        if (SourceByte != ProgrammedByte)
	    {
	        Continue = FALSE;
	        break;
	    }
	   }
        DestBuf++;
	}
	P1_4 = 0;    
	Enable_Chip_Data_Protection();

    if (!Continue)
	return(FALSE);                               
	else
	return(TRUE);                             
}

void  ReadFlash(unsigned int addr, unsigned char * buf, unsigned int len)
{
        unsigned int  i;
        unsigned char xdata * addr1;
        if(addr>=0x8000)
        {
            P1_4 = 1;
            addr1 = addr;
        }
        else
        {
            P1_4 = 0;
            addr1 = FLASH_BASE_ADDR  +addr;
        }
        for( i=0;i<len;i++)
        {
            buf[i]=*(addr1+i);
        }
        buf[len]=0;
        P1_4 = 0;
}

void Disable_Chip_Data_Protection()
{
    unsigned int adds;
	unsigned char TempByte;
    adds= (0x1823+FLASH_BASE_ADDR);
	TempByte  = *(unsigned char*)adds;	           /* set up address to be E000:1823h      */
	   adds= (0x1820+FLASH_BASE_ADDR);                  
	TempByte  = *( unsigned char*)adds;	           /* set up address to be E000:1820h      */
	   adds =(0x1822+FLASH_BASE_ADDR);                 
	TempByte  = *( unsigned char *)adds;	           /* set up address to be E000:1822h      */
	   adds =(0x0418+FLASH_BASE_ADDR);                 
	TempByte = *( unsigned char*)adds;	           /* set up address to be E000:0418h      */
	   adds  =(0x041B+FLASH_BASE_ADDR);              
	TempByte = *( unsigned char*)adds;             /* set up address to be E000:041Bh      */
	   adds = (0x0419+FLASH_BASE_ADDR) ;              
	TempByte = *( unsigned char*)adds;	           /* set up address to be E000:0419h      */
        adds=   (0x041A+FLASH_BASE_ADDR) ;           	   
	TempByte = *( unsigned char*)adds;	

}  


void Enable_Chip_Data_Protection()
{
    unsigned int adds;
	unsigned char    TempByte;
    adds= (0x1823+FLASH_BASE_ADDR);
	TempByte  = *(unsigned char*)adds;	           /* set up address to be E000:1823h      */
	   adds= (0x1820+FLASH_BASE_ADDR);                  
	TempByte  = *( unsigned char*)adds;	           /* set up address to be E000:1820h      */
	   adds =(0x1822+FLASH_BASE_ADDR);                 
	TempByte  = *( unsigned char *)adds;	           /* set up address to be E000:1822h      */
	   adds =(0x0418+FLASH_BASE_ADDR);                 
	TempByte = *( unsigned char*)adds;	           /* set up address to be E000:0418h      */
	   adds  =(0x041B+FLASH_BASE_ADDR);              
	TempByte = *( unsigned char*)adds;             /* set up address to be E000:041Bh      */
	   adds = (0x0419+FLASH_BASE_ADDR) ;              
	TempByte = *( unsigned char*)adds;	           /* set up address to be E000:0419h      */
        adds=   (0x040A+FLASH_BASE_ADDR) ;           	   
	TempByte = *( unsigned char*)adds;       
}


/******************************************************************************************************/
/*PROCEDURE:                         Check_Toggle_Ready                                               */
/*                                                                                                    */
/*During the internal write cycle, any consecutive read operation                                     */
/*on DQ6 will produce alternating 0抯 and 1抯 i.e. toggling between                                   */
/*0 and 1.  When the write 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                                                                                     */
/******************************************************************************************************/

int Check_Toggle_Ready (unsigned char *Dst)
{
	unsigned char Loop = TRUE;
	unsigned char PreData;
	unsigned char CurrData;
	unsigned long TimeOut = 0;

	PreData = *Dst;
	PreData = PreData & 0x40;
	while ((TimeOut< 0x07FFFFFF) && (Loop))
	{
		CurrData = *Dst;
		CurrData = CurrData & 0x40;
		if (PreData == CurrData)
               Loop = FALSE; 		/* ready to exit the while loop */
		PreData = CurrData;
		TimeOut++;
	}
    if(FALSE==Loop)
    return FALSE;
    else
    return TRUE;
}

/********************************************************************************************************/
/* PROCEDURE:                         Check_Data_Polling                                                */
/*                                                                                                      */
/* During the internal write cycle, any attempt to read DQ7 of the byte loaded during                   */
/* the byte-load cycle will receive the complement of the true data. Once the write                     */
/* cycle is completed, DQ7 will show true data.                                                         */
/*                                                                                                      */
/* Input:                                                                                               */
/*	Dst 	       must already set-up by the caller                                                */
/*      TrueData       this is the original (true) data                                                 */
/*                                                                                                      */
/* Output:                                                                                              */
/*           None                                                                                       */
/********************************************************************************************************/
/*
void Check_Data_Polling (unsigned char *Dst,	unsigned char TrueData)
{
	unsigned char Loop = TRUE;
	unsigned char CurrData;
	unsigned long TimeOut = 0;

	TrueData = TrueData & 0x80;
	while ((TimeOut< 0x07FFFFFF) && (Loop))
	{
		CurrData = *Dst;
		CurrData = CurrData & 0x80;
		if (TrueData == CurrData)
          Loop = FALSE;         
		TimeOut++;
	}
}
*/

⌨️ 快捷键说明

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