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