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

📄 flash.c

📁 ARM9基于WINDOWSCE的BSP源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
    return(PASS); 
}

int32 CFI_Read_Block (unsigned16 *address, unsigned16 *data, unsigned32 size)
{
    unsigned32 i = 0;  

    // Size if passed in, in bytes, but must be an integral number of longwords.
    size /= sizeof(unsigned16);

    /* Read the block as standard memory */
    for ( ; i < size; i++)
    {
        *data++ = *address++;   
    }
   
   return(PASS);
}

int32 CFI_Erase_Block (unsigned16 *address)
{
    volatile unsigned16 *vflash = (volatile unsigned16*)address;
    int32 retry = 10, iRet;
  
    CFI_Lock_Bit_Clear( address );
    
    do
    {
        retry--;
        iRet = PASS;
        
        /* Issue single block erase command */
        *vflash = BLOCK_ERASE;

        /* Confirm Action 0xd0 with block address */
        *vflash = PROGRAM_VERIFY;

        if (CFI_Check_Status(vflash)==-1) iRet = FAIL;
         
        /* Reset for Read operation */
        *vflash = READ_ARRAY; 

    } while( (0 < retry) && (FAIL == iRet) );

    CFI_Lock_Bit_Set( address );   
  
  
    return(iRet);   
}


///////////////////////////////////////////////////////////////////
// Bootloader Flash Routines.
//

DWORD ConvertNKAddr(DWORD dwAddr)
{
    // RAM address and forced flash download?
    if( dwAddr < PHYS_FLASH_BASE && g_BldrSettings.nFlags & BLDR_SETTINGS_FLAGS_FSHDLOAD)
    {
        // Convert a physical NK RAM image address to a physical Flash address
        return dwAddr + (NK_FLASH_BASE - NK_RAM_BASE);
    }
    else
    {
        // Probably already a Flash address, or we aren't forcing a download
        return dwAddr;
    }
}

BOOL OEMIsFlashAddr(DWORD dwAddr)
{
    dwAddr = ConvertNKAddr(dwAddr);
    
    // The last few blocks are reserved for eboot settings and the SIB.
    // Don't download and write to these blocks (or anything higher than 
    //  the lowest of these two sections).
    if (dwAddr >= BLDR_FLASH_BASE && dwAddr <= RESERVED_FLASH_BASE )
        return(TRUE);

    return(FALSE);
}

LPBYTE OEMMapMemAddr (DWORD dwImageStart, DWORD dwAddr)
{
    if (OEMIsFlashAddr(dwAddr))
    {
        //
        // This image is destined for flash, cache it in RAM temporarily.
        //
        dwAddr -= dwImageStart;
        dwAddr += FCACHE;
    }

    return((LPBYTE) dwAddr);
}

BOOL OEMWriteFlash(DWORD dwImageStart, DWORD dwImageLength)
{
    DWORD dwFlashAddr, dwExtraBytes = 0;
    LPBYTE pbCache = NULL;
    UCHAR nNumBlocks = 0;
    BOOL bRet = TRUE;

    if( dwImageStart != ConvertNKAddr(dwImageStart) )
    {
        // We are forcing a flash download, so set the jump address 
        dwImageStart = ConvertNKAddr(dwImageStart);
        g_BldrSettings.nJumpAddr = dwImageStart + 0x1000;
    }

    //
    // Make sure the start and end addresses are in flash.
    //
    if (!OEMIsFlashAddr(dwImageStart) || !OEMIsFlashAddr(dwImageStart + dwImageLength - 1))
    {
        EdbgOutputDebugString("ERROR: OEMWriteFlash - not a flash address (0x%x or 0x%x).\r\n", 
                dwImageStart, (dwImageStart + dwImageLength - 1));
        return(FALSE);
    }

    //
    // Make sure image start is on a block boundary.
    //
    if (dwImageStart % ARMVPB_FLASH_BLOCK_SIZE)
    {
        EdbgOutputDebugString("ERROR: OEMWriteFlash - image start address isn't on a flash block boundary (0x%x).\r\n", 
                dwImageStart);
        return(FALSE);
    }

    EdbgOutputDebugString ("INFO: Writing to FLASH: Start = 0x%X  Length = 0x%X...\r\n", 
            dwImageStart, dwImageLength);

    nNumBlocks   = (UCHAR)(dwImageLength / ARMVPB_FLASH_BLOCK_SIZE);
    dwExtraBytes = (dwImageLength % ARMVPB_FLASH_BLOCK_SIZE);
    dwFlashAddr  = dwImageStart;
    pbCache      = OEMMapMemAddr (dwImageStart, dwFlashAddr);

   // apCHARLCD_PrintXY(0, 0, "Flash Writing" );

    //
    // Write flash blocks...
    // 
    while(nNumBlocks && bRet)
    { 
        EdbgOutputDebugString("Writing to Block %d, (%d of %d):\r\n", 
                BLOCK_NUM(dwFlashAddr), 
                BLOCK_NUM(dwFlashAddr) - BLOCK_NUM(dwImageStart) + 1, 
                gnBlocks);

        if (CFI_Write_Block((unsigned16*)dwFlashAddr, 
                            (unsigned16*)pbCache, ARMVPB_FLASH_BLOCK_SIZE) != PASS)
        {
            EdbgOutputDebugString("ERROR: OEMWriteFlash - unable to write to block (block address=0x%x).\r\n", 
                    dwFlashAddr);
            bRet = FALSE;
            break;
        }

        dwFlashAddr += ARMVPB_FLASH_BLOCK_SIZE;
        pbCache = OEMMapMemAddr (dwImageStart, dwFlashAddr);
        --nNumBlocks;
    }

    //
    // If a partial block remains, write it.
    //
    if (dwExtraBytes && bRet)
    {
        EdbgOutputDebugString("Writing %d bytes of last Block %d:\r\n", 
                dwExtraBytes, BLOCK_NUM(dwFlashAddr));

        if (CFI_Write_Block((unsigned16*)dwFlashAddr, (unsigned16*)pbCache, 
                            dwExtraBytes) != PASS)
        {
            EdbgOutputDebugString("ERROR: OEMWriteFlash - unable to write to block (block address=0x%x).\r\n", 
                    dwFlashAddr);
            bRet = FALSE;
        }
    }

//    apCHARLCD_PrintXY(0, 0, "             " );

    return(bRet);
}

//
// This function is called periodically during download to allow us to
// continue the block erasure sequence...
//
void OEMContinueEraseFlash(void)
{
    UCHAR nEraseCount = BLOCK_ERASE_STEP;   // Number of blocks to erase...

    // 
    // Have we finished erasing all the blocks?
    //
    if (!gnBlocks || (gnBlockCount == gnEndBlock))
        return;

    //
    // Erase a few blocks...
    //
    while ((gnBlockCount < gnEndBlock) && nEraseCount)
    {
        if (CFI_Erase_Block((unsigned16*)BLOCK_ADDR(gnBlockCount)) != PASS)
        {
            EdbgOutputDebugString("ERROR: OEMContinueEraseFlash - flash erase error (block number %d).\r\n", 
                    gnBlockCount);
            return;
        }

        ++gnBlockCount;
        --nEraseCount;
    }

    return;
}

BOOL OEMFinishEraseFlash(void)
{
    
    EdbgOutputDebugString("INFO: Finishing flash erase...");

    while(gnBlocks && (gnBlockCount != gnEndBlock))
    {
        OEMContinueEraseFlash();
    }

    EdbgOutputDebugString("last block %d\r\n",gnBlockCount-1);

    return(TRUE);
}

BOOL OEMStartEraseFlash (DWORD dwStartAddr, DWORD dwLength)
{
    //
    // Make sure the start and end addresses are in flash.
    //
    if (!OEMIsFlashAddr(dwStartAddr) || !OEMIsFlashAddr(dwStartAddr + dwLength - 1))
    {
        EdbgOutputDebugString("ERROR: OEMStartEraseFlash - not a flash address (0x%x or 0x%x).\r\n", 
                dwStartAddr, (dwStartAddr + dwLength - 1));
        return(FALSE);
    }

    dwStartAddr = ConvertNKAddr(dwStartAddr);

    // 
    // Make sure start address is block-aligned.
    //
    if (dwStartAddr % ARMVPB_FLASH_BLOCK_SIZE)
    {
        EdbgOutputDebugString("ERROR: OEMStartEraseFlash - start address isn't block aligned (0x%x).\r\n", 
                dwStartAddr);
        return(FALSE);
    }
    if (dwLength & 0x03)
    {
        EdbgOutputDebugString("ERROR: OEMStartEraseFlash - length isn't an integral number of longwords (0x%x).\r\n", 
                dwLength);
        return(FALSE);
    }

    //
    // Determine affected flash blocks.
    //
    gnStartBlock = BLOCK_NUM(dwStartAddr);
    gnEndBlock   = BLOCK_NUM(dwStartAddr + dwLength + (ARMVPB_FLASH_BLOCK_SIZE - 1));
    gnBlocks     = (int)(gnEndBlock - gnStartBlock);
    gnBlockCount = gnStartBlock;

    EdbgOutputDebugString("Erasing flash blocks: start block = %d  end block = %d\r\n", 
            gnStartBlock, gnEndBlock-1);

    return(TRUE);
}

//
///////////////////////////////////////////////////////////////////


⌨️ 快捷键说明

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