summaryrefslogtreecommitdiff
path: root/digital/zigbit/bitcloud/stack/Components/PersistDataServer/src
diff options
context:
space:
mode:
Diffstat (limited to 'digital/zigbit/bitcloud/stack/Components/PersistDataServer/src')
-rw-r--r--digital/zigbit/bitcloud/stack/Components/PersistDataServer/src/pdsCrcService.c217
-rw-r--r--digital/zigbit/bitcloud/stack/Components/PersistDataServer/src/pdsDataServer.c206
-rw-r--r--digital/zigbit/bitcloud/stack/Components/PersistDataServer/src/pdsWriteData.c286
3 files changed, 709 insertions, 0 deletions
diff --git a/digital/zigbit/bitcloud/stack/Components/PersistDataServer/src/pdsCrcService.c b/digital/zigbit/bitcloud/stack/Components/PersistDataServer/src/pdsCrcService.c
new file mode 100644
index 00000000..de9631dc
--- /dev/null
+++ b/digital/zigbit/bitcloud/stack/Components/PersistDataServer/src/pdsCrcService.c
@@ -0,0 +1,217 @@
+/***************************************************************************//**
+ \file pdsCrcService.c
+
+ \brief Persistence Data Server implementation
+
+ \author
+ Atmel Corporation: http://www.atmel.com \n
+ Support email: avr@atmel.com
+
+ Copyright (c) 2008-2011, Atmel Corporation. All rights reserved.
+ Licensed under Atmel's Limited License Agreement (BitCloudTM).
+
+ \internal
+ History:
+ 22/01/08 A. Khromykh - Created
+ 01/11/10 A. Razinkov - Modified
+*****************************************************************************/
+
+#ifdef _COMMISSIONING_
+/******************************************************************************
+ Includes section
+******************************************************************************/
+#include <pdsMemAbstract.h>
+#include <pdsCrcService.h>
+#include <pdsAuxService.h>
+#include <taskManager.h>
+#include <csPersistentMem.h>
+#include <pdsWriteData.h>
+
+/******************************************************************************
+\brief Calculate CRC of persistent data stored in persist memory
+\
+\param[out] crcStation - pointer to CRC service structure
+******************************************************************************/
+void pdsCalculateCrc(PDS_ServiceCrc_t *crcStation)
+{
+ uint8_t tdata = 0;
+ MEMORY_DESCRIPTOR descriptor;
+
+ if (NULL == crcStation)
+ return;
+
+ crcStation->crc = 0;
+ descriptor.address = SYSTEM_BASE_EEPROM_ADDRESS;
+ descriptor.length = 1;
+ while (descriptor.address < csPersistentMemorySize)
+ {
+ descriptor.data = &tdata;
+
+ pdsWaitMemoryFree();
+
+ if (EEPROM_ERROR == READ_MEMORY(&descriptor, NULL))
+ {
+ crcStation->eepromState = PDS_EEPROM_ERROR;
+ return;
+ }
+
+ pdsWaitMemoryFree();
+
+ crcStation->crc += tdata;
+ descriptor.address++;
+ }
+ crcStation->eepromState = PDS_SUCCESS;
+}
+
+/******************************************************************************
+\brief Read CRC of stored data from persist memory
+\
+\param[out] crcStation - pointer to CRC service structure
+******************************************************************************/
+void pdsReadCrc(PDS_ServiceCrc_t *crcStation)
+{
+ MEMORY_DESCRIPTOR descriptor;
+
+ if (NULL == crcStation)
+ return;
+
+ descriptor.address = csPersistentMemorySize;
+ descriptor.length = 1;
+ while (descriptor.address < USER_BASE_EEPROM_ADDRESS)
+ {
+ descriptor.data = &(crcStation->crc);
+
+ pdsWaitMemoryFree();
+
+ if (EEPROM_ERROR == READ_MEMORY(&descriptor, NULL))
+ {
+ crcStation->eepromState = PDS_EEPROM_ERROR;
+ return;
+ }
+
+ pdsWaitMemoryFree();
+
+ if (0xFF != crcStation->crc)
+ {
+ crcStation->position = descriptor.address;
+ crcStation->eepromState = PDS_SUCCESS;
+ return;
+ }
+ descriptor.address++;
+ }
+ crcStation->position = csPersistentMemorySize;
+ crcStation->eepromState = PDS_SUCCESS;
+}
+
+/******************************************************************************
+\brief Clears whole CRC area in persist memory
+\
+\return operation result
+******************************************************************************/
+PDS_DataServerState_t pdsClearCrcArea(void)
+{
+ uint8_t value = 0xFF;
+ MEMORY_DESCRIPTOR descriptor;
+ uint8_t status;
+
+ descriptor.data = &value;
+ descriptor.address = csPersistentMemorySize;
+ descriptor.length = 1;
+
+ for (uint8_t i = 0; i < PDS_CRC_AREA; i++)
+ {
+ status = pdsWrite(&descriptor, pdsDummyCallback);
+ if (status != PDS_SUCCESS)
+ return status;
+
+ descriptor.address++;
+ }
+ return PDS_SUCCESS;
+}
+
+/******************************************************************************
+\brief Write CRC of stored data to persist memory. The ring buffer used
+\ to increase persist memory life cycle
+\
+\param[out] crcStation - pointer to CRC service structure
+******************************************************************************/
+PDS_DataServerState_t pdsWriteCrc(void)
+{
+ PDS_ServiceCrc_t crcRead, crcCalc;
+ MEMORY_DESCRIPTOR descriptor;
+ uint8_t datadelete = 0xFF;
+ PDS_DataServerState_t status;
+
+ pdsReadCrc(&crcRead);
+ if (PDS_EEPROM_ERROR == crcRead.eepromState)
+ return PDS_EEPROM_ERROR;
+
+ pdsCalculateCrc(&crcCalc);
+ if (PDS_EEPROM_ERROR == crcCalc.eepromState)
+ return PDS_EEPROM_ERROR;
+
+ if (0 == (uint8_t)(crcCalc.crc + crcRead.crc))
+ return PDS_SUCCESS;
+
+ crcCalc.crc = 0 - crcCalc.crc;
+ descriptor.address = crcRead.position;
+ descriptor.data = &datadelete;
+ descriptor.length = 1;
+
+ status = pdsWrite(&descriptor, pdsDummyCallback);
+ if (status != PDS_SUCCESS)
+ return status;
+
+ if (++descriptor.address >= USER_BASE_EEPROM_ADDRESS)
+ descriptor.address = csPersistentMemorySize;
+ descriptor.data = &(crcCalc.crc);
+
+ status = pdsWrite(&descriptor, pdsDummyCallback);
+ if (status != PDS_SUCCESS)
+ return status;
+
+ return PDS_SUCCESS;
+}
+
+/******************************************************************************
+\brief Check if any valid data exists in persist memory
+\
+\return operation result
+******************************************************************************/
+PDS_DataServerState_t pdsCheckPersistMemory(void)
+{
+ PDS_ServiceCrc_t crcRead, crcCalc;
+
+ pdsCalculateCrc(&crcCalc);
+ if (PDS_EEPROM_ERROR == crcCalc.eepromState)
+ return PDS_EEPROM_ERROR;
+
+ pdsReadCrc(&crcRead);
+ if (PDS_EEPROM_ERROR == crcRead.eepromState)
+ return PDS_EEPROM_ERROR;
+
+ if (0x00 == (uint8_t)(crcCalc.crc + crcRead.crc))
+ return PDS_SUCCESS;
+
+ return PDS_CRC_ERROR;
+}
+
+#ifdef __DBG_PDS__
+ uint8_t eepromCopy[0x400u];
+
+ void pdsDbgReadAllEeprom(void)
+ {
+ PDS_DataServerState_t status;
+ MEMORY_DESCRIPTOR descriptor;
+
+ descriptor.address = 0;
+ descriptor.data = eepromCopy;
+ descriptor.length = 0x400u;
+
+ status = pdsRead(&descriptor, pdsDummyCallback);
+ if (status != PDS_SUCCESS)
+ return;
+ }
+#endif
+#endif /* _COMMISSIONING_ */
+// eof pdsDataServer.c
diff --git a/digital/zigbit/bitcloud/stack/Components/PersistDataServer/src/pdsDataServer.c b/digital/zigbit/bitcloud/stack/Components/PersistDataServer/src/pdsDataServer.c
new file mode 100644
index 00000000..530ac0a7
--- /dev/null
+++ b/digital/zigbit/bitcloud/stack/Components/PersistDataServer/src/pdsDataServer.c
@@ -0,0 +1,206 @@
+/***************************************************************************//**
+ \file pdsDataServer.c
+
+ \brief Persistence Data Server implementation
+
+ \author
+ Atmel Corporation: http://www.atmel.com \n
+ Support email: avr@atmel.com
+
+ Copyright (c) 2008-2011, Atmel Corporation. All rights reserved.
+ Licensed under Atmel's Limited License Agreement (BitCloudTM).
+
+ \internal
+ History:
+ 22/01/08 A. Khromykh - Created
+ 01/11/10 A. Razinkov - Modified
+*****************************************************************************/
+/******************************************************************************
+ Includes section
+******************************************************************************/
+#include <pdsMemAbstract.h>
+#include <appTimer.h>
+#include <pdsDataServer.h>
+#include <pdsCrcService.h>
+#include <pdsAuxService.h>
+#include <leds.h>
+#include <pdsWriteData.h>
+#include <csPersistentMem.h>
+#include <taskManager.h>
+
+#ifdef _COMMISSIONING_
+/******************************************************************************
+ Prototypes section
+******************************************************************************/
+
+/******************************************************************************
+ External variables section
+******************************************************************************/
+/* Number of records in csPersistentMemTable*/
+extern const uint8_t csPersistentItemsAmount;
+
+/******************************************************************************
+ Implementations section
+******************************************************************************/
+/******************************************************************************
+\brief Persist Data Server initialization procedure
+******************************************************************************/
+void PDS_Init(void)
+{
+ PDS_DataServerState_t status;
+
+#ifdef USE_LED
+ BSP_OpenLeds();
+#endif
+
+ /* Check if any valid data exists in persist memory */
+ status = pdsCheckPersistMemory();
+
+ /* Valid data exists - try to update from persist memory */
+ if (PDS_SUCCESS == status)
+ {
+ if (PDS_EEPROM_ERROR != pdsUpdate())
+ {
+ pdsStartPersistServer();
+ }
+ }
+
+ else if (PDS_EEPROM_ERROR != status)
+ {
+ pdsStartPersistServer();
+ }
+}
+
+/******************************************************************************
+\brief Set the default system area values and store persistent data to persist
+ memory
+
+\return operation result
+******************************************************************************/
+PDS_DataServerState_t PDS_SetToDefault(void)
+{
+ MEMORY_DESCRIPTOR descriptor;
+ PDS_DataServerState_t status;
+
+ CS_PdsDefaultValue();
+ /* Store all persistent parameters */
+ for (uint8_t index = 0; index < csPersistentItemsAmount; index++)
+ {
+ pdsPrepareMemoryAccess(index, &descriptor);
+ status = pdsWrite(&descriptor, pdsDummyCallback);
+ if (status != PDS_SUCCESS)
+ return status;
+ }
+
+ /* Reset CRC area and rewrite CRC*/
+ status = pdsClearCrcArea();
+ if (status != PDS_SUCCESS)
+ return status;
+ status = pdsWriteCrc();
+ if (status != PDS_SUCCESS)
+ return status;
+
+ return PDS_SUCCESS;
+}
+
+/******************************************************************************
+\brief On-demand data storing in persist memory
+******************************************************************************/
+void PDS_FlushData(void)
+{
+ if (SAVE_IS_STOPED == savingIsStarted)
+ {
+ /* Force timer to finish - store data immediately */
+ HAL_StopAppTimer(&pdsEepromSaveServiceTimer);
+ pdsOnTimerSave();
+ }
+
+ while (SAVE_IS_STARTED == savingIsStarted)
+ {
+ SYS_ForceRunTask();
+ }
+}
+
+/***************************************************************************//**
+\brief Must be called only from ::APL_TaskHandler() function.\n
+ Stops persist data server.
+*******************************************************************************/
+void PDS_Stop(void)
+{
+ while (SAVE_IS_STARTED == savingIsStarted)
+ {
+ SYS_ForceRunTask();
+ }
+
+ HAL_StopAppTimer(&pdsEepromSaveServiceTimer);
+}
+#endif /* _COMMISSIONING_ */
+
+/******************************************************************************
+\brief Read data from user area in persist memory
+
+\param[in] offset - data offset in persist memory
+\param[in] length - data lenght
+\param[out] data - pointer to user data area in RAM
+\param[out] callback - callback to read-finished event handler
+
+\return operation result
+******************************************************************************/
+PDS_DataServerState_t PDS_ReadUserData(uint16_t offset, uint8_t *data, uint16_t length, void (*callback)(void))
+{
+ MEMORY_DESCRIPTOR descriptor;
+ PDS_DataServerState_t status;
+
+ descriptor.address = USER_BASE_EEPROM_ADDRESS + offset;
+ descriptor.length = length;
+ descriptor.data = data;
+
+ while(SAVE_IS_STARTED == savingIsStarted)
+ {
+ SYS_ForceRunTask();
+ }
+
+ if (NULL == callback)
+ callback = pdsDummyCallback;
+
+ status = pdsRead(&descriptor, callback);
+ if (status != PDS_SUCCESS)
+ return status;
+
+ return PDS_SUCCESS;
+}
+
+/******************************************************************************
+\brief Write data to user area in persist memory
+\
+\param[in] offset - data offset in persist memory
+\param[in] length - data lenght
+\param[out] data - pointer to user data area
+\param[out] callback - callback to read-finished event handler
+
+\return operation result
+******************************************************************************/
+PDS_DataServerState_t PDS_WriteUserData(uint16_t offset, uint8_t *data, uint16_t length, void (*callback)(void))
+{
+ MEMORY_DESCRIPTOR descriptor;
+ PDS_DataServerState_t status;
+
+ descriptor.address = USER_BASE_EEPROM_ADDRESS + offset;
+ descriptor.length = length;
+ descriptor.data = data;
+
+ while(SAVE_IS_STARTED == savingIsStarted)
+ {
+ SYS_ForceRunTask();
+ }
+
+ if (NULL == callback)
+ callback = pdsDummyCallback;
+
+ status = pdsWrite(&descriptor, callback);
+ if (status != PDS_SUCCESS)
+ return status;
+
+ return PDS_SUCCESS;
+}
+// eof pdsDataServer.c
diff --git a/digital/zigbit/bitcloud/stack/Components/PersistDataServer/src/pdsWriteData.c b/digital/zigbit/bitcloud/stack/Components/PersistDataServer/src/pdsWriteData.c
new file mode 100644
index 00000000..bb7f9859
--- /dev/null
+++ b/digital/zigbit/bitcloud/stack/Components/PersistDataServer/src/pdsWriteData.c
@@ -0,0 +1,286 @@
+/**************************************************************************//**
+ \file pdsWriteData.c
+
+ \brief Periodic data save implementation
+
+ \author
+ Atmel Corporation: http://www.atmel.com \n
+ Support email: avr@atmel.com
+
+ Copyright (c) 2008-2011, Atmel Corporation. All rights reserved.
+ Licensed under Atmel's Limited License Agreement (BitCloudTM).
+
+ \internal
+ History:
+ 22/01/08 A. Khromykh - Created
+ 01/11/10 A. Razinkov - Modified
+*****************************************************************************/
+/******************************************************************************
+ Includes section
+******************************************************************************/
+#include <pdsMemAbstract.h>
+#include <appTimer.h>
+#include <pdsCrcService.h>
+#include <pdsAuxService.h>
+#include <leds.h>
+#include <stddef.h>
+#include <csPersistentMem.h>
+#include <pdsDbg.h>
+#include <pdsWriteData.h>
+#include <taskManager.h>
+
+/******************************************************************************
+ Global variables section
+******************************************************************************/
+uint8_t savingIsStarted = SAVE_IS_STOPED;
+
+#ifdef _COMMISSIONING_
+HAL_AppTimer_t pdsEepromSaveServiceTimer;
+
+/******************************************************************************
+ External variables section
+******************************************************************************/
+/* Configuration Server persistent memory table */
+extern const CS_PersistantData_t PROGMEM_DECLARE(csPersistentMemTable[]);
+
+/* Number of records in csPersistentMemTable*/
+extern const uint8_t csPersistentItemsAmount;
+
+/* Total size of memory occupied by persistent parameters */
+extern const uint16_t csPersistentMemorySize;
+
+/******************************************************************************
+ Prototypes section
+******************************************************************************/
+static PDS_DataServerState_t pdsCommit(void);
+static bool pdsCommitStarted(MEMORY_DESCRIPTOR* descriptor);
+
+/******************************************************************************
+ Implementation section
+******************************************************************************/
+/******************************************************************************
+\brief Start internal PDS timer
+\
+\param[in] typeInterval - set timer interval. Available intervals are:
+ PDS_LONG_INTERVAL - 5 minutes
+ PDS_SHORT_INTERVAL - 50 msec
+\param[out] callback - callback on timer fired event
+
+******************************************************************************/
+void pdsStartPdsTimer(void (*callback)(void), uint8_t typeInterval)
+{
+ pdsEepromSaveServiceTimer.callback = callback;
+ if (PDS_LONG_INTERVAL == typeInterval)
+ {
+#ifdef _POWER_FAILURE_
+ uint32_t storingInterval;
+
+ CS_ReadParameter(CS_PDS_STORING_INTERVAL_ID, &storingInterval);
+ pdsEepromSaveServiceTimer.interval = storingInterval;
+#else
+ pdsEepromSaveServiceTimer.interval = STORE_TIMER_TIMEOUT;
+#endif /* _POWER_FAILURE_ */
+ }
+ else
+ pdsEepromSaveServiceTimer.interval = SHORT_TIMEOUT;
+ pdsEepromSaveServiceTimer.mode = TIMER_ONE_SHOT_MODE;
+ HAL_StartAppTimer(&pdsEepromSaveServiceTimer);
+}
+
+/*******************************************************************************
+\brief Start server work
+*******************************************************************************/
+void pdsStartPersistServer(void)
+{
+ pdsStartPdsTimer(pdsOnTimerSave, PDS_LONG_INTERVAL);
+}
+
+/******************************************************************************
+\brief Commit item value changes (if any) from Configuration Server to persist
+\ memory
+\
+\param[in] descriptor - memory descriptor to store parameter value
+
+\return true - if changes found and commit started; false - otherwise
+******************************************************************************/
+static bool pdsCommitStarted(MEMORY_DESCRIPTOR* descriptor)
+{
+ uint8_t data;
+ MEMORY_DESCRIPTOR byteAccessDescriptor =
+ {
+ .data = &data,
+ .length = 1
+ };
+
+ /* Check for any changes in byte-by-byte order */
+ for (uint16_t i = 0; i < descriptor->length; i++)
+ {
+ byteAccessDescriptor.address = descriptor->address + i;
+ pdsRead(&byteAccessDescriptor, pdsDummyCallback);
+ /* Start rewrite out of date data in persist memory*/
+ if (*byteAccessDescriptor.data != *((descriptor->data) + i))
+ {
+ pdsWrite(descriptor, pdsOnTimerSave);
+ return true;
+ }
+ }
+ return false;
+}
+
+/******************************************************************************
+\brief Update persistent items values in Configuration Server from persist memory
+\
+\return Operation result
+******************************************************************************/
+PDS_DataServerState_t pdsUpdate(void)
+{
+ PDS_DataServerState_t status;
+ MEMORY_DESCRIPTOR descriptor;
+
+ for (uint8_t item = 0; item < csPersistentItemsAmount; item++)
+ {
+ pdsPrepareMemoryAccess(item, &descriptor);
+ status = pdsRead(&descriptor, pdsDummyCallback);
+ if (status != PDS_SUCCESS)
+ return status;
+ }
+ return PDS_SUCCESS;
+}
+
+/******************************************************************************
+\brief Commit persistent memory changes (if any) from Configuration Server
+\ to persist memory. Process comes iterative way - when some item stored,
+\ this function will be called as a callback.
+\
+\return Operation result
+******************************************************************************/
+PDS_DataServerState_t pdsCommit(void)
+{
+ MEMORY_DESCRIPTOR descriptor;
+ static uint8_t item = 0;
+
+ while (item < csPersistentItemsAmount)
+ {
+ pdsPrepareMemoryAccess(item, &descriptor);
+ if(pdsCommitStarted(&descriptor))
+ return PDS_COMMIT_IN_PROGRESS;
+
+ item++;
+ }
+ item = 0;
+ return PDS_SUCCESS;
+}
+
+/******************************************************************************
+\brief Timer callback, initiates the commit process.
+******************************************************************************/
+void pdsOnTimerSave(void)
+{
+#ifdef USE_LED
+ BSP_OnLed(LED_YELLOW);
+#endif
+
+ savingIsStarted = SAVE_IS_STARTED;
+
+ if (PDS_SUCCESS == pdsCommit())
+ {
+ if (PDS_EEPROM_ERROR == pdsWriteCrc())
+ {
+ pdsStartPdsTimer(pdsOnTimerSave, PDS_SHORT_INTERVAL);
+ }
+ else
+ {
+ pdsStartPersistServer();
+#ifdef USE_LED
+ BSP_OffLed(LED_YELLOW);
+#endif
+ savingIsStarted = SAVE_IS_STOPED;
+ }
+ }
+}
+
+/******************************************************************************
+\brief Locates parameter by it's index in persistent memory table. And prepares
+\ memory descriptor to store parameter's value in EEPROM
+\
+\param[in] index - index of the parameter in persistent memory table
+\param[out]descriptor - memory descriptor to store parameter value
+******************************************************************************/
+void pdsPrepareMemoryAccess(uint8_t index, MEMORY_DESCRIPTOR* descriptor)
+{
+ CS_PersistantData_t item;
+
+ memcpy_P(&item, &csPersistentMemTable[index], sizeof(CS_PersistantData_t));
+
+ assert(item.value, PDS_PDSPREPAREMEMORYACCESS0);
+ descriptor->data = item.value;
+ descriptor->address = item.offset;
+
+ /* Calculate item size using offsets */
+ if (index == (csPersistentItemsAmount-1))
+ {
+ descriptor->length = csPersistentMemorySize - item.offset;
+ }
+ else
+ {
+ CS_PersistantData_t nextItem;
+ memcpy_P(&nextItem, &csPersistentMemTable[index+1], sizeof(CS_PersistantData_t));
+ assert(nextItem.value, PDS_PDSPREPAREMEMORYACCESS1);
+ descriptor->length = nextItem.offset - item.offset;
+ }
+}
+#endif /* _COMMISSIONING_ */
+
+/******************************************************************************
+\brief Write data to persist memory
+\
+\param[in] descriptor - memory descriptor to store parameter value
+\param[out]callback - callback to write-finished event handler
+******************************************************************************/
+PDS_DataServerState_t pdsWrite(MEMORY_DESCRIPTOR* descriptor, void (*callback)(void))
+{
+ pdsWaitMemoryFree();
+ if (EEPROM_ERROR == WRITE_MEMORY(descriptor, callback))
+ return PDS_EEPROM_ERROR;
+
+ if (callback == pdsDummyCallback)
+ pdsWaitMemoryFree();
+
+ return PDS_SUCCESS;
+}
+
+/******************************************************************************
+\brief Read data from persist memory
+\
+\param[in] descriptor - memory descriptor to read parameter value
+\param[out]callback - callback to read-finished event handler
+******************************************************************************/
+PDS_DataServerState_t pdsRead(MEMORY_DESCRIPTOR* descriptor, void (*callback)(void))
+{
+ pdsWaitMemoryFree();
+ if (EEPROM_ERROR == READ_MEMORY(descriptor, callback))
+ return PDS_EEPROM_ERROR;
+
+ if (callback == pdsDummyCallback)
+ pdsWaitMemoryFree();
+
+ return PDS_SUCCESS;
+}
+
+/******************************************************************************
+\brief Wait until memory be ready for transaction
+******************************************************************************/
+void pdsWaitMemoryFree(void)
+{
+ while(IS_MEMORY_BUSY())
+ {
+ SYS_ForceRunTask();
+ }
+}
+
+/*******************************************************************************
+\brief Dummy callback
+*******************************************************************************/
+void pdsDummyCallback(void)
+{}
+// eof pdsDataServer.c