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

📄 flashmem.c

📁 这是micrel公司宽带路由ARM9芯片的VXWORKS BSP 源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
            break;
            }

        default:
            retVal = ERROR;
        }

    return (retVal);
    }

/******************************************************************************
*
* sysFlashWrite - write data to flash memory
*
* This routine copies specified data of a specified length, <size>, into a
* specified offset, <offset>, in the flash memory.  Data is passed as a string,
* <pFB>, if not NULL.  If NULL, data is taken as a repeated sequence of
* <value>.
* The parameter <flashType> should be set to the flash device code.
* The parameter <offset> must be appropriately aligned for the width of
* the Flash devices in use.
*
* Flash 28F\f2xxx\f1 devices are programmed by a sequence of operations:
* .iP
* set up device to write
* .iP
* perform write
* .iP
* verify the write
* .LP
*
* Flash 29F\f2xxx\f1 devices are programmed by a sequence of operations:
* .iP
* set up device to write
* .iP
* perform write
* .iP
* wait for the write to complete
* .LP
*
* RETURNS: OK, or ERROR if the write operation fails.
*
* SEE ALSO: sysFlashSet()
*/

STATUS sysFlashWrite
    (
    FLASH_DEF *	pFB,		/* string to be copied; use <value> if NULL */
    int		size,		/* size to program in bytes */
    int		offset,		/* byte offset into flash memory */
    UINT8	flashType,	/* type of flash memory on-board */
    FLASH_DEF	value		/* value to program */
    )
{
    volatile FLASH_DEF * pFA;	/* flash address */
    STATUS retVal = OK;
    int ix;
    int sectorSize = 128;
    int twc = 2;	/* time for write completion */

    switch (flashType)
    {
	    case (FLASH_28F008):
	    case (FLASH_28F016):
	    case (FLASH_28F160):
	    case (FLASH_28F320):
	        SYS_FLASH_WRITE_ENABLE_RTN ();		/* raise Vpp */

            for (pFA = FLASH_CAST (FLASH_ADRS + offset); (pFA < FLASH_CAST
                (FLASH_ADRS + size + offset)) && (retVal == OK); pFA++)
            {
		        if (pFB != NULL)
		            value = *pFB++;

		        *pFA = FLASH28_CMD_PROG_SETUP;	/* write setup */
		        *pFA = value;			/* data to write */

		        /* Check Write State Machine Status */

		        do
                {
		           *pFA = FLASH28F008_CMD_READ_STATUS;
                }
		        while ((*pFA & FLASH28F008_STAT_WSMS) != FLASH28F008_STAT_WSMS);

                sysFlashDelay (6);

		        /* Check Byte Write Error Status */

		        if ((*pFA & FLASH28F008_STAT_BWS) != 0)
                {
		            *pFA = FLASH28F008_CMD_CLEAR_STATUS;
		            retVal = ERROR;
                }
            }

            pFA = FLASH_CAST (FLASH_ADRS);
            *pFA = FLASH28_CMD_RESET;

	        SYS_FLASH_WRITE_DISABLE_RTN ();		/* lower Vpp */
            break;

        case (FLASH_28F256):
        case (FLASH_28F512):
        case (FLASH_28F010):
        case (FLASH_28F020):
            {
	        SYS_FLASH_WRITE_ENABLE_RTN ();		/* raise Vpp */

            for (pFA = FLASH_CAST (FLASH_ADRS + offset); (pFA < FLASH_CAST
                (FLASH_ADRS + size + offset)) && (retVal == OK); pFA++)
	        for (ix = 0; TRUE; ix++)
	        {
		        if (pFB != NULL)
			       value = *pFB++;

	            *pFA = FLASH28_CMD_PROG_SETUP;	/* write setup */
	            *pFA = value;			/* data to write */
	            sysFlashDelay (10);			/* wait for write */

	            *pFA = FLASH28_CMD_PROG_VERIFY;	/* verify command */
	            sysFlashDelay (6);			/* wait for verify */

	            if (*pFA == value)			/* done? */
		           break;

	            if (ix == 25)			/* error? */
                {
	                retVal = ERROR;
			        break;
                }
	        }

            pFA = FLASH_CAST (FLASH_ADRS);
            *pFA = FLASH28_CMD_RESET;
            *pFA = FLASH28_CMD_READ_MEM;
	        sysFlashDelay (6);

	        SYS_FLASH_WRITE_DISABLE_RTN ();		/* lower Vpp */
            break;
            }
        case (FLASH_29F010):
            {
	        SYS_FLASH_WRITE_ENABLE_RTN ();		/* enable write */
            for (pFA = FLASH_CAST (FLASH_ADRS + offset); pFA < FLASH_CAST
                (FLASH_ADRS + size + offset) && (retVal == OK); pFA++)
            {
                *(FLASH_CAST FLASH29_REG_FIRST_CYCLE)  = FLASH29_CMD_FIRST;
                *(FLASH_CAST FLASH29_REG_SECOND_CYCLE) = FLASH29_CMD_SECOND;
                *(FLASH_CAST FLASH29_REG_FIRST_CYCLE)  = FLASH29_CMD_PROGRAM;
		        if (pFB != NULL)
		        value = *pFB++;

                *pFA = value;                    	/* data to write */
                do {
                    retVal = sysFlashDataPoll (pFA, (FLASH_DEF) value);
                } while ((*pFA != value) && (retVal == OK));
            }

            *(FLASH_CAST FLASH29_REG_FIRST_CYCLE)  = FLASH29_CMD_FIRST;
            *(FLASH_CAST FLASH29_REG_SECOND_CYCLE) = FLASH29_CMD_SECOND;
            *(FLASH_CAST FLASH29_REG_FIRST_CYCLE)  = FLASH29_CMD_READ_RESET;

	        SYS_FLASH_WRITE_DISABLE_RTN ();		/* disable write */
            break;
            }

	    case (FLASH_29C040A):
	        sectorSize = 256;
	        twc = 1;

	        /* FALL THROUGH */

        case (FLASH_29LV1024):
            {
            for (pFA = FLASH_CAST (FLASH_ADRS + offset);
		         pFA < FLASH_CAST (FLASH_ADRS + size + offset); )
            {
		       /* Enable sector write */

		       *(FLASH_CAST FLASH29_REG_FIRST_CYCLE)  = FLASH29_CMD_FIRST;
		       *(FLASH_CAST FLASH29_REG_SECOND_CYCLE) = FLASH29_CMD_SECOND;
		       *(FLASH_CAST FLASH29_REG_FIRST_CYCLE)  = FLASH29_CMD_PROGRAM;

		       /*
		        * write the sector:
		        *    29LV1024: 128 half-word accesses = 256 bytes
		        *    29C040A 256 byte accesses
		        */

		       for (ix = 0; ix < sectorSize; ix++)
               {
		          if (pFB != NULL)
			          value = *pFB++;

		          /* ensure entire sector written */

		          if (pFA >= FLASH_CAST (FLASH_ADRS + size + offset))
			          value = (FLASH_DEF) 0xFFFFFFFF;

		          *pFA++ = value;                    	/* data to write */
               }

		      /*
		       * Ensure write cycle completes. Atmel chip spec suggest
		       * waiting for a specified time rather than polling for
		       * completion.
		       *
		       * It seems that we cannot always safely use taskDelay()
		       */

		       sysFlashDelay (10000 * twc);
            }

            break;
          }

        case (FLASH_29LV033):
            {

            for (pFA = FLASH_CAST (FLASH_ADRS + offset); pFA < FLASH_CAST
                (FLASH_ADRS + size + offset) && (retVal == OK); pFA++)
            {
                *(FLASH_CAST FLASH29_REG_FIRST_CYCLE)  = FLASH29_CMD_FIRST;
                *(FLASH_CAST FLASH29_REG_SECOND_CYCLE) = FLASH29_CMD_SECOND;
                *(FLASH_CAST FLASH29_REG_FIRST_CYCLE)  = FLASH29_CMD_PROGRAM;

		        if (pFB != NULL)
		            value = *pFB++;

                *pFA = value;                    	/* data to write */
                do {
                    retVal = sysFlashDataPoll (pFA, (FLASH_DEF) value);
                } while ((*pFA != value) && (retVal == OK));
            }

            *(FLASH_CAST FLASH29_REG_FIRST_CYCLE)  = FLASH29_CMD_FIRST;
            *(FLASH_CAST FLASH29_REG_SECOND_CYCLE) = FLASH29_CMD_SECOND;
            *(FLASH_CAST FLASH29_REG_FIRST_CYCLE)  = FLASH29_CMD_READ_RESET;

            break;
            }

        default:
            retVal = ERROR;
    }

    return (retVal);
}

/******************************************************************************
*
* sysFlashTypeGet - determine the device type of on-board flash memory
*
* This routine uses the `autoselect' command to determine the device type of
* on-board flash memory for flash 29F\f2xxx\f1 devices.
*
* RETURNS: An integer indicating the device type of on-board flash memory.
*/
UINT8 sysFlashTypeGet (void)
    {
    volatile FLASH_DEF * pFA = FLASH_CAST (FLASH_ADRS);	/* flash address */
    UINT8 retVal;


    SYS_FLASH_WRITE_ENABLE_RTN ();			/* enable writes */

    *(FLASH_CAST FLASH29_REG_FIRST_CYCLE)  = FLASH29_CMD_FIRST;
    *(FLASH_CAST FLASH29_REG_SECOND_CYCLE) = FLASH29_CMD_SECOND;
    *(FLASH_CAST FLASH29_REG_FIRST_CYCLE)  = FLASH29_CMD_AUTOSELECT;

    /* 29LV1024 (at least) requires 20ms delay */

    /* It seems we cannot always safely use taskDelay() */

    sysFlashDelay (20000);

    retVal = (UINT8) *++pFA;

    *(FLASH_CAST FLASH29_REG_FIRST_CYCLE)  = FLASH29_CMD_FIRST;
    *(FLASH_CAST FLASH29_REG_SECOND_CYCLE) = FLASH29_CMD_SECOND;
    *(FLASH_CAST FLASH29_REG_FIRST_CYCLE)  = FLASH29_CMD_READ_RESET;

    sysFlashDelay (20000);

    SYS_FLASH_WRITE_DISABLE_RTN ();			/* disable writes */

    return (retVal);
    }

#ifdef INCLUDE_FLASH_SIB_FOOTER
/******************************************************************************
 *
 * footerChecksum - calculate the footer checksum.
 *
 * This function calculates the checksum for a footer.
 *
 * RETURNS: The checksum
 */

static UINT32 footerChecksum
    (
    FOOTER *	footer
    )
    {
    UINT32	checksum;
    UINT32 *	ptr;
    int         size;
    UINT32	word;

    checksum    = 0;
    size        = sizeof (FOOTER);
    ptr         = (UINT32 *)footer;

    while (size > 0)
        {
        word = *ptr++;

        if (word > ~checksum)
            checksum++;

        checksum += word;
        size -= sizeof (word);
        }

    return ~checksum;
    }

/******************************************************************************
*
* sysFlashWriteFooter - write footer to flash memory
*
* This routine initializes and writes a footer to the block defined by
* FLASH_ADRS so that this block can be seen from other utilities.
*
* RETURNS: OK or ERROR
*/

STATUS sysFlashWriteFooter
    (
    int flashType
    )
    {
    FOOTER	footer;
    FOOTER *	current;
    UINT32	writeOffset;


    /* Build a flash footer to describe this area. */

    footer.blockBase    = (char *)FLASH_ADRS;
    footer.infoBase     = NULL;
    footer.type         = TYPE_WRS_SIB;
    footer.signature    = FLASH_FOOTER_SIGNATURE;
    footer.checksum     = 0;
    footer.checksum     = footerChecksum (&footer);

    current = (FOOTER *)(FLASH_ADRS + FLASH_BLOCK_SIZE - sizeof (FOOTER));

    if (current->type == TYPE_WRS_SIB)
        return OK;

    writeOffset = FLASH_BLOCK_SIZE - sizeof (FOOTER);

    if (flashType == 0)
        flashType = sysFlashTypeGet ();

    if (sysFlashWrite(FLASH_CAST(&footer), sizeof(FOOTER),
		      writeOffset,
		      flashType, 0) != OK)
       return ERROR;

    return OK;
    }
#endif /* INCLUDE_FLASH_SIB_FOOTER */

/******************************************************************************
*
* sysFlashSet - write to flash memory
*
* This routine copies a specified string into flash memory after calling
* sysFlashErase() and clearing flash memory.
*
* If FLASH_NO_OVERLAY is defined, the parameter <offset> must be
* appropriately aligned for the Flash devices in use (device width,
* sector size etc.).
*
* If the specified string must be overlaid on the contents of flash memory,
* undefine FLASH_NO_OVERLAY.
*
* RETURNS: OK, or ERROR if the write fails or the input parameters are
* out of range.
*
* SEE ALSO: sysFlashErase(), sysFlashGet(), sysFlashTypeGet(), sysFlashWrite()
*
* INTERNAL
* If multiple tasks are calling sysFlashSet() and sysFlashGet(),
* they should use a semaphore to ensure mutually exclusive access to flash
* memory.
*/

STATUS sysFlashSet
    (
    char *	string,		/* string to be copied into flash memory */
    int		strLen,		/* maximum number of bytes to copy       */
    int		offset		/* byte offset into flash memory         */
    )
    {
    static UINT8 flashType = FLASH_MEM_TYPE;

#ifndef	FLASH_NO_OVERLAY
    char *tempBuffer;
#endif	/* FLASH_NO_OVERLAY */


    if ((offset < 0) || (strLen < 0) || ((offset + strLen) > FLASH_MEM_SIZE))
        return (ERROR);


    /* see if contents are actually changing */

    if (bcmp ((char *) (FLASH_ADRS + offset), string, strLen) == 0)
	return (OK);

#ifndef	FLASH_NO_OVERLAY
    /* first read existing data */

    if (tempBuffer = malloc(FLASH_MEM_SIZE), tempBuffer == 0)
	return (ERROR);

    bcopyBytes ((char *) FLASH_ADRS, tempBuffer, FLASH_MEM_SIZE);
    bcopyBytes (string, (tempBuffer + offset), strLen);
#endif	/* FLASH_NO_OVERLAY */

    if (flashType == 0)
	flashType = sysFlashTypeGet ();


    switch (flashType)
    {
	case FLASH_29C040A:
        case FLASH_29LV1024:
	    /* do not erase these as not required */
	    break;

	default:
	    if (sysFlashErase (flashType) == ERROR)	/* erase device */
		{
#ifndef	FLASH_NO_OVERLAY
		free (tempBuffer);
#endif
		return (ERROR);
		}
	    break;

    } /* endswitch */

#ifndef	FLASH_NO_OVERLAY				/* program device */
    if (sysFlashWrite (FLASH_CAST (tempBuffer), FLASH_MEM_SIZE, 0, flashType, 0)
	    == ERROR)
	{
	free (tempBuffer);
#else	/* FLASH_NO_OVERLAY */
    if (sysFlashWrite (FLASH_CAST (string), strLen, offset, flashType, 0) ==
	ERROR)
	{
#endif	/* FLASH_NO_OVERLAY */
	return (ERROR);
	}

#ifdef INCLUDE_FLASH_SIB_FOOTER
    /*
     * As block has been erased above, we can write the footer at the end of
     * the block.
     */

    sysFlashWriteFooter (flashType);
#endif

#ifndef	FLASH_NO_OVERLAY
    free (tempBuffer);
#endif

    return (OK);
    }

⌨️ 快捷键说明

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