打印

为什么我的NAND Flash写入速度很慢

[复制链接]
5017|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
maztower|  楼主 | 2012-3-2 19:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
DSP是DM6437
CS3接K9G8G08的NAND Flash,1G*8bit,2KB大页的

用下来感觉写入速度很慢,写一页2KB要2ms
EMIF配置如下:
Uint32 NAND_Init(Int8 CSn)
{
    Uint32 width, *CSRegs;


// EM_CSn enabled

if(CSn == 3)
   
*( volatile Uint32* )( 0x01C40000 + 0x00 ) |= 0 | ( 1 << 10 );

else if(CSn == 4)
   
*( volatile Uint32* )( 0x01C40000 + 0x00 ) |= 0 | ( 1 << 8 );

else if(CSn == 5)
   
*( volatile Uint32* )( 0x01C40000 + 0x00 ) |= 0 | ( 1 << 6 );

    *( volatile Uint32* )( 0x01E00000 + 0x14 ) = 0
            | ( 0 << 31 )           // selectStrobe
            | ( 0 << 30 )           // extWait
            | ( 0 << 26 )           // writeSetup      //   0 ns
            | ( 8 << 20 )           // writeStrobe     //  40 ns
            | ( 2 << 17 )           // writeHold       //  10 ns
            | ( 0 << 13 )           // readSetup       //   0 ns
            | ( 6 << 7 )            // readStrobe      //  25 ns
            | ( 2 << 4 )            // readHold        //  10 ns
            | ( 2 << 2 )            // turnAround      //  10 ns
            | ( 0 << 0 );           // asyncSize       //  8-bit bus

    // Set NAND flash base address
    gNandInfo.flashBase = 0x42000000+0x2000000*(CSn-2);

    //Get the CSOffset (can be 0 through 3 - corresponds with CS2 through CS5)
    gNandInfo.CSOffset = ( (gNandInfo.flashBase & (0x0FFFFFFF)) >> 25) - 1;

    // Setting the nand_width = 0(8 bit NAND) or 1(16 bit NAND). AEMIF CS2 bus Width

//   is fixed in the DM6437 to be 8-bit.
    width = (SYSTEM->BOOTCFG & 0x00010000) >> 16;
    gNandInfo.busWidth = (width)?BUS_16BIT:BUS_8BIT;

    // Setup AEMIF registers for NAND
    CSRegs = (Uint32*) &(AEMIF->AB1CR);
    CSRegs[gNandInfo.CSOffset] = 0x3FFFFFFC | width;        // Set correct ABxCR reg
    AEMIF->NANDFCR |= (0x1 << (gNandInfo.CSOffset));        // NAND enable for CSx
    NAND_ECCReadAndRestart((PNAND_INFO)&gNandInfo);


// Send reset command to NAND

flash_write_cmd( (PNAND_INFO)&gNandInfo, NAND_RESET );


if ( NAND_WaitForRdy(NAND_TIMEOUT) != E_PASS )
        return E_FAIL;



return NAND_GetDetails();
}
写入函数如下
Uint32 NAND_WritePage(Uint32 block, Uint32 page, Uint8 *src) {
volatile
Uint32 eccValue[MAX_NUM_ECCS];
volatile
Uint32 spareValue[MAX_NUM_ECCS];
volatile
Uint8 i;

    flash_write_cmd((PNAND_INFO)&gNandInfo,NAND_LO_PAGE);
    flash_write_cmd((PNAND_INFO)&gNandInfo, NAND_PGRM_START);
    // Write address bytes
    flash_write_addr_cycles((PNAND_INFO)&gNandInfo,block,page);
    // Starting the ECC in the NANDFCR register for CS2(bit no.8)
   NAND_ECCReadAndRestart((PNAND_INFO)&gNandInfo);



// Write data

for (i=0; i<gNandInfo.numOpsPerPage; i++)

{

    flash_write_bytes((PNAND_INFO)&gNandInfo, (void*) src, gNandInfo.bytesPerOp);   

   
   
   

    // Read the ECC value

    eccValue[i] = NAND_ECCReadAndRestart((PNAND_INFO)&gNandInfo);
   
//
    printf("\tWrite eccValue[i] = 0x%8.8X\r\n",eccValue[i]);   


    // Increment the pointer

    src += gNandInfo.bytesPerOp;

}



//  THE FOLLOWING IS COMMENTED SINCE NAND WRITE ECCs DON't APPEAR TO WORK
    // Write spare bytes
    for (i=0; i<MAX_NUM_ECCS; i++) {
       spareValue[i] = 0xFFFFFFFF;
    }

    for (i=0; i<gNandInfo.numOpsPerPage; i++)
    {
        // Swap the bytes for how the ROM needs them
        flash_swap_data((PNAND_INFO)&gNandInfo, (Uint32*)&(eccValue[i]));
        // Place the ECC values where the ROM read routine expects them   
        spareValue[gNandInfo.ECCOffset] = eccValue[i];
        // Actually write the Spare Bytes               
        flash_write_bytes((PNAND_INFO)&gNandInfo, (void*)(spareValue), gNandInfo.spareBytesPerOp);
    }
   

    // Write program end command
    flash_write_cmd((PNAND_INFO)&gNandInfo, NAND_PGRM_END);



// Wait for the device to be ready

if (NAND_WaitForRdy(NAND_TIMEOUT) != E_PASS)

return E_FAIL;

    // Return status check result


return NAND_WaitForStatus(NAND_TIMEOUT);
}

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

36

帖子

1

粉丝