?? flashmem.c
字號:
sysFlashDelay (20000); 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; } 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); }
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -