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

📄 flashamdmem.c

📁 这是micrel公司宽带路由ARM9芯片的VXWORKS BSP 源代码
💻 C
字号:
/* flashAmdMem.c - AMD AM29LV033 Flash memory device driver */

/* Copyright 1984-2000 Wind River Systems, Inc. */
#include "copyright_wrs.h"

/*
modification history
--------------------
V1.09:---------------------------------------------------------------------
05/13/2004 pcd
1. modify to support ks8695 board with AMD AM29LV033 flash memory .
---------------------------------------------------------------------
01m,01feb00,jpd  added support for 28F320. SPR 31293
01l,09sep98,jpd  added support for 28F016SV; minor doc fixes.
01k,20apr98,jpd  moved back into main source tree from local copy in BSPs.
01j,24mar98,jpd  added support for 29LV1024 and 29C040A.
01i,04jul97,jpd  added support for 28F008 device, made overlay buffer dynamic.
01h,25jun96,map  added documentation, and some clean up.
01g,02apr96,tam  cast FLASH_ADRS and FLASH_SIZE to UINT32 to get rid off
                 a compiler warning.
01f,12feb96,kkk  made 1st param of sysFlashDataPoll() volatile to confirm
                 to dzb's change.
01e,26jan96,dzb  added volatile to register pointers.
           +jpb  changed delay parameters to be globals if not defined.
01d,24feb94,dzb  added sysFlashWrite{En,Dis}able(), sysFlashBoardDelay().
01c,15feb94,dzb  added SYS_FLASH_DELAY_SHIFT macro.
01b,07jan94,dzb  added support for 29F0X0 flash devices.
                 cut ties to NVRAM macros.  added support for FLASH_WIDTH.
01a,05oct93,dzb  derived from version 1b of mem/iFlashMem.c.
*/

/*
DESCRIPTION
This library contains routines to manipulate flash memory.  Read and write
routines are included.

The macro values FLASH_ADRS, FLASH_SIZE, and FLASH_WIDTH must be defined to
indicate the address, size (in bytes), and the data-access width (in bytes) of
the flash memory.

If the flash memory needs to be overlaid, and the section of the memory that
needs to be overlaid is less than FLASH_SIZE, then, for efficiency, define
FLASH_SIZE_WRITABLE to the size (in bytes) of the overlay section.

The routine sysFlashDelay() creates a delay for a specified number of
microseconds.  The timing loop can be adjusted on a board-dependent basis by
defining the function sysFlashBoardDelay and values for the following macros,
.iP
SYS_FLASH_DELAY_SHIFT
.iP
SYS_FLASH_DELAY_ADJ
.iP
SYS_FLASH_DELAY_INCR
.LP
To use the routine sysFlashBoardDelay(), the macro SYS_FLASH_BOARD_DELAY
should be defined.

The macro FLASH_NO_OVERLAY should be defined when calls to sysFlashSet()
are expected to erase the flash and reprogram it with only the new data.

The macro SYS_FLASH_TYPE should be defined for flash devices that cannot be
auto-selected. This macro should be set to a flash device code defined in the
header files, <drv/mem/flash28.h> and <drv/mem/flash29.h>

To support flash devices that that need to turn on/off write protect features
(special programming voltages or other write-enable features), the macro
SYS_FLASH_WRITE, and the routines, sysFlashWriteEnable() and
sysFlashFlashWriteDisable() should be defined.


INTERNAL:
The FLASH_SIZE_WRITABLE concept doesn't work very well.  It just limits the
amount of flash that is writable, so why bother.  What it was really
intended to address was flash that is only block writable, i.e. you
can only write a complete block at a time.  To properly handle block
memory, you must copy the old block of memory to a buffer, update the
part of the buffer that is to be changed, and then write back the
complete buffer in a single write operation.

The accesses to non-volatile memory, and flash control registers needs
to be abstracted.  Macros should be used for all actual i/o operations.
*/

