⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cfiscs.c

📁 2410 NOR FLASH的 BSP
💻 C
📖 第 1 页 / 共 4 页
字号:
		 * available. We will spin on this, but only for a maximum of 5 		 * seconds.  We do the timing by taking advantage of the 		 * ever-incrementing flMsecCounter.		 */		 while ((!(CFI_WORD_READ((FlashWPTR)(flashPtr)) & SR_READY)) ||		      (!(CFI_WORD_READ((FlashWPTR)(flashPtr + 1)) & SR_READY)))		     ;	      		 /* Check to see if either part timed out: */		 if ( (!(CFI_WORD_READ(&flashPtr[0x0])     & SR_READY)) ||		    (!(CFI_WORD_READ((&flashPtr[0x1])) & SR_READY)) )		    {		    /* Send read-array command to both parts, abort. */		    CFI_LONG_WRITE(flashPtr, (ULONG) (READ_ARRAY<<16) |READ_ARRAY);		    return(flWriteFault);		    }	      		 /* Now we must write the count value (zero-based, so 0 => 1 word,		  * 1 => 2 words, etc.) for the number of words we intend to 		  * write.  Note that this code always assumes an even number of 		  * words > 0.  Half the words go in the even part, half go in the 		  * odd part.		  */		  CFI_LONG_WRITE(flashPtr, (ULONG)(((wordsThisWrite / 2)  - 1)			  <<16) | ((wordsThisWrite / 2) - 1));  /* both parts */	      		  /* Finally, write the data.  This is easy, because now the 		   * flash parts are seen as memory addresses.		   */		  /* FIXME: This is suboptimal.  It is only writing half the 		   * maximum words that could be written to each part in buffered 		   * write mode. If we double the assignments for wordsWritten & 		   * wordsThisWrite, and halve the assignment for wordsRemaining 		   * each iteration, we can probably make this work optimally.		   * Then we should probably rename some of the variables to 		   * "longsxxx".		   */		  /* last arguement is expected in bytes */		  tffscpyLongs(&((long *)flashPtr)[wordsWritten/2], 			  &((long *)buffer)[wordsWritten/2], wordsThisWrite*2);	      		  /* Now send CONFIRM_WRITE command. */		  CFI_LONG_WRITE(flashPtr, (ULONG) (CONFIRM_WRITE<<16) 				    | CONFIRM_WRITE);  /* both parts */		  /* Flow diagram says to check that status register says 		   * everything is copacetic. */		  while ( (!(CFI_WORD_READ(flashPtr)     & SR_READY)) ||			(!(CFI_WORD_READ((flashPtr + 1)) & SR_READY)) ); 		  		  /* Check to see if either part timed out: */		  if ( (!(CFI_WORD_READ(flashPtr)     & SR_READY)) ||		     (!(CFI_WORD_READ((flashPtr + 1)) & SR_READY)) )		     {		     /* Send read-array command to both parts, abort. */		     CFI_LONG_WRITE(flashPtr, (ULONG)(READ_ARRAY<<16) 					    | READ_ARRAY);		     return(flWriteFault);		     }		  else		     {		     CFI_LONG_WRITE(flashPtr, (ULONG)(READ_ARRAY<<16) 						| READ_ARRAY);		     }	       /* Now verify the write. */	       if (tffscmpWords(&((long *)flashPtr)[wordsWritten/2],		       &((long *)buffer)[wordsWritten/2], wordsThisWrite*2))		   {#ifdef DEBUG_PRINT		   DEBUG_PRINT("Debug: mtd: Buffer write verification failed (interleaved word mode)\n");#endif		   return flWriteFault;		   }	      else		   {#ifdef DEBUG_PRINT		  DEBUG_PRINT("Debug: mtd: Buffer write verification passed (interleaved word mode) at addr 0x%lx\n", 			  (ULONG) flashPtr);#endif		   }		}	      wordsRemaining  -= wordsThisWrite;  /* That many fewer words 						   * to go. */	      wordsWritten    += wordsThisWrite;  /* That many more done. */	      	    }	}    else   /* Part cannot handle writes to buffer, must write one byte at a time. */	{	}   /* Put both devices back into read mode: */       CFI_LONG_WRITE(flashPtr, (ULONG) (READ_ARRAY<<16) | READ_ARRAY);       return status;     }/*************************************************************************** * cfiscsDWordWrite - Write routine for devices on 32 bit bus. * * This code has not been tested since we have not had 32 bit devices we have * had to support. It is provided for consistancy in the hope that it will * reduce the effort needed by the folks who have to support such devices. To * avoid endianness issues commands are written to all four bytes of the * double word.  * * NOMANUAL * */LOCAL FLStatus cfiscsDWordWrite    (    FLFlash vol,    CardAddress address,    const void FAR1 *buffer,    int length,    int mode    )    {    FLStatus status = flOK;    FlashPTR flashPtr;    unsigned int from, eachWrite;    const char FAR1 *temp = (const char FAR1 *)buffer;    /* Set timeout to 5 seconds from now */    unsigned long writeTimeout = flMsecCounter + 5000;    /* Check if address and length are double word aligned */    if ((address & 0x3) || (length & 0x3))	{#ifdef DEBUG_PRINT	DEBUG_PRINT("Debug: Unaligned data - addr 0x%x - len 0x%x\n",(UINT32) address, length);#endif	return flBadParameter;	}    if (flWriteProtected(vol.socket))	return flWriteProtect;#ifdef SOCKET_12_VOLTS    if (thisCFI->vpp)	checkStatus(flNeedVpp(vol.socket));#endif    if (thisCFI->maxBytesWrite > 1) /* multi-byte write supported */	eachWrite = thisCFI->maxBytesWrite * vol.interleaving;    else	eachWrite = 4;	/* Max bus width */    for (from = 0; (int)from < length && status == flOK; from += eachWrite)         {	int thisLength = length - from;	if (thisLength > (int)eachWrite)	    thisLength = eachWrite;	flashPtr = (FlashPTR) flMap(vol.socket, address + from);    	do     	    {	    if ((thisCFI->maxBytesWrite > 1) && 		    ((thisCFI->maxBytesWrite & 0x3) == 0))		*(UINT32 *)flashPtr = (UINT32) ((WRITE_TO_BUFFER << 24) |				      (WRITE_TO_BUFFER << 16) |				      (WRITE_TO_BUFFER << 8)  |				       WRITE_TO_BUFFER);	    else		*(UINT32 *)flashPtr = (UINT32) ((PROGRAM_WORD << 24) |				      (PROGRAM_WORD << 16) |				      (PROGRAM_WORD << 8)  |				       PROGRAM_WORD);    	    } while (!(*flashPtr & SR_READY) && (flMsecCounter < writeTimeout));	if (!(*flashPtr & SR_READY))     	    {#ifdef DEBUG_PRINT	    DEBUG_PRINT("Debug: timeout error in CFISCS write.\n");#endif	    status = flWriteFault;	    }	/* If we are using the WRITE_TO_BUFFER command then we must program	 * the buffer length	 */	if ((thisCFI->maxBytesWrite > 1) && 		    ((thisCFI->maxBytesWrite & 0x3) == 0))		    *flashPtr = (thisLength << 24 | thisLength << 16 				 | thisLength << 8 | thisLength);	tffscpyLongs(flashPtr,temp + from,thisLength);	*(UINT32 *)flashPtr = (UINT32) ((CONFIRM_WRITE << 24) |			      (CONFIRM_WRITE << 16) |			      (CONFIRM_WRITE << 8)  |			       CONFIRM_WRITE);	*(UINT32 *)flashPtr = (UINT32) ((CONFIRM_WRITE << 24) |			      (CONFIRM_WRITE << 16) |			      (CONFIRM_WRITE << 8)  |			       CONFIRM_WRITE);	while (!(*(FlashDPTR) flashPtr & (SR_READY << 24)) && 	        (flMsecCounter < writeTimeout))		    ;	if (!(flMsecCounter < writeTimeout)) 	    {#ifdef DEBUG_PRINT    DEBUG_PRINT("Debug: timeout error in CFISCS write.\n");#endif	    status = flWriteFault;	    }	if (*flashPtr & WSM_ERROR) 	    {#ifdef DEBUG_PRINT    DEBUG_PRINT("Debug: error in CFISCS write.\n");#endif	    status = (*flashPtr & SR_VPP_ERROR) ? flVppFailure : flWriteFault;	    *(UINT32 *)flashPtr = (UINT32) ((CLEAR_STATUS << 24) |				  (CLEAR_STATUS << 16) |				  (CLEAR_STATUS << 8)  |				   CLEAR_STATUS);	    }	*(UINT32 *)flashPtr = (UINT32) ((READ_ARRAY << 24) |		     	      (READ_ARRAY << 16) |			      (READ_ARRAY << 8)  |			       READ_ARRAY);	}#ifdef SOCKET_12_VOLTS    if (thisCFI->vpp)	flDontNeedVpp(vol.socket);#endif    flashPtr = (FlashPTR) flMap(vol.socket, address);    /* verify the data */    if (status == flOK && tffscmpWords((void FAR0 *) flashPtr, (void FAR1 *) buffer,length)) 	{#ifdef DEBUG_PRINT    DEBUG_PRINT("Debug: CFISCS write failed in verification.\n");#endif	status = flWriteFault;	}    return status;    }#ifdef INTERLEAVED_MODE_REQUIRES_32BIT_WRITES/*************************************************************************** * cfiscsInterleavedWordErase - Erase specified number of blocks * * Given the first block and number of contiguous blocks to erase, this  * routine will erase the content of the specified region. The routine does * not support featurees like "Suspend Erase" or "Queued Erase" so the device * stays busy until all specified blocks have been erased. These features need * to be supported by the TrueFFS core to be applicable here. * * NOMANUAL * */LOCAL FLStatus cfiscsInterleavedWordErase    (    FLFlash vol,    int firstEraseBlock,    int numberOfEraseBlocks    )    {    FLStatus status = flOK;       /* unless proven otherwise */    int iBlock;    if (flWriteProtected(vol.socket))        return flWriteProtect;#ifdef SOCKET_12_VOLTS    if (thisCFI->vpp)        checkStatus(flNeedVpp(vol.socket));#endif        for (iBlock = firstEraseBlock; 	 iBlock < firstEraseBlock + numberOfEraseBlocks && status == flOK;	 iBlock++)         {        FLBoolean finished;	FlashWPTR flashPtr = (FlashWPTR) flMap(vol.socket,						iBlock * vol.erasableBlockSize);	CFI_LONG_WRITE(flashPtr, (ULONG) (SETUP_BLOCK_ERASE <<16)|SETUP_BLOCK_ERASE);	CFI_LONG_WRITE(flashPtr, (ULONG) (CONFIRM_ERASE <<16)|CONFIRM_ERASE);	/*   while (flashPtr[ix * thisCFI->interleaveFactor] != 0x80); */	do 	    {	    finished = FALSE;	    if ((flashPtr[0] == SR_READY) &&		    (flashPtr[1] == SR_READY))		{		finished = TRUE;		if (CFI_WORD_READ(flashPtr) & WSM_ERROR) 		    {#ifdef DEBUG_PRINT	  DEBUG_PRINT("Debug: CFISCS erase error on device one\n");#endif		    status = (CFI_WORD_READ(flashPtr) & SR_VPP_ERROR) 				    ?  flVppFailure : flWriteFault;		    CFI_LONG_WRITE(flashPtr, (ULONG) CLEAR_STATUS);		    }		else if (CFI_WORD_READ(&flashPtr[1]) & WSM_ERROR) 		    {#ifdef DEBUG_PRINT	  DEBUG_PRINT("Debug: CFISCS erase error on device two\n");#endif		    status = ((CFI_WORD_READ(&flashPtr[1])) & (SR_VPP_ERROR)) 				    ?  flVppFailure : flWriteFault;		    CFI_LONG_WRITE(flashPtr, (ULONG) (CLEAR_STATUS <<16) & 0xffff0000);		    }		CFI_LONG_WRITE(flashPtr, (ULONG) (READ_ARRAY <<16)|READ_ARRAY);		}	    } while (!finished);        }#ifdef SOCKET_12_VOLTS    if (thisCFI->vpp)        flDontNeedVpp(vol.socket);#endif    return status;    }#else /* !INTERLEAVED_MODE_REQUIRES_32BIT_WRITES *//*************************************************************************** * cfiscsErase - Erase specified number of blocks * * Given the first block and number of contiguous blocks to erase, this  * routine will erase the content of the specified region. The routine does * not support featurees like "Suspend Erase" or "Queued Erase" so the device * stays busy until all specified blocks have been erased. These features need * to be supported by the TrueFFS core to be applicable here. * * Each interleaved device is erased independently. The core does not * compensate for interleaving and expects interleaving to be handled here. * * NOMANUAL * */LOCAL FLStatus cfiscsErase    (    FLFlash vol,    int firstEraseBlock,    int numberOfEraseBlocks    )    {    FLStatus status = flOK;       /* unless proven otherwise */    int iBlock;    if (flWriteProtected(vol.socket))        return flWriteProtect;#ifdef DEBUG_PRINT	logMsg("ERASE: FB = %d, NB = %d\n", firstEraseBlock, numberOfEraseBlocks);#endif#ifdef SOCKET_12_VOLTS    if (thisCFI->vpp)        checkStatus(flNeedVpp(vol.socket));#endif        for (iBlock = firstEraseBlock; 	 iBlock < firstEraseBlock + numberOfEraseBlocks && status == flOK;	 iBlock++)         {	int ix;        FLBoolean finished;	FlashPTR flashPtr = (FlashPTR) flMap(vol.socket,						iBlock * vol.erasableBlockSize);	for(ix=0; ix < vol.interleaving; ix++)	    {	    flashPtr[ix * thisCFI->interleaveFactor] = SETUP_BLOCK_ERASE;	    flashPtr[ix * thisCFI->interleaveFactor] = CONFIRM_ERASE;	    flashPtr[ix * thisCFI->interleaveFactor] = CONFIRM_ERASE;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -