From b24866225a6301d3a663f874725e83c012dc25d3 Mon Sep 17 00:00:00 2001 From: Florent Duchon Date: Wed, 26 Dec 2012 17:36:00 +0100 Subject: digital/beacon: add bitcloud stack into common directory digital/zigbit --- .../HAL/drivers/ISD/src/isdImageStorage.c | 626 +++++++++++++++++ .../stack/Components/HAL/drivers/OFD/Makefile | 107 +++ .../HAL/drivers/OFD/include/ofdMemoryDriver.h | 310 +++++++++ .../Components/HAL/drivers/OFD/src/ofdAt25Driver.c | 742 ++++++++++++++++++++ .../HAL/drivers/OFD/src/ofdAt45dbDriver.c | 758 +++++++++++++++++++++ .../Components/HAL/drivers/OFD/src/ofdCommand.c | 243 +++++++ .../Components/HAL/drivers/OFD/src/ofdCrcService.c | 66 ++ .../Components/HAL/drivers/OFD/src/ofdFakeDriver.c | 218 ++++++ .../HAL/drivers/OFD/src/ofdIntFlashRead.s | 40 ++ .../HAL/drivers/OFD/src/ofdIntFlashRead.s90 | 40 ++ .../HAL/drivers/OFD/src/ofdSpiSerializer.c | 91 +++ .../drivers/USBClasses/DFU/include/dfuProtocol.h | 81 +++ .../HAL/drivers/USBClasses/DFU/src/dfuProtocol.c | 135 ++++ .../USBClasses/MSD/include/abstractMemory.h | 83 +++ .../HAL/drivers/USBClasses/MSD/include/mem.h | 106 +++ .../drivers/USBClasses/MSD/include/mscProtocol.h | 79 +++ .../drivers/USBClasses/MSD/include/scsiProtocol.h | 114 ++++ .../drivers/USBClasses/MSD/src/abstractMemory.c | 225 ++++++ .../drivers/USBClasses/MSD/src/massStorageDevice.c | 327 +++++++++ .../HAL/drivers/USBClasses/MSD/src/mmc.c | 618 +++++++++++++++++ .../HAL/drivers/USBClasses/MSD/src/mscProtocol.c | 53 ++ .../HAL/drivers/USBClasses/MSD/src/scsiProtocol.c | 398 +++++++++++ .../Components/HAL/drivers/USBClasses/VCP/Makefile | 71 ++ .../USBClasses/VCP/include/vcpCdcProtocol.h | 119 ++++ .../drivers/USBClasses/VCP/src/vcpCdcProtocol.c | 226 ++++++ .../drivers/USBClasses/VCP/src/vcpVirtualUsart.c | 498 ++++++++++++++ .../USBClasses/common/include/usbDescriptors.h | 184 +++++ .../USBClasses/common/include/usbEnumeration.h | 53 ++ .../USBClasses/common/include/usbSetupProcess.h | 51 ++ .../drivers/USBClasses/common/src/usbDescriptors.c | 424 ++++++++++++ .../drivers/USBClasses/common/src/usbEnumeration.c | 231 +++++++ .../USBClasses/common/src/usbSetupProcess.c | 90 +++ .../drivers/USBFIFO/include/usbFifoVirtualUsart.h | 69 ++ .../HAL/drivers/USBFIFO/src/usbFifoFT245RL.c | 290 ++++++++ .../HAL/drivers/USBFIFO/src/usbFifoVirtualUsart.c | 250 +++++++ .../HAL/drivers/include/isdImageStorage.h | 89 +++ .../HAL/drivers/include/massStorageDevice.h | 71 ++ .../Components/HAL/drivers/include/ofdExtMemory.h | 175 +++++ .../Components/HAL/drivers/include/usbFifoUsart.h | 109 +++ .../HAL/drivers/include/vcpVirtualUsart.h | 111 +++ 40 files changed, 8571 insertions(+) create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/drivers/ISD/src/isdImageStorage.c create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/Makefile create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/include/ofdMemoryDriver.h create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdAt25Driver.c create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdAt45dbDriver.c create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdCommand.c create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdCrcService.c create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdFakeDriver.c create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdIntFlashRead.s create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdIntFlashRead.s90 create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdSpiSerializer.c create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/DFU/include/dfuProtocol.h create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/DFU/src/dfuProtocol.c create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/MSD/include/abstractMemory.h create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/MSD/include/mem.h create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/MSD/include/mscProtocol.h create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/MSD/include/scsiProtocol.h create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/MSD/src/abstractMemory.c create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/MSD/src/massStorageDevice.c create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/MSD/src/mmc.c create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/MSD/src/mscProtocol.c create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/MSD/src/scsiProtocol.c create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/VCP/Makefile create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/VCP/include/vcpCdcProtocol.h create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/VCP/src/vcpCdcProtocol.c create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/VCP/src/vcpVirtualUsart.c create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/common/include/usbDescriptors.h create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/common/include/usbEnumeration.h create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/common/include/usbSetupProcess.h create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/common/src/usbDescriptors.c create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/common/src/usbEnumeration.c create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses/common/src/usbSetupProcess.c create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBFIFO/include/usbFifoVirtualUsart.h create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBFIFO/src/usbFifoFT245RL.c create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBFIFO/src/usbFifoVirtualUsart.c create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/drivers/include/isdImageStorage.h create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/drivers/include/massStorageDevice.h create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/drivers/include/ofdExtMemory.h create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/drivers/include/usbFifoUsart.h create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/drivers/include/vcpVirtualUsart.h (limited to 'digital/zigbit/bitcloud/stack/Components/HAL/drivers') 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 +#include +#include +#include +#include +#include +#include + +/****************************************************************************** + 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 + +/****************************************************************************** + 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 +#include +#include +#include +#include + +/****************************************************************************** + 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(¶ms, 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 *)®Status, 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(¶ms, 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(¶ms, 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(¶ms, 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(¶ms, 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(¶ms, 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 +#include +#include +#include +#include + +/****************************************************************************** + 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(¶ms, 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 *)®Status, 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(¶ms, 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(¶ms, 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(¶ms, 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(¶ms, 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(¶ms, 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 +#include + +/****************************************************************************** + 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 + +/****************************************************************************** + 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 +#include + +/****************************************************************************** + 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 +#include +#include + +/****************************************************************************** + 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 +#include + +/****************************************************************************** + 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 +#include +#include +#include +#include + +/****************************************************************************** + 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 +#include + +/****************************************************************************** + 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 +#include + +/****************************************************************************** + 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 +#include + +/****************************************************************************** + 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 + +/****************************************************************************** + 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 +#include + +/****************************************************************************** + 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 +#include +#include +#include +#include +#include +#include + +/****************************************************************************** + 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 + +/****************************************************************************** + 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 +#include + +/****************************************************************************** + 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 + +/****************************************************************************** + 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 +#include + +/****************************************************************************** + 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 +#include +#include +#include + +/****************************************************************************** + 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 +#include +#include +#include +#include + +/****************************************************************************** + 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 +#include + +/****************************************************************************** + 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 + +/****************************************************************************** + 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 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 + +/****************************************************************************** + 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 +#if (APP_INTERFACE == APP_INTERFACE_VCP) + #include +#endif // (APP_INTERFACE == APP_INTERFACE_VCP) +#if (MSD_SUPPORT == 1) + #include +#endif // (MSD_SUPPORT == 1) +#include +#include +#include + +/****************************************************************************** + 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 +#if (APP_INTERFACE == APP_INTERFACE_VCP) + #include + #if (MSD_SUPPORT == 1) + #include + #endif // (MSD_SUPPORT == 1) +#else + #if (MSD_SUPPORT == 1) + #include + #else + #include + #endif // (MSD_SUPPORT == 1) +#endif // (APP_INTERFACE == APP_INTERFACE_VCP) +#if (DFU_SUPPORT == 1) + #include + #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 + +/****************************************************************************** + 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 +#include +#include +#include + +/****************************************************************************** + 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 +#include +#include +#include + +/****************************************************************************** + 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 +#include + +/****************************************************************************** + 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 + +/****************************************************************************** + 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 + +/****************************************************************************** + 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 +#include + +/****************************************************************************** + 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 +#include + +/****************************************************************************** + 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 */ -- cgit v1.2.3