#include "types.h"
#include "vxWorks.h"
#include "string.h"
#include "stdio.h"
#include "config.h"
#include "drv/mem/flashDev.h"
#include "drv/mem/flash29.h"
#include "flash28.h"
#include "flashMem.h"


/* defines */

/* Driver debug control */
#define  DRV_DEBUGFLASH

/* Driver debug control */
#ifdef DRV_DEBUGFLASH
#define FLASHAMD_DEBUG_OFF		0x0000
#define FLASHAMD_DEBUG_ERROR    0x0001
#define FLASHAMD_DEBUG_WRITE	0x0002
#define FLASHAMD_DEBUG_READ		0x0004
#define FLASHAMD_DEBUG_ERASE	0x0008
#define FLASHAMD_DEBUG_TYPEGET	0x0010
#define FLASHAMD_DEBUG_TEST	    0x0020
#define FLASHAMD_DEBUG_ALL    	0xffff

LOCAL int flashDebug = ( FLASHAMD_DEBUG_ERROR /*| FLASHAMD_DEBUG_WRITE */ );

#define FA_DRV_PRINT(FLG, X)						\
    do {								\
    if (flashDebug & FLG)						\
	printf X;							\
    } while (0)

#else /* DRV_DEBUGFLASH */

#define FA_DRV_PRINT(FLG, X)

#endif /* DRV_DEBUGFLASH */



/* Establish default values for DELAY parameters */

#ifndef	SYS_FLASH_DELAY_SHIFT
#   define	SYS_FLASH_DELAY_SHIFT 0
#endif /*SYS_FLASH_DELAY_SHIFT*/

#ifndef	SYS_FLASH_DELAY_ADJ
#   define	SYS_FLASH_DELAY_ADJ 0
#endif	/* SYS_FLASH_DELAY_ADJ */

#ifndef	SYS_FLASH_DELAY_INCR
#   define	SYS_FLASH_DELAY_INCR 1
#endif	/* SYS_FLASH_DELAY_INCR */

/* Names of routines, or null values */

#ifdef	SYS_FLASH_WRITE
#define CSO_WRITE_PROTECT_BIT    0x10001000
#   define SYS_FLASH_WRITE_ENABLE_RTN()	sysFlashWriteEnable ()
#   define SYS_FLASH_WRITE_DISABLE_RTN() sysFlashWriteDisable ()
#else
#   define SYS_FLASH_WRITE_ENABLE_RTN()
#   define SYS_FLASH_WRITE_DISABLE_RTN()
#endif	/* SYS_FLASH_WRITE */


#ifdef	SYS_FLASH_BOARD_DELAY
#   define SYS_FLASH_BOARD_DELAY_RTN()	sysFlashBoardDelay ()
#else
#   define SYS_FLASH_BOARD_DELAY_RTN()
#endif	/* SYS_FLASH_BOARD_DELAY */

#ifdef SYS_FLASH_TYPE
#   define FLASH_MEM_TYPE		SYS_FLASH_TYPE
#else
#   define FLASH_MEM_TYPE		0
#endif	/* SYS_FLASH_TYPE */

#ifdef FLASH_SIZE_WRITEABLE
#   define FLASH_MEM_SIZE		FLASH_SIZE_WRITEABLE
#else
#   define FLASH_MEM_SIZE		FLASH_SIZE
#endif	/* FLASH_SIZE_WRITEABLE */

/* Operation status bits for Flash 29Fxxx devices */

#define Q7(ix)		((ix & 0x80) >> 7)	/* DQ7 bit */
#define Q5(ix)		((ix & 0x20) >> 5)	/* DQ5 bit */

int  flashdelaycount=10;


/*  These index must align with the data in flashCmdArray, below.
 */
typedef enum {

   OP_0x30 = 0,
   OP_0x55,
   OP_0x80,
   OP_0xA0,
   OP_0xAA,
   OP_0x20,
   OP_MAX

} FLASH_COMMAND_WORD_SELECT;

static long flashCmdArray[ 4 ][ OP_MAX ] = {
{0xF0F0F030, 0xF0F0F055, 0xF0F0F080, 0xF0F0F0A0, 0xF0F0F0AA, 0xF0F0F020},
{0xF0F030F0, 0xF0F055F0, 0xF0F080F0, 0xF0F0A0F0, 0xF0F0AAF0, 0xF0F020F0},
{0xF030F0F0, 0xF055F0F0, 0xF080F0F0, 0xF0A0F0F0, 0xF0AAF0F0, 0xF020F0F0},
{0x30F0F0F0, 0x55F0F0F0, 0x80F0F0F0, 0xA0F0F0F0, 0xAAF0F0F0, 0x20F0F0F0},
};


/* globals */

IMPORT void   sysFlashDelay (int);
IMPORT void   sysFlashBoardDelay (void);
IMPORT STATUS sysFlashDataPoll ( FLASH_DEF *, FLASH_DEF );
IMPORT int    flashEraseSector(int);


/* forward declarations */

void      AmdflashReadReset();
int       AmdflashEraseDevice(FLASH_DEF *, int);
int       AmdflashWrite(int, char *, unsigned int, unsigned int);

LOCAL int AmdflashProgramLong(FLASH_DEF *, FLASH_DEF );
LOCAL int AmdflashProgramDevice(FLASH_DEF *, FLASH_DEF, int);

void      flashTest (FLASH_DEF  value, int offset);		



int AmdflashEraseDevice( FLASH_DEF *sectorBasePtr, int device )
{
	int	    i=0;
    STATUS  retVal = OK;

    /* Write Erase Command Sequence */

    *FLASH_5555H_PTR = flashCmdArray[ device ][ OP_0xAA ];
    *FLASH_2AAAH_PTR = flashCmdArray[ device ][ OP_0x55 ];
    *FLASH_5555H_PTR = flashCmdArray[ device ][ OP_0x80 ];
    *FLASH_5555H_PTR = flashCmdArray[ device ][ OP_0xAA ];
    *FLASH_2AAAH_PTR = flashCmdArray[ device ][ OP_0x55 ];

    *sectorBasePtr = flashCmdArray[ device ][ OP_0x30 ];

    /* Verify Data from Erasing Sector with FFh */

    do 
    {
        retVal = sysFlashDataPoll (sectorBasePtr, (FLASH_DEF) 0xffffffff);
    } while ( (*sectorBasePtr != (FLASH_DEF) 0xffffffff) && (retVal == OK) && (i++<FLASH_ERASE_TIMEOUT_COUNT) );


    /* put flash back to read mode */

	AmdflashReadReset();

	FA_DRV_PRINT ( FLASHAMD_DEBUG_ERASE,
                  ("AmdflashEraseDevice(): device %d erased ok, flashAddr 0x%08X\n", (int)device, (int)sectorBasePtr ));

    return (retVal);

}


