📄 adi_am29lv081b.c
字号:
/*******************************************************************************/
/* */
/* (C) Copyright 2004 - Analog Devices, Inc. All rights reserved. */
/* */
/* FILE: a d i _ a m 2 9 l v 0 8 1 b . c ( ) */
/* */
/* CHANGES: 1.00.0 - initial release */
/* */
/* PURPOSE: Performs operations specific to the AM29LV081B flash device */
/* while adhering to the adi device drivers model. */
/* */
/*******************************************************************************/
//----- I n c l u d e s -----//
#include "adi_am29lv081b.h"
#include "util.h"
#include "Errors.h"
#ifdef __ADSP21262__
#include <def21262.h>
#include <Cdef21262.h>
#elif __ADSP21364__
#include <def21364.h>
#include <Cdef21364.h>
#elif __ADSP21375__
#include <def21375.h>
#include <Cdef21375.h>
#endif
//---- c o n s t a n t d e f i n i t i o n s -----//
static char *pFlashDesc = "AMD AM29LV081B";
static char *pDeviceCompany = "AMD";
//---- F u n c t i o n P r o t o t y p e s ----//
// (for Helper Functions) //
static ERROR_CODE EraseFlash(unsigned long ulStartAddr);
static ERROR_CODE EraseBlock( int nBlock, unsigned long ulStartAddr );
static ERROR_CODE GetCodes(int *pnManCode, int *pnDevCode, unsigned long ulStartAddr);
static ERROR_CODE GetSectorNumber( unsigned long ulAddr, int *pnSector );
static ERROR_CODE GetSectorStartEnd( unsigned long *ulStartOff, unsigned long *ulEndOff, int nSector );
static ERROR_CODE PollToggleBit( const unsigned long ulOffset, const unsigned short usValue );
static ERROR_CODE ReadFlash(const unsigned long ulOffset, unsigned short *pusValue );
static ERROR_CODE ResetFlash(unsigned long ulStartAddr);
static ERROR_CODE WriteFlash(const unsigned long ulOffset, const unsigned short usValue );
static unsigned long GetFlashStartAddress( unsigned long ulAddr);
// Open a device
static u32 adi_pdd_Open(
ADI_DEV_MANAGER_HANDLE ManagerHandle, // device manager handle
u32 DeviceNumber, // device number
ADI_DEV_DEVICE_HANDLE DeviceHandle, // device handle
ADI_DEV_PDD_HANDLE *pPDDHandle, // pointer to PDD handle location
ADI_DEV_DIRECTION Direction, // data direction
void *pEnterCriticalArg, // enter critical region parameter
ADI_DMA_MANAGER_HANDLE DMAHandle, // handle to the DMA manager
ADI_DCB_HANDLE DCBHandle, // callback handle
ADI_DCB_CALLBACK_FN DMCallback // device manager callback function
);
// Close a device
static u32 adi_pdd_Close(
ADI_DEV_PDD_HANDLE PDDHandle
);
// Read from a device
static u32 adi_pdd_Read( ADI_DEV_PDD_HANDLE PDDHandle,
ADI_DEV_BUFFER_TYPE BufferType,
ADI_DEV_BUFFER *pBuffer);
// Write to a device
static u32 adi_pdd_Write( ADI_DEV_PDD_HANDLE PDDHandle,
ADI_DEV_BUFFER_TYPE BufferType,
ADI_DEV_BUFFER *pBuffer);
// Control the device
static u32 adi_pdd_Control( ADI_DEV_PDD_HANDLE PDDHandle,
u32 Command,
void *pArg);
ADI_DEV_PDD_ENTRY_POINT ADIAM29LV081BEntryPoint =
{
adi_pdd_Open,
adi_pdd_Close,
adi_pdd_Read,
adi_pdd_Write,
adi_pdd_Control
};
// ---- P h y s i c a l D e v i c e D r i v e A P I f u n c t i o n s ----//
//----------- a d i _ p d d _ C l o s e ( ) ----------//
//
// PURPOSE
// This function opens the AM29LV081B flash device for use.
//
// INPUTS
// ManagerHandle - device manager handle
// DeviceNumber - device number
// DeviceHandle - device handle
// PDDHandle - This is the handle used to identify the device
// Direction - data direction
// *pEnterCriticalArg - enter critical region parameter
// DMAHandle - handle to the DMA manager
// DCBHandle - callback handle
// DMCallback - device manager callback function
//
// RETURN VALUE
// Result
u32 adi_pdd_Open( // Open a device
ADI_DEV_MANAGER_HANDLE ManagerHandle, // device manager handle
u32 DeviceNumber, // device number
ADI_DEV_DEVICE_HANDLE DeviceHandle, // device handle
ADI_DEV_PDD_HANDLE *pPDDHandle, // pointer to PDD handle location
ADI_DEV_DIRECTION Direction, // data direction
void *pEnterCriticalArg, // enter critical region parameter
ADI_DMA_MANAGER_HANDLE DMAHandle, // handle to the DMA manager
ADI_DCB_HANDLE DCBHandle, // callback handle
ADI_DCB_CALLBACK_FN DMCallback ) // device manager callback function
{
// check for errors if required
#ifdef ADI_AM29LV081B_ERROR_CHECKING_ENABLED
if (DeviceNumber > 0) // check the device number
return (ADI_DEV_RESULT_BAD_DEVICE_NUMBER);
if (Direction != ADI_DEV_DIRECTION_BIDIRECTIONAL) // check the direction
return (ADI_DEV_RESULT_DIRECTION_NOT_SUPPORTED);
#endif
return (NO_ERR);
}
//----------- a d i _ p d d _ C l o s e ( ) ----------//
//
// PURPOSE
// This function closes the AM29LV081B flash device.
//
// INPUTS
// PDDHandle - This is the handle used to identify the device
//
// RETURN VALUE
// Result
u32 adi_pdd_Close(ADI_DEV_PDD_HANDLE PDDHandle) // PDD handle
{
return (NO_ERR);
}
//----------- a d i _ p d d _ R e a d ( ) ----------//
//
// PURPOSE
// Provides buffers to the AM29LV081B flash device for reception
// of inbound data.
//
// INPUTS
// PDDHandle - This is the handle used to identify the device
// BufferType - This argument identifies the type of buffer: one-
// dimentional, two-dimensional or circular
// *pBuffer - The is the address of the buffer or first buffer in
// a chain of buffers
//
// RETURN VALUE
// Result
u32 adi_pdd_Read( ADI_DEV_PDD_HANDLE PDDHandle,
ADI_DEV_BUFFER_TYPE BufferType,
ADI_DEV_BUFFER *pBuffer)
{
ADI_DEV_1D_BUFFER *pBuff1D;
unsigned short *pusValue;
unsigned long *pulAbsoluteAddr;
u32 Result;
// cast our buffer to a 1D buffer
pBuff1D = (ADI_DEV_1D_BUFFER*)pBuffer;
// cast our data buffer
pusValue = (unsigned short *)pBuff1D->Data;
// cast our offset
pulAbsoluteAddr = (unsigned long *)pBuff1D->pAdditionalInfo;
Result = ReadFlash( *pulAbsoluteAddr, pusValue );
return(Result);
}
//----------- a d i _ p d d _ W r i t e ( ) ----------//
//
// PURPOSE
// Provides buffers to the AM29LV081B flash device for transmission
// of outbound data.
//
// INPUTS
// PDDHandle - This is the handle used to identify the device
// BufferType - This argument identifies the type of buffer: one-
// dimentional, two-dimensional or circular
// *pBuffer - The is the address of the buffer or first buffer in
// a chain of buffers
//
// RETURN VALUE
// Result
u32 adi_pdd_Write( ADI_DEV_PDD_HANDLE PDDHandle,
ADI_DEV_BUFFER_TYPE BufferType,
ADI_DEV_BUFFER *pBuffer)
{
ADI_DEV_1D_BUFFER *pBuff1D; // buffer pointer
short *psValue; // stores the value to be written to flash
unsigned long *pulAbsoluteAddr; // the absolute address to write
unsigned long ulFlashStartAddr; // flash start address
u32 Result; // error code returned
// cast our buffer to a 1D buffer
pBuff1D = (ADI_DEV_1D_BUFFER*)pBuffer;
// cast our data buffer
psValue = (short *)pBuff1D->Data;
// cast our offset
pulAbsoluteAddr = (unsigned long *)pBuff1D->pAdditionalInfo;
// get flash start address from absolute address
ulFlashStartAddr = GetFlashStartAddress(*pulAbsoluteAddr);
#if ( defined(__ADSP21375__) || defined(__ADSP21369__) )
WriteFlash( *pulAbsoluteAddr, 0x00 );
WriteFlash( *pulAbsoluteAddr, 0xaa );
WriteFlash( *pulAbsoluteAddr, 0x55 );
WriteFlash( *pulAbsoluteAddr, 0xa0 );
#else
WriteFlash( ulFlashStartAddr , 0xa055aa00 );
#endif
// program our actual value now
Result = WriteFlash( *pulAbsoluteAddr, *psValue);
// make sure the write was successful
Result = PollToggleBit(*pulAbsoluteAddr, *psValue & 0xff);
return(Result);
}
//----------- a d i _ p d d _ C o n t r o l ( ) ----------//
//
// PURPOSE
// This function sets or detects a configuration parameter
// for the AM29LV081B flash device.
//
// INPUTS
// PDDHandle - This is the handle used to identify the device
// Command - This is the command identifier
// *pArg - The is the address of command-specific parameter
//
// RETURN VALUE
// Result
u32 adi_pdd_Control( ADI_DEV_PDD_HANDLE PDDHandle,
u32 Command,
void *pArg)
{
ERROR_CODE ErrorCode = NO_ERR;
COMMAND_STRUCT *pCmdStruct = (COMMAND_STRUCT *)pArg;
// switch on the command
switch ( Command )
{
// erase all
case CNTRL_ERASE_ALL:
ErrorCode = EraseFlash(pCmdStruct->SEraseAll.ulFlashStartAddr);
break;
// erase sector
case CNTRL_ERASE_SECT:
ErrorCode = EraseBlock( pCmdStruct->SEraseSect.nSectorNum, pCmdStruct->SEraseSect.ulFlashStartAddr );
break;
// get manufacturer and device codes
case CNTRL_GET_CODES:
ErrorCode = GetCodes((int *)pCmdStruct->SGetCodes.pManCode, (int *)pCmdStruct->SGetCodes.pDevCode, (unsigned long)pCmdStruct->SGetCodes.ulFlashStartAddr);
break;
case CNTRL_GET_DESC:
//Filling the contents with data
//pCmdStruct->SGetDesc.pTitle = pEzKitTitle;
pCmdStruct->SGetDesc.pDesc = pFlashDesc;
pCmdStruct->SGetDesc.pFlashCompany = pDeviceCompany;
break;
// get sector number based on address
case CNTRL_GET_SECTNUM:
ErrorCode = GetSectorNumber( pCmdStruct->SGetSectNum.ulOffset, (int *)pCmdStruct->SGetSectNum.pSectorNum );
break;
// get sector number start and end offset
case CNTRL_GET_SECSTARTEND:
ErrorCode = GetSectorStartEnd( pCmdStruct->SSectStartEnd.pStartOffset, pCmdStruct->SSectStartEnd.pEndOffset, pCmdStruct->SSectStartEnd.nSectorNum );
break;
// reset
case CNTRL_RESET:
ErrorCode = ResetFlash(pCmdStruct->SReset.ulFlashStartAddr);
break;
// no command or unknown command do nothing
default:
// set our error
ErrorCode = UNKNOWN_COMMAND;
break;
}
// return
return(ErrorCode);
}
//----- H e l p e r F u n c t i o n s ----//
//----------- R e s e t F l a s h ( ) ----------//
//
// PURPOSE
// Sends a "reset" command to the flash.
//
// INPUTS
// unsigned long ulStartAddr - flash start address
//
// RETURN VALUE
// ERROR_CODE - value if any error occurs
// NO_ERR - otherwise
ERROR_CODE ResetFlash(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 reset command to the flash
// return to standard operation mode
#if ( defined(__ADSP21375__) || defined(__ADSP21369__) )
WriteFlash( ulFlashStartAddr + 0, 0x00 );
WriteFlash( ulFlashStartAddr + 1, 0x00 );
WriteFlash( ulFlashStartAddr + 2, 0x00 );
WriteFlash( ulFlashStartAddr + 3, 0xF0 );
#else
WriteFlash( ulFlashStartAddr, 0xF0000000 );
#endif
// reset should be complete
return NO_ERR;
}
//----------- E r a s e F l a s h ( ) ----------//
//
// PURPOSE
// Sends an "erase all" command to the flash.
//
// INPUTS
// unsigned long ulStartAddr - flash start address
//
// RETURN VALUE
// ERROR_CODE - value if any error occurs
// NO_ERR - otherwise
ERROR_CODE EraseFlash(unsigned long ulAddr)
{
ERROR_CODE ErrorCode = NO_ERR; // tells us if there was an error erasing flash
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);
// erase contents in Main Flash Array
#if ( defined(__ADSP21375__) || defined(__ADSP21369__) )
WriteFlash( ulFlashStartAddr + 0, 0x00 );
WriteFlash( ulFlashStartAddr + 1, 0x00 );
WriteFlash( ulFlashStartAddr + 2, 0xaa );
WriteFlash( ulFlashStartAddr + 3, 0x55 );
WriteFlash( ulFlashStartAddr + 0, 0x80 );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -