请问FLASH驱的读写!

luhechai   2010-1-25 11:07 楼主

请大家帮我看一下这个函数呀?我有点看不懂,别人写的?谢谢了呀!
请问:这里的地址:        int NewSpareAddr = 2048 + 8*(startSectorAddr%8);
        int NewDataAddr = 256*(startSectorAddr%8);
        int NewSectorAddr = startSectorAddr/8;
为什么要这么算呀?算出的是是什么地址呢?
//ljm change :need to correct ecc
BOOL FMD_ReadSector(SECTOR_ADDR startSectorAddr, LPBYTE pSectorBuff,
                        PSectorInfo pSectorInfoBuff, DWORD dwNumSectors)
{
    DWORD       i;
    BYTE        eccBuf[8];
    ECCRegVal   eccRegVal;
    EccInfo        eccOrigVal;
   // EccInfo  eccNewVal;
    DWORD EccData0,EccData1;
    unsigned short  *pU16Buf;

        int NewSpareAddr = 2048 + 8*(startSectorAddr%8);
        int NewDataAddr = 256*(startSectorAddr%8);
        int NewSectorAddr = startSectorAddr/8;
       
        pU16Buf=(unsigned short *)pSectorBuff;
//        RETAILMSG(1, (TEXT("FlashDrv!FMD!FMD_ReadSector:  startSectorAddr = %x \r\n"), startSectorAddr));
    //  Sanity check
    if (!pSectorBuff && !pSectorInfoBuff || dwNumSectors > 1) {
#ifdef BOOT_LOADER
        EdbgOutputDebugString("Invalid parameters!\r\n");
#else
       RETAILMSG(1, (TEXT("Invalid parameters!\n")));
#endif
#ifndef NOSYSCALL
        SetLastError(ERROR_INVALID_PARAMETER);
#endif
        return FALSE;
    }

        NF_Reset();

    if(!pSectorBuff) {
        //  We are reading spare only
        //RETAILMSG(1, (TEXT("FMD_ReadSectorInfo:  startSectorAddr = %d \r\n"), startSectorAddr));
        NAND_ReadSectorInfo(startSectorAddr, pSectorInfoBuff);

        //  There is no ECC for the sector info, so the read always succeed.
        return TRUE;
    }

//        RETAILMSG(1, (TEXT("FlashDrv!FMD!FMD_ReadSector:  startSectorAddr = %x \r\n"), startSectorAddr));

        GRABMUTEX();

        //  Initialize ECC register
        NF_RSTECC();
        NF_MECC_UnLock();

        //  Enable the chip
        NF_CE_L();
        NF_CLEAR_RB();

        //  Issue command
        NF_CMD(CMD_READ);

        //  Set up address
        NF_ADDR((NewDataAddr)&0xff);
       NF_ADDR(((NewDataAddr)>>8)&0xff);
        NF_ADDR((NewSectorAddr) & 0xff);
        NF_ADDR((NewSectorAddr >> 8) & 0xff);

        NF_ADDR((NewSectorAddr >> 16) & 0xff);

       
        NF_CMD(0x30);

        NF_DETECT_RB();         // Wait tR(max 12us)

        //  BUGBUG, because Media Player for Pocket PC sometimes pass us un-aligned buffer
        //  we have to waste cycle here to work around this problem
        if( ((DWORD) pSectorBuff) & 0x3) {
               
                for(i=0; i<(SECTOR_SIZE/2); i++) {
                        pU16Buf=NF_DATA_R2();
                }
               
                       
        }
       
        else {
                //  The right way.
#ifndef USENANDDMA
                ReadPage512(pSectorBuff, pNFDATA);
#else        // USENANDDMA
#ifdef USESETKMODE
                SetKMode(TRUE);
                v_pINTregs->rSRCPND=BIT_DMA3;        // Init DMA src pending.
#endif        // USESETKMODE
                // Nand to memory dma setting
                v_pDMAregs->rDISRC3  = (unsigned int)NFDATA;         // Nand flash data register
                v_pDMAregs->rDISRCC3 = (0<<1) | (1<<0); //arc=AHB,src_addr=fix
                v_pDMAregs->rDIDST3  = (int)NAND_DMA_BUFFER_PHYS;
                v_pDMAregs->rDIDSTC3 = (0<<1) | (0<<0); //dst=AHB,dst_addr=inc;
                v_pDMAregs->rDCON3   = (1<<31)|(1<<30)|(1<<29)|(1<<28)|(1<<27)|(0<<23)|(1<<22)|(2<<20)|(512/4/4);
                //Handshake,AHB,interrupt,(4-burst),whole,S/W,no_autoreload,word,count=128;

                // DMA on and start.
                v_pDMAregs->rDMASKTRIG3 = (1<<1)|(1<<0);
#ifndef USESETKMODE
                WaitForSingleObject(gDMA3IntrEvent, INFINITE);
                InterruptDone(SYSINTR_DMA3);
#else // USESETKMODE
                while(!(v_pINTregs->rSRCPND & BIT_DMA3));        // Wait until Dma transfer is done.
                v_pINTregs->rSRCPND=BIT_DMA3;
                SetKMode(FALSE);
#endif // USESETKMODE
                memcpy(pSectorBuff, pDMABuffer, 512);
#endif        // USENANDDMA
    }帮我看看这个函数好吗?谢谢了呀!

回复评论 (4)

应该跟你的FLASH的型号、大小来确定的。不同芯片每一页的大小也不一样。建议先认真看看FLASH的资料再看程序
点赞  2010-1-25 14:05
补允:
int NewDataAddr = 256*(startSectorAddr%8); NewDataAddr 这个应该是列地址
int NewSectorAddr = startSectorAddr/8; NewSectorAddr 这个应该是行地址
点赞  2010-1-25 16:26
Flash的存储结构一般分为两部分:main area和spare area,main area存储数据,spare area存储相应Sector的信息,包括badblock,reserved,以及ECC。
从你的代码来看,你的Flash是2k/page,256bytes/sector,8sectors/page.
int NewSpareAddr = 2048 + 8*(startSectorAddr%8);
=>计算spare area区域的地址偏移,列地址spare区域,其中为Sector的信息。
int NewDataAddr = 256*(startSectorAddr%8);
=>计算main area区域sector的偏移,列地址数据区域。
int NewSectorAddr = startSectorAddr/8;
=>计算sector转换为page的地址,也就是行地址。
点赞  2010-1-25 18:39
我从DATASHEET上好像没有看到有sector的概念呀,只有WINCE上才有,不过还是很感谢各位!
点赞  2010-1-26 11:12
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复