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

📄 flashloader.c

📁 linked list construct to support any number of Flash banks.
💻 C
📖 第 1 页 / 共 5 页
字号:
{
    #pragma ST_device( ReadAddr08 )
    #pragma ST_device( ReadAddr16 )
    #pragma ST_device( ReadAddr32 )

    stflash_Inst_t  *ThisElem;

    U32             LastReadP1;     /* last address to be read plus one */
    U32             LeftToRead;     /* number of bytes left to read */
    U32             OperaWidth;     /* Operation Width (in bytes) */

    U8              *TmpAddress;    /* for recasting */
    U8              *AccessAddr;    /* BaseAddress + Offset */
    U8              *DestBuff08;    /* Buffer */
    U16             *DestBuff16;    /* (U16*)Buffer */
    U32             *DestBuff32;    /* (U32*)Buffer */
    volatile U8     *ReadAddr08;    /*  8 bit read access address */
    volatile U16    *ReadAddr16;    /* 16 bit read access address */
    volatile U32    *ReadAddr32;    /* 32 bit read access address */
    ST_ErrorCode_t  RetValue = ST_NO_ERROR;  /* Default return code */


    /* Perform necessary validity checks */

    ThisElem = (stflash_Inst_t *)Handle;

    if( ThisElem->MagicNumber != MAGIC_NUMBER )     /* rogue Handle value? */
    {
        *NumberActuallyRead = 0;
        return( ST_ERROR_INVALID_HANDLE );
    }

    if( NumberToRead == 0 )                         /* no bytes to read? */
    {
        *NumberActuallyRead = 0;
        return( ST_NO_ERROR );                      /* nothing to do, OK */
    }

    LastReadP1 = Offset + NumberToRead;             /* last read addr+1 */
    if( ( LastReadP1 > ThisElem->LastOffsP1 ) ||    /* Past end of device? */
        ( Buffer == NULL ) )                        /* no buffer address? */
    {
        *NumberActuallyRead = 0;
        return( ST_ERROR_BAD_PARAMETER );
    }

    TmpAddress = (U8*)ThisElem->BaseAddress;        /* cast for addition */
    AccessAddr = TmpAddress + Offset;               /* first read addr */

    /* Check addresses and length for MIN alignment. 
       Takes no action for byte minimum, 
       but will kick-in if minimum access width is bigger than a byte. */
    if( ( ( (U32)AccessAddr &
        ThisElem->MinAccessMask ) != 0 ) ||       /* source off MIN align? */
        ( ( (U32)Buffer &
        ThisElem->MinAccessMask ) != 0 ) ||       /* dest. off MIN align? */
        ( ( NumberToRead &
        ThisElem->MinAccessMask ) != 0 ) )        /* length off MIN align? */
    {
        *NumberActuallyRead = 0;
        return( ST_ERROR_BAD_PARAMETER );         /* sorry, can't do */
    }

    TmpAddress = (U8*)ThisElem->BaseAddress;      /* cast for computation */
    AccessAddr = TmpAddress + Offset;             /* form first read addr */

    /* determine the (initial) access width to be used */
    if( ( ( (U32)AccessAddr &
            ThisElem->MaxAccessMask ) == 0 ) &&  /* source on MAX boundary? */
        ( ( (U32)Buffer &
            ThisElem->MaxAccessMask ) == 0 ) &&  /* dest. on MAX boundary? */
        ( NumberToRead >=
          ThisElem->MaxAccessWidth ) )           /* enough bytes for MAX? */
    {
        OperaWidth  = ThisElem->MaxAccessWidth;  /* high speed operation */
    }
    else
    {
        OperaWidth  = ThisElem->MinAccessWidth;  /* lower speed operation */
    }

    /* set up destination buffer and read pointers for all widths */
    DestBuff08  = Buffer;
    DestBuff16  = (U16*)Buffer;
    DestBuff32  = (U32*)Buffer;
    ReadAddr08  = AccessAddr;
    ReadAddr16  = (U16*)AccessAddr;
    ReadAddr32  = (U32*)AccessAddr;

    /* Clear Status Register (precautionary) */
    /* and commence Read Memory Array Command Sequence */

    switch( ThisElem->MaxAccessWidth )          /* use maximum access width */
    {
        case STFLASH_ACCESS_08_BITS:
            *ReadAddr08 = CLEAR_SR08;
            *ReadAddr08 = READ_MA08;
            break;

        case STFLASH_ACCESS_16_BITS:
            *ReadAddr16 = CLEAR_SR16;
            *ReadAddr16 = READ_MA16;
            break;

        case STFLASH_ACCESS_32_BITS:
            *ReadAddr32 = CLEAR_SR32;
            *ReadAddr32 = READ_MA32;
            break;

        default:
            break;
    }

    LeftToRead = NumberToRead;                 /* initialize counter */

    while( LeftToRead > 0 )                    /* whilst more bytes to read */
    {
        switch( OperaWidth )                   /* choose appropriate size */
        {
            case STFLASH_ACCESS_08_BITS:

                *DestBuff08++ = *ReadAddr08++;      /* read from Flash */
                LeftToRead   -= OperaWidth;

                break;


            case STFLASH_ACCESS_16_BITS:
                while( LeftToRead >= OperaWidth )
                {
					/*
					 * 数据取反
					 */
                    *DestBuff16++ = ~(*ReadAddr16++);  /* read from Flash */
                    LeftToRead   -= OperaWidth;
                }

                if( LeftToRead > 0 )                /* any left to read? */
                {
                    OperaWidth =                    /* drop down to MIN */
                        ThisElem-> MinAccessWidth;

                    /* transfer ptrs */
                    ReadAddr08 = (U8*)ReadAddr16;
                    DestBuff08 = (U8*)DestBuff16;
                 }

                break;


            case STFLASH_ACCESS_32_BITS:

                while( LeftToRead >= OperaWidth )
                {
                    *DestBuff32++ = *ReadAddr32++;  /* read from Flash */
                    LeftToRead   -= OperaWidth;
                }
                if( LeftToRead > 0 )                /* any left to read? */
                {
                    OperaWidth =                    /* drop down to MIN */
                        ThisElem-> MinAccessWidth;
                    
                    /* transfer ptrs */
                    ReadAddr08 = (U8*)ReadAddr32;
                    ReadAddr16 = (U16*)ReadAddr32;
                    DestBuff08 = (U8*)DestBuff32;
                    DestBuff16 = (U16*)DestBuff32;
                }

                break;


            default:

                *NumberActuallyRead =           /* this SHOULDN'T happen */
                    NumberToRead - LeftToRead;
                return( ST_ERROR_BAD_PARAMETER );
        }
    }

    /* write back to caller number of bytes read */
    *NumberActuallyRead = NumberToRead - LeftToRead;  
 
    return RetValue;
}


/****************************************************************************
Name         : STFLASH_Erase()

Description  : Performs a direct erase of a whole block.  For the ST
               device supported, the Offset specified MUST fall on one
               of the declared block boundaries, and the NumberToErase
               MUST also match the Length declared for that block.
               The call will FAIL if these pre-conditions are not met.

Parameters   : STFLASH_Handle_t Handle identifies the Flash bank,
               U32 Offset (from device BaseAddress), and
               U32 NumberToErase (bytes to erase).

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)
               ST_ERROR_TIMEOUT            Erase Timeout limit reached
               STFLASH_ERROR_ERASE         Error during Erase sequence
               STFLASH_ERROR_VPP_LOW       Vpp below minimum

See Also     : STFLASH_Init()
               STFLASH_Write()
 ****************************************************************************/

/* HCX 修改8M/16M FLASH 块擦除操作的驱动 2002。12。27 */

ST_ErrorCode_t STFLASH_Erase( STFLASH_Handle_t Handle,
                              U32              Offset[],
                              U32              NumberToErase,
							  U32              iTotalBlockNum )
{
    #pragma ST_device( EraseAddr32 )
    #pragma ST_device( EraseAddr16 )
    #pragma ST_device( EraseAddr08 )
    #pragma ST_device( Code1Addr )
    #pragma ST_device( Code2Addr )
    #pragma ST_device( Code1Addr16 )
    #pragma ST_device( Code2Addr16 )

    int i;

    stflash_Inst_t  *ThisElem;

    ST_ErrorCode_t  RetValue = ST_NO_ERROR;

    BOOL DoingErase = TRUE;         /* until completion or time-out */
    BOOL EraseLow   = FALSE;
    BOOL EraseHigh  = FALSE;
    BOOL ParamsValid = FALSE;       /* initial assumption */
    U32  CurrOffset = 0;            /* start at BaseAddress */

    U8              *TempAddress;   /* for recasting */
    U8              *Access_Addr;   /* BaseAddress + Offset */
    volatile U32    *EraseAddr32;   /* 32 bit erase access address */
    volatile U16    *EraseAddr16;   /* 16 bit erase access address */
    volatile U8     *EraseAddr08;   /*  8 bit erase access address */
    volatile U32    *Code1Addr;
    volatile U32    *Code2Addr;
    volatile U16    *Code1Addr16;
    volatile U16    *Code2Addr16;
    U32             Code1Data;
    U32             Code2Data;
    U16             Code1Data16;
    U16             Code2Data16;

    clock_t         StartTime;      /* time at which erase started */
    clock_t         Curr_Time;      /* current (low-priority) time */
    const clock_t   ClocksPerSecond = ST_GetClocksPerSecond();
                                    /* Delay used to avoid busy wait */
    U32 Data1, Data2;

    /* Perform necessary validity checks */

    ThisElem = (stflash_Inst_t *)Handle;

    if( ThisElem->MagicNumber != MAGIC_NUMBER )     /* rogue Handle value? */
    {
        return( ST_ERROR_INVALID_HANDLE );
    }

    /* walk through STFLASH_Block_t array checking
       that both Offset and NumberToErase are legal */
    for( i = 0; i < ThisElem->NumberOfBlocks; i++ )
    {
        if( ( CurrOffset == Offset[0] ) &&             /* start match? */
            ( ThisElem->Blocks[i].Length ==
                            NumberToErase ) )       /* length match? */
        {
            ParamsValid = TRUE;
            break;                                  /* stop searching */
        }

        CurrOffset += ThisElem->Blocks[i].Length;   /* next block */
    }

    if( !ParamsValid )                   /* start/length mismatch block? */
    {
        return( ST_ERROR_BAD_PARAMETER );
    }

	if( ThisElem->DeviceType == STFLASH_M29W800T || ThisElem->DeviceType == STFLASH_M29W800B ||\
		ThisElem->DeviceType == STFLASH_M29W1600T || ThisElem->DeviceType == STFLASH_M29W1600B )
    {
        switch( ThisElem->MaxAccessWidth )
        {
            case STFLASH_ACCESS_32_BITS:
                /* Setup access pointers */
                Code1Addr   = (U32*)ThisElem->BaseAddress + 
                  M29W800T_CODED_ADDR1;
                Code2Addr   = (U32*)ThisElem->BaseAddress + 
                  M29W800T_CODED_ADDR2;
                Code1Data   = M29W800T_CODED_DATA1;
                Code2Data   = M29W800T_CODED_DATA2;
                EraseAddr32 = (U32*)( (U32)ThisElem->BaseAddress + Offset[0] );
                
                /* Start Erase */
                StartTime = time_now();       /* ticks at Erase start */
                
                /* Cycle 1 - Coded cycle 1 */
                *Code1Addr   = Code1Data;
                
                /* Cycle 2 - Coded cycle 2 */
                *Code2Addr   = Code2Data;
                
                /* Cycle 3 - Block Erase Command */
                *Code1Addr   = M29W800T_BLOCK_ERASE;
                
                /* Cycle 4 - Coded cycle 1 */
                *Code1Addr   = Code1Data;
                
                /* Cycle 5 - Coded cycle 2 */
                *Code2Addr   = Code2Data;
                
                /* Cycle 6 - Erase Confirm */
                *EraseAddr32 = M29W800T_ERASE_CONFIRM;
                
                /* Read DQ2, DQ5 & DQ6 */
                Data1 = *EraseAddr32 & M29W800T_DQ256_MASK;
                while( ( ( EraseLow  == FALSE ) || 
                         ( EraseHigh == FALSE ) ) && \
					   RetValue != ST_NO_ERROR )
                  {
                    /* It typically takes 2 to 3 seconds to erase a block
                       (depending on size) so deschedule to avoid busy wait */
                    task_delay( ClocksPerSecond );
                    
                    /* Read DQ2, DQ5 & DQ6 on all chips */
                    Data2 = *EraseAddr32 & M29W800T_DQ256_MASK;
                    
                    /* Are DQ2 and DQ6 toggling? */
                    if( Data1 == Data2 )
                      {
                        EraseLow = EraseHigh = TRUE;    /* Erase was successful */
                      }
  
					  /* High or Low DQ5 = 1? */
                    else if( ( Data2 & M29W800T_DQ5_MASK ) != 0 )  

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -