summaryrefslogtreecommitdiff
path: root/digital/zigbit/bitcloud/stack/Components/HAL/drivers
diff options
context:
space:
mode:
authorFlorent Duchon2012-12-26 17:36:00 +0100
committerFlorent Duchon2013-02-13 21:21:12 +0100
commitb24866225a6301d3a663f874725e83c012dc25d3 (patch)
treeca527a2aab9abcdfbaf244c53ca63f0c531892b0 /digital/zigbit/bitcloud/stack/Components/HAL/drivers
parent2ba279f4eb2f23fa08a7c13465d16ae6ba5d0f96 (diff)
digital/beacon: add bitcloud stack into common directory digital/zigbit
Diffstat (limited to 'digital/zigbit/bitcloud/stack/Components/HAL/drivers')
-rw-r--r--digital/zigbit/bitcloud/stack/Components/HAL/drivers/ISD/src/isdImageStorage.c626
-rw-r--r--digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/Makefile107
-rw-r--r--digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/include/ofdMemoryDriver.h310
-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
-rw-r--r--digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/DFU/include/dfuProtocol.h81
-rw-r--r--digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/DFU/src/dfuProtocol.c135
-rw-r--r--digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/MSD/include/abstractMemory.h83
-rw-r--r--digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/MSD/include/mem.h106
-rw-r--r--digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/MSD/include/mscProtocol.h79
-rw-r--r--digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/MSD/include/scsiProtocol.h114
-rw-r--r--digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/MSD/src/abstractMemory.c225
-rw-r--r--digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/MSD/src/massStorageDevice.c327
-rw-r--r--digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/MSD/src/mmc.c618
-rw-r--r--digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/MSD/src/mscProtocol.c53
-rw-r--r--digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/MSD/src/scsiProtocol.c398
-rw-r--r--digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/VCP/Makefile71
-rw-r--r--digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/VCP/include/vcpCdcProtocol.h119
-rw-r--r--digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/VCP/src/vcpCdcProtocol.c226
-rw-r--r--digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/VCP/src/vcpVirtualUsart.c498
-rw-r--r--digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/common/include/usbDescriptors.h184
-rw-r--r--digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/common/include/usbEnumeration.h53
-rw-r--r--digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/common/include/usbSetupProcess.h51
-rw-r--r--digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/common/src/usbDescriptors.c424
-rw-r--r--digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/common/src/usbEnumeration.c231
-rw-r--r--digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/common/src/usbSetupProcess.c90
-rw-r--r--digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBFIFO/include/usbFifoVirtualUsart.h69
-rw-r--r--digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBFIFO/src/usbFifoFT245RL.c290
-rw-r--r--digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBFIFO/src/usbFifoVirtualUsart.c250
-rw-r--r--digital/zigbit/bitcloud/stack/Components/HAL/drivers/include/isdImageStorage.h89
-rw-r--r--digital/zigbit/bitcloud/stack/Components/HAL/drivers/include/massStorageDevice.h71
-rw-r--r--digital/zigbit/bitcloud/stack/Components/HAL/drivers/include/ofdExtMemory.h175
-rw-r--r--digital/zigbit/bitcloud/stack/Components/HAL/drivers/include/usbFifoUsart.h109
-rw-r--r--digital/zigbit/bitcloud/stack/Components/HAL/drivers/include/vcpVirtualUsart.h111
40 files changed, 8571 insertions, 0 deletions
diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/drivers/ISD/src/isdImageStorage.c b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/ISD/src/isdImageStorage.c
new file mode 100644
index 00000000..a173da69
--- /dev/null
+++ b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/ISD/src/isdImageStorage.c
@@ -0,0 +1,626 @@
+/**************************************************************************//**
+\file isdImageStorage.c
+
+\brief Implementation of image storage 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:
+ 25.05.11 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)
+
+/******************************************************************************
+ Includes section
+******************************************************************************/
+#include <isdImageStorage.h>
+#include <usart.h>
+#include <rs232Controller.h>
+#include <queue.h>
+#include <dbg.h>
+#include <appTimer.h>
+#include <mnUtils.h>
+
+/******************************************************************************
+ Defines section
+******************************************************************************/
+// Size of length field in frame
+#define LEN_SIZE (sizeof(((IsdCommandFrame_t*)NULL)->length))
+// Start of frame market
+#define SOF 0x2A
+// 500 ms interbyte timeout should be enough for everyone
+#define INTERBYTE_TIMEOUT 500
+// 5000 ms timeout between request to storage system and response from it.
+#define INTERMESSAGE_TIMEOUT 5000
+#define USART_RX_BUFFER_LENGTH 104
+
+#ifndef APP_MAX_COMMAND_PAYLOAD_SIZE
+ #define APP_MAX_COMMAND_PAYLOAD_SIZE 100
+#endif
+
+// code from runner
+#define ISD_ZCL_COMMAND_INDICATION 0x0046
+#define ISD_ZCL_COMMAND_REQUEST 0x0044
+#define ISD_DRIVER_INIT_REQUEST 0x0100
+#define ISD_DRIVER_INIT_RESPONSE 0x0101
+#define ISD_COMMAND_ID_SIZE (sizeof(uint16_t))
+#define ISD_INIT_MARKER 0x55
+/******************************************************************************
+ Types section
+******************************************************************************/
+// States of tx FSM
+typedef enum _TxState_t
+{
+ TX_ERR_OR_OFF,
+ TX_IDLE,
+ TX_SENDING_SOF,
+ TX_SENDING_DATA,
+} TxState_t;
+
+// States of rx FSM
+typedef enum _RxState_t
+{
+ RX_ERR_OR_OFF,
+ RX_WAITING_START, // AKA IDLE
+ RX_WAITING_LEN,
+ RX_WAITING_DATA,
+} RxState_t;
+
+BEGIN_PACK
+typedef struct PACK _IsdCommandFrame_t
+{
+ uint16_t length;
+ uint16_t commandId;
+ uint8_t payload[APP_MAX_COMMAND_PAYLOAD_SIZE];
+} IsdCommandFrame_t;
+
+typedef struct PACK
+{
+ uint8_t srcAddrMode;
+ ShortAddr_t srcShortAddress;
+ ExtAddr_t srcExtAddress;
+ ProfileId_t srcProfileId;
+ Endpoint_t srcEndpointId;
+ ClusterId_t srcClusterId;
+
+ ClusterId_t clusterId;
+ uint8_t direction;
+ uint8_t commandId;
+ uint8_t payload[1];
+} IsdCommandIndication_t;
+
+typedef struct PACK
+{
+ LITTLE_ENDIAN_OCTET(3,(
+ uint8_t direction : 1,
+ uint8_t generalCommand : 1,
+ uint8_t reserved : 6
+ ))
+} IsdCommandOptions_t;
+
+typedef struct PACK
+{
+ uint8_t addrMode;
+ ShortAddr_t shortAddress;
+ ExtAddr_t extAddress;
+ ProfileId_t profileId;
+ uint8_t endpoint;
+ uint8_t dstEndpoint;
+ ClusterId_t clusterId;
+ uint8_t defaultResponse;
+ IsdCommandOptions_t commandOptions;
+ uint8_t commandId;
+ uint8_t recordsCount;
+ uint8_t request[1];
+} IsdCommandRequest_t;
+END_PACK
+
+/******************************************************************************
+ Static Function Prototypes section
+******************************************************************************/
+static void isdUsartReceivedHandler(uint16_t bytesAmount);
+static void isdSendCommandFrame(void);
+static void isdUsartTransmittedHandler(void);
+static void isdInterbyteTimeoutExpired(void);
+static void isdIntermessageTimeoutExpired(void);
+static void isdInitReq(void);
+static void isdInitResp(void);
+static void isdSerialNotify(void);
+static void isdSetState(ISD_Status_t state);
+
+/******************************************************************************
+ Static variables section
+******************************************************************************/
+static HAL_UsartDescriptor_t usartDescriptor;
+static RxState_t rxState = RX_ERR_OR_OFF;
+static TxState_t txState = TX_ERR_OR_OFF;
+static uint8_t usartDescriptorRxBuffer[USART_RX_BUFFER_LENGTH];
+static IsdCommandFrame_t isdBuffer;
+
+static HAL_AppTimer_t interbyteTimer =
+{
+ .interval = INTERBYTE_TIMEOUT,
+ .mode = TIMER_ONE_SHOT_MODE,
+ .callback = isdInterbyteTimeoutExpired,
+};
+
+static HAL_AppTimer_t intermessageTimer =
+{
+ .interval = INTERMESSAGE_TIMEOUT,
+ .mode = TIMER_ONE_SHOT_MODE,
+ .callback = isdIntermessageTimeoutExpired,
+};
+
+static IsdOpenCb_t generalCb;
+static IsdUpgradeEndCb_t upgradeEndCb;
+static IsdQueryNextImageCb_t queryNextImageCb;
+static IsdImageBlockCb_t imageBlockCb;
+
+static ISD_Status_t isdState;
+
+/******************************************************************************
+ Implementations section
+******************************************************************************/
+/**************************************************************************//**
+\brief Open image storage driver
+
+\param[in] cb - callback about driver actions
+******************************************************************************/
+void ISD_Open(IsdOpenCb_t cb)
+{
+ // Implementation depends on 'length' field in IsdCommandFrame_t being one byte
+ // In case of change, several modifications would be required
+ assert_static(2 == LEN_SIZE);
+ // Also depends on 'length' field being first field of command frame
+ assert_static(0 == offsetof(IsdCommandFrame_t, length));
+
+#ifdef BSP_ENABLE_RS232_CONTROL
+ BSP_EnableRs232();
+#endif /* BSP_ENABLE_RS232_CONTROL */
+
+ usartDescriptor.tty = APP_USART_CHANNEL;
+ 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 = usartDescriptorRxBuffer;
+ usartDescriptor.rxBufferLength = USART_RX_BUFFER_LENGTH; //BULK_SIZE
+ usartDescriptor.txBuffer = NULL;
+ usartDescriptor.txBufferLength = 0;
+ usartDescriptor.rxCallback = isdUsartReceivedHandler;
+ usartDescriptor.txCallback = isdUsartTransmittedHandler;
+
+ generalCb = cb;
+
+ if (-1 != HAL_OpenUsart(&usartDescriptor))
+ {
+ rxState = RX_WAITING_START;
+ txState = TX_IDLE;
+ isdInitReq();
+ }
+ else
+ {
+ rxState = RX_ERR_OR_OFF;
+ txState = TX_ERR_OR_OFF;
+ isdSetState(ISD_HARDWARE_FAULT);
+ }
+}
+
+/**************************************************************************//**
+\brief Request to storage system about communication.
+******************************************************************************/
+static void isdInitReq(void)
+{
+ isdBuffer.commandId = ISD_DRIVER_INIT_REQUEST;
+ isdBuffer.length = ISD_COMMAND_ID_SIZE + sizeof(uint8_t);
+ isdBuffer.payload[0] = ISD_INIT_MARKER;
+
+ HAL_StartAppTimer(&intermessageTimer);
+ isdSendCommandFrame();
+}
+
+/**************************************************************************//**
+\brief Response from storage system about communication.
+******************************************************************************/
+static void isdInitResp(void)
+{
+ HAL_StopAppTimer(&intermessageTimer);
+
+ if (ISD_INIT_MARKER != isdBuffer.payload[0])
+ isdSetState(ISD_COMMUNICATION_LOST);
+ else
+ isdSetState(ISD_SUCCESS);
+}
+
+/**************************************************************************//**
+\brief Close image storage driver
+******************************************************************************/
+void ISD_Close(void)
+{
+ rxState = RX_ERR_OR_OFF;
+ txState = TX_ERR_OR_OFF;
+ HAL_CloseUsart(&usartDescriptor);
+}
+
+/**************************************************************************//**
+\brief Reset rx FSM on expiration of interbyte timeout
+******************************************************************************/
+static void isdInterbyteTimeoutExpired(void)
+{
+ if (RX_ERR_OR_OFF != rxState)
+ rxState = RX_WAITING_START;
+}
+
+/**************************************************************************//**
+\brief Callback about timout expiration between request and response
+******************************************************************************/
+static void isdIntermessageTimeoutExpired(void)
+{
+ isdSetState(ISD_COMMUNICATION_LOST);
+ isdInitReq();
+}
+
+/**************************************************************************//**
+\brief Callback on reception of serial byte(s)
+
+\param[in] bytesAmount number of received bytes
+******************************************************************************/
+static void isdUsartReceivedHandler(uint16_t bytesAmount)
+{
+ static uint16_t rxCnt = 0;
+ while (bytesAmount)
+ {
+ switch (rxState)
+ {
+ case RX_WAITING_START:
+ {
+ uint8_t data;
+ if (HAL_ReadUsart(&usartDescriptor, &data, sizeof(uint8_t)) <= 0)
+ {
+ rxState = RX_ERR_OR_OFF;
+ isdSetState(ISD_HARDWARE_FAULT);
+ return;
+ }
+ if (SOF == data)
+ rxState = RX_WAITING_LEN;
+
+ bytesAmount--;
+ }
+ break;
+
+ case RX_WAITING_LEN:
+ {
+ if (bytesAmount >= sizeof(uint16_t))
+ {
+ if (HAL_ReadUsart(&usartDescriptor, (uint8_t *)&isdBuffer.length, sizeof(uint16_t)) <= 0)
+ {
+ rxState = RX_ERR_OR_OFF;
+ isdSetState(ISD_HARDWARE_FAULT);
+ return;
+ }
+
+ // Limit length to avoid possible buffer overflow
+ isdBuffer.length = MIN(isdBuffer.length, sizeof(IsdCommandFrame_t) - LEN_SIZE);
+
+ if (isdBuffer.length > 0)
+ rxState = RX_WAITING_DATA;
+ else
+ rxState = RX_WAITING_START; // Do not allow zero len
+
+ bytesAmount -= sizeof(uint16_t);
+ rxCnt = 0;
+ }
+ else
+ return;
+ }
+ break;
+
+ case RX_WAITING_DATA:
+ {
+ int readCnt;
+ uint8_t *readPtr = (uint8_t *)&isdBuffer;
+
+ readPtr += offsetof(IsdCommandFrame_t, commandId) + rxCnt;
+ readCnt = HAL_ReadUsart(&usartDescriptor, readPtr, MIN(bytesAmount, (uint16_t) (isdBuffer.length - rxCnt)));
+
+ if (readCnt <= 0)
+ {
+ rxState = RX_ERR_OR_OFF;
+ isdSetState(ISD_HARDWARE_FAULT);
+ return;
+ }
+
+ bytesAmount -= readCnt;
+ rxCnt += readCnt;
+ if (rxCnt >= isdBuffer.length)
+ {
+ // Full packet is received
+ rxState = RX_WAITING_START;
+ isdSerialNotify();
+ }
+ }
+ break;
+
+ case RX_ERR_OR_OFF:
+ default:
+ return;
+ }
+ }
+
+ HAL_StopAppTimer(&interbyteTimer);
+
+ if (RX_WAITING_DATA == rxState || RX_WAITING_LEN == rxState)
+ HAL_StartAppTimer(&interbyteTimer);
+}
+
+/**************************************************************************//**
+\brief Sends new command frame
+
+\return result code
+******************************************************************************/
+static void isdSendCommandFrame(void)
+{
+ static uint8_t sof = SOF;
+
+ if (HAL_WriteUsart(&usartDescriptor, &sof, sizeof(sof)) > 0)
+ {
+ txState = TX_SENDING_SOF;
+ }
+ else
+ {
+ txState = TX_ERR_OR_OFF;
+ isdSetState(ISD_HARDWARE_FAULT);
+ }
+}
+
+/**************************************************************************//**
+\brief Callback on completion of single serial transmit
+******************************************************************************/
+static void isdUsartTransmittedHandler(void)
+{
+ switch (txState)
+ {
+ case TX_SENDING_SOF:
+ {
+ uint8_t *writePtr = (uint8_t *)&isdBuffer;
+
+ writePtr += offsetof(IsdCommandFrame_t, length);
+ if (HAL_WriteUsart(&usartDescriptor, writePtr, isdBuffer.length + LEN_SIZE) <= 0)
+ {
+ txState = TX_ERR_OR_OFF;
+ isdSetState(ISD_HARDWARE_FAULT);
+ }
+ else
+ txState = TX_SENDING_DATA;
+ }
+ break;
+
+ case TX_SENDING_DATA:
+ txState = TX_IDLE;
+ break;
+
+ case TX_IDLE:
+ case TX_ERR_OR_OFF:
+ default:
+ break;
+ }
+}
+
+/**************************************************************************//**
+\brief Send query next image request to storage system
+
+\param[in] addressing - pointer to structure that include client network information; \n
+\param[in] data - data payload; \n
+\param[in] cd - callback about response receiving from storage system.
+******************************************************************************/
+void ISD_QueryNextImageReq(ZCL_Addressing_t *addressing, ZCL_OtauQueryNextImageReq_t *data, IsdQueryNextImageCb_t cb)
+{
+ IsdCommandIndication_t *serialData = (IsdCommandIndication_t *)isdBuffer.payload;
+
+ if (ISD_SUCCESS != isdState)
+ return;
+
+ serialData->clusterId = addressing->clusterId;
+ serialData->commandId = QUERY_NEXT_IMAGE_REQUEST_ID;
+ serialData->srcAddrMode = addressing->addrMode;
+ serialData->srcShortAddress = addressing->addr.shortAddress;
+ serialData->srcExtAddress = addressing->addr.extAddress;
+ serialData->srcProfileId = addressing->profileId;
+ serialData->srcEndpointId = addressing->endpointId;
+ serialData->srcClusterId = addressing->clusterId;
+ serialData->direction = addressing->clusterSide;
+
+ memcpy(serialData->payload, data, sizeof(ZCL_OtauQueryNextImageReq_t));
+
+ isdBuffer.commandId = ISD_ZCL_COMMAND_INDICATION;
+ isdBuffer.length = ISD_COMMAND_ID_SIZE + sizeof(IsdCommandIndication_t) +
+ sizeof(ZCL_OtauQueryNextImageReq_t) - sizeof(uint8_t);
+
+ queryNextImageCb = cb;
+
+ HAL_StartAppTimer(&intermessageTimer);
+ isdSendCommandFrame();
+}
+
+/**************************************************************************//**
+\brief Send image block request to storage system
+
+\param[in] addressing - pointer to structure that include client network information; \n
+\param[in] data - data payload; \n
+\param[in] cd - callback about response receiving from storage system.
+******************************************************************************/
+void ISD_ImageBlockReq(ZCL_Addressing_t *addressing, ZCL_OtauImageBlockReq_t *data, IsdImageBlockCb_t cb)
+{
+ IsdCommandIndication_t *serialData = (IsdCommandIndication_t *)isdBuffer.payload;
+
+ if (ISD_SUCCESS != isdState)
+ return;
+
+ serialData->clusterId = addressing->clusterId;
+ serialData->commandId = IMAGE_BLOCK_REQUEST_ID;
+ serialData->srcAddrMode = addressing->addrMode;
+ serialData->srcShortAddress = addressing->addr.shortAddress;
+ serialData->srcExtAddress = addressing->addr.extAddress;
+ serialData->srcProfileId = addressing->profileId;
+ serialData->srcEndpointId = addressing->endpointId;
+ serialData->srcClusterId = addressing->clusterId;
+ serialData->direction = addressing->clusterSide;
+
+ memcpy(serialData->payload, data, sizeof(ZCL_OtauImageBlockReq_t));
+
+ isdBuffer.commandId = ISD_ZCL_COMMAND_INDICATION;
+ isdBuffer.length = ISD_COMMAND_ID_SIZE + sizeof(IsdCommandIndication_t) +
+ sizeof(ZCL_OtauImageBlockReq_t) - sizeof(uint8_t);
+
+ imageBlockCb = cb;
+
+ HAL_StartAppTimer(&intermessageTimer);
+ isdSendCommandFrame();
+}
+
+/**************************************************************************//**
+\brief Send upgrade end request to storage system
+
+\param[in] addressing - pointer to structure that include client network information; \n
+\param[in] data - data payload; \n
+\param[in] cd - callback about response receiving from storage system.
+******************************************************************************/
+void ISD_UpgradeEndReq(ZCL_Addressing_t *addressing, ZCL_OtauUpgradeEndReq_t *data, IsdUpgradeEndCb_t cb)
+{
+ IsdCommandIndication_t *serialData = (IsdCommandIndication_t *)isdBuffer.payload;
+
+ if (ISD_SUCCESS != isdState)
+ return;
+
+ serialData->clusterId = addressing->clusterId;
+ serialData->commandId = UPGRADE_END_REQUEST_ID;
+ serialData->srcAddrMode = addressing->addrMode;
+ serialData->srcShortAddress = addressing->addr.shortAddress;
+ serialData->srcExtAddress = addressing->addr.extAddress;
+ serialData->srcProfileId = addressing->profileId;
+ serialData->srcEndpointId = addressing->endpointId;
+ serialData->srcClusterId = addressing->clusterId;
+ serialData->direction = addressing->clusterSide;
+
+ memcpy(serialData->payload, data, sizeof(ZCL_OtauUpgradeEndReq_t));
+
+ isdBuffer.commandId = ISD_ZCL_COMMAND_INDICATION;
+ isdBuffer.length = ISD_COMMAND_ID_SIZE + sizeof(IsdCommandIndication_t) +
+ sizeof(ZCL_OtauUpgradeEndReq_t) - sizeof(uint8_t);
+
+ upgradeEndCb = cb;
+
+ HAL_StartAppTimer(&intermessageTimer);
+ isdSendCommandFrame();
+}
+
+/**************************************************************************//**
+\brief Receive any messages from storage system
+******************************************************************************/
+static void isdSerialNotify(void)
+{
+ IsdCommandRequest_t *req = (IsdCommandRequest_t *)isdBuffer.payload;
+
+ if (ISD_DRIVER_INIT_RESPONSE == isdBuffer.commandId)
+ {
+ isdInitResp();
+ return;
+ }
+
+ if (ISD_ZCL_COMMAND_REQUEST != isdBuffer.commandId)
+ return;
+
+ if (OTAU_CLUSTER_ID != req->clusterId)
+ return;
+
+ switch (req->commandId)
+ {
+ case QUERY_NEXT_IMAGE_RESPONSE_ID:
+ {
+ ZCL_OtauQueryNextImageResp_t *resp = (ZCL_OtauQueryNextImageResp_t *)req->request;
+
+ HAL_StopAppTimer(&intermessageTimer);
+ if (queryNextImageCb)
+ {
+ queryNextImageCb(resp);
+ queryNextImageCb = NULL;
+ }
+ }
+ break;
+ case IMAGE_BLOCK_RESPONSE_ID:
+ {
+ ZCL_OtauImageBlockResp_t *resp = (ZCL_OtauImageBlockResp_t *)req->request;
+
+ HAL_StopAppTimer(&intermessageTimer);
+ if (imageBlockCb)
+ {
+ imageBlockCb(resp);
+ imageBlockCb = NULL;
+ }
+ }
+ break;
+ case UPGRADE_END_RESPONSE_ID:
+ {
+ ZCL_OtauUpgradeEndResp_t *resp = (ZCL_OtauUpgradeEndResp_t *)req->request;
+
+ HAL_StopAppTimer(&intermessageTimer);
+ if (upgradeEndCb)
+ {
+ upgradeEndCb(resp);
+ upgradeEndCb = NULL;
+ }
+ else
+ {
+ ZCL_Addressing_t addr =
+ {
+ .addrMode = req->addrMode,
+ .profileId = req->profileId,
+ .endpointId = req->dstEndpoint,
+ .clusterId = req->clusterId,
+ .clusterSide = ZCL_CLIENT_CLUSTER_TYPE,
+ .manufacturerSpecCode = 0,
+ };
+
+ if (APS_EXT_ADDRESS == addr.addrMode)
+ addr.addr.extAddress = req->extAddress;
+ else
+ addr.addr.shortAddress = req->shortAddress;
+
+ ZCL_UnsolicitedUpgradeEndResp(&addr, resp);
+ }
+ }
+ break;
+ }
+}
+
+/**************************************************************************//**
+\brief Set actual driver state and report to high layer about that.
+
+\param[in] state - actual driver state
+******************************************************************************/
+static void isdSetState(ISD_Status_t state)
+{
+ isdState = state;
+
+ if (generalCb)
+ generalCb(state);
+}
+
+#endif // (APP_USE_OTAU == 1)
+#endif // _OTAU_
+
+// eof isdImageStorage.c
diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/Makefile b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/Makefile
new file mode 100644
index 00000000..ef22558f
--- /dev/null
+++ b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/Makefile
@@ -0,0 +1,107 @@
+COMPONENTS_PATH = ../../..
+#include $(COMPONENTS_PATH)/Makerules
+include $(MAKERULES)
+
+DEBUG = NO
+###### Option to switch on the fake driver ##########
+ifndef APP_USE_FAKE_OFD_DRIVER
+ APP_USE_FAKE_OFD_DRIVER = 0
+endif
+
+# Hardware flags.
+CFLAGS += $(CFLAGS_HW)
+
+##### PATHS FLAGS OF INCLUDES #########
+CFLAGS += -I./include
+CFLAGS += -I./../include
+CFLAGS += -I$(HAL_PATH)/include
+CFLAGS += -I$(HAL_HWD_COMMON_PATH)/include
+CFLAGS += -I$(SE_PATH)/include
+
+ifeq ($(DEBUG), YES)
+ CFLAGS += -D_DEBUG_
+endif
+
+#### ASM DEFINES FLAGS #######
+ifeq ($(COMPILER_TYPE), GCC)
+ ASMFLAGS = $(filter -mmcu%,$(CFLAGS))
+ ASM_FILE_EXT = s
+endif
+ifeq ($(COMPILER_TYPE), IAR)
+ ASMFLAGS = -s+ # Enables case sensitivity.
+ ASMFLAGS += -w+ # Enables warnings.
+ ASMFLAGS += -M'<>'# Change asm.macro argument quote chars.
+ ASMFLAGS += -t8 # Set tab spacing.
+ ASMFLAGS += -u_enhancedCore
+ ASMFLAGS += -D__HAS_ENHANCED_CORE__=1
+ ASMFLAGS += -D__HAS_MUL__=1
+ ASMFLAGS += -D__MEMORY_MODEL__=2
+ ifneq (, $(findstring $(HAL), ATMEGA1281 ATMEGA1284 AT90USB1287 ATMEGA128RFA1))
+ ASMFLAGS += -v3 # Select processor option: Relative jumps do not wrap.
+ endif
+ ifneq (, $(findstring $(HAL), ATMEGA2561 ATXMEGA256A3 ATXMEGA256D3))
+ ASMFLAGS += -v5 # Select processor option: Relative jumps do not wrap.
+ endif
+ ifneq (, $(findstring $(HAL), ATXMEGA256A3 ATXMEGA256D3))
+ ASMFLAGS += --xmega #Enable Xmega specific instructions
+ endif
+ ASMFLAGS += -D__HAS_ELPM__=1
+ ASMFLAGS += -S
+ ASM_FILE_EXT = s90
+endif
+
+###### LIB ##########
+BUILDDIR = .
+
+LIBDIR = ./../lib
+LDFLAGS = -L$(LIBDIR)
+PROG = OFD.elf
+LIBS = $(LIBDIR)/lib$(OFD_LIB).a
+
+driver_label:
+ @echo
+ @echo ----------------------------------------------------
+ @echo Otau flash driver library creation.
+ @echo ----------------------------------------------------
+
+ifneq ($(APP_USE_FAKE_OFD_DRIVER), 1)
+modules = \
+ ofdAt25fDriver \
+ ofdAt45dbDriver \
+ ofdCommand \
+ ofdCrcService \
+ ofdSpiSerializer
+
+asm_modules = \
+ ofdIntFlashRead
+else
+modules = \
+ ofdFakeDriver
+endif
+
+objects = $(addsuffix .o,$(addprefix $(BUILDDIR)/objs/,$(modules)))
+sources = $(addsuffix .c,$(addprefix $(BUILDDIR)/src/,$(modules)))
+objects_asm = $(addsuffix .o,$(addprefix $(BUILDDIR)/objs/,$(asm_modules)))
+sources_asm = $(addsuffix .$(ASM_FILE_EXT),$(addprefix $(BUILDDIR)/src/,$(asm_modules)))
+
+###### TARGETS ################
+all: driver_label LIB_OFD
+
+################ c part ######################
+$(BUILDDIR)/objs/%.o: $(BUILDDIR)/src/%.c
+ $(CC) $(CFLAGS) $^ -o $@
+
+################ assembler part ######################
+$(BUILDDIR)/objs/%.o: $(BUILDDIR)/src/%.$(ASM_FILE_EXT)
+ $(AS) $(ASMFLAGS) -o $@ $^
+
+################
+LIB_OFD : $(objects) $(objects_asm)
+ $(AR) $(AR_KEYS) $(LIBDIR)/lib$(OFD_LIB).a $(objects) $(objects_asm)
+ $(SIZE) -td $(LIBDIR)/lib$(OFD_LIB).a
+################
+clean:
+ @echo ----------------------------------------------------
+ @echo OTAU flash driver cleaning.
+ @echo ----------------------------------------------------
+ rm -f $(objects) $(objects_asm) $(LIBS) $(BUILDDIR)/list/*.* \ No newline at end of file
diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/include/ofdMemoryDriver.h b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/include/ofdMemoryDriver.h
new file mode 100644
index 00000000..d158af26
--- /dev/null
+++ b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/include/ofdMemoryDriver.h
@@ -0,0 +1,310 @@
+/**************************************************************************//**
+\file ofdMemoryDriver.h
+
+\brief The implementation interface of external flash.
+
+\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:
+ 31/07/09 A. Khromykh - Created
+*******************************************************************************/
+/******************************************************************************
+ * WARNING: CHANGING THIS FILE MAY AFFECT CORE FUNCTIONALITY OF THE STACK. *
+ * EXPERT USERS SHOULD PROCEED WITH CAUTION. *
+ ******************************************************************************/
+#ifndef _OFDMEMORYDRIVER_H
+#define _OFDMEMORYDRIVER_H
+
+#ifdef _OTAU_
+/******************************************************************************
+ Includes section
+******************************************************************************/
+#include <gpio.h>
+
+/******************************************************************************
+ Define(s) section
+******************************************************************************/
+#if EXTERNAL_MEMORY == AT25F2048
+
+ #if !defined(ATMEGA1281) && !defined(ATMEGA128RFA1)
+ #error 'at25f2048 is supported only for atmega1281/128rfa1.'
+ #endif
+
+ // flash instruction format (see at25f2048 manual)
+ #define WREN 0x06
+ #define WRDI 0x04
+ #define RDSR 0x05
+ #define WRSR 0x01
+ #define READ 0x03
+ #define PROGRAM 0x02
+ #define SECTOR_ERASE 0x52
+ #define CHIP_ERASE 0x62
+ #define RDID 0x15
+
+ // status register bits
+ #define RDY 0x01
+ #define WEN 0x02
+ #define BP0 0x04
+ #define BP1 0x08
+ #define WPEN 0x80
+
+ // Atmel ID
+ #define OFD_MANUFACTURER_ID 0x1F
+ // at25f2048
+ #define OFD_DEVICE_ID 0x63
+
+ #define PAGE_SIZE 256
+
+ // flash sectors
+ #define SECTOR_ONE 0x00000000ul
+ #define SECTOR_TWO 0x00010000ul
+ #define SECTOR_THREE 0x00020000ul
+ #define SECTOR_FOUR 0x00030000ul
+ // 2 Mbits
+ #define OFD_FLASH_SIZE 262144
+ // image consists mcu flash - bootloader size + eeprom size. 128k - 4k + 4k
+ #define OFD_IMAGE_SIZE 131072
+ #define OFD_FLASH_START_ADDRESS 0
+ #define OFD_IMAGE1_START_ADDRESS OFD_FLASH_START_ADDRESS
+ #define OFD_IMAGE2_START_ADDRESS (OFD_FLASH_START_ADDRESS + OFD_IMAGE_SIZE)
+
+ #define OFD_MCU_FLASH_SIZE OFD_IMAGE_SIZE
+ #define OFD_MCU_EEPROM_SIZE 4096
+ #define OFD_EEPROM_OFFSET_WITHIN_IMAGE (OFD_MCU_FLASH_SIZE - OFD_MCU_EEPROM_SIZE)
+ // 1 byte (action for bootloader), 2 bytes (images crc), 1 byte table of image types.
+ #define OFD_SERVICE_INFO_SIZE 4
+
+#elif EXTERNAL_MEMORY == AT45DB041
+
+ #if !defined(ATMEGA1281) && !defined(ATMEGA128RFA1) && !defined(ATXMEGA256A3) && !defined(ATXMEGA256D3)
+ #error 'at45db041 is supported only for atmega1281/128rfa1, atxmega256a/d3.'
+ #endif
+
+ // flash instruction format (see at45db041 manual)
+ #define WRITE_BUF1 0x84
+ #define WRITE_BUF2 0x87
+ #define RDSR 0xD7
+ #define READ 0xE8
+ #define PROGRAM_BUF1 0x88
+ #define PROGRAM_BUF2 0x89
+ #define BLOCK_ERASE 0x50
+
+ // status register bits
+ #define RDY 0x80
+ // unchanged bit mask within status register xx0111xx
+ #define STATUS_UNCHANGED_BIT_MASK 0x3C
+ #define STATUS_UNCHANGED_BITS 0x1C
+
+ #define PAGE_SIZE 264
+ // block addresses
+ #define FIRST_HALF_BLOCK_NUMBER 0
+ #define SECOND_HALF_BLOCK_NUMBER 128
+
+ // 4 Mbits
+ #define OFD_FLASH_SIZE 540672
+
+ #if defined(ATMEGA1281) || defined(ATMEGA128RFA1)
+ // image consists mcu flash - bootloader size + eeprom size. 128k - 4k + 4k
+ // image uses 497 pages. 1 block = 8 pages
+ #define OFD_USED_BLOCKS_AMOUNT 63
+ #define OFD_IMAGE_SIZE 131072
+ #define OFD_MCU_FLASH_SIZE OFD_IMAGE_SIZE
+ #define OFD_EEPROM_OFFSET_WITHIN_IMAGE (OFD_MCU_FLASH_SIZE - OFD_MCU_EEPROM_SIZE)
+ #define OFD_LOAD_NO_COMMAND_TO_NVM
+ #elif defined(ATXMEGA256A3) || defined(ATXMEGA256D3)
+ // image consists mcu flash + eeprom size. 256k + 4k
+ // image uses 1009 pages. 1 block = 8 pages
+ #define OFD_USED_BLOCKS_AMOUNT 128
+ #define OFD_IMAGE_SIZE 266240
+ #define OFD_MCU_FLASH_SIZE 262144
+ #define OFD_EEPROM_OFFSET_WITHIN_IMAGE OFD_MCU_FLASH_SIZE
+ #define OFD_LOAD_NO_COMMAND_TO_NVM NVM.CMD = NVM_CMD_NO_OPERATION_gc
+ #endif
+
+ #define OFD_FLASH_START_ADDRESS 0
+ #define OFD_IMAGE1_START_ADDRESS OFD_FLASH_START_ADDRESS
+ #define OFD_IMAGE2_START_ADDRESS 270336
+
+ #define OFD_MCU_EEPROM_SIZE 4096
+ // 1 byte (action for bootloader), 2 bytes (images crc), 1 byte table of image types.
+ #define OFD_SERVICE_INFO_SIZE 4
+
+#elif EXTERNAL_MEMORY == AT25DF041A
+
+ #if !defined(ATXMEGA256A3) && !defined(ATXMEGA256D3)
+ #error 'at25df041a is supported only for atxmega256a3.'
+ #endif
+
+ // flash instruction format (see at25df041a manual)
+ #define WREN 0x06
+ #define WRDI 0x04
+ #define RDSR 0x05
+ #define WRSR 0x01
+ #define READ 0x03
+ #define PROGRAM 0x02
+ #define SECTOR_ERASE 0xD8
+ #define CHIP_ERASE 0x60
+ #define RDID 0x9F
+ #define PROTECT_SECTOR 0x36
+ #define UNPROTECT_SECTOR 0x39
+
+ // status register arguments
+ #define GLOBAL_UNPROTECT 0x00
+ #define GLOBAL_PROTECT 0x7F
+
+ // status register bits
+ #define RDY 0x01
+ #define WEN 0x02
+ #define SWP0 0x04
+ #define SWP1 0x08
+ #define WPP 0x10
+ #define EPE 0x20
+ #define SPM 0x40
+ #define WPRL 0x80
+
+ // Atmel ID
+ #define OFD_MANUFACTURER_ID 0x1F
+ // at25df041a
+ #define OFD_DEVICE_ID_1 0x44
+ #define OFD_DEVICE_ID_2 0x01
+ #define EXT_STRING_LENGTH 0x00
+
+ #define PAGE_SIZE 256
+
+ // flash sectors
+ #define SECTOR_ONE 0x00000000ul
+ #define SECTOR_TWO 0x00010000ul
+ #define SECTOR_THREE 0x00020000ul
+ #define SECTOR_FOUR 0x00030000ul
+ // 4 Mbits
+ #define OFD_FLASH_SIZE 524288
+ // image consists mcu flash size + eeprom size. 256k + 4k
+ #define OFD_IMAGE_SIZE 266240
+ #define OFD_FLASH_START_ADDRESS 0
+ #define OFD_IMAGE1_START_ADDRESS OFD_FLASH_START_ADDRESS
+ // this is fake start address used for code compatibility
+ #define OFD_IMAGE2_START_ADDRESS (OFD_FLASH_START_ADDRESS + OFD_IMAGE_SIZE)
+
+ #define OFD_MCU_FLASH_SIZE OFD_IMAGE_SIZE
+ #define OFD_MCU_EEPROM_SIZE 4096
+ #define OFD_EEPROM_OFFSET_WITHIN_IMAGE (OFD_MCU_FLASH_SIZE - OFD_MCU_EEPROM_SIZE)
+ // 1 byte (action for bootloader), 2 bytes (images crc), 1 byte table of image types.
+ #define OFD_SERVICE_INFO_SIZE 4
+
+#else
+ #error 'Unknown memory type.'
+#endif
+
+#define OFD_START_EEPROM_SREC_ADDRESS 0x810000
+#define OFD_LITTLE_TO_BIG_ENDIAN(A) ((((uint32_t)A & 0xFFul) << 24) \
+ | (((uint32_t)A & 0xFF00ul) << 8) \
+ | (((uint32_t)A >> 8) & 0xFF00ul) \
+ | (((uint32_t)A >> 24) & 0xFFul))
+
+
+typedef struct
+{
+ union
+ {
+ uint32_t flashOffset;
+ uint16_t eepromOffset;
+ };
+ uint8_t *data;
+ uint32_t length;
+} OfdInternalMemoryAccessParam_t;
+
+// image type table
+typedef uint8_t OfdImageTable_t;
+
+/******************************************************************************
+ Prototypes section
+******************************************************************************/
+/**************************************************************************//**
+\brief Starts image erasing in the external memory.
+******************************************************************************/
+void ofdEraseImage(void);
+
+/**************************************************************************//**
+\brief Writes data to the external memory.
+******************************************************************************/
+void ofdWriteData(void);
+
+/**************************************************************************//**
+\brief Checks image crc.
+******************************************************************************/
+void ofdCheckCrc(void);
+
+/**************************************************************************//**
+\brief Starts saving internal flash.
+******************************************************************************/
+void ofdSaveCurrentFlashImage(void);
+
+/**************************************************************************//**
+\brief Reads image crc from internal eeprom.
+******************************************************************************/
+void ofdReadCrc(void);
+
+/**************************************************************************//**
+\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);
+
+/**************************************************************************//**
+\brief Finds storage space.
+******************************************************************************/
+void ofdFindStorageSpace(void);
+
+/**************************************************************************//**
+\brief Sets action for internal bootloader.
+******************************************************************************/
+void ofdSetActionForBootloader(void);
+
+/**************************************************************************//**
+\brief Flushs memory buffer to flash.
+******************************************************************************/
+void ofdFlushData(void);
+
+#if EXTERNAL_MEMORY == AT25DF041A
+/**************************************************************************//**
+\brief Unprotects memory sectors for writing and erasing.
+******************************************************************************/
+void ofdUnprotectMemorySectors(void);
+#endif
+
+/******************************************************************************
+ Inline static functions prototypes section.
+******************************************************************************/
+// Macros for the EXT_MEM_CS pin manipulation.
+#if defined(ATMEGA1281)
+
+HAL_ASSIGN_PIN(EXT_MEM_CS, F, 3);
+
+#elif defined(ATMEGA128RFA1)
+
+HAL_ASSIGN_PIN(EXT_MEM_CS, G, 5);
+
+#elif defined(ATXMEGA256A3) || defined(ATXMEGA256D3)
+
+HAL_ASSIGN_PIN(EXT_MEM_CS, D, 4);
+
+#endif
+
+#endif // _OTAU_
+
+#endif /* _OFDMEMORYDRIVER_H */
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
diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/DFU/include/dfuProtocol.h b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/DFU/include/dfuProtocol.h
new file mode 100644
index 00000000..c525cfd1
--- /dev/null
+++ b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/DFU/include/dfuProtocol.h
@@ -0,0 +1,81 @@
+/****************************************************************************//**
+ \file dfuProtocol.h
+
+ \brief Declaration of Device firmware upgrade commands.
+
+ \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:
+ 08/09/11 N. Fomin - Created
+*******************************************************************************/
+#ifndef _DFUPROTOCOL_H
+#define _DFUPROTOCOL_H
+
+/******************************************************************************
+ Includes section
+******************************************************************************/
+#include <types.h>
+#include <usbSetupProcess.h>
+
+/******************************************************************************
+ Define(s) section
+******************************************************************************/
+// data size in request structure
+#define DFU_REQUEST_DATA_SIZE 6
+// request codes for mass storage class
+#define DFU_DETACH 0x00
+#define DFU_GETSTATUS 0x03
+#define DFU_GETSTATE 0x05
+
+/******************************************************************************
+ Types section
+******************************************************************************/
+BEGIN_PACK
+// Usb host request
+typedef struct PACK
+{
+ UsbRequest_t request;
+ uint8_t bData[DFU_REQUEST_DATA_SIZE];
+} UsbDfuRequest_t;
+
+// Usb dfu get status response
+typedef struct PACK
+{
+ uint8_t bStatus;
+ uint8_t bPollTimeout[3];
+ uint8_t bState;
+ uint8_t iString;
+} DfuGetStatusResponse_t;
+
+// Usb dfu get state response
+typedef struct PACK
+{
+ uint8_t bState;
+} DfuGetStateResponse_t;
+
+typedef union PACK
+{
+ DfuGetStatusResponse_t getStatusResponse;
+ DfuGetStateResponse_t getStateResponse;
+} UsbDfuResponse_t;
+
+END_PACK
+
+/******************************************************************************
+ Prototypes section
+******************************************************************************/
+/**************************************************************************//**
+\brief Device firmware upgrade request handler.
+\param[in]
+ data - pointer to host's request.
+******************************************************************************/
+void dfuRequestHandler(uint8_t *data);
+
+#endif /* _DFUPROTOCOL_H */
+// eof dfuProtocol.h \ No newline at end of file
diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/DFU/src/dfuProtocol.c b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/DFU/src/dfuProtocol.c
new file mode 100644
index 00000000..c19f312b
--- /dev/null
+++ b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/DFU/src/dfuProtocol.c
@@ -0,0 +1,135 @@
+/****************************************************************************//**
+ \file dfuProtocol.c
+
+ \brief Implementation of Device firmware upgrade commands.
+
+ \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:
+ 08/09/11 N. Fomin - Created
+*******************************************************************************/
+/******************************************************************************
+ Includes section
+******************************************************************************/
+#include <dfuProtocol.h>
+#include <usb.h>
+#include <resetReason.h>
+#include <halFlash.h>
+#include <usbEnumeration.h>
+
+/******************************************************************************
+ Define(s) section
+******************************************************************************/
+#define DFU_STATUS_OK 0x00
+#define DFU_STATUS_MAX_POLL_TIMEOUT 0xFF
+#define DFU_STATUS_NO_STRING 0x00
+
+#define BOOTLOADER_FLAG_FLASH_OFFSET 5
+
+/******************************************************************************
+ Global variables section
+******************************************************************************/
+static UsbDfuResponse_t dfuResponse;
+static bool detachReceived = false;
+
+/******************************************************************************
+ Implementations section
+******************************************************************************/
+/**************************************************************************//**
+\brief EEPROM write callback.
+******************************************************************************/
+void dfuResetAction(void)
+{
+ HAL_WarmReset();
+}
+/**************************************************************************//**
+\brief DFU detach request handler.
+******************************************************************************/
+static void dfuDetach(void)
+{
+ uint8_t bootloaderFlag = 0x5A;
+ HAL_EepromParams_t eepromParams = {
+ .address = (FLASH_BOOTLOADER_PAGES + FLASH_EEPROM_PAGES) * IFLASH_BYTES_PER_PAGE -
+ BOOTLOADER_FLAG_FLASH_OFFSET,
+ .data = &bootloaderFlag,
+ .length = 1
+ };
+ uint16_t page;
+
+#if defined(AT91SAM7X256) || defined(AT91SAM3S4C)
+ // Acknowledge the request
+ sendZLP();
+#endif
+
+ detachReceived = true;
+
+ halFlashPrepareForWrite();
+ page = halFlashPreparePage(&eepromParams);
+ halFlashWritePage(page, false);
+ halFlashRestoreFromWrite();
+
+ HAL_RegisterEndOfBusResetHandler(dfuResetAction);
+}
+/**************************************************************************//**
+\brief DFU get status request handler.
+******************************************************************************/
+static void dfuGetStatus(void)
+{
+ uint8_t i = 2;
+
+ dfuResponse.getStatusResponse.bStatus = DFU_STATUS_OK;
+ while(i--)
+ dfuResponse.getStatusResponse.bPollTimeout[i] = DFU_STATUS_MAX_POLL_TIMEOUT;
+ dfuResponse.getStatusResponse.bState = detachReceived;
+ dfuResponse.getStatusResponse.iString = DFU_STATUS_NO_STRING;
+
+ HAL_UsbWrite(0, (void *)&dfuResponse, sizeof(DfuGetStatusResponse_t), NULL, NULL);
+}
+
+/**************************************************************************//**
+\brief DFU get state request handler.
+******************************************************************************/
+static void dfuGetState(void)
+{
+ dfuResponse.getStateResponse.bState = detachReceived;
+
+ HAL_UsbWrite(0, (void *)&dfuResponse, sizeof(DfuGetStateResponse_t), NULL, NULL);
+}
+/**************************************************************************//**
+\brief Device firmware upgrade request handler.
+\param[in]
+ data - pointer to host's request.
+******************************************************************************/
+void dfuRequestHandler(uint8_t *data)
+{
+ UsbDfuRequest_t *pRequest = NULL;
+
+ pRequest = (UsbDfuRequest_t *)data;
+ if (NULL == pRequest)
+ return;
+
+ // Check request code
+ switch (pRequest->request.bRequest)
+ {
+ case DFU_DETACH:
+ dfuDetach();
+ break;
+ case DFU_GETSTATUS:
+ dfuGetStatus();
+ break;
+ case DFU_GETSTATE:
+ dfuGetState();
+ break;
+ default:
+ HAL_Stall(0);
+ break;
+ }
+}
+
+//eof dfuProtocol.c
diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/MSD/include/abstractMemory.h b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/MSD/include/abstractMemory.h
new file mode 100644
index 00000000..2eab5f00
--- /dev/null
+++ b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/MSD/include/abstractMemory.h
@@ -0,0 +1,83 @@
+/****************************************************************************//**
+ \file abstactMemory.h
+
+ \brief Declaration of abstract memory commands.
+
+ \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:
+ 29/08/11 N. Fomin - Created
+*******************************************************************************/
+#ifndef _ABSTRACT_MEMORY_H
+#define _ABSTRACT_MEMORY_H
+
+/******************************************************************************
+ Includes section
+******************************************************************************/
+#include <types.h>
+#include <hsmci.h>
+
+/******************************************************************************
+ Types section
+******************************************************************************/
+typedef enum
+{
+ memorySuccessStatus,
+ memoryErrorStatus
+} MemoryStatus_t;
+
+/******************************************************************************
+ Prototypes section
+******************************************************************************/
+/**************************************************************************//**
+\brief Writes data to memory at "address".
+\param[in]
+ descriptor - pointer to hsmci descriptor;
+ address - address of blocks to write.
+ callback - pointer to function to nofity upper layer about end of write
+ procedure.
+\return
+ status of write procedure.
+******************************************************************************/
+MemoryStatus_t absMemWrite(HAL_HsmciDescriptor_t *descriptor, uint32_t address, void (*callback)(MemoryStatus_t));
+
+/**************************************************************************//**
+\brief Reads data from memory at "address".
+\param[in]
+ descriptor - pointer to hsmci descriptor;
+ address - address of blocks to read.
+ callback - pointer to function to nofity upper layer about end of read
+ procedure.
+\return
+ status of read procedure.
+******************************************************************************/
+MemoryStatus_t absMemRead(HAL_HsmciDescriptor_t *descriptor, uint32_t address, void (*callback)(MemoryStatus_t));
+
+/**************************************************************************//**
+\brief Performs memory initialization.
+\param[in]
+ descriptor - pointer to hsmci descriptor.
+\return
+ status of initialization procedure.
+******************************************************************************/
+MemoryStatus_t absMemInit(HAL_HsmciDescriptor_t *descriptor);
+
+/**************************************************************************//**
+\brief Reads memory capacity.
+\param[in]
+ descriptor - pointer to hsmci descriptor.
+\param[out]
+ lastBlockNumber - number of last accessible block of memory.
+\return
+ status of read capacity procedure.
+******************************************************************************/
+MemoryStatus_t absMemCapacity(HAL_HsmciDescriptor_t *descriptor, uint32_t *lastBlockNumber);
+
+#endif /* _ABSTRACT_MEMORY_H */
+// eof abstactMemory.h
diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/MSD/include/mem.h b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/MSD/include/mem.h
new file mode 100644
index 00000000..0197f13a
--- /dev/null
+++ b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/MSD/include/mem.h
@@ -0,0 +1,106 @@
+/****************************************************************************//**
+ \file mem.h
+
+ \brief Declaration of memory commands.
+
+ \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:
+ 29/08/11 N. Fomin - Created
+*******************************************************************************/
+#ifndef _MEM_H
+#define _MEM_H
+
+/******************************************************************************
+ Includes section
+******************************************************************************/
+#include <types.h>
+#include <hsmci.h>
+
+/******************************************************************************
+ Define(s) section
+******************************************************************************/
+// block length
+#define STANDARD_BLOCK_LENGTH 512
+
+/******************************************************************************
+ Types section
+******************************************************************************/
+typedef enum
+{
+ memSuccess,
+ hsmciError,
+ voltageError,
+ commandError,
+ initTimeoutError,
+ stateError,
+ hsmciReadError,
+ hsmciWriteError,
+ setMaxFreqError
+} MemStatus_t;
+
+typedef struct
+{
+ uint32_t lastLogicalBlock;
+ uint32_t logicalBlockLength;
+} MemCapacityInfo_t;
+
+/******************************************************************************
+ Prototypes section
+******************************************************************************/
+/**************************************************************************//**
+\brief Writes one data block to memory at "address".
+\param[in]
+ descriptor - pointer to hsmci descriptor;
+ address - address of block to write.
+\return
+ status of write procedure.
+******************************************************************************/
+MemStatus_t memWriteBlock(HAL_HsmciDescriptor_t *descriptor, uint32_t address, void (*callback)(MemStatus_t));
+
+/**************************************************************************//**
+\brief Reads one data block from memory at "address".
+\param[in]
+ descriptor - pointer to hsmci descriptor;
+ address - address of block to read.
+\return
+ status of read procedure.
+******************************************************************************/
+MemStatus_t memReadBlock(HAL_HsmciDescriptor_t *descriptor, uint32_t address, void (*callback)(MemStatus_t));
+
+/**************************************************************************//**
+\brief Performs memory initialization.
+\param[in]
+ commandDescr - pointer to hsmci command descriptor.
+\return
+ status of initialization procedure.
+******************************************************************************/
+MemStatus_t memInit(HAL_HsmciDescriptor_t *commandDescr);
+
+/**************************************************************************//**
+\brief Reads memory capacity.
+\param[in]
+ descriptor - pointer to hsmci descriptor.
+\param[out]
+ capInfo - pointer to memory capacity structure.
+\return
+ status of read capacity procedure.
+******************************************************************************/
+MemStatus_t memGetCapacityInfo(HAL_HsmciDescriptor_t *descriptor, MemCapacityInfo_t *capInfo);
+
+/**************************************************************************//**
+\brief Checks if memory is ready for any data transfer.
+\return
+ false - memory is busy;
+ true - memory is ready.
+******************************************************************************/
+bool memIsBusy(void);
+
+#endif /* _MEM_H */
+// eof mem.h
diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/MSD/include/mscProtocol.h b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/MSD/include/mscProtocol.h
new file mode 100644
index 00000000..aa5964ad
--- /dev/null
+++ b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/MSD/include/mscProtocol.h
@@ -0,0 +1,79 @@
+/****************************************************************************//**
+ \file mscProtocol.h
+
+ \brief Declaration of mass storage device protocol command.
+
+ \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:
+ 29/08/11 N. Fomin - Created
+*******************************************************************************/
+#ifndef _MSCPROTOCOL_H
+#define _MSCPROTOCOL_H
+
+/******************************************************************************
+ Includes section
+******************************************************************************/
+#include <types.h>
+#include <usbSetupProcess.h>
+
+/******************************************************************************
+ Define(s) section
+******************************************************************************/
+// data size in request structure
+#define MSC_REQUEST_DATA_SIZE 1
+
+// request codes for mass storage class
+#define BULK_ONLY_MASS_STORAGE_RESET 0xFF
+#define GET_MAX_LUN 0xFE
+// maximum size of CBW data
+#define CBW_DATA_SIZE 16
+
+/******************************************************************************
+ Types section
+******************************************************************************/
+BEGIN_PACK
+typedef struct PACK
+{
+ UsbRequest_t request;
+ uint8_t bData[MSC_REQUEST_DATA_SIZE];
+} UsbMscRequest_t;
+// MSC command block wrapper (CBW)
+typedef struct PACK
+{
+ uint32_t dCBWSignature;
+ uint32_t cDBWTag;
+ uint32_t dCBWDataTransferLength;
+ uint8_t bmCBWFlags;
+ uint8_t bCBWLUN;
+ uint8_t bCBWCBLength;
+ uint8_t CBWCB[CBW_DATA_SIZE];
+} MscCBW_t;
+// MSC command status wrapper (CSW)
+typedef struct PACK
+{
+ uint32_t dCSWSignature;
+ uint32_t cDSWTag;
+ uint32_t dCSWDataResidue;
+ uint8_t bCSWStatus;
+} MscCSW_t;
+END_PACK
+
+/******************************************************************************
+ Prototypes section
+******************************************************************************/
+/**************************************************************************//**
+\brief Mass storage device request handler.
+\param[in]
+ data - pointer to host's request.
+******************************************************************************/
+void msdRequestHandler(uint8_t *data);
+
+#endif /* _MSCPROTOCOL_H */
+// eof msdProtocol.h \ No newline at end of file
diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/MSD/include/scsiProtocol.h b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/MSD/include/scsiProtocol.h
new file mode 100644
index 00000000..6a10b4dc
--- /dev/null
+++ b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/MSD/include/scsiProtocol.h
@@ -0,0 +1,114 @@
+/****************************************************************************//**
+ \file scsiProtocol.h
+
+ \brief Declaration of scsi protocol commands.
+
+ \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:
+ 29/08/11 N. Fomin - Created
+*******************************************************************************/
+#ifndef _SCSIPROTOCOL_H
+#define _SCSIPROTOCOL_H
+
+/******************************************************************************
+ Includes section
+******************************************************************************/
+#include <types.h>
+
+/******************************************************************************
+ Define(s) section
+******************************************************************************/
+// Maximum response length for scsi command
+#define MAX_COMMAND_RESPONSE_LENGTH 36
+
+/******************************************************************************
+ Prototypes section
+******************************************************************************/
+/**************************************************************************//**
+\brief Checks if received scsi command is supported.
+\param[in]
+ data - pointer to received command with parameters.
+\return
+ false - command is not supported;
+ true - command is supported.
+******************************************************************************/
+bool scsiIsValidCommand(uint8_t *data);
+
+/**************************************************************************//**
+\brief Checks if any response or data transfer needed for received
+ scsi command.
+\param[in]
+ command - received command.
+\return
+ false - response is not needed;
+ true - response is needed.
+******************************************************************************/
+bool scsiIsDataInOutPhaseNeeded(uint8_t *data);
+
+/**************************************************************************//**
+\brief Checks if command is read or write command.
+\param[in]
+ command - received command.
+\return
+ false - command is not read/write command;
+ true - command is read/write command.
+******************************************************************************/
+bool scsiIsReadWriteCommand(uint8_t *data);
+
+/**************************************************************************//**
+\brief Checks if command is read command.
+\param[in]
+ command - received command.
+\return
+ false - command is not read command;
+ true - command is read command.
+******************************************************************************/
+bool scsiIsReadCommand(uint8_t *data);
+
+/**************************************************************************//**
+\brief Blocks for read/write command.
+\param[in]
+ data - pointer to received command with parameters.
+\return
+ number of blocks to read or write from memory.
+******************************************************************************/
+uint16_t scsiBlocksAmount(uint8_t *data);
+
+/**************************************************************************//**
+\brief Response for scsi command.
+\param[in]
+ command - received command.
+\param[out]
+ buffer - buffer with scsi command response.
+\return
+ length of response
+******************************************************************************/
+uint8_t scsiGetCommandResponse(uint8_t *data, uint8_t *buffer);
+
+/**************************************************************************//**
+\brief Sets number of last available memory block for scsi response.
+\param[in]
+ lastBlock - received command.
+\param[out]
+ buffer - number of last available memory block
+******************************************************************************/
+void scsiSetCapacity(uint32_t lastBlock);
+
+/**************************************************************************//**
+\brief Block address for read/write command.
+\param[in]
+ data - pointer to received command with parameters.
+\return
+ block address for read or write from memory.
+******************************************************************************/
+uint32_t scsiGetBlockAddress(uint8_t *data);
+
+#endif /* _SCSIPROTOCOL_H */
+// eof scsiProtocol.h
diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/MSD/src/abstractMemory.c b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/MSD/src/abstractMemory.c
new file mode 100644
index 00000000..dc11be63
--- /dev/null
+++ b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/MSD/src/abstractMemory.c
@@ -0,0 +1,225 @@
+/****************************************************************************//**
+ \files abstractMemory.c
+
+ \brief Implementation of amstract memory commands.
+
+ \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:
+ 30/08/11 N. Fomin - Created
+*******************************************************************************/
+/******************************************************************************
+ Includes section
+******************************************************************************/
+#include <mem.h>
+#include <abstractMemory.h>
+
+/******************************************************************************
+ Define(s) section
+******************************************************************************/
+#define RETRY_COUNT 5
+
+/******************************************************************************
+ External global variables section
+******************************************************************************/
+/******************************************************************************
+ Types section
+******************************************************************************/
+typedef struct
+{
+ uint16_t transferLength;
+ uint16_t blocksToTransfer;
+ uint32_t logicalBlockAddress;
+ HAL_HsmciDescriptor_t *hsmciDescriptor;
+ uint8_t *dataBuffer;
+} AbsMemInternal_t;
+
+/******************************************************************************
+ Global variables section
+******************************************************************************/
+static void (*absMemCallback)(MemoryStatus_t status);
+static AbsMemInternal_t apsMemInternal;
+
+/******************************************************************************
+ Implementations section
+******************************************************************************/
+/**************************************************************************//**
+\brief Current memory read callback.
+\param[in]
+ status - status of read operation.
+******************************************************************************/
+void absMemReadBlockCallback(MemStatus_t status)
+{
+ uint8_t i = RETRY_COUNT;
+ apsMemInternal.blocksToTransfer--;
+ uint16_t blocksRemaining = apsMemInternal.transferLength - apsMemInternal.blocksToTransfer;
+ HAL_HsmciDescriptor_t *descriptor = apsMemInternal.hsmciDescriptor;
+
+ if (memSuccess != status)
+ absMemCallback(memoryErrorStatus);
+ if (0 == apsMemInternal.blocksToTransfer)
+ {
+ descriptor->dataTransferDescriptor->buffer = apsMemInternal.dataBuffer;
+ absMemCallback(memorySuccessStatus);
+ return;
+ }
+
+ descriptor->dataTransferDescriptor->buffer += blocksRemaining * STANDARD_BLOCK_LENGTH;
+
+ while(i--)
+ {
+ if (memSuccess == memReadBlock(descriptor, apsMemInternal.logicalBlockAddress + blocksRemaining, absMemReadBlockCallback))
+ break;
+ }
+ if (0 == i)
+ absMemCallback(memoryErrorStatus);
+}
+
+/**************************************************************************//**
+\brief Current memory write callback.
+\param[in]
+ status - status of write operation.
+******************************************************************************/
+void absMemWriteBlockCallback(MemStatus_t status)
+{
+ uint8_t i = RETRY_COUNT;
+ apsMemInternal.blocksToTransfer--;
+ uint16_t blocksRemaining = apsMemInternal.transferLength - apsMemInternal.blocksToTransfer;
+ HAL_HsmciDescriptor_t *descriptor = apsMemInternal.hsmciDescriptor;
+
+ if (memSuccess != status)
+ absMemCallback(memoryErrorStatus);
+ if (0 == apsMemInternal.blocksToTransfer)
+ {
+ descriptor->dataTransferDescriptor->buffer = apsMemInternal.dataBuffer;
+ absMemCallback(memorySuccessStatus);
+ return;
+ }
+
+ descriptor->dataTransferDescriptor->buffer += blocksRemaining * STANDARD_BLOCK_LENGTH;
+
+ while(i--)
+ {
+ if (memSuccess == memWriteBlock(descriptor, apsMemInternal.logicalBlockAddress + blocksRemaining, absMemWriteBlockCallback))
+ break;
+ }
+ if (0 == i)
+ absMemCallback(memoryErrorStatus);
+}
+
+/**************************************************************************//**
+\brief Performs memory initialization.
+\param[in]
+ descriptor - pointer to hsmci descriptor.
+\return
+ status of initialization procedure.
+******************************************************************************/
+MemoryStatus_t absMemInit(HAL_HsmciDescriptor_t *descriptor)
+{
+ if (memSuccess != memInit(descriptor))
+ return memoryErrorStatus;
+
+ return memorySuccessStatus;
+}
+
+/**************************************************************************//**
+\brief Reads memory capacity.
+\param[in]
+ descriptor - pointer to hsmci descriptor.
+\param[out]
+ lastBlockNumber - number of last accessible block of memory.
+\return
+ status of read capacity procedure.
+******************************************************************************/
+MemoryStatus_t absMemCapacity(HAL_HsmciDescriptor_t *descriptor, uint32_t *lastBlockNumber)
+{
+ MemCapacityInfo_t capInfo;
+ uint8_t i = RETRY_COUNT;
+ MemStatus_t status;
+
+ while(i--)
+ {
+ status = memGetCapacityInfo(descriptor, &capInfo);
+ if (memSuccess == status)
+ {
+ *lastBlockNumber = capInfo.lastLogicalBlock;
+ return memorySuccessStatus;
+ }
+ }
+
+ return memoryErrorStatus;
+}
+
+/**************************************************************************//**
+\brief Writes data to memory at "address".
+\param[in]
+ descriptor - pointer to hsmci descriptor;
+ address - address of blocks to write.
+ callback - pointer to function to nofity upper layer about end of write
+ procedure.
+\return
+ status of write procedure.
+******************************************************************************/
+MemoryStatus_t absMemWrite(HAL_HsmciDescriptor_t *descriptor, uint32_t address, void (*callback)(MemoryStatus_t))
+{
+ HAL_HsmciDataTransferDescriptor_t *dataDescr = descriptor->dataTransferDescriptor;
+ uint8_t i;
+ absMemCallback = callback;
+
+ apsMemInternal.logicalBlockAddress = address;
+ apsMemInternal.transferLength = dataDescr->length / STANDARD_BLOCK_LENGTH;
+ apsMemInternal.blocksToTransfer = apsMemInternal.transferLength;
+ apsMemInternal.dataBuffer = descriptor->dataTransferDescriptor->buffer;
+
+ dataDescr->length = STANDARD_BLOCK_LENGTH;
+
+ i = RETRY_COUNT;
+ while(i--)
+ {
+ if (memSuccess == memWriteBlock(descriptor, address, absMemWriteBlockCallback))
+ return memorySuccessStatus;
+ }
+
+ return memoryErrorStatus;
+}
+
+/**************************************************************************//**
+\brief Reads data from memory at "address".
+\param[in]
+ descriptor - pointer to hsmci descriptor;
+ address - address of blocks to read.
+ callback - pointer to function to nofity upper layer about end of read
+ procedure.
+\return
+ status of read procedure.
+******************************************************************************/
+MemoryStatus_t absMemRead(HAL_HsmciDescriptor_t *descriptor, uint32_t address, void (*callback)(MemoryStatus_t))
+{
+ HAL_HsmciDataTransferDescriptor_t *dataDescr = descriptor->dataTransferDescriptor;
+ uint8_t i;
+ absMemCallback = callback;
+
+ apsMemInternal.logicalBlockAddress = address;
+ apsMemInternal.transferLength = dataDescr->length / STANDARD_BLOCK_LENGTH;
+ apsMemInternal.blocksToTransfer = apsMemInternal.transferLength;
+ apsMemInternal.dataBuffer = descriptor->dataTransferDescriptor->buffer;
+
+ dataDescr->length = STANDARD_BLOCK_LENGTH;
+
+ i = RETRY_COUNT;
+ while(i--)
+ {
+ if (memSuccess == memReadBlock(descriptor, address, absMemReadBlockCallback))
+ return memorySuccessStatus;
+ }
+
+ return memoryErrorStatus;
+}
+
+//eof abstractMemory.c
diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/MSD/src/massStorageDevice.c b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/MSD/src/massStorageDevice.c
new file mode 100644
index 00000000..94c36c42
--- /dev/null
+++ b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/MSD/src/massStorageDevice.c
@@ -0,0 +1,327 @@
+/****************************************************************************//**
+ \file massStorageDevice.c
+
+ \brief Implementation of mass storage API.
+
+ \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:
+ 29/08/11 N. Fomin - Created
+*******************************************************************************/
+/******************************************************************************
+ Includes section
+******************************************************************************/
+#include <mscProtocol.h>
+#include <usbEnumeration.h>
+#include <massStorageDevice.h>
+#include <scsiProtocol.h>
+#include <abstractMemory.h>
+#include <usbDescriptors.h>
+#include <mem.h>
+
+/******************************************************************************
+ Defines section
+******************************************************************************/
+#define CBW_SIZE 31
+#define CBW_SIGNATURE 0x43425355
+
+#define CSW_SIZE 13
+#define CSW_COMMAND_FAILED_STATUS 1
+#define CSW_COMMAND_SUCCESS_STATUS 0
+
+/******************************************************************************
+ Types section
+******************************************************************************/
+typedef enum
+{
+ MSD_COMMAND_TRANSPORT,
+ MSD_SCSI_ANSWER,
+ MSD_DATA_INOUT,
+ MSD_STATUS_TRANSPORT
+} MsdState_t;
+
+typedef struct
+{
+ uint32_t bufferOffset;
+ uint16_t buffersToTransfer;
+ uint32_t blockAddress;
+} MsdReadWriteControl_t;
+
+/******************************************************************************
+ Prototypes section
+******************************************************************************/
+static void msdBufferReadCallback(MemoryStatus_t status);
+static void msdBufferWriteCallback(MemoryStatus_t status);
+
+/******************************************************************************
+ External global variables section
+******************************************************************************/
+static UsbMscRequest_t request;
+
+/******************************************************************************
+ Global variables section
+******************************************************************************/
+// pointer to application hsmci descriptor
+static HAL_HsmciDescriptor_t msdDescr;
+HAL_HsmciDescriptor_t *msdPointDescr;
+static HAL_HsmciCommandDescriptor_t commandDescr;
+static HAL_HsmciDataTransferDescriptor_t dataTransferDescr;
+static MsdReadWriteControl_t rwControl;
+static MscCSW_t csw;
+static MsdState_t msdState;
+static MSD_Callback_t msdCallback = NULL;
+
+void msdRcvCallback(void *pArg, uint8_t status, uint16_t transferred, uint16_t remaining);
+
+/******************************************************************************
+ Implementations section
+******************************************************************************/
+/**************************************************************************//**
+\brief Transmitting callback of usb.
+\param[in]
+ pArg - pointer to some data;
+ status - result of the USB transfer.;
+ transferred - how much data are transferred;
+ remaining - how much data are not transferred.
+******************************************************************************/
+void msdTmtCallback(void *pArg, uint8_t status, uint16_t transferred, uint16_t remaining)
+{
+ (void)pArg;
+ (void)status;
+ (void)remaining;
+ (void)transferred;
+
+ if (MSD_DATA_INOUT == msdState)
+ {
+ rwControl.buffersToTransfer--;
+ rwControl.blockAddress += msdDescr.dataTransferDescriptor->length / STANDARD_BLOCK_LENGTH;
+ if (0 == rwControl.buffersToTransfer)
+ {
+ csw.bCSWStatus = CSW_COMMAND_SUCCESS_STATUS;
+ msdState = MSD_STATUS_TRANSPORT;
+ memcpy(msdDescr.dataTransferDescriptor->buffer, (uint8_t*)&csw, CSW_SIZE);
+ HAL_UsbWrite(MSD_TRANSMIT_PIPE, msdDescr.dataTransferDescriptor->buffer, CSW_SIZE, msdTmtCallback, NULL);
+ return;
+ }
+ else
+ if (memorySuccessStatus != absMemRead(&msdDescr, rwControl.blockAddress, msdBufferReadCallback))
+ msdCallback(MSD_READ_ERROR);
+
+ }
+ if (MSD_SCSI_ANSWER == msdState)
+ {
+ csw.bCSWStatus = CSW_COMMAND_SUCCESS_STATUS;
+ msdState = MSD_STATUS_TRANSPORT;
+ memcpy(msdDescr.dataTransferDescriptor->buffer, (uint8_t*)&csw, CSW_SIZE);
+ HAL_UsbWrite(MSD_TRANSMIT_PIPE, msdDescr.dataTransferDescriptor->buffer, CSW_SIZE, msdTmtCallback, NULL);
+ return;
+ }
+ if (MSD_STATUS_TRANSPORT == msdState)
+ {
+ if (msdCallback)
+ msdCallback(MSD_STATUS_SUCCESS);
+ msdState = MSD_COMMAND_TRANSPORT;
+ HAL_UsbRead(MSD_RECEIVE_PIPE, msdDescr.dataTransferDescriptor->buffer, CBW_SIZE, msdRcvCallback, NULL);
+ return;
+ }
+}
+
+/**************************************************************************//**
+\brief Receiving callback of usb.
+\param[in]
+ pArg - pointer to some data;
+ status - result of the USB transfer.;
+ transferred - how much data are transferred;
+ remaining - how much data are not transferred.
+******************************************************************************/
+void msdRcvCallback(void *pArg, uint8_t status, uint16_t transferred, uint16_t remaining)
+{
+ bool validAndMeaningful = true;
+ MscCBW_t *cbw = (MscCBW_t *)(msdDescr.dataTransferDescriptor->buffer);
+ uint8_t length;
+
+ (void)pArg;
+ (void)status;
+ (void)remaining;
+
+ if (MSD_COMMAND_TRANSPORT == msdState)
+ {
+ /* check that CBW is valid */
+ if ((CBW_SIZE != transferred) || (CBW_SIGNATURE != cbw->dCBWSignature))
+ validAndMeaningful = false;
+ if (!validAndMeaningful)
+ {
+ HAL_Stall(ADDRESS_MSC_BULKIN_PIPE & 0x03);
+ return;
+ }
+ /* check that CBW is meaningful */
+ if ((cbw->bCBWLUN > 0x0F) || (cbw->bCBWCBLength == 0) || (cbw->bCBWCBLength > 0x10) || (cbw->bmCBWFlags & 0x7F))
+ validAndMeaningful = false;
+ if (!validAndMeaningful)
+ return;
+ /* fill csw with parameters from cbw */
+ csw.cDSWTag = cbw->cDBWTag;
+ csw.dCSWSignature = CBW_SIGNATURE;
+ /* check that command is valid */
+ if (!scsiIsValidCommand(cbw->CBWCB))
+ {
+ csw.bCSWStatus = CSW_COMMAND_FAILED_STATUS;
+ msdState = MSD_STATUS_TRANSPORT;
+ memcpy(msdDescr.dataTransferDescriptor->buffer, (uint8_t*)&csw, CSW_SIZE);
+ HAL_UsbWrite(MSD_TRANSMIT_PIPE, msdDescr.dataTransferDescriptor->buffer, CSW_SIZE, msdTmtCallback, NULL);
+ return;
+ }
+ /* check that no data in-out phase is needed */
+ if (!scsiIsDataInOutPhaseNeeded(cbw->CBWCB))
+ {
+ csw.bCSWStatus = CSW_COMMAND_SUCCESS_STATUS;
+ msdState = MSD_STATUS_TRANSPORT;
+ memcpy(msdDescr.dataTransferDescriptor->buffer, (uint8_t*)&csw, CSW_SIZE);
+ HAL_UsbWrite(MSD_TRANSMIT_PIPE, msdDescr.dataTransferDescriptor->buffer, CSW_SIZE, msdTmtCallback, NULL);
+ return;
+ }
+ /* check that command is no read-write command */
+ if (!scsiIsReadWriteCommand(cbw->CBWCB))
+ {
+ csw.bCSWStatus = CSW_COMMAND_SUCCESS_STATUS;
+ msdState = MSD_SCSI_ANSWER;
+ length = scsiGetCommandResponse(cbw->CBWCB, msdDescr.dataTransferDescriptor->buffer);
+ HAL_UsbWrite(MSD_TRANSMIT_PIPE, msdDescr.dataTransferDescriptor->buffer, length, msdTmtCallback, NULL);
+ return;
+ }
+ /* check that command is read command */
+ rwControl.buffersToTransfer = scsiBlocksAmount(cbw->CBWCB) * (msdDescr.dataTransferDescriptor->length / STANDARD_BLOCK_LENGTH);
+ rwControl.blockAddress = scsiGetBlockAddress(cbw->CBWCB);
+ if (scsiIsReadCommand(cbw->CBWCB))
+ {
+ if (memorySuccessStatus != absMemRead(&msdDescr, rwControl.blockAddress, msdBufferReadCallback))
+ msdCallback(MSD_READ_ERROR);
+ }
+ else
+ HAL_UsbRead(MSD_RECEIVE_PIPE, msdDescr.dataTransferDescriptor->buffer,
+ BULK_SIZE, msdRcvCallback, NULL);
+ msdState = MSD_DATA_INOUT;
+ return;
+ }
+ if (MSD_DATA_INOUT == msdState)
+ {
+ /* increase internal write buffer offset*/
+ rwControl.bufferOffset += transferred;
+ /* if buffer is full perform write to flash */
+ if (rwControl.bufferOffset == msdDescr.dataTransferDescriptor->length)
+ {
+ if (memorySuccessStatus != absMemWrite(&msdDescr, rwControl.blockAddress, msdBufferWriteCallback))
+ msdCallback(MSD_WRITE_ERROR);
+ /* wait for hsmci bus becomes free */
+ rwControl.bufferOffset = 0;
+ rwControl.buffersToTransfer--;
+ rwControl.blockAddress += msdDescr.dataTransferDescriptor->length / STANDARD_BLOCK_LENGTH;
+ return;
+ }
+ if (0 != rwControl.buffersToTransfer)
+ HAL_UsbRead(MSD_RECEIVE_PIPE, msdDescr.dataTransferDescriptor->buffer + rwControl.bufferOffset,
+ BULK_SIZE, msdRcvCallback, NULL);
+
+ }
+}
+
+/**************************************************************************//**
+\brief Opens mass storage device.
+\param[in]
+ callback - pointer to function to notify about MSD errors and transactions;
+ responseBuffer - pointer to hsmci command response buffer; it should have
+ a size of four;
+ buffer - pointer to buffer for hsmci data transfer; it should be
+ a multiplier of 512;
+ length - length of buffer for data transfer.
+******************************************************************************/
+void MSD_Open(MSD_Callback_t callback, uint32_t *responseBuffer, uint8_t *buffer, uint32_t length)
+{
+ uint32_t lastBlock;
+
+ msdCallback = callback;
+
+ msdDescr.dataTransferDescriptor = &dataTransferDescr;
+ msdDescr.commandDescriptor = &commandDescr;
+ msdDescr.dataTransferDescriptor->buffer = buffer;
+ msdDescr.dataTransferDescriptor->length = length;
+ msdDescr.commandDescriptor->responseBuffer = responseBuffer;
+ msdDescr.dataTransferDescriptor->commandDescr = &commandDescr;
+
+ msdPointDescr = & msdDescr;
+
+ if (-1 == HAL_OpenHsmci(&msdDescr))
+ if (msdCallback)
+ msdCallback(MSD_INTERFACE_BUSY);
+
+ if (memorySuccessStatus != absMemInit(&msdDescr))
+ if (msdCallback)
+ msdCallback(MSD_MEMORY_INIT_ERROR);
+
+ if (memorySuccessStatus != absMemCapacity(&msdDescr, &lastBlock))
+ if (msdCallback)
+ msdCallback(MSD_READ_CAPACITY_ERROR);
+
+ scsiSetCapacity(lastBlock);
+
+ rwControl.bufferOffset = 0;
+ rwControl.buffersToTransfer = 0;
+ msdState = MSD_COMMAND_TRANSPORT;
+ csw.dCSWDataResidue = 0;
+
+ HAL_RegisterEndOfBusResetHandler(usbBusResetAction);
+ if (DEVICE_POWERED != HAL_GetState())
+ HAL_UsbInit((uint8_t *)&request);
+}
+
+/**************************************************************************//**
+\brief Closes mass storage device.
+******************************************************************************/
+void MSD_Close(void)
+{
+ if (-1 == HAL_CloseHsmci(&msdDescr))
+ if (msdCallback)
+ msdCallback(MSD_INTERFACE_BUSY);
+}
+
+/**************************************************************************//**
+\brief Memory read callback function.
+\param[in]
+ status - status of memory read procedure.
+******************************************************************************/
+static void msdBufferReadCallback(MemoryStatus_t status)
+{
+ if (memorySuccessStatus != status)
+ msdCallback(MSD_READ_ERROR);
+ HAL_UsbWrite(MSD_TRANSMIT_PIPE, msdDescr.dataTransferDescriptor->buffer,
+ msdDescr.dataTransferDescriptor->length, msdTmtCallback, NULL);
+}
+
+/**************************************************************************//**
+\brief Memory write callback function.
+\param[in]
+ status - status of memory write procedure.
+******************************************************************************/
+static void msdBufferWriteCallback(MemoryStatus_t status)
+{
+ if (memorySuccessStatus != status)
+ msdCallback(MSD_WRITE_ERROR);
+ if (0 == rwControl.buffersToTransfer)
+ {
+ csw.bCSWStatus = CSW_COMMAND_SUCCESS_STATUS;
+ msdState = MSD_STATUS_TRANSPORT;
+ memcpy(msdDescr.dataTransferDescriptor->buffer, (uint8_t*)&csw, CSW_SIZE);
+ HAL_UsbWrite(MSD_TRANSMIT_PIPE, msdDescr.dataTransferDescriptor->buffer, CSW_SIZE, msdTmtCallback, NULL);
+ }
+ else
+ HAL_UsbRead(MSD_RECEIVE_PIPE, msdDescr.dataTransferDescriptor->buffer,
+ BULK_SIZE, msdRcvCallback, NULL);
+}
+
+// eof massStorageDevice.c
diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/MSD/src/mmc.c b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/MSD/src/mmc.c
new file mode 100644
index 00000000..b512bd04
--- /dev/null
+++ b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/MSD/src/mmc.c
@@ -0,0 +1,618 @@
+/****************************************************************************//**
+ \files mmc.c
+
+ \brief Implementation of mmc protocol.
+
+ \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:
+ 30/08/11 N. Fomin - Created
+*******************************************************************************/
+/******************************************************************************
+ Includes section
+******************************************************************************/
+#include <mem.h>
+
+/******************************************************************************
+ Define(s) section
+******************************************************************************/
+// card voltage ranges
+#define OCR_VDD_16_17 (1 << 4)
+#define OCR_VDD_17_18 (1 << 5)
+#define OCR_VDD_18_19 (1 << 6)
+#define OCR_VDD_19_20 (1 << 7)
+#define OCR_VDD_20_21 (1 << 8)
+#define OCR_VDD_21_22 (1 << 9)
+#define OCR_VDD_22_23 (1 << 10)
+#define OCR_VDD_23_24 (1 << 11)
+#define OCR_VDD_24_25 (1 << 12)
+#define OCR_VDD_25_26 (1 << 13)
+#define OCR_VDD_26_27 (1 << 14)
+#define OCR_VDD_27_28 (1 << 15)
+#define OCR_VDD_28_29 (1 << 16)
+#define OCR_VDD_29_30 (1 << 17)
+#define OCR_VDD_30_31 (1 << 18)
+#define OCR_VDD_31_32 (1 << 19)
+#define OCR_VDD_32_33 (1 << 20)
+#define OCR_VDD_33_34 (1 << 21)
+#define OCR_VDD_34_35 (1 << 22)
+#define OCR_VDD_35_36 (1 << 23)
+// R1 response statuses
+#define STATUS_APP_CMD (1UL << 5)
+#define STATUS_SWITCH_ERROR (1UL << 7)
+#define STATUS_READY_FOR_DATA (1UL << 8)
+#define STATUS_IDLE (0UL << 9)
+#define STATUS_READY (1UL << 9)
+#define STATUS_IDENT (2UL << 9)
+#define STATUS_STBY (3UL << 9)
+#define STATUS_TRAN (4UL << 9)
+#define STATUS_DATA (5UL << 9)
+#define STATUS_RCV (6UL << 9)
+#define STATUS_PRG (7UL << 9)
+#define STATUS_DIS (8UL << 9)
+#define STATUS_STATE (0xFUL << 9)
+#define STATUS_ERASE_RESET (1UL << 13)
+#define STATUS_WP_ERASE_SKIP (1UL << 15)
+#define STATUS_CIDCSD_OVERWRITE (1UL << 16)
+#define STATUS_OVERRUN (1UL << 17)
+#define STATUS_UNERRUN (1UL << 18)
+#define STATUS_ERROR (1UL << 19)
+#define STATUS_CC_ERROR (1UL << 20)
+#define STATUS_CARD_ECC_FAILED (1UL << 21)
+#define STATUS_ILLEGAL_COMMAND (1UL << 22)
+#define STATUS_COM_CRC_ERROR (1UL << 23)
+#define STATUS_UN_LOCK_FAILED (1UL << 24)
+#define STATUS_CARD_IS_LOCKED (1UL << 25)
+#define STATUS_WP_VIOLATION (1UL << 26)
+#define STATUS_ERASE_PARAM (1UL << 27)
+#define STATUS_ERASE_SEQ_ERROR (1UL << 28)
+#define STATUS_BLOCK_LEN_ERROR (1UL << 29)
+#define STATUS_ADDRESS_MISALIGN (1UL << 30)
+#define STATUS_ADDR_OUT_OR_RANGE (1UL << 31)
+// R1 response sets
+#define ERROR_STATUS (STATUS_ADDR_OUT_OR_RANGE | STATUS_ADDRESS_MISALIGN | STATUS_BLOCK_LEN_ERROR | STATUS_ERASE_SEQ_ERROR | \
+ STATUS_ERASE_PARAM | STATUS_WP_VIOLATION | STATUS_CARD_IS_LOCKED | STATUS_UN_LOCK_FAILED | \
+ STATUS_COM_CRC_ERROR | STATUS_ILLEGAL_COMMAND | STATUS_CARD_ECC_FAILED | STATUS_CC_ERROR | STATUS_ERROR | \
+ STATUS_UNERRUN | STATUS_OVERRUN | STATUS_CIDCSD_OVERWRITE | STATUS_SWITCH_ERROR)
+// command arguments
+#define CMD0_IDLE_STATE_ARGUMENT 0
+#define CMD1_ACCESS_MODE_SECTOR (1UL << 30)
+#define CMD1_HOST_VOLTAGE_RANGE (OCR_VDD_27_28 | OCR_VDD_28_29 | OCR_VDD_29_30 | OCR_VDD_30_31 | \
+ OCR_VDD_31_32 | OCR_VDD_32_33 | OCR_VDD_33_34 | OCR_VDD_34_35 | \
+ OCR_VDD_35_36)
+#define CMD2_ARGUMENT 0
+#define CMD6_SET_4_LINE_BUS 0x03B70100
+#define CMD6_SET_HS_MODE 0x03B90100
+// relative card address
+#define REVALITE_CARD_ADDRESS (1 << 16)
+// command responses length
+#define NO_RESPONSE_LENGTH 0
+#define R1_RESPONSE_LENGTH 1
+#define R2_RESPONSE_LENGTH 4
+#define R3_RESPONSE_LENGTH 1
+// retry amount of card initialization
+#define RETRY_AMOUNT 10000
+// memory frequency masks for CDS memory register
+#define FREQ_UNITS_MASK 0x07
+#define FREQ_MULTIPLIER_MASK 0x78
+#define FREQ_MULTIPLIER_OFFSET 0x03
+// csd register definitions
+#define CSD_SPEC_VERS_FOUR 4
+
+/******************************************************************************
+ External global variables section
+******************************************************************************/
+/******************************************************************************
+ Types section
+******************************************************************************/
+typedef union
+{
+ uint32_t reg;
+ struct
+ {
+ uint32_t reserved1 : 5;
+ uint32_t appCmd : 1;
+ uint32_t urgentBkops : 1;
+ uint32_t switchError : 1;
+ uint32_t readyForData : 1;
+ uint32_t currentState : 4;
+ uint32_t eraseReset : 1;
+ uint32_t reserved2 : 1;
+ uint32_t wpEraseSkip : 1;
+ uint32_t cidCsdOverwrite : 1;
+ uint32_t overrun : 1;
+ uint32_t underrun : 1;
+ uint32_t error : 1;
+ uint32_t ccEror : 1;
+ uint32_t cardEccFailed : 1;
+ uint32_t illegalCommand : 1;
+ uint32_t comCrcError : 1;
+ uint32_t lockUnlockFailed : 1;
+ uint32_t cardIsLocked : 1;
+ uint32_t wpViolation : 1;
+ uint32_t eraseParam : 1;
+ uint32_t eraseSeqError : 1;
+ uint32_t blockLenError : 1;
+ uint32_t addressMisalign : 1;
+ uint32_t addressOutOfRange: 1;
+ };
+} MmcCardStatus_t;
+
+typedef union
+{
+ uint32_t reg;
+ struct
+ {
+ uint32_t reserverd1 : 7;
+ uint32_t voltage170_195: 1;
+ uint32_t voltage20_26 : 7;
+ uint32_t voltage27_36 : 9;
+ uint32_t reserved2 : 5;
+ uint32_t accessMode : 2;
+ uint32_t busy : 1;
+ };
+} MmcOcrRegister_t;
+
+typedef struct
+{
+ uint8_t tranSpeed;
+ uint8_t nsac;
+ uint8_t taac;
+ uint8_t reserved3 : 2;
+ uint8_t specVersion : 4;
+ uint8_t csdStructure : 2;
+ uint32_t cSizeDown : 10;
+ uint32_t reserved2 : 2;
+ uint32_t dsrImp : 1;
+ uint32_t readBlkMisalign : 1;
+ uint32_t writeBlkMisalign: 1;
+ uint32_t readBlPartial : 1;
+ uint32_t readBlLen : 4;
+ uint32_t ccc : 12;
+ uint32_t wpGroupSize : 5;
+ uint32_t eraseGroupMult : 5;
+ uint32_t eraseGroupSize : 5;
+ uint32_t cSizeMult : 3;
+ uint32_t vddWCurrMax : 3;
+ uint32_t vddWCurrMin : 3;
+ uint32_t vddRCurrMax : 3;
+ uint32_t vddRCurrMin : 3;
+ uint32_t cSizeUp : 2;
+ uint8_t notUsed : 1;
+ uint8_t crc : 7;
+ uint8_t ecc : 2;
+ uint8_t fileFormat : 2;
+ uint8_t tmpWriteProtect : 1;
+ uint8_t permWriteProtect : 1;
+ uint8_t copy : 1;
+ uint8_t fileFormatGroup : 1;
+ uint16_t contentPropApp : 1;
+ uint16_t reserved1 : 4;
+ uint16_t writeBlPartial : 1;
+ uint16_t writeBlLen : 4;
+ uint16_t r2wFactor : 3;
+ uint16_t defaultEcc : 2;
+ uint16_t wpGroupEnable : 1;
+} MmcCSDRegister_t;
+
+/******************************************************************************
+ Constants section
+******************************************************************************/
+static const uint32_t mmcFrequencyUnits[8] = {100, 1000, 10000, 100000, 0, 0, 0, 0};
+static const uint32_t mmcFrequencyMulptiplier[16] = {0, 10, 12, 13, 15, 20, 26, 30, 35, 40, 45, 52, 55, 60, 70, 80};
+
+/******************************************************************************
+ Prototypes section
+******************************************************************************/
+static bool memSendCommand(HAL_HsmciDescriptor_t *descriptor, uint32_t command, uint32_t argument, uint8_t respLength);
+static bool memCheckState(HAL_HsmciDescriptor_t *descriptor, uint16_t state);
+static bool setMaximumCommunicationFrequency(HAL_HsmciDescriptor_t *descriptor, uint8_t freqCode, bool hsMode);
+static MemStatus_t setBusWidthAndHsMode(HAL_HsmciDescriptor_t *descriptor, MmcCSDRegister_t *csdReg);
+static void (*absMemoryCallback)(MemStatus_t) = NULL;
+static HAL_HsmciDescriptor_t *memDescriptor = NULL;
+
+/******************************************************************************
+ Implementations section
+******************************************************************************/
+/**************************************************************************//**
+\brief HSMCI write callback.
+******************************************************************************/
+void memWriteCallback(void)
+{
+ MmcCardStatus_t *cardStatus;
+
+ cardStatus = (MmcCardStatus_t *)(memDescriptor->commandDescriptor->responseBuffer);
+ if (0 != (cardStatus->reg & ERROR_STATUS))
+ absMemoryCallback(hsmciWriteError);
+ absMemoryCallback(memSuccess);
+}
+
+/**************************************************************************//**
+\brief HSMCI read callback.
+******************************************************************************/
+void memReadCallback(void)
+{
+ MmcCardStatus_t *cardStatus;
+
+ cardStatus = (MmcCardStatus_t *)(memDescriptor->commandDescriptor->responseBuffer);
+ if (0 != (cardStatus->reg & ERROR_STATUS))
+ absMemoryCallback(hsmciReadError);
+ absMemoryCallback(memSuccess);
+}
+/**************************************************************************//**
+\brief Performs MMC memory initialization.
+\param[in]
+ commandDescr - pointer to hsmci command descriptor.
+\return
+ status of initialization procedure.
+******************************************************************************/
+MemStatus_t memInit(HAL_HsmciDescriptor_t *descriptor)
+{
+ uint16_t i = RETRY_AMOUNT;
+ MmcCardStatus_t *cardStatus;
+ MmcOcrRegister_t *ocrRegister;
+ MmcCSDRegister_t *csdReg;
+ HAL_HsmciCommandDescriptor_t *commandDescr = descriptor->commandDescriptor;
+ uint32_t sendOpCondResponse;
+ MemStatus_t status;
+
+ /* send first command - CMD0 with power init parameters */
+ if (!memSendCommand(descriptor, POWER_ON_INIT, CMD0_IDLE_STATE_ARGUMENT, NO_RESPONSE_LENGTH))
+ return hsmciError;
+ /* wait for hsmci bus becomes free */
+ while (!HAL_HsmciCheckReady());
+ /* send CMD0 command to go to idle mode */
+ if (!memSendCommand(descriptor, GO_IDLE_STATE, CMD0_IDLE_STATE_ARGUMENT, NO_RESPONSE_LENGTH))
+ return hsmciError;
+ /* wait for hsmci bus becomes free */
+ while (!HAL_HsmciCheckReady());
+ /* wait for internal initialization process */
+ for (; i > 0; i--)
+ {
+ /* send CMD1 command to check host and device voltage correlation */
+ if (!memSendCommand(descriptor, SEND_OP_COND, CMD1_HOST_VOLTAGE_RANGE | CMD1_ACCESS_MODE_SECTOR, R3_RESPONSE_LENGTH))
+ return hsmciError;
+ /* wait for hsmci bus becomes free */
+ while (!HAL_HsmciCheckReady());
+ ocrRegister = (MmcOcrRegister_t *)(commandDescr->responseBuffer);
+ if (!(ocrRegister->reg & CMD1_HOST_VOLTAGE_RANGE))
+ return voltageError;
+ if (0 == ocrRegister->busy)
+ continue;
+ break;
+ }
+ if (0 == i)
+ return initTimeoutError;
+ sendOpCondResponse = commandDescr->responseBuffer[0];
+ i = RETRY_AMOUNT;
+ while (i--)
+ {
+ /* send CMD2 command to get card CID number */
+ if (!memSendCommand(descriptor, ALL_SEND_CID, CMD2_ARGUMENT, R2_RESPONSE_LENGTH))
+ return hsmciError;
+ /* wait for hsmci bus becomes free */
+ while (!HAL_HsmciCheckReady());
+ if (sendOpCondResponse != commandDescr->responseBuffer[0])
+ break;
+ }
+ if (0 == i)
+ return stateError;
+ /* send CMD3 command to set card relative address */
+ if (!memSendCommand(descriptor, SEND_RELATIVE_ADDR, REVALITE_CARD_ADDRESS, R1_RESPONSE_LENGTH))
+ return hsmciError;
+ /* wait for hsmci bus becomes free */
+ while (!HAL_HsmciCheckReady());
+ cardStatus = (MmcCardStatus_t *)(commandDescr->responseBuffer);
+ if (0 != (cardStatus->reg & ERROR_STATUS))
+ return commandError;
+ if (!memCheckState(descriptor, STATUS_STBY))
+ return stateError;
+ /* send CMD9 command to read CSD register */
+ if (!memSendCommand(descriptor, SEND_CSD, REVALITE_CARD_ADDRESS, R2_RESPONSE_LENGTH))
+ return hsmciError;
+ /* wait for hsmci bus becomes free */
+ while (!HAL_HsmciCheckReady());
+ /* read allowed maximum communication frequency and set it */
+ csdReg = (MmcCSDRegister_t *)(commandDescr->responseBuffer);
+ status = setBusWidthAndHsMode(descriptor, csdReg);
+ if (status != memSuccess)
+ return setMaxFreqError;
+
+ return memSuccess;
+}
+
+/**************************************************************************//**
+\brief Reads MMC memory capacity.
+\param[in]
+ descriptor - pointer to hsmci descriptor.
+\param[out]
+ capInfo - pointer to memory capacity structure.
+\return
+ status of read capacity procedure.
+******************************************************************************/
+MemStatus_t memGetCapacityInfo(HAL_HsmciDescriptor_t *descriptor, MemCapacityInfo_t *capInfo)
+{
+ MmcCardStatus_t *cardStatus;
+ MmcCSDRegister_t *csdReg;
+ HAL_HsmciCommandDescriptor_t *commandDescr = descriptor->commandDescriptor;
+
+ /* send CMD13 command to discover current state */
+ if (!memSendCommand(descriptor, SEND_STATUS, REVALITE_CARD_ADDRESS, R1_RESPONSE_LENGTH))
+ return hsmciError;
+ /* wait for hsmci bus becomes free */
+ while (!HAL_HsmciCheckReady());
+
+ cardStatus = (MmcCardStatus_t *)(commandDescr->responseBuffer);
+ if (STATUS_TRAN == (cardStatus->reg & STATUS_TRAN))
+ {
+ /* send CMD7 command to switch to stand-by state*/
+ if (!memSendCommand(descriptor, SELECT_CARD, ~REVALITE_CARD_ADDRESS, R1_RESPONSE_LENGTH))
+ return hsmciError;
+ /* wait for hsmci bus becomes free */
+ while (!HAL_HsmciCheckReady());
+ cardStatus = (MmcCardStatus_t *)(commandDescr->responseBuffer);
+ if (0 != (cardStatus->reg & ERROR_STATUS))
+ return commandError;
+ if (!memCheckState(descriptor, STATUS_STBY))
+ return stateError;
+ }
+ /* send CMD9 command to read CSD register */
+ if (!memSendCommand(descriptor, SEND_CSD, REVALITE_CARD_ADDRESS, R2_RESPONSE_LENGTH))
+ return hsmciError;
+ /* wait for hsmci bus becomes free */
+ while (!HAL_HsmciCheckReady());
+
+ capInfo->logicalBlockLength = STANDARD_BLOCK_LENGTH;
+ csdReg = (MmcCSDRegister_t *)(commandDescr->responseBuffer);
+ capInfo->lastLogicalBlock = (1 << (csdReg->cSizeMult + 2)) * (csdReg->cSizeUp + 1 + (csdReg->cSizeDown << 2)) * ((1 << csdReg->readBlLen) / STANDARD_BLOCK_LENGTH) - 1;
+
+ if (!memCheckState(descriptor, STATUS_STBY))
+ return stateError;
+
+ /* send CMD7 command to switch to transfer state */
+ if (!memSendCommand(descriptor, SELECT_CARD, REVALITE_CARD_ADDRESS, R1_RESPONSE_LENGTH))
+ return hsmciError;
+ /* wait for hsmci bus becomes free */
+ while (!HAL_HsmciCheckReady());
+ cardStatus = (MmcCardStatus_t *)(commandDescr->responseBuffer);
+ if (0 != (cardStatus->reg & ERROR_STATUS))
+ return commandError;
+ if (!memCheckState(descriptor, STATUS_TRAN))
+ return stateError;
+
+ return memSuccess;
+}
+
+/**************************************************************************//**
+\brief Checks MMC memory state.
+\param[in]
+ descriptor - pointer to hsmci descriptor;
+ state - state in which MMC memory meant to be.
+\return
+ false - check failed;
+ true - check success.
+******************************************************************************/
+static bool memSendCommand(HAL_HsmciDescriptor_t *descriptor, uint32_t command, uint32_t argument, uint8_t respLength)
+{
+ descriptor->commandDescriptor->command = command;
+ descriptor->commandDescriptor->argument = argument;
+ descriptor->commandDescriptor->responseLength = respLength;
+
+ if (-1 == HAL_WriteHsmciCommand(descriptor))
+ return false;
+
+ return true;
+}
+
+/**************************************************************************//**
+\brief Sends MMC command.
+\param[in]
+ descriptor - pointer to hsmci descriptor;
+ command - command index and attributes;
+ argument - command argument;
+ respLength - command response length.
+\return
+ false - command sent failed;
+ true - command sent success.
+******************************************************************************/
+static bool memCheckState(HAL_HsmciDescriptor_t *descriptor, uint16_t state)
+{
+ MmcCardStatus_t *cardStatus;
+ /* send CMD13 command to discover current state */
+ if (!memSendCommand(descriptor, SEND_STATUS, REVALITE_CARD_ADDRESS, R1_RESPONSE_LENGTH))
+ return hsmciError;
+ /* wait for hsmci bus becomes free */
+ while (!HAL_HsmciCheckReady());
+ cardStatus = (MmcCardStatus_t *)(descriptor->commandDescriptor->responseBuffer);
+
+ return (cardStatus->reg & STATUS_STATE) == state;
+}
+
+/**************************************************************************//**
+\brief Writes one data block to MMC memory at "address".
+\param[in]
+ descriptor - pointer to hsmci descriptor;
+ address - address of block to write.
+\return
+ status of write procedure.
+******************************************************************************/
+MemStatus_t memWriteBlock(HAL_HsmciDescriptor_t *descriptor, uint32_t address, void (*callback)(MemStatus_t))
+{
+ HAL_HsmciCommandDescriptor_t *commandDescr = descriptor->commandDescriptor;
+ HAL_HsmciDataTransferDescriptor_t *dataDescr = descriptor->dataTransferDescriptor;
+
+ memDescriptor = descriptor;
+
+ if (!memCheckState(descriptor, STATUS_TRAN))
+ return stateError;
+
+ commandDescr->command = WRITE_BLOCK;
+ commandDescr->argument = address << 9;
+ commandDescr->responseLength = R1_RESPONSE_LENGTH;
+
+ dataDescr->direction = HSMCI_WRITE;
+ dataDescr->blockSize = STANDARD_BLOCK_LENGTH;
+ absMemoryCallback = callback;
+ descriptor->callback = memWriteCallback;
+
+ if (-1 == HAL_WriteHsmci(descriptor))
+ return hsmciWriteError;
+
+ return memSuccess;
+}
+
+/**************************************************************************//**
+\brief Reads one data block from MMC memory at "address".
+\param[in]
+ descriptor - pointer to hsmci descriptor;
+ address - address of block to read.
+\return
+ status of read procedure.
+******************************************************************************/
+MemStatus_t memReadBlock(HAL_HsmciDescriptor_t *descriptor, uint32_t address, void (*callback)(MemStatus_t))
+{
+ HAL_HsmciCommandDescriptor_t *commandDescr = descriptor->commandDescriptor;
+ HAL_HsmciDataTransferDescriptor_t *dataDescr = descriptor->dataTransferDescriptor;
+
+ memDescriptor = descriptor;
+
+ if (!memCheckState(descriptor, STATUS_TRAN))
+ return stateError;
+
+ commandDescr->command = READ_SINGLE_BLOCK;
+ commandDescr->argument = address << 9;
+ commandDescr->responseLength = R1_RESPONSE_LENGTH;
+
+ dataDescr->direction = HSMCI_READ;
+ dataDescr->blockSize = STANDARD_BLOCK_LENGTH;
+ absMemoryCallback = callback;
+ descriptor->callback = memReadCallback;
+
+ if (-1 == HAL_ReadHsmci(descriptor))
+ return hsmciReadError;
+
+ return memSuccess;
+}
+
+/**************************************************************************//**
+\brief Checks if MMC memory is ready for any data transfer.
+\return
+ false - memory is busy;
+ true - memory is ready.
+******************************************************************************/
+bool memIsBusy(void)
+{
+ return HAL_HsmciCheckReady();
+}
+
+/**************************************************************************//**
+\brief Sets maximum bus frequency for MMC memory.
+\param[in]
+ descriptor - pointer to hsmci descriptor;
+ freqCode - frequency code.
+\return
+ false - setting failed;
+ true - setting success.
+******************************************************************************/
+static bool setMaximumCommunicationFrequency(HAL_HsmciDescriptor_t *descriptor, uint8_t freqCode, bool hsMode)
+{
+ uint32_t freqUnit = mmcFrequencyUnits[freqCode & FREQ_UNITS_MASK];
+ uint32_t freqMult = mmcFrequencyMulptiplier[(freqCode & FREQ_MULTIPLIER_MASK) >> FREQ_MULTIPLIER_OFFSET];
+
+ descriptor->clockRate = freqUnit * freqMult * 100;
+ if (hsMode)
+ descriptor->clockRate *= 2;
+ if (-1 == HAL_SetHsmciSpeed(descriptor))
+ return false;
+
+ return true;
+}
+
+/**************************************************************************//**
+\brief Sets maximum 4-line dat bus and high speed mode if card supports it.
+\param[in]
+ descriptor - pointer to hsmci descriptor;
+ csdReg - pointer to csd register structure.
+\return
+ status of operation.
+******************************************************************************/
+static MemStatus_t setBusWidthAndHsMode(HAL_HsmciDescriptor_t *descriptor, MmcCSDRegister_t *csdReg)
+{
+ MmcCardStatus_t *cardStatus;
+ uint8_t specVersion = csdReg->specVersion;
+ uint8_t tranSpeed = csdReg->tranSpeed;
+ HAL_HsmciCommandDescriptor_t *commandDescr = descriptor->commandDescriptor;
+
+ /* send CMD7 command to switch to transfer state */
+ if (!memSendCommand(descriptor, SELECT_CARD, REVALITE_CARD_ADDRESS, R1_RESPONSE_LENGTH))
+ return hsmciError;
+ /* wait for hsmci bus becomes free */
+ while (!HAL_HsmciCheckReady());
+ cardStatus = (MmcCardStatus_t *)(commandDescr->responseBuffer);
+ if (0 != (cardStatus->reg & ERROR_STATUS))
+ return commandError;
+ if (!memCheckState(descriptor, STATUS_TRAN))
+ return stateError;
+
+ /* send CMD16 command to set card block length */
+ if (!memSendCommand(descriptor, SET_BLOCKLEN, STANDARD_BLOCK_LENGTH, R1_RESPONSE_LENGTH))
+ return hsmciError;
+ /* wait for hsmci bus becomes free */
+ while (!HAL_HsmciCheckReady());
+ cardStatus = (MmcCardStatus_t *)(commandDescr->responseBuffer);
+ if (0 != (cardStatus->reg & ERROR_STATUS))
+ return commandError;
+ if (!memCheckState(descriptor, STATUS_TRAN))
+ return stateError;
+
+ if (specVersion < CSD_SPEC_VERS_FOUR)
+ {
+ if (!setMaximumCommunicationFrequency(descriptor, tranSpeed, false))
+ return hsmciError;
+ else
+ return memSuccess;
+ }
+
+ /* send CMD6 command to switch to 4-line bus */
+ if (!memSendCommand(descriptor, SWITCH, CMD6_SET_4_LINE_BUS, R1_RESPONSE_LENGTH))
+ return hsmciError;
+ /* wait for hsmci bus becomes free */
+ while (!HAL_HsmciCheckReady());
+ cardStatus = (MmcCardStatus_t *)(commandDescr->responseBuffer);
+ if (0 != (cardStatus->reg & ERROR_STATUS))
+ return commandError;
+ if (!memCheckState(descriptor, STATUS_TRAN))
+ return stateError;
+
+ descriptor->busWidth = HSMCI_BUS_WIDTH_4;
+ if (-1 == HAL_SetHsmciBusWidth(descriptor))
+ return hsmciError;
+
+ /* send CMD6 command to switch to high speed mode */
+ if (!memSendCommand(descriptor, SWITCH, CMD6_SET_HS_MODE, R1_RESPONSE_LENGTH))
+ return hsmciError;
+ /* wait for hsmci bus becomes free */
+ while (!HAL_HsmciCheckReady());
+ cardStatus = (MmcCardStatus_t *)(commandDescr->responseBuffer);
+ if (0 != (cardStatus->reg & ERROR_STATUS))
+ return commandError;
+ if (!memCheckState(descriptor, STATUS_TRAN))
+ return stateError;
+
+ descriptor->highSpeedMode = true;
+ if (-1 == HAL_SetHsmciHighSpeedMode(descriptor))
+ return hsmciError;
+
+ if (!setMaximumCommunicationFrequency(descriptor, tranSpeed, false))
+ return hsmciError;
+
+ return memSuccess;
+}
+
+//eof mmc.c
diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/MSD/src/mscProtocol.c b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/MSD/src/mscProtocol.c
new file mode 100644
index 00000000..47e5c2d8
--- /dev/null
+++ b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/MSD/src/mscProtocol.c
@@ -0,0 +1,53 @@
+/****************************************************************************//**
+ \file mscProtocol.c
+
+ \brief Implementation of communication device protocol command.
+
+ \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:
+ 29/08/11 N. Fomin - Created
+*******************************************************************************/
+/******************************************************************************
+ Includes section
+******************************************************************************/
+#include <mscProtocol.h>
+#include <usb.h>
+
+/******************************************************************************
+ Implementations section
+******************************************************************************/
+/**************************************************************************//**
+\brief Mass storage device request handler.
+\param[in]
+ data - pointer to host's request.
+******************************************************************************/
+void msdRequestHandler(uint8_t *data)
+{
+ UsbMscRequest_t *pRequest = NULL;
+
+ pRequest = (UsbMscRequest_t *)data;
+ if (NULL == pRequest)
+ return;
+
+ // Check request code
+ switch (pRequest->request.bRequest)
+ {
+ case BULK_ONLY_MASS_STORAGE_RESET:
+ break;
+ case GET_MAX_LUN:
+ HAL_Stall(0);
+ break;
+ default:
+ HAL_Stall(0);
+ break;
+ }
+}
+
+//eof mscProtocol.c
diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/MSD/src/scsiProtocol.c b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/MSD/src/scsiProtocol.c
new file mode 100644
index 00000000..68c3cfb6
--- /dev/null
+++ b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/MSD/src/scsiProtocol.c
@@ -0,0 +1,398 @@
+/****************************************************************************//**
+ \files scsiProtocol.h
+
+ \brief Implementation of communication device protocol command.
+
+ \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:
+ 30/08/11 N. Fomin - Created
+*******************************************************************************/
+/******************************************************************************
+ Includes section
+******************************************************************************/
+#include <scsiProtocol.h>
+
+/******************************************************************************
+ Define(s) section
+******************************************************************************/
+// scsi commands
+#define INQUIRY 0x12
+#define READ_CAPACITY_10 0x25
+#define READ_10 0x28
+#define REQUEST_SENSE 0x03
+#define TEST_UNIT_READY 0x00
+#define WRITE_10 0x2A
+#define PREVENT_ALLOW_MEDIUM_REMOVAL 0x1E
+#define MODE_SENSE_6 0x1A
+#define READ_FORMAT_CAPACITIES 0x23
+#define VERIFY_10 0x2F
+
+// capacity definitions
+#define BLOCK_SIZE 512
+
+//inquiry definitions
+#define INQUIRY_PERIPHERAL 0x00
+#define INQUIRY_REMOVABLE 0x80
+#define INQUIRY_VERSION 0x04
+#define INQUIRY_RESPONSE_FORMAT 0x02
+#define INQUIRY_ADDITIONAL_LENGTH 0x20
+#define INQUIRY_FLAGS 0x00
+#define INQUIRY_VENDOR_ID "Atmel "
+#define INQUIRY_PRODUCT_ID "Mass Storage "
+#define INQUIRY_PRODUCT_REVISION "0001"
+
+// request sense definitions
+#define REQUEST_SENSE_CODE 0xF0
+#define REQUEST_SENSE_OBSOLETE 0x00
+#define REQUEST_SENSE_NORMAL_FLAGS 0x00
+#define REQUEST_SENSE_ERROR_FLAGS 0x05
+#define REQUEST_SENSE_INFO 0x00
+#define REQUEST_SENSE_ADDITIONAL_SENSE_LENGTH 0x0A
+#define REQUEST_SENSE_CMD_SPECIFIC_INFO 0x00
+#define REQUEST_SENSE_NORMAL_ADDITIONAL_SENSE_CODE 0x00
+#define REQUEST_SENSE_ERROR_ADDITIONAL_SENSE_CODE 0x20
+#define REQUEST_SENSE_ADDITIONAL_SENSE_CODE_QUALIFIER 0x00
+#define REQUEST_SENSE_FIELD_REPLACABLE_UNIT_CODE 0x00
+#define REQUEST_SENSE_SENSE_KEY_SPECIFIC_VALID 0x80
+#define REQUEST_SENSE_SENSE_KEY_SPECIFIC 0x00
+
+// mode sense definitions
+#define MODE_SENSE_LENGTH 0x03
+#define MODE_SENSE_MEDIA_TYPE 0x00
+#define MODE_SENSE_DEVICE_SPECIFIC 0x00
+#define MODE_SENSE_BLOCK_DESC_LENGTH 0x00
+
+// format capacities definitions
+#define FORMAT_CAPACITIES_RESERVED 0x00
+#define FORMAT_CAPACITIES_LENGTH 0x08
+#define FORMAT_CAPACITIES_DESC_TYPE 0x01
+
+/******************************************************************************
+ Types section
+******************************************************************************/
+BEGIN_PACK
+typedef struct PACK
+{
+ uint32_t lastLogicalBlock;
+ uint32_t logicalBlockLength;
+} ScsiReadCapacityResponse_t;
+
+typedef struct PACK
+{
+ uint8_t peripheral;
+ uint8_t removable;
+ uint8_t version;
+ uint8_t responseDataFormat;
+ uint8_t additionalLength;
+ uint8_t flags[3];
+ uint8_t vendorId[8];
+ uint8_t productId[16];
+ uint8_t productRevision[4];
+} ScsiInquiryResponse_t;
+
+typedef struct PACK
+{
+ uint8_t responseCodeAndValid;
+ uint8_t obsolete;
+ uint8_t flags;
+ uint32_t information;
+ uint8_t addSenseLen;
+ uint32_t cmdSpecificInfo;
+ uint8_t additionalSenseCode;
+ uint8_t additionalSenseCodeQualifier;
+ uint8_t fieldReplacableUnitCode;
+ uint8_t senseKeySpecific[3];
+} ScsiRequestSenseResponse_t;
+
+typedef struct PACK
+{
+ uint8_t modeDataLength;
+ uint8_t mediumType;
+ uint8_t deviceSpecific;
+ uint8_t blockDescriptorLength;
+} ScsiModeSense6Response_t;
+
+typedef struct PACK
+{
+ uint8_t reserved[3];
+ uint8_t length;
+ uint32_t blocksNumber;
+ uint8_t descType;
+ uint8_t blockLengthUp;
+ uint16_t blockLengthDown;
+} ScsiReadFormatCapacities_t;
+
+typedef struct PACK
+{
+ uint8_t flags;
+ uint32_t logicalBlockAddress;
+ uint8_t groupNumber;
+ uint16_t transferLength;
+ uint8_t control;
+} ScsiReadWriteCommand_t;
+
+typedef struct PACK
+{
+ uint8_t index;
+ union
+ {
+ ScsiReadWriteCommand_t rwCommand;
+ };
+} ScsiCommand_t;
+END_PACK
+
+/******************************************************************************
+ Global variables section
+******************************************************************************/
+static bool defaultRequestSenseResponse;
+static uint32_t lastLogicalBlockNum;
+
+/******************************************************************************
+ Constants section
+******************************************************************************/
+const ScsiInquiryResponse_t inquiryResponse = {
+ INQUIRY_PERIPHERAL,
+ INQUIRY_REMOVABLE,
+ INQUIRY_VERSION,
+ INQUIRY_RESPONSE_FORMAT,
+ INQUIRY_ADDITIONAL_LENGTH,
+ {INQUIRY_FLAGS, INQUIRY_FLAGS, INQUIRY_FLAGS},
+ INQUIRY_VENDOR_ID,
+ INQUIRY_PRODUCT_ID,
+ INQUIRY_PRODUCT_REVISION
+};
+
+const ScsiRequestSenseResponse_t normalRequestSenseResponse = {
+ REQUEST_SENSE_CODE,
+ REQUEST_SENSE_OBSOLETE,
+ REQUEST_SENSE_NORMAL_FLAGS,
+ SWAP32(REQUEST_SENSE_INFO),
+ REQUEST_SENSE_ADDITIONAL_SENSE_LENGTH,
+ SWAP32(REQUEST_SENSE_CMD_SPECIFIC_INFO),
+ REQUEST_SENSE_NORMAL_ADDITIONAL_SENSE_CODE,
+ REQUEST_SENSE_ADDITIONAL_SENSE_CODE_QUALIFIER,
+ REQUEST_SENSE_FIELD_REPLACABLE_UNIT_CODE,
+ {REQUEST_SENSE_SENSE_KEY_SPECIFIC_VALID, REQUEST_SENSE_SENSE_KEY_SPECIFIC, REQUEST_SENSE_SENSE_KEY_SPECIFIC}
+};
+
+const ScsiRequestSenseResponse_t errorRequestSenseResponse = {
+ REQUEST_SENSE_CODE,
+ REQUEST_SENSE_OBSOLETE,
+ REQUEST_SENSE_ERROR_FLAGS,
+ SWAP32(REQUEST_SENSE_INFO),
+ REQUEST_SENSE_ADDITIONAL_SENSE_LENGTH,
+ SWAP32(REQUEST_SENSE_CMD_SPECIFIC_INFO),
+ REQUEST_SENSE_ERROR_ADDITIONAL_SENSE_CODE,
+ REQUEST_SENSE_ADDITIONAL_SENSE_CODE_QUALIFIER,
+ REQUEST_SENSE_FIELD_REPLACABLE_UNIT_CODE,
+ {REQUEST_SENSE_SENSE_KEY_SPECIFIC_VALID, REQUEST_SENSE_SENSE_KEY_SPECIFIC, REQUEST_SENSE_SENSE_KEY_SPECIFIC}
+};
+
+const ScsiModeSense6Response_t modeSense6Response = {
+ MODE_SENSE_LENGTH,
+ MODE_SENSE_MEDIA_TYPE,
+ MODE_SENSE_DEVICE_SPECIFIC,
+ MODE_SENSE_BLOCK_DESC_LENGTH
+};
+
+/******************************************************************************
+ Implementations section
+******************************************************************************/
+
+/**************************************************************************//**
+\brief Checks if received scsi command is supported.
+\param[in]
+ data - pointer to received command with parameters.
+\return
+ false - command is not supported;
+ true - command is supported.
+******************************************************************************/
+bool scsiIsValidCommand(uint8_t *data)
+{
+ ScsiCommand_t *command = (ScsiCommand_t *)data;
+
+ command->rwCommand.transferLength = SWAP16(command->rwCommand.transferLength);
+ command->rwCommand.logicalBlockAddress = SWAP32(command->rwCommand.logicalBlockAddress);
+
+ switch (command->index)
+ {
+ case INQUIRY:
+ case READ_CAPACITY_10:
+ case TEST_UNIT_READY:
+ case PREVENT_ALLOW_MEDIUM_REMOVAL:
+ case READ_10:
+ case WRITE_10:
+ case MODE_SENSE_6:
+ case READ_FORMAT_CAPACITIES:
+ case VERIFY_10:
+ defaultRequestSenseResponse = true;
+ break;
+ case REQUEST_SENSE:
+ return true;
+ default:
+ defaultRequestSenseResponse = false;
+ break;
+ }
+
+ return defaultRequestSenseResponse;
+}
+
+/**************************************************************************//**
+\brief Checks if any response or data transfer needed for received
+ scsi command.
+\param[in]
+ command - received command.
+\return
+ false - response is not needed;
+ true - response is needed.
+******************************************************************************/
+bool scsiIsDataInOutPhaseNeeded(uint8_t *data)
+{
+ ScsiCommand_t *command = (ScsiCommand_t *)data;
+
+ if ((TEST_UNIT_READY == command->index) || (PREVENT_ALLOW_MEDIUM_REMOVAL == command->index)
+ || (VERIFY_10 == command->index))
+ return false;
+ if ((READ_10 == command->index) || (WRITE_10 == command->index))
+ if (0 == command->rwCommand.transferLength)
+ return false;
+ return true;
+}
+
+/**************************************************************************//**
+\brief Checks if command is read or write command.
+\param[in]
+ command - received command.
+\return
+ false - command is not read/write command;
+ true - command is read/write command.
+******************************************************************************/
+bool scsiIsReadWriteCommand(uint8_t *data)
+{
+ ScsiCommand_t *command = (ScsiCommand_t *)data;
+
+ return ((READ_10 == command->index) || (WRITE_10 == command->index));
+}
+
+/**************************************************************************//**
+\brief Checks if command is read command.
+\param[in]
+ command - received command.
+\return
+ false - command is not read command;
+ true - command is read command.
+******************************************************************************/
+bool scsiIsReadCommand(uint8_t *data)
+{
+ ScsiCommand_t *command = (ScsiCommand_t *)data;
+
+ return (READ_10 == command->index);
+}
+
+/**************************************************************************//**
+\brief Blocks for read/write command.
+\param[in]
+ data - pointer to received command with parameters.
+\return
+ number of blocks to read or write from memory.
+******************************************************************************/
+uint16_t scsiBlocksAmount(uint8_t *data)
+{
+ ScsiCommand_t *command = (ScsiCommand_t *)data;
+
+ if ((READ_10 == command->index) || (WRITE_10 == command->index))
+ return command->rwCommand.transferLength;
+
+ return 0;
+}
+
+/**************************************************************************//**
+\brief Response for scsi command.
+\param[in]
+ command - received command.
+\param[out]
+ buffer - buffer with scsi command response.
+\return
+ length of response
+******************************************************************************/
+uint8_t scsiGetCommandResponse(uint8_t *data, uint8_t *buffer)
+{
+ ScsiCommand_t *command = (ScsiCommand_t *)data;
+ ScsiReadCapacityResponse_t readCapacityResponse = {
+ .lastLogicalBlock = SWAP32(lastLogicalBlockNum),
+ .logicalBlockLength = SWAP32(BLOCK_SIZE)
+ };
+ ScsiReadFormatCapacities_t readFormatCapacitiesResponse = {
+ .reserved = {FORMAT_CAPACITIES_RESERVED, FORMAT_CAPACITIES_RESERVED, FORMAT_CAPACITIES_RESERVED},
+ .length = FORMAT_CAPACITIES_LENGTH,
+ .blocksNumber = SWAP32(lastLogicalBlockNum + 1),
+ .descType = FORMAT_CAPACITIES_DESC_TYPE,
+ .blockLengthUp = 0,
+ .blockLengthDown = SWAP16(BLOCK_SIZE)
+ };
+
+ if (INQUIRY == command->index)
+ {
+ memcpy(buffer, (uint8_t *)&inquiryResponse, sizeof(ScsiInquiryResponse_t));
+ return sizeof(ScsiInquiryResponse_t);
+ }
+ if (READ_CAPACITY_10 == command->index)
+ {
+ memcpy(buffer, (uint8_t *)&readCapacityResponse, sizeof(ScsiReadCapacityResponse_t));
+ return sizeof(ScsiReadCapacityResponse_t);
+ }
+ if (REQUEST_SENSE == command->index)
+ {
+ if (defaultRequestSenseResponse)
+ memcpy(buffer, (uint8_t *)&normalRequestSenseResponse, sizeof(ScsiRequestSenseResponse_t));
+ else
+ memcpy(buffer, (uint8_t *)&errorRequestSenseResponse, sizeof(ScsiRequestSenseResponse_t));
+ return sizeof(ScsiRequestSenseResponse_t);
+ }
+ if (MODE_SENSE_6 == command->index)
+ {
+ memcpy(buffer, (uint8_t *)&modeSense6Response, sizeof(ScsiModeSense6Response_t));
+ return sizeof(ScsiModeSense6Response_t);
+ }
+ if (READ_FORMAT_CAPACITIES == command->index)
+ {
+ memcpy(buffer, (uint8_t *)&readFormatCapacitiesResponse, sizeof(ScsiReadFormatCapacities_t));
+ return sizeof(ScsiReadFormatCapacities_t);
+ }
+ return 0;
+}
+
+/**************************************************************************//**
+\brief Sets number of last available memory block for scsi response.
+\param[in]
+ lastBlock - received command.
+\param[out]
+ buffer - number of last available memory block
+******************************************************************************/
+void scsiSetCapacity(uint32_t lastBlock)
+{
+ lastLogicalBlockNum = lastBlock;
+}
+
+/**************************************************************************//**
+\brief Block address for read/write command.
+\param[in]
+ data - pointer to received command with parameters.
+\return
+ block address for read or write from memory.
+******************************************************************************/
+uint32_t scsiGetBlockAddress(uint8_t *data)
+{
+ ScsiCommand_t *command = (ScsiCommand_t *)data;
+
+ return command->rwCommand.logicalBlockAddress;
+}
+
+//eof scsiProtocol.c
diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/VCP/Makefile b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/VCP/Makefile
new file mode 100644
index 00000000..604aa147
--- /dev/null
+++ b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/VCP/Makefile
@@ -0,0 +1,71 @@
+COMPONENTS_PATH = ../../../..
+#include $(COMPONENTS_PATH)/Makerules
+include $(MAKERULES)
+
+DEBUG = NO
+
+# Hardware flags.
+CFLAGS += $(CFLAGS_HW)
+
+##### PATHS FLAGS OF INCLUDES #########
+CFLAGS += -I./include
+CFLAGS += -I$(HAL_PATH)/include
+CFLAGS += -I./../common/include
+CFLAGS += -I$(SE_PATH)/include
+CFLAGS += -I$(HAL_PATH)/drivers/include
+CFLAGS += -I$(HAL_HWD_COMMON_PATH)/include
+
+#### DEFINES FLAGS #######
+ifeq ($(DEBUG), YES)
+ CFLAGS += -DUSB_TRACE
+endif
+
+###### LIB ##########
+BUILDDIR = .
+COMMONBUILDDIR = ./../common
+
+LIBDIR = ./../../lib
+LDFLAGS = -L$(LIBDIR)
+PROG = VCP.elf
+LIBS = $(LIBDIR)/lib$(VCP_LIB).a
+
+driver_label:
+ @echo
+ @echo ----------------------------------------------------
+ @echo VCP library creation.
+ @echo ----------------------------------------------------
+
+modules = \
+ vcpCdcProtocol \
+ vcpVirtualUsart
+
+commonModules = \
+ usbDescriptors \
+ usbEnumeration \
+ usbSetupProcess
+
+objects = $(addsuffix .o,$(addprefix $(BUILDDIR)/objs/,$(modules)))
+sources = $(addsuffix .c,$(addprefix $(BUILDDIR)/src/,$(modules)))
+
+commonObjects = $(addsuffix .o,$(addprefix $(COMMONBUILDDIR)/objs/,$(commonModules)))
+CommonSources = $(addsuffix .c,$(addprefix $(COMMONBUILDDIR)/src/,$(commonModules)))
+
+OBJS = $(objects)
+OBJS += $(commonObjects)
+
+###### TARGETS ################
+all: driver_label LIB_VCP
+################
+$(BUILDDIR)/objs/%.o: $(BUILDDIR)/src/%.c
+ $(CC) $(CFLAGS) $^ -o $@
+$(COMMONBUILDDIR)/objs/%.o: $(COMMONBUILDDIR)/src/%.c
+ $(CC) $(CFLAGS) $^ -o $@
+
+################
+LIB_VCP : $(OBJS)
+ $(AR) $(AR_KEYS) $(LIBDIR)/lib$(VCP_LIB).a $(OBJS)
+ $(SIZE) -td $(LIBDIR)/lib$(VCP_LIB).a
+################
+clean:
+ rm -f $(objects) $(LIBS) $(BUILDDIR)/list/*.*
+ rm -f $(commonObjects) $(LIBS) $(COMMONBUILDDIR)/list/*.* \ No newline at end of file
diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/VCP/include/vcpCdcProtocol.h b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/VCP/include/vcpCdcProtocol.h
new file mode 100644
index 00000000..e8044c41
--- /dev/null
+++ b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/VCP/include/vcpCdcProtocol.h
@@ -0,0 +1,119 @@
+/****************************************************************************//**
+ \file vcpCdcProtocol.h
+
+ \brief Declaration of communication device protocol command.
+
+ \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:
+ 05/09/08 A. Khromykh - Created
+*******************************************************************************/
+#ifndef _VCPCDCPROTOCOL_H
+#define _VCPCDCPROTOCOL_H
+
+/******************************************************************************
+ Includes section
+******************************************************************************/
+#include <types.h>
+#include <usbSetupProcess.h>
+
+/******************************************************************************
+ Define(s) section
+******************************************************************************/
+// data size in request structure
+#define CDC_REQUEST_DATA_SIZE 7
+// data size in notification structure
+#define NOTIFICATION_DATA_SIZE 2
+
+// request codes for communication interface class
+#define SEND_ENCAPSULATED_COMMAND 0x00
+#define GET_ENCAPSULATED_RESPONSE 0x01
+#define SET_COMM_FEATURE 0x02
+#define GET_COMM_FEATURE 0x03
+#define CLEAR_COMM_FEATURE 0x04
+#define SET_AUX_LINE_STATE 0x10
+#define SET_HOOK_STATE 0x11
+#define PULSE_SETUP 0x12
+#define SEND_PULSE 0x13
+#define SET_PULSE_TIME 0x14
+#define RING_AUX_JACK 0x15
+#define SET_LINE_CODING 0x20
+#define GET_LINE_CODING 0x21
+#define SET_CONTROL_LINE_STATE 0x22
+#define SEND_BREAK 0x23
+#define SET_RINGER_PARMS 0x30
+#define GET_RINGER_PARMS 0x31
+#define SET_OPERATION_PARMS 0x32
+#define GET_OPERATION_PARMS 0x33
+#define SET_LINE_PARMS 0x34
+#define GET_LINE_PARMS 0x35
+#define DIAL_DIGITS 0x36
+#define SET_UNIT_PARAMETER 0x37
+#define GET_UNIT_PARAMETER 0x38
+#define CLEAR_UNIT_PARAMETER 0x39
+#define GET_PROFILE 0x3A
+#define SET_ETHERNET_MULTICAST_FILTERS 0x40
+#define SET_ETHERNET_POWER_MANAGEMENT_PATTERNFILTER 0x41
+#define GET_ETHERNET_POWER_MANAGEMENT_PATTERNFILTER 0x42
+#define SET_ETHERNET_PACKET_FILTER 0x43
+#define GET_ETHERNET_STATISTIC 0x44
+#define SET_ATM_DATA_FORMAT 0x50
+#define GET_ATM_DEVICE_STATISTICS 0x51
+#define SET_ATM_DEFAULT_VC 0x52
+#define GET_ATM_VC_STATISTICS 0x53
+
+/******************************************************************************
+ Types section
+******************************************************************************/
+BEGIN_PACK
+// Usb host request
+typedef struct PACK
+{
+ UsbRequest_t request;
+ uint8_t bData[CDC_REQUEST_DATA_SIZE];
+} UsbCdcRequest_t;
+
+// Usb GetLineCoding device response
+typedef struct PACK
+{
+ uint32_t dwDTERate;
+ uint8_t bCharFormat;
+ uint8_t bParityType;
+ uint8_t bDataBits;
+} GetLineCodingResponse_t;
+
+typedef union PACK
+{
+ GetLineCodingResponse_t getLineCoding;
+} UsbCdcResponse_t;
+
+// Usb VCP notification
+typedef struct PACK
+{
+ uint8_t bmRequestType;
+ uint8_t bNotification;
+ uint16_t wValue;
+ uint16_t wIndex;
+ uint16_t wLength;
+ uint8_t bData[NOTIFICATION_DATA_SIZE];
+} UsbNotification_t;
+END_PACK
+
+/******************************************************************************
+ Prototypes section
+******************************************************************************/
+/******************************************************************************
+communication device request handler
+
+Parameters:
+ data - pointer to host's request
+******************************************************************************/
+void vcpRequestHandler(uint8_t *data);
+
+#endif /* _VCPCDCPROTOCOL_H */
diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/VCP/src/vcpCdcProtocol.c b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/VCP/src/vcpCdcProtocol.c
new file mode 100644
index 00000000..6ea63557
--- /dev/null
+++ b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/VCP/src/vcpCdcProtocol.c
@@ -0,0 +1,226 @@
+/****************************************************************************//**
+ \file vcpCdcProtocol.h
+
+ \brief Implementation of communication device protocol command.
+
+ \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:
+ 11/09/08 A. Khromykh - Created
+*******************************************************************************/
+/******************************************************************************
+ Includes section
+******************************************************************************/
+#include <vcpCdcProtocol.h>
+#include <usbEnumeration.h>
+#include <usart.h>
+#include <usb.h>
+
+/******************************************************************************
+ Define(s) section
+******************************************************************************/
+// virtual uart speed
+#define VU_1200 0x4B0
+#define VU_2400 0x960
+#define VU_4800 0x12C0
+#define VU_9600 0x2580
+#define VU_19200 0x4B00
+#define VU_38400 0x9600
+#define VU_57600 0xE100
+#define VU_115200 0x1C200
+
+// char size
+#define VU_1STOPBIT 0
+#define VU_1d5STOPBITS 1
+#define VU_2STOPBITS 2
+
+// parity
+#define VU_NONE 0
+#define VU_ODD 1
+#define VU_EVEN 2
+#define VU_MARK 3
+#define VU_SPACE 4
+
+// data bits number
+#define VU_5DATABITS 5
+#define VU_6DATABITS 6
+#define VU_7DATABITS 7
+#define VU_8DATABITS 8
+#define VU_16DATABITS 16
+
+/******************************************************************************
+ External global variables section
+******************************************************************************/
+extern HAL_UsartDescriptor_t *vcpPointDescrip;
+
+/******************************************************************************
+ Global variables section
+******************************************************************************/
+UsbCdcRequest_t request;
+UsbCdcResponse_t response;
+
+/******************************************************************************
+ Implementations section
+******************************************************************************/
+/******************************************************************************
+Get baud rate meaning for cdc response.
+
+Parameters:
+ baudRate - virtual uart baudRate
+******************************************************************************/
+void vcpGetBaudRate(uint32_t baudRate)
+{
+ (void)baudRate;
+ response.getLineCoding.dwDTERate = VU_115200;
+}
+
+/******************************************************************************
+Get number of stop bits meaning for cdc response.
+
+Parameters:
+ stopBits - virtual uart stop bits
+******************************************************************************/
+void vcpGetStopBits(uint8_t stopBits)
+{
+ (void)stopBits;
+ response.getLineCoding.bCharFormat = VU_1STOPBIT;
+}
+
+/******************************************************************************
+Get parity meaning for cdc response.
+
+Parameters:
+ parity - virtual uart parity
+******************************************************************************/
+void vcpGetParity(uint8_t parity)
+{
+ (void)parity;
+ response.getLineCoding.bParityType = VU_NONE;
+}
+
+/******************************************************************************
+Get data length meaning for cdc response.
+
+Parameters:
+ dataLength - virtual uart data length
+******************************************************************************/
+void vcpGetDataLength(uint8_t dataLength)
+{
+ (void)dataLength;
+ response.getLineCoding.bDataBits = VU_8DATABITS;
+}
+
+/******************************************************************************
+Get virtual uart data and send answer to host.
+******************************************************************************/
+void vcpResponseGetLineCoding(void)
+{
+ vcpGetBaudRate(vcpPointDescrip->baudrate);
+ vcpGetStopBits(vcpPointDescrip->stopbits);
+ vcpGetParity(vcpPointDescrip->parity);
+ vcpGetDataLength(vcpPointDescrip->dataLength);
+
+ HAL_UsbWrite(0, (void *)&response, sizeof(GetLineCodingResponse_t), 0, 0);
+}
+
+/******************************************************************************
+Set baud rate meaning to virtual port.
+
+Parameters:
+ baudRate - virtual uart baud rate
+******************************************************************************/
+void vcpSetBaudRate(uint32_t baudRate)
+{
+ (void)baudRate;
+}
+
+/******************************************************************************
+Set number stop bits to virtual port.
+
+Parameters:
+ stopBits - virtual uart stop bits
+******************************************************************************/
+void vcpSetStopBits(uint8_t stopBits)
+{
+ (void)stopBits;
+}
+
+/******************************************************************************
+Set parity meaning to virtual port.
+
+Parameters:
+ parity - virtual uart parity
+******************************************************************************/
+void vcpSetParity(uint8_t parity)
+{
+ (void)parity;
+}
+
+/******************************************************************************
+Set data length to virtual port.
+
+Parameters:
+ dataLength - virtual uart data length
+******************************************************************************/
+void vcpSetDataLength(uint8_t dataLength)
+{
+ (void)dataLength;
+}
+
+/******************************************************************************
+Set virtual uart data and send response to host.
+******************************************************************************/
+void vcpResponseSetLineCoding(void)
+{
+ vcpSetBaudRate(response.getLineCoding.dwDTERate);
+ vcpSetStopBits(response.getLineCoding.bCharFormat);
+ vcpSetParity(response.getLineCoding.bParityType);
+ vcpSetDataLength(response.getLineCoding.bDataBits);
+
+#if defined(AT91SAM7X256) || defined(AT91SAM3S4C)
+ sendZLP();
+#endif
+}
+
+/******************************************************************************
+communication device request handler
+
+Parameters:
+ data - pointer to host's request
+******************************************************************************/
+void vcpRequestHandler(uint8_t *data)
+{
+ UsbCdcRequest_t *pRequest = NULL;
+
+ pRequest = (UsbCdcRequest_t *)data;
+ if (NULL == pRequest)
+ return;
+
+ // Check request code
+ switch (pRequest->request.bRequest)
+ {
+ case SET_LINE_CODING:
+ HAL_UsbRead(0, (void *)&response, sizeof(GetLineCodingResponse_t), (TransferCallback_t)vcpResponseSetLineCoding, 0);
+ break;
+ case GET_LINE_CODING:
+ vcpResponseGetLineCoding();
+ break;
+ case SET_CONTROL_LINE_STATE:
+ //vcpReadDataFromSetControlLineState(pRequest->wValue); // possible in the future
+ #if defined(AT91SAM7X256) || defined(AT91SAM3S4C)
+ sendZLP();
+ #endif
+ break;
+ default:
+ HAL_Stall(0);
+ break;
+ }
+}
+
+//eof vcpCdcProtocol.c
diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/VCP/src/vcpVirtualUsart.c b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/VCP/src/vcpVirtualUsart.c
new file mode 100644
index 00000000..29469576
--- /dev/null
+++ b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/VCP/src/vcpVirtualUsart.c
@@ -0,0 +1,498 @@
+/****************************************************************************//**
+ \file vcpVirtualUart.c
+
+ \brief Implementation of virtual uart API.
+
+ \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:
+ 11/09/08 A. Khromykh - Created
+*******************************************************************************/
+/******************************************************************************
+ Includes section
+******************************************************************************/
+#include <string.h>
+#include <vcpCdcProtocol.h>
+#include <usbDescriptors.h>
+#include <usbEnumeration.h>
+#include <vcpVirtualUsart.h>
+
+/******************************************************************************
+ Types section
+******************************************************************************/
+// usart control
+typedef struct
+{
+ uint16_t rxUnusedRemaining;
+} VcpControl_t;
+
+/******************************************************************************
+ Prototypes section
+******************************************************************************/
+/******************************************************************************
+Tuning of received buffer and enable received pipe if there is free place
+in the buffer.
+Parameters:
+ descriptor - pointer to HAL_UartDescriptor_t structure;
+Returns:
+ none.
+******************************************************************************/
+void vcpEnableReadPipe(void);
+
+/******************************************************************************
+ External global variables section
+******************************************************************************/
+extern UsbCdcRequest_t request;
+extern UsbCdcResponse_t response;
+
+/******************************************************************************
+ Global variables section
+******************************************************************************/
+// pointer to application uart descriptor
+HAL_UsartDescriptor_t *vcpPointDescrip = NULL;
+// structure for internal ring buffer
+VcpControl_t vcpControl;
+
+/******************************************************************************
+ Implementations section
+******************************************************************************/
+/******************************************************************************
+Transmitting callback of virtual uart
+Parameters:
+ pArg - pointer to some data.
+ status - result of the USB transfer.
+ transferred - how much data are transferred
+ remaining - how much data are not transferred
+Returns:
+ none.
+******************************************************************************/
+void vcpTmtCallback(void *pArg, uint8_t status, uint16_t transferred, uint16_t remaining)
+{
+ (void)pArg;
+ (void)status;
+ (void)remaining;
+ uint16_t copyPor = vcpPointDescrip->service.txPointOfRead;
+ uint16_t copyPow = vcpPointDescrip->service.txPointOfWrite;
+ bool endOfTransferring = true;
+
+ if (NULL != vcpPointDescrip)
+ {
+ if (NULL != vcpPointDescrip->txBuffer)
+ { /* polling mode */
+ copyPor += transferred;
+ if (copyPor == vcpPointDescrip->txBufferLength)
+ copyPor = 0;
+
+ if (copyPor != copyPow)
+ {
+ if (copyPor > copyPow)
+ {
+ HAL_UsbWrite(VCP_TRANSMIT_PIPE, &vcpPointDescrip->txBuffer[copyPor],
+ (vcpPointDescrip->txBufferLength - copyPor), vcpTmtCallback, NULL);
+ }
+ else
+ {
+ HAL_UsbWrite(VCP_TRANSMIT_PIPE, &vcpPointDescrip->txBuffer[copyPor],
+ (copyPow - copyPor), vcpTmtCallback, NULL);
+ }
+ }
+ endOfTransferring = false;
+ vcpPointDescrip->service.txPointOfRead = copyPor;
+ } /* polling mode */
+
+ if (!endOfTransferring)
+ return;
+
+ if (!(transferred % BULK_SIZE) && transferred)
+ {
+ /*
+ Universal Serial Bus Class Definitions for Communication Devices
+ 3.8.1.1 Segment Delineation
+ This positive delineation is done using a USB short packet mechanism. When a segment spans N USB packets, the
+ first packet through packet N-1 shall be the maximum packet size defined for the USB endpoint. If the Nth packet is
+ less than maximum packet size the USB transfer of this short packet will identify the end of the segment. If the Nth
+ packet is exactly maximum packet size, it shall be followed by a zero-length packet (which is a short packet) to assure
+ the end of segment is properly identified.
+ When transmitting data to the networking device, it is assumed that the client of the host USB driver takes the
+ appropriate actions to cause a short packet to be sent to the networking device. For segments with lengths that are an
+ even multiple of the pipe’s “max packet size”, the ability to write a buffer of zero length is required to generate this
+ short packet.
+ */
+ HAL_UsbWrite(VCP_TRANSMIT_PIPE, NULL, 0, vcpTmtCallback, NULL);
+ }
+ else
+ {
+ if (NULL != vcpPointDescrip->txCallback)
+ vcpPointDescrip->txCallback();
+ }
+
+ }
+}
+
+/******************************************************************************
+Receiving callback of virtual uart
+Parameters:
+ pArg - pointer to something data.
+ status - result of the USB transfer.
+ transferred - how much data are transferred
+ remaining - how much data are not transferred
+Returns:
+ none.
+******************************************************************************/
+void vcpRcvCallback(void *pArg, uint8_t status, uint16_t transferred, uint16_t remaining)
+{
+ (void)pArg;
+ (void)status;
+ (void)remaining;
+ uint16_t number;
+ uint16_t copyPor;
+ uint16_t copyPow;
+ uint16_t copyUnr;
+
+ vcpPointDescrip->service.rxPointOfWrite += transferred;
+ copyPor = vcpPointDescrip->service.rxPointOfRead;
+ copyPow = vcpPointDescrip->service.rxPointOfWrite;
+ copyUnr = vcpControl.rxUnusedRemaining;
+
+ if (NULL != vcpPointDescrip)
+ {
+ if (NULL != vcpPointDescrip->rxCallback)
+ {
+ if (copyPow < copyPor)
+ number = copyUnr - (copyPor - copyPow);
+ else
+ number = copyPow - copyPor;
+
+ vcpPointDescrip->rxCallback(number);
+ vcpEnableReadPipe();
+ }
+ }
+}
+
+/******************************************************************************
+Open virtual com port and register uart's event handlers.
+
+Parameters:
+ descriptor - pointer to HAL_UartDescriptor_t structure
+
+Returns:
+ Returns positive uart descriptor on success or -1 in cases:
+ - bad uart channel;
+ - there are not enough resources;
+ - receiving buffer is less bulk endpoint size;
+******************************************************************************/
+int VCP_OpenUsart(HAL_UsartDescriptor_t *descriptor)
+{
+ if (NULL == descriptor)
+ return -1;
+
+ if (USART_CHANNEL_VCP != descriptor->tty)
+ return -1;
+
+ if (NULL != vcpPointDescrip)
+ return -1; /* source was opened */
+
+ vcpPointDescrip = descriptor;
+
+ vcpPointDescrip->service.rxPointOfRead = 0;
+ vcpPointDescrip->service.rxPointOfWrite = 0;
+ vcpControl.rxUnusedRemaining = vcpPointDescrip->rxBufferLength;
+ vcpPointDescrip->service.txPointOfRead = 0;
+ vcpPointDescrip->service.txPointOfWrite = 0;
+ HAL_RegisterEndOfBusResetHandler(usbBusResetAction);
+ if (DEVICE_POWERED != HAL_GetState())
+ HAL_UsbInit((uint8_t *)&request);
+
+ return (int)descriptor->tty;
+}
+
+/******************************************************************************
+Frees the virtual uart channel.
+Parameters:
+ descriptor - the uart descriptor.
+Returns:
+ Returns 0 on success or -1 if bad descriptor.
+******************************************************************************/
+int VCP_CloseUsart(HAL_UsartDescriptor_t *descriptor)
+{
+ if (NULL == descriptor)
+ return -1;
+
+ if (vcpPointDescrip != descriptor)
+ return -1;
+
+ vcpPointDescrip = NULL;
+
+ return 0;
+}
+
+/******************************************************************************
+Writes a number of bytes to a virtual uart channel.
+txCallback function will be used to notify when the transmission is finished.
+Parameters:
+ descriptor - pointer to HAL_UartDescriptor_t structure;
+ buffer - pointer to the application data buffer;
+ length - number of bytes to transfer;
+Returns:
+ -1 - bad descriptor;
+ Number of bytes placed to the buffer - success.
+******************************************************************************/
+int VCP_WriteUsart(HAL_UsartDescriptor_t *descriptor, uint8_t *buffer, uint16_t length)
+{
+ uint16_t copyPow = vcpPointDescrip->service.txPointOfWrite;
+ uint16_t copyPor = vcpPointDescrip->service.txPointOfRead;
+ uint16_t freePlace;
+ uint16_t wasWrote = 0;
+
+ if (NULL == descriptor)
+ return -1;
+
+ if (vcpPointDescrip != descriptor)
+ return -1;
+
+ if (!buffer || !length)
+ return -1;
+
+ if (NULL == descriptor->txBuffer)
+ { /* callback mode */
+ if (STATUS_SUCCESS != HAL_UsbWrite(VCP_TRANSMIT_PIPE, buffer, length, vcpTmtCallback, NULL))
+ return -1; // there is unsent data
+ return length;
+ } /* callback mode */
+ else
+ { /* polling mode */
+ if (copyPor > copyPow)
+ {
+ freePlace = copyPor - copyPow;
+ if (freePlace < length)
+ return -1; // there is unsent data
+ memcpy(&descriptor->txBuffer[copyPow], buffer, length);
+ HAL_UsbWrite(VCP_TRANSMIT_PIPE, buffer, length, vcpTmtCallback, NULL);
+ copyPow += length;
+
+ }
+ else // point of write more or equal point of read
+ {
+ freePlace = descriptor->txBufferLength - copyPow + copyPor;
+ if (freePlace < length)
+ return -1; // there is unsent data
+
+ uint16_t tempValue = descriptor->txBufferLength - copyPow;
+ if (length > tempValue)
+ {
+ memcpy(&descriptor->txBuffer[copyPow], buffer, tempValue);
+ HAL_UsbWrite(VCP_TRANSMIT_PIPE, buffer, tempValue, vcpTmtCallback, NULL);
+ buffer += tempValue;
+ length -= tempValue;
+ memcpy(descriptor->txBuffer, buffer, length);
+ copyPow = length;
+ }
+ else
+ {
+ memcpy(&descriptor->txBuffer[copyPow], buffer, length);
+ HAL_UsbWrite(VCP_TRANSMIT_PIPE, buffer, length, vcpTmtCallback, NULL);
+ copyPow += length;
+ }
+ }
+
+ if (copyPow == descriptor->txBufferLength)
+ copyPow = 0;
+ vcpPointDescrip->service.txPointOfWrite = copyPow;
+ wasWrote = length;
+
+ return wasWrote;
+ } /* polling mode */
+}
+
+/******************************************************************************
+Tuning of received buffer and enable received pipe if there is free place
+in the buffer.
+Parameters:
+ none;
+Returns:
+ none.
+******************************************************************************/
+void vcpEnableReadPipe(void)
+{
+ uint16_t copyPor = vcpPointDescrip->service.rxPointOfRead;
+ uint16_t copyPow = vcpPointDescrip->service.rxPointOfWrite;
+ uint16_t copyUnr = vcpControl.rxUnusedRemaining;
+ uint8_t usbResult = STATUS_SUCCESS;
+
+ do
+ {
+ if (copyPor < copyPow)
+ {
+ if ((vcpPointDescrip->rxBufferLength - copyPow) < BULK_SIZE)
+ {
+ copyUnr = copyPow;
+ if (0 == copyPor)
+ {
+ usbResult = STATUS_BUSY;
+ break;
+ }
+ copyPow = 0;
+ }
+ else
+ {
+ usbResult = HAL_UsbRead(VCP_RECEIVE_PIPE, &vcpPointDescrip->rxBuffer[copyPow], BULK_SIZE, vcpRcvCallback, NULL);
+ break;
+ }
+ }
+ else
+ {
+ // empty buffer
+ if (copyPow == copyPor)
+ {
+ if ((vcpPointDescrip->rxBufferLength - copyPow) < BULK_SIZE)
+ {
+ copyUnr = vcpPointDescrip->rxBufferLength;
+ copyPor = 0;
+ copyPow = 0;
+ }
+ usbResult = HAL_UsbRead(VCP_RECEIVE_PIPE, &vcpPointDescrip->rxBuffer[copyPow], BULK_SIZE, vcpRcvCallback, NULL);
+ } // copyPor > copyPow
+ else
+ {
+ if ((copyPor - copyPow) >= BULK_SIZE)
+ usbResult = HAL_UsbRead(VCP_RECEIVE_PIPE, &vcpPointDescrip->rxBuffer[copyPow], BULK_SIZE, vcpRcvCallback, NULL);
+ else
+ usbResult = STATUS_BUSY;
+ }
+ break;
+ }
+ } while(1);
+
+ if (STATUS_SUCCESS == usbResult)
+ {
+ vcpPointDescrip->service.rxPointOfRead = copyPor;
+ vcpPointDescrip->service.rxPointOfWrite = copyPow;
+ vcpControl.rxUnusedRemaining = copyUnr;
+ }
+}
+
+/*****************************************************************************
+Reads length bytes from uart and places ones to buffer.
+Parameters:
+ descriptor - uart descriptor;
+ buffer - pointer to a application buffer;
+ length - the number of bytes which should be placed to buffer
+Returns:
+ -1 - bad descriptor, bad number to read;
+ number of bytes that were placed to buffer.
+*****************************************************************************/
+int VCP_ReadUsart(HAL_UsartDescriptor_t *descriptor, uint8_t *buffer, uint16_t length)
+{
+ uint16_t wasRead = 0;
+ uint16_t firstPart = 0;
+ uint16_t copyPor = vcpPointDescrip->service.rxPointOfRead;
+ uint16_t copyPow = vcpPointDescrip->service.rxPointOfWrite;
+ uint16_t copyUnr = vcpControl.rxUnusedRemaining;
+
+ if (NULL == descriptor)
+ return -1;
+
+ if (vcpPointDescrip != descriptor)
+ return -1;
+
+ if (!buffer || !length)
+ return -1;
+
+ do
+ {
+ // buffer is empty
+ if (copyPow == copyPor)
+ break;
+
+ // [----**********---------] --- empty **** busy
+ // por pow
+ // [*****---------*******###] ### unused at the current moment
+ // pow por ur
+ // por - point of read(user read from buffer)
+ // pow - point of write(HAL write to buffer)
+ // ur - unused remaining(because remaining less then max packet size at the start read moment.)
+ if (copyPor < copyPow)
+ {
+ wasRead = copyPow - copyPor;
+
+ if (wasRead > length)
+ {
+ wasRead = length;
+ memcpy(buffer, &vcpPointDescrip->rxBuffer[copyPor], wasRead);
+ copyPor += length;
+ }
+ else
+ {
+ memcpy(buffer, &vcpPointDescrip->rxBuffer[copyPor], wasRead);
+ copyPor = copyPow;
+ }
+ break;
+ }
+ else //copyPor > copyPow
+ {
+ if ((copyPor + length) < copyUnr)
+ {
+ wasRead = length;
+ memcpy(buffer, &vcpPointDescrip->rxBuffer[copyPor], wasRead);
+ copyPor += length;
+ break;
+ }
+ else
+ {
+ firstPart = copyUnr - copyPor;
+ memcpy(buffer, &vcpPointDescrip->rxBuffer[copyPor], firstPart);
+ buffer += firstPart;
+ length -= firstPart;
+ copyUnr = vcpPointDescrip->rxBufferLength;
+ copyPor = 0;
+ }
+ }
+ } while(1);
+
+ vcpPointDescrip->service.rxPointOfRead = copyPor;
+ vcpPointDescrip->service.rxPointOfWrite = copyPow;
+ vcpControl.rxUnusedRemaining = copyUnr;
+
+ vcpEnableReadPipe();
+ wasRead += firstPart;
+
+ return wasRead;
+}
+
+/**************************************************************************//**
+\brief Checks the status of tx buffer.
+
+\param[in] descriptor - pointer to HAL_UsartDescriptor_t structure;
+\return -1 - bad descriptor, no tx buffer; \n
+ 1 - tx buffer is empty; \n
+ 0 - tx buffer is not empty;
+******************************************************************************/
+int VCP_IsTxEmpty(HAL_UsartDescriptor_t *descriptor)
+{
+ HalUsartService_t *halUsartControl;
+ uint16_t copyPow;
+ uint16_t copyPor;
+
+ if (NULL == descriptor)
+ return -1;
+
+ if (vcpPointDescrip != descriptor)
+ return -1;
+
+ halUsartControl = &descriptor->service;
+ copyPow = halUsartControl->txPointOfWrite;
+ copyPor = halUsartControl->txPointOfRead;
+
+ if (copyPow == copyPor)
+ return 1;
+ else
+ return 0;
+}
+
+// eof vcpVirtualUart.c
diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/common/include/usbDescriptors.h b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/common/include/usbDescriptors.h
new file mode 100644
index 00000000..6c07c4cb
--- /dev/null
+++ b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/common/include/usbDescriptors.h
@@ -0,0 +1,184 @@
+/****************************************************************************//**
+ \file usbDescriptors.h
+
+ \brief Declaration of descriptors structures.
+
+ \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:
+ 05/09/08 A. Khromykh - Created
+ 26/08/11 N. Fomin - Modified (MSD support)
+*******************************************************************************/
+#ifndef _USBDESCRIPTORS_H
+#define _USBDESCRIPTORS_H
+
+/******************************************************************************
+ Includes section
+******************************************************************************/
+#include <types.h>
+#include <usb.h>
+
+/******************************************************************************
+ Define(s) section
+******************************************************************************/
+#define VCP_INTERFACE_ENDPOINTS_NUMBER 2
+#define MSD_INTERFACE_ENDPOINTS_NUMBER 2
+
+#define NUMBER_OF_FIRST_INTERFACE 0x00
+#define NUMBER_OF_SECOND_INTERFACE 0x01
+#define NUMBER_OF_THIRD_INTERFACE 0x02
+#define NUMBER_OF_FOURTH_INTERFACE 0x03
+
+#define BULK_SIZE 0x0040
+
+#define ADDRESS_MSC_BULKIN_PIPE 0x85
+#define ADDRESS_MSC_BULKOUT_PIPE 0x06
+
+/******************************************************************************
+ Types section
+******************************************************************************/
+// USB standard device descriptor structure.
+BEGIN_PACK
+typedef struct PACK
+{
+ uint8_t bLength; // Size of this descriptor in bytes
+ uint8_t bDescriptorType; // Descriptor type
+ uint16_t bcdUSB; // USB specification release number in BCD format
+ uint8_t bDeviceClass; // Device class code
+ uint8_t bDeviceSubClass; // Device subclass code
+ uint8_t bDeviceProtocol; // Device protocol code
+ uint8_t bMaxPacketSize0; // Maximum packet size of endpoint 0 (in bytes)
+ uint16_t idVendor; // Vendor ID
+ uint16_t idProduct; // Product ID
+ uint16_t bcdDevice; // Device release number in BCD format
+ uint8_t iManufacturer; // Index of the manufacturer string descriptor
+ uint8_t iProduct; // Index of the product string descriptor
+ uint8_t iSerialNumber; // Index of the serial number string descriptor
+ uint8_t bNumConfigurations; // Number of possible configurations for the device
+} DeviceDescriptor_t;
+
+// USB standard configuration descriptor structure.
+typedef struct PACK
+{
+ uint8_t bLength; // Size of the descriptor in bytes
+ uint8_t bDescriptorType; // Descriptor type
+ uint16_t wTotalLength; // Length of all descriptors returned along with this configuration descriptor
+ uint8_t bNumInterfaces; // Number of interfaces in this configuration
+ uint8_t bConfigurationValue; // Value for selecting this configuration
+ uint8_t iConfiguration; // Index of the configuration string descriptor
+ uint8_t bmAttributes; // Configuration characteristics
+ uint8_t bMaxPower; // Maximum power consumption of the device when in this configuration
+} ConfigurationDescriptor_t;
+
+// USB standard interface descriptor structure.
+typedef struct PACK
+{
+ uint8_t bLength; // Size of the descriptor in bytes
+ uint8_t bDescriptorType; // Descriptor type
+ uint8_t bInterfaceNumber; // Number of the interface in its configuration
+ uint8_t bAlternateSetting; // Value to select this alternate interface setting
+ uint8_t bNumEndpoints; // Number of endpoints used by the interface (excluding endpoint 0)
+ uint8_t bInterfaceClass; // Interface class code
+ uint8_t bInterfaceSubClass; // Interface subclass code
+ uint8_t bInterfaceProtocol; // Interface protocol code
+ uint8_t iInterface; // Index of the interface string descriptor
+} InterfaceDescriptor_t;
+
+// USB header functional descriptor.
+typedef struct PACK
+{
+ uint8_t bFunctionalLength; // Size of the descriptor in bytes
+ uint8_t bDescriptorType; // Descriptor type
+ uint8_t bDescriptorSubtype; // Header functional descriptor subtype
+ uint16_t bcdCDC; // USB Class Definitions for Communication
+ // Devices Specification release number in binary-coded decimal.
+} HeaderFunctionalDescriptor_t;
+
+// USB Abstract Control Management Functional Descriptor.
+typedef struct PACK
+{
+ uint8_t bFunctionalLength; // Size of the descriptor in bytes
+ uint8_t bDescriptorType; // Descriptor type
+ uint8_t bDescriptorSubtype; // ACM descriptor subtype
+ uint8_t bmCapabilities; // The capabilities that this configuration supports
+} AbstractControlManagmentDescriptor_t;
+
+// USB Union Functional Descriptor.
+typedef struct PACK
+{
+ uint8_t bFunctionalLength; // Size of the descriptor in bytes
+ uint8_t bDescriptorType; // Descriptor type
+ uint8_t bDescriptorSubtype; // Union functional descriptor subtype
+ uint8_t bMasterInterface; // The interface number of the Communication or Data Class interface, designated as the master or controlling interface for the union
+ uint8_t bSlaveInterface0; // Interface number of first slave or associated interface in the union
+} UnionFunctionalDescriptor_t;
+
+// USB Call Management Functional Descriptor.
+typedef struct PACK
+{
+ uint8_t bFunctionalLength; // Size of the descriptor in bytes
+ uint8_t bDescriptorType; // Descriptor type
+ uint8_t bDescriptorSubtype; // Union functional descriptor subtype
+ uint8_t bmCapabilities; // The capabilities that this configuration supports
+ uint8_t bDataInterface; // Interface number of Data Class interface optionally used for call management
+} CallManagmentFunctionalDescriptor_t;
+
+// USB Interface Association Descriptor.
+typedef struct PACK
+{
+ uint8_t bLength; // Size of the descriptor in bytes
+ uint8_t bDescriptorType; // Descriptor type
+ uint8_t bFirstInterface; // Interface number of the first interface that is associated with this function
+ uint8_t bInterfaceCount; // Number of contiguous interfaces that are associated with this function
+ uint8_t bFunctionClass; // Class code
+ uint8_t bFunctionSubClass; // Subclass code
+ uint8_t bFunctionProtocol; // Protocol code
+ uint8_t iFunction; // Index of string descriptor describing this function
+} InterfaceAssociationDescriptor_t;
+
+typedef struct PACK
+{
+ uint8_t bLength; // Size of the descriptor in bytes
+ uint8_t bDescriptorType; // Descriptor type
+ uint8_t bmAttributes; // Descriptor attributes
+ uint16_t wDetachTimeOut; // Wait timeout of USB reset after DFU_DETACH request recieption
+ uint16_t wTransferSize; // Maximum number of bytes that the device can accept per control-write transaction
+ uint16_t bcdDFUVersion; // DFU Version
+} DfuFunctionalDescriptor_t;
+
+// USB frame for interface request.
+typedef struct PACK
+{
+ ConfigurationDescriptor_t config;
+#if (APP_INTERFACE == APP_INTERFACE_VCP)
+#if (MSD_SUPPORT == 1) || (DFU_SUPPORT == 1)
+ InterfaceAssociationDescriptor_t cdcIAD;
+#endif // (MSD_SUPPORT == 1) || (DFU_SUPPORT == 1)
+ InterfaceDescriptor_t interface1;
+ HeaderFunctionalDescriptor_t headerFunctional;
+ CallManagmentFunctionalDescriptor_t cmFunctionak;
+ AbstractControlManagmentDescriptor_t acmFunctional;
+ UnionFunctionalDescriptor_t unionFunctional;
+ HAL_UsbEndPointDescptr_t endpointIfc1;
+ InterfaceDescriptor_t interface2;
+ HAL_UsbEndPointDescptr_t endpointIfc2[VCP_INTERFACE_ENDPOINTS_NUMBER];
+#endif // (APP_INTERFACE == APP_INTERFACE_VCP)
+#if (MSD_SUPPORT == 1)
+ InterfaceDescriptor_t interface3;
+ HAL_UsbEndPointDescptr_t endpointIfc3[MSD_INTERFACE_ENDPOINTS_NUMBER];
+#endif // (MSD_SUPPORT == 1)
+#if (DFU_SUPPORT == 1)
+ InterfaceDescriptor_t interface4;
+ DfuFunctionalDescriptor_t dfuFuncional;
+#endif // (MSD_SUPPORT == 1)
+} ConfigurationFrameResponse_t;
+END_PACK
+
+#endif /* _VCPDESCRIPTORS_H */
+// eof usbDescriptors.h \ No newline at end of file
diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/common/include/usbEnumeration.h b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/common/include/usbEnumeration.h
new file mode 100644
index 00000000..8c04756b
--- /dev/null
+++ b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/common/include/usbEnumeration.h
@@ -0,0 +1,53 @@
+/****************************************************************************//**
+ \file usbEnumeration.h
+
+ \brief Declaration of enumeration process command.
+
+ \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:
+ 12/09/08 A. Khromykh - Created
+ 26/08/11 N. Fomin - Modified (MSD support)
+*******************************************************************************/
+#ifndef _USBENUMERATION_H
+#define _USBENUMERATION_H
+
+/******************************************************************************
+ Includes section
+******************************************************************************/
+#include <types.h>
+
+/******************************************************************************
+ Prototypes section
+******************************************************************************/
+/******************************************************************************
+Standard usb request handler
+
+Parameters:
+ data - pointer to host's request
+******************************************************************************/
+void runtimeRequestHandler(uint8_t *data);
+
+/******************************************************************************
+Standard usb request handler
+
+Parameters:
+ data - pointer to host's request
+******************************************************************************/
+void usbBusResetAction(void);
+
+#if defined(AT91SAM7X256) || defined(AT91SAM3S4C)
+/******************************************************************************
+send zero-length packet through control pipe
+******************************************************************************/
+void sendZLP(void);
+#endif
+
+#endif /* _USBENUMERATION_H */
+// eof usbEnumeration.h \ No newline at end of file
diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/common/include/usbSetupProcess.h b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/common/include/usbSetupProcess.h
new file mode 100644
index 00000000..f499a80e
--- /dev/null
+++ b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/common/include/usbSetupProcess.h
@@ -0,0 +1,51 @@
+/****************************************************************************//**
+ \file usbSetupProcess.h
+
+ \brief Declaration of setup (after numeration) process command.
+
+ \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:
+ 26/08/11 N. Fomin - Created
+*******************************************************************************/
+#ifndef _USBESETUPPROCESS_H
+#define _USBESETUPPROCESS_H
+
+/******************************************************************************
+ Includes section
+******************************************************************************/
+#include <types.h>
+
+/******************************************************************************
+ Types section
+******************************************************************************/
+BEGIN_PACK
+// Usb host request
+typedef struct PACK
+{
+ uint8_t bmRequestType;
+ uint8_t bRequest;
+ uint16_t wValue;
+ uint16_t wIndex;
+ uint16_t wLength;
+} UsbRequest_t;
+END_PACK
+/******************************************************************************
+ Prototypes section
+******************************************************************************/
+/******************************************************************************
+Usb setup process request handler
+
+Parameters:
+ data - pointer to host's request
+******************************************************************************/
+void setupProcessRequestHandler(uint8_t *data);
+
+#endif /* _USBESETUPPROCESS_H */
+// eof usbSetupProcess.h \ No newline at end of file
diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/common/src/usbDescriptors.c b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/common/src/usbDescriptors.c
new file mode 100644
index 00000000..663beeee
--- /dev/null
+++ b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/common/src/usbDescriptors.c
@@ -0,0 +1,424 @@
+/****************************************************************************//**
+ \file usbDescriptors.c
+
+ \brief Virtual communication port descriptors.
+
+ \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:
+ 11/09/08 A. Khromykh - Created
+ 26/08/11 N. Fomin - Modified (MSD support)
+*******************************************************************************/
+/******************************************************************************
+ Includes section
+******************************************************************************/
+#include <usbDescriptors.h>
+
+/******************************************************************************
+ Define(s) section
+******************************************************************************/
+// Descriptor's type definitions.
+#define DESCRIPTOR_TYPE_DEVICE 0x01
+#define DESCRIPTOR_TYPE_CONFIGURATION 0x02
+#define DESCRIPTOR_TYPE_STRING 0x03
+#define DESCRIPTOR_TYPE_INTERFACE 0x04
+#define DESCRIPTOR_TYPE_CS_INTERFACE 0x24
+#define DESCRIPTOR_TYPE_ENDPOINT 0x05
+#define DESCRIPTOR_TYPE_DEVICE_QUALIFIER 0x06
+#define DESCRIPTOR_TYPE_OTHER_SPEED_CFG 0x07
+#define DESCRIPTOR_TYPE_INTERFACE_POWER 0x08
+#define DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION 0x0B
+#define DESCRIPTOR_TYPE_DFU_FUNCTIONAL 0x21
+
+// String definitions' indexes.
+#define MANUFACTURER_STRING_INDEX 0
+#define PRODUCT_STRING_INDEX 0
+#define SERIAL_NUMBER_STRING_INDEX 0
+#define CONFIGURATION_STRING_INDEX 0
+#define FIRST_INTERFACE_STRING_INDEX 0
+#define SECOND_INTERFACE_STRING_INDEX 0
+#define THIRD_INTERFACE_STRING_INDEX 0
+#define FOURTH_INTERFACE_STRING_INDEX 0
+
+#define VENDOR_ID 0x03EB // Atmel
+#if (APP_INTERFACE == APP_INTERFACE_VCP)
+ #if (MSD_SUPPORT == 1)
+ #if (DFU_SUPPORT == 1)
+ #define PRODUCT_ID 0x6122
+ #else
+ #define PRODUCT_ID 0x6121
+ #endif // (DFU_SUPPORT == 1)
+ #else // (MSD_SUPPORT == 1)
+ #if (DFU_SUPPORT == 1)
+ #define PRODUCT_ID 0x6120
+ #else
+ #define PRODUCT_ID 0x6119
+ #endif // (DFU_SUPPORT == 1)
+ #endif // (MSD_SUPPORT == 1)
+#else // (APP_INTERFACE == APP_INTERFACE_VCP)
+ #if (MSD_SUPPORT == 1)
+ #if (DFU_SUPPORT == 1)
+ #define PRODUCT_ID 0x6124
+ #else
+ #define PRODUCT_ID 0x6123
+ #endif // (DFU_SUPPORT == 1)
+ #else // (MSD_SUPPORT == 1)
+ #define PRODUCT_ID 0x6119
+ #endif // (MSD_SUPPORT == 1)
+#endif // (APP_INTERFACE == APP_INTERFACE_VCP)
+
+#define DEVICE_RELEASE 0x0001
+#define USB_BUS_RELEASE 0x0200
+
+// Number of possible configurations for the device.
+#define NUMBER_OF_CONFIGURATIONS 0x01
+
+// Class specification parameters of communication device.
+#define CDC_DEVICE_CLASS 0x02
+#define CDC_DEVICE_SUBCLASS 0x00
+#define CDC_DEVICE_PROTOCOL 0x00
+
+// Class specification parameters of mass storage device.
+#define MSC_DEVICE_CLASS 0x00
+#define MSC_DEVICE_SUBCLASS 0x00
+#define MSC_DEVICE_PROTOCOL 0x00
+
+// Class specification parameters of composite device with CDC.
+#define COMB_DEVICE_CLASS 0xef
+#define COMB_DEVICE_SUBCLASS 0x02
+#define COMB_DEVICE_PROTOCOL 0x01
+
+// Endpoint definitions' sizes.
+#if defined(AT91SAM7X256)
+ #define SZ_CONTROL_ENDPOINT 0x08 // endpoint 0 is control pipe
+#elif defined(AT90USB1287) || defined(AT91SAM3S4C)
+ #define SZ_CONTROL_ENDPOINT 0x40 // endpoint 0 is control pipe
+#endif
+#define SZ_ACM_INT_ENDPOINT 0x0008 // endpoint 3 is interrupt pipe for abstraction control model
+#define SZ_CDC_BULKIN_ENDPOINT BULK_SIZE // endpoint 2 is bulk pipe for input communication data
+#define SZ_CDC_BULKOUT_ENDPOINT BULK_SIZE // endpoint 1 is bulk pipe for output communication data
+#define SZ_MSC_BULKIN_ENDPOINT BULK_SIZE // endpoint 2 is bulk pipe for input communication data
+#define SZ_MSC_BULKOUT_ENDPOINT BULK_SIZE // endpoint 1 is bulk pipe for output communication data
+
+// Configuration descriptor parameters.
+// Common size of all descriptors in the vcp configuration besides configuration descriptor
+#define COMMON_VCP_CFG_SIZE (sizeof(InterfaceDescriptor_t) + \
+ sizeof(HeaderFunctionalDescriptor_t) + \
+ sizeof(CallManagmentFunctionalDescriptor_t) + \
+ sizeof(AbstractControlManagmentDescriptor_t) + \
+ sizeof(UnionFunctionalDescriptor_t) + \
+ sizeof(HAL_UsbEndPointDescptr_t) + \
+ sizeof(InterfaceDescriptor_t) + \
+ sizeof(HAL_UsbEndPointDescptr_t) + \
+ sizeof(HAL_UsbEndPointDescptr_t))
+// Common size of all descriptors in the msd configuration besides configuration descriptor
+#define COMMON_MSD_CFG_SIZE (sizeof(InterfaceDescriptor_t) + \
+ sizeof(HAL_UsbEndPointDescptr_t) + \
+ sizeof(HAL_UsbEndPointDescptr_t))
+// Commom size of all descriptors for DFU besides configuration descriptor
+#define COMMON_DFU_CFG_SIZE (sizeof(InterfaceDescriptor_t) + \
+ sizeof(DfuFunctionalDescriptor_t))
+
+#if (APP_INTERFACE == APP_INTERFACE_VCP)
+ #if (MSD_SUPPORT == 1)
+ #if (DFU_SUPPORT == 1)
+ #define CFG_SIZE (COMMON_DFU_CFG_SIZE + COMMON_MSD_CFG_SIZE + COMMON_VCP_CFG_SIZE + sizeof(ConfigurationDescriptor_t) + \
+ sizeof(InterfaceAssociationDescriptor_t))
+ #else // (DFU_SUPPORT == 1)
+ #define CFG_SIZE (COMMON_MSD_CFG_SIZE + COMMON_VCP_CFG_SIZE + sizeof(ConfigurationDescriptor_t) + \
+ sizeof(InterfaceAssociationDescriptor_t))
+ #endif // (DFU_SUPPORT == 1)
+ #else // (MSD_SUPPORT == 1)
+ #if (DFU_SUPPORT == 1)
+ #define CFG_SIZE (COMMON_DFU_CFG_SIZE + COMMON_VCP_CFG_SIZE + sizeof(ConfigurationDescriptor_t) + \
+ sizeof(InterfaceAssociationDescriptor_t))
+ #else // (DFU_SUPPORT == 1)
+ #define CFG_SIZE (COMMON_VCP_CFG_SIZE + sizeof(ConfigurationDescriptor_t))
+ #endif // (DFU_SUPPORT == 1)
+ #endif
+#else // (APP_INTERFACE == APP_INTERFACE_VCP)
+ #if (DFU_SUPPORT == 1)
+ #define CFG_SIZE (COMMON_DFU_CFG_SIZE + COMMON_MSD_CFG_SIZE + sizeof(ConfigurationDescriptor_t))
+ #else // (DFU_SUPPORT == 1)
+ #define CFG_SIZE (COMMON_MSD_CFG_SIZE + sizeof(ConfigurationDescriptor_t))
+ #endif // (DFU_SUPPORT == 1)
+#endif
+
+#if (APP_INTERFACE == APP_INTERFACE_VCP)
+ #if (MSD_SUPPORT == 1)
+ #if (DFU_SUPPORT == 1)
+ #define NUMBER_OF_INTERFACES 0x04
+ #else
+ #define NUMBER_OF_INTERFACES 0x03
+ #endif
+ #else
+ #define NUMBER_OF_INTERFACES 0x02
+ #endif
+#else
+ #if (DFU_SUPPORT == 1)
+ #define NUMBER_OF_INTERFACES 0x02
+ #else
+ #define NUMBER_OF_INTERFACES 0x01
+ #endif
+#endif
+
+#define CFG_SELECTING_VALUE 0x01
+#define CFG_CHARACTERISTICS 0x80 // D7 is reserved and must be set to one for historical reasons.
+#define MAXIMUM_POWER_CONSUMPTION 0x32 // Step is 2 mA.
+
+// Parameters for interfaces descriptors
+#define ALTERNATIVE_SETTING 0x00
+#define NUMBER_USING_ENDPOINTS_FIRST_IFC 0x01
+#define NUMBER_USING_ENDPOINTS_SECOND_IFC 0x02
+#define NUMBER_USING_ENDPOINTS_THIRD_IFC 0x02
+#define NUMBER_USING_ENDPOINTS_FOURTH_IFC 0x00
+#define FIRST_IFC_CLASS 0x02
+#define FIRST_IFC_SUBCLASS 0x02
+#define FIRST_IFC_PROTOCOL 0x00
+#define SECOND_IFC_CLASS 0x0A
+#define SECOND_IFC_SUBCLASS 0x00
+#define SECOND_IFC_PROTOCOL 0x00
+#define THIRD_IFC_CLASS 0x08
+#define THIRD_IFC_SUBCLASS 0x06
+#define THIRD_IFC_PROTOCOL 0x50
+#define FOURTH_IFC_CLASS 0xFE
+#define FOURTH_IFC_SUBCLASS 0x01
+#define FOURTH_IFC_PROTOCOL 0x01
+
+// Header descriptor parameters.
+#define HEADER_SUBTYPE 0x00
+#define CDC_CLASS_DEFINITION 0x0110
+
+// call management functional descriptor parameters.
+#define CALL_MNGMT_SUBTYPE 0x01
+#define CALL_MNGMT_CAPABILITIES 0x01 // See cdc specification.
+#define NUMBER_OF_CALL_MNGMT 0x00
+
+// abstract control management functional descriptor parameters.
+#define ACM_SUBTYPE 0x02
+#define ACM_CAPABILITIES 0x02 // see cdc specification
+
+// Union functional descriptor parameters.
+#define UNION_SUBTYPE 0x06
+#define MASTER_IFC_TYPE 0x00
+#define SLAVE0_IFC_TYPE 0x01
+
+// Endpoints descriptor parameters.
+#define ADDRESS_CDC_INTERRUPT_PIPE 0x83
+#define ADDRESS_CDC_BULKIN_PIPE 0x82
+#define ADDRESS_CDC_BULKOUT_PIPE 0x01
+#define INTERRUPT_TYPE_PIPE 0x03
+#define BULK_TYPE_PIPE 0x02
+#define INTERRUPT_PIPE_POLLING 0x0A // step is 1 ms
+#define BULK_MAX_SPEED 0x00
+
+// dfu functional descriptor parameters
+#define DFU_ATTRIBUTES 0x01
+#define DFU_DETACH_TIMEOUT 0xFFFF
+#define DFU_TRANSFER_SIZE SZ_CONTROL_ENDPOINT
+#define DFU_VERSION 0x0101
+
+/******************************************************************************
+ Constants section
+******************************************************************************/
+const DeviceDescriptor_t deviceDescr = {
+ sizeof(DeviceDescriptor_t), // Size of this descriptor in bytes
+ DESCRIPTOR_TYPE_DEVICE, // Descriptor type
+ USB_BUS_RELEASE, // USB specification release number in BCD format
+#if (APP_INTERFACE == APP_INTERFACE_VCP)
+ #if (MSD_SUPPORT != 1) && (DFU_SUPPORT != 1)
+ CDC_DEVICE_CLASS, // Device class code
+ CDC_DEVICE_SUBCLASS, // Device subclass code
+ CDC_DEVICE_PROTOCOL, // Device protocol code
+ #else // (MSD_SUPPORT != 1) && (DFU_SUPPORT != 1)
+ COMB_DEVICE_CLASS, // Device class code
+ COMB_DEVICE_SUBCLASS, // Device subclass code
+ COMB_DEVICE_PROTOCOL, // Device protocol code
+ #endif // (MSD_SUPPORT != 1) && (DFU_SUPPORT != 1)
+#else // (APP_INTERFACE == APP_INTERFACE_VCP)
+ MSC_DEVICE_CLASS, // Device class code
+ MSC_DEVICE_SUBCLASS, // Device subclass code
+ MSC_DEVICE_PROTOCOL, // Device protocol code
+#endif // (APP_INTERFACE == APP_INTERFACE_VCP)
+ SZ_CONTROL_ENDPOINT, // Maximum packet size of endpoint 0 (in bytes)
+ VENDOR_ID, // Vendor ID
+ PRODUCT_ID, // Product ID
+ DEVICE_RELEASE, // Device release number in BCD format
+ MANUFACTURER_STRING_INDEX, // Index of the manufacturer string descriptor
+ PRODUCT_STRING_INDEX, // Index of the product string descriptor
+ SERIAL_NUMBER_STRING_INDEX, // Index of the serial number string descriptor
+ NUMBER_OF_CONFIGURATIONS // Number of possible configurations for the device
+};
+
+const ConfigurationFrameResponse_t usbConfigDescr = {
+ { // configuration
+ sizeof(ConfigurationDescriptor_t), // Size of the descriptor in bytes
+ DESCRIPTOR_TYPE_CONFIGURATION, // Descriptor type
+ CFG_SIZE, // Length of all descriptors returned along with this configuration descriptor
+ NUMBER_OF_INTERFACES, // Number of interfaces in this configuration
+ CFG_SELECTING_VALUE, // Value for selecting this configuration
+ CONFIGURATION_STRING_INDEX, // Index of the configuration string descriptor
+ CFG_CHARACTERISTICS, // Configuration characteristics
+ MAXIMUM_POWER_CONSUMPTION // Maximum power consumption of the device when in this configuration
+ },
+#if (APP_INTERFACE == APP_INTERFACE_VCP)
+ #if (MSD_SUPPORT == 1) || (DFU_SUPPORT == 1)
+ { // cdcIAD
+ sizeof(InterfaceAssociationDescriptor_t), // Size of this descriptor in bytes
+ DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION, // Descriptor type
+ NUMBER_OF_FIRST_INTERFACE, // Interface number of the first interface that is associated with this function
+ 2, // Number of contiguous interfaces that are associated with this function
+ CDC_DEVICE_CLASS, // Class code
+ CDC_DEVICE_SUBCLASS, // Subclass code
+ CDC_DEVICE_PROTOCOL, // Protocol code
+ FIRST_INTERFACE_STRING_INDEX //Index of string descriptor describing this function
+ },
+ #endif // (MSD_SUPPORT == 1) || (DFU_SUPPORT == 1)
+ { // interface 1
+ sizeof(InterfaceDescriptor_t), // Size of the descriptor in bytes
+ DESCRIPTOR_TYPE_INTERFACE, // Descriptor type
+ NUMBER_OF_FIRST_INTERFACE, // Number of the interface in its configuration
+ ALTERNATIVE_SETTING, // Value to select this alternate interface setting
+ NUMBER_USING_ENDPOINTS_FIRST_IFC, // Number of endpoints used by the interface (excluding endpoint 0)
+ FIRST_IFC_CLASS, // Interface class code
+ FIRST_IFC_SUBCLASS, // Interface subclass code
+ FIRST_IFC_PROTOCOL, // Interface protocol code
+ FIRST_INTERFACE_STRING_INDEX // Index of the interface string descriptor
+ },
+ { // header functional descriptor
+ sizeof(HeaderFunctionalDescriptor_t), // Size of the descriptor in bytes
+ DESCRIPTOR_TYPE_CS_INTERFACE, // Descriptor type
+ HEADER_SUBTYPE, // Header functional descriptor subtype
+ CDC_CLASS_DEFINITION // USB Class Definitions for Communication
+ },
+ { // Call Management Functional Descriptor
+ sizeof(CallManagmentFunctionalDescriptor_t), // Size of the descriptor in bytes
+ DESCRIPTOR_TYPE_CS_INTERFACE, // Descriptor type
+ CALL_MNGMT_SUBTYPE, // bDescriptor subtype: Call Management Func
+ CALL_MNGMT_CAPABILITIES, // bmCapabilities: D1 + D0
+ NUMBER_OF_CALL_MNGMT // bDataInterface: Data Class Interface 1
+ },
+ { // Abstract Control Management Functional Descriptor
+ sizeof(AbstractControlManagmentDescriptor_t), // Size of the descriptor in bytes
+ DESCRIPTOR_TYPE_CS_INTERFACE, // Descriptor type
+ ACM_SUBTYPE, // Abstract Control Management Functional descriptor subtype
+ ACM_CAPABILITIES // bmCapabilities: see cdc specification (support command type)
+ },
+ { // Union Functional Descriptor
+ sizeof(UnionFunctionalDescriptor_t), // Size of the descriptor in bytes
+ DESCRIPTOR_TYPE_CS_INTERFACE, // Descriptor type
+ UNION_SUBTYPE, // Union Functional descriptor subtype
+ MASTER_IFC_TYPE, // bMasterInterface: CDC Interface
+ SLAVE0_IFC_TYPE // bSlaveInterface0: Data Class Interface
+ },
+ { // endpoint 3
+ sizeof(HAL_UsbEndPointDescptr_t), // Size of the descriptor in bytes
+ DESCRIPTOR_TYPE_ENDPOINT, // Descriptor type
+ ADDRESS_CDC_INTERRUPT_PIPE, // Address and direction of the endpoint
+ INTERRUPT_TYPE_PIPE, // Endpoint type and additional characteristics (for isochronous endpoints)
+ SZ_ACM_INT_ENDPOINT, // Maximum packet size (in bytes) of the endpoint
+ INTERRUPT_PIPE_POLLING // Polling rate of the endpoint
+ },
+ { // interface 2
+ sizeof(InterfaceDescriptor_t), // Size of the descriptor in bytes
+ DESCRIPTOR_TYPE_INTERFACE, // Descriptor type
+ NUMBER_OF_SECOND_INTERFACE, // Number of the interface in its configuration
+ ALTERNATIVE_SETTING, // Value to select this alternate interface setting
+ NUMBER_USING_ENDPOINTS_SECOND_IFC, // Number of endpoints used by the interface (excluding endpoint 0)
+ SECOND_IFC_CLASS, // Interface class code
+ SECOND_IFC_SUBCLASS, // Interface subclass code
+ SECOND_IFC_PROTOCOL, // Interface protocol code
+ SECOND_INTERFACE_STRING_INDEX // Index of the interface string descriptor
+ },
+ {{ // endpoint 1
+ sizeof(HAL_UsbEndPointDescptr_t), // Size of the descriptor in bytes
+ DESCRIPTOR_TYPE_ENDPOINT, // Descriptor type
+ ADDRESS_CDC_BULKOUT_PIPE, // Address and direction of the endpoint
+ BULK_TYPE_PIPE, // Endpoint type and additional characteristics (for isochronous endpoints)
+ SZ_CDC_BULKOUT_ENDPOINT, // Maximum packet size (in bytes) of the endpoint
+ BULK_MAX_SPEED // Polling rate of the endpoint
+ },
+ { // endpoint 2
+ sizeof(HAL_UsbEndPointDescptr_t), // Size of the descriptor in bytes
+ DESCRIPTOR_TYPE_ENDPOINT, // Descriptor type
+ ADDRESS_CDC_BULKIN_PIPE, // Address and direction of the endpoint
+ BULK_TYPE_PIPE, // Endpoint type and additional characteristics (for isochronous endpoints)
+ SZ_CDC_BULKIN_ENDPOINT, // Maximum packet size (in bytes) of the endpoint
+ BULK_MAX_SPEED // Polling rate of the endpoint
+ }},
+#endif // (APP_INTERFACE == APP_INTERFACE_VCP)
+#if (MSD_SUPPORT == 1)
+ { // interface 3
+ sizeof(InterfaceDescriptor_t), // Size of the descriptor in bytes
+ DESCRIPTOR_TYPE_INTERFACE, // Descriptor type
+#if (APP_INTERFACE == APP_INTERFACE_VCP)
+ NUMBER_OF_THIRD_INTERFACE, // Number of the interface in its configuration
+#else
+ NUMBER_OF_FIRST_INTERFACE, // Number of the interface in its configuration
+#endif
+ ALTERNATIVE_SETTING, // Value to select this alternate interface setting
+ NUMBER_USING_ENDPOINTS_THIRD_IFC, // Number of endpoints used by the interface (excluding endpoint 0)
+ THIRD_IFC_CLASS, // Interface class code
+ THIRD_IFC_SUBCLASS, // Interface subclass code
+ THIRD_IFC_PROTOCOL, // Interface protocol code
+ THIRD_INTERFACE_STRING_INDEX // Index of the interface string descriptor
+ },
+ {{ // endpoint 6
+ sizeof(HAL_UsbEndPointDescptr_t), // Size of the descriptor in bytes
+ DESCRIPTOR_TYPE_ENDPOINT, // Descriptor type
+ ADDRESS_MSC_BULKOUT_PIPE, // Address and direction of the endpoint
+ BULK_TYPE_PIPE, // Endpoint type and additional characteristics (for isochronous endpoints)
+ SZ_MSC_BULKOUT_ENDPOINT, // Maximum packet size (in bytes) of the endpoint
+ BULK_MAX_SPEED // Polling rate of the endpoint
+ },
+ { // endpoint 5
+ sizeof(HAL_UsbEndPointDescptr_t), // Size of the descriptor in bytes
+ DESCRIPTOR_TYPE_ENDPOINT, // Descriptor type
+ ADDRESS_MSC_BULKIN_PIPE, // Address and direction of the endpoint
+ BULK_TYPE_PIPE, // Endpoint type and additional characteristics (for isochronous endpoints)
+ SZ_MSC_BULKIN_ENDPOINT, // Maximum packet size (in bytes) of the endpoint
+ BULK_MAX_SPEED // Polling rate of the endpoint
+ }},
+#endif // (MSD_SUPPORT == 1)
+#if (DFU_SUPPORT == 1)
+ { // interface 4
+ sizeof(InterfaceDescriptor_t), // Size of the descriptor in bytes
+ DESCRIPTOR_TYPE_INTERFACE, // Descriptor type
+#if (APP_INTERFACE == APP_INTERFACE_VCP)
+ #if (MSD_SUPPORT == 1)
+ NUMBER_OF_FOURTH_INTERFACE, // Number of the interface in its configuration
+ #else
+ NUMBER_OF_THIRD_INTERFACE, // Number of the interface in its configuration
+ #endif // (MSD_SUPPORT == 1)
+#else
+ #if (MSD_SUPPORT == 1)
+ NUMBER_OF_SECOND_INTERFACE, // Number of the interface in its configuration
+ #else
+ #error
+ #endif // (MSD_SUPPORT == 1)
+#endif // (APP_INTERFACE == APP_INTERFACE_VCP)
+ ALTERNATIVE_SETTING, // Value to select this alternate interface setting
+ NUMBER_USING_ENDPOINTS_FOURTH_IFC, // Number of endpoints used by the interface (excluding endpoint 0)
+ FOURTH_IFC_CLASS, // Interface class code
+ FOURTH_IFC_SUBCLASS, // Interface subclass code
+ FOURTH_IFC_PROTOCOL, // Interface protocol code
+ FOURTH_INTERFACE_STRING_INDEX // Index of the interface string descriptor
+ },
+ { // Functional descriptor
+ sizeof(DfuFunctionalDescriptor_t), // Size of the descriptor in bytes
+ DESCRIPTOR_TYPE_DFU_FUNCTIONAL, // Descriptor type
+ DFU_ATTRIBUTES, // Descriptor attributes
+ DFU_DETACH_TIMEOUT, // Wait timeout of USB reset after DFU_DETACH request recieption
+ DFU_TRANSFER_SIZE, // Maximum number of bytes that the device can accept per control-write transaction
+ DFU_VERSION // DFU Version
+ }
+#endif // (DFU_SUPPORT == 1)
+};
+
+// eof usbDescriptors.c
diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/common/src/usbEnumeration.c b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/common/src/usbEnumeration.c
new file mode 100644
index 00000000..f430b08d
--- /dev/null
+++ b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/common/src/usbEnumeration.c
@@ -0,0 +1,231 @@
+/****************************************************************************//**
+ \file usbEnumeration.c
+
+ \brief Implementation of enumeration proccess.
+
+ \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:
+ 11/09/08 A. Khromykh - Created
+ 26/08/11 N. Fomin - Modified (MSD support)
+*******************************************************************************/
+/******************************************************************************
+ Includes section
+******************************************************************************/
+#include <usbDescriptors.h>
+#if (APP_INTERFACE == APP_INTERFACE_VCP)
+ #include <vcpVirtualUsart.h>
+#endif // (APP_INTERFACE == APP_INTERFACE_VCP)
+#if (MSD_SUPPORT == 1)
+ #include <hsmci.h>
+#endif // (MSD_SUPPORT == 1)
+#include <usbSetupProcess.h>
+#include <massStorageDevice.h>
+#include <usbEnumeration.h>
+
+/******************************************************************************
+ Define(s) section
+******************************************************************************/
+// request codes for runtime work
+#define USB_GET_STATUS 0
+#define USB_CLEAR_FEATURE 1
+#define USB_SET_FEATURE 3
+#define USB_SET_ADDRESS 5
+#define USB_GET_DESCRIPTOR 6
+#define USB_SET_DESCRIPTOR 7
+#define USB_GET_CONFIGURATION 8
+#define USB_SET_CONFIGURATION 9
+#define USB_GET_INTERFACE 10
+#define USB_SET_INTERFACE 11
+#define USB_SYNCH_FRAME 12
+
+// Descriptor type definitions.
+#define DESCRIPTOR_TYPE_DEVICE 0x01
+#define DESCRIPTOR_TYPE_CONFIGURATION 0x02
+#define DESCRIPTOR_TYPE_STRING 0x03
+#define DESCRIPTOR_TYPE_INTERFACE 0x04
+#define DESCRIPTOR_TYPE_CS_INTERFACE 0x24
+#define DESCRIPTOR_TYPE_ENDPOINT 0x05
+#define DESCRIPTOR_TYPE_DEVICE_QUALIFIER 0x06
+#define DESCRIPTOR_TYPE_OTHER_SPEED_CFG 0x07
+#define DESCRIPTOR_TYPE_INTERFACE_POWER 0x08
+
+/******************************************************************************
+ External global variables section
+******************************************************************************/
+extern const ConfigurationFrameResponse_t usbConfigDescr;
+extern const DeviceDescriptor_t deviceDescr;
+#if (APP_INTERFACE == APP_INTERFACE_VCP)
+ extern HAL_UsartDescriptor_t *vcpPointDescrip;
+#endif // (APP_INTERFACE == APP_INTERFACE_VCP)
+#if (MSD_SUPPORT == 1)
+ extern HAL_HsmciDescriptor_t *msdPointDescr;
+#endif // (MSD_SUPPORT == 1)
+
+/******************************************************************************
+ Prototypes section
+******************************************************************************/
+/******************************************************************************
+usb bulk out receiving callbacks
+
+Parameters:
+ pArg - argument
+ status - index of the requested descriptor
+ length - maximum number of bytes to return
+******************************************************************************/
+void vcpRcvCallback(void *pArg, uint8_t status, uint16_t transferred, uint16_t remaining);
+void msdRcvCallback(void *pArg, uint8_t status, uint16_t transferred, uint16_t remaining);
+
+/******************************************************************************
+ Global variables section
+******************************************************************************/
+// virtual communication port address on usb
+static uint16_t usbAddress = 0;
+
+/******************************************************************************
+ Implementations section
+******************************************************************************/
+#if defined(AT91SAM7X256) || defined(AT91SAM3S4C)
+/******************************************************************************
+send zero-length packet through control pipe
+******************************************************************************/
+void sendZLP(void)
+{
+ // Acknowledge the request
+ HAL_UsbWrite(0, NULL, 0, NULL, NULL);
+}
+#endif
+
+/******************************************************************************
+Configures the device by setting it into the Configured state.
+
+Parameters:
+ cfgnum - configuration number to set
+******************************************************************************/
+void runtimeSetConfiguration(uint8_t cfgnum)
+{
+ // Set & save the desired configuration
+ HAL_SetConfiguration(cfgnum);
+
+ #if defined(AT91SAM7X256) || defined(AT91SAM3S4C)
+ // Acknowledge the request
+ sendZLP();
+ #endif
+}
+
+/******************************************************************************
+runtime get descriptor command handler
+
+Parameters:
+ type - type of the requested descriptor
+ index - index of the requested descriptor
+ length - maximum number of bytes to return
+******************************************************************************/
+void runtimeGetDescriptorHandler(uint8_t type, uint8_t index, uint16_t length)
+{
+ (void)index;
+
+ // Check the descriptor type
+ switch (type)
+ {
+ case DESCRIPTOR_TYPE_DEVICE:
+ // Adjust length and send descriptor
+ if (length > deviceDescr.bLength)
+ length = deviceDescr.bLength;
+ HAL_UsbWrite(0, (void *)&deviceDescr, length, 0, 0);
+ break;
+ case DESCRIPTOR_TYPE_CONFIGURATION:
+ // Adjust length and send descriptor
+ if (length > usbConfigDescr.config.wTotalLength)
+ length = usbConfigDescr.config.wTotalLength;
+ HAL_UsbWrite(0, (void *)&usbConfigDescr, length, 0, 0);
+ break;
+ case DESCRIPTOR_TYPE_INTERFACE:
+ HAL_Stall(0);
+ break;
+ case DESCRIPTOR_TYPE_DEVICE_QUALIFIER:
+ HAL_Stall(0);
+ break;
+ case DESCRIPTOR_TYPE_OTHER_SPEED_CFG:
+ HAL_Stall(0);
+ break;
+ case DESCRIPTOR_TYPE_ENDPOINT:
+ HAL_Stall(0);
+ break;
+ case DESCRIPTOR_TYPE_STRING:
+ HAL_Stall(0);
+ break;
+ default:
+ HAL_Stall(0);
+ break;
+ }
+}
+
+/******************************************************************************
+Standard usb request handler
+
+Parameters:
+ data - pointer to host's request
+******************************************************************************/
+void runtimeRequestHandler(uint8_t *data)
+{
+ UsbRequest_t *pRequest = NULL;
+
+ pRequest = (UsbRequest_t *)data;
+ if (NULL == pRequest)
+ return;
+
+ // Check request code
+ switch (pRequest->bRequest)
+ {
+ case USB_GET_DESCRIPTOR:
+ // Send the requested descriptor
+ runtimeGetDescriptorHandler((uint8_t)(pRequest->wValue >> 8), (uint8_t)(pRequest->wValue), pRequest->wLength);
+ break;
+ case USB_SET_ADDRESS:
+ usbAddress = pRequest->wValue & 0x7F;
+ #if defined(AT91SAM7X256) || defined(AT91SAM3S4C)
+ HAL_UsbWrite(0, 0, 0, (TransferCallback_t) HAL_SetAddress, (void *)&usbAddress);
+ #elif defined(AT90USB1287)
+ HAL_SetAddress((uint8_t *)&usbAddress);
+ #endif
+ break;
+ case USB_SET_CONFIGURATION:
+ // Set the requested configuration
+ runtimeSetConfiguration((uint8_t)pRequest->wValue);
+ #if (APP_INTERFACE == APP_INTERFACE_VCP)
+ HAL_ConfigureEndpoint((void *)&(usbConfigDescr.endpointIfc1));
+ HAL_ConfigureEndpoint((void *)&(usbConfigDescr.endpointIfc2[0]));
+ HAL_ConfigureEndpoint((void *)&(usbConfigDescr.endpointIfc2[1]));
+ HAL_UsbRead(VCP_RECEIVE_PIPE, vcpPointDescrip->rxBuffer, BULK_SIZE, vcpRcvCallback, NULL);
+ #endif // (APP_INTERFACE == APP_INTERFACE_VCP)
+ #if (MSD_SUPPORT == 1)
+ HAL_ConfigureEndpoint((void *)&(usbConfigDescr.endpointIfc3[0]));
+ HAL_ConfigureEndpoint((void *)&(usbConfigDescr.endpointIfc3[1]));
+ HAL_UsbRead(MSD_RECEIVE_PIPE, msdPointDescr->dataTransferDescriptor->buffer, BULK_SIZE, msdRcvCallback, NULL);
+ #endif // (MSD_SUPPORT == 1)
+ break;
+ default:
+ setupProcessRequestHandler(data);
+ break;
+ }
+}
+
+/******************************************************************************
+Standard usb request handler
+
+Parameters:
+ data - pointer to host's request
+******************************************************************************/
+void usbBusResetAction(void)
+{
+ HAL_RegisterRequestHandler(runtimeRequestHandler);
+}
+
+// eof usbEnumeration.c
diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/common/src/usbSetupProcess.c b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/common/src/usbSetupProcess.c
new file mode 100644
index 00000000..2a3b305e
--- /dev/null
+++ b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/common/src/usbSetupProcess.c
@@ -0,0 +1,90 @@
+/****************************************************************************//**
+ \file usbSetupProcess.c
+
+ \brief Implementation of setup (after numeration) proccess.
+
+ \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:
+ 26/08/11 N. Fomin - Created
+*******************************************************************************/
+/******************************************************************************
+ Includes section
+******************************************************************************/
+#include <usbDescriptors.h>
+#if (APP_INTERFACE == APP_INTERFACE_VCP)
+ #include <vcpCdcProtocol.h>
+ #if (MSD_SUPPORT == 1)
+ #include <mscProtocol.h>
+ #endif // (MSD_SUPPORT == 1)
+#else
+ #if (MSD_SUPPORT == 1)
+ #include <mscProtocol.h>
+ #else
+ #include <usbSetupProcess.h>
+ #endif // (MSD_SUPPORT == 1)
+#endif // (APP_INTERFACE == APP_INTERFACE_VCP)
+#if (DFU_SUPPORT == 1)
+ #include <dfuProtocol.h>
+ #if (APP_INTERFACE != APP_INTERFACE_VCP) && (MSD_SUPPORT != 1)
+ #error
+ #endif // (APP_INTERFACE != APP_INTERFACE_VCP) || (MSD_SUPPORT != 1)
+#endif // (DFU_SUPPORT == 1)
+
+/******************************************************************************
+Usb setup process request handler
+
+Parameters:
+ data - pointer to host's request
+******************************************************************************/
+void setupProcessRequestHandler(uint8_t *data)
+{
+ UsbRequest_t *pRequest = NULL;
+
+ pRequest = (UsbRequest_t *)data;
+ if (NULL == pRequest)
+ return;
+
+ switch (pRequest->wIndex)
+ {
+ #if (APP_INTERFACE == APP_INTERFACE_VCP)
+ case NUMBER_OF_FIRST_INTERFACE:
+ vcpRequestHandler(data);
+ break;
+ #endif // (APP_INTERFACE == APP_INTERFACE_VCP)
+ /* MSC commands */
+ #if (MSD_SUPPORT == 1)
+ #if (APP_INTERFACE == APP_INTERFACE_VCP)
+ case NUMBER_OF_THIRD_INTERFACE:
+ #else
+ case NUMBER_OF_FIRST_INTERFACE:
+ #endif
+ msdRequestHandler(data);
+ break;
+ #endif // (MSD_SUPPORT == 1)
+ #if (DFU_SUPPORT == 1)
+ #if (APP_INTERFACE == APP_INTERFACE_VCP)
+ #if (MSD_SUPPORT == 1)
+ case NUMBER_OF_FOURTH_INTERFACE:
+ #else
+ case NUMBER_OF_THIRD_INTERFACE:
+ #endif
+ #else
+ case NUMBER_OF_SECOND_INTERFACE:
+ #endif // (APP_INTERFACE == APP_INTERFACE_VCP)
+ dfuRequestHandler(data);
+ break;
+ #endif // (DFU_SUPPORT == 1)
+ default:
+ HAL_Stall(0);
+ break;
+ }
+}
+
+// eof usbSetupProcess.c
diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBFIFO/include/usbFifoVirtualUsart.h b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBFIFO/include/usbFifoVirtualUsart.h
new file mode 100644
index 00000000..7b000818
--- /dev/null
+++ b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBFIFO/include/usbFifoVirtualUsart.h
@@ -0,0 +1,69 @@
+/**************************************************************************//**
+\file usbFifoVirtualUsart.h
+
+\brief The declaration of interfunction 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:
+ 15.07.11 A. Khromykh - Created
+*******************************************************************************/
+#ifndef _USBFIFOVIRTUALUSART_H
+#define _USBFIFOVIRTUALUSART_H
+
+/******************************************************************************
+ Includes section
+******************************************************************************/
+#include <gpio.h>
+
+/******************************************************************************
+ Prototypes section
+******************************************************************************/
+#if defined(ATMEGA128RFA1)
+
+// the macros for the manipulation by PC6 for binary decoder
+HAL_ASSIGN_PIN(PC6, D, 6);
+// the macros for the manipulation by PC7 for binary decoder
+HAL_ASSIGN_PIN(PC7, D, 7);
+// the macros for the manipulation by RD
+HAL_ASSIGN_PIN(RD, E, 5);
+// the macros for the manipulation by WR
+HAL_ASSIGN_PIN(WR, E, 4);
+
+#elif defined(ATMEGA1281) || defined(ATMEGA2561)
+
+// the macros for the manipulation by PC6 for binary decoder
+HAL_ASSIGN_PIN(PC6, C, 6);
+// the macros for the manipulation by PC7 for binary decoder
+HAL_ASSIGN_PIN(PC7, C, 7);
+// the macros for the manipulation by RD
+HAL_ASSIGN_PIN(RD, G, 1);
+// the macros for the manipulation by WR
+HAL_ASSIGN_PIN(WR, G, 0);
+
+#else
+ #error 'USB FIFO is not supported for this mcu.'
+#endif
+
+/**************************************************************************//**
+\brief Startup initialization.
+******************************************************************************/
+void usbfifoInit(void);
+
+/**************************************************************************//**
+\brief Clear startup initialization parameters
+******************************************************************************/
+void usbfifoUnInit(void);
+
+/**************************************************************************//**
+\brief USB FIFO driver task handler.
+******************************************************************************/
+void usbfifoHandler(void);
+
+#endif /* _USBFIFOVIRTUALUSART_H */
diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBFIFO/src/usbFifoFT245RL.c b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBFIFO/src/usbFifoFT245RL.c
new file mode 100644
index 00000000..8ba0d9c5
--- /dev/null
+++ b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBFIFO/src/usbFifoFT245RL.c
@@ -0,0 +1,290 @@
+/**************************************************************************//**
+\file usbFifoFT245RL.c
+
+\brief Implementation of FT245RL 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:
+ 12.07.11 A. Khromykh - Created
+*******************************************************************************/
+/******************************************************************************
+ Includes section
+******************************************************************************/
+#include <usbFifoVirtualUsart.h>
+#include <usart.h>
+#include <atomic.h>
+#include <irq.h>
+
+/******************************************************************************
+ Define(s) section
+******************************************************************************/
+#if defined(ATMEGA128RFA1)
+// data port
+#define USB_DATA_PORT PORTB
+#define USB_DATA_DDR DDRB
+#define USB_DATA_PIN PINB
+
+#elif defined(ATMEGA1281) || defined(ATMEGA2561)
+// data port
+#define USB_DATA_PORT PORTA
+#define USB_DATA_DDR DDRA
+#define USB_DATA_PIN PINA
+
+#endif
+
+#define HANDLERS_GET(A, I) memcpy_P(A, &usbfifoHandlers[I], sizeof(UsbfifoTask_t))
+
+/******************************************************************************
+ Types section
+******************************************************************************/
+typedef volatile uint8_t UsbfifoTaskBitMask_t;
+typedef void (* UsbfifoTask_t)(void);
+
+// USB FIFO task IDs.
+typedef enum
+{
+ USB_FIFO_TASK_RX,
+ USB_FIFO_TASK_TX,
+ USB_FIFO_TASKS_NUMBER
+} UsbfifoTaskId_t;
+
+/******************************************************************************
+ Prototypes section
+******************************************************************************/
+static void usbfifoRxBufferFiller(void);
+static void usbfifoTxBufferCleaner(void);
+static void usbfifoPostTask(UsbfifoTaskId_t taskId);
+static void usbfifoTxComplete(void);
+static void usbfifoRxComplete(void);
+
+/******************************************************************************
+ External global variables section
+******************************************************************************/
+// pointer to application uart descriptor
+extern HAL_UsartDescriptor_t *usbfifoPointDescrip;
+
+/******************************************************************************
+ Global variables section
+******************************************************************************/
+static volatile UsbfifoTaskBitMask_t usbfifoTaskBitMask = 0; // USB FIFO tasks' bit mask.
+static const UsbfifoTask_t PROGMEM_DECLARE(usbfifoHandlers[USB_FIFO_TASKS_NUMBER]) =
+{
+ usbfifoRxComplete,
+ usbfifoTxComplete
+}; // List Of possible USB FIFO tasks.
+
+/******************************************************************************
+ Implementations section
+******************************************************************************/
+/**************************************************************************//**
+\brief Startup initialization.
+******************************************************************************/
+void usbfifoInit(void)
+{
+ // init decoder input pins
+ GPIO_PC6_make_out();
+ GPIO_PC7_make_out();
+ // set pins to zero to select usb FIFO
+ GPIO_PC6_clr();
+ GPIO_PC7_clr();
+
+ // setup default value
+ GPIO_RD_set();
+ GPIO_WR_set();
+ // init R\W pins
+ GPIO_RD_make_out();
+ GPIO_WR_make_out();
+
+ // register RXF interrupt
+ HAL_RegisterIrq(IRQ_7, IRQ_LOW_LEVEL, usbfifoRxBufferFiller);
+ // register TXE interrupt
+ HAL_RegisterIrq(IRQ_6, IRQ_LOW_LEVEL, usbfifoTxBufferCleaner);
+
+ USB_DATA_DDR = 0;
+}
+
+/**************************************************************************//**
+\brief Clear startup initialization parameters
+******************************************************************************/
+void usbfifoUnInit(void)
+{
+ GPIO_PC6_make_in();
+ GPIO_PC7_make_in();
+
+ GPIO_RD_make_in();
+ GPIO_WR_make_in();
+
+ HAL_DisableIrq(IRQ_7);
+ HAL_UnregisterIrq(IRQ_7);
+
+ HAL_DisableIrq(IRQ_6);
+ HAL_UnregisterIrq(IRQ_6);
+}
+
+/**************************************************************************//**
+\brief Puts the byte received to the cyclic buffer.
+******************************************************************************/
+static void usbfifoRxBufferFiller(void)
+{
+ uint16_t old;
+ uint16_t poW;
+ uint16_t poR;
+ uint8_t *buffer;
+ HalUsartService_t *control;
+
+ if (!usbfifoPointDescrip)
+ { // unregistered intrrupt is occurred
+ HAL_DisableIrq(IRQ_7);
+ return;
+ }
+
+ control = &usbfifoPointDescrip->service;
+ poW = control->rxPointOfWrite;
+ poR = control->rxPointOfRead;
+ buffer = usbfifoPointDescrip->rxBuffer;
+
+ if (!buffer)
+ {
+ HAL_DisableIrq(IRQ_7);
+ return;
+ }
+
+ old = poW;
+
+ if (++poW == usbfifoPointDescrip->rxBufferLength)
+ poW = 0;
+
+ if (poW == poR)
+ { // Buffer full.
+ HAL_DisableIrq(IRQ_7);
+ return;
+ } // Buffer full.
+
+ control->rxPointOfWrite = poW;
+ GPIO_RD_clr();
+ NOP;
+ buffer[old] = USB_DATA_PIN;
+ GPIO_RD_set();
+ control->rxBytesInBuffer++;
+ usbfifoPostTask(USB_FIFO_TASK_RX);
+}
+
+/**************************************************************************//**
+\brief Reads byte from tx buffer and sends it to fifo.
+******************************************************************************/
+static void usbfifoTxBufferCleaner(void)
+{
+ HalUsartService_t *control;
+ uint16_t poW;
+ uint16_t poR;
+
+ if (!usbfifoPointDescrip)
+ { // unregistered intrrupt is occurred
+ HAL_DisableIrq(IRQ_6);
+ return;
+ }
+
+ control = &usbfifoPointDescrip->service;
+ poW = control->txPointOfWrite;
+ poR = control->txPointOfRead;
+
+ if (poW != poR)
+ {
+ // set port as output
+ USB_DATA_DDR = 0xFF;
+ NOP;
+ USB_DATA_PORT = usbfifoPointDescrip->txBuffer[poR++];
+ GPIO_WR_clr();
+ GPIO_WR_set();
+ USB_DATA_DDR = 0;
+
+ if (poR == usbfifoPointDescrip->txBufferLength)
+ poR = 0;
+
+ control->txPointOfRead = poR;
+ }
+ else
+ { // tx buffer is empty
+ HAL_DisableIrq(IRQ_6);
+ usbfifoPostTask(USB_FIFO_TASK_TX);
+ }
+}
+
+/**************************************************************************//**
+\brief Transmitting complete handler
+******************************************************************************/
+static void usbfifoTxComplete(void)
+{
+ if (NULL == usbfifoPointDescrip)
+ return;
+
+ if (0 == usbfifoPointDescrip->txBufferLength)
+ usbfifoPointDescrip->txBuffer = NULL; // nulling pointer for callback mode
+
+ if (usbfifoPointDescrip->txCallback)
+ usbfifoPointDescrip->txCallback();
+}
+
+/**************************************************************************//**
+\brief Byte is received handler
+******************************************************************************/
+static void usbfifoRxComplete(void)
+{
+ HalUsartService_t *control;
+ uint16_t number;
+
+ if (NULL == usbfifoPointDescrip)
+ return;
+
+ control = &usbfifoPointDescrip->service;
+ ATOMIC_SECTION_ENTER
+ number = control->rxBytesInBuffer;
+ ATOMIC_SECTION_LEAVE
+
+ if (number)
+ if (NULL != usbfifoPointDescrip->rxCallback)
+ usbfifoPointDescrip->rxCallback(number);
+}
+
+/**************************************************************************//**
+\brief USB FIFO driver task handler.
+******************************************************************************/
+void usbfifoHandler(void)
+{
+ UsbfifoTask_t handler;
+ uint8_t mask = 1;
+ UsbfifoTaskId_t index = 0;
+
+ for ( ; index < USB_FIFO_TASKS_NUMBER; index++, mask <<= 1)
+ {
+ if (usbfifoTaskBitMask & mask)
+ {
+ ATOMIC_SECTION_ENTER
+ usbfifoTaskBitMask ^= mask;
+ ATOMIC_SECTION_LEAVE
+ HANDLERS_GET(&handler, index);
+ handler();
+ }
+ }
+}
+
+/**************************************************************************//**
+\brief Posts specific USART task.
+
+\param[in]
+ taskId - unique identifier of the task to be posted.
+******************************************************************************/
+static void usbfifoPostTask(UsbfifoTaskId_t taskId)
+{
+ usbfifoTaskBitMask |= (UsbfifoTaskBitMask_t)1 << taskId;
+ halPostTask4(HAL_EXT_HANDLER);
+}
+
+// eof usbFifoFT245RL.c
diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBFIFO/src/usbFifoVirtualUsart.c b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBFIFO/src/usbFifoVirtualUsart.c
new file mode 100644
index 00000000..1a909d38
--- /dev/null
+++ b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBFIFO/src/usbFifoVirtualUsart.c
@@ -0,0 +1,250 @@
+/****************************************************************************//**
+ \file usbFifoVirtualUart.c
+
+ \brief Implementation of virtual uart API.
+
+ \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:
+ 11/09/08 A. Khromykh - Created
+*******************************************************************************/
+/******************************************************************************
+ Includes section
+******************************************************************************/
+#include <usbFifoVirtualUsart.h>
+#include <usbFifoUsart.h>
+#include <atomic.h>
+#include <irq.h>
+
+/******************************************************************************
+ External global variables section
+******************************************************************************/
+extern void (* extHandler)(void);
+
+/******************************************************************************
+ Global variables section
+******************************************************************************/
+// pointer to application uart descriptor
+HAL_UsartDescriptor_t *usbfifoPointDescrip = NULL;
+
+/******************************************************************************
+ Implementations section
+******************************************************************************/
+/******************************************************************************
+Open virtual com port and register uart's event handlers.
+
+Parameters:
+ descriptor - pointer to HAL_UartDescriptor_t structure
+
+Returns:
+ Returns positive uart descriptor on success or -1 in cases:
+ - bad uart channel;
+ - there are not enough resources;
+ - receiving buffer is less bulk endpoint size;
+******************************************************************************/
+int USBFIFO_OpenUsart(HAL_UsartDescriptor_t *descriptor)
+{
+ if (NULL == descriptor)
+ return -1;
+
+ if (USART_CHANNEL_USBFIFO != descriptor->tty)
+ return -1;
+
+ if (NULL != usbfifoPointDescrip)
+ return -1; /* source was opened */
+
+ extHandler = usbfifoHandler;
+ usbfifoPointDescrip = descriptor;
+
+ usbfifoPointDescrip->service.rxPointOfRead = 0;
+ usbfifoPointDescrip->service.rxPointOfWrite = 0;
+ usbfifoPointDescrip->service.txPointOfRead = 0;
+ usbfifoPointDescrip->service.txPointOfWrite = 0;
+ usbfifoInit();
+ // enable receiver
+ HAL_EnableIrq(IRQ_7);
+
+ return (int)descriptor->tty;
+}
+
+/******************************************************************************
+Frees the virtual uart channel.
+Parameters:
+ descriptor - the uart descriptor.
+Returns:
+ Returns 0 on success or -1 if bad descriptor.
+******************************************************************************/
+int USBFIFO_CloseUsart(HAL_UsartDescriptor_t *descriptor)
+{
+ if (NULL == descriptor)
+ return -1;
+
+ if (usbfifoPointDescrip != descriptor)
+ return -1;
+
+ usbfifoPointDescrip = NULL;
+ extHandler = NULL;
+ usbfifoUnInit();
+
+ return 0;
+}
+
+/******************************************************************************
+Writes a number of bytes to a virtual uart channel.
+txCallback function will be used to notify when the transmission is finished.
+Parameters:
+ descriptor - pointer to HAL_UartDescriptor_t structure;
+ buffer - pointer to the application data buffer;
+ length - number of bytes to transfer;
+Returns:
+ -1 - bad descriptor;
+ Number of bytes placed to the buffer - success.
+******************************************************************************/
+int USBFIFO_WriteUsart(HAL_UsartDescriptor_t *descriptor, uint8_t *buffer, uint16_t length)
+{
+ uint16_t poW;
+ uint16_t poR;
+ uint16_t old;
+ uint16_t wasWrote = 0;
+ HalUsartService_t *control;
+
+ if (NULL == descriptor)
+ return -1;
+
+ if (usbfifoPointDescrip != descriptor)
+ return -1;
+
+ if (!buffer || !length)
+ return -1;
+
+ control = &descriptor->service;
+ ATOMIC_SECTION_ENTER
+ poW = control->txPointOfWrite;
+ poR = control->txPointOfRead;
+ ATOMIC_SECTION_LEAVE
+
+ if (0 == descriptor->txBufferLength)
+ { // Callback mode
+ if (poW != poR)
+ return -1; // there is unsent data
+ descriptor->txBuffer = buffer;
+ control->txPointOfWrite = length;
+ control->txPointOfRead = 0;
+ wasWrote = length;
+ } // Callback mode.
+ else
+ { // Polling mode.
+ while (wasWrote < length)
+ {
+ old = poW;
+
+ if (++poW == descriptor->txBufferLength)
+ poW = 0;
+
+ if (poW == poR)
+ { // Buffer full.
+ poW = old;
+ break;
+ } // Buffer full.
+
+ descriptor->txBuffer[old] = buffer[wasWrote++];
+ }
+
+ ATOMIC_SECTION_ENTER
+ control->txPointOfWrite = poW;
+ ATOMIC_SECTION_LEAVE
+ } // Polling mode
+
+ HAL_EnableIrq(IRQ_6);
+
+ return wasWrote;
+}
+
+/*****************************************************************************
+Reads length bytes from uart and places ones to buffer.
+Parameters:
+ descriptor - uart descriptor;
+ buffer - pointer to a application buffer;
+ length - the number of bytes which should be placed to buffer
+Returns:
+ -1 - bad descriptor, bad number to read;
+ number of bytes that were placed to buffer.
+*****************************************************************************/
+int USBFIFO_ReadUsart(HAL_UsartDescriptor_t *descriptor, uint8_t *buffer, uint16_t length)
+{
+ uint16_t wasRead = 0;
+ uint16_t poW;
+ uint16_t poR;
+ HalUsartService_t *control;
+
+ if (NULL == descriptor)
+ return -1;
+
+ if (!buffer || !length)
+ return -1;
+
+ if (descriptor != usbfifoPointDescrip)
+ return -1; // Channel is not opened.
+
+ control = &usbfifoPointDescrip->service;
+ ATOMIC_SECTION_ENTER
+ poW = control->rxPointOfWrite;
+ poR = control->rxPointOfRead;
+ ATOMIC_SECTION_LEAVE
+
+ while ((poR != poW) && (wasRead < length))
+ {
+ buffer[wasRead] = descriptor->rxBuffer[poR];
+ if (++poR == descriptor->rxBufferLength)
+ poR = 0;
+ wasRead++;
+ }
+
+ ATOMIC_SECTION_ENTER
+ control->rxPointOfRead = poR;
+ control->rxBytesInBuffer -= wasRead;
+ ATOMIC_SECTION_LEAVE
+
+ HAL_EnableIrq(IRQ_7);
+
+ return wasRead;
+}
+
+/**************************************************************************//**
+\brief Checks the status of tx buffer.
+
+\param[in] descriptor - pointer to HAL_UsartDescriptor_t structure;
+\return -1 - bad descriptor, no tx buffer; \n
+ 1 - tx buffer is empty; \n
+ 0 - tx buffer is not empty;
+******************************************************************************/
+int USBFIFO_IsTxEmpty(HAL_UsartDescriptor_t *descriptor)
+{
+ HalUsartService_t *control;
+ uint16_t poW;
+ uint16_t poR;
+
+ if (NULL == descriptor)
+ return -1;
+
+ if (descriptor != usbfifoPointDescrip)
+ return -1; // Channel is not opened.
+
+ control = &usbfifoPointDescrip->service;
+ ATOMIC_SECTION_ENTER
+ poW = control->txPointOfWrite;
+ poR = control->txPointOfRead;
+ ATOMIC_SECTION_LEAVE
+ if (poW == poR)
+ return 1;
+
+ return 0;
+}
+
+// eof usbFifoVirtualUart.c
diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/drivers/include/isdImageStorage.h b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/include/isdImageStorage.h
new file mode 100644
index 00000000..c5631189
--- /dev/null
+++ b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/include/isdImageStorage.h
@@ -0,0 +1,89 @@
+/**************************************************************************//**
+\file isdImageStorage.h
+
+\brief The public API of image storage 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:
+ 25.05.11 A. Khromykh - Created
+*******************************************************************************/
+
+#ifndef _ISDIMAGESTORAGE_H
+#define _ISDIMAGESTORAGE_H
+
+/******************************************************************************
+ Includes section
+******************************************************************************/
+#include <types.h>
+#include <zclOTAUCluster.h>
+
+/******************************************************************************
+ Define(s) section
+******************************************************************************/
+
+/******************************************************************************
+ Types section
+******************************************************************************/
+/** \brief Status which is returned by driver */
+typedef enum
+{
+ ISD_SUCCESS,
+ ISD_HARDWARE_FAULT,
+ ISD_COMMUNICATION_LOST
+} ISD_Status_t;
+
+typedef void (* IsdOpenCb_t)(ISD_Status_t);
+typedef void (* IsdQueryNextImageCb_t)(ZCL_OtauQueryNextImageResp_t *);
+typedef void (* IsdImageBlockCb_t)(ZCL_OtauImageBlockResp_t *);
+typedef void (* IsdUpgradeEndCb_t)(ZCL_OtauUpgradeEndResp_t *);
+
+/******************************************************************************
+ Prototypes section
+******************************************************************************/
+/**************************************************************************//**
+\brief Open image storage driver
+
+\param[in] cb - callback about driver actions
+******************************************************************************/
+void ISD_Open(IsdOpenCb_t cb);
+
+/**************************************************************************//**
+\brief Close image storage driver
+******************************************************************************/
+void ISD_Close(void);
+
+/**************************************************************************//**
+\brief Send query next image request to storage system
+
+\param[in] addressing - pointer to structure that include client network information; \n
+\param[in] data - data payload; \n
+\param[in] cd - callback about response receiving from storage system.
+******************************************************************************/
+void ISD_QueryNextImageReq(ZCL_Addressing_t *addressing, ZCL_OtauQueryNextImageReq_t *data, IsdQueryNextImageCb_t cb);
+
+/**************************************************************************//**
+\brief Send image block request to storage system
+
+\param[in] addressing - pointer to structure that include client network information; \n
+\param[in] data - data payload; \n
+\param[in] cd - callback about response receiving from storage system.
+******************************************************************************/
+void ISD_ImageBlockReq(ZCL_Addressing_t *addressing, ZCL_OtauImageBlockReq_t *data, IsdImageBlockCb_t cb);
+
+/**************************************************************************//**
+\brief Send upgrade end request to storage system
+
+\param[in] addressing - pointer to structure that include client network information; \n
+\param[in] data - data payload; \n
+\param[in] cd - callback about response receiving from storage system.
+******************************************************************************/
+void ISD_UpgradeEndReq(ZCL_Addressing_t *addressing, ZCL_OtauUpgradeEndReq_t *data, IsdUpgradeEndCb_t cb);
+
+#endif /* _ISDIMAGESTORAGE_H */
diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/drivers/include/massStorageDevice.h b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/include/massStorageDevice.h
new file mode 100644
index 00000000..f8957a90
--- /dev/null
+++ b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/include/massStorageDevice.h
@@ -0,0 +1,71 @@
+/****************************************************************************//**
+ \file massStorageDevice.h
+
+ \brief The header file describes the interface of the mass storage device
+
+ \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:
+ 29/08/11 N. Fomin - Created
+*******************************************************************************/
+#ifndef _MASSSTORAGEDEVICE_H
+#define _MASSSTORAGEDEVICE_H
+
+/******************************************************************************
+ Includes section
+******************************************************************************/
+#include <types.h>
+
+/******************************************************************************
+ Define(s) section
+******************************************************************************/
+#define MSD_TRANSMIT_PIPE 5
+#define MSD_RECEIVE_PIPE 6
+
+/******************************************************************************
+ Types section
+******************************************************************************/
+/** \brief Status messages for upper layer about msd status */
+typedef enum
+{
+ MSD_STATUS_SUCCESS = 0,
+ MSD_INTERFACE_BUSY,
+ MSD_MEMORY_INIT_ERROR,
+ MSD_READ_CAPACITY_ERROR,
+ MSD_READ_ERROR,
+ MSD_WRITE_ERROR
+} MSD_Status_t;
+
+typedef void (* MSD_Callback_t)(MSD_Status_t);
+
+/******************************************************************************
+ Prototypes section
+******************************************************************************/
+/**************************************************************************//**
+\brief Opens mass storage device.
+\param[in]
+ callback - pointer to function to notify about MSD errors and transactions;
+ responseBuffer - pointer to hsmci command response buffer; it should have
+ a size of four;
+ buffer - pointer to buffer for hsmci data transfer; it should be
+ a multiplier of 512;
+ length - length of buffer for data transfer.
+\return
+ nothing
+******************************************************************************/
+void MSD_Open(MSD_Callback_t callback, uint32_t *responseBuffer, uint8_t *buffer, uint32_t length);
+
+/**************************************************************************//**
+\brief Closes mass storage device.
+\return
+ nothing
+******************************************************************************/
+void MSD_Close(void);
+
+#endif /* _MASSSTORAGEDEVICE_H */
diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/drivers/include/ofdExtMemory.h b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/include/ofdExtMemory.h
new file mode 100644
index 00000000..e15ed8fd
--- /dev/null
+++ b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/include/ofdExtMemory.h
@@ -0,0 +1,175 @@
+/**************************************************************************//**
+\file ofdExtMemory.h
+
+\brief The public API of external 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:
+ 31/07/09 A. Khromykh - Created
+*******************************************************************************/
+
+#ifndef _OFDEXTMEMORY_H
+#define _OFDEXTMEMORY_H
+
+/******************************************************************************
+ Includes section
+******************************************************************************/
+#include <types.h>
+
+/******************************************************************************
+ Define(s) section
+******************************************************************************/
+/** \brief Size of memory block for internal ofd algorithms */
+#define OFD_BLOCK_FOR_CHECK_CRC 64
+#define OFD_BLOCK_SIZE OFD_BLOCK_FOR_CHECK_CRC
+
+/******************************************************************************
+ Types section
+******************************************************************************/
+/** \brief Status messages for upper component about ofd state */
+typedef enum
+{
+ OFD_STATUS_SUCCESS = 0,
+ OFD_STATUS_SERIAL_BUSY,
+ OFD_STATUS_UNKNOWN_EXTERNAL_FLASH_TYPE,
+ OFD_STATUS_INCORRECT_API_PARAMETER,
+ OFD_STATUS_INCORRECT_EEPROM_PARAMETER,
+ OFD_SERIAL_INTERFACE_BUSY
+} OFD_Status_t ;
+
+/** \brief Number of position for image in the external flash */
+typedef enum
+{
+ OFD_POSITION_1,
+ OFD_POSITION_2,
+ OFD_POSITION_MAX
+} OFD_Position_t;
+
+/** \brief Source type which was been initiator of image saving. */
+typedef enum
+{
+ OFD_IMAGE_WAS_SAVED_FROM_MCU,
+ OFD_IMAGE_WAS_WRITTEN_THROUGH_API,
+} OFD_ImageSource_t;
+
+/** \brief Parameters for access to external memory \n
+ offset - offset from start address \n
+ data - pointer to mcu ram area with\for data for\from external memory \n
+ length - size of mcu ram area with\for data. */
+typedef struct
+{
+ uint32_t offset;
+ uint8_t *data;
+ uint32_t length;
+} OFD_MemoryAccessParam_t;
+
+/** \brief image crc */
+typedef uint8_t OFD_Crc_t;
+
+/** \brief Image information. Crc and image type. */
+typedef struct
+{
+ OFD_ImageSource_t type;
+ OFD_Crc_t crc;
+} OFD_ImageInfo_t;
+
+/** \brief callback methods for OFD API. \n
+ ATTENTION!!!! Callback functions must not call public OFD API directly.
+ */
+typedef void (* OFD_Callback_t)(OFD_Status_t);
+typedef void (* OFD_InfoCallback_t)(OFD_Status_t, OFD_ImageInfo_t *);
+
+/******************************************************************************
+ Prototypes section
+******************************************************************************/
+/**************************************************************************//**
+\brief Opens serial interface and checks memory type.
+
+\param[in]
+ cb - pointer to callback
+******************************************************************************/
+void OFD_Open(OFD_Callback_t cb);
+
+/**************************************************************************//**
+\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);
+
+/**************************************************************************//**
+\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);
+
+/**************************************************************************//**
+\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);
+
+/**************************************************************************//**
+\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);
+
+/**************************************************************************//**
+\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);
+
+/**************************************************************************//**
+\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);
+
+#endif /* _OFDEXTMEMORY_H */
diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/drivers/include/usbFifoUsart.h b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/include/usbFifoUsart.h
new file mode 100644
index 00000000..8725d322
--- /dev/null
+++ b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/include/usbFifoUsart.h
@@ -0,0 +1,109 @@
+/**************************************************************************//**
+\file usbFifoUsart.h
+
+\brief The public API of usb fifo vitual COM port driver based on FTDI FT245RL.
+
+\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:
+ 12.07.11 A. Khromykh - Created
+*******************************************************************************/
+#ifndef _USBFIFOUSART_H
+#define _USBFIFOUSART_H
+
+/******************************************************************************
+ Includes section
+******************************************************************************/
+#include <types.h>
+#include <usart.h>
+
+/******************************************************************************
+ Define(s) section
+******************************************************************************/
+#define USART_CHANNEL_USBFIFO ((UsartChannel_t)6)
+
+/******************************************************************************
+ Prototypes section
+******************************************************************************/
+/**************************************************************************//**
+\brief Opens driver and registers event handlers.
+
+\param[in]
+ descriptor - pointer to HAL_UartDescriptor_t structure
+
+\return
+ Returns positive uart descriptor on success or -1 in cases: \n
+ - bad uart channel; \n
+ - there are not enough resources; \n
+ - receiving buffer is less bulk endpoint size;
+******************************************************************************/
+int USBFIFO_OpenUsart(HAL_UsartDescriptor_t *descriptor);
+
+/*************************************************************************//**
+\brief Releases the driver.
+
+\param[in]
+ descriptor - pointer to HAL_UartDescriptor_t structure
+
+\return
+ -1 - bad descriptor; \n
+ 0 - success.
+*****************************************************************************/
+int USBFIFO_CloseUsart(HAL_UsartDescriptor_t *descriptor);
+
+/**************************************************************************//**
+\brief Writes a number of bytes to driver.
+txCallback function will be used to notify when the transmission is finished.
+
+\param[in]
+ descriptor - pointer to HAL_UartDescriptor_t structure;
+
+\param[in]
+ buffer - pointer to the application data buffer;
+
+\param[in]
+ length - number of bytes to transfer;
+
+\return
+ -1 - bad descriptor; \n
+ Number of bytes placed to the buffer - success.
+******************************************************************************/
+int USBFIFO_WriteUsart(HAL_UsartDescriptor_t *descriptor, uint8_t *buffer, uint16_t length);
+
+/*************************************************************************//**
+\brief Reads a number of bytes from driver and places them to the buffer.
+
+\param[in]
+ descriptor - pointer to HAL_UartDescriptor_t structure;
+
+\param[in]
+ buffer - pointer to the application buffer;
+
+\param[in]
+ length - number of bytes to be placed to the buffer;
+
+\return
+ -1 - bad descriptor, or bad number of bytes to read; \n
+ Number of bytes placed to the buffer - success.
+*****************************************************************************/
+int USBFIFO_ReadUsart(HAL_UsartDescriptor_t *descriptor, uint8_t *buffer, uint16_t length);
+
+/**************************************************************************//**
+\brief Checks the status of tx buffer (for polling mode).
+
+\param[in]
+ descriptor - pointer to HAL_UsartDescriptor_t structure;
+\return
+ -1 - bad descriptor, no tx buffer; \n
+ 1 - tx buffer is empty; \n
+ 0 - tx buffer is not empty;
+******************************************************************************/
+int USBFIFO_IsTxEmpty(HAL_UsartDescriptor_t *descriptor);
+
+#endif /* _USBFIFOUSART_H */
diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/drivers/include/vcpVirtualUsart.h b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/include/vcpVirtualUsart.h
new file mode 100644
index 00000000..0c54d8d1
--- /dev/null
+++ b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/include/vcpVirtualUsart.h
@@ -0,0 +1,111 @@
+/****************************************************************************//**
+ \file vcpVirtualUsart.h
+
+ \brief The header file describes the interface of the virtual uart based on USB
+
+ \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:
+ 05/09/08 A. Khromykh - Created
+*******************************************************************************/
+#ifndef _VCPVIRTUALUART_H
+#define _VCPVIRTUALUART_H
+
+/******************************************************************************
+ Includes section
+******************************************************************************/
+#include <types.h>
+#include <usart.h>
+
+/******************************************************************************
+ Define(s) section
+******************************************************************************/
+#define USART_CHANNEL_VCP ((UsartChannel_t)5)
+#define VCP_TRANSMIT_PIPE 2
+#define VCP_RECEIVE_PIPE 1
+
+/******************************************************************************
+ Prototypes section
+******************************************************************************/
+/**************************************************************************//**
+\brief Registers uart's event handlers.
+
+\param[in]
+ descriptor - pointer to HAL_UartDescriptor_t structure
+
+\return
+ Returns positive uart descriptor on success or -1 in cases: \n
+ - bad uart channel; \n
+ - there are not enough resources; \n
+ - receiving buffer is less bulk endpoint size;
+******************************************************************************/
+int VCP_OpenUsart(HAL_UsartDescriptor_t *descriptor);
+
+/*************************************************************************//**
+\brief Releases the uart channel.
+
+\param[in]
+ descriptor - pointer to HAL_UartDescriptor_t structure
+
+\return
+ -1 - bad descriptor; \n
+ 0 - success.
+*****************************************************************************/
+int VCP_CloseUsart(HAL_UsartDescriptor_t *descriptor);
+
+/**************************************************************************//**
+\brief Writes a number of bytes to uart channel.
+txCallback function will be used to notify when the transmission is finished.
+
+\param[in]
+ descriptor - pointer to HAL_UartDescriptor_t structure;
+
+\param[in]
+ buffer - pointer to the application data buffer;
+
+\param[in]
+ length - number of bytes to transfer;
+
+\return
+ -1 - bad descriptor; \n
+ Number of bytes placed to the buffer - success.
+******************************************************************************/
+int VCP_WriteUsart(HAL_UsartDescriptor_t *descriptor, uint8_t *buffer, uint16_t length);
+
+/*************************************************************************//**
+\brief Reads a number of bytes from uart and places them to the buffer.
+
+\param[in]
+ descriptor - pointer to HAL_UartDescriptor_t structure;
+
+\param[in]
+ buffer - pointer to the application buffer;
+
+\param[in]
+ length - number of bytes to be placed to the buffer;
+
+\return
+ -1 - bad descriptor, or bad number of bytes to read; \n
+ Number of bytes placed to the buffer - success.
+*****************************************************************************/
+int VCP_ReadUsart(HAL_UsartDescriptor_t *descriptor, uint8_t *buffer, uint16_t length);
+
+/**************************************************************************//**
+\brief Checks the status of tx buffer (for polling mode).
+
+\param[in]
+ descriptor - pointer to HAL_UsartDescriptor_t structure;
+\return
+ -1 - bad descriptor, no tx buffer; \n
+ 1 - tx buffer is empty; \n
+ 0 - tx buffer is not empty;
+******************************************************************************/
+int VCP_IsTxEmpty(HAL_UsartDescriptor_t *descriptor);
+
+#endif /* _VCPVIRTUALUART_H */