STATUS sysFlashSet (char *buf, int length, int offset) { char *tempBuffer; UINT32 subsector_addr; /* Calculate the start address of the target subsector */ subsector_addr = offset & (~(FLASH_SUBSECTOR_SIZE-1)); /* Limit to one subsector */ if ((offset < 0) || (length < 0) || ((offset + length) > FLASH_SIZE) || ((offset - subsector_addr + length) > FLASH_SUBSECTOR_SIZE)) { return ERROR; } /* Read the contents of the target subsector into a temporary buffer */ tempBuffer = malloc(FLASH_SUBSECTOR_SIZE); sysFlashGet(tempBuffer, length, subsector_addr); /* Copy the new data over the temporary buffer */ bcopyBytes(buf, (tempBuffer+offset-subsector_addr), length); /* Erase the target subsector... */ sysFlashWriteEnable(); sysFlashSubsectorErase((void*)subsector_addr); /* ...and write the updated data out */ sysFlashWriteEnable(); sysFlashWrite((void*)subsector_addr, tempBuffer, FLASH_SUBSECTOR_SIZE); free(tempBuffer); return OK; }
void nvWrite(unsigned short *data, unsigned int len) { uint off = flashutl_desc->size - NVRAM_SPACE; sysFlashWrite(off, (uchar*)data, len); }
STATUS sysFlashSet ( char * string, /* string to be copied into flash memory */ int byteLen, /* maximum number of bytes to copy */ int offset /* byte offset into flash memory */ ) { UINT32 i, startSec; char * tempBuf; #ifndef FLASH_OVERLAY UINT32 flashStartAddr, tempBufStartAddr; #endif /* FLASH_OVERLAY */ /* limited to one sector */ if ((offset < 0) || (byteLen < 0) || (((offset % FLASH_SEGMENT_SIZE) + byteLen) > FLASH_SEGMENT_SIZE)) return (ERROR); /* see if contents are actually changing */ if (bcmp ((char *) (ALT_FLASH_ADRS + offset), string, byteLen) == 0) return (OK); if ((tempBuf = memalign(4, FLASH_SEGMENT_SIZE)) == NULL) return (ERROR); startSec = (offset) / FLASH_SEGMENT_SIZE; #ifdef FLASH_OVERLAY /* first save the current data in this sector */ bcopy((char *)(ALT_FLASH_ADRS + startSec * FLASH_SEGMENT_SIZE), tempBuf, FLASH_SEGMENT_SIZE); bcopy(string, tempBuf + (offset % FLASH_SEGMENT_SIZE), byteLen); #else bcopy(string, tempBuf, byteLen); #endif /* FLASH_OVERLAY */ if(sysFlashBlkErase(startSec) == ERROR) return (ERROR); #ifdef FLASH_OVERLAY /* program device */ for(i = 0; i < FLASH_SEGMENT_SIZE; i += 4) { if(*(UINT32 *)(tempBuf + i) == 0xffffffff) continue; if (sysFlashWrite((UINT32 *)(ALT_FLASH_ADRS + startSec * FLASH_SEGMENT_SIZE + i), *(UINT32 *)(tempBuf + i)) != OK) { free (tempBuf); return (ERROR); } } #else /* FLASH_OVERLAY */ for(i = 0; i < ((byteLen + 3) / 4); i++) { flashStartAddr = ALT_FLASH_ADRS + startSec * FLASH_SEGMENT_SIZE + (offset % FLASH_SEGMENT_SIZE) + i * 4; tempBufStartAddr = tempBuf + i * 4; /* * Note if FLASH_OVERLAY is not defined: * Here we assume that the specified start offset in a sector will * always be aligned with 4 bytes. This routines should be updated if * we find that some cases conflict with this assumption. */ if (sysFlashWrite(flashStartAddr, *(UINT32 *)tempBufStartAddr) != OK) { free (tempBuf); return (ERROR); } } #endif /* FLASH_OVERLAY */ free (tempBuf); return (OK); }