You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
129 lines
3.2 KiB
129 lines
3.2 KiB
/**
|
|
* \file
|
|
* \brief Implementation of Non-Volatile-Memory storage
|
|
* \author Erich Styger
|
|
* \license SPDX-License-Identifier: BSD-3-Clause
|
|
* This provides an implementation to store and retrieve data from the on-chip memory.
|
|
*/
|
|
|
|
#include "platform.h"
|
|
#if PL_CONFIG_HAS_NVM_CONFIG
|
|
#include "McuLib.h"
|
|
#include "NVM_Config.h"
|
|
#include <stdlib.h>
|
|
#include "fsl_flash.h"
|
|
|
|
/*! @brief Flash driver Structure */
|
|
static flash_config_t s_flashDriver;
|
|
|
|
static bool isErased(uint8_t *ptr, int nofBytes) {
|
|
while (nofBytes>0) {
|
|
if (*ptr!=0xFF) {
|
|
return false; /* byte not erased */
|
|
}
|
|
ptr++;
|
|
nofBytes--;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
uint8_t NVMC_SetBlockFlash(uint32_t addr, void *data, size_t dataSize) {
|
|
static uint32_t buf[NVMC_FLASH_BLOCK_SIZE/4]; /* backup buffer */
|
|
unsigned int i;
|
|
status_t status;
|
|
uint8_t *p, *q;
|
|
|
|
/* make backup of current content */
|
|
for(i=0;i<sizeof(buf)/4; i++) {
|
|
buf[i] = ((uint32_t*)NVMC_FLASH_START_ADDR)[i];
|
|
}
|
|
/* erase */
|
|
status = FLASH_Erase(&s_flashDriver, NVMC_FLASH_START_ADDR, s_flashDriver.PFlashSectorSize, kFLASH_ApiEraseKey);
|
|
if (status!=kStatus_FLASH_Success) {
|
|
return ERR_FAILED;
|
|
}
|
|
/* copy new data into backup */
|
|
p = ((uint8_t*)buf)+(addr-NVMC_FLASH_START_ADDR);
|
|
q = (uint8_t*)data;
|
|
for(i=0;i<dataSize; i++) {
|
|
*p = *q;
|
|
p++; q++;
|
|
}
|
|
status = FLASH_Program(&s_flashDriver, NVMC_FLASH_START_ADDR, buf, sizeof(buf));
|
|
if (status!=kStatus_FLASH_Success) {
|
|
return ERR_FAILED;
|
|
}
|
|
return ERR_OK;
|
|
}
|
|
|
|
|
|
#if PL_HAS_RADIO
|
|
uint8_t NVMC_SaveDeviceAddress16(void *data, size_t dataSize) {
|
|
uint8_t res;
|
|
|
|
if (dataSize!=2) {
|
|
return ERR_OVERFLOW;
|
|
}
|
|
res = IFsh1_SetBlockFlash((byte*)data, (IFsh1_TAddress)(NVMC_GetDeviceAddr16Addr()), dataSize);
|
|
return res;
|
|
}
|
|
#endif
|
|
|
|
uint8_t NVMC_SaveReflectanceData(void *data, uint16_t dataSize) {
|
|
if (dataSize>NVMC_REFLECTANCE_DATA_SIZE) {
|
|
return ERR_OVERFLOW;
|
|
}
|
|
return NVMC_SetBlockFlash(NVMC_REFLECTANCE_DATA_START_ADDR, data, dataSize);
|
|
}
|
|
|
|
void *NVMC_GetReflectanceData(void) {
|
|
if (isErased((uint8_t*)NVMC_REFLECTANCE_DATA_START_ADDR, NVMC_REFLECTANCE_DATA_SIZE)) {
|
|
return NULL;
|
|
}
|
|
return (void*)NVMC_REFLECTANCE_DATA_START_ADDR;
|
|
}
|
|
|
|
#if PL_CONFIG_APP_SUMO
|
|
uint8_t NVMC_SaveSumoData(void *data, uint16_t dataSize) {
|
|
if (dataSize>NVMC_SUMO_DATA_SIZE) {
|
|
return ERR_OVERFLOW;
|
|
}
|
|
return NVMC_SetBlockFlash(NVMC_SUMO_DATA_START_ADDR, data, dataSize);
|
|
}
|
|
|
|
void *NVMC_GetSumoData(void) {
|
|
if (isErased((uint8_t*)NVMC_SUMO_DATA_START_ADDR, NVMC_SUMO_DATA_SIZE)) {
|
|
return NULL;
|
|
}
|
|
return (void*)NVMC_SUMO_DATA_START_ADDR;
|
|
}
|
|
|
|
#endif /* PL_CONFIG_APP_SUMO */
|
|
|
|
uint8_t NVMC_SaveRobotData(NVMC_RobotData *data) {
|
|
return NVMC_SetBlockFlash(NVMC_ROBOT_DATA_START_ADDR, data, sizeof(NVMC_RobotData));
|
|
}
|
|
|
|
const NVMC_RobotData *NVMC_GetRobotData(void) {
|
|
if (isErased((uint8_t*)NVMC_ROBOT_DATA_START_ADDR, sizeof(NVMC_RobotData))) {
|
|
return NULL;
|
|
}
|
|
return (void*)NVMC_ROBOT_DATA_START_ADDR;
|
|
}
|
|
|
|
void NVMC_Deinit(void) {
|
|
}
|
|
|
|
void NVMC_Init(void) {
|
|
status_t status;
|
|
|
|
memset(&s_flashDriver, 0, sizeof(flash_config_t));
|
|
status = FLASH_Init(&s_flashDriver);
|
|
if (status!=kStatus_FLASH_Success) {
|
|
for(;;) {} /* error */
|
|
}
|
|
}
|
|
|
|
#endif /* PL_CONFIG_HAS_NVM_CONFIG */
|
|
|
|
|
|
|