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

📄 cfiscs.c

📁 这是WINDRIVER公司所开发的针对freescale公司最新的powerpc系列MPC8560的针对vxworks的bsp。对做powerpc嵌入式的很有用了。
💻 C
📖 第 1 页 / 共 4 页
字号:
 * cfiscsByteWrite - byte write routine * * This routine is intended to be registered as the write routine in systems * that have byte wide devices interleaved or devices that are in byte mode. * * NOMANUAL * */LOCAL FLStatus cfiscsByteWrite    (    FLFlash vol,    CardAddress address,    const void FAR1 *buffer,    int length,    int mode    )    {    FLStatus status = flOK;    FlashPTR flashPtr;    unsigned int i, from, eachWrite;    const char FAR1 *temp = (const char FAR1 *)buffer;    /* Set timeout to 5 seconds from now */    unsigned long writeTimeout = flMsecCounter + 5000;#ifdef DEBUG_PRINT    DEBUG_PRINT("Debug: entering CFISCS byte Write routine.\n");#endif    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 = vol.interleaving;    for (from = 0; (int)from < length && status == flOK; from += eachWrite) 	{	int thisLength = length - from;	FlashPTR currPtr;	unsigned tailBytes, lengthByte;	if (thisLength > (int)eachWrite)	    thisLength = eachWrite;	lengthByte = thisLength / vol.interleaving;	tailBytes = thisLength % vol.interleaving;	flashPtr = (FlashPTR) flMap(vol.socket, address + from);	for (i = 0, currPtr = flashPtr;	    ((int)i < vol.interleaving) && ((int)i < thisLength);	    i++, currPtr++) 	    {	    do 		{		*currPtr = WRITE_TO_BUFFER;		} while (!(*currPtr & SR_READY) && 			(flMsecCounter < writeTimeout));	    if (!(*currPtr & SR_READY)) 		{#ifdef DEBUG_PRINT		DEBUG_PRINT("Debug: timeout error in CFISCS write.\n");#endif		status = flWriteFault;		}	    *currPtr = i < tailBytes ? lengthByte : lengthByte - 1;	    }	tffscpy((unsigned long FAR0 *) flashPtr,temp + from,thisLength);	for (i = 0, currPtr = flashPtr;		((int)i < vol.interleaving) && ((int)i < thisLength);		i++, currPtr++)	    *currPtr = CONFIRM_WRITE;	for (i = 0, currPtr = flashPtr;		((int)i < vol.interleaving) && ((int)i < thisLength);		i++, currPtr++) 	    {	    while (!(*currPtr & SR_READY) && (flMsecCounter < writeTimeout))		;	    if (!(*currPtr & SR_READY)) 		{#ifdef DEBUG_PRINT		DEBUG_PRINT("Debug: timeout error in CFISCS write.\n");#endif		status = flWriteFault;		}	    if (*currPtr & WSM_ERROR) 		{#ifdef DEBUG_PRINT		DEBUG_PRINT("Debug: error in CFISCS write.\n");#endif		status = (*currPtr & SR_VPP_ERROR) ? 			    flVppFailure : flWriteFault;		*currPtr = CLEAR_STATUS;		}	    *currPtr = 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 && tffscmp((void FAR0 *) flashPtr,buffer,length))     	{#ifdef DEBUG_PRINT    	DEBUG_PRINT("Debug: CFISCS write failed in verification.\n");#endif    	status = flWriteFault;    	}    return status;    }/***************************************************************************** * cfiscsWordWrite - write routine for 16 bit devices  *                                                                      * Write a block of bytes to Flash in a word-mode.                     *                                                                    * This routine will be registered as the MTD flash.write routine    *                                                                  * Parameters:                                                     *      vol             : Pointer identifying drive               *      address         : Card address to write to               *      buffer          : Address of data to write              *      length          : Number of bytes to write             *      mode            : write mode (overwrite yes/no)       *                                                           * Returns:                                                 *      FLStatus        : 0 on success, failed otherwise   * * NOMANUAL * */LOCAL FLStatus cfiscsWordWrite    (    FLFlash vol,    CardAddress address,    const void FAR1 *buffer,    int length,    int mode    )    {    FLStatus status = flOK;    FlashWPTR flashPtr;    int from, eachWrite,test;    const char FAR1 *temp = (const char FAR1 *)buffer;    /* Set timeout to 5 seconds from now */    unsigned long writeTimeout = flMsecCounter + 5000;#ifdef DEBUG_PRINT    DEBUG_PRINT("Debug: entering CFISCS Word Write routine.\n");#endif    if (flWriteProtected(vol.socket))	return flWriteProtect;    if ((length & 1) || (address & 1)) /* Only write words on word-boundary */	return flBadParameter;#ifdef SOCKET_12_VOLTS    if (thisCFI->vpp)	checkStatus(flNeedVpp(vol.socket));#endif    if (thisCFI->maxBytesWrite > 1) /* multi-byte write supported */	eachWrite = thisCFI->maxBytesWrite / 2;   /* we are counting words */    else	eachWrite = 1;    test=0;    /* we assume that the interleaving is 1. */    for (from = 0; (from < length / 2) && (status == flOK); from += eachWrite) 	{	int thisLength = (length / 2) - from;	if (thisLength > eachWrite)	    thisLength = eachWrite;	flashPtr = (FlashWPTR)flMap(vol.socket, address + from * 2);	if (thisLength == 1) 	    {	    *flashPtr = (PROGRAM << 8) | PROGRAM;	    *flashPtr = (* ( (FlashWPTR) (temp + from * 2) )) ;	    } 		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 (*flashPtr & WSM_ERROR) 	    {#ifdef DEBUG_PRINT	    DEBUG_PRINT("Debug: CFISCS write error.\n");#endif	    status = (*flashPtr & SR_VPP_ERROR) ? flVppFailure : flWriteFault;	    *flashPtr = CLEAR_STATUS;	    }	*flashPtr = (READ_ARRAY<<8)|READ_ARRAY;        WRS_ASM("eieio");        if (*flashPtr != (* ( (FlashWPTR) (temp + from * 2) )))	  {	    from-=eachWrite;	    test++;	  }	if(test>100)	   {	     from+=eachWrite;	     test=0;	   }        }#ifdef SOCKET_12_VOLTS    if (thisCFI->vpp)	flDontNeedVpp(vol.socket);#endif    flashPtr = (FlashWPTR) flMap(vol.socket, address);    /* verify the data */    if (status == flOK && tffscmp((void FAR0 *) flashPtr,buffer,length)) 	{#ifdef DEBUG_PRINT	DEBUG_PRINT("Debug: CFISCS write failed in verification.\n");#endif	status = flWriteFault;	}    return status;    }#if 0/****************************************************************************** * cfiscsInterleavedWordWrite - write routine 16 bit interleaved devices *                                                                  * This routine will be registered as the MTD flash.write routine       *                                                                     * Parameters:                                                        *      vol             : Pointer identifying drive                  *      address         : Card address to write to                  *      buffer          : Address of data to write                 *      length          : Number of bytes to write                *      mode            : write mode (overwrite yes/no)          *                                                              * Returns:                                                    *      FLStatus        : 0 on success, failed otherwise      * * NOMANUAL * */LOCAL FLStatus cfiscsInterleavedWordWrite    (    FLFlash vol,    CardAddress address,    const void FAR1 *buffer,    int length,    int mode    )    {    FLStatus status = flOK;    FlashWPTR flashPtr;    unsigned long maxWordsPerWrite,  /* Number of words per WRITE/WRITE_BUFFER 					command. */                wordsWritten,      /* total written so far */                wordsRemaining,    /* number of words left to go */                wordsThisWrite;    /* number of words */ #ifdef DEBUG_PRINT    DEBUG_PRINT("Debug: entering CFISCS Interleaved Word Write routine.\n");#endif    if (flWriteProtected(vol.socket))	return flWriteProtect;    if ((length & 1) || (address & 1))  /* Only write whole words, 					   only on word-boundary */	return flBadParameter;#ifdef SOCKET_12_VOLTS    if (thisCFI->vpp)	checkStatus(flNeedVpp(vol.socket));#endif    if (thisCFI->maxBytesWrite > 1) /* multi-byte write supported? */        maxWordsPerWrite = thisCFI->maxBytesWrite;    else	maxWordsPerWrite = 1;  /* Part can only handle single-byte writes. */    flashPtr = (FlashWPTR)flMap(vol.socket, address);    /* Now program the part: */    if (maxWordsPerWrite > 1)  /* Part can handle writes of multiple 				  words to buffer */	{        wordsWritten = 0;        wordsRemaining = length / 2;  /* Number of words left to program into 					 a part, convert bytes to words. */        while (wordsRemaining > 0)	    {	    /* Figure out how many words we need to write.  This will either 	     * be the max allowed (maxWordsPerWrite), or what's left over at 	     * the end (wordsRemaining).  Make it extra-cryptic with the	     * ?: operator.	     */	     wordsThisWrite = (wordsRemaining > maxWordsPerWrite) 					 ? maxWordsPerWrite : wordsRemaining;	  	    /* if we dont have enough aligned data to use a buffered write 	     * we just use a normal write */	    if ( (wordsThisWrite <2 ) && (wordsThisWrite > 0))		{		/* data is a 1's mask, so we only try overwriting the 		 * bytes we desire ie. written a 1 should not change 		 * the state of an erase bit */		int byteCount;	        ULONG data = 0xffffffff; 	        /* clear out the bytes we are going to overwrite */		for(byteCount = 0; byteCount<length; byteCount++)		    data &= ~(0xff << (byteCount*8));		/* set the bits we dont want to clear in our data */		data |= CFI_LONGSWAP(* (ULONG *) buffer);		CFI_LONG_WRITE(flashPtr, (ULONG) (PROGRAM<<16) |PROGRAM);		CFI_LONG_WRITE(flashPtr, (ULONG) data);		/* 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)) );  		CFI_LONG_WRITE(flashPtr, (ULONG) (READ_ARRAY<<16) |READ_ARRAY); #ifdef DEBUG_PRINT  DEBUG_PRINT("Debug: mtd: Using NON-buffered write to program %ld words at addr 0x%lx\n", 	      wordsThisWrite, (ULONG) flashPtr);#endif		}	    else		{                CFI_LONG_WRITE(flashPtr, (ULONG) ((CLEAR_STATUS<<16)		                        |CLEAR_STATUS));		CFI_LONG_WRITE(flashPtr, (ULONG) (WRITE_TO_BUFFER<<16) 					|WRITE_TO_BUFFER);  /* both parts */	      		/* At this point, we must wait for XSR to indicate a buffer is 		 * 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 */

⌨️ 快捷键说明

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