📄 29f800a.c
字号:
/*====================================================================
*
* Copyright (C) 2004 Ali Corp. All Rights Reserved.
*
* File: FlashDrv.c
*
* Contents: Library routines for the Flash (x16/x8) 4Mb to 16Mb driver.
*
* this source file provides library C code for using the Flash.
* The following devices are supported in the code:
* >ST
* M29F800AT/M29F800AB
* M29W800AT/M29W800AB
* >MXIC
* MX29F400T/MX29F400B
* >AMD
* >SST
*
* The following functions are available in this library:
* FlashReadReset() to reset the flash for normal memory access
* FlashAutoSelect() to get information about the device
* FlashBlockErase() to erase one or more blocks
* FlashChipErase() to erase the whole chip
* FlashProgram() to program a word or an array
* FlashErrorStr() to return the error string of an error
*
* The hardware specific functions which need to be modified by the user are:
* FlashWrite() for writing a word to the flash
* FlashRead() for reading a word from the flash
* FlashPause() for timing short pauses (in micro seconds)
*
* A list of the error conditions is given at the end of the code.
* There are no timeouts implemented in the loops in the code. At each point
* where an infinite loop is implemented a comment /# TimeOut! #/ has been
* placed. It is up to the user to implement these to avoid the code hanging
* instead of timing out.
* Since C does not include a method for disabling interrupts to keep time-
* critical sections of code from being disabled. The user may wish to disable
* interrupt during parts of the code to avoid the FLASH_MPU_TOO_SLOW error from
* occuring if an interrupt occurs at the wrong time. Where interrupt should be
* disabled and re-enabled there is a /# DSI! #/ or /# ENI! #/ comment.
* The source code assumes that the compiler implements the numerical types as
* BYTE 8 bits
* WORD 16 bits
* DWORD 32 bits
*
* History:
* Date By Reason
* ====================
* 02-Nov-2001 Dick Ma Created and porting to M6311/M3325
* 08-Aug-2003 Jeff Chang Modify for M3355 CD upgrade
* 04-Mar-2004 Dick Ma update
********************************************************************/
#include <comsub.h>
#include <flash.h>/* Header file with global prototypes */
#include <upgrade.h>
/* Turn on/off the debug info */
/*******************************************************************************
* Function: static void FlashWrite( DWORD dwOff, WORD wVal)
*
* Description: This function is used to write a word to the flash. On many
* microprocessor systems a macro can be used instead, increasing the speed of
* the flash routines. For example:
* #define FlashWrite( dwOff, wVal ) ( BASE_ADDR[dwOff] = (WORD) wVal )
* A function is used here instead to allow the user to expand it if necessary.
* The function is made to return wVal so that it is compatible with the macro.
* Pseudo Code:
* Step 1: Write wVal to the word offset in the flash
* Step 2: return wVal
*
* Arguments: dwOff is the word offset in the flash to write to
* wVal is the value to be written
*
* Returns: wVal
*******************************************************************************/
#if (_FLASH_TYPE_ == FLASH_x8x16_16BIT_BUS)
WORD FlashWrite( DWORD dwOff, WORD wVal )
{
/* Step1, 2: Write wVal to the word offset in the flash and return it */
return BASE_ADDR[dwOff] = wVal;
}
#else if (_FLASH_TYPE_ == FLASH_x8x16_8BIT_BUS)||(_FLASH_TYPE_ == FLASH_x8_8BIT_BUS)
BYTE FlashWrite( DWORD dwOff, BYTE bVal )
{
/* Step1, 2: Write wVal to the byte offset in the flash and return it */
return BASE_ADDR[dwOff] = bVal;
}
#endif
/*******************************************************************************
* Function: WORD FlashRead( DWORD dwOff )
*
* Description: This function is used to read a word from the flash. On many
* microprocessor systems a macro can be used instead, increasing the speed of
* the flash routines. For example:
* #define FlashRead( dwOff ) ( BASE_ADDR[dwOff] )
* A function is used here instead to allow the user to expand it if necessary.
* Pseudo Code:
* Step 1: Return the value at word offset dwOff
*
* Arguments: dwOff is the word offset into the flash to read from
*
* Returns: The WORD at the word offset
*******************************************************************************/
#if (_FLASH_TYPE_ == FLASH_x8x16_16BIT_BUS)
WORD FlashRead( DWORD dwOff )
{
/* Step 1 Return the value at word offset dwOff */
return BASE_ADDR[dwOff];
}
#else if (_FLASH_TYPE_ == FLASH_x8x16_8BIT_BUS)||(_FLASH_TYPE_ == FLASH_x8_8BIT_BUS)
BYTE FlashRead( DWORD dwOff )
{
/* Step 1 Return the value at byte offset dwOff */
return BASE_ADDR[dwOff];
}
#endif
/*******************************************************************************
* Function: void FlashPause( WORD wMicroSeconds )
*
* Description: This routine returns after wMicroSeconds have elapsed. It is used
* in several parts of the code to generate a pause required for correct
* operation of the flash part.
* Pseudo Code:
* Step 1: Compute count size for pause.
* Step 2: Count to the required size.
*
* Arguments: wMicroSeconds is the length of the pause in microseconds(uS)
* m6311 running on 108 MHz
* Returns: none
*******************************************************************************/
void FlashPause( WORD wMicroSeconds )
{
DWORD i;
DWORD dwCountSize;
/* Step 1: Compute the count size */
dwCountSize = (DWORD)wMicroSeconds * FLASH_COUNTS_PER_MICROSECOND;
/* Step 2: Count to the required size */
for(i=0;i<dwCountSize;i++)
;
}
/*******************************************************************************
* Function: void FlashReadReset( void )
*
* Description: This function places the flash in the Read mode described
* in the Data Sheet. In this mode the flash can be read as normal memory.
* All of the other functions leave the flash in the Read mode so this is
* not strictly necessary. It is provided for completeness.
* Note: A wait of 10us is required if the command is called during a program or
* erase instruction. This is included here to guarantee correct operation. The
* functions in this library call this function if they suspect an error
* during programming or erasing so that the 10us pause is included. Otherwise
* they use the single instruction technique for increased speed.
* Pseudo Code:
* Step 1: write command sequence (see Commands Table of the Data Sheet)
* Step 2: wait 10us
*
* Arguments: none
*
* Return Value: none
*******************************************************************************/
void FlashReadReset( void )
{
#if (_FLASH_TYPE_ == FLASH_x8x16_16BIT_BUS)||(_FLASH_TYPE_ == FLASH_x8_8BIT_BUS)
FlashWrite( 0x5555L, 0x00AA ); /* 1st Cycle */
FlashWrite( 0x2AAAL, 0x0055 ); /* 2nd Cycle */
FlashWrite( ANY_ADDR, 0x00F0 ); /* 3rd Cycle: write 0x00F0 to ANY address */
#else if (_FLASH_TYPE_ == FLASH_x8x16_8BIT_BUS)
FlashWrite( 0xAAAAL, 0xAA ); /* 1st Cycle */
FlashWrite( 0x5555L, 0x55 ); /* 2nd Cycle */
FlashWrite( ANY_ADDR, 0xF0 ); /* 3rd Cycle: write 0x00F0 to ANY address */
#endif
FlashPause( 10 );//need wait 10us
}
/*******************************************************************************
* Function: int FlashAutoSelect( int iFunc )
*
* Description: This function can be used to read the electronic signature of the
* device, the manufacturer code/deveice code or the protection level of a block.
* Pseudo Code:
* Step 1: Send the Auto Select command to the device
* Step 2: Read the required function from the device.
* Step 3: Return the device to Read mode.
*
* Arguments: iFunc should be set to either the Read Signature values or to the
* block number. The header file defines the values for reading the Signature.
* Note: the first block is Block 0
*
* Return Value:
* When iFunc is FLASH_READ_MANUFACTURER (-2) the function returns the
* manufacturer’s code. The Manufacturer code for ST is 0020h.
* When iFunc is FLASH_READ_DEVICE_CODE (-1) the function returns the Device
* Code. The device codes for the parts are:
*******************************************************************************/
int FlashAutoSelect( int iFunc )
{
int iRetVal; /* Holds the return value */
#if (_FLASH_TYPE_ == FLASH_x8x16_16BIT_BUS)||(_FLASH_TYPE_ == FLASH_x8_8BIT_BUS)
/* Step 1: Send the Auto Select command */
FlashWrite( 0x5555L, 0x00AA ); /* 1st Cycle */
FlashWrite( 0x2AAAL, 0x0055 ); /* 2nd Cycle */
FlashWrite( 0x5555L, 0x0090 ); /* 3rd Cycle */
/* Step 2: Read the required function */
if( iFunc == FLASH_READ_MANUFACTURER )
iRetVal = (WORD) FlashRead( 0x00L ); /* A0 = A1 = 0 */
else if( iFunc == FLASH_READ_DEVICE_CODE )
iRetVal = (WORD) FlashRead( 0x01L ); /* A0 = 1, A1 = 0 */
else
iRetVal = FLASH_CMD_INVALID;
/* Step 3: Return to Read mode */
FlashWrite( ANY_ADDR, 0x00F0 ); /* Use single instruction cycle method */
#else if (_FLASH_TYPE_ == FLASH_x8x16_8BIT_BUS)
/* Step 1: Send the Auto Select command */
FlashWrite( 0xAAAAL, 0xAA ); /* 1st Cycle */
FlashWrite( 0x5555L, 0x55 ); /* 2nd Cycle */
FlashWrite( 0xAAAAL, 0x90 ); /* 3rd Cycle */
/* Step 2: Read the required function */
if( iFunc == FLASH_READ_MANUFACTURER )
iRetVal = (BYTE) FlashRead( 0x00L ); /* A-1 = A0 = A1 = 0 */
else if( iFunc == FLASH_READ_DEVICE_CODE )
iRetVal = (BYTE) FlashRead( 0x02L ); /* A-1 = 0, A0 = 1, A1 = 0 */
else
iRetVal = FLASH_CMD_INVALID;
/* Step 3: Return to Read mode */
FlashWrite( ANY_ADDR, 0xF0 ); /* Use single instruction cycle method */
#endif
return iRetVal;
}
/*******************************************************************************
* Function: static int FlashDataToggle( DWORD iTimeOut_mS )
*
* Description: The function is used to monitor the Program/Erase Controller during
* erase or program operations. It returns when the Program/Erase Controller has
* completed. In the M29F800A Data Sheet or the M29W800A Data Sheet the Data
* Toggle Flow Chart shows the operation of the function.
* Pseudo Code:
* Step 1: Read DQ6 (into a word)
* Step 2: Read DQ5 and DQ6 (into another word)
* Step 3: If DQ6 did not toggle between the two reads then return FLASH_SUCCESS
* Step 4: Else if DQ5 is zero then operation is not yet complete, goto 1
* Step 5: Else (DQ5 != 0), read DQ6 again
* Step 6: If DQ6 did not toggle between the last two reads then return
* FLASH_SUCCESS
* Step 7: Else return FLASH_TOGGLE_FAIL
*
* Arguments: none
* iTimeOut_mS is the system time out limit.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -