📄 k9f2808u0c.c
字号:
* modes : EDC flag etc. * * Returns: * FLStatus: 0 on success, otherwise failed. * *----------------------------------------------------------------------*/static FLStatus nandMTDRead( FLFlash vol, CardAddress address, /* target flash address */ void FAR1 *buffer, /* source RAM buffer */ int length, /* bytes to write */ int modes) /* Overwrite, EDC flags etc. */{ char FAR1 *temp; int readNow; /* read in sectors; first and last might be partial */ int page = modes & EXTRA ? 16 : 512; readNow = page - ((unsigned short)address & (page - 1)); temp = (char FAR1 *)buffer; #ifdef DEBUG_PRINT DEBUG_PRINT("READ: address = 0x%x, length = 0x%x\n", address, length);#endif for ( ; length > 0 ; ) { if (readNow > length) /* 如果要读的长度小于一个页面中偏移地址之后的空间大小 */ readNow = length; /* 那要读的就是该长度 04-8-6 */ /* turn off EDC on partial block read*/ /* 如果要读的长度大于一个页面的大小,就先读一个页面 */ checkStatus( readOnePage(&vol, address, temp, readNow, (readNow != SECTOR_SIZE ? (modes & ~EDC) : modes)) ); /*mode??*/ length -= readNow; address += readNow; temp += readNow; /* align at sector */ readNow = page; } return flOK ;}/*---------------------------------------------------------------------- * n a n d W r i t e * * Write some data to the flash. This routine will be registered as the * write routine for this MTD. * * Parameters: * vol : Pointer identifying drive * address : Address of sector to write to. * buffer : buffer to write from. * length : number of bytes to write (up to sector size). * modes : OVERWRITE, EDC flags etc. * * Returns: * FLStatus: 0 on success, otherwise failed. * *----------------------------------------------------------------------*/static FLStatus nandMTDWrite( FLFlash vol, CardAddress address, /* target flash address*/ const void FAR1 *buffer, /* source RAM buffer */ int length, /* bytes to write */ int modes) /* Overwrite, EDC flags etc.*/{ int writeNow; const char FAR1 *temp; FLStatus status = flOK; #ifdef VERIFY_AFTER_WRITE CardAddress saveAddress = address; unsigned short flReadback[SECTOR_SIZE / sizeof(unsigned short)];#endif /* write in sectors; first and last might be partial*/ int page = modes & EXTRA ? 16 : 512; writeNow = page - ((unsigned short)address & (page - 1)); temp = (const char FAR1 *)buffer; for ( ; length > 0 ; ) { if (writeNow > length) writeNow = length; /* turn off EDC on partial block write*/ status = writeOnePage(&vol, address, temp, writeNow, writeNow != 512 ? (modes & ~EDC) : modes); if (status != flOK) break;#ifdef VERIFY_AFTER_WRITE status = readOnePage (&vol, address, (char FAR1 *)flReadback, writeNow, (writeNow != SECTOR_SIZE ? (modes & ~EDC) : modes)); if((status != flOK) || (tffscmp(temp, flReadback, writeNow) != 0)) { status = flWriteFault; break; }#endif length -= writeNow; address += writeNow; temp += writeNow; /* align at sector */ writeNow = page; } return flOK ;}/*---------------------------------------------------------------------- * n a n d E r a s e * * Erase number of blocks. This routine will be registered as the * erase routine for this MTD. * * Parameters: * vol : Pointer identifying drive * blockNo : First block to erase. * blocksToErase : Number of blocks to erase. * * Returns: * FLStatus : 0 on success, otherwise failed. * *----------------------------------------------------------------------*/static FLStatus nandMTDErase( FLFlash vol, int blockNo, /* start' block (0 .. chipNoOfBlocks-1)*/ int blocksToErase) /* Number of blocks to be erased */{ int i; FLStatus status = flOK; if (flWriteProtected(vol.socket)) return flWriteProtect; /* blockNo %= thisVars->noOfBlocks; */ /* within flash device */ if ( blockNo + blocksToErase > thisVars->noOfBlocks ) /* accross device boundary */ return flBadParameter; #ifdef DEBUG_PRINT DEBUG_PRINT("firstBlock = 0x%x, numOfBlock = 0x%x\n", blockNo, blocksToErase); #endif for ( i=0; i < blocksToErase; i++, blockNo++ ) { unsigned short pageNo = blockNo * PAGES_PER_BLOCK ; NAND_EN(); WRITE_COMMAND(SETUP_ERASE); WRITE_ADDRESS((unsigned char)pageNo); /* A9 ~ A16 */ WRITE_ADDRESS((unsigned char)(pageNo >> 8)); /* A17 ~ A22 */ WRITE_COMMAND(CONFIRM_ERASE); waitForReady(); if(readStatus() & FAIL) { status = flWriteFault; /* erase operation failed */ } #ifdef DEBUG_PRINT DEBUG_PRINT("ERASE: blockNo = 0x%x\n", blockNo); #endif if (status != flOK) /* reset flash device and abort */ { #ifdef DEBUG_PRINT DEBUG_PRINT("Debug: erase failed in K9F2808U0C.\n"); #endif WRITE_COMMAND(RESET_FLASH); waitForReady(); break ; } } /* block loop */ return status;}/*---------------------------------------------------------------------- * c d s n M a p * * Map through buffer. This routine will be registered as the map * routine for this MTD. * * Parameters: * vol : Pointer identifying drive * address : Flash address to be mapped. * length : number of bytes to map. * * Returns: * Pointer to the buffer data was mapped to. * *----------------------------------------------------------------------*/static void FAR0 * nandMTDMap ( FLFlash vol, CardAddress address, int length ){/* nandMTDRead(&vol,address,thisBuffer,length, 0); vol.socket->remapped = TRUE; return (void FAR0 *)thisBuffer;*/ if(bufferPtr==0) { ptr=mapBuffer1; bufferPtr=1; } else if(bufferPtr==1) { ptr=mapBuffer2; bufferPtr=2; } else { ptr=mapBuffer3; bufferPtr=0; } nandMTDRead(&vol,address,ptr,length, 0); vol.socket->remapped = TRUE; return (void FAR0 *)ptr; }/*---------------------------------------------------------------------- * i s K n o w n M e d i a * * Check if this flash media is supported. Initialize relevant fields * in data structures. * * Parameters: * vol : Pointer identifying drive * vendorId_P : vendor ID read from chip. * chipId_p : chip ID read from chip. * dev : dev chips were accessed before this one. * * Returns: * TRUE if this media is supported, FALSE otherwise. * *----------------------------------------------------------------------*/static FLBoolean isKnownMedia( FLFlash vol, unsigned short vendorId_p, unsigned short chipId_p, int dev ){ if (dev == 1) { thisVars->vendorID = vendorId_p; /* remember for next chips */ thisVars->chipID = chipId_p; if (vendorId_p == 0xEC) /* Samsung */ { switch (chipId_p) { case 0x73: /*8M*/ vol.type = K9F2808U0C_FLASH; vol.flags |= BIG_PAGE; vol.chipSize = 0x1000000L; return TRUE; } } } else /* dev != 0*/ if( (vendorId_p == thisVars->vendorID) && (chipId_p == thisVars->chipID) ) return TRUE ; return FALSE ;}/*---------------------------------------------------------------------- * r e a d F l a s h I D * * Read vendor and chip IDs, count flash devices. Initialize relevant * fields in data structures. * * Parameters: * vol : Pointer identifying drive * interface : Pointer to window. * dev : dev chips were accessed before this one. * * Returns: * TRUE if this media is supported, FALSE otherwise. * *----------------------------------------------------------------------*/static int readFlashID (FLFlash vol, int dev){ unsigned char vendorId_p=0, chipId_p=0; NAND_EN(); WRITE_COMMAND(RESET_FLASH); waitForReady(); WRITE_COMMAND(READ_ID); WRITE_ADDRESS(0x00); /* Address. 1cycle */ waitForReady(); READ_DATA(vendorId_p); READ_DATA(chipId_p); #ifdef DEBUG_PRINT DEBUG_PRINT("Debug: Entering K9F6408U0C readFlashID routine--0xEC73:vendor = %x,chipID = %x\n",vendorId_p,chipId_p);#endif /*NAND_DIS();*/ if (isKnownMedia(&vol, vendorId_p, chipId_p, dev) != TRUE) /* no chip or diff.*/ return FALSE ; /* type of flash */ /* set flash parameters*/ if ( dev == 1 ) { thisVars->pageAreaSize = 0x100 * vol.interleaving; thisVars->pageSize = (vol.flags & BIG_PAGE ? 0x200 : 0x100) * vol.interleaving; thisVars->tailSize = (vol.flags & BIG_PAGE ? 16 : 8) * vol.interleaving; thisVars->pageMask = thisVars->pageSize - 1 ; vol.erasableBlockSize = PAGES_PER_BLOCK * thisVars->pageSize; thisVars->noOfBlocks = (unsigned short)( (vol.chipSize * vol.interleaving) / vol.erasableBlockSize ) ; } return TRUE ;}/*---------------------------------------------------------------------- * n a n d M T D I d e n t i f y * * Identify flash. This routine will be registered as the * identification routine for this MTD. * * Returns: * FLStatus: 0 on success, otherwise failed. * *----------------------------------------------------------------------*/FLStatus nandMTDIdentify(FLFlash vol){#ifdef DEBUG_PRINT DEBUG_PRINT("Debug: Entering K9F2808U0C identification routine\n");#endif flashInit(); flSetWindowBusWidth(vol.socket,8); /* use 8-bits */ flSetWindowSpeed(vol.socket,120); /* 120 nsec. */ flSetWindowSize(vol.socket,2); /* 4 KBytes */ vol.mtdVars = &mtdVars[flSocketNoOf(vol.socket)]; /* get pointer to buffer (we assume SINGLE_BUFFER is not defined) */ thisVars->buffer = flBufferOf(flSocketNoOf(vol.socket)); vol.interleaving = 1; vol.noOfChips = 1; /* 以1为起始 */ if(readFlashID(&vol, vol.noOfChips) != TRUE ) { #ifdef DEBUG_PRINT DEBUG_PRINT("Debug: did not identify K9F2808U0C flash media.\n"); #endif return flUnknownMedia; } /* Register our flash handlers */ vol.write = nandMTDWrite; vol.erase = nandMTDErase; vol.read = nandMTDRead; vol.map = nandMTDMap; vol.flags |= SUSPEND_FOR_WRITE;#ifdef DEBUG_PRINT DEBUG_PRINT("Debug: Identified K9F2808U0C.\n");#endif return flOK;}#if FALSE/*---------------------------------------------------------------------- * f l R e g i s t e r N A N D * * Registers this MTD for use * * Parameters: * None * * Returns: * FLStatus : 0 on success, otherwise failure *----------------------------------------------------------------------*/FLStatus flRegisterNAND(void){ if (noOfMTDs >= MTDS) return flTooManyComponents; mtdTable[noOfMTDs++] = nandMTDIdentify; return flOK;}#endif /* FALSE */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -