📄 flashloader.c
字号:
const STFLASH_InitParams_t *InitParams )
{
stflash_Inst_t *NextElem, *PrevElem; /* search list pointers */
stflash_Inst_t *ThisElem; /* element for this Init */
U32 LocalAccessMask;
U32 DeviceCode = 0xff;
U32 ManufactCode =0xff;
U32 StructSize;
int i;
ST_ErrorCode_t RetVal;
/* Perform necessary validity checks */
if( ( Name == NULL ) || /* NULL address for Name? */
( Name[0] == '\0' ) || /* NUL Name string? */
( strlen( Name ) >=
ST_MAX_DEVICE_NAME ) || /* Name string too long? */
( InitParams == NULL ) || /* NULL address for InitParams? */
(InitParams->DriverPartition == NULL) || /* NULL address for partition */
( InitParams->MinAccessWidth >
InitParams->MaxAccessWidth ) ) /* Minimum > Maximum? */
{
return( ST_ERROR_BAD_PARAMETER );
}
/* Check DeviceType is supported */
switch( InitParams->DeviceType )
{
case STFLASH_M28F411:
/* Check min access width is supported for this device */
switch( InitParams->MinAccessWidth )
{
case STFLASH_ACCESS_08_BITS: /* no break */
case STFLASH_ACCESS_16_BITS: /* no break */
case STFLASH_ACCESS_32_BITS:
break;
default: /* unsupported max width */
return( ST_ERROR_BAD_PARAMETER );
}
break;
case STFLASH_M29W800T:
case STFLASH_M29W800B:
case STFLASH_M29W1600T:
case STFLASH_M29W1600B:
/* Check min access width is supported for this device */
switch( InitParams->MinAccessWidth )
{
case STFLASH_ACCESS_16_BITS:
case STFLASH_ACCESS_32_BITS:
break;
default: /* unsupported max width */
return( ST_ERROR_BAD_PARAMETER );
}
break;
default: /* unsupported device */
return( ST_ERROR_FEATURE_NOT_SUPPORTED );
}
LocalAccessMask =
InitParams->MaxAccessWidth - 1; /* legality checked later */
if( ( InitParams->BaseAddress == NULL ) || /* BaseAddress omitted? */
( ( (U32)InitParams->BaseAddress &
LocalAccessMask ) != 0 ) || /* BaseAddress misalign? */
( ( (U32)InitParams->VppAddress &
LocalAccessMask ) != 0 ) || /* VppAddress misalign? */
( InitParams->NumberOfBlocks == 0 ) || /* no block definition? */
( InitParams->Blocks == NULL ) ) /* Blocks data ptr omitted? */
{
return( ST_ERROR_BAD_PARAMETER );
}
/* commence Read Electronic Signature Command Sequence, storing
the Device and Manufacturer Codes appropriate for MaxAccessWidth
RetVal = GetDeviceInfo( (U32)InitParams->BaseAddress,
InitParams->DeviceType,
InitParams->MaxAccessWidth,
&ManufactCode,
&DeviceCode );
if( RetVal != ST_NO_ERROR )
return RetVal;*/
StructSize = sizeof( stflash_Inst_t ) + /* determine structure size */
( ( InitParams->NumberOfBlocks - 1 ) *
sizeof( STFLASH_Block_t ) );
/* The following section is protected from re-entrancy whilst critical
elements within the stflash_Sentinel linked list are both read and
written. It is not likely that Init will be called from a multi-
tasking environment, but one never knows what a user might try.... */
if( stflash_Sentinel == NULL ) /* first Init instance? */
{
semaphore_init_fifo( &Atomic, 1 ); /* initialize semaphore */
semaphore_wait( &Atomic ); /* atomic sequence start */
stflash_Sentinel = ThisElem = /* keep a note of result */
( stflash_Inst_t* )memory_allocate(
InitParams->DriverPartition, StructSize );
}
else /* already Init'ed */
{
semaphore_wait( &Atomic ); /* atomic sequence start */
for( NextElem = stflash_Sentinel; /* start at Sentinel node */
NextElem != NULL; /* while not at list end */
NextElem = NextElem->Next ) /* advance to next element */
{
if( strcmp( Name,
NextElem->BankName ) == 0 ) /* existing DeviceName? */
{
semaphore_signal( &Atomic ); /* unlock before exit */
return ST_ERROR_ALREADY_INITIALIZED;
}
PrevElem = NextElem; /* keep trailing pointer */
}
PrevElem->Next = ThisElem = /* keep note of result */
( stflash_Inst_t* )memory_allocate(
InitParams->DriverPartition, StructSize );
}
if( ThisElem == NULL ) /* memory_allocate failure? */
{
semaphore_signal( &Atomic ); /* unlock before exit */
return( ST_ERROR_NO_MEMORY );
}
ThisElem->Next = NULL; /* mark as end of list */
strcpy( ThisElem->BankName, Name ); /* retain Name for Opens */
semaphore_signal( &Atomic ); /* end of atomic region */
ThisElem->MagicNumber = MAGIC_NUMBER; /* flag instance as valid */
ThisElem->BankOpen = FALSE; /* not opened yet */
ThisElem->LastOffsP1 = 0; /* calculated below */
ThisElem->DeviceCode = DeviceCode; /* stored for GetParams() */
ThisElem->ManufactCode = ManufactCode; /* stored for GetParams() */
ThisElem->DeviceType = InitParams->DeviceType;
ThisElem->BaseAddress = InitParams->BaseAddress;
ThisElem->VppAddress = InitParams->VppAddress;
ThisElem->MinAccessWidth = InitParams->MinAccessWidth;
ThisElem->MaxAccessWidth = InitParams->MaxAccessWidth;
ThisElem->MinAccessMask = InitParams->MinAccessWidth - 1;
ThisElem->MaxAccessMask = LocalAccessMask;
ThisElem->NumberOfBlocks = InitParams->NumberOfBlocks;
ThisElem->DriverPartition = InitParams->DriverPartition;
/* InitParams->Blocks points to the caller's structure array,
STFLASH_Block_t[]. Whilst its contents are copied into
the current instance, the last address in the bank is
calculated. This simplifies the testing of subsequent
Read/Write calls for legality of Address (offset)
and NumberToRead/Write parameters. */
for( i = 0; i < ThisElem->NumberOfBlocks; i++ )
{
ThisElem->Blocks[i] =
InitParams->Blocks[i];
ThisElem->LastOffsP1 +=
ThisElem->Blocks[i].Length;
}
return( ST_NO_ERROR );
}
/****************************************************************************
Name : STFLASH_Open()
Description : Searches the linked list of Init instances for a string
match with Device/Bank name. The address of the matching
entry is returned as the Handle, simplifying subsequent
accesses.
Parameters : ST_DeviceName_t Name is the Init supplied Flash Bank name,
STFLASH_OpenParams_t *OpenParams is a void *, and
STFLASH_Handle_t *Handle is written through to the caller.
Return Value : ST_ErrorCode_t specified as
ST_ERROR_UNKNOWN_DEVICE Bank name not found
ST_ERROR_BAD_PARAMETER Bad parameter detected
ST_ERROR_NO_FREE_HANDLES Already open
ST_NO_ERROR No errors occurred
See Also : STFLASH_Handle_t
STFLASH_Close()
****************************************************************************/
ST_ErrorCode_t STFLASH_Open( const ST_DeviceName_t Name,
const STFLASH_OpenParams_t *OpenParams,
STFLASH_Handle_t *Handle )
{
stflash_Inst_t *ThisElem;
/* Perform parameter validity checks */
if( ( Name == NULL ) || /* Name ptr uninitialised? */
( Handle == NULL ) ) /* Handle ptr uninitialised? */
{
return( ST_ERROR_BAD_PARAMETER );
}
/* One previous call to Init MUST have had the same Device Name */
for( ThisElem = stflash_Sentinel; /* start at Sentinel node */
ThisElem != NULL; /* while not at list end */
ThisElem = ThisElem->Next ) /* advance to next element */
{
if( strcmp( Name,
ThisElem->BankName ) == 0 ) /* existing DeviceName? */
{
break; /* match, terminate search */
}
}
if( ThisElem == NULL ) /* no Name match found? */
{
return( ST_ERROR_UNKNOWN_DEVICE );
}
if( ThisElem->BankOpen ) /* already open? */
{
return( ST_ERROR_NO_FREE_HANDLES );
}
ThisElem->BankOpen = TRUE; /* flag as open */
*Handle = ( STFLASH_Handle_t )ThisElem; /* write back Handle */
return( ST_NO_ERROR );
}
/****************************************************************************
Name : STFLASH_GetParams()
Description : Returns information on the specified Flash bank, perloined
from the Init call.
Parameters : STFLASH_Handle_t Handle points to the Init instance, plus
STFLASH_GetParams_t *GetParams structure pointer to which
information is written through.
Return Value : ST_ErrorCode_t specified as
ST_ERROR_INVALID_HANDLE
ST_ERROR_BAD_PARAMETER Bad parameter detected
ST_NO_ERROR No errors occurred
See Also : STFLASH_Params_t
STFLASH_Init()
****************************************************************************/
ST_ErrorCode_t STFLASH_GetParams( STFLASH_Handle_t Handle,
STFLASH_Params_t *GetParams )
{
int i;
stflash_Inst_t *ThisElem;
STFLASH_Block_t *Callers_Block_s;
ThisElem = (stflash_Inst_t *)Handle;
if( ThisElem->MagicNumber != MAGIC_NUMBER ) /* rogue Handle value? */
{
return( ST_ERROR_INVALID_HANDLE );
}
if( GetParams == NULL ) /* has caller forgotten ptr? */
{
return( ST_ERROR_BAD_PARAMETER );
}
GetParams->InitParams.BaseAddress = ThisElem->BaseAddress;
GetParams->InitParams.VppAddress = ThisElem->VppAddress;
GetParams->InitParams.MinAccessWidth = ThisElem->MinAccessWidth;
GetParams->InitParams.MaxAccessWidth = ThisElem->MaxAccessWidth;
GetParams->InitParams.NumberOfBlocks = ThisElem->NumberOfBlocks;
GetParams->InitParams.DriverPartition = ThisElem->DriverPartition;
GetParams->DeviceCode = ThisElem->DeviceCode;
GetParams->ManufactCode = ThisElem->ManufactCode;
/* the GetParams caller may not be the same as the Init caller, and
thus may not know the NumberOfBlocks. This potentially makes it
difficult for the caller to dimension the STFLASH_Block_t[]
structure, pointed to by GetParams->InitParams.Blocks element.
A NULL pointer is initially supplied if this is the case, to
indicate that we must not yet copy stflash_Block_s data. */
if( GetParams->InitParams.Blocks != NULL )
{
Callers_Block_s = GetParams->InitParams.Blocks; /* abbreviate ptr */
for( i = 0; i < ThisElem->NumberOfBlocks; i++ )
{
Callers_Block_s[i] = ThisElem->Blocks[i];
}
}
return( ST_NO_ERROR );
}
/****************************************************************************
Name : STFLASH_Read()
Description : Performs a direct read of the number of bytes
requested from the specified Flash bank. The
maximum data width is used for as much of the
operation as possible, provided that BOTH
pointers are aligned on a boundary of the
maximum access width specified during Init.
Parameters : STFLASH_Handle_t Handle identifies the bank,
U32 Offset (from device BaseAddress),
U8 *Buffer into which data is to be written,
U32 NumberToRead (bytes) from Offset, and
U32 *NumberActuallyRead (written through
by the routine).
Return Value : ST_ErrorCode_t specified as
ST_NO_ERROR No errors occurred
ST_ERROR_INVALID_HANDLE Rogue Handle value
ST_ERROR_BAD_PARAMETER Invalid parameter(s)
See Also : STFLASH_Init()
STFLASH_Write()
修改 : 段海云 2002.04.09
由于写操作数据取反 , 所以读操作也要数据取反
****************************************************************************/
ST_ErrorCode_t STFLASH_Read( STFLASH_Handle_t Handle,
U32 Offset,
U8 *Buffer,
U32 NumberToRead,
U32 *NumberActuallyRead )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -