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

📄 bootflash.c

📁 vxworks MPC8541 BSP
💻 C
字号:
/****************************************************************************
**  File Name:Flash.c
**  Function: The Flash(Now Only include AMD and SST type) driver
**  Author:Tiny
**  Date: Des.4  2002
**  Ver:V1.0
**  Modify:
** 2003.12.19 Zhouyuhui 增加获取BOOT类型和电压的函数
** 2004.05.10 FANLIHAN MODIFY
****************************************************************************/
#include "vxWorks.h"

#define _BOOTFLASH_BASE              0xFFF80000
#define _BOOTFLASH_SIZE              0x80000

/*zhou yuhui add boot flash type*/
#define  FUJTU29F040C      1
#define  AM29F040B         2
#define  AM29LV040B        3
#define  SST39VF040        4
#define  SST39SF040        5
#define  NOTSUPPORT        100

static unsigned short __AMD_ID[] = {
  0x04A4,     /*Fuj 29f040c */
  0x01A4,	  /*AMD 29f040b */
  0x014F	  /*AMD 29lv040 */
};

#define AMD_NUM   (sizeof(__AMD_ID)/sizeof(unsigned short))
 
static unsigned short __SST_ID[] = {
  0xBFD7,    /*SST 39VF040 */
  0xBFB7	 /*SST 39SF040 */
};

#define SST_NUM   (sizeof(__SST_ID)/sizeof(unsigned short))

#define __AMD_TYPE                   1
#define __SST_TYPE                   2
#define __UNKNOW_TYPE               -1

static int Flash_Type;
int Boot_Type=0;
int Voltage_Type=0;

IMPORT STATUS taskDelay(int ticks);

/*extern void sndsCacheDisable(void);
extern void sndsCacheEnable( int cachesiz );*/
#ifndef SNDS_CACHE_8K
#define SNDS_CACHE_8K	0x10
#endif

/*-------------------------------------------------------------------*/
/* Local function prototypes                                         */
/*-------------------------------------------------------------------*/
static unsigned char ReadReg(volatile unsigned char *Addr);
static void  WriteReg(volatile unsigned char *Addr, unsigned char val);
int   GetBootFlashType(unsigned long base);
static int   EraseChip(unsigned long BaseAddr);
int   FlashPrg(unsigned long BaseAddr, unsigned long Offset, unsigned char *BufAddr, unsigned int DataLen);
/*********************************************************************/
/*  ReadReg : Read a value from an 8-bit memory-mapped register      */
/*                                                                   */
/*       INPUTS: Addr: Address of register to read from              */
/*                                                                   */
/*      OUTPUTS: register value                                      */
/*                                                                   */
/*********************************************************************/
static unsigned char ReadReg(volatile unsigned char *Addr) {
  return (*(volatile unsigned char *)Addr);
}

/********************************************************************/
/*  WriteReg : Write a value to an 8-bit register                   */
/*                                                                  */
/*   INPUTS : Addr : Address of register to write to                */
/*            val  : Value to write                                 */
/*                                                                  */
/*  OUTPUTS : None                                                  */
/*                                                                  */
/********************************************************************/
static void WriteReg(volatile unsigned char *Addr, unsigned char val) {
  *(volatile unsigned char *)Addr = val;
  return;
}


/********************************************************************/
/*  GetBootFlashType : Get the Flash Type                               */
/*                                                                  */
/*   INPUTS : base :the  flash base address                         */
/*                                                                  */
/*  OUTPUTS : correct flash type or Error                           */
/*                                                                  */
/********************************************************************/
int  GetBootFlashType(unsigned long base)
{
  unsigned short mid;
  unsigned char li,hi;
  unsigned int i;
  
  WriteReg((volatile unsigned char *)(base + 0x555),0xAA);
  WriteReg((volatile unsigned char *)(base + 0x2AA),0x55);
  WriteReg((volatile unsigned char *)(base + 0x555),0x90);
  
  /* 060706 lyf:
   * A delay is necessary!
   */
  taskDelay (1);

  li = ReadReg((volatile unsigned char *)base);
  hi = ReadReg((volatile unsigned char *)(base + 1));
  mid = (li<<8)|hi;
  
  for(i=0;i<AMD_NUM;i++)
  {
    if(__AMD_ID[i] == mid)
  {
      WriteReg((unsigned char *)(base),0xF0);
      Boot_Type = (i+1);
      return __AMD_TYPE;
  }
  }

    WriteReg((volatile unsigned char *)(base + 0x5555),0xAA);
    WriteReg((volatile unsigned char *)(base + 0x2AAA),0x55);
    WriteReg((volatile unsigned char *)(base + 0x5555),0x90);
   
    li = ReadReg((volatile unsigned char *)base);
    hi = ReadReg((volatile unsigned char *)(base + 1));
    mid = (li<<8)|hi;
   
  for(i=0;i<SST_NUM;i++)
    {
    if(__SST_ID[i] == mid)
    {
      WriteReg((volatile unsigned char *)(base),0xF0);
      Boot_Type = (i+4);
      return __SST_TYPE;
    }
  }
	Boot_Type = 100;
  WriteReg((volatile unsigned char *)(base),0xF0);
  return __UNKNOW_TYPE; 
}

/********************************************************************/
/*  FlashBlankCheck : check the Flash blank error                   */
/*                                                                  */
/*   INPUTS : base :the  flash base address                         */
/*                                                                  */
/*  OUTPUTS : correct 0 or Error -1                                 */
/*                                                                  */
/********************************************************************/
static int FlashBlankCheck(unsigned long base)
{
  int i = 0;
  
  for(i=0;i<_BOOTFLASH_SIZE;i++)
  {
    if(*(unsigned char *)(base + i) != 0xFF)
      return -1;
  }
  
  return 0;
}

/********************************************************************/
/*  CheckAddSum : calculate the sum                                 */
/*                                                                  */
/*   INPUTS : base :the  flash base address                         */
/*            size :the memory size                                 */
/*                                                                  */
/*  OUTPUTS : sum                                                   */
/*                                                                  */
/********************************************************************/
static unsigned short CheckAddSum(unsigned long base,int size)
{
  unsigned short Sum = 0; 
  int i;
  
  if(((size % 2) == 0)) 
  {
    size = size/2;

    for(i = 0;i< size;i++)
      Sum += *(unsigned short *)(base + i*2);    
      
    return Sum;
  }
  else
  {
    size = size/2;

    for(i = 0;i< size;i++)
      Sum += *(unsigned short *)(base + i*2);    

    Sum += (*(unsigned char *)(base + size*2))<<8 ;
          
    return Sum;
  }
 
}


/*****************************************************
**Return 
** 0:Ok
** -1:The ic isn't amdflash or sst
**-2:can't erase
**-3:can't program
******************************************************/ 
#define FLASH_OK                0
#define FLASH_ID_ERR           -1
#define FLASH_ERASE_ERR        -2
#define FLASH_PRAG_ERR         -3

/********************************************************************/
/*  WriteToBootFlash : flush the flash                              */
/*                                                                  */
/*   INPUTS : src :data begin                                       */
/*            len :data size                                        */
/*                                                                  */
/*  OUTPUTS : correct or error                                      */
/*                                                                  */
/********************************************************************/
int  WriteToBootFlash(unsigned char *src,int len)
{
  int rc;
  unsigned short SumCheckSrc = 0;
  unsigned short SumCheckDes = 0;
 
  /*sndsCacheDisable();*/
  
  Flash_Type = rc = GetBootFlashType(_BOOTFLASH_BASE);
  
  if(__UNKNOW_TYPE == rc)
  {
    /*sndsCacheEnable(SNDS_CACHE_8K);*/
    return FLASH_ID_ERR;   /*Not find the valid Flash -1*/
  }
  
  rc = EraseChip(_BOOTFLASH_BASE);
  if(rc < 0 )
  {
    /*sndsCacheEnable(SNDS_CACHE_8K);*/
    return FLASH_ERASE_ERR;
  }
    
  rc = FlashBlankCheck(_BOOTFLASH_BASE);
  if(rc < 0 )
  {
    /*sndsCacheEnable(SNDS_CACHE_8K);*/
    return FLASH_ERASE_ERR;
  }
    
  SumCheckSrc = CheckAddSum((unsigned long)src,len);  
    
  rc = FlashPrg(_BOOTFLASH_BASE,0,src,len) ;
  if(rc < 0 )
  {
    /*sndsCacheEnable(SNDS_CACHE_8K);*/
    return FLASH_PRAG_ERR;
  }
  
  SumCheckDes = CheckAddSum(_BOOTFLASH_BASE,len);  
  
  if(SumCheckDes != SumCheckSrc)
  {
    /*sndsCacheEnable(SNDS_CACHE_8K);*/
    return FLASH_PRAG_ERR;
  }
  
  /*sndsCacheEnable(SNDS_CACHE_8K);*/
  
  return FLASH_OK;   
}




