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

📄 fl_amphilips.c

📁 NXP需要外扩FLASH产品(比如LPC22XX)的外部FLASH烧写操作.
💻 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  * AM29LV800 8 Mbit device * The code will use 4K sectors *//* Include Standard c Libraries */#include <stdio.h>#include <string.h>/* Include the specific files for the flash memory system */#include "fl_AMphilips.h"#include "config.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_AMplilips.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;extern unsigned long FL_RESET,FL_SEQ_ADD_1,FL_SEQ_ADD_2,FL_SEQ_ADD_3;extern unsigned long FL_WORD_COM_1,FL_WORD_COM_2,FL_AUTO_SELECT,FL_PROGRAM;extern unsigned long FL_ERASE_ADD_4,FL_ERASE_ADD_5,FL_CHIP_ERASE_ADD_6;extern unsigned long FL_ERASE_3,FL_ERASE_4,FL_ERASE_5,FL_SECTOR_ERASE_6;extern unsigned long FL_BLOCK_ERASE_6,FL_CHIP_ERASE_6;	unsigned long base_address = EPROM_BASE;unsigned int sector[MAX_SECTOR_SIZE/4];static long *flashptr = (long *)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 long *fp){   unsigned long d, t;   d = *(volatile long*)fp;	/* read data */   t = d ^ *(volatile long *)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 long 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)/4] = data;//delete by barry	    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)/4] = 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)/4] = 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 */  long answer;   //fwp = (short *)flashptr;   flash_command(FLASH_AUTOSEL,0,0,0);   answer = *(flashptr+1);//*(fwp+1);	    flash_command(FLASH_RESET,0,0,0);   /* just to be safe */   return( answer&0x0000FFFF );}/*  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 */   long answer;  // fwp =(short *) flashptr;   flash_command(FLASH_AUTOSEL,0,0,0);   answer = *flashptr;//*fwp;   flash_command(FLASH_RESET,0,0,0);   /* just to be safe */	   return( (answer & 0x000000FF) );}/*  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 ){   long *src;   long *dst;   int stat;   int retry = 3, retried = 0;   if( (nbytes | ((int) (flash_data)) ) & 1)    {      return -1;   }   dst = (long *)flash_data;   src = (long *)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;      //flash_command(FLASH_AUTOSEL,0,0,0);                       // flash_command(FL_PROGRAM,0,0,0);         *dst = *src;                        flash_command(FLASH_RESET,0,0,0);      //while( (*dst&0x80) != (*src&0x80) );      while ((stat = flash_status(dst)) == STATUS_BUSY)       {}      if (stat != STATUS_READY) break;      ++dst, ++src;      nbytes -= 4;   }   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( (long *)sect ) )   {      ;   }}void FlashErase(unsigned base, unsigned limit){    unsigned nbytes, nsectors, sector;    nbytes = limit - GET_SECTOR_START(base);    nsectors = nbytes / AM_SECTOR_SIZE;    nsectors += (limit % AM_SECTOR_SIZE > 0 ? 1 : 0);    for ( sector = GET_SECTOR_START(base); nsectors > 0; 	  nsectors--, sector+= AM_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[].  */bool SetDeviceParams(){           switch (device_code)   {      case  AM29LV800_ID:	 if (verbose)	    printf ("AM29LV800 recognised\n");	 sector_size = SECTOR_SIZE;	 no_of_sectors = NUM_SECTORS_400;	 	 /********************************/	 FL_RESET		= 0x00F0;	 /* Generic command bus cycle addresses */	 FL_SEQ_ADD_1	= 0x555;	 FL_SEQ_ADD_2	= 0x2AA;	 FL_SEQ_ADD_3	= 0x555;	 /* Generic command bus cycle data */	 FL_WORD_COM_1	= 0xAAA;	 FL_WORD_COM_2	= 0x555;	 /* Command specific data for cycle 3 */	 FL_AUTO_SELECT	= 0x0090;	 FL_PROGRAM	= 0x00A0;	 /* Erase function addresses and data */	 FL_ERASE_ADD_4	= 0x555;	 FL_ERASE_ADD_5	= 0x2AA;	 FL_CHIP_ERASE_ADD_6	= 0x555;	 /* Erase function addresses and data */	 FL_ERASE_3		= 0x0080;	 FL_ERASE_4		= 0x00AA;	 FL_ERASE_5		= 0x0055;	 FL_SECTOR_ERASE_6	= 0x0030;	 FL_BLOCK_ERASE_6	= 0x0050;	 FL_CHIP_ERASE_6	= 0x0010;	 	 /********************************/	 

⌨️ 快捷键说明

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