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

📄 flashloader.c

📁 linked list construct to support any number of Flash banks.
💻 C
📖 第 1 页 / 共 5 页
字号:
                             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 + -