diff options
Diffstat (limited to 'Projects/P-NUCLEO-WB55.USBDongle/Applications/BLE/BLE_MeshLightingDemo/STM32_WPAN/app/appli_nvm.c')
-rw-r--r-- | Projects/P-NUCLEO-WB55.USBDongle/Applications/BLE/BLE_MeshLightingDemo/STM32_WPAN/app/appli_nvm.c | 667 |
1 files changed, 358 insertions, 309 deletions
diff --git a/Projects/P-NUCLEO-WB55.USBDongle/Applications/BLE/BLE_MeshLightingDemo/STM32_WPAN/app/appli_nvm.c b/Projects/P-NUCLEO-WB55.USBDongle/Applications/BLE/BLE_MeshLightingDemo/STM32_WPAN/app/appli_nvm.c index 6566aa711..7379df8ae 100644 --- a/Projects/P-NUCLEO-WB55.USBDongle/Applications/BLE/BLE_MeshLightingDemo/STM32_WPAN/app/appli_nvm.c +++ b/Projects/P-NUCLEO-WB55.USBDongle/Applications/BLE/BLE_MeshLightingDemo/STM32_WPAN/app/appli_nvm.c @@ -1,9 +1,9 @@ /** - ****************************************************************************** - * @file appli_nvm.c - * @author BLE Mesh Team - * @brief User Application file - ****************************************************************************** + ****************************************************************************** + * @file appli_nvm.c + * @author BLE Mesh Team + * @brief User Application file + ****************************************************************************** * @attention * * <h2><center>© Copyright (c) 2019 STMicroelectronics. @@ -20,16 +20,25 @@ /* Includes ------------------------------------------------------------------*/ #include <string.h> #include "hal_common.h" +#include "ble_mesh.h" #include "appli_nvm.h" #include "mesh_cfg.h" +#include "pal_nvm.h" #include "appli_mesh.h" +#ifdef SAVE_MODEL_STATE_FOR_ALL_MESSAGES +#include "common.h" +#endif extern const MOBLEUINT8* _bdaddr[]; -extern const void* bnrgmNvmBase; +//extern const void* mobleNvmBase; +#ifdef SAVE_MODEL_STATE_FOR_ALL_MESSAGES +extern MOBLEUINT8 PowerOnOff_flag; +#endif +extern const void* appNvmBase; /* Reserved for Bluenrg-Mesh library */ -#define BLUENRGMESH_NVM_BASE ((unsigned int)bnrgmNvmBase) -#define BLUENRGMESH_NVM_BACKUP_BASE (BLUENRGMESH_NVM_BASE + PAGE_SIZE) +//#define BLUENRGMESH_NVM_BASE ((unsigned int)mobleNvmBase) +//#define BLUENRGMESH_NVM_BACKUP_BASE (BLUENRGMESH_NVM_BASE + PAGE_SIZE) /* * Page of size 2k, BlueNRG-1 and BlueNRG-2, reserved for application is divided into 8 subpages of each 256 bytes @@ -37,11 +46,14 @@ extern const void* bnrgmNvmBase; * Rest 7 subpages are used on rolling basis for application states. * First byte of each subpage indicates if page is valid or not */ -#define APP_NVM_BASE ((unsigned int)_bdaddr) +//#define APP_NVM_BASE ((unsigned int)_bdaddr) +#define APP_NVM_BASE ((unsigned int)appNvmBase) +#define APP_NVM_SIZE 0x00001000 + #define APP_NVM_RESERVED_SIZE 256U #define APP_NVM_SUBPAGE_SIZE 256U -#define APP_NVM_MAX_SUBPAGE 7U -#define APP_NVM_SUBPAGE_OFFSET(i) (unsigned int)(APP_NVM_BASE+APP_NVM_RESERVED_SIZE+256*i) +#define APP_NVM_MAX_SUBPAGE 15U +#define APP_NVM_SUBPAGE_OFFSET(i) (unsigned int)(APP_NVM_RESERVED_SIZE+256*(i)) /* offsets defined wrt start of subpage */ #define APP_NVM_VALID_FLAG_OFFSET 0U @@ -53,34 +65,51 @@ extern const void* bnrgmNvmBase; #define APP_NVM_LIGHT_MODEL_OFFSET (unsigned int)(APP_NVM_VALID_FLAG_SIZE+APP_NVM_RESET_COUNT_SIZE+APP_NVM_GENERIC_MODEL_SIZE) #define APP_NVM_LIGHT_MODEL_SIZE 16U +/* Private variables ---------------------------------------------------------*/ +typedef struct +{ + MOBLEUINT8 modelData[APP_NVM_GENERIC_MODEL_SIZE+APP_NVM_LIGHT_MODEL_SIZE]; + MOBLEBOOL erasePageReq; + MOBLEBOOL writeReq; +} APPLI_NVM_REQS; + +APPLI_NVM_REQS AppliNvm_Reqs; + MOBLE_RESULT AppliNvm_EraseRestoreResvNvm(void); +MOBLE_RESULT AppliNvm_FindFirstValidSubPage(MOBLEINT8* subPageIndex); +MOBLE_RESULT AppliNvm_MarkSubpageInvalid(void); +MOBLE_RESULT AppliNvm_FlashProgram(MOBLEUINT32 offset, void const *buf, MOBLEUINT32 size); +MOBLE_RESULT AppliNvm_LoadGenericState(uint8_t state[], uint8_t* size); +MOBLE_RESULT AppliNvm_LoadLightState(uint8_t state[], uint8_t* size); +#if 0 /** * @brief This function erases a specified flash page -* @param void -* @retval MOBLE_RESULT_SUCCESS on success +* @param Page Number +* @retval MOBLE_RESULT_INVALIDARG if PageNumber overflow +* MOBLE_RESULT_FALSE if flash operation is very close to next radio event +* MOBLE_RESULT_FAIL if flash command error is set +* MOBLE_RESULT_SUCCESS on success */ -MOBLE_RESULT AppliNvm_FlashErase(void) +MOBLE_RESULT AppliNvm_FlashErase(uint16_t PageNumber) { - if(BluenrgMesh_IsFlashReadyToErase()) + MOBLE_RESULT result; + + if (PageNumber < N_PAGES) { BLEMesh_StopAdvScan(); - FLASH_ErasePage((uint16_t)((APP_NVM_BASE - RESET_MANAGER_FLASH_BASE_ADDRESS) / PAGE_SIZE)); - - if (FLASH_GetFlagStatus(Flash_CMDERR) == SET) - { - return MOBLE_RESULT_FAIL; - } - else - { - return MOBLE_RESULT_SUCCESS; - } + ATOMIC_SECTION_BEGIN(); + result = MoblePalNvmErase(APP_NVM_BASE, 0); + ATOMIC_SECTION_END(); } - else + else /* Invalid page no */ { - return MOBLE_RESULT_FALSE; + result = MOBLE_RESULT_INVALIDARG; } + + return result; } +#endif /** * @brief Program word (32-bit) at a APP_NVM_BASE + APP_NVM_RESERVED_SIZE @@ -89,34 +118,37 @@ MOBLE_RESULT AppliNvm_FlashErase(void) * @param Data: word to write * @retval MOBLE_RESULT_SUCCESS on success */ -MOBLE_RESULT AppliNvm_FlashProgram(uint32_t TypeProgram, uint32_t Address, uint32_t Data[]) +//MOBLE_RESULT AppliNvm_FlashProgram(uint32_t TypeProgram, uint32_t Address, uint32_t Data[]) +MOBLE_RESULT AppliNvm_FlashProgram(MOBLEUINT32 offset, void const *buf, MOBLEUINT32 size) { - if (Address < (APP_NVM_BASE) - || Address > (APP_NVM_BASE + PAGE_SIZE) - || (Address & 0x03 != 0)) - { - return MOBLE_RESULT_INVALIDARG; - } - else - { - if(TypeProgram == FLASH_WRITE) - { - /* Program 4 bytes (32-bit) at a specified address.*/ - FLASH_ProgramWord(Address, (uint32_t) Data[0]); - } - else if(TypeProgram == FLASH_BURSTWRITE) - { - /*Program 4 words (128-bit) at a specified address.*/ - FLASH_ProgramWordBurst(Address, (uint32_t*) Data); - } - } - - if (FLASH_GetFlagStatus(Flash_CMDERR) == SET) - { - return MOBLE_RESULT_FAIL; - } - - return MOBLE_RESULT_SUCCESS; + MOBLE_RESULT result = MOBLE_RESULT_SUCCESS; + + if (offset > PAGE_SIZE) + { + result = MOBLE_RESULT_INVALIDARG; + } + else if (size == 0) + { + result = MOBLE_RESULT_FALSE; + } + else if (offset + size > (APP_NVM_BASE + PAGE_SIZE)) + { + result = MOBLE_RESULT_INVALIDARG; + } + else if (offset & 3) + { + result = MOBLE_RESULT_INVALIDARG; + } + else if (size & 3) + { + result = MOBLE_RESULT_INVALIDARG; + } + else + { + result = MoblePalNvmWrite(APP_NVM_BASE, offset, buf, size); + } + + return result; } /** @@ -127,15 +159,17 @@ MOBLE_RESULT AppliNvm_FlashProgram(uint32_t TypeProgram, uint32_t Address, uint3 */ MOBLE_RESULT AppliNvm_FindFirstValidSubPage(MOBLEINT8* subPageIndex) { - MOBLEUINT32 valid; + MOBLEUINT32 valid[2]; MOBLEINT8 subPageIdx = -1; MOBLE_RESULT result = MOBLE_RESULT_SUCCESS; /* find valid subpage */ for (MOBLEUINT8 count=0; count<APP_NVM_MAX_SUBPAGE; count++) { - memcpy((void*)&valid, (void*)(APP_NVM_SUBPAGE_OFFSET(count)), 4); - if (valid == 0xFFFFFFFF) + unsigned int offset = APP_NVM_SUBPAGE_OFFSET(count); + + memcpy((void*)&valid, (void*)(APP_NVM_BASE + offset), 8); + if ((valid[0] == 0xFFFFFFFF) && ((valid[1] == 0xFFFFFFFF))) { subPageIdx = count; break; @@ -145,8 +179,8 @@ MOBLE_RESULT AppliNvm_FindFirstValidSubPage(MOBLEINT8* subPageIndex) /* if no valid subpage found, erase all subpages and reset subPageIdx */ if (subPageIdx < 0) { - result = AppliNvm_EraseRestoreResvNvm(); - subPageIdx = 0; + AppliNvm_Reqs.erasePageReq = MOBLE_TRUE; + result = MOBLE_RESULT_FAIL; } else { @@ -160,80 +194,44 @@ MOBLE_RESULT AppliNvm_FindFirstValidSubPage(MOBLEINT8* subPageIndex) /** * @brief Mark first valid subpage as invalid. -* If no valid subpage found, erase page appli nvm to reset it -* Also copy model data from current subpage into new subpage -* It is assumed that all models are consecutive in memory -* @param model backup flag. If true, copy model states from current subpage to new subpage +* @param void * @retval MOBLE_RESULT_SUCCESS on success */ -MOBLE_RESULT AppliNvm_MarkSubpageInvalid(MOBLEBOOL modelBackup) +MOBLE_RESULT AppliNvm_MarkSubpageInvalid(void) { MOBLEUINT32 valid = 0; MOBLE_RESULT result = MOBLE_RESULT_SUCCESS; MOBLEINT8 currSubPageIdx; - MOBLEINT8 newSubPageIdx; - MOBLEUINT8 modelBackupData[APP_NVM_GENERIC_MODEL_SIZE+APP_NVM_LIGHT_MODEL_SIZE]; + MOBLEUINT8 subPageTemp[APP_NVM_SUBPAGE_SIZE]; /* find valid subpage */ result = AppliNvm_FindFirstValidSubPage(&currSubPageIdx); - if (MOBLE_FAILED(result)) + if (result != MOBLE_RESULT_SUCCESS) { - result = MOBLE_RESULT_FAIL; + /* do nothing */ } else { - if (modelBackup == MOBLE_TRUE) - { - /* copy model data from current subpage*/ - memcpy((void*)modelBackupData, - (void*)(APP_NVM_SUBPAGE_OFFSET(currSubPageIdx)+APP_NVM_GENERIC_MODEL_OFFSET), - APP_NVM_GENERIC_MODEL_SIZE+APP_NVM_LIGHT_MODEL_SIZE); - } - /* mark valid subpage as invalid */ - AppliNvm_FlashProgram(FLASH_WRITE, - APP_NVM_SUBPAGE_OFFSET(currSubPageIdx)+APP_NVM_VALID_FLAG_OFFSET, - (uint32_t*)&valid); - - /* find next valid subpage */ - result = AppliNvm_FindFirstValidSubPage(&newSubPageIdx); - + memcpy((void*)subPageTemp, + (void*)(APP_NVM_SUBPAGE_OFFSET(currSubPageIdx)), + APP_NVM_SUBPAGE_SIZE); + subPageTemp[APP_NVM_VALID_FLAG_OFFSET] = valid; + result = AppliNvm_FlashProgram(APP_NVM_SUBPAGE_OFFSET(currSubPageIdx), + (uint32_t*)&subPageTemp, + APP_NVM_SUBPAGE_SIZE); if (MOBLE_FAILED(result)) { result = MOBLE_RESULT_FAIL; } - else if (modelBackup == MOBLE_TRUE) + else if (result == MOBLE_RESULT_FALSE) { - /* update model data in new subpage */ - for (MOBLEUINT32 count=0; count<APP_NVM_GENERIC_MODEL_SIZE+APP_NVM_LIGHT_MODEL_SIZE; ) - { - if (FLASH_GetFlagStatus(Flash_CMDERR) == RESET) - { - /* If size to be written > 4 words, use FLASH_ProgramWordBurst*/ - if (APP_NVM_GENERIC_MODEL_SIZE+APP_NVM_LIGHT_MODEL_SIZE-count >= 4*N_BYTES_WORD) - { - AppliNvm_FlashProgram(FLASH_BURSTWRITE, - APP_NVM_SUBPAGE_OFFSET(newSubPageIdx)+APP_NVM_GENERIC_MODEL_OFFSET+count, - (uint32_t*)&modelBackupData[count]); - count += 4*N_BYTES_WORD; - } - /* If size to be written < 4 words, use FLASH_ProgramWord*/ - else - { - AppliNvm_FlashProgram(FLASH_WRITE, - APP_NVM_SUBPAGE_OFFSET(newSubPageIdx)+APP_NVM_GENERIC_MODEL_OFFSET+count, - (uint32_t*)&modelBackupData[count]); - count += N_BYTES_WORD; - } - } - else - { - /* Flash command error occurred */ - result = MOBLE_RESULT_FAIL; - break; - } - } + /* radio busy, try again later */ + } + else + { + /* do nothing */ } } @@ -250,9 +248,10 @@ MOBLE_RESULT AppliNvm_MarkSubpageInvalid(MOBLEBOOL modelBackup) */ MOBLE_RESULT AppliNvm_FactorySettingReset(void) { - MOBLEINT8 currSubPageIdx; + MOBLEINT8 currSubPageIdx = 0; MOBLE_RESULT result; MOBLEUINT32 resetCount; + MOBLEUINT8 subPageTemp[APP_NVM_SUBPAGE_SIZE]; result = AppliNvm_FindFirstValidSubPage(&currSubPageIdx); @@ -262,19 +261,40 @@ MOBLE_RESULT AppliNvm_FactorySettingReset(void) } else { - /* read saved reset counter from subpage */ - memcpy((void*)&resetCount, (void*)(APP_NVM_SUBPAGE_OFFSET(currSubPageIdx)+APP_NVM_RESET_COUNT_OFFSET), 4); + if(currSubPageIdx > 0) + { + /* Not the first reset */ + /* read the previous subpage */ + memcpy((void*)&(subPageTemp[0]), + (void*)(APP_NVM_BASE + APP_NVM_SUBPAGE_OFFSET(currSubPageIdx-1)), + APP_NVM_SUBPAGE_SIZE); + } + else + { + /* read the current subpage */ + memcpy((void*)&(subPageTemp[0]), + (void*)(APP_NVM_BASE + APP_NVM_SUBPAGE_OFFSET(currSubPageIdx)), + APP_NVM_SUBPAGE_SIZE); + } + + /* read reset count from the subpage */ + memcpy((void*)&resetCount, + (void*)&(subPageTemp[APP_NVM_RESET_COUNT_OFFSET]), + 4); resetCount = resetCount << 1; /* Shifting for making Bits 0 from LSB */ + memcpy((void*)&(subPageTemp[APP_NVM_RESET_COUNT_OFFSET]), (void*)&resetCount, 4); /* Check for 5 times, 5 LSB are not zero */ if (resetCount > 0xFFFFFFE0) { /* update reset count */ - AppliNvm_FlashProgram(FLASH_WRITE, - APP_NVM_SUBPAGE_OFFSET(currSubPageIdx)+APP_NVM_RESET_COUNT_OFFSET, - (uint32_t*)&resetCount); + result = AppliNvm_FlashProgram(APP_NVM_SUBPAGE_OFFSET(currSubPageIdx), + (uint32_t*)&subPageTemp, + APP_NVM_SUBPAGE_SIZE); - if (!memcmp((void*)&resetCount, (void*)(APP_NVM_SUBPAGE_OFFSET(currSubPageIdx)+APP_NVM_RESET_COUNT_OFFSET), 4)) + if (!memcmp((void*)&subPageTemp[APP_NVM_RESET_COUNT_OFFSET], + (void*)(APP_NVM_BASE + APP_NVM_SUBPAGE_OFFSET(currSubPageIdx)+APP_NVM_RESET_COUNT_OFFSET), + 4)) { /* updated value of reset count in flash */ } @@ -285,33 +305,19 @@ MOBLE_RESULT AppliNvm_FactorySettingReset(void) { Appli_LedBlink(); } - - result = AppliNvm_MarkSubpageInvalid(MOBLE_TRUE); - - if (MOBLE_FAILED(result)) - { - result = MOBLE_RESULT_FAIL; - } } else /* Device is forced to factory reset, 5 LSBs are zero */ { /* Unprovision node */ - BluenrgMesh_Unprovision(); + BLEMesh_Unprovision(); - /* Clear lib data, primary and backup nvm used by BlueNRG-Mesh lib */ - FLASH_ErasePage((uint16_t)((BLUENRGMESH_NVM_BASE - RESET_MANAGER_FLASH_BASE_ADDRESS) / PAGE_SIZE)); - FLASH_ErasePage((uint16_t)((BLUENRGMESH_NVM_BACKUP_BASE - RESET_MANAGER_FLASH_BASE_ADDRESS) / PAGE_SIZE)); + /* Clear lib data, primary and backup nvm used by BLE-Mesh lib */ + MoblePalNvmErase(NVM_BASE, 0); + MoblePalNvmErase(NVM_BASE, 0x1000); AppliNvm_ClearModelState(); - result = AppliNvm_MarkSubpageInvalid(MOBLE_FALSE); - - if (MOBLE_FAILED(result)) - { - result = MOBLE_RESULT_FAIL; - } - - BluenrgMesh_SetUnprovisionedDevBeaconInterval(100); + BLEMesh_SetUnprovisionedDevBeaconInterval(100); /* Blink 5 times to indicate factory setting reset */ for (MOBLEUINT8 i=0; i<5; i++) @@ -329,59 +335,6 @@ MOBLE_RESULT AppliNvm_FactorySettingReset(void) } /** -* @brief This function erases application Flash page data only keeping reserved Nvm data -* located at APP_NVM_BASE + APP_NVM_RESERVED_SIZE -* @param void -* @retval MOBLE_RESULT_SUCCESS on success -*/ -MOBLE_RESULT AppliNvm_EraseRestoreResvNvm(void) -{ - MOBLE_RESULT result = MOBLE_RESULT_SUCCESS; - MOBLEUINT8 reserveAreaCopy[APP_NVM_RESERVED_SIZE]; - - /* save reserve flash area */ - memcpy((void*)reserveAreaCopy, (void*)APP_NVM_BASE, APP_NVM_RESERVED_SIZE); - - /* erase page */ - FLASH_ErasePage((uint16_t)((APP_NVM_BASE - RESET_MANAGER_FLASH_BASE_ADDRESS) / PAGE_SIZE)); - - if (FLASH_GetFlagStatus(Flash_CMDERR) == SET) - { - result = MOBLE_RESULT_FAIL; - } - else - { - /* restore reserve area */ - for (MOBLEUINT32 count=0; count<APP_NVM_RESERVED_SIZE; ) - { - if (FLASH_GetFlagStatus(Flash_CMDERR) == RESET) - { - /* If size to be written > 4 words, use FLASH_ProgramWordBurst*/ - if (APP_NVM_RESERVED_SIZE-count >= 4*N_BYTES_WORD) - { - AppliNvm_FlashProgram(FLASH_BURSTWRITE,APP_NVM_BASE + count, (uint32_t*)&reserveAreaCopy[count]); - count += 4*N_BYTES_WORD; - } - /* If size to be written < 4 words, use FLASH_ProgramWord*/ - else - { - AppliNvm_FlashProgram(FLASH_WRITE,APP_NVM_BASE + count, (uint32_t*)&reserveAreaCopy[count]); - count += N_BYTES_WORD; - } - } - else - { - /* Flash command error occurred */ - result = MOBLE_RESULT_FAIL; - break; - } - } - } - - return result; -} - -/** * @brief Save model states in nvm * @param model state buff * @param model state buff size @@ -389,66 +342,19 @@ MOBLE_RESULT AppliNvm_EraseRestoreResvNvm(void) */ MOBLE_RESULT AppliNvm_SaveModelState(uint8_t* state, uint8_t size) { - MOBLE_RESULT result = MOBLE_RESULT_FAIL; /* if save model state not defined, return MOBLE_RESULT_FAIL */ + MOBLE_RESULT result = MOBLE_RESULT_SUCCESS; /* if save model state not defined, return MOBLE_RESULT_FAIL */ #if (SAVE_MODEL_STATE_NVM == 1) - MOBLEINT8 subPageIdx; - - if (size > APP_NVM_GENERIC_MODEL_SIZE+APP_NVM_LIGHT_MODEL_SIZE) + if (size > APP_NVM_MODEL_SIZE) { /* incorrect size */ result = MOBLE_RESULT_FAIL; } else { - AppliNvm_MarkSubpageInvalid(MOBLE_FALSE); - result = AppliNvm_FindFirstValidSubPage(&subPageIdx); - - if (MOBLE_FAILED(result)) - { - result = MOBLE_RESULT_FAIL; - } - else - { - /* update models states */ - for (MOBLEUINT32 count=0; count<size; ) - { - if (FLASH_GetFlagStatus(Flash_CMDERR) == RESET) - { - /* If size to be written > 4 words, use FLASH_ProgramWordBurst*/ - if (APP_NVM_RESERVED_SIZE-count >= 4*N_BYTES_WORD) - { - result = AppliNvm_FlashProgram(FLASH_BURSTWRITE, - APP_NVM_SUBPAGE_OFFSET(subPageIdx)+APP_NVM_GENERIC_MODEL_OFFSET+count, - (uint32_t*)&state[count]); - count += 4*N_BYTES_WORD; - } - /* If size to be written < 4 words, use FLASH_ProgramWord*/ - else - { - result = AppliNvm_FlashProgram(FLASH_WRITE, - APP_NVM_SUBPAGE_OFFSET(subPageIdx)+APP_NVM_GENERIC_MODEL_OFFSET+count, - (uint32_t*)&state[count]); - count += N_BYTES_WORD; - } - } - else - { - /* Flash command error occurred */ - result = MOBLE_RESULT_FAIL; - break; - } - } - - for (MOBLEUINT8 count=0; count<size; count++) - { - TRACE_M(TF_MISC, "%.2x ", *((MOBLEUINT8*)((APP_NVM_SUBPAGE_OFFSET(subPageIdx)+APP_NVM_GENERIC_MODEL_OFFSET+count)))); - } - - TRACE_M(TF_MISC,"\r\n"); - - } + memcpy(AppliNvm_Reqs.modelData, state, size); + AppliNvm_Reqs.writeReq = MOBLE_TRUE; } #endif /* SAVE_MODEL_STATE_NVM */ return result; @@ -464,8 +370,10 @@ MOBLE_RESULT AppliNvm_ClearModelState(void) MOBLE_RESULT result = MOBLE_RESULT_FAIL; /* if save model state not defined, return MOBLE_RESULT_FAIL */ #if (SAVE_MODEL_STATE_NVM == 1) + MOBLEUINT8 subPageTemp[APP_NVM_SUBPAGE_SIZE]; MOBLEINT8 subPageIdx; - MOBLEUINT8 clearBuff[16] = {0}; + MOBLEUINT8 clearBuff[APP_NVM_GENERIC_MODEL_SIZE+APP_NVM_LIGHT_MODEL_SIZE] = {0}; + MOBLEUINT32 valid = 0; result = AppliNvm_FindFirstValidSubPage(&subPageIdx); @@ -475,40 +383,41 @@ MOBLE_RESULT AppliNvm_ClearModelState(void) } else { - /* clear models states */ - for (MOBLEUINT32 count=0; count<APP_NVM_GENERIC_MODEL_SIZE+APP_NVM_LIGHT_MODEL_SIZE; ) - { - if (FLASH_GetFlagStatus(Flash_CMDERR) == RESET) - { - /* If size to be written > 4 words, use FLASH_ProgramWordBurst*/ - if (APP_NVM_RESERVED_SIZE-count >= 4*N_BYTES_WORD) - { - result = AppliNvm_FlashProgram(FLASH_BURSTWRITE, - APP_NVM_SUBPAGE_OFFSET(subPageIdx)+APP_NVM_GENERIC_MODEL_OFFSET+count, - (uint32_t*)&clearBuff[count]); - count += 4*N_BYTES_WORD; - } - /* If size to be written < 4 words, use FLASH_ProgramWord*/ - else - { - result = AppliNvm_FlashProgram(FLASH_WRITE, - APP_NVM_SUBPAGE_OFFSET(subPageIdx)+APP_NVM_GENERIC_MODEL_OFFSET+count, - (uint32_t*)&clearBuff[count]); - count += N_BYTES_WORD; - } - } - else - { - /* Flash command error occurred */ - result = MOBLE_RESULT_FAIL; - break; - } + if(subPageIdx > 1) + { /* Not the first subpage */ + /* clear models states */ + memcpy((void*)&(subPageTemp[0]), + (void*)(APP_NVM_BASE + APP_NVM_SUBPAGE_OFFSET(subPageIdx-1)), + APP_NVM_SUBPAGE_SIZE); + memcpy((void*)&subPageTemp[APP_NVM_GENERIC_MODEL_OFFSET], + (void*)(clearBuff), + APP_NVM_GENERIC_MODEL_SIZE+APP_NVM_LIGHT_MODEL_SIZE); + subPageTemp[APP_NVM_VALID_FLAG_OFFSET] = valid; + + result = AppliNvm_FlashProgram(APP_NVM_SUBPAGE_OFFSET(subPageIdx), + (uint32_t*)&subPageTemp, + APP_NVM_SUBPAGE_SIZE); + } + else + { /* First subpage */ + memcpy((void*)&(subPageTemp[0]), + (void*)(APP_NVM_BASE + APP_NVM_SUBPAGE_OFFSET(subPageIdx)), + APP_NVM_SUBPAGE_SIZE); + memcpy((void*)&subPageTemp[APP_NVM_GENERIC_MODEL_OFFSET], + (void*)(clearBuff), + APP_NVM_GENERIC_MODEL_SIZE+APP_NVM_LIGHT_MODEL_SIZE); + subPageTemp[APP_NVM_VALID_FLAG_OFFSET] = valid; + + result = AppliNvm_FlashProgram(APP_NVM_SUBPAGE_OFFSET(subPageIdx), + (uint32_t*)&subPageTemp, + APP_NVM_SUBPAGE_SIZE); } } #endif /* SAVE_MODEL_STATE_NVM */ return result; } +#if 0 /** * @brief Load generic states from nvm * @param generic state buff @@ -518,32 +427,41 @@ MOBLE_RESULT AppliNvm_ClearModelState(void) MOBLE_RESULT AppliNvm_LoadGenericState(uint8_t state[], uint8_t* size) { #if (SAVE_MODEL_STATE_NVM == 1) - MOBLEINT8 subPageIdx; MOBLE_RESULT result = MOBLE_RESULT_SUCCESS; + MOBLEUINT8 subPageTemp[APP_NVM_SUBPAGE_SIZE]; + MOBLEINT8 subPageIdx; result = AppliNvm_FindFirstValidSubPage(&subPageIdx); - - if (MOBLE_FAILED(result)) - { - *size = 0; - result = MOBLE_RESULT_FAIL; - } - else - { - /* read saved reset counter from subpage */ - memcpy((void*)state, (void*)(APP_NVM_SUBPAGE_OFFSET(subPageIdx)+APP_NVM_GENERIC_MODEL_OFFSET), APP_NVM_GENERIC_MODEL_SIZE); - *size = APP_NVM_GENERIC_MODEL_SIZE; - } - - for (MOBLEUINT8 count=0; count<(*size); count++) + if (result == MOBLE_RESULT_SUCCESS) { - TRACE_M(TF_MISC, "%.2x ", *(state+count)); + if(subPageIdx > 0) + { + /* Not the first reset */ + /* read the previous subpage */ + memcpy((void*)&(subPageTemp[0]), + (void*)(APP_NVM_BASE + APP_NVM_SUBPAGE_OFFSET(subPageIdx-1)), + APP_NVM_SUBPAGE_SIZE); + + memcpy((void*)&(state[0]), + (void*)&(subPageTemp[APP_NVM_GENERIC_MODEL_OFFSET]), + APP_NVM_GENERIC_MODEL_SIZE); + *size = APP_NVM_GENERIC_MODEL_SIZE; + } + else + { + /* read the current subpage */ + memcpy((void*)&(subPageTemp[0]), + (void*)(APP_NVM_BASE + APP_NVM_SUBPAGE_OFFSET(subPageIdx)), + APP_NVM_SUBPAGE_SIZE); + + memcpy((void*)&(state[0]), + (void*)&(subPageTemp[APP_NVM_GENERIC_MODEL_OFFSET]), + APP_NVM_GENERIC_MODEL_SIZE); + *size = APP_NVM_GENERIC_MODEL_SIZE; + } } - - TRACE_M(TF_MISC,"\r\n"); - return result; -#else +#else /* SAVE_MODEL_STATE_NVM */ *size = 0; return MOBLE_RESULT_SUCCESS; #endif /* SAVE_MODEL_STATE_NVM */ @@ -558,34 +476,165 @@ MOBLE_RESULT AppliNvm_LoadGenericState(uint8_t state[], uint8_t* size) MOBLE_RESULT AppliNvm_LoadLightState(uint8_t state[], uint8_t* size) { #if (SAVE_MODEL_STATE_NVM == 1) - MOBLEINT8 subPageIdx; +// MOBLE_RESULT result = MOBLE_RESULT_SUCCESS; +// +// memcpy((void*)state, (void*)(AppliNvm_Reqs.modelData+APP_NVM_GENERIC_MODEL_SIZE), APP_NVM_LIGHT_MODEL_SIZE); +// *size = APP_NVM_GENERIC_MODEL_SIZE; +// +// return result; MOBLE_RESULT result = MOBLE_RESULT_SUCCESS; + MOBLEUINT8 subPageTemp[APP_NVM_SUBPAGE_SIZE]; + MOBLEINT8 subPageIdx; result = AppliNvm_FindFirstValidSubPage(&subPageIdx); - - if (MOBLE_FAILED(result)) + if (result == MOBLE_RESULT_SUCCESS) { - *size = 0; - result = MOBLE_RESULT_FAIL; + if(subPageIdx > 1) + { + /* Not the first reset */ + /* read the previous subpage */ + memcpy((void*)&(subPageTemp[0]), + (void*)(APP_NVM_BASE + APP_NVM_SUBPAGE_OFFSET(subPageIdx-1)), + APP_NVM_SUBPAGE_SIZE); + + memcpy((void*)&(state[0]), + (void*)&(subPageTemp[APP_NVM_LIGHT_MODEL_OFFSET]), + APP_NVM_LIGHT_MODEL_SIZE); + *size = APP_NVM_LIGHT_MODEL_SIZE; + } + else + { + /* read the current subpage */ + memcpy((void*)&(subPageTemp[0]), + (void*)(APP_NVM_BASE + APP_NVM_SUBPAGE_OFFSET(subPageIdx)), + APP_NVM_SUBPAGE_SIZE); + + memcpy((void*)&(state[0]), + (void*)&(subPageTemp[APP_NVM_LIGHT_MODEL_OFFSET]), + APP_NVM_LIGHT_MODEL_SIZE); + *size = APP_NVM_LIGHT_MODEL_SIZE; + } } - else - { - /* read saved reset counter from subpage */ - memcpy((void*)state, (void*)(APP_NVM_SUBPAGE_OFFSET(subPageIdx)+APP_NVM_LIGHT_MODEL_OFFSET), APP_NVM_LIGHT_MODEL_SIZE); - *size = APP_NVM_LIGHT_MODEL_SIZE; + return result; +#else /* SAVE_MODEL_STATE_NVM */ + *size = 0; + return MOBLE_RESULT_SUCCESS; +#endif /* SAVE_MODEL_STATE_NVM */ } +#endif - for (MOBLEUINT8 count=0; count<(*size); count++) - { - TRACE_M(TF_MISC, "%.2x ", *(state+count)); - } - - TRACE_M(TF_MISC,"\r\n"); +/** +* @brief Load Model states from nvm +* @param model state buff +* @param model state buff size +* @retval MOBLE_RESULT_SUCCESS on success +*/ +MOBLE_RESULT AppliNvm_LoadModelState(uint8_t state[], uint8_t* size) +{ +#if (SAVE_MODEL_STATE_NVM == 1) + MOBLE_RESULT result = MOBLE_RESULT_SUCCESS; + + memcpy((void*)state, (void*)(AppliNvm_Reqs.modelData), APP_NVM_MODEL_SIZE); + *size = APP_NVM_MODEL_SIZE; return result; -#else +#else /* SAVE_MODEL_STATE_NVM */ *size = 0; return MOBLE_RESULT_SUCCESS; #endif /* SAVE_MODEL_STATE_NVM */ } +/** +* @brief Process NVM erase and write requests +* @param void +* @retval void +*/ +void AppliNvm_Process(void) +{ + MOBLE_RESULT result; + MOBLEINT8 subPageIdx; + uint8_t reserveAreaCopy[APP_NVM_RESERVED_SIZE]; + + /* Erase if required */ + if (AppliNvm_Reqs.erasePageReq == MOBLE_TRUE) + { + /* save reserve flash area */ + memcpy((void*)reserveAreaCopy, (void*)APP_NVM_BASE, APP_NVM_RESERVED_SIZE); + + result = MoblePalNvmErase(APP_NVM_BASE, 0); + + if (result == MOBLE_RESULT_SUCCESS) + { + AppliNvm_Reqs.erasePageReq = MOBLE_FALSE; + AppliNvm_Reqs.writeReq = MOBLE_TRUE; + /* restore reserve area */ +/* FLASH_ProgramWordBurst(APP_NVM_BASE, (uint32_t*)reserveAreaCopy); */ + result = AppliNvm_FlashProgram(0, + (uint32_t*)&reserveAreaCopy, + APP_NVM_RESERVED_SIZE); + if (result == MOBLE_RESULT_SUCCESS) + { + AppliNvm_Reqs.writeReq = MOBLE_FALSE; + } + } + } + + if (AppliNvm_Reqs.erasePageReq == MOBLE_FALSE + && AppliNvm_Reqs.writeReq == MOBLE_TRUE) + { + result = AppliNvm_FindFirstValidSubPage(&subPageIdx); + if (result == MOBLE_RESULT_SUCCESS) + { + MOBLEUINT8 subPageTemp[APP_NVM_SUBPAGE_SIZE]; + MOBLEUINT32 valid = 0; + + if(subPageIdx > 0) + { + /* Not the first reset */ + /* read the previous subpage */ + memcpy((void*)&(subPageTemp[0]), + (void*)(APP_NVM_BASE + APP_NVM_SUBPAGE_OFFSET(subPageIdx-1)), + APP_NVM_SUBPAGE_SIZE); + } + else + { + /* read the current subpage */ + memcpy((void*)&(subPageTemp[0]), + (void*)(APP_NVM_BASE + APP_NVM_SUBPAGE_OFFSET(subPageIdx)), + APP_NVM_SUBPAGE_SIZE); + } + + memcpy((void*)&(subPageTemp[APP_NVM_GENERIC_MODEL_OFFSET]), + (void*)&(AppliNvm_Reqs.modelData), + APP_NVM_GENERIC_MODEL_SIZE+APP_NVM_LIGHT_MODEL_SIZE); + + subPageTemp[APP_NVM_VALID_FLAG_OFFSET] = valid; + + result = AppliNvm_FlashProgram(APP_NVM_SUBPAGE_OFFSET(subPageIdx), + (uint8_t*)subPageTemp, + APP_NVM_SUBPAGE_SIZE); + + if (result == MOBLE_RESULT_SUCCESS) + { + AppliNvm_Reqs.writeReq = MOBLE_FALSE; + } + } + else + { + /* do nothing */ + } + } +} + +/** +* @brief Fuction used to set the flag which is responsible for storing the + states in flash. +* @param void +* @retval void +*/ +void AppliNvm_SaveMessageParam (void) +{ +#ifdef SAVE_MODEL_STATE_FOR_ALL_MESSAGES + PowerOnOff_flag = FLAG_SET; +#endif +} |