summaryrefslogtreecommitdiff
path: root/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src
diff options
context:
space:
mode:
Diffstat (limited to 'digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src')
-rw-r--r--digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdAt25Driver.c742
-rw-r--r--digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdAt45dbDriver.c758
-rw-r--r--digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdCommand.c243
-rw-r--r--digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdCrcService.c66
-rw-r--r--digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdFakeDriver.c218
-rw-r--r--digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdIntFlashRead.s40
-rw-r--r--digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdIntFlashRead.s9040
-rw-r--r--digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdSpiSerializer.c91
8 files changed, 2198 insertions, 0 deletions
diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdAt25Driver.c b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdAt25Driver.c
new file mode 100644
index 00000000..4f470eb4
--- /dev/null
+++ b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdAt25Driver.c
@@ -0,0 +1,742 @@
+/**************************************************************************//**
+\file ofdAt25fDriver.c
+
+\brief Implementation of chip-flash interface.
+
+\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:
+ 5/12/07 A. Khromykh - Created
+*******************************************************************************/
+/******************************************************************************
+ * WARNING: CHANGING THIS FILE MAY AFFECT CORE FUNCTIONALITY OF THE STACK. *
+ * EXPERT USERS SHOULD PROCEED WITH CAUTION. *
+ ******************************************************************************/
+
+#ifdef _OTAU_
+#if ((EXTERNAL_MEMORY == AT25F2048) ||(EXTERNAL_MEMORY == AT25DF041A)) && (APP_USE_OTAU == 1)
+#if APP_USE_FAKE_OFD_DRIVER == 0
+
+/******************************************************************************
+ Includes section
+******************************************************************************/
+#include <ofdExtMemory.h>
+#include <ofdMemoryDriver.h>
+#include <spi.h>
+#include <eeprom.h>
+#include <appTimer.h>
+
+/******************************************************************************
+ Define(s) section
+******************************************************************************/
+#define SPI_BUSY_POLL_PERIOD 10
+// cycles of counting flash crc before context gap.
+#define ATOMIC_COUNTING 128
+#define EEPROM_OK 0
+#define EEPROM_BUSY -2
+
+/******************************************************************************
+ Types section
+******************************************************************************/
+typedef enum
+{
+ FLASH_BUSY,
+ FLASH_READY
+} FlashBusyState_t;
+
+typedef enum
+{
+ FLASH_TRANSACTION,
+ EEPROM_TRANSACTION
+} DelayedTransactionType_t;
+
+/******************************************************************************
+ Prototypes section
+******************************************************************************/
+static inline uint8_t ofdReadStatusRegister(void);
+static inline void ofdStartPollTimer(DelayedTransactionType_t type);
+static void ofdReadImageTable(void);
+static void ofdSaveCrcCallback(void);
+static void ofdContinueEraseImage(void);
+static void ofdSaveCurrentEepromImage(void);
+static void ofdFlushCrcCallback(OFD_Status_t status, OFD_ImageInfo_t *pInfo);
+static void ofdSaveCurrentEepromImageContinue(void);
+static void ofdPollBusyState(void);
+static void ofdStartFlashDelayedTransaction(void);
+static void ofdStartEepromDelayedTransaction(void);
+uint8_t ofdReadInternalFlash(uint32_t flashAddress);
+#if defined(_OFD_DEBUG_)
+void ofdReadData(uint32_t address, uint8_t *data, uint16_t size, OFD_Callback_t cb);
+#endif
+
+/******************************************************************************
+ External variables section
+******************************************************************************/
+extern HAL_SpiDescriptor_t spiDesc;
+extern OFD_Position_t sectorNumber;
+extern OFD_Position_t actionSector;
+extern OFD_Callback_t ofdCallback;
+extern OFD_Callback_t ofdAuxCallback;
+extern OFD_MemoryAccessParam_t localAccessStructure;
+extern OFD_ImageInfo_t imageInfo;
+extern OfdImageTable_t imageTable;
+extern OfdInternalMemoryAccessParam_t internalAccessParam;
+
+/******************************************************************************
+ Global variables section
+******************************************************************************/
+static HAL_AppTimer_t ofdBusyTimer =
+{
+ .interval = SPI_BUSY_POLL_PERIOD,
+ .mode = TIMER_ONE_SHOT_MODE,
+};
+void (* delayedTransaction)(void) = NULL;
+#if defined(_OFD_DEBUG_)
+static HAL_UsartDescriptor_t usartDescriptor;
+static uint32_t debugOffset = 0ul;
+static uint8_t debugBuffer[OFD_BLOCK_SIZE];
+#endif
+
+/******************************************************************************
+ Implementations section
+******************************************************************************/
+/**************************************************************************//**
+\brief Checks flash station.
+
+\return flash states: \n
+ FLASH_BUSY \n
+ FLASH_READY
+******************************************************************************/
+static inline FlashBusyState_t ofdCheckBusyState(void)
+{
+ uint8_t statusReg = ofdReadStatusRegister();
+
+ if (!(statusReg & RDY))
+ return FLASH_READY;
+
+ return FLASH_BUSY;
+}
+
+/**************************************************************************//**
+\brief Starts flash delayed transaction.
+******************************************************************************/
+static void ofdStartFlashDelayedTransaction(void)
+{
+ if (FLASH_READY == ofdCheckBusyState())
+ delayedTransaction();
+ else
+ ofdStartPollTimer(FLASH_TRANSACTION);
+}
+
+/**************************************************************************//**
+\brief Starts eeprom delayed transaction.
+******************************************************************************/
+static void ofdStartEepromDelayedTransaction(void)
+{
+ if (!HAL_IsEepromBusy())
+ delayedTransaction();
+ else
+ ofdStartPollTimer(EEPROM_TRANSACTION);
+}
+
+/**************************************************************************//**
+\brief Starts timer for start delayed transaction.
+
+\param[in]
+ type - transaction type (flash or eeprom)
+******************************************************************************/
+static inline void ofdStartPollTimer(DelayedTransactionType_t type)
+{
+ if (FLASH_TRANSACTION == type)
+ ofdBusyTimer.callback = ofdStartFlashDelayedTransaction;
+ else
+ ofdBusyTimer.callback = ofdStartEepromDelayedTransaction;
+
+ HAL_StartAppTimer(&ofdBusyTimer);
+}
+
+/**************************************************************************//**
+\brief Routine of eeprom access.
+\param[in]
+ result - result of hal eeprom action
+\param[in]
+ action - initiator action
+\return
+ false - incorrect parameters
+ true - eeprom transaction is started
+******************************************************************************/
+static bool ofdEepromHandler(int result, void(* action)())
+{
+ switch (result)
+ {
+ case EEPROM_OK:
+ return true;
+ case EEPROM_BUSY:
+ delayedTransaction = action;
+ ofdStartPollTimer(EEPROM_TRANSACTION);
+ return true;
+ default:
+ return false;
+ }
+}
+
+/**************************************************************************//**
+\brief Returns SUCCESS status.
+******************************************************************************/
+static void ofdReturnSuccessStatus(void)
+{
+ if (ofdCallback)
+ ofdCallback(OFD_STATUS_SUCCESS);
+}
+
+/**************************************************************************//**
+\brief Reads image table.
+******************************************************************************/
+static void ofdReadImageTable(void)
+{
+ HAL_EepromParams_t params;
+
+ params.address = OFD_SERVICE_INFO_SIZE - sizeof(OfdImageTable_t);
+ params.data = &imageTable;
+ params.length = sizeof(OfdImageTable_t);
+
+ if (!ofdEepromHandler(HAL_ReadEeprom(&params, ofdReturnSuccessStatus), ofdReadImageTable))
+ if (ofdCallback)
+ ofdCallback(OFD_STATUS_INCORRECT_EEPROM_PARAMETER);
+}
+
+/**************************************************************************//**
+\brief Reads manufacturer ID and chip ID.
+******************************************************************************/
+void ofdFindStorageSpace(void)
+{
+ uint64_t manufacId = RDID;
+
+ if (FLASH_BUSY == ofdCheckBusyState())
+ { // waits till flash ready
+ delayedTransaction = ofdFindStorageSpace;
+ ofdStartPollTimer(FLASH_TRANSACTION);
+ return;
+ }
+
+ GPIO_EXT_MEM_CS_clr();
+#if EXTERNAL_MEMORY == AT25F2048
+ HAL_ReadSpi(&spiDesc, (uint8_t *)&manufacId, sizeof(uint32_t)-1);
+#elif EXTERNAL_MEMORY == AT25DF041A
+ HAL_ReadSpi(&spiDesc, (uint8_t *)&manufacId, sizeof(uint64_t)-3);
+#endif
+ GPIO_EXT_MEM_CS_set();
+
+ if (OFD_MANUFACTURER_ID == (uint8_t)(manufacId >> 8))
+ {
+#if EXTERNAL_MEMORY == AT25F2048
+ if (OFD_DEVICE_ID == (uint8_t)(manufacId >> 16))
+#elif EXTERNAL_MEMORY == AT25DF041A
+ if ((OFD_DEVICE_ID_1 == (uint8_t)(manufacId >> 16)) &&
+ (OFD_DEVICE_ID_2 == (uint8_t)(manufacId >> 24)) &&
+ (EXT_STRING_LENGTH == (uint8_t)(manufacId >> 32)))
+#endif
+ {
+ // read image table to global variable
+ ofdReadImageTable();
+ return;
+ }
+ }
+
+ if (ofdCallback)
+ ofdCallback(OFD_STATUS_UNKNOWN_EXTERNAL_FLASH_TYPE);
+}
+
+/**************************************************************************//**
+\brief Reads status register from the external flash.
+
+\return status register
+******************************************************************************/
+static inline uint8_t ofdReadStatusRegister(void)
+{
+ uint16_t regStatus = RDSR;
+
+ GPIO_EXT_MEM_CS_clr();
+ HAL_ReadSpi(&spiDesc, (uint8_t *)&regStatus, sizeof(uint16_t));
+ GPIO_EXT_MEM_CS_set();
+
+ return (uint8_t)(regStatus >> 8);
+}
+
+/**************************************************************************//**
+\brief Sends "write enable" command to the external flash.
+******************************************************************************/
+void ofdSendWriteEnable(void)
+{
+ uint8_t wren = WREN;
+
+ GPIO_EXT_MEM_CS_clr();
+ HAL_WriteSpi(&spiDesc, &wren, sizeof(uint8_t));
+ GPIO_EXT_MEM_CS_set();
+}
+
+/**************************************************************************//**
+\brief Starts physical sector erasing in the external memory.
+
+\param[in]
+ sectorNumber - address from erased sector
+******************************************************************************/
+void ofdEraseSector(uint32_t sectorNumber)
+{
+ uint32_t erasedSector = sectorNumber | ((uint32_t)SECTOR_ERASE << 24);
+
+ ofdSendWriteEnable();
+ erasedSector = OFD_LITTLE_TO_BIG_ENDIAN(erasedSector);
+ GPIO_EXT_MEM_CS_clr();
+ HAL_WriteSpi(&spiDesc, (uint8_t *)&erasedSector, sizeof(uint32_t));
+ GPIO_EXT_MEM_CS_set();
+}
+
+/**************************************************************************//**
+\brief Starts image erasing in the external memory.
+******************************************************************************/
+void ofdEraseImage(void)
+{
+ if (FLASH_BUSY == ofdCheckBusyState())
+ { // waits till flash ready
+ delayedTransaction = ofdEraseImage;
+ ofdStartPollTimer(FLASH_TRANSACTION);
+ return;
+ }
+
+ if (OFD_POSITION_1 == sectorNumber)
+ ofdEraseSector(SECTOR_ONE);
+ else
+ ofdEraseSector(SECTOR_THREE);
+
+ delayedTransaction = ofdContinueEraseImage;
+ ofdStartPollTimer(FLASH_TRANSACTION);
+}
+
+/**************************************************************************//**
+\brief Continues image erasing in the external memory.
+******************************************************************************/
+static void ofdContinueEraseImage(void)
+{
+ if (OFD_POSITION_1 == sectorNumber)
+ ofdEraseSector(SECTOR_TWO);
+ else
+ ofdEraseSector(SECTOR_FOUR);
+
+ ofdReturnSuccessStatus();
+}
+
+/**************************************************************************//**
+\brief Writes data to the external memory.
+******************************************************************************/
+void ofdWriteData(void)
+{
+ uint8_t *dataPointer;
+ uint16_t dataLength;
+ uint32_t dataAddress;
+ uint8_t writeInstruc = PROGRAM;
+
+ if (!localAccessStructure.length)
+ {
+ ofdReturnSuccessStatus();
+ return;
+ }
+
+ if (FLASH_BUSY == ofdCheckBusyState())
+ { // waits till flash ready
+ delayedTransaction = ofdWriteData;
+ ofdStartPollTimer(FLASH_TRANSACTION);
+ return;
+ }
+
+ dataAddress = OFD_LITTLE_TO_BIG_ENDIAN(localAccessStructure.offset);
+ dataAddress >>= 8;
+ dataPointer = localAccessStructure.data;
+ dataLength = PAGE_SIZE - (uint8_t)localAccessStructure.offset;
+ if (dataLength >= localAccessStructure.length)
+ dataLength = localAccessStructure.length;
+
+ localAccessStructure.data += dataLength;
+ localAccessStructure.offset += dataLength;
+ localAccessStructure.length -= dataLength;
+
+ ofdSendWriteEnable();
+ GPIO_EXT_MEM_CS_clr();
+ HAL_WriteSpi(&spiDesc, &writeInstruc, sizeof(uint8_t));
+ HAL_WriteSpi(&spiDesc, (uint8_t *)&dataAddress, sizeof(uint32_t)-1);
+ HAL_WriteSpi(&spiDesc, dataPointer, dataLength);
+ GPIO_EXT_MEM_CS_set();
+
+ delayedTransaction = ofdWriteData;
+ ofdStartPollTimer(FLASH_TRANSACTION);
+}
+
+/**************************************************************************//**
+\brief Calls callback about end of eeprom saving.
+******************************************************************************/
+static void ofdSaveCrcCallback(void)
+{
+ if (ofdCallback)
+ ((OFD_InfoCallback_t)ofdCallback)(OFD_STATUS_SUCCESS, &imageInfo);
+}
+
+/**************************************************************************//**
+\brief Saves image table to the internal eeprom.
+******************************************************************************/
+void ofdSaveImageTable(void)
+{
+ HAL_EepromParams_t params;
+
+ params.address = OFD_SERVICE_INFO_SIZE-1;
+ params.data = &imageTable;
+ params.length = sizeof(OfdImageTable_t);
+
+ if (!ofdEepromHandler(HAL_WriteEeprom(&params, ofdSaveCrcCallback), ofdSaveImageTable))
+ if (ofdCallback)
+ ((OFD_InfoCallback_t)ofdCallback)(OFD_STATUS_INCORRECT_EEPROM_PARAMETER, &imageInfo);
+}
+
+/**************************************************************************//**
+\brief Saves crc to the internal eeprom.
+******************************************************************************/
+void ofdSaveCrc(void)
+{
+ HAL_EepromParams_t params;
+
+ params.address = sectorNumber + 1;
+ params.data = &imageInfo.crc;
+ params.length = sizeof(uint8_t);
+
+ if (!ofdEepromHandler(HAL_WriteEeprom(&params, ofdSaveImageTable), ofdSaveCrc))
+ if (ofdCallback)
+ ((OFD_InfoCallback_t)ofdCallback)(OFD_STATUS_INCORRECT_EEPROM_PARAMETER, &imageInfo);
+}
+
+/**************************************************************************//**
+\brief Flushs memory buffer to flash.
+******************************************************************************/
+void ofdFlushData(void)
+{}
+
+/**************************************************************************//**
+\brief Checks image crc.
+******************************************************************************/
+void ofdCheckCrc(void)
+{
+ uint32_t address;
+ uint8_t writeInstruc = READ;
+ uint8_t atomicCounting = ATOMIC_COUNTING;
+
+ if (FLASH_BUSY == ofdCheckBusyState())
+ { // waits till flash ready
+ delayedTransaction = ofdCheckCrc;
+ ofdStartPollTimer(FLASH_TRANSACTION);
+ return;
+ }
+
+ while (atomicCounting--)
+ {
+ address = localAccessStructure.offset;
+ address = OFD_LITTLE_TO_BIG_ENDIAN(address<<8);
+ GPIO_EXT_MEM_CS_clr();
+ HAL_WriteSpi(&spiDesc, &writeInstruc, sizeof(uint8_t));
+ HAL_WriteSpi(&spiDesc, (uint8_t *)&address, sizeof(uint32_t)-1);
+ HAL_ReadSpi(&spiDesc, localAccessStructure.data, OFD_BLOCK_FOR_CHECK_CRC);
+ GPIO_EXT_MEM_CS_set(); // release spi cs
+ imageInfo.crc = ofdCrc(imageInfo.crc, localAccessStructure.data, OFD_BLOCK_FOR_CHECK_CRC);
+ localAccessStructure.offset += OFD_BLOCK_FOR_CHECK_CRC;
+ localAccessStructure.length -= OFD_BLOCK_FOR_CHECK_CRC;
+ if (!localAccessStructure.length)
+ {
+ ofdSaveCrc();
+ return;
+ }
+ }
+ // context gap
+ delayedTransaction = ofdCheckCrc;
+ ofdStartPollTimer(FLASH_TRANSACTION);
+}
+
+/**************************************************************************//**
+\brief Callback for saving internal flash.
+
+\param[in] status - status of the data flash writing
+******************************************************************************/
+void ofdWriteFlashDataCallback(OFD_Status_t status)
+{
+ uint32_t maxOffset;
+
+ if (OFD_STATUS_SUCCESS != status)
+ {
+ if (ofdAuxCallback)
+ ofdAuxCallback(status);
+ return;
+ }
+ if (OFD_POSITION_1 == sectorNumber)
+ maxOffset = OFD_IMAGE1_START_ADDRESS + OFD_MCU_FLASH_SIZE - OFD_MCU_EEPROM_SIZE;
+ else
+ maxOffset = OFD_IMAGE2_START_ADDRESS + OFD_MCU_FLASH_SIZE - OFD_MCU_EEPROM_SIZE;
+
+ if (localAccessStructure.offset < maxOffset)
+ { // save mcu flash
+ ofdSaveCurrentFlashImage();
+ return;
+ }
+
+ internalAccessParam.eepromOffset = 0;
+ // save eeprom image
+ ofdSaveCurrentEepromImage();
+}
+
+/**************************************************************************//**
+\brief Starts saving internal flash.
+******************************************************************************/
+void ofdSaveCurrentFlashImage(void)
+{
+#if EXTERNAL_MEMORY == AT25F2048
+ uint16_t itr;
+
+ localAccessStructure.length = OFD_BLOCK_FOR_CHECK_CRC;
+ localAccessStructure.data = internalAccessParam.data;
+ for (itr = 0; itr < OFD_BLOCK_FOR_CHECK_CRC; itr++)
+ internalAccessParam.data[itr] = ofdReadInternalFlash(internalAccessParam.flashOffset++);
+ internalAccessParam.length -= OFD_BLOCK_FOR_CHECK_CRC;
+ ofdCallback = ofdWriteFlashDataCallback;
+ ofdWriteData();
+#elif EXTERNAL_MEMORY == AT25DF041A
+ ofdSetActionForBootloader();
+#endif
+}
+
+/**************************************************************************//**
+\brief Callback for saving internal eeprom.
+
+\param[in] status - status of the data eeprom writing
+******************************************************************************/
+void ofdWriteEepromDataCallback(OFD_Status_t status)
+{
+ uint32_t maxOffset;
+
+ if (OFD_STATUS_SUCCESS != status)
+ {
+ if (ofdAuxCallback)
+ ofdAuxCallback(status);
+ return;
+ }
+ if (OFD_POSITION_1 == sectorNumber)
+ maxOffset = OFD_IMAGE1_START_ADDRESS + OFD_MCU_FLASH_SIZE;
+ else
+ maxOffset = OFD_IMAGE2_START_ADDRESS + OFD_MCU_FLASH_SIZE;
+
+ if (localAccessStructure.offset < maxOffset)
+ { // save mcu eeprom
+ ofdSaveCurrentEepromImage();
+ return;
+ }
+
+ // start check crc
+ OFD_FlushAndCheckCrc(sectorNumber, internalAccessParam.data, ofdFlushCrcCallback);
+}
+
+/**************************************************************************//**
+\brief Starts saving internal eeprom.
+******************************************************************************/
+static void ofdSaveCurrentEepromImage(void)
+{
+ HAL_EepromParams_t params;
+
+ params.address = internalAccessParam.eepromOffset;
+ params.data = internalAccessParam.data;
+ params.length = OFD_BLOCK_FOR_CHECK_CRC;
+
+ if (!ofdEepromHandler(HAL_ReadEeprom(&params, ofdSaveCurrentEepromImageContinue), ofdSaveCurrentEepromImage))
+ if (ofdAuxCallback)
+ ofdAuxCallback(OFD_STATUS_INCORRECT_EEPROM_PARAMETER);
+}
+
+/**************************************************************************//**
+\brief Continues saving internal flash.
+******************************************************************************/
+static void ofdSaveCurrentEepromImageContinue(void)
+{
+ localAccessStructure.length = OFD_BLOCK_FOR_CHECK_CRC;
+ localAccessStructure.data = internalAccessParam.data;
+ if (0 == internalAccessParam.eepromOffset)
+ memset(internalAccessParam.data, 0xFF, OFD_SERVICE_INFO_SIZE);
+
+ internalAccessParam.eepromOffset += OFD_BLOCK_FOR_CHECK_CRC;
+ internalAccessParam.length -= OFD_BLOCK_FOR_CHECK_CRC;
+ ofdCallback = ofdWriteEepromDataCallback;
+ ofdWriteData();
+}
+
+/**************************************************************************//**
+\brief Callback for start of saving of action for bootloader.
+
+\param[in]
+ status - status of the crc saving to eeprom
+\param[in]
+ pInfo - ponter to image information
+******************************************************************************/
+static void ofdFlushCrcCallback(OFD_Status_t status, OFD_ImageInfo_t *pInfo)
+{
+ (void)pInfo;
+
+ if (OFD_STATUS_SUCCESS != status)
+ {
+ if (ofdAuxCallback)
+ ofdAuxCallback(status);
+ return;
+ }
+ ofdSetActionForBootloader();
+}
+
+/**************************************************************************//**
+\brief Sets action for internal bootloader.
+******************************************************************************/
+void ofdSetActionForBootloader(void)
+{
+ HAL_EepromParams_t params;
+
+ params.address = 0;
+ params.data = (uint8_t *)&actionSector;
+ params.length = sizeof(OFD_Position_t);
+
+ if (!ofdEepromHandler(HAL_WriteEeprom(&params, ofdPollBusyState), ofdSetActionForBootloader))
+ if (ofdAuxCallback)
+ ofdAuxCallback(OFD_STATUS_INCORRECT_EEPROM_PARAMETER);
+}
+
+/**************************************************************************//**
+\brief Waits for end of image saving.
+******************************************************************************/
+static void ofdPollBusyState(void)
+{
+ if (FLASH_BUSY == ofdCheckBusyState())
+ { // waits till flash ready
+ delayedTransaction = ofdPollBusyState;
+ ofdStartPollTimer(FLASH_TRANSACTION);
+ return;
+ }
+
+ if (ofdAuxCallback)
+ ofdAuxCallback(OFD_STATUS_SUCCESS);
+}
+
+/**************************************************************************//**
+\brief Reads image crc from internal eeprom.
+******************************************************************************/
+void ofdReadCrc(void)
+{
+ HAL_EepromParams_t params;
+
+ params.address = sectorNumber + 1;
+ params.data = &imageInfo.crc;
+ params.length = sizeof(uint8_t);
+
+ if (!ofdEepromHandler(HAL_ReadEeprom(&params, ofdSaveCrcCallback), ofdReadCrc))
+ if (ofdCallback)
+ ((OFD_InfoCallback_t)ofdCallback)(OFD_STATUS_INCORRECT_EEPROM_PARAMETER, &imageInfo);
+}
+
+#if EXTERNAL_MEMORY == AT25DF041A
+/**************************************************************************//**
+\brief Unprotects memory sectors for writing and erasing.
+******************************************************************************/
+void ofdUnprotectMemorySectors(void)
+{
+ uint8_t unprotect = WRSR;
+ uint8_t unprotectArg = GLOBAL_UNPROTECT;
+
+ ofdSendWriteEnable();
+ GPIO_EXT_MEM_CS_clr();
+ HAL_WriteSpi(&spiDesc, &unprotect, sizeof(uint8_t));
+ HAL_WriteSpi(&spiDesc, &unprotectArg, sizeof(uint8_t));
+ GPIO_EXT_MEM_CS_set();
+}
+#endif
+
+#if defined(_OFD_DEBUG_)
+/**************************************************************************//**
+\brief Flash read callback.
+******************************************************************************/
+void ofdReadConfirm(OFD_Status_t status)
+{
+ HAL_WriteUsart(&usartDescriptor, debugBuffer, OFD_BLOCK_SIZE);
+}
+
+/**************************************************************************//**
+\brief Usart write callback.
+******************************************************************************/
+void usartWriteConfirm(void)
+{
+ debugOffset += OFD_BLOCK_SIZE;
+ if (debugOffset < OFD_IMAGE_SIZE)
+ {
+ ofdReadData(debugOffset, debugBuffer, OFD_BLOCK_SIZE, ofdReadConfirm);
+ }
+}
+
+/**************************************************************************//**
+\brief Initialization of usart for consinsting of flash transmitting.
+******************************************************************************/
+void ofdInitDebugInterface(void)
+{
+ usartDescriptor.tty = USART_CHANNEL_1;
+ usartDescriptor.mode = USART_MODE_ASYNC;
+ usartDescriptor.flowControl = USART_FLOW_CONTROL_NONE;
+ usartDescriptor.baudrate = USART_BAUDRATE_38400;
+ usartDescriptor.dataLength = USART_DATA8;
+ usartDescriptor.parity = USART_PARITY_NONE;
+ usartDescriptor.stopbits = USART_STOPBIT_1;
+ usartDescriptor.rxBuffer = NULL;
+ usartDescriptor.rxBufferLength = 0;
+ usartDescriptor.txBuffer = NULL;
+ usartDescriptor.txBufferLength = 0;
+ usartDescriptor.rxCallback = NULL;
+ usartDescriptor.txCallback = usartWriteConfirm;
+
+ HAL_OpenUsart(&usartDescriptor);
+ ofdReadData(debugOffset, debugBuffer, OFD_BLOCK_SIZE, ofdReadConfirm);
+}
+
+/**************************************************************************//**
+\brief Reads data from the external memory.
+
+\param[in]
+ address - flash cell address
+\param[out]
+ data - pointer to memory buffer
+\param[in]
+ size - size of memory buffer
+\param[in]
+ cb - pointer to callback
+******************************************************************************/
+void ofdReadData(uint32_t address, uint8_t *data, uint16_t size, OFD_Callback_t cb)
+{
+ uint8_t writeInstruc = READ;
+
+ while (FLASH_BUSY == ofdCheckBusyState())
+ {;}// waits till flash ready
+
+ address = OFD_LITTLE_TO_BIG_ENDIAN(address<<8);
+ GPIO_EXT_MEM_CS_clr();
+ HAL_WriteSpi(&spiDesc, &writeInstruc, sizeof(uint8_t));
+ HAL_WriteSpi(&spiDesc, (uint8_t *)&address, sizeof(uint32_t)-1);
+ HAL_ReadSpi(&spiDesc, data, size);
+ GPIO_EXT_MEM_CS_set();
+ if (cb)
+ cb(OFD_STATUS_SUCCESS);
+}
+#endif // defined(_OFD_DEBUG_)
+
+#endif // APP_USE_FAKE_OFD_DRIVER == 0
+#endif // ((EXTERNAL_MEMORY == AT25F2048) ||(EXTERNAL_MEMORY == AT25DF041A)) && (APP_USE_OTAU == 1)
+#endif // _OTAU_
+// eof ofdAt25fDriver.c
diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdAt45dbDriver.c b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdAt45dbDriver.c
new file mode 100644
index 00000000..f06d765d
--- /dev/null
+++ b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdAt45dbDriver.c
@@ -0,0 +1,758 @@
+/**************************************************************************//**
+\file ofdAt45dbDriver.c
+
+\brief Implementation of chip-flash interface.
+
+\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:
+ 20/07/10 A. Khromykh - Created
+*******************************************************************************/
+/******************************************************************************
+ * WARNING: CHANGING THIS FILE MAY AFFECT CORE FUNCTIONALITY OF THE STACK. *
+ * EXPERT USERS SHOULD PROCEED WITH CAUTION. *
+ ******************************************************************************/
+
+#ifdef _OTAU_
+#if (EXTERNAL_MEMORY == AT45DB041) && (APP_USE_OTAU == 1)
+#if APP_USE_FAKE_OFD_DRIVER == 0
+
+/******************************************************************************
+ Includes section
+******************************************************************************/
+#include <ofdExtMemory.h>
+#include <ofdMemoryDriver.h>
+#include <spi.h>
+#include <eeprom.h>
+#include <appTimer.h>
+
+/******************************************************************************
+ Define(s) section
+******************************************************************************/
+#define SPI_BUSY_POLL_PERIOD 10
+// cycles of counting flash crc before context gap.
+#define ATOMIC_COUNTING 128
+#define EEPROM_OK 0
+#define EEPROM_BUSY -2
+#define ALL_DATA_HAS_BEEN_SAVED 0xFFFFFFFFul
+
+/******************************************************************************
+ Types section
+******************************************************************************/
+typedef enum
+{
+ FLASH_BUSY,
+ FLASH_READY
+} FlashBusyState_t;
+
+typedef enum
+{
+ FLASH_TRANSACTION,
+ EEPROM_TRANSACTION
+} DelayedTransactionType_t;
+
+/******************************************************************************
+ Prototypes section
+******************************************************************************/
+static inline uint8_t ofdReadStatusRegister(void);
+static inline void ofdStartPollTimer(DelayedTransactionType_t type);
+static void ofdReadImageTable(void);
+static void ofdSaveCrcCallback(void);
+static void ofdSaveCurrentEepromImage(void);
+static void ofdFlushCrcCallback(OFD_Status_t status, OFD_ImageInfo_t *pInfo);
+static void ofdSaveCurrentEepromImageContinue(void);
+static void ofdPollBusyState(void);
+static void ofdStartFlashDelayedTransaction(void);
+static void ofdStartEepromDelayedTransaction(void);
+static void ofdClearFlashInternalBuffer(void);
+uint8_t ofdReadInternalFlash(uint32_t flashAddress);
+#if defined(_OFD_DEBUG_)
+void ofdReadData(uint32_t address, uint8_t *data, uint16_t size, OFD_Callback_t cb);
+#endif
+
+/******************************************************************************
+ External variables section
+******************************************************************************/
+extern HAL_SpiDescriptor_t spiDesc;
+extern OFD_Position_t sectorNumber;
+extern OFD_Position_t actionSector;
+extern OFD_Callback_t ofdCallback;
+extern OFD_Callback_t ofdAuxCallback;
+extern OFD_MemoryAccessParam_t localAccessStructure;
+extern OFD_ImageInfo_t imageInfo;
+extern OfdImageTable_t imageTable;
+extern OfdInternalMemoryAccessParam_t internalAccessParam;
+
+/******************************************************************************
+ Global variables section
+******************************************************************************/
+static HAL_AppTimer_t ofdBusyTimer =
+{
+ .interval = SPI_BUSY_POLL_PERIOD,
+ .mode = TIMER_ONE_SHOT_MODE,
+};
+void (* delayedTransaction)(void) = NULL;
+static uint16_t serviceGapData = 0;
+static uint32_t flushedPageAddr = ALL_DATA_HAS_BEEN_SAVED;
+#if defined(_OFD_DEBUG_)
+static HAL_UsartDescriptor_t usartDescriptor;
+static uint32_t debugOffset = 0ul;
+static uint8_t debugBuffer[OFD_BLOCK_SIZE];
+#endif
+
+/******************************************************************************
+ Implementations section
+******************************************************************************/
+/**************************************************************************//**
+\brief Checks flash state.
+
+\return flash states: \n
+ FLASH_BUSY \n
+ FLASH_READY
+******************************************************************************/
+static inline FlashBusyState_t ofdCheckBusyState(void)
+{
+ uint8_t statusReg = ofdReadStatusRegister();
+
+ if (statusReg & RDY)
+ return FLASH_READY;
+
+ return FLASH_BUSY;
+}
+
+/**************************************************************************//**
+\brief Starts flash delayed transaction.
+******************************************************************************/
+static void ofdStartFlashDelayedTransaction(void)
+{
+ if (FLASH_READY == ofdCheckBusyState())
+ delayedTransaction();
+ else
+ ofdStartPollTimer(FLASH_TRANSACTION);
+}
+
+/**************************************************************************//**
+\brief Starts eeprom delayed transaction.
+******************************************************************************/
+static void ofdStartEepromDelayedTransaction(void)
+{
+ if (!HAL_IsEepromBusy())
+ delayedTransaction();
+ else
+ ofdStartPollTimer(EEPROM_TRANSACTION);
+}
+
+/**************************************************************************//**
+\brief Starts timer for start delayed transaction.
+
+\param[in]
+ type - transaction type (flash or eeprom)
+******************************************************************************/
+static inline void ofdStartPollTimer(DelayedTransactionType_t type)
+{
+ if (FLASH_TRANSACTION == type)
+ ofdBusyTimer.callback = ofdStartFlashDelayedTransaction;
+ else
+ ofdBusyTimer.callback = ofdStartEepromDelayedTransaction;
+
+ HAL_StartAppTimer(&ofdBusyTimer);
+}
+
+/**************************************************************************//**
+\brief Routine of eeprom access.
+\param[in]
+ result - result of hal eeprom action
+\param[in]
+ action - initiator action
+\return
+ false - incorrect parameters
+ true - eeprom transaction is started
+******************************************************************************/
+static bool ofdEepromHandler(int result, void(* action)())
+{
+ switch (result)
+ {
+ case EEPROM_OK:
+ return true;
+ case EEPROM_BUSY:
+ delayedTransaction = action;
+ ofdStartPollTimer(EEPROM_TRANSACTION);
+ return true;
+ default:
+ return false;
+ }
+}
+
+/**************************************************************************//**
+\brief Returns SUCCESS status.
+******************************************************************************/
+static void ofdReturnSuccessStatus(void)
+{
+ if (ofdCallback)
+ ofdCallback(OFD_STATUS_SUCCESS);
+}
+
+/**************************************************************************//**
+\brief Reads image table.
+******************************************************************************/
+static void ofdReadImageTable(void)
+{
+ HAL_EepromParams_t params;
+
+ params.address = OFD_SERVICE_INFO_SIZE - sizeof(OfdImageTable_t);
+ params.data = &imageTable;
+ params.length = sizeof(OfdImageTable_t);
+
+ if (!ofdEepromHandler(HAL_ReadEeprom(&params, ofdReturnSuccessStatus), ofdReadImageTable))
+ if (ofdCallback)
+ ofdCallback(OFD_STATUS_INCORRECT_EEPROM_PARAMETER);
+}
+
+/**************************************************************************//**
+\brief Reads status register and check unchanged bits.
+******************************************************************************/
+void ofdFindStorageSpace(void)
+{
+ if (STATUS_UNCHANGED_BITS == (ofdReadStatusRegister() & STATUS_UNCHANGED_BIT_MASK))
+ {
+ // read image table to global variable
+ ofdReadImageTable();
+ return;
+ }
+
+ if (ofdCallback)
+ ofdCallback(OFD_STATUS_UNKNOWN_EXTERNAL_FLASH_TYPE);
+}
+
+/**************************************************************************//**
+\brief Reads status register from the external flash.
+
+\return status register
+******************************************************************************/
+static inline uint8_t ofdReadStatusRegister(void)
+{
+ uint16_t regStatus = RDSR;
+
+ GPIO_EXT_MEM_CS_clr();
+ HAL_ReadSpi(&spiDesc, (uint8_t *)&regStatus, sizeof(uint16_t));
+ GPIO_EXT_MEM_CS_set();
+
+ return (uint8_t)(regStatus >> 8);
+}
+
+/**************************************************************************//**
+\brief Starts physical block(8 pages) erasing in the external memory.
+
+\param[in]
+ blockNumber - address of the erased block
+******************************************************************************/
+void ofdEraseBlock(uint8_t blockNumber)
+{
+ uint32_t erasedBlock = OFD_LITTLE_TO_BIG_ENDIAN((uint32_t)blockNumber << 4);
+
+ erasedBlock >>= 8;
+ erasedBlock |= BLOCK_ERASE;
+
+ GPIO_EXT_MEM_CS_clr();
+ HAL_WriteSpi(&spiDesc, (uint8_t *)&erasedBlock, sizeof(uint32_t));
+ GPIO_EXT_MEM_CS_set();
+}
+
+/**************************************************************************//**
+\brief Starts image erasing in the external memory.
+******************************************************************************/
+void ofdEraseImage(void)
+{
+ if (FLASH_BUSY == ofdCheckBusyState())
+ { // waits till flash ready
+ delayedTransaction = ofdEraseImage;
+ ofdStartPollTimer(FLASH_TRANSACTION);
+ return;
+ }
+
+ if (OFD_POSITION_1 == sectorNumber)
+ ofdEraseBlock(FIRST_HALF_BLOCK_NUMBER + serviceGapData++);
+ else
+ ofdEraseBlock(SECOND_HALF_BLOCK_NUMBER + serviceGapData++);
+
+ if (serviceGapData < OFD_USED_BLOCKS_AMOUNT)
+ {
+ delayedTransaction = ofdEraseImage;
+ ofdStartPollTimer(FLASH_TRANSACTION);
+ }
+ else
+ {
+ serviceGapData = 0;
+ ofdReturnSuccessStatus();
+ }
+}
+
+/**************************************************************************//**
+\brief Writes data to the external memory.
+******************************************************************************/
+void ofdWriteData(void)
+{
+ uint8_t *dataPointer;
+ uint16_t dataLength;
+ uint32_t address;
+ uint32_t pageAddr;
+ uint32_t byteAddr;
+
+ if (!localAccessStructure.length)
+ {
+ ofdReturnSuccessStatus();
+ return;
+ }
+
+ if (FLASH_BUSY == ofdCheckBusyState())
+ { // waits till flash ready
+ delayedTransaction = ofdWriteData;
+ ofdStartPollTimer(FLASH_TRANSACTION);
+ return;
+ }
+
+ pageAddr = localAccessStructure.offset / PAGE_SIZE;
+
+ if ((pageAddr > flushedPageAddr) && (ALL_DATA_HAS_BEEN_SAVED != flushedPageAddr))
+ { // there is gap in the image address map.
+ ofdFlushData();
+ delayedTransaction = ofdClearFlashInternalBuffer;
+ ofdStartPollTimer(FLASH_TRANSACTION);
+ return;
+ }
+
+ flushedPageAddr = pageAddr;
+ byteAddr = localAccessStructure.offset % PAGE_SIZE;
+ dataPointer = localAccessStructure.data;
+
+ if ((byteAddr + localAccessStructure.length) > PAGE_SIZE)
+ dataLength = PAGE_SIZE - byteAddr;
+ else
+ dataLength = localAccessStructure.length;
+
+ localAccessStructure.data += dataLength;
+ localAccessStructure.offset += dataLength;
+ localAccessStructure.length -= dataLength;
+
+ address = OFD_LITTLE_TO_BIG_ENDIAN(byteAddr);
+ address |= WRITE_BUF1;
+
+ GPIO_EXT_MEM_CS_clr();
+ HAL_WriteSpi(&spiDesc, (uint8_t *)&address, sizeof(uint32_t));
+ HAL_WriteSpi(&spiDesc, dataPointer, dataLength);
+ GPIO_EXT_MEM_CS_set();
+
+ if (PAGE_SIZE == (byteAddr + dataLength))
+ {
+ ofdFlushData();
+ delayedTransaction = ofdClearFlashInternalBuffer;
+ ofdStartPollTimer(FLASH_TRANSACTION);
+ return;
+ }
+
+ ofdReturnSuccessStatus();
+}
+
+/**************************************************************************//**
+\brief Calls callback about end of eeprom saving.
+******************************************************************************/
+static void ofdSaveCrcCallback(void)
+{
+ if (ofdCallback)
+ ((OFD_InfoCallback_t)ofdCallback)(OFD_STATUS_SUCCESS, &imageInfo);
+}
+
+/**************************************************************************//**
+\brief Saves image table to the internal eeprom.
+******************************************************************************/
+void ofdSaveImageTable(void)
+{
+ HAL_EepromParams_t params;
+
+ params.address = OFD_SERVICE_INFO_SIZE-1;
+ params.data = &imageTable;
+ params.length = sizeof(OfdImageTable_t);
+
+ if (!ofdEepromHandler(HAL_WriteEeprom(&params, ofdSaveCrcCallback), ofdSaveImageTable))
+ if (ofdCallback)
+ ((OFD_InfoCallback_t)ofdCallback)(OFD_STATUS_INCORRECT_EEPROM_PARAMETER, &imageInfo);
+}
+
+/**************************************************************************//**
+\brief Saves crc to the internal eeprom.
+******************************************************************************/
+void ofdSaveCrc(void)
+{
+ HAL_EepromParams_t params;
+
+ params.address = sectorNumber + 1;
+ params.data = &imageInfo.crc;
+ params.length = sizeof(uint8_t);
+
+ if (!ofdEepromHandler(HAL_WriteEeprom(&params, ofdSaveImageTable), ofdSaveCrc))
+ if (ofdCallback)
+ ((OFD_InfoCallback_t)ofdCallback)(OFD_STATUS_INCORRECT_EEPROM_PARAMETER, &imageInfo);
+}
+
+/**************************************************************************//**
+\brief Clears internal flash buffer.
+******************************************************************************/
+static void ofdClearFlashInternalBuffer(void)
+{
+ uint32_t address = 0ul;
+ uint64_t data;
+ uint8_t itr;
+
+ if (FLASH_BUSY == ofdCheckBusyState())
+ { // waits till flash ready
+ delayedTransaction = ofdClearFlashInternalBuffer;
+ ofdStartPollTimer(FLASH_TRANSACTION);
+ return;
+ }
+
+ memset((uint8_t *)&data, 0xFF, sizeof(uint64_t));
+
+ address |= WRITE_BUF1;
+ GPIO_EXT_MEM_CS_clr();
+ HAL_WriteSpi(&spiDesc, (uint8_t *)&address, sizeof(uint32_t));
+ for (itr = 0; itr < (PAGE_SIZE / sizeof(uint64_t)); itr++)
+ HAL_WriteSpi(&spiDesc, (uint8_t *)&data, sizeof(uint64_t));
+ GPIO_EXT_MEM_CS_set();
+
+ ofdWriteData();
+}
+
+/**************************************************************************//**
+\brief Flushs memory buffer to flash.
+******************************************************************************/
+void ofdFlushData(void)
+{
+ if (ALL_DATA_HAS_BEEN_SAVED == flushedPageAddr)
+ return;
+
+ flushedPageAddr = OFD_LITTLE_TO_BIG_ENDIAN(flushedPageAddr << 1);
+ flushedPageAddr >>= 8;
+ flushedPageAddr |= PROGRAM_BUF1;
+ GPIO_EXT_MEM_CS_clr();
+ HAL_WriteSpi(&spiDesc, (uint8_t *)&flushedPageAddr, sizeof(uint32_t));
+ GPIO_EXT_MEM_CS_set();
+ flushedPageAddr = ALL_DATA_HAS_BEEN_SAVED;
+}
+
+/**************************************************************************//**
+\brief Checks image crc.
+******************************************************************************/
+void ofdCheckCrc(void)
+{
+ uint32_t address;
+ uint32_t pageAddr;
+ uint32_t byteAddr;
+ uint8_t atomicCounting = ATOMIC_COUNTING;
+
+ if (FLASH_BUSY == ofdCheckBusyState())
+ { // waits till flash ready
+ delayedTransaction = ofdCheckCrc;
+ ofdStartPollTimer(FLASH_TRANSACTION);
+ return;
+ }
+
+ while (atomicCounting--)
+ {
+ pageAddr = localAccessStructure.offset / PAGE_SIZE;
+ byteAddr = localAccessStructure.offset % PAGE_SIZE;
+ address = byteAddr | (pageAddr << 9) | ((uint32_t)READ << 24);
+ address = OFD_LITTLE_TO_BIG_ENDIAN(address);
+ GPIO_EXT_MEM_CS_clr();
+ HAL_WriteSpi(&spiDesc, (uint8_t *)&address, sizeof(uint32_t));
+ // load 32 don't care bits
+ HAL_WriteSpi(&spiDesc, (uint8_t *)&address, sizeof(uint32_t));
+ HAL_ReadSpi(&spiDesc, localAccessStructure.data, OFD_BLOCK_FOR_CHECK_CRC);
+ GPIO_EXT_MEM_CS_set(); // release spi cs
+ imageInfo.crc = ofdCrc(imageInfo.crc, localAccessStructure.data, OFD_BLOCK_FOR_CHECK_CRC);
+ localAccessStructure.offset += OFD_BLOCK_FOR_CHECK_CRC;
+ localAccessStructure.length -= OFD_BLOCK_FOR_CHECK_CRC;
+ if (!localAccessStructure.length)
+ {
+ ofdSaveCrc();
+ return;
+ }
+ }
+ // context gap
+ delayedTransaction = ofdCheckCrc;
+ ofdStartPollTimer(FLASH_TRANSACTION);
+}
+
+/**************************************************************************//**
+\brief Callback for saving internal flash.
+
+\param[in] status - status of the data flash writing
+******************************************************************************/
+void ofdWriteFlashDataCallback(OFD_Status_t status)
+{
+ uint32_t maxOffset;
+
+ if (OFD_STATUS_SUCCESS != status)
+ {
+ if (ofdAuxCallback)
+ ofdAuxCallback(status);
+ return;
+ }
+ if (OFD_POSITION_1 == sectorNumber)
+ maxOffset = OFD_IMAGE1_START_ADDRESS + OFD_EEPROM_OFFSET_WITHIN_IMAGE;
+ else
+ maxOffset = OFD_IMAGE2_START_ADDRESS + OFD_EEPROM_OFFSET_WITHIN_IMAGE;
+
+ if (localAccessStructure.offset < maxOffset)
+ { // save mcu flash
+ ofdSaveCurrentFlashImage();
+ return;
+ }
+
+ internalAccessParam.eepromOffset = 0;
+ // save eeprom image
+ ofdSaveCurrentEepromImage();
+}
+
+/**************************************************************************//**
+\brief Starts saving internal flash.
+******************************************************************************/
+void ofdSaveCurrentFlashImage(void)
+{
+ uint16_t itr;
+
+ localAccessStructure.length = OFD_BLOCK_FOR_CHECK_CRC;
+ localAccessStructure.data = internalAccessParam.data;
+ for (itr = 0; itr < OFD_BLOCK_FOR_CHECK_CRC; itr++)
+ {
+ OFD_LOAD_NO_COMMAND_TO_NVM;
+ internalAccessParam.data[itr] = ofdReadInternalFlash(internalAccessParam.flashOffset++);
+ }
+ internalAccessParam.length -= OFD_BLOCK_FOR_CHECK_CRC;
+ ofdCallback = ofdWriteFlashDataCallback;
+ ofdWriteData();
+}
+
+/**************************************************************************//**
+\brief Callback for saving internal eeprom.
+
+\param[in] status - status of the data eeprom writing
+******************************************************************************/
+void ofdWriteEepromDataCallback(OFD_Status_t status)
+{
+ uint32_t maxOffset;
+
+ if (OFD_STATUS_SUCCESS != status)
+ {
+ if (ofdAuxCallback)
+ ofdAuxCallback(status);
+ return;
+ }
+ if (OFD_POSITION_1 == sectorNumber)
+ maxOffset = OFD_IMAGE1_START_ADDRESS + OFD_IMAGE_SIZE;
+ else
+ maxOffset = OFD_IMAGE2_START_ADDRESS + OFD_IMAGE_SIZE;
+
+ if (localAccessStructure.offset < maxOffset)
+ { // save mcu eeprom
+ ofdSaveCurrentEepromImage();
+ return;
+ }
+
+ // start check crc
+ OFD_FlushAndCheckCrc(sectorNumber, internalAccessParam.data, ofdFlushCrcCallback);
+}
+
+/**************************************************************************//**
+\brief Starts saving internal eeprom.
+******************************************************************************/
+static void ofdSaveCurrentEepromImage(void)
+{
+ HAL_EepromParams_t params;
+
+ params.address = internalAccessParam.eepromOffset;
+ params.data = internalAccessParam.data;
+ params.length = OFD_BLOCK_FOR_CHECK_CRC;
+
+ if (!ofdEepromHandler(HAL_ReadEeprom(&params, ofdSaveCurrentEepromImageContinue), ofdSaveCurrentEepromImage))
+ if (ofdAuxCallback)
+ ofdAuxCallback(OFD_STATUS_INCORRECT_EEPROM_PARAMETER);
+}
+
+/**************************************************************************//**
+\brief Continues saving internal flash.
+******************************************************************************/
+static void ofdSaveCurrentEepromImageContinue(void)
+{
+ localAccessStructure.length = OFD_BLOCK_FOR_CHECK_CRC;
+ localAccessStructure.data = internalAccessParam.data;
+ if (0 == internalAccessParam.eepromOffset)
+ memset(internalAccessParam.data, 0xFF, OFD_SERVICE_INFO_SIZE);
+
+ internalAccessParam.eepromOffset += OFD_BLOCK_FOR_CHECK_CRC;
+ internalAccessParam.length -= OFD_BLOCK_FOR_CHECK_CRC;
+ ofdCallback = ofdWriteEepromDataCallback;
+ ofdWriteData();
+}
+
+/**************************************************************************//**
+\brief Callback for start of saving of action for bootloader.
+
+\param[in]
+ status - status of the crc saving to eeprom
+\param[in]
+ pInfo - ponter to image information
+******************************************************************************/
+static void ofdFlushCrcCallback(OFD_Status_t status, OFD_ImageInfo_t *pInfo)
+{
+ (void)pInfo;
+
+ if (OFD_STATUS_SUCCESS != status)
+ {
+ if (ofdAuxCallback)
+ ofdAuxCallback(status);
+ return;
+ }
+ ofdSetActionForBootloader();
+}
+
+/**************************************************************************//**
+\brief Sets action for internal bootloader.
+******************************************************************************/
+void ofdSetActionForBootloader(void)
+{
+ HAL_EepromParams_t params;
+
+ params.address = 0;
+ params.data = (uint8_t *)&actionSector;
+ params.length = sizeof(OFD_Position_t);
+
+ if (!ofdEepromHandler(HAL_WriteEeprom(&params, ofdPollBusyState), ofdSetActionForBootloader))
+ if (ofdAuxCallback)
+ ofdAuxCallback(OFD_STATUS_INCORRECT_EEPROM_PARAMETER);
+}
+
+/**************************************************************************//**
+\brief Waits for end of image saving.
+******************************************************************************/
+static void ofdPollBusyState(void)
+{
+ if (FLASH_BUSY == ofdCheckBusyState())
+ { // waits till flash ready
+ delayedTransaction = ofdPollBusyState;
+ ofdStartPollTimer(FLASH_TRANSACTION);
+ return;
+ }
+
+ if (ofdAuxCallback)
+ ofdAuxCallback(OFD_STATUS_SUCCESS);
+}
+
+/**************************************************************************//**
+\brief Reads image crc from internal eeprom.
+******************************************************************************/
+void ofdReadCrc(void)
+{
+ HAL_EepromParams_t params;
+
+ params.address = sectorNumber + 1;
+ params.data = &imageInfo.crc;
+ params.length = sizeof(uint8_t);
+
+ if (!ofdEepromHandler(HAL_ReadEeprom(&params, ofdSaveCrcCallback), ofdReadCrc))
+ if (ofdCallback)
+ ((OFD_InfoCallback_t)ofdCallback)(OFD_STATUS_INCORRECT_EEPROM_PARAMETER, &imageInfo);
+}
+
+#if defined(_OFD_DEBUG_)
+/**************************************************************************//**
+\brief Flash read callback.
+******************************************************************************/
+void ofdReadConfirm(OFD_Status_t status)
+{
+ HAL_WriteUsart(&usartDescriptor, debugBuffer, OFD_BLOCK_SIZE);
+}
+
+/**************************************************************************//**
+\brief Usart write callback.
+******************************************************************************/
+void usartWriteConfirm(void)
+{
+ debugOffset += OFD_BLOCK_SIZE;
+ if (debugOffset < OFD_IMAGE_SIZE)
+ {
+ ofdReadData(debugOffset, debugBuffer, OFD_BLOCK_SIZE, ofdReadConfirm);
+ }
+}
+
+/**************************************************************************//**
+\brief Initialization of usart for consinsting of flash transmitting.
+******************************************************************************/
+void ofdInitDebugInterface(void)
+{
+#if defined(ATMEGA1281) || defined(ATMEGA128RFA1)
+ usartDescriptor.tty = USART_CHANNEL_1;
+#elif defined(ATXMEGA256A3) || defined(ATXMEGA256D3)
+ usartDescriptor.tty = USART_CHANNEL_F0;
+#endif
+ usartDescriptor.mode = USART_MODE_ASYNC;
+ usartDescriptor.flowControl = USART_FLOW_CONTROL_NONE;
+ usartDescriptor.baudrate = USART_BAUDRATE_38400;
+ usartDescriptor.dataLength = USART_DATA8;
+ usartDescriptor.parity = USART_PARITY_NONE;
+ usartDescriptor.stopbits = USART_STOPBIT_1;
+ usartDescriptor.rxBuffer = NULL;
+ usartDescriptor.rxBufferLength = 0;
+ usartDescriptor.txBuffer = NULL;
+ usartDescriptor.txBufferLength = 0;
+ usartDescriptor.rxCallback = NULL;
+ usartDescriptor.txCallback = usartWriteConfirm;
+
+ HAL_OpenUsart(&usartDescriptor);
+ ofdReadData(debugOffset, debugBuffer, OFD_BLOCK_SIZE, ofdReadConfirm);
+}
+
+/**************************************************************************//**
+\brief Reads data from the external memory.
+
+\param[in]
+ address - flash cell address
+\param[out]
+ data - pointer to memory buffer
+\param[in]
+ size - size of memory buffer
+\param[in]
+ cb - pointer to callback
+******************************************************************************/
+void ofdReadData(uint32_t address, uint8_t *data, uint16_t size, OFD_Callback_t cb)
+{
+ uint32_t pageAddr;
+ uint32_t byteAddr;
+
+
+ while (FLASH_BUSY == ofdCheckBusyState())
+ {;}// waits till flash ready
+ pageAddr = address / PAGE_SIZE;
+ byteAddr = address % PAGE_SIZE;
+ address = byteAddr | (pageAddr << 9) | ((uint32_t)READ << 24);
+ address = OFD_LITTLE_TO_BIG_ENDIAN(address);
+ GPIO_EXT_MEM_CS_clr();
+ HAL_WriteSpi(&spiDesc, (uint8_t *)&address, sizeof(uint32_t));
+ // load 32 don't care bits
+ HAL_WriteSpi(&spiDesc, (uint8_t *)&address, sizeof(uint32_t));
+ HAL_ReadSpi(&spiDesc, data, size);
+ GPIO_EXT_MEM_CS_set();
+ if (cb)
+ cb(OFD_STATUS_SUCCESS);
+}
+#endif // defined(_OFD_DEBUG_)
+
+#endif // APP_USE_FAKE_OFD_DRIVER == 0
+#endif // (EXTERNAL_MEMORY == AT45DB041) && (APP_USE_OTAU == 1)
+#endif // _OTAU_
+// eof ofdAt25fDriver.c
diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdCommand.c b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdCommand.c
new file mode 100644
index 00000000..02a71723
--- /dev/null
+++ b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdCommand.c
@@ -0,0 +1,243 @@
+/**************************************************************************//**
+\file ofdCommand.c
+
+\brief Implementation of OTAU flash driver interface.
+
+\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:
+ 7/08/09 A. Khromykh - Created
+*******************************************************************************/
+/******************************************************************************
+ * WARNING: CHANGING THIS FILE MAY AFFECT CORE FUNCTIONALITY OF THE STACK. *
+ * EXPERT USERS SHOULD PROCEED WITH CAUTION. *
+ ******************************************************************************/
+
+#ifdef _OTAU_
+#if (APP_USE_OTAU == 1)
+#if APP_USE_FAKE_OFD_DRIVER == 0
+
+/******************************************************************************
+ Includes section
+******************************************************************************/
+#include <ofdExtMemory.h>
+#include <ofdMemoryDriver.h>
+
+/******************************************************************************
+ Define(s) section
+******************************************************************************/
+#define CRC_INITIALIZATION_VALUE 0xFF
+
+/******************************************************************************
+ Global variables section
+******************************************************************************/
+OFD_Position_t sectorNumber = 0;
+OFD_Position_t actionSector = 0;
+OFD_Callback_t ofdCallback = NULL;
+OFD_Callback_t ofdAuxCallback = NULL;
+OFD_MemoryAccessParam_t localAccessStructure;
+OfdInternalMemoryAccessParam_t internalAccessParam;
+OFD_ImageInfo_t imageInfo;
+OfdImageTable_t imageTable;
+
+/******************************************************************************
+ Implementations section
+******************************************************************************/
+/**************************************************************************//**
+\brief Erases image in the external memory.
+
+\param[in]
+ pos - image position in the external memory
+\param[in]
+ cb - pointer to callback
+******************************************************************************/
+void OFD_EraseImage(OFD_Position_t pos, OFD_Callback_t cb)
+{
+ if (pos >= OFD_POSITION_MAX)
+ {
+ if (cb)
+ cb(OFD_STATUS_INCORRECT_API_PARAMETER);
+ return;
+ }
+
+ sectorNumber = pos;
+ ofdCallback = cb;
+ ofdEraseImage();
+}
+
+/**************************************************************************//**
+\brief Writes data to the external memory.
+
+\param[in]
+ pos - image position for new data
+\param[in]
+ accessParam - pointer to the access structure
+\param[in]
+ cb - pointer to callback
+******************************************************************************/
+void OFD_Write(OFD_Position_t pos, OFD_MemoryAccessParam_t *accessParam, OFD_Callback_t cb)
+{
+ if ((pos >= OFD_POSITION_MAX) || (NULL == accessParam))
+ {
+ if (cb)
+ cb(OFD_STATUS_INCORRECT_API_PARAMETER);
+ return;
+ }
+
+ sectorNumber = pos;
+ ofdCallback = cb;
+ localAccessStructure = *accessParam;
+
+ // set table info like "image was written through api"
+ imageTable |= (OfdImageTable_t)(1 << pos);
+
+ if (localAccessStructure.offset >= OFD_START_EEPROM_SREC_ADDRESS)
+ localAccessStructure.offset -= (OFD_START_EEPROM_SREC_ADDRESS - OFD_EEPROM_OFFSET_WITHIN_IMAGE);
+
+ if (OFD_POSITION_1 == sectorNumber)
+ localAccessStructure.offset += OFD_IMAGE1_START_ADDRESS;
+ else
+ localAccessStructure.offset += OFD_IMAGE2_START_ADDRESS;
+
+ ofdWriteData();
+}
+
+/**************************************************************************//**
+\brief Flushes data from internal buffer, checks image crc and saves it to
+the external memory.
+
+\param[in]
+ pos - image position for new data
+\param[in]
+ countBuff - pointer to the memory for internal data (memory size must be OFD_BLOCK_FOR_CHECK_CRC)
+\param[in]
+ cb - pointer to callback
+******************************************************************************/
+void OFD_FlushAndCheckCrc(OFD_Position_t pos, uint8_t *countBuff, OFD_InfoCallback_t cb)
+{
+ if ((pos >= OFD_POSITION_MAX) || (NULL == countBuff))
+ {
+ if (cb)
+ cb(OFD_STATUS_INCORRECT_API_PARAMETER, &imageInfo);
+ return;
+ }
+
+ ofdFlushData();
+
+ sectorNumber = pos;
+ ofdCallback = (OFD_Callback_t)cb;
+ imageInfo.crc = CRC_INITIALIZATION_VALUE;
+
+ localAccessStructure.data = countBuff;
+ localAccessStructure.length = OFD_IMAGE_SIZE;
+ if (OFD_POSITION_1 == sectorNumber)
+ localAccessStructure.offset = OFD_IMAGE1_START_ADDRESS;
+ else
+ localAccessStructure.offset = OFD_IMAGE2_START_ADDRESS;
+
+ ofdCheckCrc();
+}
+
+/**************************************************************************//**
+\brief Saves current mcu flash and eeprom to the external memory, checks crc for its
+and set command for bootloader.
+
+\param[in]
+ whereToSave - image position for current mcu flash and eeprom
+\param[in]
+ from - new image position
+\param[in]
+ copyBuff - pointer to the memory for internal data (memory size must be OFD_BLOCK_FOR_CHECK_CRC)
+\param[in]
+ cb - pointer to callback
+******************************************************************************/
+void OFD_SwitchToNewImage(OFD_Position_t whereToSave, OFD_Position_t from, uint8_t *copyBuff, OFD_Callback_t cb)
+{
+ if ((whereToSave >= OFD_POSITION_MAX) || (from >= OFD_POSITION_MAX) || (whereToSave == from) || (NULL == copyBuff))
+ {
+ if (cb)
+ cb(OFD_STATUS_INCORRECT_API_PARAMETER);
+ return;
+ }
+
+ sectorNumber = whereToSave;
+ actionSector = from;
+ ofdAuxCallback = cb;
+
+ // set table info like "image was saved from mcu"
+ imageTable &= (OfdImageTable_t)~(1 << sectorNumber);
+
+ internalAccessParam.flashOffset = 0ul;
+ internalAccessParam.data = copyBuff;
+ internalAccessParam.length = OFD_IMAGE_SIZE;
+
+ if (OFD_POSITION_1 == sectorNumber)
+ localAccessStructure.offset = OFD_IMAGE1_START_ADDRESS;
+ else
+ localAccessStructure.offset = OFD_IMAGE2_START_ADDRESS;
+
+ ofdSaveCurrentFlashImage();
+}
+
+/**************************************************************************//**
+\brief Reads image informations.
+
+\param[in]
+ pos - image position
+\param[in]
+ cb - pointer to callback
+******************************************************************************/
+void OFD_ReadImageInfo(OFD_Position_t pos, OFD_InfoCallback_t cb)
+{
+ if (pos >= OFD_POSITION_MAX)
+ {
+ if (cb)
+ cb(OFD_STATUS_INCORRECT_API_PARAMETER, &imageInfo);
+ return;
+ }
+
+ sectorNumber = pos;
+
+ if (imageTable & (1 << pos))
+ imageInfo.type = OFD_IMAGE_WAS_WRITTEN_THROUGH_API;
+ else
+ imageInfo.type = OFD_IMAGE_WAS_SAVED_FROM_MCU;
+
+ ofdCallback = (OFD_Callback_t)cb;
+
+ ofdReadCrc();
+}
+
+/**************************************************************************//**
+\brief Sets command for bootloader.
+
+\param[in]
+ from - image position
+\param[in]
+ cb - pointer to callback
+******************************************************************************/
+void OFD_ChangeImage(OFD_Position_t from, OFD_Callback_t cb)
+{
+ if (from >= OFD_POSITION_MAX)
+ {
+ if (cb)
+ cb(OFD_STATUS_INCORRECT_API_PARAMETER);
+ return;
+ }
+
+ actionSector = from;
+ ofdAuxCallback = cb;
+ ofdSetActionForBootloader();
+}
+
+#endif // APP_USE_FAKE_OFD_DRIVER == 0
+#endif // (APP_USE_OTAU == 1)
+#endif // _OTAU_
+
+// eof ofdCommand.c
diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdCrcService.c b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdCrcService.c
new file mode 100644
index 00000000..3ba6ed45
--- /dev/null
+++ b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdCrcService.c
@@ -0,0 +1,66 @@
+/**************************************************************************//**
+\file ofdCrcService.c
+
+\brief Implementation of crc counting algorithm.
+
+\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:
+ 7/08/09 A. Khromykh - Created
+*******************************************************************************/
+/******************************************************************************
+ * WARNING: CHANGING THIS FILE MAY AFFECT CORE FUNCTIONALITY OF THE STACK. *
+ * EXPERT USERS SHOULD PROCEED WITH CAUTION. *
+ ******************************************************************************/
+
+#ifdef _OTAU_
+#if (APP_USE_OTAU == 1)
+#if APP_USE_FAKE_OFD_DRIVER == 0
+
+/******************************************************************************
+ Includes section
+******************************************************************************/
+#include <types.h>
+
+/******************************************************************************
+ Implementations section
+******************************************************************************/
+/**************************************************************************//**
+\brief Counts crc current memory area. CRC-8. Polynom 0x31 x^8 + x^5 + x^4 + 1.
+
+\param[in]
+ crc - first crc state
+\param[in]
+ pcBlock - pointer to the memory for crc counting
+\param[in]
+ length - memory size
+
+\return
+ current area crc
+******************************************************************************/
+uint8_t ofdCrc(uint8_t crc, uint8_t *pcBlock, uint8_t length)
+{
+ uint8_t i;
+
+ while (length--)
+ {
+ crc ^= *pcBlock++;
+
+ for (i = 0; i < 8; i++)
+ crc = crc & 0x80 ? (crc << 1) ^ 0x31 : crc << 1;
+ }
+
+ return crc;
+}
+
+#endif // APP_USE_FAKE_OFD_DRIVER == 0
+#endif // (APP_USE_OTAU == 1)
+#endif // _OTAU_
+
+// eof ofdCrcService.c
diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdFakeDriver.c b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdFakeDriver.c
new file mode 100644
index 00000000..2d781c70
--- /dev/null
+++ b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdFakeDriver.c
@@ -0,0 +1,218 @@
+/**************************************************************************//**
+\file ofdFakeDriver.c
+
+\brief Implementation of OTAU fake flash driver.
+
+\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:
+ 2/06/10 A. Khromykh - Created
+*******************************************************************************/
+/******************************************************************************
+ * WARNING: CHANGING THIS FILE MAY AFFECT CORE FUNCTIONALITY OF THE STACK. *
+ * EXPERT USERS SHOULD PROCEED WITH CAUTION. *
+ ******************************************************************************/
+
+#ifdef _OTAU_
+#if (APP_USE_OTAU == 1)
+#if APP_USE_FAKE_OFD_DRIVER == 1
+
+/******************************************************************************
+ Includes section
+******************************************************************************/
+#include <ofdExtMemory.h>
+#include <appTimer.h>
+
+/******************************************************************************
+ Define(s) section
+******************************************************************************/
+#define CALL_CALLBACK_TIME 10
+
+/******************************************************************************
+ Prototypes section
+******************************************************************************/
+static void ofdRunDriverCb(void);
+static void ofdRunInfoDriverCb(void);
+
+/******************************************************************************
+ Global variables section
+******************************************************************************/
+static HAL_AppTimer_t ofdCallbackRunner =
+{
+ .interval = CALL_CALLBACK_TIME,
+ .mode = TIMER_ONE_SHOT_MODE,
+};
+OFD_Callback_t ofdFuncCb = NULL;
+OFD_InfoCallback_t ofdFuncInfoCb = NULL;
+OFD_ImageInfo_t ofdImageInfo =
+{
+ .type = OFD_IMAGE_WAS_SAVED_FROM_MCU,
+ .crc = 0x00
+};
+
+/******************************************************************************
+ Implementations section
+******************************************************************************/
+/**************************************************************************//**
+\brief Run flash driver callback if that has been initialized.
+******************************************************************************/
+static void ofdRunDriverCb(void)
+{
+ if (ofdFuncCb)
+ {
+ ofdFuncCb(OFD_STATUS_SUCCESS);
+ }
+}
+
+/**************************************************************************//**
+\brief Run flash information driver callback if that has been initialized.
+******************************************************************************/
+static void ofdRunInfoDriverCb(void)
+{
+ if (ofdFuncInfoCb)
+ {
+ ofdFuncInfoCb(OFD_STATUS_SUCCESS, &ofdImageInfo);
+ }
+}
+
+/**************************************************************************//**
+\brief Opens serial interface and checks memory type.
+
+\param[in]
+ cb - pointer to callback
+******************************************************************************/
+void OFD_Open(OFD_Callback_t cb)
+{
+ ofdFuncCb = cb;
+ ofdCallbackRunner.callback = ofdRunDriverCb;
+ HAL_StartAppTimer(&ofdCallbackRunner);
+}
+
+/**************************************************************************//**
+\brief Closes serial interface.
+******************************************************************************/
+void OFD_Close(void)
+{
+}
+
+/**************************************************************************//**
+\brief Erases image in the external memory.
+
+\param[in]
+ pos - image position in the external memory
+\param[in]
+ cb - pointer to callback
+******************************************************************************/
+void OFD_EraseImage(OFD_Position_t pos, OFD_Callback_t cb)
+{
+ (void)pos;
+ ofdFuncCb = cb;
+ ofdCallbackRunner.callback = ofdRunDriverCb;
+ HAL_StartAppTimer(&ofdCallbackRunner);
+}
+
+/**************************************************************************//**
+\brief Writes data to the external memory.
+
+\param[in]
+ pos - image position for new data
+\param[in]
+ accessParam - pointer to the access structure
+\param[in]
+ cb - pointer to callback
+******************************************************************************/
+void OFD_Write(OFD_Position_t pos, OFD_MemoryAccessParam_t *accessParam, OFD_Callback_t cb)
+{
+ (void)pos;
+ (void)accessParam;
+ ofdFuncCb = cb;
+ ofdCallbackRunner.callback = ofdRunDriverCb;
+ HAL_StartAppTimer(&ofdCallbackRunner);
+}
+
+/**************************************************************************//**
+\brief Flushes data from internal buffer, checks image crc and saves it to
+the external memory.
+
+\param[in]
+ pos - image position for new data
+\param[in]
+ countBuff - pointer to the memory for internal data (memory size must be OFD_BLOCK_FOR_CHECK_CRC)
+\param[in]
+ cb - pointer to callback
+******************************************************************************/
+void OFD_FlushAndCheckCrc(OFD_Position_t pos, uint8_t *countBuff, OFD_InfoCallback_t cb)
+{
+ (void)pos;
+ (void)countBuff;
+ ofdFuncInfoCb = cb;
+ ofdCallbackRunner.callback = ofdRunInfoDriverCb;
+ HAL_StartAppTimer(&ofdCallbackRunner);
+}
+
+/**************************************************************************//**
+\brief Saves current mcu flash and eeprom to the external memory, checks crc for its
+and set command for bootloader.
+
+\param[in]
+ whereToSave - image position for current mcu flash and eeprom
+\param[in]
+ from - new image position
+\param[in]
+ copyBuff - pointer to the memory for internal data (memory size must be OFD_BLOCK_FOR_CHECK_CRC)
+\param[in]
+ cb - pointer to callback
+******************************************************************************/
+void OFD_SwitchToNewImage(OFD_Position_t whereToSave, OFD_Position_t from, uint8_t *copyBuff, OFD_Callback_t cb)
+{
+ (void)whereToSave;
+ (void)from;
+ (void)copyBuff;
+ ofdFuncCb = cb;
+ ofdCallbackRunner.callback = ofdRunDriverCb;
+ HAL_StartAppTimer(&ofdCallbackRunner);
+}
+
+/**************************************************************************//**
+\brief Sets command for bootloader.
+
+\param[in]
+ from - image position
+\param[in]
+ cb - pointer to callback
+******************************************************************************/
+void OFD_ChangeImage(OFD_Position_t from, OFD_Callback_t cb)
+{
+ (void)from;
+ ofdFuncCb = cb;
+ ofdCallbackRunner.callback = ofdRunDriverCb;
+ HAL_StartAppTimer(&ofdCallbackRunner);
+}
+
+/**************************************************************************//**
+\brief Reads image informations.
+
+\param[in]
+ pos - image position
+\param[in]
+ cb - pointer to callback
+******************************************************************************/
+void OFD_ReadImageInfo(OFD_Position_t pos, OFD_InfoCallback_t cb)
+{
+ (void)pos;
+ ofdFuncInfoCb = cb;
+ ofdCallbackRunner.callback = ofdRunInfoDriverCb;
+ HAL_StartAppTimer(&ofdCallbackRunner);
+}
+
+#endif // _OTAU_
+#endif // (APP_USE_OTAU == 1)
+#endif // APP_USE_FAKE_OFD_DRIVER == 1
+
+// eof ofdFakeDriver.c
diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdIntFlashRead.s b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdIntFlashRead.s
new file mode 100644
index 00000000..b3267377
--- /dev/null
+++ b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdIntFlashRead.s
@@ -0,0 +1,40 @@
+/**************************************************************************//**
+ \file ofdIntFlashRead.s
+
+ \brief Implementation of internal flash reading.
+
+ \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:
+ 13/08/09 A. Khromykh - Created
+*******************************************************************************/
+
+/*******************************************************************************
+Reads byte from internal flash
+Parameters:
+ R25:R24:R23:R22 - Byte address into flash.
+Returns:
+ R24 - read byte from flash.
+*******************************************************************************/
+.section .text
+.global ofdReadInternalFlash
+ofdReadInternalFlash:
+ push r31 ; Store Z to stack
+ push r30 ; Store Z to stack
+ in r25, 0x3B ; Save RAMPZ.
+ out 0x3B, r24 ; Load RAMPZ with the MSB of the address.
+ movw r30, r22 ; Move low bytes of address to ZH:ZL from R23:R22
+ elpm r24, Z ; Extended load program memory from Z address
+ out 0x3B, r25 ; Restore RAMPZ register.
+ pop r30 ; Restore Z
+ pop r31 ; Restore Z
+ ret ; return from function
+
+; eof ofdIntFlashRead.s
+
diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdIntFlashRead.s90 b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdIntFlashRead.s90
new file mode 100644
index 00000000..9fc8e941
--- /dev/null
+++ b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdIntFlashRead.s90
@@ -0,0 +1,40 @@
+/**************************************************************************//**
+ \file ofdIntFlashRead.s90
+
+ \brief Implementation of internal flash reading.
+
+ \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:
+ 19/02/10 A. Khromykh - Created
+*******************************************************************************/
+
+/*******************************************************************************
+Reads byte from internal flash
+Parameters:
+ R19:R18:R17:R16 - Byte address into flash.
+Returns:
+ R16 - read byte from flash.
+*******************************************************************************/
+PUBLIC ofdReadInternalFlash
+RSEG CODE
+ofdReadInternalFlash:
+ push r31 ; Store Z to stack
+ push r30 ; Store Z to stack
+ in r19, 0x3B ; Save RAMPZ.
+ out 0x3B, r18 ; Load RAMPZ with the MSB of the address.
+ movw r31:r30, r17:r16 ; Move low bytes of address to ZH:ZL from R17:R16
+ elpm r16, Z ; Extended load program memory from Z address
+ out 0x3B, r19 ; Restore RAMPZ register.
+ pop r30 ; Restore Z
+ pop r31 ; Restore Z
+ ret ; return from function
+
+; eof ofdIntFlashRead.s90
+END
diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdSpiSerializer.c b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdSpiSerializer.c
new file mode 100644
index 00000000..9994f2ed
--- /dev/null
+++ b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdSpiSerializer.c
@@ -0,0 +1,91 @@
+/**************************************************************************//**
+\file ofdSerializer.c
+
+\brief Implementation of capturing of serial interface.
+
+\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:
+ 7/08/09 A. Khromykh - Created
+*******************************************************************************/
+/******************************************************************************
+ * WARNING: CHANGING THIS FILE MAY AFFECT CORE FUNCTIONALITY OF THE STACK. *
+ * EXPERT USERS SHOULD PROCEED WITH CAUTION. *
+ ******************************************************************************/
+
+#ifdef _OTAU_
+#if (APP_USE_OTAU == 1)
+#if APP_USE_FAKE_OFD_DRIVER == 0
+
+/******************************************************************************
+ Includes section
+******************************************************************************/
+#include <ofdExtMemory.h>
+#include <ofdMemoryDriver.h>
+#include <spi.h>
+
+/******************************************************************************
+ External variables section
+******************************************************************************/
+extern OFD_Callback_t ofdCallback;
+
+/******************************************************************************
+ Global variables section
+******************************************************************************/
+HAL_SpiDescriptor_t spiDesc;
+
+/******************************************************************************
+ Implementations section
+******************************************************************************/
+/**************************************************************************//**
+\brief Opens serial interface and checks memory type.
+
+\param[in]
+ cb - pointer to callback
+******************************************************************************/
+void OFD_Open(OFD_Callback_t cb)
+{
+ ofdCallback = cb;
+
+#if defined(ATMEGA1281) || defined(ATMEGA128RFA1)
+ spiDesc.tty = SPI_CHANNEL_0;
+ spiDesc.baudRate = SPI_CLOCK_RATE_2000;
+#elif defined(ATXMEGA256A3) || defined(ATXMEGA256D3)
+ spiDesc.tty = SPI_CHANNEL_D;
+ spiDesc.baudRate = SPI_CLOCK_RATE_8000;
+#endif
+ spiDesc.clockMode = SPI_CLOCK_MODE3;
+ spiDesc.dataOrder = SPI_DATA_MSB_FIRST;
+ spiDesc.callback = NULL;
+
+ if (-1 == HAL_OpenSpi(&spiDesc))
+ if (ofdCallback)
+ ofdCallback(OFD_SERIAL_INTERFACE_BUSY);
+
+ GPIO_EXT_MEM_CS_set();
+ GPIO_EXT_MEM_CS_make_out();
+ ofdFindStorageSpace();
+#if EXTERNAL_MEMORY == AT25DF041A
+ ofdUnprotectMemorySectors();
+#endif
+}
+
+/**************************************************************************//**
+\brief Closes serial interface.
+******************************************************************************/
+void OFD_Close(void)
+{
+ HAL_CloseSpi(&spiDesc);
+}
+
+#endif // APP_USE_FAKE_OFD_DRIVER == 0
+#endif // (APP_USE_OTAU == 1)
+#endif // _OTAU_
+
+// eof ofdSerialize.c