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/Core/Inc/usbh_conf_template.h | 151 +++++ stmhal/usbhost/Core/Inc/usbh_core.h | 161 +++++ stmhal/usbhost/Core/Inc/usbh_ctlreq.h | 147 +++++ stmhal/usbhost/Core/Inc/usbh_def.h | 480 ++++++++++++++ stmhal/usbhost/Core/Inc/usbh_ioreq.h | 159 +++++ stmhal/usbhost/Core/Inc/usbh_pipes.h | 124 ++++ stmhal/usbhost/Core/Src/usbh_conf_template.c | 270 ++++++++ stmhal/usbhost/Core/Src/usbh_core.c | 936 +++++++++++++++++++++++++++ stmhal/usbhost/Core/Src/usbh_ctlreq.c | 881 +++++++++++++++++++++++++ stmhal/usbhost/Core/Src/usbh_ioreq.c | 358 ++++++++++ stmhal/usbhost/Core/Src/usbh_pipes.c | 204 ++++++ 11 files changed, 3871 insertions(+) create mode 100644 stmhal/usbhost/Core/Inc/usbh_conf_template.h create mode 100644 stmhal/usbhost/Core/Inc/usbh_core.h create mode 100644 stmhal/usbhost/Core/Inc/usbh_ctlreq.h create mode 100644 stmhal/usbhost/Core/Inc/usbh_def.h create mode 100644 stmhal/usbhost/Core/Inc/usbh_ioreq.h create mode 100644 stmhal/usbhost/Core/Inc/usbh_pipes.h create mode 100644 stmhal/usbhost/Core/Src/usbh_conf_template.c create mode 100644 stmhal/usbhost/Core/Src/usbh_core.c create mode 100644 stmhal/usbhost/Core/Src/usbh_ctlreq.c create mode 100644 stmhal/usbhost/Core/Src/usbh_ioreq.c create mode 100644 stmhal/usbhost/Core/Src/usbh_pipes.c (limited to 'stmhal/usbhost/Core') diff --git a/stmhal/usbhost/Core/Inc/usbh_conf_template.h b/stmhal/usbhost/Core/Inc/usbh_conf_template.h new file mode 100644 index 000000000..8f85e1360 --- /dev/null +++ b/stmhal/usbhost/Core/Inc/usbh_conf_template.h @@ -0,0 +1,151 @@ +/** + ****************************************************************************** + * @file USBH_conf.h + * @author MCD Application Team + * @version V3.0.0 + * @date 18-February-2014 + * @brief General low level driver configuration + ****************************************************************************** + * @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 inclusion -------------------------------------*/ +#ifndef __USBH_CONF__H__ +#define __USBH_CONF__H__ + +#include "stm32f4xx.h" +#include +#include +#include + +/* Includes ------------------------------------------------------------------*/ + +/** @addtogroup USBH_OTG_DRIVER + * @{ + */ + +/** @defgroup USBH_CONF + * @brief usb otg low level driver configuration file + * @{ + */ + +/** @defgroup USBH_CONF_Exported_Defines + * @{ + */ + +#define USBH_MAX_NUM_ENDPOINTS 2 +#define USBH_MAX_NUM_INTERFACES 2 +#define USBH_MAX_NUM_CONFIGURATION 1 +#define USBH_KEEP_CFG_DESCRIPTOR 1 +#define USBH_MAX_NUM_SUPPORTED_CLASS 1 +#define USBH_MAX_SIZE_CONFIGURATION 0x200 +#define USBH_MAX_DATA_BUFFER 0x200 +#define USBH_DEBUG_LEVEL 2 +#define USBH_USE_OS 1 + +/** @defgroup USBH_Exported_Macros + * @{ + */ + + /* Memory management macros */ +#define USBH_malloc malloc +#define USBH_free free +#define USBH_memset memset +#define USBH_memcpy memcpy + + /* DEBUG macros */ + + +#if (USBH_DEBUG_LEVEL > 0) +#define USBH_UsrLog(...) printf(__VA_ARGS__);\ + printf("\n"); +#else +#define USBH_UsrLog(...) +#endif + + +#if (USBH_DEBUG_LEVEL > 1) + +#define USBH_ErrLog(...) printf("ERROR: ") ;\ + printf(__VA_ARGS__);\ + printf("\n"); +#else +#define USBH_ErrLog(...) +#endif + + +#if (USBH_DEBUG_LEVEL > 2) +#define USBH_DbgLog(...) printf("DEBUG : ") ;\ + printf(__VA_ARGS__);\ + printf("\n"); +#else +#define USBH_DbgLog(...) +#endif + +/** + * @} + */ + +/** + * @} + */ + + +/** @defgroup USBH_CONF_Exported_Types + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBH_CONF_Exported_Macros + * @{ + */ +/** + * @} + */ + +/** @defgroup USBH_CONF_Exported_Variables + * @{ + */ +/** + * @} + */ + +/** @defgroup USBH_CONF_Exported_FunctionsPrototype + * @{ + */ +/** + * @} + */ + + +#endif //__USBH_CONF__H__ + + +/** + * @} + */ + +/** + * @} + */ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/stmhal/usbhost/Core/Inc/usbh_core.h b/stmhal/usbhost/Core/Inc/usbh_core.h new file mode 100644 index 000000000..bc3da6d1f --- /dev/null +++ b/stmhal/usbhost/Core/Inc/usbh_core.h @@ -0,0 +1,161 @@ +/** + ****************************************************************************** + * @file usbh_core.h + * @author MCD Application Team + * @version V3.0.0 + * @date 18-February-2014 + * @brief Header file for usbh_core.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_CORE_H +#define __USBH_CORE_H + +/* Includes ------------------------------------------------------------------*/ +#include "usbh_conf.h" +#include "usbh_def.h" +#include "usbh_ioreq.h" +#include "usbh_pipes.h" +#include "usbh_ctlreq.h" + +/** @addtogroup USBH_LIB + * @{ + */ + +/** @addtogroup USBH_LIB_CORE +* @{ +*/ + +/** @defgroup USBH_CORE + * @brief This file is the Header file for usbh_core.c + * @{ + */ + + +/** @defgroup USBH_CORE_Exported_Defines + * @{ + */ + +/** + * @} + */ +#define HOST_USER_SELECT_CONFIGURATION 1 +#define HOST_USER_CLASS_ACTIVE 2 +#define HOST_USER_CLASS_SELECTED 3 +#define HOST_USER_CONNECTION 4 +#define HOST_USER_DISCONNECTION 5 + + + +/** + * @} + */ + + + +/** @defgroup USBH_CORE_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBH_CORE_Exported_Variables + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBH_CORE_Exported_FunctionsPrototype + * @{ + */ + + +USBH_StatusTypeDef USBH_Init(USBH_HandleTypeDef *phost, void (*pUsrFunc)(USBH_HandleTypeDef *phost, uint8_t ), uint8_t id); +USBH_StatusTypeDef USBH_DeInit(USBH_HandleTypeDef *phost); +USBH_StatusTypeDef USBH_RegisterClass(USBH_HandleTypeDef *phost, USBH_ClassTypeDef *pclass); +USBH_StatusTypeDef USBH_SelectInterface(USBH_HandleTypeDef *phost, uint8_t interface); +uint8_t USBH_FindInterface(USBH_HandleTypeDef *phost, + uint8_t Class, + uint8_t SubClass, + uint8_t Protocol); +uint8_t USBH_GetActiveClass(USBH_HandleTypeDef *phost); + +uint8_t USBH_FindInterfaceIndex(USBH_HandleTypeDef *phost, + uint8_t interface_number, + uint8_t alt_settings); + +USBH_StatusTypeDef USBH_Start (USBH_HandleTypeDef *phost); +USBH_StatusTypeDef USBH_Stop (USBH_HandleTypeDef *phost); +USBH_StatusTypeDef USBH_Process (USBH_HandleTypeDef *phost); +USBH_StatusTypeDef USBH_ReEnumerate (USBH_HandleTypeDef *phost); + +/* USBH Low Level Driver */ +USBH_StatusTypeDef USBH_LL_Init (USBH_HandleTypeDef *phost); +USBH_StatusTypeDef USBH_LL_DeInit (USBH_HandleTypeDef *phost); +USBH_StatusTypeDef USBH_LL_Start (USBH_HandleTypeDef *phost); +USBH_StatusTypeDef USBH_LL_Stop (USBH_HandleTypeDef *phost); + +USBH_StatusTypeDef USBH_LL_Connect (USBH_HandleTypeDef *phost); +USBH_StatusTypeDef USBH_LL_Disconnect (USBH_HandleTypeDef *phost); +USBH_SpeedTypeDef USBH_LL_GetSpeed (USBH_HandleTypeDef *phost); +USBH_StatusTypeDef USBH_LL_ResetPort (USBH_HandleTypeDef *phost); +uint32_t USBH_LL_GetLastXferSize (USBH_HandleTypeDef *phost, uint8_t ); +USBH_StatusTypeDef USBH_LL_DriverVBUS (USBH_HandleTypeDef *phost, uint8_t ); + +USBH_StatusTypeDef USBH_LL_OpenPipe (USBH_HandleTypeDef *phost, uint8_t, uint8_t, uint8_t, uint8_t , uint8_t, uint16_t ); +USBH_StatusTypeDef USBH_LL_ClosePipe (USBH_HandleTypeDef *phost, uint8_t ); +USBH_StatusTypeDef USBH_LL_SubmitURB (USBH_HandleTypeDef *phost, uint8_t, uint8_t,uint8_t, uint8_t, uint8_t*, uint16_t, uint8_t ); +USBH_URBStateTypeDef USBH_LL_GetURBState (USBH_HandleTypeDef *phost, uint8_t ); +#if (USBH_USE_OS == 1) +USBH_StatusTypeDef USBH_LL_NotifyURBChange (USBH_HandleTypeDef *phost); +#endif +USBH_StatusTypeDef USBH_LL_SetToggle (USBH_HandleTypeDef *phost, uint8_t , uint8_t ); +uint8_t USBH_LL_GetToggle (USBH_HandleTypeDef *phost, uint8_t ); + +/* USBH Time base */ +void USBH_Delay (uint32_t Delay); +void USBH_LL_SetTimer (USBH_HandleTypeDef *phost, uint32_t ); +void USBH_LL_IncTimer (USBH_HandleTypeDef *phost); +/** + * @} + */ + +#endif /* __CORE_H */ +/** + * @} + */ + +/** + * @} + */ + +/** +* @} +*/ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + + + diff --git a/stmhal/usbhost/Core/Inc/usbh_ctlreq.h b/stmhal/usbhost/Core/Inc/usbh_ctlreq.h new file mode 100644 index 000000000..cd61755e3 --- /dev/null +++ b/stmhal/usbhost/Core/Inc/usbh_ctlreq.h @@ -0,0 +1,147 @@ +/** + ****************************************************************************** + * @file usbh_ctlreq.h + * @author MCD Application Team + * @version V3.0.0 + * @date 18-February-2014 + * @brief Header file for usbh_ctlreq.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_CTLREQ_H +#define __USBH_CTLREQ_H + +/* Includes ------------------------------------------------------------------*/ +#include "usbh_core.h" + +/** @addtogroup USBH_LIB + * @{ + */ + +/** @addtogroup USBH_LIB_CORE +* @{ +*/ + +/** @defgroup USBH_CTLREQ + * @brief This file is the + * @{ + */ + + +/** @defgroup USBH_CTLREQ_Exported_Defines + * @{ + */ +/*Standard Feature Selector for clear feature command*/ +#define FEATURE_SELECTOR_ENDPOINT 0X00 +#define FEATURE_SELECTOR_DEVICE 0X01 + + +#define INTERFACE_DESC_TYPE 0x04 +#define ENDPOINT_DESC_TYPE 0x05 +#define INTERFACE_DESC_SIZE 0x09 + +/** + * @} + */ + + +/** @defgroup USBH_CTLREQ_Exported_Types + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBH_CTLREQ_Exported_Macros + * @{ + */ +/** + * @} + */ + +/** @defgroup USBH_CTLREQ_Exported_Variables + * @{ + */ +extern uint8_t USBH_CfgDesc[512]; +/** + * @} + */ + +/** @defgroup USBH_CTLREQ_Exported_FunctionsPrototype + * @{ + */ +USBH_StatusTypeDef USBH_CtlReq (USBH_HandleTypeDef *phost, + uint8_t *buff, + uint16_t length); + +USBH_StatusTypeDef USBH_GetDescriptor(USBH_HandleTypeDef *phost, + uint8_t req_type, + uint16_t value_idx, + uint8_t* buff, + uint16_t length ); + +USBH_StatusTypeDef USBH_Get_DevDesc(USBH_HandleTypeDef *phost, + uint8_t length); + +USBH_StatusTypeDef USBH_Get_StringDesc(USBH_HandleTypeDef *phost, + uint8_t string_index, + uint8_t *buff, + uint16_t length); + +USBH_StatusTypeDef USBH_SetCfg(USBH_HandleTypeDef *phost, + uint16_t configuration_value); + +USBH_StatusTypeDef USBH_Get_CfgDesc(USBH_HandleTypeDef *phost, + uint16_t length); + +USBH_StatusTypeDef USBH_SetAddress(USBH_HandleTypeDef *phost, + uint8_t DeviceAddress); + +USBH_StatusTypeDef USBH_SetInterface(USBH_HandleTypeDef *phost, + uint8_t ep_num, uint8_t altSetting); + +USBH_StatusTypeDef USBH_ClrFeature(USBH_HandleTypeDef *phost, + uint8_t ep_num); + +USBH_DescHeader_t *USBH_GetNextDesc (uint8_t *pbuf, + uint16_t *ptr); +/** + * @} + */ + +#endif /* __USBH_CTLREQ_H */ + +/** + * @} + */ + +/** + * @} + */ + +/** +* @} +*/ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + + diff --git a/stmhal/usbhost/Core/Inc/usbh_def.h b/stmhal/usbhost/Core/Inc/usbh_def.h new file mode 100644 index 000000000..cf24d69f3 --- /dev/null +++ b/stmhal/usbhost/Core/Inc/usbh_def.h @@ -0,0 +1,480 @@ +/** + ****************************************************************************** + * @file usbh_def.h + * @author MCD Application Team + * @version V3.0.0 + * @date 18-February-2014 + * @brief Definitions used in the USB host library + ****************************************************************************** + * @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. + * + ****************************************************************************** + */ + +/** @addtogroup USBH_LIB + * @{ + */ + +/** @addtogroup USBH_LIB_CORE +* @{ +*/ + +/** @defgroup USBH_DEF + * @brief This file is includes USB descriptors + * @{ + */ + +#ifndef USBH_DEF_H +#define USBH_DEF_H + +#include "usbh_conf.h" + +#ifndef NULL +#define NULL ((void *)0) +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + + +#define ValBit(VAR,POS) (VAR & (1 << POS)) +#define SetBit(VAR,POS) (VAR |= (1 << POS)) +#define ClrBit(VAR,POS) (VAR &= ((1 << POS)^255)) + +#define LE16(addr) (((uint16_t)(*((uint8_t *)(addr))))\ + + (((uint16_t)(*(((uint8_t *)(addr)) + 1))) << 8)) + +#define LE16S(addr) (uint16_t)(LE16((addr))) + +#define LE32(addr) ((((uint32_t)(*(((uint8_t *)(addr)) + 0))) + \ + (((uint32_t)(*(((uint8_t *)(addr)) + 1))) << 8) + \ + (((uint32_t)(*(((uint8_t *)(addr)) + 2))) << 16) + \ + (((uint32_t)(*(((uint8_t *)(addr)) + 3))) << 24))) + +#define LE64(addr) ((((uint64_t)(*(((uint8_t *)(addr)) + 0))) + \ + (((uint64_t)(*(((uint8_t *)(addr)) + 1))) << 8) +\ + (((uint64_t)(*(((uint8_t *)(addr)) + 2))) << 16) +\ + (((uint64_t)(*(((uint8_t *)(addr)) + 3))) << 24) +\ + (((uint64_t)(*(((uint8_t *)(addr)) + 4))) << 32) +\ + (((uint64_t)(*(((uint8_t *)(addr)) + 5))) << 40) +\ + (((uint64_t)(*(((uint8_t *)(addr)) + 6))) << 48) +\ + (((uint64_t)(*(((uint8_t *)(addr)) + 7))) << 56))) + + +#define LE24(addr) ((((uint32_t)(*(((uint8_t *)(addr)) + 0))) + \ + (((uint32_t)(*(((uint8_t *)(addr)) + 1))) << 8) + \ + (((uint32_t)(*(((uint8_t *)(addr)) + 2))) << 16))) + + +#define LE32S(addr) (int32_t)(LE32((addr))) + + + +#define USB_LEN_DESC_HDR 0x02 +#define USB_LEN_DEV_DESC 0x12 +#define USB_LEN_CFG_DESC 0x09 +#define USB_LEN_IF_DESC 0x09 +#define USB_LEN_EP_DESC 0x07 +#define USB_LEN_OTG_DESC 0x03 +#define USB_LEN_SETUP_PKT 0x08 + +/* bmRequestType :D7 Data Phase Transfer Direction */ +#define USB_REQ_DIR_MASK 0x80 +#define USB_H2D 0x00 +#define USB_D2H 0x80 + +/* bmRequestType D6..5 Type */ +#define USB_REQ_TYPE_STANDARD 0x00 +#define USB_REQ_TYPE_CLASS 0x20 +#define USB_REQ_TYPE_VENDOR 0x40 +#define USB_REQ_TYPE_RESERVED 0x60 + +/* bmRequestType D4..0 Recipient */ +#define USB_REQ_RECIPIENT_DEVICE 0x00 +#define USB_REQ_RECIPIENT_INTERFACE 0x01 +#define USB_REQ_RECIPIENT_ENDPOINT 0x02 +#define USB_REQ_RECIPIENT_OTHER 0x03 + +/* Table 9-4. Standard Request Codes */ +/* bRequest , Value */ +#define USB_REQ_GET_STATUS 0x00 +#define USB_REQ_CLEAR_FEATURE 0x01 +#define USB_REQ_SET_FEATURE 0x03 +#define USB_REQ_SET_ADDRESS 0x05 +#define USB_REQ_GET_DESCRIPTOR 0x06 +#define USB_REQ_SET_DESCRIPTOR 0x07 +#define USB_REQ_GET_CONFIGURATION 0x08 +#define USB_REQ_SET_CONFIGURATION 0x09 +#define USB_REQ_GET_INTERFACE 0x0A +#define USB_REQ_SET_INTERFACE 0x0B +#define USB_REQ_SYNCH_FRAME 0x0C + +/* Table 9-5. Descriptor Types of USB Specifications */ +#define USB_DESC_TYPE_DEVICE 1 +#define USB_DESC_TYPE_CONFIGURATION 2 +#define USB_DESC_TYPE_STRING 3 +#define USB_DESC_TYPE_INTERFACE 4 +#define USB_DESC_TYPE_ENDPOINT 5 +#define USB_DESC_TYPE_DEVICE_QUALIFIER 6 +#define USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION 7 +#define USB_DESC_TYPE_INTERFACE_POWER 8 +#define USB_DESC_TYPE_HID 0x21 +#define USB_DESC_TYPE_HID_REPORT 0x22 + + +#define USB_DEVICE_DESC_SIZE 18 +#define USB_CONFIGURATION_DESC_SIZE 9 +#define USB_HID_DESC_SIZE 9 +#define USB_INTERFACE_DESC_SIZE 9 +#define USB_ENDPOINT_DESC_SIZE 7 + +/* Descriptor Type and Descriptor Index */ +/* Use the following values when calling the function USBH_GetDescriptor */ +#define USB_DESC_DEVICE ((USB_DESC_TYPE_DEVICE << 8) & 0xFF00) +#define USB_DESC_CONFIGURATION ((USB_DESC_TYPE_CONFIGURATION << 8) & 0xFF00) +#define USB_DESC_STRING ((USB_DESC_TYPE_STRING << 8) & 0xFF00) +#define USB_DESC_INTERFACE ((USB_DESC_TYPE_INTERFACE << 8) & 0xFF00) +#define USB_DESC_ENDPOINT ((USB_DESC_TYPE_INTERFACE << 8) & 0xFF00) +#define USB_DESC_DEVICE_QUALIFIER ((USB_DESC_TYPE_DEVICE_QUALIFIER << 8) & 0xFF00) +#define USB_DESC_OTHER_SPEED_CONFIGURATION ((USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION << 8) & 0xFF00) +#define USB_DESC_INTERFACE_POWER ((USB_DESC_TYPE_INTERFACE_POWER << 8) & 0xFF00) +#define USB_DESC_HID_REPORT ((USB_DESC_TYPE_HID_REPORT << 8) & 0xFF00) +#define USB_DESC_HID ((USB_DESC_TYPE_HID << 8) & 0xFF00) + + +#define USB_EP_TYPE_CTRL 0x00 +#define USB_EP_TYPE_ISOC 0x01 +#define USB_EP_TYPE_BULK 0x02 +#define USB_EP_TYPE_INTR 0x03 + +#define USB_EP_DIR_OUT 0x00 +#define USB_EP_DIR_IN 0x80 +#define USB_EP_DIR_MSK 0x80 + +#define USBH_MAX_PIPES_NBR 15 + + + +#define USBH_DEVICE_ADDRESS_DEFAULT 0 +#define USBH_MAX_ERROR_COUNT 2 +#define USBH_DEVICE_ADDRESS 1 + + +/** + * @} + */ + + +#define USBH_CONFIGURATION_DESCRIPTOR_SIZE (USB_CONFIGURATION_DESC_SIZE \ + + USB_INTERFACE_DESC_SIZE\ + + (USBH_MAX_NUM_ENDPOINTS * USB_ENDPOINT_DESC_SIZE)) + + +#define CONFIG_DESC_wTOTAL_LENGTH (ConfigurationDescriptorData.ConfigDescfield.\ + ConfigurationDescriptor.wTotalLength) + + +typedef union +{ + uint16_t w; + struct BW + { + uint8_t msb; + uint8_t lsb; + } + bw; +} +uint16_t_uint8_t; + + +typedef union _USB_Setup +{ + uint32_t d8[2]; + + struct _SetupPkt_Struc + { + uint8_t bmRequestType; + uint8_t bRequest; + uint16_t_uint8_t wValue; + uint16_t_uint8_t wIndex; + uint16_t_uint8_t wLength; + } b; +} +USB_Setup_TypeDef; + +typedef struct _DescHeader +{ + uint8_t bLength; + uint8_t bDescriptorType; +} +USBH_DescHeader_t; + +typedef struct _DeviceDescriptor +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t bcdUSB; /* USB Specification Number which device complies too */ + uint8_t bDeviceClass; + uint8_t bDeviceSubClass; + uint8_t bDeviceProtocol; + /* If equal to Zero, each interface specifies its own class + code if equal to 0xFF, the class code is vendor specified. + Otherwise field is valid Class Code.*/ + uint8_t bMaxPacketSize; + uint16_t idVendor; /* Vendor ID (Assigned by USB Org) */ + uint16_t idProduct; /* Product ID (Assigned by Manufacturer) */ + uint16_t bcdDevice; /* Device Release Number */ + uint8_t iManufacturer; /* Index of Manufacturer String Descriptor */ + uint8_t iProduct; /* Index of Product String Descriptor */ + uint8_t iSerialNumber; /* Index of Serial Number String Descriptor */ + uint8_t bNumConfigurations; /* Number of Possible Configurations */ +} +USBH_DevDescTypeDef; + +typedef struct _EndpointDescriptor +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bEndpointAddress; /* indicates what endpoint this descriptor is describing */ + uint8_t bmAttributes; /* specifies the transfer type. */ + uint16_t wMaxPacketSize; /* Maximum Packet Size this endpoint is capable of sending or receiving */ + uint8_t bInterval; /* is used to specify the polling interval of certain transfers. */ +} +USBH_EpDescTypeDef; + +typedef struct _InterfaceDescriptor +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bInterfaceNumber; + uint8_t bAlternateSetting; /* Value used to select alternative setting */ + uint8_t bNumEndpoints; /* Number of Endpoints used for this interface */ + uint8_t bInterfaceClass; /* Class Code (Assigned by USB Org) */ + uint8_t bInterfaceSubClass; /* Subclass Code (Assigned by USB Org) */ + uint8_t bInterfaceProtocol; /* Protocol Code */ + uint8_t iInterface; /* Index of String Descriptor Describing this interface */ + USBH_EpDescTypeDef Ep_Desc[USBH_MAX_NUM_ENDPOINTS]; +} +USBH_InterfaceDescTypeDef; + + +typedef struct _ConfigurationDescriptor +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t wTotalLength; /* Total Length of Data Returned */ + uint8_t bNumInterfaces; /* Number of Interfaces */ + uint8_t bConfigurationValue; /* Value to use as an argument to select this configuration*/ + uint8_t iConfiguration; /*Index of String Descriptor Describing this configuration */ + uint8_t bmAttributes; /* D7 Bus Powered , D6 Self Powered, D5 Remote Wakeup , D4..0 Reserved (0)*/ + uint8_t bMaxPower; /*Maximum Power Consumption */ + USBH_InterfaceDescTypeDef Itf_Desc[USBH_MAX_NUM_INTERFACES]; +} +USBH_CfgDescTypeDef; + + +/* Following USB Host status */ +typedef enum +{ + USBH_OK = 0, + USBH_BUSY, + USBH_FAIL, + USBH_NOT_SUPPORTED, + USBH_UNRECOVERED_ERROR, + USBH_ERROR_SPEED_UNKNOWN, +}USBH_StatusTypeDef; + + +/** @defgroup USBH_CORE_Exported_Types + * @{ + */ + +typedef enum +{ + USBH_SPEED_HIGH = 0, + USBH_SPEED_FULL = 1, + USBH_SPEED_LOW = 2, + +}USBH_SpeedTypeDef; + +/* Following states are used for gState */ +typedef enum +{ + HOST_IDLE =0, + HOST_DEV_WAIT_FOR_ATTACHMENT, + HOST_DEV_ATTACHED, + HOST_DEV_DISCONNECTED, + HOST_DETECT_DEVICE_SPEED, + HOST_ENUMERATION, + HOST_CLASS_REQUEST, + HOST_INPUT, + HOST_SET_CONFIGURATION, + HOST_CHECK_CLASS, + HOST_CLASS, + HOST_SUSPENDED, + HOST_ABORT_STATE, +}HOST_StateTypeDef; + +/* Following states are used for EnumerationState */ +typedef enum +{ + ENUM_IDLE = 0, + ENUM_GET_FULL_DEV_DESC, + ENUM_SET_ADDR, + ENUM_GET_CFG_DESC, + ENUM_GET_FULL_CFG_DESC, + ENUM_GET_MFC_STRING_DESC, + ENUM_GET_PRODUCT_STRING_DESC, + ENUM_GET_SERIALNUM_STRING_DESC, +} ENUM_StateTypeDef; + +/* Following states are used for CtrlXferStateMachine */ +typedef enum +{ + CTRL_IDLE =0, + CTRL_SETUP, + CTRL_SETUP_WAIT, + CTRL_DATA_IN, + CTRL_DATA_IN_WAIT, + CTRL_DATA_OUT, + CTRL_DATA_OUT_WAIT, + CTRL_STATUS_IN, + CTRL_STATUS_IN_WAIT, + CTRL_STATUS_OUT, + CTRL_STATUS_OUT_WAIT, + CTRL_ERROR, + CTRL_STALLED, + CTRL_COMPLETE +}CTRL_StateTypeDef; + + +/* Following states are used for RequestState */ +typedef enum +{ + CMD_IDLE =0, + CMD_SEND, + CMD_WAIT +} CMD_StateTypeDef; + +typedef enum { + USBH_URB_IDLE = 0, + USBH_URB_DONE, + USBH_URB_NOTREADY, + USBH_URB_NYET, + USBH_URB_ERROR, + USBH_URB_STALL +}USBH_URBStateTypeDef; + +typedef enum +{ + USBH_PORT_EVENT = 1, + USBH_URB_EVENT, + USBH_CONTROL_EVENT, + USBH_CLASS_EVENT, + USBH_STATE_CHANGED_EVENT, +} +USBH_OSEventTypeDef; + +/* Control request structure */ +typedef struct +{ + uint8_t pipe_in; + uint8_t pipe_out; + uint8_t pipe_size; + uint8_t *buff; + uint16_t length; + uint16_t timer; + USB_Setup_TypeDef setup; + CTRL_StateTypeDef state; + uint8_t errorcount; + +} USBH_CtrlTypeDef; + +/* Attached device structure */ +typedef struct +{ +#if (USBH_KEEP_CFG_DESCRIPTOR == 1) + uint8_t CfgDesc_Raw[USBH_MAX_SIZE_CONFIGURATION]; +#endif + uint8_t Data[USBH_MAX_DATA_BUFFER]; + uint8_t address; + uint8_t speed; + __IO uint8_t is_connected; + uint8_t current_interface; + USBH_DevDescTypeDef DevDesc; + USBH_CfgDescTypeDef CfgDesc; + +}USBH_DeviceTypeDef; + +struct _USBH_HandleTypeDef; + +/* USB Host Class structure */ +typedef struct +{ + const char *Name; + uint8_t ClassCode; + USBH_StatusTypeDef (*Init) (struct _USBH_HandleTypeDef *phost); + USBH_StatusTypeDef (*DeInit) (struct _USBH_HandleTypeDef *phost); + USBH_StatusTypeDef (*Requests) (struct _USBH_HandleTypeDef *phost); + USBH_StatusTypeDef (*BgndProcess) (struct _USBH_HandleTypeDef *phost); + USBH_StatusTypeDef (*SOFProcess) (struct _USBH_HandleTypeDef *phost); + void* pData; +} USBH_ClassTypeDef; + +/* USB Host handle structure */ +typedef struct _USBH_HandleTypeDef +{ + __IO HOST_StateTypeDef gState; /* Host State Machine Value */ + ENUM_StateTypeDef EnumState; /* Enumeration state Machine */ + CMD_StateTypeDef RequestState; + USBH_CtrlTypeDef Control; + USBH_DeviceTypeDef device; + USBH_ClassTypeDef* pClass[USBH_MAX_NUM_SUPPORTED_CLASS]; + USBH_ClassTypeDef* pActiveClass; + uint32_t ClassNumber; + uint32_t Pipes[15]; + __IO uint32_t Timer; + uint8_t id; + void* pData; + void (* pUser )(struct _USBH_HandleTypeDef *pHandle, uint8_t id); + +#if (USBH_USE_OS == 1) + osMessageQId os_event; + osThreadId thread; +#endif + +} USBH_HandleTypeDef; + + +#if defined ( __GNUC__ ) + #ifndef __weak + #define __weak __attribute__((weak)) + #endif /* __weak */ + #ifndef __packed + #define __packed __attribute__((__packed__)) + #endif /* __packed */ +#endif /* __GNUC__ */ + +#endif + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/stmhal/usbhost/Core/Inc/usbh_ioreq.h b/stmhal/usbhost/Core/Inc/usbh_ioreq.h new file mode 100644 index 000000000..463d4ea37 --- /dev/null +++ b/stmhal/usbhost/Core/Inc/usbh_ioreq.h @@ -0,0 +1,159 @@ +/** + ****************************************************************************** + * @file usbh_ioreq.h + * @author MCD Application Team + * @version V3.0.0 + * @date 18-February-2014 + * @brief Header file for usbh_ioreq.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_IOREQ_H +#define __USBH_IOREQ_H + +/* Includes ------------------------------------------------------------------*/ +#include "usbh_conf.h" +#include "usbh_core.h" +/** @addtogroup USBH_LIB + * @{ + */ + +/** @addtogroup USBH_LIB_CORE +* @{ +*/ + +/** @defgroup USBH_IOREQ + * @brief This file is the header file for usbh_ioreq.c + * @{ + */ + + +/** @defgroup USBH_IOREQ_Exported_Defines + * @{ + */ + +#define USBH_PID_SETUP 0 +#define USBH_PID_DATA 1 + +#define USBH_EP_CONTROL 0 +#define USBH_EP_ISO 1 +#define USBH_EP_BULK 2 +#define USBH_EP_INTERRUPT 3 + +#define USBH_SETUP_PKT_SIZE 8 +/** + * @} + */ + + +/** @defgroup USBH_IOREQ_Exported_Types + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBH_IOREQ_Exported_Macros + * @{ + */ +/** + * @} + */ + +/** @defgroup USBH_IOREQ_Exported_Variables + * @{ + */ +/** + * @} + */ + +/** @defgroup USBH_IOREQ_Exported_FunctionsPrototype + * @{ + */ +USBH_StatusTypeDef USBH_CtlSendSetup (USBH_HandleTypeDef *phost, + uint8_t *buff, + uint8_t hc_num); + +USBH_StatusTypeDef USBH_CtlSendData (USBH_HandleTypeDef *phost, + uint8_t *buff, + uint16_t length, + uint8_t hc_num, + uint8_t do_ping ); + +USBH_StatusTypeDef USBH_CtlReceiveData(USBH_HandleTypeDef *phost, + uint8_t *buff, + uint16_t length, + uint8_t hc_num); + +USBH_StatusTypeDef USBH_BulkReceiveData(USBH_HandleTypeDef *phost, + uint8_t *buff, + uint16_t length, + uint8_t hc_num); + +USBH_StatusTypeDef USBH_BulkSendData (USBH_HandleTypeDef *phost, + uint8_t *buff, + uint16_t length, + uint8_t hc_num, + uint8_t do_ping ); + +USBH_StatusTypeDef USBH_InterruptReceiveData(USBH_HandleTypeDef *phost, + uint8_t *buff, + uint8_t length, + uint8_t hc_num); + +USBH_StatusTypeDef USBH_InterruptSendData(USBH_HandleTypeDef *phost, + uint8_t *buff, + uint8_t length, + uint8_t hc_num); + + +USBH_StatusTypeDef USBH_IsocReceiveData(USBH_HandleTypeDef *phost, + uint8_t *buff, + uint32_t length, + uint8_t hc_num); + + +USBH_StatusTypeDef USBH_IsocSendData(USBH_HandleTypeDef *phost, + uint8_t *buff, + uint32_t length, + uint8_t hc_num); +/** + * @} + */ + +#endif /* __USBH_IOREQ_H */ + +/** + * @} + */ + +/** + * @} + */ + +/** +* @} +*/ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + + diff --git a/stmhal/usbhost/Core/Inc/usbh_pipes.h b/stmhal/usbhost/Core/Inc/usbh_pipes.h new file mode 100644 index 000000000..d72cd5387 --- /dev/null +++ b/stmhal/usbhost/Core/Inc/usbh_pipes.h @@ -0,0 +1,124 @@ +/** + ****************************************************************************** + * @file usbh_PIPES.h + * @author MCD Application Team + * @version V3.0.0 + * @date 18-February-2014 + * @brief Header file for usbh_pipes.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_PIPES_H +#define __USBH_PIPES_H + +/* Includes ------------------------------------------------------------------*/ +#include "usbh_core.h" + +/** @addtogroup USBH_LIB + * @{ + */ + +/** @addtogroup USBH_LIB_CORE +* @{ +*/ + +/** @defgroup USBH_PIPES + * @brief This file is the header file for usbh_PIPES.c + * @{ + */ + +/** @defgroup USBH_PIPES_Exported_Defines + * @{ + */ +/** + * @} + */ + +/** @defgroup USBH_PIPES_Exported_Types + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBH_PIPES_Exported_Macros + * @{ + */ +/** + * @} + */ + +/** @defgroup USBH_PIPES_Exported_Variables + * @{ + */ +/** + * @} + */ + +/** @defgroup USBH_PIPES_Exported_FunctionsPrototype + * @{ + */ + +USBH_StatusTypeDef USBH_OpenPipe (USBH_HandleTypeDef *phost, + uint8_t ch_num, + uint8_t epnum, + uint8_t dev_address, + uint8_t speed, + uint8_t ep_type, + uint16_t mps); + +USBH_StatusTypeDef USBH_ClosePipe (USBH_HandleTypeDef *phost, + uint8_t pipe_num); + +uint8_t USBH_AllocPipe (USBH_HandleTypeDef *phost, + uint8_t ep_addr); + +USBH_StatusTypeDef USBH_FreePipe (USBH_HandleTypeDef *phost, + uint8_t idx); + + + + +/** + * @} + */ + + + +#endif /* __USBH_PIPES_H */ + + +/** + * @} + */ + +/** + * @} + */ + +/** +* @} +*/ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + + diff --git a/stmhal/usbhost/Core/Src/usbh_conf_template.c b/stmhal/usbhost/Core/Src/usbh_conf_template.c new file mode 100644 index 000000000..1c25f7b2e --- /dev/null +++ b/stmhal/usbhost/Core/Src/usbh_conf_template.c @@ -0,0 +1,270 @@ +/** + ****************************************************************************** + * @file usb_bsp.c + * @author MCD Application Team + * @version V3.0.0 + * @date 18-February-2014 + * @brief This file implements the board support package for the USB host library + ****************************************************************************** + * @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_core.h" + +/** + * @brief USBH_LL_Init + * Initialize the Low Level portion of the Host driver. + * @param phost: Host handle + * @retval USBH Status + */ +USBH_StatusTypeDef USBH_LL_Init (USBH_HandleTypeDef *phost) +{ + + return USBH_OK; +} + +/** + * @brief USBH_LL_DeInit + * De-Initialize the Low Level portion of the Host driver. + * @param phost: Host handle + * @retval USBH Status + */ +USBH_StatusTypeDef USBH_LL_DeInit (USBH_HandleTypeDef *phost) +{ + + return USBH_OK; +} + +/** + * @brief USBH_LL_Start + * Start the Low Level portion of the Host driver. + * @param phost: Host handle + * @retval USBH Status + */ +USBH_StatusTypeDef USBH_LL_Start(USBH_HandleTypeDef *phost) +{ + + return USBH_OK; +} + +/** + * @brief USBH_LL_Stop + * Stop the Low Level portion of the Host driver. + * @param phost: Host handle + * @retval USBH Status + */ +USBH_StatusTypeDef USBH_LL_Stop (USBH_HandleTypeDef *phost) +{ + + return USBH_OK; +} + +/** + * @brief USBH_LL_GetSpeed + * Return the USB Host Speed from the Low Level Driver. + * @param phost: Host handle + * @retval USBH Speeds + */ +USBH_SpeedTypeDef USBH_LL_GetSpeed (USBH_HandleTypeDef *phost) +{ + USBH_SpeedTypeDef speed = 0; + + + return speed; +} + +/** + * @brief USBH_LL_ResetPort + * Reset the Host Port of the Low Level Driver. + * @param phost: Host handle + * @retval USBH Status + */ +USBH_StatusTypeDef USBH_LL_ResetPort (USBH_HandleTypeDef *phost) +{ + + return USBH_OK; +} + +/** + * @brief USBH_LL_GetLastXferSize + * Return the last transfered packet size. + * @param phost: Host handle + * @param pipe: Pipe index + * @retval Packet Size + */ +uint32_t USBH_LL_GetLastXferSize (USBH_HandleTypeDef *phost, uint8_t pipe) +{ + +} + +/** + * @brief USBH_LL_OpenPipe + * Open a pipe of the Low Level Driver. + * @param phost: Host handle + * @param pipe_num: Pipe index + * @param epnum: Endpoint Number + * @param dev_address: Device USB address + * @param speed: Device Speed + * @param ep_type: Endpoint Type + * @param mps: Endpoint Max Packet Size + * @retval USBH Status + */ +USBH_StatusTypeDef USBH_LL_OpenPipe (USBH_HandleTypeDef *phost, + uint8_t pipe_num, + uint8_t epnum, + uint8_t dev_address, + uint8_t speed, + uint8_t ep_type, + uint16_t mps) +{ + + return USBH_OK; +} + +/** + * @brief USBH_LL_ClosePipe + * Close a pipe of the Low Level Driver. + * @param phost: Host handle + * @param pipe_num: Pipe index + * @retval USBH Status + */ +USBH_StatusTypeDef USBH_LL_ClosePipe (USBH_HandleTypeDef *phost, uint8_t pipe) +{ + +} +/** + * @brief USBH_LL_SubmitURB + * Submit a new URB to the low level driver. + * @param phost: Host handle + * @param pipe: Pipe index + * This parameter can be a value from 1 to 15 + * @param direction : Channel number + * This parameter can be one of the these values: + * 0 : Output + * 1 : Input + * @param ep_type : Endpoint Type + * This parameter can be one of the these values: + * @arg EP_TYPE_CTRL: Control type + * @arg EP_TYPE_ISOC: Isochrounous type + * @arg EP_TYPE_BULK: Bulk type + * @arg EP_TYPE_INTR: Interrupt type + * @param token : Endpoint Type + * This parameter can be one of the these values: + * @arg 0: PID_SETUP + * @arg 1: PID_DATA + * @param pbuff : pointer to URB data + * @param length : Length of URB data + * @param do_ping : activate do ping protocol (for high speed only) + * This parameter can be one of the these values: + * 0 : do ping inactive + * 1 : do ping active + * @retval Status + */ + +USBH_StatusTypeDef USBH_LL_SubmitURB (USBH_HandleTypeDef *phost, + uint8_t pipe, + uint8_t direction , + uint8_t ep_type, + uint8_t token, + uint8_t* pbuff, + uint16_t length, + uint8_t do_ping ) +{ + + return USBH_OK; +} + +/** + * @brief USBH_LL_GetURBState + * Get a URB state from the low level driver. + * @param phost: Host handle + * @param pipe: Pipe index + * This parameter can be a value from 1 to 15 + * @retval URB state + * This parameter can be one of the these values: + * @arg URB_IDLE + * @arg URB_DONE + * @arg URB_NOTREADY + * @arg URB_NYET + * @arg URB_ERROR + * @arg URB_STALL + */ +USBH_URBStateTypeDef USBH_LL_GetURBState (USBH_HandleTypeDef *phost, uint8_t pipe) +{ + +} + +/** + * @brief USBH_LL_DriverVBUS + * Drive VBUS. + * @param phost: Host handle + * @param state : VBUS state + * This parameter can be one of the these values: + * 0 : VBUS Active + * 1 : VBUS Inactive + * @retval Status + */ + +USBH_StatusTypeDef USBH_LL_DriverVBUS (USBH_HandleTypeDef *phost, uint8_t state) +{ + + return USBH_OK; +} + +/** + * @brief USBH_LL_SetToggle + * Set toggle for a pipe. + * @param phost: Host handle + * @param pipe: Pipe index + * @param pipe_num: Pipe index + * @param toggle: toggle (0/1) + * @retval Status + */ +USBH_StatusTypeDef USBH_LL_SetToggle (USBH_HandleTypeDef *phost, uint8_t pipe, uint8_t toggle) +{ + + return USBH_OK; +} + +/** + * @brief USBH_LL_GetToggle + * Return the current toggle of a pipe. + * @param phost: Host handle + * @param pipe: Pipe index + * @retval toggle (0/1) + */ +uint8_t USBH_LL_GetToggle (USBH_HandleTypeDef *phost, uint8_t pipe) +{ + uint8_t toggle = 0; + + + return toggle; +} +/** + * @brief USBH_Delay + * Delay routine for the USB Host Library + * @param Delay: Delay in ms + * @retval None + */ +void USBH_Delay (uint32_t Delay) +{ + +} +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/stmhal/usbhost/Core/Src/usbh_core.c b/stmhal/usbhost/Core/Src/usbh_core.c new file mode 100644 index 000000000..9d2727a89 --- /dev/null +++ b/stmhal/usbhost/Core/Src/usbh_core.c @@ -0,0 +1,936 @@ +/** + ****************************************************************************** + * @file usbh_core.c + * @author MCD Application Team + * @version V3.0.0 + * @date 18-February-2014 + * @brief This file implements the functions for the core state machine process + * the enumeration and the control transfer process + ****************************************************************************** + * @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_core.h" + + +/** @addtogroup USBH_LIB + * @{ + */ + +/** @addtogroup USBH_LIB_CORE + * @{ + */ + +/** @defgroup USBH_CORE + * @brief TThis file handles the basic enumaration when a device is connected + * to the host. + * @{ + */ + + +/** @defgroup USBH_CORE_Private_Defines + * @{ + */ +#define USBH_ADDRESS_DEFAULT 0 +#define USBH_ADDRESS_ASSIGNED 1 +#define USBH_MPS_DEFAULT 0x40 +/** + * @} + */ + +/** @defgroup USBH_CORE_Private_Macros + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBH_CORE_Private_Variables + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBH_CORE_Private_Functions + * @{ + */ +static USBH_StatusTypeDef USBH_HandleEnum (USBH_HandleTypeDef *phost); +static void USBH_HandleSof (USBH_HandleTypeDef *phost); +static USBH_StatusTypeDef DeInitStateMachine(USBH_HandleTypeDef *phost); + +#if (USBH_USE_OS == 1) +static void USBH_Process_OS(void const * argument); +#endif + +/** + * @brief HCD_Init + * Initialize the HOST Core. + * @param phost: Host Handle + * @param pUsrFunc: User Callback + * @retval USBH Status + */ +USBH_StatusTypeDef USBH_Init(USBH_HandleTypeDef *phost, void (*pUsrFunc)(USBH_HandleTypeDef *phost, uint8_t ), uint8_t id) +{ + /* Check whether the USB Host handle is valid */ + if(phost == NULL) + { + USBH_ErrLog("Invalid Host handle"); + return USBH_FAIL; + } + + /* Set DRiver ID */ + phost->id = id; + + /* Unlink class*/ + phost->pActiveClass = NULL; + phost->ClassNumber = 0; + + /* Restore default states and prepare EP0 */ + DeInitStateMachine(phost); + + /* Assign User process */ + if(pUsrFunc != NULL) + { + phost->pUser = pUsrFunc; + } + +#if (USBH_USE_OS == 1) + + /* Create USB Host Queue */ + osMessageQDef(USBH_Queue, 10, uint16_t); + phost->os_event = osMessageCreate (osMessageQ(USBH_Queue), NULL); + + /*Create USB Host Task */ + osThreadDef(USBH_Thread, USBH_Process_OS, USBH_PROCESS_PRIO, 0, 8 * configMINIMAL_STACK_SIZE); + phost->thread = osThreadCreate (osThread(USBH_Thread), phost); +#endif + + /* Initialize low level driver */ + USBH_LL_Init(phost); + return USBH_OK; +} + +/** + * @brief HCD_Init + * De-Initialize the Host portion of the driver. + * @param phost: Host Handle + * @retval USBH Status + */ +USBH_StatusTypeDef USBH_DeInit(USBH_HandleTypeDef *phost) +{ + DeInitStateMachine(phost); + + if(phost->pData != NULL) + { + phost->pActiveClass->pData = NULL; + USBH_LL_Stop(phost); + } + + return USBH_OK; +} + +/** + * @brief DeInitStateMachine + * De-Initialize the Host state machine. + * @param phost: Host Handle + * @retval USBH Status + */ +static USBH_StatusTypeDef DeInitStateMachine(USBH_HandleTypeDef *phost) +{ + uint32_t i = 0; + + /* Clear Pipes flags*/ + for ( ; i < USBH_MAX_PIPES_NBR; i++) + { + phost->Pipes[i] = 0; + } + + for(i = 0; i< USBH_MAX_DATA_BUFFER; i++) + { + phost->device.Data[i] = 0; + } + + phost->gState = HOST_IDLE; + phost->EnumState = ENUM_IDLE; + phost->RequestState = CMD_SEND; + phost->Timer = 0; + + phost->Control.state = CTRL_SETUP; + phost->Control.pipe_size = USBH_MPS_DEFAULT; + phost->Control.errorcount = 0; + + phost->device.address = USBH_ADDRESS_DEFAULT; + phost->device.speed = USBH_SPEED_FULL; + + return USBH_OK; +} + +/** + * @brief USBH_RegisterClass + * Link class driver to Host Core. + * @param phost : Host Handle + * @param pclass: Class handle + * @retval USBH Status + */ +USBH_StatusTypeDef USBH_RegisterClass(USBH_HandleTypeDef *phost, USBH_ClassTypeDef *pclass) +{ + USBH_StatusTypeDef status = USBH_OK; + + if(pclass != 0) + { + if(phost->ClassNumber < USBH_MAX_NUM_SUPPORTED_CLASS) + { + /* link the class tgo the USB Host handle */ + phost->pClass[phost->ClassNumber++] = pclass; + status = USBH_OK; + } + else + { + USBH_ErrLog("Max Class Number reached"); + status = USBH_FAIL; + } + } + else + { + USBH_ErrLog("Invalid Class handle"); + status = USBH_FAIL; + } + + return status; +} + +/** + * @brief USBH_SelectInterface + * Select current interface. + * @param phost: Host Handle + * @param interface: Interface number + * @retval USBH Status + */ +USBH_StatusTypeDef USBH_SelectInterface(USBH_HandleTypeDef *phost, uint8_t interface) +{ + USBH_StatusTypeDef status = USBH_OK; + + if(interface < phost->device.CfgDesc.bNumInterfaces) + { + phost->device.current_interface = interface; + USBH_UsrLog ("Switching to Interface (#%d)", interface); + USBH_UsrLog ("Class : %xh", phost->device.CfgDesc.Itf_Desc[interface].bInterfaceClass ); + USBH_UsrLog ("SubClass : %xh", phost->device.CfgDesc.Itf_Desc[interface].bInterfaceSubClass ); + USBH_UsrLog ("Protocol : %xh", phost->device.CfgDesc.Itf_Desc[interface].bInterfaceProtocol ); + } + else + { + USBH_ErrLog ("Cannot Select This Interface."); + status = USBH_FAIL; + } + return status; +} + +/** + * @brief USBH_GetActiveClass + * Return Device Class. + * @param phost: Host Handle + * @param interface: Interface index + * @retval Class Code + */ +uint8_t USBH_GetActiveClass(USBH_HandleTypeDef *phost) +{ + return (phost->device.CfgDesc.Itf_Desc[0].bInterfaceClass); +} +/** + * @brief USBH_FindInterface + * Find the interface index for a specific class. + * @param phost: Host Handle + * @param Class: Class code + * @param SubClass: SubClass code + * @param Protocol: Protocol code + * @retval interface index in the configuration structure + * @note : (1)interface index 0xFF means interface index not found + */ +uint8_t USBH_FindInterface(USBH_HandleTypeDef *phost, uint8_t Class, uint8_t SubClass, uint8_t Protocol) +{ + USBH_InterfaceDescTypeDef *pif ; + USBH_CfgDescTypeDef *pcfg ; + int8_t if_ix = 0; + + pif = (USBH_InterfaceDescTypeDef *)0; + pcfg = &phost->device.CfgDesc; + + if((pif->bInterfaceClass == 0xFF) &&(pif->bInterfaceSubClass == 0xFF) && (pif->bInterfaceProtocol == 0xFF)) + { + return 0xFF; + } + + while (if_ix < USBH_MAX_NUM_INTERFACES) + { + pif = &pcfg->Itf_Desc[if_ix]; + if(((pif->bInterfaceClass == Class) || (Class == 0xFF))&& + ((pif->bInterfaceSubClass == SubClass) || (SubClass == 0xFF))&& + ((pif->bInterfaceProtocol == Protocol) || (Protocol == 0xFF))) + { + return if_ix; + } + if_ix++; + } + return 0xFF; +} + +/** + * @brief USBH_FindInterfaceIndex + * Find the interface index for a specific class interface and alternate setting number. + * @param phost: Host Handle + * @param interface_number: interface number + * @param alt_settings : alaternate setting number + * @retval interface index in the configuration structure + * @note : (1)interface index 0xFF means interface index not found + */ +uint8_t USBH_FindInterfaceIndex(USBH_HandleTypeDef *phost, uint8_t interface_number, uint8_t alt_settings) +{ + USBH_InterfaceDescTypeDef *pif ; + USBH_CfgDescTypeDef *pcfg ; + int8_t if_ix = 0; + + pif = (USBH_InterfaceDescTypeDef *)0; + pcfg = &phost->device.CfgDesc; + + while (if_ix < USBH_MAX_NUM_INTERFACES) + { + pif = &pcfg->Itf_Desc[if_ix]; + if((pif->bInterfaceNumber == interface_number) && (pif->bAlternateSetting == alt_settings)) + { + return if_ix; + } + if_ix++; + } + return 0xFF; +} + +/** + * @brief USBH_Start + * Start the USB Host Core. + * @param phost: Host Handle + * @retval USBH Status + */ +USBH_StatusTypeDef USBH_Start (USBH_HandleTypeDef *phost) +{ + /* Start the low level driver */ + USBH_LL_Start(phost); + + /* Activate VBUS on the port */ + USBH_LL_DriverVBUS (phost, TRUE); + + return USBH_OK; +} + +/** + * @brief USBH_Stop + * Stop the USB Host Core. + * @param phost: Host Handle + * @retval USBH Status + */ +USBH_StatusTypeDef USBH_Stop (USBH_HandleTypeDef *phost) +{ + /* Stop and cleanup the low level driver */ + USBH_LL_Stop(phost); + + /* DeActivate VBUS on the port */ + USBH_LL_DriverVBUS (phost, FALSE); + + /* FRee Control Pipes */ + USBH_FreePipe (phost, phost->Control.pipe_in); + USBH_FreePipe (phost, phost->Control.pipe_out); + + return USBH_OK; +} + +/** + * @brief HCD_ReEnumerate + * Perform a new Enumeration phase. + * @param phost: Host Handle + * @retval USBH Status + */ +USBH_StatusTypeDef USBH_ReEnumerate (USBH_HandleTypeDef *phost) +{ + /*Stop Host */ + USBH_Stop(phost); + + /*Device has disconnected, so wait for 200 ms */ + USBH_Delay(200); + + /* Set State machines in default state */ + DeInitStateMachine(phost); + + /* Start again the host */ + USBH_Start(phost); + +#if (USBH_USE_OS == 1) + osMessagePut ( phost->os_event, USBH_PORT_EVENT, 0); +#endif + return USBH_OK; +} + +/** + * @brief USBH_Process + * Background process of the USB Core. + * @param phost: Host Handle + * @retval USBH Status + */ +USBH_StatusTypeDef USBH_Process(USBH_HandleTypeDef *phost) +{ + __IO USBH_StatusTypeDef status = USBH_FAIL; + uint8_t idx = 0; + + switch (phost->gState) + { + case HOST_IDLE : + + if (phost->device.is_connected) + { + /* Wait for 200 ms after connection */ + phost->gState = HOST_DEV_WAIT_FOR_ATTACHMENT; + USBH_Delay(200); + USBH_LL_ResetPort(phost); +#if (USBH_USE_OS == 1) + osMessagePut ( phost->os_event, USBH_PORT_EVENT, 0); +#endif + } + break; + + case HOST_DEV_WAIT_FOR_ATTACHMENT: + break; + + case HOST_DEV_ATTACHED : + + USBH_UsrLog("USB Device Attached"); + + /* Wait for 100 ms after Reset */ + USBH_Delay(100); + + phost->device.speed = USBH_LL_GetSpeed(phost); + + phost->gState = HOST_ENUMERATION; + + phost->Control.pipe_out = USBH_AllocPipe (phost, 0x00); + phost->Control.pipe_in = USBH_AllocPipe (phost, 0x80); + + + /* Open Control pipes */ + USBH_OpenPipe (phost, + phost->Control.pipe_in, + 0x80, + phost->device.address, + phost->device.speed, + USBH_EP_CONTROL, + phost->Control.pipe_size); + + /* Open Control pipes */ + USBH_OpenPipe (phost, + phost->Control.pipe_out, + 0x00, + phost->device.address, + phost->device.speed, + USBH_EP_CONTROL, + phost->Control.pipe_size); + +#if (USBH_USE_OS == 1) + osMessagePut ( phost->os_event, USBH_PORT_EVENT, 0); +#endif + + break; + + case HOST_ENUMERATION: + /* Check for enumeration status */ + if ( USBH_HandleEnum(phost) == USBH_OK) + { + /* The function shall return USBH_OK when full enumeration is complete */ + USBH_UsrLog ("Enumeration done."); + phost->device.current_interface = 0; + if(phost->device.DevDesc.bNumConfigurations == 1) + { + USBH_UsrLog ("This device has only 1 configuration."); + phost->gState = HOST_SET_CONFIGURATION; + + } + else + { + phost->gState = HOST_INPUT; + } + + } + break; + + case HOST_INPUT: + { + /* user callback for end of device basic enumeration */ + if(phost->pUser != NULL) + { + phost->pUser(phost, HOST_USER_SELECT_CONFIGURATION); + phost->gState = HOST_SET_CONFIGURATION; + +#if (USBH_USE_OS == 1) + osMessagePut ( phost->os_event, USBH_STATE_CHANGED_EVENT, 0); +#endif + } + } + break; + + case HOST_SET_CONFIGURATION: + /* set configuration */ + if (USBH_SetCfg(phost, phost->device.CfgDesc.bConfigurationValue) == USBH_OK) + { + phost->gState = HOST_CHECK_CLASS; + USBH_UsrLog ("Default configuration set."); + + } + + break; + + case HOST_CHECK_CLASS: + + if(phost->ClassNumber == 0) + { + USBH_UsrLog ("No Class has been registered."); + } + else + { + phost->pActiveClass = NULL; + + for (idx = 0; idx < USBH_MAX_NUM_SUPPORTED_CLASS ; idx ++) + { + if(phost->pClass[idx]->ClassCode == phost->device.CfgDesc.Itf_Desc[0].bInterfaceClass) + { + phost->pActiveClass = phost->pClass[idx]; + } + } + + if(phost->pActiveClass != NULL) + { + if(phost->pActiveClass->Init(phost)== USBH_OK) + { + phost->gState = HOST_CLASS_REQUEST; + USBH_UsrLog ("%s class started.", phost->pActiveClass->Name); + + /* Inform user that a class has been activated */ + phost->pUser(phost, HOST_USER_CLASS_SELECTED); + } + else + { + phost->gState = HOST_ABORT_STATE; + USBH_UsrLog ("Device not supporting %s class.", phost->pActiveClass->Name); + } + } + else + { + phost->gState = HOST_ABORT_STATE; + USBH_UsrLog ("No registered class for this device."); + } + } + +#if (USBH_USE_OS == 1) + osMessagePut ( phost->os_event, USBH_STATE_CHANGED_EVENT, 0); +#endif + break; + + case HOST_CLASS_REQUEST: + /* process class standard contol requests state machine */ + + if(phost->pActiveClass != NULL) + { + status = phost->pActiveClass->Requests(phost); + + if(status == USBH_OK) + { + phost->gState = HOST_CLASS; + } + } + else + { + phost->gState = HOST_ABORT_STATE; + USBH_ErrLog ("Invalid Class Driver."); + +#if (USBH_USE_OS == 1) + osMessagePut ( phost->os_event, USBH_STATE_CHANGED_EVENT, 0); +#endif + } + + break; + case HOST_CLASS: + /* process class state machine */ + if(phost->pActiveClass != NULL) + { + phost->pActiveClass->BgndProcess(phost); + } + break; + + case HOST_DEV_DISCONNECTED : + + DeInitStateMachine(phost); + + /* Re-Initilaize Host for new Enumeration */ + if(phost->pActiveClass != NULL) + { + phost->pActiveClass->DeInit(phost); + phost->pActiveClass = NULL; + } + break; + + case HOST_ABORT_STATE: + default : + break; + } + return USBH_OK; +} + + +/** + * @brief USBH_HandleEnum + * This function includes the complete enumeration process + * @param phost: Host Handle + * @retval USBH_Status + */ +static USBH_StatusTypeDef USBH_HandleEnum (USBH_HandleTypeDef *phost) +{ + USBH_StatusTypeDef Status = USBH_BUSY; + + switch (phost->EnumState) + { + case ENUM_IDLE: + /* Get Device Desc for only 1st 8 bytes : To get EP0 MaxPacketSize */ + if ( USBH_Get_DevDesc(phost, 8) == USBH_OK) + { + phost->Control.pipe_size = phost->device.DevDesc.bMaxPacketSize; + + phost->EnumState = ENUM_GET_FULL_DEV_DESC; + + /* modify control channels configuration for MaxPacket size */ + USBH_OpenPipe (phost, + phost->Control.pipe_in, + 0x80, + phost->device.address, + phost->device.speed, + USBH_EP_CONTROL, + phost->Control.pipe_size); + + /* Open Control pipes */ + USBH_OpenPipe (phost, + phost->Control.pipe_out, + 0x00, + phost->device.address, + phost->device.speed, + USBH_EP_CONTROL, + phost->Control.pipe_size); + + } + break; + + case ENUM_GET_FULL_DEV_DESC: + /* Get FULL Device Desc */ + if ( USBH_Get_DevDesc(phost, USB_DEVICE_DESC_SIZE)== USBH_OK) + { + USBH_UsrLog("PID: %xh", phost->device.DevDesc.idProduct ); + USBH_UsrLog("VID: %xh", phost->device.DevDesc.idVendor ); + + phost->EnumState = ENUM_SET_ADDR; + + } + break; + + case ENUM_SET_ADDR: + /* set address */ + if ( USBH_SetAddress(phost, USBH_DEVICE_ADDRESS) == USBH_OK) + { + USBH_Delay(2); + phost->device.address = USBH_DEVICE_ADDRESS; + + /* user callback for device address assigned */ + USBH_UsrLog("Address (#%d) assigned.", phost->device.address); + phost->EnumState = ENUM_GET_CFG_DESC; + + /* modify control channels to update device address */ + USBH_OpenPipe (phost, + phost->Control.pipe_in, + 0x80, + phost->device.address, + phost->device.speed, + USBH_EP_CONTROL, + phost->Control.pipe_size); + + /* Open Control pipes */ + USBH_OpenPipe (phost, + phost->Control.pipe_out, + 0x00, + phost->device.address, + phost->device.speed, + USBH_EP_CONTROL, + phost->Control.pipe_size); + } + break; + + case ENUM_GET_CFG_DESC: + /* get standard configuration descriptor */ + if ( USBH_Get_CfgDesc(phost, + USB_CONFIGURATION_DESC_SIZE) == USBH_OK) + { + phost->EnumState = ENUM_GET_FULL_CFG_DESC; + } + break; + + case ENUM_GET_FULL_CFG_DESC: + /* get FULL config descriptor (config, interface, endpoints) */ + if (USBH_Get_CfgDesc(phost, + phost->device.CfgDesc.wTotalLength) == USBH_OK) + { + phost->EnumState = ENUM_GET_MFC_STRING_DESC; + } + break; + + case ENUM_GET_MFC_STRING_DESC: + if (phost->device.DevDesc.iManufacturer != 0) + { /* Check that Manufacturer String is available */ + + if ( USBH_Get_StringDesc(phost, + phost->device.DevDesc.iManufacturer, + phost->device.Data , + 0xff) == USBH_OK) + { + /* User callback for Manufacturing string */ + USBH_UsrLog("Manufacturer : %s", (char *)phost->device.Data); + phost->EnumState = ENUM_GET_PRODUCT_STRING_DESC; + +#if (USBH_USE_OS == 1) + osMessagePut ( phost->os_event, USBH_STATE_CHANGED_EVENT, 0); +#endif + } + } + else + { + USBH_UsrLog("Manufacturer : N/A"); + phost->EnumState = ENUM_GET_PRODUCT_STRING_DESC; +#if (USBH_USE_OS == 1) + osMessagePut ( phost->os_event, USBH_STATE_CHANGED_EVENT, 0); +#endif + } + break; + + case ENUM_GET_PRODUCT_STRING_DESC: + if (phost->device.DevDesc.iProduct != 0) + { /* Check that Product string is available */ + if ( USBH_Get_StringDesc(phost, + phost->device.DevDesc.iProduct, + phost->device.Data, + 0xff) == USBH_OK) + { + /* User callback for Product string */ + USBH_UsrLog("Product : %s", (char *)phost->device.Data); + phost->EnumState = ENUM_GET_SERIALNUM_STRING_DESC; + } + } + else + { + USBH_UsrLog("Product : N/A"); + phost->EnumState = ENUM_GET_SERIALNUM_STRING_DESC; +#if (USBH_USE_OS == 1) + osMessagePut ( phost->os_event, USBH_STATE_CHANGED_EVENT, 0); +#endif + } + break; + + case ENUM_GET_SERIALNUM_STRING_DESC: + if (phost->device.DevDesc.iSerialNumber != 0) + { /* Check that Serial number string is available */ + if ( USBH_Get_StringDesc(phost, + phost->device.DevDesc.iSerialNumber, + phost->device.Data, + 0xff) == USBH_OK) + { + /* User callback for Serial number string */ + USBH_UsrLog("Serial Number : %s", (char *)phost->device.Data); + Status = USBH_OK; + } + } + else + { + USBH_UsrLog("Serial Number : N/A"); + Status = USBH_OK; +#if (USBH_USE_OS == 1) + osMessagePut ( phost->os_event, USBH_STATE_CHANGED_EVENT, 0); +#endif + } + break; + + default: + break; + } + return Status; +} + +/** + * @brief USBH_LL_SetTimer + * Set the initial Host Timer tick + * @param phost: Host Handle + * @retval None + */ +void USBH_LL_SetTimer (USBH_HandleTypeDef *phost, uint32_t time) +{ + phost->Timer = time; +} +/** + * @brief USBH_LL_IncTimer + * Increment Host Timer tick + * @param phost: Host Handle + * @retval None + */ +void USBH_LL_IncTimer (USBH_HandleTypeDef *phost) +{ + phost->Timer ++; + USBH_HandleSof(phost); +} + +/** + * @brief USBH_HandleSof + * Call SOF process + * @param phost: Host Handle + * @retval None + */ +void USBH_HandleSof (USBH_HandleTypeDef *phost) +{ + if((phost->gState == HOST_CLASS)&&(phost->pActiveClass != NULL)) + { + phost->pActiveClass->SOFProcess(phost); + } +} +/** + * @brief USBH_LL_Connect + * Handle USB Host connexion event + * @param phost: Host Handle + * @retval USBH_Status + */ +USBH_StatusTypeDef USBH_LL_Connect (USBH_HandleTypeDef *phost) +{ + if(phost->gState == HOST_IDLE ) + { + phost->device.is_connected = 1; + phost->gState = HOST_IDLE ; + + if(phost->pUser != NULL) + { + phost->pUser(phost, HOST_USER_CONNECTION); + } + } + else if(phost->gState == HOST_DEV_WAIT_FOR_ATTACHMENT ) + { + phost->gState = HOST_DEV_ATTACHED ; + } +#if (USBH_USE_OS == 1) + osMessagePut ( phost->os_event, USBH_PORT_EVENT, 0); +#endif + + return USBH_OK; +} + +/** + * @brief USBH_LL_Disconnect + * Handle USB Host disconnexion event + * @param phost: Host Handle + * @retval USBH_Status + */ +USBH_StatusTypeDef USBH_LL_Disconnect (USBH_HandleTypeDef *phost) +{ + /*Stop Host */ + USBH_LL_Stop(phost); + + /* FRee Control Pipes */ + USBH_FreePipe (phost, phost->Control.pipe_in); + USBH_FreePipe (phost, phost->Control.pipe_out); + + phost->device.is_connected = 0; + + if(phost->pUser != NULL) + { + phost->pUser(phost, HOST_USER_DISCONNECTION); + } + USBH_UsrLog("USB Device disconnected"); + + /* Start the low level driver */ + USBH_LL_Start(phost); + + phost->gState = HOST_DEV_DISCONNECTED; + +#if (USBH_USE_OS == 1) + osMessagePut ( phost->os_event, USBH_PORT_EVENT, 0); +#endif + + return USBH_OK; +} + + +#if (USBH_USE_OS == 1) +/** + * @brief USB Host Thread task + * @param pvParameters not used + * @retval None + */ +static void USBH_Process_OS(void const * argument) +{ + osEvent event; + + for(;;) + { + event = osMessageGet(((USBH_HandleTypeDef *)argument)->os_event, osWaitForever ); + + if( event.status == osEventMessage ) + { + USBH_Process((USBH_HandleTypeDef *)argument); + } + } +} + +/** +* @brief USBH_LL_NotifyURBChange +* Notify URB state Change +* @param phost: Host handle +* @retval USBH Status +*/ +USBH_StatusTypeDef USBH_LL_NotifyURBChange (USBH_HandleTypeDef *phost) +{ + osMessagePut ( phost->os_event, USBH_URB_EVENT, 0); + return USBH_OK; +} +#endif +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/stmhal/usbhost/Core/Src/usbh_ctlreq.c b/stmhal/usbhost/Core/Src/usbh_ctlreq.c new file mode 100644 index 000000000..58bc34d64 --- /dev/null +++ b/stmhal/usbhost/Core/Src/usbh_ctlreq.c @@ -0,0 +1,881 @@ +/** + ****************************************************************************** + * @file usbh_ctlreq.c + * @author MCD Application Team + * @version V3.0.0 + * @date 18-February-2014 + * @brief This file implements the control requests for device enumeration + ****************************************************************************** + * @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_ctlreq.h" + +/** @addtogroup USBH_LIB +* @{ +*/ + +/** @addtogroup USBH_LIB_CORE +* @{ +*/ + +/** @defgroup USBH_CTLREQ +* @brief This file implements the standard requests for device enumeration +* @{ +*/ + + +/** @defgroup USBH_CTLREQ_Private_Defines +* @{ +*/ +/** +* @} +*/ + + +/** @defgroup USBH_CTLREQ_Private_TypesDefinitions +* @{ +*/ +/** +* @} +*/ + + + +/** @defgroup USBH_CTLREQ_Private_Macros +* @{ +*/ +/** +* @} +*/ + + +/** @defgroup USBH_CTLREQ_Private_Variables +* @{ +*/ +/** +* @} +*/ + +/** @defgroup USBH_CTLREQ_Private_FunctionPrototypes +* @{ +*/ +static USBH_StatusTypeDef USBH_HandleControl (USBH_HandleTypeDef *phost); + +static void USBH_ParseDevDesc (USBH_DevDescTypeDef* , uint8_t *buf, uint16_t length); + +static void USBH_ParseCfgDesc (USBH_CfgDescTypeDef* cfg_desc, + uint8_t *buf, + uint16_t length); + + +static void USBH_ParseEPDesc (USBH_EpDescTypeDef *ep_descriptor, uint8_t *buf); +static void USBH_ParseStringDesc (uint8_t* psrc, uint8_t* pdest, uint16_t length); +static void USBH_ParseInterfaceDesc (USBH_InterfaceDescTypeDef *if_descriptor, uint8_t *buf); + + +/** +* @} +*/ + + +/** @defgroup USBH_CTLREQ_Private_Functions +* @{ +*/ + + +/** + * @brief USBH_Get_DevDesc + * Issue Get Device Descriptor command to the device. Once the response + * received, it parses the device descriptor and updates the status. + * @param phost: Host Handle + * @param length: Length of the descriptor + * @retval USBH Status + */ +USBH_StatusTypeDef USBH_Get_DevDesc(USBH_HandleTypeDef *phost, uint8_t length) +{ + USBH_StatusTypeDef status; + + if((status = USBH_GetDescriptor(phost, + USB_REQ_RECIPIENT_DEVICE | USB_REQ_TYPE_STANDARD, + USB_DESC_DEVICE, + phost->device.Data, + length)) == USBH_OK) + { + /* Commands successfully sent and Response Received */ + USBH_ParseDevDesc(&phost->device.DevDesc, phost->device.Data, length); + } + return status; +} + +/** + * @brief USBH_Get_CfgDesc + * Issues Configuration Descriptor to the device. Once the response + * received, it parses the configuartion descriptor and updates the + * status. + * @param phost: Host Handle + * @param length: Length of the descriptor + * @retval USBH Status + */ +USBH_StatusTypeDef USBH_Get_CfgDesc(USBH_HandleTypeDef *phost, + uint16_t length) + +{ + USBH_StatusTypeDef status; + uint8_t *pData; +#if (USBH_KEEP_CFG_DESCRIPTOR == 1) + pData = phost->device.CfgDesc_Raw; +#else + pData = phost->device.Data; +#endif + if((status = USBH_GetDescriptor(phost, + USB_REQ_RECIPIENT_DEVICE | USB_REQ_TYPE_STANDARD, + USB_DESC_CONFIGURATION, + pData, + length)) == USBH_OK) + { + + /* Commands successfully sent and Response Received */ + USBH_ParseCfgDesc (&phost->device.CfgDesc, + pData, + length); + + } + return status; +} + + +/** + * @brief USBH_Get_StringDesc + * Issues string Descriptor command to the device. Once the response + * received, it parses the string descriptor and updates the status. + * @param phost: Host Handle + * @param string_index: String index for the descriptor + * @param buff: Buffer address for the descriptor + * @param length: Length of the descriptor + * @retval USBH Status + */ +USBH_StatusTypeDef USBH_Get_StringDesc(USBH_HandleTypeDef *phost, + uint8_t string_index, + uint8_t *buff, + uint16_t length) +{ + USBH_StatusTypeDef status; + if((status = USBH_GetDescriptor(phost, + USB_REQ_RECIPIENT_DEVICE | USB_REQ_TYPE_STANDARD, + USB_DESC_STRING | string_index, + phost->device.Data, + length)) == USBH_OK) + { + /* Commands successfully sent and Response Received */ + USBH_ParseStringDesc(phost->device.Data,buff, length); + } + return status; +} + +/** + * @brief USBH_GetDescriptor + * Issues Descriptor command to the device. Once the response received, + * it parses the descriptor and updates the status. + * @param phost: Host Handle + * @param req_type: Descriptor type + * @param value_idx: wValue for the GetDescriptr request + * @param buff: Buffer to store the descriptor + * @param length: Length of the descriptor + * @retval USBH Status + */ +USBH_StatusTypeDef USBH_GetDescriptor(USBH_HandleTypeDef *phost, + uint8_t req_type, + uint16_t value_idx, + uint8_t* buff, + uint16_t length ) +{ + if(phost->RequestState == CMD_SEND) + { + phost->Control.setup.b.bmRequestType = USB_D2H | req_type; + phost->Control.setup.b.bRequest = USB_REQ_GET_DESCRIPTOR; + phost->Control.setup.b.wValue.w = value_idx; + + if ((value_idx & 0xff00) == USB_DESC_STRING) + { + phost->Control.setup.b.wIndex.w = 0x0409; + } + else + { + phost->Control.setup.b.wIndex.w = 0; + } + phost->Control.setup.b.wLength.w = length; + } + return USBH_CtlReq(phost, buff , length ); +} + +/** + * @brief USBH_SetAddress + * This command sets the address to the connected device + * @param phost: Host Handle + * @param DeviceAddress: Device address to assign + * @retval USBH Status + */ +USBH_StatusTypeDef USBH_SetAddress(USBH_HandleTypeDef *phost, + uint8_t DeviceAddress) +{ + if(phost->RequestState == CMD_SEND) + { + phost->Control.setup.b.bmRequestType = USB_H2D | USB_REQ_RECIPIENT_DEVICE | \ + USB_REQ_TYPE_STANDARD; + + phost->Control.setup.b.bRequest = USB_REQ_SET_ADDRESS; + + phost->Control.setup.b.wValue.w = (uint16_t)DeviceAddress; + phost->Control.setup.b.wIndex.w = 0; + phost->Control.setup.b.wLength.w = 0; + } + return USBH_CtlReq(phost, 0 , 0 ); +} + +/** + * @brief USBH_SetCfg + * The command sets the configuration value to the connected device + * @param phost: Host Handle + * @param cfg_idx: Configuration value + * @retval USBH Status + */ +USBH_StatusTypeDef USBH_SetCfg(USBH_HandleTypeDef *phost, + uint16_t cfg_idx) +{ + if(phost->RequestState == CMD_SEND) + { + phost->Control.setup.b.bmRequestType = USB_H2D | USB_REQ_RECIPIENT_DEVICE |\ + USB_REQ_TYPE_STANDARD; + phost->Control.setup.b.bRequest = USB_REQ_SET_CONFIGURATION; + phost->Control.setup.b.wValue.w = cfg_idx; + phost->Control.setup.b.wIndex.w = 0; + phost->Control.setup.b.wLength.w = 0; + } + + return USBH_CtlReq(phost, 0 , 0 ); +} + +/** + * @brief USBH_SetInterface + * The command sets the Interface value to the connected device + * @param phost: Host Handle + * @param altSetting: Interface value + * @retval USBH Status + */ +USBH_StatusTypeDef USBH_SetInterface(USBH_HandleTypeDef *phost, + uint8_t ep_num, uint8_t altSetting) +{ + + if(phost->RequestState == CMD_SEND) + { + phost->Control.setup.b.bmRequestType = USB_H2D | USB_REQ_RECIPIENT_INTERFACE | \ + USB_REQ_TYPE_STANDARD; + + phost->Control.setup.b.bRequest = USB_REQ_SET_INTERFACE; + phost->Control.setup.b.wValue.w = altSetting; + phost->Control.setup.b.wIndex.w = ep_num; + phost->Control.setup.b.wLength.w = 0; + } + return USBH_CtlReq(phost, 0 , 0 ); +} + +/** + * @brief USBH_ClrFeature + * This request is used to clear or disable a specific feature. + * @param phost: Host Handle + * @param ep_num: endpoint number + * @param hc_num: Host channel number + * @retval USBH Status + */ +USBH_StatusTypeDef USBH_ClrFeature(USBH_HandleTypeDef *phost, + uint8_t ep_num) +{ + if(phost->RequestState == CMD_SEND) + { + phost->Control.setup.b.bmRequestType = USB_H2D | + USB_REQ_RECIPIENT_ENDPOINT | + USB_REQ_TYPE_STANDARD; + + phost->Control.setup.b.bRequest = USB_REQ_CLEAR_FEATURE; + phost->Control.setup.b.wValue.w = FEATURE_SELECTOR_ENDPOINT; + phost->Control.setup.b.wIndex.w = ep_num; + phost->Control.setup.b.wLength.w = 0; + } + return USBH_CtlReq(phost, 0 , 0 ); +} + +/** + * @brief USBH_ParseDevDesc + * This function Parses the device descriptor + * @param dev_desc: device_descriptor destinaton address + * @param buf: Buffer where the source descriptor is available + * @param length: Length of the descriptor + * @retval None + */ +static void USBH_ParseDevDesc (USBH_DevDescTypeDef* dev_desc, + uint8_t *buf, + uint16_t length) +{ + dev_desc->bLength = *(uint8_t *) (buf + 0); + dev_desc->bDescriptorType = *(uint8_t *) (buf + 1); + dev_desc->bcdUSB = LE16 (buf + 2); + dev_desc->bDeviceClass = *(uint8_t *) (buf + 4); + dev_desc->bDeviceSubClass = *(uint8_t *) (buf + 5); + dev_desc->bDeviceProtocol = *(uint8_t *) (buf + 6); + dev_desc->bMaxPacketSize = *(uint8_t *) (buf + 7); + + if (length > 8) + { /* For 1st time after device connection, Host may issue only 8 bytes for + Device Descriptor Length */ + dev_desc->idVendor = LE16 (buf + 8); + dev_desc->idProduct = LE16 (buf + 10); + dev_desc->bcdDevice = LE16 (buf + 12); + dev_desc->iManufacturer = *(uint8_t *) (buf + 14); + dev_desc->iProduct = *(uint8_t *) (buf + 15); + dev_desc->iSerialNumber = *(uint8_t *) (buf + 16); + dev_desc->bNumConfigurations = *(uint8_t *) (buf + 17); + } +} + +/** + * @brief USBH_ParseCfgDesc + * This function Parses the configuration descriptor + * @param cfg_desc: Configuration Descriptor address + * @param buf: Buffer where the source descriptor is available + * @param length: Length of the descriptor + * @retval None + */ +static void USBH_ParseCfgDesc (USBH_CfgDescTypeDef* cfg_desc, + uint8_t *buf, + uint16_t length) +{ + USBH_InterfaceDescTypeDef *pif ; + USBH_EpDescTypeDef *pep; + USBH_DescHeader_t *pdesc = (USBH_DescHeader_t *)buf; + uint16_t ptr; + int8_t if_ix = 0; + int8_t ep_ix = 0; + + pdesc = (USBH_DescHeader_t *)buf; + + /* Parse configuration descriptor */ + cfg_desc->bLength = *(uint8_t *) (buf + 0); + cfg_desc->bDescriptorType = *(uint8_t *) (buf + 1); + cfg_desc->wTotalLength = LE16 (buf + 2); + cfg_desc->bNumInterfaces = *(uint8_t *) (buf + 4); + cfg_desc->bConfigurationValue = *(uint8_t *) (buf + 5); + cfg_desc->iConfiguration = *(uint8_t *) (buf + 6); + cfg_desc->bmAttributes = *(uint8_t *) (buf + 7); + cfg_desc->bMaxPower = *(uint8_t *) (buf + 8); + + + if (length > USB_CONFIGURATION_DESC_SIZE) + { + ptr = USB_LEN_CFG_DESC; + pif = (USBH_InterfaceDescTypeDef *)0; + + + while ((if_ix < USBH_MAX_NUM_INTERFACES ) && (ptr < cfg_desc->wTotalLength)) + { + pdesc = USBH_GetNextDesc((uint8_t *)pdesc, &ptr); + if (pdesc->bDescriptorType == USB_DESC_TYPE_INTERFACE) + { + pif = &cfg_desc->Itf_Desc[if_ix]; + USBH_ParseInterfaceDesc (pif, (uint8_t *)pdesc); + + ep_ix = 0; + pep = (USBH_EpDescTypeDef *)0; + while ((ep_ix < pif->bNumEndpoints) && (ptr < cfg_desc->wTotalLength)) + { + pdesc = USBH_GetNextDesc((void* )pdesc, &ptr); + if (pdesc->bDescriptorType == USB_DESC_TYPE_ENDPOINT) + { + pep = &cfg_desc->Itf_Desc[if_ix].Ep_Desc[ep_ix]; + USBH_ParseEPDesc (pep, (uint8_t *)pdesc); + ep_ix++; + } + } + if_ix++; + } + } + } +} + + + +/** + * @brief USBH_ParseInterfaceDesc + * This function Parses the interface descriptor + * @param if_descriptor : Interface descriptor destination + * @param buf: Buffer where the descriptor data is available + * @retval None + */ +static void USBH_ParseInterfaceDesc (USBH_InterfaceDescTypeDef *if_descriptor, + uint8_t *buf) +{ + if_descriptor->bLength = *(uint8_t *) (buf + 0); + if_descriptor->bDescriptorType = *(uint8_t *) (buf + 1); + if_descriptor->bInterfaceNumber = *(uint8_t *) (buf + 2); + if_descriptor->bAlternateSetting = *(uint8_t *) (buf + 3); + if_descriptor->bNumEndpoints = *(uint8_t *) (buf + 4); + if_descriptor->bInterfaceClass = *(uint8_t *) (buf + 5); + if_descriptor->bInterfaceSubClass = *(uint8_t *) (buf + 6); + if_descriptor->bInterfaceProtocol = *(uint8_t *) (buf + 7); + if_descriptor->iInterface = *(uint8_t *) (buf + 8); +} + +/** + * @brief USBH_ParseEPDesc + * This function Parses the endpoint descriptor + * @param ep_descriptor: Endpoint descriptor destination address + * @param buf: Buffer where the parsed descriptor stored + * @retval None + */ +static void USBH_ParseEPDesc (USBH_EpDescTypeDef *ep_descriptor, + uint8_t *buf) +{ + + ep_descriptor->bLength = *(uint8_t *) (buf + 0); + ep_descriptor->bDescriptorType = *(uint8_t *) (buf + 1); + ep_descriptor->bEndpointAddress = *(uint8_t *) (buf + 2); + ep_descriptor->bmAttributes = *(uint8_t *) (buf + 3); + ep_descriptor->wMaxPacketSize = LE16 (buf + 4); + ep_descriptor->bInterval = *(uint8_t *) (buf + 6); +} + +/** + * @brief USBH_ParseStringDesc + * This function Parses the string descriptor + * @param psrc: Source pointer containing the descriptor data + * @param pdest: Destination address pointer + * @param length: Length of the descriptor + * @retval None + */ +static void USBH_ParseStringDesc (uint8_t* psrc, + uint8_t* pdest, + uint16_t length) +{ + uint16_t strlength; + uint16_t idx; + + /* The UNICODE string descriptor is not NULL-terminated. The string length is + computed by substracting two from the value of the first byte of the descriptor. + */ + + /* Check which is lower size, the Size of string or the length of bytes read + from the device */ + + if ( psrc[1] == USB_DESC_TYPE_STRING) + { /* Make sure the Descriptor is String Type */ + + /* psrc[0] contains Size of Descriptor, subtract 2 to get the length of string */ + strlength = ( ( (psrc[0]-2) <= length) ? (psrc[0]-2) :length); + psrc += 2; /* Adjust the offset ignoring the String Len and Descriptor type */ + + for (idx = 0; idx < strlength; idx+=2 ) + {/* Copy Only the string and ignore the UNICODE ID, hence add the src */ + *pdest = psrc[idx]; + pdest++; + } + *pdest = 0; /* mark end of string */ + } +} + +/** + * @brief USBH_GetNextDesc + * This function return the next descriptor header + * @param buf: Buffer where the cfg descriptor is available + * @param ptr: data popinter inside the cfg descriptor + * @retval next header + */ +USBH_DescHeader_t *USBH_GetNextDesc (uint8_t *pbuf, uint16_t *ptr) +{ + USBH_DescHeader_t *pnext; + + *ptr += ((USBH_DescHeader_t *)pbuf)->bLength; + pnext = (USBH_DescHeader_t *)((uint8_t *)pbuf + \ + ((USBH_DescHeader_t *)pbuf)->bLength); + + return(pnext); +} + + +/** + * @brief USBH_CtlReq + * USBH_CtlReq sends a control request and provide the status after + * completion of the request + * @param phost: Host Handle + * @param req: Setup Request Structure + * @param buff: data buffer address to store the response + * @param length: length of the response + * @retval USBH Status + */ +USBH_StatusTypeDef USBH_CtlReq (USBH_HandleTypeDef *phost, + uint8_t *buff, + uint16_t length) +{ + USBH_StatusTypeDef status; + status = USBH_BUSY; + + switch (phost->RequestState) + { + case CMD_SEND: + /* Start a SETUP transfer */ + phost->Control.buff = buff; + phost->Control.length = length; + phost->Control.state = CTRL_SETUP; + phost->RequestState = CMD_WAIT; + status = USBH_BUSY; +#if (USBH_USE_OS == 1) + osMessagePut ( phost->os_event, USBH_CONTROL_EVENT, 0); +#endif + break; + + case CMD_WAIT: + status = USBH_HandleControl(phost); + if (status == USBH_OK) + { + /* Commands successfully sent and Response Received */ + phost->RequestState = CMD_SEND; + phost->Control.state =CTRL_IDLE; + status = USBH_OK; + } + else if (status == USBH_FAIL) + { + /* Failure Mode */ + phost->RequestState = CMD_SEND; + status = USBH_FAIL; + } + break; + + default: + break; + } + return status; +} + +/** + * @brief USBH_HandleControl + * Handles the USB control transfer state machine + * @param phost: Host Handle + * @retval USBH Status + */ +static USBH_StatusTypeDef USBH_HandleControl (USBH_HandleTypeDef *phost) +{ + uint8_t direction; + USBH_StatusTypeDef status = USBH_BUSY; + USBH_URBStateTypeDef URB_Status = USBH_URB_IDLE; + + switch (phost->Control.state) + { + case CTRL_SETUP: + /* send a SETUP packet */ + USBH_CtlSendSetup (phost, + (uint8_t *)phost->Control.setup.d8 , + phost->Control.pipe_out); + + phost->Control.state = CTRL_SETUP_WAIT; + break; + + case CTRL_SETUP_WAIT: + + URB_Status = USBH_LL_GetURBState(phost, phost->Control.pipe_out); + /* case SETUP packet sent successfully */ + if(URB_Status == USBH_URB_DONE) + { + direction = (phost->Control.setup.b.bmRequestType & USB_REQ_DIR_MASK); + + /* check if there is a data stage */ + if (phost->Control.setup.b.wLength.w != 0 ) + { + if (direction == USB_D2H) + { + /* Data Direction is IN */ + phost->Control.state = CTRL_DATA_IN; + } + else + { + /* Data Direction is OUT */ + phost->Control.state = CTRL_DATA_OUT; + } + } + /* No DATA stage */ + else + { + /* If there is No Data Transfer Stage */ + if (direction == USB_D2H) + { + /* Data Direction is IN */ + phost->Control.state = CTRL_STATUS_OUT; + } + else + { + /* Data Direction is OUT */ + phost->Control.state = CTRL_STATUS_IN; + } + } +#if (USBH_USE_OS == 1) + osMessagePut ( phost->os_event, USBH_CONTROL_EVENT, 0); +#endif + } + else if(URB_Status == USBH_URB_ERROR) + { + phost->Control.state = CTRL_ERROR; +#if (USBH_USE_OS == 1) + osMessagePut ( phost->os_event, USBH_CONTROL_EVENT, 0); +#endif + } + break; + + case CTRL_DATA_IN: + /* Issue an IN token */ + phost->Control.timer = phost->Timer; + USBH_CtlReceiveData(phost, + phost->Control.buff, + phost->Control.length, + phost->Control.pipe_in); + + phost->Control.state = CTRL_DATA_IN_WAIT; + break; + + case CTRL_DATA_IN_WAIT: + + URB_Status = USBH_LL_GetURBState(phost , phost->Control.pipe_in); + + /* check is DATA packet transfered successfully */ + if (URB_Status == USBH_URB_DONE) + { + phost->Control.state = CTRL_STATUS_OUT; +#if (USBH_USE_OS == 1) + osMessagePut ( phost->os_event, USBH_CONTROL_EVENT, 0); +#endif + } + + /* manage error cases*/ + if (URB_Status == USBH_URB_STALL) + { + /* In stall case, return to previous machine state*/ + status = USBH_NOT_SUPPORTED; +#if (USBH_USE_OS == 1) + osMessagePut ( phost->os_event, USBH_CONTROL_EVENT, 0); +#endif + } + else if (URB_Status == USBH_URB_ERROR) + { + /* Device error */ + phost->Control.state = CTRL_ERROR; +#if (USBH_USE_OS == 1) + osMessagePut ( phost->os_event, USBH_CONTROL_EVENT, 0); +#endif + } + break; + + case CTRL_DATA_OUT: + + USBH_CtlSendData (phost, + phost->Control.buff, + phost->Control.length , + phost->Control.pipe_out, + 1); + phost->Control.timer = phost->Timer; + phost->Control.state = CTRL_DATA_OUT_WAIT; + break; + + case CTRL_DATA_OUT_WAIT: + + URB_Status = USBH_LL_GetURBState(phost , phost->Control.pipe_out); + + if (URB_Status == USBH_URB_DONE) + { /* If the Setup Pkt is sent successful, then change the state */ + phost->Control.state = CTRL_STATUS_IN; +#if (USBH_USE_OS == 1) + osMessagePut ( phost->os_event, USBH_CONTROL_EVENT, 0); +#endif + } + + /* handle error cases */ + else if (URB_Status == USBH_URB_STALL) + { + /* In stall case, return to previous machine state*/ + phost->Control.state = CTRL_STALLED; + status = USBH_NOT_SUPPORTED; +#if (USBH_USE_OS == 1) + osMessagePut ( phost->os_event, USBH_CONTROL_EVENT, 0); +#endif + } + else if (URB_Status == USBH_URB_NOTREADY) + { + /* Nack received from device */ + phost->Control.state = CTRL_DATA_OUT; + +#if (USBH_USE_OS == 1) + osMessagePut ( phost->os_event, USBH_CONTROL_EVENT, 0); +#endif + } + else if (URB_Status == USBH_URB_ERROR) + { + /* device error */ + phost->Control.state = CTRL_ERROR; + status = USBH_FAIL; + +#if (USBH_USE_OS == 1) + osMessagePut ( phost->os_event, USBH_CONTROL_EVENT, 0); +#endif + } + break; + + + case CTRL_STATUS_IN: + /* Send 0 bytes out packet */ + USBH_CtlReceiveData (phost, + 0, + 0, + phost->Control.pipe_in); + phost->Control.timer = phost->Timer; + phost->Control.state = CTRL_STATUS_IN_WAIT; + + break; + + case CTRL_STATUS_IN_WAIT: + + URB_Status = USBH_LL_GetURBState(phost , phost->Control.pipe_in); + + if ( URB_Status == USBH_URB_DONE) + { /* Control transfers completed, Exit the State Machine */ + phost->Control.state = CTRL_COMPLETE; + status = USBH_OK; +#if (USBH_USE_OS == 1) + osMessagePut ( phost->os_event, USBH_CONTROL_EVENT, 0); +#endif + } + + else if (URB_Status == USBH_URB_ERROR) + { + phost->Control.state = CTRL_ERROR; +#if (USBH_USE_OS == 1) + osMessagePut ( phost->os_event, USBH_CONTROL_EVENT, 0); +#endif + } + else if(URB_Status == USBH_URB_STALL) + { + /* Control transfers completed, Exit the State Machine */ + status = USBH_NOT_SUPPORTED; + +#if (USBH_USE_OS == 1) + osMessagePut ( phost->os_event, USBH_CONTROL_EVENT, 0); +#endif + } + break; + + case CTRL_STATUS_OUT: + USBH_CtlSendData (phost, + 0, + 0, + phost->Control.pipe_out, + 1); + phost->Control.timer = phost->Timer; + phost->Control.state = CTRL_STATUS_OUT_WAIT; + break; + + case CTRL_STATUS_OUT_WAIT: + + URB_Status = USBH_LL_GetURBState(phost , phost->Control.pipe_out); + if (URB_Status == USBH_URB_DONE) + { + status = USBH_OK; + phost->Control.state = CTRL_COMPLETE; + +#if (USBH_USE_OS == 1) + osMessagePut ( phost->os_event, USBH_CONTROL_EVENT, 0); +#endif + } + else if (URB_Status == USBH_URB_NOTREADY) + { + phost->Control.state = CTRL_STATUS_OUT; + +#if (USBH_USE_OS == 1) + osMessagePut ( phost->os_event, USBH_CONTROL_EVENT, 0); +#endif + } + else if (URB_Status == USBH_URB_ERROR) + { + phost->Control.state = CTRL_ERROR; + +#if (USBH_USE_OS == 1) + osMessagePut ( phost->os_event, USBH_CONTROL_EVENT, 0); +#endif + } + break; + + case CTRL_ERROR: + /* + After a halt condition is encountered or an error is detected by the + host, a control endpoint is allowed to recover by accepting the next Setup + PID; i.e., recovery actions via some other pipe are not required for control + endpoints. For the Default Control Pipe, a device reset will ultimately be + required to clear the halt or error condition if the next Setup PID is not + accepted. + */ + if (++ phost->Control.errorcount <= USBH_MAX_ERROR_COUNT) + { + /* try to recover control */ + USBH_LL_Stop(phost); + + /* Do the transmission again, starting from SETUP Packet */ + phost->Control.state = CTRL_SETUP; + phost->RequestState = CMD_SEND; + } + else + { + phost->Control.errorcount = 0; + USBH_ErrLog("Control error"); + status = USBH_FAIL; + + } + break; + + default: + break; + } + return status; +} + +/** +* @} +*/ + +/** +* @} +*/ + +/** +* @} +*/ + +/** +* @} +*/ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + + + + diff --git a/stmhal/usbhost/Core/Src/usbh_ioreq.c b/stmhal/usbhost/Core/Src/usbh_ioreq.c new file mode 100644 index 000000000..280020355 --- /dev/null +++ b/stmhal/usbhost/Core/Src/usbh_ioreq.c @@ -0,0 +1,358 @@ +/** + ****************************************************************************** + * @file usbh_ioreq.c + * @author MCD Application Team + * @version V3.0.0 + * @date 18-February-2014 + * @brief This file handles the issuing of the USB transactions + ****************************************************************************** + * @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_ioreq.h" + +/** @addtogroup USBH_LIB + * @{ + */ + +/** @addtogroup USBH_LIB_CORE +* @{ +*/ + +/** @defgroup USBH_IOREQ + * @brief This file handles the standard protocol processing (USB v2.0) + * @{ + */ + + +/** @defgroup USBH_IOREQ_Private_Defines + * @{ + */ + +/** + * @} + */ + + +/** @defgroup USBH_IOREQ_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + + + +/** @defgroup USBH_IOREQ_Private_Macros + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBH_IOREQ_Private_Variables + * @{ + */ +/** + * @} + */ +/** @defgroup USBH_IOREQ_Private_FunctionPrototypes + * @{ + */ + +/** + * @} + */ + + +/** @defgroup USBH_IOREQ_Private_Functions + * @{ + */ + + + +/** + * @brief USBH_CtlSendSetup + * Sends the Setup Packet to the Device + * @param phost: Host Handle + * @param buff: Buffer pointer from which the Data will be send to Device + * @param pipe_num: Pipe Number + * @retval USBH Status + */ +USBH_StatusTypeDef USBH_CtlSendSetup (USBH_HandleTypeDef *phost, + uint8_t *buff, + uint8_t pipe_num) +{ + + USBH_LL_SubmitURB (phost, /* Driver handle */ + pipe_num, /* Pipe index */ + 0, /* Direction : OUT */ + USBH_EP_CONTROL, /* EP type */ + USBH_PID_SETUP, /* Type setup */ + buff, /* data buffer */ + USBH_SETUP_PKT_SIZE, /* data length */ + 0); + return USBH_OK; +} + + +/** + * @brief USBH_CtlSendData + * Sends a data Packet to the Device + * @param phost: Host Handle + * @param buff: Buffer pointer from which the Data will be sent to Device + * @param length: Length of the data to be sent + * @param pipe_num: Pipe Number + * @retval USBH Status + */ +USBH_StatusTypeDef USBH_CtlSendData (USBH_HandleTypeDef *phost, + uint8_t *buff, + uint16_t length, + uint8_t pipe_num, + uint8_t do_ping ) +{ + if(phost->device.speed != USBH_SPEED_HIGH) + { + do_ping = 0; + } + + USBH_LL_SubmitURB (phost, /* Driver handle */ + pipe_num, /* Pipe index */ + 0, /* Direction : OUT */ + USBH_EP_CONTROL, /* EP type */ + USBH_PID_DATA, /* Type Data */ + buff, /* data buffer */ + length, /* data length */ + do_ping); /* do ping (HS Only)*/ + + return USBH_OK; +} + + +/** + * @brief USBH_CtlReceiveData + * Receives the Device Response to the Setup Packet + * @param phost: Host Handle + * @param buff: Buffer pointer in which the response needs to be copied + * @param length: Length of the data to be received + * @param pipe_num: Pipe Number + * @retval USBH Status. + */ +USBH_StatusTypeDef USBH_CtlReceiveData(USBH_HandleTypeDef *phost, + uint8_t* buff, + uint16_t length, + uint8_t pipe_num) +{ + USBH_LL_SubmitURB (phost, /* Driver handle */ + pipe_num, /* Pipe index */ + 1, /* Direction : IN */ + USBH_EP_CONTROL, /* EP type */ + USBH_PID_DATA, /* Type Data */ + buff, /* data buffer */ + length, /* data length */ + 0); + return USBH_OK; + +} + + +/** + * @brief USBH_BulkSendData + * Sends the Bulk Packet to the device + * @param phost: Host Handle + * @param buff: Buffer pointer from which the Data will be sent to Device + * @param length: Length of the data to be sent + * @param pipe_num: Pipe Number + * @retval USBH Status + */ +USBH_StatusTypeDef USBH_BulkSendData (USBH_HandleTypeDef *phost, + uint8_t *buff, + uint16_t length, + uint8_t pipe_num, + uint8_t do_ping ) +{ + if(phost->device.speed != USBH_SPEED_HIGH) + { + do_ping = 0; + } + + USBH_LL_SubmitURB (phost, /* Driver handle */ + pipe_num, /* Pipe index */ + 0, /* Direction : IN */ + USBH_EP_BULK, /* EP type */ + USBH_PID_DATA, /* Type Data */ + buff, /* data buffer */ + length, /* data length */ + do_ping); /* do ping (HS Only)*/ + return USBH_OK; +} + + +/** + * @brief USBH_BulkReceiveData + * Receives IN bulk packet from device + * @param phost: Host Handle + * @param buff: Buffer pointer in which the received data packet to be copied + * @param length: Length of the data to be received + * @param pipe_num: Pipe Number + * @retval USBH Status. + */ +USBH_StatusTypeDef USBH_BulkReceiveData(USBH_HandleTypeDef *phost, + uint8_t *buff, + uint16_t length, + uint8_t pipe_num) +{ + USBH_LL_SubmitURB (phost, /* Driver handle */ + pipe_num, /* Pipe index */ + 1, /* Direction : IN */ + USBH_EP_BULK, /* EP type */ + USBH_PID_DATA, /* Type Data */ + buff, /* data buffer */ + length, /* data length */ + 0); + return USBH_OK; +} + + +/** + * @brief USBH_InterruptReceiveData + * Receives the Device Response to the Interrupt IN token + * @param phost: Host Handle + * @param buff: Buffer pointer in which the response needs to be copied + * @param length: Length of the data to be received + * @param pipe_num: Pipe Number + * @retval USBH Status. + */ +USBH_StatusTypeDef USBH_InterruptReceiveData(USBH_HandleTypeDef *phost, + uint8_t *buff, + uint8_t length, + uint8_t pipe_num) +{ + USBH_LL_SubmitURB (phost, /* Driver handle */ + pipe_num, /* Pipe index */ + 1, /* Direction : IN */ + USBH_EP_INTERRUPT, /* EP type */ + USBH_PID_DATA, /* Type Data */ + buff, /* data buffer */ + length, /* data length */ + 0); + + return USBH_OK; +} + +/** + * @brief USBH_InterruptSendData + * Sends the data on Interrupt OUT Endpoint + * @param phost: Host Handle + * @param buff: Buffer pointer from where the data needs to be copied + * @param length: Length of the data to be sent + * @param pipe_num: Pipe Number + * @retval USBH Status. + */ +USBH_StatusTypeDef USBH_InterruptSendData(USBH_HandleTypeDef *phost, + uint8_t *buff, + uint8_t length, + uint8_t pipe_num) +{ + USBH_LL_SubmitURB (phost, /* Driver handle */ + pipe_num, /* Pipe index */ + 0, /* Direction : OUT */ + USBH_EP_INTERRUPT, /* EP type */ + USBH_PID_DATA, /* Type Data */ + buff, /* data buffer */ + length, /* data length */ + 0); + + return USBH_OK; +} + +/** + * @brief USBH_IsocReceiveData + * Receives the Device Response to the Isochronous IN token + * @param phost: Host Handle + * @param buff: Buffer pointer in which the response needs to be copied + * @param length: Length of the data to be received + * @param pipe_num: Pipe Number + * @retval USBH Status. + */ +USBH_StatusTypeDef USBH_IsocReceiveData(USBH_HandleTypeDef *phost, + uint8_t *buff, + uint32_t length, + uint8_t pipe_num) +{ + USBH_LL_SubmitURB (phost, /* Driver handle */ + pipe_num, /* Pipe index */ + 1, /* Direction : IN */ + USBH_EP_ISO, /* EP type */ + USBH_PID_DATA, /* Type Data */ + buff, /* data buffer */ + length, /* data length */ + 0); + + + return USBH_OK; +} + +/** + * @brief USBH_IsocSendData + * Sends the data on Isochronous OUT Endpoint + * @param phost: Host Handle + * @param buff: Buffer pointer from where the data needs to be copied + * @param length: Length of the data to be sent + * @param pipe_num: Pipe Number + * @retval USBH Status. + */ +USBH_StatusTypeDef USBH_IsocSendData(USBH_HandleTypeDef *phost, + uint8_t *buff, + uint32_t length, + uint8_t pipe_num) +{ + USBH_LL_SubmitURB (phost, /* Driver handle */ + pipe_num, /* Pipe index */ + 0, /* Direction : OUT */ + USBH_EP_ISO, /* EP type */ + USBH_PID_DATA, /* Type Data */ + buff, /* data buffer */ + length, /* data length */ + 0); + + return USBH_OK; +} +/** +* @} +*/ + +/** +* @} +*/ + +/** +* @} +*/ + +/** +* @} +*/ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + + + diff --git a/stmhal/usbhost/Core/Src/usbh_pipes.c b/stmhal/usbhost/Core/Src/usbh_pipes.c new file mode 100644 index 000000000..9dcc4c517 --- /dev/null +++ b/stmhal/usbhost/Core/Src/usbh_pipes.c @@ -0,0 +1,204 @@ +/** + ****************************************************************************** + * @file usbh_pipes.c + * @author MCD Application Team + * @version V3.0.0 + * @date 18-February-2014 + * @brief This file implements functions for opening and closing Pipes + ****************************************************************************** + * @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_pipes.h" + +/** @addtogroup USBH_LIB + * @{ + */ + +/** @addtogroup USBH_LIB_CORE +* @{ +*/ + +/** @defgroup USBH_PIPES + * @brief This file includes opening and closing Pipes + * @{ + */ + +/** @defgroup USBH_PIPES_Private_Defines + * @{ + */ +/** + * @} + */ + +/** @defgroup USBH_PIPES_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBH_PIPES_Private_Macros + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBH_PIPES_Private_Variables + * @{ + */ + +/** + * @} + */ + + +/** @defgroup USBH_PIPES_Private_Functions + * @{ + */ +static uint16_t USBH_GetFreePipe (USBH_HandleTypeDef *phost); + + +/** + * @brief USBH_Open_Pipe + * Open a pipe + * @param phost: Host Handle + * @param pipe_num: Pipe Number + * @param dev_address: USB Device address allocated to attached device + * @param speed : USB device speed (Full/Low) + * @param ep_type: end point type (Bulk/int/ctl) + * @param mps: max pkt size + * @retval USBH Status + */ +USBH_StatusTypeDef USBH_OpenPipe (USBH_HandleTypeDef *phost, + uint8_t pipe_num, + uint8_t epnum, + uint8_t dev_address, + uint8_t speed, + uint8_t ep_type, + uint16_t mps) +{ + + USBH_LL_OpenPipe(phost, + pipe_num, + epnum, + dev_address, + speed, + ep_type, + mps); + + return USBH_OK; + +} + +/** + * @brief USBH_ClosePipe + * Close a pipe + * @param phost: Host Handle + * @param pipe_num: Pipe Number + * @retval USBH Status + */ +USBH_StatusTypeDef USBH_ClosePipe (USBH_HandleTypeDef *phost, + uint8_t pipe_num) +{ + + USBH_LL_ClosePipe(phost, pipe_num); + + return USBH_OK; + +} + +/** + * @brief USBH_Alloc_Pipe + * Allocate a new Pipe + * @param phost: Host Handle + * @param ep_addr: End point for which the Pipe to be allocated + * @retval Pipe number + */ +uint8_t USBH_AllocPipe (USBH_HandleTypeDef *phost, uint8_t ep_addr) +{ + uint16_t pipe; + + pipe = USBH_GetFreePipe(phost); + + if (pipe != 0xFFFF) + { + phost->Pipes[pipe] = 0x8000 | ep_addr; + } + return pipe; +} + +/** + * @brief USBH_Free_Pipe + * Free the USB Pipe + * @param phost: Host Handle + * @param idx: Pipe number to be freed + * @retval USBH Status + */ +USBH_StatusTypeDef USBH_FreePipe (USBH_HandleTypeDef *phost, uint8_t idx) +{ + if(idx < 11) + { + phost->Pipes[idx] &= 0x7FFF; + } + return USBH_OK; +} + +/** + * @brief USBH_GetFreePipe + * @param phost: Host Handle + * Get a free Pipe number for allocation to a device endpoint + * @retval idx: Free Pipe number + */ +static uint16_t USBH_GetFreePipe (USBH_HandleTypeDef *phost) +{ + uint8_t idx = 0; + + for (idx = 0 ; idx < 11 ; idx++) + { + if ((phost->Pipes[idx] & 0x8000) == 0) + { + return idx; + } + } + return 0xFFFF; +} +/** +* @} +*/ + +/** +* @} +*/ + +/** +* @} +*/ + +/** +* @} +*/ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + + -- cgit v1.2.3