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 --- .../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 +++ 21 files changed, 4166 insertions(+) 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 (limited to 'digital/zigbit/bitcloud/stack/Components/HAL/drivers/USBClasses') 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 -- cgit v1.2.3