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

📄 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 页
字号:

                        // To see if DQ6 is toggling
                        if ((ulDataWritten & CREATE_MASK_16(bIsPaired, AMD_FLASH_DQ6_X16)) != 
                            (ulDataRead & CREATE_MASK_16(bIsPaired, AMD_FLASH_DQ6_X16))) {
                            // DQ6 is toggling
                            ERRORMSG(ZONE_HAL_ERROR, 
                                (TEXT("Program failure [0x%x] 0x%x : expect 0x%x\r\n"), 
                                ulProgramAddress, ulDataWritten, ulDataToWrite));

                            // Probably due to an attempt to program a 0 to 1.
                            ERRORMSG(ZONE_HAL_ERROR, 
                                (TEXT("DQ6 is toggling. Probably due to an attempt to program a 0 to 1!\r\n"))) ;

                            bSuccess = FALSE;
                        }
                    }
                }
            } // end poll for datum prog done
            
            // Check for prog timeout.
            if (!bDone && (j == g_FlashProgInfo.ulMaxDatumProgTOFactor))
                bSuccess = FALSE;

            if (!bSuccess)
                break;

            // Since the polling needs to occur on the last datum programmed
            // to the buffer the math to advance the pointers
            // for next datum is left until now
            pulData = (ULONG *)((ULONG)pulData + dwBusWidth);
            ulProgramAddress += dwBusWidth;
        } // End prog datum loop
        
        if (g_FlashProgInfo.bUnlockBypassSupport) {
            // Exit bypass mode
            WR_FLASH_REG_INDEXED16(bIsPaired, ulFlashBase, 
                CYCLE_1_ADDR_RESET_BYPASS, CYCLE_1_DATA_RESET_BYPASS);
            WR_FLASH_REG_INDEXED16(bIsPaired, ulFlashBase, 
                CYCLE_2_ADDR_RESET_BYPASS, CYCLE_2_DATA_RESET_BYPASS);
        }
    }
   
    // Use write buffer programming if at least 1 page of data to write
    // and supported (write buffer size non zero).
    // Refer to AMD's "Write buffer programming and page buffer read" 
    // application note for more details.
    if (bSuccess && dwNumPages > 0) {
        // Find start sector address and size
        ulFlashSectorAddr = pFlashDesc->FlashBase;
        bDone = FALSE;
        
        for (ulCurRegion = 0; 
            !bDone && (ulCurRegion < pFlashDesc->Geometry.NumEraseBlockRegions); 
            ulCurRegion++) {

            // Get erase block size
            ulSectorSize = bIsPaired ?  
                2 * pFlashDesc->Geometry.EraseBlockInfo[ulCurRegion].EraseBlockSize * CFI_ERASE_BLOCK_SIZE_MULTP :
                pFlashDesc->Geometry.EraseBlockInfo[ulCurRegion].EraseBlockSize * CFI_ERASE_BLOCK_SIZE_MULTP;
                
            ulNumRegionBlocks = (ULONG)(pFlashDesc->Geometry.EraseBlockInfo[ulCurRegion].NumIdentEraseBlocks + 1);

            for (ulCurBlock = 0; !bDone && (ulCurBlock < ulNumRegionBlocks); ulCurBlock++) {
                DEBUGMSG(ZONE_HAL_FUNCTION, 
                    (TEXT("ulFlashSectorAddr 0x%x\r\n"), ulFlashSectorAddr));

                if ((ulProgramAddress >= ulFlashSectorAddr) &&
                    (ulProgramAddress < (ulFlashSectorAddr + ulSectorSize))) {
                    // Found sector, break
                    bDone = TRUE;
                } else {
                    // Increment flash walk address
                    ulFlashSectorAddr += ulSectorSize;
                }
            }
        }
        
        // Program address may be middle of sector
        ulSectorSize -= ulProgramAddress - ulFlashSectorAddr;

        DEBUGMSG(ZONE_HAL_FUNCTION, (TEXT("Sector 0x%x Size 0x%x\r\n"), 
            ulFlashSectorAddr, ulSectorSize));
        
        ulBufDatumSize = bIsPaired ? (ulWriteBufferSize / sizeof(ULONG)) :
            (ulWriteBufferSize / sizeof(USHORT));

        for (i = 0; bSuccess && i < dwNumPages; i++) {
            bDone = FALSE;
#ifdef DEBUG
            ulPageStart = ulProgramAddress;

            DEBUGMSG(ZONE_HAL_FUNCTION, (TEXT("Page %d\r\n"), i));
            
            for (j = 0; j < ulBufDatumSize; j++)
                DEBUGMSG(ZONE_HAL_FUNCTION, (TEXT("[0x%x] 0x%x\r\n"), 
                    (ulPageStart + j), bIsPaired? *((volatile ULONG *)(ulPageStart + j)) : 
                    *((volatile USHORT *)(ulPageStart + j))));
#endif
            ulDataToWrite = bIsPaired? *(ULONG *)pulData : *(USHORT *)pulData;

            if (bIgnore0to1) {
                for(j = 0; j < (ulBufDatumSize); j++)
                    ulIgnoreBuffer[j] = bIsPaired ? *((volatile ULONG *)ulProgramAddress + j) 
                        : *((volatile USHORT *)ulProgramAddress + j);

                ulDataToWrite &= ulIgnoreBuffer[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_16(bIsPaired, ulProgramAddress, CYCLE_3_DATA_WR_BUFR);
            WR_FLASH_REG_16(bIsPaired, ulProgramAddress, (ulBufDatumSize - 1));
            WR_FLASH_16(bIsPaired, ulProgramAddress, ulDataToWrite);

            for (j = 0; j < (ulBufDatumSize - 1); j++) {
                pulData = (ULONG *)((ULONG)pulData + dwBusWidth);
                ulProgramAddress += dwBusWidth;
                ulDataToWrite = bIsPaired? *(ULONG *)pulData : *(USHORT *)pulData;
                
                if (bIgnore0to1)
                    ulDataToWrite &= ulIgnoreBuffer[j + 1];
                
                WR_FLASH_16(bIsPaired, ulProgramAddress, ulDataToWrite);
            }
            
            WR_FLASH_REG_16(bIsPaired, ulFlashSectorAddr, CYCLE_1_DATA_WR_BUFR_PROGRAM);

#ifdef USE_OS_SERVICES
            for (j = 0; bSuccess && !bDone && j < g_FlashProgInfo.ulMaxBufferProgTOFactor; j++) {
                StallExecution(g_FlashProgInfo.ulBufferProgTO_us);
#else
            j = 0;
            while (!bDone && bSuccess && j++ < CHECK_STATUS_TIMEOUT) {
#endif
                ulDataWritten = bIsPaired? *((volatile ULONG *)(ulProgramAddress)) : 
                    *((volatile USHORT *)(ulProgramAddress));

                DEBUGMSG(ZONE_HAL_FUNCTION, (TEXT("[0x%x] 0x%x : expect 0x%x\r\n"), 
                    ulProgramAddress, ulDataWritten, ulDataToWrite));

                if ((ulDataWritten & CREATE_MASK_16(bIsPaired, AMD_FLASH_DQ7_X16)) == 
                    (ulDataToWrite & CREATE_MASK_16(bIsPaired, AMD_FLASH_DQ7_X16))) {
                    if (ulDataWritten != ulDataToWrite) {
                        ulDataWritten = bIsPaired ? *((volatile ULONG *)(ulProgramAddress)) : 
                            *((volatile USHORT *)(ulProgramAddress));
                            
                        DEBUGMSG(ZONE_HAL_FUNCTION, (TEXT("[0x%x] 0x%x : expect 0x%x\r\n"), 
                            ulProgramAddress, ulDataWritten, ulDataToWrite));

                        if (ulDataWritten == ulDataToWrite) {
                            // page is programmed properly
                            bDone = TRUE;
                        } else {
                            // programming failure
                            ERRORMSG(ZONE_HAL_ERROR, (TEXT("program buffer failure [0x%x] 0x%x : expect 0x%x\r\n"), 
                                ulProgramAddress, ulDataWritten, ulDataToWrite));
                            bSuccess = FALSE;
                        }
                    } else {
                        // page is programmed properly
                        bDone = TRUE;
                    }
                } else {
                    if ((ulDataWritten & CREATE_MASK_16(bIsPaired, AMD_FLASH_DQ5_X16)) == 
                        CREATE_MASK_16(bIsPaired, AMD_FLASH_DQ5_X16)) {
                        ulDataWritten = bIsPaired ? *((volatile ULONG *)(ulProgramAddress)) : 
                            *((volatile USHORT *)(ulProgramAddress));
                            
                        if ((ulDataWritten & CREATE_MASK_16(bIsPaired, AMD_FLASH_DQ7_X16)) != 
                            (ulDataToWrite & CREATE_MASK_16(bIsPaired, AMD_FLASH_DQ7_X16))) {
                            ERRORMSG(ZONE_HAL_ERROR, (TEXT("Program Buffer failure: Poll cnt %d [0x%x] 0x%x : expect 0x%x\r\n"), 
                                j, ulProgramAddress, ulDataWritten, ulDataToWrite)) ;
                            bSuccess = FALSE;
                        }
                    } else if((ulDataWritten & CREATE_MASK_16(bIsPaired, AMD_FLASH_DQ1_X16)) 
                        == CREATE_MASK_16(bIsPaired, AMD_FLASH_DQ1_X16)) {
                        ulDataWritten = bIsPaired ? *((volatile ULONG *)(ulProgramAddress)) : 
                            *((volatile USHORT *)(ulProgramAddress));

                        if ((ulDataWritten & CREATE_MASK_16(bIsPaired, AMD_FLASH_DQ7_X16)) 
                            != (ulDataToWrite & CREATE_MASK_16(bIsPaired, AMD_FLASH_DQ7_X16))) {
                            ERRORMSG(ZONE_HAL_ERROR, (TEXT("Program Buffer aborted: Poll cnt %d [0x%x] 0x%x : expect 0x%x\r\n"), 
                                j, ulProgramAddress, ulDataWritten, ulDataToWrite)) ;
                            bSuccess = FALSE;
                        }
                    }
                }
            } // end page done poll
            
            // Check for prog timeout.
#ifdef USE_OS_SERVICES
            if (!bDone && j == g_FlashProgInfo.ulMaxBufferProgTOFactor)
#else
            if (!bDone && j > CHECK_STATUS_TIMEOUT)
#endif
                bSuccess = FALSE;

            if (!bSuccess)
                break;

            if (bDone) {
#ifdef DEBUG
                for (j = 0; j < ulBufDatumSize; j++)
                    DEBUGMSG(ZONE_HAL_FUNCTION, (TEXT("[0x%x] 0x%x\r\n"), 
                        (ulPageStart + j), bIsPaired? *((volatile ULONG *)(ulPageStart + j)) : 
                        *((volatile USHORT *)(ulPageStart + j)) ));
#endif

                // since the polling needs to occur on the last datum programmed
                // to the buffer the math to advance the pointers
                // for next page is left until now
                ulLen -= ulWriteBufferSize;
                pulData = (ULONG *)((ULONG)pulData + dwBusWidth);
                ulProgramAddress += dwBusWidth;
                ulSectorSize -= ulWriteBufferSize;
                ulProgBytes += ulWriteBufferSize;

                if (ulSectorSize == 0) {
                    // Next sector
                    ulFlashSectorAddr = ulProgramAddress;
                    ulCurBlock++;
                    if (ulCurBlock >= ulNumRegionBlocks) {
                        ulCurRegion++;
                        ulCurBlock = 0;
                        ulSectorSize = bIsPaired 
                            ? 2 * pFlashDesc->Geometry.EraseBlockInfo[ulCurRegion].EraseBlockSize * CFI_ERASE_BLOCK_SIZE_MULTP
                            : pFlashDesc->Geometry.EraseBlockInfo[ulCurRegion].EraseBlockSize * CFI_ERASE_BLOCK_SIZE_MULTP;
                        ulNumRegionBlocks = (ULONG)(pFlashDesc->Geometry.EraseBlockInfo[ulCurRegion].NumIdentEraseBlocks + 1);
                    }
                    DEBUGMSG(ZONE_HAL_FUNCTION, (TEXT("Sector 0x%x Size 0x%x\r\n"), 
                        ulFlashSectorAddr, ulSectorSize));
                }
            }
        }  // end loop pages
    }


    //
    // Tail unaligned bytes programming (Single word programming)
    //
    if (ulBufAlignTailBytes != 0) {
        ulProgBytes = ulBufAlignTailBytes;

        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;
            }

            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.

⌨️ 快捷键说明

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