/** @file hal/micro/cortexm3/nvm.c * @brief Cortex-M3 Non-Volatile Memory data storage system. * * This file implements the NVM data storage system. Refer to nvm.h for * full documentation of how the NVM data storage system works, is configured, * and is accessed. * * */ #include PLATFORM_HEADER #include "error.h" #ifdef NVM_RAM_EMULATION static int16u calibrationData[32+2]={ 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, }; int8u halCommonReadFromNvm(void *data, int32u offset, int16u length) { halCommonMemCopy(data, ((int8u *) calibrationData) + offset, length); return ST_SUCCESS; } int8u halCommonWriteToNvm(const void *data, int32u offset, int16u length) { halCommonMemCopy(((int8u *) calibrationData) + offset, data, length); return ST_SUCCESS; } #else //flash.h gives access to halInternalFlashErase and halInternalFlashWrite. #include "hal/micro/cortexm3/flash.h" //nvm.h includes memmap.h. These two headers define the key parameters: // MFB_PAGE_SIZE_B // MFB_TOP // NVM_LEFT_PAGE // NVM_RIGHT_PAGE // NVM_DATA_SIZE_B // NVM_FLASH_PAGE_COUNT // NVM_MGMT_SIZE_B #include "hal/micro/cortexm3/nvm.h" //Define two variables that hold the actual NVM data storage. LEFT and RIGHT //are not required to be continuous memory blocks so they can be define //separately. The linker is responsible for placing these storage containers //on flash page boundaries. NO_STRIPPING __no_init VAR_AT_SEGMENT (const int8u nvmStorageLeft[NVM_DATA_SIZE_B], __NVM__); NO_STRIPPING __no_init VAR_AT_SEGMENT (const int8u nvmStorageRight[NVM_DATA_SIZE_B], __NVM__); static int8u determineState(void) { int32u leftMgmt = *(int32u *)NVM_LEFT_PAGE; int32u rightMgmt = *(int32u *)NVM_RIGHT_PAGE; int8u state=0; if((leftMgmt==0xFFFF0000) && (rightMgmt==0xFFFFFFFF)) { //State 1 and state 4 use identical mgmt words. The function //determineState() is only called at the start of a NVM read //or write. During a read, state 1 and 4 both read from the //LEFT so there is no reason to make a distinction. During //a write, the system will see the current page as LEFT and //therefore be transitioning from LEFT to RIGHT so state 4 is //correct. State 1 is only required to transition from 0 to 2. state = 4; } else if((leftMgmt==0xFFFF0000) && (rightMgmt==0xFF00FFFF)) { state = 2; } else if((leftMgmt==0xFFFF0000) && (rightMgmt==0xFF000000)) { state = 3; } else if((leftMgmt==0xFFFF0000) && (rightMgmt==0xFFFFFFFF)) { state = 4; } else if((leftMgmt==0xFFFF0000) && (rightMgmt==0xFFFFFF00)) { state = 5; } else if((leftMgmt==0xFF000000) && (rightMgmt==0xFFFFFF00)) { state = 6; } else if((leftMgmt==0xFF000000) && (rightMgmt==0xFFFF0000)) { state = 7; } else if((leftMgmt==0xFFFFFFFF) && (rightMgmt==0xFFFF0000)) { state = 8; } else if((leftMgmt==0xFFFFFF00) && (rightMgmt==0xFFFF0000)) { state = 9; } else if((leftMgmt==0xFFFFFF00) && (rightMgmt==0xFF000000)) { state = 10; } else { //State 0 is used to indicate erased or invalid. state = 0; } return state; } int8u halCommonReadFromNvm(void *data, int32u offset, int16u length) { int16u i; int16u *flash; //Remember: all flash writes are 16bits. int16u *ram = (int16u*)data; //The NVM data storage system cannot function if the LEFT and RIGHT //storage are not aligned to physical flash pages. assert((NVM_LEFT_PAGE%MFB_PAGE_SIZE_B)==0); assert((NVM_RIGHT_PAGE%MFB_PAGE_SIZE_B)==0); //The offset of the NVM data must be 16bit aligned. assert((offset&0x1)==0); //The length of the NVM data must be 16bit aligned. assert((length&0x1)==0); assert(offset+length0;i--) { address = (page+((i-1)*MFB_PAGE_SIZE_B)); flash = (int8u *)address; //Scan the page to determine if it is fully erased already. //If the flash is not erased, erase it. The purpose of scanning //first is to save a little time if erasing is not required. for(k=0;k