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