Sync inav to Gitea
Make sure docs are updated / settings_md (push) Canceled after 0s
Build firmware / test (push) Canceled after 0s
Build firmware / build-SITL-Windows (push) Canceled after 0s
Build firmware / build-SITL-Mac (push) Canceled after 0s
Build firmware / build-SITL-Linux (push) Canceled after 0s
Build firmware / build-SITL-Linux-arm64 (push) Canceled after 0s
Build firmware / upload-artifacts (push) Canceled after 0s
Build firmware / build-single-target (push) Canceled after 0s
Build firmware / build (9) (push) Canceled after 0s
Build firmware / build (8) (push) Canceled after 0s
Build firmware / build (7) (push) Canceled after 0s
Build firmware / build (6) (push) Canceled after 0s
Build firmware / build (5) (push) Canceled after 0s
Build firmware / build (4) (push) Canceled after 0s
Build firmware / build (3) (push) Canceled after 0s
Build firmware / build (2) (push) Canceled after 0s
Build firmware / build (14) (push) Canceled after 0s
Build firmware / build (13) (push) Canceled after 0s
Build firmware / build (12) (push) Canceled after 0s
Build firmware / build (11) (push) Canceled after 0s
Build firmware / build (10) (push) Canceled after 0s
Build firmware / build (1) (push) Canceled after 0s
Build firmware / build (0) (push) Canceled after 0s
Build firmware / detect (push) Canceled after 0s
Build pre-release / build (push) Canceled after 0s
Build pre-release / Release (push) Canceled after 0s

This commit is contained in:
2026-08-03 16:37:40 +08:00
commit dac37fd077
14095 changed files with 5603119 additions and 0 deletions
@@ -0,0 +1,584 @@
/**
******************************************************************************
* @file usbh_audio.h
* @author MCD Application Team
* @brief This file contains all the prototypes for the usbh_audio.c
******************************************************************************
* @attention
*
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Define to prevent recursive ----------------------------------------------*/
#ifndef __USBH_AUDIO_H
#define __USBH_AUDIO_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "usbh_core.h"
/** @addtogroup USBH_LIB
* @{
*/
/** @addtogroup USBH_CLASS
* @{
*/
/** @addtogroup USBH_AUDIO_CLASS
* @{
*/
/** @defgroup USBH_AUDIO_CORE
* @brief This file is the Header file for usbh_audio.c
* @{
*/
/** @defgroup USBH_AUDIO_CORE_Exported_Types
* @{
*/
/* States for AUDIO State Machine */
typedef enum
{
AUDIO_INIT = 0,
AUDIO_IDLE,
AUDIO_CS_REQUESTS,
AUDIO_SET_DEFAULT_FEATURE_UNIT,
AUDIO_SET_INTERFACE,
AUDIO_SET_STREAMING_INTERFACE,
AUDIO_SET_CUR1,
AUDIO_GET_MIN,
AUDIO_GET_MAX,
AUDIO_GET_RES,
AUDIO_GET_CUR1,
AUDIO_SET_CUR2,
AUDIO_GET_CUR2,
AUDIO_SET_CUR3,
AUDIO_SET_INTERFACE0,
AUDIO_SET_INTERFACE1,
AUDIO_SET_INTERFACE2,
AUDIO_ISOC_OUT,
AUDIO_ISOC_IN,
AUDIO_ISOC_POLL,
AUDIO_ERROR,
}
AUDIO_StateTypeDef;
typedef enum
{
AUDIO_REQ_INIT = 1,
AUDIO_REQ_IDLE,
AUDIO_REQ_SET_DEFAULT_IN_INTERFACE,
AUDIO_REQ_SET_DEFAULT_OUT_INTERFACE,
AUDIO_REQ_SET_IN_INTERFACE,
AUDIO_REQ_SET_OUT_INTERFACE,
AUDIO_REQ_CS_REQUESTS,
}
AUDIO_ReqStateTypeDef;
typedef enum
{
AUDIO_REQ_SET_VOLUME = 1,
AUDIO_REQ_SET_MUTE,
AUDIO_REQ_GET_CURR_VOLUME,
AUDIO_REQ_GET_MIN_VOLUME,
AUDIO_REQ_GET_MAX_VOLUME,
AUDIO_REQ_GET_VOLUME,
AUDIO_REQ_GET_RESOLUTION,
AUDIO_REQ_CS_IDLE,
}
AUDIO_CSReqStateTypeDef;
typedef enum
{
AUDIO_PLAYBACK_INIT = 1,
AUDIO_PLAYBACK_SET_EP,
AUDIO_PLAYBACK_SET_EP_FREQ,
AUDIO_PLAYBACK_PLAY,
AUDIO_PLAYBACK_IDLE,
}
AUDIO_PlayStateTypeDef;
typedef enum
{
VOLUME_UP = 1,
VOLUME_DOWN = 2,
}
AUDIO_VolumeCtrlTypeDef;
typedef enum
{
AUDIO_CONTROL_INIT = 1,
AUDIO_CONTROL_CHANGE,
AUDIO_CONTROL_IDLE,
AUDIO_CONTROL_VOLUME_UP,
AUDIO_CONTROL_VOLUME_DOWN,
}
AUDIO_ControlStateTypeDef;
typedef enum
{
AUDIO_DATA_START_OUT = 1,
AUDIO_DATA_OUT,
}
AUDIO_ProcessingTypeDef;
/* Structure for AUDIO process */
typedef struct
{
uint8_t Channels;
uint8_t Bits;
uint32_t SampleRate;
}
AUDIO_FormatTypeDef;
typedef struct
{
uint8_t Ep;
uint16_t EpSize;
uint8_t AltSettings;
uint8_t interface;
uint8_t valid;
uint16_t Poll;
}
AUDIO_STREAMING_IN_HandleTypeDef;
typedef struct
{
uint8_t Ep;
uint16_t EpSize;
uint8_t AltSettings;
uint8_t interface;
uint8_t valid;
uint16_t Poll;
}
AUDIO_STREAMING_OUT_HandleTypeDef;
typedef struct
{
uint8_t mute;
uint32_t volumeMin;
uint32_t volumeMax;
uint32_t volume;
uint32_t resolution;
}
AUDIO_ControlAttributeTypeDef;
typedef struct
{
uint8_t Ep;
uint16_t EpSize;
uint8_t interface;
uint8_t AltSettings;
uint8_t supported;
uint8_t Pipe;
uint8_t Poll;
uint32_t timer;
uint8_t asociated_as;
uint8_t asociated_mixer;
uint8_t asociated_selector;
uint8_t asociated_feature;
uint8_t asociated_terminal;
uint8_t asociated_channels;
uint32_t frequency;
uint8_t *buf;
uint8_t *cbuf;
uint32_t partial_ptr;
uint32_t global_ptr;
uint16_t frame_length;
uint32_t total_length;
AUDIO_ControlAttributeTypeDef attribute;
}
AUDIO_InterfaceStreamPropTypeDef;
typedef struct
{
uint8_t Ep;
uint16_t EpSize;
uint8_t interface;
uint8_t supported;
uint8_t Pipe;
uint8_t Poll;
uint32_t timer;
}
AUDIO_InterfaceControlPropTypeDef;
#define AUDIO_MAX_AUDIO_STD_INTERFACE 5U
#define AUDIO_MAX_FREQ_SUPPORTED 5U
#define AUDIO_MAX_STREAMING_INTERFACE 5U
#define AUDIO_MAX_NUM_IN_TERMINAL 4U
#define AUDIO_MAX_NUM_OUT_TERMINAL 4U
#define AUDIO_MAX_NUM_FEATURE_UNIT 4U
#define AUDIO_MAX_NUM_MIXER_UNIT 4U
#define AUDIO_MAX_NUM_SELECTOR_UNIT 4U
#define HEADPHONE_SUPPORTED 1U
#define MICROPHONE_SUPPORTED 2U
#define HEADSET_SUPPORTED 3U
#define AUDIO_MAX_SAMFREQ_NBR 5U
#define AUDIO_MAX_INTERFACE_NBR 5U
#define AUDIO_MAX_CONTROLS_NBR 5U
/*Class-Specific AS(Audio Streaming) Interface Descriptor*/
typedef struct
{
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubtype;
uint8_t bTerminalLink;
uint8_t bDelay;
uint8_t wFormatTag[2];
}
AUDIO_ASGeneralDescTypeDef;
/*Class-Specific AS(Audio Streaming) Format Type Descriptor*/
typedef struct
{
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubtype;
uint8_t bFormatType;
uint8_t bNrChannels;
uint8_t bSubframeSize;
uint8_t bBitResolution;
uint8_t bSamFreqType;
uint8_t tSamFreq[AUDIO_MAX_SAMFREQ_NBR][3];
}
AUDIO_ASFormatTypeDescTypeDef;
/*Class-Specific AS(Audio Streaming) Interface Descriptor*/
typedef struct
{
AUDIO_ASGeneralDescTypeDef *GeneralDesc;
AUDIO_ASFormatTypeDescTypeDef *FormatTypeDesc;
}
AUDIO_ASDescTypeDef;
/* 4.3.2 Class-Specific AC Interface Descriptor */
typedef struct
{
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubtype;
uint8_t bcdADC[2];
uint8_t wTotalLength[2];
uint8_t bInCollection;
uint8_t baInterfaceNr[AUDIO_MAX_INTERFACE_NBR];
}
AUDIO_HeaderDescTypeDef;
/* 4.3.2.1 Input Terminal Descriptor */
typedef struct
{
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubtype;
uint8_t bTerminalID;
uint8_t wTerminalType[2];
uint8_t bAssocTerminal;
uint8_t bNrChannels;
uint8_t wChannelConfig[2];
uint8_t iChannelNames;
uint8_t iTerminal;
}
AUDIO_ITDescTypeDef;
/* 4.3.2.2 Output Terminal Descriptor */
typedef struct
{
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubtype;
uint8_t bTerminalID;
uint8_t wTerminalType[2];
uint8_t bAssocTerminal;
uint8_t bSourceID;
uint8_t iTerminal;
}
AUDIO_OTDescTypeDef;
/* 4.3.2.3 Feature Descriptor */
typedef struct
{
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubtype;
uint8_t bUnitID;
uint8_t bSourceID;
uint8_t bControlSize;
uint8_t bmaControls[AUDIO_MAX_CONTROLS_NBR][2];
}
AUDIO_FeatureDescTypeDef;
/* 4.3.2.3 Feature Descriptor */
typedef struct
{
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubtype;
uint8_t bUnitID;
uint8_t bNrInPins;
uint8_t bSourceID0;
uint8_t bSourceID1;
uint8_t bNrChannels;
uint8_t bmChannelsConfig[2];
uint8_t iChannelsNames;
uint8_t bmaControls;
uint8_t iMixer;
}
AUDIO_MixerDescTypeDef;
/* 4.3.2.3 Feature Descriptor */
typedef struct
{
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubtype;
uint8_t bUnitID;
uint8_t bNrInPins;
uint8_t bSourceID0;
uint8_t iSelector;
}
AUDIO_SelectorDescTypeDef;
/*Class-Specific AC(Audio Control) Interface Descriptor*/
typedef struct
{
AUDIO_HeaderDescTypeDef *HeaderDesc;
AUDIO_ITDescTypeDef *InputTerminalDesc [AUDIO_MAX_NUM_IN_TERMINAL];
AUDIO_OTDescTypeDef *OutputTerminalDesc[AUDIO_MAX_NUM_OUT_TERMINAL];
AUDIO_FeatureDescTypeDef *FeatureUnitDesc [AUDIO_MAX_NUM_FEATURE_UNIT];
AUDIO_MixerDescTypeDef *MixerUnitDesc [AUDIO_MAX_NUM_MIXER_UNIT];
AUDIO_SelectorDescTypeDef *SelectorUnitDesc [AUDIO_MAX_NUM_SELECTOR_UNIT];
}
AUDIO_ACDescTypeDef;
/*Class-Specific AC : Global descriptor*/
typedef struct
{
AUDIO_ACDescTypeDef cs_desc; /* Only one control descriptor*/
AUDIO_ASDescTypeDef as_desc[AUDIO_MAX_STREAMING_INTERFACE];
uint16_t ASNum;
uint16_t InputTerminalNum;
uint16_t OutputTerminalNum;
uint16_t FeatureUnitNum;
uint16_t SelectorUnitNum;
uint16_t MixerUnitNum;
}
AUDIO_ClassSpecificDescTypedef;
typedef struct _AUDIO_Process
{
AUDIO_ReqStateTypeDef req_state;
AUDIO_CSReqStateTypeDef cs_req_state;
AUDIO_PlayStateTypeDef play_state;
AUDIO_ControlStateTypeDef control_state;
AUDIO_ProcessingTypeDef processing_state;
AUDIO_STREAMING_IN_HandleTypeDef stream_in[AUDIO_MAX_AUDIO_STD_INTERFACE];
AUDIO_STREAMING_OUT_HandleTypeDef stream_out[AUDIO_MAX_AUDIO_STD_INTERFACE];
AUDIO_ClassSpecificDescTypedef class_desc;
AUDIO_InterfaceStreamPropTypeDef headphone;
AUDIO_InterfaceStreamPropTypeDef microphone;
AUDIO_InterfaceControlPropTypeDef control;
uint16_t mem [8];
uint8_t temp_feature;
uint8_t temp_channels;
}
AUDIO_HandleTypeDef;
/**
* @}
*/
/** @defgroup USBH_AUDIO_CORE_Exported_Defines
* @{
*/
/*Audio Interface Subclass Codes*/
#define AC_CLASS 0x01U
/* A.2 Audio Interface Subclass Codes */
#define USB_SUBCLASS_AUDIOCONTROL 0x01U
#define USB_SUBCLASS_AUDIOSTREAMING 0x02U
#define USB_SUBCLASS_MIDISTREAMING 0x03U
#define USB_DESC_TYPE_CS_INTERFACE 0x24U
#define USB_DESC_TYPE_CS_ENDPOINT 0x25U
/* A.5 Audio Class-Specific AC Interface Descriptor Subtypes */
#define UAC_HEADER 0x01U
#define UAC_INPUT_TERMINAL 0x02U
#define UAC_OUTPUT_TERMINAL 0x03U
#define UAC_MIXER_UNIT 0x04U
#define UAC_SELECTOR_UNIT 0x05U
#define UAC_FEATURE_UNIT 0x06U
#define UAC_PROCESSING_UNIT 0x07U
#define UAC_EXTENSION_UNIT 0x08U
/*Audio Class-Specific Endpoint Descriptor Subtypes*/
#define EP_CONTROL_UNDEFINED 0x00U
#define SAMPLING_FREQ_CONTROL 0x01U
#define PITCH_CONTROL 0x02U
/*Feature unit control selector*/
#define FU_CONTROL_UNDEFINED 0x00U
#define MUTE_CONTROL 0x01U
#define VOLUME_CONTROL 0x02U
#define BASS_CONTROL 0x03U
#define MID_CONTROL 0x04U
#define TREBLE_CONTROL 0x05U
#define GRAPHIC_EQUALIZER_CONTROL 0x06U
#define AUTOMATIC_GAIN_CONTROL 0x07U
#define DELAY_CONTROL 0x08U
#define BASS_BOOST_CONTROL 0x09U
#define LOUDNESS_CONTROL 0x0AU
/*Terminal control selector*/
#define TE_CONTROL_UNDEFINED 0x00U
#define COPY_PROTECT_CONTROL 0x01U
/* A.6 Audio Class-Specific AS Interface Descriptor Subtypes */
#define UAC_AS_GENERAL 0x01U
#define UAC_FORMAT_TYPE 0x02U
#define UAC_FORMAT_SPECIFIC 0x03U
/* A.8 Audio Class-Specific Endpoint Descriptor Subtypes */
#define UAC_EP_GENERAL 0x01U
/* A.9 Audio Class-Specific Request Codes */
#define UAC_SET_ 0x00U
#define UAC_GET_ 0x80U
#define UAC__CUR 0x01U
#define UAC__MIN 0x02U
#define UAC__MAX 0x03U
#define UAC__RES 0x04U
#define UAC__MEM 0x05U
#define UAC_SET_CUR (UAC_SET_ | UAC__CUR)
#define UAC_GET_CUR (UAC_GET_ | UAC__CUR)
#define UAC_SET_MIN (UAC_SET_ | UAC__MIN)
#define UAC_GET_MIN (UAC_GET_ | UAC__MIN)
#define UAC_SET_MAX (UAC_SET_ | UAC__MAX)
#define UAC_GET_MAX (UAC_GET_ | UAC__MAX)
#define UAC_SET_RES (UAC_SET_ | UAC__RES)
#define UAC_GET_RES (UAC_GET_ | UAC__RES)
#define UAC_SET_MEM (UAC_SET_ | UAC__MEM)
#define UAC_GET_MEM (UAC_GET_ | UAC__MEM)
#define UAC_GET_STAT 0xffU
/* MIDI - A.1 MS Class-Specific Interface Descriptor Subtypes */
#define UAC_MS_HEADER 0x01U
#define UAC_MIDI_IN_JACK 0x02U
#define UAC_MIDI_OUT_JACK 0x03U
/* MIDI - A.1 MS Class-Specific Endpoint Descriptor Subtypes */
#define UAC_MS_GENERAL 0x01U
/* Terminals - 2.1 USB Terminal Types */
#define UAC_TERMINAL_UNDEFINED 0x100U
#define UAC_TERMINAL_STREAMING 0x101U
#define UAC_TERMINAL_VENDOR_SPEC 0x1FFU
/**
* @}
*/
/** @defgroup USBH_AUDIO_CORE_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBH_AUDIO_CORE_Exported_Variables
* @{
*/
extern USBH_ClassTypeDef AUDIO_Class;
#define USBH_AUDIO_CLASS &AUDIO_Class
/**
* @}
*/
/** @defgroup USBH_AUDIO_CORE_Exported_FunctionsPrototype
* @{
*/
USBH_StatusTypeDef USBH_AUDIO_SetFrequency(USBH_HandleTypeDef *phost,
uint16_t SampleRate,
uint8_t NbrChannels,
uint8_t BitPerSample);
USBH_StatusTypeDef USBH_AUDIO_Play(USBH_HandleTypeDef *phost, uint8_t *buf, uint32_t length);
USBH_StatusTypeDef USBH_AUDIO_Stop(USBH_HandleTypeDef *phost);
USBH_StatusTypeDef USBH_AUDIO_Suspend(USBH_HandleTypeDef *phost);
USBH_StatusTypeDef USBH_AUDIO_Resume(USBH_HandleTypeDef *phost);
USBH_StatusTypeDef USBH_AUDIO_SetVolume(USBH_HandleTypeDef *phost, AUDIO_VolumeCtrlTypeDef volume_ctl);
USBH_StatusTypeDef USBH_AUDIO_ChangeOutBuffer(USBH_HandleTypeDef *phost, uint8_t *buf);
int32_t USBH_AUDIO_GetOutOffset(USBH_HandleTypeDef *phost);
void USBH_AUDIO_FrequencySet(USBH_HandleTypeDef *phost);
#define USBH_AUDIO_FrequencySetCallback USBH_AUDIO_FrequencySet
void USBH_AUDIO_BufferEmptyCallback(USBH_HandleTypeDef *phost);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __USBH_AUDIO_H */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
@@ -0,0 +1,446 @@
/**
******************************************************************************
* @file usbh_cdc.h
* @author MCD Application Team
* @brief This file contains all the prototypes for the usbh_cdc.c
******************************************************************************
* @attention
*
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Define to prevent recursive ----------------------------------------------*/
#ifndef __USBH_CDC_H
#define __USBH_CDC_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "usbh_core.h"
/** @addtogroup USBH_LIB
* @{
*/
/** @addtogroup USBH_CLASS
* @{
*/
/** @addtogroup USBH_CDC_CLASS
* @{
*/
/** @defgroup USBH_CDC_CORE
* @brief This file is the Header file for usbh_core.c
* @{
*/
/*Communication Class codes*/
#define USB_CDC_CLASS 0x02U
#define COMMUNICATION_INTERFACE_CLASS_CODE 0x02U
/*Data Interface Class Codes*/
#define DATA_INTERFACE_CLASS_CODE 0x0AU
/*Communication sub class codes*/
#define RESERVED 0x00U
#define DIRECT_LINE_CONTROL_MODEL 0x01U
#define ABSTRACT_CONTROL_MODEL 0x02U
#define TELEPHONE_CONTROL_MODEL 0x03U
#define MULTICHANNEL_CONTROL_MODEL 0x04U
#define CAPI_CONTROL_MODEL 0x05U
#define ETHERNET_NETWORKING_CONTROL_MODEL 0x06U
#define ATM_NETWORKING_CONTROL_MODEL 0x07U
/*Communication Interface Class Control Protocol Codes*/
#define NO_CLASS_SPECIFIC_PROTOCOL_CODE 0x00U
#define COMMON_AT_COMMAND 0x01U
#define VENDOR_SPECIFIC 0xFFU
#define CS_INTERFACE 0x24U
#define CDC_PAGE_SIZE_64 0x40U
/*Class-Specific Request Codes*/
#define CDC_SEND_ENCAPSULATED_COMMAND 0x00U
#define CDC_GET_ENCAPSULATED_RESPONSE 0x01U
#define CDC_SET_COMM_FEATURE 0x02U
#define CDC_GET_COMM_FEATURE 0x03U
#define CDC_CLEAR_COMM_FEATURE 0x04U
#define CDC_SET_AUX_LINE_STATE 0x10U
#define CDC_SET_HOOK_STATE 0x11U
#define CDC_PULSE_SETUP 0x12U
#define CDC_SEND_PULSE 0x13U
#define CDC_SET_PULSE_TIME 0x14U
#define CDC_RING_AUX_JACK 0x15U
#define CDC_SET_LINE_CODING 0x20U
#define CDC_GET_LINE_CODING 0x21U
#define CDC_SET_CONTROL_LINE_STATE 0x22U
#define CDC_SEND_BREAK 0x23U
#define CDC_SET_RINGER_PARMS 0x30U
#define CDC_GET_RINGER_PARMS 0x31U
#define CDC_SET_OPERATION_PARMS 0x32U
#define CDC_GET_OPERATION_PARMS 0x33U
#define CDC_SET_LINE_PARMS 0x34U
#define CDC_GET_LINE_PARMS 0x35U
#define CDC_DIAL_DIGITS 0x36U
#define CDC_SET_UNIT_PARAMETER 0x37U
#define CDC_GET_UNIT_PARAMETER 0x38U
#define CDC_CLEAR_UNIT_PARAMETER 0x39U
#define CDC_GET_PROFILE 0x3AU
#define CDC_SET_ETHERNET_MULTICAST_FILTERS 0x40U
#define CDC_SET_ETHERNET_POWER_MANAGEMENT_PATTERN FILTER 0x41U
#define CDC_GET_ETHERNET_POWER_MANAGEMENT_PATTERN FILTER 0x42U
#define CDC_SET_ETHERNET_PACKET_FILTER 0x43U
#define CDC_GET_ETHERNET_STATISTIC 0x44U
#define CDC_SET_ATM_DATA_FORMAT 0x50U
#define CDC_GET_ATM_DEVICE_STATISTICS 0x51U
#define CDC_SET_ATM_DEFAULT_VC 0x52U
#define CDC_GET_ATM_VC_STATISTICS 0x53U
/* wValue for SetControlLineState*/
#define CDC_ACTIVATE_CARRIER_SIGNAL_RTS 0x0002U
#define CDC_DEACTIVATE_CARRIER_SIGNAL_RTS 0x0000U
#define CDC_ACTIVATE_SIGNAL_DTR 0x0001U
#define CDC_DEACTIVATE_SIGNAL_DTR 0x0000U
#define LINE_CODING_STRUCTURE_SIZE 0x07U
/**
* @}
*/
/** @defgroup USBH_CDC_CORE_Exported_Types
* @{
*/
/* States for CDC State Machine */
typedef enum
{
CDC_IDLE = 0U,
CDC_SEND_DATA,
CDC_SEND_DATA_WAIT,
CDC_RECEIVE_DATA,
CDC_RECEIVE_DATA_WAIT,
}
CDC_DataStateTypeDef;
typedef enum
{
CDC_IDLE_STATE = 0U,
CDC_SET_LINE_CODING_STATE,
CDC_GET_LAST_LINE_CODING_STATE,
CDC_TRANSFER_DATA,
CDC_ERROR_STATE,
}
CDC_StateTypeDef;
/*Line coding structure*/
typedef union _CDC_LineCodingStructure
{
uint8_t Array[LINE_CODING_STRUCTURE_SIZE];
struct
{
uint32_t dwDTERate; /*Data terminal rate, in bits per second*/
uint8_t bCharFormat; /*Stop bits
0 - 1 Stop bit
1 - 1.5 Stop bits
2 - 2 Stop bits*/
uint8_t bParityType; /* Parity
0 - None
1 - Odd
2 - Even
3 - Mark
4 - Space*/
uint8_t bDataBits; /* Data bits (5, 6, 7, 8 or 16). */
} b;
}
CDC_LineCodingTypeDef;
/* Header Functional Descriptor
--------------------------------------------------------------------------------
Offset| field | Size | Value | Description
------|---------------------|-------|------------|------------------------------
0 | bFunctionLength | 1 | number | Size of this descriptor.
1 | bDescriptorType | 1 | Constant | CS_INTERFACE (0x24)
2 | bDescriptorSubtype | 1 | Constant | Identifier (ID) of functional
| | | | descriptor.
3 | bcdCDC | 2 | |
| | | Number | USB Class Definitions for
| | | | Communication Devices Specification
| | | | release number in binary-coded
| | | | decimal
------|---------------------|-------|------------|------------------------------
*/
typedef struct _FunctionalDescriptorHeader
{
uint8_t bLength; /*Size of this descriptor.*/
uint8_t bDescriptorType; /*CS_INTERFACE (0x24)*/
uint8_t bDescriptorSubType; /* Header functional descriptor subtype as*/
uint16_t bcdCDC; /* USB Class Definitions for Communication
Devices Specification release number in
binary-coded decimal. */
}
CDC_HeaderFuncDesc_TypeDef;
/* Call Management Functional Descriptor
--------------------------------------------------------------------------------
Offset| field | Size | Value | Description
------|---------------------|-------|------------|------------------------------
0 | bFunctionLength | 1 | number | Size of this descriptor.
1 | bDescriptorType | 1 | Constant | CS_INTERFACE (0x24)
2 | bDescriptorSubtype | 1 | Constant | Call Management functional
| | | | descriptor subtype.
3 | bmCapabilities | 1 | Bitmap | The capabilities that this configuration
| | | | supports:
| | | | D7..D2: RESERVED (Reset to zero)
| | | | D1: 0 - Device sends/receives call
| | | | management information only over
| | | | the Communication Class
| | | | interface.
| | | | 1 - Device can send/receive call
| \ | | management information over a
| | | | Data Class interface.
| | | | D0: 0 - Device does not handle call
| | | | management itself.
| | | | 1 - Device handles call
| | | | management itself.
| | | | The previous bits, in combination, identify
| | | | which call management scenario is used. If bit
| | | | D0 is reset to 0, then the value of bit D1 is
| | | | ignored. In this case, bit D1 is reset to zero for
| | | | future compatibility.
4 | bDataInterface | 1 | Number | Interface number of Data Class interface
| | | | optionally used for call management.
------|---------------------|-------|------------|------------------------------
*/
typedef struct _CallMgmtFunctionalDescriptor
{
uint8_t bLength; /*Size of this functional descriptor, in bytes.*/
uint8_t bDescriptorType; /*CS_INTERFACE (0x24)*/
uint8_t bDescriptorSubType; /* Call Management functional descriptor subtype*/
uint8_t bmCapabilities; /* bmCapabilities: D0+D1 */
uint8_t bDataInterface; /*bDataInterface: 1*/
}
CDC_CallMgmtFuncDesc_TypeDef;
/* Abstract Control Management Functional Descriptor
--------------------------------------------------------------------------------
Offset| field | Size | Value | Description
------|---------------------|-------|------------|------------------------------
0 | bFunctionLength | 1 | number | Size of functional descriptor, in bytes.
1 | bDescriptorType | 1 | Constant | CS_INTERFACE (0x24)
2 | bDescriptorSubtype | 1 | Constant | Abstract Control Management
| | | | functional descriptor subtype.
3 | bmCapabilities | 1 | Bitmap | The capabilities that this configuration
| | | | supports ((A bit value of zero means that the
| | | | request is not supported.) )
D7..D4: RESERVED (Reset to zero)
| | | | D3: 1 - Device supports the notification
| | | | Network_Connection.
| | | | D2: 1 - Device supports the request
| | | | Send_Break
| | | | D1: 1 - Device supports the request
| \ | | combination of Set_Line_Coding,
| | | | Set_Control_Line_State, Get_Line_Coding, and the
notification Serial_State.
| | | | D0: 1 - Device supports the request
| | | | combination of Set_Comm_Feature,
| | | | Clear_Comm_Feature, and Get_Comm_Feature.
| | | | The previous bits, in combination, identify
| | | | which requests/notifications are supported by
| | | | a Communication Class interface with the
| | | | SubClass code of Abstract Control Model.
------|---------------------|-------|------------|------------------------------
*/
typedef struct _AbstractCntrlMgmtFunctionalDescriptor
{
uint8_t bLength; /*Size of this functional descriptor, in bytes.*/
uint8_t bDescriptorType; /*CS_INTERFACE (0x24)*/
uint8_t bDescriptorSubType; /* Abstract Control Management functional
descriptor subtype*/
uint8_t bmCapabilities; /* The capabilities that this configuration supports */
}
CDC_AbstCntrlMgmtFuncDesc_TypeDef;
/* Union Functional Descriptor
--------------------------------------------------------------------------------
Offset| field | Size | Value | Description
------|---------------------|-------|------------|------------------------------
0 | bFunctionLength | 1 | number | Size of this descriptor.
1 | bDescriptorType | 1 | Constant | CS_INTERFACE (0x24)
2 | bDescriptorSubtype | 1 | Constant | Union functional
| | | | descriptor subtype.
3 | bMasterInterface | 1 | Constant | The interface number of the
| | | | Communication or Data Class interface
4 | bSlaveInterface0 | 1 | Number | nterface number of first slave or associated
| | | | interface in the union.
------|---------------------|-------|------------|------------------------------
*/
typedef struct _UnionFunctionalDescriptor
{
uint8_t bLength; /*Size of this functional descriptor, in bytes*/
uint8_t bDescriptorType; /*CS_INTERFACE (0x24)*/
uint8_t bDescriptorSubType; /* Union functional descriptor SubType*/
uint8_t bMasterInterface; /* The interface number of the Communication or
Data Class interface,*/
uint8_t bSlaveInterface0; /*Interface number of first slave*/
}
CDC_UnionFuncDesc_TypeDef;
typedef struct _USBH_CDCInterfaceDesc
{
CDC_HeaderFuncDesc_TypeDef CDC_HeaderFuncDesc;
CDC_CallMgmtFuncDesc_TypeDef CDC_CallMgmtFuncDesc;
CDC_AbstCntrlMgmtFuncDesc_TypeDef CDC_AbstCntrlMgmtFuncDesc;
CDC_UnionFuncDesc_TypeDef CDC_UnionFuncDesc;
}
CDC_InterfaceDesc_Typedef;
/* Structure for CDC process */
typedef struct
{
uint8_t NotifPipe;
uint8_t NotifEp;
uint8_t buff[8];
uint16_t NotifEpSize;
}
CDC_CommItfTypedef;
typedef struct
{
uint8_t InPipe;
uint8_t OutPipe;
uint8_t OutEp;
uint8_t InEp;
uint8_t buff[8];
uint16_t OutEpSize;
uint16_t InEpSize;
}
CDC_DataItfTypedef;
/* Structure for CDC process */
typedef struct _CDC_Process
{
CDC_CommItfTypedef CommItf;
CDC_DataItfTypedef DataItf;
uint8_t *pTxData;
uint8_t *pRxData;
uint32_t TxDataLength;
uint32_t RxDataLength;
CDC_InterfaceDesc_Typedef CDC_Desc;
CDC_LineCodingTypeDef LineCoding;
CDC_LineCodingTypeDef *pUserLineCoding;
CDC_StateTypeDef state;
CDC_DataStateTypeDef data_tx_state;
CDC_DataStateTypeDef data_rx_state;
uint8_t Rx_Poll;
}
CDC_HandleTypeDef;
/**
* @}
*/
/** @defgroup USBH_CDC_CORE_Exported_Defines
* @{
*/
/**
* @}
*/
/** @defgroup USBH_CDC_CORE_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBH_CDC_CORE_Exported_Variables
* @{
*/
extern USBH_ClassTypeDef CDC_Class;
#define USBH_CDC_CLASS &CDC_Class
/**
* @}
*/
/** @defgroup USBH_CDC_CORE_Exported_FunctionsPrototype
* @{
*/
USBH_StatusTypeDef USBH_CDC_SetLineCoding(USBH_HandleTypeDef *phost,
CDC_LineCodingTypeDef *linecoding);
USBH_StatusTypeDef USBH_CDC_GetLineCoding(USBH_HandleTypeDef *phost,
CDC_LineCodingTypeDef *linecoding);
USBH_StatusTypeDef USBH_CDC_Transmit(USBH_HandleTypeDef *phost,
uint8_t *pbuff,
uint32_t length);
USBH_StatusTypeDef USBH_CDC_Receive(USBH_HandleTypeDef *phost,
uint8_t *pbuff,
uint32_t length);
uint16_t USBH_CDC_GetLastReceivedDataSize(USBH_HandleTypeDef *phost);
USBH_StatusTypeDef USBH_CDC_Stop(USBH_HandleTypeDef *phost);
void USBH_CDC_LineCodingChanged(USBH_HandleTypeDef *phost);
void USBH_CDC_TransmitCallback(USBH_HandleTypeDef *phost);
void USBH_CDC_ReceiveCallback(USBH_HandleTypeDef *phost);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __USBH_CDC_H */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
@@ -0,0 +1,831 @@
/**
******************************************************************************
* @file usbh_cdc.c
* @author MCD Application Team
* @brief This file is the CDC Layer Handlers for USB Host CDC class.
*
******************************************************************************
* @attention
*
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
* @verbatim
*
* ===================================================================
* CDC Class Driver Description
* ===================================================================
* This driver manages the "Universal Serial Bus Class Definitions for Communications Devices
* Revision 1.2 November 16, 2007" and the sub-protocol specification of "Universal Serial Bus
* Communications Class Subclass Specification for PSTN Devices Revision 1.2 February 9, 2007"
* This driver implements the following aspects of the specification:
* - Device descriptor management
* - Configuration descriptor management
* - Enumeration as CDC device with 2 data endpoints (IN and OUT) and 1 command endpoint (IN)
* - Requests management (as described in section 6.2 in specification)
* - Abstract Control Model compliant
* - Union Functional collection (using 1 IN endpoint for control)
* - Data interface class
*
* @endverbatim
*
******************************************************************************
*/
/* BSPDependencies
- "stm32xxxxx_{eval}{discovery}{nucleo_144}.c"
- "stm32xxxxx_{eval}{discovery}_io.c"
- "stm32xxxxx_{eval}{discovery}{adafruit}_sd.c"
- "stm32xxxxx_{eval}{discovery}{adafruit}_lcd.c"
- "stm32xxxxx_{eval}{discovery}_sdram.c"
EndBSPDependencies */
/* Includes ------------------------------------------------------------------*/
#include "usbh_cdc.h"
/** @addtogroup USBH_LIB
* @{
*/
/** @addtogroup USBH_CLASS
* @{
*/
/** @addtogroup USBH_CDC_CLASS
* @{
*/
/** @defgroup USBH_CDC_CORE
* @brief This file includes CDC Layer Handlers for USB Host CDC class.
* @{
*/
/** @defgroup USBH_CDC_CORE_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @defgroup USBH_CDC_CORE_Private_Defines
* @{
*/
#define USBH_CDC_BUFFER_SIZE 1024
/**
* @}
*/
/** @defgroup USBH_CDC_CORE_Private_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBH_CDC_CORE_Private_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USBH_CDC_CORE_Private_FunctionPrototypes
* @{
*/
static USBH_StatusTypeDef USBH_CDC_InterfaceInit(USBH_HandleTypeDef *phost);
static USBH_StatusTypeDef USBH_CDC_InterfaceDeInit(USBH_HandleTypeDef *phost);
static USBH_StatusTypeDef USBH_CDC_Process(USBH_HandleTypeDef *phost);
static USBH_StatusTypeDef USBH_CDC_SOFProcess(USBH_HandleTypeDef *phost);
static USBH_StatusTypeDef USBH_CDC_ClassRequest(USBH_HandleTypeDef *phost);
static USBH_StatusTypeDef GetLineCoding(USBH_HandleTypeDef *phost,
CDC_LineCodingTypeDef *linecoding);
static USBH_StatusTypeDef SetLineCoding(USBH_HandleTypeDef *phost,
CDC_LineCodingTypeDef *linecoding);
static void CDC_ProcessTransmission(USBH_HandleTypeDef *phost);
static void CDC_ProcessReception(USBH_HandleTypeDef *phost);
USBH_ClassTypeDef CDC_Class =
{
"CDC",
USB_CDC_CLASS,
USBH_CDC_InterfaceInit,
USBH_CDC_InterfaceDeInit,
USBH_CDC_ClassRequest,
USBH_CDC_Process,
USBH_CDC_SOFProcess,
NULL,
};
/**
* @}
*/
/** @defgroup USBH_CDC_CORE_Private_Functions
* @{
*/
/**
* @brief USBH_CDC_InterfaceInit
* The function init the CDC class.
* @param phost: Host handle
* @retval USBH Status
*/
static USBH_StatusTypeDef USBH_CDC_InterfaceInit(USBH_HandleTypeDef *phost)
{
USBH_StatusTypeDef status;
uint8_t interface;
CDC_HandleTypeDef *CDC_Handle;
interface = USBH_FindInterface(phost, COMMUNICATION_INTERFACE_CLASS_CODE,
ABSTRACT_CONTROL_MODEL, COMMON_AT_COMMAND);
if ((interface == 0xFFU) || (interface >= USBH_MAX_NUM_INTERFACES)) /* No Valid Interface */
{
USBH_DbgLog("Cannot Find the interface for Communication Interface Class.", phost->pActiveClass->Name);
return USBH_FAIL;
}
status = USBH_SelectInterface(phost, interface);
if (status != USBH_OK)
{
return USBH_FAIL;
}
phost->pActiveClass->pData = (CDC_HandleTypeDef *)USBH_malloc(sizeof(CDC_HandleTypeDef));
CDC_Handle = (CDC_HandleTypeDef *) phost->pActiveClass->pData;
if (CDC_Handle == NULL)
{
USBH_DbgLog("Cannot allocate memory for CDC Handle");
return USBH_FAIL;
}
/* Initialize cdc handler */
(void)USBH_memset(CDC_Handle, 0, sizeof(CDC_HandleTypeDef));
/*Collect the notification endpoint address and length*/
if ((phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[0].bEndpointAddress & 0x80U) != 0U)
{
CDC_Handle->CommItf.NotifEp = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[0].bEndpointAddress;
CDC_Handle->CommItf.NotifEpSize = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[0].wMaxPacketSize;
}
/*Allocate the length for host channel number in*/
CDC_Handle->CommItf.NotifPipe = USBH_AllocPipe(phost, CDC_Handle->CommItf.NotifEp);
/* Open pipe for Notification endpoint */
(void)USBH_OpenPipe(phost, CDC_Handle->CommItf.NotifPipe, CDC_Handle->CommItf.NotifEp,
phost->device.address, phost->device.speed, USB_EP_TYPE_INTR,
CDC_Handle->CommItf.NotifEpSize);
(void)USBH_LL_SetToggle(phost, CDC_Handle->CommItf.NotifPipe, 0U);
interface = USBH_FindInterface(phost, DATA_INTERFACE_CLASS_CODE,
RESERVED, NO_CLASS_SPECIFIC_PROTOCOL_CODE);
if ((interface == 0xFFU) || (interface >= USBH_MAX_NUM_INTERFACES)) /* No Valid Interface */
{
USBH_DbgLog("Cannot Find the interface for Data Interface Class.", phost->pActiveClass->Name);
return USBH_FAIL;
}
/*Collect the class specific endpoint address and length*/
if ((phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[0].bEndpointAddress & 0x80U) != 0U)
{
CDC_Handle->DataItf.InEp = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[0].bEndpointAddress;
CDC_Handle->DataItf.InEpSize = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[0].wMaxPacketSize;
}
else
{
CDC_Handle->DataItf.OutEp = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[0].bEndpointAddress;
CDC_Handle->DataItf.OutEpSize = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[0].wMaxPacketSize;
}
if ((phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[1].bEndpointAddress & 0x80U) != 0U)
{
CDC_Handle->DataItf.InEp = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[1].bEndpointAddress;
CDC_Handle->DataItf.InEpSize = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[1].wMaxPacketSize;
}
else
{
CDC_Handle->DataItf.OutEp = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[1].bEndpointAddress;
CDC_Handle->DataItf.OutEpSize = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[1].wMaxPacketSize;
}
/*Allocate the length for host channel number out*/
CDC_Handle->DataItf.OutPipe = USBH_AllocPipe(phost, CDC_Handle->DataItf.OutEp);
/*Allocate the length for host channel number in*/
CDC_Handle->DataItf.InPipe = USBH_AllocPipe(phost, CDC_Handle->DataItf.InEp);
/* Open channel for OUT endpoint */
(void)USBH_OpenPipe(phost, CDC_Handle->DataItf.OutPipe, CDC_Handle->DataItf.OutEp,
phost->device.address, phost->device.speed, USB_EP_TYPE_BULK,
CDC_Handle->DataItf.OutEpSize);
/* Open channel for IN endpoint */
(void)USBH_OpenPipe(phost, CDC_Handle->DataItf.InPipe, CDC_Handle->DataItf.InEp,
phost->device.address, phost->device.speed, USB_EP_TYPE_BULK,
CDC_Handle->DataItf.InEpSize);
CDC_Handle->state = CDC_IDLE_STATE;
(void)USBH_LL_SetToggle(phost, CDC_Handle->DataItf.OutPipe, 0U);
(void)USBH_LL_SetToggle(phost, CDC_Handle->DataItf.InPipe, 0U);
return USBH_OK;
}
/**
* @brief USBH_CDC_InterfaceDeInit
* The function DeInit the Pipes used for the CDC class.
* @param phost: Host handle
* @retval USBH Status
*/
static USBH_StatusTypeDef USBH_CDC_InterfaceDeInit(USBH_HandleTypeDef *phost)
{
CDC_HandleTypeDef *CDC_Handle = (CDC_HandleTypeDef *) phost->pActiveClass->pData;
if ((CDC_Handle->CommItf.NotifPipe) != 0U)
{
(void)USBH_ClosePipe(phost, CDC_Handle->CommItf.NotifPipe);
(void)USBH_FreePipe(phost, CDC_Handle->CommItf.NotifPipe);
CDC_Handle->CommItf.NotifPipe = 0U; /* Reset the Channel as Free */
}
if ((CDC_Handle->DataItf.InPipe) != 0U)
{
(void)USBH_ClosePipe(phost, CDC_Handle->DataItf.InPipe);
(void)USBH_FreePipe(phost, CDC_Handle->DataItf.InPipe);
CDC_Handle->DataItf.InPipe = 0U; /* Reset the Channel as Free */
}
if ((CDC_Handle->DataItf.OutPipe) != 0U)
{
(void)USBH_ClosePipe(phost, CDC_Handle->DataItf.OutPipe);
(void)USBH_FreePipe(phost, CDC_Handle->DataItf.OutPipe);
CDC_Handle->DataItf.OutPipe = 0U; /* Reset the Channel as Free */
}
if ((phost->pActiveClass->pData) != NULL)
{
USBH_free(phost->pActiveClass->pData);
phost->pActiveClass->pData = 0U;
}
return USBH_OK;
}
/**
* @brief USBH_CDC_ClassRequest
* The function is responsible for handling Standard requests
* for CDC class.
* @param phost: Host handle
* @retval USBH Status
*/
static USBH_StatusTypeDef USBH_CDC_ClassRequest(USBH_HandleTypeDef *phost)
{
USBH_StatusTypeDef status;
CDC_HandleTypeDef *CDC_Handle = (CDC_HandleTypeDef *) phost->pActiveClass->pData;
/* Issue the get line coding request */
status = GetLineCoding(phost, &CDC_Handle->LineCoding);
if (status == USBH_OK)
{
phost->pUser(phost, HOST_USER_CLASS_ACTIVE);
}
else if (status == USBH_NOT_SUPPORTED)
{
USBH_ErrLog("Control error: CDC: Device Get Line Coding configuration failed");
}
else
{
/* .. */
}
return status;
}
/**
* @brief USBH_CDC_Process
* The function is for managing state machine for CDC data transfers
* @param phost: Host handle
* @retval USBH Status
*/
static USBH_StatusTypeDef USBH_CDC_Process(USBH_HandleTypeDef *phost)
{
USBH_StatusTypeDef status = USBH_BUSY;
USBH_StatusTypeDef req_status = USBH_OK;
CDC_HandleTypeDef *CDC_Handle = (CDC_HandleTypeDef *) phost->pActiveClass->pData;
switch (CDC_Handle->state)
{
case CDC_IDLE_STATE:
status = USBH_OK;
break;
case CDC_SET_LINE_CODING_STATE:
req_status = SetLineCoding(phost, CDC_Handle->pUserLineCoding);
if (req_status == USBH_OK)
{
CDC_Handle->state = CDC_GET_LAST_LINE_CODING_STATE;
}
else
{
if (req_status != USBH_BUSY)
{
CDC_Handle->state = CDC_ERROR_STATE;
}
}
break;
case CDC_GET_LAST_LINE_CODING_STATE:
req_status = GetLineCoding(phost, &(CDC_Handle->LineCoding));
if (req_status == USBH_OK)
{
CDC_Handle->state = CDC_IDLE_STATE;
if ((CDC_Handle->LineCoding.b.bCharFormat == CDC_Handle->pUserLineCoding->b.bCharFormat) &&
(CDC_Handle->LineCoding.b.bDataBits == CDC_Handle->pUserLineCoding->b.bDataBits) &&
(CDC_Handle->LineCoding.b.bParityType == CDC_Handle->pUserLineCoding->b.bParityType) &&
(CDC_Handle->LineCoding.b.dwDTERate == CDC_Handle->pUserLineCoding->b.dwDTERate))
{
USBH_CDC_LineCodingChanged(phost);
}
}
else
{
if (req_status != USBH_BUSY)
{
CDC_Handle->state = CDC_ERROR_STATE;
}
}
break;
case CDC_TRANSFER_DATA:
CDC_ProcessTransmission(phost);
CDC_ProcessReception(phost);
break;
case CDC_ERROR_STATE:
req_status = USBH_ClrFeature(phost, 0x00U);
if (req_status == USBH_OK)
{
/*Change the state to waiting*/
CDC_Handle->state = CDC_IDLE_STATE;
}
break;
default:
break;
}
return status;
}
/**
* @brief USBH_CDC_SOFProcess
* The function is for managing SOF callback
* @param phost: Host handle
* @retval USBH Status
*/
static USBH_StatusTypeDef USBH_CDC_SOFProcess(USBH_HandleTypeDef *phost)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(phost);
return USBH_OK;
}
/**
* @brief USBH_CDC_Stop
* Stop current CDC Transmission
* @param phost: Host handle
* @retval USBH Status
*/
USBH_StatusTypeDef USBH_CDC_Stop(USBH_HandleTypeDef *phost)
{
CDC_HandleTypeDef *CDC_Handle = (CDC_HandleTypeDef *) phost->pActiveClass->pData;
if (phost->gState == HOST_CLASS)
{
CDC_Handle->state = CDC_IDLE_STATE;
(void)USBH_ClosePipe(phost, CDC_Handle->CommItf.NotifPipe);
(void)USBH_ClosePipe(phost, CDC_Handle->DataItf.InPipe);
(void)USBH_ClosePipe(phost, CDC_Handle->DataItf.OutPipe);
}
return USBH_OK;
}
/**
* @brief This request allows the host to find out the currently
* configured line coding.
* @param pdev: Selected device
* @retval USBH_StatusTypeDef : USB ctl xfer status
*/
static USBH_StatusTypeDef GetLineCoding(USBH_HandleTypeDef *phost, CDC_LineCodingTypeDef *linecoding)
{
phost->Control.setup.b.bmRequestType = USB_D2H | USB_REQ_TYPE_CLASS | \
USB_REQ_RECIPIENT_INTERFACE;
phost->Control.setup.b.bRequest = CDC_GET_LINE_CODING;
phost->Control.setup.b.wValue.w = 0U;
phost->Control.setup.b.wIndex.w = 0U;
phost->Control.setup.b.wLength.w = LINE_CODING_STRUCTURE_SIZE;
return USBH_CtlReq(phost, linecoding->Array, LINE_CODING_STRUCTURE_SIZE);
}
/**
* @brief This request allows the host to specify typical asynchronous
* line-character formatting properties
* This request applies to asynchronous byte stream data class interfaces
* and endpoints
* @param pdev: Selected device
* @retval USBH_StatusTypeDef : USB ctl xfer status
*/
static USBH_StatusTypeDef SetLineCoding(USBH_HandleTypeDef *phost,
CDC_LineCodingTypeDef *linecoding)
{
phost->Control.setup.b.bmRequestType = USB_H2D | USB_REQ_TYPE_CLASS |
USB_REQ_RECIPIENT_INTERFACE;
phost->Control.setup.b.bRequest = CDC_SET_LINE_CODING;
phost->Control.setup.b.wValue.w = 0U;
phost->Control.setup.b.wIndex.w = 0U;
phost->Control.setup.b.wLength.w = LINE_CODING_STRUCTURE_SIZE;
return USBH_CtlReq(phost, linecoding->Array, LINE_CODING_STRUCTURE_SIZE);
}
/**
* @brief This function prepares the state before issuing the class specific commands
* @param None
* @retval None
*/
USBH_StatusTypeDef USBH_CDC_SetLineCoding(USBH_HandleTypeDef *phost,
CDC_LineCodingTypeDef *linecoding)
{
CDC_HandleTypeDef *CDC_Handle = (CDC_HandleTypeDef *) phost->pActiveClass->pData;
if (phost->gState == HOST_CLASS)
{
CDC_Handle->state = CDC_SET_LINE_CODING_STATE;
CDC_Handle->pUserLineCoding = linecoding;
#if (USBH_USE_OS == 1U)
USBH_OS_PutMessage(phost, USBH_CLASS_EVENT, 0U, 0U);
#endif /* (USBH_USE_OS == 1U) */
}
return USBH_OK;
}
/**
* @brief This function prepares the state before issuing the class specific commands
* @param None
* @retval None
*/
USBH_StatusTypeDef USBH_CDC_GetLineCoding(USBH_HandleTypeDef *phost,
CDC_LineCodingTypeDef *linecoding)
{
CDC_HandleTypeDef *CDC_Handle = (CDC_HandleTypeDef *) phost->pActiveClass->pData;
if ((phost->gState == HOST_CLASS) || (phost->gState == HOST_CLASS_REQUEST))
{
*linecoding = CDC_Handle->LineCoding;
return USBH_OK;
}
else
{
return USBH_FAIL;
}
}
/**
* @brief This function return last received data size
* @param None
* @retval None
*/
uint16_t USBH_CDC_GetLastReceivedDataSize(USBH_HandleTypeDef *phost)
{
uint32_t dataSize;
CDC_HandleTypeDef *CDC_Handle = (CDC_HandleTypeDef *) phost->pActiveClass->pData;
if (phost->gState == HOST_CLASS)
{
dataSize = USBH_LL_GetLastXferSize(phost, CDC_Handle->DataItf.InPipe);
}
else
{
dataSize = 0U;
}
return (uint16_t)dataSize;
}
/**
* @brief This function prepares the state before issuing the class specific commands
* @param None
* @retval None
*/
USBH_StatusTypeDef USBH_CDC_Transmit(USBH_HandleTypeDef *phost, uint8_t *pbuff, uint32_t length)
{
USBH_StatusTypeDef Status = USBH_BUSY;
CDC_HandleTypeDef *CDC_Handle = (CDC_HandleTypeDef *) phost->pActiveClass->pData;
if ((CDC_Handle->state == CDC_IDLE_STATE) || (CDC_Handle->state == CDC_TRANSFER_DATA))
{
CDC_Handle->pTxData = pbuff;
CDC_Handle->TxDataLength = length;
CDC_Handle->state = CDC_TRANSFER_DATA;
CDC_Handle->data_tx_state = CDC_SEND_DATA;
Status = USBH_OK;
#if (USBH_USE_OS == 1U)
USBH_OS_PutMessage(phost, USBH_CLASS_EVENT, 0U, 0U);
#endif /* (USBH_USE_OS == 1U) */
}
return Status;
}
/**
* @brief This function prepares the state before issuing the class specific commands
* @param None
* @retval None
*/
USBH_StatusTypeDef USBH_CDC_Receive(USBH_HandleTypeDef *phost, uint8_t *pbuff, uint32_t length)
{
USBH_StatusTypeDef Status = USBH_BUSY;
CDC_HandleTypeDef *CDC_Handle = (CDC_HandleTypeDef *) phost->pActiveClass->pData;
if ((CDC_Handle->state == CDC_IDLE_STATE) || (CDC_Handle->state == CDC_TRANSFER_DATA))
{
CDC_Handle->pRxData = pbuff;
CDC_Handle->RxDataLength = length;
CDC_Handle->state = CDC_TRANSFER_DATA;
CDC_Handle->data_rx_state = CDC_RECEIVE_DATA;
Status = USBH_OK;
#if (USBH_USE_OS == 1U)
USBH_OS_PutMessage(phost, USBH_CLASS_EVENT, 0U, 0U);
#endif /* (USBH_USE_OS == 1U) */
}
return Status;
}
/**
* @brief The function is responsible for sending data to the device
* @param pdev: Selected device
* @retval None
*/
static void CDC_ProcessTransmission(USBH_HandleTypeDef *phost)
{
CDC_HandleTypeDef *CDC_Handle = (CDC_HandleTypeDef *) phost->pActiveClass->pData;
USBH_URBStateTypeDef URB_Status = USBH_URB_IDLE;
switch (CDC_Handle->data_tx_state)
{
case CDC_SEND_DATA:
if (CDC_Handle->TxDataLength > CDC_Handle->DataItf.OutEpSize)
{
(void)USBH_BulkSendData(phost,
CDC_Handle->pTxData,
CDC_Handle->DataItf.OutEpSize,
CDC_Handle->DataItf.OutPipe,
1U);
}
else
{
(void)USBH_BulkSendData(phost,
CDC_Handle->pTxData,
(uint16_t)CDC_Handle->TxDataLength,
CDC_Handle->DataItf.OutPipe,
1U);
}
CDC_Handle->data_tx_state = CDC_SEND_DATA_WAIT;
break;
case CDC_SEND_DATA_WAIT:
URB_Status = USBH_LL_GetURBState(phost, CDC_Handle->DataItf.OutPipe);
/* Check the status done for transmission */
if (URB_Status == USBH_URB_DONE)
{
if (CDC_Handle->TxDataLength > CDC_Handle->DataItf.OutEpSize)
{
CDC_Handle->TxDataLength -= CDC_Handle->DataItf.OutEpSize;
CDC_Handle->pTxData += CDC_Handle->DataItf.OutEpSize;
}
else
{
CDC_Handle->TxDataLength = 0U;
}
if (CDC_Handle->TxDataLength > 0U)
{
CDC_Handle->data_tx_state = CDC_SEND_DATA;
}
else
{
CDC_Handle->data_tx_state = CDC_IDLE;
USBH_CDC_TransmitCallback(phost);
}
#if (USBH_USE_OS == 1U)
USBH_OS_PutMessage(phost, USBH_CLASS_EVENT, 0U, 0U);
#endif /* (USBH_USE_OS == 1U) */
}
else
{
if (URB_Status == USBH_URB_NOTREADY)
{
CDC_Handle->data_tx_state = CDC_SEND_DATA;
#if (USBH_USE_OS == 1U)
USBH_OS_PutMessage(phost, USBH_CLASS_EVENT, 0U, 0U);
#endif /* (USBH_USE_OS == 1U) */
}
}
break;
default:
break;
}
}
/**
* @brief This function responsible for reception of data from the device
* @param pdev: Selected device
* @retval None
*/
static void CDC_ProcessReception(USBH_HandleTypeDef *phost)
{
CDC_HandleTypeDef *CDC_Handle = (CDC_HandleTypeDef *) phost->pActiveClass->pData;
USBH_URBStateTypeDef URB_Status = USBH_URB_IDLE;
uint32_t length;
switch (CDC_Handle->data_rx_state)
{
case CDC_RECEIVE_DATA:
(void)USBH_BulkReceiveData(phost,
CDC_Handle->pRxData,
CDC_Handle->DataItf.InEpSize,
CDC_Handle->DataItf.InPipe);
#if defined (USBH_IN_NAK_PROCESS) && (USBH_IN_NAK_PROCESS == 1U)
phost->NakTimer = phost->Timer;
#endif /* defined (USBH_IN_NAK_PROCESS) && (USBH_IN_NAK_PROCESS == 1U) */
CDC_Handle->data_rx_state = CDC_RECEIVE_DATA_WAIT;
break;
case CDC_RECEIVE_DATA_WAIT:
URB_Status = USBH_LL_GetURBState(phost, CDC_Handle->DataItf.InPipe);
/*Check the status done for reception*/
if (URB_Status == USBH_URB_DONE)
{
length = USBH_LL_GetLastXferSize(phost, CDC_Handle->DataItf.InPipe);
if (((CDC_Handle->RxDataLength - length) > 0U) && (length == CDC_Handle->DataItf.InEpSize))
{
CDC_Handle->RxDataLength -= length;
CDC_Handle->pRxData += length;
CDC_Handle->data_rx_state = CDC_RECEIVE_DATA;
}
else
{
CDC_Handle->data_rx_state = CDC_IDLE;
USBH_CDC_ReceiveCallback(phost);
}
#if (USBH_USE_OS == 1U)
USBH_OS_PutMessage(phost, USBH_CLASS_EVENT, 0U, 0U);
#endif /* (USBH_USE_OS == 1U) */
}
#if defined (USBH_IN_NAK_PROCESS) && (USBH_IN_NAK_PROCESS == 1U)
else if (URB_Status == USBH_URB_NAK_WAIT)
{
CDC_Handle->data_rx_state = CDC_RECEIVE_DATA_WAIT;
if ((phost->Timer - phost->NakTimer) > phost->NakTimeout)
{
phost->NakTimer = phost->Timer;
USBH_ActivatePipe(phost, CDC_Handle->DataItf.InPipe);
}
#if (USBH_USE_OS == 1U)
USBH_OS_PutMessage(phost, USBH_CLASS_EVENT, 0U, 0U);
#endif /* (USBH_USE_OS == 1U) */
}
#endif /* defined (USBH_IN_NAK_PROCESS) && (USBH_IN_NAK_PROCESS == 1U) */
else
{
/* .. */
}
break;
default:
break;
}
}
/**
* @brief The function informs user that data have been received
* @param pdev: Selected device
* @retval None
*/
__weak void USBH_CDC_TransmitCallback(USBH_HandleTypeDef *phost)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(phost);
}
/**
* @brief The function informs user that data have been sent
* @param pdev: Selected device
* @retval None
*/
__weak void USBH_CDC_ReceiveCallback(USBH_HandleTypeDef *phost)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(phost);
}
/**
* @brief The function informs user that Settings have been changed
* @param pdev: Selected device
* @retval None
*/
__weak void USBH_CDC_LineCodingChanged(USBH_HandleTypeDef *phost)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(phost);
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
@@ -0,0 +1,342 @@
/**
******************************************************************************
* @file usbh_hid.h
* @author MCD Application Team
* @brief This file contains all the prototypes for the usbh_hid.c
******************************************************************************
* @attention
*
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Define to prevent recursive ----------------------------------------------*/
#ifndef __USBH_HID_H
#define __USBH_HID_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "usbh_core.h"
#include "usbh_hid_mouse.h"
#include "usbh_hid_keybd.h"
/** @addtogroup USBH_LIB
* @{
*/
/** @addtogroup USBH_CLASS
* @{
*/
/** @addtogroup USBH_HID_CLASS
* @{
*/
/** @defgroup USBH_HID_CORE
* @brief This file is the Header file for usbh_hid.c
* @{
*/
/** @defgroup USBH_HID_CORE_Exported_Types
* @{
*/
#define HID_MIN_POLL 10U
#define HID_REPORT_SIZE 16U
#define HID_MAX_USAGE 10U
#define HID_MAX_NBR_REPORT_FMT 10U
#define HID_QUEUE_SIZE 10U
#define HID_ITEM_LONG 0xFEU
#define HID_ITEM_TYPE_MAIN 0x00U
#define HID_ITEM_TYPE_GLOBAL 0x01U
#define HID_ITEM_TYPE_LOCAL 0x02U
#define HID_ITEM_TYPE_RESERVED 0x03U
#define HID_MAIN_ITEM_TAG_INPUT 0x08U
#define HID_MAIN_ITEM_TAG_OUTPUT 0x09U
#define HID_MAIN_ITEM_TAG_COLLECTION 0x0AU
#define HID_MAIN_ITEM_TAG_FEATURE 0x0BU
#define HID_MAIN_ITEM_TAG_ENDCOLLECTION 0x0CU
#define HID_GLOBAL_ITEM_TAG_USAGE_PAGE 0x00U
#define HID_GLOBAL_ITEM_TAG_LOG_MIN 0x01U
#define HID_GLOBAL_ITEM_TAG_LOG_MAX 0x02U
#define HID_GLOBAL_ITEM_TAG_PHY_MIN 0x03U
#define HID_GLOBAL_ITEM_TAG_PHY_MAX 0x04U
#define HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT 0x05U
#define HID_GLOBAL_ITEM_TAG_UNIT 0x06U
#define HID_GLOBAL_ITEM_TAG_REPORT_SIZE 0x07U
#define HID_GLOBAL_ITEM_TAG_REPORT_ID 0x08U
#define HID_GLOBAL_ITEM_TAG_REPORT_COUNT 0x09U
#define HID_GLOBAL_ITEM_TAG_PUSH 0x0AU
#define HID_GLOBAL_ITEM_TAG_POP 0x0BU
#define HID_LOCAL_ITEM_TAG_USAGE 0x00U
#define HID_LOCAL_ITEM_TAG_USAGE_MIN 0x01U
#define HID_LOCAL_ITEM_TAG_USAGE_MAX 0x02U
#define HID_LOCAL_ITEM_TAG_DESIGNATOR_INDEX 0x03U
#define HID_LOCAL_ITEM_TAG_DESIGNATOR_MIN 0x04U
#define HID_LOCAL_ITEM_TAG_DESIGNATOR_MAX 0x05U
#define HID_LOCAL_ITEM_TAG_STRING_INDEX 0x07U
#define HID_LOCAL_ITEM_TAG_STRING_MIN 0x08U
#define HID_LOCAL_ITEM_TAG_STRING_MAX 0x09U
#define HID_LOCAL_ITEM_TAG_DELIMITER 0x0AU
/* States for HID State Machine */
typedef enum
{
USBH_HID_INIT = 0,
USBH_HID_IDLE,
USBH_HID_SEND_DATA,
USBH_HID_BUSY,
USBH_HID_GET_DATA,
USBH_HID_SYNC,
USBH_HID_POLL,
USBH_HID_ERROR,
}
USBH_HID_StateTypeDef;
typedef enum
{
USBH_HID_REQ_INIT = 0,
USBH_HID_REQ_IDLE,
USBH_HID_REQ_GET_REPORT_DESC,
USBH_HID_REQ_GET_HID_DESC,
USBH_HID_REQ_SET_IDLE,
USBH_HID_REQ_SET_PROTOCOL,
USBH_HID_REQ_SET_REPORT,
}
HID_CtlStateTypeDef;
typedef enum
{
HID_MOUSE = 0x01,
HID_KEYBOARD = 0x02,
HID_UNKNOWN = 0xFF,
}
HID_TypeTypeDef;
typedef struct _HID_ReportData
{
uint8_t ReportID;
uint8_t ReportType;
uint16_t UsagePage;
uint32_t Usage[HID_MAX_USAGE];
uint32_t NbrUsage;
uint32_t UsageMin;
uint32_t UsageMax;
int32_t LogMin;
int32_t LogMax;
int32_t PhyMin;
int32_t PhyMax;
int32_t UnitExp;
uint32_t Unit;
uint32_t ReportSize;
uint32_t ReportCnt;
uint32_t Flag;
uint32_t PhyUsage;
uint32_t AppUsage;
uint32_t LogUsage;
}
HID_ReportDataTypeDef;
typedef struct _HID_ReportIDTypeDef
{
uint8_t Size; /* Report size return by the device id */
uint8_t ReportID; /* Report Id */
uint8_t Type; /* Report Type (INPUT/OUTPUT/FEATURE) */
} HID_ReportIDTypeDef;
typedef struct _HID_CollectionTypeDef
{
uint32_t Usage;
uint8_t Type;
struct _HID_CollectionTypeDef *NextPtr;
} HID_CollectionTypeDef;
typedef struct _HID_AppCollectionTypeDef
{
uint32_t Usage;
uint8_t Type;
uint8_t NbrReportFmt;
HID_ReportDataTypeDef ReportData[HID_MAX_NBR_REPORT_FMT];
} HID_AppCollectionTypeDef;
typedef struct _HIDDescriptor
{
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t bcdHID; /* indicates what endpoint this descriptor is describing */
uint8_t bCountryCode; /* specifies the transfer type. */
uint8_t bNumDescriptors; /* specifies the transfer type. */
uint8_t bReportDescriptorType; /* Maximum Packet Size this endpoint is capable of sending or receiving */
uint16_t wItemLength; /* is used to specify the polling interval of certain transfers. */
}
HID_DescTypeDef;
typedef struct
{
uint8_t *buf;
uint16_t head;
uint16_t tail;
uint16_t size;
uint8_t lock;
} FIFO_TypeDef;
/* Structure for HID process */
typedef struct _HID_Process
{
uint8_t OutPipe;
uint8_t InPipe;
USBH_HID_StateTypeDef state;
uint8_t OutEp;
uint8_t InEp;
HID_CtlStateTypeDef ctl_state;
FIFO_TypeDef fifo;
uint8_t *pData;
uint16_t length;
uint8_t ep_addr;
uint16_t poll;
uint32_t timer;
uint8_t DataReady;
HID_DescTypeDef HID_Desc;
USBH_StatusTypeDef(* Init)(USBH_HandleTypeDef *phost);
}
HID_HandleTypeDef;
/**
* @}
*/
/** @defgroup USBH_HID_CORE_Exported_Defines
* @{
*/
#define USB_HID_GET_REPORT 0x01U
#define USB_HID_GET_IDLE 0x02U
#define USB_HID_GET_PROTOCOL 0x03U
#define USB_HID_SET_REPORT 0x09U
#define USB_HID_SET_IDLE 0x0AU
#define USB_HID_SET_PROTOCOL 0x0BU
/* HID Class Codes */
#define USB_HID_CLASS 0x03U
/* Interface Descriptor field values for HID Boot Protocol */
#define HID_BOOT_CODE 0x01U
#define HID_KEYBRD_BOOT_CODE 0x01U
#define HID_MOUSE_BOOT_CODE 0x02U
/**
* @}
*/
/** @defgroup USBH_HID_CORE_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBH_HID_CORE_Exported_Variables
* @{
*/
extern USBH_ClassTypeDef HID_Class;
#define USBH_HID_CLASS &HID_Class
/**
* @}
*/
/** @defgroup USBH_HID_CORE_Exported_FunctionsPrototype
* @{
*/
USBH_StatusTypeDef USBH_HID_SetReport(USBH_HandleTypeDef *phost,
uint8_t reportType,
uint8_t reportId,
uint8_t *reportBuff,
uint8_t reportLen);
USBH_StatusTypeDef USBH_HID_GetReport(USBH_HandleTypeDef *phost,
uint8_t reportType,
uint8_t reportId,
uint8_t *reportBuff,
uint8_t reportLen);
USBH_StatusTypeDef USBH_HID_GetHIDReportDescriptor(USBH_HandleTypeDef *phost,
uint16_t length);
USBH_StatusTypeDef USBH_HID_GetHIDDescriptor(USBH_HandleTypeDef *phost,
uint16_t length);
USBH_StatusTypeDef USBH_HID_SetIdle(USBH_HandleTypeDef *phost,
uint8_t duration,
uint8_t reportId);
USBH_StatusTypeDef USBH_HID_SetProtocol(USBH_HandleTypeDef *phost,
uint8_t protocol);
void USBH_HID_EventCallback(USBH_HandleTypeDef *phost);
HID_TypeTypeDef USBH_HID_GetDeviceType(USBH_HandleTypeDef *phost);
uint8_t USBH_HID_GetPollInterval(USBH_HandleTypeDef *phost);
void USBH_HID_FifoInit(FIFO_TypeDef *f, uint8_t *buf, uint16_t size);
uint16_t USBH_HID_FifoRead(FIFO_TypeDef *f, void *buf, uint16_t nbytes);
uint16_t USBH_HID_FifoWrite(FIFO_TypeDef *f, void *buf, uint16_t nbytes);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __USBH_HID_H */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
@@ -0,0 +1,320 @@
/**
******************************************************************************
* @file usbh_hid_keybd.h
* @author MCD Application Team
* @brief This file contains all the prototypes for the usbh_hid_keybd.c
******************************************************************************
* @attention
*
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Define to prevent recursive -----------------------------------------------*/
#ifndef __USBH_HID_KEYBD_H
#define __USBH_HID_KEYBD_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "usbh_hid.h"
#include "usbh_hid_keybd.h"
/** @addtogroup USBH_LIB
* @{
*/
/** @addtogroup USBH_CLASS
* @{
*/
/** @addtogroup USBH_HID_CLASS
* @{
*/
/** @defgroup USBH_HID_KEYBD
* @brief This file is the Header file for usbh_hid_keybd.c
* @{
*/
/** @defgroup USBH_HID_KEYBD_Exported_Types
* @{
*/
#ifndef USBH_HID_KEYBD_REPORT_SIZE
#define USBH_HID_KEYBD_REPORT_SIZE 0x8U
#endif /* USBH_HID_KEYBD_REPORT_SIZE */
#define KEY_NONE 0x00
#define KEY_ERRORROLLOVER 0x01
#define KEY_POSTFAIL 0x02
#define KEY_ERRORUNDEFINED 0x03
#define KEY_A 0x04
#define KEY_B 0x05
#define KEY_C 0x06
#define KEY_D 0x07
#define KEY_E 0x08
#define KEY_F 0x09
#define KEY_G 0x0A
#define KEY_H 0x0B
#define KEY_I 0x0C
#define KEY_J 0x0D
#define KEY_K 0x0E
#define KEY_L 0x0F
#define KEY_M 0x10
#define KEY_N 0x11
#define KEY_O 0x12
#define KEY_P 0x13
#define KEY_Q 0x14
#define KEY_R 0x15
#define KEY_S 0x16
#define KEY_T 0x17
#define KEY_U 0x18
#define KEY_V 0x19
#define KEY_W 0x1A
#define KEY_X 0x1B
#define KEY_Y 0x1C
#define KEY_Z 0x1D
#define KEY_1_EXCLAMATION_MARK 0x1E
#define KEY_2_AT 0x1F
#define KEY_3_NUMBER_SIGN 0x20
#define KEY_4_DOLLAR 0x21
#define KEY_5_PERCENT 0x22
#define KEY_6_CARET 0x23
#define KEY_7_AMPERSAND 0x24
#define KEY_8_ASTERISK 0x25
#define KEY_9_OPARENTHESIS 0x26
#define KEY_0_CPARENTHESIS 0x27
#define KEY_ENTER 0x28
#define KEY_ESCAPE 0x29
#define KEY_BACKSPACE 0x2A
#define KEY_TAB 0x2B
#define KEY_SPACEBAR 0x2C
#define KEY_MINUS_UNDERSCORE 0x2D
#define KEY_EQUAL_PLUS 0x2E
#define KEY_OBRACKET_AND_OBRACE 0x2F
#define KEY_CBRACKET_AND_CBRACE 0x30
#define KEY_BACKSLASH_VERTICAL_BAR 0x31
#define KEY_NONUS_NUMBER_SIGN_TILDE 0x32
#define KEY_SEMICOLON_COLON 0x33
#define KEY_SINGLE_AND_DOUBLE_QUOTE 0x34
#define KEY_GRAVE_ACCENT_AND_TILDE 0x35
#define KEY_COMMA_AND_LESS 0x36
#define KEY_DOT_GREATER 0x37
#define KEY_SLASH_QUESTION 0x38
#define KEY_CAPS_LOCK 0x39
#define KEY_F1 0x3A
#define KEY_F2 0x3B
#define KEY_F3 0x3C
#define KEY_F4 0x3D
#define KEY_F5 0x3E
#define KEY_F6 0x3F
#define KEY_F7 0x40
#define KEY_F8 0x41
#define KEY_F9 0x42
#define KEY_F10 0x43
#define KEY_F11 0x44
#define KEY_F12 0x45
#define KEY_PRINTSCREEN 0x46
#define KEY_SCROLL_LOCK 0x47
#define KEY_PAUSE 0x48
#define KEY_INSERT 0x49
#define KEY_HOME 0x4A
#define KEY_PAGEUP 0x4B
#define KEY_DELETE 0x4C
#define KEY_END1 0x4D
#define KEY_PAGEDOWN 0x4E
#define KEY_RIGHTARROW 0x4F
#define KEY_LEFTARROW 0x50
#define KEY_DOWNARROW 0x51
#define KEY_UPARROW 0x52
#define KEY_KEYPAD_NUM_LOCK_AND_CLEAR 0x53
#define KEY_KEYPAD_SLASH 0x54
#define KEY_KEYPAD_ASTERIKS 0x55
#define KEY_KEYPAD_MINUS 0x56
#define KEY_KEYPAD_PLUS 0x57
#define KEY_KEYPAD_ENTER 0x58
#define KEY_KEYPAD_1_END 0x59
#define KEY_KEYPAD_2_DOWN_ARROW 0x5A
#define KEY_KEYPAD_3_PAGEDN 0x5B
#define KEY_KEYPAD_4_LEFT_ARROW 0x5C
#define KEY_KEYPAD_5 0x5D
#define KEY_KEYPAD_6_RIGHT_ARROW 0x5E
#define KEY_KEYPAD_7_HOME 0x5F
#define KEY_KEYPAD_8_UP_ARROW 0x60
#define KEY_KEYPAD_9_PAGEUP 0x61
#define KEY_KEYPAD_0_INSERT 0x62
#define KEY_KEYPAD_DECIMAL_SEPARATOR_DELETE 0x63
#define KEY_NONUS_BACK_SLASH_VERTICAL_BAR 0x64
#define KEY_APPLICATION 0x65
#define KEY_POWER 0x66
#define KEY_KEYPAD_EQUAL 0x67
#define KEY_F13 0x68
#define KEY_F14 0x69
#define KEY_F15 0x6A
#define KEY_F16 0x6B
#define KEY_F17 0x6C
#define KEY_F18 0x6D
#define KEY_F19 0x6E
#define KEY_F20 0x6F
#define KEY_F21 0x70
#define KEY_F22 0x71
#define KEY_F23 0x72
#define KEY_F24 0x73
#define KEY_EXECUTE 0x74
#define KEY_HELP 0x75
#define KEY_MENU 0x76
#define KEY_SELECT 0x77
#define KEY_STOP 0x78
#define KEY_AGAIN 0x79
#define KEY_UNDO 0x7A
#define KEY_CUT 0x7B
#define KEY_COPY 0x7C
#define KEY_PASTE 0x7D
#define KEY_FIND 0x7E
#define KEY_MUTE 0x7F
#define KEY_VOLUME_UP 0x80
#define KEY_VOLUME_DOWN 0x81
#define KEY_LOCKING_CAPS_LOCK 0x82
#define KEY_LOCKING_NUM_LOCK 0x83
#define KEY_LOCKING_SCROLL_LOCK 0x84
#define KEY_KEYPAD_COMMA 0x85
#define KEY_KEYPAD_EQUAL_SIGN 0x86
#define KEY_INTERNATIONAL1 0x87
#define KEY_INTERNATIONAL2 0x88
#define KEY_INTERNATIONAL3 0x89
#define KEY_INTERNATIONAL4 0x8A
#define KEY_INTERNATIONAL5 0x8B
#define KEY_INTERNATIONAL6 0x8C
#define KEY_INTERNATIONAL7 0x8D
#define KEY_INTERNATIONAL8 0x8E
#define KEY_INTERNATIONAL9 0x8F
#define KEY_LANG1 0x90
#define KEY_LANG2 0x91
#define KEY_LANG3 0x92
#define KEY_LANG4 0x93
#define KEY_LANG5 0x94
#define KEY_LANG6 0x95
#define KEY_LANG7 0x96
#define KEY_LANG8 0x97
#define KEY_LANG9 0x98
#define KEY_ALTERNATE_ERASE 0x99
#define KEY_SYSREQ 0x9A
#define KEY_CANCEL 0x9B
#define KEY_CLEAR 0x9C
#define KEY_PRIOR 0x9D
#define KEY_RETURN 0x9E
#define KEY_SEPARATOR 0x9F
#define KEY_OUT 0xA0
#define KEY_OPER 0xA1
#define KEY_CLEAR_AGAIN 0xA2
#define KEY_CRSEL 0xA3
#define KEY_EXSEL 0xA4
#define KEY_KEYPAD_00 0xB0
#define KEY_KEYPAD_000 0xB1
#define KEY_THOUSANDS_SEPARATOR 0xB2
#define KEY_DECIMAL_SEPARATOR 0xB3
#define KEY_CURRENCY_UNIT 0xB4
#define KEY_CURRENCY_SUB_UNIT 0xB5
#define KEY_KEYPAD_OPARENTHESIS 0xB6
#define KEY_KEYPAD_CPARENTHESIS 0xB7
#define KEY_KEYPAD_OBRACE 0xB8
#define KEY_KEYPAD_CBRACE 0xB9
#define KEY_KEYPAD_TAB 0xBA
#define KEY_KEYPAD_BACKSPACE 0xBB
#define KEY_KEYPAD_A 0xBC
#define KEY_KEYPAD_B 0xBD
#define KEY_KEYPAD_C 0xBE
#define KEY_KEYPAD_D 0xBF
#define KEY_KEYPAD_E 0xC0
#define KEY_KEYPAD_F 0xC1
#define KEY_KEYPAD_XOR 0xC2
#define KEY_KEYPAD_CARET 0xC3
#define KEY_KEYPAD_PERCENT 0xC4
#define KEY_KEYPAD_LESS 0xC5
#define KEY_KEYPAD_GREATER 0xC6
#define KEY_KEYPAD_AMPERSAND 0xC7
#define KEY_KEYPAD_LOGICAL_AND 0xC8
#define KEY_KEYPAD_VERTICAL_BAR 0xC9
#define KEY_KEYPAD_LOGIACL_OR 0xCA
#define KEY_KEYPAD_COLON 0xCB
#define KEY_KEYPAD_NUMBER_SIGN 0xCC
#define KEY_KEYPAD_SPACE 0xCD
#define KEY_KEYPAD_AT 0xCE
#define KEY_KEYPAD_EXCLAMATION_MARK 0xCF
#define KEY_KEYPAD_MEMORY_STORE 0xD0
#define KEY_KEYPAD_MEMORY_RECALL 0xD1
#define KEY_KEYPAD_MEMORY_CLEAR 0xD2
#define KEY_KEYPAD_MEMORY_ADD 0xD3
#define KEY_KEYPAD_MEMORY_SUBTRACT 0xD4
#define KEY_KEYPAD_MEMORY_MULTIPLY 0xD5
#define KEY_KEYPAD_MEMORY_DIVIDE 0xD6
#define KEY_KEYPAD_PLUSMINUS 0xD7
#define KEY_KEYPAD_CLEAR 0xD8
#define KEY_KEYPAD_CLEAR_ENTRY 0xD9
#define KEY_KEYPAD_BINARY 0xDA
#define KEY_KEYPAD_OCTAL 0xDB
#define KEY_KEYPAD_DECIMAL 0xDC
#define KEY_KEYPAD_HEXADECIMAL 0xDD
#define KEY_LEFTCONTROL 0xE0
#define KEY_LEFTSHIFT 0xE1
#define KEY_LEFTALT 0xE2
#define KEY_LEFT_GUI 0xE3
#define KEY_RIGHTCONTROL 0xE4
#define KEY_RIGHTSHIFT 0xE5
#define KEY_RIGHTALT 0xE6
#define KEY_RIGHT_GUI 0xE7
typedef struct
{
uint8_t state;
uint8_t lctrl;
uint8_t lshift;
uint8_t lalt;
uint8_t lgui;
uint8_t rctrl;
uint8_t rshift;
uint8_t ralt;
uint8_t rgui;
uint8_t keys[6];
}
HID_KEYBD_Info_TypeDef;
USBH_StatusTypeDef USBH_HID_KeybdInit(USBH_HandleTypeDef *phost);
HID_KEYBD_Info_TypeDef *USBH_HID_GetKeybdInfo(USBH_HandleTypeDef *phost);
uint8_t USBH_HID_GetASCIICode(HID_KEYBD_Info_TypeDef *info);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __USBH_HID_KEYBD_H */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
@@ -0,0 +1,119 @@
/**
******************************************************************************
* @file usbh_hid_mouse.h
* @author MCD Application Team
* @brief This file contains all the prototypes for the usbh_hid_mouse.c
******************************************************************************
* @attention
*
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Define to prevent recursive ----------------------------------------------*/
#ifndef __USBH_HID_MOUSE_H
#define __USBH_HID_MOUSE_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "usbh_hid.h"
/** @addtogroup USBH_LIB
* @{
*/
/** @addtogroup USBH_CLASS
* @{
*/
/** @addtogroup USBH_HID_CLASS
* @{
*/
/** @defgroup USBH_HID_MOUSE
* @brief This file is the Header file for usbh_hid_mouse.c
* @{
*/
/** @defgroup USBH_HID_MOUSE_Exported_Types
* @{
*/
typedef struct _HID_MOUSE_Info
{
uint8_t x;
uint8_t y;
uint8_t buttons[3];
}
HID_MOUSE_Info_TypeDef;
/**
* @}
*/
/** @defgroup USBH_HID_MOUSE_Exported_Defines
* @{
*/
#ifndef USBH_HID_MOUSE_REPORT_SIZE
#define USBH_HID_MOUSE_REPORT_SIZE 0x8U
#endif /* USBH_HID_MOUSE_REPORT_SIZE */
/**
* @}
*/
/** @defgroup USBH_HID_MOUSE_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBH_HID_MOUSE_Exported_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USBH_HID_MOUSE_Exported_FunctionsPrototype
* @{
*/
USBH_StatusTypeDef USBH_HID_MouseInit(USBH_HandleTypeDef *phost);
HID_MOUSE_Info_TypeDef *USBH_HID_GetMouseInfo(USBH_HandleTypeDef *phost);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __USBH_HID_MOUSE_H */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
@@ -0,0 +1,96 @@
/**
******************************************************************************
* @file usbh_hid_parser.c
* @author MCD Application Team
* @brief This file is the header file of the usbh_hid_parser.c
******************************************************************************
* @attention
*
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Define to prevent recursive -----------------------------------------------*/
#ifndef __USBH_HID_PARSER_H
#define __USBH_HID_PARSER_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "usbh_hid.h"
#include "usbh_hid_usage.h"
/** @addtogroup USBH_LIB
* @{
*/
/** @addtogroup USBH_CLASS
* @{
*/
/** @addtogroup USBH_HID_CLASS
* @{
*/
/** @defgroup USBH_HID_PARSER
* @brief This file is the Header file for usbh_hid_parser.c
* @{
*/
/** @defgroup USBH_HID_PARSER_Exported_Types
* @{
*/
typedef struct
{
uint8_t *data;
uint32_t size;
uint8_t shift;
uint8_t count;
uint8_t sign;
uint32_t logical_min; /*min value device can return*/
uint32_t logical_max; /*max value device can return*/
uint32_t physical_min; /*min vale read can report*/
uint32_t physical_max; /*max value read can report*/
uint32_t resolution;
}
HID_Report_ItemTypedef;
uint32_t HID_ReadItem(HID_Report_ItemTypedef *ri, uint8_t ndx);
uint32_t HID_WriteItem(HID_Report_ItemTypedef *ri, uint32_t value, uint8_t ndx);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __USBH_HID_PARSER_H */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
@@ -0,0 +1,191 @@
/**
******************************************************************************
* @file usbh_hid_usage.c
* @author MCD Application Team
* @brief This file contain the USAGE page codes
******************************************************************************
* @attention
*
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Define to prevent recursive ----------------------------------------------*/
#ifndef __USDH_HID_USAGE_H
#define __USDH_HID_USAGE_H
#ifdef __cplusplus
extern "C" {
#endif
/** @addtogroup USBH_LIB
* @{
*/
/** @addtogroup USBH_CLASS
* @{
*/
/** @addtogroup USBH_HID_CLASS
* @{
*/
/** @defgroup USBH_HID_USAGE
* @brief This file is the Header file for usbh_hid_usage.c
* @{
*/
/** @defgroup USBH_HID_USAGE_Exported_Types
* @{
*/
/****************************************************/
/* HID 1.11 usage pages */
/****************************************************/
#define HID_USAGE_PAGE_UNDEFINED uint16_t (0x00) /* Undefined */
/**** Top level pages */
#define HID_USAGE_PAGE_GEN_DES uint16_t (0x01) /* Generic Desktop Controls*/
#define HID_USAGE_PAGE_SIM_CTR uint16_t (0x02) /* Simulation Controls */
#define HID_USAGE_PAGE_VR_CTR uint16_t (0x03) /* VR Controls */
#define HID_USAGE_PAGE_SPORT_CTR uint16_t (0x04) /* Sport Controls */
#define HID_USAGE_PAGE_GAME_CTR uint16_t (0x05) /* Game Controls */
#define HID_USAGE_PAGE_GEN_DEV uint16_t (0x06) /* Generic Device Controls */
#define HID_USAGE_PAGE_KEYB uint16_t (0x07) /* Keyboard/Keypad */
#define HID_USAGE_PAGE_LED uint16_t (0x08) /* LEDs */
#define HID_USAGE_PAGE_BUTTON uint16_t (0x09) /* Button */
#define HID_USAGE_PAGE_ORDINAL uint16_t (0x0A) /* Ordinal */
#define HID_USAGE_PAGE_PHONE uint16_t (0x0B) /* Telephony */
#define HID_USAGE_PAGE_CONSUMER uint16_t (0x0C) /* Consumer */
#define HID_USAGE_PAGE_DIGITIZER uint16_t (0x0D) /* Digitizer*/
/* 0E Reserved */
#define HID_USAGE_PAGE_PID uint16_t (0x0F) /* PID Page (force feedback and related devices) */
#define HID_USAGE_PAGE_UNICODE uint16_t (0x10) /* Unicode */
/* 11-13 Reserved */
#define HID_USAGE_PAGE_ALNUM_DISP uint16_t (0x14) /* Alphanumeric Display */
/* 15-1f Reserved */
/**** END of top level pages */
/* 25-3f Reserved */
#define HID_USAGE_PAGE_MEDICAL uint16_t (0x40) /* Medical Instruments */
/* 41-7F Reserved */
/*80-83 Monitor pages USB Device Class Definition for Monitor Devices
84-87 Power pages USB Device Class Definition for Power Devices */
/* 88-8B Reserved */
#define HID_USAGE_PAGE_BARCODE uint16_t (0x8C) /* Bar Code Scanner page */
#define HID_USAGE_PAGE_SCALE uint16_t (0x8D) /* Scale page */
#define HID_USAGE_PAGE_MSR uint16_t (0x8E) /* Magnetic Stripe Reading (MSR) Devices */
#define HID_USAGE_PAGE_POS uint16_t (0x8F) /* Reserved Point of Sale pages */
#define HID_USAGE_PAGE_CAMERA_CTR uint16_t (0x90) /* Camera Control Page */
#define HID_USAGE_PAGE_ARCADE uint16_t (0x91) /* Arcade Page */
/****************************************************/
/* Usage definitions for the "Generic Desktop" page */
/****************************************************/
#define HID_USAGE_UNDEFINED uint16_t (0x00) /* Undefined */
#define HID_USAGE_POINTER uint16_t (0x01) /* Pointer (Physical Collection) */
#define HID_USAGE_MOUSE uint16_t (0x02) /* Mouse (Application Collection) */
/* 03 Reserved */
#define HID_USAGE_JOYSTICK uint16_t (0x04) /* Joystick (Application Collection) */
#define HID_USAGE_GAMEPAD uint16_t (0x05) /* Game Pad (Application Collection) */
#define HID_USAGE_KBD uint16_t (0x06) /* Keyboard (Application Collection) */
#define HID_USAGE_KEYPAD uint16_t (0x07) /* Keypad (Application Collection) */
#define HID_USAGE_MAX_CTR uint16_t (0x08) /* Multi-axis Controller (Application Collection) */
/* 09-2F Reserved */
#define HID_USAGE_X uint16_t (0x30) /* X (Dynamic Value) */
#define HID_USAGE_Y uint16_t (0x31) /* Y (Dynamic Value) */
#define HID_USAGE_Z uint16_t (0x32) /* Z (Dynamic Value) */
#define HID_USAGE_RX uint16_t (0x33) /* Rx (Dynamic Value) */
#define HID_USAGE_RY uint16_t (0x34) /* Ry (Dynamic Value) */
#define HID_USAGE_RZ uint16_t (0x35) /* Rz (Dynamic Value) */
#define HID_USAGE_SLIDER uint16_t (0x36) /* Slider (Dynamic Value) */
#define HID_USAGE_DIAL uint16_t (0x37) /* Dial (Dynamic Value) */
#define HID_USAGE_WHEEL uint16_t (0x38) /* Wheel (Dynamic Value) */
#define HID_USAGE_HATSW uint16_t (0x39) /* Hat switch (Dynamic Value) */
#define HID_USAGE_COUNTEDBUF uint16_t (0x3A) /* Counted Buffer (Logical Collection) */
#define HID_USAGE_BYTECOUNT uint16_t (0x3B) /* Byte Count (Dynamic Value) */
#define HID_USAGE_MOTIONWAKE uint16_t (0x3C) /* Motion Wakeup (One Shot Control) */
#define HID_USAGE_START uint16_t (0x3D) /* Start (On/Off Control) */
#define HID_USAGE_SELECT uint16_t (0x3E) /* Select (On/Off Control) */
/* 3F Reserved */
#define HID_USAGE_VX uint16_t (0x40) /* Vx (Dynamic Value) */
#define HID_USAGE_VY uint16_t (0x41) /* Vy (Dynamic Value) */
#define HID_USAGE_VZ uint16_t (0x42) /* Vz (Dynamic Value) */
#define HID_USAGE_VBRX uint16_t (0x43) /* Vbrx (Dynamic Value) */
#define HID_USAGE_VBRY uint16_t (0x44) /* Vbry (Dynamic Value) */
#define HID_USAGE_VBRZ uint16_t (0x45) /* Vbrz (Dynamic Value) */
#define HID_USAGE_VNO uint16_t (0x46) /* Vno (Dynamic Value) */
#define HID_USAGE_FEATNOTIF uint16_t (0x47) /* Feature Notification (Dynamic Value),(Dynamic Flag) */
/* 48-7F Reserved */
#define HID_USAGE_SYSCTL uint16_t (0x80) /* System Control (Application Collection) */
#define HID_USAGE_PWDOWN uint16_t (0x81) /* System Power Down (One Shot Control) */
#define HID_USAGE_SLEEP uint16_t (0x82) /* System Sleep (One Shot Control) */
#define HID_USAGE_WAKEUP uint16_t (0x83) /* System Wake Up (One Shot Control) */
#define HID_USAGE_CONTEXTM uint16_t (0x84) /* System Context Menu (One Shot Control) */
#define HID_USAGE_MAINM uint16_t (0x85) /* System Main Menu (One Shot Control) */
#define HID_USAGE_APPM uint16_t (0x86) /* System App Menu (One Shot Control) */
#define HID_USAGE_MENUHELP uint16_t (0x87) /* System Menu Help (One Shot Control) */
#define HID_USAGE_MENUEXIT uint16_t (0x88) /* System Menu Exit (One Shot Control) */
#define HID_USAGE_MENUSELECT uint16_t (0x89) /* System Menu Select (One Shot Control) */
#define HID_USAGE_SYSM_RIGHT uint16_t (0x8A) /* System Menu Right (Re-Trigger Control) */
#define HID_USAGE_SYSM_LEFT uint16_t (0x8B) /* System Menu Left (Re-Trigger Control) */
#define HID_USAGE_SYSM_UP uint16_t (0x8C) /* System Menu Up (Re-Trigger Control) */
#define HID_USAGE_SYSM_DOWN uint16_t (0x8D) /* System Menu Down (Re-Trigger Control) */
#define HID_USAGE_COLDRESET uint16_t (0x8E) /* System Cold Restart (One Shot Control) */
#define HID_USAGE_WARMRESET uint16_t (0x8F) /* System Warm Restart (One Shot Control) */
#define HID_USAGE_DUP uint16_t (0x90) /* D-pad Up (On/Off Control) */
#define HID_USAGE_DDOWN uint16_t (0x91) /* D-pad Down (On/Off Control) */
#define HID_USAGE_DRIGHT uint16_t (0x92) /* D-pad Right (On/Off Control) */
#define HID_USAGE_DLEFT uint16_t (0x93) /* D-pad Left (On/Off Control) */
/* 94-9F Reserved */
#define HID_USAGE_SYS_DOCK uint16_t (0xA0) /* System Dock (One Shot Control) */
#define HID_USAGE_SYS_UNDOCK uint16_t (0xA1) /* System Undock (One Shot Control) */
#define HID_USAGE_SYS_SETUP uint16_t (0xA2) /* System Setup (One Shot Control) */
#define HID_USAGE_SYS_BREAK uint16_t (0xA3) /* System Break (One Shot Control) */
#define HID_USAGE_SYS_DBGBRK uint16_t (0xA4) /* System Debugger Break (One Shot Control) */
#define HID_USAGE_APP_BRK uint16_t (0xA5) /* Application Break (One Shot Control) */
#define HID_USAGE_APP_DBGBRK uint16_t (0xA6) /* Application Debugger Break (One Shot Control) */
#define HID_USAGE_SYS_SPKMUTE uint16_t (0xA7) /* System Speaker Mute (One Shot Control) */
#define HID_USAGE_SYS_HIBERN uint16_t (0xA8) /* System Hibernate (One Shot Control) */
/* A9-AF Reserved */
#define HID_USAGE_SYS_SIDPINV uint16_t (0xB0) /* System Display Invert (One Shot Control) */
#define HID_USAGE_SYS_DISPINT uint16_t (0xB1) /* System Display Internal (One Shot Control) */
#define HID_USAGE_SYS_DISPEXT uint16_t (0xB2) /* System Display External (One Shot Control) */
#define HID_USAGE_SYS_DISPBOTH uint16_t (0xB3) /* System Display Both (One Shot Control) */
#define HID_USAGE_SYS_DISPDUAL uint16_t (0xB4) /* System Display Dual (One Shot Control) */
#define HID_USAGE_SYS_DISPTGLIE uint16_t (0xB5) /* System Display Toggle Int/Ext (One Shot Control) */
#define HID_USAGE_SYS_DISP_SWAP uint16_t (0xB6) /* System Display Swap Primary/Secondary (One Shot Control) */
#define HID_USAGE_SYS_DIPS_LCDA uint16_t (0xB7) /* System Display LCD Autoscale (One Shot Control) */
/* B8-FFFF Reserved */
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __USDH_HID_USAGE_H */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
@@ -0,0 +1,924 @@
/**
******************************************************************************
* @file usbh_hid.c
* @author MCD Application Team
* @brief This file is the HID Layer Handlers for USB Host HID class.
*
******************************************************************************
* @attention
*
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
* @verbatim
*
* ===================================================================
* HID Class Description
* ===================================================================
* This module manages the HID class V1.11 following the "Device Class Definition
* for Human Interface Devices (HID) Version 1.11 Jun 27, 2001".
* This driver implements the following aspects of the specification:
* - The Boot Interface Subclass
* - The Mouse and Keyboard protocols
*
* @endverbatim
*
******************************************************************************
*/
/* BSPDependencies
- "stm32xxxxx_{eval}{discovery}{nucleo_144}.c"
- "stm32xxxxx_{eval}{discovery}_io.c"
- "stm32xxxxx_{eval}{discovery}{adafruit}_lcd.c"
- "stm32xxxxx_{eval}{discovery}_sdram.c"
EndBSPDependencies */
/* Includes ------------------------------------------------------------------*/
#include "usbh_hid.h"
#include "usbh_hid_parser.h"
/** @addtogroup USBH_LIB
* @{
*/
/** @addtogroup USBH_CLASS
* @{
*/
/** @addtogroup USBH_HID_CLASS
* @{
*/
/** @defgroup USBH_HID_CORE
* @brief This file includes HID Layer Handlers for USB Host HID class.
* @{
*/
/** @defgroup USBH_HID_CORE_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @defgroup USBH_HID_CORE_Private_Defines
* @{
*/
/**
* @}
*/
/** @defgroup USBH_HID_CORE_Private_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBH_HID_CORE_Private_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USBH_HID_CORE_Private_FunctionPrototypes
* @{
*/
static USBH_StatusTypeDef USBH_HID_InterfaceInit(USBH_HandleTypeDef *phost);
static USBH_StatusTypeDef USBH_HID_InterfaceDeInit(USBH_HandleTypeDef *phost);
static USBH_StatusTypeDef USBH_HID_ClassRequest(USBH_HandleTypeDef *phost);
static USBH_StatusTypeDef USBH_HID_Process(USBH_HandleTypeDef *phost);
static USBH_StatusTypeDef USBH_HID_SOFProcess(USBH_HandleTypeDef *phost);
static void USBH_HID_ParseHIDDesc(HID_DescTypeDef *desc, uint8_t *buf);
extern USBH_StatusTypeDef USBH_HID_MouseInit(USBH_HandleTypeDef *phost);
extern USBH_StatusTypeDef USBH_HID_KeybdInit(USBH_HandleTypeDef *phost);
USBH_ClassTypeDef HID_Class =
{
"HID",
USB_HID_CLASS,
USBH_HID_InterfaceInit,
USBH_HID_InterfaceDeInit,
USBH_HID_ClassRequest,
USBH_HID_Process,
USBH_HID_SOFProcess,
NULL,
};
/**
* @}
*/
/** @defgroup USBH_HID_CORE_Private_Functions
* @{
*/
/**
* @brief USBH_HID_InterfaceInit
* The function init the HID class.
* @param phost: Host handle
* @retval USBH Status
*/
static USBH_StatusTypeDef USBH_HID_InterfaceInit(USBH_HandleTypeDef *phost)
{
USBH_StatusTypeDef status;
HID_HandleTypeDef *HID_Handle;
uint16_t ep_mps;
uint8_t max_ep;
uint8_t num = 0U;
uint8_t interface;
interface = USBH_FindInterface(phost, phost->pActiveClass->ClassCode, HID_BOOT_CODE, 0xFFU);
if ((interface == 0xFFU) || (interface >= USBH_MAX_NUM_INTERFACES)) /* No Valid Interface */
{
USBH_DbgLog("Cannot Find the interface for %s class.", phost->pActiveClass->Name);
return USBH_FAIL;
}
status = USBH_SelectInterface(phost, interface);
if (status != USBH_OK)
{
return USBH_FAIL;
}
phost->pActiveClass->pData = (HID_HandleTypeDef *)USBH_malloc(sizeof(HID_HandleTypeDef));
HID_Handle = (HID_HandleTypeDef *) phost->pActiveClass->pData;
if (HID_Handle == NULL)
{
USBH_DbgLog("Cannot allocate memory for HID Handle");
return USBH_FAIL;
}
/* Initialize hid handler */
(void)USBH_memset(HID_Handle, 0, sizeof(HID_HandleTypeDef));
HID_Handle->state = USBH_HID_ERROR;
/*Decode Bootclass Protocol: Mouse or Keyboard*/
if (phost->device.CfgDesc.Itf_Desc[interface].bInterfaceProtocol == HID_KEYBRD_BOOT_CODE)
{
USBH_UsrLog("KeyBoard device found!");
HID_Handle->Init = USBH_HID_KeybdInit;
}
else if (phost->device.CfgDesc.Itf_Desc[interface].bInterfaceProtocol == HID_MOUSE_BOOT_CODE)
{
USBH_UsrLog("Mouse device found!");
HID_Handle->Init = USBH_HID_MouseInit;
}
else
{
USBH_UsrLog("Protocol not supported.");
return USBH_FAIL;
}
HID_Handle->state = USBH_HID_INIT;
HID_Handle->ctl_state = USBH_HID_REQ_INIT;
HID_Handle->ep_addr = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[0].bEndpointAddress;
HID_Handle->length = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[0].wMaxPacketSize;
HID_Handle->poll = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[0].bInterval;
if (HID_Handle->poll < HID_MIN_POLL)
{
HID_Handle->poll = HID_MIN_POLL;
}
/* Check of available number of endpoints */
/* Find the number of EPs in the Interface Descriptor */
/* Choose the lower number in order not to overrun the buffer allocated */
max_ep = ((phost->device.CfgDesc.Itf_Desc[interface].bNumEndpoints <= USBH_MAX_NUM_ENDPOINTS) ?
phost->device.CfgDesc.Itf_Desc[interface].bNumEndpoints : USBH_MAX_NUM_ENDPOINTS);
/* Decode endpoint IN and OUT address from interface descriptor */
for (num = 0U; num < max_ep; num++)
{
if ((phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[num].bEndpointAddress & 0x80U) != 0U)
{
HID_Handle->InEp = (phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[num].bEndpointAddress);
HID_Handle->InPipe = USBH_AllocPipe(phost, HID_Handle->InEp);
ep_mps = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[num].wMaxPacketSize;
/* Open pipe for IN endpoint */
(void)USBH_OpenPipe(phost, HID_Handle->InPipe, HID_Handle->InEp, phost->device.address,
phost->device.speed, USB_EP_TYPE_INTR, ep_mps);
(void)USBH_LL_SetToggle(phost, HID_Handle->InPipe, 0U);
}
else
{
HID_Handle->OutEp = (phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[num].bEndpointAddress);
HID_Handle->OutPipe = USBH_AllocPipe(phost, HID_Handle->OutEp);
ep_mps = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[num].wMaxPacketSize;
/* Open pipe for OUT endpoint */
(void)USBH_OpenPipe(phost, HID_Handle->OutPipe, HID_Handle->OutEp, phost->device.address,
phost->device.speed, USB_EP_TYPE_INTR, ep_mps);
(void)USBH_LL_SetToggle(phost, HID_Handle->OutPipe, 0U);
}
}
return USBH_OK;
}
/**
* @brief USBH_HID_InterfaceDeInit
* The function DeInit the Pipes used for the HID class.
* @param phost: Host handle
* @retval USBH Status
*/
static USBH_StatusTypeDef USBH_HID_InterfaceDeInit(USBH_HandleTypeDef *phost)
{
HID_HandleTypeDef *HID_Handle = (HID_HandleTypeDef *) phost->pActiveClass->pData;
if (HID_Handle->InPipe != 0x00U)
{
(void)USBH_ClosePipe(phost, HID_Handle->InPipe);
(void)USBH_FreePipe(phost, HID_Handle->InPipe);
HID_Handle->InPipe = 0U; /* Reset the pipe as Free */
}
if (HID_Handle->OutPipe != 0x00U)
{
(void)USBH_ClosePipe(phost, HID_Handle->OutPipe);
(void)USBH_FreePipe(phost, HID_Handle->OutPipe);
HID_Handle->OutPipe = 0U; /* Reset the pipe as Free */
}
if ((phost->pActiveClass->pData) != NULL)
{
USBH_free(phost->pActiveClass->pData);
phost->pActiveClass->pData = 0U;
}
return USBH_OK;
}
/**
* @brief USBH_HID_ClassRequest
* The function is responsible for handling Standard requests
* for HID class.
* @param phost: Host handle
* @retval USBH Status
*/
static USBH_StatusTypeDef USBH_HID_ClassRequest(USBH_HandleTypeDef *phost)
{
USBH_StatusTypeDef status = USBH_BUSY;
USBH_StatusTypeDef classReqStatus = USBH_BUSY;
HID_HandleTypeDef *HID_Handle = (HID_HandleTypeDef *) phost->pActiveClass->pData;
/* Switch HID state machine */
switch (HID_Handle->ctl_state)
{
case USBH_HID_REQ_INIT:
case USBH_HID_REQ_GET_HID_DESC:
USBH_HID_ParseHIDDesc(&HID_Handle->HID_Desc, phost->device.CfgDesc_Raw);
HID_Handle->ctl_state = USBH_HID_REQ_GET_REPORT_DESC;
break;
case USBH_HID_REQ_GET_REPORT_DESC:
/* Get Report Desc */
classReqStatus = USBH_HID_GetHIDReportDescriptor(phost, HID_Handle->HID_Desc.wItemLength);
if (classReqStatus == USBH_OK)
{
/* The descriptor is available in phost->device.Data */
HID_Handle->ctl_state = USBH_HID_REQ_SET_IDLE;
}
else if (classReqStatus == USBH_NOT_SUPPORTED)
{
USBH_ErrLog("Control error: HID: Device Get Report Descriptor request failed");
status = USBH_FAIL;
}
else
{
/* .. */
}
break;
case USBH_HID_REQ_SET_IDLE:
classReqStatus = USBH_HID_SetIdle(phost, 0U, 0U);
/* set Idle */
if (classReqStatus == USBH_OK)
{
HID_Handle->ctl_state = USBH_HID_REQ_SET_PROTOCOL;
}
else
{
if (classReqStatus == USBH_NOT_SUPPORTED)
{
HID_Handle->ctl_state = USBH_HID_REQ_SET_PROTOCOL;
}
}
break;
case USBH_HID_REQ_SET_PROTOCOL:
/* set protocol */
classReqStatus = USBH_HID_SetProtocol(phost, 0U);
if (classReqStatus == USBH_OK)
{
HID_Handle->ctl_state = USBH_HID_REQ_IDLE;
/* all requests performed */
phost->pUser(phost, HOST_USER_CLASS_ACTIVE);
status = USBH_OK;
}
else if (classReqStatus == USBH_NOT_SUPPORTED)
{
USBH_ErrLog("Control error: HID: Device Set protocol request failed");
status = USBH_FAIL;
}
else
{
/* .. */
}
break;
case USBH_HID_REQ_IDLE:
default:
break;
}
return status;
}
/**
* @brief USBH_HID_Process
* The function is for managing state machine for HID data transfers
* @param phost: Host handle
* @retval USBH Status
*/
static USBH_StatusTypeDef USBH_HID_Process(USBH_HandleTypeDef *phost)
{
USBH_StatusTypeDef status = USBH_OK;
HID_HandleTypeDef *HID_Handle = (HID_HandleTypeDef *) phost->pActiveClass->pData;
uint32_t XferSize;
switch (HID_Handle->state)
{
case USBH_HID_INIT:
status = HID_Handle->Init(phost);
if (status == USBH_OK)
{
HID_Handle->state = USBH_HID_IDLE;
}
else
{
USBH_ErrLog("HID Class Init failed");
HID_Handle->state = USBH_HID_ERROR;
status = USBH_FAIL;
}
#if (USBH_USE_OS == 1U)
USBH_OS_PutMessage(phost, USBH_URB_EVENT, 0U, 0U);
#endif /* (USBH_USE_OS == 1U) */
break;
case USBH_HID_IDLE:
status = USBH_HID_GetReport(phost, 0x01U, 0U, HID_Handle->pData, (uint8_t)HID_Handle->length);
if (status == USBH_OK)
{
HID_Handle->state = USBH_HID_SYNC;
}
else if (status == USBH_BUSY)
{
HID_Handle->state = USBH_HID_IDLE;
status = USBH_OK;
}
else if (status == USBH_NOT_SUPPORTED)
{
HID_Handle->state = USBH_HID_SYNC;
status = USBH_OK;
}
else
{
HID_Handle->state = USBH_HID_ERROR;
status = USBH_FAIL;
}
#if (USBH_USE_OS == 1U)
USBH_OS_PutMessage(phost, USBH_URB_EVENT, 0U, 0U);
#endif /* (USBH_USE_OS == 1U) */
break;
case USBH_HID_SYNC:
/* Sync with start of Even Frame */
if ((phost->Timer & 1U) != 0U)
{
HID_Handle->state = USBH_HID_GET_DATA;
}
#if (USBH_USE_OS == 1U)
USBH_OS_PutMessage(phost, USBH_URB_EVENT, 0U, 0U);
#endif /* (USBH_USE_OS == 1U) */
break;
case USBH_HID_GET_DATA:
(void)USBH_InterruptReceiveData(phost, HID_Handle->pData,
(uint8_t)HID_Handle->length,
HID_Handle->InPipe);
HID_Handle->state = USBH_HID_POLL;
HID_Handle->timer = phost->Timer;
HID_Handle->DataReady = 0U;
break;
case USBH_HID_POLL:
if (USBH_LL_GetURBState(phost, HID_Handle->InPipe) == USBH_URB_DONE)
{
XferSize = USBH_LL_GetLastXferSize(phost, HID_Handle->InPipe);
if ((HID_Handle->DataReady == 0U) && (XferSize != 0U) && (HID_Handle->fifo.buf != NULL))
{
(void)USBH_HID_FifoWrite(&HID_Handle->fifo, HID_Handle->pData, HID_Handle->length);
HID_Handle->DataReady = 1U;
USBH_HID_EventCallback(phost);
#if (USBH_USE_OS == 1U)
USBH_OS_PutMessage(phost, USBH_URB_EVENT, 0U, 0U);
#endif /* (USBH_USE_OS == 1U) */
}
}
else
{
/* IN Endpoint Stalled */
if (USBH_LL_GetURBState(phost, HID_Handle->InPipe) == USBH_URB_STALL)
{
/* Issue Clear Feature on interrupt IN endpoint */
if (USBH_ClrFeature(phost, HID_Handle->ep_addr) == USBH_OK)
{
/* Change state to issue next IN token */
HID_Handle->state = USBH_HID_GET_DATA;
}
}
}
break;
default:
break;
}
return status;
}
/**
* @brief USBH_HID_SOFProcess
* The function is for managing the SOF Process
* @param phost: Host handle
* @retval USBH Status
*/
static USBH_StatusTypeDef USBH_HID_SOFProcess(USBH_HandleTypeDef *phost)
{
HID_HandleTypeDef *HID_Handle = (HID_HandleTypeDef *) phost->pActiveClass->pData;
if (HID_Handle->state == USBH_HID_POLL)
{
if ((phost->Timer - HID_Handle->timer) >= HID_Handle->poll)
{
HID_Handle->state = USBH_HID_GET_DATA;
#if (USBH_USE_OS == 1U)
USBH_OS_PutMessage(phost, USBH_URB_EVENT, 0U, 0U);
#endif /* (USBH_USE_OS == 1U) */
}
}
return USBH_OK;
}
/**
* @brief USBH_Get_HID_ReportDescriptor
* Issue report Descriptor command to the device. Once the response
* received, parse the report descriptor and update the status.
* @param phost: Host handle
* @param Length : HID Report Descriptor Length
* @retval USBH Status
*/
USBH_StatusTypeDef USBH_HID_GetHIDReportDescriptor(USBH_HandleTypeDef *phost,
uint16_t length)
{
USBH_StatusTypeDef status;
if (length > sizeof(phost->device.Data))
{
USBH_ErrLog("Control error: Get HID Report Descriptor failed, data buffer size issue");
return USBH_NOT_SUPPORTED;
}
status = USBH_GetDescriptor(phost,
USB_REQ_RECIPIENT_INTERFACE | USB_REQ_TYPE_STANDARD,
USB_DESC_HID_REPORT,
phost->device.Data,
length);
/* HID report descriptor is available in phost->device.Data.
In case of USB Boot Mode devices for In report handling ,
HID report descriptor parsing is not required.
In case, for supporting Non-Boot Protocol devices and output reports,
user may parse the report descriptor*/
return status;
}
/**
* @brief USBH_Get_HID_Descriptor
* Issue HID Descriptor command to the device. Once the response
* received, parse the report descriptor and update the status.
* @param phost: Host handle
* @param Length : HID Descriptor Length
* @retval USBH Status
*/
USBH_StatusTypeDef USBH_HID_GetHIDDescriptor(USBH_HandleTypeDef *phost,
uint16_t length)
{
USBH_StatusTypeDef status;
if (length > sizeof(phost->device.Data))
{
USBH_ErrLog("Control error: Get HID Descriptor failed, data buffer size issue");
return USBH_NOT_SUPPORTED;
}
status = USBH_GetDescriptor(phost,
USB_REQ_RECIPIENT_INTERFACE | USB_REQ_TYPE_STANDARD,
USB_DESC_HID,
phost->device.Data,
length);
return status;
}
/**
* @brief USBH_Set_Idle
* Set Idle State.
* @param phost: Host handle
* @param duration: Duration for HID Idle request
* @param reportId : Targeted report ID for Set Idle request
* @retval USBH Status
*/
USBH_StatusTypeDef USBH_HID_SetIdle(USBH_HandleTypeDef *phost,
uint8_t duration,
uint8_t reportId)
{
phost->Control.setup.b.bmRequestType = USB_H2D | USB_REQ_RECIPIENT_INTERFACE | \
USB_REQ_TYPE_CLASS;
phost->Control.setup.b.bRequest = USB_HID_SET_IDLE;
phost->Control.setup.b.wValue.w = (uint16_t)(((uint32_t)duration << 8U) | (uint32_t)reportId);
phost->Control.setup.b.wIndex.w = 0U;
phost->Control.setup.b.wLength.w = 0U;
return USBH_CtlReq(phost, NULL, 0U);
}
/**
* @brief USBH_HID_Set_Report
* Issues Set Report
* @param phost: Host handle
* @param reportType : Report type to be sent
* @param reportId : Targeted report ID for Set Report request
* @param reportBuff : Report Buffer
* @param reportLen : Length of data report to be send
* @retval USBH Status
*/
USBH_StatusTypeDef USBH_HID_SetReport(USBH_HandleTypeDef *phost,
uint8_t reportType,
uint8_t reportId,
uint8_t *reportBuff,
uint8_t reportLen)
{
phost->Control.setup.b.bmRequestType = USB_H2D | USB_REQ_RECIPIENT_INTERFACE | \
USB_REQ_TYPE_CLASS;
phost->Control.setup.b.bRequest = USB_HID_SET_REPORT;
phost->Control.setup.b.wValue.w = (uint16_t)(((uint32_t)reportType << 8U) | (uint32_t)reportId);
phost->Control.setup.b.wIndex.w = 0U;
phost->Control.setup.b.wLength.w = reportLen;
return USBH_CtlReq(phost, reportBuff, (uint16_t)reportLen);
}
/**
* @brief USBH_HID_GetReport
* retrieve Set Report
* @param phost: Host handle
* @param reportType : Report type to be sent
* @param reportId : Targeted report ID for Set Report request
* @param reportBuff : Report Buffer
* @param reportLen : Length of data report to be send
* @retval USBH Status
*/
USBH_StatusTypeDef USBH_HID_GetReport(USBH_HandleTypeDef *phost,
uint8_t reportType,
uint8_t reportId,
uint8_t *reportBuff,
uint8_t reportLen)
{
phost->Control.setup.b.bmRequestType = USB_D2H | USB_REQ_RECIPIENT_INTERFACE | \
USB_REQ_TYPE_CLASS;
phost->Control.setup.b.bRequest = USB_HID_GET_REPORT;
phost->Control.setup.b.wValue.w = (uint16_t)(((uint32_t)reportType << 8U) | (uint32_t)reportId);
phost->Control.setup.b.wIndex.w = 0U;
phost->Control.setup.b.wLength.w = reportLen;
return USBH_CtlReq(phost, reportBuff, (uint16_t)reportLen);
}
/**
* @brief USBH_Set_Protocol
* Set protocol State.
* @param phost: Host handle
* @param protocol : Set Protocol for HID : boot/report protocol
* @retval USBH Status
*/
USBH_StatusTypeDef USBH_HID_SetProtocol(USBH_HandleTypeDef *phost,
uint8_t protocol)
{
phost->Control.setup.b.bmRequestType = USB_H2D | USB_REQ_RECIPIENT_INTERFACE
| USB_REQ_TYPE_CLASS;
phost->Control.setup.b.bRequest = USB_HID_SET_PROTOCOL;
if (protocol != 0U)
{
phost->Control.setup.b.wValue.w = 0U;
}
else
{
phost->Control.setup.b.wValue.w = 1U;
}
phost->Control.setup.b.wIndex.w = 0U;
phost->Control.setup.b.wLength.w = 0U;
return USBH_CtlReq(phost, NULL, 0U);
}
/**
* @brief USBH_ParseHIDDesc
* This function Parse the HID descriptor
* @param desc: HID Descriptor
* @param buf: Buffer where the source descriptor is available
* @retval None
*/
static void USBH_HID_ParseHIDDesc(HID_DescTypeDef *desc, uint8_t *buf)
{
USBH_DescHeader_t *pdesc = (USBH_DescHeader_t *)buf;
uint16_t CfgDescLen;
uint16_t ptr;
CfgDescLen = LE16(buf + 2U);
if (CfgDescLen > USB_CONFIGURATION_DESC_SIZE)
{
ptr = USB_LEN_CFG_DESC;
while (ptr < CfgDescLen)
{
pdesc = USBH_GetNextDesc((uint8_t *)pdesc, &ptr);
if (pdesc->bDescriptorType == USB_DESC_TYPE_HID)
{
desc->bLength = *(uint8_t *)((uint8_t *)pdesc + 0U);
desc->bDescriptorType = *(uint8_t *)((uint8_t *)pdesc + 1U);
desc->bcdHID = LE16((uint8_t *)pdesc + 2U);
desc->bCountryCode = *(uint8_t *)((uint8_t *)pdesc + 4U);
desc->bNumDescriptors = *(uint8_t *)((uint8_t *)pdesc + 5U);
desc->bReportDescriptorType = *(uint8_t *)((uint8_t *)pdesc + 6U);
desc->wItemLength = LE16((uint8_t *)pdesc + 7U);
break;
}
}
}
}
/**
* @brief USBH_HID_GetDeviceType
* Return Device function.
* @param phost: Host handle
* @retval HID function: HID_MOUSE / HID_KEYBOARD
*/
HID_TypeTypeDef USBH_HID_GetDeviceType(USBH_HandleTypeDef *phost)
{
HID_TypeTypeDef type = HID_UNKNOWN;
uint8_t InterfaceProtocol;
if (phost->gState == HOST_CLASS)
{
InterfaceProtocol = phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].bInterfaceProtocol;
if (InterfaceProtocol == HID_KEYBRD_BOOT_CODE)
{
type = HID_KEYBOARD;
}
else
{
if (InterfaceProtocol == HID_MOUSE_BOOT_CODE)
{
type = HID_MOUSE;
}
}
}
return type;
}
/**
* @brief USBH_HID_GetPollInterval
* Return HID device poll time
* @param phost: Host handle
* @retval poll time (ms)
*/
uint8_t USBH_HID_GetPollInterval(USBH_HandleTypeDef *phost)
{
HID_HandleTypeDef *HID_Handle = (HID_HandleTypeDef *) phost->pActiveClass->pData;
if ((phost->gState == HOST_CLASS_REQUEST) ||
(phost->gState == HOST_INPUT) ||
(phost->gState == HOST_SET_CONFIGURATION) ||
(phost->gState == HOST_CHECK_CLASS) ||
((phost->gState == HOST_CLASS)))
{
return (uint8_t)(HID_Handle->poll);
}
else
{
return 0U;
}
}
/**
* @brief USBH_HID_FifoInit
* Initialize FIFO.
* @param f: Fifo address
* @param buf: Fifo buffer
* @param size: Fifo Size
* @retval none
*/
void USBH_HID_FifoInit(FIFO_TypeDef *f, uint8_t *buf, uint16_t size)
{
f->head = 0U;
f->tail = 0U;
f->lock = 0U;
f->size = size;
f->buf = buf;
}
/**
* @brief USBH_HID_FifoRead
* Read from FIFO.
* @param f: Fifo address
* @param buf: read buffer
* @param nbytes: number of item to read
* @retval number of read items
*/
uint16_t USBH_HID_FifoRead(FIFO_TypeDef *f, void *buf, uint16_t nbytes)
{
uint16_t i;
uint8_t *p;
p = (uint8_t *) buf;
if (f->lock == 0U)
{
f->lock = 1U;
for (i = 0U; i < nbytes; i++)
{
if (f->tail != f->head)
{
*p++ = f->buf[f->tail];
f->tail++;
if (f->tail == f->size)
{
f->tail = 0U;
}
}
else
{
f->lock = 0U;
return i;
}
}
}
f->lock = 0U;
return nbytes;
}
/**
* @brief USBH_HID_FifoWrite
* Write To FIFO.
* @param f: Fifo address
* @param buf: read buffer
* @param nbytes: number of item to write
* @retval number of written items
*/
uint16_t USBH_HID_FifoWrite(FIFO_TypeDef *f, void *buf, uint16_t nbytes)
{
uint16_t i;
uint8_t *p;
p = (uint8_t *) buf;
if (f->lock == 0U)
{
f->lock = 1U;
for (i = 0U; i < nbytes; i++)
{
if (((f->head + 1U) == f->tail) ||
(((f->head + 1U) == f->size) && (f->tail == 0U)))
{
f->lock = 0U;
return i;
}
else
{
f->buf[f->head] = *p++;
f->head++;
if (f->head == f->size)
{
f->head = 0U;
}
}
}
}
f->lock = 0U;
return nbytes;
}
/**
* @brief The function is a callback about HID Data events
* @param phost: Selected device
* @retval None
*/
__weak void USBH_HID_EventCallback(USBH_HandleTypeDef *phost)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(phost);
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
@@ -0,0 +1,526 @@
/**
******************************************************************************
* @file usbh_hid_keybd.c
* @author MCD Application Team
* @brief This file is the application layer for USB Host HID Keyboard handling
* QWERTY and AZERTY Keyboard are supported as per the selection in
* usbh_hid_keybd.h
******************************************************************************
* @attention
*
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* BSPDependencies
- "stm32xxxxx_{eval}{discovery}{nucleo_144}.c"
- "stm32xxxxx_{eval}{discovery}_io.c"
- "stm32xxxxx_{eval}{discovery}{adafruit}_lcd.c"
- "stm32xxxxx_{eval}{discovery}_sdram.c"
EndBSPDependencies */
/* Includes ------------------------------------------------------------------*/
#include "usbh_hid_keybd.h"
#include "usbh_hid_parser.h"
/** @addtogroup USBH_LIB
* @{
*/
/** @addtogroup USBH_CLASS
* @{
*/
/** @addtogroup USBH_HID_CLASS
* @{
*/
/** @defgroup USBH_HID_KEYBD
* @brief This file includes HID Layer Handlers for USB Host HID class.
* @{
*/
/** @defgroup USBH_HID_KEYBD_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @defgroup USBH_HID_KEYBD_Private_Defines
* @{
*/
/**
* @}
*/
#ifndef AZERTY_KEYBOARD
#define QWERTY_KEYBOARD
#endif
#define KBD_LEFT_CTRL 0x01
#define KBD_LEFT_SHIFT 0x02
#define KBD_LEFT_ALT 0x04
#define KBD_LEFT_GUI 0x08
#define KBD_RIGHT_CTRL 0x10
#define KBD_RIGHT_SHIFT 0x20
#define KBD_RIGHT_ALT 0x40
#define KBD_RIGHT_GUI 0x80
#define KBR_MAX_NBR_PRESSED 6
/** @defgroup USBH_HID_KEYBD_Private_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBH_HID_KEYBD_Private_FunctionPrototypes
* @{
*/
static USBH_StatusTypeDef USBH_HID_KeybdDecode(USBH_HandleTypeDef *phost);
/**
* @}
*/
/** @defgroup USBH_HID_KEYBD_Private_Variables
* @{
*/
HID_KEYBD_Info_TypeDef keybd_info;
uint8_t keybd_rx_report_buf[USBH_HID_KEYBD_REPORT_SIZE];
uint8_t keybd_report_data[USBH_HID_KEYBD_REPORT_SIZE];
static const HID_Report_ItemTypedef imp_0_lctrl =
{
keybd_report_data, /*data*/
1, /*size*/
0, /*shift*/
0, /*count (only for array items)*/
0, /*signed?*/
0, /*min value read can return*/
1, /*max value read can return*/
0, /*min vale device can report*/
1, /*max value device can report*/
1 /*resolution*/
};
static const HID_Report_ItemTypedef imp_0_lshift =
{
keybd_report_data, /*data*/
1, /*size*/
1, /*shift*/
0, /*count (only for array items)*/
0, /*signed?*/
0, /*min value read can return*/
1, /*max value read can return*/
0, /*min vale device can report*/
1, /*max value device can report*/
1 /*resolution*/
};
static const HID_Report_ItemTypedef imp_0_lalt =
{
keybd_report_data, /*data*/
1, /*size*/
2, /*shift*/
0, /*count (only for array items)*/
0, /*signed?*/
0, /*min value read can return*/
1, /*max value read can return*/
0, /*min vale device can report*/
1, /*max value device can report*/
1 /*resolution*/
};
static const HID_Report_ItemTypedef imp_0_lgui =
{
keybd_report_data, /*data*/
1, /*size*/
3, /*shift*/
0, /*count (only for array items)*/
0, /*signed?*/
0, /*min value read can return*/
1, /*max value read can return*/
0, /*min vale device can report*/
1, /*max value device can report*/
1 /*resolution*/
};
static const HID_Report_ItemTypedef imp_0_rctrl =
{
keybd_report_data, /*data*/
1, /*size*/
4, /*shift*/
0, /*count (only for array items)*/
0, /*signed?*/
0, /*min value read can return*/
1, /*max value read can return*/
0, /*min vale device can report*/
1, /*max value device can report*/
1 /*resolution*/
};
static const HID_Report_ItemTypedef imp_0_rshift =
{
keybd_report_data, /*data*/
1, /*size*/
5, /*shift*/
0, /*count (only for array items)*/
0, /*signed?*/
0, /*min value read can return*/
1, /*max value read can return*/
0, /*min vale device can report*/
1, /*max value device can report*/
1 /*resolution*/
};
static const HID_Report_ItemTypedef imp_0_ralt =
{
keybd_report_data, /*data*/
1, /*size*/
6, /*shift*/
0, /*count (only for array items)*/
0, /*signed?*/
0, /*min value read can return*/
1, /*max value read can return*/
0, /*min vale device can report*/
1, /*max value device can report*/
1 /*resolution*/
};
static const HID_Report_ItemTypedef imp_0_rgui =
{
keybd_report_data, /*data*/
1, /*size*/
7, /*shift*/
0, /*count (only for array items)*/
0, /*signed?*/
0, /*min value read can return*/
1, /*max value read can return*/
0, /*min vale device can report*/
1, /*max value device can report*/
1 /*resolution*/
};
static const HID_Report_ItemTypedef imp_0_key_array =
{
keybd_report_data + 2U, /*data*/
8, /*size*/
0, /*shift*/
6, /*count (only for array items)*/
0, /*signed?*/
0, /*min value read can return*/
101, /*max value read can return*/
0, /*min vale device can report*/
101, /*max value device can report*/
1 /*resolution*/
};
#ifdef QWERTY_KEYBOARD
static const uint8_t HID_KEYBRD_Key[] =
{
/* 0 */ '\0', /* 1 */ '`', /* 2 */ '1', /* 3 */ '2',
/* 4 */ '3', /* 5 */ '4', /* 6 */ '5', /* 7 */ '6',
/* 8 */ '7', /* 9 */ '8', /* 10 */ '9', /* 11 */ '0',
/* 12 */ '-', /* 13 */ '=', /* 14 */ '\0', /* 15 */ '\b',
/* 16 */ '\t', /* 17 */ 'q', /* 18 */ 'w', /* 19 */ 'e',
/* 20 */ 'r', /* 21 */ 't', /* 22 */ 'y', /* 23 */ 'u',
/* 24 */ 'i', /* 25 */ 'o', /* 26 */ 'p', /* 27 */ '[',
/* 28 */ ']', /* 29 */ '\\', /* 30 */ '\0', /* 31 */ 'a',
/* 32 */ 's', /* 33 */ 'd', /* 34 */ 'f', /* 35 */ 'g',
/* 36 */ 'h', /* 37 */ 'j', /* 38 */ 'k', /* 39 */ 'l',
/* 40 */ ';', /* 41 */ '\'', /* 42 */ '\0', /* 43 */ '\n',
/* 44 */ '\0', /* 45 */ '\0', /* 46 */ 'z', /* 47 */ 'x',
/* 48 */ 'c', /* 49 */ 'v', /* 50 */ 'b', /* 51 */ 'n',
/* 52 */ 'm', /* 53 */ ',', /* 54 */ '.', /* 55 */ '/',
/* 56 */ '\0', /* 57 */ '\0', /* 58 */ '\0', /* 59 */ '\0',
/* 60 */ '\0', /* 61 */ ' ', /* 62 */ '\0', /* 63 */ '\0',
/* 64 */ '\0', /* 65 */ '\0', /* 66 */ '\0', /* 67 */ '\0',
/* 68 */ '\0', /* 69 */ '\0', /* 70 */ '\0', /* 71 */ '\0',
/* 72 */ '\0', /* 73 */ '\0', /* 74 */ '\0', /* 75 */ '\0',
/* 76 */ '\0', /* 77 */ '\0', /* 78 */ '\0', /* 79 */ '\0',
/* 80 */ '\r', /* 81 */ '\0', /* 82 */ '\0', /* 83 */ '\0',
/* 84 */ '\0', /* 85 */ '\0', /* 86 */ '\0', /* 87 */ '\0',
/* 88 */ '\0', /* 89 */ '\0', /* 90 */ '\0', /* 91 */ '7',
/* 92 */ '4', /* 93 */ '1', /* 94 */ '\0', /* 95 */ '/',
/* 96 */ '8', /* 97 */ '5', /* 98 */ '2', /* 99 */ '0',
/*100 */ '*', /*101 */ '9', /*102 */ '6', /*103 */ '3',
/*104 */ '.', /*105 */ '-', /*106 */ '+', /*107 */ '\0',
/*108 */ '\n', /*109 */ '\0', /*110 */ 0x1B, /*111 */ '\0',
/*112 */ '\0', /*113 */ '\0', /*114 */ '\0', /*115 */ '\0',
/*116 */ '\0', /*117 */ '\0', /*118 */ '\0', /*119 */ '\0',
/*120 */ '\0', /*121 */ '\0', /*122 */ '\0', /*123 */ '\0',
/*124 */ '\0', /*125 */ '\0', /*126 */ '\0', /*127 */ '\0',
/*128 */ '\0', /*129 */ '\0', /*130 */ '\0', /*131 */ '\0'
};
static const uint8_t HID_KEYBRD_ShiftKey[] =
{
/* 0 */ '\0', /* 1 */ '~', /* 2 */ '!', /* 3 */ '@',
/* 4 */ '#', /* 5 */ '$', /* 6 */ '%', /* 7 */ '^',
/* 8 */ '&', /* 9 */ '*', /* 10 */ '(', /* 11 */ ')',
/* 12 */ '_', /* 13 */ '+', /* 14 */ '\0', /* 15 */ '\b',
/* 16 */ '\0', /* 17 */ 'Q', /* 18 */ 'W', /* 19 */ 'E',
/* 20 */ 'R', /* 21 */ 'T', /* 22 */ 'Y', /* 23 */ 'U',
/* 24 */ 'I', /* 25 */ 'O', /* 26 */ 'P', /* 27 */ '{',
/* 28 */ '}', /* 29 */ '|', /* 30 */ '\0', /* 31 */ 'A',
/* 32 */ 'S', /* 33 */ 'D', /* 34 */ 'F', /* 35 */ 'G',
/* 36 */ 'H', /* 37 */ 'J', /* 38 */ 'K', /* 39 */ 'L',
/* 40 */ ':', /* 41 */ '"', /* 42 */ '\0', /* 43 */ '\n',
/* 44 */ '\0', /* 45 */ '\0', /* 46 */ 'Z', /* 47 */ 'X',
/* 48 */ 'C', /* 49 */ 'V', /* 50 */ 'B', /* 51 */ 'N',
/* 52 */ 'M', /* 53 */ '<', /* 54 */ '>', /* 55 */ '?',
/* 56 */ '\0', /* 57 */ '\0', /* 58 */ '\0', /* 59 */ '\0',
/* 60 */ '\0', /* 61 */ ' ', /* 62 */ '\0', /* 63 */ '\0',
/* 64 */ '\0', /* 65 */ '\0', /* 66 */ '\0', /* 67 */ '\0',
/* 68 */ '\0', /* 69 */ '\0', /* 70 */ '\0', /* 71 */ '\0',
/* 72 */ '\0', /* 73 */ '\0', /* 74 */ '\0', /* 75 */ '\0',
/* 76 */ '\0', /* 77 */ '\0', /* 78 */ '\0', /* 79 */ '\0',
/* 80 */ '\0', /* 81 */ '\0', /* 82 */ '\0', /* 83 */ '\0',
/* 84 */ '\0', /* 85 */ '\0', /* 86 */ '\0', /* 87 */ '\0',
/* 88 */ '\0', /* 89 */ '\0', /* 90 */ '\0', /* 91 */ '\0',
/* 92 */ '\0', /* 93 */ '\0', /* 94 */ '\0', /* 95 */ '/',
/* 96 */ '\0', /* 97 */ '\0', /* 98 */ '\0', /* 99 */ '\0',
/*100 */ '*', /*101 */ '\0', /*102 */ '\0', /*103 */ '\0',
/*104 */ '\0', /*105 */ '-', /*106 */ '+', /*107 */ '\0',
/*108 */ '\n', /*109 */ '\0', /*110 */ 0x1B, /*111 */ '\0',
/*112 */ '\0', /*113 */ '\0', /*114 */ '\0', /*115 */ '\0',
/*116 */ '\0', /*117 */ '\0', /*118 */ '\0', /*119 */ '\0',
/*120 */ '\0', /*121 */ '\0', /*122 */ '\0', /*123 */ '\0',
/*124 */ '\0', /*125 */ '\0', /*126 */ '\0', /*127 */ '\0',
/*128 */ '\0', /*129 */ '\0', /*130 */ '\0', /*131 */ '\0'
};
#else /* AZERTY Keyboard defined */
static const uint8_t HID_KEYBRD_Key[] =
{
/* 0 */ '\0', /* 1 */ '²', /* 2 */ '&', /* 3 */ 'é',
/* 4 */ '"', /* 5 */ '\'', /* 6 */ '(', /* 7 */ '-',
/* 8 */ 'è', /* 9 */ '_', /* 10 */ 'ç', /* 11 */ 'à',
/* 12 */ ')', /* 13 */ '=', /* 14 */ '\0', /* 15 */ '\b',
/* 16 */ '\t', /* 17 */ 'a', /* 18 */ 'z', /* 19 */ 'e',
/* 20 */ 'r', /* 21 */ 't', /* 22 */ 'y', /* 23 */ 'u',
/* 24 */ 'i', /* 25 */ 'o', /* 26 */ 'p', /* 27 */ '^',
/* 28 */ '$', /* 29 */ '\\', /* 30 */ '\0', /* 31 */ 'q',
/* 32 */ 's', /* 33 */ 'd', /* 34 */ 'f', /* 35 */ 'g',
/* 36 */ 'h', /* 37 */ 'j', /* 38 */ 'k', /* 39 */ 'l',
/* 40 */ 'm', /* 41 */ 'ù', /* 42 */ '*', /* 43 */ '\n',
/* 44 */ '\0', /* 45 */ '<', /* 46 */ 'w', /* 47 */ 'x',
/* 48 */ 'c', /* 49 */ 'v', /* 50 */ 'b', /* 51 */ 'n',
/* 52 */ ',', /* 53 */ ';', /* 54 */ ':', /* 55 */ '!',
/* 56 */ '\0', /* 57 */ '\0', /* 58 */ '\0', /* 59 */ '\0',
/* 60 */ '\0', /* 61 */ ' ', /* 62 */ '\0', /* 63 */ '\0',
/* 64 */ '\0', /* 65 */ '\0', /* 66 */ '\0', /* 67 */ '\0',
/* 68 */ '\0', /* 69 */ '\0', /* 70 */ '\0', /* 71 */ '\0',
/* 72 */ '\0', /* 73 */ '\0', /* 74 */ '\0', /* 75 */ '\0',
/* 76 */ '\0', /* 77 */ '\0', /* 78 */ '\0', /* 79 */ '\0',
/* 80 */ '\0', /* 81 */ '\0', /* 82 */ '\0', /* 83 */ '\0',
/* 84 */ '\0', /* 85 */ '\0', /* 86 */ '\0', /* 87 */ '\0',
/* 88 */ '\0', /* 89 */ '\0', /* 90 */ '\0', /* 91 */ '7',
/* 92 */ '4', /* 93 */ '1', /* 94 */ '\0', /* 95 */ '/',
/* 96 */ '8', /* 97 */ '5', /* 98 */ '2', /* 99 */ '0',
/*100 */ '*', /*101 */ '9', /*102 */ '6', /*103 */ '3',
/*104 */ '.', /*105 */ '-', /*106 */ '+', /*107 */ '\0',
/*108 */ '\n', /*109 */ '\0', /*110 */ 0x1B, /*111 */ '\0',
/*112 */ '\0', /*113 */ '\0', /*114 */ '\0', /*115 */ '\0',
/*116 */ '\0', /*117 */ '\0', /*118 */ '\0', /*119 */ '\0',
/*120 */ '\0', /*121 */ '\0', /*122 */ '\0', /*123 */ '\0',
/*124 */ '\0', /*125 */ '\0', /*126 */ '\0', /*127 */ '\0',
/*128 */ '\0', /*129 */ '\0', /*130 */ '\0', /*131 */ '\0'
};
static const uint8_t HID_KEYBRD_ShiftKey[] =
{
/* 0 */ '\0', /* 1 */ '\0', /* 2 */ '1', /* 3 */ '2',
/* 4 */ '3', /* 5 */ '4', /* 6 */ '5', /* 7 */ '6',
/* 8 */ '7', /* 9 */ '8', /* 10 */ '9', /* 11 */ '0',
/* 12 */ '°', /* 13 */ '+', /* 14 */ '\0', /* 15 */ '\b',
/* 16 */ '\t', /* 17 */ 'A', /* 18 */ 'Z', /* 19 */ 'E',
/* 20 */ 'R', /* 21 */ 'T', /* 22 */ 'Y', /* 23 */ 'U',
/* 24 */ 'I', /* 25 */ 'O', /* 26 */ 'P', /* 27 */ '¨',
/* 28 */ '£', /* 29 */ 'µ', /* 30 */ '\0', /* 31 */ 'Q',
/* 32 */ 'S', /* 33 */ 'D', /* 34 */ 'F', /* 35 */ 'G',
/* 36 */ 'H', /* 37 */ 'J', /* 38 */ 'K', /* 39 */ 'L',
/* 40 */ 'M', /* 41 */ '%', /* 42 */ 'µ', /* 43 */ '\n',
/* 44 */ '\0', /* 45 */ '>', /* 46 */ 'W', /* 47 */ 'X',
/* 48 */ 'C', /* 49 */ 'V', /* 50 */ 'B', /* 51 */ 'N',
/* 52 */ '?', /* 53 */ '.', /* 54 */ '/', /* 55 */ '§',
/* 56 */ '\0', /* 57 */ '\0', /* 58 */ '\0', /* 59 */ '\0',
/* 60 */ '\0', /* 61 */ ' ', /* 62 */ '\0', /* 63 */ '\0',
/* 64 */ '\0', /* 65 */ '\0', /* 66 */ '\0', /* 67 */ '\0',
/* 68 */ '\0', /* 69 */ '\0', /* 70 */ '\0', /* 71 */ '\0',
/* 72 */ '\0', /* 73 */ '\0', /* 74 */ '\0', /* 75 */ '\0',
/* 76 */ '\0', /* 77 */ '\0', /* 78 */ '\0', /* 79 */ '\0',
/* 80 */ '\0', /* 81 */ '\0', /* 82 */ '\0', /* 83 */ '\0',
/* 84 */ '\0', /* 85 */ '\0', /* 86 */ '\0', /* 87 */ '\0',
/* 88 */ '\0', /* 89 */ '\0', /* 90 */ '\0', /* 91 */ '7',
/* 92 */ '\0', /* 93 */ '\0', /* 94 */ '\0', /* 95 */ '/',
/* 96 */ '\0', /* 97 */ '\0', /* 98 */ '\0', /* 99 */ '\0',
/*100 */ '*', /*101 */ '\0', /*102 */ '\0', /*103 */ '\0',
/*104 */ '\0', /*105 */ '-', /*106 */ '+', /*107 */ '\0',
/*108 */ '\n', /*109 */ '\0', /*110 */ 0x1B, /*111 */ '\0',
/*112 */ '\0', /*113 */ '\0', /*114 */ '\0', /*115 */ '\0',
/*116 */ '\0', /*117 */ '\0', /*118 */ '\0', /*119 */ '\0',
/*120 */ '\0', /*121 */ '\0', /*122 */ '\0', /*123 */ '\0',
/*124 */ '\0', /*125 */ '\0', /*126 */ '\0', /*127 */ '\0',
/*128 */ '\0', /*129 */ '\0', /*130 */ '\0', /*131 */ '\0'
};
#endif
static const uint8_t HID_KEYBRD_Codes[] =
{
0, 0, 0, 0, 31, 50, 48, 33,
19, 34, 35, 36, 24, 37, 38, 39, /* 0x00 - 0x0F */
52, 51, 25, 26, 17, 20, 32, 21,
23, 49, 18, 47, 22, 46, 2, 3, /* 0x10 - 0x1F */
4, 5, 6, 7, 8, 9, 10, 11,
43, 110, 15, 16, 61, 12, 13, 27, /* 0x20 - 0x2F */
28, 29, 42, 40, 41, 1, 53, 54,
55, 30, 112, 113, 114, 115, 116, 117, /* 0x30 - 0x3F */
118, 119, 120, 121, 122, 123, 124, 125,
126, 75, 80, 85, 76, 81, 86, 89, /* 0x40 - 0x4F */
79, 84, 83, 90, 95, 100, 105, 106,
108, 93, 98, 103, 92, 97, 102, 91, /* 0x50 - 0x5F */
96, 101, 99, 104, 45, 129, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, /* 0x60 - 0x6F */
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, /* 0x70 - 0x7F */
0, 0, 0, 0, 0, 107, 0, 56,
0, 0, 0, 0, 0, 0, 0, 0, /* 0x80 - 0x8F */
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, /* 0x90 - 0x9F */
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, /* 0xA0 - 0xAF */
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, /* 0xB0 - 0xBF */
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, /* 0xC0 - 0xCF */
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, /* 0xD0 - 0xDF */
58, 44, 60, 127, 64, 57, 62, 128 /* 0xE0 - 0xE7 */
};
/**
* @brief USBH_HID_KeybdInit
* The function init the HID keyboard.
* @param phost: Host handle
* @retval USBH Status
*/
USBH_StatusTypeDef USBH_HID_KeybdInit(USBH_HandleTypeDef *phost)
{
uint32_t x;
HID_HandleTypeDef *HID_Handle = (HID_HandleTypeDef *) phost->pActiveClass->pData;
keybd_info.lctrl = 0U;
keybd_info.lshift = 0U;
keybd_info.lalt = 0U;
keybd_info.lgui = 0U;
keybd_info.rctrl = 0U;
keybd_info.rshift = 0U;
keybd_info.ralt = 0U;
keybd_info.rgui = 0U;
for (x = 0U; x < sizeof(keybd_report_data); x++)
{
keybd_report_data[x] = 0U;
keybd_rx_report_buf[x] = 0U;
}
if (HID_Handle->length > (sizeof(keybd_report_data)))
{
HID_Handle->length = (uint16_t)(sizeof(keybd_report_data));
}
HID_Handle->pData = keybd_rx_report_buf;
if ((HID_QUEUE_SIZE * sizeof(keybd_report_data)) > sizeof(phost->device.Data))
{
return USBH_FAIL;
}
else
{
USBH_HID_FifoInit(&HID_Handle->fifo, phost->device.Data, (uint16_t)(HID_QUEUE_SIZE * sizeof(keybd_report_data)));
}
return USBH_OK;
}
/**
* @brief USBH_HID_GetKeybdInfo
* The function return keyboard information.
* @param phost: Host handle
* @retval keyboard information
*/
HID_KEYBD_Info_TypeDef *USBH_HID_GetKeybdInfo(USBH_HandleTypeDef *phost)
{
if (USBH_HID_KeybdDecode(phost) == USBH_OK)
{
return &keybd_info;
}
else
{
return NULL;
}
}
/**
* @brief USBH_HID_KeybdDecode
* The function decode keyboard data.
* @param phost: Host handle
* @retval USBH Status
*/
static USBH_StatusTypeDef USBH_HID_KeybdDecode(USBH_HandleTypeDef *phost)
{
uint8_t x;
HID_HandleTypeDef *HID_Handle = (HID_HandleTypeDef *) phost->pActiveClass->pData;
if ((HID_Handle->length == 0U) || (HID_Handle->fifo.buf == NULL))
{
return USBH_FAIL;
}
/*Fill report */
if (USBH_HID_FifoRead(&HID_Handle->fifo, &keybd_report_data, HID_Handle->length) == HID_Handle->length)
{
keybd_info.lctrl = (uint8_t)HID_ReadItem((HID_Report_ItemTypedef *) &imp_0_lctrl, 0U);
keybd_info.lshift = (uint8_t)HID_ReadItem((HID_Report_ItemTypedef *) &imp_0_lshift, 0U);
keybd_info.lalt = (uint8_t)HID_ReadItem((HID_Report_ItemTypedef *) &imp_0_lalt, 0U);
keybd_info.lgui = (uint8_t)HID_ReadItem((HID_Report_ItemTypedef *) &imp_0_lgui, 0U);
keybd_info.rctrl = (uint8_t)HID_ReadItem((HID_Report_ItemTypedef *) &imp_0_rctrl, 0U);
keybd_info.rshift = (uint8_t)HID_ReadItem((HID_Report_ItemTypedef *) &imp_0_rshift, 0U);
keybd_info.ralt = (uint8_t)HID_ReadItem((HID_Report_ItemTypedef *) &imp_0_ralt, 0U);
keybd_info.rgui = (uint8_t)HID_ReadItem((HID_Report_ItemTypedef *) &imp_0_rgui, 0U);
for (x = 0U; x < sizeof(keybd_info.keys); x++)
{
keybd_info.keys[x] = (uint8_t)HID_ReadItem((HID_Report_ItemTypedef *) &imp_0_key_array, x);
}
return USBH_OK;
}
return USBH_FAIL;
}
/**
* @brief USBH_HID_GetASCIICode
* The function decode keyboard data into ASCII characters.
* @param phost: Host handle
* @param info: Keyboard information
* @retval ASCII code
*/
uint8_t USBH_HID_GetASCIICode(HID_KEYBD_Info_TypeDef *info)
{
uint8_t output;
if ((info->lshift != 0U) || (info->rshift != 0U))
{
output = HID_KEYBRD_ShiftKey[HID_KEYBRD_Codes[info->keys[0]]];
}
else
{
output = HID_KEYBRD_Key[HID_KEYBRD_Codes[info->keys[0]]];
}
return output;
}
@@ -0,0 +1,282 @@
/**
******************************************************************************
* @file usbh_hid_mouse.c
* @author MCD Application Team
* @brief This file is the application layer for USB Host HID Mouse Handling.
******************************************************************************
* @attention
*
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* BSPDependencies
- "stm32xxxxx_{eval}{discovery}{nucleo_144}.c"
- "stm32xxxxx_{eval}{discovery}_io.c"
- "stm32xxxxx_{eval}{discovery}{adafruit}_lcd.c"
- "stm32xxxxx_{eval}{discovery}_sdram.c"
EndBSPDependencies */
/* Includes ------------------------------------------------------------------*/
#include "usbh_hid_mouse.h"
#include "usbh_hid_parser.h"
/** @addtogroup USBH_LIB
* @{
*/
/** @addtogroup USBH_CLASS
* @{
*/
/** @addtogroup USBH_HID_CLASS
* @{
*/
/** @defgroup USBH_HID_MOUSE
* @brief This file includes HID Layer Handlers for USB Host HID class.
* @{
*/
/** @defgroup USBH_HID_MOUSE_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @defgroup USBH_HID_MOUSE_Private_Defines
* @{
*/
/**
* @}
*/
/** @defgroup USBH_HID_MOUSE_Private_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBH_HID_MOUSE_Private_FunctionPrototypes
* @{
*/
static USBH_StatusTypeDef USBH_HID_MouseDecode(USBH_HandleTypeDef *phost);
/**
* @}
*/
/** @defgroup USBH_HID_MOUSE_Private_Variables
* @{
*/
HID_MOUSE_Info_TypeDef mouse_info;
uint8_t mouse_report_data[USBH_HID_MOUSE_REPORT_SIZE];
uint8_t mouse_rx_report_buf[USBH_HID_MOUSE_REPORT_SIZE];
/* Structures defining how to access items in a HID mouse report */
/* Access button 1 state. */
static const HID_Report_ItemTypedef prop_b1 =
{
mouse_report_data, /*data*/
1, /*size*/
0, /*shift*/
0, /*count (only for array items)*/
0, /*signed?*/
0, /*min value read can return*/
1, /*max value read can return*/
0, /*min value device can report*/
1, /*max value device can report*/
1 /*resolution*/
};
/* Access button 2 state. */
static const HID_Report_ItemTypedef prop_b2 =
{
mouse_report_data, /*data*/
1, /*size*/
1, /*shift*/
0, /*count (only for array items)*/
0, /*signed?*/
0, /*min value read can return*/
1, /*max value read can return*/
0, /*min value device can report*/
1, /*max value device can report*/
1 /*resolution*/
};
/* Access button 3 state. */
static const HID_Report_ItemTypedef prop_b3 =
{
mouse_report_data, /*data*/
1, /*size*/
2, /*shift*/
0, /*count (only for array items)*/
0, /*signed?*/
0, /*min value read can return*/
1, /*max value read can return*/
0, /*min vale device can report*/
1, /*max value device can report*/
1 /*resolution*/
};
/* Access x coordinate change. */
static const HID_Report_ItemTypedef prop_x =
{
mouse_report_data + 1U, /*data*/
8, /*size*/
0, /*shift*/
0, /*count (only for array items)*/
1, /*signed?*/
0, /*min value read can return*/
0xFFFF,/*max value read can return*/
0, /*min vale device can report*/
0xFFFF,/*max value device can report*/
1 /*resolution*/
};
/* Access y coordinate change. */
static const HID_Report_ItemTypedef prop_y =
{
mouse_report_data + 2U, /*data*/
8, /*size*/
0, /*shift*/
0, /*count (only for array items)*/
1, /*signed?*/
0, /*min value read can return*/
0xFFFF,/*max value read can return*/
0, /*min vale device can report*/
0xFFFF,/*max value device can report*/
1 /*resolution*/
};
/**
* @}
*/
/** @defgroup USBH_HID_MOUSE_Private_Functions
* @{
*/
/**
* @brief USBH_HID_MouseInit
* The function init the HID mouse.
* @param phost: Host handle
* @retval USBH Status
*/
USBH_StatusTypeDef USBH_HID_MouseInit(USBH_HandleTypeDef *phost)
{
uint32_t i;
HID_HandleTypeDef *HID_Handle = (HID_HandleTypeDef *) phost->pActiveClass->pData;
mouse_info.x = 0U;
mouse_info.y = 0U;
mouse_info.buttons[0] = 0U;
mouse_info.buttons[1] = 0U;
mouse_info.buttons[2] = 0U;
for (i = 0U; i < sizeof(mouse_report_data); i++)
{
mouse_report_data[i] = 0U;
mouse_rx_report_buf[i] = 0U;
}
if (HID_Handle->length > sizeof(mouse_report_data))
{
HID_Handle->length = (uint16_t)sizeof(mouse_report_data);
}
HID_Handle->pData = mouse_rx_report_buf;
if ((HID_QUEUE_SIZE * sizeof(mouse_report_data)) > sizeof(phost->device.Data))
{
return USBH_FAIL;
}
else
{
USBH_HID_FifoInit(&HID_Handle->fifo, phost->device.Data, (uint16_t)(HID_QUEUE_SIZE * sizeof(mouse_report_data)));
}
return USBH_OK;
}
/**
* @brief USBH_HID_GetMouseInfo
* The function return mouse information.
* @param phost: Host handle
* @retval mouse information
*/
HID_MOUSE_Info_TypeDef *USBH_HID_GetMouseInfo(USBH_HandleTypeDef *phost)
{
if (USBH_HID_MouseDecode(phost) == USBH_OK)
{
return &mouse_info;
}
else
{
return NULL;
}
}
/**
* @brief USBH_HID_MouseDecode
* The function decode mouse data.
* @param phost: Host handle
* @retval USBH Status
*/
static USBH_StatusTypeDef USBH_HID_MouseDecode(USBH_HandleTypeDef *phost)
{
HID_HandleTypeDef *HID_Handle = (HID_HandleTypeDef *) phost->pActiveClass->pData;
if ((HID_Handle->length == 0U) || (HID_Handle->fifo.buf == NULL))
{
return USBH_FAIL;
}
/*Fill report */
if (USBH_HID_FifoRead(&HID_Handle->fifo, &mouse_report_data, HID_Handle->length) == HID_Handle->length)
{
/*Decode report */
mouse_info.x = (uint8_t)HID_ReadItem((HID_Report_ItemTypedef *) &prop_x, 0U);
mouse_info.y = (uint8_t)HID_ReadItem((HID_Report_ItemTypedef *) &prop_y, 0U);
mouse_info.buttons[0] = (uint8_t)HID_ReadItem((HID_Report_ItemTypedef *) &prop_b1, 0U);
mouse_info.buttons[1] = (uint8_t)HID_ReadItem((HID_Report_ItemTypedef *) &prop_b2, 0U);
mouse_info.buttons[2] = (uint8_t)HID_ReadItem((HID_Report_ItemTypedef *) &prop_b3, 0U);
return USBH_OK;
}
return USBH_FAIL;
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
@@ -0,0 +1,236 @@
/**
******************************************************************************
* @file usbh_hid_parser.c
* @author MCD Application Team
* @brief This file is the HID Layer Handlers for USB Host HID class.
******************************************************************************
* @attention
*
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* BSPDependencies
- "stm32xxxxx_{eval}{discovery}{nucleo_144}.c"
- "stm32xxxxx_{eval}{discovery}_io.c"
- "stm32xxxxx_{eval}{discovery}{adafruit}_lcd.c"
- "stm32xxxxx_{eval}{discovery}_sdram.c"
EndBSPDependencies */
/* Includes ------------------------------------------------------------------*/
#include "usbh_hid_parser.h"
/** @addtogroup USBH_LIB
* @{
*/
/** @addtogroup USBH_CLASS
* @{
*/
/** @addtogroup USBH_HID_CLASS
* @{
*/
/** @defgroup USBH_HID_PARSER
* @brief This file includes HID parsers for USB Host HID class.
* @{
*/
/** @defgroup USBH_HID_PARSER_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @defgroup USBH_HID_PARSER_Private_Defines
* @{
*/
/**
* @}
*/
/** @defgroup USBH_HID_PARSER_Private_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBH_HID_PARSER_Private_FunctionPrototypes
* @{
*/
/**
* @}
*/
/** @defgroup USBH_HID_PARSER_Private_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USBH_HID_PARSER_Private_Functions
* @{
*/
/**
* @brief HID_ReadItem
* The function read a report item.
* @param ri: report item
* @param ndx: report index
* @retval status (0 : fail / otherwise: item value)
*/
uint32_t HID_ReadItem(HID_Report_ItemTypedef *ri, uint8_t ndx)
{
uint32_t val = 0U;
uint32_t x = 0U;
uint32_t bofs;
uint8_t *data = ri->data;
uint8_t shift = ri->shift;
/* get the logical value of the item */
/* if this is an array, we may need to offset ri->data.*/
if (ri->count > 0U)
{
/* If app tries to read outside of the array. */
if (ri->count <= ndx)
{
return (0U);
}
/* calculate bit offset */
bofs = ndx * ri->size;
bofs += shift;
/* calculate byte offset + shift pair from bit offset. */
data += bofs / 8U;
shift = (uint8_t)(bofs % 8U);
}
/* read data bytes in little endian order */
for (x = 0U; x < (((ri->size & 0x7U) != 0U) ? ((ri->size / 8U) + 1U) : (ri->size / 8U)); x++)
{
val = (uint32_t)((uint32_t)(*data) << (x * 8U));
}
val = (val >> shift) & (((uint32_t)1U << ri->size) - 1U);
if ((val < ri->logical_min) || (val > ri->logical_max))
{
return (0U);
}
/* convert logical value to physical value */
/* See if the number is negative or not. */
if ((ri->sign != 0U) && ((val & ((uint32_t)1U << (ri->size - 1U))) != 0U))
{
/* yes, so sign extend value to 32 bits. */
uint32_t vs = (uint32_t)((0xffffffffU & ~((1U << (ri->size)) - 1U)) | val);
if (ri->resolution == 1U)
{
return ((uint32_t)vs);
}
return ((uint32_t)(vs * ri->resolution));
}
else
{
if (ri->resolution == 1U)
{
return (val);
}
return (val * ri->resolution);
}
}
/**
* @brief HID_WriteItem
* The function write a report item.
* @param ri: report item
* @param ndx: report index
* @retval status (1: fail/ 0 : Ok)
*/
uint32_t HID_WriteItem(HID_Report_ItemTypedef *ri, uint32_t value, uint8_t ndx)
{
uint32_t x;
uint32_t mask;
uint32_t bofs;
uint8_t *data = ri->data;
uint8_t shift = ri->shift;
if ((value < ri->physical_min) || (value > ri->physical_max))
{
return (1U);
}
/* if this is an array, we may need to offset ri->data.*/
if (ri->count > 0U)
{
/* If app tries to read outside of the array. */
if (ri->count >= ndx)
{
return (0U);
}
/* calculate bit offset */
bofs = ndx * ri->size;
bofs += shift;
/* calculate byte offset + shift pair from bit offset. */
data += bofs / 8U;
shift = (uint8_t)(bofs % 8U);
}
/* Convert physical value to logical value. */
if (ri->resolution != 1U)
{
value = value / ri->resolution;
}
/* Write logical value to report in little endian order. */
mask = ((uint32_t)1U << ri->size) - 1U;
value = (value & mask) << shift;
for (x = 0U; x < (((ri->size & 0x7U) != 0U) ? ((ri->size / 8U) + 1U) : (ri->size / 8U)); x++)
{
*(ri->data + x) = (uint8_t)((*(ri->data + x) & ~(mask >> (x * 8U))) |
((value >> (x * 8U)) & (mask >> (x * 8U))));
}
return 0U;
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
@@ -0,0 +1,216 @@
/**
******************************************************************************
* @file usbh_msc.h
* @author MCD Application Team
* @brief This file contains all the prototypes for the usbh_msc.c
******************************************************************************
* @attention
*
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Define to prevent recursive ----------------------------------------------*/
#ifndef __USBH_MSC_H
#define __USBH_MSC_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "usbh_core.h"
#include "usbh_msc_bot.h"
#include "usbh_msc_scsi.h"
/** @addtogroup USBH_LIB
* @{
*/
/** @addtogroup USBH_CLASS
* @{
*/
/** @addtogroup USBH_MSC_CLASS
* @{
*/
/** @defgroup USBH_MSC_CORE
* @brief This file is the Header file for usbh_msc.c
* @{
*/
/** @defgroup USBH_MSC_CORE_Exported_Types
* @{
*/
typedef enum
{
MSC_INIT = 0,
MSC_IDLE,
MSC_TEST_UNIT_READY,
MSC_READ_CAPACITY10,
MSC_READ_INQUIRY,
MSC_REQUEST_SENSE,
MSC_READ,
MSC_WRITE,
MSC_UNRECOVERED_ERROR,
MSC_PERIODIC_CHECK,
MSC_USER_NOTIFY
}
MSC_StateTypeDef;
typedef enum
{
MSC_OK,
MSC_NOT_READY,
MSC_ERROR,
}
MSC_ErrorTypeDef;
typedef enum
{
MSC_REQ_IDLE = 0,
MSC_REQ_RESET,
MSC_REQ_GET_MAX_LUN,
MSC_REQ_ERROR,
}
MSC_ReqStateTypeDef;
#ifndef MAX_SUPPORTED_LUN
#define MAX_SUPPORTED_LUN 2U
#endif
/* Structure for LUN */
typedef struct
{
MSC_StateTypeDef state;
MSC_ErrorTypeDef error;
USBH_StatusTypeDef prev_ready_state;
SCSI_CapacityTypeDef capacity;
SCSI_SenseTypeDef sense;
SCSI_StdInquiryDataTypeDef inquiry;
uint8_t state_changed;
}
MSC_LUNTypeDef;
/* Structure for MSC process */
typedef struct _MSC_Process
{
uint8_t max_lun;
uint8_t Reserved[3];
uint8_t InPipe;
uint8_t OutPipe;
uint8_t OutEp;
uint8_t InEp;
uint16_t OutEpSize;
uint16_t InEpSize;
MSC_StateTypeDef state;
MSC_ErrorTypeDef error;
MSC_ReqStateTypeDef req_state;
MSC_ReqStateTypeDef prev_req_state;
BOT_HandleTypeDef hbot;
MSC_LUNTypeDef unit[MAX_SUPPORTED_LUN];
uint16_t current_lun;
uint16_t lun;
uint16_t rw_lun;
uint32_t timer;
}
MSC_HandleTypeDef;
/**
* @}
*/
/** @defgroup USBH_MSC_CORE_Exported_Defines
* @{
*/
#define USB_REQ_BOT_RESET 0xFFU
#define USB_REQ_GET_MAX_LUN 0xFEU
/* MSC Class Codes */
#define USB_MSC_CLASS 0x08U
/* Interface Descriptor field values for HID Boot Protocol */
#define MSC_BOT 0x50U
#define MSC_TRANSPARENT 0x06U
/**
* @}
*/
/** @defgroup USBH_MSC_CORE_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBH_MSC_CORE_Exported_Variables
* @{
*/
extern USBH_ClassTypeDef USBH_msc;
#define USBH_MSC_CLASS &USBH_msc
/**
* @}
*/
/** @defgroup USBH_MSC_CORE_Exported_FunctionsPrototype
* @{
*/
uint8_t USBH_MSC_IsReady(USBH_HandleTypeDef *phost);
uint8_t USBH_MSC_GetMaxLUN(USBH_HandleTypeDef *phost);
uint8_t USBH_MSC_UnitIsReady(USBH_HandleTypeDef *phost, uint8_t lun);
USBH_StatusTypeDef USBH_MSC_GetLUNInfo(USBH_HandleTypeDef *phost, uint8_t lun,
MSC_LUNTypeDef *info);
USBH_StatusTypeDef USBH_MSC_Read(USBH_HandleTypeDef *phost, uint8_t lun,
uint32_t address, uint8_t *pbuf, uint32_t length);
USBH_StatusTypeDef USBH_MSC_Write(USBH_HandleTypeDef *phost, uint8_t lun,
uint32_t address, uint8_t *pbuf, uint32_t length);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __USBH_MSC_H */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
@@ -0,0 +1,230 @@
/**
******************************************************************************
* @file usbh_msc_bot.h
* @author MCD Application Team
* @brief Header file for usbh_msc_bot.c
******************************************************************************
* @attention
*
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Define to prevent recursive ----------------------------------------------*/
#ifndef __USBH_MSC_BOT_H
#define __USBH_MSC_BOT_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "usbh_core.h"
/** @addtogroup USBH_LIB
* @{
*/
/** @addtogroup USBH_CLASS
* @{
*/
/** @addtogroup USBH_MSC_CLASS
* @{
*/
/** @defgroup USBH_MSC_BOT
* @brief This file is the Header file for usbh_msc_bot.c
* @{
*/
/** @defgroup USBH_MSC_BOT_Exported_Types
* @{
*/
typedef enum
{
BOT_OK = 0,
BOT_FAIL = 1,
BOT_PHASE_ERROR = 2,
BOT_BUSY = 3
}
BOT_StatusTypeDef;
typedef enum
{
BOT_CMD_IDLE = 0,
BOT_CMD_SEND,
BOT_CMD_WAIT,
}
BOT_CMDStateTypeDef;
/* CSW Status Definitions */
typedef enum
{
BOT_CSW_CMD_PASSED = 0x00,
BOT_CSW_CMD_FAILED = 0x01,
BOT_CSW_PHASE_ERROR = 0x02,
}
BOT_CSWStatusTypeDef;
typedef enum
{
BOT_SEND_CBW = 1,
BOT_SEND_CBW_WAIT,
BOT_DATA_IN,
BOT_DATA_IN_WAIT,
BOT_DATA_OUT,
BOT_DATA_OUT_WAIT,
BOT_RECEIVE_CSW,
BOT_RECEIVE_CSW_WAIT,
BOT_ERROR_IN,
BOT_ERROR_OUT,
BOT_UNRECOVERED_ERROR
}
BOT_StateTypeDef;
typedef union
{
struct __CBW
{
uint32_t Signature;
uint32_t Tag;
uint32_t DataTransferLength;
uint8_t Flags;
uint8_t LUN;
uint8_t CBLength;
uint8_t CB[16];
} field;
uint8_t data[31];
}
BOT_CBWTypeDef;
typedef union
{
struct __CSW
{
uint32_t Signature;
uint32_t Tag;
uint32_t DataResidue;
uint8_t Status;
} field;
uint8_t data[13];
}
BOT_CSWTypeDef;
typedef struct
{
uint32_t data[16];
BOT_StateTypeDef state;
BOT_StateTypeDef prev_state;
BOT_CMDStateTypeDef cmd_state;
BOT_CBWTypeDef cbw;
uint8_t Reserved1;
BOT_CSWTypeDef csw;
uint8_t Reserved2[3];
uint8_t *pbuf;
}
BOT_HandleTypeDef;
/**
* @}
*/
/** @defgroup USBH_MSC_BOT_Exported_Defines
* @{
*/
#define BOT_CBW_SIGNATURE 0x43425355U
#define BOT_CBW_TAG 0x20304050U
#define BOT_CSW_SIGNATURE 0x53425355U
#define BOT_CBW_LENGTH 31U
#define BOT_CSW_LENGTH 13U
#define BOT_SEND_CSW_DISABLE 0U
#define BOT_SEND_CSW_ENABLE 1U
#define BOT_DIR_IN 0U
#define BOT_DIR_OUT 1U
#define BOT_DIR_BOTH 2U
#define BOT_PAGE_LENGTH 512U
#define BOT_CBW_CB_LENGTH 16U
#define MAX_BULK_STALL_COUNT_LIMIT 0x04U /* If STALL is seen on Bulk
Endpoint continuously, this means
that device and Host has phase error
Hence a Reset is needed */
/**
* @}
*/
/** @defgroup USBH_MSC_BOT_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBH_MSC_BOT_Exported_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USBH_MSC_BOT_Exported_FunctionsPrototype
* @{
*/
USBH_StatusTypeDef USBH_MSC_BOT_REQ_Reset(USBH_HandleTypeDef *phost);
USBH_StatusTypeDef USBH_MSC_BOT_REQ_GetMaxLUN(USBH_HandleTypeDef *phost, uint8_t *Maxlun);
USBH_StatusTypeDef USBH_MSC_BOT_Init(USBH_HandleTypeDef *phost);
USBH_StatusTypeDef USBH_MSC_BOT_Process(USBH_HandleTypeDef *phost, uint8_t lun);
USBH_StatusTypeDef USBH_MSC_BOT_Error(USBH_HandleTypeDef *phost, uint8_t lun);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __USBH_MSC_BOT_H__ */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
@@ -0,0 +1,215 @@
/**
******************************************************************************
* @file usbh_msc_scsi.h
* @author MCD Application Team
* @brief Header file for usbh_msc_scsi.c
******************************************************************************
* @attention
*
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Define to prevent recursive ----------------------------------------------*/
#ifndef __USBH_MSC_SCSI_H
#define __USBH_MSC_SCSI_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "usbh_core.h"
/** @addtogroup USBH_LIB
* @{
*/
/** @addtogroup USBH_CLASS
* @{
*/
/** @addtogroup USBH_MSC_CLASS
* @{
*/
/** @defgroup USBH_MSC_SCSI
* @brief This file is the Header file for usbh_msc_scsi.c
* @{
*/
/* Capacity data */
typedef struct
{
uint32_t block_nbr;
uint16_t block_size;
} SCSI_CapacityTypeDef;
/* Sense data */
typedef struct
{
uint8_t key;
uint8_t asc;
uint8_t ascq;
} SCSI_SenseTypeDef;
/* INQUIRY data */
typedef struct
{
uint8_t PeripheralQualifier;
uint8_t DeviceType;
uint8_t RemovableMedia;
uint8_t vendor_id[9];
uint8_t product_id[17];
uint8_t revision_id[5];
} SCSI_StdInquiryDataTypeDef;
/** @defgroup USBH_MSC_SCSI_Exported_Defines
* @{
*/
#define OPCODE_TEST_UNIT_READY 0x00U
#define OPCODE_READ_CAPACITY10 0x25U
#define OPCODE_READ10 0x28U
#define OPCODE_WRITE10 0x2AU
#define OPCODE_REQUEST_SENSE 0x03U
#define OPCODE_INQUIRY 0x12U
#define DATA_LEN_MODE_TEST_UNIT_READY 0U
#define DATA_LEN_READ_CAPACITY10 8U
#define DATA_LEN_INQUIRY 36U
#define DATA_LEN_REQUEST_SENSE 14U
#define CBW_CB_LENGTH 16U
#define CBW_LENGTH 10U
/** @defgroup USBH_MSC_SCSI_Exported_Defines
* @{
*/
#define SCSI_SENSE_KEY_NO_SENSE 0x00U
#define SCSI_SENSE_KEY_RECOVERED_ERROR 0x01U
#define SCSI_SENSE_KEY_NOT_READY 0x02U
#define SCSI_SENSE_KEY_MEDIUM_ERROR 0x03U
#define SCSI_SENSE_KEY_HARDWARE_ERROR 0x04U
#define SCSI_SENSE_KEY_ILLEGAL_REQUEST 0x05U
#define SCSI_SENSE_KEY_UNIT_ATTENTION 0x06U
#define SCSI_SENSE_KEY_DATA_PROTECT 0x07U
#define SCSI_SENSE_KEY_BLANK_CHECK 0x08U
#define SCSI_SENSE_KEY_VENDOR_SPECIFIC 0x09U
#define SCSI_SENSE_KEY_COPY_ABORTED 0x0AU
#define SCSI_SENSE_KEY_ABORTED_COMMAND 0x0BU
#define SCSI_SENSE_KEY_VOLUME_OVERFLOW 0x0DU
#define SCSI_SENSE_KEY_MISCOMPARE 0x0EU
/**
* @}
*/
/** @defgroup USBH_MSC_SCSI_Exported_Defines
* @{
*/
#define SCSI_ASC_NO_ADDITIONAL_SENSE_INFORMATION 0x00
#define SCSI_ASC_LOGICAL_UNIT_NOT_READY 0x04
#define SCSI_ASC_INVALID_FIELD_IN_CDB 0x24
#define SCSI_ASC_WRITE_PROTECTED 0x27
#define SCSI_ASC_FORMAT_ERROR 0x31
#define SCSI_ASC_INVALID_COMMAND_OPERATION_CODE 0x20
#define SCSI_ASC_NOT_READY_TO_READY_CHANGE 0x28
#define SCSI_ASC_MEDIUM_NOT_PRESENT 0x3A
/**
* @}
*/
/** @defgroup USBH_MSC_SCSI_Exported_Defines
* @{
*/
#define SCSI_ASCQ_FORMAT_COMMAND_FAILED 0x01
#define SCSI_ASCQ_INITIALIZING_COMMAND_REQUIRED 0x02
#define SCSI_ASCQ_OPERATION_IN_PROGRESS 0x07
/**
* @}
*/
/** @defgroup USBH_MSC_SCSI_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup _Exported_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USBH_MSC_SCSI_Exported_FunctionsPrototype
* @{
*/
USBH_StatusTypeDef USBH_MSC_SCSI_TestUnitReady(USBH_HandleTypeDef *phost,
uint8_t lun);
USBH_StatusTypeDef USBH_MSC_SCSI_ReadCapacity(USBH_HandleTypeDef *phost,
uint8_t lun,
SCSI_CapacityTypeDef *capacity);
USBH_StatusTypeDef USBH_MSC_SCSI_Inquiry(USBH_HandleTypeDef *phost,
uint8_t lun,
SCSI_StdInquiryDataTypeDef *inquiry);
USBH_StatusTypeDef USBH_MSC_SCSI_RequestSense(USBH_HandleTypeDef *phost,
uint8_t lun,
SCSI_SenseTypeDef *sense_data);
USBH_StatusTypeDef USBH_MSC_SCSI_Write(USBH_HandleTypeDef *phost,
uint8_t lun,
uint32_t address,
uint8_t *pbuf,
uint32_t length);
USBH_StatusTypeDef USBH_MSC_SCSI_Read(USBH_HandleTypeDef *phost,
uint8_t lun,
uint32_t address,
uint8_t *pbuf,
uint32_t length);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __USBH_MSC_SCSI_H */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
@@ -0,0 +1,869 @@
/**
******************************************************************************
* @file usbh_msc.c
* @author MCD Application Team
* @brief This file implements the MSC class driver functions
*
******************************************************************************
* @attention
*
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
* @verbatim
*
* ===================================================================
* MSC Class Description
* ===================================================================
* This module manages the MSC class V1.0 following the "Universal
* Serial Bus Mass Storage Class (MSC) Bulk-Only Transport (BOT) Version 1.0
* Sep. 31, 1999".
* This driver implements the following aspects of the specification:
* - Bulk-Only Transport protocol
* - Subclass : SCSI transparent command set (ref. SCSI Primary Commands - 3 (SPC-3))
*
* @endverbatim
*
******************************************************************************
*/
/* BSPDependencies
- "stm32xxxxx_{eval}{discovery}{nucleo_144}.c"
- "stm32xxxxx_{eval}{discovery}_io.c"
- "stm32xxxxx_{eval}{discovery}{adafruit}_lcd.c"
- "stm32xxxxx_{eval}{discovery}_sdram.c"
EndBSPDependencies */
/* Includes ------------------------------------------------------------------*/
#include "usbh_msc.h"
#include "usbh_msc_bot.h"
#include "usbh_msc_scsi.h"
/** @addtogroup USBH_LIB
* @{
*/
/** @addtogroup USBH_CLASS
* @{
*/
/** @addtogroup USBH_MSC_CLASS
* @{
*/
/** @defgroup USBH_MSC_CORE
* @brief This file includes the mass storage related functions
* @{
*/
/** @defgroup USBH_MSC_CORE_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @defgroup USBH_MSC_CORE_Private_Defines
* @{
*/
/**
* @}
*/
/** @defgroup USBH_MSC_CORE_Private_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBH_MSC_CORE_Private_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USBH_MSC_CORE_Private_FunctionPrototypes
* @{
*/
static USBH_StatusTypeDef USBH_MSC_InterfaceInit(USBH_HandleTypeDef *phost);
static USBH_StatusTypeDef USBH_MSC_InterfaceDeInit(USBH_HandleTypeDef *phost);
static USBH_StatusTypeDef USBH_MSC_Process(USBH_HandleTypeDef *phost);
static USBH_StatusTypeDef USBH_MSC_ClassRequest(USBH_HandleTypeDef *phost);
static USBH_StatusTypeDef USBH_MSC_SOFProcess(USBH_HandleTypeDef *phost);
static USBH_StatusTypeDef USBH_MSC_RdWrProcess(USBH_HandleTypeDef *phost, uint8_t lun);
USBH_ClassTypeDef USBH_msc =
{
"MSC",
USB_MSC_CLASS,
USBH_MSC_InterfaceInit,
USBH_MSC_InterfaceDeInit,
USBH_MSC_ClassRequest,
USBH_MSC_Process,
USBH_MSC_SOFProcess,
NULL,
};
/**
* @}
*/
/** @defgroup USBH_MSC_CORE_Exported_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USBH_MSC_CORE_Private_Functions
* @{
*/
/**
* @brief USBH_MSC_InterfaceInit
* The function init the MSC class.
* @param phost: Host handle
* @retval USBH Status
*/
static USBH_StatusTypeDef USBH_MSC_InterfaceInit(USBH_HandleTypeDef *phost)
{
USBH_StatusTypeDef status;
uint8_t interface;
MSC_HandleTypeDef *MSC_Handle;
interface = USBH_FindInterface(phost, phost->pActiveClass->ClassCode, MSC_TRANSPARENT, MSC_BOT);
if ((interface == 0xFFU) || (interface >= USBH_MAX_NUM_INTERFACES)) /* Not Valid Interface */
{
USBH_DbgLog("Cannot Find the interface for %s class.", phost->pActiveClass->Name);
return USBH_FAIL;
}
status = USBH_SelectInterface(phost, interface);
if (status != USBH_OK)
{
return USBH_FAIL;
}
phost->pActiveClass->pData = (MSC_HandleTypeDef *)USBH_malloc(sizeof(MSC_HandleTypeDef));
MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
if (MSC_Handle == NULL)
{
USBH_DbgLog("Cannot allocate memory for MSC Handle");
return USBH_FAIL;
}
/* Initialize msc handler */
(void)USBH_memset(MSC_Handle, 0, sizeof(MSC_HandleTypeDef));
if ((phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[0].bEndpointAddress & 0x80U) != 0U)
{
MSC_Handle->InEp = (phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[0].bEndpointAddress);
MSC_Handle->InEpSize = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[0].wMaxPacketSize;
}
else
{
MSC_Handle->OutEp = (phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[0].bEndpointAddress);
MSC_Handle->OutEpSize = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[0].wMaxPacketSize;
}
if ((phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[1].bEndpointAddress & 0x80U) != 0U)
{
MSC_Handle->InEp = (phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[1].bEndpointAddress);
MSC_Handle->InEpSize = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[1].wMaxPacketSize;
}
else
{
MSC_Handle->OutEp = (phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[1].bEndpointAddress);
MSC_Handle->OutEpSize = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[1].wMaxPacketSize;
}
MSC_Handle->state = MSC_INIT;
MSC_Handle->error = MSC_OK;
MSC_Handle->req_state = MSC_REQ_IDLE;
MSC_Handle->OutPipe = USBH_AllocPipe(phost, MSC_Handle->OutEp);
MSC_Handle->InPipe = USBH_AllocPipe(phost, MSC_Handle->InEp);
(void)USBH_MSC_BOT_Init(phost);
/* Open the new channels */
if ((MSC_Handle->OutEp != 0U) && (MSC_Handle->OutEpSize != 0U))
{
(void)USBH_OpenPipe(phost, MSC_Handle->OutPipe, MSC_Handle->OutEp,
phost->device.address, phost->device.speed,
USB_EP_TYPE_BULK, MSC_Handle->OutEpSize);
}
else
{
return USBH_NOT_SUPPORTED;
}
if ((MSC_Handle->InEp != 0U) && (MSC_Handle->InEpSize != 0U))
{
(void)USBH_OpenPipe(phost, MSC_Handle->InPipe, MSC_Handle->InEp,
phost->device.address, phost->device.speed, USB_EP_TYPE_BULK,
MSC_Handle->InEpSize);
}
else
{
return USBH_NOT_SUPPORTED;
}
(void)USBH_LL_SetToggle(phost, MSC_Handle->InPipe, 0U);
(void)USBH_LL_SetToggle(phost, MSC_Handle->OutPipe, 0U);
return USBH_OK;
}
/**
* @brief USBH_MSC_InterfaceDeInit
* The function DeInit the Pipes used for the MSC class.
* @param phost: Host handle
* @retval USBH Status
*/
static USBH_StatusTypeDef USBH_MSC_InterfaceDeInit(USBH_HandleTypeDef *phost)
{
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
if ((MSC_Handle->OutPipe) != 0U)
{
(void)USBH_ClosePipe(phost, MSC_Handle->OutPipe);
(void)USBH_FreePipe(phost, MSC_Handle->OutPipe);
MSC_Handle->OutPipe = 0U; /* Reset the Channel as Free */
}
if ((MSC_Handle->InPipe != 0U))
{
(void)USBH_ClosePipe(phost, MSC_Handle->InPipe);
(void)USBH_FreePipe(phost, MSC_Handle->InPipe);
MSC_Handle->InPipe = 0U; /* Reset the Channel as Free */
}
if ((phost->pActiveClass->pData) != NULL)
{
USBH_free(phost->pActiveClass->pData);
phost->pActiveClass->pData = 0U;
}
return USBH_OK;
}
/**
* @brief USBH_MSC_ClassRequest
* The function is responsible for handling Standard requests
* for MSC class.
* @param phost: Host handle
* @retval USBH Status
*/
static USBH_StatusTypeDef USBH_MSC_ClassRequest(USBH_HandleTypeDef *phost)
{
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
USBH_StatusTypeDef status = USBH_BUSY;
uint8_t lun_idx;
/* Switch MSC REQ state machine */
switch (MSC_Handle->req_state)
{
case MSC_REQ_IDLE:
case MSC_REQ_GET_MAX_LUN:
/* Issue GetMaxLUN request */
status = USBH_MSC_BOT_REQ_GetMaxLUN(phost, &MSC_Handle->max_lun);
/* When devices do not support the GetMaxLun request, this should
be considered as only one logical unit is supported */
if (status == USBH_NOT_SUPPORTED)
{
MSC_Handle->max_lun = 0U;
status = USBH_OK;
}
if (status == USBH_OK)
{
MSC_Handle->max_lun = (MSC_Handle->max_lun > MAX_SUPPORTED_LUN) ? MAX_SUPPORTED_LUN : (MSC_Handle->max_lun + 1U);
USBH_UsrLog("Number of supported LUN: %d", MSC_Handle->max_lun);
for (lun_idx = 0U; lun_idx < MSC_Handle->max_lun; lun_idx++)
{
MSC_Handle->unit[lun_idx].prev_ready_state = USBH_FAIL;
MSC_Handle->unit[lun_idx].state_changed = 0U;
}
}
break;
case MSC_REQ_ERROR:
/* a Clear Feature should be issued here */
if (USBH_ClrFeature(phost, 0x00U) == USBH_OK)
{
MSC_Handle->req_state = MSC_Handle->prev_req_state;
}
break;
default:
break;
}
return status;
}
/**
* @brief USBH_MSC_Process
* The function is for managing state machine for MSC data transfers
* @param phost: Host handle
* @retval USBH Status
*/
static USBH_StatusTypeDef USBH_MSC_Process(USBH_HandleTypeDef *phost)
{
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
USBH_StatusTypeDef error = USBH_BUSY;
USBH_StatusTypeDef scsi_status = USBH_BUSY;
USBH_StatusTypeDef ready_status = USBH_BUSY;
switch (MSC_Handle->state)
{
case MSC_INIT:
if (MSC_Handle->current_lun < MSC_Handle->max_lun)
{
MSC_Handle->unit[MSC_Handle->current_lun].error = MSC_NOT_READY;
/* Switch MSC REQ state machine */
switch (MSC_Handle->unit[MSC_Handle->current_lun].state)
{
case MSC_INIT:
USBH_UsrLog("LUN #%d: ", MSC_Handle->current_lun);
MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_READ_INQUIRY;
MSC_Handle->timer = phost->Timer;
break;
case MSC_READ_INQUIRY:
scsi_status = USBH_MSC_SCSI_Inquiry(phost, (uint8_t)MSC_Handle->current_lun, &MSC_Handle->unit[MSC_Handle->current_lun].inquiry);
if (scsi_status == USBH_OK)
{
USBH_UsrLog("Inquiry Vendor : %s", MSC_Handle->unit[MSC_Handle->current_lun].inquiry.vendor_id);
USBH_UsrLog("Inquiry Product : %s", MSC_Handle->unit[MSC_Handle->current_lun].inquiry.product_id);
USBH_UsrLog("Inquiry Version : %s", MSC_Handle->unit[MSC_Handle->current_lun].inquiry.revision_id);
MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_TEST_UNIT_READY;
}
else if (scsi_status == USBH_FAIL)
{
MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_REQUEST_SENSE;
}
else
{
if (scsi_status == USBH_UNRECOVERED_ERROR)
{
MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_UNRECOVERED_ERROR;
MSC_Handle->unit[MSC_Handle->current_lun].error = MSC_ERROR;
}
}
break;
case MSC_TEST_UNIT_READY:
ready_status = USBH_MSC_SCSI_TestUnitReady(phost, (uint8_t)MSC_Handle->current_lun);
if (ready_status == USBH_OK)
{
if (MSC_Handle->unit[MSC_Handle->current_lun].prev_ready_state != USBH_OK)
{
MSC_Handle->unit[MSC_Handle->current_lun].state_changed = 1U;
USBH_UsrLog("MSC Device ready");
}
else
{
MSC_Handle->unit[MSC_Handle->current_lun].state_changed = 0U;
}
MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_READ_CAPACITY10;
MSC_Handle->unit[MSC_Handle->current_lun].error = MSC_OK;
MSC_Handle->unit[MSC_Handle->current_lun].prev_ready_state = USBH_OK;
}
else if (ready_status == USBH_FAIL)
{
/* Media not ready, so try to check again during 10s */
if (MSC_Handle->unit[MSC_Handle->current_lun].prev_ready_state != USBH_FAIL)
{
MSC_Handle->unit[MSC_Handle->current_lun].state_changed = 1U;
USBH_UsrLog("MSC Device NOT ready");
}
else
{
MSC_Handle->unit[MSC_Handle->current_lun].state_changed = 0U;
}
MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_REQUEST_SENSE;
MSC_Handle->unit[MSC_Handle->current_lun].error = MSC_NOT_READY;
MSC_Handle->unit[MSC_Handle->current_lun].prev_ready_state = USBH_FAIL;
}
else
{
if (ready_status == USBH_UNRECOVERED_ERROR)
{
MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_UNRECOVERED_ERROR;
MSC_Handle->unit[MSC_Handle->current_lun].error = MSC_ERROR;
}
}
break;
case MSC_READ_CAPACITY10:
scsi_status = USBH_MSC_SCSI_ReadCapacity(phost, (uint8_t)MSC_Handle->current_lun, &MSC_Handle->unit[MSC_Handle->current_lun].capacity);
if (scsi_status == USBH_OK)
{
if (MSC_Handle->unit[MSC_Handle->current_lun].state_changed == 1U)
{
USBH_UsrLog("MSC Device capacity : %u Bytes", \
(unsigned int)(MSC_Handle->unit[MSC_Handle->current_lun].capacity.block_nbr *
MSC_Handle->unit[MSC_Handle->current_lun].capacity.block_size));
USBH_UsrLog("Block number : %u", (unsigned int)(MSC_Handle->unit[MSC_Handle->current_lun].capacity.block_nbr));
USBH_UsrLog("Block Size : %u", (unsigned int)(MSC_Handle->unit[MSC_Handle->current_lun].capacity.block_size));
}
MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_IDLE;
MSC_Handle->unit[MSC_Handle->current_lun].error = MSC_OK;
MSC_Handle->current_lun++;
}
else if (scsi_status == USBH_FAIL)
{
MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_REQUEST_SENSE;
}
else
{
if (scsi_status == USBH_UNRECOVERED_ERROR)
{
MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_UNRECOVERED_ERROR;
MSC_Handle->unit[MSC_Handle->current_lun].error = MSC_ERROR;
}
}
break;
case MSC_REQUEST_SENSE:
scsi_status = USBH_MSC_SCSI_RequestSense(phost, (uint8_t)MSC_Handle->current_lun, &MSC_Handle->unit[MSC_Handle->current_lun].sense);
if (scsi_status == USBH_OK)
{
if ((MSC_Handle->unit[MSC_Handle->current_lun].sense.key == SCSI_SENSE_KEY_UNIT_ATTENTION) ||
(MSC_Handle->unit[MSC_Handle->current_lun].sense.key == SCSI_SENSE_KEY_NOT_READY))
{
if ((phost->Timer - MSC_Handle->timer) < 10000U)
{
MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_TEST_UNIT_READY;
break;
}
}
USBH_UsrLog("Sense Key : %x", MSC_Handle->unit[MSC_Handle->current_lun].sense.key);
USBH_UsrLog("Additional Sense Code : %x", MSC_Handle->unit[MSC_Handle->current_lun].sense.asc);
USBH_UsrLog("Additional Sense Code Qualifier: %x", MSC_Handle->unit[MSC_Handle->current_lun].sense.ascq);
MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_IDLE;
MSC_Handle->current_lun++;
}
else if (scsi_status == USBH_FAIL)
{
USBH_UsrLog("MSC Device NOT ready");
MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_UNRECOVERED_ERROR;
MSC_Handle->unit[MSC_Handle->current_lun].error = MSC_ERROR;
}
else
{
if (scsi_status == USBH_UNRECOVERED_ERROR)
{
MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_UNRECOVERED_ERROR;
MSC_Handle->unit[MSC_Handle->current_lun].error = MSC_ERROR;
}
}
break;
case MSC_UNRECOVERED_ERROR:
MSC_Handle->current_lun++;
break;
default:
break;
}
#if (USBH_USE_OS == 1U)
USBH_OS_PutMessage(phost, USBH_CLASS_EVENT, 0U, 0U);
#endif /* (USBH_USE_OS == 1U) */
}
else
{
MSC_Handle->current_lun = 0U;
MSC_Handle->state = MSC_USER_NOTIFY;
#if (USBH_USE_OS == 1U)
USBH_OS_PutMessage(phost, USBH_CLASS_EVENT, 0U, 0U);
#endif /* (USBH_USE_OS == 1U) */
}
break;
case MSC_USER_NOTIFY:
if (MSC_Handle->lun < MSC_Handle->max_lun)
{
MSC_Handle->current_lun = MSC_Handle->lun;
if (MSC_Handle->unit[MSC_Handle->current_lun].error == MSC_OK)
{
phost->pUser(phost, HOST_USER_CLASS_ACTIVE);
}
else
{
phost->pUser(phost, HOST_USER_UNRECOVERED_ERROR);
}
MSC_Handle->lun++;
}
else
{
MSC_Handle->lun = 0U;
MSC_Handle->state = MSC_IDLE;
}
#if (USBH_USE_OS == 1U)
USBH_OS_PutMessage(phost, USBH_CLASS_EVENT, 0U, 0U);
#endif /* (USBH_USE_OS == 1U) */
break;
case MSC_IDLE:
error = USBH_OK;
break;
default:
break;
}
return error;
}
/**
* @brief USBH_MSC_SOFProcess
* The function is for SOF state
* @param phost: Host handle
* @retval USBH Status
*/
static USBH_StatusTypeDef USBH_MSC_SOFProcess(USBH_HandleTypeDef *phost)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(phost);
return USBH_OK;
}
/**
* @brief USBH_MSC_RdWrProcess
* The function is for managing state machine for MSC I/O Process
* @param phost: Host handle
* @param lun: logical Unit Number
* @retval USBH Status
*/
static USBH_StatusTypeDef USBH_MSC_RdWrProcess(USBH_HandleTypeDef *phost, uint8_t lun)
{
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
USBH_StatusTypeDef error = USBH_BUSY;
USBH_StatusTypeDef scsi_status = USBH_BUSY;
/* Switch MSC REQ state machine */
switch (MSC_Handle->unit[lun].state)
{
case MSC_READ:
scsi_status = USBH_MSC_SCSI_Read(phost, lun, 0U, NULL, 0U);
if (scsi_status == USBH_OK)
{
MSC_Handle->unit[lun].state = MSC_IDLE;
error = USBH_OK;
}
else if (scsi_status == USBH_FAIL)
{
MSC_Handle->unit[lun].state = MSC_REQUEST_SENSE;
}
else
{
if (scsi_status == USBH_UNRECOVERED_ERROR)
{
MSC_Handle->unit[lun].state = MSC_UNRECOVERED_ERROR;
error = USBH_FAIL;
}
}
#if (USBH_USE_OS == 1U)
USBH_OS_PutMessage(phost, USBH_CLASS_EVENT, 0U, 0U);
#endif /* (USBH_USE_OS == 1U) */
break;
case MSC_WRITE:
scsi_status = USBH_MSC_SCSI_Write(phost, lun, 0U, NULL, 0U);
if (scsi_status == USBH_OK)
{
MSC_Handle->unit[lun].state = MSC_IDLE;
error = USBH_OK;
}
else if (scsi_status == USBH_FAIL)
{
MSC_Handle->unit[lun].state = MSC_REQUEST_SENSE;
}
else
{
if (scsi_status == USBH_UNRECOVERED_ERROR)
{
MSC_Handle->unit[lun].state = MSC_UNRECOVERED_ERROR;
error = USBH_FAIL;
}
}
#if (USBH_USE_OS == 1U)
USBH_OS_PutMessage(phost, USBH_CLASS_EVENT, 0U, 0U);
#endif /* (USBH_USE_OS == 1U) */
break;
case MSC_REQUEST_SENSE:
scsi_status = USBH_MSC_SCSI_RequestSense(phost, lun, &MSC_Handle->unit[lun].sense);
if (scsi_status == USBH_OK)
{
USBH_UsrLog("Sense Key : %x", MSC_Handle->unit[lun].sense.key);
USBH_UsrLog("Additional Sense Code : %x", MSC_Handle->unit[lun].sense.asc);
USBH_UsrLog("Additional Sense Code Qualifier: %x", MSC_Handle->unit[lun].sense.ascq);
MSC_Handle->unit[lun].state = MSC_IDLE;
MSC_Handle->unit[lun].error = MSC_ERROR;
error = USBH_FAIL;
}
else if (scsi_status == USBH_FAIL)
{
USBH_UsrLog("MSC Device NOT ready");
}
else
{
if (scsi_status == USBH_UNRECOVERED_ERROR)
{
MSC_Handle->unit[lun].state = MSC_UNRECOVERED_ERROR;
error = USBH_FAIL;
}
}
#if (USBH_USE_OS == 1U)
USBH_OS_PutMessage(phost, USBH_CLASS_EVENT, 0U, 0U);
#endif /* (USBH_USE_OS == 1U) */
break;
default:
break;
}
return error;
}
/**
* @brief USBH_MSC_IsReady
* The function check if the MSC function is ready
* @param phost: Host handle
* @retval USBH Status
*/
uint8_t USBH_MSC_IsReady(USBH_HandleTypeDef *phost)
{
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
uint8_t res;
if ((phost->gState == HOST_CLASS) && (MSC_Handle->state == MSC_IDLE))
{
res = 1U;
}
else
{
res = 0U;
}
return res;
}
/**
* @brief USBH_MSC_GetMaxLUN
* The function return the Max LUN supported
* @param phost: Host handle
* @retval logical Unit Number supported
*/
uint8_t USBH_MSC_GetMaxLUN(USBH_HandleTypeDef *phost)
{
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
if ((phost->gState == HOST_CLASS) && (MSC_Handle->state == MSC_IDLE))
{
return (uint8_t)MSC_Handle->max_lun;
}
return 0xFFU;
}
/**
* @brief USBH_MSC_UnitIsReady
* The function check whether a LUN is ready
* @param phost: Host handle
* @param lun: logical Unit Number
* @retval Lun status (0: not ready / 1: ready)
*/
uint8_t USBH_MSC_UnitIsReady(USBH_HandleTypeDef *phost, uint8_t lun)
{
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
uint8_t res;
/* Store the current lun */
MSC_Handle->current_lun = lun;
if ((phost->gState == HOST_CLASS) && (MSC_Handle->unit[lun].error == MSC_OK))
{
res = 1U;
}
else
{
res = 0U;
}
return res;
}
/**
* @brief USBH_MSC_GetLUNInfo
* The function return a LUN information
* @param phost: Host handle
* @param lun: logical Unit Number
* @retval USBH Status
*/
USBH_StatusTypeDef USBH_MSC_GetLUNInfo(USBH_HandleTypeDef *phost, uint8_t lun, MSC_LUNTypeDef *info)
{
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
/* Store the current lun */
MSC_Handle->current_lun = lun;
if (phost->gState == HOST_CLASS)
{
(void)USBH_memcpy(info, &MSC_Handle->unit[lun], sizeof(MSC_LUNTypeDef));
return USBH_OK;
}
else
{
return USBH_FAIL;
}
}
/**
* @brief USBH_MSC_Read
* The function performs a Read operation
* @param phost: Host handle
* @param lun: logical Unit Number
* @param address: sector address
* @param pbuf: pointer to data
* @param length: number of sector to read
* @retval USBH Status
*/
USBH_StatusTypeDef USBH_MSC_Read(USBH_HandleTypeDef *phost,
uint8_t lun,
uint32_t address,
uint8_t *pbuf,
uint32_t length)
{
uint32_t timeout;
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
/* Store the current lun */
MSC_Handle->current_lun = lun;
if ((phost->device.PortEnabled == 0U) ||
(phost->gState != HOST_CLASS) ||
(MSC_Handle->unit[lun].state != MSC_IDLE))
{
return USBH_FAIL;
}
MSC_Handle->unit[lun].state = MSC_READ;
(void)USBH_MSC_SCSI_Read(phost, lun, address, pbuf, length);
timeout = phost->Timer;
while (USBH_MSC_RdWrProcess(phost, lun) == USBH_BUSY)
{
if (((phost->Timer - timeout) > (10000U * length)) || (phost->device.PortEnabled == 0U))
{
return USBH_FAIL;
}
}
return USBH_OK;
}
/**
* @brief USBH_MSC_Write
* The function performs a Write operation
* @param phost: Host handle
* @param lun: logical Unit Number
* @param address: sector address
* @param pbuf: pointer to data
* @param length: number of sector to write
* @retval USBH Status
*/
USBH_StatusTypeDef USBH_MSC_Write(USBH_HandleTypeDef *phost,
uint8_t lun,
uint32_t address,
uint8_t *pbuf,
uint32_t length)
{
uint32_t timeout;
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
/* Store the current lun */
MSC_Handle->current_lun = lun;
if ((phost->device.PortEnabled == 0U) ||
(phost->gState != HOST_CLASS) ||
(MSC_Handle->unit[lun].state != MSC_IDLE))
{
return USBH_FAIL;
}
MSC_Handle->unit[lun].state = MSC_WRITE;
(void)USBH_MSC_SCSI_Write(phost, lun, address, pbuf, length);
timeout = phost->Timer;
while (USBH_MSC_RdWrProcess(phost, lun) == USBH_BUSY)
{
if (((phost->Timer - timeout) > (10000U * length)) || (phost->device.PortEnabled == 0U))
{
return USBH_FAIL;
}
}
return USBH_OK;
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
@@ -0,0 +1,687 @@
/**
******************************************************************************
* @file usbh_msc_bot.c
* @author MCD Application Team
* @brief This file includes the BOT protocol related functions
******************************************************************************
* @attention
*
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* BSPDependencies
- "stm32xxxxx_{eval}{discovery}{nucleo_144}.c"
- "stm32xxxxx_{eval}{discovery}_io.c"
- "stm32xxxxx_{eval}{discovery}{adafruit}_lcd.c"
- "stm32xxxxx_{eval}{discovery}_sdram.c"
EndBSPDependencies */
/* Includes ------------------------------------------------------------------*/
#include "usbh_msc_bot.h"
#include "usbh_msc.h"
/** @addtogroup USBH_LIB
* @{
*/
/** @addtogroup USBH_CLASS
* @{
*/
/** @addtogroup USBH_MSC_CLASS
* @{
*/
/** @defgroup USBH_MSC_BOT
* @brief This file includes the mass storage related functions
* @{
*/
/** @defgroup USBH_MSC_BOT_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @defgroup USBH_MSC_BOT_Private_Defines
* @{
*/
/**
* @}
*/
/** @defgroup USBH_MSC_BOT_Private_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBH_MSC_BOT_Private_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USBH_MSC_BOT_Private_FunctionPrototypes
* @{
*/
static USBH_StatusTypeDef USBH_MSC_BOT_Abort(USBH_HandleTypeDef *phost, uint8_t lun, uint8_t dir);
static BOT_CSWStatusTypeDef USBH_MSC_DecodeCSW(USBH_HandleTypeDef *phost);
/**
* @}
*/
/** @defgroup USBH_MSC_BOT_Exported_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USBH_MSC_BOT_Private_Functions
* @{
*/
/**
* @brief USBH_MSC_BOT_REQ_Reset
* The function the MSC BOT Reset request.
* @param phost: Host handle
* @retval USBH Status
*/
USBH_StatusTypeDef USBH_MSC_BOT_REQ_Reset(USBH_HandleTypeDef *phost)
{
phost->Control.setup.b.bmRequestType = USB_H2D | USB_REQ_TYPE_CLASS
| USB_REQ_RECIPIENT_INTERFACE;
phost->Control.setup.b.bRequest = USB_REQ_BOT_RESET;
phost->Control.setup.b.wValue.w = 0U;
phost->Control.setup.b.wIndex.w = 0U;
phost->Control.setup.b.wLength.w = 0U;
return USBH_CtlReq(phost, NULL, 0U);
}
/**
* @brief USBH_MSC_BOT_REQ_GetMaxLUN
* The function the MSC BOT GetMaxLUN request.
* @param phost: Host handle
* @param Maxlun: pointer to Maxlun variable
* @retval USBH Status
*/
USBH_StatusTypeDef USBH_MSC_BOT_REQ_GetMaxLUN(USBH_HandleTypeDef *phost, uint8_t *Maxlun)
{
phost->Control.setup.b.bmRequestType = USB_D2H | USB_REQ_TYPE_CLASS
| USB_REQ_RECIPIENT_INTERFACE;
phost->Control.setup.b.bRequest = USB_REQ_GET_MAX_LUN;
phost->Control.setup.b.wValue.w = 0U;
phost->Control.setup.b.wIndex.w = 0U;
phost->Control.setup.b.wLength.w = 1U;
return USBH_CtlReq(phost, Maxlun, 1U);
}
/**
* @brief USBH_MSC_BOT_Init
* The function Initializes the BOT protocol.
* @param phost: Host handle
* @retval USBH Status
*/
USBH_StatusTypeDef USBH_MSC_BOT_Init(USBH_HandleTypeDef *phost)
{
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
MSC_Handle->hbot.cbw.field.Signature = BOT_CBW_SIGNATURE;
MSC_Handle->hbot.cbw.field.Tag = BOT_CBW_TAG;
MSC_Handle->hbot.state = BOT_SEND_CBW;
MSC_Handle->hbot.cmd_state = BOT_CMD_SEND;
return USBH_OK;
}
/**
* @brief USBH_MSC_BOT_Process
* The function handle the BOT protocol.
* @param phost: Host handle
* @param lun: Logical Unit Number
* @retval USBH Status
*/
USBH_StatusTypeDef USBH_MSC_BOT_Process(USBH_HandleTypeDef *phost, uint8_t lun)
{
USBH_StatusTypeDef status = USBH_BUSY;
USBH_StatusTypeDef error = USBH_BUSY;
BOT_CSWStatusTypeDef CSW_Status = BOT_CSW_CMD_FAILED;
USBH_URBStateTypeDef URB_Status = USBH_URB_IDLE;
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
uint8_t toggle = 0U;
switch (MSC_Handle->hbot.state)
{
case BOT_SEND_CBW:
MSC_Handle->hbot.cbw.field.LUN = lun;
MSC_Handle->hbot.state = BOT_SEND_CBW_WAIT;
(void)USBH_BulkSendData(phost, MSC_Handle->hbot.cbw.data,
BOT_CBW_LENGTH, MSC_Handle->OutPipe, 1U);
break;
case BOT_SEND_CBW_WAIT:
URB_Status = USBH_LL_GetURBState(phost, MSC_Handle->OutPipe);
if (URB_Status == USBH_URB_DONE)
{
if (MSC_Handle->hbot.cbw.field.DataTransferLength != 0U)
{
/* If there is Data Transfer Stage */
if (((MSC_Handle->hbot.cbw.field.Flags) & USB_REQ_DIR_MASK) == USB_D2H)
{
/* Data Direction is IN */
MSC_Handle->hbot.state = BOT_DATA_IN;
}
else
{
/* Data Direction is OUT */
MSC_Handle->hbot.state = BOT_DATA_OUT;
}
}
else
{
/* If there is NO Data Transfer Stage */
MSC_Handle->hbot.state = BOT_RECEIVE_CSW;
}
#if (USBH_USE_OS == 1U)
USBH_OS_PutMessage(phost, USBH_URB_EVENT, 0U, 0U);
#endif /* (USBH_USE_OS == 1U) */
}
else if (URB_Status == USBH_URB_NOTREADY)
{
/* Re-send CBW */
MSC_Handle->hbot.state = BOT_SEND_CBW;
#if (USBH_USE_OS == 1U)
USBH_OS_PutMessage(phost, USBH_URB_EVENT, 0U, 0U);
#endif /* (USBH_USE_OS == 1U) */
}
else
{
if (URB_Status == USBH_URB_STALL)
{
MSC_Handle->hbot.state = BOT_ERROR_OUT;
#if (USBH_USE_OS == 1U)
USBH_OS_PutMessage(phost, USBH_URB_EVENT, 0U, 0U);
#endif /* (USBH_USE_OS == 1U) */
}
}
break;
case BOT_DATA_IN:
/* Send first packet */
(void)USBH_BulkReceiveData(phost, MSC_Handle->hbot.pbuf,
MSC_Handle->InEpSize, MSC_Handle->InPipe);
#if defined (USBH_IN_NAK_PROCESS) && (USBH_IN_NAK_PROCESS == 1U)
phost->NakTimer = phost->Timer;
#endif /* defined (USBH_IN_NAK_PROCESS) && (USBH_IN_NAK_PROCESS == 1U) */
MSC_Handle->hbot.state = BOT_DATA_IN_WAIT;
break;
case BOT_DATA_IN_WAIT:
URB_Status = USBH_LL_GetURBState(phost, MSC_Handle->InPipe);
if (URB_Status == USBH_URB_DONE)
{
/* Adjust Data pointer and data length */
if (MSC_Handle->hbot.cbw.field.DataTransferLength > MSC_Handle->InEpSize)
{
MSC_Handle->hbot.pbuf += MSC_Handle->InEpSize;
MSC_Handle->hbot.cbw.field.DataTransferLength -= MSC_Handle->InEpSize;
}
else
{
MSC_Handle->hbot.cbw.field.DataTransferLength = 0U;
}
/* More Data To be Received */
if (MSC_Handle->hbot.cbw.field.DataTransferLength > 0U)
{
/* Send next packet */
(void)USBH_BulkReceiveData(phost, MSC_Handle->hbot.pbuf,
MSC_Handle->InEpSize, MSC_Handle->InPipe);
#if defined (USBH_IN_NAK_PROCESS) && (USBH_IN_NAK_PROCESS == 1U)
phost->NakTimer = phost->Timer;
#endif /* defined (USBH_IN_NAK_PROCESS) && (USBH_IN_NAK_PROCESS == 1U) */
}
else
{
/* If value was 0, and successful transfer, then change the state */
MSC_Handle->hbot.state = BOT_RECEIVE_CSW;
#if (USBH_USE_OS == 1U)
USBH_OS_PutMessage(phost, USBH_URB_EVENT, 0U, 0U);
#endif /* (USBH_USE_OS == 1U) */
}
}
#if defined (USBH_IN_NAK_PROCESS) && (USBH_IN_NAK_PROCESS == 1U)
else if (URB_Status == USBH_URB_NAK_WAIT)
{
MSC_Handle->hbot.state = BOT_DATA_IN_WAIT;
if ((phost->Timer - phost->NakTimer) > phost->NakTimeout)
{
phost->NakTimer = phost->Timer;
USBH_ActivatePipe(phost, MSC_Handle->InPipe);
}
#if (USBH_USE_OS == 1U)
USBH_OS_PutMessage(phost, USBH_URB_EVENT, 0U, 0U);
#endif /* (USBH_USE_OS == 1U) */
}
#endif /* defined (USBH_IN_NAK_PROCESS) && (USBH_IN_NAK_PROCESS == 1U) */
else if (URB_Status == USBH_URB_STALL)
{
/* This is Data IN Stage STALL Condition */
MSC_Handle->hbot.state = BOT_ERROR_IN;
/* Refer to USB Mass-Storage Class : BOT (www.usb.org)
6.7.2 Host expects to receive data from the device
3. On a STALL condition receiving data, then:
The host shall accept the data received.
The host shall clear the Bulk-In pipe.
4. The host shall attempt to receive a CSW.*/
#if (USBH_USE_OS == 1U)
USBH_OS_PutMessage(phost, USBH_URB_EVENT, 0U, 0U);
#endif /* (USBH_USE_OS == 1U) */
}
else
{
}
break;
case BOT_DATA_OUT:
(void)USBH_BulkSendData(phost, MSC_Handle->hbot.pbuf,
MSC_Handle->OutEpSize, MSC_Handle->OutPipe, 1U);
MSC_Handle->hbot.state = BOT_DATA_OUT_WAIT;
break;
case BOT_DATA_OUT_WAIT:
URB_Status = USBH_LL_GetURBState(phost, MSC_Handle->OutPipe);
if (URB_Status == USBH_URB_DONE)
{
/* Adjust Data pointer and data length */
if (MSC_Handle->hbot.cbw.field.DataTransferLength > MSC_Handle->OutEpSize)
{
MSC_Handle->hbot.pbuf += MSC_Handle->OutEpSize;
MSC_Handle->hbot.cbw.field.DataTransferLength -= MSC_Handle->OutEpSize;
}
else
{
MSC_Handle->hbot.cbw.field.DataTransferLength = 0U;
}
/* More Data To be Sent */
if (MSC_Handle->hbot.cbw.field.DataTransferLength > 0U)
{
(void)USBH_BulkSendData(phost, MSC_Handle->hbot.pbuf,
MSC_Handle->OutEpSize, MSC_Handle->OutPipe, 1U);
}
else
{
/* If value was 0, and successful transfer, then change the state */
MSC_Handle->hbot.state = BOT_RECEIVE_CSW;
}
#if (USBH_USE_OS == 1U)
USBH_OS_PutMessage(phost, USBH_URB_EVENT, 0U, 0U);
#endif /* (USBH_USE_OS == 1U) */
}
else if (URB_Status == USBH_URB_NOTREADY)
{
/* Resend same data */
MSC_Handle->hbot.state = BOT_DATA_OUT;
#if (USBH_USE_OS == 1U)
USBH_OS_PutMessage(phost, USBH_URB_EVENT, 0U, 0U);
#endif /* (USBH_USE_OS == 1U) */
}
else if (URB_Status == USBH_URB_STALL)
{
MSC_Handle->hbot.state = BOT_ERROR_OUT;
/* Refer to USB Mass-Storage Class : BOT (www.usb.org)
6.7.3 Ho - Host expects to send data to the device
3. On a STALL condition sending data, then:
" The host shall clear the Bulk-Out pipe.
4. The host shall attempt to receive a CSW.
*/
#if (USBH_USE_OS == 1U)
USBH_OS_PutMessage(phost, USBH_URB_EVENT, 0U, 0U);
#endif /* (USBH_USE_OS == 1U) */
}
else
{
}
break;
case BOT_RECEIVE_CSW:
(void)USBH_BulkReceiveData(phost, MSC_Handle->hbot.csw.data,
BOT_CSW_LENGTH, MSC_Handle->InPipe);
MSC_Handle->hbot.state = BOT_RECEIVE_CSW_WAIT;
#if defined (USBH_IN_NAK_PROCESS) && (USBH_IN_NAK_PROCESS == 1U)
phost->NakTimer = phost->Timer;
#endif /* defined (USBH_IN_NAK_PROCESS) && (USBH_IN_NAK_PROCESS == 1U) */
break;
case BOT_RECEIVE_CSW_WAIT:
URB_Status = USBH_LL_GetURBState(phost, MSC_Handle->InPipe);
/* Decode CSW */
if (URB_Status == USBH_URB_DONE)
{
MSC_Handle->hbot.state = BOT_SEND_CBW;
MSC_Handle->hbot.cmd_state = BOT_CMD_SEND;
CSW_Status = USBH_MSC_DecodeCSW(phost);
if (CSW_Status == BOT_CSW_CMD_PASSED)
{
status = USBH_OK;
}
else
{
status = USBH_FAIL;
}
#if (USBH_USE_OS == 1U)
USBH_OS_PutMessage(phost, USBH_URB_EVENT, 0U, 0U);
#endif /* (USBH_USE_OS == 1U) */
}
#if defined (USBH_IN_NAK_PROCESS) && (USBH_IN_NAK_PROCESS == 1U)
else if (URB_Status == USBH_URB_NAK_WAIT)
{
MSC_Handle->hbot.state = BOT_RECEIVE_CSW_WAIT;
if ((phost->Timer - phost->NakTimer) > phost->NakTimeout)
{
phost->NakTimer = phost->Timer;
USBH_ActivatePipe(phost, MSC_Handle->InPipe);
}
#if (USBH_USE_OS == 1U)
USBH_OS_PutMessage(phost, USBH_URB_EVENT, 0U, 0U);
#endif /* (USBH_USE_OS == 1U) */
}
#endif /* defined (USBH_IN_NAK_PROCESS) && (USBH_IN_NAK_PROCESS == 1U) */
else if (URB_Status == USBH_URB_STALL)
{
MSC_Handle->hbot.state = BOT_ERROR_IN;
#if (USBH_USE_OS == 1U)
USBH_OS_PutMessage(phost, USBH_URB_EVENT, 0U, 0U);
#endif /* (USBH_USE_OS == 1U) */
}
else
{
}
break;
case BOT_ERROR_IN:
error = USBH_MSC_BOT_Abort(phost, lun, BOT_DIR_IN);
if (error == USBH_OK)
{
MSC_Handle->hbot.state = BOT_RECEIVE_CSW;
}
else if (error == USBH_UNRECOVERED_ERROR)
{
/* This means that there is a STALL Error limit, Do Reset Recovery */
MSC_Handle->hbot.state = BOT_UNRECOVERED_ERROR;
}
else
{
}
break;
case BOT_ERROR_OUT:
error = USBH_MSC_BOT_Abort(phost, lun, BOT_DIR_OUT);
if (error == USBH_OK)
{
toggle = USBH_LL_GetToggle(phost, MSC_Handle->OutPipe);
(void)USBH_LL_SetToggle(phost, MSC_Handle->OutPipe, 1U - toggle);
(void)USBH_LL_SetToggle(phost, MSC_Handle->InPipe, 0U);
MSC_Handle->hbot.state = BOT_ERROR_IN;
}
else
{
if (error == USBH_UNRECOVERED_ERROR)
{
MSC_Handle->hbot.state = BOT_UNRECOVERED_ERROR;
}
}
break;
case BOT_UNRECOVERED_ERROR:
status = USBH_MSC_BOT_REQ_Reset(phost);
if (status == USBH_OK)
{
MSC_Handle->hbot.state = BOT_SEND_CBW;
}
break;
default:
break;
}
return status;
}
/**
* @brief USBH_MSC_BOT_Abort
* The function handle the BOT Abort process.
* @param phost: Host handle
* @param lun: Logical Unit Number
* @param dir: direction (0: out / 1 : in)
* @retval USBH Status
*/
static USBH_StatusTypeDef USBH_MSC_BOT_Abort(USBH_HandleTypeDef *phost, uint8_t lun, uint8_t dir)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(lun);
USBH_StatusTypeDef status = USBH_FAIL;
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
switch (dir)
{
case BOT_DIR_IN :
/* send ClrFeture on Bulk IN endpoint */
status = USBH_ClrFeature(phost, MSC_Handle->InEp);
break;
case BOT_DIR_OUT :
/*send ClrFeature on Bulk OUT endpoint */
status = USBH_ClrFeature(phost, MSC_Handle->OutEp);
break;
default:
break;
}
return status;
}
/**
* @brief USBH_MSC_BOT_DecodeCSW
* This function decodes the CSW received by the device and updates the
* same to upper layer.
* @param phost: Host handle
* @retval USBH Status
* @notes
* Refer to USB Mass-Storage Class : BOT (www.usb.org)
* 6.3.1 Valid CSW Conditions :
* The host shall consider the CSW valid when:
* 1. dCSWSignature is equal to 53425355h
* 2. the CSW is 13 (Dh) bytes in length,
* 3. dCSWTag matches the dCBWTag from the corresponding CBW.
*/
static BOT_CSWStatusTypeDef USBH_MSC_DecodeCSW(USBH_HandleTypeDef *phost)
{
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
BOT_CSWStatusTypeDef status = BOT_CSW_CMD_FAILED;
/*Checking if the transfer length is different than 13*/
if (USBH_LL_GetLastXferSize(phost, MSC_Handle->InPipe) != BOT_CSW_LENGTH)
{
/*(4) Hi > Dn (Host expects to receive data from the device,
Device intends to transfer no data)
(5) Hi > Di (Host expects to receive data from the device,
Device intends to send data to the host)
(9) Ho > Dn (Host expects to send data to the device,
Device intends to transfer no data)
(11) Ho > Do (Host expects to send data to the device,
Device intends to receive data from the host)*/
status = BOT_CSW_PHASE_ERROR;
}
else
{
/* CSW length is Correct */
/* Check validity of the CSW Signature and CSWStatus */
if (MSC_Handle->hbot.csw.field.Signature == BOT_CSW_SIGNATURE)
{
/* Check Condition 1. dCSWSignature is equal to 53425355h */
if (MSC_Handle->hbot.csw.field.Tag == MSC_Handle->hbot.cbw.field.Tag)
{
/* Check Condition 3. dCSWTag matches the dCBWTag from the
corresponding CBW */
if (MSC_Handle->hbot.csw.field.Status == 0U)
{
/* Refer to USB Mass-Storage Class : BOT (www.usb.org)
Hn Host expects no data transfers
Hi Host expects to receive data from the device
Ho Host expects to send data to the device
Dn Device intends to transfer no data
Di Device intends to send data to the host
Do Device intends to receive data from the host
Section 6.7
(1) Hn = Dn (Host expects no data transfers,
Device intends to transfer no data)
(6) Hi = Di (Host expects to receive data from the device,
Device intends to send data to the host)
(12) Ho = Do (Host expects to send data to the device,
Device intends to receive data from the host)
*/
status = BOT_CSW_CMD_PASSED;
}
else if (MSC_Handle->hbot.csw.field.Status == 1U)
{
status = BOT_CSW_CMD_FAILED;
}
else if (MSC_Handle->hbot.csw.field.Status == 2U)
{
/* Refer to USB Mass-Storage Class : BOT (www.usb.org)
Section 6.7
(2) Hn < Di ( Host expects no data transfers,
Device intends to send data to the host)
(3) Hn < Do ( Host expects no data transfers,
Device intends to receive data from the host)
(7) Hi < Di ( Host expects to receive data from the device,
Device intends to send data to the host)
(8) Hi <> Do ( Host expects to receive data from the device,
Device intends to receive data from the host)
(10) Ho <> Di (Host expects to send data to the device,
Di Device intends to send data to the host)
(13) Ho < Do (Host expects to send data to the device,
Device intends to receive data from the host)
*/
status = BOT_CSW_PHASE_ERROR;
}
else
{
}
} /* CSW Tag Matching is Checked */
} /* CSW Signature Correct Checking */
else
{
/* If the CSW Signature is not valid, We sall return the Phase Error to
Upper Layers for Reset Recovery */
status = BOT_CSW_PHASE_ERROR;
}
} /* CSW Length Check*/
return status;
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
@@ -0,0 +1,469 @@
/**
******************************************************************************
* @file usbh_msc_scsi.c
* @author MCD Application Team
* @brief This file implements the SCSI commands
******************************************************************************
* @attention
*
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* BSPDependencies
- "stm32xxxxx_{eval}{discovery}{nucleo_144}.c"
- "stm32xxxxx_{eval}{discovery}_io.c"
- "stm32xxxxx_{eval}{discovery}{adafruit}_lcd.c"
- "stm32xxxxx_{eval}{discovery}_sdram.c"
EndBSPDependencies */
/* Includes ------------------------------------------------------------------*/
#include "usbh_msc.h"
#include "usbh_msc_scsi.h"
#include "usbh_msc_bot.h"
/** @addtogroup USBH_LIB
* @{
*/
/** @addtogroup USBH_CLASS
* @{
*/
/** @addtogroup USBH_MSC_CLASS
* @{
*/
/** @defgroup USBH_MSC_SCSI
* @brief This file includes the mass storage related functions
* @{
*/
/** @defgroup USBH_MSC_SCSI_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @defgroup USBH_MSC_SCSI_Private_Defines
* @{
*/
/**
* @}
*/
/** @defgroup USBH_MSC_SCSI_Private_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBH_MSC_SCSI_Private_FunctionPrototypes
* @{
*/
/**
* @}
*/
/** @defgroup USBH_MSC_SCSI_Exported_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USBH_MSC_SCSI_Private_Functions
* @{
*/
/**
* @brief USBH_MSC_SCSI_TestUnitReady
* Issue TestUnitReady command.
* @param phost: Host handle
* @param lun: Logical Unit Number
* @retval USBH Status
*/
USBH_StatusTypeDef USBH_MSC_SCSI_TestUnitReady(USBH_HandleTypeDef *phost,
uint8_t lun)
{
USBH_StatusTypeDef error = USBH_FAIL;
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
switch (MSC_Handle->hbot.cmd_state)
{
case BOT_CMD_SEND:
/* Prepare the CBW and relevant field */
MSC_Handle->hbot.cbw.field.DataTransferLength = DATA_LEN_MODE_TEST_UNIT_READY;
MSC_Handle->hbot.cbw.field.Flags = USB_EP_DIR_OUT;
MSC_Handle->hbot.cbw.field.CBLength = CBW_LENGTH;
(void)USBH_memset(MSC_Handle->hbot.cbw.field.CB, 0, CBW_CB_LENGTH);
MSC_Handle->hbot.cbw.field.CB[0] = OPCODE_TEST_UNIT_READY;
MSC_Handle->hbot.state = BOT_SEND_CBW;
MSC_Handle->hbot.cmd_state = BOT_CMD_WAIT;
error = USBH_BUSY;
break;
case BOT_CMD_WAIT:
error = USBH_MSC_BOT_Process(phost, lun);
break;
default:
break;
}
return error;
}
/**
* @brief USBH_MSC_SCSI_ReadCapacity
* Issue Read Capacity command.
* @param phost: Host handle
* @param lun: Logical Unit Number
* @param capacity: pointer to the capacity structure
* @retval USBH Status
*/
USBH_StatusTypeDef USBH_MSC_SCSI_ReadCapacity(USBH_HandleTypeDef *phost,
uint8_t lun,
SCSI_CapacityTypeDef *capacity)
{
USBH_StatusTypeDef error = USBH_BUSY;
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
switch (MSC_Handle->hbot.cmd_state)
{
case BOT_CMD_SEND:
/* Prepare the CBW and relevant field */
MSC_Handle->hbot.cbw.field.DataTransferLength = DATA_LEN_READ_CAPACITY10;
MSC_Handle->hbot.cbw.field.Flags = USB_EP_DIR_IN;
MSC_Handle->hbot.cbw.field.CBLength = CBW_LENGTH;
(void)USBH_memset(MSC_Handle->hbot.cbw.field.CB, 0, CBW_CB_LENGTH);
MSC_Handle->hbot.cbw.field.CB[0] = OPCODE_READ_CAPACITY10;
MSC_Handle->hbot.state = BOT_SEND_CBW;
MSC_Handle->hbot.cmd_state = BOT_CMD_WAIT;
MSC_Handle->hbot.pbuf = (uint8_t *)(void *)MSC_Handle->hbot.data;
error = USBH_BUSY;
break;
case BOT_CMD_WAIT:
error = USBH_MSC_BOT_Process(phost, lun);
if (error == USBH_OK)
{
/* Assign the capacity */
capacity->block_nbr = MSC_Handle->hbot.pbuf[3] | ((uint32_t)MSC_Handle->hbot.pbuf[2] << 8U) | \
((uint32_t)MSC_Handle->hbot.pbuf[1] << 16U) | ((uint32_t)MSC_Handle->hbot.pbuf[0] << 24U);
/* Assign the page length */
capacity->block_size = (uint16_t)(MSC_Handle->hbot.pbuf[7] | ((uint32_t)MSC_Handle->hbot.pbuf[6] << 8U));
}
break;
default:
break;
}
return error;
}
/**
* @brief USBH_MSC_SCSI_Inquiry
* Issue Inquiry command.
* @param phost: Host handle
* @param lun: Logical Unit Number
* @param capacity: pointer to the inquiry structure
* @retval USBH Status
*/
USBH_StatusTypeDef USBH_MSC_SCSI_Inquiry(USBH_HandleTypeDef *phost, uint8_t lun,
SCSI_StdInquiryDataTypeDef *inquiry)
{
USBH_StatusTypeDef error = USBH_FAIL;
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
switch (MSC_Handle->hbot.cmd_state)
{
case BOT_CMD_SEND:
/* Prepare the CBW and relevant field */
MSC_Handle->hbot.cbw.field.DataTransferLength = DATA_LEN_INQUIRY;
MSC_Handle->hbot.cbw.field.Flags = USB_EP_DIR_IN;
MSC_Handle->hbot.cbw.field.CBLength = CBW_LENGTH;
(void)USBH_memset(MSC_Handle->hbot.cbw.field.CB, 0, CBW_LENGTH);
MSC_Handle->hbot.cbw.field.CB[0] = OPCODE_INQUIRY;
MSC_Handle->hbot.cbw.field.CB[1] = (lun << 5);
MSC_Handle->hbot.cbw.field.CB[2] = 0U;
MSC_Handle->hbot.cbw.field.CB[3] = 0U;
MSC_Handle->hbot.cbw.field.CB[4] = 0x24U;
MSC_Handle->hbot.cbw.field.CB[5] = 0U;
MSC_Handle->hbot.state = BOT_SEND_CBW;
MSC_Handle->hbot.cmd_state = BOT_CMD_WAIT;
MSC_Handle->hbot.pbuf = (uint8_t *)(void *)MSC_Handle->hbot.data;
error = USBH_BUSY;
break;
case BOT_CMD_WAIT:
error = USBH_MSC_BOT_Process(phost, lun);
if (error == USBH_OK)
{
(void)USBH_memset(inquiry, 0, sizeof(SCSI_StdInquiryDataTypeDef));
/* Assign Inquiry Data */
inquiry->DeviceType = MSC_Handle->hbot.pbuf[0] & 0x1FU;
inquiry->PeripheralQualifier = MSC_Handle->hbot.pbuf[0] >> 5U;
if (((uint32_t)MSC_Handle->hbot.pbuf[1] & 0x80U) == 0x80U)
{
inquiry->RemovableMedia = 1U;
}
else
{
inquiry->RemovableMedia = 0U;
}
(void)USBH_memcpy(inquiry->vendor_id, &MSC_Handle->hbot.pbuf[8], 8U);
(void)USBH_memcpy(inquiry->product_id, &MSC_Handle->hbot.pbuf[16], 16U);
(void)USBH_memcpy(inquiry->revision_id, &MSC_Handle->hbot.pbuf[32], 4U);
}
break;
default:
break;
}
return error;
}
/**
* @brief USBH_MSC_SCSI_RequestSense
* Issue RequestSense command.
* @param phost: Host handle
* @param lun: Logical Unit Number
* @param capacity: pointer to the sense data structure
* @retval USBH Status
*/
USBH_StatusTypeDef USBH_MSC_SCSI_RequestSense(USBH_HandleTypeDef *phost,
uint8_t lun,
SCSI_SenseTypeDef *sense_data)
{
USBH_StatusTypeDef error = USBH_FAIL;
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
switch (MSC_Handle->hbot.cmd_state)
{
case BOT_CMD_SEND:
/* Prepare the CBW and relevant field */
MSC_Handle->hbot.cbw.field.DataTransferLength = DATA_LEN_REQUEST_SENSE;
MSC_Handle->hbot.cbw.field.Flags = USB_EP_DIR_IN;
MSC_Handle->hbot.cbw.field.CBLength = CBW_LENGTH;
(void)USBH_memset(MSC_Handle->hbot.cbw.field.CB, 0, CBW_CB_LENGTH);
MSC_Handle->hbot.cbw.field.CB[0] = OPCODE_REQUEST_SENSE;
MSC_Handle->hbot.cbw.field.CB[1] = (lun << 5);
MSC_Handle->hbot.cbw.field.CB[2] = 0U;
MSC_Handle->hbot.cbw.field.CB[3] = 0U;
MSC_Handle->hbot.cbw.field.CB[4] = DATA_LEN_REQUEST_SENSE;
MSC_Handle->hbot.cbw.field.CB[5] = 0U;
MSC_Handle->hbot.state = BOT_SEND_CBW;
MSC_Handle->hbot.cmd_state = BOT_CMD_WAIT;
MSC_Handle->hbot.pbuf = (uint8_t *)(void *)MSC_Handle->hbot.data;
error = USBH_BUSY;
break;
case BOT_CMD_WAIT:
error = USBH_MSC_BOT_Process(phost, lun);
if (error == USBH_OK)
{
sense_data->key = MSC_Handle->hbot.pbuf[2] & 0x0FU;
sense_data->asc = MSC_Handle->hbot.pbuf[12];
sense_data->ascq = MSC_Handle->hbot.pbuf[13];
if (sense_data->asc == SCSI_ASC_MEDIUM_NOT_PRESENT)
{
USBH_UsrLog("MSC Device MEDIUM not present");
error = USBH_UNRECOVERED_ERROR;
}
}
break;
default:
break;
}
return error;
}
/**
* @brief USBH_MSC_SCSI_Write
* Issue write10 command.
* @param phost: Host handle
* @param lun: Logical Unit Number
* @param address: sector address
* @param pbuf: pointer to data
* @param length: number of sector to write
* @retval USBH Status
*/
USBH_StatusTypeDef USBH_MSC_SCSI_Write(USBH_HandleTypeDef *phost,
uint8_t lun,
uint32_t address,
uint8_t *pbuf,
uint32_t length)
{
USBH_StatusTypeDef error = USBH_FAIL;
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
switch (MSC_Handle->hbot.cmd_state)
{
case BOT_CMD_SEND:
/* Prepare the CBW and relevant field */
MSC_Handle->hbot.cbw.field.DataTransferLength = length * MSC_Handle->unit[lun].capacity.block_size;
MSC_Handle->hbot.cbw.field.Flags = USB_EP_DIR_OUT;
MSC_Handle->hbot.cbw.field.CBLength = CBW_LENGTH;
(void)USBH_memset(MSC_Handle->hbot.cbw.field.CB, 0, CBW_CB_LENGTH);
MSC_Handle->hbot.cbw.field.CB[0] = OPCODE_WRITE10;
/* Logical block address */
MSC_Handle->hbot.cbw.field.CB[2] = (((uint8_t *)(void *)&address)[3]);
MSC_Handle->hbot.cbw.field.CB[3] = (((uint8_t *)(void *)&address)[2]);
MSC_Handle->hbot.cbw.field.CB[4] = (((uint8_t *)(void *)&address)[1]);
MSC_Handle->hbot.cbw.field.CB[5] = (((uint8_t *)(void *)&address)[0]);
/*Transfer length */
MSC_Handle->hbot.cbw.field.CB[7] = (((uint8_t *)(void *)&length)[1]);
MSC_Handle->hbot.cbw.field.CB[8] = (((uint8_t *)(void *)&length)[0]);
MSC_Handle->hbot.state = BOT_SEND_CBW;
MSC_Handle->hbot.cmd_state = BOT_CMD_WAIT;
MSC_Handle->hbot.pbuf = pbuf;
error = USBH_BUSY;
break;
case BOT_CMD_WAIT:
error = USBH_MSC_BOT_Process(phost, lun);
break;
default:
break;
}
return error;
}
/**
* @brief USBH_MSC_SCSI_Read
* Issue Read10 command.
* @param phost: Host handle
* @param lun: Logical Unit Number
* @param address: sector address
* @param pbuf: pointer to data
* @param length: number of sector to read
* @retval USBH Status
*/
USBH_StatusTypeDef USBH_MSC_SCSI_Read(USBH_HandleTypeDef *phost,
uint8_t lun,
uint32_t address,
uint8_t *pbuf,
uint32_t length)
{
USBH_StatusTypeDef error = USBH_FAIL;
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
switch (MSC_Handle->hbot.cmd_state)
{
case BOT_CMD_SEND:
/* Prepare the CBW and relevant field */
MSC_Handle->hbot.cbw.field.DataTransferLength = length * MSC_Handle->unit[lun].capacity.block_size;
MSC_Handle->hbot.cbw.field.Flags = USB_EP_DIR_IN;
MSC_Handle->hbot.cbw.field.CBLength = CBW_LENGTH;
(void)USBH_memset(MSC_Handle->hbot.cbw.field.CB, 0, CBW_CB_LENGTH);
MSC_Handle->hbot.cbw.field.CB[0] = OPCODE_READ10;
/* Logical block address */
MSC_Handle->hbot.cbw.field.CB[2] = (((uint8_t *)(void *)&address)[3]);
MSC_Handle->hbot.cbw.field.CB[3] = (((uint8_t *)(void *)&address)[2]);
MSC_Handle->hbot.cbw.field.CB[4] = (((uint8_t *)(void *)&address)[1]);
MSC_Handle->hbot.cbw.field.CB[5] = (((uint8_t *)(void *)&address)[0]);
/* Transfer length */
MSC_Handle->hbot.cbw.field.CB[7] = (((uint8_t *)(void *)&length)[1]);
MSC_Handle->hbot.cbw.field.CB[8] = (((uint8_t *)(void *)&length)[0]);
MSC_Handle->hbot.state = BOT_SEND_CBW;
MSC_Handle->hbot.cmd_state = BOT_CMD_WAIT;
MSC_Handle->hbot.pbuf = pbuf;
error = USBH_BUSY;
break;
case BOT_CMD_WAIT:
error = USBH_MSC_BOT_Process(phost, lun);
break;
default:
break;
}
return error;
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
@@ -0,0 +1,260 @@
/**
******************************************************************************
* @file usbh_mtp.h
* @author MCD Application Team
* @brief This file contains all the prototypes for the usbh_mtp.c
******************************************************************************
* @attention
*
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Define to prevent recursive ----------------------------------------------*/
#ifndef __USBH_MTP_H
#define __USBH_MTP_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "usbh_mtp_ptp.h"
#include "usbh_core.h"
/** @addtogroup USBH_LIB
* @{
*/
/** @addtogroup USBH_CLASS
* @{
*/
/** @addtogroup USBH_MTP_CLASS
* @{
*/
/** @defgroup USBH_MTP_CORE
* @brief This file is the Header file for usbh_mtp.c
* @{
*/
/*Communication Class codes*/
#define USB_MTP_CLASS 0x06U /* Still Image Class)*/
#define MTP_MAX_STORAGE_UNITS_NBR PTP_MAX_STORAGE_UNITS_NBR
/**
* @}
*/
/** @defgroup USBH_MTP_CORE_Exported_Types
* @{
*/
typedef enum
{
MTP_IDLE = 0,
MTP_GETDEVICEINFO,
MTP_OPENSESSION,
MTP_CLOSESESSION,
MTP_GETSTORAGEIDS,
MTP_GETSTORAGEINFO,
}
MTP_StateTypeDef;
typedef enum
{
MTP_EVENTS_INIT = 0,
MTP_EVENTS_GETDATA,
}
MTP_EventsStateTypeDef;
typedef struct
{
MTP_EventsStateTypeDef state;
uint32_t timer;
uint16_t poll;
PTP_EventContainerTypedef container;
}
MTP_EventHandleTypedef;
typedef struct
{
uint32_t CurrentStorageId;
uint32_t ObjectFormatCode;
uint32_t CurrentObjectHandler;
uint8_t ObjectHandlerNbr;
uint32_t Objdepth;
}
MTP_ParamsTypedef;
typedef struct
{
PTP_DeviceInfoTypedef devinfo;
PTP_StorageIDsTypedef storids;
PTP_StorageInfoTypedef storinfo[MTP_MAX_STORAGE_UNITS_NBR];
PTP_ObjectHandlesTypedef Handles;
}
MTP_InfoTypedef;
/* Structure for MTP process */
typedef struct _MTP_Process
{
MTP_InfoTypedef info;
MTP_ParamsTypedef params;
uint8_t DataInPipe;
uint8_t DataOutPipe;
uint8_t NotificationPipe;
uint8_t DataOutEp;
uint8_t DataInEp;
uint8_t NotificationEp;
uint16_t DataOutEpSize;
uint16_t DataInEpSize;
uint16_t NotificationEpSize;
MTP_StateTypeDef state;
MTP_EventHandleTypedef events;
PTP_HandleTypeDef ptp;
uint32_t current_storage_unit;
uint32_t is_ready;
}
MTP_HandleTypeDef;
#define MTP_StorageInfoTypedef PTP_StorageInfoTypedef
#define MTP_ObjectHandlesTypedef PTP_ObjectHandlesTypedef
#define MTP_ObjectInfoTypedef PTP_ObjectInfoTypedef
/**
* @}
*/
/** @defgroup USBH_MTP_CORE_Exported_Defines
* @{
*/
/**
* @}
*/
/** @defgroup USBH_MTP_CORE_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBH_MTP_CORE_Exported_Variables
* @{
*/
extern USBH_ClassTypeDef MTP_Class;
#define USBH_MTP_CLASS &MTP_Class
/**
* @}
*/
/** @defgroup USBH_MTP_CORE_Exported_FunctionsPrototype
* @{
*/
uint8_t USBH_MTP_IsReady(USBH_HandleTypeDef *phost);
USBH_StatusTypeDef USBH_MTP_SelectStorage(USBH_HandleTypeDef *phost, uint8_t storage_idx);
USBH_StatusTypeDef USBH_MTP_GetNumStorage(USBH_HandleTypeDef *phost, uint8_t *storage_num);
USBH_StatusTypeDef USBH_MTP_GetNumObjects(USBH_HandleTypeDef *phost,
uint32_t storage_idx,
uint32_t objectformatcode,
uint32_t associationOH,
uint32_t *numobs);
USBH_StatusTypeDef USBH_MTP_GetStorageInfo(USBH_HandleTypeDef *phost,
uint8_t storage_idx,
MTP_StorageInfoTypedef *info);
USBH_StatusTypeDef USBH_MTP_GetObjectHandles(USBH_HandleTypeDef *phost,
uint32_t storage_idx,
uint32_t objectformatcode,
uint32_t associationOH,
PTP_ObjectHandlesTypedef *objecthandles);
USBH_StatusTypeDef USBH_MTP_GetObjectInfo(USBH_HandleTypeDef *phost,
uint32_t handle,
PTP_ObjectInfoTypedef *objectinfo);
USBH_StatusTypeDef USBH_MTP_DeleteObject(USBH_HandleTypeDef *phost,
uint32_t handle,
uint32_t objectformatcode);
USBH_StatusTypeDef USBH_MTP_GetObject(USBH_HandleTypeDef *phost,
uint32_t handle,
uint8_t *object);
USBH_StatusTypeDef USBH_MTP_GetPartialObject(USBH_HandleTypeDef *phost,
uint32_t handle,
uint32_t offset,
uint32_t maxbytes,
uint8_t *object,
uint32_t *len);
USBH_StatusTypeDef USBH_MTP_GetObjectPropsSupported(USBH_HandleTypeDef *phost,
uint16_t ofc,
uint32_t *propnum,
uint16_t *props);
USBH_StatusTypeDef USBH_MTP_GetObjectPropDesc(USBH_HandleTypeDef *phost,
uint16_t opc,
uint16_t ofc,
PTP_ObjectPropDescTypeDef *opd);
USBH_StatusTypeDef USBH_MTP_GetObjectPropList(USBH_HandleTypeDef *phost,
uint32_t handle,
MTP_PropertiesTypedef *pprops,
uint32_t *nrofprops);
USBH_StatusTypeDef USBH_MTP_SendObject(USBH_HandleTypeDef *phost,
uint32_t handle,
uint8_t *object,
uint32_t size);
USBH_StatusTypeDef USBH_MTP_GetDevicePropDesc(USBH_HandleTypeDef *phost,
uint16_t propcode,
PTP_DevicePropDescTypdef *devicepropertydesc);
void USBH_MTP_EventsCallback(USBH_HandleTypeDef *phost, uint32_t event, uint32_t param);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __USBH_MTP_H */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,119 @@
/**
******************************************************************************
* @file usbh_template.h
* @author MCD Application Team
* @brief This file contains all the prototypes for the usbh_template.c
******************************************************************************
* @attention
*
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Define to prevent recursive ----------------------------------------------*/
#ifndef __USBH_TEMPLATE_H
#define __USBH_TEMPLATE_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "usbh_core.h"
/** @addtogroup USBH_LIB
* @{
*/
/** @addtogroup USBH_CLASS
* @{
*/
/** @addtogroup USBH_TEMPLATE_CLASS
* @{
*/
/** @defgroup USBH_TEMPLATE_CLASS
* @brief This file is the Header file for usbh_template.c
* @{
*/
/**
* @}
*/
/** @defgroup USBH_TEMPLATE_CLASS_Exported_Types
* @{
*/
/* States for TEMPLATE State Machine */
/**
* @}
*/
/** @defgroup USBH_TEMPLATE_CLASS_Exported_Defines
* @{
*/
/**
* @}
*/
/** @defgroup USBH_TEMPLATE_CLASS_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBH_TEMPLATE_CLASS_Exported_Variables
* @{
*/
extern USBH_ClassTypeDef TEMPLATE_Class;
#define USBH_TEMPLATE_CLASS &TEMPLATE_Class
/**
* @}
*/
/** @defgroup USBH_TEMPLATE_CLASS_Exported_FunctionsPrototype
* @{
*/
USBH_StatusTypeDef USBH_TEMPLATE_IOProcess(USBH_HandleTypeDef *phost);
USBH_StatusTypeDef USBH_TEMPLATE_Init(USBH_HandleTypeDef *phost);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __USBH_TEMPLATE_H */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
@@ -0,0 +1,236 @@
/**
******************************************************************************
* @file usbh_mtp.c
* @author MCD Application Team
* @brief This file is the MTP Layer Handlers for USB Host MTP class.
*
*
******************************************************************************
* @attention
*
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "usbh_template.h"
/** @addtogroup USBH_LIB
* @{
*/
/** @addtogroup USBH_CLASS
* @{
*/
/** @addtogroup USBH_TEMPLATE_CLASS
* @{
*/
/** @defgroup USBH_TEMPLATE_CORE
* @brief This file includes TEMPLATE Layer Handlers for USB Host TEMPLATE class.
* @{
*/
/** @defgroup USBH_TEMPLATE_CORE_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @defgroup USBH_TEMPLATE_CORE_Private_Defines
* @{
*/
/**
* @}
*/
/** @defgroup USBH_TEMPLATE_CORE_Private_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBH_TEMPLATE_CORE_Private_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USBH_TEMPLATE_CORE_Private_FunctionPrototypes
* @{
*/
static USBH_StatusTypeDef USBH_TEMPLATE_InterfaceInit(USBH_HandleTypeDef *phost);
static USBH_StatusTypeDef USBH_TEMPLATE_InterfaceDeInit(USBH_HandleTypeDef *phost);
static USBH_StatusTypeDef USBH_TEMPLATE_Process(USBH_HandleTypeDef *phost);
static USBH_StatusTypeDef USBH_TEMPLATE_ClassRequest(USBH_HandleTypeDef *phost);
USBH_ClassTypeDef TEMPLATE_Class =
{
"TEMPLATE",
USB_TEMPLATE_CLASS,
USBH_TEMPLATE_InterfaceInit,
USBH_TEMPLATE_InterfaceDeInit,
USBH_TEMPLATE_ClassRequest,
USBH_TEMPLATE_Process
};
/**
* @}
*/
/** @defgroup USBH_TEMPLATE_CORE_Private_Functions
* @{
*/
/**
* @brief USBH_TEMPLATE_InterfaceInit
* The function init the TEMPLATE class.
* @param phost: Host handle
* @retval USBH Status
*/
static USBH_StatusTypeDef USBH_TEMPLATE_InterfaceInit(USBH_HandleTypeDef *phost)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(phost);
return USBH_OK;
}
/**
* @brief USBH_TEMPLATE_InterfaceDeInit
* The function DeInit the Pipes used for the TEMPLATE class.
* @param phost: Host handle
* @retval USBH Status
*/
USBH_StatusTypeDef USBH_TEMPLATE_InterfaceDeInit(USBH_HandleTypeDef *phost)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(phost);
return USBH_OK;
}
/**
* @brief USBH_TEMPLATE_ClassRequest
* The function is responsible for handling Standard requests
* for TEMPLATE class.
* @param phost: Host handle
* @retval USBH Status
*/
static USBH_StatusTypeDef USBH_TEMPLATE_ClassRequest(USBH_HandleTypeDef *phost)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(phost);
return USBH_OK;
}
/**
* @brief USBH_TEMPLATE_Process
* The function is for managing state machine for TEMPLATE data transfers
* @param phost: Host handle
* @retval USBH Status
*/
static USBH_StatusTypeDef USBH_TEMPLATE_Process(USBH_HandleTypeDef *phost)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(phost);
return USBH_OK;
}
/**
* @brief USBH_TEMPLATE_Init
* The function Initialize the TEMPLATE function
* @param phost: Host handle
* @retval USBH Status
*/
USBH_StatusTypeDef USBH_TEMPLATE_Init(USBH_HandleTypeDef *phost)
{
USBH_StatusTypeDef Status = USBH_BUSY;
#if (USBH_USE_OS == 1U)
osEvent event;
event = osMessageGet(phost->class_ready_event, osWaitForever);
if (event.status == osEventMessage)
{
if (event.value.v == USBH_CLASS_EVENT)
{
#else
while ((Status == USBH_BUSY) || (Status == USBH_FAIL))
{
/* Host background process */
USBH_Process(phost);
if (phost->gState == HOST_CLASS)
{
#endif
Status = USBH_OK;
}
}
return Status;
}
/**
* @brief USBH_TEMPLATE_IOProcess
* TEMPLATE TEMPLATE process
* @param phost: Host handle
* @retval USBH Status
*/
USBH_StatusTypeDef USBH_TEMPLATE_IOProcess(USBH_HandleTypeDef *phost)
{
if (phost->device.is_connected == 1U)
{
if (phost->gState == HOST_CLASS)
{
USBH_TEMPLATE_Process(phost);
}
}
return USBH_OK;
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
@@ -0,0 +1,151 @@
/**
******************************************************************************
* @file usbh_conf_template.h
* @author MCD Application Team
* @brief Header file for usbh_conf_template.c
******************************************************************************
* @attention
*
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USBH_CONF_TEMPLATE_H
#define __USBH_CONF_TEMPLATE_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "stm32fxxx.h" /* replace 'stm32xxx' with your HAL driver header filename, ex: stm32f4xx.h */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/** @addtogroup STM32_USB_HOST_LIBRARY
* @{
*/
/** @defgroup USBH_CONF
* @brief usb host low level driver configuration file
* @{
*/
/** @defgroup USBH_CONF_Exported_Defines
* @{
*/
#define USBH_MAX_NUM_ENDPOINTS 2U
#define USBH_MAX_NUM_INTERFACES 2U
#define USBH_MAX_NUM_CONFIGURATION 1U
#define USBH_KEEP_CFG_DESCRIPTOR 1U
#define USBH_MAX_NUM_SUPPORTED_CLASS 1U
#define USBH_MAX_SIZE_CONFIGURATION 0x200U
#define USBH_MAX_DATA_BUFFER 0x200U
#define USBH_DEBUG_LEVEL 2U
#define USBH_USE_OS 1U
#define USBH_IN_NAK_PROCESS 0
/** @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 > 0U)
#define USBH_UsrLog(...) do { \
printf(__VA_ARGS__); \
printf("\n"); \
} while (0)
#else
#define USBH_UsrLog(...) do {} while (0)
#endif
#if (USBH_DEBUG_LEVEL > 1U)
#define USBH_ErrLog(...) do { \
printf("ERROR: "); \
printf(__VA_ARGS__); \
printf("\n"); \
} while (0)
#else
#define USBH_ErrLog(...) do {} while (0)
#endif
#if (USBH_DEBUG_LEVEL > 2U)
#define USBH_DbgLog(...) do { \
printf("DEBUG : "); \
printf(__VA_ARGS__); \
printf("\n"); \
} while (0)
#else
#define USBH_DbgLog(...) do {} while (0)
#endif
/**
* @}
*/
/**
* @}
*/
/** @defgroup USBH_CONF_Exported_Types
* @{
*/
/**
* @}
*/
/** @defgroup USBH_CONF_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBH_CONF_Exported_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USBH_CONF_Exported_FunctionsPrototype
* @{
*/
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __USBH_CONF_TEMPLATE_H */
/**
* @}
*/
/**
* @}
*/
@@ -0,0 +1,178 @@
/**
******************************************************************************
* @file usbh_core.h
* @author MCD Application Team
* @brief Header file for usbh_core.c
******************************************************************************
* @attention
*
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Define to prevent recursive ----------------------------------------------*/
#ifndef __USBH_CORE_H
#define __USBH_CORE_H
#ifdef __cplusplus
extern "C" {
#endif
/* 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 0x01U
#define HOST_USER_CLASS_ACTIVE 0x02U
#define HOST_USER_CLASS_SELECTED 0x03U
#define HOST_USER_CONNECTION 0x04U
#define HOST_USER_DISCONNECTION 0x05U
#define HOST_USER_UNRECOVERED_ERROR 0x06U
/**
* @}
*/
/** @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 id), uint8_t id);
USBH_StatusTypeDef USBH_DeInit(USBH_HandleTypeDef *phost);
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_StatusTypeDef USBH_RegisterClass(USBH_HandleTypeDef *phost, USBH_ClassTypeDef *pclass);
USBH_StatusTypeDef USBH_SelectInterface(USBH_HandleTypeDef *phost, uint8_t interface);
uint8_t USBH_FindInterfaceIndex(USBH_HandleTypeDef *phost, uint8_t interface_number, uint8_t alt_settings);
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_IsPortEnabled(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 pipe);
USBH_StatusTypeDef USBH_LL_DriverVBUS(USBH_HandleTypeDef *phost, uint8_t state);
USBH_StatusTypeDef USBH_LL_OpenPipe(USBH_HandleTypeDef *phost,
uint8_t pipe,
uint8_t epnum,
uint8_t dev_address,
uint8_t speed,
uint8_t ep_type,
uint16_t mps);
USBH_StatusTypeDef USBH_LL_ActivatePipe(USBH_HandleTypeDef *phost, uint8_t pipe);
USBH_StatusTypeDef USBH_LL_ClosePipe(USBH_HandleTypeDef *phost, uint8_t pipe);
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);
USBH_URBStateTypeDef USBH_LL_GetURBState(USBH_HandleTypeDef *phost, uint8_t pipe);
#if (USBH_USE_OS == 1U)
USBH_StatusTypeDef USBH_LL_NotifyURBChange(USBH_HandleTypeDef *phost);
void USBH_OS_PutMessage(USBH_HandleTypeDef *phost, USBH_OSEventTypeDef message, uint32_t timeout, uint32_t priority);
#endif /*(USBH_USE_OS == 1U) */
USBH_StatusTypeDef USBH_LL_SetToggle(USBH_HandleTypeDef *phost, uint8_t pipe, uint8_t toggle);
uint8_t USBH_LL_GetToggle(USBH_HandleTypeDef *phost, uint8_t pipe);
void USBH_LL_PortDisabled(USBH_HandleTypeDef *phost);
void USBH_LL_PortEnabled(USBH_HandleTypeDef *phost);
/* USBH Time base */
void USBH_LL_SetTimer(USBH_HandleTypeDef *phost, uint32_t time);
void USBH_LL_IncTimer(USBH_HandleTypeDef *phost);
void USBH_Delay(uint32_t Delay);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __USBH_CORE_H */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
@@ -0,0 +1,138 @@
/**
******************************************************************************
* @file usbh_ctlreq.h
* @author MCD Application Team
* @brief Header file for usbh_ctlreq.c
******************************************************************************
* @attention
*
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Define to prevent recursive ----------------------------------------------*/
#ifndef __USBH_CTLREQ_H
#define __USBH_CTLREQ_H
#ifdef __cplusplus
extern "C" {
#endif
/* 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 0x00U
#define FEATURE_SELECTOR_DEVICE 0x01U
#define FEATURE_SELECTOR_REMOTEWAKEUP 0X01U
#define INTERFACE_DESC_TYPE 0x04U
#define ENDPOINT_DESC_TYPE 0x05U
#define INTERFACE_DESC_SIZE 0x09U
/**
* @}
*/
/** @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, uint16_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 cfg_idx);
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_SetFeature(USBH_HandleTypeDef *phost, uint8_t wValue);
USBH_StatusTypeDef USBH_ClrFeature(USBH_HandleTypeDef *phost, uint8_t ep_num);
USBH_DescHeader_t *USBH_GetNextDesc(uint8_t *pbuf, uint16_t *ptr);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __USBH_CTLREQ_H */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
@@ -0,0 +1,519 @@
/**
******************************************************************************
* @file usbh_def.h
* @author MCD Application Team
* @brief Definitions used in the USB host library
******************************************************************************
* @attention
*
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Define to prevent recursive ----------------------------------------------*/
#ifndef USBH_DEF_H
#define USBH_DEF_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "usbh_conf.h"
/** @addtogroup USBH_LIB
* @{
*/
/** @addtogroup USBH_LIB_CORE
* @{
*/
/** @defgroup USBH_DEF
* @brief This file is includes USB descriptors
* @{
*/
#ifndef NULL
#define NULL 0U
#endif
#ifndef FALSE
#define FALSE 0U
#endif
#ifndef TRUE
#define TRUE 1U
#endif
#ifndef USBH_DEV_RESET_TIMEOUT
#define USBH_DEV_RESET_TIMEOUT 1000U
#endif
#define ValBit(VAR,POS) (VAR & (1 << POS))
#define SetBit(VAR,POS) (VAR |= (1 << POS))
#define ClrBit(VAR,POS) (VAR &= ((1 << POS)^255))
#ifndef MIN
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#endif
#ifndef MAX
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#endif
#define LE16(addr) (((uint16_t)(addr)[0]) | \
((uint16_t)(((uint32_t)(addr)[1]) << 8)))
#define LE24(addr) (((uint32_t)(addr)[0]) | \
(((uint32_t)(addr)[1]) << 8) | \
(((uint32_t)(addr)[2]) << 16))
#define LE32(addr) (((uint32_t)(addr)[0]) | \
(((uint32_t)(addr)[1]) << 8) | \
(((uint32_t)(addr)[2]) << 16) | \
(((uint32_t)(addr)[3]) << 24))
#define LE64(addr) (((uint64_t)(addr)[0]) | \
(((uint64_t)(addr)[1]) << 8) | \
(((uint64_t)(addr)[2]) << 16) | \
(((uint64_t)(addr)[3]) << 24) | \
(((uint64_t)(addr)[4]) << 32) | \
(((uint64_t)(addr)[5]) << 40) | \
(((uint64_t)(addr)[6]) << 48) | \
(((uint64_t)(addr)[7]) << 56))
#define LE16S(addr) ((int16_t)(LE16((addr))))
#define LE24S(addr) ((int32_t)(LE24((addr))))
#define LE32S(addr) ((int32_t)(LE32((addr))))
#define LE64S(addr) ((int64_t)(LE64((addr))))
#ifndef USBH_MAX_DATA_BUFFER
#define USBH_MAX_DATA_BUFFER 0x400U
#endif
#define USBH_MAX_EP_PACKET_SIZE 0x400U
#define USB_LEN_DESC_HDR 0x02U
#define USB_LEN_DEV_DESC 0x12U
#define USB_LEN_CFG_DESC 0x09U
#define USB_LEN_IF_DESC 0x09U
#define USB_LEN_EP_DESC 0x07U
#define USB_LEN_OTG_DESC 0x03U
#define USB_LEN_SETUP_PKT 0x08U
/* bmRequestType :D7 Data Phase Transfer Direction */
#define USB_REQ_DIR_MASK 0x80U
#define USB_H2D 0x00U
#define USB_D2H 0x80U
/* bmRequestType D6..5 Type */
#define USB_REQ_TYPE_STANDARD 0x00U
#define USB_REQ_TYPE_CLASS 0x20U
#define USB_REQ_TYPE_VENDOR 0x40U
#define USB_REQ_TYPE_RESERVED 0x60U
/* bmRequestType D4..0 Recipient */
#define USB_REQ_RECIPIENT_DEVICE 0x00U
#define USB_REQ_RECIPIENT_INTERFACE 0x01U
#define USB_REQ_RECIPIENT_ENDPOINT 0x02U
#define USB_REQ_RECIPIENT_OTHER 0x03U
/* Table 9-4. Standard Request Codes */
/* bRequest , Value */
#define USB_REQ_GET_STATUS 0x00U
#define USB_REQ_CLEAR_FEATURE 0x01U
#define USB_REQ_SET_FEATURE 0x03U
#define USB_REQ_SET_ADDRESS 0x05U
#define USB_REQ_GET_DESCRIPTOR 0x06U
#define USB_REQ_SET_DESCRIPTOR 0x07U
#define USB_REQ_GET_CONFIGURATION 0x08U
#define USB_REQ_SET_CONFIGURATION 0x09U
#define USB_REQ_GET_INTERFACE 0x0AU
#define USB_REQ_SET_INTERFACE 0x0BU
#define USB_REQ_SYNCH_FRAME 0x0CU
/* Table 9-5. Descriptor Types of USB Specifications */
#define USB_DESC_TYPE_DEVICE 0x01U
#define USB_DESC_TYPE_CONFIGURATION 0x02U
#define USB_DESC_TYPE_STRING 0x03U
#define USB_DESC_TYPE_INTERFACE 0x04U
#define USB_DESC_TYPE_ENDPOINT 0x05U
#define USB_DESC_TYPE_DEVICE_QUALIFIER 0x06U
#define USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION 0x07U
#define USB_DESC_TYPE_INTERFACE_POWER 0x08U
#define USB_DESC_TYPE_HID 0x21U
#define USB_DESC_TYPE_HID_REPORT 0x22U
#define USB_DEVICE_DESC_SIZE 0x12U
#define USB_CONFIGURATION_DESC_SIZE 0x09U
#define USB_HID_DESC_SIZE 0x09U
#define USB_INTERFACE_DESC_SIZE 0x09U
#define USB_ENDPOINT_DESC_SIZE 0x07U
/* Descriptor Type and Descriptor Index */
/* Use the following values when calling the function USBH_GetDescriptor */
#define USB_DESC_DEVICE ((USB_DESC_TYPE_DEVICE << 8) & 0xFF00U)
#define USB_DESC_CONFIGURATION ((USB_DESC_TYPE_CONFIGURATION << 8) & 0xFF00U)
#define USB_DESC_STRING ((USB_DESC_TYPE_STRING << 8) & 0xFF00U)
#define USB_DESC_INTERFACE ((USB_DESC_TYPE_INTERFACE << 8) & 0xFF00U)
#define USB_DESC_ENDPOINT ((USB_DESC_TYPE_INTERFACE << 8) & 0xFF00U)
#define USB_DESC_DEVICE_QUALIFIER ((USB_DESC_TYPE_DEVICE_QUALIFIER << 8) & 0xFF00U)
#define USB_DESC_OTHER_SPEED_CONFIGURATION ((USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION << 8) & 0xFF00U)
#define USB_DESC_INTERFACE_POWER ((USB_DESC_TYPE_INTERFACE_POWER << 8) & 0xFF00U)
#define USB_DESC_HID_REPORT ((USB_DESC_TYPE_HID_REPORT << 8) & 0xFF00U)
#define USB_DESC_HID ((USB_DESC_TYPE_HID << 8) & 0xFF00U)
#define USB_EP_TYPE_CTRL 0x00U
#define USB_EP_TYPE_ISOC 0x01U
#define USB_EP_TYPE_BULK 0x02U
#define USB_EP_TYPE_INTR 0x03U
#define USB_EP_DIR_OUT 0x00U
#define USB_EP_DIR_IN 0x80U
#define USB_EP_DIR_MSK 0x80U
#ifndef USBH_MAX_PIPES_NBR
#define USBH_MAX_PIPES_NBR 16U
#endif /* USBH_MAX_PIPES_NBR */
#ifndef USBH_NAK_SOF_COUNT
#define USBH_NAK_SOF_COUNT 0x01U
#endif /* USBH_NAK_SOF_COUNT */
#define USBH_DEVICE_ADDRESS_DEFAULT 0x00U
#define USBH_DEVICE_ADDRESS 0x01U
#define USBH_MAX_ERROR_COUNT 0x02U
#if (USBH_USE_OS == 1U)
#define MSGQUEUE_OBJECTS 0x10U
#endif /* (USBH_USE_OS == 1U) */
/**
* @}
*/
#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 = 0U,
USBH_SPEED_FULL = 1U,
USBH_SPEED_LOW = 2U,
} USBH_SpeedTypeDef;
/* Following states are used for gState */
typedef enum
{
HOST_IDLE = 0U,
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_SET_WAKEUP_FEATURE,
HOST_CHECK_CLASS,
HOST_CLASS,
HOST_SUSPENDED,
HOST_ABORT_STATE,
} HOST_StateTypeDef;
/* Following states are used for EnumerationState */
typedef enum
{
ENUM_IDLE = 0U,
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 = 0U,
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 = 0U,
CMD_SEND,
CMD_WAIT
} CMD_StateTypeDef;
typedef enum
{
USBH_URB_IDLE = 0U,
USBH_URB_DONE,
USBH_URB_NOTREADY,
USBH_URB_NYET,
USBH_URB_ERROR,
USBH_URB_STALL,
USBH_URB_NAK_WAIT
} USBH_URBStateTypeDef;
typedef enum
{
USBH_PORT_EVENT = 1U,
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
{
uint8_t CfgDesc_Raw[USBH_MAX_SIZE_CONFIGURATION];
uint8_t Data[USBH_MAX_DATA_BUFFER];
uint8_t address;
uint8_t speed;
uint8_t EnumCnt;
uint8_t RstCnt;
__IO uint8_t is_connected;
__IO uint8_t is_disconnected;
__IO uint8_t is_ReEnumerated;
__IO uint8_t PortEnabled;
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[16];
__IO uint32_t Timer;
#if defined (USBH_IN_NAK_PROCESS) && (USBH_IN_NAK_PROCESS == 1U)
uint32_t NakTimer;
uint32_t NakTimeout;
#endif /* defined (USBH_IN_NAK_PROCESS) && (USBH_IN_NAK_PROCESS == 1U) */
uint32_t Timeout;
uint8_t id;
void *pData;
void (* pUser)(struct _USBH_HandleTypeDef *pHandle, uint8_t id);
#if (USBH_USE_OS == 1U)
#if osCMSIS < 0x20000
osMessageQId os_event;
osThreadId thread;
#else
osMessageQueueId_t os_event;
osThreadId_t thread;
#endif
uint32_t os_msg;
#endif /* (USBH_USE_OS == 1U) */
} USBH_HandleTypeDef;
#if defined ( __GNUC__ )
#ifndef __weak
#define __weak __attribute__((weak))
#endif /* __weak */
#ifndef __packed
#define __packed __attribute__((__packed__))
#endif /* __packed */
#endif /* __GNUC__ */
#ifdef __cplusplus
}
#endif
#endif /* USBH_DEF_H */
@@ -0,0 +1,157 @@
/**
******************************************************************************
* @file usbh_ioreq.h
* @author MCD Application Team
* @brief Header file for usbh_ioreq.c
******************************************************************************
* @attention
*
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Define to prevent recursive ----------------------------------------------*/
#ifndef __USBH_IOREQ_H
#define __USBH_IOREQ_H
#ifdef __cplusplus
extern "C" {
#endif
/* 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 0U
#define USBH_PID_DATA 1U
#define USBH_EP_CONTROL 0U
#define USBH_EP_ISO 1U
#define USBH_EP_BULK 2U
#define USBH_EP_INTERRUPT 3U
#define USBH_SETUP_PKT_SIZE 8U
/**
* @}
*/
/** @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 pipe_num);
USBH_StatusTypeDef USBH_CtlSendData(USBH_HandleTypeDef *phost,
uint8_t *buff,
uint16_t length,
uint8_t pipe_num,
uint8_t do_ping);
USBH_StatusTypeDef USBH_CtlReceiveData(USBH_HandleTypeDef *phost,
uint8_t *buff,
uint16_t length,
uint8_t pipe_num);
USBH_StatusTypeDef USBH_BulkReceiveData(USBH_HandleTypeDef *phost,
uint8_t *buff,
uint16_t length,
uint8_t pipe_num);
USBH_StatusTypeDef USBH_BulkSendData(USBH_HandleTypeDef *phost,
uint8_t *buff,
uint16_t length,
uint8_t pipe_num,
uint8_t do_ping);
USBH_StatusTypeDef USBH_InterruptReceiveData(USBH_HandleTypeDef *phost,
uint8_t *buff,
uint8_t length,
uint8_t pipe_num);
USBH_StatusTypeDef USBH_InterruptSendData(USBH_HandleTypeDef *phost,
uint8_t *buff,
uint8_t length,
uint8_t pipe_num);
USBH_StatusTypeDef USBH_IsocReceiveData(USBH_HandleTypeDef *phost,
uint8_t *buff,
uint32_t length,
uint8_t pipe_num);
USBH_StatusTypeDef USBH_IsocSendData(USBH_HandleTypeDef *phost,
uint8_t *buff,
uint32_t length,
uint8_t pipe_num);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __USBH_IOREQ_H */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
@@ -0,0 +1,122 @@
/**
******************************************************************************
* @file usbh_pipes.h
* @author MCD Application Team
* @brief Header file for usbh_pipes.c
******************************************************************************
* @attention
*
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Define to prevent recursive ----------------------------------------------*/
#ifndef __USBH_PIPES_H
#define __USBH_PIPES_H
#ifdef __cplusplus
extern "C" {
#endif
/* 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 pipe_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);
#if defined (USBH_IN_NAK_PROCESS) && (USBH_IN_NAK_PROCESS == 1U)
USBH_StatusTypeDef USBH_ActivatePipe(USBH_HandleTypeDef *phost,
uint8_t pipe_num);
#endif /* defined (USBH_IN_NAK_PROCESS) && (USBH_IN_NAK_PROCESS == 1U) */
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __USBH_PIPES_H */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
@@ -0,0 +1,328 @@
/**
******************************************************************************
* @file usbh_conf.c
* @author MCD Application Team
* @brief This file implements the board support package for the USB host library
******************************************************************************
* @attention
*
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* 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)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(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)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(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)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(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)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(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)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(phost);
USBH_SpeedTypeDef speed = USBH_SPEED_FULL;
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)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(phost);
return USBH_OK;
}
/**
* @brief USBH_LL_GetLastXferSize
* Return the last transferred packet size.
* @param phost: Host handle
* @param pipe: Pipe index
* @retval Packet Size
*/
uint32_t USBH_LL_GetLastXferSize(USBH_HandleTypeDef *phost, uint8_t pipe)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(phost);
UNUSED(pipe);
return 0U;
}
/**
* @brief USBH_LL_OpenPipe
* Open a pipe of the Low Level Driver.
* @param phost: Host handle
* @param pipe: 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,
uint8_t epnum,
uint8_t dev_address,
uint8_t speed,
uint8_t ep_type,
uint16_t mps)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(phost);
UNUSED(pipe);
UNUSED(epnum);
UNUSED(dev_address);
UNUSED(speed);
UNUSED(ep_type);
UNUSED(mps);
return USBH_OK;
}
/**
* @brief USBH_LL_ClosePipe
* Close a pipe of the Low Level Driver.
* @param phost: Host handle
* @param pipe: Pipe index
* @retval USBH Status
*/
USBH_StatusTypeDef USBH_LL_ClosePipe(USBH_HandleTypeDef *phost, uint8_t pipe)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(phost);
UNUSED(pipe);
return USBH_OK;
}
/**
* @brief USBH_LL_ActivatePipe
* Activate a pipe of the Low Level Driver.
* @param phost: Host handle
* @param pipe: Pipe index
* @retval USBH Status
*/
USBH_StatusTypeDef USBH_LL_ActivatePipe(USBH_HandleTypeDef *phost, uint8_t pipe)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(phost);
UNUSED(pipe);
return USBH_OK;
}
/**
* @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: Isochronous 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)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(phost);
UNUSED(pipe);
UNUSED(direction);
UNUSED(ep_type);
UNUSED(token);
UNUSED(pbuff);
UNUSED(length);
UNUSED(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)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(phost);
UNUSED(pipe);
return USBH_URB_IDLE;
}
/**
* @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 Inactive
* 1 : VBUS Active
* @retval Status
*/
USBH_StatusTypeDef USBH_LL_DriverVBUS(USBH_HandleTypeDef *phost, uint8_t state)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(phost);
UNUSED(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)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(phost);
UNUSED(pipe);
UNUSED(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)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(phost);
UNUSED(pipe);
uint8_t toggle = 0U;
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)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(Delay);
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,347 @@
/**
******************************************************************************
* @file usbh_ioreq.c
* @author MCD Application Team
* @brief This file handles the issuing of the USB transactions
******************************************************************************
* @attention
*
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* 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)
{
(void)USBH_LL_SubmitURB(phost, /* Driver handle */
pipe_num, /* Pipe index */
0U, /* Direction : OUT */
USBH_EP_CONTROL, /* EP type */
USBH_PID_SETUP, /* Type setup */
buff, /* data buffer */
USBH_SETUP_PKT_SIZE, /* data length */
0U);
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 = 0U;
}
(void)USBH_LL_SubmitURB(phost, /* Driver handle */
pipe_num, /* Pipe index */
0U, /* 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)
{
(void)USBH_LL_SubmitURB(phost, /* Driver handle */
pipe_num, /* Pipe index */
1U, /* Direction : IN */
USBH_EP_CONTROL, /* EP type */
USBH_PID_DATA, /* Type Data */
buff, /* data buffer */
length, /* data length */
0U);
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 = 0U;
}
(void)USBH_LL_SubmitURB(phost, /* Driver handle */
pipe_num, /* Pipe index */
0U, /* 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)
{
(void)USBH_LL_SubmitURB(phost, /* Driver handle */
pipe_num, /* Pipe index */
1U, /* Direction : IN */
USBH_EP_BULK, /* EP type */
USBH_PID_DATA, /* Type Data */
buff, /* data buffer */
length, /* data length */
0U);
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)
{
(void)USBH_LL_SubmitURB(phost, /* Driver handle */
pipe_num, /* Pipe index */
1U, /* Direction : IN */
USBH_EP_INTERRUPT, /* EP type */
USBH_PID_DATA, /* Type Data */
buff, /* data buffer */
(uint16_t)length, /* data length */
0U);
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)
{
(void)USBH_LL_SubmitURB(phost, /* Driver handle */
pipe_num, /* Pipe index */
0U, /* Direction : OUT */
USBH_EP_INTERRUPT, /* EP type */
USBH_PID_DATA, /* Type Data */
buff, /* data buffer */
(uint16_t)length, /* data length */
0U);
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)
{
(void)USBH_LL_SubmitURB(phost, /* Driver handle */
pipe_num, /* Pipe index */
1U, /* Direction : IN */
USBH_EP_ISO, /* EP type */
USBH_PID_DATA, /* Type Data */
buff, /* data buffer */
(uint16_t)length, /* data length */
0U);
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)
{
(void)USBH_LL_SubmitURB(phost, /* Driver handle */
pipe_num, /* Pipe index */
0U, /* Direction : OUT */
USBH_EP_ISO, /* EP type */
USBH_PID_DATA, /* Type Data */
buff, /* data buffer */
(uint16_t)length, /* data length */
0U);
return USBH_OK;
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
@@ -0,0 +1,200 @@
/**
******************************************************************************
* @file usbh_pipes.c
* @author MCD Application Team
* @brief This file implements functions for opening and closing Pipes
******************************************************************************
* @attention
*
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* 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)
{
(void)USBH_LL_OpenPipe(phost, pipe_num, epnum, dev_address, speed, ep_type, mps);
return USBH_OK;
}
#if defined (USBH_IN_NAK_PROCESS) && (USBH_IN_NAK_PROCESS == 1U)
/**
* @brief USBH_ActivatePipe
* Activate a pipe
* @param phost: Host Handle
* @param pipe_num: Pipe Number
* @retval USBH Status
*/
USBH_StatusTypeDef USBH_ActivatePipe(USBH_HandleTypeDef *phost, uint8_t pipe_num)
{
USBH_LL_ActivatePipe(phost, pipe_num);
return USBH_OK;
}
#endif /* defined (USBH_IN_NAK_PROCESS) && (USBH_IN_NAK_PROCESS == 1U) */
/**
* @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)
{
(void)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 != 0xFFFFU)
{
phost->Pipes[pipe & 0xFU] = (uint32_t)(0x8000U | ep_addr);
}
return (uint8_t)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 < USBH_MAX_PIPES_NBR)
{
phost->Pipes[idx] &= 0x7FFFU;
}
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 = 0U;
for (idx = 0U; idx < USBH_MAX_PIPES_NBR; idx++)
{
if ((phost->Pipes[idx] & 0x8000U) == 0U)
{
return (uint16_t)idx;
}
}
return 0xFFFFU;
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
@@ -0,0 +1,80 @@
SLA0044 Rev5/February 2018
## Software license agreement
### __ULTIMATE LIBERTY SOFTWARE LICENSE AGREEMENT__
BY INSTALLING, COPYING, DOWNLOADING, ACCESSING OR OTHERWISE USING THIS SOFTWARE
OR ANY PART THEREOF (AND THE RELATED DOCUMENTATION) FROM STMICROELECTRONICS
INTERNATIONAL N.V, SWISS BRANCH AND/OR ITS AFFILIATED COMPANIES
(STMICROELECTRONICS), THE RECIPIENT, ON BEHALF OF HIMSELF OR HERSELF, OR ON
BEHALF OF ANY ENTITY BY WHICH SUCH RECIPIENT IS EMPLOYED AND/OR ENGAGED AGREES
TO BE BOUND BY THIS SOFTWARE LICENSE AGREEMENT.
Under STMicroelectronics intellectual property rights, the redistribution,
reproduction and use in source and binary forms of the software or any part
thereof, with or without modification, are permitted provided that the following
conditions are met:
1. Redistribution of source code (modified or not) must retain any copyright
notice, this list of conditions and the disclaimer set forth below as items 10
and 11.
2. Redistributions in binary form, except as embedded into microcontroller or
microprocessor device manufactured by or for STMicroelectronics or a software
update for such device, must reproduce any copyright notice provided with the
binary code, this list of conditions, and the disclaimer set forth below as
items 10 and 11, in documentation and/or other materials provided with the
distribution.
3. Neither the name of STMicroelectronics nor the names of other contributors to
this software may be used to endorse or promote products derived from this
software or part thereof without specific written permission.
4. This software or any part thereof, including modifications and/or derivative
works of this software, must be used and execute solely and exclusively on or in
combination with a microcontroller or microprocessor device manufactured by or
for STMicroelectronics.
5. No use, reproduction or redistribution of this software partially or totally
may be done in any manner that would subject this software to any Open Source
Terms. “Open Source Terms” shall mean any open source license which requires as
part of distribution of software that the source code of such software is
distributed therewith or otherwise made available, or open source license that
substantially complies with the Open Source definition specified at
www.opensource.org and any other comparable open source license such as for
example GNU General Public License (GPL), Eclipse Public License (EPL), Apache
Software License, BSD license or MIT license.
6. STMicroelectronics has no obligation to provide any maintenance, support or
updates for the software.
7. The software is and will remain the exclusive property of STMicroelectronics
and its licensors. The recipient will not take any action that jeopardizes
STMicroelectronics and its licensors' proprietary rights or acquire any rights
in the software, except the limited rights specified hereunder.
8. The recipient shall comply with all applicable laws and regulations affecting
the use of the software or any part thereof including any applicable export
control law or regulation.
9. Redistribution and use of this software or any part thereof other than as
permitted under this license is void and will automatically terminate your
rights under this license.
10. THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY RIGHTS, WHICH ARE
DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT SHALL
STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
11. EXCEPT AS EXPRESSLY PERMITTED HEREUNDER, NO LICENSE OR OTHER RIGHTS, WHETHER
EXPRESS OR IMPLIED, ARE GRANTED UNDER ANY PATENT OR OTHER INTELLECTUAL PROPERTY
RIGHTS OF STMICROELECTRONICS OR ANY THIRD PARTY.
@@ -0,0 +1,36 @@
# Middleware USB Host MCU Component
![supported tag](https://img.shields.io/badge/tag-v3.5.0-brightgreen.svg)
## Overview
**STM32Cube** is an STMicroelectronics original initiative to ease developers' life by reducing efforts, time and cost.
**STM32Cube** covers the overall STM32 products portfolio. It includes a comprehensive embedded software platform delivered for each STM32 series.
* The CMSIS modules (core and device) corresponding to the ARM(tm) core implemented in this STM32 product.
* The STM32 HAL-LL drivers, an abstraction layer offering a set of APIs ensuring maximized portability across the STM32 portfolio.
* The BSP drivers of each evaluation, demonstration or nucleo board provided for this STM32 series.
* A consistent set of middleware libraries such as RTOS, USB, FatFS, graphics, touch sensing library...
* A full set of software projects (basic examples, applications, and demonstrations) for each board provided for this STM32 series.
Two models of publication are proposed for the STM32Cube embedded software:
* The monolithic **MCU Package**: all STM32Cube software modules of one STM32 series are present (Drivers, Middleware, Projects, Utilities) in the repository (usual name **STM32Cubexx**, xx corresponding to the STM32 series).
* The **MCU component**: each STM32Cube software module being part of the STM32Cube MCU Package, is delivered as an individual repository, allowing the user to select and get only the required software functions.
## Description
This **stm32_mw_usb_host** MCU component repository is one element **common to all** STM32Cube MCU embedded software packages, providing the **USB Host MCU Middleware** part.
It represents ST offer to ensure the support of USB Host role on STM32 MCUs.
It includes two main modules:
* **Core** module for the USB host standard peripheral control APIs. It includes the files ensuring USB 2.0 standard code implementation for an USB host.
These files APIs will be called within every USB Host application regardless the desired functionality.
* **Class** module for the commonly supported classes APIs. it includes the files including different USB host classes. All STM32 USB classes are implemented according to the USB 2.0 and every classs specifications. These files APIs will be called within USB Host applications according to the desired functionality.
## Release note
Details about the content of this release are available in the release note [here](https://htmlpreview.github.io/?https://github.com/STMicroelectronics/STM32CubeH7/blob/master/Middlewares/ST/STM32_USB_Host_Library/Release_Notes.html).
## Troubleshooting
Please refer to the [CONTRIBUTING.md](CONTRIBUTING.md) guide.
@@ -0,0 +1,809 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<meta charset="utf-8" />
<meta name="generator" content="pandoc" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
<title>Release Notes for STM32Cube USB Host Library</title>
<style>
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
span.underline{text-decoration: underline;}
div.column{display: inline-block; vertical-align: top; width: 50%;}
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
ul.task-list{list-style: none;}
.display.math{display: block; text-align: center; margin: 0.5rem auto;}
</style>
<link rel="stylesheet" href="_htmresc/mini-st.css" />
<link rel="icon" type="image/x-icon" href="_htmresc/favicon.png" />
<!--[if lt IE 9]>
<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
<![endif]-->
</head>
<body>
<div class="row">
<div class="col-sm-12 col-lg-4">
<center>
<h1 id="release-notes-for-stm32cube-usb-host-library">Release Notes for
<mark>STM32Cube USB Host Library</mark></h1>
<p>Copyright © 2015 STMicroelectronics<br />
</p>
<a href="https://www.st.com" class="logo"><img
src="_htmresc/st_logo_2020.png" alt="ST logo" /></a>
</center>
<h1 id="purpose">Purpose</h1>
<p>The USB host library comes on top of the STM32Cube™ USB host HAL
driver and offers all the APIs required to develop an USB host
application.</p>
<p>The main USB host library features are:</p>
<ul>
<li>Support of multi packet transfer features allowing the reception of
big amount of data without splitting it into max packet size
transfers.</li>
<li>Support of most common USB Class drivers (HID, CDC, MSC, MTP,
AUDIO1.0)</li>
<li>Configuration files to interface with Cube HAL and change the
library configuration without changing the library code (Read
Only).</li>
<li>32-bits aligned data structures to handle DMA based transfer in High
speed modes.</li>
</ul>
<p>Here is the list of references to user documents:</p>
<ul>
<li><a
href="https://www.st.com/resource/en/user_manual/dm00105256-stm32cube-usb-host-library-stmicroelectronics.pdf">UM1720</a>
: STM32Cube USB host library User Manual</li>
<li><a href="https://wiki.st.com/stm32mcu/wiki/USB_overview">Wiki
Page</a> : STM32Cube USB Wiki Page</li>
</ul>
</div>
<section id="update-history" class="col-sm-12 col-lg-8">
<h1>Update History</h1>
<div class="collapse">
<input type="checkbox" id="collapse-section20" checked aria-hidden="true"><label for="collapse-section20" aria-hidden="true">V3.5.3 / 26-September-2024</label>
<div>
<h2 id="main-changes">Main Changes</h2>
<table>
<thead>
<tr class="header">
<th style="text-align: left;">Headline</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;"><strong>Core</strong></td>
</tr>
<tr class="even">
<td style="text-align: left;">Improve usage of CMSIS RTOS message queue</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Add new API to allow activating USB host pipe from STM32 HAL</td>
</tr>
<tr class="even">
<td style="text-align: left;"><strong>HID Class</strong></td>
</tr>
<tr class="odd">
<td style="text-align: left;"> Fix keyboard layout mapping for AZERTY keyboards</td>
</tr>
<tr class="even">
<td style="text-align: left;"> Add escape to Keyboard layouts mapping</td>
</tr>
<tr class="odd">
<td style="text-align: left;"><strong>MSC/CDC/MTP Classes</strong></td>
</tr>
<tr class="even">
<td style="text-align: left;">Allow re-activating host IN channel based on SOF timer to reduce NAK IT with some USB peripherals</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="collapse">
<input type="checkbox" id="collapse-section19" aria-hidden="true"><label for="collapse-section19" aria-hidden="true">V3.5.2 / 11-December-2023</label>
<div>
<h2 id="main-changes">Main Changes</h2>
<table>
<thead>
<tr class="header">
<th style="text-align: left;">Headline</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;"><strong>Core</strong></td>
</tr>
<tr class="even">
<td style="text-align: left;">Avoid infinite loop in case device descriptor length was wrongly set to zero</td>
</tr>
<tr class="odd">
<td style="text-align: left;"><strong>MSC Class</strong></td>
</tr>
<tr class="even">
<td style="text-align: left;">Add support of multi-LUN storage devices</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Report error for non-ready media</td>
</tr>
<tr class="even">
<td style="text-align: left;"><strong>Audio Class</strong></td>
</tr>
<tr class="odd">
<td style="text-align: left;">Report error for unsupported audio sample rate</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="collapse">
<input type="checkbox" id="collapse-section18" aria-hidden="true"><label for="collapse-section18" aria-hidden="true">V3.5.1 / 10-January-2023</label>
<div>
<h2 id="main-changes">Main Changes</h2>
<table>
<thead>
<tr class="header">
<th style="text-align: left;">Headline</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;"><strong>Core</strong></td>
</tr>
<tr class="even">
<td style="text-align: left;">Ensure the number of endpoints parsed does not exceed defined USBH_MAX_NUM_ENDPOINTS</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Use correct endpoint length for audio midi subclass devices</td>
</tr>
<tr class="even">
<td style="text-align: left;"><strong>HID Class</strong></td>
</tr>
<tr class="odd">
<td style="text-align: left;">Prevent buffer overflow during HID get descriptors</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="collapse">
<input type="checkbox" id="collapse-section17" aria-hidden="true"><label for="collapse-section17" aria-hidden="true">V3.5.0 / 05-August-2022</label>
<div>
<h2 id="main-changes">Main Changes</h2>
<table>
<thead>
<tr class="header">
<th style="text-align: left;">Headline</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;"><strong>Core</strong></td>
</tr>
<tr class="even">
<td style="text-align: left;">Fix potential corruption of Endpoints MaxPacketSize</td>
</tr>
<tr class="odd">
<td style="text-align: left;"><strong>HID Class</strong></td>
</tr>
<tr class="even">
<td style="text-align: left;">Fix potential buffer overflow</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="collapse">
<input type="checkbox" id="collapse-section16" aria-hidden="true"><label for="collapse-section16" aria-hidden="true">V3.4.1 / 04-April-2022</label>
<div>
<h2 id="main-changes">Main Changes</h2>
<table>
<thead>
<tr class="header">
<th style="text-align: left;">Headline</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">Update the way to declare licenses</td>
</tr>
<tr class="even">
<td style="text-align: left;">Fix code spelling and improve code
style</td>
</tr>
<tr class="odd">
<td style="text-align: left;"><strong>HID Class</strong></td>
</tr>
<tr class="even">
<td style="text-align: left;">Modify some variables names to avoid
duplication versus device for HID class</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="collapse">
<input type="checkbox" id="collapse-section15" aria-hidden="true"><label for="collapse-section15" aria-hidden="true">V3.4.0 / 23-April-2021</label>
<div>
<h2 id="main-changes-1">Main Changes</h2>
<table>
<thead>
<tr class="header">
<th style="text-align: left;">Headline</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;"><strong>Core driver:</strong></td>
</tr>
<tr class="even">
<td style="text-align: left;">Fixes added to free RTOS resource during
USB host DeInit</td>
</tr>
<tr class="odd">
<td style="text-align: left;">CodeSpell and mcuAstlye fixes</td>
</tr>
<tr class="even">
<td style="text-align: left;">Multiple MisraC 2012 fixes</td>
</tr>
<tr class="odd">
<td style="text-align: left;"><strong>All Classes:</strong></td>
</tr>
<tr class="even">
<td style="text-align: left;">CodeSpell and mcuAstlye fixes</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Multiple MisraC 2012 fixes</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="collapse">
<input type="checkbox" id="collapse-section14" aria-hidden="true"><label for="collapse-section14" aria-hidden="true">V3.3.5 / 26-January-2021</label>
<div>
<h2 id="main-changes-2">Main Changes</h2>
<table>
<thead>
<tr class="header">
<th style="text-align: left;">Headline</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;"><strong>Core driver:</strong></td>
</tr>
<tr class="even">
<td style="text-align: left;">Improve enumeration phase by adding some
specifications requirements checks.</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Add error signaling for some out of
specification devices descriptors fields.</td>
</tr>
<tr class="even">
<td style="text-align: left;"><strong>MSC Class:</strong></td>
</tr>
<tr class="odd">
<td style="text-align: left;">usbh_msc.c: add checking on both IN and
OUT pipes construction.</td>
</tr>
<tr class="even">
<td style="text-align: left;"><strong>HID Class:</strong></td>
</tr>
<tr class="odd">
<td style="text-align: left;">Fix wrong keyboard key defines.</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="collapse">
<input type="checkbox" id="collapse-section13" aria-hidden="true"><label for="collapse-section13" aria-hidden="true">V3.3.4 / 08-January-2020</label>
<div>
<h2 id="main-changes-3">Main Changes</h2>
<table>
<thead>
<tr class="header">
<th style="text-align: left;">Headline</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;"><strong>Core driver:</strong></td>
</tr>
<tr class="even">
<td style="text-align: left;">Improve enumeration phase and avoid silent
responses.</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Add device reset trial mechanism during
enumeration phase.</td>
</tr>
<tr class="even">
<td style="text-align: left;"><strong>MSC Class:</strong></td>
</tr>
<tr class="odd">
<td style="text-align: left;">usbh_msc.c: update max_lun field to be
uint8_t instead of uint32_t.</td>
</tr>
<tr class="even">
<td style="text-align: left;"><strong>HID Class:</strong></td>
</tr>
<tr class="odd">
<td style="text-align: left;">Get HID descriptor by parsing the device
descriptor in order to improve interoperability with buggy devices that
Stall host Get HID descriptor request.</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="collapse">
<input type="checkbox" id="collapse-section12" aria-hidden="true"><label for="collapse-section12" aria-hidden="true">V3.3.3 / 29-April-2019</label>
<div>
<h2 id="main-changes-4">Main Changes</h2>
<table>
<thead>
<tr class="header">
<th style="text-align: left;">Headline</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">Fix misra-C 2012 high severity
violations</td>
</tr>
<tr class="even">
<td style="text-align: left;"><strong>Core driver:</strong></td>
</tr>
<tr class="odd">
<td style="text-align: left;">usbh_core.c: Rework USB host Core process
in order to improve Device connection / disconnection robustness</td>
</tr>
<tr class="even">
<td style="text-align: left;"><strong>MSC Class:</strong></td>
</tr>
<tr class="odd">
<td style="text-align: left;">usbh_msc.c: Update USBH_MSC_GetMaxLUN() to
prevent corruption of supported LUNs</td>
</tr>
<tr class="even">
<td style="text-align: left;"><strong>HID Class:</strong></td>
</tr>
<tr class="odd">
<td style="text-align: left;">Prevent race between USB buffer and
Application fifo buffer, this was ensured by allocating a dedicated
buffer for received report</td>
</tr>
<tr class="even">
<td style="text-align: left;">Prevent overflow on USB buffer for devices
that could have report size greater than 4bytes</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="collapse">
<input type="checkbox" id="collapse-section11" aria-hidden="true"><label for="collapse-section11" aria-hidden="true">V3.3.2 / 24-January-2019</label>
<div>
<h2 id="main-changes-5">Main Changes</h2>
<table>
<thead>
<tr class="header">
<th style="text-align: left;">Headline</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;"><strong>Core driver:</strong></td>
</tr>
<tr class="even">
<td style="text-align: left;">usbh_core.c: fix on USBH_Deinit() API,
prevent freeing pActiveClass-&gt;pData pointer during host Deinit, this
is manged by the Class drivers.</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="collapse">
<input type="checkbox" id="collapse-section10" aria-hidden="true"><label for="collapse-section10" aria-hidden="true">V3.3.1 / 09-July-2018</label>
<div>
<h2 id="main-changes-6">Main Changes</h2>
<table>
<thead>
<tr class="header">
<th style="text-align: left;">Headline</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">Fix interoperability issue with HP
mouse</td>
</tr>
<tr class="even">
<td style="text-align: left;">Add compatibility with FreeRTOS CMSIS V2
API changes</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Update License section and add link to get
copy of ST Ultimate Liberty license SLA0044</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="collapse">
<input type="checkbox" id="collapse-section9" aria-hidden="true"><label for="collapse-section9" aria-hidden="true">V3.3.0 / 23-January-2018</label>
<div>
<h2 id="main-changes-7">Main Changes</h2>
<table>
<thead>
<tr class="header">
<th style="text-align: left;">Headline</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">Update license section to Ultimate
Liberty</td>
</tr>
<tr class="even">
<td style="text-align: left;">Update some functions to be MISRA-C 2004
compliant</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Improve USB Core enumeration state
machine</td>
</tr>
<tr class="even">
<td style="text-align: left;">Fix Device fast plug/unplug issue</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Improve interoperability with non
compliant USB devices</td>
</tr>
<tr class="even">
<td style="text-align: left;">Add support of Host set remote wakeup
enable feature</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Fix USB Host MSC set correct sector
size</td>
</tr>
<tr class="even">
<td style="text-align: left;">MSC: Set correct LUN number if returned
LUN number exceeds max supported value</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="collapse">
<input type="checkbox" id="collapse-section8" aria-hidden="true"><label for="collapse-section8" aria-hidden="true">V3.2.2 / 07-July-2015</label>
<div>
<h2 id="main-changes-8">Main Changes</h2>
<table>
<thead>
<tr class="header">
<th style="text-align: left;">Headline</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;"><strong>MSC Class:</strong></td>
</tr>
<tr class="even">
<td style="text-align: left;">usbh_msc.c: Fix MSC Get Ready Delay
issue</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="collapse">
<input type="checkbox" id="collapse-section7" aria-hidden="true"><label for="collapse-section7" aria-hidden="true">V3.2.1 / 26-June-2015</label>
<div>
<h2 id="main-changes-9">Main Changes</h2>
<table>
<thead>
<tr class="header">
<th style="text-align: left;">Headline</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;"><strong>Core driver:</strong></td>
</tr>
<tr class="even">
<td style="text-align: left;">usbh_def.h: update USBH_MAX_PIPES_NBR
literal definition to be conditioned by #ifndef directive, to allow
application code to change its value (i.e. in the compiler
preprocessor)</td>
</tr>
<tr class="odd">
<td style="text-align: left;"><strong>MSC Class:</strong></td>
</tr>
<tr class="even">
<td style="text-align: left;">usbh_msc.c:</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Update USBH_MSC_GetMaxLUN() to return the
correct number of supported LUNs (was returning 0xFF)</td>
</tr>
<tr class="even">
<td style="text-align: left;">Fix timeout calculation issue</td>
</tr>
<tr class="odd">
<td style="text-align: left;">usbh_msc.h:</td>
</tr>
<tr class="even">
<td style="text-align: left;">update MAX_SUPPORTED_LUN literal
definition to be conditioned by #ifndef directive, to allow application
code to change its value (i.e.in the compiler preprocessor)</td>
</tr>
<tr class="odd">
<td style="text-align: left;"><strong>HID Class:</strong></td>
</tr>
<tr class="even">
<td style="text-align: left;">usbh_hid.h: fix HIDs handle “Timer” type
to uint32_t instead of uint16_t</td>
</tr>
<tr class="odd">
<td style="text-align: left;"><strong>MTP Class:</strong></td>
</tr>
<tr class="even">
<td style="text-align: left;">usbh_mtp.c : Fix timeout calculation
issue</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="collapse">
<input type="checkbox" id="collapse-section6" aria-hidden="true"><label for="collapse-section6" aria-hidden="true">V3.2.0 / 04-November-2014</label>
<div>
<h2 id="main-changes-10">Main Changes</h2>
<table>
<thead>
<tr class="header">
<th style="text-align: left;">Headline</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">Update all drivers to be C++
compliant</td>
</tr>
<tr class="even">
<td style="text-align: left;">Miscellaneous source code comments
update</td>
</tr>
<tr class="odd">
<td style="text-align: left;"><strong>Core driver</strong></td>
</tr>
<tr class="even">
<td style="text-align: left;">usbh_core.c: remove HOST_IDLE state in
USBH_LL_Connect() function</td>
</tr>
<tr class="odd">
<td style="text-align: left;"><strong>MSC class</strong></td>
</tr>
<tr class="even">
<td style="text-align: left;">Update to manage correctly older USB Keys
that do not support GetMaxLun request</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="collapse">
<input type="checkbox" id="collapse-section5" aria-hidden="true"><label for="collapse-section5" aria-hidden="true">V3.1.0 / 19-June-2014</label>
<div>
<h2 id="main-changes-11">Main Changes</h2>
<table>
<thead>
<tr class="header">
<th style="text-align: left;">Headline</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;"><strong>Core driver</strong></td>
</tr>
<tr class="even">
<td style="text-align: left;">Add a new define USBH_PROCESS_STACK_SIZE
in the usbh_conf.h file to change the default internal USB host process
stack. Note that by omitting this define, the default stack size (2KB)
is used</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Add a user callback to handle
unrecoverable error case in the application</td>
</tr>
<tr class="even">
<td style="text-align: left;">Remove the wrong check on the interface
descriptor index in the USBH_FindInterface() function</td>
</tr>
<tr class="odd">
<td style="text-align: left;"><strong>All classes</strong></td>
</tr>
<tr class="even">
<td style="text-align: left;">Update class description in files comment
by adding reference to the used USB class specification revision</td>
</tr>
<tr class="odd">
<td style="text-align: left;"><strong>Audio, CDC and MTP
classes</strong></td>
</tr>
<tr class="even">
<td style="text-align: left;">Add full RTOS support by handling state
transitions through OS messages</td>
</tr>
<tr class="odd">
<td style="text-align: left;"><strong>HID class</strong></td>
</tr>
<tr class="even">
<td style="text-align: left;">Add new API USBH_HID_GetPollInterval() to
allow user to retrieve the needed poll time (interval between two
USBD_HID_SendReport())</td>
</tr>
<tr class="odd">
<td style="text-align: left;"><strong>Audio class</strong></td>
</tr>
<tr class="even">
<td style="text-align: left;">Add a new weak callback
USBH_AUDIO_BufferEmptyCallback() to indicate the end of audio data
processing on the user buffer</td>
</tr>
<tr class="odd">
<td style="text-align: left;"><strong>MSC class</strong></td>
</tr>
<tr class="even">
<td style="text-align: left;">Return mass storage device capacity in
Bytes in the user log message instead of MBytes</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="collapse">
<input type="checkbox" id="collapse-section4" aria-hidden="true"><label for="collapse-section4" aria-hidden="true">V3.0.0 / 18-February-2014</label>
<div>
<h2 id="main-changes-12">Main Changes</h2>
<table>
<thead>
<tr class="header">
<th style="text-align: left;">Headline</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">Major update based on STM32Cube
specification: Library Core, Classes architecture and APIs modified
vs. V2.1.0, and thus the 2 versions are not compatible.</td>
</tr>
<tr class="even">
<td style="text-align: left;"><strong>This version has to be used only
with STM32Cube based development</strong></td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="collapse">
<input type="checkbox" id="collapse-section3" aria-hidden="true"><label for="collapse-section3" aria-hidden="true">V2.1.0 / 19-March-2012</label>
<div>
<h2 id="main-changes-13">Main Changes</h2>
<table>
<thead>
<tr class="header">
<th style="text-align: left;">Headline</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">Official support of STM32F4xx devices</td>
</tr>
<tr class="even">
<td style="text-align: left;">All source files: license disclaimer text
update and add link to the License file on ST Internet</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Add ISR structure to link the low level
driver to the Host library</td>
</tr>
<tr class="even">
<td style="text-align: left;">Change length parameter in the I/O
operations to handle large amount of data</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Enhance the configuration descriptor
parsing method to take into account multi interface devices</td>
</tr>
<tr class="even">
<td style="text-align: left;">Miscellaneous bug fix</td>
</tr>
<tr class="odd">
<td style="text-align: left;"><strong>HID class</strong></td>
</tr>
<tr class="even">
<td style="text-align: left;">Remove blocking even frame synchronization
loop</td>
</tr>
<tr class="odd">
<td style="text-align: left;"><strong>MSC class</strong></td>
</tr>
<tr class="even">
<td style="text-align: left;">Handle correctly the BOT transfer with
length &lt; max length</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Handle multi sector length data in the FAT
FS interface</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="collapse">
<input type="checkbox" id="collapse-section2" aria-hidden="true"><label for="collapse-section2" aria-hidden="true">V2.0.0 / 22-July-2011</label>
<div>
<h2 id="main-changes-14">Main Changes</h2>
<table>
<thead>
<tr class="header">
<th style="text-align: left;">Headline</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">econd official version supporting
STM32F105/7 and STM32F2xx devices</td>
</tr>
<tr class="even">
<td style="text-align: left;">dd support for <strong>STM32F2xx</strong>
devices</td>
</tr>
<tr class="odd">
<td style="text-align: left;">dd multi interface feature</td>
</tr>
<tr class="even">
<td style="text-align: left;">dd dynamic configuration parsing</td>
</tr>
<tr class="odd">
<td style="text-align: left;">dd USBH_DeAllocate_AllChannel function in
the Host channel management layer to clean up channels allocation table
when de-initializing the library</td>
</tr>
<tr class="even">
<td style="text-align: left;">hange the core layer to stop correctly the
host core and free all allocated channels</td>
</tr>
<tr class="odd">
<td style="text-align: left;">dd usbh_conf.h file in the application
layer to customize some user parameters</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="collapse">
<input type="checkbox" id="collapse-section1" aria-hidden="true"><label for="collapse-section1" aria-hidden="true">V1.0.0 / 29-November-2010</label>
<div>
<h2 id="main-changes-15">Main Changes</h2>
<p>Created</p>
</div>
</section>
</div>
</div>
<footer class="sticky">
<div class="columns">
<div class="column" style="width:95%;">
</div><div class="column" style="width:5%;">
<p><abbr title="Based on template cx566953 version 2.1">Info</abbr></p>
</div>
</div>
</footer>
</body>
</html>
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

File diff suppressed because it is too large Load Diff
Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB