From dd38d907244bc0e483c3d760f2ba464a394ec229 Mon Sep 17 00:00:00 2001 From: Dave Hylands Date: Tue, 11 Mar 2014 23:55:41 -0700 Subject: Initial checkin with STM HAL This compiles and links, but hasn't been tested on a board yet and even if it was run, it doesn't currently do anything. --- stmhal/usbhost/Class/CDC/Inc/usbh_cdc.h | 449 +++++++++++++++++++ stmhal/usbhost/Class/CDC/Src/usbh_cdc.c | 755 ++++++++++++++++++++++++++++++++ 2 files changed, 1204 insertions(+) create mode 100644 stmhal/usbhost/Class/CDC/Inc/usbh_cdc.h create mode 100644 stmhal/usbhost/Class/CDC/Src/usbh_cdc.c (limited to 'stmhal/usbhost/Class/CDC') diff --git a/stmhal/usbhost/Class/CDC/Inc/usbh_cdc.h b/stmhal/usbhost/Class/CDC/Inc/usbh_cdc.h new file mode 100644 index 000000000..df11bfdda --- /dev/null +++ b/stmhal/usbhost/Class/CDC/Inc/usbh_cdc.h @@ -0,0 +1,449 @@ +/** + ****************************************************************************** + * @file usbh_cdc.h + * @author MCD Application Team + * @version V3.0.0 + * @date 18-February-2014 + * @brief This file contains all the prototypes for the usbh_cdc.c + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2014 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Define to prevent recursive ----------------------------------------------*/ +#ifndef __USBH_CDC_CORE_H +#define __USBH_CDC_CORE_H + +/* Includes ------------------------------------------------------------------*/ +#include "usbh_core.h" + + +/** @addtogroup USBH_LIB +* @{ +*/ + +/** @addtogroup USBH_CLASS +* @{ +*/ + +/** @addtogroup USBH_CDC_CLASS +* @{ +*/ + +/** @defgroup USBH_CDC_CORE +* @brief This file is the Header file for USBH_CDC_CORE.c +* @{ +*/ + + + + +/*Communication Class codes*/ +#define USB_CDC_CLASS 0x02 +#define COMMUNICATION_INTERFACE_CLASS_CODE 0x02 + +/*Data Interface Class Codes*/ +#define DATA_INTERFACE_CLASS_CODE 0x0A + +/*Communcation sub class codes*/ +#define RESERVED 0x00 +#define DIRECT_LINE_CONTROL_MODEL 0x01 +#define ABSTRACT_CONTROL_MODEL 0x02 +#define TELEPHONE_CONTROL_MODEL 0x03 +#define MULTICHANNEL_CONTROL_MODEL 0x04 +#define CAPI_CONTROL_MODEL 0x05 +#define ETHERNET_NETWORKING_CONTROL_MODEL 0x06 +#define ATM_NETWORKING_CONTROL_MODEL 0x07 + + +/*Communication Interface Class Control Protocol Codes*/ +#define NO_CLASS_SPECIFIC_PROTOCOL_CODE 0x00 +#define COMMON_AT_COMMAND 0x01 +#define VENDOR_SPECIFIC 0xFF + + +#define CS_INTERFACE 0x24 +#define CDC_PAGE_SIZE_64 0x40 + +/*Class-Specific Request Codes*/ +#define CDC_SEND_ENCAPSULATED_COMMAND 0x00 +#define CDC_GET_ENCAPSULATED_RESPONSE 0x01 +#define CDC_SET_COMM_FEATURE 0x02 +#define CDC_GET_COMM_FEATURE 0x03 +#define CDC_CLEAR_COMM_FEATURE 0x04 + +#define CDC_SET_AUX_LINE_STATE 0x10 +#define CDC_SET_HOOK_STATE 0x11 +#define CDC_PULSE_SETUP 0x12 +#define CDC_SEND_PULSE 0x13 +#define CDC_SET_PULSE_TIME 0x14 +#define CDC_RING_AUX_JACK 0x15 + +#define CDC_SET_LINE_CODING 0x20 +#define CDC_GET_LINE_CODING 0x21 +#define CDC_SET_CONTROL_LINE_STATE 0x22 +#define CDC_SEND_BREAK 0x23 + +#define CDC_SET_RINGER_PARMS 0x30 +#define CDC_GET_RINGER_PARMS 0x31 +#define CDC_SET_OPERATION_PARMS 0x32 +#define CDC_GET_OPERATION_PARMS 0x33 +#define CDC_SET_LINE_PARMS 0x34 +#define CDC_GET_LINE_PARMS 0x35 +#define CDC_DIAL_DIGITS 0x36 +#define CDC_SET_UNIT_PARAMETER 0x37 +#define CDC_GET_UNIT_PARAMETER 0x38 +#define CDC_CLEAR_UNIT_PARAMETER 0x39 +#define CDC_GET_PROFILE 0x3A + +#define CDC_SET_ETHERNET_MULTICAST_FILTERS 0x40 +#define CDC_SET_ETHERNET_POWER_MANAGEMENT_PATTERN FILTER 0x41 +#define CDC_GET_ETHERNET_POWER_MANAGEMENT_PATTERN FILTER 0x42 +#define CDC_SET_ETHERNET_PACKET_FILTER 0x43 +#define CDC_GET_ETHERNET_STATISTIC 0x44 + +#define CDC_SET_ATM_DATA_FORMAT 0x50 +#define CDC_GET_ATM_DEVICE_STATISTICS 0x51 +#define CDC_SET_ATM_DEFAULT_VC 0x52 +#define CDC_GET_ATM_VC_STATISTICS 0x53 + + +/* wValue for SetControlLineState*/ +#define CDC_ACTIVATE_CARRIER_SIGNAL_RTS 0x0002 +#define CDC_DEACTIVATE_CARRIER_SIGNAL_RTS 0x0000 +#define CDC_ACTIVATE_SIGNAL_DTR 0x0001 +#define CDC_DEACTIVATE_SIGNAL_DTR 0x0000 + +#define LINE_CODING_STRUCTURE_SIZE 0x07 +/** + * @} + */ + +/** @defgroup USBH_CDC_CORE_Exported_Types +* @{ +*/ + +/* States for CDC State Machine */ +typedef enum +{ + CDC_IDLE= 0, + CDC_SEND_DATA, + CDC_SEND_DATA_WAIT, + CDC_RECEIVE_DATA, + CDC_RECEIVE_DATA_WAIT, +} +CDC_DataStateTypeDef; + +typedef enum +{ + CDC_IDLE_STATE= 0, + CDC_SET_LINE_CODING_STATE, + CDC_GET_LAST_LINE_CODING_STATE, + CDC_TRANSFER_DATA, + CDC_ERROR_STATE, +} +CDC_StateTypeDef; + + +/*Line coding structure*/ +typedef union _CDC_LineCodingStructure +{ + uint8_t Array[LINE_CODING_STRUCTURE_SIZE]; + + struct + { + + uint32_t dwDTERate; /*Data terminal rate, in bits per second*/ + uint8_t bCharFormat; /*Stop bits + 0 - 1 Stop bit + 1 - 1.5 Stop bits + 2 - 2 Stop bits*/ + uint8_t bParityType; /* Parity + 0 - None + 1 - Odd + 2 - Even + 3 - Mark + 4 - Space*/ + uint8_t bDataBits; /* Data bits (5, 6, 7, 8 or 16). */ + }b; +} +CDC_LineCodingTypeDef; + + + +/* Header Functional Descriptor +-------------------------------------------------------------------------------- +Offset| field | Size | Value | Description +------|---------------------|-------|------------|------------------------------ +0 | bFunctionLength | 1 | number | Size of this descriptor. +1 | bDescriptorType | 1 | Constant | CS_INTERFACE (0x24) +2 | bDescriptorSubtype | 1 | Constant | Identifier (ID) of functional + | | | | descriptor. +3 | bcdCDC | 2 | | + | | | Number | USB Class Definitions for + | | | | Communication Devices Specification + | | | | release number in binary-coded + | | | | decimal +------|---------------------|-------|------------|------------------------------ +*/ +typedef struct _FunctionalDescriptorHeader +{ + uint8_t bLength; /*Size of this descriptor.*/ + uint8_t bDescriptorType; /*CS_INTERFACE (0x24)*/ + uint8_t bDescriptorSubType; /* Header functional descriptor subtype as*/ + uint16_t bcdCDC; /* USB Class Definitions for Communication + Devices Specification release number in + binary-coded decimal. */ +} +CDC_HeaderFuncDesc_TypeDef; +/* Call Management Functional Descriptor +-------------------------------------------------------------------------------- +Offset| field | Size | Value | Description +------|---------------------|-------|------------|------------------------------ +0 | bFunctionLength | 1 | number | Size of this descriptor. +1 | bDescriptorType | 1 | Constant | CS_INTERFACE (0x24) +2 | bDescriptorSubtype | 1 | Constant | Call Management functional + | | | | descriptor subtype. +3 | bmCapabilities | 1 | Bitmap | The capabilities that this configuration + | | | | supports: + | | | | D7..D2: RESERVED (Reset to zero) + | | | | D1: 0 - Device sends/receives call + | | | | management information only over + | | | | the Communication Class + | | | | interface. + | | | | 1 - Device can send/receive call + | \ | | management information over a + | | | | Data Class interface. + | | | | D0: 0 - Device does not handle call + | | | | management itself. + | | | | 1 - Device handles call + | | | | management itself. + | | | | The previous bits, in combination, identify + | | | | which call management scenario is used. If bit + | | | | D0 is reset to 0, then the value of bit D1 is + | | | | ignored. In this case, bit D1 is reset to zero for + | | | | future compatibility. +4 | bDataInterface | 1 | Number | Interface number of Data Class interface + | | | | optionally used for call management. +------|---------------------|-------|------------|------------------------------ +*/ +typedef struct _CallMgmtFunctionalDescriptor +{ + uint8_t bLength; /*Size of this functional descriptor, in bytes.*/ + uint8_t bDescriptorType; /*CS_INTERFACE (0x24)*/ + uint8_t bDescriptorSubType; /* Call Management functional descriptor subtype*/ + uint8_t bmCapabilities; /* bmCapabilities: D0+D1 */ + uint8_t bDataInterface; /*bDataInterface: 1*/ +} +CDC_CallMgmtFuncDesc_TypeDef; +/* Abstract Control Management Functional Descriptor +-------------------------------------------------------------------------------- +Offset| field | Size | Value | Description +------|---------------------|-------|------------|------------------------------ +0 | bFunctionLength | 1 | number | Size of functional descriptor, in bytes. +1 | bDescriptorType | 1 | Constant | CS_INTERFACE (0x24) +2 | bDescriptorSubtype | 1 | Constant | Abstract Control Management + | | | | functional descriptor subtype. +3 | bmCapabilities | 1 | Bitmap | The capabilities that this configuration + | | | | supports ((A bit value of zero means that the + | | | | request is not supported.) ) + D7..D4: RESERVED (Reset to zero) + | | | | D3: 1 - Device supports the notification + | | | | Network_Connection. + | | | | D2: 1 - Device supports the request + | | | | Send_Break + | | | | D1: 1 - Device supports the request + | \ | | combination of Set_Line_Coding, + | | | | Set_Control_Line_State, Get_Line_Coding, and the + notification Serial_State. + | | | | D0: 1 - Device supports the request + | | | | combination of Set_Comm_Feature, + | | | | Clear_Comm_Feature, and Get_Comm_Feature. + | | | | The previous bits, in combination, identify + | | | | which requests/notifications are supported by + | | | | a Communication Class interface with the + | | | | SubClass code of Abstract Control Model. +------|---------------------|-------|------------|------------------------------ +*/ +typedef struct _AbstractCntrlMgmtFunctionalDescriptor +{ + uint8_t bLength; /*Size of this functional descriptor, in bytes.*/ + uint8_t bDescriptorType; /*CS_INTERFACE (0x24)*/ + uint8_t bDescriptorSubType; /* Abstract Control Management functional + descriptor subtype*/ + uint8_t bmCapabilities; /* The capabilities that this configuration supports */ +} +CDC_AbstCntrlMgmtFuncDesc_TypeDef; +/* Union Functional Descriptor +-------------------------------------------------------------------------------- +Offset| field | Size | Value | Description +------|---------------------|-------|------------|------------------------------ +0 | bFunctionLength | 1 | number | Size of this descriptor. +1 | bDescriptorType | 1 | Constant | CS_INTERFACE (0x24) +2 | bDescriptorSubtype | 1 | Constant | Union functional + | | | | descriptor subtype. +3 | bMasterInterface | 1 | Constant | The interface number of the + | | | | Communication or Data Class interface +4 | bSlaveInterface0 | 1 | Number | nterface number of first slave or associated + | | | | interface in the union. +------|---------------------|-------|------------|------------------------------ +*/ +typedef struct _UnionFunctionalDescriptor +{ + uint8_t bLength; /*Size of this functional descriptor, in bytes*/ + uint8_t bDescriptorType; /*CS_INTERFACE (0x24)*/ + uint8_t bDescriptorSubType; /* Union functional descriptor SubType*/ + uint8_t bMasterInterface; /* The interface number of the Communication or + Data Class interface,*/ + uint8_t bSlaveInterface0; /*Interface number of first slave*/ +} +CDC_UnionFuncDesc_TypeDef; + +typedef struct _USBH_CDCInterfaceDesc +{ + CDC_HeaderFuncDesc_TypeDef CDC_HeaderFuncDesc; + CDC_CallMgmtFuncDesc_TypeDef CDC_CallMgmtFuncDesc; + CDC_AbstCntrlMgmtFuncDesc_TypeDef CDC_AbstCntrlMgmtFuncDesc; + CDC_UnionFuncDesc_TypeDef CDC_UnionFuncDesc; +} +CDC_InterfaceDesc_Typedef; + + +/* Structure for CDC process */ +typedef struct +{ + uint8_t NotifPipe; + uint8_t NotifEp; + uint8_t buff[8]; + uint16_t NotifEpSize; +} +CDC_CommItfTypedef ; + +typedef struct +{ + uint8_t InPipe; + uint8_t OutPipe; + uint8_t OutEp; + uint8_t InEp; + uint8_t buff[8]; + uint16_t OutEpSize; + uint16_t InEpSize; +} +CDC_DataItfTypedef ; + +/* Structure for CDC process */ +typedef struct _CDC_Process +{ + CDC_CommItfTypedef CommItf; + CDC_DataItfTypedef DataItf; + uint8_t *pTxData; + uint8_t *pRxData; + uint32_t TxDataLength; + uint32_t RxDataLength; + CDC_InterfaceDesc_Typedef CDC_Desc; + CDC_LineCodingTypeDef LineCoding; + CDC_LineCodingTypeDef *pUserLineCoding; + CDC_StateTypeDef state; + CDC_DataStateTypeDef data_tx_state; + CDC_DataStateTypeDef data_rx_state; + uint8_t Rx_Poll; +} +CDC_HandleTypeDef; + +/** +* @} +*/ + +/** @defgroup USBH_CDC_CORE_Exported_Defines +* @{ +*/ + +/** +* @} +*/ + +/** @defgroup USBH_CDC_CORE_Exported_Macros +* @{ +*/ +/** +* @} +*/ + +/** @defgroup USBH_CDC_CORE_Exported_Variables +* @{ +*/ +extern USBH_ClassTypeDef CDC_Class; +#define USBH_CDC_CLASS &CDC_Class + +/** +* @} +*/ + +/** @defgroup USBH_CDC_CORE_Exported_FunctionsPrototype +* @{ +*/ + +USBH_StatusTypeDef USBH_CDC_SetLineCoding(USBH_HandleTypeDef *phost, + CDC_LineCodingTypeDef *linecoding); + +USBH_StatusTypeDef USBH_CDC_GetLineCoding(USBH_HandleTypeDef *phost, + CDC_LineCodingTypeDef *linecoding); + +USBH_StatusTypeDef USBH_CDC_Transmit(USBH_HandleTypeDef *phost, + uint8_t *pbuff, + uint32_t length); + +USBH_StatusTypeDef USBH_CDC_Receive(USBH_HandleTypeDef *phost, + uint8_t *pbuff, + uint32_t length); + + +uint16_t USBH_CDC_GetLastReceivedDataSize(USBH_HandleTypeDef *phost); + +USBH_StatusTypeDef USBH_CDC_Stop(USBH_HandleTypeDef *phost); + +void USBH_CDC_LineCodingChanged(USBH_HandleTypeDef *phost); + +void USBH_CDC_TransmitCallback(USBH_HandleTypeDef *phost); + +void USBH_CDC_ReceiveCallback(USBH_HandleTypeDef *phost); + +/** +* @} +*/ + + +#endif /* __USBH_CDC_CORE_H */ + +/** +* @} +*/ + +/** +* @} +*/ + +/** +* @} +*/ + +/** +* @} +*/ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/stmhal/usbhost/Class/CDC/Src/usbh_cdc.c b/stmhal/usbhost/Class/CDC/Src/usbh_cdc.c new file mode 100644 index 000000000..250e1fc7b --- /dev/null +++ b/stmhal/usbhost/Class/CDC/Src/usbh_cdc.c @@ -0,0 +1,755 @@ +/** + ****************************************************************************** + * @file usbh_cdc.c + * @author MCD Application Team + * @version V3.0.0 + * @date 18-February-2014 + * @brief This file is the CDC Layer Handlers for USB Host CDC class. + * + * @verbatim + * + * =================================================================== + * CDC Class Description + * =================================================================== + * This module manages the MSC class V1.11 following the "Device Class Definition + * for Human Interface Devices (CDC) Version 1.11 Jun 27, 2001". + * This driver implements the following aspects of the specification: + * - The Boot Interface Subclass + * - The Mouse and Keyboard protocols + * + * @endverbatim + * + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2014 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbh_cdc.h" + +/** @addtogroup USBH_LIB +* @{ +*/ + +/** @addtogroup USBH_CLASS +* @{ +*/ + +/** @addtogroup USBH_CDC_CLASS +* @{ +*/ + +/** @defgroup USBH_CDC_CORE +* @brief This file includes CDC Layer Handlers for USB Host CDC class. +* @{ +*/ + +/** @defgroup USBH_CDC_CORE_Private_TypesDefinitions +* @{ +*/ +/** +* @} +*/ + + +/** @defgroup USBH_CDC_CORE_Private_Defines +* @{ +*/ +#define USBH_CDC_BUFFER_SIZE 1024 +/** +* @} +*/ + + +/** @defgroup USBH_CDC_CORE_Private_Macros +* @{ +*/ +/** +* @} +*/ + + +/** @defgroup USBH_CDC_CORE_Private_Variables +* @{ +*/ +/** +* @} +*/ + + +/** @defgroup USBH_CDC_CORE_Private_FunctionPrototypes +* @{ +*/ + +static USBH_StatusTypeDef USBH_CDC_InterfaceInit (USBH_HandleTypeDef *phost); + +static USBH_StatusTypeDef USBH_CDC_InterfaceDeInit (USBH_HandleTypeDef *phost); + +static USBH_StatusTypeDef USBH_CDC_Process(USBH_HandleTypeDef *phost); + +static USBH_StatusTypeDef USBH_CDC_SOFProcess(USBH_HandleTypeDef *phost); + +static USBH_StatusTypeDef USBH_CDC_ClassRequest (USBH_HandleTypeDef *phost); + +static USBH_StatusTypeDef GetLineCoding(USBH_HandleTypeDef *phost, + CDC_LineCodingTypeDef *linecoding); + +static USBH_StatusTypeDef SetLineCoding(USBH_HandleTypeDef *phost, + CDC_LineCodingTypeDef *linecoding); + +static void CDC_ProcessTransmission(USBH_HandleTypeDef *phost); + +static void CDC_ProcessReception(USBH_HandleTypeDef *phost); + +USBH_ClassTypeDef CDC_Class = +{ + "CDC", + USB_CDC_CLASS, + USBH_CDC_InterfaceInit, + USBH_CDC_InterfaceDeInit, + USBH_CDC_ClassRequest, + USBH_CDC_Process, + USBH_CDC_SOFProcess, + NULL, +}; +/** +* @} +*/ + + +/** @defgroup USBH_CDC_CORE_Private_Functions +* @{ +*/ + +/** + * @brief USBH_CDC_InterfaceInit + * The function init the CDC class. + * @param phost: Host handle + * @retval USBH Status + */ +static USBH_StatusTypeDef USBH_CDC_InterfaceInit (USBH_HandleTypeDef *phost) +{ + + USBH_StatusTypeDef status = USBH_FAIL ; + uint8_t interface; + CDC_HandleTypeDef *CDC_Handle; + + interface = USBH_FindInterface(phost, + COMMUNICATION_INTERFACE_CLASS_CODE, + ABSTRACT_CONTROL_MODEL, + COMMON_AT_COMMAND); + + if(interface == 0xFF) /* No Valid Interface */ + { + USBH_DbgLog ("Cannot Find the interface for Communication Interface Class.", phost->pActiveClass->Name); + } + else + { + USBH_SelectInterface (phost, interface); + phost->pActiveClass->pData = (CDC_HandleTypeDef *)USBH_malloc (sizeof(CDC_HandleTypeDef)); + CDC_Handle = phost->pActiveClass->pData; + + /*Collect the notification endpoint address and length*/ + if(phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[0].bEndpointAddress & 0x80) + { + CDC_Handle->CommItf.NotifEp = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[0].bEndpointAddress; + CDC_Handle->CommItf.NotifEpSize = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[0].wMaxPacketSize; + } + + /*Allocate the length for host channel number in*/ + CDC_Handle->CommItf.NotifPipe = USBH_AllocPipe(phost, CDC_Handle->CommItf.NotifEp); + + /* Open pipe for Notification endpoint */ + USBH_OpenPipe (phost, + CDC_Handle->CommItf.NotifPipe, + CDC_Handle->CommItf.NotifEp, + phost->device.address, + phost->device.speed, + USB_EP_TYPE_INTR, + CDC_Handle->CommItf.NotifEpSize); + + USBH_LL_SetToggle (phost, CDC_Handle->CommItf.NotifPipe, 0); + + interface = USBH_FindInterface(phost, + DATA_INTERFACE_CLASS_CODE, + RESERVED, + NO_CLASS_SPECIFIC_PROTOCOL_CODE); + + if(interface == 0xFF) /* No Valid Interface */ + { + USBH_DbgLog ("Cannot Find the interface for Data Interface Class.", phost->pActiveClass->Name); + } + else + { + /*Collect the class specific endpoint address and length*/ + if(phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[0].bEndpointAddress & 0x80) + { + CDC_Handle->DataItf.InEp = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[0].bEndpointAddress; + CDC_Handle->DataItf.InEpSize = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[0].wMaxPacketSize; + } + else + { + CDC_Handle->DataItf.OutEp = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[0].bEndpointAddress; + CDC_Handle->DataItf.OutEpSize = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[0].wMaxPacketSize; + } + + if(phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[1].bEndpointAddress & 0x80) + { + CDC_Handle->DataItf.InEp = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[1].bEndpointAddress; + CDC_Handle->DataItf.InEpSize = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[1].wMaxPacketSize; + } + else + { + CDC_Handle->DataItf.OutEp = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[1].bEndpointAddress; + CDC_Handle->DataItf.OutEpSize = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[1].wMaxPacketSize; + } + + /*Allocate the length for host channel number out*/ + CDC_Handle->DataItf.OutPipe = USBH_AllocPipe(phost, CDC_Handle->DataItf.OutEp); + + /*Allocate the length for host channel number in*/ + CDC_Handle->DataItf.InPipe = USBH_AllocPipe(phost, CDC_Handle->DataItf.InEp); + + /* Open channel for OUT endpoint */ + USBH_OpenPipe (phost, + CDC_Handle->DataItf.OutPipe, + CDC_Handle->DataItf.OutEp, + phost->device.address, + phost->device.speed, + USB_EP_TYPE_BULK, + CDC_Handle->DataItf.OutEpSize); + /* Open channel for IN endpoint */ + USBH_OpenPipe (phost, + CDC_Handle->DataItf.InPipe, + CDC_Handle->DataItf.InEp, + phost->device.address, + phost->device.speed, + USB_EP_TYPE_BULK, + CDC_Handle->DataItf.InEpSize); + + CDC_Handle->state = CDC_IDLE_STATE; + + USBH_LL_SetToggle (phost, CDC_Handle->DataItf.OutPipe,0); + USBH_LL_SetToggle (phost, CDC_Handle->DataItf.InPipe,0); + status = USBH_OK; + } + } + return status; +} + + + +/** + * @brief USBH_CDC_InterfaceDeInit + * The function DeInit the Pipes used for the CDC class. + * @param phost: Host handle + * @retval USBH Status + */ +USBH_StatusTypeDef USBH_CDC_InterfaceDeInit (USBH_HandleTypeDef *phost) +{ + CDC_HandleTypeDef *CDC_Handle = phost->pActiveClass->pData; + + if ( CDC_Handle->CommItf.NotifPipe) + { + USBH_ClosePipe(phost, CDC_Handle->CommItf.NotifPipe); + USBH_FreePipe (phost, CDC_Handle->CommItf.NotifPipe); + CDC_Handle->CommItf.NotifPipe = 0; /* Reset the Channel as Free */ + } + + if ( CDC_Handle->DataItf.InPipe) + { + USBH_ClosePipe(phost, CDC_Handle->DataItf.InPipe); + USBH_FreePipe (phost, CDC_Handle->DataItf.InPipe); + CDC_Handle->DataItf.InPipe = 0; /* Reset the Channel as Free */ + } + + if ( CDC_Handle->DataItf.OutPipe) + { + USBH_ClosePipe(phost, CDC_Handle->DataItf.OutPipe); + USBH_FreePipe (phost, CDC_Handle->DataItf.OutPipe); + CDC_Handle->DataItf.OutPipe = 0; /* Reset the Channel as Free */ + } + + if(phost->pActiveClass->pData) + { + USBH_free (phost->pActiveClass->pData); + phost->pActiveClass->pData = 0; + } + + return USBH_OK; +} + +/** + * @brief USBH_CDC_ClassRequest + * The function is responsible for handling Standard requests + * for CDC class. + * @param phost: Host handle + * @retval USBH Status + */ +static USBH_StatusTypeDef USBH_CDC_ClassRequest (USBH_HandleTypeDef *phost) +{ + USBH_StatusTypeDef status = USBH_FAIL ; + CDC_HandleTypeDef *CDC_Handle = phost->pActiveClass->pData; + + /*Issue the get line coding request*/ + status = GetLineCoding(phost, &CDC_Handle->LineCoding); + if(status == USBH_OK) + { + phost->pUser(phost, HOST_USER_CLASS_ACTIVE); + } + return status; +} + + +/** + * @brief USBH_CDC_Process + * The function is for managing state machine for CDC data transfers + * @param phost: Host handle + * @retval USBH Status + */ +static USBH_StatusTypeDef USBH_CDC_Process (USBH_HandleTypeDef *phost) +{ + USBH_StatusTypeDef status = USBH_BUSY; + USBH_StatusTypeDef req_status = USBH_OK; + CDC_HandleTypeDef *CDC_Handle = phost->pActiveClass->pData; + + switch(CDC_Handle->state) + { + + case CDC_IDLE_STATE: + status = USBH_OK; + break; + + case CDC_SET_LINE_CODING_STATE: + req_status = SetLineCoding(phost, CDC_Handle->pUserLineCoding); + + if(req_status == USBH_OK) + { + CDC_Handle->state = CDC_GET_LAST_LINE_CODING_STATE; + } + + else if(req_status != USBH_BUSY) + { + CDC_Handle->state = CDC_ERROR_STATE; + } + break; + + + case CDC_GET_LAST_LINE_CODING_STATE: + req_status = GetLineCoding(phost, &(CDC_Handle->LineCoding)); + + if(req_status == USBH_OK) + { + CDC_Handle->state = CDC_IDLE_STATE; + + if((CDC_Handle->LineCoding.b.bCharFormat == CDC_Handle->pUserLineCoding->b.bCharFormat) && + (CDC_Handle->LineCoding.b.bDataBits == CDC_Handle->pUserLineCoding->b.bDataBits) && + (CDC_Handle->LineCoding.b.bParityType == CDC_Handle->pUserLineCoding->b.bParityType) && + (CDC_Handle->LineCoding.b.dwDTERate == CDC_Handle->pUserLineCoding->b.dwDTERate)) + { + USBH_CDC_LineCodingChanged(phost); + } + } + + else if(req_status != USBH_BUSY) + { + CDC_Handle->state = CDC_ERROR_STATE; + } + + break; + + case CDC_TRANSFER_DATA: + CDC_ProcessTransmission(phost); + CDC_ProcessReception(phost); + break; + + case CDC_ERROR_STATE: + req_status = USBH_ClrFeature(phost, 0x00); + + if(req_status == USBH_OK ) + { + /*Change the state to waiting*/ + CDC_Handle->state = CDC_IDLE_STATE ; + } + break; + + default: + break; + + } + + return status; +} + +/** + * @brief USBH_CDC_SOFProcess + * The function is for managing SOF callback + * @param phost: Host handle + * @retval USBH Status + */ +static USBH_StatusTypeDef USBH_CDC_SOFProcess (USBH_HandleTypeDef *phost) +{ + return USBH_OK; +} + + + /** + * @brief USBH_CDC_Stop + * Stop current CDC Transmission + * @param phost: Host handle + * @retval USBH Status + */ +USBH_StatusTypeDef USBH_CDC_Stop(USBH_HandleTypeDef *phost) +{ + CDC_HandleTypeDef *CDC_Handle = phost->pActiveClass->pData; + + if(phost->gState == HOST_CLASS) + { + CDC_Handle->state = CDC_IDLE_STATE; + + USBH_ClosePipe(phost, CDC_Handle->CommItf.NotifPipe); + USBH_ClosePipe(phost, CDC_Handle->DataItf.InPipe); + USBH_ClosePipe(phost, CDC_Handle->DataItf.OutPipe); + } + return USBH_OK; +} +/** + * @brief This request allows the host to find out the currently + * configured line coding. + * @param pdev: Selected device + * @retval USBH_StatusTypeDef : USB ctl xfer status + */ +static USBH_StatusTypeDef GetLineCoding(USBH_HandleTypeDef *phost, CDC_LineCodingTypeDef *linecoding) +{ + + phost->Control.setup.b.bmRequestType = USB_D2H | USB_REQ_TYPE_CLASS | \ + USB_REQ_RECIPIENT_INTERFACE; + + phost->Control.setup.b.bRequest = CDC_GET_LINE_CODING; + phost->Control.setup.b.wValue.w = 0; + phost->Control.setup.b.wIndex.w = 0; + phost->Control.setup.b.wLength.w = LINE_CODING_STRUCTURE_SIZE; + + return USBH_CtlReq(phost, linecoding->Array, LINE_CODING_STRUCTURE_SIZE); +} + + +/** + * @brief This request allows the host to specify typical asynchronous + * line-character formatting properties + * This request applies to asynchronous byte stream data class interfaces + * and endpoints + * @param pdev: Selected device + * @retval USBH_StatusTypeDef : USB ctl xfer status + */ +static USBH_StatusTypeDef SetLineCoding(USBH_HandleTypeDef *phost, CDC_LineCodingTypeDef *linecodin) +{ + phost->Control.setup.b.bmRequestType = USB_H2D | USB_REQ_TYPE_CLASS | \ + USB_REQ_RECIPIENT_INTERFACE; + + phost->Control.setup.b.bRequest = CDC_SET_LINE_CODING; + phost->Control.setup.b.wValue.w = 0; + + phost->Control.setup.b.wIndex.w = 0; + + phost->Control.setup.b.wLength.w = LINE_CODING_STRUCTURE_SIZE; + + return USBH_CtlReq(phost, linecodin->Array , LINE_CODING_STRUCTURE_SIZE ); +} + +/** +* @brief This function prepares the state before issuing the class specific commands +* @param None +* @retval None +*/ +USBH_StatusTypeDef USBH_CDC_SetLineCoding(USBH_HandleTypeDef *phost, CDC_LineCodingTypeDef *linecodin) +{ + CDC_HandleTypeDef *CDC_Handle = phost->pActiveClass->pData; + if(phost->gState == HOST_CLASS) + { + CDC_Handle->state = CDC_SET_LINE_CODING_STATE; + CDC_Handle->pUserLineCoding = linecodin; + +#if (USBH_USE_OS == 1) + osMessagePut ( phost->os_event, USBH_CLASS_EVENT, 0); +#endif + } + return USBH_OK; +} + +/** +* @brief This function prepares the state before issuing the class specific commands +* @param None +* @retval None +*/ +USBH_StatusTypeDef USBH_CDC_GetLineCoding(USBH_HandleTypeDef *phost, CDC_LineCodingTypeDef *linecodin) +{ + CDC_HandleTypeDef *CDC_Handle = phost->pActiveClass->pData; + + if((phost->gState == HOST_CLASS) ||(phost->gState == HOST_CLASS_REQUEST)) + { + *linecodin = CDC_Handle->LineCoding; + return USBH_OK; + } + else + { + return USBH_FAIL; + } +} + +/** + * @brief This function return last recieved data size + * @param None + * @retval None + */ +uint16_t USBH_CDC_GetLastReceivedDataSize(USBH_HandleTypeDef *phost) +{ + CDC_HandleTypeDef *CDC_Handle = phost->pActiveClass->pData; + + if(phost->gState == HOST_CLASS) + { + return USBH_LL_GetLastXferSize(phost, CDC_Handle->DataItf.InPipe);; + } + else + { + return 0; + } +} + +/** + * @brief This function prepares the state before issuing the class specific commands + * @param None + * @retval None + */ +USBH_StatusTypeDef USBH_CDC_Transmit(USBH_HandleTypeDef *phost, uint8_t *pbuff, uint32_t length) +{ + USBH_StatusTypeDef Status = USBH_BUSY; + CDC_HandleTypeDef *CDC_Handle = phost->pActiveClass->pData; + + if((CDC_Handle->state == CDC_IDLE_STATE) || (CDC_Handle->state == CDC_TRANSFER_DATA)) + { + CDC_Handle->pTxData = pbuff; + CDC_Handle->TxDataLength = length; + CDC_Handle->state = CDC_TRANSFER_DATA; + CDC_Handle->data_tx_state = CDC_SEND_DATA; + Status = USBH_OK; + } + return Status; +} + + +/** +* @brief This function prepares the state before issuing the class specific commands +* @param None +* @retval None +*/ +USBH_StatusTypeDef USBH_CDC_Receive(USBH_HandleTypeDef *phost, uint8_t *pbuff, uint32_t length) +{ + USBH_StatusTypeDef Status = USBH_BUSY; + CDC_HandleTypeDef *CDC_Handle = phost->pActiveClass->pData; + + if((CDC_Handle->state == CDC_IDLE_STATE) || (CDC_Handle->state == CDC_TRANSFER_DATA)) + { + CDC_Handle->pRxData = pbuff; + CDC_Handle->RxDataLength = length; + CDC_Handle->state = CDC_TRANSFER_DATA; + CDC_Handle->data_rx_state = CDC_RECEIVE_DATA; + Status = USBH_OK; + } + return Status; +} + +/** +* @brief The function is responsible for sending data to the device +* @param pdev: Selected device +* @retval None +*/ +static void CDC_ProcessTransmission(USBH_HandleTypeDef *phost) +{ + CDC_HandleTypeDef *CDC_Handle = phost->pActiveClass->pData; + USBH_URBStateTypeDef URB_Status = USBH_URB_IDLE; + + switch(CDC_Handle->data_tx_state) + { + + case CDC_SEND_DATA: + if(CDC_Handle->TxDataLength > CDC_Handle->DataItf.OutEpSize) + { + USBH_BulkSendData (phost, + CDC_Handle->pTxData, + CDC_Handle->DataItf.OutEpSize, + CDC_Handle->DataItf.OutPipe, + 1); + } + else + { + USBH_BulkSendData (phost, + CDC_Handle->pTxData, + CDC_Handle->TxDataLength, + CDC_Handle->DataItf.OutPipe, + 1); + } + + CDC_Handle->data_tx_state = CDC_SEND_DATA_WAIT; + + break; + + case CDC_SEND_DATA_WAIT: + + URB_Status = USBH_LL_GetURBState(phost, CDC_Handle->DataItf.OutPipe); + + /*Check the status done for transmssion*/ + if(URB_Status == USBH_URB_DONE ) + { + if(CDC_Handle->TxDataLength > CDC_Handle->DataItf.OutEpSize) + { + CDC_Handle->TxDataLength -= CDC_Handle->DataItf.OutEpSize ; + CDC_Handle->pTxData += CDC_Handle->DataItf.OutEpSize; + } + else + { + CDC_Handle->TxDataLength = 0; + } + + if( CDC_Handle->TxDataLength > 0) + { + CDC_Handle->data_tx_state = CDC_SEND_DATA; + } + else + { + CDC_Handle->data_tx_state = CDC_IDLE; + USBH_CDC_TransmitCallback(phost); + + } + } + else if( URB_Status == USBH_URB_NOTREADY ) + { + CDC_Handle->data_tx_state = CDC_SEND_DATA; + } + break; + default: + break; + } +} +/** +* @brief This function responsible for reception of data from the device +* @param pdev: Selected device +* @retval None +*/ + +static void CDC_ProcessReception(USBH_HandleTypeDef *phost) +{ + CDC_HandleTypeDef *CDC_Handle = phost->pActiveClass->pData; + USBH_URBStateTypeDef URB_Status = USBH_URB_IDLE; + uint16_t length; + + switch(CDC_Handle->data_rx_state) + { + + case CDC_RECEIVE_DATA: + + USBH_BulkReceiveData (phost, + CDC_Handle->pRxData, + CDC_Handle->DataItf.InEpSize, + CDC_Handle->DataItf.InPipe); + + CDC_Handle->data_rx_state = CDC_RECEIVE_DATA_WAIT; + + break; + + case CDC_RECEIVE_DATA_WAIT: + + URB_Status = USBH_LL_GetURBState(phost, CDC_Handle->DataItf.InPipe); + + /*Check the status done for reception*/ + if(URB_Status == USBH_URB_DONE ) + { + length = USBH_LL_GetLastXferSize(phost, CDC_Handle->DataItf.InPipe); + + if(((CDC_Handle->RxDataLength - length) > 0) && (length > CDC_Handle->DataItf.InEpSize)) + { + CDC_Handle->RxDataLength -= length ; + CDC_Handle->pRxData += length; + CDC_Handle->data_rx_state = CDC_RECEIVE_DATA; + } + else + { + CDC_Handle->data_rx_state = CDC_IDLE; + USBH_CDC_ReceiveCallback(phost); + } + } + break; + + default: + break; + } +} + +/** +* @brief The function informs user that data have been received +* @param pdev: Selected device +* @retval None +*/ +__weak void USBH_CDC_TransmitCallback(USBH_HandleTypeDef *phost) +{ + +} + + /** +* @brief The function informs user that data have been sent +* @param pdev: Selected device +* @retval None +*/ +__weak void USBH_CDC_ReceiveCallback(USBH_HandleTypeDef *phost) +{ + +} + + /** +* @brief The function informs user that Settings have been changed +* @param pdev: Selected device +* @retval None +*/ +__weak void USBH_CDC_LineCodingChanged(USBH_HandleTypeDef *phost) +{ + +} + +/** +* @} +*/ + +/** +* @} +*/ + +/** +* @} +*/ + + +/** +* @} +*/ + + +/** +* @} +*/ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ -- cgit v1.2.3