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

📄 amd.c

📁 Microsoft WinCE 6.0 BSP FINAL release source code for use with the i.MX27ADS TO2 WCE600_FINAL_MX27_S
💻 C
📖 第 1 页 / 共 5 页
字号:
    WR_FLASH_REG_INDEXED16(bIsPaired, ulFlashBase, CYCLE_4_ADDR_EXIT_SECSI, CYCLE_4_DATA_EXIT_SECSI);

    // Get driver prog info & store for easy access.
    // Single datum timeouts
    if (pFlashDesc->SysInt.Typical.SnglWordProgTO_us)
        g_FlashProgInfo.ulDatumProgTO_us = (1 << pFlashDesc->SysInt.Typical.SnglWordProgTO_us);
    else
        g_FlashProgInfo.ulDatumProgTO_us = POLLING_WRBYPASS_LIFETIME_US;
    
    if (pFlashDesc->SysInt.Max.SnglWordProgTO_us)
        g_FlashProgInfo.ulMaxDatumProgTOFactor = 1 << pFlashDesc->SysInt.Max.SnglWordProgTO_us;
    else
        g_FlashProgInfo.ulMaxDatumProgTOFactor = POLLING_WRBYPASS_LIFETIME_FACTOR;

    // Write buffer timeouts. 
    if (pFlashDesc->SysInt.Typical.WriteBuffTO_us)
        g_FlashProgInfo.ulBufferProgTO_us = (1 << (pFlashDesc->SysInt.Typical.WriteBuffTO_us));
    else
        g_FlashProgInfo.ulBufferProgTO_us = POLLING_WRBUFR_LIFETIME_US;
    
    if (pFlashDesc->SysInt.Max.WriteBuffTO_us)
        g_FlashProgInfo.ulMaxBufferProgTOFactor = 1 << pFlashDesc->SysInt.Max.WriteBuffTO_us;
    else
        g_FlashProgInfo.ulMaxBufferProgTOFactor = POLLING_WRBUFR_LIFETIME_FACTOR;

    // Sector erase timeouts
    if (pFlashDesc->SysInt.Typical.BlockEraseTO_ms)
        g_FlashProgInfo.ulSectorEraseTO_ms = (1 << pFlashDesc->SysInt.Typical.BlockEraseTO_ms);
    else
        g_FlashProgInfo.ulSectorEraseTO_ms = ERASE_BLOCK_TIMEOUT_MS;
    
    if (pFlashDesc->SysInt.Max.BlockEraseTO_ms)
        g_FlashProgInfo.ulMaxSectorEraseTOFactor = 1 << pFlashDesc->SysInt.Max.BlockEraseTO_ms;
    else
        g_FlashProgInfo.ulMaxSectorEraseTOFactor = ERASE_BLOCK_TIMEOUT_FACTOR;

    // Chip erase timeouts
    if (pFlashDesc->SysInt.Typical.ChipEraseTO_ms)
        g_FlashProgInfo.ulChipEraseTO_ms = (1 << pFlashDesc->SysInt.Typical.ChipEraseTO_ms);
    else
        g_FlashProgInfo.ulChipEraseTO_ms = ERASE_CHIP_TIMEOUT_MS;
    
    if (pFlashDesc->SysInt.Max.ChipEraseTO_ms)
        g_FlashProgInfo.ulMaxChipEraseTOFactor = 1 << pFlashDesc->SysInt.Max.ChipEraseTO_ms;
    else
        g_FlashProgInfo.ulMaxChipEraseTOFactor = ERASE_CHIP_TIMEOUT_FACTOR;
    
    PrintFlashProgInfo(&g_FlashProgInfo);

    // Set device width
    pFlashDesc->DeviceWidth = 16;
    pFlashDesc->PairedFlash = bIsPaired;

#ifdef USE_OS_SERVICES
    // Calibrate CEDDK's counter for the StallExecution() API
    CalibrateStallCounter();
#endif

_exit:
    // exit CFI query mode by issuing a soft reset
    WR_FLASH_REG_INDEXED16(bIsPaired, ulFlashBase, CYCLE_1_ADDR_RESET, CYCLE_1_DATA_RESET);

    DEBUGMSG(ZONE_HAL_FUNCTION, (TEXT("AMD_IsFlashSupported-\r\n")));
    return bSuccess;
}

//-----------------------------------------------------------------------------
//
// Function: AMDx16_Program
//
// Function performs programming of AMD 16bit mode flash devices.
//
// Programming Notes:
// DQ7 indicates the programming is complete however this does not
// guarantee the value that was programmed to the device is correct
// Test to make sure the data programmed is the data that is being
// read from the device.
// ****************************************************************
// Note:
// Just prior to the completion of an Embedded Program or Erase 
// operation, DQ7 may change asynchronously with DQ0朌Q6 while 
// Output Enable (OE#) is asserted low. That is, the device may 
// change from providing status information to valid data on DQ7. 
// Depending on when the system samples the DQ7 output, it may read 
// the status or valid data.  Even if the device has completed 
// the program or erase operation and DQ7 has valid data, the data 
// outputs on DQ0朌Q6 may be still invalid.  Valid data on DQ0朌Q7 
// will appear on successive read cycles.
// **************************************************************** 
// If DQ5 is a 1, it may not necessarily be true that a time out has 
// occurred and the value should be checked once more to see if it 
// was successfully programmed.
// In addition the value that was programmed may have this bit set
// in which case the check for the proper value is also required.
// *****************************************************************
//
// Parameters:
//      pFlashDesc
//          [in] pointer to NOR flash descriptor
//
//      ulStartAddress
//          [in] start address to start programming
//
//      pData
//          [in] ptr to data buffer
//
//      ulLen
//          [in] length of data
//
// Returns:
//      FALSE if programming failed
//
//-----------------------------------------------------------------------------
BOOL AMDx16_Program(NOR_FLASH_DESC *pFlashDesc, ULONG ulProgramAddress, 
    UCHAR *pData, ULONG ulLen, BOOL bIgnore0to1)
{
    ULONG ulFlashBase;
    BOOL bIsPaired;
    ULONG *pulData;
    ULONG i;
    ULONG j;
    ULONG retry;
    DWORD dwBusWidth;
    ULONG ulWriteBufferSize;
    ULONG ulBufAlignBytes;
    ULONG ulBufAlignTailBytes;
    ULONG dwNumPages;
    ULONG ulProgBytes;                                                    
    ULONG ulDataToWrite;
    ULONG ulDataWritten;
    ULONG ulDataRead;
    ULONG ulBufDatumSize;
    ULONG ulFlashSectorAddr;
    ULONG ulSectorSize;
    ULONG ulCurRegion;
    ULONG ulCurBlock;
    ULONG ulNumRegionBlocks;
    BOOL bDone;
    BOOL bSuccess;
    ULONG ulIgnoreBuffer[AMD_BUF_PROG_MAX_DATUM];
#ifdef DEBUG
    ULONG ulPageStart;
#endif

    DEBUGMSG(ZONE_HAL_FUNCTION, (TEXT("AMDx16_Program+: 0x%x 0x%x 0x%x\r\n"),
        ulProgramAddress, pData, ulLen));

    if (!pFlashDesc && !pData) {
    	DEBUGMSG(ZONE_HAL_ERROR, (TEXT("AMDx16_Program: null param\r\n")));
        return FALSE;
    }
        
    bIsPaired = pFlashDesc->PairedFlash;
    ulFlashBase = pFlashDesc->FlashBase;

    // Let the flash know the size of the buffer we plan to send 
    // Note: that this is a 0-based word count and we simulatenously
    // write it to both flash parts (upper and lower).
    ulWriteBufferSize = (pFlashDesc->Geometry.WriteBuffSize) ?
        (bIsPaired ? ((1 << pFlashDesc->Geometry.WriteBuffSize) * 2) : 
        (1 << pFlashDesc->Geometry.WriteBuffSize)) : 0;

    dwNumPages = (ulWriteBufferSize) ? (ulLen / ulWriteBufferSize) : 0;
    ulBufAlignBytes = (ulWriteBufferSize) ? ulProgramAddress % ulWriteBufferSize : 0;
    ulBufAlignTailBytes = (ulWriteBufferSize) ? ((ulLen - ulBufAlignBytes) % ulWriteBufferSize) : 0;

    pulData = (ULONG *)pData;
    bSuccess = TRUE;
    
    DEBUGMSG(ZONE_HAL_INFO, (TEXT("ulWriteBufferSize 0x%x\r\n"), ulWriteBufferSize));

    // Use bypass mode single datum non-buffered program method for
    // 1. no write buffer support or data < 1 page.
    // 2. Align program address to write buffer page
    // Refer to single word program operation in flash specification 
    // for more details
    dwBusWidth = bIsPaired? sizeof(ULONG) : sizeof(USHORT);

    if ((ulBufAlignBytes != 0) || (dwNumPages == 0)) {
        ulProgBytes = (ulWriteBufferSize) ? ulBufAlignBytes : ulLen;

        DEBUGMSG(ZONE_HAL_FUNCTION, (TEXT("dwBufAlignBytes 0x%x dwNumPages 0x%x ulProgBytes 0x%x\r\n"), 
            ulBufAlignBytes, dwNumPages, ulProgBytes));

        for (i = 0; i < ulProgBytes; i += dwBusWidth) {
            bDone = FALSE;
            
            ulDataToWrite = bIsPaired ? *(ULONG *)pulData : *(USHORT *)pulData;
            
            if (bIgnore0to1) {
                ulDataWritten = bIsPaired ? *(volatile ULONG *)ulProgramAddress : 
                    *(volatile USHORT *)ulProgramAddress;

                ulDataToWrite &= ulDataWritten;
            }
            
            DEBUGMSG(ZONE_HAL_FUNCTION, (TEXT("Before: [0x%x] 0x%x\r\n"), 
                ulProgramAddress, bIsPaired ? *((volatile ULONG *)(ulProgramAddress)) : 
                *((volatile USHORT *)(ulProgramAddress))));

            if (g_FlashProgInfo.bUnlockBypassSupport) {
                // Send unlock bypass enter command for first datum
                if (i == 0) {
                    WR_FLASH_REG_INDEXED16(bIsPaired, ulFlashBase, 
                        CYCLE_1_ADDR_UNLOCK_x16, CYCLE_1_DATA_UNLOCK);
                    WR_FLASH_REG_INDEXED16(bIsPaired, ulFlashBase, 
                        CYCLE_2_ADDR_UNLOCK_x16, CYCLE_2_DATA_UNLOCK);
                    WR_FLASH_REG_INDEXED16(bIsPaired, ulFlashBase, 
                        CYCLE_3_ADDR_CMD_x16, CYCLE_3_DATA_UNLOCK_BYPASS);
                }
                WR_FLASH_REG_INDEXED16(bIsPaired, ulFlashBase, 
                    CYCLE_1_ADDR_PROGRAM_BYPASS, CYCLE_1_DATA_PROGRAM_BYPASS);
                WR_FLASH_16(bIsPaired, ulProgramAddress, ulDataToWrite);
            } else {
                // 4 cycle per datum program 
                WR_FLASH_REG_INDEXED16(bIsPaired, ulFlashBase, 
                    CYCLE_1_ADDR_UNLOCK_x16, CYCLE_1_DATA_UNLOCK);
                WR_FLASH_REG_INDEXED16(bIsPaired, ulFlashBase, 
                    CYCLE_2_ADDR_UNLOCK_x16, CYCLE_2_DATA_UNLOCK);
                WR_FLASH_REG_INDEXED16(bIsPaired, ulFlashBase, 
                    UNLOCK_ADDR1_x16, CYCLE_3_DATA_PROGRAM);
                WR_FLASH_16(bIsPaired, ulProgramAddress, ulDataToWrite);
            }
            
            j = 0;
            while (!bDone && bSuccess && (j++ < CHECK_STATUS_TIMEOUT)) {
                // Read 1
                ulDataWritten = bIsPaired ? 
                    *((volatile ULONG *)(ulProgramAddress)) : 
                    *((volatile USHORT *)(ulProgramAddress));

                // D7 will be driven to complement of D7 written to the FLASH.  
                // When it is driven to the value just written,
                // the program operation is complete.
                if ((ulDataWritten & CREATE_MASK_16(bIsPaired, AMD_FLASH_DQ7_X16)) == 
                    (ulDataToWrite & CREATE_MASK_16(bIsPaired, AMD_FLASH_DQ7_X16))) {

                    // DQ7 = valid data, do Read2 and Read 3
                    ulDataWritten = bIsPaired ? 
                            *((volatile ULONG *)(ulProgramAddress)) : 
                            *((volatile USHORT *)(ulProgramAddress));
                        
                    ulDataWritten = bIsPaired ? 
                            *((volatile ULONG *)(ulProgramAddress)) : 
                            *((volatile USHORT *)(ulProgramAddress));

                    // Spec indiates that D7 may be valid while other data lines are still invalid.
                    if (ulDataWritten != ulDataToWrite) {
                        
                        // Try reading again before we report an error.  We want to avoid 
                        // reporting an error here because EBOOT has no recovery and
                        // will terminate the flashing procedure.
                        for (retry = 10; retry > 0 && !bDone; retry--) {
                            
                            ulDataWritten = bIsPaired ? 
                                *((volatile ULONG *)(ulProgramAddress)) : 
                                *((volatile USHORT *)(ulProgramAddress));

                            if (ulDataWritten == ulDataToWrite) {
                                // Programmed properly
                                bDone = TRUE;
                            }
                        }

                        // Now report an error if the value we wanted did not get programmed
                        if (!bDone) {
                            // Programming failure
                            ERRORMSG(ZONE_HAL_ERROR, 
                                (TEXT("Program failure [0x%x] 0x%x : expect 0x%x\r\n"), 
                                ulProgramAddress, ulDataWritten, ulDataToWrite));
                            
                            bSuccess = FALSE;
                        }
                    } else {
                        // Datum is programmed properly
                        bDone = TRUE;
                    }
                } else {
                    if ((ulDataWritten & CREATE_MASK_16(bIsPaired, AMD_FLASH_DQ5_X16)) == 
                        CREATE_MASK_16(bIsPaired, AMD_FLASH_DQ5_X16)) {

                        // Read 2
                        ulDataWritten = bIsPaired ? 
                            *((volatile ULONG *)(ulProgramAddress)) : 
                            *((volatile USHORT *)(ulProgramAddress));

                        // Read 3
                        ulDataRead = bIsPaired ? 
                            *((volatile ULONG *)(ulProgramAddress)) : 
                            *((volatile USHORT *)(ulProgramAddress));

⌨️ 快捷键说明

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