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

📄 fl_sst.c

📁 AT91所有开发板的资料 AT91所有开发板的资料
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  $Revision: 1.2 $ *    $Author: mechavar $ *      $Date: 2000/06/20 18:23:46 $ * *  Copyright (c) 1999 ARM, INC. *  All rights reserved * * * This file currently will recognise and program the FLASH EPROMS from  * SST :- *      SST39VF400 4 Mbit device * The code will use 4K sectors *//* Include Standard c Libraries */#include <stdio.h>/* Include the specific files for the flash memory system */#include "fl_sst.h"/********************************************************************** *             P R E P R O C E S S O R   D E F I N E S **********************************************************************//* Local routine defines for the fl_sst.c module */#define WORD_TRUE         1typedef int bool;#ifndef TRUE#define TRUE (bool)1#endif#ifndef FALSE#define FALSE (bool)0#endif#define ASSERT(cond)   if (!cond) fprintf(stderr, "Assertion failed in file %s line %d\n", __MODULE__, __LINE__);#define divroundup(x, y)   ((unsigned long)((x) + ((y)-1)) / (unsigned long)(y))/********************************************************************** *                    P R O G R A M   D A T A **********************************************************************/extern FILE *image;extern bool file_defined;extern unsigned long filesize;extern bool filesize_defined;extern unsigned long sector_size;extern unsigned long no_of_sectors;extern unsigned long start_offset;extern bool verbose;extern bool quiet;extern int manuf_code, device_code;extern bool base_defined;extern bool rom_identified;extern unsigned long romsize;unsigned long base_address = EPROM_BASE;unsigned int sector[MAX_SECTOR_SIZE/4];static short *flashptr = (short *)EPROM_BASE;  /* flash window *//********************************************************************** *          P R O T O T Y P E   D E C L A R A T I O N S **********************************************************************/extern void needBaseAddress(void);extern void openFile(void);extern void RomInfo(char *msg);extern void needStartOffset(void);extern void needFilename(void);extern void FileInfo(void);extern void ShowProgress(int sectors_done);extern bool getYesOrNo(char *msg, bool def);bool checkFileSize(char *action);/********************************************************************** *                 L O C A L   F U N C T I O N S **********************************************************************//*  Flash_status utilizes the DQ6 polling algorithm described in  the flash data book.*/ static int flash_status(volatile short *fp){   unsigned char d, t;   d = *(volatile char *)fp;	/* read data */   t = d ^ *(volatile char *)fp; /* read it again and see what toggled */   if (t == 0)    {           /* no toggles, nothing's happening */      return STATUS_READY;   }   else    {      return STATUS_BUSY;   }}/*  Flash_command() is the main driver function.*/static void flash_command(int command, int sector, int offset, 			  unsigned int data){   int retry;      /* Some commands may not work the first time, but will work      on successive attempts.    */            static int retrycount[] = {0,0,0,0,15,15,15,0};   if ( command > FLASH_LASTCMD )   {      /* assume reset device to read mode */      command = FLASH_RESET;   }   retry = retrycount[command];  again:   if (command == FLASH_SELECT) {      return;   } else if (command == FLASH_RESET ) {      flashptr[0] = FL_RESET;      }   else {      flashptr[FL_SEQ_ADD_1] = FL_WORD_COM_1;       /* unlock 1 */      flashptr[FL_SEQ_ADD_2] = FL_WORD_COM_2;       /* unlock 2 */      switch (command) {	 case FLASH_AUTOSEL:	    flashptr[FL_SEQ_ADD_3] = FL_AUTO_SELECT;	    break;	 case FLASH_PROG:	    flashptr[FL_SEQ_ADD_3] = FL_PROGRAM;	    flashptr[(sector+offset)/2] = data;	    break;	 case FLASH_CERASE:	    flashptr[FL_SEQ_ADD_3] = FL_ERASE_3;	    flashptr[FL_ERASE_ADD_4] = FL_ERASE_4;	    flashptr[FL_ERASE_ADD_5] = FL_ERASE_5;	    flashptr[FL_CHIP_ERASE_ADD_6] = FL_CHIP_ERASE_6;	    break;	 case FLASH_BERASE:	    flashptr[FL_SEQ_ADD_3]  = FL_ERASE_3;	    flashptr[FL_ERASE_ADD_4]  = FL_ERASE_4;	    flashptr[FL_ERASE_ADD_5]  = FL_ERASE_5;	    flashptr[(sector)/2] = FL_BLOCK_ERASE_6;	    break;	 case FLASH_SERASE:	    flashptr[FL_SEQ_ADD_3]  = FL_ERASE_3;	    flashptr[FL_ERASE_ADD_4]  = FL_ERASE_4;	    flashptr[FL_ERASE_ADD_5]  = FL_ERASE_5;	    flashptr[(sector)/2] = FL_SECTOR_ERASE_6;	    break;      }   }   if (retry-- > 0 && flash_status(flashptr) == STATUS_READY) {      goto again;   }}/*  flash_get_device_id() will perform an autoselect sequence on the   flash device, and return the device id of the component.           This function automatically resets to read mode.                 */static int flash_get_device_id(){   short *fwp;		/* flash window */   short answer;   fwp = flashptr;   flash_command(FLASH_AUTOSEL,0,0,0);   answer = *(fwp+1);	    flash_command(FLASH_RESET,0,0,0);   /* just to be safe */   return( answer );}/*  flash_get_manuf_code() will perform an autoselect sequence on the  flash device, and return the manufacturer code of the component.   This function automatically resets to read mode.                 */static int flash_get_manuf_code(){   short *fwp; /* flash window */   short answer;   fwp = flashptr;   flash_command(FLASH_AUTOSEL,0,0,0);   answer = *fwp;   flash_command(FLASH_RESET,0,0,0);   /* just to be safe */	   return( (answer & 0x00FF) );}/*  Flash_write extends the functionality of flash_program() by providing an  faster way to program multiple data words, without needing the function  overhead of looping algorithms which program word by word.  This function  utilizes fast pointers to quickly loop through bulk data.*/static int flash_write(char *flash_data, char *buf,                 int nbytes ){   short *src, *dst;   int stat;   int retry = 3, retried = 0;   if( (nbytes | ((int) (flash_data)) ) & 1)    {      return -1;   }   dst = (short *)flash_data;   src = (short *)buf;  again:   flash_command(FLASH_RESET,0,0,0);   while ((stat = flash_status(flashptr)) == STATUS_BUSY)    {}   if (stat != STATUS_READY)    {      return (char *)src - buf;   }   while (nbytes > 0)    {      flashptr[FL_SEQ_ADD_1] = FL_WORD_COM_1;       /* unlock 1 */      flashptr[FL_SEQ_ADD_2] = FL_WORD_COM_2;       /* unlock 2 */      flashptr[FL_SEQ_ADD_3] = FL_PROGRAM;      *dst = *src;      while ((stat = flash_status(dst)) == STATUS_BUSY)       {}      if (stat != STATUS_READY) break;      ++dst, ++src;      nbytes -= 2;   }   if (stat != STATUS_READY || nbytes != 0)    {      if (retry-- > 0) {	 ++retried;	 goto again;     /* and retry the last word */      }      flash_command(FLASH_RESET,0,0,0);   }   return (char *)src - buf;}int flashAccessDenied( unsigned start_addr, unsigned end_addr ){   if ( start_addr < base_address )   {      return( ADDR_TOO_LOW );   }   if ( base_address + (no_of_sectors * sector_size)  < end_addr )   {      return( ADDR_TOO_HI );   }   if ( start_addr < ROM_PROTECT_LIMIT )   {      return( ADDR_PROTECTED );   }   return( 0 );}void Erase_Sector( unsigned sect ){   flash_command( FLASH_SERASE, sect - base_address, 0, 0 );   while ( STATUS_BUSY == flash_status( (short *)sect ) )   {      ;   }}void FlashErase(unsigned base, unsigned limit){    unsigned nbytes, nsectors, sector;    nbytes = limit - GET_SECTOR_START(base);    nsectors = nbytes / SST39_SECTOR_SIZE;    nsectors += (limit % SST39_SECTOR_SIZE > 0 ? 1 : 0);    for ( sector = GET_SECTOR_START(base); nsectors > 0; 	  nsectors--, sector+= SST39_SECTOR_SIZE )    {       Erase_Sector( sector );    }}int checkEraseReq( char *pSrc, unsigned extent ){   while ( extent > 0 )   {      if ( 0xFF == *pSrc )      {	 pSrc++;	 extent--;	 continue;      }      return( extent );   }   return( 0 );}/********************************************************************** *                 P U B L I C   F U N C T I O N S **********************************************************************//*      SetDeviceParams() will set parameters for simple contiguous writing of the    flash.    sector_size is an arbitrarily chosen buffer size for file writes.    sector_size must divide into 8K with no remainder.    no_of_sectors is the number of sector-sized sectors in the device.      These parameters are independent of the actual Flash block    organization. For that, see memdesc[].  */

⌨️ 快捷键说明

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