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