int AmdflashWrite
( 
    int sectorNum, 
    char *buff, 
    unsigned int offset, 
    unsigned int count
)
{
	volatile FLASH_DEF * flashBuffPtr ;   /* flash address */
	FLASH_DEF * curBuffPtr ;              /* string to be programed */
    int         writeCount , i ;
    STATUS      retVal = OK;



    /*  Program (count / sizeof(long)) long words into Flash.
     */

    curBuffPtr = (FLASH_DEF *)buff;
    writeCount = (count / sizeof( FLASH_DEF ));
    flashBuffPtr = (FLASH_DEF *)(FLASH_BASE_ADDRESS + (sectorNum * FLASH_BANK_SECTOR_SIZE) + offset);

    FA_DRV_PRINT (FLASHAMD_DEBUG_WRITE,
               ("AmdflashWrite(): sectorNum %d, offset %d, writeCount %d, flashAddr 0x%08X\n", 
                 sectorNum, offset, writeCount, (int)flashBuffPtr));

    for( i = 0; i < writeCount; i++ ) 
	{
		if ( retVal = (STATUS)AmdflashProgramLong( flashBuffPtr, *curBuffPtr ) == ERROR ) 
        {
		    FA_DRV_PRINT (FLASHAMD_DEBUG_ERROR,
                  ("AmdflashWrite(): Failed: Sector %d, flashAddress 0x%08X, dataBuf 0x%08X=0x%02x \n", 
                    sectorNum, (int)flashBuffPtr, (int)curBuffPtr, *curBuffPtr));
			break;
		} 
		else 
		{
            /* print out '.' every 64K(one sector) words */
			/*  if((((unsigned int)flashBuffPtr) % 0x40000) == 0) */
            /* printf("."); */
 
			flashBuffPtr++;
			curBuffPtr++;
		}
    }

    /* put flash back to read mode 
     */

	AmdflashReadReset();

    return( retVal );
}

LOCAL int AmdflashProgramLong
( 
    FLASH_DEF *addr, 
    FLASH_DEF val 
)
{
	int	device;

    for( device = 0; device < FLASH_BANK_WIDTH; device++ ) 
	{
		if( AmdflashProgramDevice( addr, val, device) == ERROR ) 
		{
            FA_DRV_PRINT (FLASHAMD_DEBUG_ERROR,
				      ("AmdflashProgramLong(): device %d failed, flashAddr 0x%08X programed with dataBuf 0x%x\n", 
                        device, (int)addr, val));
			return( ERROR );
		}
    }

    return( OK );

}

LOCAL int AmdflashProgramDevice
( 
    FLASH_DEF  *addr, 
    FLASH_DEF   value, 
    int         device 
)
{
    int	        i=0;
    STATUS      retVal = OK;

    /* Write Program Command Sequence */

    *FLASH_5555H_PTR = flashCmdArray[ device ][ OP_0xAA ];
    *FLASH_2AAAH_PTR = flashCmdArray[ device ][ OP_0x55 ];
    *FLASH_5555H_PTR = flashCmdArray[ device ][ OP_0xA0 ];


    /* Program Data (dataBuf) to flash address (addr) */
    *addr = value;

    /* Verify - Data read compare with Data wrote */
    do 
    {
        retVal = sysFlashDataPoll (addr, (FLASH_DEF) value);
    } while ( (*addr != value) && (retVal == OK) && (i++<FLASH_ERASE_TIMEOUT_COUNT) );

    return (retVal);

}


void AmdflashReadReset()
{  
    *FLASH_5555H_PTR = FLASH29_CMD_FIRST;
    *FLASH_2AAAH_PTR = FLASH29_CMD_SECOND;
    *FLASH_5555H_PTR = FLASH29_CMD_READ_RESET;

}



void flashTest
    (
    FLASH_DEF 	value,		    /* value to program */
    int		    sectorOffset	/* sector offset into flash memory */
    )
{
    static FLASH_DEF str[256];
    STATUS           status;

    
    FA_DRV_PRINT (FLASHAMD_DEBUG_TEST,
               ("flashTest(): value 0x%X, sectorOffset %d \n", value, sectorOffset));

    memset (str, value, sizeof(str));

	if( flashEraseSector( sectorOffset ) == ERROR )
        return;

    status = AmdflashWrite ( sectorOffset, str, 0, 16 );
    
    if (status == ERROR)
       FA_DRV_PRINT (FLASHAMD_DEBUG_ERROR,
	             ("program data 0x%x to flash sector offset %08x  fail\n", value, sectorOffset));
    else   
       FA_DRV_PRINT (FLASHAMD_DEBUG_TEST,
                 ("program data 0x%x to flash sector offset %08x  OK\n", value, sectorOffset));
    
}	

⌨️ 快捷键说明

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