/********************************************************************/
/*  EraseChip : Erases FLASH                                        */
/*                                                                  */
/*  INPUTS : BaseAddr : Base address of FLASH to be erased          */
/*            Offset   : Offset from base to start erasing.         */
/*            DataLen  : Number of bytes to be written              */
/*                                                                  */
/* OUTPUTS : Success(0) or failure (-1)                             */
/*                                                                  */
/********************************************************************/
static int EraseChip(unsigned long BaseAddr)
{
 int i ;
 
 if (__AMD_TYPE == Flash_Type )
 { 
   WriteReg((volatile unsigned char *)(BaseAddr + 0x555), 0xAA);
   WriteReg((volatile unsigned char *)(BaseAddr + 0x2AA), 0x55);
   WriteReg((volatile unsigned char *)(BaseAddr + 0x555), 0x80);
   WriteReg((volatile unsigned char *)(BaseAddr + 0x555), 0xAA);
   WriteReg((volatile unsigned char *)(BaseAddr + 0x2AA), 0x55);
   WriteReg((volatile unsigned char *)(BaseAddr + 0x555), 0x10);
 }
 else if(__SST_TYPE == Flash_Type)
 {
   WriteReg((volatile unsigned char *)(BaseAddr + 0x5555), 0xAA);
   WriteReg((volatile unsigned char *)(BaseAddr + 0x2AAA), 0x55);
   WriteReg((volatile unsigned char *)(BaseAddr + 0x5555), 0x80);
   WriteReg((volatile unsigned char *)(BaseAddr + 0x5555), 0xAA);
   WriteReg((volatile unsigned char *)(BaseAddr + 0x2AAA), 0x55);
   WriteReg((volatile unsigned char *)(BaseAddr + 0x5555), 0x10);
 }
 else
  return(-1);

 i = 1000;
 
 while (i--)
 {
    taskDelay(1);
    
   /* poll until the erase is complete */
    if ((ReadReg((volatile unsigned char *)BaseAddr) & 0x80) != 0)
    {
         break;
    }
    if ((ReadReg((volatile unsigned char *)BaseAddr) & 0x20) != 0)
    {
         if ((ReadReg((volatile unsigned char *)BaseAddr) & 0x80)!=0)
         {
               break;
         } 
         else
         {
               return(-2);
         }
    }
 }

 taskDelay(100);

 WriteReg((volatile unsigned char *)(BaseAddr), 0xF0);

 return(0);
}

void FB_DELAY(unsigned long nusecs)
{
    unsigned long j, k, i=0x1234;

    while(nusecs--)
    {
        for (j=0; j<30; j++)
            k = j * i;
        
        k = k + 1;
    }
}

/*******************************************************************/
/* FlashPrg  : This function is used to store data in the FLASH.   */
/*                                                                 */
/*   INPUTS : BaseAddr : Base address of FLASH                     */
/*            Offset   : Offset from base to start programming     */
/*            BufAddr  : Pointer to buffer which contains data     */
/*            DataLen  : Number of bytes to be written             */
/*                                                                 */
/*  OUTPUTS : Write operation successful (0) or not (-1)           */
/*                                                                 */
/*******************************************************************/
int FlashPrg(unsigned long BaseAddr, unsigned long Offset, unsigned char *BufAddr, unsigned int DataLen) 
{
unsigned int    i, retry;
unsigned char  *start;
unsigned char  data, status;


   i=0;
   start = (unsigned char *)(BaseAddr + Offset);
 
   while(1)
   {

     data = status = BufAddr[i];
     status ^= 0xFF;
     status &= 0x80;

     if (data != 0xFF)
     {
        if (__AMD_TYPE == Flash_Type)
        { 
           WriteReg((volatile unsigned char *)(BaseAddr + 0x555), 0xAA);
           WriteReg((volatile unsigned char *)(BaseAddr + 0x2AA), 0x55);
           WriteReg((volatile unsigned char *)(BaseAddr + 0x555), 0xA0);
        }
        else if(__SST_TYPE == Flash_Type)
        {
          WriteReg((volatile unsigned char *)(BaseAddr + 0x5555), 0xAA);
          WriteReg((volatile unsigned char *)(BaseAddr + 0x2AAA), 0x55);
          WriteReg((volatile unsigned char *)(BaseAddr + 0x5555), 0xA0);
        }
        else
          return(-1);
        /* Write data to the next ROM address */
        *start = data;
 
        retry = 50;

        while (retry--)
        {
            if ((ReadReg((volatile unsigned char *)start) & 0x80) != status)
                break;
            else
                FB_DELAY(1);
        }

        if (!retry)
            return(-2);
     }

     /* Increment to the next ROM address and the next byte of data. */
     i++;
     start++;

     /* Exit when finished. */
     if (i == DataLen)
      	break;
    }
    
    *start = 0xF0;

    return(0);
}


void GetVoltage()
{
	unsigned char BtType;
	BtType = Boot_Type;
	switch(BtType)
	{
		case FUJTU29F040C:
				Voltage_Type = 2;
				break;
		case AM29F040B:
				Voltage_Type = 2;
				break;
		case AM29LV040B:
				Voltage_Type = 1;
				break;
		case SST39VF040:
				Voltage_Type = 1;
				break;
		case SST39SF040:
				Voltage_Type = 2;
				break;
		default:
				Voltage_Type = 100;
				break;
	}				
}

⌨️ 快捷键说明

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