Advanced Distributed Systems module at HSLU
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.
 
 
ADIS_Projects/ADIS_Sumo/Sumo/NVM_Config.c

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 */