📄 adi_am29lv081b.c
字号:
WriteFlash( ulFlashStartAddr + 1, 0xaa );
WriteFlash( ulFlashStartAddr + 2, 0x55 );
WriteFlash( ulFlashStartAddr + 3, 0x10 );
#else
WriteFlash( ulFlashStartAddr + 0, 0x55aa0000 );
WriteFlash( ulFlashStartAddr + 1, 0x1055aa80 );
#endif
// poll until the command has completed
ErrorCode = PollToggleBit(ulFlashStartAddr, 0xFF);
// erase should be complete
return ErrorCode;
}
//----------- E r a s e B l o c k ( ) ----------//
//
// PURPOSE
// Sends an "erase block" command to the flash.
//
// INPUTS
// int nBlock - block to erase
// unsigned long ulStartAddr - flash start address
//
// RETURN VALUE
// ERROR_CODE - value if any error occurs
// NO_ERR - otherwise
ERROR_CODE EraseBlock( int nBlock, unsigned long ulAddr )
{
ERROR_CODE ErrorCode = NO_ERR; //tells us if there was an error erasing flash
unsigned long ulSectStart = 0x0; //stores the sector start offset
unsigned long ulSectEnd = 0x0; //stores the sector end offset(however we do not use it here)
unsigned long ulFlashStartAddr; //flash start address
// get flash start address from absolute address
// The ulAddr should ideally be pointing to the flash start
// address. However we just verify it here again.
ulFlashStartAddr = GetFlashStartAddress(ulAddr);
// Get the sector start offset
// we get the end offset too however we do not actually use it for Erase sector
GetSectorStartEnd( &ulSectStart, &ulSectEnd, nBlock );
// send the erase block command to the flash
#if ( defined(__ADSP21375__) || defined(__ADSP21369__) )
WriteFlash( (ulFlashStartAddr + ulSectStart + 0), 0x00 );
WriteFlash( (ulFlashStartAddr + ulSectStart + 1), 0x00 );
WriteFlash( (ulFlashStartAddr + ulSectStart + 2), 0xaa );
WriteFlash( (ulFlashStartAddr + ulSectStart + 3), 0x55 );
WriteFlash( (ulFlashStartAddr + ulSectStart + 0), 0x80 );
WriteFlash( (ulFlashStartAddr + ulSectStart + 1), 0xaa );
WriteFlash( (ulFlashStartAddr + ulSectStart + 2), 0x55 );
WriteFlash( (ulFlashStartAddr + ulSectStart + 3), 0x30 );
#else
WriteFlash( (ulFlashStartAddr + ulSectStart ), 0x55aa0000 );
WriteFlash( (ulFlashStartAddr + ulSectStart ), 0x3055aa80 );
#endif
// poll until the command has completed
ErrorCode = PollToggleBit(ulFlashStartAddr + ulSectStart, 0xFF);
// block erase should be complete
return ErrorCode;
}
//----------- P o l l T o g g l e B i t ( ) ----------//
//
// PURPOSE
// Polls the toggle bit in the flash to see when the operation
// is complete.
//
// INPUTS
// unsigned long ulAddr - address in flash
//
// RETURN VALUE
// ERROR_CODE - value if any error occurs
// NO_ERR - otherwise
ERROR_CODE PollToggleBit( const unsigned long ulOffset, const unsigned short usValue )
{
bool bError = TRUE; // flag to indicate error
bool bPass = FALSE; // flag indicating passing
int nTimeOut = 0x1FFFFF; // timeout after a while
ERROR_CODE ErrorCode = NO_ERR; // flag to indicate error
unsigned short nReadVal = 0;
while( bError && !bPass )
{
// read the data
ReadFlash( ulOffset, &nReadVal );
// see if the data read == data written
if( (nReadVal & 0xFF) != usValue )
{
// check DQ5 bit for error
if( (nReadVal & 0x20) == 0x20 )
bError = FALSE;
}
else
bPass = TRUE;
}
// if we didn't pass yet then make sure DQ7 was
// not changing simultaneously with DQ5
if( !bPass )
{
ReadFlash( ulOffset, &nReadVal );
// see if the data read == data written
if( (nReadVal & 0xFF) == usValue )
bPass = TRUE;
}
if( !bPass )
ErrorCode = POLL_TIMEOUT;
// we can return
return ErrorCode;
}
//----------- G e t C o d e s ( ) ----------//
//
// PURPOSE
// Sends an "auto select" command to the flash which will allow
// us to get the manufacturer and device codes.
//
// INPUTS
// int *pnManCode - pointer to manufacture code
// int *pnDevCode - pointer to device code
// unsigned long ulStartAddr - flash start address
//
// RETURN VALUE
// ERROR_CODE - value if any error occurs
// NO_ERR - otherwise
ERROR_CODE GetCodes(int *pnManCode, int *pnDevCode, unsigned long ulAddr)
{
unsigned long ulFlashStartAddr; //flash start address
// get flash start address from absolute address
// The ulAddr should ideally be pointing to the flash start
// address. However we just verify it here again.
ulFlashStartAddr = GetFlashStartAddress(ulAddr);
// send the auto select command to the flash
// return to standard operation mode
#if ( defined(__ADSP21375__) || defined(__ADSP21369__) )
WriteFlash( ulFlashStartAddr + 0, 0x00 );
WriteFlash( ulFlashStartAddr + 1, 0xAA );
WriteFlash( ulFlashStartAddr + 2, 0x55 );
WriteFlash( ulFlashStartAddr + 3, 0x90 );
#else
WriteFlash( ulFlashStartAddr, 0x9055aa00 );
#endif
// read the manufacturer code
ReadFlash( ulFlashStartAddr , (unsigned short *)pnManCode );
*pnManCode &= 0x00FF;
ReadFlash( ulFlashStartAddr + 1, (unsigned short *)pnDevCode );
*pnDevCode &= 0x00FF;
// we need to issue another command to get the part out
// of auto select mode so issue a reset which just puts
// the device back in read mode
ResetFlash(ulAddr);
// ok
return NO_ERR;
}
//----------- G e t S e c t o r N u m b e r ( ) ----------//
//
// PURPOSE
// Gets a sector number based on the offset.
//
// INPUTS
// unsigned long ulAddr - absolute address
// int *pnSector - pointer to sector number
//
// RETURN VALUE
// ERROR_CODE - value if any error occurs
// NO_ERR - otherwise
ERROR_CODE GetSectorNumber( unsigned long ulAddr, int *pnSector )
{
int nSector = 0;
// get offset from absolute address
unsigned long ulMask = 0x3fffff; //offset mask
unsigned long ulOffset= ulAddr & ulMask; //offset
// determine the sector
nSector = ulOffset & 0xffff0000;
nSector = ulOffset >> 16;
nSector = nSector & 0x000f;
// if it is a valid sector, set it
if ( (nSector >= 0) && (nSector < NUM_SECTORS) )
*pnSector = nSector;
// else it is an invalid sector
else
return INVALID_SECTOR;
// ok
return NO_ERR;
}
//----------- G e t S e c t o r S t a r t E n d ( ) ----------//
//
// PURPOSE
// Gets a sector start and end address based on the sector number.
//
// INPUTS
// unsigned long *ulStartOff - pointer to the start offset
// unsigned long *ulEndOff - pointer to the end offset
// int nSector - sector number
//
// RETURN VALUE
// ERROR_CODE - value if any error occurs
// NO_ERR - otherwise
ERROR_CODE GetSectorStartEnd( unsigned long *ulStartOff, unsigned long *ulEndOff, int nSector )
{
// The blocks in the flash memory are asymmetrically arranged
// Thus we use block sizes to determine the block addresses
unsigned long ulBlkSize = 0x10000; // Block size 0
// block is in main flash
if( ( nSector < NUM_SECTORS ))
{
*ulStartOff =(nSector * ulBlkSize );
*ulEndOff = ( (*ulStartOff) + ulBlkSize ) - 1;
}
// no such sector
else
return INVALID_SECTOR;
// ok
return NO_ERR;
}
//----------- G e t F l a s h S t a r t A d d r e s s ( ) ----------//
//
// PURPOSE
// Gets flash start address from an absolute address.
//
// INPUTS
// unsigned long ulAddr - absolute address
//
// RETURN VALUE
// unsigned long - Flash start address
unsigned long GetFlashStartAddress( unsigned long ulAddr)
{
ERROR_CODE ErrorCode = NO_ERR; //tells us if there was an error erasing flash
unsigned long ulFlashStartAddr; //flash start address
unsigned long ulSectStartAddr; //sector start address
unsigned long ulSectEndAddr; //sector end address
unsigned long ulMask; //offset mask
// get flash start address from absolute address
GetSectorStartEnd( &ulSectStartAddr, &ulSectEndAddr, (NUM_SECTORS-1));
ulMask = ~(ulSectEndAddr);
ulFlashStartAddr = ulAddr & ulMask;
return(ulFlashStartAddr);
}
//----------- R e a d F l a s h ( ) ----------//
//
// PURPOSE
// Reads a value from an address in flash.
//
// INPUTS
// unsigned long ulAddr - the address to read from
// int pnValue - pointer to store value read from flash
//
// RETURN VALUE
// ERROR_CODE - value if any error occurs
// NO_ERR - otherwise
ERROR_CODE ReadFlash( const unsigned long ulAddr, unsigned short *pusValue )
{
#if ( defined(__ADSP21375__) || defined(__ADSP21369__) )
// set our flash address to where we want to read
volatile unsigned short *pFlashAddr = (volatile unsigned short *)(ulAddr);
// read the value
*pusValue = (unsigned short)*pFlashAddr;
#else //if __ADSP21364__ & __ADSP21262__
//--- Core-Driven Transfer to read from Parallel Port ---//
unsigned short val = 0;
unsigned short ReadEnable = PPDUR32 | PPEN; // enables PP read
// Initiate parallel port registers ---/
*pEMPP = 0; // setup DMA modify
*pEIPP = ulAddr ;// setup DMA destination
*pICPP = 1;
*pECPP = 1;
// Initialize PPCTL register with appropriate settings
*pPPCTL = ReadEnable; // enables PP read
// Wait two core-clock cycles after PPEN is set for the parallel
// port to fetch two 32-bit data words
asm("nop;");
asm("nop;");
val = (*pRXPP) & 0xFF;
// poll to ensure parallel port has completed the transfer
do{
;}
while( (*pPPCTL & (PPBS|PPDS)) != 0);
// Fetch data from RXPP
*pPPCTL = 0; // clear dma control register
*pusValue = val; // put the value at the location passed in
#endif
// ok
return NO_ERR;
}
//----------- W r i t e F l a s h ( ) ----------//
//
// PURPOSE
// Write a value to an address in flash.
//
// INPUTS
// unsigned long ulAddr - address to write to
// unsigned short nValue - value to write
//
// RETURN VALUE
// ERROR_CODE - value if any error occurs
// NO_ERR - otherwise
ERROR_CODE WriteFlash( const unsigned long ulAddr, const unsigned short usValue )
{
#if ( defined(__ADSP21375__) || defined(__ADSP21369__) )
// set the address
volatile unsigned short *pFlashAddr = (volatile unsigned short *)(ulAddr);
*pFlashAddr = usValue;
#else // if __ADSP21364__ or __ADSP21262__
//--- Core-Driven Transfer to write to Parallel Port ---//
unsigned short WriteEnable = PPDUR32 | PPTRAN | PPEN; // enables PP write
//--- Initiate parallel port registers ---/
*pEMPP = 0;
*pEIPP = ulAddr;
*pICPP = 1;
*pECPP = 4;
// Initialize PPCTL register with appropriate settings
*pPPCTL = WriteEnable;
*pTXPP = usValue;
*pPPCTL |= PPDEN|PPEN;
//poll to ensure parallel port has completed the transfer
do{
;}
while( (*pPPCTL & (PPBS|PPDS)) != 0);
// clear dma control register
*pPPCTL = 0;
#endif
// ok
return NO_ERR;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -