Added more STM32 USB libraries.

This commit is contained in:
Solomon Peachy 2013-09-17 10:59:12 -04:00
parent 9fe33784e8
commit 7883bfc9d8
82 changed files with 28845 additions and 0 deletions

View File

@ -0,0 +1,164 @@
/**
******************************************************************************
* @file usbd_audio_core.h
* @author MCD Application Team
* @version V1.1.0
* @date 19-March-2012
* @brief header file for the usbd_audio_core.c file.
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#ifndef __USB_AUDIO_CORE_H_
#define __USB_AUDIO_CORE_H_
#include "usbd_ioreq.h"
#include "usbd_req.h"
#include "usbd_desc.h"
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
* @{
*/
/** @defgroup usbd_audio
* @brief This file is the Header file for USBD_audio.c
* @{
*/
/** @defgroup usbd_audio_Exported_Defines
* @{
*/
/* AudioFreq * DataSize (2 bytes) * NumChannels (Stereo: 2) */
#define AUDIO_OUT_PACKET (uint32_t)(((USBD_AUDIO_FREQ * 2 * 2) /1000))
/* Number of sub-packets in the audio transfer buffer. You can modify this value but always make sure
that it is an even number and higher than 3 */
#define OUT_PACKET_NUM 4
/* Total size of the audio transfer buffer */
#define TOTAL_OUT_BUF_SIZE ((uint32_t)(AUDIO_OUT_PACKET * OUT_PACKET_NUM))
#define AUDIO_CONFIG_DESC_SIZE 109
#define AUDIO_INTERFACE_DESC_SIZE 9
#define USB_AUDIO_DESC_SIZ 0x09
#define AUDIO_STANDARD_ENDPOINT_DESC_SIZE 0x09
#define AUDIO_STREAMING_ENDPOINT_DESC_SIZE 0x07
#define AUDIO_DESCRIPTOR_TYPE 0x21
#define USB_DEVICE_CLASS_AUDIO 0x01
#define AUDIO_SUBCLASS_AUDIOCONTROL 0x01
#define AUDIO_SUBCLASS_AUDIOSTREAMING 0x02
#define AUDIO_PROTOCOL_UNDEFINED 0x00
#define AUDIO_STREAMING_GENERAL 0x01
#define AUDIO_STREAMING_FORMAT_TYPE 0x02
/* Audio Descriptor Types */
#define AUDIO_INTERFACE_DESCRIPTOR_TYPE 0x24
#define AUDIO_ENDPOINT_DESCRIPTOR_TYPE 0x25
/* Audio Control Interface Descriptor Subtypes */
#define AUDIO_CONTROL_HEADER 0x01
#define AUDIO_CONTROL_INPUT_TERMINAL 0x02
#define AUDIO_CONTROL_OUTPUT_TERMINAL 0x03
#define AUDIO_CONTROL_FEATURE_UNIT 0x06
#define AUDIO_INPUT_TERMINAL_DESC_SIZE 0x0C
#define AUDIO_OUTPUT_TERMINAL_DESC_SIZE 0x09
#define AUDIO_STREAMING_INTERFACE_DESC_SIZE 0x07
#define AUDIO_CONTROL_MUTE 0x0001
#define AUDIO_FORMAT_TYPE_I 0x01
#define AUDIO_FORMAT_TYPE_III 0x03
#define USB_ENDPOINT_TYPE_ISOCHRONOUS 0x01
#define AUDIO_ENDPOINT_GENERAL 0x01
#define AUDIO_REQ_GET_CUR 0x81
#define AUDIO_REQ_SET_CUR 0x01
#define AUDIO_OUT_STREAMING_CTRL 0x02
/**
* @}
*/
/** @defgroup USBD_CORE_Exported_TypesDefinitions
* @{
*/
typedef struct _Audio_Fops
{
uint8_t (*Init) (uint32_t AudioFreq, uint32_t Volume, uint32_t options);
uint8_t (*DeInit) (uint32_t options);
uint8_t (*AudioCmd) (uint8_t* pbuf, uint32_t size, uint8_t cmd);
uint8_t (*VolumeCtl) (uint8_t vol);
uint8_t (*MuteCtl) (uint8_t cmd);
uint8_t (*PeriodicTC) (uint8_t cmd);
uint8_t (*GetState) (void);
}AUDIO_FOPS_TypeDef;
/**
* @}
*/
/** @defgroup USBD_CORE_Exported_Macros
* @{
*/
#define AUDIO_PACKET_SZE(frq) (uint8_t)(((frq * 2 * 2)/1000) & 0xFF), \
(uint8_t)((((frq * 2 * 2)/1000) >> 8) & 0xFF)
#define SAMPLE_FREQ(frq) (uint8_t)(frq), (uint8_t)((frq >> 8)), (uint8_t)((frq >> 16))
/**
* @}
*/
/** @defgroup USBD_CORE_Exported_Variables
* @{
*/
extern USBD_Class_cb_TypeDef AUDIO_cb;
/**
* @}
*/
/** @defgroup USB_CORE_Exported_Functions
* @{
*/
/**
* @}
*/
#endif // __USB_AUDIO_CORE_H_
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,125 @@
/**
******************************************************************************
* @file usbd_audio_out_if.h
* @author MCD Application Team
* @version V1.1.0
* @date 19-March-2012
* @brief header file for the usbd_audio_out_if.c file.
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#ifndef __USB_AUDIO_OUT_IF_H_
#define __USB_AUDIO_OUT_IF_H_
#ifdef STM32F2XX
#include "stm322xg_usb_audio_codec.h"
#elif defined(STM32F4XX)
#include "stm324xg_usb_audio_codec.h"
#elif defined(STM32F10X_CL)
#include "stm3210c_usb_audio_codec.h"
#endif /* STM32F2XX */
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
* @{
*/
/** @defgroup usbd_audio
* @brief This file is the Header file for USBD_audio.c
* @{
*/
/** @defgroup usbd_audio_Exported_Defines
* @{
*/
/* Audio Commands enmueration */
typedef enum
{
AUDIO_CMD_PLAY = 1,
AUDIO_CMD_PAUSE,
AUDIO_CMD_STOP,
}AUDIO_CMD_TypeDef;
/* Mute commands */
#define AUDIO_MUTE 0x01
#define AUDIO_UNMUTE 0x00
/* Functions return value */
#define AUDIO_OK 0x00
#define AUDIO_FAIL 0xFF
/* Audio Machine States */
#define AUDIO_STATE_INACTIVE 0x00
#define AUDIO_STATE_ACTIVE 0x01
#define AUDIO_STATE_PLAYING 0x02
#define AUDIO_STATE_PAUSED 0x03
#define AUDIO_STATE_STOPPED 0x04
#define AUDIO_STATE_ERROR 0x05
/**
* @}
*/
/** @defgroup USBD_CORE_Exported_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @defgroup USBD_CORE_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBD_CORE_Exported_Variables
* @{
*/
extern AUDIO_FOPS_TypeDef AUDIO_OUT_fops;
/**
* @}
*/
/** @defgroup USB_CORE_Exported_Functions
* @{
*/
/**
* @}
*/
#endif /* __USB_AUDIO_OUT_IF_H_ */
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,671 @@
/**
******************************************************************************
* @file usbd_audio_core.c
* @author MCD Application Team
* @version V1.1.0
* @date 19-March-2012
* @brief This file provides the high layer firmware functions to manage the
* following functionalities of the USB Audio Class:
* - Initialization and Configuration of high and low layer
* - Enumeration as Audio Streaming Device
* - Audio Streaming data transfer
* - AudioControl requests management
* - Error management
*
* @verbatim
*
* ===================================================================
* Audio Class Driver Description
* ===================================================================
* This driver manages the Audio Class 1.0 following the "USB Device Class Definition for
* Audio Devices V1.0 Mar 18, 98".
* This driver implements the following aspects of the specification:
* - Device descriptor management
* - Configuration descriptor management
* - Standard AC Interface Descriptor management
* - 1 Audio Streaming Interface (with single channel, PCM, Stereo mode)
* - 1 Audio Streaming Endpoint
* - 1 Audio Terminal Input (1 channel)
* - Audio Class-Specific AC Interfaces
* - Audio Class-Specific AS Interfaces
* - AudioControl Requests: only SET_CUR and GET_CUR requests are supported (for Mute)
* - Audio Feature Unit (limited to Mute control)
* - Audio Synchronization type: Asynchronous
* - Single fixed audio sampling rate (configurable in usbd_conf.h file)
*
* @note
* The Audio Class 1.0 is based on USB Specification 1.0 and thus supports only
* Low and Full speed modes and does not allow High Speed transfers.
* Please refer to "USB Device Class Definition for Audio Devices V1.0 Mar 18, 98"
* for more details.
*
* These aspects may be enriched or modified for a specific user application.
*
* This driver doesn't implement the following aspects of the specification
* (but it is possible to manage these features with some modifications on this driver):
* - AudioControl Endpoint management
* - AudioControl requsests other than SET_CUR and GET_CUR
* - Abstraction layer for AudioControl requests (only Mute functionality is managed)
* - Audio Synchronization type: Adaptive
* - Audio Compression modules and interfaces
* - MIDI interfaces and modules
* - Mixer/Selector/Processing/Extension Units (Feature unit is limited to Mute control)
* - Any other application-specific modules
* - Multiple and Variable audio sampling rates
* - Out Streaming Endpoint/Interface (microphone)
*
* @endverbatim
*
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "usbd_audio_core.h"
#include "usbd_audio_out_if.h"
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
* @{
*/
/** @defgroup usbd_audio
* @brief usbd core module
* @{
*/
/** @defgroup usbd_audio_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @defgroup usbd_audio_Private_Defines
* @{
*/
/**
* @}
*/
/** @defgroup usbd_audio_Private_Macros
* @{
*/
/**
* @}
*/
/** @defgroup usbd_audio_Private_FunctionPrototypes
* @{
*/
/*********************************************
AUDIO Device library callbacks
*********************************************/
static uint8_t usbd_audio_Init (void *pdev, uint8_t cfgidx);
static uint8_t usbd_audio_DeInit (void *pdev, uint8_t cfgidx);
static uint8_t usbd_audio_Setup (void *pdev, USB_SETUP_REQ *req);
static uint8_t usbd_audio_EP0_RxReady(void *pdev);
static uint8_t usbd_audio_DataIn (void *pdev, uint8_t epnum);
static uint8_t usbd_audio_DataOut (void *pdev, uint8_t epnum);
static uint8_t usbd_audio_SOF (void *pdev);
static uint8_t usbd_audio_OUT_Incplt (void *pdev);
/*********************************************
AUDIO Requests management functions
*********************************************/
static void AUDIO_Req_GetCurrent(void *pdev, USB_SETUP_REQ *req);
static void AUDIO_Req_SetCurrent(void *pdev, USB_SETUP_REQ *req);
static uint8_t *USBD_audio_GetCfgDesc (uint8_t speed, uint16_t *length);
/**
* @}
*/
/** @defgroup usbd_audio_Private_Variables
* @{
*/
/* Main Buffer for Audio Data Out transfers and its relative pointers */
uint8_t IsocOutBuff [TOTAL_OUT_BUF_SIZE * 2];
uint8_t* IsocOutWrPtr = IsocOutBuff;
uint8_t* IsocOutRdPtr = IsocOutBuff;
/* Main Buffer for Audio Control Rrequests transfers and its relative variables */
uint8_t AudioCtl[64];
uint8_t AudioCtlCmd = 0;
uint32_t AudioCtlLen = 0;
uint8_t AudioCtlUnit = 0;
static uint32_t PlayFlag = 0;
static __IO uint32_t usbd_audio_AltSet = 0;
static uint8_t usbd_audio_CfgDesc[AUDIO_CONFIG_DESC_SIZE];
/* AUDIO interface class callbacks structure */
USBD_Class_cb_TypeDef AUDIO_cb =
{
usbd_audio_Init,
usbd_audio_DeInit,
usbd_audio_Setup,
NULL, /* EP0_TxSent */
usbd_audio_EP0_RxReady,
usbd_audio_DataIn,
usbd_audio_DataOut,
usbd_audio_SOF,
NULL,
usbd_audio_OUT_Incplt,
USBD_audio_GetCfgDesc,
#ifdef USB_OTG_HS_CORE
USBD_audio_GetCfgDesc, /* use same config as per FS */
#endif
};
/* USB AUDIO device Configuration Descriptor */
static uint8_t usbd_audio_CfgDesc[AUDIO_CONFIG_DESC_SIZE] =
{
/* Configuration 1 */
0x09, /* bLength */
USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType */
LOBYTE(AUDIO_CONFIG_DESC_SIZE), /* wTotalLength 109 bytes*/
HIBYTE(AUDIO_CONFIG_DESC_SIZE),
0x02, /* bNumInterfaces */
0x01, /* bConfigurationValue */
0x00, /* iConfiguration */
0xC0, /* bmAttributes BUS Powred*/
0x32, /* bMaxPower = 100 mA*/
/* 09 byte*/
/* USB Speaker Standard interface descriptor */
AUDIO_INTERFACE_DESC_SIZE, /* bLength */
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
0x00, /* bInterfaceNumber */
0x00, /* bAlternateSetting */
0x00, /* bNumEndpoints */
USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */
AUDIO_SUBCLASS_AUDIOCONTROL, /* bInterfaceSubClass */
AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */
0x00, /* iInterface */
/* 09 byte*/
/* USB Speaker Class-specific AC Interface Descriptor */
AUDIO_INTERFACE_DESC_SIZE, /* bLength */
AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
AUDIO_CONTROL_HEADER, /* bDescriptorSubtype */
0x00, /* 1.00 */ /* bcdADC */
0x01,
0x27, /* wTotalLength = 39*/
0x00,
0x01, /* bInCollection */
0x01, /* baInterfaceNr */
/* 09 byte*/
/* USB Speaker Input Terminal Descriptor */
AUDIO_INPUT_TERMINAL_DESC_SIZE, /* bLength */
AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
AUDIO_CONTROL_INPUT_TERMINAL, /* bDescriptorSubtype */
0x01, /* bTerminalID */
0x01, /* wTerminalType AUDIO_TERMINAL_USB_STREAMING 0x0101 */
0x01,
0x00, /* bAssocTerminal */
0x01, /* bNrChannels */
0x00, /* wChannelConfig 0x0000 Mono */
0x00,
0x00, /* iChannelNames */
0x00, /* iTerminal */
/* 12 byte*/
/* USB Speaker Audio Feature Unit Descriptor */
0x09, /* bLength */
AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
AUDIO_CONTROL_FEATURE_UNIT, /* bDescriptorSubtype */
AUDIO_OUT_STREAMING_CTRL, /* bUnitID */
0x01, /* bSourceID */
0x01, /* bControlSize */
AUDIO_CONTROL_MUTE, /* bmaControls(0) */
0x00, /* bmaControls(1) */
0x00, /* iTerminal */
/* 09 byte*/
/*USB Speaker Output Terminal Descriptor */
0x09, /* bLength */
AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
AUDIO_CONTROL_OUTPUT_TERMINAL, /* bDescriptorSubtype */
0x03, /* bTerminalID */
0x01, /* wTerminalType 0x0301*/
0x03,
0x00, /* bAssocTerminal */
0x02, /* bSourceID */
0x00, /* iTerminal */
/* 09 byte*/
/* USB Speaker Standard AS Interface Descriptor - Audio Streaming Zero Bandwith */
/* Interface 1, Alternate Setting 0 */
AUDIO_INTERFACE_DESC_SIZE, /* bLength */
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
0x01, /* bInterfaceNumber */
0x00, /* bAlternateSetting */
0x00, /* bNumEndpoints */
USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */
AUDIO_SUBCLASS_AUDIOSTREAMING, /* bInterfaceSubClass */
AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */
0x00, /* iInterface */
/* 09 byte*/
/* USB Speaker Standard AS Interface Descriptor - Audio Streaming Operational */
/* Interface 1, Alternate Setting 1 */
AUDIO_INTERFACE_DESC_SIZE, /* bLength */
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
0x01, /* bInterfaceNumber */
0x01, /* bAlternateSetting */
0x01, /* bNumEndpoints */
USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */
AUDIO_SUBCLASS_AUDIOSTREAMING, /* bInterfaceSubClass */
AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */
0x00, /* iInterface */
/* 09 byte*/
/* USB Speaker Audio Streaming Interface Descriptor */
AUDIO_STREAMING_INTERFACE_DESC_SIZE, /* bLength */
AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
AUDIO_STREAMING_GENERAL, /* bDescriptorSubtype */
0x01, /* bTerminalLink */
0x01, /* bDelay */
0x01, /* wFormatTag AUDIO_FORMAT_PCM 0x0001*/
0x00,
/* 07 byte*/
/* USB Speaker Audio Type III Format Interface Descriptor */
0x0B, /* bLength */
AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
AUDIO_STREAMING_FORMAT_TYPE, /* bDescriptorSubtype */
AUDIO_FORMAT_TYPE_III, /* bFormatType */
0x02, /* bNrChannels */
0x02, /* bSubFrameSize : 2 Bytes per frame (16bits) */
16, /* bBitResolution (16-bits per sample) */
0x01, /* bSamFreqType only one frequency supported */
SAMPLE_FREQ(USBD_AUDIO_FREQ), /* Audio sampling frequency coded on 3 bytes */
/* 11 byte*/
/* Endpoint 1 - Standard Descriptor */
AUDIO_STANDARD_ENDPOINT_DESC_SIZE, /* bLength */
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */
AUDIO_OUT_EP, /* bEndpointAddress 1 out endpoint*/
USB_ENDPOINT_TYPE_ISOCHRONOUS, /* bmAttributes */
AUDIO_PACKET_SZE(USBD_AUDIO_FREQ), /* wMaxPacketSize in Bytes (Freq(Samples)*2(Stereo)*2(HalfWord)) */
0x01, /* bInterval */
0x00, /* bRefresh */
0x00, /* bSynchAddress */
/* 09 byte*/
/* Endpoint - Audio Streaming Descriptor*/
AUDIO_STREAMING_ENDPOINT_DESC_SIZE, /* bLength */
AUDIO_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */
AUDIO_ENDPOINT_GENERAL, /* bDescriptor */
0x00, /* bmAttributes */
0x00, /* bLockDelayUnits */
0x00, /* wLockDelay */
0x00,
/* 07 byte*/
} ;
/**
* @}
*/
/** @defgroup usbd_audio_Private_Functions
* @{
*/
/**
* @brief usbd_audio_Init
* Initilaizes the AUDIO interface.
* @param pdev: device instance
* @param cfgidx: Configuration index
* @retval status
*/
static uint8_t usbd_audio_Init (void *pdev,
uint8_t cfgidx)
{
/* Open EP OUT */
DCD_EP_Open(pdev,
AUDIO_OUT_EP,
AUDIO_OUT_PACKET,
USB_OTG_EP_ISOC);
/* Initialize the Audio output Hardware layer */
if (AUDIO_OUT_fops.Init(USBD_AUDIO_FREQ, DEFAULT_VOLUME, 0) != USBD_OK)
{
return USBD_FAIL;
}
/* Prepare Out endpoint to receive audio data */
DCD_EP_PrepareRx(pdev,
AUDIO_OUT_EP,
(uint8_t*)IsocOutBuff,
AUDIO_OUT_PACKET);
return USBD_OK;
}
/**
* @brief usbd_audio_Init
* DeInitializes the AUDIO layer.
* @param pdev: device instance
* @param cfgidx: Configuration index
* @retval status
*/
static uint8_t usbd_audio_DeInit (void *pdev,
uint8_t cfgidx)
{
DCD_EP_Close (pdev , AUDIO_OUT_EP);
/* DeInitialize the Audio output Hardware layer */
if (AUDIO_OUT_fops.DeInit(0) != USBD_OK)
{
return USBD_FAIL;
}
return USBD_OK;
}
/**
* @brief usbd_audio_Setup
* Handles the Audio control request parsing.
* @param pdev: instance
* @param req: usb requests
* @retval status
*/
static uint8_t usbd_audio_Setup (void *pdev,
USB_SETUP_REQ *req)
{
uint16_t len=USB_AUDIO_DESC_SIZ;
uint8_t *pbuf=usbd_audio_CfgDesc + 18;
switch (req->bmRequest & USB_REQ_TYPE_MASK)
{
/* AUDIO Class Requests -------------------------------*/
case USB_REQ_TYPE_CLASS :
switch (req->bRequest)
{
case AUDIO_REQ_GET_CUR:
AUDIO_Req_GetCurrent(pdev, req);
break;
case AUDIO_REQ_SET_CUR:
AUDIO_Req_SetCurrent(pdev, req);
break;
default:
USBD_CtlError (pdev, req);
return USBD_FAIL;
}
break;
/* Standard Requests -------------------------------*/
case USB_REQ_TYPE_STANDARD:
switch (req->bRequest)
{
case USB_REQ_GET_DESCRIPTOR:
if( (req->wValue >> 8) == AUDIO_DESCRIPTOR_TYPE)
{
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
pbuf = usbd_audio_Desc;
#else
pbuf = usbd_audio_CfgDesc + 18;
#endif
len = MIN(USB_AUDIO_DESC_SIZ , req->wLength);
}
USBD_CtlSendData (pdev,
pbuf,
len);
break;
case USB_REQ_GET_INTERFACE :
USBD_CtlSendData (pdev,
(uint8_t *)&usbd_audio_AltSet,
1);
break;
case USB_REQ_SET_INTERFACE :
if ((uint8_t)(req->wValue) < AUDIO_TOTAL_IF_NUM)
{
usbd_audio_AltSet = (uint8_t)(req->wValue);
}
else
{
/* Call the error management function (command will be nacked */
USBD_CtlError (pdev, req);
}
break;
}
}
return USBD_OK;
}
/**
* @brief usbd_audio_EP0_RxReady
* Handles audio control requests data.
* @param pdev: device device instance
* @retval status
*/
static uint8_t usbd_audio_EP0_RxReady (void *pdev)
{
/* Check if an AudioControl request has been issued */
if (AudioCtlCmd == AUDIO_REQ_SET_CUR)
{/* In this driver, to simplify code, only SET_CUR request is managed */
/* Check for which addressed unit the AudioControl request has been issued */
if (AudioCtlUnit == AUDIO_OUT_STREAMING_CTRL)
{/* In this driver, to simplify code, only one unit is manage */
/* Call the audio interface mute function */
AUDIO_OUT_fops.MuteCtl(AudioCtl[0]);
/* Reset the AudioCtlCmd variable to prevent re-entering this function */
AudioCtlCmd = 0;
AudioCtlLen = 0;
}
}
return USBD_OK;
}
/**
* @brief usbd_audio_DataIn
* Handles the audio IN data stage.
* @param pdev: instance
* @param epnum: endpoint number
* @retval status
*/
static uint8_t usbd_audio_DataIn (void *pdev, uint8_t epnum)
{
return USBD_OK;
}
/**
* @brief usbd_audio_DataOut
* Handles the Audio Out data stage.
* @param pdev: instance
* @param epnum: endpoint number
* @retval status
*/
static uint8_t usbd_audio_DataOut (void *pdev, uint8_t epnum)
{
if (epnum == AUDIO_OUT_EP)
{
/* Increment the Buffer pointer or roll it back when all buffers are full */
if (IsocOutWrPtr >= (IsocOutBuff + (AUDIO_OUT_PACKET * OUT_PACKET_NUM)))
{/* All buffers are full: roll back */
IsocOutWrPtr = IsocOutBuff;
}
else
{/* Increment the buffer pointer */
IsocOutWrPtr += AUDIO_OUT_PACKET;
}
/* Toggle the frame index */
((USB_OTG_CORE_HANDLE*)pdev)->dev.out_ep[epnum].even_odd_frame =
(((USB_OTG_CORE_HANDLE*)pdev)->dev.out_ep[epnum].even_odd_frame)? 0:1;
/* Prepare Out endpoint to receive next audio packet */
DCD_EP_PrepareRx(pdev,
AUDIO_OUT_EP,
(uint8_t*)(IsocOutWrPtr),
AUDIO_OUT_PACKET);
/* Trigger the start of streaming only when half buffer is full */
if ((PlayFlag == 0) && (IsocOutWrPtr >= (IsocOutBuff + ((AUDIO_OUT_PACKET * OUT_PACKET_NUM) / 2))))
{
/* Enable start of Streaming */
PlayFlag = 1;
}
}
return USBD_OK;
}
/**
* @brief usbd_audio_SOF
* Handles the SOF event (data buffer update and synchronization).
* @param pdev: instance
* @param epnum: endpoint number
* @retval status
*/
static uint8_t usbd_audio_SOF (void *pdev)
{
/* Check if there are available data in stream buffer.
In this function, a single variable (PlayFlag) is used to avoid software delays.
The play operation must be executed as soon as possible after the SOF detection. */
if (PlayFlag)
{
/* Start playing received packet */
AUDIO_OUT_fops.AudioCmd((uint8_t*)(IsocOutRdPtr), /* Samples buffer pointer */
AUDIO_OUT_PACKET, /* Number of samples in Bytes */
AUDIO_CMD_PLAY); /* Command to be processed */
/* Increment the Buffer pointer or roll it back when all buffers all full */
if (IsocOutRdPtr >= (IsocOutBuff + (AUDIO_OUT_PACKET * OUT_PACKET_NUM)))
{/* Roll back to the start of buffer */
IsocOutRdPtr = IsocOutBuff;
}
else
{/* Increment to the next sub-buffer */
IsocOutRdPtr += AUDIO_OUT_PACKET;
}
/* If all available buffers have been consumed, stop playing */
if (IsocOutRdPtr == IsocOutWrPtr)
{
/* Pause the audio stream */
AUDIO_OUT_fops.AudioCmd((uint8_t*)(IsocOutBuff), /* Samples buffer pointer */
AUDIO_OUT_PACKET, /* Number of samples in Bytes */
AUDIO_CMD_PAUSE); /* Command to be processed */
/* Stop entering play loop */
PlayFlag = 0;
/* Reset buffer pointers */
IsocOutRdPtr = IsocOutBuff;
IsocOutWrPtr = IsocOutBuff;
}
}
return USBD_OK;
}
/**
* @brief usbd_audio_OUT_Incplt
* Handles the iso out incomplete event.
* @param pdev: instance
* @retval status
*/
static uint8_t usbd_audio_OUT_Incplt (void *pdev)
{
return USBD_OK;
}
/******************************************************************************
AUDIO Class requests management
******************************************************************************/
/**
* @brief AUDIO_Req_GetCurrent
* Handles the GET_CUR Audio control request.
* @param pdev: instance
* @param req: setup class request
* @retval status
*/
static void AUDIO_Req_GetCurrent(void *pdev, USB_SETUP_REQ *req)
{
/* Send the current mute state */
USBD_CtlSendData (pdev,
AudioCtl,
req->wLength);
}
/**
* @brief AUDIO_Req_SetCurrent
* Handles the SET_CUR Audio control request.
* @param pdev: instance
* @param req: setup class request
* @retval status
*/
static void AUDIO_Req_SetCurrent(void *pdev, USB_SETUP_REQ *req)
{
if (req->wLength)
{
/* Prepare the reception of the buffer over EP0 */
USBD_CtlPrepareRx (pdev,
AudioCtl,
req->wLength);
/* Set the global variables indicating current request and its length
to the function usbd_audio_EP0_RxReady() which will process the request */
AudioCtlCmd = AUDIO_REQ_SET_CUR; /* Set the request value */
AudioCtlLen = req->wLength; /* Set the request data length */
AudioCtlUnit = HIBYTE(req->wIndex); /* Set the request target unit */
}
}
/**
* @brief USBD_audio_GetCfgDesc
* Returns configuration descriptor.
* @param speed : current device speed
* @param length : pointer data length
* @retval pointer to descriptor buffer
*/
static uint8_t *USBD_audio_GetCfgDesc (uint8_t speed, uint16_t *length)
{
*length = sizeof (usbd_audio_CfgDesc);
return usbd_audio_CfgDesc;
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,321 @@
/**
******************************************************************************
* @file usbd_audio_out_if.c
* @author MCD Application Team
* @version V1.1.0
* @date 19-March-2012
* @brief This file provides the Audio Out (palyback) interface API.
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "usbd_audio_core.h"
#include "usbd_audio_out_if.h"
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
* @{
*/
/** @defgroup usbd_audio_out_if
* @brief usbd out interface module
* @{
*/
/** @defgroup usbd_audio_out_if_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @defgroup usbd_audio_out_if_Private_Defines
* @{
*/
/**
* @}
*/
/** @defgroup usbd_audio_out_if_Private_Macros
* @{
*/
/**
* @}
*/
/** @defgroup usbd_audio_out_if_Private_FunctionPrototypes
* @{
*/
static uint8_t Init (uint32_t AudioFreq, uint32_t Volume, uint32_t options);
static uint8_t DeInit (uint32_t options);
static uint8_t AudioCmd (uint8_t* pbuf, uint32_t size, uint8_t cmd);
static uint8_t VolumeCtl (uint8_t vol);
static uint8_t MuteCtl (uint8_t cmd);
static uint8_t PeriodicTC (uint8_t cmd);
static uint8_t GetState (void);
/**
* @}
*/
/** @defgroup usbd_audio_out_if_Private_Variables
* @{
*/
AUDIO_FOPS_TypeDef AUDIO_OUT_fops =
{
Init,
DeInit,
AudioCmd,
VolumeCtl,
MuteCtl,
PeriodicTC,
GetState
};
static uint8_t AudioState = AUDIO_STATE_INACTIVE;
/**
* @}
*/
/** @defgroup usbd_audio_out_if_Private_Functions
* @{
*/
/**
* @brief Init
* Initialize and configures all required resources for audio play function.
* @param AudioFreq: Statrtup audio frequency.
* @param Volume: Startup volume to be set.
* @param options: specific options passed to low layer function.
* @retval AUDIO_OK if all operations succeed, AUDIO_FAIL else.
*/
static uint8_t Init (uint32_t AudioFreq,
uint32_t Volume,
uint32_t options)
{
static uint32_t Initialized = 0;
/* Check if the low layer has already been initialized */
if (Initialized == 0)
{
/* Call low layer function */
if (EVAL_AUDIO_Init(OUTPUT_DEVICE_AUTO, Volume, AudioFreq) != 0)
{
AudioState = AUDIO_STATE_ERROR;
return AUDIO_FAIL;
}
/* Set the Initialization flag to prevent reinitializing the interface again */
Initialized = 1;
}
/* Update the Audio state machine */
AudioState = AUDIO_STATE_ACTIVE;
return AUDIO_OK;
}
/**
* @brief DeInit
* Free all resources used by low layer and stops audio-play function.
* @param options: options passed to low layer function.
* @retval AUDIO_OK if all operations succeed, AUDIO_FAIL else.
*/
static uint8_t DeInit (uint32_t options)
{
/* Update the Audio state machine */
AudioState = AUDIO_STATE_INACTIVE;
return AUDIO_OK;
}
/**
* @brief AudioCmd
* Play, Stop, Pause or Resume current file.
* @param pbuf: address from which file shoud be played.
* @param size: size of the current buffer/file.
* @param cmd: command to be executed, can be AUDIO_CMD_PLAY , AUDIO_CMD_PAUSE,
* AUDIO_CMD_RESUME or AUDIO_CMD_STOP.
* @retval AUDIO_OK if all operations succeed, AUDIO_FAIL else.
*/
static uint8_t AudioCmd(uint8_t* pbuf,
uint32_t size,
uint8_t cmd)
{
/* Check the current state */
if ((AudioState == AUDIO_STATE_INACTIVE) || (AudioState == AUDIO_STATE_ERROR))
{
AudioState = AUDIO_STATE_ERROR;
return AUDIO_FAIL;
}
switch (cmd)
{
/* Process the PLAY command ----------------------------*/
case AUDIO_CMD_PLAY:
/* If current state is Active or Stopped */
if ((AudioState == AUDIO_STATE_ACTIVE) || \
(AudioState == AUDIO_STATE_STOPPED) || \
(AudioState == AUDIO_STATE_PLAYING))
{
Audio_MAL_Play((uint32_t)pbuf, (size/2));
AudioState = AUDIO_STATE_PLAYING;
return AUDIO_OK;
}
/* If current state is Paused */
else if (AudioState == AUDIO_STATE_PAUSED)
{
if (EVAL_AUDIO_PauseResume(AUDIO_RESUME, (uint32_t)pbuf, (size/2)) != 0)
{
AudioState = AUDIO_STATE_ERROR;
return AUDIO_FAIL;
}
else
{
AudioState = AUDIO_STATE_PLAYING;
return AUDIO_OK;
}
}
else /* Not allowed command */
{
return AUDIO_FAIL;
}
/* Process the STOP command ----------------------------*/
case AUDIO_CMD_STOP:
if (AudioState != AUDIO_STATE_PLAYING)
{
/* Unsupported command */
return AUDIO_FAIL;
}
else if (EVAL_AUDIO_Stop(CODEC_PDWN_SW) != 0)
{
AudioState = AUDIO_STATE_ERROR;
return AUDIO_FAIL;
}
else
{
AudioState = AUDIO_STATE_STOPPED;
return AUDIO_OK;
}
/* Process the PAUSE command ---------------------------*/
case AUDIO_CMD_PAUSE:
if (AudioState != AUDIO_STATE_PLAYING)
{
/* Unsupported command */
return AUDIO_FAIL;
}
else if (EVAL_AUDIO_PauseResume(AUDIO_PAUSE, (uint32_t)pbuf, (size/2)) != 0)
{
AudioState = AUDIO_STATE_ERROR;
return AUDIO_FAIL;
}
else
{
AudioState = AUDIO_STATE_PAUSED;
return AUDIO_OK;
}
/* Unsupported command ---------------------------------*/
default:
return AUDIO_FAIL;
}
}
/**
* @brief VolumeCtl
* Set the volume level in %
* @param vol: volume level to be set in % (from 0% to 100%)
* @retval AUDIO_OK if all operations succeed, AUDIO_FAIL else.
*/
static uint8_t VolumeCtl (uint8_t vol)
{
/* Call low layer volume setting function */
if (EVAL_AUDIO_VolumeCtl(vol) != 0)
{
AudioState = AUDIO_STATE_ERROR;
return AUDIO_FAIL;
}
return AUDIO_OK;
}
/**
* @brief MuteCtl
* Mute or Unmute the audio current output
* @param cmd: can be 0 to unmute, or 1 to mute.
* @retval AUDIO_OK if all operations succeed, AUDIO_FAIL else.
*/
static uint8_t MuteCtl (uint8_t cmd)
{
/* Call low layer mute setting function */
if (EVAL_AUDIO_Mute(cmd) != 0)
{
AudioState = AUDIO_STATE_ERROR;
return AUDIO_FAIL;
}
return AUDIO_OK;
}
/**
* @brief
*
* @param
* @param
* @retval AUDIO_OK if all operations succeed, AUDIO_FAIL else.
*/
static uint8_t PeriodicTC (uint8_t cmd)
{
return AUDIO_OK;
}
/**
* @brief GetState
* Return the current state of the audio machine
* @param None
* @retval Current State.
*/
static uint8_t GetState (void)
{
return AudioState;
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,143 @@
/**
******************************************************************************
* @file usbd_cdc_core.h
* @author MCD Application Team
* @version V1.1.0
* @date 19-March-2012
* @brief header file for the usbd_cdc_core.c file.
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#ifndef __USB_CDC_CORE_H_
#define __USB_CDC_CORE_H_
#include "usbd_ioreq.h"
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
* @{
*/
/** @defgroup usbd_cdc
* @brief This file is the Header file for USBD_cdc.c
* @{
*/
/** @defgroup usbd_cdc_Exported_Defines
* @{
*/
#define USB_CDC_CONFIG_DESC_SIZ (67)
#define USB_CDC_DESC_SIZ (67-9)
#define CDC_DESCRIPTOR_TYPE 0x21
#define DEVICE_CLASS_CDC 0x02
#define DEVICE_SUBCLASS_CDC 0x00
#define USB_DEVICE_DESCRIPTOR_TYPE 0x01
#define USB_CONFIGURATION_DESCRIPTOR_TYPE 0x02
#define USB_STRING_DESCRIPTOR_TYPE 0x03
#define USB_INTERFACE_DESCRIPTOR_TYPE 0x04
#define USB_ENDPOINT_DESCRIPTOR_TYPE 0x05
#define STANDARD_ENDPOINT_DESC_SIZE 0x09
#define CDC_DATA_IN_PACKET_SIZE CDC_DATA_MAX_PACKET_SIZE
#define CDC_DATA_OUT_PACKET_SIZE CDC_DATA_MAX_PACKET_SIZE
/*---------------------------------------------------------------------*/
/* CDC definitions */
/*---------------------------------------------------------------------*/
/**************************************************/
/* CDC Requests */
/**************************************************/
#define SEND_ENCAPSULATED_COMMAND 0x00
#define GET_ENCAPSULATED_RESPONSE 0x01
#define SET_COMM_FEATURE 0x02
#define GET_COMM_FEATURE 0x03
#define CLEAR_COMM_FEATURE 0x04
#define SET_LINE_CODING 0x20
#define GET_LINE_CODING 0x21
#define SET_CONTROL_LINE_STATE 0x22
#define SEND_BREAK 0x23
#define NO_CMD 0xFF
/**
* @}
*/
/** @defgroup USBD_CORE_Exported_TypesDefinitions
* @{
*/
typedef struct _CDC_IF_PROP
{
uint16_t (*pIf_Init) (void);
uint16_t (*pIf_DeInit) (void);
uint16_t (*pIf_Ctrl) (uint32_t Cmd, uint8_t* Buf, uint32_t Len);
uint16_t (*pIf_DataTx) (uint8_t* Buf, uint32_t Len);
uint16_t (*pIf_DataRx) (uint8_t* Buf, uint32_t Len);
}
CDC_IF_Prop_TypeDef;
/**
* @}
*/
/** @defgroup USBD_CORE_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBD_CORE_Exported_Variables
* @{
*/
extern USBD_Class_cb_TypeDef USBD_CDC_cb;
/**
* @}
*/
/** @defgroup USB_CORE_Exported_Functions
* @{
*/
/**
* @}
*/
#endif // __USB_CDC_CORE_H_
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,46 @@
/**
******************************************************************************
* @file usbd_cdc_if_template.h
* @author MCD Application Team
* @version V1.1.0
* @date 19-March-2012
* @brief Header for dfu_mal.c file.
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USBD_CDC_IF_TEMPLATE_H
#define __USBD_CDC_IF_TEMPLATE_H
/* Includes ------------------------------------------------------------------*/
#include "usb_conf.h"
#include "usbd_conf.h"
#include "usbd_cdc_core.h"
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
extern CDC_IF_Prop_TypeDef TEMPLATE_fops;
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
#endif /* __USBD_CDC_IF_TEMPLATE_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,817 @@
/**
******************************************************************************
* @file usbd_cdc_core.c
* @author MCD Application Team
* @version V1.1.0
* @date 19-March-2012
* @brief This file provides the high layer firmware functions to manage the
* following functionalities of the USB CDC Class:
* - Initialization and Configuration of high and low layer
* - Enumeration as CDC Device (and enumeration for each implemented memory interface)
* - OUT/IN data transfer
* - Command IN transfer (class requests management)
* - Error management
*
* @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
* @note
* For the Abstract Control Model, this core allows only transmitting the requests to
* lower layer dispatcher (ie. usbd_cdc_vcp.c/.h) which should manage each request and
* perform relative actions.
*
* These aspects may be enriched or modified for a specific user application.
*
* This driver doesn't implement the following aspects of the specification
* (but it is possible to manage these features with some modifications on this driver):
* - Any class-specific aspect relative to communication classes should be managed by user application.
* - All communication classes other than PSTN are not managed
*
* @endverbatim
*
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "usbd_cdc_core.h"
#include "usbd_desc.h"
#include "usbd_req.h"
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
* @{
*/
/** @defgroup usbd_cdc
* @brief usbd core module
* @{
*/
/** @defgroup usbd_cdc_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @defgroup usbd_cdc_Private_Defines
* @{
*/
/**
* @}
*/
/** @defgroup usbd_cdc_Private_Macros
* @{
*/
/**
* @}
*/
/** @defgroup usbd_cdc_Private_FunctionPrototypes
* @{
*/
/*********************************************
CDC Device library callbacks
*********************************************/
static uint8_t usbd_cdc_Init (void *pdev, uint8_t cfgidx);
static uint8_t usbd_cdc_DeInit (void *pdev, uint8_t cfgidx);
static uint8_t usbd_cdc_Setup (void *pdev, USB_SETUP_REQ *req);
static uint8_t usbd_cdc_EP0_RxReady (void *pdev);
static uint8_t usbd_cdc_DataIn (void *pdev, uint8_t epnum);
static uint8_t usbd_cdc_DataOut (void *pdev, uint8_t epnum);
static uint8_t usbd_cdc_SOF (void *pdev);
/*********************************************
CDC specific management functions
*********************************************/
static void Handle_USBAsynchXfer (void *pdev);
static uint8_t *USBD_cdc_GetCfgDesc (uint8_t speed, uint16_t *length);
#ifdef USE_USB_OTG_HS
static uint8_t *USBD_cdc_GetOtherCfgDesc (uint8_t speed, uint16_t *length);
#endif
/**
* @}
*/
/** @defgroup usbd_cdc_Private_Variables
* @{
*/
extern CDC_IF_Prop_TypeDef APP_FOPS;
extern uint8_t USBD_DeviceDesc [USB_SIZ_DEVICE_DESC];
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
__ALIGN_BEGIN uint8_t usbd_cdc_CfgDesc [USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END ;
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
__ALIGN_BEGIN uint8_t usbd_cdc_OtherCfgDesc [USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END ;
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
__ALIGN_BEGIN static __IO uint32_t usbd_cdc_AltSet __ALIGN_END = 0;
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
__ALIGN_BEGIN uint8_t USB_Rx_Buffer [CDC_DATA_MAX_PACKET_SIZE] __ALIGN_END ;
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
__ALIGN_BEGIN uint8_t APP_Rx_Buffer [APP_RX_DATA_SIZE] __ALIGN_END ;
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
__ALIGN_BEGIN uint8_t CmdBuff[CDC_CMD_PACKET_SZE] __ALIGN_END ;
uint32_t APP_Rx_ptr_in = 0;
uint32_t APP_Rx_ptr_out = 0;
uint32_t APP_Rx_length = 0;
uint8_t USB_Tx_State = 0;
static uint32_t cdcCmd = 0xFF;
static uint32_t cdcLen = 0;
/* CDC interface class callbacks structure */
USBD_Class_cb_TypeDef USBD_CDC_cb =
{
usbd_cdc_Init,
usbd_cdc_DeInit,
usbd_cdc_Setup,
NULL, /* EP0_TxSent, */
usbd_cdc_EP0_RxReady,
usbd_cdc_DataIn,
usbd_cdc_DataOut,
usbd_cdc_SOF,
NULL,
NULL,
USBD_cdc_GetCfgDesc,
#ifdef USE_USB_OTG_HS
USBD_cdc_GetOtherCfgDesc, /* use same cobfig as per FS */
#endif /* USE_USB_OTG_HS */
};
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
/* USB CDC device Configuration Descriptor */
__ALIGN_BEGIN uint8_t usbd_cdc_CfgDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END =
{
/*Configuration Descriptor*/
0x09, /* bLength: Configuration Descriptor size */
USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */
USB_CDC_CONFIG_DESC_SIZ, /* wTotalLength:no of returned bytes */
0x00,
0x02, /* bNumInterfaces: 2 interface */
0x01, /* bConfigurationValue: Configuration value */
0x00, /* iConfiguration: Index of string descriptor describing the configuration */
0xC0, /* bmAttributes: self powered */
0x32, /* MaxPower 0 mA */
/*---------------------------------------------------------------------------*/
/*Interface Descriptor */
0x09, /* bLength: Interface Descriptor size */
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: Interface */
/* Interface descriptor type */
0x00, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x01, /* bNumEndpoints: One endpoints used */
0x02, /* bInterfaceClass: Communication Interface Class */
0x02, /* bInterfaceSubClass: Abstract Control Model */
0x01, /* bInterfaceProtocol: Common AT commands */
0x00, /* iInterface: */
/*Header Functional Descriptor*/
0x05, /* bLength: Endpoint Descriptor size */
0x24, /* bDescriptorType: CS_INTERFACE */
0x00, /* bDescriptorSubtype: Header Func Desc */
0x10, /* bcdCDC: spec release number */
0x01,
/*Call Management Functional Descriptor*/
0x05, /* bFunctionLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x01, /* bDescriptorSubtype: Call Management Func Desc */
0x00, /* bmCapabilities: D0+D1 */
0x01, /* bDataInterface: 1 */
/*ACM Functional Descriptor*/
0x04, /* bFunctionLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x02, /* bDescriptorSubtype: Abstract Control Management desc */
0x02, /* bmCapabilities */
/*Union Functional Descriptor*/
0x05, /* bFunctionLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x06, /* bDescriptorSubtype: Union func desc */
0x00, /* bMasterInterface: Communication class interface */
0x01, /* bSlaveInterface0: Data Class Interface */
/*Endpoint 2 Descriptor*/
0x07, /* bLength: Endpoint Descriptor size */
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
CDC_CMD_EP, /* bEndpointAddress */
0x03, /* bmAttributes: Interrupt */
LOBYTE(CDC_CMD_PACKET_SZE), /* wMaxPacketSize: */
HIBYTE(CDC_CMD_PACKET_SZE),
#ifdef USE_USB_OTG_HS
0x10, /* bInterval: */
#else
0xFF, /* bInterval: */
#endif /* USE_USB_OTG_HS */
/*---------------------------------------------------------------------------*/
/*Data class interface descriptor*/
0x09, /* bLength: Endpoint Descriptor size */
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: */
0x01, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x02, /* bNumEndpoints: Two endpoints used */
0x0A, /* bInterfaceClass: CDC */
0x00, /* bInterfaceSubClass: */
0x00, /* bInterfaceProtocol: */
0x00, /* iInterface: */
/*Endpoint OUT Descriptor*/
0x07, /* bLength: Endpoint Descriptor size */
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
CDC_OUT_EP, /* bEndpointAddress */
0x02, /* bmAttributes: Bulk */
LOBYTE(CDC_DATA_MAX_PACKET_SIZE), /* wMaxPacketSize: */
HIBYTE(CDC_DATA_MAX_PACKET_SIZE),
0x00, /* bInterval: ignore for Bulk transfer */
/*Endpoint IN Descriptor*/
0x07, /* bLength: Endpoint Descriptor size */
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
CDC_IN_EP, /* bEndpointAddress */
0x02, /* bmAttributes: Bulk */
LOBYTE(CDC_DATA_MAX_PACKET_SIZE), /* wMaxPacketSize: */
HIBYTE(CDC_DATA_MAX_PACKET_SIZE),
0x00 /* bInterval: ignore for Bulk transfer */
} ;
#ifdef USE_USB_OTG_HS
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
__ALIGN_BEGIN uint8_t usbd_cdc_OtherCfgDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END =
{
0x09, /* bLength: Configuation Descriptor size */
USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION,
USB_CDC_CONFIG_DESC_SIZ,
0x00,
0x02, /* bNumInterfaces: 2 interfaces */
0x01, /* bConfigurationValue: */
0x04, /* iConfiguration: */
0xC0, /* bmAttributes: */
0x32, /* MaxPower 100 mA */
/*Interface Descriptor */
0x09, /* bLength: Interface Descriptor size */
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: Interface */
/* Interface descriptor type */
0x00, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x01, /* bNumEndpoints: One endpoints used */
0x02, /* bInterfaceClass: Communication Interface Class */
0x02, /* bInterfaceSubClass: Abstract Control Model */
0x01, /* bInterfaceProtocol: Common AT commands */
0x00, /* iInterface: */
/*Header Functional Descriptor*/
0x05, /* bLength: Endpoint Descriptor size */
0x24, /* bDescriptorType: CS_INTERFACE */
0x00, /* bDescriptorSubtype: Header Func Desc */
0x10, /* bcdCDC: spec release number */
0x01,
/*Call Management Functional Descriptor*/
0x05, /* bFunctionLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x01, /* bDescriptorSubtype: Call Management Func Desc */
0x00, /* bmCapabilities: D0+D1 */
0x01, /* bDataInterface: 1 */
/*ACM Functional Descriptor*/
0x04, /* bFunctionLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x02, /* bDescriptorSubtype: Abstract Control Management desc */
0x02, /* bmCapabilities */
/*Union Functional Descriptor*/
0x05, /* bFunctionLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x06, /* bDescriptorSubtype: Union func desc */
0x00, /* bMasterInterface: Communication class interface */
0x01, /* bSlaveInterface0: Data Class Interface */
/*Endpoint 2 Descriptor*/
0x07, /* bLength: Endpoint Descriptor size */
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
CDC_CMD_EP, /* bEndpointAddress */
0x03, /* bmAttributes: Interrupt */
LOBYTE(CDC_CMD_PACKET_SZE), /* wMaxPacketSize: */
HIBYTE(CDC_CMD_PACKET_SZE),
0xFF, /* bInterval: */
/*---------------------------------------------------------------------------*/
/*Data class interface descriptor*/
0x09, /* bLength: Endpoint Descriptor size */
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: */
0x01, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x02, /* bNumEndpoints: Two endpoints used */
0x0A, /* bInterfaceClass: CDC */
0x00, /* bInterfaceSubClass: */
0x00, /* bInterfaceProtocol: */
0x00, /* iInterface: */
/*Endpoint OUT Descriptor*/
0x07, /* bLength: Endpoint Descriptor size */
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
CDC_OUT_EP, /* bEndpointAddress */
0x02, /* bmAttributes: Bulk */
0x40, /* wMaxPacketSize: */
0x00,
0x00, /* bInterval: ignore for Bulk transfer */
/*Endpoint IN Descriptor*/
0x07, /* bLength: Endpoint Descriptor size */
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
CDC_IN_EP, /* bEndpointAddress */
0x02, /* bmAttributes: Bulk */
0x40, /* wMaxPacketSize: */
0x00,
0x00 /* bInterval */
};
#endif /* USE_USB_OTG_HS */
/**
* @}
*/
/** @defgroup usbd_cdc_Private_Functions
* @{
*/
/**
* @brief usbd_cdc_Init
* Initilaize the CDC interface
* @param pdev: device instance
* @param cfgidx: Configuration index
* @retval status
*/
static uint8_t usbd_cdc_Init (void *pdev,
uint8_t cfgidx)
{
uint8_t *pbuf;
/* Open EP IN */
DCD_EP_Open(pdev,
CDC_IN_EP,
CDC_DATA_IN_PACKET_SIZE,
USB_OTG_EP_BULK);
/* Open EP OUT */
DCD_EP_Open(pdev,
CDC_OUT_EP,
CDC_DATA_OUT_PACKET_SIZE,
USB_OTG_EP_BULK);
/* Open Command IN EP */
DCD_EP_Open(pdev,
CDC_CMD_EP,
CDC_CMD_PACKET_SZE,
USB_OTG_EP_INT);
pbuf = (uint8_t *)USBD_DeviceDesc;
pbuf[4] = DEVICE_CLASS_CDC;
pbuf[5] = DEVICE_SUBCLASS_CDC;
/* Initialize the Interface physical components */
APP_FOPS.pIf_Init();
/* Prepare Out endpoint to receive next packet */
DCD_EP_PrepareRx(pdev,
CDC_OUT_EP,
(uint8_t*)(USB_Rx_Buffer),
CDC_DATA_OUT_PACKET_SIZE);
return USBD_OK;
}
/**
* @brief usbd_cdc_Init
* DeInitialize the CDC layer
* @param pdev: device instance
* @param cfgidx: Configuration index
* @retval status
*/
static uint8_t usbd_cdc_DeInit (void *pdev,
uint8_t cfgidx)
{
/* Open EP IN */
DCD_EP_Close(pdev,
CDC_IN_EP);
/* Open EP OUT */
DCD_EP_Close(pdev,
CDC_OUT_EP);
/* Open Command IN EP */
DCD_EP_Close(pdev,
CDC_CMD_EP);
/* Restore default state of the Interface physical components */
APP_FOPS.pIf_DeInit();
return USBD_OK;
}
/**
* @brief usbd_cdc_Setup
* Handle the CDC specific requests
* @param pdev: instance
* @param req: usb requests
* @retval status
*/
static uint8_t usbd_cdc_Setup (void *pdev,
USB_SETUP_REQ *req)
{
uint16_t len=USB_CDC_DESC_SIZ;
uint8_t *pbuf=usbd_cdc_CfgDesc + 9;
switch (req->bmRequest & USB_REQ_TYPE_MASK)
{
/* CDC Class Requests -------------------------------*/
case USB_REQ_TYPE_CLASS :
/* Check if the request is a data setup packet */
if (req->wLength)
{
/* Check if the request is Device-to-Host */
if (req->bmRequest & 0x80)
{
/* Get the data to be sent to Host from interface layer */
APP_FOPS.pIf_Ctrl(req->bRequest, CmdBuff, req->wLength);
/* Send the data to the host */
USBD_CtlSendData (pdev,
CmdBuff,
req->wLength);
}
else /* Host-to-Device requeset */
{
/* Set the value of the current command to be processed */
cdcCmd = req->bRequest;
cdcLen = req->wLength;
/* Prepare the reception of the buffer over EP0
Next step: the received data will be managed in usbd_cdc_EP0_TxSent()
function. */
USBD_CtlPrepareRx (pdev,
CmdBuff,
req->wLength);
}
}
else /* No Data request */
{
/* Transfer the command to the interface layer */
APP_FOPS.pIf_Ctrl(req->bRequest, NULL, 0);
}
return USBD_OK;
default:
USBD_CtlError (pdev, req);
return USBD_FAIL;
/* Standard Requests -------------------------------*/
case USB_REQ_TYPE_STANDARD:
switch (req->bRequest)
{
case USB_REQ_GET_DESCRIPTOR:
if( (req->wValue >> 8) == CDC_DESCRIPTOR_TYPE)
{
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
pbuf = usbd_cdc_Desc;
#else
pbuf = usbd_cdc_CfgDesc + 9 + (9 * USBD_ITF_MAX_NUM);
#endif
len = MIN(USB_CDC_DESC_SIZ , req->wLength);
}
USBD_CtlSendData (pdev,
pbuf,
len);
break;
case USB_REQ_GET_INTERFACE :
USBD_CtlSendData (pdev,
(uint8_t *)&usbd_cdc_AltSet,
1);
break;
case USB_REQ_SET_INTERFACE :
if ((uint8_t)(req->wValue) < USBD_ITF_MAX_NUM)
{
usbd_cdc_AltSet = (uint8_t)(req->wValue);
}
else
{
/* Call the error management function (command will be nacked */
USBD_CtlError (pdev, req);
}
break;
}
}
return USBD_OK;
}
/**
* @brief usbd_cdc_EP0_RxReady
* Data received on control endpoint
* @param pdev: device device instance
* @retval status
*/
static uint8_t usbd_cdc_EP0_RxReady (void *pdev)
{
if (cdcCmd != NO_CMD)
{
/* Process the data */
APP_FOPS.pIf_Ctrl(cdcCmd, CmdBuff, cdcLen);
/* Reset the command variable to default value */
cdcCmd = NO_CMD;
}
return USBD_OK;
}
/**
* @brief usbd_audio_DataIn
* Data sent on non-control IN endpoint
* @param pdev: device instance
* @param epnum: endpoint number
* @retval status
*/
static uint8_t usbd_cdc_DataIn (void *pdev, uint8_t epnum)
{
uint16_t USB_Tx_ptr;
uint16_t USB_Tx_length;
if (USB_Tx_State == 1)
{
if (APP_Rx_length == 0)
{
USB_Tx_State = 0;
}
else
{
if (APP_Rx_length > CDC_DATA_IN_PACKET_SIZE){
USB_Tx_ptr = APP_Rx_ptr_out;
USB_Tx_length = CDC_DATA_IN_PACKET_SIZE;
APP_Rx_ptr_out += CDC_DATA_IN_PACKET_SIZE;
APP_Rx_length -= CDC_DATA_IN_PACKET_SIZE;
}
else
{
USB_Tx_ptr = APP_Rx_ptr_out;
USB_Tx_length = APP_Rx_length;
APP_Rx_ptr_out += APP_Rx_length;
APP_Rx_length = 0;
}
/* Prepare the available data buffer to be sent on IN endpoint */
DCD_EP_Tx (pdev,
CDC_IN_EP,
(uint8_t*)&APP_Rx_Buffer[USB_Tx_ptr],
USB_Tx_length);
}
}
return USBD_OK;
}
/**
* @brief usbd_cdc_DataOut
* Data received on non-control Out endpoint
* @param pdev: device instance
* @param epnum: endpoint number
* @retval status
*/
static uint8_t usbd_cdc_DataOut (void *pdev, uint8_t epnum)
{
uint16_t USB_Rx_Cnt;
/* Get the received data buffer and update the counter */
USB_Rx_Cnt = ((USB_OTG_CORE_HANDLE*)pdev)->dev.out_ep[epnum].xfer_count;
/* USB data will be immediately processed, this allow next USB traffic being
NAKed till the end of the application Xfer */
APP_FOPS.pIf_DataRx(USB_Rx_Buffer, USB_Rx_Cnt);
/* Prepare Out endpoint to receive next packet */
DCD_EP_PrepareRx(pdev,
CDC_OUT_EP,
(uint8_t*)(USB_Rx_Buffer),
CDC_DATA_OUT_PACKET_SIZE);
return USBD_OK;
}
/**
* @brief usbd_audio_SOF
* Start Of Frame event management
* @param pdev: instance
* @param epnum: endpoint number
* @retval status
*/
static uint8_t usbd_cdc_SOF (void *pdev)
{
static uint32_t FrameCount = 0;
if (FrameCount++ == CDC_IN_FRAME_INTERVAL)
{
/* Reset the frame counter */
FrameCount = 0;
/* Check the data to be sent through IN pipe */
Handle_USBAsynchXfer(pdev);
}
return USBD_OK;
}
/**
* @brief Handle_USBAsynchXfer
* Send data to USB
* @param pdev: instance
* @retval None
*/
static void Handle_USBAsynchXfer (void *pdev)
{
uint16_t USB_Tx_ptr;
uint16_t USB_Tx_length;
if(USB_Tx_State != 1)
{
if (APP_Rx_ptr_out == APP_RX_DATA_SIZE)
{
APP_Rx_ptr_out = 0;
}
if(APP_Rx_ptr_out == APP_Rx_ptr_in)
{
USB_Tx_State = 0;
return;
}
if(APP_Rx_ptr_out > APP_Rx_ptr_in) /* rollback */
{
APP_Rx_length = APP_RX_DATA_SIZE - APP_Rx_ptr_out;
}
else
{
APP_Rx_length = APP_Rx_ptr_in - APP_Rx_ptr_out;
}
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
APP_Rx_length &= ~0x03;
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
if (APP_Rx_length > CDC_DATA_IN_PACKET_SIZE)
{
USB_Tx_ptr = APP_Rx_ptr_out;
USB_Tx_length = CDC_DATA_IN_PACKET_SIZE;
APP_Rx_ptr_out += CDC_DATA_IN_PACKET_SIZE;
APP_Rx_length -= CDC_DATA_IN_PACKET_SIZE;
}
else
{
USB_Tx_ptr = APP_Rx_ptr_out;
USB_Tx_length = APP_Rx_length;
APP_Rx_ptr_out += APP_Rx_length;
APP_Rx_length = 0;
}
USB_Tx_State = 1;
DCD_EP_Tx (pdev,
CDC_IN_EP,
(uint8_t*)&APP_Rx_Buffer[USB_Tx_ptr],
USB_Tx_length);
}
}
/**
* @brief USBD_cdc_GetCfgDesc
* Return configuration descriptor
* @param speed : current device speed
* @param length : pointer data length
* @retval pointer to descriptor buffer
*/
static uint8_t *USBD_cdc_GetCfgDesc (uint8_t speed, uint16_t *length)
{
*length = sizeof (usbd_cdc_CfgDesc);
return usbd_cdc_CfgDesc;
}
/**
* @brief USBD_cdc_GetCfgDesc
* Return configuration descriptor
* @param speed : current device speed
* @param length : pointer data length
* @retval pointer to descriptor buffer
*/
#ifdef USE_USB_OTG_HS
static uint8_t *USBD_cdc_GetOtherCfgDesc (uint8_t speed, uint16_t *length)
{
*length = sizeof (usbd_cdc_OtherCfgDesc);
return usbd_cdc_OtherCfgDesc;
}
#endif
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,207 @@
/**
******************************************************************************
* @file usbd_cdc_if_template.c
* @author MCD Application Team
* @version V1.1.0
* @date 19-March-2012
* @brief Generic media access Layer.
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
#pragma data_alignment = 4
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
/* Includes ------------------------------------------------------------------*/
#include "usbd_cdc_if_template.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* These are external variables imported from CDC core to be used for IN
transfer management. */
extern uint8_t APP_Rx_Buffer []; /* Write CDC received data in this buffer.
These data will be sent over USB IN endpoint
in the CDC core functions. */
extern uint32_t APP_Rx_ptr_in; /* Increment this pointer or roll it back to
start address when writing received data
in the buffer APP_Rx_Buffer. */
/* Private function prototypes -----------------------------------------------*/
static uint16_t TEMPLATE_Init (void);
static uint16_t TEMPLATE_DeInit (void);
static uint16_t TEMPLATE_Ctrl (uint32_t Cmd, uint8_t* Buf, uint32_t Len);
static uint16_t TEMPLATE_DataTx (uint8_t* Buf, uint32_t Len);
static uint16_t TEMPLATE_DataRx (uint8_t* Buf, uint32_t Len);
CDC_IF_Prop_TypeDef TEMPLATE_fops =
{
TEMPLATE_Init,
TEMPLATE_DeInit,
TEMPLATE_Ctrl,
TEMPLATE_DataTx,
TEMPLATE_DataRx
};
/* Private functions ---------------------------------------------------------*/
/**
* @brief TEMPLATE_Init
* Initializes the CDC media low layer
* @param None
* @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL
*/
static uint16_t TEMPLATE_Init(void)
{
/*
Add your initialization code here
*/
return USBD_OK;
}
/**
* @brief TEMPLATE_DeInit
* DeInitializes the CDC media low layer
* @param None
* @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL
*/
static uint16_t TEMPLATE_DeInit(void)
{
/*
Add your deinitialization code here
*/
return USBD_OK;
}
/**
* @brief TEMPLATE_Ctrl
* Manage the CDC class requests
* @param Cmd: Command code
* @param Buf: Buffer containing command data (request parameters)
* @param Len: Number of data to be sent (in bytes)
* @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL
*/
static uint16_t TEMPLATE_Ctrl (uint32_t Cmd, uint8_t* Buf, uint32_t Len)
{
switch (Cmd)
{
case SEND_ENCAPSULATED_COMMAND:
/* Add your code here */
break;
case GET_ENCAPSULATED_RESPONSE:
/* Add your code here */
break;
case SET_COMM_FEATURE:
/* Add your code here */
break;
case GET_COMM_FEATURE:
/* Add your code here */
break;
case CLEAR_COMM_FEATURE:
/* Add your code here */
break;
case SET_LINE_CODING:
/* Add your code here */
break;
case GET_LINE_CODING:
/* Add your code here */
break;
case SET_CONTROL_LINE_STATE:
/* Add your code here */
break;
case SEND_BREAK:
/* Add your code here */
break;
default:
break;
}
return USBD_OK;
}
/**
* @brief TEMPLATE_DataTx
* CDC received data to be send over USB IN endpoint are managed in
* this function.
* @param Buf: Buffer of data to be sent
* @param Len: Number of data to be sent (in bytes)
* @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL
*/
static uint16_t TEMPLATE_DataTx (uint8_t* Buf, uint32_t Len)
{
/* Get the data to be sent */
for (i = 0; i < Len; i++)
{
/* APP_Rx_Buffer[APP_Rx_ptr_in] = XXX_ReceiveData(XXX); */
}
/* Increment the in pointer */
APP_Rx_ptr_in++;
/* To avoid buffer overflow */
if(APP_Rx_ptr_in == APP_RX_DATA_SIZE)
{
APP_Rx_ptr_in = 0;
}
return USBD_OK;
}
/**
* @brief TEMPLATE_DataRx
* Data received over USB OUT endpoint are sent over CDC interface
* through this function.
*
* @note
* This function will block any OUT packet reception on USB endpoint
* untill exiting this function. If you exit this function before transfer
* is complete on CDC interface (ie. using DMA controller) it will result
* in receiving more data while previous ones are still not sent.
*
* @param Buf: Buffer of data to be received
* @param Len: Number of data received (in bytes)
* @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL
*/
static uint16_t TEMPLATE_DataRx (uint8_t* Buf, uint32_t Len)
{
uint32_t i;
/* Send the received buffer */
for (i = 0; i < Len; i++)
{
/* XXXX_SendData(XXXX, *(Buf + i) ); */
}
return USBD_OK;
}
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,193 @@
/**
******************************************************************************
* @file usbd_dfu_core.h
* @author MCD Application Team
* @version V1.1.0
* @date 19-March-2012
* @brief header file for the usbd_dfu_core.c file.
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#ifndef __USB_DFU_CORE_H_
#define __USB_DFU_CORE_H_
#include "usbd_ioreq.h"
#include "usbd_dfu_mal.h"
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
* @{
*/
/** @defgroup usbd_dfu
* @brief This file is the Header file for USBD_dfu.c
* @{
*/
/** @defgroup usbd_dfu_Exported_Defines
* @{
*/
#define USB_DFU_CONFIG_DESC_SIZ (18 + (9 * USBD_ITF_MAX_NUM))
#define USB_DFU_DESC_SIZ 9
#define DFU_DESCRIPTOR_TYPE 0x21
/*---------------------------------------------------------------------*/
/* DFU definitions */
/*---------------------------------------------------------------------*/
/**************************************************/
/* DFU Requests DFU states */
/**************************************************/
#define STATE_appIDLE 0
#define STATE_appDETACH 1
#define STATE_dfuIDLE 2
#define STATE_dfuDNLOAD_SYNC 3
#define STATE_dfuDNBUSY 4
#define STATE_dfuDNLOAD_IDLE 5
#define STATE_dfuMANIFEST_SYNC 6
#define STATE_dfuMANIFEST 7
#define STATE_dfuMANIFEST_WAIT_RESET 8
#define STATE_dfuUPLOAD_IDLE 9
#define STATE_dfuERROR 10
/**************************************************/
/* DFU Requests DFU status */
/**************************************************/
#define STATUS_OK 0x00
#define STATUS_ERRTARGET 0x01
#define STATUS_ERRFILE 0x02
#define STATUS_ERRWRITE 0x03
#define STATUS_ERRERASE 0x04
#define STATUS_ERRCHECK_ERASED 0x05
#define STATUS_ERRPROG 0x06
#define STATUS_ERRVERIFY 0x07
#define STATUS_ERRADDRESS 0x08
#define STATUS_ERRNOTDONE 0x09
#define STATUS_ERRFIRMWARE 0x0A
#define STATUS_ERRVENDOR 0x0B
#define STATUS_ERRUSBR 0x0C
#define STATUS_ERRPOR 0x0D
#define STATUS_ERRUNKNOWN 0x0E
#define STATUS_ERRSTALLEDPKT 0x0F
/**************************************************/
/* DFU Requests DFU states Manifestation State */
/**************************************************/
#define Manifest_complete 0x00
#define Manifest_In_Progress 0x01
/**************************************************/
/* Special Commands with Download Request */
/**************************************************/
#define CMD_GETCOMMANDS 0x00
#define CMD_SETADDRESSPOINTER 0x21
#define CMD_ERASE 0x41
/**************************************************/
/* Other defines */
/**************************************************/
/* Bit Detach capable = bit 3 in bmAttributes field */
#define DFU_DETACH_MASK (uint8_t)(1 << 4)
/**
* @}
*/
/** @defgroup USBD_CORE_Exported_TypesDefinitions
* @{
*/
/**************************************************/
/* DFU Requests */
/**************************************************/
typedef enum _DFU_REQUESTS {
DFU_DETACH = 0,
DFU_DNLOAD = 1,
DFU_UPLOAD,
DFU_GETSTATUS,
DFU_CLRSTATUS,
DFU_GETSTATE,
DFU_ABORT
} DFU_REQUESTS;
typedef void (*pFunction)(void);
/**
* @}
*/
/** @defgroup USBD_CORE_Exported_Macros
* @{
*/
/********** Descriptor of DFU interface 0 Alternate setting n ****************/
#define USBD_DFU_IF_DESC(n) 0x09, /* bLength: Interface Descriptor size */ \
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ \
0x00, /* bInterfaceNumber: Number of Interface */ \
(n), /* bAlternateSetting: Alternate setting */ \
0x00, /* bNumEndpoints*/ \
0xFE, /* bInterfaceClass: Application Specific Class Code */ \
0x01, /* bInterfaceSubClass : Device Firmware Upgrade Code */ \
0x02, /* nInterfaceProtocol: DFU mode protocol */ \
USBD_IDX_INTERFACE_STR + (n) + 1 /* iInterface: Index of string descriptor */ \
/* 18 */
/**
* @}
*/
/** @defgroup USBD_CORE_Exported_Variables
* @{
*/
extern USBD_Class_cb_TypeDef DFU_cb;
/**
* @}
*/
/** @defgroup USB_CORE_Exported_Functions
* @{
*/
/**
* @}
*/
#endif // __USB_DFU_CORE_H_
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,81 @@
/**
******************************************************************************
* @file usbd_dfu_mal.h
* @author MCD Application Team
* @version V1.1.0
* @date 19-March-2012
* @brief Header for usbd_dfu_mal.c file.
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __DFU_MAL_H
#define __DFU_MAL_H
/* Includes ------------------------------------------------------------------*/
#include "usb_conf.h"
#include "usbd_conf.h"
#include "usbd_dfu_core.h"
/* Exported types ------------------------------------------------------------*/
typedef struct _DFU_MAL_PROP
{
const uint8_t* pStrDesc;
uint16_t (*pMAL_Init) (void);
uint16_t (*pMAL_DeInit) (void);
uint16_t (*pMAL_Erase) (uint32_t Add);
uint16_t (*pMAL_Write) (uint32_t Add, uint32_t Len);
uint8_t *(*pMAL_Read) (uint32_t Add, uint32_t Len);
uint16_t (*pMAL_CheckAdd) (uint32_t Add);
const uint32_t EraseTiming;
const uint32_t WriteTiming;
}
DFU_MAL_Prop_TypeDef;
/* Exported constants --------------------------------------------------------*/
#define MAL_OK 0
#define MAL_FAIL 1
/* utils macro ---------------------------------------------------------------*/
#define _1st_BYTE(x) (uint8_t)((x)&0xFF) /* 1st addressing cycle */
#define _2nd_BYTE(x) (uint8_t)(((x)&0xFF00)>>8) /* 2nd addressing cycle */
#define _3rd_BYTE(x) (uint8_t)(((x)&0xFF0000)>>16) /* 3rd addressing cycle */
#define _4th_BYTE(x) (uint8_t)(((x)&0xFF000000)>>24) /* 4th addressing cycle */
/* Exported macro ------------------------------------------------------------*/
#define SET_POLLING_TIMING(x) buffer[1] = _1st_BYTE(x);\
buffer[2] = _2nd_BYTE(x);\
buffer[3] = _3rd_BYTE(x);
/* Exported functions ------------------------------------------------------- */
uint16_t MAL_Init (void);
uint16_t MAL_DeInit (void);
uint16_t MAL_Erase (uint32_t SectorAddress);
uint16_t MAL_Write (uint32_t SectorAddress, uint32_t DataLength);
uint8_t *MAL_Read (uint32_t SectorAddress, uint32_t DataLength);
uint16_t MAL_GetStatus(uint32_t SectorAddress ,uint8_t Cmd, uint8_t *buffer);
extern uint8_t MAL_Buffer[XFERSIZE]; /* RAM Buffer for Downloaded Data */
#endif /* __DFU_MAL_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,58 @@
/**
******************************************************************************
* @file usbd_flash_if.h
* @author MCD Application Team
* @version V1.1.0
* @date 19-March-2012
* @brief Header for usbd_flash_if.c file.
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __FLASH_IF_MAL_H
#define __FLASH_IF_MAL_H
/* Includes ------------------------------------------------------------------*/
#include "usbd_dfu_mal.h"
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
#define FLASH_START_ADD 0x08000000
#ifdef STM32F2XX
#define FLASH_END_ADD 0x08100000
#define FLASH_IF_STRING "@Internal Flash /0x08000000/03*016Ka,01*016Kg,01*064Kg,07*128Kg"
#elif defined(STM32F4XX)
#define FLASH_END_ADD 0x08100000
#define FLASH_IF_STRING "@Internal Flash /0x08000000/03*016Ka,01*016Kg,01*064Kg,07*128Kg"
#elif defined(STM32F10X_CL)
#define FLASH_END_ADD 0x08040000
#define FLASH_IF_STRING "@Internal Flash /0x08000000/06*002Ka,122*002Kg"
#endif /* STM32F2XX */
extern DFU_MAL_Prop_TypeDef DFU_Flash_cb;
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
#endif /* __FLASH_IF_MAL_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,51 @@
/**
******************************************************************************
* @file usbd_mem_if_template.h
* @author MCD Application Team
* @version V1.1.0
* @date 19-March-2012
* @brief Header for usbd_mem_if_template.c file.
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __MEM_IF_MAL_H
#define __MEM_IF_MAL_H
/* Includes ------------------------------------------------------------------*/
#include "usb_conf.h"
#include "usbd_dfu_mal.h"
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
#define MEM_START_ADD 0x00000000 /* Dummy start address */
#define MEM_END_ADD (uint32_t)(MEM_START_ADD + (5 * 1024)) /* Dummy Size = 5KB */
#define MEM_IF_STRING "@Dummy Memory /0x00000000/01*002Kg,03*001Kg"
extern DFU_MAL_Prop_TypeDef DFU_Mem_cb;
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
#endif /* __MEM_IF_MAL_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,49 @@
/**
******************************************************************************
* @file usbd_otp_if.h
* @author MCD Application Team
* @version V1.1.0
* @date 19-March-2012
* @brief Header for usbd_otp_if.c file.
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __OTP_IF_MAL_H
#define __OTP_IF_MAL_H
/* Includes ------------------------------------------------------------------*/
#include "usbd_dfu_mal.h"
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
#define OTP_START_ADD 0x1FFF7800
#define OTP_END_ADD (uint32_t)(OTP_START_ADD + 528)
#define OTP_IF_STRING "@OTP Area /0x1FFF7800/01*512 g,01*016 g"
extern DFU_MAL_Prop_TypeDef DFU_Otp_cb;
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
#endif /* __OTP_IF_MAL_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,287 @@
/**
******************************************************************************
* @file usbd_dfu_mal.c
* @author MCD Application Team
* @version V1.1.0
* @date 19-March-2012
* @brief Generic media access Layer.
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "usbd_dfu_mal.h"
#include "usbd_flash_if.h"
#ifdef DFU_MAL_SUPPORT_OTP
#include "usbd_otp_if.h"
#endif
#ifdef DFU_MAL_SUPPORT_MEM
#include "usbd_mem_if_template.h"
#endif
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Global Memories callback and string descriptors reference tables.
To add a new memory, modify the value of MAX_USED_MEDIA in usbd_dfu_mal.h
and add the pointer to the callback structure in this table.
Then add the pointer to the memory string descriptor in usbd_dfu_StringDesc table.
No other operation is required. */
DFU_MAL_Prop_TypeDef* tMALTab[MAX_USED_MEDIA] = {
&DFU_Flash_cb
#ifdef DFU_MAL_SUPPORT_OTP
, &DFU_Otp_cb
#endif
#ifdef DFU_MAL_SUPPORT_MEM
, &DFU_Mem_cb
#endif
};
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
__ALIGN_BEGIN const uint8_t* usbd_dfu_StringDesc[MAX_USED_MEDIA] __ALIGN_END = {
FLASH_IF_STRING
#ifdef DFU_MAL_SUPPORT_OTP
, OTP_IF_STRING
#endif
#ifdef DFU_MAL_SUPPORT_MEM
, MEM_IF_STRING
#endif
};
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
/* RAM Buffer for Downloaded Data */
__ALIGN_BEGIN uint8_t MAL_Buffer[XFERSIZE] __ALIGN_END ;
/* Private function prototypes -----------------------------------------------*/
static uint8_t MAL_CheckAdd (uint32_t Add);
/* Private functions ---------------------------------------------------------*/
/**
* @brief MAL_Init
* Initializes the Media on the STM32
* @param None
* @retval Result of the opeartion (MAL_OK in all cases)
*/
uint16_t MAL_Init(void)
{
uint32_t memIdx = 0;
/* Init all supported memories */
for(memIdx = 0; memIdx < MAX_USED_MEDIA; memIdx++)
{
/* If the check addres is positive, exit with the memory index */
if (tMALTab[memIdx]->pMAL_Init != NULL)
{
tMALTab[memIdx]->pMAL_Init();
}
}
return MAL_OK;
}
/**
* @brief MAL_DeInit
* DeInitializes the Media on the STM32
* @param None
* @retval Result of the opeartion (MAL_OK in all cases)
*/
uint16_t MAL_DeInit(void)
{
uint32_t memIdx = 0;
/* Init all supported memories */
for(memIdx = 0; memIdx < MAX_USED_MEDIA; memIdx++)
{
/* Check if the command is supported */
if (tMALTab[memIdx]->pMAL_DeInit != NULL)
{
tMALTab[memIdx]->pMAL_DeInit();
}
}
return MAL_OK;
}
/**
* @brief MAL_Erase
* Erase a sector of memory.
* @param Add: Sector address/code
* @retval Result of the opeartion: MAL_OK if all operations are OK else MAL_FAIL
*/
uint16_t MAL_Erase(uint32_t Add)
{
uint32_t memIdx = MAL_CheckAdd(Add);
/* Check if the area is protected */
if (DFU_MAL_IS_PROTECTED_AREA(Add))
{
return MAL_FAIL;
}
if (memIdx < MAX_USED_MEDIA)
{
/* Check if the command is supported */
if (tMALTab[memIdx]->pMAL_Erase != NULL)
{
return tMALTab[memIdx]->pMAL_Erase(Add);
}
else
{
return MAL_FAIL;
}
}
else
{
return MAL_FAIL;
}
}
/**
* @brief MAL_Write
* Write sectors of memory.
* @param Add: Sector address/code
* @param Len: Number of data to be written (in bytes)
* @retval Result of the opeartion: MAL_OK if all operations are OK else MAL_FAIL
*/
uint16_t MAL_Write (uint32_t Add, uint32_t Len)
{
uint32_t memIdx = MAL_CheckAdd(Add);
/* Check if the area is protected */
if (DFU_MAL_IS_PROTECTED_AREA(Add))
{
return MAL_FAIL;
}
if (memIdx < MAX_USED_MEDIA)
{
/* Check if the command is supported */
if (tMALTab[memIdx]->pMAL_Write != NULL)
{
return tMALTab[memIdx]->pMAL_Write(Add, Len);
}
else
{
return MAL_FAIL;
}
}
else
{
return MAL_FAIL;
}
}
/**
* @brief MAL_Read
* Read sectors of memory.
* @param Add: Sector address/code
* @param Len: Number of data to be written (in bytes)
* @retval Buffer pointer
*/
uint8_t *MAL_Read (uint32_t Add, uint32_t Len)
{
uint32_t memIdx = MAL_CheckAdd(Add);
if (memIdx < MAX_USED_MEDIA)
{
/* Check if the command is supported */
if (tMALTab[memIdx]->pMAL_Read != NULL)
{
return tMALTab[memIdx]->pMAL_Read(Add, Len);
}
else
{
return MAL_Buffer;
}
}
else
{
return MAL_Buffer;
}
}
/**
* @brief MAL_GetStatus
* Get the status of a given memory.
* @param Add: Sector address/code (allow to determine which memory will be addressed)
* @param Cmd: 0 for erase and 1 for write
* @param buffer: pointer to the buffer where the status data will be stored.
* @retval Buffer pointer
*/
uint16_t MAL_GetStatus(uint32_t Add , uint8_t Cmd, uint8_t *buffer)
{
uint32_t memIdx = MAL_CheckAdd(Add);
if (memIdx < MAX_USED_MEDIA)
{
if (Cmd & 0x01)
{
SET_POLLING_TIMING(tMALTab[memIdx]->EraseTiming);
}
else
{
SET_POLLING_TIMING(tMALTab[memIdx]->WriteTiming);
}
return MAL_OK;
}
else
{
return MAL_FAIL;
}
}
/**
* @brief MAL_CheckAdd
* Determine which memory should be managed.
* @param Add: Sector address/code (allow to determine which memory will be addressed)
* @retval Index of the addressed memory.
*/
static uint8_t MAL_CheckAdd(uint32_t Add)
{
uint32_t memIdx = 0;
/* Check with all supported memories */
for(memIdx = 0; memIdx < MAX_USED_MEDIA; memIdx++)
{
/* If the check addres is positive, exit with the memory index */
if (tMALTab[memIdx]->pMAL_CheckAdd(Add) == MAL_OK)
{
return memIdx;
}
}
/* If no memory found, return MAX_USED_MEDIA */
return (MAX_USED_MEDIA);
}
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,227 @@
/**
******************************************************************************
* @file usbd_flash_if.c
* @author MCD Application Team
* @version V1.1.0
* @date 19-March-2012
* @brief Specific media access Layer for internal flash.
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "usbd_flash_if.h"
#include "usbd_dfu_mal.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
uint16_t FLASH_If_Init(void);
uint16_t FLASH_If_Erase (uint32_t Add);
uint16_t FLASH_If_Write (uint32_t Add, uint32_t Len);
uint8_t *FLASH_If_Read (uint32_t Add, uint32_t Len);
uint16_t FLASH_If_DeInit(void);
uint16_t FLASH_If_CheckAdd(uint32_t Add);
/* Private variables ---------------------------------------------------------*/
DFU_MAL_Prop_TypeDef DFU_Flash_cb =
{
FLASH_IF_STRING,
FLASH_If_Init,
FLASH_If_DeInit,
FLASH_If_Erase,
FLASH_If_Write,
FLASH_If_Read,
FLASH_If_CheckAdd,
50, /* Erase Time in ms */
50 /* Programming Time in ms */
};
/* Private functions ---------------------------------------------------------*/
/**
* @brief FLASH_If_Init
* Memory initialization routine.
* @param None
* @retval MAL_OK if operation is successeful, MAL_FAIL else.
*/
uint16_t FLASH_If_Init(void)
{
/* Unlock the internal flash */
FLASH_Unlock();
return MAL_OK;
}
/**
* @brief FLASH_If_DeInit
* Memory deinitialization routine.
* @param None
* @retval MAL_OK if operation is successeful, MAL_FAIL else.
*/
uint16_t FLASH_If_DeInit(void)
{
/* Lock the internal flash */
FLASH_Lock();
return MAL_OK;
}
/*******************************************************************************
* Function Name : FLASH_If_Erase
* Description : Erase sector
* Input : None
* Output : None
* Return : None
*******************************************************************************/
uint16_t FLASH_If_Erase(uint32_t Add)
{
#if defined (STM32F2XX) || defined (STM32F4XX)
/* Check which sector has to be erased */
if (Add < 0x08004000)
{
FLASH_EraseSector(FLASH_Sector_0, VoltageRange_3);
}
else if (Add < 0x08008000)
{
FLASH_EraseSector(FLASH_Sector_1, VoltageRange_3);
}
else if (Add < 0x0800C000)
{
FLASH_EraseSector(FLASH_Sector_2, VoltageRange_3);
}
else if (Add < 0x08010000)
{
FLASH_EraseSector(FLASH_Sector_3, VoltageRange_3);
}
else if (Add < 0x08020000)
{
FLASH_EraseSector(FLASH_Sector_4, VoltageRange_3);
}
else if (Add < 0x08040000)
{
FLASH_EraseSector(FLASH_Sector_5, VoltageRange_3);
}
else if (Add < 0x08060000)
{
FLASH_EraseSector(FLASH_Sector_6, VoltageRange_3);
}
else if (Add < 0x08080000)
{
FLASH_EraseSector(FLASH_Sector_7, VoltageRange_3);
}
else if (Add < 0x080A0000)
{
FLASH_EraseSector(FLASH_Sector_8, VoltageRange_3);
}
else if (Add < 0x080C0000)
{
FLASH_EraseSector(FLASH_Sector_9, VoltageRange_3);
}
else if (Add < 0x080E0000)
{
FLASH_EraseSector(FLASH_Sector_10, VoltageRange_3);
}
else if (Add < 0x08100000)
{
FLASH_EraseSector(FLASH_Sector_11, VoltageRange_3);
}
else
{
return MAL_FAIL;
}
#elif defined(STM32F10X_CL)
/* Call the standard Flash erase function */
FLASH_ErasePage(Add);
#endif /* STM32F2XX */
return MAL_OK;
}
/**
* @brief FLASH_If_Write
* Memory write routine.
* @param Add: Address to be written to.
* @param Len: Number of data to be written (in bytes).
* @retval MAL_OK if operation is successeful, MAL_FAIL else.
*/
uint16_t FLASH_If_Write(uint32_t Add, uint32_t Len)
{
uint32_t idx = 0;
if (Len & 0x3) /* Not an aligned data */
{
for (idx = Len; idx < ((Len & 0xFFFC) + 4); idx++)
{
MAL_Buffer[idx] = 0xFF;
}
}
/* Data received are Word multiple */
for (idx = 0; idx < Len; idx = idx + 4)
{
FLASH_ProgramWord(Add, *(uint32_t *)(MAL_Buffer + idx));
Add += 4;
}
return MAL_OK;
}
/**
* @brief FLASH_If_Read
* Memory read routine.
* @param Add: Address to be read from.
* @param Len: Number of data to be read (in bytes).
* @retval Pointer to the phyisical address where data should be read.
*/
uint8_t *FLASH_If_Read (uint32_t Add, uint32_t Len)
{
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
uint32_t idx = 0;
for (idx = 0; idx < Len; idx += 4)
{
*(uint32_t*)(MAL_Buffer + idx) = *(uint32_t *)(Add + idx);
}
return (uint8_t*)(MAL_Buffer);
#else
return (uint8_t *)(Add);
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
}
/**
* @brief FLASH_If_CheckAdd
* Check if the address is an allowed address for this memory.
* @param Add: Address to be checked.
* @param Len: Number of data to be read (in bytes).
* @retval MAL_OK if the address is allowed, MAL_FAIL else.
*/
uint16_t FLASH_If_CheckAdd(uint32_t Add)
{
if ((Add >= FLASH_START_ADD) && (Add < FLASH_END_ADD))
{
return MAL_OK;
}
else
{
return MAL_FAIL;
}
}
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,139 @@
/**
******************************************************************************
* @file usbd_mem_if_template.c
* @author MCD Application Team
* @version V1.1.0
* @date 19-March-2012
* @brief Specific media access Layer for a template memory. This file is
provided as template example showing how to implement a new memory
interface based on pre-defined API.
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "usbd_mem_if_template.h"
#include "usbd_dfu_mal.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
uint16_t MEM_If_Init(void);
uint16_t MEM_If_Erase (uint32_t Add);
uint16_t MEM_If_Write (uint32_t Add, uint32_t Len);
uint8_t *MEM_If_Read (uint32_t Add, uint32_t Len);
uint16_t MEM_If_DeInit(void);
uint16_t MEM_If_CheckAdd(uint32_t Add);
/* Private variables ---------------------------------------------------------*/
DFU_MAL_Prop_TypeDef DFU_Mem_cb =
{
MEM_IF_STRING,
MEM_If_Init,
MEM_If_DeInit,
MEM_If_Erase,
MEM_If_Write,
MEM_If_Read,
MEM_If_CheckAdd,
10, /* Erase Time in ms */
10 /* Programming Time in ms */
};
/* Private functions ---------------------------------------------------------*/
/**
* @brief MEM_If_Init
* Memory initialization routine.
* @param None
* @retval MAL_OK if operation is successeful, MAL_FAIL else.
*/
uint16_t MEM_If_Init(void)
{
return MAL_OK;
}
/**
* @brief MEM_If_DeInit
* Memory deinitialization routine.
* @param None
* @retval MAL_OK if operation is successeful, MAL_FAIL else.
*/
uint16_t MEM_If_DeInit(void)
{
return MAL_OK;
}
/**
* @brief MEM_If_Erase
* Erase sector.
* @param Add: Address of sector to be erased.
* @retval MAL_OK if operation is successeful, MAL_FAIL else.
*/
uint16_t MEM_If_Erase(uint32_t Add)
{
return MAL_OK;
}
/**
* @brief MEM_If_Write
* Memory write routine.
* @param Add: Address to be written to.
* @param Len: Number of data to be written (in bytes).
* @retval MAL_OK if operation is successeful, MAL_FAIL else.
*/
uint16_t MEM_If_Write(uint32_t Add, uint32_t Len)
{
return MAL_OK;
}
/**
* @brief MEM_If_Read
* Memory read routine.
* @param Add: Address to be read from.
* @param Len: Number of data to be read (in bytes).
* @retval Pointer to the phyisical address where data should be read.
*/
uint8_t *MEM_If_Read (uint32_t Add, uint32_t Len)
{
/* Return a valid address to avoid HardFault */
return (uint8_t*)(MAL_Buffer);
}
/**
* @brief MEM_If_CheckAdd
* Check if the address is an allowed address for this memory.
* @param Add: Address to be checked.
* @param Len: Number of data to be read (in bytes).
* @retval MAL_OK if the address is allowed, MAL_FAIL else.
*/
uint16_t MEM_If_CheckAdd(uint32_t Add)
{
if ((Add >= MEM_START_ADD) && (Add < MEM_END_ADD))
{
return MAL_OK;
}
else
{
return MAL_FAIL;
}
}
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,126 @@
/**
******************************************************************************
* @file usbd_otp_if.c
* @author MCD Application Team
* @version V1.1.0
* @date 19-March-2012
* @brief Specific media access Layer for OTP (One Time Programming) memory.
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "usbd_otp_if.h"
#include "usbd_dfu_mal.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
uint16_t OTP_If_Write (uint32_t Add, uint32_t Len);
uint8_t *OTP_If_Read (uint32_t Add, uint32_t Len);
uint16_t OTP_If_DeInit(void);
uint16_t OTP_If_CheckAdd(uint32_t Add);
/* Private variables ---------------------------------------------------------*/
DFU_MAL_Prop_TypeDef DFU_Otp_cb =
{
OTP_IF_STRING,
NULL, /* Init not supported*/
NULL, /* DeInit not supported */
NULL, /* Erase not supported */
OTP_If_Write,
OTP_If_Read,
OTP_If_CheckAdd,
1, /* Erase Time in ms */
10 /* Programming Time in ms */
};
/* Private functions ---------------------------------------------------------*/
/**
* @brief OTP_If_Write
* Memory write routine.
* @param Add: Address to be written to.
* @param Len: Number of data to be written (in bytes).
* @retval MAL_OK if operation is successeful, MAL_FAIL else.
*/
uint16_t OTP_If_Write(uint32_t Add, uint32_t Len)
{
uint32_t idx = 0;
if (Len & 0x3) /* Not an aligned data */
{
for (idx = Len; idx < ((Len & 0xFFFC) + 4); idx++)
{
MAL_Buffer[idx] = 0xFF;
}
}
/* Data received are Word multiple */
for (idx = 0; idx < Len; idx = idx + 4)
{
FLASH_ProgramWord(Add, *(uint32_t *)(MAL_Buffer + idx));
Add += 4;
}
return MAL_OK;
}
/**
* @brief OTP_If_Read
* Memory read routine.
* @param Add: Address to be read from.
* @param Len: Number of data to be read (in bytes).
* @retval Pointer to the phyisical address where data should be read.
*/
uint8_t *OTP_If_Read (uint32_t Add, uint32_t Len)
{
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
uint32_t idx = 0;
for (idx = 0; idx < Len; idx += 4)
{
*(uint32_t*)(MAL_Buffer + idx) = *(uint32_t *)(Add + idx);
}
return (uint8_t*)(MAL_Buffer);
#else
return (uint8_t*)(Add);
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
}
/**
* @brief OTP_If_CheckAdd
* Check if the address is an allowed address for this memory.
* @param Add: Address to be checked.
* @param Len: Number of data to be read (in bytes).
* @retval MAL_OK if the address is allowed, MAL_FAIL else.
*/
uint16_t OTP_If_CheckAdd(uint32_t Add)
{
if ((Add >= OTP_START_ADD) && (Add < OTP_END_ADD))
{
return MAL_OK;
}
else
{
return MAL_FAIL;
}
}
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,116 @@
/**
******************************************************************************
* @file usbd_hid_core.h
* @author MCD Application Team
* @version V1.1.0
* @date 19-March-2012
* @brief header file for the usbd_hid_core.c file.
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#ifndef __USB_HID_CORE_H_
#define __USB_HID_CORE_H_
#include "usbd_ioreq.h"
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
* @{
*/
/** @defgroup USBD_HID
* @brief This file is the Header file for USBD_msc.c
* @{
*/
/** @defgroup USBD_HID_Exported_Defines
* @{
*/
#define USB_HID_CONFIG_DESC_SIZ 34
#define USB_HID_DESC_SIZ 9
#define HID_MOUSE_REPORT_DESC_SIZE 74
#define HID_DESCRIPTOR_TYPE 0x21
#define HID_REPORT_DESC 0x22
#define HID_REQ_SET_PROTOCOL 0x0B
#define HID_REQ_GET_PROTOCOL 0x03
#define HID_REQ_SET_IDLE 0x0A
#define HID_REQ_GET_IDLE 0x02
#define HID_REQ_SET_REPORT 0x09
#define HID_REQ_GET_REPORT 0x01
/**
* @}
*/
/** @defgroup USBD_CORE_Exported_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @defgroup USBD_CORE_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBD_CORE_Exported_Variables
* @{
*/
extern USBD_Class_cb_TypeDef USBD_HID_cb;
/**
* @}
*/
/** @defgroup USB_CORE_Exported_Functions
* @{
*/
uint8_t USBD_HID_SendReport (USB_OTG_CORE_HANDLE *pdev,
uint8_t *report,
uint16_t len);
/**
* @}
*/
#endif // __USB_HID_CORE_H_
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,487 @@
/**
******************************************************************************
* @file usbd_hid_core.c
* @author MCD Application Team
* @version V1.1.0
* @date 19-March-2012
* @brief This file provides the HID core functions.
*
* @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 protocol
* - Usage Page : Generic Desktop
* - Usage : Joystick)
* - Collection : Application
*
* @note In HS mode and when the DMA is used, all variables and data structures
* dealing with the DMA during the transaction process should be 32-bit aligned.
*
*
* @endverbatim
*
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "usbd_hid_core.h"
#include "usbd_desc.h"
#include "usbd_req.h"
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
* @{
*/
/** @defgroup USBD_HID
* @brief usbd core module
* @{
*/
/** @defgroup USBD_HID_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @defgroup USBD_HID_Private_Defines
* @{
*/
/**
* @}
*/
/** @defgroup USBD_HID_Private_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBD_HID_Private_FunctionPrototypes
* @{
*/
static uint8_t USBD_HID_Init (void *pdev,
uint8_t cfgidx);
static uint8_t USBD_HID_DeInit (void *pdev,
uint8_t cfgidx);
static uint8_t USBD_HID_Setup (void *pdev,
USB_SETUP_REQ *req);
static uint8_t *USBD_HID_GetCfgDesc (uint8_t speed, uint16_t *length);
static uint8_t USBD_HID_DataIn (void *pdev, uint8_t epnum);
/**
* @}
*/
/** @defgroup USBD_HID_Private_Variables
* @{
*/
USBD_Class_cb_TypeDef USBD_HID_cb =
{
USBD_HID_Init,
USBD_HID_DeInit,
USBD_HID_Setup,
NULL, /*EP0_TxSent*/
NULL, /*EP0_RxReady*/
USBD_HID_DataIn, /*DataIn*/
NULL, /*DataOut*/
NULL, /*SOF */
NULL,
NULL,
USBD_HID_GetCfgDesc,
#ifdef USB_OTG_HS_CORE
USBD_HID_GetCfgDesc, /* use same config as per FS */
#endif
};
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
__ALIGN_BEGIN static uint32_t USBD_HID_AltSet __ALIGN_END = 0;
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
__ALIGN_BEGIN static uint32_t USBD_HID_Protocol __ALIGN_END = 0;
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
__ALIGN_BEGIN static uint32_t USBD_HID_IdleState __ALIGN_END = 0;
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
/* USB HID device Configuration Descriptor */
__ALIGN_BEGIN static uint8_t USBD_HID_CfgDesc[USB_HID_CONFIG_DESC_SIZ] __ALIGN_END =
{
0x09, /* bLength: Configuration Descriptor size */
USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */
USB_HID_CONFIG_DESC_SIZ,
/* wTotalLength: Bytes returned */
0x00,
0x01, /*bNumInterfaces: 1 interface*/
0x01, /*bConfigurationValue: Configuration value*/
0x00, /*iConfiguration: Index of string descriptor describing
the configuration*/
0xE0, /*bmAttributes: bus powered and Support Remote Wake-up */
0x32, /*MaxPower 100 mA: this current is used for detecting Vbus*/
/************** Descriptor of Joystick Mouse interface ****************/
/* 09 */
0x09, /*bLength: Interface Descriptor size*/
USB_INTERFACE_DESCRIPTOR_TYPE,/*bDescriptorType: Interface descriptor type*/
0x00, /*bInterfaceNumber: Number of Interface*/
0x00, /*bAlternateSetting: Alternate setting*/
0x01, /*bNumEndpoints*/
0x03, /*bInterfaceClass: HID*/
0x01, /*bInterfaceSubClass : 1=BOOT, 0=no boot*/
0x02, /*nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse*/
0, /*iInterface: Index of string descriptor*/
/******************** Descriptor of Joystick Mouse HID ********************/
/* 18 */
0x09, /*bLength: HID Descriptor size*/
HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID*/
0x11, /*bcdHID: HID Class Spec release number*/
0x01,
0x00, /*bCountryCode: Hardware target country*/
0x01, /*bNumDescriptors: Number of HID class descriptors to follow*/
0x22, /*bDescriptorType*/
HID_MOUSE_REPORT_DESC_SIZE,/*wItemLength: Total length of Report descriptor*/
0x00,
/******************** Descriptor of Mouse endpoint ********************/
/* 27 */
0x07, /*bLength: Endpoint Descriptor size*/
USB_ENDPOINT_DESCRIPTOR_TYPE, /*bDescriptorType:*/
HID_IN_EP, /*bEndpointAddress: Endpoint Address (IN)*/
0x03, /*bmAttributes: Interrupt endpoint*/
HID_IN_PACKET, /*wMaxPacketSize: 4 Byte max */
0x00,
0x0A, /*bInterval: Polling Interval (10 ms)*/
/* 34 */
} ;
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
/* USB HID device Configuration Descriptor */
__ALIGN_BEGIN static uint8_t USBD_HID_Desc[USB_HID_DESC_SIZ] __ALIGN_END=
{
/* 18 */
0x09, /*bLength: HID Descriptor size*/
HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID*/
0x11, /*bcdHID: HID Class Spec release number*/
0x01,
0x00, /*bCountryCode: Hardware target country*/
0x01, /*bNumDescriptors: Number of HID class descriptors to follow*/
0x22, /*bDescriptorType*/
HID_MOUSE_REPORT_DESC_SIZE,/*wItemLength: Total length of Report descriptor*/
0x00,
};
#endif
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
__ALIGN_BEGIN static uint8_t HID_MOUSE_ReportDesc[HID_MOUSE_REPORT_DESC_SIZE] __ALIGN_END =
{
0x05, 0x01,
0x09, 0x02,
0xA1, 0x01,
0x09, 0x01,
0xA1, 0x00,
0x05, 0x09,
0x19, 0x01,
0x29, 0x03,
0x15, 0x00,
0x25, 0x01,
0x95, 0x03,
0x75, 0x01,
0x81, 0x02,
0x95, 0x01,
0x75, 0x05,
0x81, 0x01,
0x05, 0x01,
0x09, 0x30,
0x09, 0x31,
0x09, 0x38,
0x15, 0x81,
0x25, 0x7F,
0x75, 0x08,
0x95, 0x03,
0x81, 0x06,
0xC0, 0x09,
0x3c, 0x05,
0xff, 0x09,
0x01, 0x15,
0x00, 0x25,
0x01, 0x75,
0x01, 0x95,
0x02, 0xb1,
0x22, 0x75,
0x06, 0x95,
0x01, 0xb1,
0x01, 0xc0
};
/**
* @}
*/
/** @defgroup USBD_HID_Private_Functions
* @{
*/
/**
* @brief USBD_HID_Init
* Initialize the HID interface
* @param pdev: device instance
* @param cfgidx: Configuration index
* @retval status
*/
static uint8_t USBD_HID_Init (void *pdev,
uint8_t cfgidx)
{
/* Open EP IN */
DCD_EP_Open(pdev,
HID_IN_EP,
HID_IN_PACKET,
USB_OTG_EP_INT);
/* Open EP OUT */
DCD_EP_Open(pdev,
HID_OUT_EP,
HID_OUT_PACKET,
USB_OTG_EP_INT);
return USBD_OK;
}
/**
* @brief USBD_HID_Init
* DeInitialize the HID layer
* @param pdev: device instance
* @param cfgidx: Configuration index
* @retval status
*/
static uint8_t USBD_HID_DeInit (void *pdev,
uint8_t cfgidx)
{
/* Close HID EPs */
DCD_EP_Close (pdev , HID_IN_EP);
DCD_EP_Close (pdev , HID_OUT_EP);
return USBD_OK;
}
/**
* @brief USBD_HID_Setup
* Handle the HID specific requests
* @param pdev: instance
* @param req: usb requests
* @retval status
*/
static uint8_t USBD_HID_Setup (void *pdev,
USB_SETUP_REQ *req)
{
uint16_t len = 0;
uint8_t *pbuf = NULL;
switch (req->bmRequest & USB_REQ_TYPE_MASK)
{
case USB_REQ_TYPE_CLASS :
switch (req->bRequest)
{
case HID_REQ_SET_PROTOCOL:
USBD_HID_Protocol = (uint8_t)(req->wValue);
break;
case HID_REQ_GET_PROTOCOL:
USBD_CtlSendData (pdev,
(uint8_t *)&USBD_HID_Protocol,
1);
break;
case HID_REQ_SET_IDLE:
USBD_HID_IdleState = (uint8_t)(req->wValue >> 8);
break;
case HID_REQ_GET_IDLE:
USBD_CtlSendData (pdev,
(uint8_t *)&USBD_HID_IdleState,
1);
break;
default:
USBD_CtlError (pdev, req);
return USBD_FAIL;
}
break;
case USB_REQ_TYPE_STANDARD:
switch (req->bRequest)
{
case USB_REQ_GET_DESCRIPTOR:
if( req->wValue >> 8 == HID_REPORT_DESC)
{
len = MIN(HID_MOUSE_REPORT_DESC_SIZE , req->wLength);
pbuf = HID_MOUSE_ReportDesc;
}
else if( req->wValue >> 8 == HID_DESCRIPTOR_TYPE)
{
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
pbuf = USBD_HID_Desc;
#else
pbuf = USBD_HID_CfgDesc + 0x12;
#endif
len = MIN(USB_HID_DESC_SIZ , req->wLength);
}
USBD_CtlSendData (pdev,
pbuf,
len);
break;
case USB_REQ_GET_INTERFACE :
USBD_CtlSendData (pdev,
(uint8_t *)&USBD_HID_AltSet,
1);
break;
case USB_REQ_SET_INTERFACE :
USBD_HID_AltSet = (uint8_t)(req->wValue);
break;
}
}
return USBD_OK;
}
/**
* @brief USBD_HID_SendReport
* Send HID Report
* @param pdev: device instance
* @param buff: pointer to report
* @retval status
*/
uint8_t USBD_HID_SendReport (USB_OTG_CORE_HANDLE *pdev,
uint8_t *report,
uint16_t len)
{
if (pdev->dev.device_status == USB_OTG_CONFIGURED )
{
DCD_EP_Tx (pdev, HID_IN_EP, report, len);
}
return USBD_OK;
}
/**
* @brief USBD_HID_GetCfgDesc
* return configuration descriptor
* @param speed : current device speed
* @param length : pointer data length
* @retval pointer to descriptor buffer
*/
static uint8_t *USBD_HID_GetCfgDesc (uint8_t speed, uint16_t *length)
{
*length = sizeof (USBD_HID_CfgDesc);
return USBD_HID_CfgDesc;
}
/**
* @brief USBD_HID_DataIn
* handle data IN Stage
* @param pdev: device instance
* @param epnum: endpoint index
* @retval status
*/
static uint8_t USBD_HID_DataIn (void *pdev,
uint8_t epnum)
{
/* Ensure that the FIFO is empty before a new transfer, this condition could
be caused by a new transfer before the end of the previous transfer */
DCD_EP_Flush(pdev, HID_IN_EP);
return USBD_OK;
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,153 @@
/**
******************************************************************************
* @file usbd_msc_bot.h
* @author MCD Application Team
* @version V1.1.0
* @date 19-March-2012
* @brief header for the usbd_msc_bot.c file
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#include "usbd_core.h"
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USBD_MSC_BOT_H
#define __USBD_MSC_BOT_H
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
* @{
*/
/** @defgroup MSC_BOT
* @brief This file is the Header file for usbd_bot.c
* @{
*/
/** @defgroup USBD_CORE_Exported_Defines
* @{
*/
#define BOT_IDLE 0 /* Idle state */
#define BOT_DATA_OUT 1 /* Data Out state */
#define BOT_DATA_IN 2 /* Data In state */
#define BOT_LAST_DATA_IN 3 /* Last Data In Last */
#define BOT_SEND_DATA 4 /* Send Immediate data */
#define BOT_CBW_SIGNATURE 0x43425355
#define BOT_CSW_SIGNATURE 0x53425355
#define BOT_CBW_LENGTH 31
#define BOT_CSW_LENGTH 13
/* CSW Status Definitions */
#define CSW_CMD_PASSED 0x00
#define CSW_CMD_FAILED 0x01
#define CSW_PHASE_ERROR 0x02
/* BOT Status */
#define BOT_STATE_NORMAL 0
#define BOT_STATE_RECOVERY 1
#define BOT_STATE_ERROR 2
#define DIR_IN 0
#define DIR_OUT 1
#define BOTH_DIR 2
/**
* @}
*/
/** @defgroup MSC_CORE_Private_TypesDefinitions
* @{
*/
typedef struct _MSC_BOT_CBW
{
uint32_t dSignature;
uint32_t dTag;
uint32_t dDataLength;
uint8_t bmFlags;
uint8_t bLUN;
uint8_t bCBLength;
uint8_t CB[16];
}
MSC_BOT_CBW_TypeDef;
typedef struct _MSC_BOT_CSW
{
uint32_t dSignature;
uint32_t dTag;
uint32_t dDataResidue;
uint8_t bStatus;
}
MSC_BOT_CSW_TypeDef;
/**
* @}
*/
/** @defgroup USBD_CORE_Exported_Types
* @{
*/
extern uint8_t MSC_BOT_Data[];
extern uint16_t MSC_BOT_DataLen;
extern uint8_t MSC_BOT_State;
extern uint8_t MSC_BOT_BurstMode;
extern MSC_BOT_CBW_TypeDef MSC_BOT_cbw;
extern MSC_BOT_CSW_TypeDef MSC_BOT_csw;
/**
* @}
*/
/** @defgroup USBD_CORE_Exported_FunctionsPrototypes
* @{
*/
void MSC_BOT_Init (USB_OTG_CORE_HANDLE *pdev);
void MSC_BOT_Reset (USB_OTG_CORE_HANDLE *pdev);
void MSC_BOT_DeInit (USB_OTG_CORE_HANDLE *pdev);
void MSC_BOT_DataIn (USB_OTG_CORE_HANDLE *pdev,
uint8_t epnum);
void MSC_BOT_DataOut (USB_OTG_CORE_HANDLE *pdev,
uint8_t epnum);
void MSC_BOT_SendCSW (USB_OTG_CORE_HANDLE *pdev,
uint8_t CSW_Status);
void MSC_BOT_CplClrFeature (USB_OTG_CORE_HANDLE *pdev,
uint8_t epnum);
/**
* @}
*/
#endif /* __USBD_MSC_BOT_H */
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,77 @@
/**
******************************************************************************
* @file usbd_msc_core.h
* @author MCD Application Team
* @version V1.1.0
* @date 19-March-2012
* @brief header for the usbd_msc_core.c file
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef _USB_MSC_CORE_H_
#define _USB_MSC_CORE_H_
#include "usbd_ioreq.h"
/** @addtogroup USBD_MSC_BOT
* @{
*/
/** @defgroup USBD_MSC
* @brief This file is the Header file for USBD_msc.c
* @{
*/
/** @defgroup USBD_BOT_Exported_Defines
* @{
*/
#define BOT_GET_MAX_LUN 0xFE
#define BOT_RESET 0xFF
#define USB_MSC_CONFIG_DESC_SIZ 32
#define MSC_EPIN_SIZE MSC_MAX_PACKET
#define MSC_EPOUT_SIZE MSC_MAX_PACKET
/**
* @}
*/
/** @defgroup USB_CORE_Exported_Types
* @{
*/
extern USBD_Class_cb_TypeDef USBD_MSC_cb;
/**
* @}
*/
/**
* @}
*/
#endif // _USB_MSC_CORE_H_
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,104 @@
/**
******************************************************************************
* @file usbd_msc_data.h
* @author MCD Application Team
* @version V1.1.0
* @date 19-March-2012
* @brief header for the usbd_msc_data.c file
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef _USBD_MSC_DATA_H_
#define _USBD_MSC_DATA_H_
/* Includes ------------------------------------------------------------------*/
#include "usbd_conf.h"
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
* @{
*/
/** @defgroup USB_INFO
* @brief general defines for the usb device library file
* @{
*/
/** @defgroup USB_INFO_Exported_Defines
* @{
*/
#define MODE_SENSE6_LEN 8
#define MODE_SENSE10_LEN 8
#define LENGTH_INQUIRY_PAGE00 7
#define LENGTH_FORMAT_CAPACITIES 20
/**
* @}
*/
/** @defgroup USBD_INFO_Exported_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @defgroup USBD_INFO_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBD_INFO_Exported_Variables
* @{
*/
extern const uint8_t MSC_Page00_Inquiry_Data[];
extern const uint8_t MSC_Mode_Sense6_data[];
extern const uint8_t MSC_Mode_Sense10_data[] ;
/**
* @}
*/
/** @defgroup USBD_INFO_Exported_FunctionsPrototype
* @{
*/
/**
* @}
*/
#endif /* _USBD_MSC_DATA_H_ */
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,112 @@
/**
******************************************************************************
* @file usbd_msc_mem.h
* @author MCD Application Team
* @version V1.1.0
* @date 19-March-2012
* @brief header for the STORAGE DISK file file
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USBD_MEM_H
#define __USBD_MEM_H
/* Includes ------------------------------------------------------------------*/
#include "usbd_def.h"
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
* @{
*/
/** @defgroup USBD_MEM
* @brief header file for the storage disk file
* @{
*/
/** @defgroup USBD_MEM_Exported_Defines
* @{
*/
#define USBD_STD_INQUIRY_LENGTH 36
/**
* @}
*/
/** @defgroup USBD_MEM_Exported_TypesDefinitions
* @{
*/
typedef struct _USBD_STORAGE
{
int8_t (* Init) (uint8_t lun);
int8_t (* GetCapacity) (uint8_t lun, uint32_t *block_num, uint32_t *block_size);
int8_t (* IsReady) (uint8_t lun);
int8_t (* IsWriteProtected) (uint8_t lun);
int8_t (* Read) (uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len);
int8_t (* Write)(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len);
int8_t (* GetMaxLun)(void);
int8_t *pInquiry;
}USBD_STORAGE_cb_TypeDef;
/**
* @}
*/
/** @defgroup USBD_MEM_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBD_MEM_Exported_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USBD_MEM_Exported_FunctionsPrototype
* @{
*/
extern USBD_STORAGE_cb_TypeDef *USBD_STORAGE_fops;
/**
* @}
*/
#endif /* __USBD_MEM_H */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,195 @@
/**
******************************************************************************
* @file usbd_msc_scsi.h
* @author MCD Application Team
* @version V1.1.0
* @date 19-March-2012
* @brief header for the usbd_msc_scsi.c file
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USBD_MSC_SCSI_H
#define __USBD_MSC_SCSI_H
/* Includes ------------------------------------------------------------------*/
#include "usbd_def.h"
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
* @{
*/
/** @defgroup USBD_SCSI
* @brief header file for the storage disk file
* @{
*/
/** @defgroup USBD_SCSI_Exported_Defines
* @{
*/
#define SENSE_LIST_DEEPTH 4
/* SCSI Commands */
#define SCSI_FORMAT_UNIT 0x04
#define SCSI_INQUIRY 0x12
#define SCSI_MODE_SELECT6 0x15
#define SCSI_MODE_SELECT10 0x55
#define SCSI_MODE_SENSE6 0x1A
#define SCSI_MODE_SENSE10 0x5A
#define SCSI_ALLOW_MEDIUM_REMOVAL 0x1E
#define SCSI_READ6 0x08
#define SCSI_READ10 0x28
#define SCSI_READ12 0xA8
#define SCSI_READ16 0x88
#define SCSI_READ_CAPACITY10 0x25
#define SCSI_READ_CAPACITY16 0x9E
#define SCSI_REQUEST_SENSE 0x03
#define SCSI_START_STOP_UNIT 0x1B
#define SCSI_TEST_UNIT_READY 0x00
#define SCSI_WRITE6 0x0A
#define SCSI_WRITE10 0x2A
#define SCSI_WRITE12 0xAA
#define SCSI_WRITE16 0x8A
#define SCSI_VERIFY10 0x2F
#define SCSI_VERIFY12 0xAF
#define SCSI_VERIFY16 0x8F
#define SCSI_SEND_DIAGNOSTIC 0x1D
#define SCSI_READ_FORMAT_CAPACITIES 0x23
#define NO_SENSE 0
#define RECOVERED_ERROR 1
#define NOT_READY 2
#define MEDIUM_ERROR 3
#define HARDWARE_ERROR 4
#define ILLEGAL_REQUEST 5
#define UNIT_ATTENTION 6
#define DATA_PROTECT 7
#define BLANK_CHECK 8
#define VENDOR_SPECIFIC 9
#define COPY_ABORTED 10
#define ABORTED_COMMAND 11
#define VOLUME_OVERFLOW 13
#define MISCOMPARE 14
#define INVALID_CDB 0x20
#define INVALID_FIELED_IN_COMMAND 0x24
#define PARAMETER_LIST_LENGTH_ERROR 0x1A
#define INVALID_FIELD_IN_PARAMETER_LIST 0x26
#define ADDRESS_OUT_OF_RANGE 0x21
#define MEDIUM_NOT_PRESENT 0x3A
#define MEDIUM_HAVE_CHANGED 0x28
#define WRITE_PROTECTED 0x27
#define UNRECOVERED_READ_ERROR 0x11
#define WRITE_FAULT 0x03
#define READ_FORMAT_CAPACITY_DATA_LEN 0x0C
#define READ_CAPACITY10_DATA_LEN 0x08
#define MODE_SENSE10_DATA_LEN 0x08
#define MODE_SENSE6_DATA_LEN 0x04
#define REQUEST_SENSE_DATA_LEN 0x12
#define STANDARD_INQUIRY_DATA_LEN 0x24
#define BLKVFY 0x04
extern uint8_t Page00_Inquiry_Data[];
extern uint8_t Standard_Inquiry_Data[];
extern uint8_t Standard_Inquiry_Data2[];
extern uint8_t Mode_Sense6_data[];
extern uint8_t Mode_Sense10_data[];
extern uint8_t Scsi_Sense_Data[];
extern uint8_t ReadCapacity10_Data[];
extern uint8_t ReadFormatCapacity_Data [];
/**
* @}
*/
/** @defgroup USBD_SCSI_Exported_TypesDefinitions
* @{
*/
typedef struct _SENSE_ITEM {
char Skey;
union {
struct _ASCs {
char ASC;
char ASCQ;
}b;
unsigned int ASC;
char *pData;
} w;
} SCSI_Sense_TypeDef;
/**
* @}
*/
/** @defgroup USBD_SCSI_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBD_SCSI_Exported_Variables
* @{
*/
extern SCSI_Sense_TypeDef SCSI_Sense [SENSE_LIST_DEEPTH];
extern uint8_t SCSI_Sense_Head;
extern uint8_t SCSI_Sense_Tail;
/**
* @}
*/
/** @defgroup USBD_SCSI_Exported_FunctionsPrototype
* @{
*/
int8_t SCSI_ProcessCmd(USB_OTG_CORE_HANDLE *pdev,
uint8_t lun,
uint8_t *cmd);
void SCSI_SenseCode(uint8_t lun,
uint8_t sKey,
uint8_t ASC);
/**
* @}
*/
#endif /* __USBD_MSC_SCSI_H */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,400 @@
/**
******************************************************************************
* @file usbd_msc_bot.c
* @author MCD Application Team
* @version V1.1.0
* @date 19-March-2012
* @brief This file provides all the BOT protocol core functions.
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "usbd_msc_bot.h"
#include "usbd_msc_scsi.h"
#include "usbd_ioreq.h"
#include "usbd_msc_mem.h"
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
* @{
*/
/** @defgroup MSC_BOT
* @brief BOT protocol module
* @{
*/
/** @defgroup MSC_BOT_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @defgroup MSC_BOT_Private_Defines
* @{
*/
/**
* @}
*/
/** @defgroup MSC_BOT_Private_Macros
* @{
*/
/**
* @}
*/
/** @defgroup MSC_BOT_Private_Variables
* @{
*/
uint16_t MSC_BOT_DataLen;
uint8_t MSC_BOT_State;
uint8_t MSC_BOT_Status;
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
__ALIGN_BEGIN uint8_t MSC_BOT_Data[MSC_MEDIA_PACKET] __ALIGN_END ;
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
__ALIGN_BEGIN MSC_BOT_CBW_TypeDef MSC_BOT_cbw __ALIGN_END ;
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
__ALIGN_BEGIN MSC_BOT_CSW_TypeDef MSC_BOT_csw __ALIGN_END ;
/**
* @}
*/
/** @defgroup MSC_BOT_Private_FunctionPrototypes
* @{
*/
static void MSC_BOT_CBW_Decode (USB_OTG_CORE_HANDLE *pdev);
static void MSC_BOT_SendData (USB_OTG_CORE_HANDLE *pdev,
uint8_t* pbuf,
uint16_t len);
static void MSC_BOT_Abort(USB_OTG_CORE_HANDLE *pdev);
/**
* @}
*/
/** @defgroup MSC_BOT_Private_Functions
* @{
*/
/**
* @brief MSC_BOT_Init
* Initialize the BOT Process
* @param pdev: device instance
* @retval None
*/
void MSC_BOT_Init (USB_OTG_CORE_HANDLE *pdev)
{
MSC_BOT_State = BOT_IDLE;
MSC_BOT_Status = BOT_STATE_NORMAL;
USBD_STORAGE_fops->Init(0);
DCD_EP_Flush(pdev, MSC_OUT_EP);
DCD_EP_Flush(pdev, MSC_IN_EP);
/* Prapare EP to Receive First BOT Cmd */
DCD_EP_PrepareRx (pdev,
MSC_OUT_EP,
(uint8_t *)&MSC_BOT_cbw,
BOT_CBW_LENGTH);
}
/**
* @brief MSC_BOT_Reset
* Reset the BOT Machine
* @param pdev: device instance
* @retval None
*/
void MSC_BOT_Reset (USB_OTG_CORE_HANDLE *pdev)
{
MSC_BOT_State = BOT_IDLE;
MSC_BOT_Status = BOT_STATE_RECOVERY;
/* Prapare EP to Receive First BOT Cmd */
DCD_EP_PrepareRx (pdev,
MSC_OUT_EP,
(uint8_t *)&MSC_BOT_cbw,
BOT_CBW_LENGTH);
}
/**
* @brief MSC_BOT_DeInit
* Uninitialize the BOT Machine
* @param pdev: device instance
* @retval None
*/
void MSC_BOT_DeInit (USB_OTG_CORE_HANDLE *pdev)
{
MSC_BOT_State = BOT_IDLE;
}
/**
* @brief MSC_BOT_DataIn
* Handle BOT IN data stage
* @param pdev: device instance
* @param epnum: endpoint index
* @retval None
*/
void MSC_BOT_DataIn (USB_OTG_CORE_HANDLE *pdev,
uint8_t epnum)
{
switch (MSC_BOT_State)
{
case BOT_DATA_IN:
if(SCSI_ProcessCmd(pdev,
MSC_BOT_cbw.bLUN,
&MSC_BOT_cbw.CB[0]) < 0)
{
MSC_BOT_SendCSW (pdev, CSW_CMD_FAILED);
}
break;
case BOT_SEND_DATA:
case BOT_LAST_DATA_IN:
MSC_BOT_SendCSW (pdev, CSW_CMD_PASSED);
break;
default:
break;
}
}
/**
* @brief MSC_BOT_DataOut
* Proccess MSC OUT data
* @param pdev: device instance
* @param epnum: endpoint index
* @retval None
*/
void MSC_BOT_DataOut (USB_OTG_CORE_HANDLE *pdev,
uint8_t epnum)
{
switch (MSC_BOT_State)
{
case BOT_IDLE:
MSC_BOT_CBW_Decode(pdev);
break;
case BOT_DATA_OUT:
if(SCSI_ProcessCmd(pdev,
MSC_BOT_cbw.bLUN,
&MSC_BOT_cbw.CB[0]) < 0)
{
MSC_BOT_SendCSW (pdev, CSW_CMD_FAILED);
}
break;
default:
break;
}
}
/**
* @brief MSC_BOT_CBW_Decode
* Decode the CBW command and set the BOT state machine accordingtly
* @param pdev: device instance
* @retval None
*/
static void MSC_BOT_CBW_Decode (USB_OTG_CORE_HANDLE *pdev)
{
MSC_BOT_csw.dTag = MSC_BOT_cbw.dTag;
MSC_BOT_csw.dDataResidue = MSC_BOT_cbw.dDataLength;
if ((USBD_GetRxCount (pdev ,MSC_OUT_EP) != BOT_CBW_LENGTH) ||
(MSC_BOT_cbw.dSignature != BOT_CBW_SIGNATURE)||
(MSC_BOT_cbw.bLUN > 1) ||
(MSC_BOT_cbw.bCBLength < 1) ||
(MSC_BOT_cbw.bCBLength > 16))
{
SCSI_SenseCode(MSC_BOT_cbw.bLUN,
ILLEGAL_REQUEST,
INVALID_CDB);
MSC_BOT_Status = BOT_STATE_ERROR;
MSC_BOT_Abort(pdev);
}
else
{
if(SCSI_ProcessCmd(pdev,
MSC_BOT_cbw.bLUN,
&MSC_BOT_cbw.CB[0]) < 0)
{
MSC_BOT_Abort(pdev);
}
/*Burst xfer handled internally*/
else if ((MSC_BOT_State != BOT_DATA_IN) &&
(MSC_BOT_State != BOT_DATA_OUT) &&
(MSC_BOT_State != BOT_LAST_DATA_IN))
{
if (MSC_BOT_DataLen > 0)
{
MSC_BOT_SendData(pdev,
MSC_BOT_Data,
MSC_BOT_DataLen);
}
else if (MSC_BOT_DataLen == 0)
{
MSC_BOT_SendCSW (pdev,
CSW_CMD_PASSED);
}
}
}
}
/**
* @brief MSC_BOT_SendData
* Send the requested data
* @param pdev: device instance
* @param buf: pointer to data buffer
* @param len: Data Length
* @retval None
*/
static void MSC_BOT_SendData(USB_OTG_CORE_HANDLE *pdev,
uint8_t* buf,
uint16_t len)
{
len = MIN (MSC_BOT_cbw.dDataLength, len);
MSC_BOT_csw.dDataResidue -= len;
MSC_BOT_csw.bStatus = CSW_CMD_PASSED;
MSC_BOT_State = BOT_SEND_DATA;
DCD_EP_Tx (pdev, MSC_IN_EP, buf, len);
}
/**
* @brief MSC_BOT_SendCSW
* Send the Command Status Wrapper
* @param pdev: device instance
* @param status : CSW status
* @retval None
*/
void MSC_BOT_SendCSW (USB_OTG_CORE_HANDLE *pdev,
uint8_t CSW_Status)
{
MSC_BOT_csw.dSignature = BOT_CSW_SIGNATURE;
MSC_BOT_csw.bStatus = CSW_Status;
MSC_BOT_State = BOT_IDLE;
DCD_EP_Tx (pdev,
MSC_IN_EP,
(uint8_t *)&MSC_BOT_csw,
BOT_CSW_LENGTH);
/* Prapare EP to Receive next Cmd */
DCD_EP_PrepareRx (pdev,
MSC_OUT_EP,
(uint8_t *)&MSC_BOT_cbw,
BOT_CBW_LENGTH);
}
/**
* @brief MSC_BOT_Abort
* Abort the current transfer
* @param pdev: device instance
* @retval status
*/
static void MSC_BOT_Abort (USB_OTG_CORE_HANDLE *pdev)
{
if ((MSC_BOT_cbw.bmFlags == 0) &&
(MSC_BOT_cbw.dDataLength != 0) &&
(MSC_BOT_Status == BOT_STATE_NORMAL) )
{
DCD_EP_Stall(pdev, MSC_OUT_EP );
}
DCD_EP_Stall(pdev, MSC_IN_EP);
if(MSC_BOT_Status == BOT_STATE_ERROR)
{
DCD_EP_PrepareRx (pdev,
MSC_OUT_EP,
(uint8_t *)&MSC_BOT_cbw,
BOT_CBW_LENGTH);
}
}
/**
* @brief MSC_BOT_CplClrFeature
* Complete the clear feature request
* @param pdev: device instance
* @param epnum: endpoint index
* @retval None
*/
void MSC_BOT_CplClrFeature (USB_OTG_CORE_HANDLE *pdev, uint8_t epnum)
{
if(MSC_BOT_Status == BOT_STATE_ERROR )/* Bad CBW Signature */
{
DCD_EP_Stall(pdev, MSC_IN_EP);
MSC_BOT_Status = BOT_STATE_NORMAL;
}
else if(((epnum & 0x80) == 0x80) && ( MSC_BOT_Status != BOT_STATE_RECOVERY))
{
MSC_BOT_SendCSW (pdev, CSW_CMD_FAILED);
}
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,496 @@
/**
******************************************************************************
* @file usbd_msc_core.c
* @author MCD Application Team
* @version V1.1.0
* @date 19-March-2012
* @brief This file provides all the MSC core functions.
*
* @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
*
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "usbd_msc_mem.h"
#include "usbd_msc_core.h"
#include "usbd_msc_bot.h"
#include "usbd_req.h"
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
* @{
*/
/** @defgroup MSC_CORE
* @brief Mass storage core module
* @{
*/
/** @defgroup MSC_CORE_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @defgroup MSC_CORE_Private_Defines
* @{
*/
/**
* @}
*/
/** @defgroup MSC_CORE_Private_Macros
* @{
*/
/**
* @}
*/
/** @defgroup MSC_CORE_Private_FunctionPrototypes
* @{
*/
uint8_t USBD_MSC_Init (void *pdev,
uint8_t cfgidx);
uint8_t USBD_MSC_DeInit (void *pdev,
uint8_t cfgidx);
uint8_t USBD_MSC_Setup (void *pdev,
USB_SETUP_REQ *req);
uint8_t USBD_MSC_DataIn (void *pdev,
uint8_t epnum);
uint8_t USBD_MSC_DataOut (void *pdev,
uint8_t epnum);
uint8_t *USBD_MSC_GetCfgDesc (uint8_t speed,
uint16_t *length);
#ifdef USB_OTG_HS_CORE
uint8_t *USBD_MSC_GetOtherCfgDesc (uint8_t speed,
uint16_t *length);
#endif
uint8_t USBD_MSC_CfgDesc[USB_MSC_CONFIG_DESC_SIZ];
/**
* @}
*/
/** @defgroup MSC_CORE_Private_Variables
* @{
*/
USBD_Class_cb_TypeDef USBD_MSC_cb =
{
USBD_MSC_Init,
USBD_MSC_DeInit,
USBD_MSC_Setup,
NULL, /*EP0_TxSent*/
NULL, /*EP0_RxReady*/
USBD_MSC_DataIn,
USBD_MSC_DataOut,
NULL, /*SOF */
NULL,
NULL,
USBD_MSC_GetCfgDesc,
#ifdef USB_OTG_HS_CORE
USBD_MSC_GetOtherCfgDesc,
#endif
};
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
/* USB Mass storage device Configuration Descriptor */
/* All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */
__ALIGN_BEGIN uint8_t USBD_MSC_CfgDesc[USB_MSC_CONFIG_DESC_SIZ] __ALIGN_END =
{
0x09, /* bLength: Configuation Descriptor size */
USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
USB_MSC_CONFIG_DESC_SIZ,
0x00,
0x01, /* bNumInterfaces: 1 interface */
0x01, /* bConfigurationValue: */
0x04, /* iConfiguration: */
0xC0, /* bmAttributes: */
0x32, /* MaxPower 100 mA */
/******************** Mass Storage interface ********************/
0x09, /* bLength: Interface Descriptor size */
0x04, /* bDescriptorType: */
0x00, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x02, /* bNumEndpoints*/
0x08, /* bInterfaceClass: MSC Class */
0x06, /* bInterfaceSubClass : SCSI transparent*/
0x50, /* nInterfaceProtocol */
0x05, /* iInterface: */
/******************** Mass Storage Endpoints ********************/
0x07, /*Endpoint descriptor length = 7*/
0x05, /*Endpoint descriptor type */
MSC_IN_EP, /*Endpoint address (IN, address 1) */
0x02, /*Bulk endpoint type */
LOBYTE(MSC_MAX_PACKET),
HIBYTE(MSC_MAX_PACKET),
0x00, /*Polling interval in milliseconds */
0x07, /*Endpoint descriptor length = 7 */
0x05, /*Endpoint descriptor type */
MSC_OUT_EP, /*Endpoint address (OUT, address 1) */
0x02, /*Bulk endpoint type */
LOBYTE(MSC_MAX_PACKET),
HIBYTE(MSC_MAX_PACKET),
0x00 /*Polling interval in milliseconds*/
};
#ifdef USB_OTG_HS_CORE
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
__ALIGN_BEGIN uint8_t USBD_MSC_OtherCfgDesc[USB_MSC_CONFIG_DESC_SIZ] __ALIGN_END =
{
0x09, /* bLength: Configuation Descriptor size */
USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION,
USB_MSC_CONFIG_DESC_SIZ,
0x00,
0x01, /* bNumInterfaces: 1 interface */
0x01, /* bConfigurationValue: */
0x04, /* iConfiguration: */
0xC0, /* bmAttributes: */
0x32, /* MaxPower 100 mA */
/******************** Mass Storage interface ********************/
0x09, /* bLength: Interface Descriptor size */
0x04, /* bDescriptorType: */
0x00, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x02, /* bNumEndpoints*/
0x08, /* bInterfaceClass: MSC Class */
0x06, /* bInterfaceSubClass : SCSI transparent command set*/
0x50, /* nInterfaceProtocol */
0x05, /* iInterface: */
/******************** Mass Storage Endpoints ********************/
0x07, /*Endpoint descriptor length = 7*/
0x05, /*Endpoint descriptor type */
MSC_IN_EP, /*Endpoint address (IN, address 1) */
0x02, /*Bulk endpoint type */
0x40,
0x00,
0x00, /*Polling interval in milliseconds */
0x07, /*Endpoint descriptor length = 7 */
0x05, /*Endpoint descriptor type */
MSC_OUT_EP, /*Endpoint address (OUT, address 1) */
0x02, /*Bulk endpoint type */
0x40,
0x00,
0x00 /*Polling interval in milliseconds*/
};
#endif
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
__ALIGN_BEGIN static uint8_t USBD_MSC_MaxLun __ALIGN_END = 0;
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
__ALIGN_BEGIN static uint8_t USBD_MSC_AltSet __ALIGN_END = 0;
/**
* @}
*/
/** @defgroup MSC_CORE_Private_Functions
* @{
*/
/**
* @brief USBD_MSC_Init
* Initialize the mass storage configuration
* @param pdev: device instance
* @param cfgidx: configuration index
* @retval status
*/
uint8_t USBD_MSC_Init (void *pdev,
uint8_t cfgidx)
{
USBD_MSC_DeInit(pdev , cfgidx );
/* Open EP IN */
DCD_EP_Open(pdev,
MSC_IN_EP,
MSC_EPIN_SIZE,
USB_OTG_EP_BULK);
/* Open EP OUT */
DCD_EP_Open(pdev,
MSC_OUT_EP,
MSC_EPOUT_SIZE,
USB_OTG_EP_BULK);
/* Init the BOT layer */
MSC_BOT_Init(pdev);
return USBD_OK;
}
/**
* @brief USBD_MSC_DeInit
* DeInitilaize the mass storage configuration
* @param pdev: device instance
* @param cfgidx: configuration index
* @retval status
*/
uint8_t USBD_MSC_DeInit (void *pdev,
uint8_t cfgidx)
{
/* Close MSC EPs */
DCD_EP_Close (pdev , MSC_IN_EP);
DCD_EP_Close (pdev , MSC_OUT_EP);
/* Un Init the BOT layer */
MSC_BOT_DeInit(pdev);
return USBD_OK;
}
/**
* @brief USBD_MSC_Setup
* Handle the MSC specific requests
* @param pdev: device instance
* @param req: USB request
* @retval status
*/
uint8_t USBD_MSC_Setup (void *pdev, USB_SETUP_REQ *req)
{
switch (req->bmRequest & USB_REQ_TYPE_MASK)
{
/* Class request */
case USB_REQ_TYPE_CLASS :
switch (req->bRequest)
{
case BOT_GET_MAX_LUN :
if((req->wValue == 0) &&
(req->wLength == 1) &&
((req->bmRequest & 0x80) == 0x80))
{
USBD_MSC_MaxLun = USBD_STORAGE_fops->GetMaxLun();
if(USBD_MSC_MaxLun > 0)
{
USBD_CtlSendData (pdev,
&USBD_MSC_MaxLun,
1);
}
else
{
USBD_CtlError(pdev , req);
return USBD_FAIL;
}
}
else
{
USBD_CtlError(pdev , req);
return USBD_FAIL;
}
break;
case BOT_RESET :
if((req->wValue == 0) &&
(req->wLength == 0) &&
((req->bmRequest & 0x80) != 0x80))
{
MSC_BOT_Reset(pdev);
}
else
{
USBD_CtlError(pdev , req);
return USBD_FAIL;
}
break;
default:
USBD_CtlError(pdev , req);
return USBD_FAIL;
}
break;
/* Interface & Endpoint request */
case USB_REQ_TYPE_STANDARD:
switch (req->bRequest)
{
case USB_REQ_GET_INTERFACE :
USBD_CtlSendData (pdev,
&USBD_MSC_AltSet,
1);
break;
case USB_REQ_SET_INTERFACE :
USBD_MSC_AltSet = (uint8_t)(req->wValue);
break;
case USB_REQ_CLEAR_FEATURE:
/* Flush the FIFO and Clear the stall status */
DCD_EP_Flush(pdev, (uint8_t)req->wIndex);
/* Re-activate the EP */
DCD_EP_Close (pdev , (uint8_t)req->wIndex);
if((((uint8_t)req->wIndex) & 0x80) == 0x80)
{
DCD_EP_Open(pdev,
((uint8_t)req->wIndex),
MSC_EPIN_SIZE,
USB_OTG_EP_BULK);
}
else
{
DCD_EP_Open(pdev,
((uint8_t)req->wIndex),
MSC_EPOUT_SIZE,
USB_OTG_EP_BULK);
}
/* Handle BOT error */
MSC_BOT_CplClrFeature(pdev, (uint8_t)req->wIndex);
break;
}
break;
default:
break;
}
return USBD_OK;
}
/**
* @brief USBD_MSC_DataIn
* handle data IN Stage
* @param pdev: device instance
* @param epnum: endpoint index
* @retval status
*/
uint8_t USBD_MSC_DataIn (void *pdev,
uint8_t epnum)
{
MSC_BOT_DataIn(pdev , epnum);
return USBD_OK;
}
/**
* @brief USBD_MSC_DataOut
* handle data OUT Stage
* @param pdev: device instance
* @param epnum: endpoint index
* @retval status
*/
uint8_t USBD_MSC_DataOut (void *pdev,
uint8_t epnum)
{
MSC_BOT_DataOut(pdev , epnum);
return USBD_OK;
}
/**
* @brief USBD_MSC_GetCfgDesc
* return configuration descriptor
* @param speed : current device speed
* @param length : pointer data length
* @retval pointer to descriptor buffer
*/
uint8_t *USBD_MSC_GetCfgDesc (uint8_t speed, uint16_t *length)
{
*length = sizeof (USBD_MSC_CfgDesc);
return USBD_MSC_CfgDesc;
}
/**
* @brief USBD_MSC_GetOtherCfgDesc
* return other speed configuration descriptor
* @param speed : current device speed
* @param length : pointer data length
* @retval pointer to descriptor buffer
*/
#ifdef USB_OTG_HS_CORE
uint8_t *USBD_MSC_GetOtherCfgDesc (uint8_t speed,
uint16_t *length)
{
*length = sizeof (USBD_MSC_OtherCfgDesc);
return USBD_MSC_OtherCfgDesc;
}
#endif
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,134 @@
/**
******************************************************************************
* @file usbd_msc_data.c
* @author MCD Application Team
* @version V1.1.0
* @date 19-March-2012
* @brief This file provides all the vital inquiry pages and sense data.
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "usbd_msc_data.h"
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
* @{
*/
/** @defgroup MSC_DATA
* @brief Mass storage info/data module
* @{
*/
/** @defgroup MSC_DATA_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @defgroup MSC_DATA_Private_Defines
* @{
*/
/**
* @}
*/
/** @defgroup MSC_DATA_Private_Macros
* @{
*/
/**
* @}
*/
/** @defgroup MSC_DATA_Private_Variables
* @{
*/
/* USB Mass storage Page 0 Inquiry Data */
const uint8_t MSC_Page00_Inquiry_Data[] = {//7
0x00,
0x00,
0x00,
(LENGTH_INQUIRY_PAGE00 - 4),
0x00,
0x80,
0x83
};
/* USB Mass storage sense 6 Data */
const uint8_t MSC_Mode_Sense6_data[] = {
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00
};
/* USB Mass storage sense 10 Data */
const uint8_t MSC_Mode_Sense10_data[] = {
0x00,
0x06,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00
};
/**
* @}
*/
/** @defgroup MSC_DATA_Private_FunctionPrototypes
* @{
*/
/**
* @}
*/
/** @defgroup MSC_DATA_Private_Functions
* @{
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,728 @@
/**
******************************************************************************
* @file usbd_msc_scsi.c
* @author MCD Application Team
* @version V1.1.0
* @date 19-March-2012
* @brief This file provides all the USBD SCSI layer functions.
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "usbd_msc_bot.h"
#include "usbd_msc_scsi.h"
#include "usbd_msc_mem.h"
#include "usbd_msc_data.h"
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
* @{
*/
/** @defgroup MSC_SCSI
* @brief Mass storage SCSI layer module
* @{
*/
/** @defgroup MSC_SCSI_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @defgroup MSC_SCSI_Private_Defines
* @{
*/
/**
* @}
*/
/** @defgroup MSC_SCSI_Private_Macros
* @{
*/
/**
* @}
*/
/** @defgroup MSC_SCSI_Private_Variables
* @{
*/
SCSI_Sense_TypeDef SCSI_Sense [SENSE_LIST_DEEPTH];
uint8_t SCSI_Sense_Head;
uint8_t SCSI_Sense_Tail;
uint32_t SCSI_blk_size;
uint32_t SCSI_blk_nbr;
uint32_t SCSI_blk_addr;
uint32_t SCSI_blk_len;
USB_OTG_CORE_HANDLE *cdev;
/**
* @}
*/
/** @defgroup MSC_SCSI_Private_FunctionPrototypes
* @{
*/
static int8_t SCSI_TestUnitReady(uint8_t lun, uint8_t *params);
static int8_t SCSI_Inquiry(uint8_t lun, uint8_t *params);
static int8_t SCSI_ReadFormatCapacity(uint8_t lun, uint8_t *params);
static int8_t SCSI_ReadCapacity10(uint8_t lun, uint8_t *params);
static int8_t SCSI_RequestSense (uint8_t lun, uint8_t *params);
static int8_t SCSI_StartStopUnit(uint8_t lun, uint8_t *params);
static int8_t SCSI_ModeSense6 (uint8_t lun, uint8_t *params);
static int8_t SCSI_ModeSense10 (uint8_t lun, uint8_t *params);
static int8_t SCSI_Write10(uint8_t lun , uint8_t *params);
static int8_t SCSI_Read10(uint8_t lun , uint8_t *params);
static int8_t SCSI_Verify10(uint8_t lun, uint8_t *params);
static int8_t SCSI_CheckAddressRange (uint8_t lun ,
uint32_t blk_offset ,
uint16_t blk_nbr);
static int8_t SCSI_ProcessRead (uint8_t lun);
static int8_t SCSI_ProcessWrite (uint8_t lun);
/**
* @}
*/
/** @defgroup MSC_SCSI_Private_Functions
* @{
*/
/**
* @brief SCSI_ProcessCmd
* Process SCSI commands
* @param pdev: device instance
* @param lun: Logical unit number
* @param params: Command parameters
* @retval status
*/
int8_t SCSI_ProcessCmd(USB_OTG_CORE_HANDLE *pdev,
uint8_t lun,
uint8_t *params)
{
cdev = pdev;
switch (params[0])
{
case SCSI_TEST_UNIT_READY:
return SCSI_TestUnitReady(lun, params);
case SCSI_REQUEST_SENSE:
return SCSI_RequestSense (lun, params);
case SCSI_INQUIRY:
return SCSI_Inquiry(lun, params);
case SCSI_START_STOP_UNIT:
return SCSI_StartStopUnit(lun, params);
case SCSI_ALLOW_MEDIUM_REMOVAL:
return SCSI_StartStopUnit(lun, params);
case SCSI_MODE_SENSE6:
return SCSI_ModeSense6 (lun, params);
case SCSI_MODE_SENSE10:
return SCSI_ModeSense10 (lun, params);
case SCSI_READ_FORMAT_CAPACITIES:
return SCSI_ReadFormatCapacity(lun, params);
case SCSI_READ_CAPACITY10:
return SCSI_ReadCapacity10(lun, params);
case SCSI_READ10:
return SCSI_Read10(lun, params);
case SCSI_WRITE10:
return SCSI_Write10(lun, params);
case SCSI_VERIFY10:
return SCSI_Verify10(lun, params);
default:
SCSI_SenseCode(lun,
ILLEGAL_REQUEST,
INVALID_CDB);
return -1;
}
}
/**
* @brief SCSI_TestUnitReady
* Process SCSI Test Unit Ready Command
* @param lun: Logical unit number
* @param params: Command parameters
* @retval status
*/
static int8_t SCSI_TestUnitReady(uint8_t lun, uint8_t *params)
{
/* case 9 : Hi > D0 */
if (MSC_BOT_cbw.dDataLength != 0)
{
SCSI_SenseCode(MSC_BOT_cbw.bLUN,
ILLEGAL_REQUEST,
INVALID_CDB);
return -1;
}
if(USBD_STORAGE_fops->IsReady(lun) !=0 )
{
SCSI_SenseCode(lun,
NOT_READY,
MEDIUM_NOT_PRESENT);
return -1;
}
MSC_BOT_DataLen = 0;
return 0;
}
/**
* @brief SCSI_Inquiry
* Process Inquiry command
* @param lun: Logical unit number
* @param params: Command parameters
* @retval status
*/
static int8_t SCSI_Inquiry(uint8_t lun, uint8_t *params)
{
uint8_t* pPage;
uint16_t len;
if (params[1] & 0x01)/*Evpd is set*/
{
pPage = (uint8_t *)MSC_Page00_Inquiry_Data;
len = LENGTH_INQUIRY_PAGE00;
}
else
{
pPage = (uint8_t *)&USBD_STORAGE_fops->pInquiry[lun * USBD_STD_INQUIRY_LENGTH];
len = pPage[4] + 5;
if (params[4] <= len)
{
len = params[4];
}
}
MSC_BOT_DataLen = len;
while (len)
{
len--;
MSC_BOT_Data[len] = pPage[len];
}
return 0;
}
/**
* @brief SCSI_ReadCapacity10
* Process Read Capacity 10 command
* @param lun: Logical unit number
* @param params: Command parameters
* @retval status
*/
static int8_t SCSI_ReadCapacity10(uint8_t lun, uint8_t *params)
{
if(USBD_STORAGE_fops->GetCapacity(lun, &SCSI_blk_nbr, &SCSI_blk_size) != 0)
{
SCSI_SenseCode(lun,
NOT_READY,
MEDIUM_NOT_PRESENT);
return -1;
}
else
{
MSC_BOT_Data[0] = (uint8_t)(SCSI_blk_nbr - 1 >> 24);
MSC_BOT_Data[1] = (uint8_t)(SCSI_blk_nbr - 1 >> 16);
MSC_BOT_Data[2] = (uint8_t)(SCSI_blk_nbr - 1 >> 8);
MSC_BOT_Data[3] = (uint8_t)(SCSI_blk_nbr - 1);
MSC_BOT_Data[4] = (uint8_t)(SCSI_blk_size >> 24);
MSC_BOT_Data[5] = (uint8_t)(SCSI_blk_size >> 16);
MSC_BOT_Data[6] = (uint8_t)(SCSI_blk_size >> 8);
MSC_BOT_Data[7] = (uint8_t)(SCSI_blk_size);
MSC_BOT_DataLen = 8;
return 0;
}
}
/**
* @brief SCSI_ReadFormatCapacity
* Process Read Format Capacity command
* @param lun: Logical unit number
* @param params: Command parameters
* @retval status
*/
static int8_t SCSI_ReadFormatCapacity(uint8_t lun, uint8_t *params)
{
uint32_t blk_size;
uint32_t blk_nbr;
uint16_t i;
for(i=0 ; i < 12 ; i++)
{
MSC_BOT_Data[i] = 0;
}
if(USBD_STORAGE_fops->GetCapacity(lun, &blk_nbr, &blk_size) != 0)
{
SCSI_SenseCode(lun,
NOT_READY,
MEDIUM_NOT_PRESENT);
return -1;
}
else
{
MSC_BOT_Data[3] = 0x08;
MSC_BOT_Data[4] = (uint8_t)(blk_nbr - 1 >> 24);
MSC_BOT_Data[5] = (uint8_t)(blk_nbr - 1 >> 16);
MSC_BOT_Data[6] = (uint8_t)(blk_nbr - 1 >> 8);
MSC_BOT_Data[7] = (uint8_t)(blk_nbr - 1);
MSC_BOT_Data[8] = 0x02;
MSC_BOT_Data[9] = (uint8_t)(blk_size >> 16);
MSC_BOT_Data[10] = (uint8_t)(blk_size >> 8);
MSC_BOT_Data[11] = (uint8_t)(blk_size);
MSC_BOT_DataLen = 12;
return 0;
}
}
/**
* @brief SCSI_ModeSense6
* Process Mode Sense6 command
* @param lun: Logical unit number
* @param params: Command parameters
* @retval status
*/
static int8_t SCSI_ModeSense6 (uint8_t lun, uint8_t *params)
{
uint16_t len = 8 ;
MSC_BOT_DataLen = len;
while (len)
{
len--;
MSC_BOT_Data[len] = MSC_Mode_Sense6_data[len];
}
return 0;
}
/**
* @brief SCSI_ModeSense10
* Process Mode Sense10 command
* @param lun: Logical unit number
* @param params: Command parameters
* @retval status
*/
static int8_t SCSI_ModeSense10 (uint8_t lun, uint8_t *params)
{
uint16_t len = 8;
MSC_BOT_DataLen = len;
while (len)
{
len--;
MSC_BOT_Data[len] = MSC_Mode_Sense10_data[len];
}
return 0;
}
/**
* @brief SCSI_RequestSense
* Process Request Sense command
* @param lun: Logical unit number
* @param params: Command parameters
* @retval status
*/
static int8_t SCSI_RequestSense (uint8_t lun, uint8_t *params)
{
uint8_t i;
for(i=0 ; i < REQUEST_SENSE_DATA_LEN ; i++)
{
MSC_BOT_Data[i] = 0;
}
MSC_BOT_Data[0] = 0x70;
MSC_BOT_Data[7] = REQUEST_SENSE_DATA_LEN - 6;
if((SCSI_Sense_Head != SCSI_Sense_Tail)) {
MSC_BOT_Data[2] = SCSI_Sense[SCSI_Sense_Head].Skey;
MSC_BOT_Data[12] = SCSI_Sense[SCSI_Sense_Head].w.b.ASCQ;
MSC_BOT_Data[13] = SCSI_Sense[SCSI_Sense_Head].w.b.ASC;
SCSI_Sense_Head++;
if (SCSI_Sense_Head == SENSE_LIST_DEEPTH)
{
SCSI_Sense_Head = 0;
}
}
MSC_BOT_DataLen = REQUEST_SENSE_DATA_LEN;
if (params[4] <= REQUEST_SENSE_DATA_LEN)
{
MSC_BOT_DataLen = params[4];
}
return 0;
}
/**
* @brief SCSI_SenseCode
* Load the last error code in the error list
* @param lun: Logical unit number
* @param sKey: Sense Key
* @param ASC: Additional Sense Key
* @retval none
*/
void SCSI_SenseCode(uint8_t lun, uint8_t sKey, uint8_t ASC)
{
SCSI_Sense[SCSI_Sense_Tail].Skey = sKey;
SCSI_Sense[SCSI_Sense_Tail].w.ASC = ASC << 8;
SCSI_Sense_Tail++;
if (SCSI_Sense_Tail == SENSE_LIST_DEEPTH)
{
SCSI_Sense_Tail = 0;
}
}
/**
* @brief SCSI_StartStopUnit
* Process Start Stop Unit command
* @param lun: Logical unit number
* @param params: Command parameters
* @retval status
*/
static int8_t SCSI_StartStopUnit(uint8_t lun, uint8_t *params)
{
MSC_BOT_DataLen = 0;
return 0;
}
/**
* @brief SCSI_Read10
* Process Read10 command
* @param lun: Logical unit number
* @param params: Command parameters
* @retval status
*/
static int8_t SCSI_Read10(uint8_t lun , uint8_t *params)
{
if(MSC_BOT_State == BOT_IDLE) /* Idle */
{
/* case 10 : Ho <> Di */
if ((MSC_BOT_cbw.bmFlags & 0x80) != 0x80)
{
SCSI_SenseCode(MSC_BOT_cbw.bLUN,
ILLEGAL_REQUEST,
INVALID_CDB);
return -1;
}
if(USBD_STORAGE_fops->IsReady(lun) !=0 )
{
SCSI_SenseCode(lun,
NOT_READY,
MEDIUM_NOT_PRESENT);
return -1;
}
SCSI_blk_addr = (params[2] << 24) | \
(params[3] << 16) | \
(params[4] << 8) | \
params[5];
SCSI_blk_len = (params[7] << 8) | \
params[8];
if( SCSI_CheckAddressRange(lun, SCSI_blk_addr, SCSI_blk_len) < 0)
{
return -1; /* error */
}
MSC_BOT_State = BOT_DATA_IN;
SCSI_blk_addr *= SCSI_blk_size;
SCSI_blk_len *= SCSI_blk_size;
/* cases 4,5 : Hi <> Dn */
if (MSC_BOT_cbw.dDataLength != SCSI_blk_len)
{
SCSI_SenseCode(MSC_BOT_cbw.bLUN,
ILLEGAL_REQUEST,
INVALID_CDB);
return -1;
}
}
MSC_BOT_DataLen = MSC_MEDIA_PACKET;
return SCSI_ProcessRead(lun);
}
/**
* @brief SCSI_Write10
* Process Write10 command
* @param lun: Logical unit number
* @param params: Command parameters
* @retval status
*/
static int8_t SCSI_Write10 (uint8_t lun , uint8_t *params)
{
if (MSC_BOT_State == BOT_IDLE) /* Idle */
{
/* case 8 : Hi <> Do */
if ((MSC_BOT_cbw.bmFlags & 0x80) == 0x80)
{
SCSI_SenseCode(MSC_BOT_cbw.bLUN,
ILLEGAL_REQUEST,
INVALID_CDB);
return -1;
}
/* Check whether Media is ready */
if(USBD_STORAGE_fops->IsReady(lun) !=0 )
{
SCSI_SenseCode(lun,
NOT_READY,
MEDIUM_NOT_PRESENT);
return -1;
}
/* Check If media is write-protected */
if(USBD_STORAGE_fops->IsWriteProtected(lun) !=0 )
{
SCSI_SenseCode(lun,
NOT_READY,
WRITE_PROTECTED);
return -1;
}
SCSI_blk_addr = (params[2] << 24) | \
(params[3] << 16) | \
(params[4] << 8) | \
params[5];
SCSI_blk_len = (params[7] << 8) | \
params[8];
/* check if LBA address is in the right range */
if(SCSI_CheckAddressRange(lun, SCSI_blk_addr, SCSI_blk_len) < 0)
{
return -1; /* error */
}
SCSI_blk_addr *= SCSI_blk_size;
SCSI_blk_len *= SCSI_blk_size;
/* cases 3,11,13 : Hn,Ho <> D0 */
if (MSC_BOT_cbw.dDataLength != SCSI_blk_len)
{
SCSI_SenseCode(MSC_BOT_cbw.bLUN,
ILLEGAL_REQUEST,
INVALID_CDB);
return -1;
}
/* Prepare EP to receive first data packet */
MSC_BOT_State = BOT_DATA_OUT;
DCD_EP_PrepareRx (cdev,
MSC_OUT_EP,
MSC_BOT_Data,
MIN (SCSI_blk_len, MSC_MEDIA_PACKET));
}
else /* Write Process ongoing */
{
return SCSI_ProcessWrite(lun);
}
return 0;
}
/**
* @brief SCSI_Verify10
* Process Verify10 command
* @param lun: Logical unit number
* @param params: Command parameters
* @retval status
*/
static int8_t SCSI_Verify10(uint8_t lun , uint8_t *params){
if ((params[1]& 0x02) == 0x02)
{
SCSI_SenseCode (lun, ILLEGAL_REQUEST, INVALID_FIELED_IN_COMMAND);
return -1; /* Error, Verify Mode Not supported*/
}
if(SCSI_CheckAddressRange(lun, SCSI_blk_addr, SCSI_blk_len) < 0)
{
return -1; /* error */
}
MSC_BOT_DataLen = 0;
return 0;
}
/**
* @brief SCSI_CheckAddressRange
* Check address range
* @param lun: Logical unit number
* @param blk_offset: first block address
* @param blk_nbr: number of block to be processed
* @retval status
*/
static int8_t SCSI_CheckAddressRange (uint8_t lun , uint32_t blk_offset , uint16_t blk_nbr)
{
if ((blk_offset + blk_nbr) > SCSI_blk_nbr )
{
SCSI_SenseCode(lun, ILLEGAL_REQUEST, ADDRESS_OUT_OF_RANGE);
return -1;
}
return 0;
}
/**
* @brief SCSI_ProcessRead
* Handle Read Process
* @param lun: Logical unit number
* @retval status
*/
static int8_t SCSI_ProcessRead (uint8_t lun)
{
uint32_t len;
len = MIN(SCSI_blk_len , MSC_MEDIA_PACKET);
if( USBD_STORAGE_fops->Read(lun ,
MSC_BOT_Data,
SCSI_blk_addr / SCSI_blk_size,
len / SCSI_blk_size) < 0)
{
SCSI_SenseCode(lun, HARDWARE_ERROR, UNRECOVERED_READ_ERROR);
return -1;
}
DCD_EP_Tx (cdev,
MSC_IN_EP,
MSC_BOT_Data,
len);
SCSI_blk_addr += len;
SCSI_blk_len -= len;
/* case 6 : Hi = Di */
MSC_BOT_csw.dDataResidue -= len;
if (SCSI_blk_len == 0)
{
MSC_BOT_State = BOT_LAST_DATA_IN;
}
return 0;
}
/**
* @brief SCSI_ProcessWrite
* Handle Write Process
* @param lun: Logical unit number
* @retval status
*/
static int8_t SCSI_ProcessWrite (uint8_t lun)
{
uint32_t len;
len = MIN(SCSI_blk_len , MSC_MEDIA_PACKET);
if(USBD_STORAGE_fops->Write(lun ,
MSC_BOT_Data,
SCSI_blk_addr / SCSI_blk_size,
len / SCSI_blk_size) < 0)
{
SCSI_SenseCode(lun, HARDWARE_ERROR, WRITE_FAULT);
return -1;
}
SCSI_blk_addr += len;
SCSI_blk_len -= len;
/* case 12 : Ho = Do */
MSC_BOT_csw.dDataResidue -= len;
if (SCSI_blk_len == 0)
{
MSC_BOT_SendCSW (cdev, CSW_CMD_PASSED);
}
else
{
/* Prapare EP to Receive next packet */
DCD_EP_PrepareRx (cdev,
MSC_OUT_EP,
MSC_BOT_Data,
MIN (SCSI_blk_len, MSC_MEDIA_PACKET));
}
return 0;
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,185 @@
/**
******************************************************************************
* @file usbd_storage_template.c
* @author MCD Application Team
* @version V1.1.0
* @date 19-March-2012
* @brief Memory management layer
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "usbd_msc_mem.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Extern function prototypes ------------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
#define STORAGE_LUN_NBR 1
int8_t STORAGE_Init (uint8_t lun);
int8_t STORAGE_GetCapacity (uint8_t lun,
uint32_t *block_num,
uint16_t *block_size);
int8_t STORAGE_IsReady (uint8_t lun);
int8_t STORAGE_IsWriteProtected (uint8_t lun);
int8_t STORAGE_Read (uint8_t lun,
uint8_t *buf,
uint32_t blk_addr,
uint16_t blk_len);
int8_t STORAGE_Write (uint8_t lun,
uint8_t *buf,
uint32_t blk_addr,
uint16_t blk_len);
int8_t STORAGE_GetMaxLun (void);
/* USB Mass storage Standard Inquiry Data */
const int8_t STORAGE_Inquirydata[] = {//36
/* LUN 0 */
0x00,
0x80,
0x02,
0x02,
(USBD_STD_INQUIRY_LENGTH - 5),
0x00,
0x00,
0x00,
'S', 'T', 'M', ' ', ' ', ' ', ' ', ' ', /* Manufacturer : 8 bytes */
'P', 'r', 'o', 'd', 'u', 't', ' ', ' ', /* Product : 16 Bytes */
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
'0', '.', '0' ,'1', /* Version : 4 Bytes */
};
USBD_STORAGE_cb_TypeDef USBD_MICRO_SDIO_fops =
{
STORAGE_Init,
STORAGE_GetCapacity,
STORAGE_IsReady,
STORAGE_IsWriteProtected,
STORAGE_Read,
STORAGE_Write,
STORAGE_GetMaxLun,
STORAGE_Inquirydata,
};
USBD_STORAGE_cb_TypeDef *USBD_STORAGE_fops = &USBD_MICRO_SDIO_fops;
/*******************************************************************************
* Function Name : Read_Memory
* Description : Handle the Read operation from the microSD card.
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
int8_t STORAGE_Init (uint8_t lun)
{
return (0);
}
/*******************************************************************************
* Function Name : Read_Memory
* Description : Handle the Read operation from the STORAGE card.
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
int8_t STORAGE_GetCapacity (uint8_t lun, uint32_t *block_num, uint16_t *block_size)
{
return (0);
}
/*******************************************************************************
* Function Name : Read_Memory
* Description : Handle the Read operation from the STORAGE card.
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
int8_t STORAGE_IsReady (uint8_t lun)
{
return (0);
}
/*******************************************************************************
* Function Name : Read_Memory
* Description : Handle the Read operation from the STORAGE card.
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
int8_t STORAGE_IsWriteProtected (uint8_t lun)
{
return 0;
}
/*******************************************************************************
* Function Name : Read_Memory
* Description : Handle the Read operation from the STORAGE card.
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
int8_t STORAGE_Read (uint8_t lun,
uint8_t *buf,
uint32_t blk_addr,
uint16_t blk_len)
{
return 0;
}
/*******************************************************************************
* Function Name : Write_Memory
* Description : Handle the Write operation to the STORAGE card.
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
int8_t STORAGE_Write (uint8_t lun,
uint8_t *buf,
uint32_t blk_addr,
uint16_t blk_len)
{
return (0);
}
/*******************************************************************************
* Function Name : Write_Memory
* Description : Handle the Write operation to the STORAGE card.
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
int8_t STORAGE_GetMaxLun (void)
{
return (STORAGE_LUN_NBR - 1);
}
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,82 @@
/**
******************************************************************************
* @file usbd_conf_template.h
* @author MCD Application Team
* @version V1.1.0
* @date 19-March-2012
* @brief usb device configuration template file
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USBD_CONF__H__
#define __USBD_CONF__H__
/* Includes ------------------------------------------------------------------*/
#include "usb_conf.h"
/** @defgroup USB_CONF_Exported_Defines
* @{
*/
#define USE_USB_OTG_HS
#define USBD_CFG_MAX_NUM 1
#define USB_MAX_STR_DESC_SIZ 64
#define USBD_EP0_MAX_PACKET_SIZE 64
/**
* @}
*/
/** @defgroup USB_CONF_Exported_Types
* @{
*/
/**
* @}
*/
/** @defgroup USB_CONF_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USB_CONF_Exported_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USB_CONF_Exported_FunctionsPrototype
* @{
*/
/**
* @}
*/
#endif //__USBD_CONF__H__
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,120 @@
/**
******************************************************************************
* @file usbd_core.h
* @author MCD Application Team
* @version V1.1.0
* @date 19-March-2012
* @brief Header file for usbd_core.c
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USBD_CORE_H
#define __USBD_CORE_H
/* Includes ------------------------------------------------------------------*/
#include "usb_dcd.h"
#include "usbd_def.h"
#include "usbd_conf.h"
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
* @{
*/
/** @defgroup USBD_CORE
* @brief This file is the Header file for usbd_core.c file
* @{
*/
/** @defgroup USBD_CORE_Exported_Defines
* @{
*/
typedef enum {
USBD_OK = 0,
USBD_BUSY,
USBD_FAIL,
}USBD_Status;
/**
* @}
*/
/** @defgroup USBD_CORE_Exported_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @defgroup USBD_CORE_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBD_CORE_Exported_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USBD_CORE_Exported_FunctionsPrototype
* @{
*/
void USBD_Init(USB_OTG_CORE_HANDLE *pdev,
USB_OTG_CORE_ID_TypeDef coreID,
USBD_DEVICE *pDevice,
USBD_Class_cb_TypeDef *class_cb,
USBD_Usr_cb_TypeDef *usr_cb);
USBD_Status USBD_DeInit(USB_OTG_CORE_HANDLE *pdev);
USBD_Status USBD_ClrCfg(USB_OTG_CORE_HANDLE *pdev, uint8_t cfgidx);
USBD_Status USBD_SetCfg(USB_OTG_CORE_HANDLE *pdev, uint8_t cfgidx);
/**
* @}
*/
#endif /* __USBD_CORE_H */
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,156 @@
/**
******************************************************************************
* @file usbd_def.h
* @author MCD Application Team
* @version V1.1.0
* @date 19-March-2012
* @brief general defines for the usb device library
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USBD_DEF_H
#define __USBD_DEF_H
/* Includes ------------------------------------------------------------------*/
#include "usbd_conf.h"
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
* @{
*/
/** @defgroup USB_DEF
* @brief general defines for the usb device library file
* @{
*/
/** @defgroup USB_DEF_Exported_Defines
* @{
*/
#ifndef NULL
#define NULL 0
#endif
#define USB_LEN_DEV_QUALIFIER_DESC 0x0A
#define USB_LEN_DEV_DESC 0x12
#define USB_LEN_CFG_DESC 0x09
#define USB_LEN_IF_DESC 0x09
#define USB_LEN_EP_DESC 0x07
#define USB_LEN_OTG_DESC 0x03
#define USBD_IDX_LANGID_STR 0x00
#define USBD_IDX_MFC_STR 0x01
#define USBD_IDX_PRODUCT_STR 0x02
#define USBD_IDX_SERIAL_STR 0x03
#define USBD_IDX_CONFIG_STR 0x04
#define USBD_IDX_INTERFACE_STR 0x05
#define USB_REQ_TYPE_STANDARD 0x00
#define USB_REQ_TYPE_CLASS 0x20
#define USB_REQ_TYPE_VENDOR 0x40
#define USB_REQ_TYPE_MASK 0x60
#define USB_REQ_RECIPIENT_DEVICE 0x00
#define USB_REQ_RECIPIENT_INTERFACE 0x01
#define USB_REQ_RECIPIENT_ENDPOINT 0x02
#define USB_REQ_RECIPIENT_MASK 0x03
#define USB_REQ_GET_STATUS 0x00
#define USB_REQ_CLEAR_FEATURE 0x01
#define USB_REQ_SET_FEATURE 0x03
#define USB_REQ_SET_ADDRESS 0x05
#define USB_REQ_GET_DESCRIPTOR 0x06
#define USB_REQ_SET_DESCRIPTOR 0x07
#define USB_REQ_GET_CONFIGURATION 0x08
#define USB_REQ_SET_CONFIGURATION 0x09
#define USB_REQ_GET_INTERFACE 0x0A
#define USB_REQ_SET_INTERFACE 0x0B
#define USB_REQ_SYNCH_FRAME 0x0C
#define USB_DESC_TYPE_DEVICE 1
#define USB_DESC_TYPE_CONFIGURATION 2
#define USB_DESC_TYPE_STRING 3
#define USB_DESC_TYPE_INTERFACE 4
#define USB_DESC_TYPE_ENDPOINT 5
#define USB_DESC_TYPE_DEVICE_QUALIFIER 6
#define USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION 7
#define USB_CONFIG_REMOTE_WAKEUP 2
#define USB_CONFIG_SELF_POWERED 1
#define USB_FEATURE_EP_HALT 0
#define USB_FEATURE_REMOTE_WAKEUP 1
#define USB_FEATURE_TEST_MODE 2
/**
* @}
*/
/** @defgroup USBD_DEF_Exported_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @defgroup USBD_DEF_Exported_Macros
* @{
*/
#define SWAPBYTE(addr) (((uint16_t)(*((uint8_t *)(addr)))) + \
(((uint16_t)(*(((uint8_t *)(addr)) + 1))) << 8))
#define LOBYTE(x) ((uint8_t)(x & 0x00FF))
#define HIBYTE(x) ((uint8_t)((x & 0xFF00) >>8))
/**
* @}
*/
/** @defgroup USBD_DEF_Exported_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USBD_DEF_Exported_FunctionsPrototype
* @{
*/
/**
* @}
*/
#endif /* __USBD_DEF_H */
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,121 @@
/**
******************************************************************************
* @file usbd_ioreq.h
* @author MCD Application Team
* @version V1.1.0
* @date 19-March-2012
* @brief header file for the usbd_ioreq.c file
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USBD_IOREQ_H_
#define __USBD_IOREQ_H_
/* Includes ------------------------------------------------------------------*/
#include "usbd_def.h"
#include "usbd_core.h"
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
* @{
*/
/** @defgroup USBD_IOREQ
* @brief header file for the usbd_ioreq.c file
* @{
*/
/** @defgroup USBD_IOREQ_Exported_Defines
* @{
*/
/**
* @}
*/
/** @defgroup USBD_IOREQ_Exported_Types
* @{
*/
/**
* @}
*/
/** @defgroup USBD_IOREQ_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBD_IOREQ_Exported_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USBD_IOREQ_Exported_FunctionsPrototype
* @{
*/
USBD_Status USBD_CtlSendData (USB_OTG_CORE_HANDLE *pdev,
uint8_t *buf,
uint16_t len);
USBD_Status USBD_CtlContinueSendData (USB_OTG_CORE_HANDLE *pdev,
uint8_t *pbuf,
uint16_t len);
USBD_Status USBD_CtlPrepareRx (USB_OTG_CORE_HANDLE *pdev,
uint8_t *pbuf,
uint16_t len);
USBD_Status USBD_CtlContinueRx (USB_OTG_CORE_HANDLE *pdev,
uint8_t *pbuf,
uint16_t len);
USBD_Status USBD_CtlSendStatus (USB_OTG_CORE_HANDLE *pdev);
USBD_Status USBD_CtlReceiveStatus (USB_OTG_CORE_HANDLE *pdev);
uint16_t USBD_GetRxCount (USB_OTG_CORE_HANDLE *pdev ,
uint8_t epnum);
/**
* @}
*/
#endif /* __USBD_IOREQ_H_ */
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,108 @@
/**
******************************************************************************
* @file usbd_req.h
* @author MCD Application Team
* @version V1.1.0
* @date 19-March-2012
* @brief header file for the usbd_req.c file
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_REQUEST_H_
#define __USB_REQUEST_H_
/* Includes ------------------------------------------------------------------*/
#include "usbd_def.h"
#include "usbd_core.h"
#include "usbd_conf.h"
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
* @{
*/
/** @defgroup USBD_REQ
* @brief header file for the usbd_ioreq.c file
* @{
*/
/** @defgroup USBD_REQ_Exported_Defines
* @{
*/
/**
* @}
*/
/** @defgroup USBD_REQ_Exported_Types
* @{
*/
/**
* @}
*/
/** @defgroup USBD_REQ_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBD_REQ_Exported_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USBD_REQ_Exported_FunctionsPrototype
* @{
*/
USBD_Status USBD_StdDevReq (USB_OTG_CORE_HANDLE *pdev, USB_SETUP_REQ *req);
USBD_Status USBD_StdItfReq (USB_OTG_CORE_HANDLE *pdev, USB_SETUP_REQ *req);
USBD_Status USBD_StdEPReq (USB_OTG_CORE_HANDLE *pdev, USB_SETUP_REQ *req);
void USBD_ParseSetupRequest( USB_OTG_CORE_HANDLE *pdev,
USB_SETUP_REQ *req);
void USBD_CtlError( USB_OTG_CORE_HANDLE *pdev,
USB_SETUP_REQ *req);
void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len);
/**
* @}
*/
#endif /* __USB_REQUEST_H_ */
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,141 @@
/**
******************************************************************************
* @file usbd_usr.h
* @author MCD Application Team
* @version V1.1.0
* @date 19-March-2012
* @brief Header file for usbd_usr.c
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USBD_USR_H__
#define __USBD_USR_H__
/* Includes ------------------------------------------------------------------*/
#include "usbd_core.h"
/** @addtogroup USBD_USER
* @{
*/
/** @addtogroup USBD_MSC_DEMO_USER_CALLBACKS
* @{
*/
/** @defgroup USBD_USR
* @brief This file is the Header file for usbd_usr.c
* @{
*/
/** @defgroup USBD_USR_Exported_Types
* @{
*/
extern USBD_Usr_cb_TypeDef USR_cb;
extern USBD_Usr_cb_TypeDef USR_FS_cb;
extern USBD_Usr_cb_TypeDef USR_HS_cb;
/**
* @}
*/
/** @defgroup USBD_USR_Exported_Defines
* @{
*/
/**
* @}
*/
/** @defgroup USBD_USR_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBD_USR_Exported_Variables
* @{
*/
void USBD_USR_Init(void);
void USBD_USR_DeviceReset (uint8_t speed);
void USBD_USR_DeviceConfigured (void);
void USBD_USR_DeviceSuspended(void);
void USBD_USR_DeviceResumed(void);
void USBD_USR_DeviceConnected(void);
void USBD_USR_DeviceDisconnected(void);
void USBD_USR_FS_Init(void);
void USBD_USR_FS_DeviceReset (uint8_t speed);
void USBD_USR_FS_DeviceConfigured (void);
void USBD_USR_FS_DeviceSuspended(void);
void USBD_USR_FS_DeviceResumed(void);
void USBD_USR_FS_DeviceConnected(void);
void USBD_USR_FS_DeviceDisconnected(void);
void USBD_USR_HS_Init(void);
void USBD_USR_HS_DeviceReset (uint8_t speed);
void USBD_USR_HS_DeviceConfigured (void);
void USBD_USR_HS_DeviceSuspended(void);
void USBD_USR_HS_DeviceResumed(void);
void USBD_USR_HS_DeviceConnected(void);
void USBD_USR_HS_DeviceDisconnected(void);
/**
* @}
*/
/** @defgroup USBD_USR_Exported_FunctionsPrototype
* @{
*/
/**
* @}
*/
#endif /*__USBD_USR_H__*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,506 @@
/**
******************************************************************************
* @file usbd_core.c
* @author MCD Application Team
* @version V1.1.0
* @date 19-March-2012
* @brief This file provides all the USBD core functions.
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "usbd_core.h"
#include "usbd_req.h"
#include "usbd_ioreq.h"
#include "usb_dcd_int.h"
#include "usb_bsp.h"
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
* @{
*/
/** @defgroup USBD_CORE
* @brief usbd core module
* @{
*/
/** @defgroup USBD_CORE_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @defgroup USBD_CORE_Private_Defines
* @{
*/
/**
* @}
*/
/** @defgroup USBD_CORE_Private_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBD_CORE_Private_FunctionPrototypes
* @{
*/
static uint8_t USBD_SetupStage(USB_OTG_CORE_HANDLE *pdev);
static uint8_t USBD_DataOutStage(USB_OTG_CORE_HANDLE *pdev , uint8_t epnum);
static uint8_t USBD_DataInStage(USB_OTG_CORE_HANDLE *pdev , uint8_t epnum);
static uint8_t USBD_SOF(USB_OTG_CORE_HANDLE *pdev);
static uint8_t USBD_Reset(USB_OTG_CORE_HANDLE *pdev);
static uint8_t USBD_Suspend(USB_OTG_CORE_HANDLE *pdev);
static uint8_t USBD_Resume(USB_OTG_CORE_HANDLE *pdev);
#ifdef VBUS_SENSING_ENABLED
static uint8_t USBD_DevConnected(USB_OTG_CORE_HANDLE *pdev);
static uint8_t USBD_DevDisconnected(USB_OTG_CORE_HANDLE *pdev);
#endif
static uint8_t USBD_IsoINIncomplete(USB_OTG_CORE_HANDLE *pdev);
static uint8_t USBD_IsoOUTIncomplete(USB_OTG_CORE_HANDLE *pdev);
static uint8_t USBD_RunTestMode (USB_OTG_CORE_HANDLE *pdev) ;
/**
* @}
*/
/** @defgroup USBD_CORE_Private_Variables
* @{
*/
__IO USB_OTG_DCTL_TypeDef SET_TEST_MODE;
USBD_DCD_INT_cb_TypeDef USBD_DCD_INT_cb =
{
USBD_DataOutStage,
USBD_DataInStage,
USBD_SetupStage,
USBD_SOF,
USBD_Reset,
USBD_Suspend,
USBD_Resume,
USBD_IsoINIncomplete,
USBD_IsoOUTIncomplete,
#ifdef VBUS_SENSING_ENABLED
USBD_DevConnected,
USBD_DevDisconnected,
#endif
};
USBD_DCD_INT_cb_TypeDef *USBD_DCD_INT_fops = &USBD_DCD_INT_cb;
/**
* @}
*/
/** @defgroup USBD_CORE_Private_Functions
* @{
*/
/**
* @brief USBD_Init
* Initailizes the device stack and load the class driver
* @param pdev: device instance
* @param core_address: USB OTG core ID
* @param class_cb: Class callback structure address
* @param usr_cb: User callback structure address
* @retval None
*/
void USBD_Init(USB_OTG_CORE_HANDLE *pdev,
USB_OTG_CORE_ID_TypeDef coreID,
USBD_DEVICE *pDevice,
USBD_Class_cb_TypeDef *class_cb,
USBD_Usr_cb_TypeDef *usr_cb)
{
/* Hardware Init */
USB_OTG_BSP_Init(pdev);
USBD_DeInit(pdev);
/*Register class and user callbacks */
pdev->dev.class_cb = class_cb;
pdev->dev.usr_cb = usr_cb;
pdev->dev.usr_device = pDevice;
/* set USB OTG core params */
DCD_Init(pdev , coreID);
/* Upon Init call usr callback */
pdev->dev.usr_cb->Init();
/* Enable Interrupts */
USB_OTG_BSP_EnableInterrupt(pdev);
}
/**
* @brief USBD_DeInit
* Re-Initialize th device library
* @param pdev: device instance
* @retval status: status
*/
USBD_Status USBD_DeInit(USB_OTG_CORE_HANDLE *pdev)
{
/* Software Init */
return USBD_OK;
}
/**
* @brief USBD_SetupStage
* Handle the setup stage
* @param pdev: device instance
* @retval status
*/
static uint8_t USBD_SetupStage(USB_OTG_CORE_HANDLE *pdev)
{
USB_SETUP_REQ req;
USBD_ParseSetupRequest(pdev , &req);
switch (req.bmRequest & 0x1F)
{
case USB_REQ_RECIPIENT_DEVICE:
USBD_StdDevReq (pdev, &req);
break;
case USB_REQ_RECIPIENT_INTERFACE:
USBD_StdItfReq(pdev, &req);
break;
case USB_REQ_RECIPIENT_ENDPOINT:
USBD_StdEPReq(pdev, &req);
break;
default:
DCD_EP_Stall(pdev , req.bmRequest & 0x80);
break;
}
return USBD_OK;
}
/**
* @brief USBD_DataOutStage
* Handle data out stage
* @param pdev: device instance
* @param epnum: endpoint index
* @retval status
*/
static uint8_t USBD_DataOutStage(USB_OTG_CORE_HANDLE *pdev , uint8_t epnum)
{
USB_OTG_EP *ep;
if(epnum == 0)
{
ep = &pdev->dev.out_ep[0];
if ( pdev->dev.device_state == USB_OTG_EP0_DATA_OUT)
{
if(ep->rem_data_len > ep->maxpacket)
{
ep->rem_data_len -= ep->maxpacket;
if(pdev->cfg.dma_enable == 1)
{
/* in slave mode this, is handled by the RxSTSQLvl ISR */
ep->xfer_buff += ep->maxpacket;
}
USBD_CtlContinueRx (pdev,
ep->xfer_buff,
MIN(ep->rem_data_len ,ep->maxpacket));
}
else
{
if((pdev->dev.class_cb->EP0_RxReady != NULL)&&
(pdev->dev.device_status == USB_OTG_CONFIGURED))
{
pdev->dev.class_cb->EP0_RxReady(pdev);
}
USBD_CtlSendStatus(pdev);
}
}
}
else if((pdev->dev.class_cb->DataOut != NULL)&&
(pdev->dev.device_status == USB_OTG_CONFIGURED))
{
pdev->dev.class_cb->DataOut(pdev, epnum);
}
return USBD_OK;
}
/**
* @brief USBD_DataInStage
* Handle data in stage
* @param pdev: device instance
* @param epnum: endpoint index
* @retval status
*/
static uint8_t USBD_DataInStage(USB_OTG_CORE_HANDLE *pdev , uint8_t epnum)
{
USB_OTG_EP *ep;
if(epnum == 0)
{
ep = &pdev->dev.in_ep[0];
if ( pdev->dev.device_state == USB_OTG_EP0_DATA_IN)
{
if(ep->rem_data_len > ep->maxpacket)
{
ep->rem_data_len -= ep->maxpacket;
if(pdev->cfg.dma_enable == 1)
{
/* in slave mode this, is handled by the TxFifoEmpty ISR */
ep->xfer_buff += ep->maxpacket;
}
USBD_CtlContinueSendData (pdev,
ep->xfer_buff,
ep->rem_data_len);
}
else
{ /* last packet is MPS multiple, so send ZLP packet */
if((ep->total_data_len % ep->maxpacket == 0) &&
(ep->total_data_len >= ep->maxpacket) &&
(ep->total_data_len < ep->ctl_data_len ))
{
USBD_CtlContinueSendData(pdev , NULL, 0);
ep->ctl_data_len = 0;
}
else
{
if((pdev->dev.class_cb->EP0_TxSent != NULL)&&
(pdev->dev.device_status == USB_OTG_CONFIGURED))
{
pdev->dev.class_cb->EP0_TxSent(pdev);
}
USBD_CtlReceiveStatus(pdev);
}
}
}
if (pdev->dev.test_mode == 1)
{
USBD_RunTestMode(pdev);
pdev->dev.test_mode = 0;
}
}
else if((pdev->dev.class_cb->DataIn != NULL)&&
(pdev->dev.device_status == USB_OTG_CONFIGURED))
{
pdev->dev.class_cb->DataIn(pdev, epnum);
}
return USBD_OK;
}
/**
* @brief USBD_RunTestMode
* Launch test mode process
* @param pdev: device instance
* @retval status
*/
static uint8_t USBD_RunTestMode (USB_OTG_CORE_HANDLE *pdev)
{
USB_OTG_WRITE_REG32(&pdev->regs.DREGS->DCTL, SET_TEST_MODE.d32);
return USBD_OK;
}
/**
* @brief USBD_Reset
* Handle Reset event
* @param pdev: device instance
* @retval status
*/
static uint8_t USBD_Reset(USB_OTG_CORE_HANDLE *pdev)
{
/* Open EP0 OUT */
DCD_EP_Open(pdev,
0x00,
USB_OTG_MAX_EP0_SIZE,
EP_TYPE_CTRL);
/* Open EP0 IN */
DCD_EP_Open(pdev,
0x80,
USB_OTG_MAX_EP0_SIZE,
EP_TYPE_CTRL);
/* Upon Reset call usr call back */
pdev->dev.device_status = USB_OTG_DEFAULT;
pdev->dev.usr_cb->DeviceReset(pdev->cfg.speed);
return USBD_OK;
}
/**
* @brief USBD_Resume
* Handle Resume event
* @param pdev: device instance
* @retval status
*/
static uint8_t USBD_Resume(USB_OTG_CORE_HANDLE *pdev)
{
/* Upon Resume call usr call back */
pdev->dev.usr_cb->DeviceResumed();
pdev->dev.device_status = pdev->dev.device_old_status;
pdev->dev.device_status = USB_OTG_CONFIGURED;
return USBD_OK;
}
/**
* @brief USBD_Suspend
* Handle Suspend event
* @param pdev: device instance
* @retval status
*/
static uint8_t USBD_Suspend(USB_OTG_CORE_HANDLE *pdev)
{
pdev->dev.device_old_status = pdev->dev.device_status;
pdev->dev.device_status = USB_OTG_SUSPENDED;
/* Upon Resume call usr call back */
pdev->dev.usr_cb->DeviceSuspended();
return USBD_OK;
}
/**
* @brief USBD_SOF
* Handle SOF event
* @param pdev: device instance
* @retval status
*/
static uint8_t USBD_SOF(USB_OTG_CORE_HANDLE *pdev)
{
if(pdev->dev.class_cb->SOF)
{
pdev->dev.class_cb->SOF(pdev);
}
return USBD_OK;
}
/**
* @brief USBD_SetCfg
* Configure device and start the interface
* @param pdev: device instance
* @param cfgidx: configuration index
* @retval status
*/
USBD_Status USBD_SetCfg(USB_OTG_CORE_HANDLE *pdev, uint8_t cfgidx)
{
pdev->dev.class_cb->Init(pdev, cfgidx);
/* Upon set config call usr call back */
pdev->dev.usr_cb->DeviceConfigured();
return USBD_OK;
}
/**
* @brief USBD_ClrCfg
* Clear current configuration
* @param pdev: device instance
* @param cfgidx: configuration index
* @retval status: USBD_Status
*/
USBD_Status USBD_ClrCfg(USB_OTG_CORE_HANDLE *pdev, uint8_t cfgidx)
{
pdev->dev.class_cb->DeInit(pdev, cfgidx);
return USBD_OK;
}
/**
* @brief USBD_IsoINIncomplete
* Handle iso in incomplete event
* @param pdev: device instance
* @retval status
*/
static uint8_t USBD_IsoINIncomplete(USB_OTG_CORE_HANDLE *pdev)
{
pdev->dev.class_cb->IsoINIncomplete(pdev);
return USBD_OK;
}
/**
* @brief USBD_IsoOUTIncomplete
* Handle iso out incomplete event
* @param pdev: device instance
* @retval status
*/
static uint8_t USBD_IsoOUTIncomplete(USB_OTG_CORE_HANDLE *pdev)
{
pdev->dev.class_cb->IsoOUTIncomplete(pdev);
return USBD_OK;
}
#ifdef VBUS_SENSING_ENABLED
/**
* @brief USBD_DevConnected
* Handle device connection event
* @param pdev: device instance
* @retval status
*/
static uint8_t USBD_DevConnected(USB_OTG_CORE_HANDLE *pdev)
{
pdev->dev.usr_cb->DeviceConnected();
pdev->dev.connection_status = 1;
return USBD_OK;
}
/**
* @brief USBD_DevDisconnected
* Handle device disconnection event
* @param pdev: device instance
* @retval status
*/
static uint8_t USBD_DevDisconnected(USB_OTG_CORE_HANDLE *pdev)
{
pdev->dev.usr_cb->DeviceDisconnected();
pdev->dev.class_cb->DeInit(pdev, 0);
pdev->dev.connection_status = 0;
return USBD_OK;
}
#endif
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,244 @@
/**
******************************************************************************
* @file usbd_ioreq.c
* @author MCD Application Team
* @version V1.1.0
* @date 19-March-2012
* @brief This file provides the IO requests APIs for control endpoints.
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "usbd_ioreq.h"
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
* @{
*/
/** @defgroup USBD_IOREQ
* @brief control I/O requests module
* @{
*/
/** @defgroup USBD_IOREQ_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @defgroup USBD_IOREQ_Private_Defines
* @{
*/
/**
* @}
*/
/** @defgroup USBD_IOREQ_Private_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBD_IOREQ_Private_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USBD_IOREQ_Private_FunctionPrototypes
* @{
*/
/**
* @}
*/
/** @defgroup USBD_IOREQ_Private_Functions
* @{
*/
/**
* @brief USBD_CtlSendData
* send data on the ctl pipe
* @param pdev: device instance
* @param buff: pointer to data buffer
* @param len: length of data to be sent
* @retval status
*/
USBD_Status USBD_CtlSendData (USB_OTG_CORE_HANDLE *pdev,
uint8_t *pbuf,
uint16_t len)
{
USBD_Status ret = USBD_OK;
pdev->dev.in_ep[0].total_data_len = len;
pdev->dev.in_ep[0].rem_data_len = len;
pdev->dev.device_state = USB_OTG_EP0_DATA_IN;
DCD_EP_Tx (pdev, 0, pbuf, len);
return ret;
}
/**
* @brief USBD_CtlContinueSendData
* continue sending data on the ctl pipe
* @param pdev: device instance
* @param buff: pointer to data buffer
* @param len: length of data to be sent
* @retval status
*/
USBD_Status USBD_CtlContinueSendData (USB_OTG_CORE_HANDLE *pdev,
uint8_t *pbuf,
uint16_t len)
{
USBD_Status ret = USBD_OK;
DCD_EP_Tx (pdev, 0, pbuf, len);
return ret;
}
/**
* @brief USBD_CtlPrepareRx
* receive data on the ctl pipe
* @param pdev: USB OTG device instance
* @param buff: pointer to data buffer
* @param len: length of data to be received
* @retval status
*/
USBD_Status USBD_CtlPrepareRx (USB_OTG_CORE_HANDLE *pdev,
uint8_t *pbuf,
uint16_t len)
{
USBD_Status ret = USBD_OK;
pdev->dev.out_ep[0].total_data_len = len;
pdev->dev.out_ep[0].rem_data_len = len;
pdev->dev.device_state = USB_OTG_EP0_DATA_OUT;
DCD_EP_PrepareRx (pdev,
0,
pbuf,
len);
return ret;
}
/**
* @brief USBD_CtlContinueRx
* continue receive data on the ctl pipe
* @param pdev: USB OTG device instance
* @param buff: pointer to data buffer
* @param len: length of data to be received
* @retval status
*/
USBD_Status USBD_CtlContinueRx (USB_OTG_CORE_HANDLE *pdev,
uint8_t *pbuf,
uint16_t len)
{
USBD_Status ret = USBD_OK;
DCD_EP_PrepareRx (pdev,
0,
pbuf,
len);
return ret;
}
/**
* @brief USBD_CtlSendStatus
* send zero lzngth packet on the ctl pipe
* @param pdev: USB OTG device instance
* @retval status
*/
USBD_Status USBD_CtlSendStatus (USB_OTG_CORE_HANDLE *pdev)
{
USBD_Status ret = USBD_OK;
pdev->dev.device_state = USB_OTG_EP0_STATUS_IN;
DCD_EP_Tx (pdev,
0,
NULL,
0);
USB_OTG_EP0_OutStart(pdev);
return ret;
}
/**
* @brief USBD_CtlReceiveStatus
* receive zero lzngth packet on the ctl pipe
* @param pdev: USB OTG device instance
* @retval status
*/
USBD_Status USBD_CtlReceiveStatus (USB_OTG_CORE_HANDLE *pdev)
{
USBD_Status ret = USBD_OK;
pdev->dev.device_state = USB_OTG_EP0_STATUS_OUT;
DCD_EP_PrepareRx ( pdev,
0,
NULL,
0);
USB_OTG_EP0_OutStart(pdev);
return ret;
}
/**
* @brief USBD_GetRxCount
* returns the received data length
* @param pdev: USB OTG device instance
* epnum: endpoint index
* @retval Rx Data blength
*/
uint16_t USBD_GetRxCount (USB_OTG_CORE_HANDLE *pdev , uint8_t epnum)
{
return pdev->dev.out_ep[epnum].xfer_count;
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,868 @@
/**
******************************************************************************
* @file usbd_req.c
* @author MCD Application Team
* @version V1.1.0
* @date 19-March-2012
* @brief This file provides the standard USB requests following chapter 9.
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "usbd_req.h"
#include "usbd_ioreq.h"
#include "usbd_desc.h"
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
* @{
*/
/** @defgroup USBD_REQ
* @brief USB standard requests module
* @{
*/
/** @defgroup USBD_REQ_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @defgroup USBD_REQ_Private_Defines
* @{
*/
/**
* @}
*/
/** @defgroup USBD_REQ_Private_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBD_REQ_Private_Variables
* @{
*/
extern __IO USB_OTG_DCTL_TypeDef SET_TEST_MODE;
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
__ALIGN_BEGIN uint32_t USBD_ep_status __ALIGN_END = 0;
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
__ALIGN_BEGIN uint32_t USBD_default_cfg __ALIGN_END = 0;
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
__ALIGN_BEGIN uint32_t USBD_cfg_status __ALIGN_END = 0;
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
__ALIGN_BEGIN uint8_t USBD_StrDesc[USB_MAX_STR_DESC_SIZ] __ALIGN_END ;
/**
* @}
*/
/** @defgroup USBD_REQ_Private_FunctionPrototypes
* @{
*/
static void USBD_GetDescriptor(USB_OTG_CORE_HANDLE *pdev,
USB_SETUP_REQ *req);
static void USBD_SetAddress(USB_OTG_CORE_HANDLE *pdev,
USB_SETUP_REQ *req);
static void USBD_SetConfig(USB_OTG_CORE_HANDLE *pdev,
USB_SETUP_REQ *req);
static void USBD_GetConfig(USB_OTG_CORE_HANDLE *pdev,
USB_SETUP_REQ *req);
static void USBD_GetStatus(USB_OTG_CORE_HANDLE *pdev,
USB_SETUP_REQ *req);
static void USBD_SetFeature(USB_OTG_CORE_HANDLE *pdev,
USB_SETUP_REQ *req);
static void USBD_ClrFeature(USB_OTG_CORE_HANDLE *pdev,
USB_SETUP_REQ *req);
static uint8_t USBD_GetLen(uint8_t *buf);
/**
* @}
*/
/** @defgroup USBD_REQ_Private_Functions
* @{
*/
/**
* @brief USBD_StdDevReq
* Handle standard usb device requests
* @param pdev: device instance
* @param req: usb request
* @retval status
*/
USBD_Status USBD_StdDevReq (USB_OTG_CORE_HANDLE *pdev, USB_SETUP_REQ *req)
{
USBD_Status ret = USBD_OK;
switch (req->bRequest)
{
case USB_REQ_GET_DESCRIPTOR:
USBD_GetDescriptor (pdev, req) ;
break;
case USB_REQ_SET_ADDRESS:
USBD_SetAddress(pdev, req);
break;
case USB_REQ_SET_CONFIGURATION:
USBD_SetConfig (pdev , req);
break;
case USB_REQ_GET_CONFIGURATION:
USBD_GetConfig (pdev , req);
break;
case USB_REQ_GET_STATUS:
USBD_GetStatus (pdev , req);
break;
case USB_REQ_SET_FEATURE:
USBD_SetFeature (pdev , req);
break;
case USB_REQ_CLEAR_FEATURE:
USBD_ClrFeature (pdev , req);
break;
default:
USBD_CtlError(pdev , req);
break;
}
return ret;
}
/**
* @brief USBD_StdItfReq
* Handle standard usb interface requests
* @param pdev: USB OTG device instance
* @param req: usb request
* @retval status
*/
USBD_Status USBD_StdItfReq (USB_OTG_CORE_HANDLE *pdev, USB_SETUP_REQ *req)
{
USBD_Status ret = USBD_OK;
switch (pdev->dev.device_status)
{
case USB_OTG_CONFIGURED:
if (LOBYTE(req->wIndex) <= USBD_ITF_MAX_NUM)
{
pdev->dev.class_cb->Setup (pdev, req);
if((req->wLength == 0)&& (ret == USBD_OK))
{
USBD_CtlSendStatus(pdev);
}
}
else
{
USBD_CtlError(pdev , req);
}
break;
default:
USBD_CtlError(pdev , req);
break;
}
return ret;
}
/**
* @brief USBD_StdEPReq
* Handle standard usb endpoint requests
* @param pdev: USB OTG device instance
* @param req: usb request
* @retval status
*/
USBD_Status USBD_StdEPReq (USB_OTG_CORE_HANDLE *pdev, USB_SETUP_REQ *req)
{
uint8_t ep_addr;
USBD_Status ret = USBD_OK;
ep_addr = LOBYTE(req->wIndex);
switch (req->bRequest)
{
case USB_REQ_SET_FEATURE :
switch (pdev->dev.device_status)
{
case USB_OTG_ADDRESSED:
if ((ep_addr != 0x00) && (ep_addr != 0x80))
{
DCD_EP_Stall(pdev , ep_addr);
}
break;
case USB_OTG_CONFIGURED:
if (req->wValue == USB_FEATURE_EP_HALT)
{
if ((ep_addr != 0x00) && (ep_addr != 0x80))
{
DCD_EP_Stall(pdev , ep_addr);
}
}
pdev->dev.class_cb->Setup (pdev, req);
USBD_CtlSendStatus(pdev);
break;
default:
USBD_CtlError(pdev , req);
break;
}
break;
case USB_REQ_CLEAR_FEATURE :
switch (pdev->dev.device_status)
{
case USB_OTG_ADDRESSED:
if ((ep_addr != 0x00) && (ep_addr != 0x80))
{
DCD_EP_Stall(pdev , ep_addr);
}
break;
case USB_OTG_CONFIGURED:
if (req->wValue == USB_FEATURE_EP_HALT)
{
if ((ep_addr != 0x00) && (ep_addr != 0x80))
{
DCD_EP_ClrStall(pdev , ep_addr);
pdev->dev.class_cb->Setup (pdev, req);
}
USBD_CtlSendStatus(pdev);
}
break;
default:
USBD_CtlError(pdev , req);
break;
}
break;
case USB_REQ_GET_STATUS:
switch (pdev->dev.device_status)
{
case USB_OTG_ADDRESSED:
if ((ep_addr != 0x00) && (ep_addr != 0x80))
{
DCD_EP_Stall(pdev , ep_addr);
}
break;
case USB_OTG_CONFIGURED:
if ((ep_addr & 0x80)== 0x80)
{
if(pdev->dev.in_ep[ep_addr & 0x7F].is_stall)
{
USBD_ep_status = 0x0001;
}
else
{
USBD_ep_status = 0x0000;
}
}
else if ((ep_addr & 0x80)== 0x00)
{
if(pdev->dev.out_ep[ep_addr].is_stall)
{
USBD_ep_status = 0x0001;
}
else
{
USBD_ep_status = 0x0000;
}
}
USBD_CtlSendData (pdev,
(uint8_t *)&USBD_ep_status,
2);
break;
default:
USBD_CtlError(pdev , req);
break;
}
break;
default:
break;
}
return ret;
}
/**
* @brief USBD_GetDescriptor
* Handle Get Descriptor requests
* @param pdev: device instance
* @param req: usb request
* @retval status
*/
static void USBD_GetDescriptor(USB_OTG_CORE_HANDLE *pdev,
USB_SETUP_REQ *req)
{
uint16_t len;
uint8_t *pbuf;
switch (req->wValue >> 8)
{
case USB_DESC_TYPE_DEVICE:
pbuf = pdev->dev.usr_device->GetDeviceDescriptor(pdev->cfg.speed, &len);
if ((req->wLength == 64) ||( pdev->dev.device_status == USB_OTG_DEFAULT))
{
len = 8;
}
break;
case USB_DESC_TYPE_CONFIGURATION:
pbuf = (uint8_t *)pdev->dev.class_cb->GetConfigDescriptor(pdev->cfg.speed, &len);
#ifdef USB_OTG_HS_CORE
if((pdev->cfg.speed == USB_OTG_SPEED_FULL )&&
(pdev->cfg.phy_itface == USB_OTG_ULPI_PHY))
{
pbuf = (uint8_t *)pdev->dev.class_cb->GetOtherConfigDescriptor(pdev->cfg.speed, &len);
}
#endif
pbuf[1] = USB_DESC_TYPE_CONFIGURATION;
pdev->dev.pConfig_descriptor = pbuf;
break;
case USB_DESC_TYPE_STRING:
switch ((uint8_t)(req->wValue))
{
case USBD_IDX_LANGID_STR:
pbuf = pdev->dev.usr_device->GetLangIDStrDescriptor(pdev->cfg.speed, &len);
break;
case USBD_IDX_MFC_STR:
pbuf = pdev->dev.usr_device->GetManufacturerStrDescriptor(pdev->cfg.speed, &len);
break;
case USBD_IDX_PRODUCT_STR:
pbuf = pdev->dev.usr_device->GetProductStrDescriptor(pdev->cfg.speed, &len);
break;
case USBD_IDX_SERIAL_STR:
pbuf = pdev->dev.usr_device->GetSerialStrDescriptor(pdev->cfg.speed, &len);
break;
case USBD_IDX_CONFIG_STR:
pbuf = pdev->dev.usr_device->GetConfigurationStrDescriptor(pdev->cfg.speed, &len);
break;
case USBD_IDX_INTERFACE_STR:
pbuf = pdev->dev.usr_device->GetInterfaceStrDescriptor(pdev->cfg.speed, &len);
break;
default:
#ifdef USB_SUPPORT_USER_STRING_DESC
pbuf = pdev->dev.class_cb->GetUsrStrDescriptor(pdev->cfg.speed, (req->wValue) , &len);
break;
#else
USBD_CtlError(pdev , req);
return;
#endif /* USBD_CtlError(pdev , req); */
}
break;
case USB_DESC_TYPE_DEVICE_QUALIFIER:
#ifdef USB_OTG_HS_CORE
if(pdev->cfg.speed == USB_OTG_SPEED_HIGH )
{
pbuf = (uint8_t *)pdev->dev.class_cb->GetConfigDescriptor(pdev->cfg.speed, &len);
USBD_DeviceQualifierDesc[4]= pbuf[14];
USBD_DeviceQualifierDesc[5]= pbuf[15];
USBD_DeviceQualifierDesc[6]= pbuf[16];
pbuf = USBD_DeviceQualifierDesc;
len = USB_LEN_DEV_QUALIFIER_DESC;
break;
}
else
{
USBD_CtlError(pdev , req);
return;
}
#else
USBD_CtlError(pdev , req);
return;
#endif
case USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION:
#ifdef USB_OTG_HS_CORE
if(pdev->cfg.speed == USB_OTG_SPEED_HIGH )
{
pbuf = (uint8_t *)pdev->dev.class_cb->GetOtherConfigDescriptor(pdev->cfg.speed, &len);
pbuf[1] = USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION;
break;
}
else
{
USBD_CtlError(pdev , req);
return;
}
#else
USBD_CtlError(pdev , req);
return;
#endif
default:
USBD_CtlError(pdev , req);
return;
}
if((len != 0)&& (req->wLength != 0))
{
len = MIN(len , req->wLength);
USBD_CtlSendData (pdev,
pbuf,
len);
}
}
/**
* @brief USBD_SetAddress
* Set device address
* @param pdev: device instance
* @param req: usb request
* @retval status
*/
static void USBD_SetAddress(USB_OTG_CORE_HANDLE *pdev,
USB_SETUP_REQ *req)
{
uint8_t dev_addr;
if ((req->wIndex == 0) && (req->wLength == 0))
{
dev_addr = (uint8_t)(req->wValue) & 0x7F;
if (pdev->dev.device_status == USB_OTG_CONFIGURED)
{
USBD_CtlError(pdev , req);
}
else
{
pdev->dev.device_address = dev_addr;
DCD_EP_SetAddress(pdev, dev_addr);
USBD_CtlSendStatus(pdev);
if (dev_addr != 0)
{
pdev->dev.device_status = USB_OTG_ADDRESSED;
}
else
{
pdev->dev.device_status = USB_OTG_DEFAULT;
}
}
}
else
{
USBD_CtlError(pdev , req);
}
}
/**
* @brief USBD_SetConfig
* Handle Set device configuration request
* @param pdev: device instance
* @param req: usb request
* @retval status
*/
static void USBD_SetConfig(USB_OTG_CORE_HANDLE *pdev,
USB_SETUP_REQ *req)
{
static uint8_t cfgidx;
cfgidx = (uint8_t)(req->wValue);
if (cfgidx > USBD_CFG_MAX_NUM )
{
USBD_CtlError(pdev , req);
}
else
{
switch (pdev->dev.device_status)
{
case USB_OTG_ADDRESSED:
if (cfgidx)
{
pdev->dev.device_config = cfgidx;
pdev->dev.device_status = USB_OTG_CONFIGURED;
USBD_SetCfg(pdev , cfgidx);
USBD_CtlSendStatus(pdev);
}
else
{
USBD_CtlSendStatus(pdev);
}
break;
case USB_OTG_CONFIGURED:
if (cfgidx == 0)
{
pdev->dev.device_status = USB_OTG_ADDRESSED;
pdev->dev.device_config = cfgidx;
USBD_ClrCfg(pdev , cfgidx);
USBD_CtlSendStatus(pdev);
}
else if (cfgidx != pdev->dev.device_config)
{
/* Clear old configuration */
USBD_ClrCfg(pdev , pdev->dev.device_config);
/* set new configuration */
pdev->dev.device_config = cfgidx;
USBD_SetCfg(pdev , cfgidx);
USBD_CtlSendStatus(pdev);
}
else
{
USBD_CtlSendStatus(pdev);
}
break;
default:
USBD_CtlError(pdev , req);
break;
}
}
}
/**
* @brief USBD_GetConfig
* Handle Get device configuration request
* @param pdev: device instance
* @param req: usb request
* @retval status
*/
static void USBD_GetConfig(USB_OTG_CORE_HANDLE *pdev,
USB_SETUP_REQ *req)
{
if (req->wLength != 1)
{
USBD_CtlError(pdev , req);
}
else
{
switch (pdev->dev.device_status )
{
case USB_OTG_ADDRESSED:
USBD_CtlSendData (pdev,
(uint8_t *)&USBD_default_cfg,
1);
break;
case USB_OTG_CONFIGURED:
USBD_CtlSendData (pdev,
&pdev->dev.device_config,
1);
break;
default:
USBD_CtlError(pdev , req);
break;
}
}
}
/**
* @brief USBD_GetStatus
* Handle Get Status request
* @param pdev: device instance
* @param req: usb request
* @retval status
*/
static void USBD_GetStatus(USB_OTG_CORE_HANDLE *pdev,
USB_SETUP_REQ *req)
{
switch (pdev->dev.device_status)
{
case USB_OTG_ADDRESSED:
case USB_OTG_CONFIGURED:
#ifdef USBD_SELF_POWERED
USBD_cfg_status = USB_CONFIG_SELF_POWERED;
#else
USBD_cfg_status = 0x00;
#endif
if (pdev->dev.DevRemoteWakeup)
{
USBD_cfg_status |= USB_CONFIG_REMOTE_WAKEUP;
}
USBD_CtlSendData (pdev,
(uint8_t *)&USBD_cfg_status,
2);
break;
default :
USBD_CtlError(pdev , req);
break;
}
}
/**
* @brief USBD_SetFeature
* Handle Set device feature request
* @param pdev: device instance
* @param req: usb request
* @retval status
*/
static void USBD_SetFeature(USB_OTG_CORE_HANDLE *pdev,
USB_SETUP_REQ *req)
{
USB_OTG_DCTL_TypeDef dctl;
uint8_t test_mode = 0;
if (req->wValue == USB_FEATURE_REMOTE_WAKEUP)
{
pdev->dev.DevRemoteWakeup = 1;
pdev->dev.class_cb->Setup (pdev, req);
USBD_CtlSendStatus(pdev);
}
else if ((req->wValue == USB_FEATURE_TEST_MODE) &&
((req->wIndex & 0xFF) == 0))
{
dctl.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DCTL);
test_mode = req->wIndex >> 8;
switch (test_mode)
{
case 1: // TEST_J
dctl.b.tstctl = 1;
break;
case 2: // TEST_K
dctl.b.tstctl = 2;
break;
case 3: // TEST_SE0_NAK
dctl.b.tstctl = 3;
break;
case 4: // TEST_PACKET
dctl.b.tstctl = 4;
break;
case 5: // TEST_FORCE_ENABLE
dctl.b.tstctl = 5;
break;
}
SET_TEST_MODE = dctl;
pdev->dev.test_mode = 1;
USBD_CtlSendStatus(pdev);
}
}
/**
* @brief USBD_ClrFeature
* Handle clear device feature request
* @param pdev: device instance
* @param req: usb request
* @retval status
*/
static void USBD_ClrFeature(USB_OTG_CORE_HANDLE *pdev,
USB_SETUP_REQ *req)
{
switch (pdev->dev.device_status)
{
case USB_OTG_ADDRESSED:
case USB_OTG_CONFIGURED:
if (req->wValue == USB_FEATURE_REMOTE_WAKEUP)
{
pdev->dev.DevRemoteWakeup = 0;
pdev->dev.class_cb->Setup (pdev, req);
USBD_CtlSendStatus(pdev);
}
break;
default :
USBD_CtlError(pdev , req);
break;
}
}
/**
* @brief USBD_ParseSetupRequest
* Copy buffer into setup structure
* @param pdev: device instance
* @param req: usb request
* @retval None
*/
void USBD_ParseSetupRequest( USB_OTG_CORE_HANDLE *pdev,
USB_SETUP_REQ *req)
{
req->bmRequest = *(uint8_t *) (pdev->dev.setup_packet);
req->bRequest = *(uint8_t *) (pdev->dev.setup_packet + 1);
req->wValue = SWAPBYTE (pdev->dev.setup_packet + 2);
req->wIndex = SWAPBYTE (pdev->dev.setup_packet + 4);
req->wLength = SWAPBYTE (pdev->dev.setup_packet + 6);
pdev->dev.in_ep[0].ctl_data_len = req->wLength ;
pdev->dev.device_state = USB_OTG_EP0_SETUP;
}
/**
* @brief USBD_CtlError
* Handle USB low level Error
* @param pdev: device instance
* @param req: usb request
* @retval None
*/
void USBD_CtlError( USB_OTG_CORE_HANDLE *pdev,
USB_SETUP_REQ *req)
{
DCD_EP_Stall(pdev , 0x80);
DCD_EP_Stall(pdev , 0);
USB_OTG_EP0_OutStart(pdev);
}
/**
* @brief USBD_GetString
* Convert Ascii string into unicode one
* @param desc : descriptor buffer
* @param unicode : Formatted string buffer (unicode)
* @param len : descriptor length
* @retval None
*/
void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len)
{
uint8_t idx = 0;
if (desc != NULL)
{
*len = USBD_GetLen(desc) * 2 + 2;
unicode[idx++] = *len;
unicode[idx++] = USB_DESC_TYPE_STRING;
while (*desc != NULL)
{
unicode[idx++] = *desc++;
unicode[idx++] = 0x00;
}
}
}
/**
* @brief USBD_GetLen
* return the string length
* @param buf : pointer to the ascii string buffer
* @retval string length
*/
static uint8_t USBD_GetLen(uint8_t *buf)
{
uint8_t len = 0;
while (*buf != NULL)
{
len++;
buf++;
}
return len;
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,950 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40"><head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<link rel="File-List" href="Release_Notes_for_STM32F2xx_StdPeriph_Driver_files/filelist.xml">
<link rel="Edit-Time-Data" href="Release_Notes_for_STM32F2xx_StdPeriph_Driver_files/editdata.mso"><!--[if !mso]>
<style>
v\:* {behavior:url(#default#VML);}
o\:* {behavior:url(#default#VML);}
w\:* {behavior:url(#default#VML);}
.shape {behavior:url(#default#VML);}
</style>
<![endif]-->
<title>Release Notes for STM32F105/7xx, STM32F2xx and STM32F4xx USB Device Library</title><!--[if gte mso 9]><xml>
<o:DocumentProperties>
<o:Author>STMicroelectronics</o:Author>
<o:LastAuthor>Raouf Hosni</o:LastAuthor>
<o:Revision>39</o:Revision>
<o:TotalTime>137</o:TotalTime>
<o:Created>2009-02-27T19:26:00Z</o:Created>
<o:LastSaved>2010-10-15T11:07:00Z</o:LastSaved>
<o:Pages>3</o:Pages>
<o:Words>973</o:Words>
<o:Characters>5548</o:Characters>
<o:Company>STMicroelectronics</o:Company>
<o:Lines>46</o:Lines>
<o:Paragraphs>13</o:Paragraphs>
<o:CharactersWithSpaces>6508</o:CharactersWithSpaces>
<o:Version>12.00</o:Version>
</o:DocumentProperties>
</xml><![endif]--><link rel="themeData" href="Release_Notes_for_STM32F2xx_StdPeriph_Driver_files/themedata.thmx">
<link rel="colorSchemeMapping" href="Release_Notes_for_STM32F2xx_StdPeriph_Driver_files/colorschememapping.xml"><!--[if gte mso 9]><xml>
<w:WordDocument>
<w:Zoom>110</w:Zoom>
<w:TrackMoves>false</w:TrackMoves>
<w:TrackFormatting/>
<w:ValidateAgainstSchemas/>
<w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid>
<w:IgnoreMixedContent>false</w:IgnoreMixedContent>
<w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText>
<w:DoNotPromoteQF/>
<w:LidThemeOther>EN-US</w:LidThemeOther>
<w:LidThemeAsian>X-NONE</w:LidThemeAsian>
<w:LidThemeComplexScript>X-NONE</w:LidThemeComplexScript>
<w:Compatibility>
<w:BreakWrappedTables/>
<w:SnapToGridInCell/>
<w:WrapTextWithPunct/>
<w:UseAsianBreakRules/>
<w:DontGrowAutofit/>
<w:SplitPgBreakAndParaMark/>
<w:DontVertAlignCellWithSp/>
<w:DontBreakConstrainedForcedTables/>
<w:DontVertAlignInTxbx/>
<w:Word11KerningPairs/>
<w:CachedColBalance/>
</w:Compatibility>
<w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel>
<m:mathPr>
<m:mathFont m:val="Cambria Math"/>
<m:brkBin m:val="before"/>
<m:brkBinSub m:val="&#45;-"/>
<m:smallFrac m:val="off"/>
<m:dispDef/>
<m:lMargin m:val="0"/>
<m:rMargin m:val="0"/>
<m:defJc m:val="centerGroup"/>
<m:wrapIndent m:val="1440"/>
<m:intLim m:val="subSup"/>
<m:naryLim m:val="undOvr"/>
</m:mathPr></w:WordDocument>
</xml><![endif]--><!--[if gte mso 9]><xml>
<w:LatentStyles DefLockedState="false" DefUnhideWhenUsed="false"
DefSemiHidden="false" DefQFormat="false" LatentStyleCount="267">
<w:LsdException Locked="false" QFormat="true" Name="Normal"/>
<w:LsdException Locked="false" QFormat="true" Name="heading 1"/>
<w:LsdException Locked="false" QFormat="true" Name="heading 2"/>
<w:LsdException Locked="false" QFormat="true" Name="heading 3"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
QFormat="true" Name="heading 4"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
QFormat="true" Name="heading 5"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
QFormat="true" Name="heading 6"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
QFormat="true" Name="heading 7"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
QFormat="true" Name="heading 8"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
QFormat="true" Name="heading 9"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
QFormat="true" Name="caption"/>
<w:LsdException Locked="false" QFormat="true" Name="Title"/>
<w:LsdException Locked="false" Priority="1" Name="Default Paragraph Font"/>
<w:LsdException Locked="false" QFormat="true" Name="Subtitle"/>
<w:LsdException Locked="false" QFormat="true" Name="Strong"/>
<w:LsdException Locked="false" QFormat="true" Name="Emphasis"/>
<w:LsdException Locked="false" Priority="99" Name="No List"/>
<w:LsdException Locked="false" Priority="99" SemiHidden="true"
Name="Placeholder Text"/>
<w:LsdException Locked="false" Priority="1" QFormat="true" Name="No Spacing"/>
<w:LsdException Locked="false" Priority="60" Name="Light Shading"/>
<w:LsdException Locked="false" Priority="61" Name="Light List"/>
<w:LsdException Locked="false" Priority="62" Name="Light Grid"/>
<w:LsdException Locked="false" Priority="63" Name="Medium Shading 1"/>
<w:LsdException Locked="false" Priority="64" Name="Medium Shading 2"/>
<w:LsdException Locked="false" Priority="65" Name="Medium List 1"/>
<w:LsdException Locked="false" Priority="66" Name="Medium List 2"/>
<w:LsdException Locked="false" Priority="67" Name="Medium Grid 1"/>
<w:LsdException Locked="false" Priority="68" Name="Medium Grid 2"/>
<w:LsdException Locked="false" Priority="69" Name="Medium Grid 3"/>
<w:LsdException Locked="false" Priority="70" Name="Dark List"/>
<w:LsdException Locked="false" Priority="71" Name="Colorful Shading"/>
<w:LsdException Locked="false" Priority="72" Name="Colorful List"/>
<w:LsdException Locked="false" Priority="73" Name="Colorful Grid"/>
<w:LsdException Locked="false" Priority="60" Name="Light Shading Accent 1"/>
<w:LsdException Locked="false" Priority="61" Name="Light List Accent 1"/>
<w:LsdException Locked="false" Priority="62" Name="Light Grid Accent 1"/>
<w:LsdException Locked="false" Priority="63" Name="Medium Shading 1 Accent 1"/>
<w:LsdException Locked="false" Priority="64" Name="Medium Shading 2 Accent 1"/>
<w:LsdException Locked="false" Priority="65" Name="Medium List 1 Accent 1"/>
<w:LsdException Locked="false" Priority="99" SemiHidden="true" Name="Revision"/>
<w:LsdException Locked="false" Priority="34" QFormat="true"
Name="List Paragraph"/>
<w:LsdException Locked="false" Priority="29" QFormat="true" Name="Quote"/>
<w:LsdException Locked="false" Priority="30" QFormat="true"
Name="Intense Quote"/>
<w:LsdException Locked="false" Priority="66" Name="Medium List 2 Accent 1"/>
<w:LsdException Locked="false" Priority="67" Name="Medium Grid 1 Accent 1"/>
<w:LsdException Locked="false" Priority="68" Name="Medium Grid 2 Accent 1"/>
<w:LsdException Locked="false" Priority="69" Name="Medium Grid 3 Accent 1"/>
<w:LsdException Locked="false" Priority="70" Name="Dark List Accent 1"/>
<w:LsdException Locked="false" Priority="71" Name="Colorful Shading Accent 1"/>
<w:LsdException Locked="false" Priority="72" Name="Colorful List Accent 1"/>
<w:LsdException Locked="false" Priority="73" Name="Colorful Grid Accent 1"/>
<w:LsdException Locked="false" Priority="60" Name="Light Shading Accent 2"/>
<w:LsdException Locked="false" Priority="61" Name="Light List Accent 2"/>
<w:LsdException Locked="false" Priority="62" Name="Light Grid Accent 2"/>
<w:LsdException Locked="false" Priority="63" Name="Medium Shading 1 Accent 2"/>
<w:LsdException Locked="false" Priority="64" Name="Medium Shading 2 Accent 2"/>
<w:LsdException Locked="false" Priority="65" Name="Medium List 1 Accent 2"/>
<w:LsdException Locked="false" Priority="66" Name="Medium List 2 Accent 2"/>
<w:LsdException Locked="false" Priority="67" Name="Medium Grid 1 Accent 2"/>
<w:LsdException Locked="false" Priority="68" Name="Medium Grid 2 Accent 2"/>
<w:LsdException Locked="false" Priority="69" Name="Medium Grid 3 Accent 2"/>
<w:LsdException Locked="false" Priority="70" Name="Dark List Accent 2"/>
<w:LsdException Locked="false" Priority="71" Name="Colorful Shading Accent 2"/>
<w:LsdException Locked="false" Priority="72" Name="Colorful List Accent 2"/>
<w:LsdException Locked="false" Priority="73" Name="Colorful Grid Accent 2"/>
<w:LsdException Locked="false" Priority="60" Name="Light Shading Accent 3"/>
<w:LsdException Locked="false" Priority="61" Name="Light List Accent 3"/>
<w:LsdException Locked="false" Priority="62" Name="Light Grid Accent 3"/>
<w:LsdException Locked="false" Priority="63" Name="Medium Shading 1 Accent 3"/>
<w:LsdException Locked="false" Priority="64" Name="Medium Shading 2 Accent 3"/>
<w:LsdException Locked="false" Priority="65" Name="Medium List 1 Accent 3"/>
<w:LsdException Locked="false" Priority="66" Name="Medium List 2 Accent 3"/>
<w:LsdException Locked="false" Priority="67" Name="Medium Grid 1 Accent 3"/>
<w:LsdException Locked="false" Priority="68" Name="Medium Grid 2 Accent 3"/>
<w:LsdException Locked="false" Priority="69" Name="Medium Grid 3 Accent 3"/>
<w:LsdException Locked="false" Priority="70" Name="Dark List Accent 3"/>
<w:LsdException Locked="false" Priority="71" Name="Colorful Shading Accent 3"/>
<w:LsdException Locked="false" Priority="72" Name="Colorful List Accent 3"/>
<w:LsdException Locked="false" Priority="73" Name="Colorful Grid Accent 3"/>
<w:LsdException Locked="false" Priority="60" Name="Light Shading Accent 4"/>
<w:LsdException Locked="false" Priority="61" Name="Light List Accent 4"/>
<w:LsdException Locked="false" Priority="62" Name="Light Grid Accent 4"/>
<w:LsdException Locked="false" Priority="63" Name="Medium Shading 1 Accent 4"/>
<w:LsdException Locked="false" Priority="64" Name="Medium Shading 2 Accent 4"/>
<w:LsdException Locked="false" Priority="65" Name="Medium List 1 Accent 4"/>
<w:LsdException Locked="false" Priority="66" Name="Medium List 2 Accent 4"/>
<w:LsdException Locked="false" Priority="67" Name="Medium Grid 1 Accent 4"/>
<w:LsdException Locked="false" Priority="68" Name="Medium Grid 2 Accent 4"/>
<w:LsdException Locked="false" Priority="69" Name="Medium Grid 3 Accent 4"/>
<w:LsdException Locked="false" Priority="70" Name="Dark List Accent 4"/>
<w:LsdException Locked="false" Priority="71" Name="Colorful Shading Accent 4"/>
<w:LsdException Locked="false" Priority="72" Name="Colorful List Accent 4"/>
<w:LsdException Locked="false" Priority="73" Name="Colorful Grid Accent 4"/>
<w:LsdException Locked="false" Priority="60" Name="Light Shading Accent 5"/>
<w:LsdException Locked="false" Priority="61" Name="Light List Accent 5"/>
<w:LsdException Locked="false" Priority="62" Name="Light Grid Accent 5"/>
<w:LsdException Locked="false" Priority="63" Name="Medium Shading 1 Accent 5"/>
<w:LsdException Locked="false" Priority="64" Name="Medium Shading 2 Accent 5"/>
<w:LsdException Locked="false" Priority="65" Name="Medium List 1 Accent 5"/>
<w:LsdException Locked="false" Priority="66" Name="Medium List 2 Accent 5"/>
<w:LsdException Locked="false" Priority="67" Name="Medium Grid 1 Accent 5"/>
<w:LsdException Locked="false" Priority="68" Name="Medium Grid 2 Accent 5"/>
<w:LsdException Locked="false" Priority="69" Name="Medium Grid 3 Accent 5"/>
<w:LsdException Locked="false" Priority="70" Name="Dark List Accent 5"/>
<w:LsdException Locked="false" Priority="71" Name="Colorful Shading Accent 5"/>
<w:LsdException Locked="false" Priority="72" Name="Colorful List Accent 5"/>
<w:LsdException Locked="false" Priority="73" Name="Colorful Grid Accent 5"/>
<w:LsdException Locked="false" Priority="60" Name="Light Shading Accent 6"/>
<w:LsdException Locked="false" Priority="61" Name="Light List Accent 6"/>
<w:LsdException Locked="false" Priority="62" Name="Light Grid Accent 6"/>
<w:LsdException Locked="false" Priority="63" Name="Medium Shading 1 Accent 6"/>
<w:LsdException Locked="false" Priority="64" Name="Medium Shading 2 Accent 6"/>
<w:LsdException Locked="false" Priority="65" Name="Medium List 1 Accent 6"/>
<w:LsdException Locked="false" Priority="66" Name="Medium List 2 Accent 6"/>
<w:LsdException Locked="false" Priority="67" Name="Medium Grid 1 Accent 6"/>
<w:LsdException Locked="false" Priority="68" Name="Medium Grid 2 Accent 6"/>
<w:LsdException Locked="false" Priority="69" Name="Medium Grid 3 Accent 6"/>
<w:LsdException Locked="false" Priority="70" Name="Dark List Accent 6"/>
<w:LsdException Locked="false" Priority="71" Name="Colorful Shading Accent 6"/>
<w:LsdException Locked="false" Priority="72" Name="Colorful List Accent 6"/>
<w:LsdException Locked="false" Priority="73" Name="Colorful Grid Accent 6"/>
<w:LsdException Locked="false" Priority="19" QFormat="true"
Name="Subtle Emphasis"/>
<w:LsdException Locked="false" Priority="21" QFormat="true"
Name="Intense Emphasis"/>
<w:LsdException Locked="false" Priority="31" QFormat="true"
Name="Subtle Reference"/>
<w:LsdException Locked="false" Priority="32" QFormat="true"
Name="Intense Reference"/>
<w:LsdException Locked="false" Priority="33" QFormat="true" Name="Book Title"/>
<w:LsdException Locked="false" Priority="37" SemiHidden="true"
UnhideWhenUsed="true" Name="Bibliography"/>
<w:LsdException Locked="false" Priority="39" SemiHidden="true"
UnhideWhenUsed="true" QFormat="true" Name="TOC Heading"/>
</w:LatentStyles>
</xml><![endif]-->
<style>
<!--
/* Font Definitions */
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;
mso-font-charset:1;
mso-generic-font-family:roman;
mso-font-format:other;
mso-font-pitch:variable;
mso-font-signature:0 0 0 0 0 0;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;
mso-font-charset:0;
mso-generic-font-family:swiss;
mso-font-pitch:variable;
mso-font-signature:-1610611985 1073750139 0 0 159 0;}
@font-face
{font-family:Tahoma;
panose-1:2 11 6 4 3 5 4 4 2 4;
mso-font-charset:0;
mso-generic-font-family:swiss;
mso-font-pitch:variable;
mso-font-signature:1627400839 -2147483648 8 0 66047 0;}
@font-face
{font-family:Verdana;
panose-1:2 11 6 4 3 5 4 4 2 4;
mso-font-charset:0;
mso-generic-font-family:swiss;
mso-font-pitch:variable;
mso-font-signature:536871559 0 0 0 415 0;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{mso-style-unhide:no;
mso-style-qformat:yes;
mso-style-parent:"";
margin:0in;
margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:12.0pt;
font-family:"Times New Roman","serif";
mso-fareast-font-family:"Times New Roman";}
h1
{mso-style-unhide:no;
mso-style-qformat:yes;
mso-style-link:"Heading 1 Char";
mso-margin-top-alt:auto;
margin-right:0in;
mso-margin-bottom-alt:auto;
margin-left:0in;
mso-pagination:widow-orphan;
mso-outline-level:1;
font-size:24.0pt;
font-family:"Times New Roman","serif";
mso-fareast-font-family:"Times New Roman";
mso-fareast-theme-font:minor-fareast;
font-weight:bold;}
h2
{mso-style-unhide:no;
mso-style-qformat:yes;
mso-style-link:"Heading 2 Char";
mso-style-next:Normal;
margin-top:12.0pt;
margin-right:0in;
margin-bottom:3.0pt;
margin-left:0in;
mso-pagination:widow-orphan;
page-break-after:avoid;
mso-outline-level:2;
font-size:14.0pt;
font-family:"Arial","sans-serif";
mso-fareast-font-family:"Times New Roman";
mso-fareast-theme-font:minor-fareast;
font-weight:bold;
font-style:italic;}
h3
{mso-style-unhide:no;
mso-style-qformat:yes;
mso-style-link:"Heading 3 Char";
mso-margin-top-alt:auto;
margin-right:0in;
mso-margin-bottom-alt:auto;
margin-left:0in;
mso-pagination:widow-orphan;
mso-outline-level:3;
font-size:13.5pt;
font-family:"Times New Roman","serif";
mso-fareast-font-family:"Times New Roman";
mso-fareast-theme-font:minor-fareast;
font-weight:bold;}
a:link, span.MsoHyperlink
{mso-style-unhide:no;
color:blue;
text-decoration:underline;
text-underline:single;}
a:visited, span.MsoHyperlinkFollowed
{mso-style-unhide:no;
color:blue;
text-decoration:underline;
text-underline:single;}
p
{mso-style-unhide:no;
mso-margin-top-alt:auto;
margin-right:0in;
mso-margin-bottom-alt:auto;
margin-left:0in;
mso-pagination:widow-orphan;
font-size:12.0pt;
font-family:"Times New Roman","serif";
mso-fareast-font-family:"Times New Roman";}
p.MsoAcetate, li.MsoAcetate, div.MsoAcetate
{mso-style-unhide:no;
mso-style-link:"Balloon Text Char";
margin:0in;
margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:8.0pt;
font-family:"Tahoma","sans-serif";
mso-fareast-font-family:"Times New Roman";}
span.Heading1Char
{mso-style-name:"Heading 1 Char";
mso-style-unhide:no;
mso-style-locked:yes;
mso-style-link:"Heading 1";
mso-ansi-font-size:14.0pt;
mso-bidi-font-size:14.0pt;
font-family:"Cambria","serif";
mso-ascii-font-family:Cambria;
mso-ascii-theme-font:major-latin;
mso-fareast-font-family:"Times New Roman";
mso-fareast-theme-font:major-fareast;
mso-hansi-font-family:Cambria;
mso-hansi-theme-font:major-latin;
mso-bidi-font-family:"Times New Roman";
mso-bidi-theme-font:major-bidi;
color:#365F91;
mso-themecolor:accent1;
mso-themeshade:191;
font-weight:bold;}
span.Heading2Char
{mso-style-name:"Heading 2 Char";
mso-style-unhide:no;
mso-style-locked:yes;
mso-style-link:"Heading 2";
mso-ansi-font-size:13.0pt;
mso-bidi-font-size:13.0pt;
font-family:"Cambria","serif";
mso-ascii-font-family:Cambria;
mso-ascii-theme-font:major-latin;
mso-fareast-font-family:"Times New Roman";
mso-fareast-theme-font:major-fareast;
mso-hansi-font-family:Cambria;
mso-hansi-theme-font:major-latin;
mso-bidi-font-family:"Times New Roman";
mso-bidi-theme-font:major-bidi;
color:#4F81BD;
mso-themecolor:accent1;
font-weight:bold;}
span.Heading3Char
{mso-style-name:"Heading 3 Char";
mso-style-unhide:no;
mso-style-locked:yes;
mso-style-link:"Heading 3";
mso-ansi-font-size:12.0pt;
mso-bidi-font-size:12.0pt;
font-family:"Cambria","serif";
mso-ascii-font-family:Cambria;
mso-ascii-theme-font:major-latin;
mso-fareast-font-family:"Times New Roman";
mso-fareast-theme-font:major-fareast;
mso-hansi-font-family:Cambria;
mso-hansi-theme-font:major-latin;
mso-bidi-font-family:"Times New Roman";
mso-bidi-theme-font:major-bidi;
color:#4F81BD;
mso-themecolor:accent1;
font-weight:bold;}
span.BalloonTextChar
{mso-style-name:"Balloon Text Char";
mso-style-unhide:no;
mso-style-locked:yes;
mso-style-link:"Balloon Text";
mso-ansi-font-size:8.0pt;
mso-bidi-font-size:8.0pt;
font-family:"Tahoma","sans-serif";
mso-ascii-font-family:Tahoma;
mso-hansi-font-family:Tahoma;
mso-bidi-font-family:Tahoma;}
.MsoChpDefault
{mso-style-type:export-only;
mso-default-props:yes;
font-size:10.0pt;
mso-ansi-font-size:10.0pt;
mso-bidi-font-size:10.0pt;}
@page WordSection1
{size:8.5in 11.0in;
margin:1.0in 1.25in 1.0in 1.25in;
mso-header-margin:.5in;
mso-footer-margin:.5in;
mso-paper-source:0;}
div.WordSection1
{page:WordSection1;}
/* List Definitions */
@list l0
{mso-list-id:62067358;
mso-list-template-ids:-174943062;}
@list l0:level1
{mso-level-number-format:bullet;
mso-level-text:\F0B7;
mso-level-tab-stop:.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l0:level2
{mso-level-tab-stop:1.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l0:level3
{mso-level-tab-stop:1.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l0:level4
{mso-level-tab-stop:2.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l0:level5
{mso-level-tab-stop:2.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l0:level6
{mso-level-tab-stop:3.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l0:level7
{mso-level-tab-stop:3.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l0:level8
{mso-level-tab-stop:4.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l0:level9
{mso-level-tab-stop:4.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l1
{mso-list-id:128015942;
mso-list-template-ids:-90681214;}
@list l1:level1
{mso-level-tab-stop:.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l1:level2
{mso-level-tab-stop:1.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l1:level3
{mso-level-tab-stop:1.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l1:level4
{mso-level-tab-stop:2.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l1:level5
{mso-level-tab-stop:2.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l1:level6
{mso-level-tab-stop:3.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l1:level7
{mso-level-tab-stop:3.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l1:level8
{mso-level-tab-stop:4.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l1:level9
{mso-level-tab-stop:4.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l2
{mso-list-id:216556000;
mso-list-template-ids:925924412;}
@list l2:level1
{mso-level-number-format:bullet;
mso-level-text:\F0B7;
mso-level-tab-stop:.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l2:level2
{mso-level-number-format:bullet;
mso-level-text:\F0B7;
mso-level-tab-stop:1.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l2:level3
{mso-level-tab-stop:1.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l2:level4
{mso-level-tab-stop:2.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l2:level5
{mso-level-tab-stop:2.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l2:level6
{mso-level-tab-stop:3.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l2:level7
{mso-level-tab-stop:3.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l2:level8
{mso-level-tab-stop:4.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l2:level9
{mso-level-tab-stop:4.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l3
{mso-list-id:562446694;
mso-list-template-ids:913898366;}
@list l3:level1
{mso-level-number-format:bullet;
mso-level-text:\F0B7;
mso-level-tab-stop:.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l3:level2
{mso-level-tab-stop:1.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l3:level3
{mso-level-tab-stop:1.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l3:level4
{mso-level-tab-stop:2.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l3:level5
{mso-level-tab-stop:2.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l3:level6
{mso-level-tab-stop:3.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l3:level7
{mso-level-tab-stop:3.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l3:level8
{mso-level-tab-stop:4.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l3:level9
{mso-level-tab-stop:4.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l4
{mso-list-id:797802132;
mso-list-template-ids:-1971191336;}
@list l4:level1
{mso-level-tab-stop:.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l4:level2
{mso-level-tab-stop:1.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l4:level3
{mso-level-tab-stop:1.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l4:level4
{mso-level-tab-stop:2.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l4:level5
{mso-level-tab-stop:2.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l4:level6
{mso-level-tab-stop:3.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l4:level7
{mso-level-tab-stop:3.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l4:level8
{mso-level-tab-stop:4.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l4:level9
{mso-level-tab-stop:4.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l5
{mso-list-id:907304066;
mso-list-template-ids:1969781532;}
@list l5:level1
{mso-level-tab-stop:.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l5:level2
{mso-level-tab-stop:1.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l5:level3
{mso-level-tab-stop:1.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l5:level4
{mso-level-tab-stop:2.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l5:level5
{mso-level-tab-stop:2.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l5:level6
{mso-level-tab-stop:3.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l5:level7
{mso-level-tab-stop:3.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l5:level8
{mso-level-tab-stop:4.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l5:level9
{mso-level-tab-stop:4.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l6
{mso-list-id:1050613616;
mso-list-template-ids:-1009886748;}
@list l6:level1
{mso-level-number-format:bullet;
mso-level-text:\F0B7;
mso-level-tab-stop:.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l6:level2
{mso-level-number-format:bullet;
mso-level-text:\F0B7;
mso-level-tab-stop:1.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l6:level3
{mso-level-tab-stop:1.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l6:level4
{mso-level-tab-stop:2.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l6:level5
{mso-level-tab-stop:2.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l6:level6
{mso-level-tab-stop:3.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l6:level7
{mso-level-tab-stop:3.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l6:level8
{mso-level-tab-stop:4.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l6:level9
{mso-level-tab-stop:4.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l7
{mso-list-id:1234970193;
mso-list-template-ids:2055904002;}
@list l7:level1
{mso-level-number-format:bullet;
mso-level-text:\F0B7;
mso-level-tab-stop:.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l7:level2
{mso-level-number-format:bullet;
mso-level-text:\F0B7;
mso-level-tab-stop:1.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l7:level3
{mso-level-tab-stop:1.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l7:level4
{mso-level-tab-stop:2.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l7:level5
{mso-level-tab-stop:2.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l7:level6
{mso-level-tab-stop:3.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l7:level7
{mso-level-tab-stop:3.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l7:level8
{mso-level-tab-stop:4.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l7:level9
{mso-level-tab-stop:4.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l8
{mso-list-id:1846092290;
mso-list-template-ids:-768590846;}
@list l8:level1
{mso-level-start-at:2;
mso-level-tab-stop:.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l8:level2
{mso-level-tab-stop:1.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l8:level3
{mso-level-tab-stop:1.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l8:level4
{mso-level-tab-stop:2.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l8:level5
{mso-level-tab-stop:2.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l8:level6
{mso-level-tab-stop:3.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l8:level7
{mso-level-tab-stop:3.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l8:level8
{mso-level-tab-stop:4.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l8:level9
{mso-level-tab-stop:4.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l9
{mso-list-id:1894656566;
mso-list-template-ids:1199983812;}
@list l9:level1
{mso-level-start-at:2;
mso-level-tab-stop:.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l9:level2
{mso-level-tab-stop:1.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l9:level3
{mso-level-tab-stop:1.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l9:level4
{mso-level-tab-stop:2.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l9:level5
{mso-level-tab-stop:2.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l9:level6
{mso-level-tab-stop:3.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l9:level7
{mso-level-tab-stop:3.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l9:level8
{mso-level-tab-stop:4.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l9:level9
{mso-level-tab-stop:4.5in;
mso-level-number-position:left;
text-indent:-.25in;}
ol
{margin-bottom:0in;}
ul
{margin-bottom:0in;}
-->
</style><!--[if gte mso 10]>
<style>
/* Style Definitions */
table.MsoNormalTable
{mso-style-name:"Table Normal";
mso-tstyle-rowband-size:0;
mso-tstyle-colband-size:0;
mso-style-noshow:yes;
mso-style-priority:99;
mso-style-qformat:yes;
mso-style-parent:"";
mso-padding-alt:0in 5.4pt 0in 5.4pt;
mso-para-margin:0in;
mso-para-margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:10.0pt;
font-family:"Times New Roman","serif";}
</style>
<![endif]--><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="7170"/>
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1"/>
</o:shapelayout></xml><![endif]--><meta content="MCD Application Team" name="author"></head>
<body style="" link="blue" vlink="blue">
<div class="WordSection1">
<p class="MsoNormal"><span style="font-family: &quot;Arial&quot;,&quot;sans-serif&quot;;"><o:p>&nbsp;</o:p></span></p>
<div align="center">
<table class="MsoNormalTable" style="width: 675pt;" border="0" cellpadding="0" cellspacing="0" width="900">
<tbody><tr style="">
<td style="padding: 0in;" valign="top">
<table class="MsoNormalTable" style="width: 675pt;" border="0" cellpadding="0" cellspacing="0" width="900">
<tbody><tr style="">
<td style="padding: 0in 5.4pt;" valign="top">
<p class="MsoNormal"><span style="font-size: 8pt; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; color: blue;"><a href="../../Release_Notes.html">Back to Release page</a></span><span style="font-size: 10pt;"><o:p></o:p></span></p>
</td>
</tr>
<tr style="">
<td style="padding: 1.5pt;">
<h1 style="margin-bottom: 0.25in; text-align: center;" align="center"><span style="font-size: 20pt; font-family: &quot;Verdana&quot;,&quot;sans-serif&quot;; color: rgb(51, 102, 255);">Release Notes for STM32F105/7xx, STM32F2xx and STM32F4xx&nbsp;USB Device Library</span><span style="font-size: 20pt; font-family: &quot;Verdana&quot;,&quot;sans-serif&quot;;"><o:p></o:p></span></h1>
<p class="MsoNormal" style="text-align: center;" align="center"><span style="font-size: 10pt; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; color: black;">Copyright
2012 STMicroelectronics</span><span style="color: black;"><u1:p></u1:p><o:p></o:p></span></p>
<p class="MsoNormal" style="text-align: center;" align="center"><span style="font-size: 10pt; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; color: black;"><img style="border: 0px solid ; width: 86px; height: 65px;" alt="" id="_x0000_i1026" src="../../_htmresc/logo.bmp"></span><span style="font-size: 10pt;"><o:p></o:p></span></p>
</td>
</tr>
</tbody></table>
<p class="MsoNormal"><span style="font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; display: none;"><o:p>&nbsp;</o:p></span></p>
<table class="MsoNormalTable" style="width: 675pt;" border="0" cellpadding="0" width="900">
<tbody><tr style="">
<td style="padding: 0in;" valign="top">
<h2 style="background: rgb(51, 102, 255) none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"><span style="font-size: 12pt; color: white;">Contents<o:p></o:p></span></h2>
<ol style="margin-top: 0in;" start="1" type="1">
<li class="MsoNormal" style="color: black; margin-top: 4.5pt; margin-bottom: 4.5pt;"><span style="font-size: 10pt; font-family: &quot;Verdana&quot;,&quot;sans-serif&quot;;"><a href="#History">Update History</a><o:p></o:p></span></li>
<li class="MsoNormal" style="color: black; margin-top: 4.5pt; margin-bottom: 4.5pt;"><span style="font-size: 10pt; font-family: &quot;Verdana&quot;,&quot;sans-serif&quot;;"><a href="#License">License</a><o:p></o:p></span></li>
</ol>
<h2 style="background: rgb(51, 102, 255) none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"><a name="History"></a><span style="font-size: 12pt; color: white;">Update History</span></h2><h3 style="background: rgb(51, 102, 255) none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; margin-right: 500pt; width: 200px;"><span style="font-size: 10pt; font-family: Arial; color: white;">V1.1.0 / 19-March-2012<o:p></o:p></span></h3>
<p class="MsoNormal" style="margin: 4.5pt 0cm 4.5pt 18pt;"><b style=""><u><span style="font-size: 10pt; font-family: Verdana; color: black;">Main
Changes<o:p></o:p></span></u></b></p>
<ul style="margin-top: 0cm;" type="square"><li class="MsoNormal" style="color: black; margin-top: 4.5pt; margin-bottom: 4.5pt;"><span style="font-size: 10pt; font-family: Verdana;">Official support of </span><span style="font-size: 10pt; font-family: Verdana;"><span style="font-weight: bold; font-style: italic;">STM32F4xx</span> devices</span></li><li class="MsoNormal" style="color: black; margin-top: 4.5pt; margin-bottom: 4.5pt;"><span style="font-size: 10pt; font-family: Verdana;">All source files: license disclaimer text update and add link to the License file on ST Internet.<br></span></li><li class="MsoNormal" style="color: black; margin-top: 4.5pt; margin-bottom: 4.5pt;"><span style="font-size: 10pt; font-family: Verdana;">Handle test mode in the set feature request</span></li><li class="MsoNormal" style="color: black; margin-top: 4.5pt; margin-bottom: 4.5pt;"><span style="font-size: 10pt; font-family: Verdana;">Handle dynamically the USB SELF POWERED feature</span></li><li class="MsoNormal" style="color: black; margin-top: 4.5pt; margin-bottom: 4.5pt;"><span style="font-size: 10pt; font-family: Verdana;">Handle correctly the USBD_CtlError process to take into account error during Control OUT stage</span></li><li class="MsoNormal" style="color: black; margin-top: 4.5pt; margin-bottom: 4.5pt;"><span style="font-size: 10pt; font-family: Verdana;">Miscellaneous bug fix</span></li></ul><h3 style="background: rgb(51, 102, 255) none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; margin-right: 500pt; width: 171px;"><span style="font-size: 10pt; font-family: Arial; color: white;">V1.0.0 / 22-July-2011<o:p></o:p></span></h3><p class="MsoNormal" style="margin: 4.5pt 0cm 4.5pt 18pt;"><b style=""><u><span style="font-size: 10pt; font-family: Verdana; color: black;">Main
Changes<o:p></o:p></span></u></b></p>
<ul style="margin-top: 0cm;" type="square"><li class="MsoNormal" style="color: black; margin-top: 4.5pt; margin-bottom: 4.5pt;"><span style="font-size: 10pt; font-family: Verdana;">First official version for <span style="font-weight: bold; font-style: italic;">STM32F105/7xx</span> and <span style="font-weight: bold; font-style: italic;">STM32F2xx</span> devices</span></li></ul><span style="font-size: 10pt; font-family: Verdana;"></span><br><span style="font-size: 10pt; font-family: &quot;Verdana&quot;,&quot;sans-serif&quot;;"></span>
<h2 style="background: rgb(51, 102, 255) none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"><a name="License"></a><span style="font-size: 12pt; color: white;">License<o:p></o:p></span></h2>
<p class="MsoNormal"><span style="font-size: 10pt; font-family: &quot;Verdana&quot;,&quot;sans-serif&quot;; color: black;">Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); You may not use this&nbsp;</span><span style="font-size: 10pt; font-family: &quot;Verdana&quot;,&quot;sans-serif&quot;; color: black;">package</span><span style="font-size: 10pt; font-family: &quot;Verdana&quot;,&quot;sans-serif&quot;; color: black;"> except in compliance with the License. You may obtain a copy of the License at:<br><br></span></p><div style="text-align: center;"><span style="font-size: 10pt; font-family: &quot;Verdana&quot;,&quot;sans-serif&quot;; color: black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a target="_blank" href="http://www.st.com/software_license_agreement_liberty_v2">http://www.st.com/software_license_agreement_liberty_v2</a></span><br><span style="font-size: 10pt; font-family: &quot;Verdana&quot;,&quot;sans-serif&quot;; color: black;"></span></div><span style="font-size: 10pt; font-family: &quot;Verdana&quot;,&quot;sans-serif&quot;; color: black;"><br>Unless
required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, <br>WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See
the License for the specific language governing permissions and
limitations under the License.</span>
<div class="MsoNormal" style="text-align: center;" align="center"><span style="color: black;">
<hr align="center" size="2" width="100%">
</span></div>
<p class="MsoNormal" style="margin: 4.5pt 0in 4.5pt 0.25in; text-align: center;" align="center"><span style="font-size: 10pt; font-family: &quot;Verdana&quot;,&quot;sans-serif&quot;; color: black;">For
complete documentation on </span><span style="font-size: 10pt; font-family: &quot;Verdana&quot;,&quot;sans-serif&quot;;">STM32<span style="color: black;">
Microcontrollers visit </span><u><span style="color: blue;"><a href="http://www.st.com/internet/mcu/family/141.jsp" target="_blank">www.st.com/STM32</a></span></u></span><span style="font-size: 10pt; font-family: &quot;Verdana&quot;,&quot;sans-serif&quot;;"><u><span style="color: blue;"><a href="http://www.st.com/stm32" target="_blank"></a></span></u></span><span style="color: black;"><o:p></o:p></span></p>
</td>
</tr>
</tbody></table>
<p class="MsoNormal"><span style="font-size: 10pt;"><o:p></o:p></span></p>
</td>
</tr>
</tbody></table>
</div>
<p class="MsoNormal"><o:p>&nbsp;</o:p></p>
</div>
</body></html>

View File

@ -0,0 +1,203 @@
/**
******************************************************************************
* @file usbh_hid_core.h
* @author MCD Application Team
* @version V2.1.0
* @date 19-March-2012
* @brief This file contains all the prototypes for the usbh_hid_core.c
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Define to prevent recursive ----------------------------------------------*/
#ifndef __USBH_HID_CORE_H
#define __USBH_HID_CORE_H
/* Includes ------------------------------------------------------------------*/
#include "usbh_core.h"
#include "usbh_stdreq.h"
#include "usb_bsp.h"
#include "usbh_ioreq.h"
#include "usbh_hcs.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_CORE.c
* @{
*/
/** @defgroup USBH_HID_CORE_Exported_Types
* @{
*/
#define HID_MIN_POLL 10
/* States for HID State Machine */
typedef enum
{
HID_IDLE= 0,
HID_SEND_DATA,
HID_BUSY,
HID_GET_DATA,
HID_SYNC,
HID_POLL,
HID_ERROR,
}
HID_State;
typedef enum
{
HID_REQ_IDLE = 0,
HID_REQ_GET_REPORT_DESC,
HID_REQ_GET_HID_DESC,
HID_REQ_SET_IDLE,
HID_REQ_SET_PROTOCOL,
HID_REQ_SET_REPORT,
}
HID_CtlState;
typedef struct HID_cb
{
void (*Init) (void);
void (*Decode) (uint8_t *data);
} HID_cb_TypeDef;
typedef struct _HID_Report
{
uint8_t ReportID;
uint8_t ReportType;
uint16_t UsagePage;
uint32_t Usage[2];
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_Report_TypeDef;
/* Structure for HID process */
typedef struct _HID_Process
{
uint8_t buff[64];
uint8_t hc_num_in;
uint8_t hc_num_out;
HID_State state;
uint8_t HIDIntOutEp;
uint8_t HIDIntInEp;
HID_CtlState ctl_state;
uint16_t length;
uint8_t ep_addr;
uint16_t poll;
__IO uint16_t timer;
HID_cb_TypeDef *cb;
}
HID_Machine_TypeDef;
/**
* @}
*/
/** @defgroup USBH_HID_CORE_Exported_Defines
* @{
*/
#define USB_HID_REQ_GET_REPORT 0x01
#define USB_HID_GET_IDLE 0x02
#define USB_HID_GET_PROTOCOL 0x03
#define USB_HID_SET_REPORT 0x09
#define USB_HID_SET_IDLE 0x0A
#define USB_HID_SET_PROTOCOL 0x0B
/**
* @}
*/
/** @defgroup USBH_HID_CORE_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBH_HID_CORE_Exported_Variables
* @{
*/
extern USBH_Class_cb_TypeDef HID_cb;
/**
* @}
*/
/** @defgroup USBH_HID_CORE_Exported_FunctionsPrototype
* @{
*/
USBH_Status USBH_Set_Report (USB_OTG_CORE_HANDLE *pdev,
USBH_HOST *phost,
uint8_t reportType,
uint8_t reportId,
uint8_t reportLen,
uint8_t* reportBuff);
/**
* @}
*/
#endif /* __USBH_HID_CORE_H */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,128 @@
/**
******************************************************************************
* @file usbh_hid_keybd.h
* @author MCD Application Team
* @version V2.1.0
* @date 19-March-2012
* @brief This file contains all the prototypes for the usbh_hid_keybd.c
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Define to prevent recursive -----------------------------------------------*/
#ifndef __USBH_HID_KEYBD_H
#define __USBH_HID_KEYBD_H
/* Includes ------------------------------------------------------------------*/
#include "usb_conf.h"
#include "usbh_hid_core.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
* @{
*/
/**
* @}
*/
/** @defgroup USBH_HID_KEYBD_Exported_Defines
* @{
*/
//#define QWERTY_KEYBOARD
#define AZERTY_KEYBOARD
#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_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBH_HID_KEYBD_Exported_Variables
* @{
*/
extern HID_cb_TypeDef HID_KEYBRD_cb;
/**
* @}
*/
/** @defgroup USBH_HID_KEYBD_Exported_FunctionsPrototype
* @{
*/
void USR_KEYBRD_Init (void);
void USR_KEYBRD_ProcessData (uint8_t pbuf);
/**
* @}
*/
#endif /* __USBH_HID_KEYBD_H */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,120 @@
/**
******************************************************************************
* @file usbh_hid_mouse.h
* @author MCD Application Team
* @version V2.1.0
* @date 19-March-2012
* @brief This file contains all the prototypes for the usbh_hid_mouse.c
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Define to prevent recursive ----------------------------------------------*/
#ifndef __USBH_HID_MOUSE_H
#define __USBH_HID_MOUSE_H
/* Includes ------------------------------------------------------------------*/
#include "usbh_hid_core.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_Data
{
uint8_t x;
uint8_t y;
uint8_t z; /* Not Supported */
uint8_t button;
}
HID_MOUSE_Data_TypeDef;
/**
* @}
*/
/** @defgroup USBH_HID_MOUSE_Exported_Defines
* @{
*/
/**
* @}
*/
/** @defgroup USBH_HID_MOUSE_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBH_HID_MOUSE_Exported_Variables
* @{
*/
extern HID_cb_TypeDef HID_MOUSE_cb;
extern HID_MOUSE_Data_TypeDef HID_MOUSE_Data;
/**
* @}
*/
/** @defgroup USBH_HID_MOUSE_Exported_FunctionsPrototype
* @{
*/
void USR_MOUSE_Init (void);
void USR_MOUSE_ProcessData (HID_MOUSE_Data_TypeDef *data);
/**
* @}
*/
#endif /* __USBH_HID_MOUSE_H */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,657 @@
/**
******************************************************************************
* @file usbh_hid_core.c
* @author MCD Application Team
* @version V2.1.0
* @date 19-March-2012
* @brief This file is the HID Layer Handlers for USB Host HID class.
*
* @verbatim
*
* ===================================================================
* HID Class Description
* ===================================================================
* This module manages the MSC 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
*
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "usbh_hid_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 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
* @{
*/
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
__ALIGN_BEGIN HID_Machine_TypeDef HID_Machine __ALIGN_END ;
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
__ALIGN_BEGIN HID_Report_TypeDef HID_Report __ALIGN_END ;
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
__ALIGN_BEGIN USB_Setup_TypeDef HID_Setup __ALIGN_END ;
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
__ALIGN_BEGIN USBH_HIDDesc_TypeDef HID_Desc __ALIGN_END ;
__IO uint8_t start_toggle = 0;
/**
* @}
*/
/** @defgroup USBH_HID_CORE_Private_FunctionPrototypes
* @{
*/
static USBH_Status USBH_HID_InterfaceInit (USB_OTG_CORE_HANDLE *pdev ,
void *phost);
static void USBH_ParseHIDDesc (USBH_HIDDesc_TypeDef *desc, uint8_t *buf);
static void USBH_HID_InterfaceDeInit (USB_OTG_CORE_HANDLE *pdev ,
void *phost);
static USBH_Status USBH_HID_Handle(USB_OTG_CORE_HANDLE *pdev ,
void *phost);
static USBH_Status USBH_HID_ClassRequest(USB_OTG_CORE_HANDLE *pdev ,
void *phost);
static USBH_Status USBH_Get_HID_ReportDescriptor (USB_OTG_CORE_HANDLE *pdev,
USBH_HOST *phost,
uint16_t length);
static USBH_Status USBH_Get_HID_Descriptor (USB_OTG_CORE_HANDLE *pdev,\
USBH_HOST *phost,
uint16_t length);
static USBH_Status USBH_Set_Idle (USB_OTG_CORE_HANDLE *pdev,
USBH_HOST *phost,
uint8_t duration,
uint8_t reportId);
static USBH_Status USBH_Set_Protocol (USB_OTG_CORE_HANDLE *pdev,
USBH_HOST *phost,
uint8_t protocol);
USBH_Class_cb_TypeDef HID_cb =
{
USBH_HID_InterfaceInit,
USBH_HID_InterfaceDeInit,
USBH_HID_ClassRequest,
USBH_HID_Handle
};
/**
* @}
*/
/** @defgroup USBH_HID_CORE_Private_Functions
* @{
*/
/**
* @brief USBH_HID_InterfaceInit
* The function init the HID class.
* @param pdev: Selected device
* @param hdev: Selected device property
* @retval USBH_Status :Response for USB HID driver intialization
*/
static USBH_Status USBH_HID_InterfaceInit ( USB_OTG_CORE_HANDLE *pdev,
void *phost)
{
uint8_t maxEP;
USBH_HOST *pphost = phost;
uint8_t num =0;
USBH_Status status = USBH_BUSY ;
HID_Machine.state = HID_ERROR;
if(pphost->device_prop.Itf_Desc[0].bInterfaceSubClass == HID_BOOT_CODE)
{
/*Decode Bootclass Protocl: Mouse or Keyboard*/
if(pphost->device_prop.Itf_Desc[0].bInterfaceProtocol == HID_KEYBRD_BOOT_CODE)
{
HID_Machine.cb = &HID_KEYBRD_cb;
}
else if(pphost->device_prop.Itf_Desc[0].bInterfaceProtocol == HID_MOUSE_BOOT_CODE)
{
HID_Machine.cb = &HID_MOUSE_cb;
}
HID_Machine.state = HID_IDLE;
HID_Machine.ctl_state = HID_REQ_IDLE;
HID_Machine.ep_addr = pphost->device_prop.Ep_Desc[0][0].bEndpointAddress;
HID_Machine.length = pphost->device_prop.Ep_Desc[0][0].wMaxPacketSize;
HID_Machine.poll = pphost->device_prop.Ep_Desc[0][0].bInterval ;
if (HID_Machine.poll < HID_MIN_POLL)
{
HID_Machine.poll = HID_MIN_POLL;
}
/* Check fo 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 */
maxEP = ( (pphost->device_prop.Itf_Desc[0].bNumEndpoints <= USBH_MAX_NUM_ENDPOINTS) ?
pphost->device_prop.Itf_Desc[0].bNumEndpoints :
USBH_MAX_NUM_ENDPOINTS);
/* Decode endpoint IN and OUT address from interface descriptor */
for (num=0; num < maxEP; num++)
{
if(pphost->device_prop.Ep_Desc[0][num].bEndpointAddress & 0x80)
{
HID_Machine.HIDIntInEp = (pphost->device_prop.Ep_Desc[0][num].bEndpointAddress);
HID_Machine.hc_num_in =\
USBH_Alloc_Channel(pdev,
pphost->device_prop.Ep_Desc[0][num].bEndpointAddress);
/* Open channel for IN endpoint */
USBH_Open_Channel (pdev,
HID_Machine.hc_num_in,
pphost->device_prop.address,
pphost->device_prop.speed,
EP_TYPE_INTR,
HID_Machine.length);
}
else
{
HID_Machine.HIDIntOutEp = (pphost->device_prop.Ep_Desc[0][num].bEndpointAddress);
HID_Machine.hc_num_out =\
USBH_Alloc_Channel(pdev,
pphost->device_prop.Ep_Desc[0][num].bEndpointAddress);
/* Open channel for OUT endpoint */
USBH_Open_Channel (pdev,
HID_Machine.hc_num_out,
pphost->device_prop.address,
pphost->device_prop.speed,
EP_TYPE_INTR,
HID_Machine.length);
}
}
start_toggle =0;
status = USBH_OK;
}
else
{
pphost->usr_cb->DeviceNotSupported();
}
return status;
}
/**
* @brief USBH_HID_InterfaceDeInit
* The function DeInit the Host Channels used for the HID class.
* @param pdev: Selected device
* @param hdev: Selected device property
* @retval None
*/
void USBH_HID_InterfaceDeInit ( USB_OTG_CORE_HANDLE *pdev,
void *phost)
{
//USBH_HOST *pphost = phost;
if(HID_Machine.hc_num_in != 0x00)
{
USB_OTG_HC_Halt(pdev, HID_Machine.hc_num_in);
USBH_Free_Channel (pdev, HID_Machine.hc_num_in);
HID_Machine.hc_num_in = 0; /* Reset the Channel as Free */
}
if(HID_Machine.hc_num_out != 0x00)
{
USB_OTG_HC_Halt(pdev, HID_Machine.hc_num_out);
USBH_Free_Channel (pdev, HID_Machine.hc_num_out);
HID_Machine.hc_num_out = 0; /* Reset the Channel as Free */
}
start_toggle = 0;
}
/**
* @brief USBH_HID_ClassRequest
* The function is responsible for handling HID Class requests
* for HID class.
* @param pdev: Selected device
* @param hdev: Selected device property
* @retval USBH_Status :Response for USB Set Protocol request
*/
static USBH_Status USBH_HID_ClassRequest(USB_OTG_CORE_HANDLE *pdev ,
void *phost)
{
USBH_HOST *pphost = phost;
USBH_Status status = USBH_BUSY;
USBH_Status classReqStatus = USBH_BUSY;
/* Switch HID state machine */
switch (HID_Machine.ctl_state)
{
case HID_IDLE:
case HID_REQ_GET_HID_DESC:
/* Get HID Desc */
if (USBH_Get_HID_Descriptor (pdev, pphost, USB_HID_DESC_SIZE)== USBH_OK)
{
USBH_ParseHIDDesc(&HID_Desc, pdev->host.Rx_Buffer);
HID_Machine.ctl_state = HID_REQ_GET_REPORT_DESC;
}
break;
case HID_REQ_GET_REPORT_DESC:
/* Get Report Desc */
if (USBH_Get_HID_ReportDescriptor(pdev , pphost, HID_Desc.wItemLength) == USBH_OK)
{
HID_Machine.ctl_state = HID_REQ_SET_IDLE;
}
break;
case HID_REQ_SET_IDLE:
classReqStatus = USBH_Set_Idle (pdev, pphost, 0, 0);
/* set Idle */
if (classReqStatus == USBH_OK)
{
HID_Machine.ctl_state = HID_REQ_SET_PROTOCOL;
}
else if(classReqStatus == USBH_NOT_SUPPORTED)
{
HID_Machine.ctl_state = HID_REQ_SET_PROTOCOL;
}
break;
case HID_REQ_SET_PROTOCOL:
/* set protocol */
if (USBH_Set_Protocol (pdev ,pphost, 0) == USBH_OK)
{
HID_Machine.ctl_state = HID_REQ_IDLE;
/* all requests performed*/
status = USBH_OK;
}
break;
default:
break;
}
return status;
}
/**
* @brief USBH_HID_Handle
* The function is for managing state machine for HID data transfers
* @param pdev: Selected device
* @param hdev: Selected device property
* @retval USBH_Status
*/
static USBH_Status USBH_HID_Handle(USB_OTG_CORE_HANDLE *pdev ,
void *phost)
{
USBH_HOST *pphost = phost;
USBH_Status status = USBH_OK;
switch (HID_Machine.state)
{
case HID_IDLE:
HID_Machine.cb->Init();
HID_Machine.state = HID_SYNC;
case HID_SYNC:
/* Sync with start of Even Frame */
if(USB_OTG_IsEvenFrame(pdev) == TRUE)
{
HID_Machine.state = HID_GET_DATA;
}
break;
case HID_GET_DATA:
USBH_InterruptReceiveData(pdev,
HID_Machine.buff,
HID_Machine.length,
HID_Machine.hc_num_in);
start_toggle = 1;
HID_Machine.state = HID_POLL;
HID_Machine.timer = HCD_GetCurrentFrame(pdev);
break;
case HID_POLL:
if(( HCD_GetCurrentFrame(pdev) - HID_Machine.timer) >= HID_Machine.poll)
{
HID_Machine.state = HID_GET_DATA;
}
else if(HCD_GetURB_State(pdev , HID_Machine.hc_num_in) == URB_DONE)
{
if(start_toggle == 1) /* handle data once */
{
start_toggle = 0;
HID_Machine.cb->Decode(HID_Machine.buff);
}
}
else if(HCD_GetURB_State(pdev, HID_Machine.hc_num_in) == URB_STALL) /* IN Endpoint Stalled */
{
/* Issue Clear Feature on interrupt IN endpoint */
if( (USBH_ClrFeature(pdev,
pphost,
HID_Machine.ep_addr,
HID_Machine.hc_num_in)) == USBH_OK)
{
/* Change state to issue next IN token */
HID_Machine.state = HID_GET_DATA;
}
}
break;
default:
break;
}
return status;
}
/**
* @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 pdev : Selected device
* @param Length : HID Report Descriptor Length
* @retval USBH_Status : Response for USB HID Get Report Descriptor Request
*/
static USBH_Status USBH_Get_HID_ReportDescriptor (USB_OTG_CORE_HANDLE *pdev,
USBH_HOST *phost,
uint16_t length)
{
USBH_Status status;
status = USBH_GetDescriptor(pdev,
phost,
USB_REQ_RECIPIENT_INTERFACE
| USB_REQ_TYPE_STANDARD,
USB_DESC_HID_REPORT,
pdev->host.Rx_Buffer,
length);
/* HID report descriptor is available in pdev->host.Rx_Buffer.
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 pdev : Selected device
* @param Length : HID Descriptor Length
* @retval USBH_Status : Response for USB HID Get Report Descriptor Request
*/
static USBH_Status USBH_Get_HID_Descriptor (USB_OTG_CORE_HANDLE *pdev,
USBH_HOST *phost,
uint16_t length)
{
USBH_Status status;
status = USBH_GetDescriptor(pdev,
phost,
USB_REQ_RECIPIENT_INTERFACE
| USB_REQ_TYPE_STANDARD,
USB_DESC_HID,
pdev->host.Rx_Buffer,
length);
return status;
}
/**
* @brief USBH_Set_Idle
* Set Idle State.
* @param pdev: Selected device
* @param duration: Duration for HID Idle request
* @param reportID : Targetted report ID for Set Idle request
* @retval USBH_Status : Response for USB Set Idle request
*/
static USBH_Status USBH_Set_Idle (USB_OTG_CORE_HANDLE *pdev,
USBH_HOST *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 = (duration << 8 ) | reportId;
phost->Control.setup.b.wIndex.w = 0;
phost->Control.setup.b.wLength.w = 0;
return USBH_CtlReq(pdev, phost, 0 , 0 );
}
/**
* @brief USBH_Set_Report
* Issues Set Report
* @param pdev: Selected device
* @param reportType : Report type to be sent
* @param reportID : Targetted report ID for Set Report request
* @param reportLen : Length of data report to be send
* @param reportBuff : Report Buffer
* @retval USBH_Status : Response for USB Set Idle request
*/
USBH_Status USBH_Set_Report (USB_OTG_CORE_HANDLE *pdev,
USBH_HOST *phost,
uint8_t reportType,
uint8_t reportId,
uint8_t reportLen,
uint8_t* reportBuff)
{
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 = (reportType << 8 ) | reportId;
phost->Control.setup.b.wIndex.w = 0;
phost->Control.setup.b.wLength.w = reportLen;
return USBH_CtlReq(pdev, phost, reportBuff , reportLen );
}
/**
* @brief USBH_Set_Protocol
* Set protocol State.
* @param pdev: Selected device
* @param protocol : Set Protocol for HID : boot/report protocol
* @retval USBH_Status : Response for USB Set Protocol request
*/
static USBH_Status USBH_Set_Protocol(USB_OTG_CORE_HANDLE *pdev,
USBH_HOST *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 != 0)
{
/* Boot Protocol */
phost->Control.setup.b.wValue.w = 0;
}
else
{
/*Report Protocol*/
phost->Control.setup.b.wValue.w = 1;
}
phost->Control.setup.b.wIndex.w = 0;
phost->Control.setup.b.wLength.w = 0;
return USBH_CtlReq(pdev, phost, 0 , 0 );
}
/**
* @brief USBH_ParseHIDDesc
* This function Parse the HID descriptor
* @param buf: Buffer where the source descriptor is available
* @retval None
*/
static void USBH_ParseHIDDesc (USBH_HIDDesc_TypeDef *desc, uint8_t *buf)
{
desc->bLength = *(uint8_t *) (buf + 0);
desc->bDescriptorType = *(uint8_t *) (buf + 1);
desc->bcdHID = LE16 (buf + 2);
desc->bCountryCode = *(uint8_t *) (buf + 4);
desc->bNumDescriptors = *(uint8_t *) (buf + 5);
desc->bReportDescriptorType = *(uint8_t *) (buf + 6);
desc->wItemLength = LE16 (buf + 7);
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,344 @@
/**
******************************************************************************
* @file usbh_hid_keybd.c
* @author MCD Application Team
* @version V2.1.0
* @date 19-March-2012
* @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
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "usbh_hid_keybd.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
* @{
*/
/**
* @}
*/
/** @defgroup USBH_HID_KEYBD_Private_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBH_HID_KEYBD_Private_FunctionPrototypes
* @{
*/
static void KEYBRD_Init (void);
static void KEYBRD_Decode(uint8_t *data);
/**
* @}
*/
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
#if defined (__CC_ARM) /*!< ARM Compiler */
__align(4)
#elif defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#elif defined (__GNUC__) /*!< GNU Compiler */
#pragma pack(4)
#elif defined (__TASKING__) /*!< TASKING Compiler */
__align(4)
#endif /* __CC_ARM */
#endif
/** @defgroup USBH_HID_KEYBD_Private_Variables
* @{
*/
HID_cb_TypeDef HID_KEYBRD_cb=
{
KEYBRD_Init,
KEYBRD_Decode
};
/*
*******************************************************************************
* LOCAL CONSTANTS
*******************************************************************************
*/
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 */
};
#ifdef QWERTY_KEYBOARD
static const int8_t HID_KEYBRD_Key[] = {
'\0', '`', '1', '2', '3', '4', '5', '6',
'7', '8', '9', '0', '-', '=', '\0', '\r',
'\t', 'q', 'w', 'e', 'r', 't', 'y', 'u',
'i', 'o', 'p', '[', ']', '\\',
'\0', 'a', 's', 'd', 'f', 'g', 'h', 'j',
'k', 'l', ';', '\'', '\0', '\n',
'\0', '\0', 'z', 'x', 'c', 'v', 'b', 'n',
'm', ',', '.', '/', '\0', '\0',
'\0', '\0', '\0', ' ', '\0', '\0', '\0', '\0',
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
'\0', '\0', '\0', '\0', '\0', '\r', '\0', '\0',
'\0', '\0', '\0', '\0', '\0', '\0',
'\0', '\0', '7', '4', '1',
'\0', '/', '8', '5', '2',
'0', '*', '9', '6', '3',
'.', '-', '+', '\0', '\n', '\0', '\0', '\0', '\0', '\0', '\0',
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
'\0', '\0', '\0', '\0'
};
static const int8_t HID_KEYBRD_ShiftKey[] = {
'\0', '~', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')',
'_', '+', '\0', '\0', '\0', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U',
'I', 'O', 'P', '{', '}', '|', '\0', 'A', 'S', 'D', 'F', 'G',
'H', 'J', 'K', 'L', ':', '"', '\0', '\n', '\0', '\0', 'Z', 'X',
'C', 'V', 'B', 'N', 'M', '<', '>', '?', '\0', '\0', '\0', '\0',
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0'
};
#else
static const int8_t HID_KEYBRD_Key[] = {
'\0', '`', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0',
'-', '=', '\0', '\r', '\t', 'a', 'z', 'e', 'r', 't', 'y', 'u',
'i', 'o', 'p', '[', ']', '\\', '\0', 'q', 's', 'd', 'f', 'g',
'h', 'j', 'k', 'l', 'm', '\0', '\0', '\n', '\0', '\0', 'w', 'x',
'c', 'v', 'b', 'n', ',', ';', ':', '!', '\0', '\0', '\0', '\0',
'\0', ' ', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\r', '\0', '\0', '\0',
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '7', '4', '1','\0', '/',
'8', '5', '2', '0', '*', '9', '6', '3', '.', '-', '+', '\0',
'\n', '\0', '\0', '\0', '\0', '\0', '\0','\0', '\0', '\0', '\0', '\0', '\0',
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0'
};
static const int8_t HID_KEYBRD_ShiftKey[] = {
'\0', '~', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_',
'+', '\0', '\0', '\0', 'A', 'Z', 'E', 'R', 'T', 'Y', 'U', 'I', 'O',
'P', '{', '}', '*', '\0', 'Q', 'S', 'D', 'F', 'G', 'H', 'J', 'K',
'L', 'M', '%', '\0', '\n', '\0', '\0', 'W', 'X', 'C', 'V', 'B', 'N',
'?', '.', '/', '\0', '\0', '\0','\0', '\0', '\0', '\0', '\0', '\0', '\0',
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0'
};
#endif
/**
* @}
*/
/** @defgroup USBH_HID_KEYBD_Private_Functions
* @{
*/
/**
* @brief KEYBRD_Init.
* Initialize the keyboard function.
* @param None
* @retval None
*/
static void KEYBRD_Init (void)
{
/* Call User Init*/
USR_KEYBRD_Init();
}
/**
* @brief KEYBRD_ProcessData.
* The function is to decode the pressed keys.
* @param pbuf : Pointer to the HID IN report data buffer
* @retval None
*/
static void KEYBRD_Decode(uint8_t *pbuf)
{
static uint8_t shift;
static uint8_t keys[KBR_MAX_NBR_PRESSED];
static uint8_t keys_new[KBR_MAX_NBR_PRESSED];
static uint8_t keys_last[KBR_MAX_NBR_PRESSED];
static uint8_t key_newest;
static uint8_t nbr_keys;
static uint8_t nbr_keys_new;
static uint8_t nbr_keys_last;
uint8_t ix;
uint8_t jx;
uint8_t error;
uint8_t output;
nbr_keys = 0;
nbr_keys_new = 0;
nbr_keys_last = 0;
key_newest = 0x00;
/* Check if Shift key is pressed */
if ((pbuf[0] == KBD_LEFT_SHIFT) || (pbuf[0] == KBD_RIGHT_SHIFT)) {
shift = TRUE;
} else {
shift = FALSE;
}
error = FALSE;
/* Check for the value of pressed key */
for (ix = 2; ix < 2 + KBR_MAX_NBR_PRESSED; ix++) {
if ((pbuf[ix] == 0x01) ||
(pbuf[ix] == 0x02) ||
(pbuf[ix] == 0x03)) {
error = TRUE;
}
}
if (error == TRUE) {
return;
}
nbr_keys = 0;
nbr_keys_new = 0;
for (ix = 2; ix < 2 + KBR_MAX_NBR_PRESSED; ix++) {
if (pbuf[ix] != 0) {
keys[nbr_keys] = pbuf[ix];
nbr_keys++;
for (jx = 0; jx < nbr_keys_last; jx++) {
if (pbuf[ix] == keys_last[jx]) {
break;
}
}
if (jx == nbr_keys_last) {
keys_new[nbr_keys_new] = pbuf[ix];
nbr_keys_new++;
}
}
}
if (nbr_keys_new == 1) {
key_newest = keys_new[0];
if (shift == TRUE) {
output = HID_KEYBRD_ShiftKey[HID_KEYBRD_Codes[key_newest]];
} else {
output = HID_KEYBRD_Key[HID_KEYBRD_Codes[key_newest]];
}
/* call user process handle */
USR_KEYBRD_ProcessData(output);
} else {
key_newest = 0x00;
}
nbr_keys_last = nbr_keys;
for (ix = 0; ix < KBR_MAX_NBR_PRESSED; ix++) {
keys_last[ix] = keys[ix];
}
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,161 @@
/**
******************************************************************************
* @file usbh_hid_mouse.c
* @author MCD Application Team
* @version V2.1.0
* @date 19-March-2012
* @brief This file is the application layer for USB Host HID Mouse Handling.
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "usbh_hid_mouse.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 void MOUSE_Init (void);
static void MOUSE_Decode(uint8_t *data);
/**
* @}
*/
/** @defgroup USBH_HID_MOUSE_Private_Variables
* @{
*/
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
#if defined (__CC_ARM) /*!< ARM Compiler */
__align(4)
#elif defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#elif defined (__GNUC__) /*!< GNU Compiler */
#pragma pack(4)
#elif defined (__TASKING__) /*!< TASKING Compiler */
__align(4)
#endif /* __CC_ARM */
#endif
HID_MOUSE_Data_TypeDef HID_MOUSE_Data;
HID_cb_TypeDef HID_MOUSE_cb =
{
MOUSE_Init,
MOUSE_Decode,
};
/**
* @}
*/
/** @defgroup USBH_HID_MOUSE_Private_Functions
* @{
*/
/**
* @brief MOUSE_Init
* Init Mouse State.
* @param None
* @retval None
*/
static void MOUSE_Init ( void)
{
/* Call User Init*/
USR_MOUSE_Init();
}
/**
* @brief MOUSE_Decode
* Decode Mouse data
* @param data : Pointer to Mouse HID data buffer
* @retval None
*/
static void MOUSE_Decode(uint8_t *data)
{
HID_MOUSE_Data.button = data[0];
HID_MOUSE_Data.x = data[1];
HID_MOUSE_Data.y = data[2];
USR_MOUSE_ProcessData(&HID_MOUSE_Data);
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,227 @@
/**
******************************************************************************
* @file usbh_msc_bot.h
* @author MCD Application Team
* @version V2.1.0
* @date 19-March-2012
* @brief Header file for usbh_msc_bot.c
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Define to prevent recursive ----------------------------------------------*/
#ifndef __USBH_MSC_BOT_H__
#define __USBH_MSC_BOT_H__
/* Includes ------------------------------------------------------------------*/
#include "usbh_stdreq.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_core.c
* @{
*/
/** @defgroup USBH_MSC_BOT_Exported_Types
* @{
*/
typedef union _USBH_CBW_Block
{
struct __CBW
{
uint32_t CBWSignature;
uint32_t CBWTag;
uint32_t CBWTransferLength;
uint8_t CBWFlags;
uint8_t CBWLUN;
uint8_t CBWLength;
uint8_t CBWCB[16];
}field;
uint8_t CBWArray[31];
}HostCBWPkt_TypeDef;
typedef enum
{
USBH_MSC_BOT_INIT_STATE = 0,
USBH_MSC_BOT_RESET,
USBH_MSC_GET_MAX_LUN,
USBH_MSC_TEST_UNIT_READY,
USBH_MSC_READ_CAPACITY10,
USBH_MSC_MODE_SENSE6,
USBH_MSC_REQUEST_SENSE,
USBH_MSC_BOT_USB_TRANSFERS,
USBH_MSC_DEFAULT_APPLI_STATE,
USBH_MSC_CTRL_ERROR_STATE,
USBH_MSC_UNRECOVERED_STATE
}
MSCState;
typedef struct _BOTXfer
{
uint8_t MSCState;
uint8_t MSCStateBkp;
uint8_t MSCStateCurrent;
uint8_t CmdStateMachine;
uint8_t BOTState;
uint8_t BOTStateBkp;
uint8_t* pRxTxBuff;
uint16_t DataLength;
uint8_t BOTXferErrorCount;
uint8_t BOTXferStatus;
} USBH_BOTXfer_TypeDef;
typedef union _USBH_CSW_Block
{
struct __CSW
{
uint32_t CSWSignature;
uint32_t CSWTag;
uint32_t CSWDataResidue;
uint8_t CSWStatus;
}field;
uint8_t CSWArray[13];
}HostCSWPkt_TypeDef;
/**
* @}
*/
/** @defgroup USBH_MSC_BOT_Exported_Defines
* @{
*/
#define USBH_MSC_SEND_CBW 1
#define USBH_MSC_SENT_CBW 2
#define USBH_MSC_BOT_DATAIN_STATE 3
#define USBH_MSC_BOT_DATAOUT_STATE 4
#define USBH_MSC_RECEIVE_CSW_STATE 5
#define USBH_MSC_DECODE_CSW 6
#define USBH_MSC_BOT_ERROR_IN 7
#define USBH_MSC_BOT_ERROR_OUT 8
#define USBH_MSC_BOT_CBW_SIGNATURE 0x43425355
#define USBH_MSC_BOT_CBW_TAG 0x20304050
#define USBH_MSC_BOT_CSW_SIGNATURE 0x53425355
#define USBH_MSC_CSW_DATA_LENGTH 0x000D
#define USBH_MSC_BOT_CBW_PACKET_LENGTH 31
#define USBH_MSC_CSW_LENGTH 13
#define USBH_MSC_CSW_MAX_LENGTH 63
/* CSW Status Definitions */
#define USBH_MSC_CSW_CMD_PASSED 0x00
#define USBH_MSC_CSW_CMD_FAILED 0x01
#define USBH_MSC_CSW_PHASE_ERROR 0x02
#define USBH_MSC_SEND_CSW_DISABLE 0
#define USBH_MSC_SEND_CSW_ENABLE 1
#define USBH_MSC_DIR_IN 0
#define USBH_MSC_DIR_OUT 1
#define USBH_MSC_BOTH_DIR 2
//#define USBH_MSC_PAGE_LENGTH 0x40
#define USBH_MSC_PAGE_LENGTH 512
#define CBW_CB_LENGTH 16
#define CBW_LENGTH 10
#define CBW_LENGTH_TEST_UNIT_READY 6
#define USB_REQ_BOT_RESET 0xFF
#define USB_REQ_GET_MAX_LUN 0xFE
#define MAX_BULK_STALL_COUNT_LIMIT 0x04 /* If STALL is seen on Bulk
Endpoint continously, 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
* @{
*/
extern USBH_BOTXfer_TypeDef USBH_MSC_BOTXferParam;
extern HostCBWPkt_TypeDef USBH_MSC_CBWData;
extern HostCSWPkt_TypeDef USBH_MSC_CSWData;
/**
* @}
*/
/** @defgroup USBH_MSC_BOT_Exported_FunctionsPrototype
* @{
*/
void USBH_MSC_HandleBOTXfer(USB_OTG_CORE_HANDLE *pdev,
USBH_HOST *phost);
uint8_t USBH_MSC_DecodeCSW(USB_OTG_CORE_HANDLE *pdev,
USBH_HOST *phost);
void USBH_MSC_Init(USB_OTG_CORE_HANDLE *pdev);
USBH_Status USBH_MSC_BOT_Abort(USB_OTG_CORE_HANDLE *pdev,
USBH_HOST *phost,
uint8_t direction);
/**
* @}
*/
#endif //__USBH_MSC_BOT_H__
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,147 @@
/**
******************************************************************************
* @file usbh_msc_core.h
* @author MCD Application Team
* @version V2.1.0
* @date 19-March-2012
* @brief This file contains all the prototypes for the usbh_msc_core.c
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Define to prevent recursive ----------------------------------------------*/
#ifndef __USBH_MSC_CORE_H
#define __USBH_MSC_CORE_H
/* Includes ------------------------------------------------------------------*/
#include "usbh_core.h"
#include "usbh_stdreq.h"
#include "usb_bsp.h"
#include "usbh_ioreq.h"
#include "usbh_hcs.h"
#include "usbh_msc_core.h"
#include "usbh_msc_scsi.h"
#include "usbh_msc_bot.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_core.c
* @{
*/
/** @defgroup USBH_MSC_CORE_Exported_Types
* @{
*/
/* Structure for MSC process */
typedef struct _MSC_Process
{
uint8_t hc_num_in;
uint8_t hc_num_out;
uint8_t MSBulkOutEp;
uint8_t MSBulkInEp;
uint16_t MSBulkInEpSize;
uint16_t MSBulkOutEpSize;
uint8_t buff[USBH_MSC_MPS_SIZE];
uint8_t maxLun;
}
MSC_Machine_TypeDef;
/**
* @}
*/
/** @defgroup USBH_MSC_CORE_Exported_Defines
* @{
*/
#define USB_REQ_BOT_RESET 0xFF
#define USB_REQ_GET_MAX_LUN 0xFE
/**
* @}
*/
/** @defgroup USBH_MSC_CORE_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBH_MSC_CORE_Exported_Variables
* @{
*/
extern USBH_Class_cb_TypeDef USBH_MSC_cb;
extern MSC_Machine_TypeDef MSC_Machine;
extern uint8_t MSCErrorCount;
/**
* @}
*/
/** @defgroup USBH_MSC_CORE_Exported_FunctionsPrototype
* @{
*/
/**
* @}
*/
#endif /* __USBH_MSC_CORE_H */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,169 @@
/**
******************************************************************************
* @file usbh_msc_scsi.h
* @author MCD Application Team
* @version V2.1.0
* @date 19-March-2012
* @brief Header file for usbh_msc_scsi.c
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Define to prevent recursive ----------------------------------------------*/
#ifndef __USBH_MSC_SCSI_H__
#define __USBH_MSC_SCSI_H__
/* Includes ------------------------------------------------------------------*/
#include "usbh_stdreq.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
* @{
*/
/** @defgroup USBH_MSC_SCSI_Exported_Types
* @{
*/
typedef enum {
USBH_MSC_OK = 0,
USBH_MSC_FAIL = 1,
USBH_MSC_PHASE_ERROR = 2,
USBH_MSC_BUSY = 3
}USBH_MSC_Status_TypeDef;
typedef enum {
CMD_UNINITIALIZED_STATE =0,
CMD_SEND_STATE,
CMD_WAIT_STATUS
} CMD_STATES_TypeDef;
typedef struct __MassStorageParameter
{
uint32_t MSCapacity;
uint32_t MSSenseKey;
uint16_t MSPageLength;
uint8_t MSBulkOutEp;
uint8_t MSBulkInEp;
uint8_t MSWriteProtect;
} MassStorageParameter_TypeDef;
/**
* @}
*/
/** @defgroup USBH_MSC_SCSI_Exported_Defines
* @{
*/
#define OPCODE_TEST_UNIT_READY 0X00
#define OPCODE_READ_CAPACITY10 0x25
#define OPCODE_MODE_SENSE6 0x1A
#define OPCODE_READ10 0x28
#define OPCODE_WRITE10 0x2A
#define OPCODE_REQUEST_SENSE 0x03
#define DESC_REQUEST_SENSE 0X00
#define ALLOCATION_LENGTH_REQUEST_SENSE 63
#define XFER_LEN_READ_CAPACITY10 8
#define XFER_LEN_MODE_SENSE6 63
#define MASK_MODE_SENSE_WRITE_PROTECT 0x80
#define MODE_SENSE_PAGE_CONTROL_FIELD 0x00
#define MODE_SENSE_PAGE_CODE 0x3F
#define DISK_WRITE_PROTECTED 0x01
/**
* @}
*/
/** @defgroup USBH_MSC_SCSI_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup _Exported_Variables
* @{
*/
extern MassStorageParameter_TypeDef USBH_MSC_Param;
/**
* @}
*/
/** @defgroup USBH_MSC_SCSI_Exported_FunctionsPrototype
* @{
*/
uint8_t USBH_MSC_TestUnitReady(USB_OTG_CORE_HANDLE *pdev);
uint8_t USBH_MSC_ReadCapacity10(USB_OTG_CORE_HANDLE *pdev);
uint8_t USBH_MSC_ModeSense6(USB_OTG_CORE_HANDLE *pdev);
uint8_t USBH_MSC_RequestSense(USB_OTG_CORE_HANDLE *pdev);
uint8_t USBH_MSC_Write10(USB_OTG_CORE_HANDLE *pdev,
uint8_t *,
uint32_t ,
uint32_t );
uint8_t USBH_MSC_Read10(USB_OTG_CORE_HANDLE *pdev,
uint8_t *,
uint32_t ,
uint32_t );
void USBH_MSC_StateMachine(USB_OTG_CORE_HANDLE *pdev);
/**
* @}
*/
#endif //__USBH_MSC_SCSI_H__
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,632 @@
/**
******************************************************************************
* @file usbh_msc_bot.c
* @author MCD Application Team
* @version V2.1.0
* @date 19-March-2012
* @brief This file includes the mass storage related functions
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "usbh_msc_core.h"
#include "usbh_msc_scsi.h"
#include "usbh_msc_bot.h"
#include "usbh_ioreq.h"
#include "usbh_def.h"
#include "usb_hcd_int.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
* @{
*/
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
__ALIGN_BEGIN HostCBWPkt_TypeDef USBH_MSC_CBWData __ALIGN_END ;
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
__ALIGN_BEGIN HostCSWPkt_TypeDef USBH_MSC_CSWData __ALIGN_END ;
static uint32_t BOTStallErrorCount; /* Keeps count of STALL Error Cases*/
/**
* @}
*/
/** @defgroup USBH_MSC_BOT_Private_FunctionPrototypes
* @{
*/
/**
* @}
*/
/** @defgroup USBH_MSC_BOT_Exported_Variables
* @{
*/
USBH_BOTXfer_TypeDef USBH_MSC_BOTXferParam;
/**
* @}
*/
/** @defgroup USBH_MSC_BOT_Private_Functions
* @{
*/
/**
* @brief USBH_MSC_Init
* Initializes the mass storage parameters
* @param None
* @retval None
*/
void USBH_MSC_Init(USB_OTG_CORE_HANDLE *pdev )
{
if(HCD_IsDeviceConnected(pdev))
{
USBH_MSC_CBWData.field.CBWSignature = USBH_MSC_BOT_CBW_SIGNATURE;
USBH_MSC_CBWData.field.CBWTag = USBH_MSC_BOT_CBW_TAG;
USBH_MSC_CBWData.field.CBWLUN = 0; /*Only one LUN is supported*/
USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
}
BOTStallErrorCount = 0;
MSCErrorCount = 0;
}
/**
* @brief USBH_MSC_HandleBOTXfer
* This function manages the different states of BOT transfer and
* updates the status to upper layer.
* @param None
* @retval None
*
*/
void USBH_MSC_HandleBOTXfer (USB_OTG_CORE_HANDLE *pdev ,USBH_HOST *phost)
{
uint8_t xferDirection, index;
static uint32_t remainingDataLength;
static uint8_t *datapointer , *datapointer_prev;
static uint8_t error_direction;
USBH_Status status;
URB_STATE URB_Status = URB_IDLE;
if(HCD_IsDeviceConnected(pdev))
{
switch (USBH_MSC_BOTXferParam.BOTState)
{
case USBH_MSC_SEND_CBW:
/* send CBW */
USBH_BulkSendData (pdev,
&USBH_MSC_CBWData.CBWArray[0],
USBH_MSC_BOT_CBW_PACKET_LENGTH ,
MSC_Machine.hc_num_out);
USBH_MSC_BOTXferParam.BOTStateBkp = USBH_MSC_SEND_CBW;
USBH_MSC_BOTXferParam.BOTState = USBH_MSC_SENT_CBW;
break;
case USBH_MSC_SENT_CBW:
URB_Status = HCD_GetURB_State(pdev , MSC_Machine.hc_num_out);
if(URB_Status == URB_DONE)
{
BOTStallErrorCount = 0;
USBH_MSC_BOTXferParam.BOTStateBkp = USBH_MSC_SENT_CBW;
/* If the CBW Pkt is sent successful, then change the state */
xferDirection = (USBH_MSC_CBWData.field.CBWFlags & USB_REQ_DIR_MASK);
if ( USBH_MSC_CBWData.field.CBWTransferLength != 0 )
{
remainingDataLength = USBH_MSC_CBWData.field.CBWTransferLength ;
datapointer = USBH_MSC_BOTXferParam.pRxTxBuff;
datapointer_prev = datapointer;
/* If there is Data Transfer Stage */
if (xferDirection == USB_D2H)
{
/* Data Direction is IN */
USBH_MSC_BOTXferParam.BOTState = USBH_MSC_BOT_DATAIN_STATE;
}
else
{
/* Data Direction is OUT */
USBH_MSC_BOTXferParam.BOTState = USBH_MSC_BOT_DATAOUT_STATE;
}
}
else
{/* If there is NO Data Transfer Stage */
USBH_MSC_BOTXferParam.BOTState = USBH_MSC_RECEIVE_CSW_STATE;
}
}
else if(URB_Status == URB_NOTREADY)
{
USBH_MSC_BOTXferParam.BOTState = USBH_MSC_BOTXferParam.BOTStateBkp;
}
else if(URB_Status == URB_STALL)
{
error_direction = USBH_MSC_DIR_OUT;
USBH_MSC_BOTXferParam.BOTState = USBH_MSC_BOT_ERROR_OUT;
}
break;
case USBH_MSC_BOT_DATAIN_STATE:
URB_Status = HCD_GetURB_State(pdev , MSC_Machine.hc_num_in);
/* BOT DATA IN stage */
if((URB_Status == URB_DONE) ||(USBH_MSC_BOTXferParam.BOTStateBkp != USBH_MSC_BOT_DATAIN_STATE))
{
BOTStallErrorCount = 0;
USBH_MSC_BOTXferParam.BOTStateBkp = USBH_MSC_BOT_DATAIN_STATE;
if(remainingDataLength > MSC_Machine.MSBulkInEpSize)
{
USBH_BulkReceiveData (pdev,
datapointer,
MSC_Machine.MSBulkInEpSize ,
MSC_Machine.hc_num_in);
remainingDataLength -= MSC_Machine.MSBulkInEpSize;
datapointer = datapointer + MSC_Machine.MSBulkInEpSize;
}
else if ( remainingDataLength == 0)
{
/* If value was 0, and successful transfer, then change the state */
USBH_MSC_BOTXferParam.BOTState = USBH_MSC_RECEIVE_CSW_STATE;
}
else
{
USBH_BulkReceiveData (pdev,
datapointer,
remainingDataLength ,
MSC_Machine.hc_num_in);
remainingDataLength = 0; /* Reset this value and keep in same state */
}
}
else if(URB_Status == URB_STALL)
{
/* This is Data Stage STALL Condition */
error_direction = USBH_MSC_DIR_IN;
USBH_MSC_BOTXferParam.BOTState = USBH_MSC_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.
USBH_MSC_BOTXferParam.BOTStateBkp is used to switch to the Original
state after the ClearFeature Command is issued.
*/
USBH_MSC_BOTXferParam.BOTStateBkp = USBH_MSC_RECEIVE_CSW_STATE;
}
break;
case USBH_MSC_BOT_DATAOUT_STATE:
/* BOT DATA OUT stage */
URB_Status = HCD_GetURB_State(pdev , MSC_Machine.hc_num_out);
if(URB_Status == URB_DONE)
{
BOTStallErrorCount = 0;
USBH_MSC_BOTXferParam.BOTStateBkp = USBH_MSC_BOT_DATAOUT_STATE;
if(remainingDataLength > MSC_Machine.MSBulkOutEpSize)
{
USBH_BulkSendData (pdev,
datapointer,
MSC_Machine.MSBulkOutEpSize ,
MSC_Machine.hc_num_out);
datapointer_prev = datapointer;
datapointer = datapointer + MSC_Machine.MSBulkOutEpSize;
remainingDataLength = remainingDataLength - MSC_Machine.MSBulkOutEpSize;
}
else if ( remainingDataLength == 0)
{
/* If value was 0, and successful transfer, then change the state */
USBH_MSC_BOTXferParam.BOTState = USBH_MSC_RECEIVE_CSW_STATE;
}
else
{
USBH_BulkSendData (pdev,
datapointer,
remainingDataLength ,
MSC_Machine.hc_num_out);
remainingDataLength = 0; /* Reset this value and keep in same state */
}
}
else if(URB_Status == URB_NOTREADY)
{
if(datapointer != datapointer_prev)
{
USBH_BulkSendData (pdev,
(datapointer - MSC_Machine.MSBulkOutEpSize),
MSC_Machine.MSBulkOutEpSize ,
MSC_Machine.hc_num_out);
}
else
{
USBH_BulkSendData (pdev,
datapointer,
MSC_Machine.MSBulkOutEpSize ,
MSC_Machine.hc_num_out);
}
}
else if(URB_Status == URB_STALL)
{
error_direction = USBH_MSC_DIR_OUT;
USBH_MSC_BOTXferParam.BOTState = USBH_MSC_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.
The Above statement will do the clear the Bulk-Out pipe.
The Below statement will help in Getting the CSW.
USBH_MSC_BOTXferParam.BOTStateBkp is used to switch to the Original
state after the ClearFeature Command is issued.
*/
USBH_MSC_BOTXferParam.BOTStateBkp = USBH_MSC_RECEIVE_CSW_STATE;
}
break;
case USBH_MSC_RECEIVE_CSW_STATE:
/* BOT CSW stage */
/* NOTE: We cannot reset the BOTStallErrorCount here as it may come from
the clearFeature from previous command */
USBH_MSC_BOTXferParam.BOTStateBkp = USBH_MSC_RECEIVE_CSW_STATE;
USBH_MSC_BOTXferParam.pRxTxBuff = USBH_MSC_CSWData.CSWArray;
USBH_MSC_BOTXferParam.DataLength = USBH_MSC_CSW_MAX_LENGTH;
for(index = USBH_MSC_CSW_LENGTH; index != 0; index--)
{
USBH_MSC_CSWData.CSWArray[index] = 0;
}
USBH_MSC_CSWData.CSWArray[0] = 0;
USBH_BulkReceiveData (pdev,
USBH_MSC_BOTXferParam.pRxTxBuff,
USBH_MSC_CSW_MAX_LENGTH ,
MSC_Machine.hc_num_in);
USBH_MSC_BOTXferParam.BOTState = USBH_MSC_DECODE_CSW;
break;
case USBH_MSC_DECODE_CSW:
URB_Status = HCD_GetURB_State(pdev , MSC_Machine.hc_num_in);
/* Decode CSW */
if(URB_Status == URB_DONE)
{
BOTStallErrorCount = 0;
USBH_MSC_BOTXferParam.BOTStateBkp = USBH_MSC_RECEIVE_CSW_STATE;
USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOTXferParam.MSCStateCurrent ;
USBH_MSC_BOTXferParam.BOTXferStatus = USBH_MSC_DecodeCSW(pdev , phost);
}
else if(URB_Status == URB_STALL)
{
error_direction = USBH_MSC_DIR_IN;
USBH_MSC_BOTXferParam.BOTState = USBH_MSC_BOT_ERROR_IN;
}
break;
case USBH_MSC_BOT_ERROR_IN:
status = USBH_MSC_BOT_Abort(pdev, phost, USBH_MSC_DIR_IN);
if (status == USBH_OK)
{
/* Check if the error was due in Both the directions */
if (error_direction == USBH_MSC_BOTH_DIR)
{/* If Both directions are Needed, Switch to OUT Direction */
USBH_MSC_BOTXferParam.BOTState = USBH_MSC_BOT_ERROR_OUT;
}
else
{
/* Switch Back to the Original State, In many cases this will be
USBH_MSC_RECEIVE_CSW_STATE state */
USBH_MSC_BOTXferParam.BOTState = USBH_MSC_BOTXferParam.BOTStateBkp;
}
}
else if (status == USBH_UNRECOVERED_ERROR)
{
/* This means that there is a STALL Error limit, Do Reset Recovery */
USBH_MSC_BOTXferParam.BOTXferStatus = USBH_MSC_PHASE_ERROR;
}
break;
case USBH_MSC_BOT_ERROR_OUT:
status = USBH_MSC_BOT_Abort(pdev, phost, USBH_MSC_DIR_OUT);
if ( status == USBH_OK)
{ /* Switch Back to the Original State */
USBH_MSC_BOTXferParam.BOTState = USBH_MSC_BOTXferParam.BOTStateBkp;
}
else if (status == USBH_UNRECOVERED_ERROR)
{
/* This means that there is a STALL Error limit, Do Reset Recovery */
USBH_MSC_BOTXferParam.BOTXferStatus = USBH_MSC_PHASE_ERROR;
}
break;
default:
break;
}
}
}
/**
* @brief USBH_MSC_BOT_Abort
* This function manages the different Error handling for STALL
* @param direction : IN / OUT
* @retval None
*/
USBH_Status USBH_MSC_BOT_Abort(USB_OTG_CORE_HANDLE *pdev,
USBH_HOST *phost,
uint8_t direction)
{
USBH_Status status;
status = USBH_BUSY;
switch (direction)
{
case USBH_MSC_DIR_IN :
/* send ClrFeture on Bulk IN endpoint */
status = USBH_ClrFeature(pdev,
phost,
MSC_Machine.MSBulkInEp,
MSC_Machine.hc_num_in);
break;
case USBH_MSC_DIR_OUT :
/*send ClrFeature on Bulk OUT endpoint */
status = USBH_ClrFeature(pdev,
phost,
MSC_Machine.MSBulkOutEp,
MSC_Machine.hc_num_out);
break;
default:
break;
}
BOTStallErrorCount++; /* Check Continous Number of times, STALL has Occured */
if (BOTStallErrorCount > MAX_BULK_STALL_COUNT_LIMIT )
{
status = USBH_UNRECOVERED_ERROR;
}
return status;
}
/**
* @brief USBH_MSC_DecodeCSW
* This function decodes the CSW received by the device and updates the
* same to upper layer.
* @param None
* @retval On success USBH_MSC_OK, on failure USBH_MSC_FAIL
* @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.
*/
uint8_t USBH_MSC_DecodeCSW(USB_OTG_CORE_HANDLE *pdev , USBH_HOST *phost)
{
uint8_t status;
uint32_t dataXferCount = 0;
status = USBH_MSC_FAIL;
if(HCD_IsDeviceConnected(pdev))
{
/*Checking if the transfer length is diffrent than 13*/
dataXferCount = HCD_GetXferCnt(pdev, MSC_Machine.hc_num_in);
if(dataXferCount != USBH_MSC_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 = USBH_MSC_PHASE_ERROR;
}
else
{ /* CSW length is Correct */
/* Check validity of the CSW Signature and CSWStatus */
if(USBH_MSC_CSWData.field.CSWSignature == USBH_MSC_BOT_CSW_SIGNATURE)
{/* Check Condition 1. dCSWSignature is equal to 53425355h */
if(USBH_MSC_CSWData.field.CSWTag == USBH_MSC_CBWData.field.CBWTag)
{
/* Check Condition 3. dCSWTag matches the dCBWTag from the
corresponding CBW */
if(USBH_MSC_CSWData.field.CSWStatus == USBH_MSC_OK)
{
/* 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 = USBH_MSC_OK;
}
else if(USBH_MSC_CSWData.field.CSWStatus == USBH_MSC_FAIL)
{
status = USBH_MSC_FAIL;
}
else if(USBH_MSC_CSWData.field.CSWStatus == USBH_MSC_PHASE_ERROR)
{
/* 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 = USBH_MSC_PHASE_ERROR;
}
} /* 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 = USBH_MSC_PHASE_ERROR;
}
} /* CSW Length Check*/
}
USBH_MSC_BOTXferParam.BOTXferStatus = status;
return status;
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,566 @@
/**
******************************************************************************
* @file usbh_msc_core.c
* @author MCD Application Team
* @version V2.1.0
* @date 19-March-2012
* @brief This file implements the MSC class driver functions
* ===================================================================
* 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
*
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "usbh_msc_core.h"
#include "usbh_msc_scsi.h"
#include "usbh_msc_bot.h"
#include "usbh_core.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
* @{
*/
#define USBH_MSC_ERROR_RETRY_LIMIT 10
/**
* @}
*/
/** @defgroup USBH_MSC_CORE_Private_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBH_MSC_CORE_Private_Variables
* @{
*/
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
__ALIGN_BEGIN MSC_Machine_TypeDef MSC_Machine __ALIGN_END ;
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
__ALIGN_BEGIN USB_Setup_TypeDef MSC_Setup __ALIGN_END ;
uint8_t MSCErrorCount = 0;
/**
* @}
*/
/** @defgroup USBH_MSC_CORE_Private_FunctionPrototypes
* @{
*/
static USBH_Status USBH_MSC_InterfaceInit (USB_OTG_CORE_HANDLE *pdev ,
void *phost);
static void USBH_MSC_InterfaceDeInit (USB_OTG_CORE_HANDLE *pdev ,
void *phost);
static USBH_Status USBH_MSC_Handle(USB_OTG_CORE_HANDLE *pdev ,
void *phost);
static USBH_Status USBH_MSC_ClassRequest(USB_OTG_CORE_HANDLE *pdev ,
void *phost);
static USBH_Status USBH_MSC_BOTReset(USB_OTG_CORE_HANDLE *pdev,
USBH_HOST *phost);
static USBH_Status USBH_MSC_GETMaxLUN(USB_OTG_CORE_HANDLE *pdev,
USBH_HOST *phost);
USBH_Class_cb_TypeDef USBH_MSC_cb =
{
USBH_MSC_InterfaceInit,
USBH_MSC_InterfaceDeInit,
USBH_MSC_ClassRequest,
USBH_MSC_Handle,
};
void USBH_MSC_ErrorHandle(uint8_t status);
/**
* @}
*/
/** @defgroup USBH_MSC_CORE_Exported_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USBH_MSC_CORE_Private_Functions
* @{
*/
/**
* @brief USBH_MSC_InterfaceInit
* Interface initialization for MSC class.
* @param pdev: Selected device
* @param hdev: Selected device property
* @retval USBH_Status : Status of class request handled.
*/
static USBH_Status USBH_MSC_InterfaceInit ( USB_OTG_CORE_HANDLE *pdev,
void *phost)
{
USBH_HOST *pphost = phost;
if((pphost->device_prop.Itf_Desc[0].bInterfaceClass == MSC_CLASS) && \
(pphost->device_prop.Itf_Desc[0].bInterfaceProtocol == MSC_PROTOCOL))
{
if(pphost->device_prop.Ep_Desc[0][0].bEndpointAddress & 0x80)
{
MSC_Machine.MSBulkInEp = (pphost->device_prop.Ep_Desc[0][0].bEndpointAddress);
MSC_Machine.MSBulkInEpSize = pphost->device_prop.Ep_Desc[0][0].wMaxPacketSize;
}
else
{
MSC_Machine.MSBulkOutEp = (pphost->device_prop.Ep_Desc[0][0].bEndpointAddress);
MSC_Machine.MSBulkOutEpSize = pphost->device_prop.Ep_Desc[0] [0].wMaxPacketSize;
}
if(pphost->device_prop.Ep_Desc[0][1].bEndpointAddress & 0x80)
{
MSC_Machine.MSBulkInEp = (pphost->device_prop.Ep_Desc[0][1].bEndpointAddress);
MSC_Machine.MSBulkInEpSize = pphost->device_prop.Ep_Desc[0][1].wMaxPacketSize;
}
else
{
MSC_Machine.MSBulkOutEp = (pphost->device_prop.Ep_Desc[0][1].bEndpointAddress);
MSC_Machine.MSBulkOutEpSize = pphost->device_prop.Ep_Desc[0][1].wMaxPacketSize;
}
MSC_Machine.hc_num_out = USBH_Alloc_Channel(pdev,
MSC_Machine.MSBulkOutEp);
MSC_Machine.hc_num_in = USBH_Alloc_Channel(pdev,
MSC_Machine.MSBulkInEp);
/* Open the new channels */
USBH_Open_Channel (pdev,
MSC_Machine.hc_num_out,
pphost->device_prop.address,
pphost->device_prop.speed,
EP_TYPE_BULK,
MSC_Machine.MSBulkOutEpSize);
USBH_Open_Channel (pdev,
MSC_Machine.hc_num_in,
pphost->device_prop.address,
pphost->device_prop.speed,
EP_TYPE_BULK,
MSC_Machine.MSBulkInEpSize);
}
else
{
pphost->usr_cb->DeviceNotSupported();
}
return USBH_OK ;
}
/**
* @brief USBH_MSC_InterfaceDeInit
* De-Initialize interface by freeing host channels allocated to interface
* @param pdev: Selected device
* @param hdev: Selected device property
* @retval None
*/
void USBH_MSC_InterfaceDeInit ( USB_OTG_CORE_HANDLE *pdev,
void *phost)
{
if ( MSC_Machine.hc_num_out)
{
USB_OTG_HC_Halt(pdev, MSC_Machine.hc_num_out);
USBH_Free_Channel (pdev, MSC_Machine.hc_num_out);
MSC_Machine.hc_num_out = 0; /* Reset the Channel as Free */
}
if ( MSC_Machine.hc_num_in)
{
USB_OTG_HC_Halt(pdev, MSC_Machine.hc_num_in);
USBH_Free_Channel (pdev, MSC_Machine.hc_num_in);
MSC_Machine.hc_num_in = 0; /* Reset the Channel as Free */
}
}
/**
* @brief USBH_MSC_ClassRequest
* This function will only initialize the MSC state machine
* @param pdev: Selected device
* @param hdev: Selected device property
* @retval USBH_Status : Status of class request handled.
*/
static USBH_Status USBH_MSC_ClassRequest(USB_OTG_CORE_HANDLE *pdev ,
void *phost)
{
USBH_Status status = USBH_OK ;
USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOT_INIT_STATE;
return status;
}
/**
* @brief USBH_MSC_Handle
* MSC state machine handler
* @param pdev: Selected device
* @param hdev: Selected device property
* @retval USBH_Status
*/
static USBH_Status USBH_MSC_Handle(USB_OTG_CORE_HANDLE *pdev ,
void *phost)
{
USBH_HOST *pphost = phost;
USBH_Status status = USBH_BUSY;
uint8_t mscStatus = USBH_MSC_BUSY;
uint8_t appliStatus = 0;
static uint8_t maxLunExceed = FALSE;
if(HCD_IsDeviceConnected(pdev))
{
switch(USBH_MSC_BOTXferParam.MSCState)
{
case USBH_MSC_BOT_INIT_STATE:
USBH_MSC_Init(pdev);
USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOT_RESET;
break;
case USBH_MSC_BOT_RESET:
/* Issue BOT RESET request */
status = USBH_MSC_BOTReset(pdev, phost);
if(status == USBH_OK )
{
USBH_MSC_BOTXferParam.MSCState = USBH_MSC_GET_MAX_LUN;
}
if(status == USBH_NOT_SUPPORTED )
{
/* If the Command has failed, then we need to move to Next State, after
STALL condition is cleared by Control-Transfer */
USBH_MSC_BOTXferParam.MSCStateBkp = USBH_MSC_GET_MAX_LUN;
/* a Clear Feature should be issued here */
USBH_MSC_BOTXferParam.MSCState = USBH_MSC_CTRL_ERROR_STATE;
}
break;
case USBH_MSC_GET_MAX_LUN:
/* Issue GetMaxLUN request */
status = USBH_MSC_GETMaxLUN(pdev, phost);
if(status == USBH_OK )
{
MSC_Machine.maxLun = *(MSC_Machine.buff) ;
/* If device has more that one logical unit then it is not supported */
if((MSC_Machine.maxLun > 0) && (maxLunExceed == FALSE))
{
maxLunExceed = TRUE;
pphost->usr_cb->DeviceNotSupported();
break;
}
USBH_MSC_BOTXferParam.MSCState = USBH_MSC_TEST_UNIT_READY;
}
if(status == USBH_NOT_SUPPORTED )
{
/* If the Command has failed, then we need to move to Next State, after
STALL condition is cleared by Control-Transfer */
USBH_MSC_BOTXferParam.MSCStateBkp = USBH_MSC_TEST_UNIT_READY;
/* a Clear Feature should be issued here */
USBH_MSC_BOTXferParam.MSCState = USBH_MSC_CTRL_ERROR_STATE;
}
break;
case USBH_MSC_CTRL_ERROR_STATE:
/* Issue Clearfeature request */
status = USBH_ClrFeature(pdev,
phost,
0x00,
pphost->Control.hc_num_out);
if(status == USBH_OK )
{
/* If GetMaxLun Request not support, assume Single LUN configuration */
MSC_Machine.maxLun = 0;
USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOTXferParam.MSCStateBkp;
}
break;
case USBH_MSC_TEST_UNIT_READY:
/* Issue SCSI command TestUnitReady */
mscStatus = USBH_MSC_TestUnitReady(pdev);
if(mscStatus == USBH_MSC_OK )
{
USBH_MSC_BOTXferParam.MSCState = USBH_MSC_READ_CAPACITY10;
MSCErrorCount = 0;
status = USBH_OK;
}
else
{
USBH_MSC_ErrorHandle(mscStatus);
}
break;
case USBH_MSC_READ_CAPACITY10:
/* Issue READ_CAPACITY10 SCSI command */
mscStatus = USBH_MSC_ReadCapacity10(pdev);
if(mscStatus == USBH_MSC_OK )
{
USBH_MSC_BOTXferParam.MSCState = USBH_MSC_MODE_SENSE6;
MSCErrorCount = 0;
status = USBH_OK;
}
else
{
USBH_MSC_ErrorHandle(mscStatus);
}
break;
case USBH_MSC_MODE_SENSE6:
/* Issue ModeSense6 SCSI command for detecting if device is write-protected */
mscStatus = USBH_MSC_ModeSense6(pdev);
if(mscStatus == USBH_MSC_OK )
{
USBH_MSC_BOTXferParam.MSCState = USBH_MSC_DEFAULT_APPLI_STATE;
MSCErrorCount = 0;
status = USBH_OK;
}
else
{
USBH_MSC_ErrorHandle(mscStatus);
}
break;
case USBH_MSC_REQUEST_SENSE:
/* Issue RequestSense SCSI command for retreiving error code */
mscStatus = USBH_MSC_RequestSense(pdev);
if(mscStatus == USBH_MSC_OK )
{
USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOTXferParam.MSCStateBkp;
status = USBH_OK;
}
else
{
USBH_MSC_ErrorHandle(mscStatus);
}
break;
case USBH_MSC_BOT_USB_TRANSFERS:
/* Process the BOT state machine */
USBH_MSC_HandleBOTXfer(pdev , phost);
break;
case USBH_MSC_DEFAULT_APPLI_STATE:
/* Process Application callback for MSC */
appliStatus = pphost->usr_cb->UserApplication();
if(appliStatus == 0)
{
USBH_MSC_BOTXferParam.MSCState = USBH_MSC_DEFAULT_APPLI_STATE;
}
else if (appliStatus == 1)
{
/* De-init requested from application layer */
status = USBH_APPLY_DEINIT;
}
break;
case USBH_MSC_UNRECOVERED_STATE:
status = USBH_UNRECOVERED_ERROR;
break;
default:
break;
}
}
return status;
}
/**
* @brief USBH_MSC_BOTReset
* This request is used to reset the mass storage device and its
* associated interface. This class-specific request shall ready the
* device for the next CBW from the host.
* @param pdev: Selected device
* @retval USBH_Status : Status of class request handled.
*/
static USBH_Status USBH_MSC_BOTReset(USB_OTG_CORE_HANDLE *pdev,
USBH_HOST *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 = 0;
phost->Control.setup.b.wIndex.w = 0;
phost->Control.setup.b.wLength.w = 0;
return USBH_CtlReq(pdev, phost, 0 , 0 );
}
/**
* @brief USBH_MSC_GETMaxLUN
* This request is used to reset the mass storage device and its
* associated interface. This class-specific request shall ready the
* device for the next CBW from the host.
* @param pdev: Selected device
* @retval USBH_Status : USB ctl xfer status
*/
static USBH_Status USBH_MSC_GETMaxLUN(USB_OTG_CORE_HANDLE *pdev , USBH_HOST *phost)
{
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 = 0;
phost->Control.setup.b.wIndex.w = 0;
phost->Control.setup.b.wLength.w = 1;
return USBH_CtlReq(pdev, phost, MSC_Machine.buff , 1 );
}
/**
* @brief USBH_MSC_ErrorHandle
* The function is for handling errors occuring during the MSC
* state machine
* @param status
* @retval None
*/
void USBH_MSC_ErrorHandle(uint8_t status)
{
if(status == USBH_MSC_FAIL)
{
MSCErrorCount++;
if(MSCErrorCount < USBH_MSC_ERROR_RETRY_LIMIT)
{ /* Try MSC level error recovery, Issue the request Sense to get
Drive error reason */
USBH_MSC_BOTXferParam.MSCState = USBH_MSC_REQUEST_SENSE;
USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
}
else
{
/* Error trials exceeded the limit, go to unrecovered state */
USBH_MSC_BOTXferParam.MSCState = USBH_MSC_UNRECOVERED_STATE;
}
}
else if(status == USBH_MSC_PHASE_ERROR)
{
/* Phase error, Go to Unrecoovered state */
USBH_MSC_BOTXferParam.MSCState = USBH_MSC_UNRECOVERED_STATE;
}
else if(status == USBH_MSC_BUSY)
{
/*No change in state*/
}
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,186 @@
#include "usb_conf.h"
#include "diskio.h"
#include "usbh_msc_core.h"
/*--------------------------------------------------------------------------
Module Private Functions and Variables
---------------------------------------------------------------------------*/
static volatile DSTATUS Stat = STA_NOINIT; /* Disk status */
extern USB_OTG_CORE_HANDLE USB_OTG_Core;
extern USBH_HOST USB_Host;
/*-----------------------------------------------------------------------*/
/* Initialize Disk Drive */
/*-----------------------------------------------------------------------*/
DSTATUS disk_initialize (
BYTE drv /* Physical drive number (0) */
)
{
if(HCD_IsDeviceConnected(&USB_OTG_Core))
{
Stat &= ~STA_NOINIT;
}
return Stat;
}
/*-----------------------------------------------------------------------*/
/* Get Disk Status */
/*-----------------------------------------------------------------------*/
DSTATUS disk_status (
BYTE drv /* Physical drive number (0) */
)
{
if (drv) return STA_NOINIT; /* Supports only single drive */
return Stat;
}
/*-----------------------------------------------------------------------*/
/* Read Sector(s) */
/*-----------------------------------------------------------------------*/
DRESULT disk_read (
BYTE drv, /* Physical drive number (0) */
BYTE *buff, /* Pointer to the data buffer to store read data */
DWORD sector, /* Start sector number (LBA) */
BYTE count /* Sector count (1..255) */
)
{
BYTE status = USBH_MSC_OK;
if (drv || !count) return RES_PARERR;
if (Stat & STA_NOINIT) return RES_NOTRDY;
if(HCD_IsDeviceConnected(&USB_OTG_Core))
{
do
{
status = USBH_MSC_Read10(&USB_OTG_Core, buff,sector,512 * count);
USBH_MSC_HandleBOTXfer(&USB_OTG_Core ,&USB_Host);
if(!HCD_IsDeviceConnected(&USB_OTG_Core))
{
return RES_ERROR;
}
}
while(status == USBH_MSC_BUSY );
}
if(status == USBH_MSC_OK)
return RES_OK;
return RES_ERROR;
}
/*-----------------------------------------------------------------------*/
/* Write Sector(s) */
/*-----------------------------------------------------------------------*/
#if _READONLY == 0
DRESULT disk_write (
BYTE drv, /* Physical drive number (0) */
const BYTE *buff, /* Pointer to the data to be written */
DWORD sector, /* Start sector number (LBA) */
BYTE count /* Sector count (1..255) */
)
{
BYTE status = USBH_MSC_OK;
if (drv || !count) return RES_PARERR;
if (Stat & STA_NOINIT) return RES_NOTRDY;
if (Stat & STA_PROTECT) return RES_WRPRT;
if(HCD_IsDeviceConnected(&USB_OTG_Core))
{
do
{
status = USBH_MSC_Write10(&USB_OTG_Core,(BYTE*)buff,sector,512 * count);
USBH_MSC_HandleBOTXfer(&USB_OTG_Core, &USB_Host);
if(!HCD_IsDeviceConnected(&USB_OTG_Core))
{
return RES_ERROR;
}
}
while(status == USBH_MSC_BUSY );
}
if(status == USBH_MSC_OK)
return RES_OK;
return RES_ERROR;
}
#endif /* _READONLY == 0 */
/*-----------------------------------------------------------------------*/
/* Miscellaneous Functions */
/*-----------------------------------------------------------------------*/
#if _USE_IOCTL != 0
DRESULT disk_ioctl (
BYTE drv, /* Physical drive number (0) */
BYTE ctrl, /* Control code */
void *buff /* Buffer to send/receive control data */
)
{
DRESULT res = RES_OK;
if (drv) return RES_PARERR;
res = RES_ERROR;
if (Stat & STA_NOINIT) return RES_NOTRDY;
switch (ctrl) {
case CTRL_SYNC : /* Make sure that no pending write process */
res = RES_OK;
break;
case GET_SECTOR_COUNT : /* Get number of sectors on the disk (DWORD) */
*(DWORD*)buff = (DWORD) USBH_MSC_Param.MSCapacity;
res = RES_OK;
break;
case GET_SECTOR_SIZE : /* Get R/W sector size (WORD) */
*(WORD*)buff = 512;
res = RES_OK;
break;
case GET_BLOCK_SIZE : /* Get erase block size in unit of sector (DWORD) */
*(DWORD*)buff = 512;
break;
default:
res = RES_PARERR;
}
return res;
}
#endif /* _USE_IOCTL != 0 */

View File

@ -0,0 +1,680 @@
/**
******************************************************************************
* @file usbh_msc_scsi.c
* @author MCD Application Team
* @version V2.1.0
* @date 19-March-2012
* @brief This file implements the SCSI commands
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "usbh_msc_core.h"
#include "usbh_msc_scsi.h"
#include "usbh_msc_bot.h"
#include "usbh_ioreq.h"
#include "usbh_def.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
* @{
*/
MassStorageParameter_TypeDef USBH_MSC_Param;
/**
* @}
*/
/** @defgroup USBH_MSC_SCSI_Private_Defines
* @{
*/
/**
* @}
*/
/** @defgroup USBH_MSC_SCSI_Private_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBH_MSC_SCSI_Private_Variables
* @{
*/
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
__ALIGN_BEGIN uint8_t USBH_DataInBuffer[512] __ALIGN_END ;
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
__ALIGN_BEGIN uint8_t USBH_DataOutBuffer[512] __ALIGN_END ;
/**
* @}
*/
/** @defgroup USBH_MSC_SCSI_Private_FunctionPrototypes
* @{
*/
/**
* @}
*/
/** @defgroup USBH_MSC_SCSI_Exported_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USBH_MSC_SCSI_Private_Functions
* @{
*/
/**
* @brief USBH_MSC_TestUnitReady
* Issues 'Test unit ready' command to the device. Once the response
* received, it updates the status to upper layer.
* @param None
* @retval Status
*/
uint8_t USBH_MSC_TestUnitReady (USB_OTG_CORE_HANDLE *pdev)
{
uint8_t index;
USBH_MSC_Status_TypeDef status = USBH_MSC_BUSY;
if(HCD_IsDeviceConnected(pdev))
{
switch(USBH_MSC_BOTXferParam.CmdStateMachine)
{
case CMD_SEND_STATE:
/*Prepare the CBW and relevent field*/
USBH_MSC_CBWData.field.CBWTransferLength = 0; /* No Data Transfer */
USBH_MSC_CBWData.field.CBWFlags = USB_EP_DIR_OUT;
USBH_MSC_CBWData.field.CBWLength = CBW_LENGTH_TEST_UNIT_READY;
USBH_MSC_BOTXferParam.pRxTxBuff = USBH_MSC_CSWData.CSWArray;
USBH_MSC_BOTXferParam.DataLength = USBH_MSC_CSW_MAX_LENGTH;
USBH_MSC_BOTXferParam.MSCStateCurrent = USBH_MSC_TEST_UNIT_READY;
for(index = CBW_CB_LENGTH; index != 0; index--)
{
USBH_MSC_CBWData.field.CBWCB[index] = 0x00;
}
USBH_MSC_CBWData.field.CBWCB[0] = OPCODE_TEST_UNIT_READY;
USBH_MSC_BOTXferParam.BOTState = USBH_MSC_SEND_CBW;
/* Start the transfer, then let the state
machine magage the other transactions */
USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOT_USB_TRANSFERS;
USBH_MSC_BOTXferParam.BOTXferStatus = USBH_MSC_BUSY;
USBH_MSC_BOTXferParam.CmdStateMachine = CMD_WAIT_STATUS;
status = USBH_MSC_BUSY;
break;
case CMD_WAIT_STATUS:
if(USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_OK)
{
/* Commands successfully sent and Response Received */
USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
status = USBH_MSC_OK;
}
else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_FAIL )
{
/* Failure Mode */
USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
status = USBH_MSC_FAIL;
}
else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_PHASE_ERROR )
{
/* Failure Mode */
USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
status = USBH_MSC_PHASE_ERROR;
}
break;
default:
break;
}
}
return status;
}
/**
* @brief USBH_MSC_ReadCapacity10
* Issue the read capacity command to the device. Once the response
* received, it updates the status to upper layer
* @param None
* @retval Status
*/
uint8_t USBH_MSC_ReadCapacity10(USB_OTG_CORE_HANDLE *pdev)
{
uint8_t index;
USBH_MSC_Status_TypeDef status = USBH_MSC_BUSY;
if(HCD_IsDeviceConnected(pdev))
{
switch(USBH_MSC_BOTXferParam.CmdStateMachine)
{
case CMD_SEND_STATE:
/*Prepare the CBW and relevent field*/
USBH_MSC_CBWData.field.CBWTransferLength = XFER_LEN_READ_CAPACITY10;
USBH_MSC_CBWData.field.CBWFlags = USB_EP_DIR_IN;
USBH_MSC_CBWData.field.CBWLength = CBW_LENGTH;
USBH_MSC_BOTXferParam.pRxTxBuff = USBH_DataInBuffer;
USBH_MSC_BOTXferParam.MSCStateCurrent = USBH_MSC_READ_CAPACITY10;
for(index = CBW_CB_LENGTH; index != 0; index--)
{
USBH_MSC_CBWData.field.CBWCB[index] = 0x00;
}
USBH_MSC_CBWData.field.CBWCB[0] = OPCODE_READ_CAPACITY10;
USBH_MSC_BOTXferParam.BOTState = USBH_MSC_SEND_CBW;
/* Start the transfer, then let the state machine manage the other
transactions */
USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOT_USB_TRANSFERS;
USBH_MSC_BOTXferParam.BOTXferStatus = USBH_MSC_BUSY;
USBH_MSC_BOTXferParam.CmdStateMachine = CMD_WAIT_STATUS;
status = USBH_MSC_BUSY;
break;
case CMD_WAIT_STATUS:
if(USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_OK)
{
/*assign the capacity*/
(((uint8_t*)&USBH_MSC_Param.MSCapacity )[3]) = USBH_DataInBuffer[0];
(((uint8_t*)&USBH_MSC_Param.MSCapacity )[2]) = USBH_DataInBuffer[1];
(((uint8_t*)&USBH_MSC_Param.MSCapacity )[1]) = USBH_DataInBuffer[2];
(((uint8_t*)&USBH_MSC_Param.MSCapacity )[0]) = USBH_DataInBuffer[3];
/*assign the page length*/
(((uint8_t*)&USBH_MSC_Param.MSPageLength )[1]) = USBH_DataInBuffer[6];
(((uint8_t*)&USBH_MSC_Param.MSPageLength )[0]) = USBH_DataInBuffer[7];
/* Commands successfully sent and Response Received */
USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
status = USBH_MSC_OK;
}
else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_FAIL )
{
/* Failure Mode */
USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
status = USBH_MSC_FAIL;
}
else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_PHASE_ERROR )
{
/* Failure Mode */
USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
status = USBH_MSC_PHASE_ERROR;
}
else
{
/* Wait for the Commands to get Completed */
/* NO Change in state Machine */
}
break;
default:
break;
}
}
return status;
}
/**
* @brief USBH_MSC_ModeSense6
* Issue the Mode Sense6 Command to the device. This function is used
* for reading the WriteProtect Status of the Mass-Storage device.
* @param None
* @retval Status
*/
uint8_t USBH_MSC_ModeSense6(USB_OTG_CORE_HANDLE *pdev)
{
uint8_t index;
USBH_MSC_Status_TypeDef status = USBH_MSC_BUSY;
if(HCD_IsDeviceConnected(pdev))
{
switch(USBH_MSC_BOTXferParam.CmdStateMachine)
{
case CMD_SEND_STATE:
/*Prepare the CBW and relevent field*/
USBH_MSC_CBWData.field.CBWTransferLength = XFER_LEN_MODE_SENSE6;
USBH_MSC_CBWData.field.CBWFlags = USB_EP_DIR_IN;
USBH_MSC_CBWData.field.CBWLength = CBW_LENGTH;
USBH_MSC_BOTXferParam.pRxTxBuff = USBH_DataInBuffer;
USBH_MSC_BOTXferParam.MSCStateCurrent = USBH_MSC_MODE_SENSE6;
for(index = CBW_CB_LENGTH; index != 0; index--)
{
USBH_MSC_CBWData.field.CBWCB[index] = 0x00;
}
USBH_MSC_CBWData.field.CBWCB[0] = OPCODE_MODE_SENSE6;
USBH_MSC_CBWData.field.CBWCB[2] = MODE_SENSE_PAGE_CONTROL_FIELD | \
MODE_SENSE_PAGE_CODE;
USBH_MSC_CBWData.field.CBWCB[4] = XFER_LEN_MODE_SENSE6;
USBH_MSC_BOTXferParam.BOTState = USBH_MSC_SEND_CBW;
/* Start the transfer, then let the state machine manage the other
transactions */
USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOT_USB_TRANSFERS;
USBH_MSC_BOTXferParam.BOTXferStatus = USBH_MSC_BUSY;
USBH_MSC_BOTXferParam.CmdStateMachine = CMD_WAIT_STATUS;
status = USBH_MSC_BUSY;
break;
case CMD_WAIT_STATUS:
if(USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_OK)
{
/* Assign the Write Protect status */
/* If WriteProtect = 0, Writing is allowed
If WriteProtect != 0, Disk is Write Protected */
if ( USBH_DataInBuffer[2] & MASK_MODE_SENSE_WRITE_PROTECT)
{
USBH_MSC_Param.MSWriteProtect = DISK_WRITE_PROTECTED;
}
else
{
USBH_MSC_Param.MSWriteProtect = 0;
}
/* Commands successfully sent and Response Received */
USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
status = USBH_MSC_OK;
}
else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_FAIL )
{
/* Failure Mode */
USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
status = USBH_MSC_FAIL;
}
else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_PHASE_ERROR )
{
/* Failure Mode */
USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
status = USBH_MSC_PHASE_ERROR;
}
else
{
/* Wait for the Commands to get Completed */
/* NO Change in state Machine */
}
break;
default:
break;
}
}
return status;
}
/**
* @brief USBH_MSC_RequestSense
* Issues the Request Sense command to the device. Once the response
* received, it updates the status to upper layer
* @param None
* @retval Status
*/
uint8_t USBH_MSC_RequestSense(USB_OTG_CORE_HANDLE *pdev)
{
USBH_MSC_Status_TypeDef status = USBH_MSC_BUSY;
uint8_t index;
if(HCD_IsDeviceConnected(pdev))
{
switch(USBH_MSC_BOTXferParam.CmdStateMachine)
{
case CMD_SEND_STATE:
/*Prepare the CBW and relevent field*/
USBH_MSC_CBWData.field.CBWTransferLength = \
ALLOCATION_LENGTH_REQUEST_SENSE;
USBH_MSC_CBWData.field.CBWFlags = USB_EP_DIR_IN;
USBH_MSC_CBWData.field.CBWLength = CBW_LENGTH;
USBH_MSC_BOTXferParam.pRxTxBuff = USBH_DataInBuffer;
USBH_MSC_BOTXferParam.MSCStateBkp = USBH_MSC_BOTXferParam.MSCStateCurrent;
USBH_MSC_BOTXferParam.MSCStateCurrent = USBH_MSC_REQUEST_SENSE;
for(index = CBW_CB_LENGTH; index != 0; index--)
{
USBH_MSC_CBWData.field.CBWCB[index] = 0x00;
}
USBH_MSC_CBWData.field.CBWCB[0] = OPCODE_REQUEST_SENSE;
USBH_MSC_CBWData.field.CBWCB[1] = DESC_REQUEST_SENSE;
USBH_MSC_CBWData.field.CBWCB[4] = ALLOCATION_LENGTH_REQUEST_SENSE;
USBH_MSC_BOTXferParam.BOTState = USBH_MSC_SEND_CBW;
/* Start the transfer, then let the state machine magage
the other transactions */
USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOT_USB_TRANSFERS;
USBH_MSC_BOTXferParam.BOTXferStatus = USBH_MSC_BUSY;
USBH_MSC_BOTXferParam.CmdStateMachine = CMD_WAIT_STATUS;
status = USBH_MSC_BUSY;
break;
case CMD_WAIT_STATUS:
if(USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_OK)
{
/* Get Sense data*/
(((uint8_t*)&USBH_MSC_Param.MSSenseKey )[3]) = USBH_DataInBuffer[0];
(((uint8_t*)&USBH_MSC_Param.MSSenseKey )[2]) = USBH_DataInBuffer[1];
(((uint8_t*)&USBH_MSC_Param.MSSenseKey )[1]) = USBH_DataInBuffer[2];
(((uint8_t*)&USBH_MSC_Param.MSSenseKey )[0]) = USBH_DataInBuffer[3];
/* Commands successfully sent and Response Received */
USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
status = USBH_MSC_OK;
}
else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_FAIL )
{
/* Failure Mode */
USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
status = USBH_MSC_FAIL;
}
else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_PHASE_ERROR )
{
/* Failure Mode */
USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
status = USBH_MSC_PHASE_ERROR;
}
else
{
/* Wait for the Commands to get Completed */
/* NO Change in state Machine */
}
break;
default:
break;
}
}
return status;
}
/**
* @brief USBH_MSC_Write10
* Issue the write command to the device. Once the response received,
* it updates the status to upper layer
* @param dataBuffer : DataBuffer contains the data to write
* @param address : Address to which the data will be written
* @param nbOfbytes : NbOfbytes to be written
* @retval Status
*/
uint8_t USBH_MSC_Write10(USB_OTG_CORE_HANDLE *pdev,
uint8_t *dataBuffer,
uint32_t address,
uint32_t nbOfbytes)
{
uint8_t index;
USBH_MSC_Status_TypeDef status = USBH_MSC_BUSY;
uint16_t nbOfPages;
if(HCD_IsDeviceConnected(pdev))
{
switch(USBH_MSC_BOTXferParam.CmdStateMachine)
{
case CMD_SEND_STATE:
USBH_MSC_CBWData.field.CBWTransferLength = nbOfbytes;
USBH_MSC_CBWData.field.CBWFlags = USB_EP_DIR_OUT;
USBH_MSC_CBWData.field.CBWLength = CBW_LENGTH;
USBH_MSC_BOTXferParam.pRxTxBuff = dataBuffer;
for(index = CBW_CB_LENGTH; index != 0; index--)
{
USBH_MSC_CBWData.field.CBWCB[index] = 0x00;
}
USBH_MSC_CBWData.field.CBWCB[0] = OPCODE_WRITE10;
/*logical block address*/
USBH_MSC_CBWData.field.CBWCB[2] = (((uint8_t*)&address)[3]) ;
USBH_MSC_CBWData.field.CBWCB[3] = (((uint8_t*)&address)[2]);
USBH_MSC_CBWData.field.CBWCB[4] = (((uint8_t*)&address)[1]);
USBH_MSC_CBWData.field.CBWCB[5] = (((uint8_t*)&address)[0]);
/*USBH_MSC_PAGE_LENGTH = 512*/
nbOfPages = nbOfbytes/ USBH_MSC_PAGE_LENGTH;
/*Tranfer length */
USBH_MSC_CBWData.field.CBWCB[7] = (((uint8_t *)&nbOfPages)[1]) ;
USBH_MSC_CBWData.field.CBWCB[8] = (((uint8_t *)&nbOfPages)[0]) ;
USBH_MSC_BOTXferParam.BOTState = USBH_MSC_SEND_CBW;
/* Start the transfer, then let the state machine
magage the other transactions */
USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOT_USB_TRANSFERS;
USBH_MSC_BOTXferParam.BOTXferStatus = USBH_MSC_BUSY;
USBH_MSC_BOTXferParam.CmdStateMachine = CMD_WAIT_STATUS;
status = USBH_MSC_BUSY;
break;
case CMD_WAIT_STATUS:
if(USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_OK)
{
/* Commands successfully sent and Response Received */
USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
status = USBH_MSC_OK;
}
else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_FAIL )
{
/* Failure Mode */
USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
}
else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_PHASE_ERROR )
{
/* Failure Mode */
USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
status = USBH_MSC_PHASE_ERROR;
}
break;
default:
break;
}
}
return status;
}
/**
* @brief USBH_MSC_Read10
* Issue the read command to the device. Once the response received,
* it updates the status to upper layer
* @param dataBuffer : DataBuffer will contain the data to be read
* @param address : Address from which the data will be read
* @param nbOfbytes : NbOfbytes to be read
* @retval Status
*/
uint8_t USBH_MSC_Read10(USB_OTG_CORE_HANDLE *pdev,
uint8_t *dataBuffer,
uint32_t address,
uint32_t nbOfbytes)
{
uint8_t index;
static USBH_MSC_Status_TypeDef status = USBH_MSC_BUSY;
uint16_t nbOfPages;
status = USBH_MSC_BUSY;
if(HCD_IsDeviceConnected(pdev))
{
switch(USBH_MSC_BOTXferParam.CmdStateMachine)
{
case CMD_SEND_STATE:
/*Prepare the CBW and relevent field*/
USBH_MSC_CBWData.field.CBWTransferLength = nbOfbytes;
USBH_MSC_CBWData.field.CBWFlags = USB_EP_DIR_IN;
USBH_MSC_CBWData.field.CBWLength = CBW_LENGTH;
USBH_MSC_BOTXferParam.pRxTxBuff = dataBuffer;
for(index = CBW_CB_LENGTH; index != 0; index--)
{
USBH_MSC_CBWData.field.CBWCB[index] = 0x00;
}
USBH_MSC_CBWData.field.CBWCB[0] = OPCODE_READ10;
/*logical block address*/
USBH_MSC_CBWData.field.CBWCB[2] = (((uint8_t*)&address)[3]);
USBH_MSC_CBWData.field.CBWCB[3] = (((uint8_t*)&address)[2]);
USBH_MSC_CBWData.field.CBWCB[4] = (((uint8_t*)&address)[1]);
USBH_MSC_CBWData.field.CBWCB[5] = (((uint8_t*)&address)[0]);
/*USBH_MSC_PAGE_LENGTH = 512*/
nbOfPages = nbOfbytes/ USBH_MSC_PAGE_LENGTH;
/*Tranfer length */
USBH_MSC_CBWData.field.CBWCB[7] = (((uint8_t *)&nbOfPages)[1]) ;
USBH_MSC_CBWData.field.CBWCB[8] = (((uint8_t *)&nbOfPages)[0]) ;
USBH_MSC_BOTXferParam.BOTState = USBH_MSC_SEND_CBW;
/* Start the transfer, then let the state machine
magage the other transactions */
USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOT_USB_TRANSFERS;
USBH_MSC_BOTXferParam.BOTXferStatus = USBH_MSC_BUSY;
USBH_MSC_BOTXferParam.CmdStateMachine = CMD_WAIT_STATUS;
status = USBH_MSC_BUSY;
break;
case CMD_WAIT_STATUS:
if((USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_OK) && \
(HCD_IsDeviceConnected(pdev)))
{
/* Commands successfully sent and Response Received */
USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
status = USBH_MSC_OK;
}
else if (( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_FAIL ) && \
(HCD_IsDeviceConnected(pdev)))
{
/* Failure Mode */
USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
}
else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_PHASE_ERROR )
{
/* Failure Mode */
USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
status = USBH_MSC_PHASE_ERROR;
}
else
{
/* Wait for the Commands to get Completed */
/* NO Change in state Machine */
}
break;
default:
break;
}
}
return status;
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,101 @@
/**
******************************************************************************
* @file usbh_conf_template
* @author MCD Application Team
* @version V2.1.0
* @date 19-March-2012
* @brief General USB Host library configuration
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USBH_CONF__H__
#define __USBH_CONF__H__
/* Includes ------------------------------------------------------------------*/
/** @addtogroup USBH_OTG_DRIVER
* @{
*/
/** @defgroup USBH_CONF
* @brief usb otg low level driver configuration file
* @{
*/
/** @defgroup USBH_CONF_Exported_Defines
* @{
*/
#define USBH_MAX_NUM_ENDPOINTS 2
#define USBH_MAX_NUM_INTERFACES 2
#ifdef USE_USB_OTG_FS
#define USBH_MSC_MPS_SIZE 0x40
#else
#define USBH_MSC_MPS_SIZE 0x200
#endif
/**
* @}
*/
/** @defgroup USBH_CONF_Exported_Types
* @{
*/
/**
* @}
*/
/** @defgroup USBH_CONF_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBH_CONF_Exported_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USBH_CONF_Exported_FunctionsPrototype
* @{
*/
/**
* @}
*/
#endif //__USBH_CONF__H__
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,295 @@
/**
******************************************************************************
* @file usbh_core.h
* @author MCD Application Team
* @version V2.1.0
* @date 19-March-2012
* @brief Header file for usbh_core.c
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Define to prevent recursive ----------------------------------------------*/
#ifndef __USBH_CORE_H
#define __USBH_CORE_H
/* Includes ------------------------------------------------------------------*/
#include "usb_hcd.h"
#include "usbh_def.h"
#include "usbh_conf.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 MSC_CLASS 0x08
#define HID_CLASS 0x03
#define MSC_PROTOCOL 0x50
#define CBI_PROTOCOL 0x01
#define USBH_MAX_ERROR_COUNT 2
#define USBH_DEVICE_ADDRESS_DEFAULT 0
#define USBH_DEVICE_ADDRESS 1
/**
* @}
*/
/** @defgroup USBH_CORE_Exported_Types
* @{
*/
typedef enum {
USBH_OK = 0,
USBH_BUSY,
USBH_FAIL,
USBH_NOT_SUPPORTED,
USBH_UNRECOVERED_ERROR,
USBH_ERROR_SPEED_UNKNOWN,
USBH_APPLY_DEINIT
}USBH_Status;
/* Following states are used for gState */
typedef enum {
HOST_IDLE =0,
HOST_DEV_ATTACHED,
HOST_DEV_DISCONNECTED,
HOST_DETECT_DEVICE_SPEED,
HOST_ENUMERATION,
HOST_CLASS_REQUEST,
HOST_CLASS,
HOST_CTRL_XFER,
HOST_USR_INPUT,
HOST_SUSPENDED,
HOST_ERROR_STATE
}HOST_State;
/* Following states are used for EnumerationState */
typedef enum {
ENUM_IDLE = 0,
ENUM_GET_FULL_DEV_DESC,
ENUM_SET_ADDR,
ENUM_GET_CFG_DESC,
ENUM_GET_FULL_CFG_DESC,
ENUM_GET_MFC_STRING_DESC,
ENUM_GET_PRODUCT_STRING_DESC,
ENUM_GET_SERIALNUM_STRING_DESC,
ENUM_SET_CONFIGURATION,
ENUM_DEV_CONFIGURED
} ENUM_State;
/* Following states are used for CtrlXferStateMachine */
typedef enum {
CTRL_IDLE =0,
CTRL_SETUP,
CTRL_SETUP_WAIT,
CTRL_DATA_IN,
CTRL_DATA_IN_WAIT,
CTRL_DATA_OUT,
CTRL_DATA_OUT_WAIT,
CTRL_STATUS_IN,
CTRL_STATUS_IN_WAIT,
CTRL_STATUS_OUT,
CTRL_STATUS_OUT_WAIT,
CTRL_ERROR,
CTRL_STALLED,
CTRL_COMPLETE
}
CTRL_State;
typedef enum {
USBH_USR_NO_RESP = 0,
USBH_USR_RESP_OK = 1,
}
USBH_USR_Status;
/* Following states are used for RequestState */
typedef enum {
CMD_IDLE =0,
CMD_SEND,
CMD_WAIT
} CMD_State;
typedef struct _Ctrl
{
uint8_t hc_num_in;
uint8_t hc_num_out;
uint8_t ep0size;
uint8_t *buff;
uint16_t length;
uint8_t errorcount;
uint16_t timer;
CTRL_STATUS status;
USB_Setup_TypeDef setup;
CTRL_State state;
} USBH_Ctrl_TypeDef;
typedef struct _DeviceProp
{
uint8_t address;
uint8_t speed;
USBH_DevDesc_TypeDef Dev_Desc;
USBH_CfgDesc_TypeDef Cfg_Desc;
USBH_InterfaceDesc_TypeDef Itf_Desc[USBH_MAX_NUM_INTERFACES];
USBH_EpDesc_TypeDef Ep_Desc[USBH_MAX_NUM_INTERFACES][USBH_MAX_NUM_ENDPOINTS];
USBH_HIDDesc_TypeDef HID_Desc;
}USBH_Device_TypeDef;
typedef struct _USBH_Class_cb
{
USBH_Status (*Init)\
(USB_OTG_CORE_HANDLE *pdev , void *phost);
void (*DeInit)\
(USB_OTG_CORE_HANDLE *pdev , void *phost);
USBH_Status (*Requests)\
(USB_OTG_CORE_HANDLE *pdev , void *phost);
USBH_Status (*Machine)\
(USB_OTG_CORE_HANDLE *pdev , void *phost);
} USBH_Class_cb_TypeDef;
typedef struct _USBH_USR_PROP
{
void (*Init)(void); /* HostLibInitialized */
void (*DeInit)(void); /* HostLibInitialized */
void (*DeviceAttached)(void); /* DeviceAttached */
void (*ResetDevice)(void);
void (*DeviceDisconnected)(void);
void (*OverCurrentDetected)(void);
void (*DeviceSpeedDetected)(uint8_t DeviceSpeed); /* DeviceSpeed */
void (*DeviceDescAvailable)(void *); /* DeviceDescriptor is available */
void (*DeviceAddressAssigned)(void); /* Address is assigned to USB Device */
void (*ConfigurationDescAvailable)(USBH_CfgDesc_TypeDef *,
USBH_InterfaceDesc_TypeDef *,
USBH_EpDesc_TypeDef *);
/* Configuration Descriptor available */
void (*ManufacturerString)(void *); /* ManufacturerString*/
void (*ProductString)(void *); /* ProductString*/
void (*SerialNumString)(void *); /* SerialNubString*/
void (*EnumerationDone)(void); /* Enumeration finished */
USBH_USR_Status (*UserInput)(void);
int (*UserApplication) (void);
void (*DeviceNotSupported)(void); /* Device is not supported*/
void (*UnrecoveredError)(void);
}
USBH_Usr_cb_TypeDef;
typedef struct _Host_TypeDef
{
HOST_State gState; /* Host State Machine Value */
HOST_State gStateBkp; /* backup of previous State machine value */
ENUM_State EnumState; /* Enumeration state Machine */
CMD_State RequestState;
USBH_Ctrl_TypeDef Control;
USBH_Device_TypeDef device_prop;
USBH_Class_cb_TypeDef *class_cb;
USBH_Usr_cb_TypeDef *usr_cb;
} USBH_HOST, *pUSBH_HOST;
/**
* @}
*/
/** @defgroup USBH_CORE_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBH_CORE_Exported_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USBH_CORE_Exported_FunctionsPrototype
* @{
*/
void USBH_Init(USB_OTG_CORE_HANDLE *pdev,
USB_OTG_CORE_ID_TypeDef coreID,
USBH_HOST *phost,
USBH_Class_cb_TypeDef *class_cb,
USBH_Usr_cb_TypeDef *usr_cb);
USBH_Status USBH_DeInit(USB_OTG_CORE_HANDLE *pdev,
USBH_HOST *phost);
void USBH_Process(USB_OTG_CORE_HANDLE *pdev ,
USBH_HOST *phost);
void USBH_ErrorHandle(USBH_HOST *phost,
USBH_Status errType);
/**
* @}
*/
#endif /* __USBH_CORE_H */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,288 @@
/**
******************************************************************************
* @file usbh_def.h
* @author MCD Application Team
* @version V2.1.0
* @date 19-March-2012
* @brief Definitions used in the USB host library
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/** @addtogroup USBH_LIB
* @{
*/
/** @addtogroup USBH_LIB_CORE
* @{
*/
/** @defgroup USBH_DEF
* @brief This file is includes USB descriptors
* @{
*/
#ifndef USBH_DEF_H
#define USBH_DEF_H
#ifndef USBH_NULL
#define USBH_NULL ((void *)0)
#endif
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
#define ValBit(VAR,POS) (VAR & (1 << POS))
#define SetBit(VAR,POS) (VAR |= (1 << POS))
#define ClrBit(VAR,POS) (VAR &= ((1 << POS)^255))
#define LE16(addr) (((u16)(*((u8 *)(addr))))\
+ (((u16)(*(((u8 *)(addr)) + 1))) << 8))
#define USB_LEN_DESC_HDR 0x02
#define USB_LEN_DEV_DESC 0x12
#define USB_LEN_CFG_DESC 0x09
#define USB_LEN_IF_DESC 0x09
#define USB_LEN_EP_DESC 0x07
#define USB_LEN_OTG_DESC 0x03
#define USB_LEN_SETUP_PKT 0x08
/* bmRequestType :D7 Data Phase Transfer Direction */
#define USB_REQ_DIR_MASK 0x80
#define USB_H2D 0x00
#define USB_D2H 0x80
/* bmRequestType D6..5 Type */
#define USB_REQ_TYPE_STANDARD 0x00
#define USB_REQ_TYPE_CLASS 0x20
#define USB_REQ_TYPE_VENDOR 0x40
#define USB_REQ_TYPE_RESERVED 0x60
/* bmRequestType D4..0 Recipient */
#define USB_REQ_RECIPIENT_DEVICE 0x00
#define USB_REQ_RECIPIENT_INTERFACE 0x01
#define USB_REQ_RECIPIENT_ENDPOINT 0x02
#define USB_REQ_RECIPIENT_OTHER 0x03
/* Table 9-4. Standard Request Codes */
/* bRequest , Value */
#define USB_REQ_GET_STATUS 0x00
#define USB_REQ_CLEAR_FEATURE 0x01
#define USB_REQ_SET_FEATURE 0x03
#define USB_REQ_SET_ADDRESS 0x05
#define USB_REQ_GET_DESCRIPTOR 0x06
#define USB_REQ_SET_DESCRIPTOR 0x07
#define USB_REQ_GET_CONFIGURATION 0x08
#define USB_REQ_SET_CONFIGURATION 0x09
#define USB_REQ_GET_INTERFACE 0x0A
#define USB_REQ_SET_INTERFACE 0x0B
#define USB_REQ_SYNCH_FRAME 0x0C
/* Table 9-5. Descriptor Types of USB Specifications */
#define USB_DESC_TYPE_DEVICE 1
#define USB_DESC_TYPE_CONFIGURATION 2
#define USB_DESC_TYPE_STRING 3
#define USB_DESC_TYPE_INTERFACE 4
#define USB_DESC_TYPE_ENDPOINT 5
#define USB_DESC_TYPE_DEVICE_QUALIFIER 6
#define USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION 7
#define USB_DESC_TYPE_INTERFACE_POWER 8
#define USB_DESC_TYPE_HID 0x21
#define USB_DESC_TYPE_HID_REPORT 0x22
#define USB_DEVICE_DESC_SIZE 18
#define USB_CONFIGURATION_DESC_SIZE 9
#define USB_HID_DESC_SIZE 9
#define USB_INTERFACE_DESC_SIZE 9
#define USB_ENDPOINT_DESC_SIZE 7
/* Descriptor Type and Descriptor Index */
/* Use the following values when calling the function USBH_GetDescriptor */
#define USB_DESC_DEVICE ((USB_DESC_TYPE_DEVICE << 8) & 0xFF00)
#define USB_DESC_CONFIGURATION ((USB_DESC_TYPE_CONFIGURATION << 8) & 0xFF00)
#define USB_DESC_STRING ((USB_DESC_TYPE_STRING << 8) & 0xFF00)
#define USB_DESC_INTERFACE ((USB_DESC_TYPE_INTERFACE << 8) & 0xFF00)
#define USB_DESC_ENDPOINT ((USB_DESC_TYPE_INTERFACE << 8) & 0xFF00)
#define USB_DESC_DEVICE_QUALIFIER ((USB_DESC_TYPE_DEVICE_QUALIFIER << 8) & 0xFF00)
#define USB_DESC_OTHER_SPEED_CONFIGURATION ((USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION << 8) & 0xFF00)
#define USB_DESC_INTERFACE_POWER ((USB_DESC_TYPE_INTERFACE_POWER << 8) & 0xFF00)
#define USB_DESC_HID_REPORT ((USB_DESC_TYPE_HID_REPORT << 8) & 0xFF00)
#define USB_DESC_HID ((USB_DESC_TYPE_HID << 8) & 0xFF00)
#define USB_EP_TYPE_CTRL 0x00
#define USB_EP_TYPE_ISOC 0x01
#define USB_EP_TYPE_BULK 0x02
#define USB_EP_TYPE_INTR 0x03
#define USB_EP_DIR_OUT 0x00
#define USB_EP_DIR_IN 0x80
#define USB_EP_DIR_MSK 0x80
/* supported classes */
#define USB_MSC_CLASS 0x08
#define USB_HID_CLASS 0x03
/* Interface Descriptor field values for HID Boot Protocol */
#define HID_BOOT_CODE 0x01
#define HID_KEYBRD_BOOT_CODE 0x01
#define HID_MOUSE_BOOT_CODE 0x02
/* As per USB specs 9.2.6.4 :Standard request with data request timeout: 5sec
Standard request with no data stage timeout : 50ms */
#define DATA_STAGE_TIMEOUT 5000
#define NODATA_STAGE_TIMEOUT 50
/**
* @}
*/
#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)
/* This Union is copied from usb_core.h */
typedef union
{
uint16_t w;
struct BW
{
uint8_t msb;
uint8_t lsb;
}
bw;
}
uint16_t_uint8_t;
typedef union _USB_Setup
{
uint8_t d8[8];
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_DevDesc_TypeDef;
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_CfgDesc_TypeDef;
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. */
}
USBH_HIDDesc_TypeDef;
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_InterfaceDesc_TypeDef;
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_EpDesc_TypeDef;
#endif
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,129 @@
/**
******************************************************************************
* @file usbh_hcs.h
* @author MCD Application Team
* @version V2.1.0
* @date 19-March-2012
* @brief Header file for usbh_hcs.c
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Define to prevent recursive ----------------------------------------------*/
#ifndef __USBH_HCS_H
#define __USBH_HCS_H
/* Includes ------------------------------------------------------------------*/
#include "usbh_core.h"
/** @addtogroup USBH_LIB
* @{
*/
/** @addtogroup USBH_LIB_CORE
* @{
*/
/** @defgroup USBH_HCS
* @brief This file is the header file for usbh_hcs.c
* @{
*/
/** @defgroup USBH_HCS_Exported_Defines
* @{
*/
#define HC_MAX 8
#define HC_OK 0x0000
#define HC_USED 0x8000
#define HC_ERROR 0xFFFF
#define HC_USED_MASK 0x7FFF
/**
* @}
*/
/** @defgroup USBH_HCS_Exported_Types
* @{
*/
/**
* @}
*/
/** @defgroup USBH_HCS_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBH_HCS_Exported_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USBH_HCS_Exported_FunctionsPrototype
* @{
*/
uint8_t USBH_Alloc_Channel(USB_OTG_CORE_HANDLE *pdev, uint8_t ep_addr);
uint8_t USBH_Free_Channel (USB_OTG_CORE_HANDLE *pdev, uint8_t idx);
uint8_t USBH_DeAllocate_AllChannel (USB_OTG_CORE_HANDLE *pdev);
uint8_t USBH_Open_Channel (USB_OTG_CORE_HANDLE *pdev,
uint8_t ch_num,
uint8_t dev_address,
uint8_t speed,
uint8_t ep_type,
uint16_t mps);
uint8_t USBH_Modify_Channel (USB_OTG_CORE_HANDLE *pdev,
uint8_t hc_num,
uint8_t dev_address,
uint8_t speed,
uint8_t ep_type,
uint16_t mps);
/**
* @}
*/
#endif /* __USBH_HCS_H */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,156 @@
/**
******************************************************************************
* @file usbh_ioreq.h
* @author MCD Application Team
* @version V2.1.0
* @date 19-March-2012
* @brief Header file for usbh_ioreq.c
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Define to prevent recursive ----------------------------------------------*/
#ifndef __USBH_IOREQ_H
#define __USBH_IOREQ_H
/* Includes ------------------------------------------------------------------*/
#include "usb_conf.h"
#include "usbh_core.h"
#include "usbh_def.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_SETUP_PKT_SIZE 8
#define USBH_EP0_EP_NUM 0
#define USBH_MAX_PACKET_SIZE 0x40
/**
* @}
*/
/** @defgroup USBH_IOREQ_Exported_Types
* @{
*/
/**
* @}
*/
/** @defgroup USBH_IOREQ_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBH_IOREQ_Exported_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USBH_IOREQ_Exported_FunctionsPrototype
* @{
*/
USBH_Status USBH_CtlSendSetup ( USB_OTG_CORE_HANDLE *pdev,
uint8_t *buff,
uint8_t hc_num);
USBH_Status USBH_CtlSendData ( USB_OTG_CORE_HANDLE *pdev,
uint8_t *buff,
uint16_t length,
uint8_t hc_num);
USBH_Status USBH_CtlReceiveData( USB_OTG_CORE_HANDLE *pdev,
uint8_t *buff,
uint16_t length,
uint8_t hc_num);
USBH_Status USBH_BulkReceiveData( USB_OTG_CORE_HANDLE *pdev,
uint8_t *buff,
uint16_t length,
uint8_t hc_num);
USBH_Status USBH_BulkSendData ( USB_OTG_CORE_HANDLE *pdev,
uint8_t *buff,
uint16_t length,
uint8_t hc_num);
USBH_Status USBH_InterruptReceiveData( USB_OTG_CORE_HANDLE *pdev,
uint8_t *buff,
uint8_t length,
uint8_t hc_num);
USBH_Status USBH_InterruptSendData( USB_OTG_CORE_HANDLE *pdev,
uint8_t *buff,
uint8_t length,
uint8_t hc_num);
USBH_Status USBH_CtlReq (USB_OTG_CORE_HANDLE *pdev,
USBH_HOST *phost,
uint8_t *buff,
uint16_t length);
USBH_Status USBH_IsocReceiveData( USB_OTG_CORE_HANDLE *pdev,
uint8_t *buff,
uint32_t length,
uint8_t hc_num);
USBH_Status USBH_IsocSendData( USB_OTG_CORE_HANDLE *pdev,
uint8_t *buff,
uint32_t length,
uint8_t hc_num);
/**
* @}
*/
#endif /* __USBH_IOREQ_H */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,161 @@
/**
******************************************************************************
* @file usbh_stdreq.h
* @author MCD Application Team
* @version V2.1.0
* @date 19-March-2012
* @brief Header file for usbh_stdreq.c
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Define to prevent recursive ----------------------------------------------*/
#ifndef __USBH_STDREQ_H
#define __USBH_STDREQ_H
/* Includes ------------------------------------------------------------------*/
#include "usb_conf.h"
#include "usb_hcd.h"
#include "usbh_core.h"
#include "usbh_def.h"
/** @addtogroup USBH_LIB
* @{
*/
/** @addtogroup USBH_LIB_CORE
* @{
*/
/** @defgroup USBH_STDREQ
* @brief This file is the
* @{
*/
/** @defgroup USBH_STDREQ_Exported_Defines
* @{
*/
/*Standard Feature Selector for clear feature command*/
#define FEATURE_SELECTOR_ENDPOINT 0X00
#define FEATURE_SELECTOR_DEVICE 0X01
#define INTERFACE_DESC_TYPE 0x04
#define ENDPOINT_DESC_TYPE 0x05
#define INTERFACE_DESC_SIZE 0x09
#define USBH_HID_CLASS 0x03
/**
* @}
*/
/** @defgroup USBH_STDREQ_Exported_Types
* @{
*/
/**
* @}
*/
/** @defgroup USBH_STDREQ_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBH_STDREQ_Exported_Variables
* @{
*/
extern uint8_t USBH_CfgDesc[512];
/**
* @}
*/
/** @defgroup USBH_STDREQ_Exported_FunctionsPrototype
* @{
*/
USBH_Status USBH_GetDescriptor(USB_OTG_CORE_HANDLE *pdev,
USBH_HOST *phost,
uint8_t req_type,
uint16_t value_idx,
uint8_t* buff,
uint16_t length );
USBH_Status USBH_Get_DevDesc(USB_OTG_CORE_HANDLE *pdev,
USBH_HOST *phost,
uint8_t length);
USBH_Status USBH_Get_StringDesc(USB_OTG_CORE_HANDLE *pdev,
USBH_HOST *phost,
uint8_t string_index,
uint8_t *buff,
uint16_t length);
USBH_Status USBH_SetCfg(USB_OTG_CORE_HANDLE *pdev,
USBH_HOST *phost,
uint16_t configuration_value);
USBH_Status USBH_Get_CfgDesc(USB_OTG_CORE_HANDLE *pdev,
USBH_HOST *phost,
uint16_t length);
USBH_Status USBH_SetAddress(USB_OTG_CORE_HANDLE *pdev,
USBH_HOST *phost,
uint8_t DeviceAddress);
USBH_Status USBH_ClrFeature(USB_OTG_CORE_HANDLE *pdev,
USBH_HOST *phost,
uint8_t ep_num, uint8_t hc_num);
USBH_Status USBH_SetInterface(USB_OTG_CORE_HANDLE *pdev,
USBH_HOST *phost,
uint8_t ep_num, uint8_t altSetting);
USBH_Status USBH_Issue_ClrFeature(USB_OTG_CORE_HANDLE *pdev,
USBH_HOST *phost,
uint8_t ep_num);
USBH_DescHeader_t *USBH_GetNextDesc (uint8_t *pbuf,
uint16_t *ptr);
/**
* @}
*/
#endif /* __USBH_STDREQ_H */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,857 @@
/**
******************************************************************************
* @file usbh_core.c
* @author MCD Application Team
* @version V2.1.0
* @date 19-March-2012
* @brief This file implements the functions for the core state machine process
* the enumeration and the control transfer process
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "usbh_ioreq.h"
#include "usb_bsp.h"
#include "usbh_hcs.h"
#include "usbh_stdreq.h"
#include "usbh_core.h"
#include "usb_hcd_int.h"
/** @addtogroup USBH_LIB
* @{
*/
/** @addtogroup USBH_LIB_CORE
* @{
*/
/** @defgroup USBH_CORE
* @brief TThis file handles the basic enumaration when a device is connected
* to the host.
* @{
*/
/** @defgroup USBH_CORE_Private_TypesDefinitions
* @{
*/
uint8_t USBH_Disconnected (USB_OTG_CORE_HANDLE *pdev);
uint8_t USBH_Connected (USB_OTG_CORE_HANDLE *pdev);
uint8_t USBH_SOF (USB_OTG_CORE_HANDLE *pdev);
USBH_HCD_INT_cb_TypeDef USBH_HCD_INT_cb =
{
USBH_SOF,
USBH_Connected,
USBH_Disconnected,
};
USBH_HCD_INT_cb_TypeDef *USBH_HCD_INT_fops = &USBH_HCD_INT_cb;
/**
* @}
*/
/** @defgroup USBH_CORE_Private_Defines
* @{
*/
/**
* @}
*/
/** @defgroup USBH_CORE_Private_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBH_CORE_Private_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USBH_CORE_Private_FunctionPrototypes
* @{
*/
static USBH_Status USBH_HandleEnum(USB_OTG_CORE_HANDLE *pdev, USBH_HOST *phost);
USBH_Status USBH_HandleControl (USB_OTG_CORE_HANDLE *pdev, USBH_HOST *phost);
/**
* @}
*/
/** @defgroup USBH_CORE_Private_Functions
* @{
*/
/**
* @brief USBH_Connected
* USB Connect callback function from the Interrupt.
* @param selected device
* @retval Status
*/
uint8_t USBH_Connected (USB_OTG_CORE_HANDLE *pdev)
{
pdev->host.ConnSts = 1;
return 0;
}
/**
* @brief USBH_Disconnected
* USB Disconnect callback function from the Interrupt.
* @param selected device
* @retval Status
*/
uint8_t USBH_Disconnected (USB_OTG_CORE_HANDLE *pdev)
{
pdev->host.ConnSts = 0;
return 0;
}
/**
* @brief USBH_SOF
* USB SOF callback function from the Interrupt.
* @param selected device
* @retval Status
*/
uint8_t USBH_SOF (USB_OTG_CORE_HANDLE *pdev)
{
/* This callback could be used to implement a scheduler process */
return 0;
}
/**
* @brief USBH_Init
* Host hardware and stack initializations
* @param class_cb: Class callback structure address
* @param usr_cb: User callback structure address
* @retval None
*/
void USBH_Init(USB_OTG_CORE_HANDLE *pdev,
USB_OTG_CORE_ID_TypeDef coreID,
USBH_HOST *phost,
USBH_Class_cb_TypeDef *class_cb,
USBH_Usr_cb_TypeDef *usr_cb)
{
/* Hardware Init */
USB_OTG_BSP_Init(pdev);
/* configure GPIO pin used for switching VBUS power */
USB_OTG_BSP_ConfigVBUS(0);
/* Host de-initializations */
USBH_DeInit(pdev, phost);
/*Register class and user callbacks */
phost->class_cb = class_cb;
phost->usr_cb = usr_cb;
/* Start the USB OTG core */
HCD_Init(pdev , coreID);
/* Upon Init call usr call back */
phost->usr_cb->Init();
/* Enable Interrupts */
USB_OTG_BSP_EnableInterrupt(pdev);
}
/**
* @brief USBH_DeInit
* Re-Initialize Host
* @param None
* @retval status: USBH_Status
*/
USBH_Status USBH_DeInit(USB_OTG_CORE_HANDLE *pdev, USBH_HOST *phost)
{
/* Software Init */
phost->gState = HOST_IDLE;
phost->gStateBkp = HOST_IDLE;
phost->EnumState = ENUM_IDLE;
phost->RequestState = CMD_SEND;
phost->Control.state = CTRL_SETUP;
phost->Control.ep0size = USB_OTG_MAX_EP0_SIZE;
phost->device_prop.address = USBH_DEVICE_ADDRESS_DEFAULT;
phost->device_prop.speed = HPRT0_PRTSPD_FULL_SPEED;
USBH_Free_Channel (pdev, phost->Control.hc_num_in);
USBH_Free_Channel (pdev, phost->Control.hc_num_out);
return USBH_OK;
}
/**
* @brief USBH_Process
* USB Host core main state machine process
* @param None
* @retval None
*/
void USBH_Process(USB_OTG_CORE_HANDLE *pdev , USBH_HOST *phost)
{
volatile USBH_Status status = USBH_FAIL;
/* check for Host port events */
if ((HCD_IsDeviceConnected(pdev) == 0)&& (phost->gState != HOST_IDLE))
{
if(phost->gState != HOST_DEV_DISCONNECTED)
{
phost->gState = HOST_DEV_DISCONNECTED;
}
}
switch (phost->gState)
{
case HOST_IDLE :
if (HCD_IsDeviceConnected(pdev))
{
phost->gState = HOST_DEV_ATTACHED;
USB_OTG_BSP_mDelay(100);
}
break;
case HOST_DEV_ATTACHED :
phost->usr_cb->DeviceAttached();
phost->Control.hc_num_out = USBH_Alloc_Channel(pdev, 0x00);
phost->Control.hc_num_in = USBH_Alloc_Channel(pdev, 0x80);
/* Reset USB Device */
if ( HCD_ResetPort(pdev) == 0)
{
phost->usr_cb->ResetDevice();
/* Wait for USB USBH_ISR_PrtEnDisableChange()
Host is Now ready to start the Enumeration
*/
phost->device_prop.speed = HCD_GetCurrentSpeed(pdev);
phost->gState = HOST_ENUMERATION;
phost->usr_cb->DeviceSpeedDetected(phost->device_prop.speed);
/* Open Control pipes */
USBH_Open_Channel (pdev,
phost->Control.hc_num_in,
phost->device_prop.address,
phost->device_prop.speed,
EP_TYPE_CTRL,
phost->Control.ep0size);
/* Open Control pipes */
USBH_Open_Channel (pdev,
phost->Control.hc_num_out,
phost->device_prop.address,
phost->device_prop.speed,
EP_TYPE_CTRL,
phost->Control.ep0size);
}
break;
case HOST_ENUMERATION:
/* Check for enumeration status */
if ( USBH_HandleEnum(pdev , phost) == USBH_OK)
{
/* The function shall return USBH_OK when full enumeration is complete */
/* user callback for end of device basic enumeration */
phost->usr_cb->EnumerationDone();
phost->gState = HOST_USR_INPUT;
}
break;
case HOST_USR_INPUT:
/*The function should return user response true to move to class state */
if ( phost->usr_cb->UserInput() == USBH_USR_RESP_OK)
{
if((phost->class_cb->Init(pdev, phost))\
== USBH_OK)
{
phost->gState = HOST_CLASS_REQUEST;
}
}
break;
case HOST_CLASS_REQUEST:
/* process class standard contol requests state machine */
status = phost->class_cb->Requests(pdev, phost);
if(status == USBH_OK)
{
phost->gState = HOST_CLASS;
}
else
{
USBH_ErrorHandle(phost, status);
}
break;
case HOST_CLASS:
/* process class state machine */
status = phost->class_cb->Machine(pdev, phost);
USBH_ErrorHandle(phost, status);
break;
case HOST_CTRL_XFER:
/* process control transfer state machine */
USBH_HandleControl(pdev, phost);
break;
case HOST_SUSPENDED:
break;
case HOST_ERROR_STATE:
/* Re-Initilaize Host for new Enumeration */
USBH_DeInit(pdev, phost);
phost->usr_cb->DeInit();
phost->class_cb->DeInit(pdev, &phost->device_prop);
break;
case HOST_DEV_DISCONNECTED :
/* Manage User disconnect operations*/
phost->usr_cb->DeviceDisconnected();
/* Re-Initilaize Host for new Enumeration */
USBH_DeInit(pdev, phost);
phost->usr_cb->DeInit();
phost->class_cb->DeInit(pdev, &phost->device_prop);
USBH_DeAllocate_AllChannel(pdev);
phost->gState = HOST_IDLE;
break;
default :
break;
}
}
/**
* @brief USBH_ErrorHandle
* This function handles the Error on Host side.
* @param errType : Type of Error or Busy/OK state
* @retval None
*/
void USBH_ErrorHandle(USBH_HOST *phost, USBH_Status errType)
{
/* Error unrecovered or not supported device speed */
if ( (errType == USBH_ERROR_SPEED_UNKNOWN) ||
(errType == USBH_UNRECOVERED_ERROR) )
{
phost->usr_cb->UnrecoveredError();
phost->gState = HOST_ERROR_STATE;
}
/* USB host restart requested from application layer */
else if(errType == USBH_APPLY_DEINIT)
{
phost->gState = HOST_ERROR_STATE;
/* user callback for initalization */
phost->usr_cb->Init();
}
}
/**
* @brief USBH_HandleEnum
* This function includes the complete enumeration process
* @param pdev: Selected device
* @retval USBH_Status
*/
static USBH_Status USBH_HandleEnum(USB_OTG_CORE_HANDLE *pdev, USBH_HOST *phost)
{
USBH_Status Status = USBH_BUSY;
uint8_t Local_Buffer[64];
switch (phost->EnumState)
{
case ENUM_IDLE:
/* Get Device Desc for only 1st 8 bytes : To get EP0 MaxPacketSize */
if ( USBH_Get_DevDesc(pdev , phost, 8) == USBH_OK)
{
phost->Control.ep0size = phost->device_prop.Dev_Desc.bMaxPacketSize;
/* Issue Reset */
HCD_ResetPort(pdev);
phost->EnumState = ENUM_GET_FULL_DEV_DESC;
/* modify control channels configuration for MaxPacket size */
USBH_Modify_Channel (pdev,
phost->Control.hc_num_out,
0,
0,
0,
phost->Control.ep0size);
USBH_Modify_Channel (pdev,
phost->Control.hc_num_in,
0,
0,
0,
phost->Control.ep0size);
}
break;
case ENUM_GET_FULL_DEV_DESC:
/* Get FULL Device Desc */
if ( USBH_Get_DevDesc(pdev, phost, USB_DEVICE_DESC_SIZE)\
== USBH_OK)
{
/* user callback for device descriptor available */
phost->usr_cb->DeviceDescAvailable(&phost->device_prop.Dev_Desc);
phost->EnumState = ENUM_SET_ADDR;
}
break;
case ENUM_SET_ADDR:
/* set address */
if ( USBH_SetAddress(pdev, phost, USBH_DEVICE_ADDRESS) == USBH_OK)
{
USB_OTG_BSP_mDelay(2);
phost->device_prop.address = USBH_DEVICE_ADDRESS;
/* user callback for device address assigned */
phost->usr_cb->DeviceAddressAssigned();
phost->EnumState = ENUM_GET_CFG_DESC;
/* modify control channels to update device address */
USBH_Modify_Channel (pdev,
phost->Control.hc_num_in,
phost->device_prop.address,
0,
0,
0);
USBH_Modify_Channel (pdev,
phost->Control.hc_num_out,
phost->device_prop.address,
0,
0,
0);
}
break;
case ENUM_GET_CFG_DESC:
/* get standard configuration descriptor */
if ( USBH_Get_CfgDesc(pdev,
phost,
USB_CONFIGURATION_DESC_SIZE) == USBH_OK)
{
phost->EnumState = ENUM_GET_FULL_CFG_DESC;
}
break;
case ENUM_GET_FULL_CFG_DESC:
/* get FULL config descriptor (config, interface, endpoints) */
if (USBH_Get_CfgDesc(pdev,
phost,
phost->device_prop.Cfg_Desc.wTotalLength) == USBH_OK)
{
/* User callback for configuration descriptors available */
phost->usr_cb->ConfigurationDescAvailable(&phost->device_prop.Cfg_Desc,
phost->device_prop.Itf_Desc,
phost->device_prop.Ep_Desc[0]);
phost->EnumState = ENUM_GET_MFC_STRING_DESC;
}
break;
case ENUM_GET_MFC_STRING_DESC:
if (phost->device_prop.Dev_Desc.iManufacturer != 0)
{ /* Check that Manufacturer String is available */
if ( USBH_Get_StringDesc(pdev,
phost,
phost->device_prop.Dev_Desc.iManufacturer,
Local_Buffer ,
0xff) == USBH_OK)
{
/* User callback for Manufacturing string */
phost->usr_cb->ManufacturerString(Local_Buffer);
phost->EnumState = ENUM_GET_PRODUCT_STRING_DESC;
}
}
else
{
phost->usr_cb->ManufacturerString("N/A");
phost->EnumState = ENUM_GET_PRODUCT_STRING_DESC;
}
break;
case ENUM_GET_PRODUCT_STRING_DESC:
if (phost->device_prop.Dev_Desc.iProduct != 0)
{ /* Check that Product string is available */
if ( USBH_Get_StringDesc(pdev,
phost,
phost->device_prop.Dev_Desc.iProduct,
Local_Buffer,
0xff) == USBH_OK)
{
/* User callback for Product string */
phost->usr_cb->ProductString(Local_Buffer);
phost->EnumState = ENUM_GET_SERIALNUM_STRING_DESC;
}
}
else
{
phost->usr_cb->ProductString("N/A");
phost->EnumState = ENUM_GET_SERIALNUM_STRING_DESC;
}
break;
case ENUM_GET_SERIALNUM_STRING_DESC:
if (phost->device_prop.Dev_Desc.iSerialNumber != 0)
{ /* Check that Serial number string is available */
if ( USBH_Get_StringDesc(pdev,
phost,
phost->device_prop.Dev_Desc.iSerialNumber,
Local_Buffer,
0xff) == USBH_OK)
{
/* User callback for Serial number string */
phost->usr_cb->SerialNumString(Local_Buffer);
phost->EnumState = ENUM_SET_CONFIGURATION;
}
}
else
{
phost->usr_cb->SerialNumString("N/A");
phost->EnumState = ENUM_SET_CONFIGURATION;
}
break;
case ENUM_SET_CONFIGURATION:
/* set configuration (default config) */
if (USBH_SetCfg(pdev,
phost,
phost->device_prop.Cfg_Desc.bConfigurationValue) == USBH_OK)
{
phost->EnumState = ENUM_DEV_CONFIGURED;
}
break;
case ENUM_DEV_CONFIGURED:
/* user callback for enumeration done */
Status = USBH_OK;
break;
default:
break;
}
return Status;
}
/**
* @brief USBH_HandleControl
* Handles the USB control transfer state machine
* @param pdev: Selected device
* @retval Status
*/
USBH_Status USBH_HandleControl (USB_OTG_CORE_HANDLE *pdev, USBH_HOST *phost)
{
uint8_t direction;
static uint16_t timeout = 0;
USBH_Status status = USBH_OK;
URB_STATE URB_Status = URB_IDLE;
phost->Control.status = CTRL_START;
switch (phost->Control.state)
{
case CTRL_SETUP:
/* send a SETUP packet */
USBH_CtlSendSetup (pdev,
phost->Control.setup.d8 ,
phost->Control.hc_num_out);
phost->Control.state = CTRL_SETUP_WAIT;
break;
case CTRL_SETUP_WAIT:
URB_Status = HCD_GetURB_State(pdev , phost->Control.hc_num_out);
/* case SETUP packet sent successfully */
if(URB_Status == URB_DONE)
{
direction = (phost->Control.setup.b.bmRequestType & USB_REQ_DIR_MASK);
/* check if there is a data stage */
if (phost->Control.setup.b.wLength.w != 0 )
{
timeout = DATA_STAGE_TIMEOUT;
if (direction == USB_D2H)
{
/* Data Direction is IN */
phost->Control.state = CTRL_DATA_IN;
}
else
{
/* Data Direction is OUT */
phost->Control.state = CTRL_DATA_OUT;
}
}
/* No DATA stage */
else
{
timeout = NODATA_STAGE_TIMEOUT;
/* If there is No Data Transfer Stage */
if (direction == USB_D2H)
{
/* Data Direction is IN */
phost->Control.state = CTRL_STATUS_OUT;
}
else
{
/* Data Direction is OUT */
phost->Control.state = CTRL_STATUS_IN;
}
}
/* Set the delay timer to enable timeout for data stage completion */
phost->Control.timer = HCD_GetCurrentFrame(pdev);
}
else if(URB_Status == URB_ERROR)
{
phost->Control.state = CTRL_ERROR;
phost->Control.status = CTRL_XACTERR;
}
break;
case CTRL_DATA_IN:
/* Issue an IN token */
USBH_CtlReceiveData(pdev,
phost->Control.buff,
phost->Control.length,
phost->Control.hc_num_in);
phost->Control.state = CTRL_DATA_IN_WAIT;
break;
case CTRL_DATA_IN_WAIT:
URB_Status = HCD_GetURB_State(pdev , phost->Control.hc_num_in);
/* check is DATA packet transfered successfully */
if (URB_Status == URB_DONE)
{
phost->Control.state = CTRL_STATUS_OUT;
}
/* manage error cases*/
if (URB_Status == URB_STALL)
{
/* In stall case, return to previous machine state*/
phost->gState = phost->gStateBkp;
}
else if (URB_Status == URB_ERROR)
{
/* Device error */
phost->Control.state = CTRL_ERROR;
}
else if ((HCD_GetCurrentFrame(pdev)- phost->Control.timer) > timeout)
{
/* timeout for IN transfer */
phost->Control.state = CTRL_ERROR;
}
break;
case CTRL_DATA_OUT:
/* Start DATA out transfer (only one DATA packet)*/
pdev->host.hc[phost->Control.hc_num_out].toggle_out = 1;
USBH_CtlSendData (pdev,
phost->Control.buff,
phost->Control.length ,
phost->Control.hc_num_out);
phost->Control.state = CTRL_DATA_OUT_WAIT;
break;
case CTRL_DATA_OUT_WAIT:
URB_Status = HCD_GetURB_State(pdev , phost->Control.hc_num_out);
if (URB_Status == URB_DONE)
{ /* If the Setup Pkt is sent successful, then change the state */
phost->Control.state = CTRL_STATUS_IN;
}
/* handle error cases */
else if (URB_Status == URB_STALL)
{
/* In stall case, return to previous machine state*/
phost->gState = phost->gStateBkp;
phost->Control.state = CTRL_STALLED;
}
else if (URB_Status == URB_NOTREADY)
{
/* Nack received from device */
phost->Control.state = CTRL_DATA_OUT;
}
else if (URB_Status == URB_ERROR)
{
/* device error */
phost->Control.state = CTRL_ERROR;
}
break;
case CTRL_STATUS_IN:
/* Send 0 bytes out packet */
USBH_CtlReceiveData (pdev,
0,
0,
phost->Control.hc_num_in);
phost->Control.state = CTRL_STATUS_IN_WAIT;
break;
case CTRL_STATUS_IN_WAIT:
URB_Status = HCD_GetURB_State(pdev , phost->Control.hc_num_in);
if ( URB_Status == URB_DONE)
{ /* Control transfers completed, Exit the State Machine */
phost->gState = phost->gStateBkp;
phost->Control.state = CTRL_COMPLETE;
}
else if (URB_Status == URB_ERROR)
{
phost->Control.state = CTRL_ERROR;
}
else if((HCD_GetCurrentFrame(pdev)\
- phost->Control.timer) > timeout)
{
phost->Control.state = CTRL_ERROR;
}
else if(URB_Status == URB_STALL)
{
/* Control transfers completed, Exit the State Machine */
phost->gState = phost->gStateBkp;
phost->Control.status = CTRL_STALL;
status = USBH_NOT_SUPPORTED;
}
break;
case CTRL_STATUS_OUT:
pdev->host.hc[phost->Control.hc_num_out].toggle_out ^= 1;
USBH_CtlSendData (pdev,
0,
0,
phost->Control.hc_num_out);
phost->Control.state = CTRL_STATUS_OUT_WAIT;
break;
case CTRL_STATUS_OUT_WAIT:
URB_Status = HCD_GetURB_State(pdev , phost->Control.hc_num_out);
if (URB_Status == URB_DONE)
{
phost->gState = phost->gStateBkp;
phost->Control.state = CTRL_COMPLETE;
}
else if (URB_Status == URB_NOTREADY)
{
phost->Control.state = CTRL_STATUS_OUT;
}
else if (URB_Status == URB_ERROR)
{
phost->Control.state = CTRL_ERROR;
}
break;
case CTRL_ERROR:
/*
After a halt condition is encountered or an error is detected by the
host, a control endpoint is allowed to recover by accepting the next Setup
PID; i.e., recovery actions via some other pipe are not required for control
endpoints. For the Default Control Pipe, a device reset will ultimately be
required to clear the halt or error condition if the next Setup PID is not
accepted.
*/
if (++ phost->Control.errorcount <= USBH_MAX_ERROR_COUNT)
{
/* Do the transmission again, starting from SETUP Packet */
phost->Control.state = CTRL_SETUP;
}
else
{
phost->Control.status = CTRL_FAIL;
phost->gState = phost->gStateBkp;
status = USBH_FAIL;
}
break;
default:
break;
}
return status;
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,259 @@
/**
******************************************************************************
* @file usbh_hcs.c
* @author MCD Application Team
* @version V2.1.0
* @date 19-March-2012
* @brief This file implements functions for opening and closing host channels
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "usbh_hcs.h"
/** @addtogroup USBH_LIB
* @{
*/
/** @addtogroup USBH_LIB_CORE
* @{
*/
/** @defgroup USBH_HCS
* @brief This file includes opening and closing host channels
* @{
*/
/** @defgroup USBH_HCS_Private_Defines
* @{
*/
/**
* @}
*/
/** @defgroup USBH_HCS_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @defgroup USBH_HCS_Private_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBH_HCS_Private_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USBH_HCS_Private_FunctionPrototypes
* @{
*/
static uint16_t USBH_GetFreeChannel (USB_OTG_CORE_HANDLE *pdev);
/**
* @}
*/
/** @defgroup USBH_HCS_Private_Functions
* @{
*/
/**
* @brief USBH_Open_Channel
* Open a pipe
* @param pdev : Selected device
* @param hc_num: Host channel 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 Status
*/
uint8_t USBH_Open_Channel (USB_OTG_CORE_HANDLE *pdev,
uint8_t hc_num,
uint8_t dev_address,
uint8_t speed,
uint8_t ep_type,
uint16_t mps)
{
pdev->host.hc[hc_num].ep_num = pdev->host.channel[hc_num]& 0x7F;
pdev->host.hc[hc_num].ep_is_in = (pdev->host.channel[hc_num] & 0x80 ) == 0x80;
pdev->host.hc[hc_num].dev_addr = dev_address;
pdev->host.hc[hc_num].ep_type = ep_type;
pdev->host.hc[hc_num].max_packet = mps;
pdev->host.hc[hc_num].speed = speed;
pdev->host.hc[hc_num].toggle_in = 0;
pdev->host.hc[hc_num].toggle_out = 0;
if(speed == HPRT0_PRTSPD_HIGH_SPEED)
{
pdev->host.hc[hc_num].do_ping = 1;
}
USB_OTG_HC_Init(pdev, hc_num) ;
return HC_OK;
}
/**
* @brief USBH_Modify_Channel
* Modify a pipe
* @param pdev : Selected device
* @param hc_num: Host channel 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 Status
*/
uint8_t USBH_Modify_Channel (USB_OTG_CORE_HANDLE *pdev,
uint8_t hc_num,
uint8_t dev_address,
uint8_t speed,
uint8_t ep_type,
uint16_t mps)
{
if(dev_address != 0)
{
pdev->host.hc[hc_num].dev_addr = dev_address;
}
if((pdev->host.hc[hc_num].max_packet != mps) && (mps != 0))
{
pdev->host.hc[hc_num].max_packet = mps;
}
if((pdev->host.hc[hc_num].speed != speed ) && (speed != 0 ))
{
pdev->host.hc[hc_num].speed = speed;
}
USB_OTG_HC_Init(pdev, hc_num);
return HC_OK;
}
/**
* @brief USBH_Alloc_Channel
* Allocate a new channel for the pipe
* @param ep_addr: End point for which the channel to be allocated
* @retval hc_num: Host channel number
*/
uint8_t USBH_Alloc_Channel (USB_OTG_CORE_HANDLE *pdev, uint8_t ep_addr)
{
uint16_t hc_num;
hc_num = USBH_GetFreeChannel(pdev);
if (hc_num != HC_ERROR)
{
pdev->host.channel[hc_num] = HC_USED | ep_addr;
}
return hc_num;
}
/**
* @brief USBH_Free_Pipe
* Free the USB host channel
* @param idx: Channel number to be freed
* @retval Status
*/
uint8_t USBH_Free_Channel (USB_OTG_CORE_HANDLE *pdev, uint8_t idx)
{
if(idx < HC_MAX)
{
pdev->host.channel[idx] &= HC_USED_MASK;
}
return USBH_OK;
}
/**
* @brief USBH_DeAllocate_AllChannel
* Free all USB host channel
* @param pdev : core instance
* @retval Status
*/
uint8_t USBH_DeAllocate_AllChannel (USB_OTG_CORE_HANDLE *pdev)
{
uint8_t idx;
for (idx = 2; idx < HC_MAX ; idx ++)
{
pdev->host.channel[idx] = 0;
}
return USBH_OK;
}
/**
* @brief USBH_GetFreeChannel
* Get a free channel number for allocation to a device endpoint
* @param None
* @retval idx: Free Channel number
*/
static uint16_t USBH_GetFreeChannel (USB_OTG_CORE_HANDLE *pdev)
{
uint8_t idx = 0;
for (idx = 0 ; idx < HC_MAX ; idx++)
{
if ((pdev->host.channel[idx] & HC_USED) == 0)
{
return idx;
}
}
return HC_ERROR;
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,474 @@
/**
******************************************************************************
* @file usbh_ioreq.c
* @author MCD Application Team
* @version V2.1.0
* @date 19-March-2012
* @brief This file handles the issuing of the USB transactions
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "usbh_ioreq.h"
/** @addtogroup USBH_LIB
* @{
*/
/** @addtogroup USBH_LIB_CORE
* @{
*/
/** @defgroup USBH_IOREQ
* @brief This file handles the standard protocol processing (USB v2.0)
* @{
*/
/** @defgroup USBH_IOREQ_Private_Defines
* @{
*/
/**
* @}
*/
/** @defgroup USBH_IOREQ_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @defgroup USBH_IOREQ_Private_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBH_IOREQ_Private_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USBH_IOREQ_Private_FunctionPrototypes
* @{
*/
static USBH_Status USBH_SubmitSetupRequest(USBH_HOST *phost,
uint8_t* buff,
uint16_t length);
/**
* @}
*/
/** @defgroup USBH_IOREQ_Private_Functions
* @{
*/
/**
* @brief USBH_CtlReq
* USBH_CtlReq sends a control request and provide the status after
* completion of the request
* @param pdev: Selected device
* @param req: Setup Request Structure
* @param buff: data buffer address to store the response
* @param length: length of the response
* @retval Status
*/
USBH_Status USBH_CtlReq (USB_OTG_CORE_HANDLE *pdev,
USBH_HOST *phost,
uint8_t *buff,
uint16_t length)
{
USBH_Status status;
status = USBH_BUSY;
switch (phost->RequestState)
{
case CMD_SEND:
/* Start a SETUP transfer */
USBH_SubmitSetupRequest(phost, buff, length);
phost->RequestState = CMD_WAIT;
status = USBH_BUSY;
break;
case CMD_WAIT:
if (phost->Control.state == CTRL_COMPLETE )
{
/* Commands successfully sent and Response Received */
phost->RequestState = CMD_SEND;
phost->Control.state =CTRL_IDLE;
status = USBH_OK;
}
else if (phost->Control.state == CTRL_ERROR)
{
/* Failure Mode */
phost->RequestState = CMD_SEND;
status = USBH_FAIL;
}
else if (phost->Control.state == CTRL_STALLED )
{
/* Commands successfully sent and Response Received */
phost->RequestState = CMD_SEND;
status = USBH_NOT_SUPPORTED;
}
break;
default:
break;
}
return status;
}
/**
* @brief USBH_CtlSendSetup
* Sends the Setup Packet to the Device
* @param pdev: Selected device
* @param buff: Buffer pointer from which the Data will be send to Device
* @param hc_num: Host channel Number
* @retval Status
*/
USBH_Status USBH_CtlSendSetup ( USB_OTG_CORE_HANDLE *pdev,
uint8_t *buff,
uint8_t hc_num){
pdev->host.hc[hc_num].ep_is_in = 0;
pdev->host.hc[hc_num].data_pid = HC_PID_SETUP;
pdev->host.hc[hc_num].xfer_buff = buff;
pdev->host.hc[hc_num].xfer_len = USBH_SETUP_PKT_SIZE;
return (USBH_Status)HCD_SubmitRequest (pdev , hc_num);
}
/**
* @brief USBH_CtlSendData
* Sends a data Packet to the Device
* @param pdev: Selected device
* @param buff: Buffer pointer from which the Data will be sent to Device
* @param length: Length of the data to be sent
* @param hc_num: Host channel Number
* @retval Status
*/
USBH_Status USBH_CtlSendData ( USB_OTG_CORE_HANDLE *pdev,
uint8_t *buff,
uint16_t length,
uint8_t hc_num)
{
pdev->host.hc[hc_num].ep_is_in = 0;
pdev->host.hc[hc_num].xfer_buff = buff;
pdev->host.hc[hc_num].xfer_len = length;
if ( length == 0 )
{ /* For Status OUT stage, Length==0, Status Out PID = 1 */
pdev->host.hc[hc_num].toggle_out = 1;
}
/* Set the Data Toggle bit as per the Flag */
if ( pdev->host.hc[hc_num].toggle_out == 0)
{ /* Put the PID 0 */
pdev->host.hc[hc_num].data_pid = HC_PID_DATA0;
}
else
{ /* Put the PID 1 */
pdev->host.hc[hc_num].data_pid = HC_PID_DATA1 ;
}
HCD_SubmitRequest (pdev , hc_num);
return USBH_OK;
}
/**
* @brief USBH_CtlReceiveData
* Receives the Device Response to the Setup Packet
* @param pdev: Selected device
* @param buff: Buffer pointer in which the response needs to be copied
* @param length: Length of the data to be received
* @param hc_num: Host channel Number
* @retval Status.
*/
USBH_Status USBH_CtlReceiveData(USB_OTG_CORE_HANDLE *pdev,
uint8_t* buff,
uint16_t length,
uint8_t hc_num)
{
pdev->host.hc[hc_num].ep_is_in = 1;
pdev->host.hc[hc_num].data_pid = HC_PID_DATA1;
pdev->host.hc[hc_num].xfer_buff = buff;
pdev->host.hc[hc_num].xfer_len = length;
HCD_SubmitRequest (pdev , hc_num);
return USBH_OK;
}
/**
* @brief USBH_BulkSendData
* Sends the Bulk Packet to the device
* @param pdev: Selected device
* @param buff: Buffer pointer from which the Data will be sent to Device
* @param length: Length of the data to be sent
* @param hc_num: Host channel Number
* @retval Status
*/
USBH_Status USBH_BulkSendData ( USB_OTG_CORE_HANDLE *pdev,
uint8_t *buff,
uint16_t length,
uint8_t hc_num)
{
pdev->host.hc[hc_num].ep_is_in = 0;
pdev->host.hc[hc_num].xfer_buff = buff;
pdev->host.hc[hc_num].xfer_len = length;
/* Set the Data Toggle bit as per the Flag */
if ( pdev->host.hc[hc_num].toggle_out == 0)
{ /* Put the PID 0 */
pdev->host.hc[hc_num].data_pid = HC_PID_DATA0;
}
else
{ /* Put the PID 1 */
pdev->host.hc[hc_num].data_pid = HC_PID_DATA1 ;
}
HCD_SubmitRequest (pdev , hc_num);
return USBH_OK;
}
/**
* @brief USBH_BulkReceiveData
* Receives IN bulk packet from device
* @param pdev: Selected device
* @param buff: Buffer pointer in which the received data packet to be copied
* @param length: Length of the data to be received
* @param hc_num: Host channel Number
* @retval Status.
*/
USBH_Status USBH_BulkReceiveData( USB_OTG_CORE_HANDLE *pdev,
uint8_t *buff,
uint16_t length,
uint8_t hc_num)
{
pdev->host.hc[hc_num].ep_is_in = 1;
pdev->host.hc[hc_num].xfer_buff = buff;
pdev->host.hc[hc_num].xfer_len = length;
if( pdev->host.hc[hc_num].toggle_in == 0)
{
pdev->host.hc[hc_num].data_pid = HC_PID_DATA0;
}
else
{
pdev->host.hc[hc_num].data_pid = HC_PID_DATA1;
}
HCD_SubmitRequest (pdev , hc_num);
return USBH_OK;
}
/**
* @brief USBH_InterruptReceiveData
* Receives the Device Response to the Interrupt IN token
* @param pdev: Selected device
* @param buff: Buffer pointer in which the response needs to be copied
* @param length: Length of the data to be received
* @param hc_num: Host channel Number
* @retval Status.
*/
USBH_Status USBH_InterruptReceiveData( USB_OTG_CORE_HANDLE *pdev,
uint8_t *buff,
uint8_t length,
uint8_t hc_num)
{
pdev->host.hc[hc_num].ep_is_in = 1;
pdev->host.hc[hc_num].xfer_buff = buff;
pdev->host.hc[hc_num].xfer_len = length;
if(pdev->host.hc[hc_num].toggle_in == 0)
{
pdev->host.hc[hc_num].data_pid = HC_PID_DATA0;
}
else
{
pdev->host.hc[hc_num].data_pid = HC_PID_DATA1;
}
/* toggle DATA PID */
pdev->host.hc[hc_num].toggle_in ^= 1;
HCD_SubmitRequest (pdev , hc_num);
return USBH_OK;
}
/**
* @brief USBH_InterruptSendData
* Sends the data on Interrupt OUT Endpoint
* @param pdev: Selected device
* @param buff: Buffer pointer from where the data needs to be copied
* @param length: Length of the data to be sent
* @param hc_num: Host channel Number
* @retval Status.
*/
USBH_Status USBH_InterruptSendData( USB_OTG_CORE_HANDLE *pdev,
uint8_t *buff,
uint8_t length,
uint8_t hc_num)
{
pdev->host.hc[hc_num].ep_is_in = 0;
pdev->host.hc[hc_num].xfer_buff = buff;
pdev->host.hc[hc_num].xfer_len = length;
if(pdev->host.hc[hc_num].toggle_in == 0)
{
pdev->host.hc[hc_num].data_pid = HC_PID_DATA0;
}
else
{
pdev->host.hc[hc_num].data_pid = HC_PID_DATA1;
}
pdev->host.hc[hc_num].toggle_in ^= 1;
HCD_SubmitRequest (pdev , hc_num);
return USBH_OK;
}
/**
* @brief USBH_SubmitSetupRequest
* Start a setup transfer by changing the state-machine and
* initializing the required variables needed for the Control Transfer
* @param pdev: Selected device
* @param setup: Setup Request Structure
* @param buff: Buffer used for setup request
* @param length: Length of the data
* @retval Status.
*/
static USBH_Status USBH_SubmitSetupRequest(USBH_HOST *phost,
uint8_t* buff,
uint16_t length)
{
/* Save Global State */
phost->gStateBkp = phost->gState;
/* Prepare the Transactions */
phost->gState = HOST_CTRL_XFER;
phost->Control.buff = buff;
phost->Control.length = length;
phost->Control.state = CTRL_SETUP;
return USBH_OK;
}
/**
* @brief USBH_IsocReceiveData
* Receives the Device Response to the Isochronous IN token
* @param pdev: Selected device
* @param buff: Buffer pointer in which the response needs to be copied
* @param length: Length of the data to be received
* @param hc_num: Host channel Number
* @retval Status.
*/
USBH_Status USBH_IsocReceiveData( USB_OTG_CORE_HANDLE *pdev,
uint8_t *buff,
uint32_t length,
uint8_t hc_num)
{
pdev->host.hc[hc_num].ep_is_in = 1;
pdev->host.hc[hc_num].xfer_buff = buff;
pdev->host.hc[hc_num].xfer_len = length;
pdev->host.hc[hc_num].data_pid = HC_PID_DATA0;
HCD_SubmitRequest (pdev , hc_num);
return USBH_OK;
}
/**
* @brief USBH_IsocSendData
* Sends the data on Isochronous OUT Endpoint
* @param pdev: Selected device
* @param buff: Buffer pointer from where the data needs to be copied
* @param length: Length of the data to be sent
* @param hc_num: Host channel Number
* @retval Status.
*/
USBH_Status USBH_IsocSendData( USB_OTG_CORE_HANDLE *pdev,
uint8_t *buff,
uint32_t length,
uint8_t hc_num)
{
pdev->host.hc[hc_num].ep_is_in = 0;
pdev->host.hc[hc_num].xfer_buff = buff;
pdev->host.hc[hc_num].xfer_len = length;
pdev->host.hc[hc_num].data_pid = HC_PID_DATA0;
HCD_SubmitRequest (pdev , hc_num);
return USBH_OK;
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,607 @@
/**
******************************************************************************
* @file usbh_stdreq.c
* @author MCD Application Team
* @version V2.1.0
* @date 19-March-2012
* @brief This file implements the standard requests for device enumeration
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "usbh_ioreq.h"
#include "usbh_stdreq.h"
/** @addtogroup USBH_LIB
* @{
*/
/** @addtogroup USBH_LIB_CORE
* @{
*/
/** @defgroup USBH_STDREQ
* @brief This file implements the standard requests for device enumeration
* @{
*/
/** @defgroup USBH_STDREQ_Private_Defines
* @{
*/
/**
* @}
*/
/** @defgroup USBH_STDREQ_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @defgroup USBH_STDREQ_Private_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBH_STDREQ_Private_Variables
* @{
*/
/**
* @}
*/
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
__ALIGN_BEGIN uint8_t USBH_CfgDesc[512] __ALIGN_END ;
/** @defgroup USBH_STDREQ_Private_FunctionPrototypes
* @{
*/
static void USBH_ParseDevDesc (USBH_DevDesc_TypeDef* , uint8_t *buf, uint16_t length);
static void USBH_ParseCfgDesc (USBH_CfgDesc_TypeDef* cfg_desc,
USBH_InterfaceDesc_TypeDef* itf_desc,
USBH_EpDesc_TypeDef ep_desc[][USBH_MAX_NUM_ENDPOINTS],
uint8_t *buf,
uint16_t length);
static void USBH_ParseInterfaceDesc (USBH_InterfaceDesc_TypeDef *if_descriptor, uint8_t *buf);
static void USBH_ParseEPDesc (USBH_EpDesc_TypeDef *ep_descriptor, uint8_t *buf);
static void USBH_ParseStringDesc (uint8_t* psrc, uint8_t* pdest, uint16_t length);
/**
* @}
*/
/** @defgroup USBH_STDREQ_Private_Functions
* @{
*/
/**
* @brief USBH_Get_DevDesc
* Issue Get Device Descriptor command to the device. Once the response
* received, it parses the device descriptor and updates the status.
* @param pdev: Selected device
* @param dev_desc: Device Descriptor buffer address
* @param pdev->host.Rx_Buffer: Receive Buffer address
* @param length: Length of the descriptor
* @retval Status
*/
USBH_Status USBH_Get_DevDesc(USB_OTG_CORE_HANDLE *pdev,
USBH_HOST *phost,
uint8_t length)
{
USBH_Status status;
if((status = USBH_GetDescriptor(pdev,
phost,
USB_REQ_RECIPIENT_DEVICE | USB_REQ_TYPE_STANDARD,
USB_DESC_DEVICE,
pdev->host.Rx_Buffer,
length)) == USBH_OK)
{
/* Commands successfully sent and Response Received */
USBH_ParseDevDesc(&phost->device_prop.Dev_Desc, pdev->host.Rx_Buffer, length);
}
return status;
}
/**
* @brief USBH_Get_CfgDesc
* Issues Configuration Descriptor to the device. Once the response
* received, it parses the configuartion descriptor and updates the
* status.
* @param pdev: Selected device
* @param cfg_desc: Configuration Descriptor address
* @param itf_desc: Interface Descriptor address
* @param ep_desc: Endpoint Descriptor address
* @param length: Length of the descriptor
* @retval Status
*/
USBH_Status USBH_Get_CfgDesc(USB_OTG_CORE_HANDLE *pdev,
USBH_HOST *phost,
uint16_t length)
{
USBH_Status status;
uint16_t index = 0;
if((status = USBH_GetDescriptor(pdev,
phost,
USB_REQ_RECIPIENT_DEVICE | USB_REQ_TYPE_STANDARD,
USB_DESC_CONFIGURATION,
pdev->host.Rx_Buffer,
length)) == USBH_OK)
{
/*save Cfg descriptor for class parsing usage */
for( ; index < length ; index ++)
{
USBH_CfgDesc[index] = pdev->host.Rx_Buffer[index];
}
/* Commands successfully sent and Response Received */
USBH_ParseCfgDesc (&phost->device_prop.Cfg_Desc,
phost->device_prop.Itf_Desc,
phost->device_prop.Ep_Desc,
pdev->host.Rx_Buffer,
length);
}
return status;
}
/**
* @brief USBH_Get_StringDesc
* Issues string Descriptor command to the device. Once the response
* received, it parses the string descriptor and updates the status.
* @param pdev: Selected device
* @param string_index: String index for the descriptor
* @param buff: Buffer address for the descriptor
* @param length: Length of the descriptor
* @retval Status
*/
USBH_Status USBH_Get_StringDesc(USB_OTG_CORE_HANDLE *pdev,
USBH_HOST *phost,
uint8_t string_index,
uint8_t *buff,
uint16_t length)
{
USBH_Status status;
if((status = USBH_GetDescriptor(pdev,
phost,
USB_REQ_RECIPIENT_DEVICE | USB_REQ_TYPE_STANDARD,
USB_DESC_STRING | string_index,
pdev->host.Rx_Buffer,
length)) == USBH_OK)
{
/* Commands successfully sent and Response Received */
USBH_ParseStringDesc(pdev->host.Rx_Buffer,buff, length);
}
return status;
}
/**
* @brief USBH_GetDescriptor
* Issues Descriptor command to the device. Once the response received,
* it parses the descriptor and updates the status.
* @param pdev: Selected device
* @param req_type: Descriptor type
* @param value_idx: wValue for the GetDescriptr request
* @param buff: Buffer to store the descriptor
* @param length: Length of the descriptor
* @retval Status
*/
USBH_Status USBH_GetDescriptor(USB_OTG_CORE_HANDLE *pdev,
USBH_HOST *phost,
uint8_t req_type,
uint16_t value_idx,
uint8_t* buff,
uint16_t length )
{
phost->Control.setup.b.bmRequestType = USB_D2H | req_type;
phost->Control.setup.b.bRequest = USB_REQ_GET_DESCRIPTOR;
phost->Control.setup.b.wValue.w = value_idx;
if ((value_idx & 0xff00) == USB_DESC_STRING)
{
phost->Control.setup.b.wIndex.w = 0x0409;
}
else
{
phost->Control.setup.b.wIndex.w = 0;
}
phost->Control.setup.b.wLength.w = length;
return USBH_CtlReq(pdev, phost, buff , length );
}
/**
* @brief USBH_SetAddress
* This command sets the address to the connected device
* @param pdev: Selected device
* @param DeviceAddress: Device address to assign
* @retval Status
*/
USBH_Status USBH_SetAddress(USB_OTG_CORE_HANDLE *pdev,
USBH_HOST *phost,
uint8_t DeviceAddress)
{
phost->Control.setup.b.bmRequestType = USB_H2D | USB_REQ_RECIPIENT_DEVICE | \
USB_REQ_TYPE_STANDARD;
phost->Control.setup.b.bRequest = USB_REQ_SET_ADDRESS;
phost->Control.setup.b.wValue.w = (uint16_t)DeviceAddress;
phost->Control.setup.b.wIndex.w = 0;
phost->Control.setup.b.wLength.w = 0;
return USBH_CtlReq(pdev, phost, 0 , 0 );
}
/**
* @brief USBH_SetCfg
* The command sets the configuration value to the connected device
* @param pdev: Selected device
* @param cfg_idx: Configuration value
* @retval Status
*/
USBH_Status USBH_SetCfg(USB_OTG_CORE_HANDLE *pdev,
USBH_HOST *phost,
uint16_t cfg_idx)
{
phost->Control.setup.b.bmRequestType = USB_H2D | USB_REQ_RECIPIENT_DEVICE |\
USB_REQ_TYPE_STANDARD;
phost->Control.setup.b.bRequest = USB_REQ_SET_CONFIGURATION;
phost->Control.setup.b.wValue.w = cfg_idx;
phost->Control.setup.b.wIndex.w = 0;
phost->Control.setup.b.wLength.w = 0;
return USBH_CtlReq(pdev, phost, 0 , 0 );
}
/**
* @brief USBH_SetInterface
* The command sets the Interface value to the connected device
* @param pdev: Selected device
* @param itf_idx: Interface value
* @retval Status
*/
USBH_Status USBH_SetInterface(USB_OTG_CORE_HANDLE *pdev,
USBH_HOST *phost,
uint8_t ep_num, uint8_t altSetting)
{
phost->Control.setup.b.bmRequestType = USB_H2D | USB_REQ_RECIPIENT_INTERFACE | \
USB_REQ_TYPE_STANDARD;
phost->Control.setup.b.bRequest = USB_REQ_SET_INTERFACE;
phost->Control.setup.b.wValue.w = altSetting;
phost->Control.setup.b.wIndex.w = ep_num;
phost->Control.setup.b.wLength.w = 0;
return USBH_CtlReq(pdev, phost, 0 , 0 );
}
/**
* @brief USBH_ClrFeature
* This request is used to clear or disable a specific feature.
* @param pdev: Selected device
* @param ep_num: endpoint number
* @param hc_num: Host channel number
* @retval Status
*/
USBH_Status USBH_ClrFeature(USB_OTG_CORE_HANDLE *pdev,
USBH_HOST *phost,
uint8_t ep_num,
uint8_t hc_num)
{
phost->Control.setup.b.bmRequestType = USB_H2D |
USB_REQ_RECIPIENT_ENDPOINT |
USB_REQ_TYPE_STANDARD;
phost->Control.setup.b.bRequest = USB_REQ_CLEAR_FEATURE;
phost->Control.setup.b.wValue.w = FEATURE_SELECTOR_ENDPOINT;
phost->Control.setup.b.wIndex.w = ep_num;
phost->Control.setup.b.wLength.w = 0;
if ((ep_num & USB_REQ_DIR_MASK ) == USB_D2H)
{ /* EP Type is IN */
pdev->host.hc[hc_num].toggle_in = 0;
}
else
{/* EP Type is OUT */
pdev->host.hc[hc_num].toggle_out = 0;
}
return USBH_CtlReq(pdev, phost, 0 , 0 );
}
/**
* @brief USBH_ParseDevDesc
* This function Parses the device descriptor
* @param dev_desc: device_descriptor destinaton address
* @param buf: Buffer where the source descriptor is available
* @param length: Length of the descriptor
* @retval None
*/
static void USBH_ParseDevDesc (USBH_DevDesc_TypeDef* dev_desc,
uint8_t *buf,
uint16_t length)
{
dev_desc->bLength = *(uint8_t *) (buf + 0);
dev_desc->bDescriptorType = *(uint8_t *) (buf + 1);
dev_desc->bcdUSB = LE16 (buf + 2);
dev_desc->bDeviceClass = *(uint8_t *) (buf + 4);
dev_desc->bDeviceSubClass = *(uint8_t *) (buf + 5);
dev_desc->bDeviceProtocol = *(uint8_t *) (buf + 6);
dev_desc->bMaxPacketSize = *(uint8_t *) (buf + 7);
if (length > 8)
{ /* For 1st time after device connection, Host may issue only 8 bytes for
Device Descriptor Length */
dev_desc->idVendor = LE16 (buf + 8);
dev_desc->idProduct = LE16 (buf + 10);
dev_desc->bcdDevice = LE16 (buf + 12);
dev_desc->iManufacturer = *(uint8_t *) (buf + 14);
dev_desc->iProduct = *(uint8_t *) (buf + 15);
dev_desc->iSerialNumber = *(uint8_t *) (buf + 16);
dev_desc->bNumConfigurations = *(uint8_t *) (buf + 17);
}
}
/**
* @brief USBH_ParseCfgDesc
* This function Parses the configuration descriptor
* @param cfg_desc: Configuration Descriptor address
* @param itf_desc: Interface Descriptor address
* @param ep_desc: Endpoint Descriptor address
* @param buf: Buffer where the source descriptor is available
* @param length: Length of the descriptor
* @retval None
*/
static void USBH_ParseCfgDesc (USBH_CfgDesc_TypeDef* cfg_desc,
USBH_InterfaceDesc_TypeDef* itf_desc,
USBH_EpDesc_TypeDef ep_desc[][USBH_MAX_NUM_ENDPOINTS],
uint8_t *buf,
uint16_t length)
{
USBH_InterfaceDesc_TypeDef *pif ;
USBH_InterfaceDesc_TypeDef temp_pif ;
USBH_EpDesc_TypeDef *pep;
USBH_DescHeader_t *pdesc = (USBH_DescHeader_t *)buf;
uint16_t ptr;
int8_t if_ix = 0;
int8_t ep_ix = 0;
static uint16_t prev_ep_size = 0;
static uint8_t prev_itf = 0;
pdesc = (USBH_DescHeader_t *)buf;
/* Parse configuration descriptor */
cfg_desc->bLength = *(uint8_t *) (buf + 0);
cfg_desc->bDescriptorType = *(uint8_t *) (buf + 1);
cfg_desc->wTotalLength = LE16 (buf + 2);
cfg_desc->bNumInterfaces = *(uint8_t *) (buf + 4);
cfg_desc->bConfigurationValue = *(uint8_t *) (buf + 5);
cfg_desc->iConfiguration = *(uint8_t *) (buf + 6);
cfg_desc->bmAttributes = *(uint8_t *) (buf + 7);
cfg_desc->bMaxPower = *(uint8_t *) (buf + 8);
if (length > USB_CONFIGURATION_DESC_SIZE)
{
ptr = USB_LEN_CFG_DESC;
if ( cfg_desc->bNumInterfaces <= USBH_MAX_NUM_INTERFACES)
{
pif = (USBH_InterfaceDesc_TypeDef *)0;
while (ptr < cfg_desc->wTotalLength )
{
pdesc = USBH_GetNextDesc((uint8_t *)pdesc, &ptr);
if (pdesc->bDescriptorType == USB_DESC_TYPE_INTERFACE)
{
if_ix = *(((uint8_t *)pdesc ) + 2);
pif = &itf_desc[if_ix];
if((*((uint8_t *)pdesc + 3)) < 3)
{
USBH_ParseInterfaceDesc (&temp_pif, (uint8_t *)pdesc);
ep_ix = 0;
/* Parse Ep descriptors relative to the current interface */
if(temp_pif.bNumEndpoints <= USBH_MAX_NUM_ENDPOINTS)
{
while (ep_ix < temp_pif.bNumEndpoints)
{
pdesc = USBH_GetNextDesc((void* )pdesc, &ptr);
if (pdesc->bDescriptorType == USB_DESC_TYPE_ENDPOINT)
{
pep = &ep_desc[if_ix][ep_ix];
if(prev_itf != if_ix)
{
prev_itf = if_ix;
USBH_ParseInterfaceDesc (pif, (uint8_t *)&temp_pif);
}
else
{
if(prev_ep_size > LE16((uint8_t *)pdesc + 4))
{
break;
}
else
{
USBH_ParseInterfaceDesc (pif, (uint8_t *)&temp_pif);
}
}
USBH_ParseEPDesc (pep, (uint8_t *)pdesc);
prev_ep_size = LE16((uint8_t *)pdesc + 4);
ep_ix++;
}
}
}
}
}
}
}
prev_ep_size = 0;
prev_itf = 0;
}
}
/**
* @brief USBH_ParseInterfaceDesc
* This function Parses the interface descriptor
* @param if_descriptor : Interface descriptor destination
* @param buf: Buffer where the descriptor data is available
* @retval None
*/
static void USBH_ParseInterfaceDesc (USBH_InterfaceDesc_TypeDef *if_descriptor,
uint8_t *buf)
{
if_descriptor->bLength = *(uint8_t *) (buf + 0);
if_descriptor->bDescriptorType = *(uint8_t *) (buf + 1);
if_descriptor->bInterfaceNumber = *(uint8_t *) (buf + 2);
if_descriptor->bAlternateSetting = *(uint8_t *) (buf + 3);
if_descriptor->bNumEndpoints = *(uint8_t *) (buf + 4);
if_descriptor->bInterfaceClass = *(uint8_t *) (buf + 5);
if_descriptor->bInterfaceSubClass = *(uint8_t *) (buf + 6);
if_descriptor->bInterfaceProtocol = *(uint8_t *) (buf + 7);
if_descriptor->iInterface = *(uint8_t *) (buf + 8);
}
/**
* @brief USBH_ParseEPDesc
* This function Parses the endpoint descriptor
* @param ep_descriptor: Endpoint descriptor destination address
* @param buf: Buffer where the parsed descriptor stored
* @retval None
*/
static void USBH_ParseEPDesc (USBH_EpDesc_TypeDef *ep_descriptor,
uint8_t *buf)
{
ep_descriptor->bLength = *(uint8_t *) (buf + 0);
ep_descriptor->bDescriptorType = *(uint8_t *) (buf + 1);
ep_descriptor->bEndpointAddress = *(uint8_t *) (buf + 2);
ep_descriptor->bmAttributes = *(uint8_t *) (buf + 3);
ep_descriptor->wMaxPacketSize = LE16 (buf + 4);
ep_descriptor->bInterval = *(uint8_t *) (buf + 6);
}
/**
* @brief USBH_ParseStringDesc
* This function Parses the string descriptor
* @param psrc: Source pointer containing the descriptor data
* @param pdest: Destination address pointer
* @param length: Length of the descriptor
* @retval None
*/
static void USBH_ParseStringDesc (uint8_t* psrc,
uint8_t* pdest,
uint16_t length)
{
uint16_t strlength;
uint16_t idx;
/* The UNICODE string descriptor is not NULL-terminated. The string length is
computed by substracting two from the value of the first byte of the descriptor.
*/
/* Check which is lower size, the Size of string or the length of bytes read
from the device */
if ( psrc[1] == USB_DESC_TYPE_STRING)
{ /* Make sure the Descriptor is String Type */
/* psrc[0] contains Size of Descriptor, subtract 2 to get the length of string */
strlength = ( ( (psrc[0]-2) <= length) ? (psrc[0]-2) :length);
psrc += 2; /* Adjust the offset ignoring the String Len and Descriptor type */
for (idx = 0; idx < strlength; idx+=2 )
{/* Copy Only the string and ignore the UNICODE ID, hence add the src */
*pdest = psrc[idx];
pdest++;
}
*pdest = 0; /* mark end of string */
}
}
/**
* @brief USBH_GetNextDesc
* This function return the next descriptor header
* @param buf: Buffer where the cfg descriptor is available
* @param ptr: data popinter inside the cfg descriptor
* @retval next header
*/
USBH_DescHeader_t *USBH_GetNextDesc (uint8_t *pbuf, uint16_t *ptr)
{
USBH_DescHeader_t *pnext;
*ptr += ((USBH_DescHeader_t *)pbuf)->bLength;
pnext = (USBH_DescHeader_t *)((uint8_t *)pbuf + \
((USBH_DescHeader_t *)pbuf)->bLength);
return(pnext);
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,953 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40"><head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<link rel="File-List" href="Release_Notes_for_STM32F2xx_StdPeriph_Driver_files/filelist.xml">
<link rel="Edit-Time-Data" href="Release_Notes_for_STM32F2xx_StdPeriph_Driver_files/editdata.mso"><!--[if !mso]>
<style>
v\:* {behavior:url(#default#VML);}
o\:* {behavior:url(#default#VML);}
w\:* {behavior:url(#default#VML);}
.shape {behavior:url(#default#VML);}
</style>
<![endif]-->
<title>Release Notes for STM32F105/7xx, STM32F2xx and STM32F4xx USB Host Library</title><!--[if gte mso 9]><xml>
<o:DocumentProperties>
<o:Author>STMicroelectronics</o:Author>
<o:LastAuthor>Raouf Hosni</o:LastAuthor>
<o:Revision>39</o:Revision>
<o:TotalTime>137</o:TotalTime>
<o:Created>2009-02-27T19:26:00Z</o:Created>
<o:LastSaved>2010-10-15T11:07:00Z</o:LastSaved>
<o:Pages>3</o:Pages>
<o:Words>973</o:Words>
<o:Characters>5548</o:Characters>
<o:Company>STMicroelectronics</o:Company>
<o:Lines>46</o:Lines>
<o:Paragraphs>13</o:Paragraphs>
<o:CharactersWithSpaces>6508</o:CharactersWithSpaces>
<o:Version>12.00</o:Version>
</o:DocumentProperties>
</xml><![endif]--><link rel="themeData" href="Release_Notes_for_STM32F2xx_StdPeriph_Driver_files/themedata.thmx">
<link rel="colorSchemeMapping" href="Release_Notes_for_STM32F2xx_StdPeriph_Driver_files/colorschememapping.xml"><!--[if gte mso 9]><xml>
<w:WordDocument>
<w:Zoom>110</w:Zoom>
<w:TrackMoves>false</w:TrackMoves>
<w:TrackFormatting/>
<w:ValidateAgainstSchemas/>
<w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid>
<w:IgnoreMixedContent>false</w:IgnoreMixedContent>
<w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText>
<w:DoNotPromoteQF/>
<w:LidThemeOther>EN-US</w:LidThemeOther>
<w:LidThemeAsian>X-NONE</w:LidThemeAsian>
<w:LidThemeComplexScript>X-NONE</w:LidThemeComplexScript>
<w:Compatibility>
<w:BreakWrappedTables/>
<w:SnapToGridInCell/>
<w:WrapTextWithPunct/>
<w:UseAsianBreakRules/>
<w:DontGrowAutofit/>
<w:SplitPgBreakAndParaMark/>
<w:DontVertAlignCellWithSp/>
<w:DontBreakConstrainedForcedTables/>
<w:DontVertAlignInTxbx/>
<w:Word11KerningPairs/>
<w:CachedColBalance/>
</w:Compatibility>
<w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel>
<m:mathPr>
<m:mathFont m:val="Cambria Math"/>
<m:brkBin m:val="before"/>
<m:brkBinSub m:val="&#45;-"/>
<m:smallFrac m:val="off"/>
<m:dispDef/>
<m:lMargin m:val="0"/>
<m:rMargin m:val="0"/>
<m:defJc m:val="centerGroup"/>
<m:wrapIndent m:val="1440"/>
<m:intLim m:val="subSup"/>
<m:naryLim m:val="undOvr"/>
</m:mathPr></w:WordDocument>
</xml><![endif]--><!--[if gte mso 9]><xml>
<w:LatentStyles DefLockedState="false" DefUnhideWhenUsed="false"
DefSemiHidden="false" DefQFormat="false" LatentStyleCount="267">
<w:LsdException Locked="false" QFormat="true" Name="Normal"/>
<w:LsdException Locked="false" QFormat="true" Name="heading 1"/>
<w:LsdException Locked="false" QFormat="true" Name="heading 2"/>
<w:LsdException Locked="false" QFormat="true" Name="heading 3"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
QFormat="true" Name="heading 4"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
QFormat="true" Name="heading 5"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
QFormat="true" Name="heading 6"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
QFormat="true" Name="heading 7"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
QFormat="true" Name="heading 8"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
QFormat="true" Name="heading 9"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
QFormat="true" Name="caption"/>
<w:LsdException Locked="false" QFormat="true" Name="Title"/>
<w:LsdException Locked="false" Priority="1" Name="Default Paragraph Font"/>
<w:LsdException Locked="false" QFormat="true" Name="Subtitle"/>
<w:LsdException Locked="false" QFormat="true" Name="Strong"/>
<w:LsdException Locked="false" QFormat="true" Name="Emphasis"/>
<w:LsdException Locked="false" Priority="99" Name="No List"/>
<w:LsdException Locked="false" Priority="99" SemiHidden="true"
Name="Placeholder Text"/>
<w:LsdException Locked="false" Priority="1" QFormat="true" Name="No Spacing"/>
<w:LsdException Locked="false" Priority="60" Name="Light Shading"/>
<w:LsdException Locked="false" Priority="61" Name="Light List"/>
<w:LsdException Locked="false" Priority="62" Name="Light Grid"/>
<w:LsdException Locked="false" Priority="63" Name="Medium Shading 1"/>
<w:LsdException Locked="false" Priority="64" Name="Medium Shading 2"/>
<w:LsdException Locked="false" Priority="65" Name="Medium List 1"/>
<w:LsdException Locked="false" Priority="66" Name="Medium List 2"/>
<w:LsdException Locked="false" Priority="67" Name="Medium Grid 1"/>
<w:LsdException Locked="false" Priority="68" Name="Medium Grid 2"/>
<w:LsdException Locked="false" Priority="69" Name="Medium Grid 3"/>
<w:LsdException Locked="false" Priority="70" Name="Dark List"/>
<w:LsdException Locked="false" Priority="71" Name="Colorful Shading"/>
<w:LsdException Locked="false" Priority="72" Name="Colorful List"/>
<w:LsdException Locked="false" Priority="73" Name="Colorful Grid"/>
<w:LsdException Locked="false" Priority="60" Name="Light Shading Accent 1"/>
<w:LsdException Locked="false" Priority="61" Name="Light List Accent 1"/>
<w:LsdException Locked="false" Priority="62" Name="Light Grid Accent 1"/>
<w:LsdException Locked="false" Priority="63" Name="Medium Shading 1 Accent 1"/>
<w:LsdException Locked="false" Priority="64" Name="Medium Shading 2 Accent 1"/>
<w:LsdException Locked="false" Priority="65" Name="Medium List 1 Accent 1"/>
<w:LsdException Locked="false" Priority="99" SemiHidden="true" Name="Revision"/>
<w:LsdException Locked="false" Priority="34" QFormat="true"
Name="List Paragraph"/>
<w:LsdException Locked="false" Priority="29" QFormat="true" Name="Quote"/>
<w:LsdException Locked="false" Priority="30" QFormat="true"
Name="Intense Quote"/>
<w:LsdException Locked="false" Priority="66" Name="Medium List 2 Accent 1"/>
<w:LsdException Locked="false" Priority="67" Name="Medium Grid 1 Accent 1"/>
<w:LsdException Locked="false" Priority="68" Name="Medium Grid 2 Accent 1"/>
<w:LsdException Locked="false" Priority="69" Name="Medium Grid 3 Accent 1"/>
<w:LsdException Locked="false" Priority="70" Name="Dark List Accent 1"/>
<w:LsdException Locked="false" Priority="71" Name="Colorful Shading Accent 1"/>
<w:LsdException Locked="false" Priority="72" Name="Colorful List Accent 1"/>
<w:LsdException Locked="false" Priority="73" Name="Colorful Grid Accent 1"/>
<w:LsdException Locked="false" Priority="60" Name="Light Shading Accent 2"/>
<w:LsdException Locked="false" Priority="61" Name="Light List Accent 2"/>
<w:LsdException Locked="false" Priority="62" Name="Light Grid Accent 2"/>
<w:LsdException Locked="false" Priority="63" Name="Medium Shading 1 Accent 2"/>
<w:LsdException Locked="false" Priority="64" Name="Medium Shading 2 Accent 2"/>
<w:LsdException Locked="false" Priority="65" Name="Medium List 1 Accent 2"/>
<w:LsdException Locked="false" Priority="66" Name="Medium List 2 Accent 2"/>
<w:LsdException Locked="false" Priority="67" Name="Medium Grid 1 Accent 2"/>
<w:LsdException Locked="false" Priority="68" Name="Medium Grid 2 Accent 2"/>
<w:LsdException Locked="false" Priority="69" Name="Medium Grid 3 Accent 2"/>
<w:LsdException Locked="false" Priority="70" Name="Dark List Accent 2"/>
<w:LsdException Locked="false" Priority="71" Name="Colorful Shading Accent 2"/>
<w:LsdException Locked="false" Priority="72" Name="Colorful List Accent 2"/>
<w:LsdException Locked="false" Priority="73" Name="Colorful Grid Accent 2"/>
<w:LsdException Locked="false" Priority="60" Name="Light Shading Accent 3"/>
<w:LsdException Locked="false" Priority="61" Name="Light List Accent 3"/>
<w:LsdException Locked="false" Priority="62" Name="Light Grid Accent 3"/>
<w:LsdException Locked="false" Priority="63" Name="Medium Shading 1 Accent 3"/>
<w:LsdException Locked="false" Priority="64" Name="Medium Shading 2 Accent 3"/>
<w:LsdException Locked="false" Priority="65" Name="Medium List 1 Accent 3"/>
<w:LsdException Locked="false" Priority="66" Name="Medium List 2 Accent 3"/>
<w:LsdException Locked="false" Priority="67" Name="Medium Grid 1 Accent 3"/>
<w:LsdException Locked="false" Priority="68" Name="Medium Grid 2 Accent 3"/>
<w:LsdException Locked="false" Priority="69" Name="Medium Grid 3 Accent 3"/>
<w:LsdException Locked="false" Priority="70" Name="Dark List Accent 3"/>
<w:LsdException Locked="false" Priority="71" Name="Colorful Shading Accent 3"/>
<w:LsdException Locked="false" Priority="72" Name="Colorful List Accent 3"/>
<w:LsdException Locked="false" Priority="73" Name="Colorful Grid Accent 3"/>
<w:LsdException Locked="false" Priority="60" Name="Light Shading Accent 4"/>
<w:LsdException Locked="false" Priority="61" Name="Light List Accent 4"/>
<w:LsdException Locked="false" Priority="62" Name="Light Grid Accent 4"/>
<w:LsdException Locked="false" Priority="63" Name="Medium Shading 1 Accent 4"/>
<w:LsdException Locked="false" Priority="64" Name="Medium Shading 2 Accent 4"/>
<w:LsdException Locked="false" Priority="65" Name="Medium List 1 Accent 4"/>
<w:LsdException Locked="false" Priority="66" Name="Medium List 2 Accent 4"/>
<w:LsdException Locked="false" Priority="67" Name="Medium Grid 1 Accent 4"/>
<w:LsdException Locked="false" Priority="68" Name="Medium Grid 2 Accent 4"/>
<w:LsdException Locked="false" Priority="69" Name="Medium Grid 3 Accent 4"/>
<w:LsdException Locked="false" Priority="70" Name="Dark List Accent 4"/>
<w:LsdException Locked="false" Priority="71" Name="Colorful Shading Accent 4"/>
<w:LsdException Locked="false" Priority="72" Name="Colorful List Accent 4"/>
<w:LsdException Locked="false" Priority="73" Name="Colorful Grid Accent 4"/>
<w:LsdException Locked="false" Priority="60" Name="Light Shading Accent 5"/>
<w:LsdException Locked="false" Priority="61" Name="Light List Accent 5"/>
<w:LsdException Locked="false" Priority="62" Name="Light Grid Accent 5"/>
<w:LsdException Locked="false" Priority="63" Name="Medium Shading 1 Accent 5"/>
<w:LsdException Locked="false" Priority="64" Name="Medium Shading 2 Accent 5"/>
<w:LsdException Locked="false" Priority="65" Name="Medium List 1 Accent 5"/>
<w:LsdException Locked="false" Priority="66" Name="Medium List 2 Accent 5"/>
<w:LsdException Locked="false" Priority="67" Name="Medium Grid 1 Accent 5"/>
<w:LsdException Locked="false" Priority="68" Name="Medium Grid 2 Accent 5"/>
<w:LsdException Locked="false" Priority="69" Name="Medium Grid 3 Accent 5"/>
<w:LsdException Locked="false" Priority="70" Name="Dark List Accent 5"/>
<w:LsdException Locked="false" Priority="71" Name="Colorful Shading Accent 5"/>
<w:LsdException Locked="false" Priority="72" Name="Colorful List Accent 5"/>
<w:LsdException Locked="false" Priority="73" Name="Colorful Grid Accent 5"/>
<w:LsdException Locked="false" Priority="60" Name="Light Shading Accent 6"/>
<w:LsdException Locked="false" Priority="61" Name="Light List Accent 6"/>
<w:LsdException Locked="false" Priority="62" Name="Light Grid Accent 6"/>
<w:LsdException Locked="false" Priority="63" Name="Medium Shading 1 Accent 6"/>
<w:LsdException Locked="false" Priority="64" Name="Medium Shading 2 Accent 6"/>
<w:LsdException Locked="false" Priority="65" Name="Medium List 1 Accent 6"/>
<w:LsdException Locked="false" Priority="66" Name="Medium List 2 Accent 6"/>
<w:LsdException Locked="false" Priority="67" Name="Medium Grid 1 Accent 6"/>
<w:LsdException Locked="false" Priority="68" Name="Medium Grid 2 Accent 6"/>
<w:LsdException Locked="false" Priority="69" Name="Medium Grid 3 Accent 6"/>
<w:LsdException Locked="false" Priority="70" Name="Dark List Accent 6"/>
<w:LsdException Locked="false" Priority="71" Name="Colorful Shading Accent 6"/>
<w:LsdException Locked="false" Priority="72" Name="Colorful List Accent 6"/>
<w:LsdException Locked="false" Priority="73" Name="Colorful Grid Accent 6"/>
<w:LsdException Locked="false" Priority="19" QFormat="true"
Name="Subtle Emphasis"/>
<w:LsdException Locked="false" Priority="21" QFormat="true"
Name="Intense Emphasis"/>
<w:LsdException Locked="false" Priority="31" QFormat="true"
Name="Subtle Reference"/>
<w:LsdException Locked="false" Priority="32" QFormat="true"
Name="Intense Reference"/>
<w:LsdException Locked="false" Priority="33" QFormat="true" Name="Book Title"/>
<w:LsdException Locked="false" Priority="37" SemiHidden="true"
UnhideWhenUsed="true" Name="Bibliography"/>
<w:LsdException Locked="false" Priority="39" SemiHidden="true"
UnhideWhenUsed="true" QFormat="true" Name="TOC Heading"/>
</w:LatentStyles>
</xml><![endif]-->
<style>
<!--
/* Font Definitions */
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;
mso-font-charset:1;
mso-generic-font-family:roman;
mso-font-format:other;
mso-font-pitch:variable;
mso-font-signature:0 0 0 0 0 0;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;
mso-font-charset:0;
mso-generic-font-family:swiss;
mso-font-pitch:variable;
mso-font-signature:-1610611985 1073750139 0 0 159 0;}
@font-face
{font-family:Tahoma;
panose-1:2 11 6 4 3 5 4 4 2 4;
mso-font-charset:0;
mso-generic-font-family:swiss;
mso-font-pitch:variable;
mso-font-signature:1627400839 -2147483648 8 0 66047 0;}
@font-face
{font-family:Verdana;
panose-1:2 11 6 4 3 5 4 4 2 4;
mso-font-charset:0;
mso-generic-font-family:swiss;
mso-font-pitch:variable;
mso-font-signature:536871559 0 0 0 415 0;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{mso-style-unhide:no;
mso-style-qformat:yes;
mso-style-parent:"";
margin:0in;
margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:12.0pt;
font-family:"Times New Roman","serif";
mso-fareast-font-family:"Times New Roman";}
h1
{mso-style-unhide:no;
mso-style-qformat:yes;
mso-style-link:"Heading 1 Char";
mso-margin-top-alt:auto;
margin-right:0in;
mso-margin-bottom-alt:auto;
margin-left:0in;
mso-pagination:widow-orphan;
mso-outline-level:1;
font-size:24.0pt;
font-family:"Times New Roman","serif";
mso-fareast-font-family:"Times New Roman";
mso-fareast-theme-font:minor-fareast;
font-weight:bold;}
h2
{mso-style-unhide:no;
mso-style-qformat:yes;
mso-style-link:"Heading 2 Char";
mso-style-next:Normal;
margin-top:12.0pt;
margin-right:0in;
margin-bottom:3.0pt;
margin-left:0in;
mso-pagination:widow-orphan;
page-break-after:avoid;
mso-outline-level:2;
font-size:14.0pt;
font-family:"Arial","sans-serif";
mso-fareast-font-family:"Times New Roman";
mso-fareast-theme-font:minor-fareast;
font-weight:bold;
font-style:italic;}
h3
{mso-style-unhide:no;
mso-style-qformat:yes;
mso-style-link:"Heading 3 Char";
mso-margin-top-alt:auto;
margin-right:0in;
mso-margin-bottom-alt:auto;
margin-left:0in;
mso-pagination:widow-orphan;
mso-outline-level:3;
font-size:13.5pt;
font-family:"Times New Roman","serif";
mso-fareast-font-family:"Times New Roman";
mso-fareast-theme-font:minor-fareast;
font-weight:bold;}
a:link, span.MsoHyperlink
{mso-style-unhide:no;
color:blue;
text-decoration:underline;
text-underline:single;}
a:visited, span.MsoHyperlinkFollowed
{mso-style-unhide:no;
color:blue;
text-decoration:underline;
text-underline:single;}
p
{mso-style-unhide:no;
mso-margin-top-alt:auto;
margin-right:0in;
mso-margin-bottom-alt:auto;
margin-left:0in;
mso-pagination:widow-orphan;
font-size:12.0pt;
font-family:"Times New Roman","serif";
mso-fareast-font-family:"Times New Roman";}
p.MsoAcetate, li.MsoAcetate, div.MsoAcetate
{mso-style-unhide:no;
mso-style-link:"Balloon Text Char";
margin:0in;
margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:8.0pt;
font-family:"Tahoma","sans-serif";
mso-fareast-font-family:"Times New Roman";}
span.Heading1Char
{mso-style-name:"Heading 1 Char";
mso-style-unhide:no;
mso-style-locked:yes;
mso-style-link:"Heading 1";
mso-ansi-font-size:14.0pt;
mso-bidi-font-size:14.0pt;
font-family:"Cambria","serif";
mso-ascii-font-family:Cambria;
mso-ascii-theme-font:major-latin;
mso-fareast-font-family:"Times New Roman";
mso-fareast-theme-font:major-fareast;
mso-hansi-font-family:Cambria;
mso-hansi-theme-font:major-latin;
mso-bidi-font-family:"Times New Roman";
mso-bidi-theme-font:major-bidi;
color:#365F91;
mso-themecolor:accent1;
mso-themeshade:191;
font-weight:bold;}
span.Heading2Char
{mso-style-name:"Heading 2 Char";
mso-style-unhide:no;
mso-style-locked:yes;
mso-style-link:"Heading 2";
mso-ansi-font-size:13.0pt;
mso-bidi-font-size:13.0pt;
font-family:"Cambria","serif";
mso-ascii-font-family:Cambria;
mso-ascii-theme-font:major-latin;
mso-fareast-font-family:"Times New Roman";
mso-fareast-theme-font:major-fareast;
mso-hansi-font-family:Cambria;
mso-hansi-theme-font:major-latin;
mso-bidi-font-family:"Times New Roman";
mso-bidi-theme-font:major-bidi;
color:#4F81BD;
mso-themecolor:accent1;
font-weight:bold;}
span.Heading3Char
{mso-style-name:"Heading 3 Char";
mso-style-unhide:no;
mso-style-locked:yes;
mso-style-link:"Heading 3";
mso-ansi-font-size:12.0pt;
mso-bidi-font-size:12.0pt;
font-family:"Cambria","serif";
mso-ascii-font-family:Cambria;
mso-ascii-theme-font:major-latin;
mso-fareast-font-family:"Times New Roman";
mso-fareast-theme-font:major-fareast;
mso-hansi-font-family:Cambria;
mso-hansi-theme-font:major-latin;
mso-bidi-font-family:"Times New Roman";
mso-bidi-theme-font:major-bidi;
color:#4F81BD;
mso-themecolor:accent1;
font-weight:bold;}
span.BalloonTextChar
{mso-style-name:"Balloon Text Char";
mso-style-unhide:no;
mso-style-locked:yes;
mso-style-link:"Balloon Text";
mso-ansi-font-size:8.0pt;
mso-bidi-font-size:8.0pt;
font-family:"Tahoma","sans-serif";
mso-ascii-font-family:Tahoma;
mso-hansi-font-family:Tahoma;
mso-bidi-font-family:Tahoma;}
.MsoChpDefault
{mso-style-type:export-only;
mso-default-props:yes;
font-size:10.0pt;
mso-ansi-font-size:10.0pt;
mso-bidi-font-size:10.0pt;}
@page WordSection1
{size:8.5in 11.0in;
margin:1.0in 1.25in 1.0in 1.25in;
mso-header-margin:.5in;
mso-footer-margin:.5in;
mso-paper-source:0;}
div.WordSection1
{page:WordSection1;}
/* List Definitions */
@list l0
{mso-list-id:62067358;
mso-list-template-ids:-174943062;}
@list l0:level1
{mso-level-number-format:bullet;
mso-level-text:\F0B7;
mso-level-tab-stop:.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l0:level2
{mso-level-tab-stop:1.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l0:level3
{mso-level-tab-stop:1.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l0:level4
{mso-level-tab-stop:2.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l0:level5
{mso-level-tab-stop:2.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l0:level6
{mso-level-tab-stop:3.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l0:level7
{mso-level-tab-stop:3.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l0:level8
{mso-level-tab-stop:4.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l0:level9
{mso-level-tab-stop:4.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l1
{mso-list-id:128015942;
mso-list-template-ids:-90681214;}
@list l1:level1
{mso-level-tab-stop:.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l1:level2
{mso-level-tab-stop:1.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l1:level3
{mso-level-tab-stop:1.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l1:level4
{mso-level-tab-stop:2.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l1:level5
{mso-level-tab-stop:2.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l1:level6
{mso-level-tab-stop:3.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l1:level7
{mso-level-tab-stop:3.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l1:level8
{mso-level-tab-stop:4.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l1:level9
{mso-level-tab-stop:4.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l2
{mso-list-id:216556000;
mso-list-template-ids:925924412;}
@list l2:level1
{mso-level-number-format:bullet;
mso-level-text:\F0B7;
mso-level-tab-stop:.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l2:level2
{mso-level-number-format:bullet;
mso-level-text:\F0B7;
mso-level-tab-stop:1.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l2:level3
{mso-level-tab-stop:1.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l2:level4
{mso-level-tab-stop:2.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l2:level5
{mso-level-tab-stop:2.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l2:level6
{mso-level-tab-stop:3.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l2:level7
{mso-level-tab-stop:3.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l2:level8
{mso-level-tab-stop:4.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l2:level9
{mso-level-tab-stop:4.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l3
{mso-list-id:562446694;
mso-list-template-ids:913898366;}
@list l3:level1
{mso-level-number-format:bullet;
mso-level-text:\F0B7;
mso-level-tab-stop:.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l3:level2
{mso-level-tab-stop:1.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l3:level3
{mso-level-tab-stop:1.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l3:level4
{mso-level-tab-stop:2.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l3:level5
{mso-level-tab-stop:2.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l3:level6
{mso-level-tab-stop:3.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l3:level7
{mso-level-tab-stop:3.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l3:level8
{mso-level-tab-stop:4.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l3:level9
{mso-level-tab-stop:4.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l4
{mso-list-id:797802132;
mso-list-template-ids:-1971191336;}
@list l4:level1
{mso-level-tab-stop:.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l4:level2
{mso-level-tab-stop:1.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l4:level3
{mso-level-tab-stop:1.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l4:level4
{mso-level-tab-stop:2.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l4:level5
{mso-level-tab-stop:2.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l4:level6
{mso-level-tab-stop:3.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l4:level7
{mso-level-tab-stop:3.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l4:level8
{mso-level-tab-stop:4.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l4:level9
{mso-level-tab-stop:4.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l5
{mso-list-id:907304066;
mso-list-template-ids:1969781532;}
@list l5:level1
{mso-level-tab-stop:.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l5:level2
{mso-level-tab-stop:1.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l5:level3
{mso-level-tab-stop:1.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l5:level4
{mso-level-tab-stop:2.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l5:level5
{mso-level-tab-stop:2.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l5:level6
{mso-level-tab-stop:3.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l5:level7
{mso-level-tab-stop:3.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l5:level8
{mso-level-tab-stop:4.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l5:level9
{mso-level-tab-stop:4.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l6
{mso-list-id:1050613616;
mso-list-template-ids:-1009886748;}
@list l6:level1
{mso-level-number-format:bullet;
mso-level-text:\F0B7;
mso-level-tab-stop:.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l6:level2
{mso-level-number-format:bullet;
mso-level-text:\F0B7;
mso-level-tab-stop:1.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l6:level3
{mso-level-tab-stop:1.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l6:level4
{mso-level-tab-stop:2.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l6:level5
{mso-level-tab-stop:2.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l6:level6
{mso-level-tab-stop:3.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l6:level7
{mso-level-tab-stop:3.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l6:level8
{mso-level-tab-stop:4.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l6:level9
{mso-level-tab-stop:4.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l7
{mso-list-id:1234970193;
mso-list-template-ids:2055904002;}
@list l7:level1
{mso-level-number-format:bullet;
mso-level-text:\F0B7;
mso-level-tab-stop:.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l7:level2
{mso-level-number-format:bullet;
mso-level-text:\F0B7;
mso-level-tab-stop:1.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l7:level3
{mso-level-tab-stop:1.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l7:level4
{mso-level-tab-stop:2.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l7:level5
{mso-level-tab-stop:2.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l7:level6
{mso-level-tab-stop:3.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l7:level7
{mso-level-tab-stop:3.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l7:level8
{mso-level-tab-stop:4.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l7:level9
{mso-level-tab-stop:4.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l8
{mso-list-id:1846092290;
mso-list-template-ids:-768590846;}
@list l8:level1
{mso-level-start-at:2;
mso-level-tab-stop:.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l8:level2
{mso-level-tab-stop:1.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l8:level3
{mso-level-tab-stop:1.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l8:level4
{mso-level-tab-stop:2.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l8:level5
{mso-level-tab-stop:2.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l8:level6
{mso-level-tab-stop:3.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l8:level7
{mso-level-tab-stop:3.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l8:level8
{mso-level-tab-stop:4.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l8:level9
{mso-level-tab-stop:4.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l9
{mso-list-id:1894656566;
mso-list-template-ids:1199983812;}
@list l9:level1
{mso-level-start-at:2;
mso-level-tab-stop:.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l9:level2
{mso-level-tab-stop:1.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l9:level3
{mso-level-tab-stop:1.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l9:level4
{mso-level-tab-stop:2.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l9:level5
{mso-level-tab-stop:2.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l9:level6
{mso-level-tab-stop:3.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l9:level7
{mso-level-tab-stop:3.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l9:level8
{mso-level-tab-stop:4.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l9:level9
{mso-level-tab-stop:4.5in;
mso-level-number-position:left;
text-indent:-.25in;}
ol
{margin-bottom:0in;}
ul
{margin-bottom:0in;}
-->
</style><!--[if gte mso 10]>
<style>
/* Style Definitions */
table.MsoNormalTable
{mso-style-name:"Table Normal";
mso-tstyle-rowband-size:0;
mso-tstyle-colband-size:0;
mso-style-noshow:yes;
mso-style-priority:99;
mso-style-qformat:yes;
mso-style-parent:"";
mso-padding-alt:0in 5.4pt 0in 5.4pt;
mso-para-margin:0in;
mso-para-margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:10.0pt;
font-family:"Times New Roman","serif";}
</style>
<![endif]--><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="7170"/>
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1"/>
</o:shapelayout></xml><![endif]--><meta content="MCD Application Team" name="author"></head>
<body style="" link="blue" vlink="blue">
<div class="WordSection1">
<p class="MsoNormal"><span style="font-family: &quot;Arial&quot;,&quot;sans-serif&quot;;"><o:p>&nbsp;</o:p></span></p>
<div align="center">
<table class="MsoNormalTable" style="width: 675pt;" border="0" cellpadding="0" cellspacing="0" width="900">
<tbody><tr style="">
<td style="padding: 0in;" valign="top">
<table class="MsoNormalTable" style="width: 675pt;" border="0" cellpadding="0" cellspacing="0" width="900">
<tbody><tr style="">
<td style="padding: 0in 5.4pt;" valign="top">
<p class="MsoNormal"><span style="font-size: 8pt; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; color: blue;"><a href="../../Release_Notes.html">Back to Release page</a></span><span style="font-size: 10pt;"><o:p></o:p></span></p>
</td>
</tr>
<tr style="">
<td style="padding: 1.5pt;">
<h1 style="margin-bottom: 0.25in; text-align: center;" align="center"><span style="font-size: 20pt; font-family: &quot;Verdana&quot;,&quot;sans-serif&quot;; color: rgb(51, 102, 255);">Release Notes for STM32F105/7xx, STM32F2xx and STM32F4xx USB Host Library</span><span style="font-size: 20pt; font-family: &quot;Verdana&quot;,&quot;sans-serif&quot;;"><o:p></o:p></span></h1>
<p class="MsoNormal" style="text-align: center;" align="center"><span style="font-size: 10pt; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; color: black;">Copyright
2012 STMicroelectronics</span><span style="color: black;"><u1:p></u1:p><o:p></o:p></span></p>
<p class="MsoNormal" style="text-align: center;" align="center"><span style="font-size: 10pt; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; color: black;"><img id="_x0000_i1026" src="../../_htmresc/logo.bmp" border="0" height="65" width="86"></span><span style="font-size: 10pt;"><o:p></o:p></span></p>
</td>
</tr>
</tbody></table>
<p class="MsoNormal"><span style="font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; display: none;"><o:p>&nbsp;</o:p></span></p>
<table class="MsoNormalTable" style="width: 675pt;" border="0" cellpadding="0" width="900">
<tbody><tr style="">
<td style="padding: 0in;" valign="top">
<h2 style="background: rgb(51, 102, 255) none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"><span style="font-size: 12pt; color: white;">Contents<o:p></o:p></span></h2>
<ol style="margin-top: 0in;" start="1" type="1">
<li class="MsoNormal" style="color: black; margin-top: 4.5pt; margin-bottom: 4.5pt;"><span style="font-size: 10pt; font-family: &quot;Verdana&quot;,&quot;sans-serif&quot;;"><a href="#History">Update History</a><o:p></o:p></span></li>
<li class="MsoNormal" style="color: black; margin-top: 4.5pt; margin-bottom: 4.5pt;"><span style="font-size: 10pt; font-family: &quot;Verdana&quot;,&quot;sans-serif&quot;;"><a href="#License">License</a><o:p></o:p></span></li>
</ol>
<h2 style="background: rgb(51, 102, 255) none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"><a name="History"></a><span style="font-size: 12pt; color: white;">Update History</span></h2><h3 style="background: rgb(51, 102, 255) none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; margin-right: 500pt; width: 200px;"><span style="font-size: 10pt; font-family: Arial; color: white;">V2.1.0 / 19-March-2012<o:p></o:p></span></h3>
<p class="MsoNormal" style="margin: 4.5pt 0cm 4.5pt 18pt;"><b style=""><u><span style="font-size: 10pt; font-family: Verdana; color: black;">Main
Changes<o:p></o:p></span></u></b></p>
<ul style="margin-top: 0cm;" type="square"><li class="MsoNormal" style="color: black; margin-top: 4.5pt; margin-bottom: 4.5pt;"><span style="font-size: 10pt; font-family: Verdana;">Official support of </span><span style="font-size: 10pt; font-family: Verdana;"><span style="font-weight: bold; font-style: italic;">STM32F4xx</span> devices</span></li><li class="MsoNormal" style="color: black; margin-top: 4.5pt; margin-bottom: 4.5pt;"><span style="font-size: 10pt; font-family: Verdana;">All source files: license disclaimer text update and add link to the License file on ST Internet</span></li><li class="MsoNormal" style="color: black; margin-top: 4.5pt; margin-bottom: 4.5pt;"><span style="font-size: 10pt; font-family: Verdana;">Add ISR structure to link the low level driver to the Host library</span></li><li class="MsoNormal" style="color: black; margin-top: 4.5pt; margin-bottom: 4.5pt;"><span style="font-size: 10pt; font-family: Verdana;">Change length parameter in the I/O operations to handle large amount of data</span></li><li class="MsoNormal" style="color: black; margin-top: 4.5pt; margin-bottom: 4.5pt;"><span style="font-size: 10pt; font-family: Verdana;">Enhance the configuration descriptor parsing method to take into account multi interface devices</span></li><li class="MsoNormal" style="color: black; margin-top: 4.5pt; margin-bottom: 4.5pt;"><span style="font-size: 10pt; font-family: Verdana;">HID class</span></li><ul><li class="MsoNormal" style="color: black; margin-top: 4.5pt; margin-bottom: 4.5pt;"><span style="font-size: 10pt; font-family: Verdana;">Remove blocking even frame synchronization loop</span></li></ul><li class="MsoNormal" style="color: black; margin-top: 4.5pt; margin-bottom: 4.5pt;"><span style="font-size: 10pt; font-family: Verdana;">MSC class</span></li><ul><li class="MsoNormal" style="color: black; margin-top: 4.5pt; margin-bottom: 4.5pt;"><span style="font-size: 10pt; font-family: Verdana;">Handle correctly the BOT transfer with length &lt; max length</span></li></ul><ul><li class="MsoNormal" style="color: black; margin-top: 4.5pt; margin-bottom: 4.5pt;"><span style="font-size: 10pt; font-family: Verdana;">Handle multi sector length data in the FAT FS interface</span></li></ul><li class="MsoNormal" style="color: black; margin-top: 4.5pt; margin-bottom: 4.5pt;"><span style="font-size: 10pt; font-family: Verdana;">Miscellaneous bug fix<br></span></li></ul><h3 style="background: rgb(51, 102, 255) none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; margin-right: 500pt; width: 171px;"><span style="font-size: 10pt; font-family: Arial; color: white;">V2.0.0 / 22-July-2011 <o:p></o:p></span></h3><p class="MsoNormal" style="margin: 4.5pt 0cm 4.5pt 18pt;"><b style=""><u><span style="font-size: 10pt; font-family: Verdana; color: black;">Main
Changes<o:p></o:p></span></u></b></p>
<ul style="margin-top: 0cm;" type="square"><li class="MsoNormal" style="color: black; margin-top: 4.5pt; margin-bottom: 4.5pt;"><span style="font-size: 10pt; font-family: Verdana;">Second official version supporting STM32F105/7 and STM32F2xx devices</span></li><li class="MsoNormal" style="color: black; margin-top: 4.5pt; margin-bottom: 4.5pt;"><span style="font-size: 10pt; font-family: Verdana;">Add support for <span style="font-weight: bold; font-style: italic;">STM32F2xx</span> devices</span><span style="font-size: 10pt; font-family: Verdana;"></span></li><li class="MsoNormal" style="color: black; margin-top: 4.5pt; margin-bottom: 4.5pt;"><span style="font-size: 10pt; font-family: Verdana;">Add multi interface feature</span><span style="font-size: 10pt; font-family: Verdana;"></span></li><li class="MsoNormal" style="color: black; margin-top: 4.5pt; margin-bottom: 4.5pt;"><span style="font-size: 10pt; font-family: Verdana;">Add dynamic configuration parsing</span></li><li class="MsoNormal" style="color: black; margin-top: 4.5pt; margin-bottom: 4.5pt;"><span style="font-size: 10pt; font-family: Verdana;">Add
USBH_DeAllocate_AllChannel function in the Host channel management
layer to clean up channels allocation table when de-initializing the
library</span></li><li class="MsoNormal" style="color: black; margin-top: 4.5pt; margin-bottom: 4.5pt;"><span style="font-size: 10pt; font-family: Verdana;">Change the core layer to stop correctly the host core and free all allocated channels</span></li><li class="MsoNormal" style="color: black; margin-top: 4.5pt; margin-bottom: 4.5pt;"><span style="font-size: 10pt; font-family: Verdana;">Add usbh_conf.h file in the application layer to customize some user parameters</span></li></ul><span style="font-size: 10pt; font-family: Verdana;"><br></span><h3 style="background: rgb(51, 102, 255) none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; margin-right: 500pt; width: 171px;"><span style="font-size: 10pt; font-family: Arial; color: white;">V1.0.0&nbsp;- 11/29/2010<o:p></o:p></span></h3>
<ul style="margin-top: 0cm;" type="square"><li class="MsoNormal" style="color: black; margin-top: 4.5pt; margin-bottom: 4.5pt;"><span style="font-size: 10pt; font-family: Verdana;">Created&nbsp;</span></li></ul><h2 style="background: rgb(51, 102, 255) none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"><a name="License"></a><span style="font-size: 12pt; color: white;">License<o:p></o:p></span></h2>
<p class="MsoNormal"><span style="font-size: 10pt; font-family: &quot;Verdana&quot;,&quot;sans-serif&quot;; color: black;">Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); You may not use this&nbsp;</span><span style="font-size: 10pt; font-family: &quot;Verdana&quot;,&quot;sans-serif&quot;; color: black;">package</span><span style="font-size: 10pt; font-family: &quot;Verdana&quot;,&quot;sans-serif&quot;; color: black;"> except in compliance with the License. You may obtain a copy of the License at:<br><br></span></p><div style="text-align: center;"><span style="font-size: 10pt; font-family: &quot;Verdana&quot;,&quot;sans-serif&quot;; color: black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a target="_blank" href="http://www.st.com/software_license_agreement_liberty_v2">http://www.st.com/software_license_agreement_liberty_v2</a></span><br><span style="font-size: 10pt; font-family: &quot;Verdana&quot;,&quot;sans-serif&quot;; color: black;"></span></div><span style="font-size: 10pt; font-family: &quot;Verdana&quot;,&quot;sans-serif&quot;; color: black;"><br>Unless
required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, <br>WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See
the License for the specific language governing permissions and
limitations under the License.</span>
<div class="MsoNormal" style="text-align: center;" align="center"><span style="color: black;">
<hr align="center" size="2" width="100%">
</span></div>
<p class="MsoNormal" style="margin: 4.5pt 0in 4.5pt 0.25in; text-align: center;" align="center"><span style="font-size: 10pt; font-family: &quot;Verdana&quot;,&quot;sans-serif&quot;; color: black;">For
complete documentation on </span><span style="font-size: 10pt; font-family: &quot;Verdana&quot;,&quot;sans-serif&quot;;">STM32<span style="color: black;">
Microcontrollers visit </span><u><span style="color: blue;"><a href="http://www.st.com/internet/mcu/family/141.jsp" target="_blank">www.st.com/STM32</a></span></u></span><span style="font-size: 10pt; font-family: &quot;Verdana&quot;,&quot;sans-serif&quot;;"><u><span style="color: blue;"><a href="http://www.st.com/stm32" target="_blank"></a></span></u></span><span style="color: black;"><o:p></o:p></span></p>
</td>
</tr>
</tbody></table>
<p class="MsoNormal"><span style="font-size: 10pt;"><o:p></o:p></span></p>
</td>
</tr>
</tbody></table>
</div>
<p class="MsoNormal"><o:p>&nbsp;</o:p></p>
</div>
</body></html>

View File

@ -0,0 +1,950 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40"><head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<link rel="File-List" href="Release_Notes_for_STM32F2xx_StdPeriph_Driver_files/filelist.xml">
<link rel="Edit-Time-Data" href="Release_Notes_for_STM32F2xx_StdPeriph_Driver_files/editdata.mso"><!--[if !mso]>
<style>
v\:* {behavior:url(#default#VML);}
o\:* {behavior:url(#default#VML);}
w\:* {behavior:url(#default#VML);}
.shape {behavior:url(#default#VML);}
</style>
<![endif]-->
<title>Release Notes for STM32F105/7xx, STM32F2xx and STM32F4xx USB OTG Driver</title><!--[if gte mso 9]><xml>
<o:DocumentProperties>
<o:Author>STMicroelectronics</o:Author>
<o:LastAuthor>Raouf Hosni</o:LastAuthor>
<o:Revision>39</o:Revision>
<o:TotalTime>137</o:TotalTime>
<o:Created>2009-02-27T19:26:00Z</o:Created>
<o:LastSaved>2010-10-15T11:07:00Z</o:LastSaved>
<o:Pages>3</o:Pages>
<o:Words>973</o:Words>
<o:Characters>5548</o:Characters>
<o:Company>STMicroelectronics</o:Company>
<o:Lines>46</o:Lines>
<o:Paragraphs>13</o:Paragraphs>
<o:CharactersWithSpaces>6508</o:CharactersWithSpaces>
<o:Version>12.00</o:Version>
</o:DocumentProperties>
</xml><![endif]--><link rel="themeData" href="Release_Notes_for_STM32F2xx_StdPeriph_Driver_files/themedata.thmx">
<link rel="colorSchemeMapping" href="Release_Notes_for_STM32F2xx_StdPeriph_Driver_files/colorschememapping.xml"><!--[if gte mso 9]><xml>
<w:WordDocument>
<w:Zoom>110</w:Zoom>
<w:TrackMoves>false</w:TrackMoves>
<w:TrackFormatting/>
<w:ValidateAgainstSchemas/>
<w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid>
<w:IgnoreMixedContent>false</w:IgnoreMixedContent>
<w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText>
<w:DoNotPromoteQF/>
<w:LidThemeOther>EN-US</w:LidThemeOther>
<w:LidThemeAsian>X-NONE</w:LidThemeAsian>
<w:LidThemeComplexScript>X-NONE</w:LidThemeComplexScript>
<w:Compatibility>
<w:BreakWrappedTables/>
<w:SnapToGridInCell/>
<w:WrapTextWithPunct/>
<w:UseAsianBreakRules/>
<w:DontGrowAutofit/>
<w:SplitPgBreakAndParaMark/>
<w:DontVertAlignCellWithSp/>
<w:DontBreakConstrainedForcedTables/>
<w:DontVertAlignInTxbx/>
<w:Word11KerningPairs/>
<w:CachedColBalance/>
</w:Compatibility>
<w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel>
<m:mathPr>
<m:mathFont m:val="Cambria Math"/>
<m:brkBin m:val="before"/>
<m:brkBinSub m:val="&#45;-"/>
<m:smallFrac m:val="off"/>
<m:dispDef/>
<m:lMargin m:val="0"/>
<m:rMargin m:val="0"/>
<m:defJc m:val="centerGroup"/>
<m:wrapIndent m:val="1440"/>
<m:intLim m:val="subSup"/>
<m:naryLim m:val="undOvr"/>
</m:mathPr></w:WordDocument>
</xml><![endif]--><!--[if gte mso 9]><xml>
<w:LatentStyles DefLockedState="false" DefUnhideWhenUsed="false"
DefSemiHidden="false" DefQFormat="false" LatentStyleCount="267">
<w:LsdException Locked="false" QFormat="true" Name="Normal"/>
<w:LsdException Locked="false" QFormat="true" Name="heading 1"/>
<w:LsdException Locked="false" QFormat="true" Name="heading 2"/>
<w:LsdException Locked="false" QFormat="true" Name="heading 3"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
QFormat="true" Name="heading 4"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
QFormat="true" Name="heading 5"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
QFormat="true" Name="heading 6"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
QFormat="true" Name="heading 7"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
QFormat="true" Name="heading 8"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
QFormat="true" Name="heading 9"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
QFormat="true" Name="caption"/>
<w:LsdException Locked="false" QFormat="true" Name="Title"/>
<w:LsdException Locked="false" Priority="1" Name="Default Paragraph Font"/>
<w:LsdException Locked="false" QFormat="true" Name="Subtitle"/>
<w:LsdException Locked="false" QFormat="true" Name="Strong"/>
<w:LsdException Locked="false" QFormat="true" Name="Emphasis"/>
<w:LsdException Locked="false" Priority="99" Name="No List"/>
<w:LsdException Locked="false" Priority="99" SemiHidden="true"
Name="Placeholder Text"/>
<w:LsdException Locked="false" Priority="1" QFormat="true" Name="No Spacing"/>
<w:LsdException Locked="false" Priority="60" Name="Light Shading"/>
<w:LsdException Locked="false" Priority="61" Name="Light List"/>
<w:LsdException Locked="false" Priority="62" Name="Light Grid"/>
<w:LsdException Locked="false" Priority="63" Name="Medium Shading 1"/>
<w:LsdException Locked="false" Priority="64" Name="Medium Shading 2"/>
<w:LsdException Locked="false" Priority="65" Name="Medium List 1"/>
<w:LsdException Locked="false" Priority="66" Name="Medium List 2"/>
<w:LsdException Locked="false" Priority="67" Name="Medium Grid 1"/>
<w:LsdException Locked="false" Priority="68" Name="Medium Grid 2"/>
<w:LsdException Locked="false" Priority="69" Name="Medium Grid 3"/>
<w:LsdException Locked="false" Priority="70" Name="Dark List"/>
<w:LsdException Locked="false" Priority="71" Name="Colorful Shading"/>
<w:LsdException Locked="false" Priority="72" Name="Colorful List"/>
<w:LsdException Locked="false" Priority="73" Name="Colorful Grid"/>
<w:LsdException Locked="false" Priority="60" Name="Light Shading Accent 1"/>
<w:LsdException Locked="false" Priority="61" Name="Light List Accent 1"/>
<w:LsdException Locked="false" Priority="62" Name="Light Grid Accent 1"/>
<w:LsdException Locked="false" Priority="63" Name="Medium Shading 1 Accent 1"/>
<w:LsdException Locked="false" Priority="64" Name="Medium Shading 2 Accent 1"/>
<w:LsdException Locked="false" Priority="65" Name="Medium List 1 Accent 1"/>
<w:LsdException Locked="false" Priority="99" SemiHidden="true" Name="Revision"/>
<w:LsdException Locked="false" Priority="34" QFormat="true"
Name="List Paragraph"/>
<w:LsdException Locked="false" Priority="29" QFormat="true" Name="Quote"/>
<w:LsdException Locked="false" Priority="30" QFormat="true"
Name="Intense Quote"/>
<w:LsdException Locked="false" Priority="66" Name="Medium List 2 Accent 1"/>
<w:LsdException Locked="false" Priority="67" Name="Medium Grid 1 Accent 1"/>
<w:LsdException Locked="false" Priority="68" Name="Medium Grid 2 Accent 1"/>
<w:LsdException Locked="false" Priority="69" Name="Medium Grid 3 Accent 1"/>
<w:LsdException Locked="false" Priority="70" Name="Dark List Accent 1"/>
<w:LsdException Locked="false" Priority="71" Name="Colorful Shading Accent 1"/>
<w:LsdException Locked="false" Priority="72" Name="Colorful List Accent 1"/>
<w:LsdException Locked="false" Priority="73" Name="Colorful Grid Accent 1"/>
<w:LsdException Locked="false" Priority="60" Name="Light Shading Accent 2"/>
<w:LsdException Locked="false" Priority="61" Name="Light List Accent 2"/>
<w:LsdException Locked="false" Priority="62" Name="Light Grid Accent 2"/>
<w:LsdException Locked="false" Priority="63" Name="Medium Shading 1 Accent 2"/>
<w:LsdException Locked="false" Priority="64" Name="Medium Shading 2 Accent 2"/>
<w:LsdException Locked="false" Priority="65" Name="Medium List 1 Accent 2"/>
<w:LsdException Locked="false" Priority="66" Name="Medium List 2 Accent 2"/>
<w:LsdException Locked="false" Priority="67" Name="Medium Grid 1 Accent 2"/>
<w:LsdException Locked="false" Priority="68" Name="Medium Grid 2 Accent 2"/>
<w:LsdException Locked="false" Priority="69" Name="Medium Grid 3 Accent 2"/>
<w:LsdException Locked="false" Priority="70" Name="Dark List Accent 2"/>
<w:LsdException Locked="false" Priority="71" Name="Colorful Shading Accent 2"/>
<w:LsdException Locked="false" Priority="72" Name="Colorful List Accent 2"/>
<w:LsdException Locked="false" Priority="73" Name="Colorful Grid Accent 2"/>
<w:LsdException Locked="false" Priority="60" Name="Light Shading Accent 3"/>
<w:LsdException Locked="false" Priority="61" Name="Light List Accent 3"/>
<w:LsdException Locked="false" Priority="62" Name="Light Grid Accent 3"/>
<w:LsdException Locked="false" Priority="63" Name="Medium Shading 1 Accent 3"/>
<w:LsdException Locked="false" Priority="64" Name="Medium Shading 2 Accent 3"/>
<w:LsdException Locked="false" Priority="65" Name="Medium List 1 Accent 3"/>
<w:LsdException Locked="false" Priority="66" Name="Medium List 2 Accent 3"/>
<w:LsdException Locked="false" Priority="67" Name="Medium Grid 1 Accent 3"/>
<w:LsdException Locked="false" Priority="68" Name="Medium Grid 2 Accent 3"/>
<w:LsdException Locked="false" Priority="69" Name="Medium Grid 3 Accent 3"/>
<w:LsdException Locked="false" Priority="70" Name="Dark List Accent 3"/>
<w:LsdException Locked="false" Priority="71" Name="Colorful Shading Accent 3"/>
<w:LsdException Locked="false" Priority="72" Name="Colorful List Accent 3"/>
<w:LsdException Locked="false" Priority="73" Name="Colorful Grid Accent 3"/>
<w:LsdException Locked="false" Priority="60" Name="Light Shading Accent 4"/>
<w:LsdException Locked="false" Priority="61" Name="Light List Accent 4"/>
<w:LsdException Locked="false" Priority="62" Name="Light Grid Accent 4"/>
<w:LsdException Locked="false" Priority="63" Name="Medium Shading 1 Accent 4"/>
<w:LsdException Locked="false" Priority="64" Name="Medium Shading 2 Accent 4"/>
<w:LsdException Locked="false" Priority="65" Name="Medium List 1 Accent 4"/>
<w:LsdException Locked="false" Priority="66" Name="Medium List 2 Accent 4"/>
<w:LsdException Locked="false" Priority="67" Name="Medium Grid 1 Accent 4"/>
<w:LsdException Locked="false" Priority="68" Name="Medium Grid 2 Accent 4"/>
<w:LsdException Locked="false" Priority="69" Name="Medium Grid 3 Accent 4"/>
<w:LsdException Locked="false" Priority="70" Name="Dark List Accent 4"/>
<w:LsdException Locked="false" Priority="71" Name="Colorful Shading Accent 4"/>
<w:LsdException Locked="false" Priority="72" Name="Colorful List Accent 4"/>
<w:LsdException Locked="false" Priority="73" Name="Colorful Grid Accent 4"/>
<w:LsdException Locked="false" Priority="60" Name="Light Shading Accent 5"/>
<w:LsdException Locked="false" Priority="61" Name="Light List Accent 5"/>
<w:LsdException Locked="false" Priority="62" Name="Light Grid Accent 5"/>
<w:LsdException Locked="false" Priority="63" Name="Medium Shading 1 Accent 5"/>
<w:LsdException Locked="false" Priority="64" Name="Medium Shading 2 Accent 5"/>
<w:LsdException Locked="false" Priority="65" Name="Medium List 1 Accent 5"/>
<w:LsdException Locked="false" Priority="66" Name="Medium List 2 Accent 5"/>
<w:LsdException Locked="false" Priority="67" Name="Medium Grid 1 Accent 5"/>
<w:LsdException Locked="false" Priority="68" Name="Medium Grid 2 Accent 5"/>
<w:LsdException Locked="false" Priority="69" Name="Medium Grid 3 Accent 5"/>
<w:LsdException Locked="false" Priority="70" Name="Dark List Accent 5"/>
<w:LsdException Locked="false" Priority="71" Name="Colorful Shading Accent 5"/>
<w:LsdException Locked="false" Priority="72" Name="Colorful List Accent 5"/>
<w:LsdException Locked="false" Priority="73" Name="Colorful Grid Accent 5"/>
<w:LsdException Locked="false" Priority="60" Name="Light Shading Accent 6"/>
<w:LsdException Locked="false" Priority="61" Name="Light List Accent 6"/>
<w:LsdException Locked="false" Priority="62" Name="Light Grid Accent 6"/>
<w:LsdException Locked="false" Priority="63" Name="Medium Shading 1 Accent 6"/>
<w:LsdException Locked="false" Priority="64" Name="Medium Shading 2 Accent 6"/>
<w:LsdException Locked="false" Priority="65" Name="Medium List 1 Accent 6"/>
<w:LsdException Locked="false" Priority="66" Name="Medium List 2 Accent 6"/>
<w:LsdException Locked="false" Priority="67" Name="Medium Grid 1 Accent 6"/>
<w:LsdException Locked="false" Priority="68" Name="Medium Grid 2 Accent 6"/>
<w:LsdException Locked="false" Priority="69" Name="Medium Grid 3 Accent 6"/>
<w:LsdException Locked="false" Priority="70" Name="Dark List Accent 6"/>
<w:LsdException Locked="false" Priority="71" Name="Colorful Shading Accent 6"/>
<w:LsdException Locked="false" Priority="72" Name="Colorful List Accent 6"/>
<w:LsdException Locked="false" Priority="73" Name="Colorful Grid Accent 6"/>
<w:LsdException Locked="false" Priority="19" QFormat="true"
Name="Subtle Emphasis"/>
<w:LsdException Locked="false" Priority="21" QFormat="true"
Name="Intense Emphasis"/>
<w:LsdException Locked="false" Priority="31" QFormat="true"
Name="Subtle Reference"/>
<w:LsdException Locked="false" Priority="32" QFormat="true"
Name="Intense Reference"/>
<w:LsdException Locked="false" Priority="33" QFormat="true" Name="Book Title"/>
<w:LsdException Locked="false" Priority="37" SemiHidden="true"
UnhideWhenUsed="true" Name="Bibliography"/>
<w:LsdException Locked="false" Priority="39" SemiHidden="true"
UnhideWhenUsed="true" QFormat="true" Name="TOC Heading"/>
</w:LatentStyles>
</xml><![endif]-->
<style>
<!--
/* Font Definitions */
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;
mso-font-charset:1;
mso-generic-font-family:roman;
mso-font-format:other;
mso-font-pitch:variable;
mso-font-signature:0 0 0 0 0 0;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;
mso-font-charset:0;
mso-generic-font-family:swiss;
mso-font-pitch:variable;
mso-font-signature:-1610611985 1073750139 0 0 159 0;}
@font-face
{font-family:Tahoma;
panose-1:2 11 6 4 3 5 4 4 2 4;
mso-font-charset:0;
mso-generic-font-family:swiss;
mso-font-pitch:variable;
mso-font-signature:1627400839 -2147483648 8 0 66047 0;}
@font-face
{font-family:Verdana;
panose-1:2 11 6 4 3 5 4 4 2 4;
mso-font-charset:0;
mso-generic-font-family:swiss;
mso-font-pitch:variable;
mso-font-signature:536871559 0 0 0 415 0;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{mso-style-unhide:no;
mso-style-qformat:yes;
mso-style-parent:"";
margin:0in;
margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:12.0pt;
font-family:"Times New Roman","serif";
mso-fareast-font-family:"Times New Roman";}
h1
{mso-style-unhide:no;
mso-style-qformat:yes;
mso-style-link:"Heading 1 Char";
mso-margin-top-alt:auto;
margin-right:0in;
mso-margin-bottom-alt:auto;
margin-left:0in;
mso-pagination:widow-orphan;
mso-outline-level:1;
font-size:24.0pt;
font-family:"Times New Roman","serif";
mso-fareast-font-family:"Times New Roman";
mso-fareast-theme-font:minor-fareast;
font-weight:bold;}
h2
{mso-style-unhide:no;
mso-style-qformat:yes;
mso-style-link:"Heading 2 Char";
mso-style-next:Normal;
margin-top:12.0pt;
margin-right:0in;
margin-bottom:3.0pt;
margin-left:0in;
mso-pagination:widow-orphan;
page-break-after:avoid;
mso-outline-level:2;
font-size:14.0pt;
font-family:"Arial","sans-serif";
mso-fareast-font-family:"Times New Roman";
mso-fareast-theme-font:minor-fareast;
font-weight:bold;
font-style:italic;}
h3
{mso-style-unhide:no;
mso-style-qformat:yes;
mso-style-link:"Heading 3 Char";
mso-margin-top-alt:auto;
margin-right:0in;
mso-margin-bottom-alt:auto;
margin-left:0in;
mso-pagination:widow-orphan;
mso-outline-level:3;
font-size:13.5pt;
font-family:"Times New Roman","serif";
mso-fareast-font-family:"Times New Roman";
mso-fareast-theme-font:minor-fareast;
font-weight:bold;}
a:link, span.MsoHyperlink
{mso-style-unhide:no;
color:blue;
text-decoration:underline;
text-underline:single;}
a:visited, span.MsoHyperlinkFollowed
{mso-style-unhide:no;
color:blue;
text-decoration:underline;
text-underline:single;}
p
{mso-style-unhide:no;
mso-margin-top-alt:auto;
margin-right:0in;
mso-margin-bottom-alt:auto;
margin-left:0in;
mso-pagination:widow-orphan;
font-size:12.0pt;
font-family:"Times New Roman","serif";
mso-fareast-font-family:"Times New Roman";}
p.MsoAcetate, li.MsoAcetate, div.MsoAcetate
{mso-style-unhide:no;
mso-style-link:"Balloon Text Char";
margin:0in;
margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:8.0pt;
font-family:"Tahoma","sans-serif";
mso-fareast-font-family:"Times New Roman";}
span.Heading1Char
{mso-style-name:"Heading 1 Char";
mso-style-unhide:no;
mso-style-locked:yes;
mso-style-link:"Heading 1";
mso-ansi-font-size:14.0pt;
mso-bidi-font-size:14.0pt;
font-family:"Cambria","serif";
mso-ascii-font-family:Cambria;
mso-ascii-theme-font:major-latin;
mso-fareast-font-family:"Times New Roman";
mso-fareast-theme-font:major-fareast;
mso-hansi-font-family:Cambria;
mso-hansi-theme-font:major-latin;
mso-bidi-font-family:"Times New Roman";
mso-bidi-theme-font:major-bidi;
color:#365F91;
mso-themecolor:accent1;
mso-themeshade:191;
font-weight:bold;}
span.Heading2Char
{mso-style-name:"Heading 2 Char";
mso-style-unhide:no;
mso-style-locked:yes;
mso-style-link:"Heading 2";
mso-ansi-font-size:13.0pt;
mso-bidi-font-size:13.0pt;
font-family:"Cambria","serif";
mso-ascii-font-family:Cambria;
mso-ascii-theme-font:major-latin;
mso-fareast-font-family:"Times New Roman";
mso-fareast-theme-font:major-fareast;
mso-hansi-font-family:Cambria;
mso-hansi-theme-font:major-latin;
mso-bidi-font-family:"Times New Roman";
mso-bidi-theme-font:major-bidi;
color:#4F81BD;
mso-themecolor:accent1;
font-weight:bold;}
span.Heading3Char
{mso-style-name:"Heading 3 Char";
mso-style-unhide:no;
mso-style-locked:yes;
mso-style-link:"Heading 3";
mso-ansi-font-size:12.0pt;
mso-bidi-font-size:12.0pt;
font-family:"Cambria","serif";
mso-ascii-font-family:Cambria;
mso-ascii-theme-font:major-latin;
mso-fareast-font-family:"Times New Roman";
mso-fareast-theme-font:major-fareast;
mso-hansi-font-family:Cambria;
mso-hansi-theme-font:major-latin;
mso-bidi-font-family:"Times New Roman";
mso-bidi-theme-font:major-bidi;
color:#4F81BD;
mso-themecolor:accent1;
font-weight:bold;}
span.BalloonTextChar
{mso-style-name:"Balloon Text Char";
mso-style-unhide:no;
mso-style-locked:yes;
mso-style-link:"Balloon Text";
mso-ansi-font-size:8.0pt;
mso-bidi-font-size:8.0pt;
font-family:"Tahoma","sans-serif";
mso-ascii-font-family:Tahoma;
mso-hansi-font-family:Tahoma;
mso-bidi-font-family:Tahoma;}
.MsoChpDefault
{mso-style-type:export-only;
mso-default-props:yes;
font-size:10.0pt;
mso-ansi-font-size:10.0pt;
mso-bidi-font-size:10.0pt;}
@page WordSection1
{size:8.5in 11.0in;
margin:1.0in 1.25in 1.0in 1.25in;
mso-header-margin:.5in;
mso-footer-margin:.5in;
mso-paper-source:0;}
div.WordSection1
{page:WordSection1;}
/* List Definitions */
@list l0
{mso-list-id:62067358;
mso-list-template-ids:-174943062;}
@list l0:level1
{mso-level-number-format:bullet;
mso-level-text:\F0B7;
mso-level-tab-stop:.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l0:level2
{mso-level-tab-stop:1.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l0:level3
{mso-level-tab-stop:1.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l0:level4
{mso-level-tab-stop:2.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l0:level5
{mso-level-tab-stop:2.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l0:level6
{mso-level-tab-stop:3.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l0:level7
{mso-level-tab-stop:3.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l0:level8
{mso-level-tab-stop:4.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l0:level9
{mso-level-tab-stop:4.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l1
{mso-list-id:128015942;
mso-list-template-ids:-90681214;}
@list l1:level1
{mso-level-tab-stop:.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l1:level2
{mso-level-tab-stop:1.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l1:level3
{mso-level-tab-stop:1.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l1:level4
{mso-level-tab-stop:2.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l1:level5
{mso-level-tab-stop:2.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l1:level6
{mso-level-tab-stop:3.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l1:level7
{mso-level-tab-stop:3.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l1:level8
{mso-level-tab-stop:4.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l1:level9
{mso-level-tab-stop:4.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l2
{mso-list-id:216556000;
mso-list-template-ids:925924412;}
@list l2:level1
{mso-level-number-format:bullet;
mso-level-text:\F0B7;
mso-level-tab-stop:.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l2:level2
{mso-level-number-format:bullet;
mso-level-text:\F0B7;
mso-level-tab-stop:1.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l2:level3
{mso-level-tab-stop:1.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l2:level4
{mso-level-tab-stop:2.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l2:level5
{mso-level-tab-stop:2.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l2:level6
{mso-level-tab-stop:3.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l2:level7
{mso-level-tab-stop:3.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l2:level8
{mso-level-tab-stop:4.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l2:level9
{mso-level-tab-stop:4.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l3
{mso-list-id:562446694;
mso-list-template-ids:913898366;}
@list l3:level1
{mso-level-number-format:bullet;
mso-level-text:\F0B7;
mso-level-tab-stop:.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l3:level2
{mso-level-tab-stop:1.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l3:level3
{mso-level-tab-stop:1.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l3:level4
{mso-level-tab-stop:2.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l3:level5
{mso-level-tab-stop:2.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l3:level6
{mso-level-tab-stop:3.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l3:level7
{mso-level-tab-stop:3.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l3:level8
{mso-level-tab-stop:4.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l3:level9
{mso-level-tab-stop:4.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l4
{mso-list-id:797802132;
mso-list-template-ids:-1971191336;}
@list l4:level1
{mso-level-tab-stop:.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l4:level2
{mso-level-tab-stop:1.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l4:level3
{mso-level-tab-stop:1.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l4:level4
{mso-level-tab-stop:2.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l4:level5
{mso-level-tab-stop:2.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l4:level6
{mso-level-tab-stop:3.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l4:level7
{mso-level-tab-stop:3.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l4:level8
{mso-level-tab-stop:4.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l4:level9
{mso-level-tab-stop:4.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l5
{mso-list-id:907304066;
mso-list-template-ids:1969781532;}
@list l5:level1
{mso-level-tab-stop:.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l5:level2
{mso-level-tab-stop:1.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l5:level3
{mso-level-tab-stop:1.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l5:level4
{mso-level-tab-stop:2.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l5:level5
{mso-level-tab-stop:2.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l5:level6
{mso-level-tab-stop:3.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l5:level7
{mso-level-tab-stop:3.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l5:level8
{mso-level-tab-stop:4.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l5:level9
{mso-level-tab-stop:4.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l6
{mso-list-id:1050613616;
mso-list-template-ids:-1009886748;}
@list l6:level1
{mso-level-number-format:bullet;
mso-level-text:\F0B7;
mso-level-tab-stop:.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l6:level2
{mso-level-number-format:bullet;
mso-level-text:\F0B7;
mso-level-tab-stop:1.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l6:level3
{mso-level-tab-stop:1.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l6:level4
{mso-level-tab-stop:2.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l6:level5
{mso-level-tab-stop:2.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l6:level6
{mso-level-tab-stop:3.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l6:level7
{mso-level-tab-stop:3.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l6:level8
{mso-level-tab-stop:4.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l6:level9
{mso-level-tab-stop:4.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l7
{mso-list-id:1234970193;
mso-list-template-ids:2055904002;}
@list l7:level1
{mso-level-number-format:bullet;
mso-level-text:\F0B7;
mso-level-tab-stop:.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l7:level2
{mso-level-number-format:bullet;
mso-level-text:\F0B7;
mso-level-tab-stop:1.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l7:level3
{mso-level-tab-stop:1.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l7:level4
{mso-level-tab-stop:2.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l7:level5
{mso-level-tab-stop:2.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l7:level6
{mso-level-tab-stop:3.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l7:level7
{mso-level-tab-stop:3.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l7:level8
{mso-level-tab-stop:4.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l7:level9
{mso-level-tab-stop:4.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l8
{mso-list-id:1846092290;
mso-list-template-ids:-768590846;}
@list l8:level1
{mso-level-start-at:2;
mso-level-tab-stop:.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l8:level2
{mso-level-tab-stop:1.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l8:level3
{mso-level-tab-stop:1.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l8:level4
{mso-level-tab-stop:2.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l8:level5
{mso-level-tab-stop:2.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l8:level6
{mso-level-tab-stop:3.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l8:level7
{mso-level-tab-stop:3.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l8:level8
{mso-level-tab-stop:4.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l8:level9
{mso-level-tab-stop:4.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l9
{mso-list-id:1894656566;
mso-list-template-ids:1199983812;}
@list l9:level1
{mso-level-start-at:2;
mso-level-tab-stop:.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l9:level2
{mso-level-tab-stop:1.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l9:level3
{mso-level-tab-stop:1.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l9:level4
{mso-level-tab-stop:2.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l9:level5
{mso-level-tab-stop:2.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l9:level6
{mso-level-tab-stop:3.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l9:level7
{mso-level-tab-stop:3.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l9:level8
{mso-level-tab-stop:4.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l9:level9
{mso-level-tab-stop:4.5in;
mso-level-number-position:left;
text-indent:-.25in;}
ol
{margin-bottom:0in;}
ul
{margin-bottom:0in;}
-->
</style><!--[if gte mso 10]>
<style>
/* Style Definitions */
table.MsoNormalTable
{mso-style-name:"Table Normal";
mso-tstyle-rowband-size:0;
mso-tstyle-colband-size:0;
mso-style-noshow:yes;
mso-style-priority:99;
mso-style-qformat:yes;
mso-style-parent:"";
mso-padding-alt:0in 5.4pt 0in 5.4pt;
mso-para-margin:0in;
mso-para-margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:10.0pt;
font-family:"Times New Roman","serif";}
</style>
<![endif]--><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="7170"/>
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1"/>
</o:shapelayout></xml><![endif]--><meta content="MCD Application Team" name="author"></head>
<body style="" link="blue" vlink="blue">
<div class="WordSection1">
<p class="MsoNormal"><span style="font-family: &quot;Arial&quot;,&quot;sans-serif&quot;;"><o:p>&nbsp;</o:p></span></p>
<div align="center">
<table class="MsoNormalTable" style="width: 675pt;" border="0" cellpadding="0" cellspacing="0" width="900">
<tbody><tr style="">
<td style="padding: 0in;" valign="top">
<table class="MsoNormalTable" style="width: 675pt;" border="0" cellpadding="0" cellspacing="0" width="900">
<tbody><tr style="">
<td style="padding: 0in 5.4pt;" valign="top">
<p class="MsoNormal"><span style="font-size: 8pt; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; color: blue;"><a href="../../Release_Notes.html">Back to Release page</a></span><span style="font-size: 10pt;"><o:p></o:p></span></p>
</td>
</tr>
<tr style="">
<td style="padding: 1.5pt;">
<h1 style="margin-bottom: 0.25in; text-align: center;" align="center"><span style="font-size: 20pt; font-family: &quot;Verdana&quot;,&quot;sans-serif&quot;; color: rgb(51, 102, 255);">Release Notes for STM32F105/7xx, STM32F2xx and STM32F4xx USB OTG Driver</span><span style="font-size: 20pt; font-family: &quot;Verdana&quot;,&quot;sans-serif&quot;;"><o:p></o:p></span></h1>
<p class="MsoNormal" style="text-align: center;" align="center"><span style="font-size: 10pt; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; color: black;">Copyright
2012 STMicroelectronics</span><span style="color: black;"><u1:p></u1:p><o:p></o:p></span></p>
<p class="MsoNormal" style="text-align: center;" align="center"><span style="font-size: 10pt; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; color: black;"><img id="_x0000_i1026" src="../../_htmresc/logo.bmp" border="0" height="65" width="86"></span><span style="font-size: 10pt;"><o:p></o:p></span></p>
</td>
</tr>
</tbody></table>
<p class="MsoNormal"><span style="font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; display: none;"><o:p>&nbsp;</o:p></span></p>
<table class="MsoNormalTable" style="width: 675pt;" border="0" cellpadding="0" width="900">
<tbody><tr style="">
<td style="padding: 0in;" valign="top">
<h2 style="background: rgb(51, 102, 255) none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"><span style="font-size: 12pt; color: white;">Contents<o:p></o:p></span></h2>
<ol style="margin-top: 0in;" start="1" type="1">
<li class="MsoNormal" style="color: black; margin-top: 4.5pt; margin-bottom: 4.5pt;"><span style="font-size: 10pt; font-family: &quot;Verdana&quot;,&quot;sans-serif&quot;;"><a href="#History">Update History</a><o:p></o:p></span></li>
<li class="MsoNormal" style="color: black; margin-top: 4.5pt; margin-bottom: 4.5pt;"><span style="font-size: 10pt; font-family: &quot;Verdana&quot;,&quot;sans-serif&quot;;"><a href="#License">License</a><o:p></o:p></span></li>
</ol>
<h2 style="background: rgb(51, 102, 255) none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"><a name="History"></a><span style="font-size: 12pt; color: white;">Update History</span></h2><h3 style="background: rgb(51, 102, 255) none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; margin-right: 500pt; width: 200px;"><span style="font-size: 10pt; font-family: Arial; color: white;">V2.1.0 / 19-March-2012<o:p></o:p></span></h3>
<p class="MsoNormal" style="margin: 4.5pt 0cm 4.5pt 18pt;"><b style=""><u><span style="font-size: 10pt; font-family: Verdana; color: black;">Main
Changes<o:p></o:p></span></u></b></p>
<ul style="margin-top: 0cm;" type="square"><li class="MsoNormal" style="color: black; margin-top: 4.5pt; margin-bottom: 4.5pt;"><span style="font-size: 10pt; font-family: Verdana;">Official support of </span><span style="font-size: 10pt; font-family: Verdana;"><span style="font-weight: bold; font-style: italic;">STM32F4xx</span> devices</span></li><li class="MsoNormal" style="color: black; margin-top: 4.5pt; margin-bottom: 4.5pt;"><span style="font-size: 10pt; font-family: Verdana;">All source files: license disclaimer text update and add link to the License file on ST Internet</span></li><li class="MsoNormal" style="color: black; margin-top: 4.5pt; margin-bottom: 4.5pt;"><span style="font-size: 10pt; font-family: Verdana;">Unmask Session request interrupt to handle the connect event during the core start-up</span></li><li class="MsoNormal" style="color: black; margin-top: 4.5pt; margin-bottom: 4.5pt;"><span style="font-size: 10pt; font-family: Verdana;">Remove any reference to the USB HS external I2C PHY</span></li><li class="MsoNormal" style="color: black; margin-top: 4.5pt; margin-bottom: 4.5pt;"><span style="font-size: 10pt; font-family: Verdana;">Update optimization pragma for AR Compiler</span></li><li class="MsoNormal" style="color: black; margin-top: 4.5pt; margin-bottom: 4.5pt;"><span style="font-size: 10pt; font-family: Verdana;">Handle Correctly the Low Speed device connection in HS mode</span></li><li class="MsoNormal" style="color: black; margin-top: 4.5pt; margin-bottom: 4.5pt;"><span style="font-size: 10pt; font-family: Verdana;">Add a wrapper to isolate the library from the low level driver: connection done through ISR structure<br></span></li><li class="MsoNormal" style="color: black; margin-top: 4.5pt; margin-bottom: 4.5pt;"><span style="font-size: 10pt; font-family: Verdana;">Miscellaneous bug fix</span></li></ul><h3 style="background: rgb(51, 102, 255) none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; margin-right: 500pt; width: 171px;"><span style="font-size: 10pt; font-family: Arial; color: white;">V2.0.0 / 22-July-2011 <o:p></o:p></span></h3><p class="MsoNormal" style="margin: 4.5pt 0cm 4.5pt 18pt;"><b style=""><u><span style="font-size: 10pt; font-family: Verdana; color: black;">Main
Changes<o:p></o:p></span></u></b></p>
<ul style="margin-top: 0cm;" type="square"><li class="MsoNormal" style="color: black; margin-top: 4.5pt; margin-bottom: 4.5pt;"><span style="font-size: 10pt; font-family: Verdana;">Second official version supporting <span style="font-weight: bold; font-style: italic;">STM32F105/7</span> and <span style="font-weight: bold; font-style: italic;">STM32F2xx</span> devices</span></li><li class="MsoNormal" style="color: black; margin-top: 4.5pt; margin-bottom: 4.5pt;"><span style="font-size: 10pt; font-family: Verdana;">Rename the Library from "<span style="font-style: italic;">STM32_USB_HOST_Driver</span>" to "<span style="font-style: italic;">STM32_USB_OTG_Driver</span>"</span></li><li class="MsoNormal" style="color: black; margin-top: 4.5pt; margin-bottom: 4.5pt;"><span style="font-size: 10pt; font-family: Verdana;">Add support for <span style="font-weight: bold; font-style: italic;">STM32F2xx</span> devices</span><span style="font-size: 10pt; font-family: Verdana;"></span></li><li class="MsoNormal" style="color: black; margin-top: 4.5pt; margin-bottom: 4.5pt;"><span style="font-size: 10pt; font-family: Verdana;">Add support for Device and OTG modes</span></li><li class="MsoNormal" style="color: black; margin-top: 4.5pt; margin-bottom: 4.5pt;"><span style="font-size: 10pt; font-family: Verdana;">Change HCD layer to support High speed core</span></li><li class="MsoNormal" style="color: black; margin-top: 4.5pt; margin-bottom: 4.5pt;"><span style="font-size: 10pt; font-family: Verdana;">Change the Low level driver to support multi core support for Host mode</span></li><li class="MsoNormal" style="color: black; margin-top: 4.5pt; margin-bottom: 4.5pt;"><span style="font-size: 10pt; font-family: Verdana;">Add Stop mechanism for Host and Device modes</span></li><li class="MsoNormal" style="color: black; margin-top: 4.5pt; margin-bottom: 4.5pt;"><span style="font-size: 10pt; font-family: Verdana;">Change VBUS enabling method, to use the external or the internal VBUS when using the ULPI</span></li></ul><span style="font-size: 10pt; font-family: Verdana;"></span><h3 style="background: rgb(51, 102, 255) none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; margin-right: 500pt; width: 171px;"><span style="font-size: 10pt; font-family: Arial; color: white;">V1.0.0&nbsp;- 11/29/2010<o:p></o:p></span></h3>
<ul style="margin-top: 0cm;" type="square"><li class="MsoNormal" style="color: black; margin-top: 4.5pt; margin-bottom: 4.5pt;"><span style="font-size: 10pt; font-family: Verdana;">Created&nbsp;</span></li></ul><h2 style="background: rgb(51, 102, 255) none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"><a name="License"></a><span style="font-size: 12pt; color: white;">License<o:p></o:p></span></h2>
<p class="MsoNormal"><span style="font-size: 10pt; font-family: &quot;Verdana&quot;,&quot;sans-serif&quot;; color: black;">Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); You may not use this&nbsp;</span><span style="font-size: 10pt; font-family: &quot;Verdana&quot;,&quot;sans-serif&quot;; color: black;">package</span><span style="font-size: 10pt; font-family: &quot;Verdana&quot;,&quot;sans-serif&quot;; color: black;"> except in compliance with the License. You may obtain a copy of the License at:<br><br></span></p><div style="text-align: center;"><span style="font-size: 10pt; font-family: &quot;Verdana&quot;,&quot;sans-serif&quot;; color: black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a target="_blank" href="http://www.st.com/software_license_agreement_liberty_v2">http://www.st.com/software_license_agreement_liberty_v2</a></span><br><span style="font-size: 10pt; font-family: &quot;Verdana&quot;,&quot;sans-serif&quot;; color: black;"></span></div><span style="font-size: 10pt; font-family: &quot;Verdana&quot;,&quot;sans-serif&quot;; color: black;"><br>Unless
required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, <br>WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See
the License for the specific language governing permissions and
limitations under the License.</span>
<div class="MsoNormal" style="text-align: center;" align="center"><span style="color: black;">
<hr align="center" size="2" width="100%">
</span></div>
<p class="MsoNormal" style="margin: 4.5pt 0in 4.5pt 0.25in; text-align: center;" align="center"><span style="font-size: 10pt; font-family: &quot;Verdana&quot;,&quot;sans-serif&quot;; color: black;">For
complete documentation on </span><span style="font-size: 10pt; font-family: &quot;Verdana&quot;,&quot;sans-serif&quot;;">STM32<span style="color: black;">
Microcontrollers visit </span><u><span style="color: blue;"><a href="http://www.st.com/internet/mcu/family/141.jsp" target="_blank">www.st.com/STM32</a></span></u></span><span style="font-size: 10pt; font-family: &quot;Verdana&quot;,&quot;sans-serif&quot;;"><u><span style="color: blue;"><a href="http://www.st.com/stm32" target="_blank"></a></span></u></span><span style="color: black;"><o:p></o:p></span></p>
</td>
</tr>
</tbody></table>
<p class="MsoNormal"><span style="font-size: 10pt;"><o:p></o:p></span></p>
</td>
</tr>
</tbody></table>
</div>
<p class="MsoNormal"><o:p>&nbsp;</o:p></p>
</div>
</body></html>

View File

@ -0,0 +1,103 @@
/**
******************************************************************************
* @file usb_bsp.h
* @author MCD Application Team
* @version V2.1.0
* @date 19-March-2012
* @brief Specific api's relative to the used hardware platform
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_BSP__H__
#define __USB_BSP__H__
/* Includes ------------------------------------------------------------------*/
#include "usb_core.h"
#include "usb_conf.h"
/** @addtogroup USB_OTG_DRIVER
* @{
*/
/** @defgroup USB_BSP
* @brief This file is the
* @{
*/
/** @defgroup USB_BSP_Exported_Defines
* @{
*/
/**
* @}
*/
/** @defgroup USB_BSP_Exported_Types
* @{
*/
/**
* @}
*/
/** @defgroup USB_BSP_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USB_BSP_Exported_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USB_BSP_Exported_FunctionsPrototype
* @{
*/
void BSP_Init(void);
void USB_OTG_BSP_Init (USB_OTG_CORE_HANDLE *pdev);
void USB_OTG_BSP_uDelay (const uint32_t usec);
void USB_OTG_BSP_mDelay (const uint32_t msec);
void USB_OTG_BSP_EnableInterrupt (USB_OTG_CORE_HANDLE *pdev);
#ifdef USE_HOST_MODE
void USB_OTG_BSP_ConfigVBUS(USB_OTG_CORE_HANDLE *pdev);
void USB_OTG_BSP_DriveVBUS(USB_OTG_CORE_HANDLE *pdev,uint8_t state);
#endif
/**
* @}
*/
#endif //__USB_BSP__H__
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,306 @@
/**
******************************************************************************
* @file usb_conf.h
* @author MCD Application Team
* @version V2.1.0
* @date 19-March-2012
* @brief General low level driver configuration
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_CONF__H__
#define __USB_CONF__H__
/* Includes ------------------------------------------------------------------*/
#include "usb_conf.h"
/** @addtogroup USB_OTG_DRIVER
* @{
*/
/** @defgroup USB_CONF
* @brief USB low level driver configuration file
* @{
*/
/** @defgroup USB_CONF_Exported_Defines
* @{
*/
/* USB Core and PHY interface configuration.
Tip: To avoid modifying these defines each time you need to change the USB
configuration, you can declare the needed define in your toolchain
compiler preprocessor.
*/
/****************** USB OTG FS PHY CONFIGURATION *******************************
* The USB OTG FS Core supports one on-chip Full Speed PHY.
*
* The USE_EMBEDDED_PHY symbol is defined in the project compiler preprocessor
* when FS core is used.
*******************************************************************************/
#ifndef USE_USB_OTG_FS
//#define USE_USB_OTG_FS
#endif /* USE_USB_OTG_FS */
#ifdef USE_USB_OTG_FS
#define USB_OTG_FS_CORE
#endif
/****************** USB OTG HS PHY CONFIGURATION *******************************
* The USB OTG HS Core supports two PHY interfaces:
* (i) An ULPI interface for the external High Speed PHY: the USB HS Core will
* operate in High speed mode
* (ii) An on-chip Full Speed PHY: the USB HS Core will operate in Full speed mode
*
* You can select the PHY to be used using one of these two defines:
* (i) USE_ULPI_PHY: if the USB OTG HS Core is to be used in High speed mode
* (ii) USE_EMBEDDED_PHY: if the USB OTG HS Core is to be used in Full speed mode
*
* Notes:
* - The USE_ULPI_PHY symbol is defined in the project compiler preprocessor as
* default PHY when HS core is used.
* - On STM322xG-EVAL and STM324xG-EVAL boards, only configuration(i) is available.
* Configuration (ii) need a different hardware, for more details refer to your
* STM32 device datasheet.
*******************************************************************************/
#ifndef USE_USB_OTG_HS
//#define USE_USB_OTG_HS
#endif /* USE_USB_OTG_HS */
#ifndef USE_ULPI_PHY
//#define USE_ULPI_PHY
#endif /* USE_ULPI_PHY */
#ifndef USE_EMBEDDED_PHY
//#define USE_EMBEDDED_PHY
#endif /* USE_EMBEDDED_PHY */
#ifdef USE_USB_OTG_HS
#define USB_OTG_HS_CORE
#endif
/*******************************************************************************
* FIFO Size Configuration in Device mode
*
* (i) Receive data FIFO size = RAM for setup packets +
* OUT endpoint control information +
* data OUT packets + miscellaneous
* Space = ONE 32-bits words
* --> RAM for setup packets = 10 spaces
* (n is the nbr of CTRL EPs the device core supports)
* --> OUT EP CTRL info = 1 space
* (one space for status information written to the FIFO along with each
* received packet)
* --> data OUT packets = (Largest Packet Size / 4) + 1 spaces
* (MINIMUM to receive packets)
* --> OR data OUT packets = at least 2*(Largest Packet Size / 4) + 1 spaces
* (if high-bandwidth EP is enabled or multiple isochronous EPs)
* --> miscellaneous = 1 space per OUT EP
* (one space for transfer complete status information also pushed to the
* FIFO with each endpoint's last packet)
*
* (ii)MINIMUM RAM space required for each IN EP Tx FIFO = MAX packet size for
* that particular IN EP. More space allocated in the IN EP Tx FIFO results
* in a better performance on the USB and can hide latencies on the AHB.
*
* (iii) TXn min size = 16 words. (n : Transmit FIFO index)
* (iv) When a TxFIFO is not used, the Configuration should be as follows:
* case 1 : n > m and Txn is not used (n,m : Transmit FIFO indexes)
* --> Txm can use the space allocated for Txn.
* case2 : n < m and Txn is not used (n,m : Transmit FIFO indexes)
* --> Txn should be configured with the minimum space of 16 words
* (v) The FIFO is used optimally when used TxFIFOs are allocated in the top
* of the FIFO.Ex: use EP1 and EP2 as IN instead of EP1 and EP3 as IN ones.
*******************************************************************************/
/*******************************************************************************
* FIFO Size Configuration in Host mode
*
* (i) Receive data FIFO size = (Largest Packet Size / 4) + 1 or
* 2x (Largest Packet Size / 4) + 1, If a
* high-bandwidth channel or multiple isochronous
* channels are enabled
*
* (ii) For the host nonperiodic Transmit FIFO is the largest maximum packet size
* for all supported nonperiodic OUT channels. Typically, a space
* corresponding to two Largest Packet Size is recommended.
*
* (iii) The minimum amount of RAM required for Host periodic Transmit FIFO is
* the largest maximum packet size for all supported periodic OUT channels.
* If there is at least one High Bandwidth Isochronous OUT endpoint,
* then the space must be at least two times the maximum packet size for
* that channel.
*******************************************************************************/
/****************** USB OTG HS CONFIGURATION **********************************/
#ifdef USB_OTG_HS_CORE
#define RX_FIFO_HS_SIZE 512
#define TX0_FIFO_HS_SIZE 512
#define TX1_FIFO_HS_SIZE 512
#define TX2_FIFO_HS_SIZE 0
#define TX3_FIFO_HS_SIZE 0
#define TX4_FIFO_HS_SIZE 0
#define TX5_FIFO_HS_SIZE 0
#define TXH_NP_HS_FIFOSIZ 96
#define TXH_P_HS_FIFOSIZ 96
// #define USB_OTG_HS_LOW_PWR_MGMT_SUPPORT
// #define USB_OTG_HS_SOF_OUTPUT_ENABLED
// #define USB_OTG_INTERNAL_VBUS_ENABLED
#define USB_OTG_EXTERNAL_VBUS_ENABLED
#ifdef USE_ULPI_PHY
#define USB_OTG_ULPI_PHY_ENABLED
#endif
#ifdef USE_EMBEDDED_PHY
#define USB_OTG_EMBEDDED_PHY_ENABLED
#endif
#define USB_OTG_HS_INTERNAL_DMA_ENABLED
#define USB_OTG_HS_DEDICATED_EP1_ENABLED
#endif
/****************** USB OTG FS CONFIGURATION **********************************/
#ifdef USB_OTG_FS_CORE
#define RX_FIFO_FS_SIZE 128
#define TX0_FIFO_FS_SIZE 64
#define TX1_FIFO_FS_SIZE 128
#define TX2_FIFO_FS_SIZE 0
#define TX3_FIFO_FS_SIZE 0
#define TXH_NP_HS_FIFOSIZ 96
#define TXH_P_HS_FIFOSIZ 96
// #define USB_OTG_FS_LOW_PWR_MGMT_SUPPORT
// #define USB_OTG_FS_SOF_OUTPUT_ENABLED
#endif
/****************** USB OTG MISC CONFIGURATION ********************************/
//#define VBUS_SENSING_ENABLED
/****************** USB OTG MODE CONFIGURATION ********************************/
//#define USE_HOST_MODE
#define USE_DEVICE_MODE
//#define USE_OTG_MODE
#ifndef USB_OTG_FS_CORE
#ifndef USB_OTG_HS_CORE
#error "USB_OTG_HS_CORE or USB_OTG_FS_CORE should be defined"
#endif
#endif
#ifndef USE_DEVICE_MODE
#ifndef USE_HOST_MODE
#error "USE_DEVICE_MODE or USE_HOST_MODE should be defined"
#endif
#endif
#ifndef USE_USB_OTG_HS
#ifndef USE_USB_OTG_FS
#error "USE_USB_OTG_HS or USE_USB_OTG_FS should be defined"
#endif
#else //USE_USB_OTG_HS
#ifndef USE_ULPI_PHY
#ifndef USE_EMBEDDED_PHY
#error "USE_ULPI_PHY or USE_EMBEDDED_PHY should be defined"
#endif
#endif
#endif
/****************** C Compilers dependant keywords ****************************/
/* In HS mode and when the DMA is used, all variables and data structures dealing
with the DMA during the transaction process should be 4-bytes aligned */
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
#if defined (__GNUC__) /* GNU Compiler */
#define __ALIGN_END __attribute__ ((aligned (4)))
#define __ALIGN_BEGIN
#else
#define __ALIGN_END
#if defined (__CC_ARM) /* ARM Compiler */
#define __ALIGN_BEGIN __align(4)
#elif defined (__ICCARM__) /* IAR Compiler */
#define __ALIGN_BEGIN
#elif defined (__TASKING__) /* TASKING Compiler */
#define __ALIGN_BEGIN __align(4)
#endif /* __CC_ARM */
#endif /* __GNUC__ */
#else
#define __ALIGN_BEGIN
#define __ALIGN_END
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
/* __packed keyword used to decrease the data type alignment to 1-byte */
#if defined (__CC_ARM) /* ARM Compiler */
#define __packed __packed
#elif defined (__ICCARM__) /* IAR Compiler */
#define __packed __packed
#elif defined ( __GNUC__ ) /* GNU Compiler */
#define __packed __attribute__ ((__packed__))
#elif defined (__TASKING__) /* TASKING Compiler */
#define __packed __unaligned
#endif /* __CC_ARM */
/**
* @}
*/
/** @defgroup USB_CONF_Exported_Types
* @{
*/
/**
* @}
*/
/** @defgroup USB_CONF_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USB_CONF_Exported_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USB_CONF_Exported_FunctionsPrototype
* @{
*/
/**
* @}
*/
#endif //__USB_CONF__H__
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,417 @@
/**
******************************************************************************
* @file usb_core.h
* @author MCD Application Team
* @version V2.1.0
* @date 19-March-2012
* @brief Header of the Core Layer
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_CORE_H__
#define __USB_CORE_H__
/* Includes ------------------------------------------------------------------*/
#include "usb_conf.h"
#include "usb_regs.h"
#include "usb_defines.h"
/** @addtogroup USB_OTG_DRIVER
* @{
*/
/** @defgroup USB_CORE
* @brief usb otg driver core layer
* @{
*/
/** @defgroup USB_CORE_Exported_Defines
* @{
*/
#define USB_OTG_EP0_IDLE 0
#define USB_OTG_EP0_SETUP 1
#define USB_OTG_EP0_DATA_IN 2
#define USB_OTG_EP0_DATA_OUT 3
#define USB_OTG_EP0_STATUS_IN 4
#define USB_OTG_EP0_STATUS_OUT 5
#define USB_OTG_EP0_STALL 6
#define USB_OTG_EP_TX_DIS 0x0000
#define USB_OTG_EP_TX_STALL 0x0010
#define USB_OTG_EP_TX_NAK 0x0020
#define USB_OTG_EP_TX_VALID 0x0030
#define USB_OTG_EP_RX_DIS 0x0000
#define USB_OTG_EP_RX_STALL 0x1000
#define USB_OTG_EP_RX_NAK 0x2000
#define USB_OTG_EP_RX_VALID 0x3000
/**
* @}
*/
#define MAX_DATA_LENGTH 0x200
/** @defgroup USB_CORE_Exported_Types
* @{
*/
typedef enum {
USB_OTG_OK = 0,
USB_OTG_FAIL
}USB_OTG_STS;
typedef enum {
HC_IDLE = 0,
HC_XFRC,
HC_HALTED,
HC_NAK,
HC_NYET,
HC_STALL,
HC_XACTERR,
HC_BBLERR,
HC_DATATGLERR,
}HC_STATUS;
typedef enum {
URB_IDLE = 0,
URB_DONE,
URB_NOTREADY,
URB_ERROR,
URB_STALL
}URB_STATE;
typedef enum {
CTRL_START = 0,
CTRL_XFRC,
CTRL_HALTED,
CTRL_NAK,
CTRL_STALL,
CTRL_XACTERR,
CTRL_BBLERR,
CTRL_DATATGLERR,
CTRL_FAIL
}CTRL_STATUS;
typedef struct USB_OTG_hc
{
uint8_t dev_addr ;
uint8_t ep_num;
uint8_t ep_is_in;
uint8_t speed;
uint8_t do_ping;
uint8_t ep_type;
uint16_t max_packet;
uint8_t data_pid;
uint8_t *xfer_buff;
uint32_t xfer_len;
uint32_t xfer_count;
uint8_t toggle_in;
uint8_t toggle_out;
uint32_t dma_addr;
}
USB_OTG_HC , *PUSB_OTG_HC;
typedef struct USB_OTG_ep
{
uint8_t num;
uint8_t is_in;
uint8_t is_stall;
uint8_t type;
uint8_t data_pid_start;
uint8_t even_odd_frame;
uint16_t tx_fifo_num;
uint32_t maxpacket;
/* transaction level variables*/
uint8_t *xfer_buff;
uint32_t dma_addr;
uint32_t xfer_len;
uint32_t xfer_count;
/* Transfer level variables*/
uint32_t rem_data_len;
uint32_t total_data_len;
uint32_t ctl_data_len;
}
USB_OTG_EP , *PUSB_OTG_EP;
typedef struct USB_OTG_core_cfg
{
uint8_t host_channels;
uint8_t dev_endpoints;
uint8_t speed;
uint8_t dma_enable;
uint16_t mps;
uint16_t TotalFifoSize;
uint8_t phy_itface;
uint8_t Sof_output;
uint8_t low_power;
uint8_t coreID;
}
USB_OTG_CORE_CFGS, *PUSB_OTG_CORE_CFGS;
typedef struct usb_setup_req {
uint8_t bmRequest;
uint8_t bRequest;
uint16_t wValue;
uint16_t wIndex;
uint16_t wLength;
} USB_SETUP_REQ;
typedef struct _Device_TypeDef
{
uint8_t *(*GetDeviceDescriptor)( uint8_t speed , uint16_t *length);
uint8_t *(*GetLangIDStrDescriptor)( uint8_t speed , uint16_t *length);
uint8_t *(*GetManufacturerStrDescriptor)( uint8_t speed , uint16_t *length);
uint8_t *(*GetProductStrDescriptor)( uint8_t speed , uint16_t *length);
uint8_t *(*GetSerialStrDescriptor)( uint8_t speed , uint16_t *length);
uint8_t *(*GetConfigurationStrDescriptor)( uint8_t speed , uint16_t *length);
uint8_t *(*GetInterfaceStrDescriptor)( uint8_t speed , uint16_t *length);
} USBD_DEVICE, *pUSBD_DEVICE;
//typedef struct USB_OTG_hPort
//{
// void (*Disconnect) (void *phost);
// void (*Connect) (void *phost);
// uint8_t ConnStatus;
// uint8_t DisconnStatus;
// uint8_t ConnHandled;
// uint8_t DisconnHandled;
//} USB_OTG_hPort_TypeDef;
typedef struct _Device_cb
{
uint8_t (*Init) (void *pdev , uint8_t cfgidx);
uint8_t (*DeInit) (void *pdev , uint8_t cfgidx);
/* Control Endpoints*/
uint8_t (*Setup) (void *pdev , USB_SETUP_REQ *req);
uint8_t (*EP0_TxSent) (void *pdev );
uint8_t (*EP0_RxReady) (void *pdev );
/* Class Specific Endpoints*/
uint8_t (*DataIn) (void *pdev , uint8_t epnum);
uint8_t (*DataOut) (void *pdev , uint8_t epnum);
uint8_t (*SOF) (void *pdev);
uint8_t (*IsoINIncomplete) (void *pdev);
uint8_t (*IsoOUTIncomplete) (void *pdev);
uint8_t *(*GetConfigDescriptor)( uint8_t speed , uint16_t *length);
#ifdef USB_OTG_HS_CORE
uint8_t *(*GetOtherConfigDescriptor)( uint8_t speed , uint16_t *length);
#endif
#ifdef USB_SUPPORT_USER_STRING_DESC
uint8_t *(*GetUsrStrDescriptor)( uint8_t speed ,uint8_t index, uint16_t *length);
#endif
} USBD_Class_cb_TypeDef;
typedef struct _USBD_USR_PROP
{
void (*Init)(void);
void (*DeviceReset)(uint8_t speed);
void (*DeviceConfigured)(void);
void (*DeviceSuspended)(void);
void (*DeviceResumed)(void);
void (*DeviceConnected)(void);
void (*DeviceDisconnected)(void);
}
USBD_Usr_cb_TypeDef;
typedef struct _DCD
{
uint8_t device_config;
uint8_t device_state;
uint8_t device_status;
uint8_t device_old_status;
uint8_t device_address;
uint8_t connection_status;
uint8_t test_mode;
uint32_t DevRemoteWakeup;
USB_OTG_EP in_ep [USB_OTG_MAX_TX_FIFOS];
USB_OTG_EP out_ep [USB_OTG_MAX_TX_FIFOS];
uint8_t setup_packet [8*3];
USBD_Class_cb_TypeDef *class_cb;
USBD_Usr_cb_TypeDef *usr_cb;
USBD_DEVICE *usr_device;
uint8_t *pConfig_descriptor;
}
DCD_DEV , *DCD_PDEV;
typedef struct _HCD
{
uint8_t Rx_Buffer [MAX_DATA_LENGTH];
__IO uint32_t ConnSts;
__IO uint32_t ErrCnt[USB_OTG_MAX_TX_FIFOS];
__IO uint32_t XferCnt[USB_OTG_MAX_TX_FIFOS];
__IO HC_STATUS HC_Status[USB_OTG_MAX_TX_FIFOS];
__IO URB_STATE URB_State[USB_OTG_MAX_TX_FIFOS];
USB_OTG_HC hc [USB_OTG_MAX_TX_FIFOS];
uint16_t channel [USB_OTG_MAX_TX_FIFOS];
// USB_OTG_hPort_TypeDef *port_cb;
}
HCD_DEV , *USB_OTG_USBH_PDEV;
typedef struct _OTG
{
uint8_t OTG_State;
uint8_t OTG_PrevState;
uint8_t OTG_Mode;
}
OTG_DEV , *USB_OTG_USBO_PDEV;
typedef struct USB_OTG_handle
{
USB_OTG_CORE_CFGS cfg;
USB_OTG_CORE_REGS regs;
#ifdef USE_DEVICE_MODE
DCD_DEV dev;
#endif
#ifdef USE_HOST_MODE
HCD_DEV host;
#endif
#ifdef USE_OTG_MODE
OTG_DEV otg;
#endif
}
USB_OTG_CORE_HANDLE , *PUSB_OTG_CORE_HANDLE;
/**
* @}
*/
/** @defgroup USB_CORE_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USB_CORE_Exported_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USB_CORE_Exported_FunctionsPrototype
* @{
*/
USB_OTG_STS USB_OTG_CoreInit (USB_OTG_CORE_HANDLE *pdev);
USB_OTG_STS USB_OTG_SelectCore (USB_OTG_CORE_HANDLE *pdev,
USB_OTG_CORE_ID_TypeDef coreID);
USB_OTG_STS USB_OTG_EnableGlobalInt (USB_OTG_CORE_HANDLE *pdev);
USB_OTG_STS USB_OTG_DisableGlobalInt(USB_OTG_CORE_HANDLE *pdev);
void* USB_OTG_ReadPacket (USB_OTG_CORE_HANDLE *pdev ,
uint8_t *dest,
uint16_t len);
USB_OTG_STS USB_OTG_WritePacket (USB_OTG_CORE_HANDLE *pdev ,
uint8_t *src,
uint8_t ch_ep_num,
uint16_t len);
USB_OTG_STS USB_OTG_FlushTxFifo (USB_OTG_CORE_HANDLE *pdev , uint32_t num);
USB_OTG_STS USB_OTG_FlushRxFifo (USB_OTG_CORE_HANDLE *pdev);
uint32_t USB_OTG_ReadCoreItr (USB_OTG_CORE_HANDLE *pdev);
uint32_t USB_OTG_ReadOtgItr (USB_OTG_CORE_HANDLE *pdev);
uint8_t USB_OTG_IsHostMode (USB_OTG_CORE_HANDLE *pdev);
uint8_t USB_OTG_IsDeviceMode (USB_OTG_CORE_HANDLE *pdev);
uint32_t USB_OTG_GetMode (USB_OTG_CORE_HANDLE *pdev);
USB_OTG_STS USB_OTG_PhyInit (USB_OTG_CORE_HANDLE *pdev);
USB_OTG_STS USB_OTG_SetCurrentMode (USB_OTG_CORE_HANDLE *pdev,
uint8_t mode);
/*********************** HOST APIs ********************************************/
#ifdef USE_HOST_MODE
USB_OTG_STS USB_OTG_CoreInitHost (USB_OTG_CORE_HANDLE *pdev);
USB_OTG_STS USB_OTG_EnableHostInt (USB_OTG_CORE_HANDLE *pdev);
USB_OTG_STS USB_OTG_HC_Init (USB_OTG_CORE_HANDLE *pdev, uint8_t hc_num);
USB_OTG_STS USB_OTG_HC_Halt (USB_OTG_CORE_HANDLE *pdev, uint8_t hc_num);
USB_OTG_STS USB_OTG_HC_StartXfer (USB_OTG_CORE_HANDLE *pdev, uint8_t hc_num);
USB_OTG_STS USB_OTG_HC_DoPing (USB_OTG_CORE_HANDLE *pdev , uint8_t hc_num);
uint32_t USB_OTG_ReadHostAllChannels_intr (USB_OTG_CORE_HANDLE *pdev);
uint32_t USB_OTG_ResetPort (USB_OTG_CORE_HANDLE *pdev);
uint32_t USB_OTG_ReadHPRT0 (USB_OTG_CORE_HANDLE *pdev);
void USB_OTG_DriveVbus (USB_OTG_CORE_HANDLE *pdev, uint8_t state);
void USB_OTG_InitFSLSPClkSel (USB_OTG_CORE_HANDLE *pdev ,uint8_t freq);
uint8_t USB_OTG_IsEvenFrame (USB_OTG_CORE_HANDLE *pdev) ;
void USB_OTG_StopHost (USB_OTG_CORE_HANDLE *pdev);
#endif
/********************* DEVICE APIs ********************************************/
#ifdef USE_DEVICE_MODE
USB_OTG_STS USB_OTG_CoreInitDev (USB_OTG_CORE_HANDLE *pdev);
USB_OTG_STS USB_OTG_EnableDevInt (USB_OTG_CORE_HANDLE *pdev);
uint32_t USB_OTG_ReadDevAllInEPItr (USB_OTG_CORE_HANDLE *pdev);
enum USB_OTG_SPEED USB_OTG_GetDeviceSpeed (USB_OTG_CORE_HANDLE *pdev);
USB_OTG_STS USB_OTG_EP0Activate (USB_OTG_CORE_HANDLE *pdev);
USB_OTG_STS USB_OTG_EPActivate (USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep);
USB_OTG_STS USB_OTG_EPDeactivate(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep);
USB_OTG_STS USB_OTG_EPStartXfer (USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep);
USB_OTG_STS USB_OTG_EP0StartXfer(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep);
USB_OTG_STS USB_OTG_EPSetStall (USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep);
USB_OTG_STS USB_OTG_EPClearStall (USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep);
uint32_t USB_OTG_ReadDevAllOutEp_itr (USB_OTG_CORE_HANDLE *pdev);
uint32_t USB_OTG_ReadDevOutEP_itr (USB_OTG_CORE_HANDLE *pdev , uint8_t epnum);
uint32_t USB_OTG_ReadDevAllInEPItr (USB_OTG_CORE_HANDLE *pdev);
void USB_OTG_InitDevSpeed (USB_OTG_CORE_HANDLE *pdev , uint8_t speed);
uint8_t USBH_IsEvenFrame (USB_OTG_CORE_HANDLE *pdev);
void USB_OTG_EP0_OutStart(USB_OTG_CORE_HANDLE *pdev);
void USB_OTG_ActiveRemoteWakeup(USB_OTG_CORE_HANDLE *pdev);
void USB_OTG_UngateClock(USB_OTG_CORE_HANDLE *pdev);
void USB_OTG_StopDevice(USB_OTG_CORE_HANDLE *pdev);
void USB_OTG_SetEPStatus (USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep , uint32_t Status);
uint32_t USB_OTG_GetEPStatus(USB_OTG_CORE_HANDLE *pdev ,USB_OTG_EP *ep);
#endif
/**
* @}
*/
#endif /* __USB_CORE_H__ */
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,164 @@
/**
******************************************************************************
* @file usb_dcd.h
* @author MCD Application Team
* @version V2.1.0
* @date 19-March-2012
* @brief Peripheral Driver Header file
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __DCD_H__
#define __DCD_H__
/* Includes ------------------------------------------------------------------*/
#include "usb_core.h"
/** @addtogroup USB_OTG_DRIVER
* @{
*/
/** @defgroup USB_DCD
* @brief This file is the
* @{
*/
/** @defgroup USB_DCD_Exported_Defines
* @{
*/
#define USB_OTG_EP_CONTROL 0
#define USB_OTG_EP_ISOC 1
#define USB_OTG_EP_BULK 2
#define USB_OTG_EP_INT 3
#define USB_OTG_EP_MASK 3
/* Device Status */
#define USB_OTG_DEFAULT 1
#define USB_OTG_ADDRESSED 2
#define USB_OTG_CONFIGURED 3
#define USB_OTG_SUSPENDED 4
/**
* @}
*/
/** @defgroup USB_DCD_Exported_Types
* @{
*/
/********************************************************************************
Data structure type
********************************************************************************/
typedef struct
{
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bEndpointAddress;
uint8_t bmAttributes;
uint16_t wMaxPacketSize;
uint8_t bInterval;
}
EP_DESCRIPTOR , *PEP_DESCRIPTOR;
/**
* @}
*/
/** @defgroup USB_DCD_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USB_DCD_Exported_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USB_DCD_Exported_FunctionsPrototype
* @{
*/
/********************************************************************************
EXPORTED FUNCTION FROM THE USB-OTG LAYER
********************************************************************************/
void DCD_Init(USB_OTG_CORE_HANDLE *pdev ,
USB_OTG_CORE_ID_TypeDef coreID);
void DCD_DevConnect (USB_OTG_CORE_HANDLE *pdev);
void DCD_DevDisconnect (USB_OTG_CORE_HANDLE *pdev);
void DCD_EP_SetAddress (USB_OTG_CORE_HANDLE *pdev,
uint8_t address);
uint32_t DCD_EP_Open(USB_OTG_CORE_HANDLE *pdev ,
uint8_t ep_addr,
uint16_t ep_mps,
uint8_t ep_type);
uint32_t DCD_EP_Close (USB_OTG_CORE_HANDLE *pdev,
uint8_t ep_addr);
uint32_t DCD_EP_PrepareRx ( USB_OTG_CORE_HANDLE *pdev,
uint8_t ep_addr,
uint8_t *pbuf,
uint16_t buf_len);
uint32_t DCD_EP_Tx (USB_OTG_CORE_HANDLE *pdev,
uint8_t ep_addr,
uint8_t *pbuf,
uint32_t buf_len);
uint32_t DCD_EP_Stall (USB_OTG_CORE_HANDLE *pdev,
uint8_t epnum);
uint32_t DCD_EP_ClrStall (USB_OTG_CORE_HANDLE *pdev,
uint8_t epnum);
uint32_t DCD_EP_Flush (USB_OTG_CORE_HANDLE *pdev,
uint8_t epnum);
uint32_t DCD_Handle_ISR(USB_OTG_CORE_HANDLE *pdev);
uint32_t DCD_GetEPStatus(USB_OTG_CORE_HANDLE *pdev ,
uint8_t epnum);
void DCD_SetEPStatus (USB_OTG_CORE_HANDLE *pdev ,
uint8_t epnum ,
uint32_t Status);
/**
* @}
*/
#endif //__DCD_H__
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,127 @@
/**
******************************************************************************
* @file usb_dcd_int.h
* @author MCD Application Team
* @version V2.1.0
* @date 19-March-2012
* @brief Peripheral Device Interface Layer
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef USB_DCD_INT_H__
#define USB_DCD_INT_H__
/* Includes ------------------------------------------------------------------*/
#include "usb_dcd.h"
/** @addtogroup USB_OTG_DRIVER
* @{
*/
/** @defgroup USB_DCD_INT
* @brief This file is the
* @{
*/
/** @defgroup USB_DCD_INT_Exported_Defines
* @{
*/
typedef struct _USBD_DCD_INT
{
uint8_t (* DataOutStage) (USB_OTG_CORE_HANDLE *pdev , uint8_t epnum);
uint8_t (* DataInStage) (USB_OTG_CORE_HANDLE *pdev , uint8_t epnum);
uint8_t (* SetupStage) (USB_OTG_CORE_HANDLE *pdev);
uint8_t (* SOF) (USB_OTG_CORE_HANDLE *pdev);
uint8_t (* Reset) (USB_OTG_CORE_HANDLE *pdev);
uint8_t (* Suspend) (USB_OTG_CORE_HANDLE *pdev);
uint8_t (* Resume) (USB_OTG_CORE_HANDLE *pdev);
uint8_t (* IsoINIncomplete) (USB_OTG_CORE_HANDLE *pdev);
uint8_t (* IsoOUTIncomplete) (USB_OTG_CORE_HANDLE *pdev);
uint8_t (* DevConnected) (USB_OTG_CORE_HANDLE *pdev);
uint8_t (* DevDisconnected) (USB_OTG_CORE_HANDLE *pdev);
}USBD_DCD_INT_cb_TypeDef;
extern USBD_DCD_INT_cb_TypeDef *USBD_DCD_INT_fops;
/**
* @}
*/
/** @defgroup USB_DCD_INT_Exported_Types
* @{
*/
/**
* @}
*/
/** @defgroup USB_DCD_INT_Exported_Macros
* @{
*/
#define CLEAR_IN_EP_INTR(epnum,intr) \
diepint.d32=0; \
diepint.b.intr = 1; \
USB_OTG_WRITE_REG32(&pdev->regs.INEP_REGS[epnum]->DIEPINT,diepint.d32);
#define CLEAR_OUT_EP_INTR(epnum,intr) \
doepint.d32=0; \
doepint.b.intr = 1; \
USB_OTG_WRITE_REG32(&pdev->regs.OUTEP_REGS[epnum]->DOEPINT,doepint.d32);
/**
* @}
*/
/** @defgroup USB_DCD_INT_Exported_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USB_DCD_INT_Exported_FunctionsPrototype
* @{
*/
uint32_t USBD_OTG_ISR_Handler (USB_OTG_CORE_HANDLE *pdev);
/**
* @}
*/
#endif // USB_DCD_INT_H__
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,249 @@
/**
******************************************************************************
* @file usb_defines.h
* @author MCD Application Team
* @version V2.1.0
* @date 19-March-2012
* @brief Header of the Core Layer
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_DEF_H__
#define __USB_DEF_H__
/* Includes ------------------------------------------------------------------*/
#include "usb_conf.h"
/** @addtogroup USB_OTG_DRIVER
* @{
*/
/** @defgroup USB_DEFINES
* @brief This file is the
* @{
*/
/** @defgroup USB_DEFINES_Exported_Defines
* @{
*/
/**
* @}
*/
/** @defgroup _CORE_DEFINES_
* @{
*/
#define USB_OTG_SPEED_PARAM_HIGH 0
#define USB_OTG_SPEED_PARAM_HIGH_IN_FULL 1
#define USB_OTG_SPEED_PARAM_FULL 3
#define USB_OTG_SPEED_HIGH 0
#define USB_OTG_SPEED_FULL 1
#define USB_OTG_ULPI_PHY 1
#define USB_OTG_EMBEDDED_PHY 2
/**
* @}
*/
/** @defgroup _GLOBAL_DEFINES_
* @{
*/
#define GAHBCFG_TXFEMPTYLVL_EMPTY 1
#define GAHBCFG_TXFEMPTYLVL_HALFEMPTY 0
#define GAHBCFG_GLBINT_ENABLE 1
#define GAHBCFG_INT_DMA_BURST_SINGLE 0
#define GAHBCFG_INT_DMA_BURST_INCR 1
#define GAHBCFG_INT_DMA_BURST_INCR4 3
#define GAHBCFG_INT_DMA_BURST_INCR8 5
#define GAHBCFG_INT_DMA_BURST_INCR16 7
#define GAHBCFG_DMAENABLE 1
#define GAHBCFG_TXFEMPTYLVL_EMPTY 1
#define GAHBCFG_TXFEMPTYLVL_HALFEMPTY 0
#define GRXSTS_PKTSTS_IN 2
#define GRXSTS_PKTSTS_IN_XFER_COMP 3
#define GRXSTS_PKTSTS_DATA_TOGGLE_ERR 5
#define GRXSTS_PKTSTS_CH_HALTED 7
/**
* @}
*/
/** @defgroup _OnTheGo_DEFINES_
* @{
*/
#define MODE_HNP_SRP_CAPABLE 0
#define MODE_SRP_ONLY_CAPABLE 1
#define MODE_NO_HNP_SRP_CAPABLE 2
#define MODE_SRP_CAPABLE_DEVICE 3
#define MODE_NO_SRP_CAPABLE_DEVICE 4
#define MODE_SRP_CAPABLE_HOST 5
#define MODE_NO_SRP_CAPABLE_HOST 6
#define A_HOST 1
#define A_SUSPEND 2
#define A_PERIPHERAL 3
#define B_PERIPHERAL 4
#define B_HOST 5
#define DEVICE_MODE 0
#define HOST_MODE 1
#define OTG_MODE 2
/**
* @}
*/
/** @defgroup __DEVICE_DEFINES_
* @{
*/
#define DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ 0
#define DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ 1
#define DSTS_ENUMSPD_LS_PHY_6MHZ 2
#define DSTS_ENUMSPD_FS_PHY_48MHZ 3
#define DCFG_FRAME_INTERVAL_80 0
#define DCFG_FRAME_INTERVAL_85 1
#define DCFG_FRAME_INTERVAL_90 2
#define DCFG_FRAME_INTERVAL_95 3
#define DEP0CTL_MPS_64 0
#define DEP0CTL_MPS_32 1
#define DEP0CTL_MPS_16 2
#define DEP0CTL_MPS_8 3
#define EP_SPEED_LOW 0
#define EP_SPEED_FULL 1
#define EP_SPEED_HIGH 2
#define EP_TYPE_CTRL 0
#define EP_TYPE_ISOC 1
#define EP_TYPE_BULK 2
#define EP_TYPE_INTR 3
#define EP_TYPE_MSK 3
#define STS_GOUT_NAK 1
#define STS_DATA_UPDT 2
#define STS_XFER_COMP 3
#define STS_SETUP_COMP 4
#define STS_SETUP_UPDT 6
/**
* @}
*/
/** @defgroup __HOST_DEFINES_
* @{
*/
#define HC_PID_DATA0 0
#define HC_PID_DATA2 1
#define HC_PID_DATA1 2
#define HC_PID_SETUP 3
#define HPRT0_PRTSPD_HIGH_SPEED 0
#define HPRT0_PRTSPD_FULL_SPEED 1
#define HPRT0_PRTSPD_LOW_SPEED 2
#define HCFG_30_60_MHZ 0
#define HCFG_48_MHZ 1
#define HCFG_6_MHZ 2
#define HCCHAR_CTRL 0
#define HCCHAR_ISOC 1
#define HCCHAR_BULK 2
#define HCCHAR_INTR 3
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
/**
* @}
*/
/** @defgroup USB_DEFINES_Exported_Types
* @{
*/
typedef enum
{
USB_OTG_HS_CORE_ID = 0,
USB_OTG_FS_CORE_ID = 1
}USB_OTG_CORE_ID_TypeDef;
/**
* @}
*/
/** @defgroup USB_DEFINES_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USB_DEFINES_Exported_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USB_DEFINES_Exported_FunctionsPrototype
* @{
*/
/**
* @}
*/
/** @defgroup Internal_Macro's
* @{
*/
#define USB_OTG_READ_REG32(reg) (*(__IO uint32_t *)reg)
#define USB_OTG_WRITE_REG32(reg,value) (*(__IO uint32_t *)reg = value)
#define USB_OTG_MODIFY_REG32(reg,clear_mask,set_mask) \
USB_OTG_WRITE_REG32(reg, (((USB_OTG_READ_REG32(reg)) & ~clear_mask) | set_mask ) )
/********************************************************************************
ENUMERATION TYPE
********************************************************************************/
enum USB_OTG_SPEED {
USB_SPEED_UNKNOWN = 0,
USB_SPEED_LOW,
USB_SPEED_FULL,
USB_SPEED_HIGH
};
#endif //__USB_DEFINES__H__
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,108 @@
/**
******************************************************************************
* @file usb_hcd.h
* @author MCD Application Team
* @version V2.1.0
* @date 19-March-2012
* @brief Host layer Header file
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_HCD_H__
#define __USB_HCD_H__
/* Includes ------------------------------------------------------------------*/
#include "usb_regs.h"
#include "usb_core.h"
/** @addtogroup USB_OTG_DRIVER
* @{
*/
/** @defgroup USB_HCD
* @brief This file is the
* @{
*/
/** @defgroup USB_HCD_Exported_Defines
* @{
*/
/**
* @}
*/
/** @defgroup USB_HCD_Exported_Types
* @{
*/
/**
* @}
*/
/** @defgroup USB_HCD_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USB_HCD_Exported_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USB_HCD_Exported_FunctionsPrototype
* @{
*/
uint32_t HCD_Init (USB_OTG_CORE_HANDLE *pdev ,
USB_OTG_CORE_ID_TypeDef coreID);
uint32_t HCD_HC_Init (USB_OTG_CORE_HANDLE *pdev ,
uint8_t hc_num);
uint32_t HCD_SubmitRequest (USB_OTG_CORE_HANDLE *pdev ,
uint8_t hc_num) ;
uint32_t HCD_GetCurrentSpeed (USB_OTG_CORE_HANDLE *pdev);
uint32_t HCD_ResetPort (USB_OTG_CORE_HANDLE *pdev);
uint32_t HCD_IsDeviceConnected (USB_OTG_CORE_HANDLE *pdev);
uint32_t HCD_GetCurrentFrame (USB_OTG_CORE_HANDLE *pdev) ;
URB_STATE HCD_GetURB_State (USB_OTG_CORE_HANDLE *pdev, uint8_t ch_num);
uint32_t HCD_GetXferCnt (USB_OTG_CORE_HANDLE *pdev, uint8_t ch_num);
HC_STATUS HCD_GetHCState (USB_OTG_CORE_HANDLE *pdev, uint8_t ch_num) ;
/**
* @}
*/
#endif //__USB_HCD_H__
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,141 @@
/**
******************************************************************************
* @file usb_hcd_int.h
* @author MCD Application Team
* @version V2.1.0
* @date 19-March-2012
* @brief Peripheral Device Interface Layer
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __HCD_INT_H__
#define __HCD_INT_H__
/* Includes ------------------------------------------------------------------*/
#include "usb_hcd.h"
/** @addtogroup USB_OTG_DRIVER
* @{
*/
/** @defgroup USB_HCD_INT
* @brief This file is the
* @{
*/
/** @defgroup USB_HCD_INT_Exported_Defines
* @{
*/
/**
* @}
*/
/** @defgroup USB_HCD_INT_Exported_Types
* @{
*/
typedef struct _USBH_HCD_INT
{
uint8_t (* SOF) (USB_OTG_CORE_HANDLE *pdev);
uint8_t (* DevConnected) (USB_OTG_CORE_HANDLE *pdev);
uint8_t (* DevDisconnected) (USB_OTG_CORE_HANDLE *pdev);
}USBH_HCD_INT_cb_TypeDef;
extern USBH_HCD_INT_cb_TypeDef *USBH_HCD_INT_fops;
/**
* @}
*/
/** @defgroup USB_HCD_INT_Exported_Macros
* @{
*/
#define CLEAR_HC_INT(HC_REGS, intr) \
{\
USB_OTG_HCINTn_TypeDef hcint_clear; \
hcint_clear.d32 = 0; \
hcint_clear.b.intr = 1; \
USB_OTG_WRITE_REG32(&((HC_REGS)->HCINT), hcint_clear.d32);\
}\
#define MASK_HOST_INT_CHH(hc_num) { USB_OTG_HCINTMSK_TypeDef INTMSK; \
INTMSK.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[hc_num]->HCINTMSK); \
INTMSK.b.chhltd = 0; \
USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCINTMSK, INTMSK.d32);}
#define UNMASK_HOST_INT_CHH(hc_num) { USB_OTG_HCINTMSK_TypeDef INTMSK; \
INTMSK.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[hc_num]->HCINTMSK); \
INTMSK.b.chhltd = 1; \
USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCINTMSK, INTMSK.d32);}
#define MASK_HOST_INT_ACK(hc_num) { USB_OTG_HCINTMSK_TypeDef INTMSK; \
INTMSK.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[hc_num]->HCINTMSK); \
INTMSK.b.ack = 0; \
USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCINTMSK, GINTMSK.d32);}
#define UNMASK_HOST_INT_ACK(hc_num) { USB_OTG_HCGINTMSK_TypeDef INTMSK; \
INTMSK.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[hc_num]->HCINTMSK); \
INTMSK.b.ack = 1; \
USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCINTMSK, INTMSK.d32);}
/**
* @}
*/
/** @defgroup USB_HCD_INT_Exported_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USB_HCD_INT_Exported_FunctionsPrototype
* @{
*/
/* Callbacks handler */
void ConnectCallback_Handler(USB_OTG_CORE_HANDLE *pdev);
void Disconnect_Callback_Handler(USB_OTG_CORE_HANDLE *pdev);
void Overcurrent_Callback_Handler(USB_OTG_CORE_HANDLE *pdev);
uint32_t USBH_OTG_ISR_Handler (USB_OTG_CORE_HANDLE *pdev);
/**
* @}
*/
#endif //__HCD_INT_H__
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,99 @@
/**
******************************************************************************
* @file usb_otg.h
* @author MCD Application Team
* @version V2.1.0
* @date 19-March-2012
* @brief OTG Core Header
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_OTG__
#define __USB_OTG__
/** @addtogroup USB_OTG_DRIVER
* @{
*/
/** @defgroup USB_OTG
* @brief This file is the
* @{
*/
/** @defgroup USB_OTG_Exported_Defines
* @{
*/
void USB_OTG_InitiateSRP(void);
void USB_OTG_InitiateHNP(uint8_t state , uint8_t mode);
void USB_OTG_Switchback (USB_OTG_CORE_DEVICE *pdev);
uint32_t USB_OTG_GetCurrentState (USB_OTG_CORE_DEVICE *pdev);
/**
* @}
*/
/** @defgroup USB_OTG_Exported_Types
* @{
*/
/**
* @}
*/
/** @defgroup USB_OTG_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USB_OTG_Exported_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USB_OTG_Exported_FunctionsPrototype
* @{
*/
/**
* @}
*/
#endif //__USB_OTG__
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,206 @@
/**
******************************************************************************
* @file usb_bsp.c
* @author MCD Application Team
* @version V2.1.0
* @date 19-March-2012
* @brief This file is responsible to offer board support package and is
* configurable by user.
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "usb_bsp.h"
/** @addtogroup USB_OTG_DRIVER
* @{
*/
/** @defgroup USB_BSP
* @brief This file is responsible to offer board support package
* @{
*/
/** @defgroup USB_BSP_Private_Defines
* @{
*/
/**
* @}
*/
/** @defgroup USB_BSP_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @defgroup USB_BSP_Private_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBH_BSP_Private_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USBH_BSP_Private_FunctionPrototypes
* @{
*/
/**
* @}
*/
/** @defgroup USB_BSP_Private_Functions
* @{
*/
/**
* @brief USB_OTG_BSP_Init
* Initilizes BSP configurations
* @param None
* @retval None
*/
void USB_OTG_BSP_Init(void)
{
}
/**
* @brief USB_OTG_BSP_EnableInterrupt
* Enabele USB Global interrupt
* @param None
* @retval None
*/
void USB_OTG_BSP_EnableInterrupt(void)
{
}
/**
* @brief BSP_Drive_VBUS
* Drives the Vbus signal through IO
* @param speed : Full, Low
* @param state : VBUS states
* @retval None
*/
void USB_OTG_BSP_DriveVBUS(uint32_t speed, uint8_t state)
{
}
/**
* @brief USB_OTG_BSP_ConfigVBUS
* Configures the IO for the Vbus and OverCurrent
* @param Speed : Full, Low
* @retval None
*/
void USB_OTG_BSP_ConfigVBUS(uint32_t speed)
{
}
/**
* @brief USB_OTG_BSP_TimeInit
* Initialises delay unit Systick timer /Timer2
* @param None
* @retval None
*/
void USB_OTG_BSP_TimeInit ( void )
{
}
/**
* @brief USB_OTG_BSP_uDelay
* This function provides delay time in micro sec
* @param usec : Value of delay required in micro sec
* @retval None
*/
void USB_OTG_BSP_uDelay (const uint32_t usec)
{
uint32_t count = 0;
const uint32_t utime = (120 * usec / 7);
do
{
if ( ++count > utime )
{
return ;
}
}
while (1);
}
/**
* @brief USB_OTG_BSP_mDelay
* This function provides delay time in milli sec
* @param msec : Value of delay required in milli sec
* @retval None
*/
void USB_OTG_BSP_mDelay (const uint32_t msec)
{
USB_OTG_BSP_uDelay(msec * 1000);
}
/**
* @brief USB_OTG_BSP_TimerIRQ
* Time base IRQ
* @param None
* @retval None
*/
void USB_OTG_BSP_TimerIRQ (void)
{
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,478 @@
/**
******************************************************************************
* @file usb_dcd.c
* @author MCD Application Team
* @version V2.1.0
* @date 19-March-2012
* @brief Peripheral Device Interface Layer
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "usb_dcd.h"
#include "usb_bsp.h"
/** @addtogroup USB_OTG_DRIVER
* @{
*/
/** @defgroup USB_DCD
* @brief This file is the interface between EFSL ans Host mass-storage class
* @{
*/
/** @defgroup USB_DCD_Private_Defines
* @{
*/
/**
* @}
*/
/** @defgroup USB_DCD_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @defgroup USB_DCD_Private_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USB_DCD_Private_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USB_DCD_Private_FunctionPrototypes
* @{
*/
/**
* @}
*/
/** @defgroup USB_DCD_Private_Functions
* @{
*/
void DCD_Init(USB_OTG_CORE_HANDLE *pdev ,
USB_OTG_CORE_ID_TypeDef coreID)
{
uint32_t i;
USB_OTG_EP *ep;
USB_OTG_SelectCore (pdev , coreID);
pdev->dev.device_status = USB_OTG_DEFAULT;
pdev->dev.device_address = 0;
/* Init ep structure */
for (i = 0; i < pdev->cfg.dev_endpoints ; i++)
{
ep = &pdev->dev.in_ep[i];
/* Init ep structure */
ep->is_in = 1;
ep->num = i;
ep->tx_fifo_num = i;
/* Control until ep is actvated */
ep->type = EP_TYPE_CTRL;
ep->maxpacket = USB_OTG_MAX_EP0_SIZE;
ep->xfer_buff = 0;
ep->xfer_len = 0;
}
for (i = 0; i < pdev->cfg.dev_endpoints; i++)
{
ep = &pdev->dev.out_ep[i];
/* Init ep structure */
ep->is_in = 0;
ep->num = i;
ep->tx_fifo_num = i;
/* Control until ep is activated */
ep->type = EP_TYPE_CTRL;
ep->maxpacket = USB_OTG_MAX_EP0_SIZE;
ep->xfer_buff = 0;
ep->xfer_len = 0;
}
USB_OTG_DisableGlobalInt(pdev);
/*Init the Core (common init.) */
USB_OTG_CoreInit(pdev);
/* Force Device Mode*/
USB_OTG_SetCurrentMode(pdev, DEVICE_MODE);
/* Init Device */
USB_OTG_CoreInitDev(pdev);
/* Enable USB Global interrupt */
USB_OTG_EnableGlobalInt(pdev);
}
/**
* @brief Configure an EP
* @param pdev : Device instance
* @param epdesc : Endpoint Descriptor
* @retval : status
*/
uint32_t DCD_EP_Open(USB_OTG_CORE_HANDLE *pdev ,
uint8_t ep_addr,
uint16_t ep_mps,
uint8_t ep_type)
{
USB_OTG_EP *ep;
if ((ep_addr & 0x80) == 0x80)
{
ep = &pdev->dev.in_ep[ep_addr & 0x7F];
}
else
{
ep = &pdev->dev.out_ep[ep_addr & 0x7F];
}
ep->num = ep_addr & 0x7F;
ep->is_in = (0x80 & ep_addr) != 0;
ep->maxpacket = ep_mps;
ep->type = ep_type;
if (ep->is_in)
{
/* Assign a Tx FIFO */
ep->tx_fifo_num = ep->num;
}
/* Set initial data PID. */
if (ep_type == USB_OTG_EP_BULK )
{
ep->data_pid_start = 0;
}
USB_OTG_EPActivate(pdev , ep );
return 0;
}
/**
* @brief called when an EP is disabled
* @param pdev: device instance
* @param ep_addr: endpoint address
* @retval : status
*/
uint32_t DCD_EP_Close(USB_OTG_CORE_HANDLE *pdev , uint8_t ep_addr)
{
USB_OTG_EP *ep;
if ((ep_addr&0x80) == 0x80)
{
ep = &pdev->dev.in_ep[ep_addr & 0x7F];
}
else
{
ep = &pdev->dev.out_ep[ep_addr & 0x7F];
}
ep->num = ep_addr & 0x7F;
ep->is_in = (0x80 & ep_addr) != 0;
USB_OTG_EPDeactivate(pdev , ep );
return 0;
}
/**
* @brief DCD_EP_PrepareRx
* @param pdev: device instance
* @param ep_addr: endpoint address
* @param pbuf: pointer to Rx buffer
* @param buf_len: data length
* @retval : status
*/
uint32_t DCD_EP_PrepareRx( USB_OTG_CORE_HANDLE *pdev,
uint8_t ep_addr,
uint8_t *pbuf,
uint16_t buf_len)
{
USB_OTG_EP *ep;
ep = &pdev->dev.out_ep[ep_addr & 0x7F];
/*setup and start the Xfer */
ep->xfer_buff = pbuf;
ep->xfer_len = buf_len;
ep->xfer_count = 0;
ep->is_in = 0;
ep->num = ep_addr & 0x7F;
if (pdev->cfg.dma_enable == 1)
{
ep->dma_addr = (uint32_t)pbuf;
}
if ( ep->num == 0 )
{
USB_OTG_EP0StartXfer(pdev , ep);
}
else
{
USB_OTG_EPStartXfer(pdev, ep );
}
return 0;
}
/**
* @brief Transmit data over USB
* @param pdev: device instance
* @param ep_addr: endpoint address
* @param pbuf: pointer to Tx buffer
* @param buf_len: data length
* @retval : status
*/
uint32_t DCD_EP_Tx ( USB_OTG_CORE_HANDLE *pdev,
uint8_t ep_addr,
uint8_t *pbuf,
uint32_t buf_len)
{
USB_OTG_EP *ep;
ep = &pdev->dev.in_ep[ep_addr & 0x7F];
/* Setup and start the Transfer */
ep->is_in = 1;
ep->num = ep_addr & 0x7F;
ep->xfer_buff = pbuf;
ep->dma_addr = (uint32_t)pbuf;
ep->xfer_count = 0;
ep->xfer_len = buf_len;
if ( ep->num == 0 )
{
USB_OTG_EP0StartXfer(pdev , ep);
}
else
{
USB_OTG_EPStartXfer(pdev, ep );
}
return 0;
}
/**
* @brief Stall an endpoint.
* @param pdev: device instance
* @param epnum: endpoint address
* @retval : status
*/
uint32_t DCD_EP_Stall (USB_OTG_CORE_HANDLE *pdev, uint8_t epnum)
{
USB_OTG_EP *ep;
if ((0x80 & epnum) == 0x80)
{
ep = &pdev->dev.in_ep[epnum & 0x7F];
}
else
{
ep = &pdev->dev.out_ep[epnum];
}
ep->is_stall = 1;
ep->num = epnum & 0x7F;
ep->is_in = ((epnum & 0x80) == 0x80);
USB_OTG_EPSetStall(pdev , ep);
return (0);
}
/**
* @brief Clear stall condition on endpoints.
* @param pdev: device instance
* @param epnum: endpoint address
* @retval : status
*/
uint32_t DCD_EP_ClrStall (USB_OTG_CORE_HANDLE *pdev, uint8_t epnum)
{
USB_OTG_EP *ep;
if ((0x80 & epnum) == 0x80)
{
ep = &pdev->dev.in_ep[epnum & 0x7F];
}
else
{
ep = &pdev->dev.out_ep[epnum];
}
ep->is_stall = 0;
ep->num = epnum & 0x7F;
ep->is_in = ((epnum & 0x80) == 0x80);
USB_OTG_EPClearStall(pdev , ep);
return (0);
}
/**
* @brief This Function flushes the FIFOs.
* @param pdev: device instance
* @param epnum: endpoint address
* @retval : status
*/
uint32_t DCD_EP_Flush (USB_OTG_CORE_HANDLE *pdev , uint8_t epnum)
{
if ((epnum & 0x80) == 0x80)
{
USB_OTG_FlushTxFifo(pdev, epnum & 0x7F);
}
else
{
USB_OTG_FlushRxFifo(pdev);
}
return (0);
}
/**
* @brief This Function set USB device address
* @param pdev: device instance
* @param address: new device address
* @retval : status
*/
void DCD_EP_SetAddress (USB_OTG_CORE_HANDLE *pdev, uint8_t address)
{
USB_OTG_DCFG_TypeDef dcfg;
dcfg.d32 = 0;
dcfg.b.devaddr = address;
USB_OTG_MODIFY_REG32( &pdev->regs.DREGS->DCFG, 0, dcfg.d32);
}
/**
* @brief Connect device (enable internal pull-up)
* @param pdev: device instance
* @retval : None
*/
void DCD_DevConnect (USB_OTG_CORE_HANDLE *pdev)
{
#ifndef USE_OTG_MODE
USB_OTG_DCTL_TypeDef dctl;
dctl.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DCTL);
/* Connect device */
dctl.b.sftdiscon = 0;
USB_OTG_WRITE_REG32(&pdev->regs.DREGS->DCTL, dctl.d32);
USB_OTG_BSP_mDelay(3);
#endif
}
/**
* @brief Disconnect device (disable internal pull-up)
* @param pdev: device instance
* @retval : None
*/
void DCD_DevDisconnect (USB_OTG_CORE_HANDLE *pdev)
{
#ifndef USE_OTG_MODE
USB_OTG_DCTL_TypeDef dctl;
dctl.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DCTL);
/* Disconnect device for 3ms */
dctl.b.sftdiscon = 1;
USB_OTG_WRITE_REG32(&pdev->regs.DREGS->DCTL, dctl.d32);
USB_OTG_BSP_mDelay(3);
#endif
}
/**
* @brief returns the EP Status
* @param pdev : Selected device
* epnum : endpoint address
* @retval : EP status
*/
uint32_t DCD_GetEPStatus(USB_OTG_CORE_HANDLE *pdev ,uint8_t epnum)
{
USB_OTG_EP *ep;
uint32_t Status = 0;
if ((0x80 & epnum) == 0x80)
{
ep = &pdev->dev.in_ep[epnum & 0x7F];
}
else
{
ep = &pdev->dev.out_ep[epnum];
}
Status = USB_OTG_GetEPStatus(pdev ,ep);
/* Return the current status */
return Status;
}
/**
* @brief Set the EP Status
* @param pdev : Selected device
* Status : new Status
* epnum : EP address
* @retval : None
*/
void DCD_SetEPStatus (USB_OTG_CORE_HANDLE *pdev , uint8_t epnum , uint32_t Status)
{
USB_OTG_EP *ep;
if ((0x80 & epnum) == 0x80)
{
ep = &pdev->dev.in_ep[epnum & 0x7F];
}
else
{
ep = &pdev->dev.out_ep[epnum];
}
USB_OTG_SetEPStatus(pdev ,ep , Status);
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,869 @@
/**
******************************************************************************
* @file usb_dcd_int.c
* @author MCD Application Team
* @version V2.1.0
* @date 19-March-2012
* @brief Peripheral Device interrupt subroutines
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "usb_dcd_int.h"
/** @addtogroup USB_OTG_DRIVER
* @{
*/
/** @defgroup USB_DCD_INT
* @brief This file contains the interrupt subroutines for the Device mode.
* @{
*/
/** @defgroup USB_DCD_INT_Private_Defines
* @{
*/
/**
* @}
*/
/** @defgroup USB_DCD_INT_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @defgroup USB_DCD_INT_Private_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USB_DCD_INT_Private_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USB_DCD_INT_Private_FunctionPrototypes
* @{
*/
/* static functions */
static uint32_t DCD_ReadDevInEP (USB_OTG_CORE_HANDLE *pdev, uint8_t epnum);
/* Interrupt Handlers */
static uint32_t DCD_HandleInEP_ISR(USB_OTG_CORE_HANDLE *pdev);
static uint32_t DCD_HandleOutEP_ISR(USB_OTG_CORE_HANDLE *pdev);
static uint32_t DCD_HandleSof_ISR(USB_OTG_CORE_HANDLE *pdev);
static uint32_t DCD_HandleRxStatusQueueLevel_ISR(USB_OTG_CORE_HANDLE *pdev);
static uint32_t DCD_WriteEmptyTxFifo(USB_OTG_CORE_HANDLE *pdev , uint32_t epnum);
static uint32_t DCD_HandleUsbReset_ISR(USB_OTG_CORE_HANDLE *pdev);
static uint32_t DCD_HandleEnumDone_ISR(USB_OTG_CORE_HANDLE *pdev);
static uint32_t DCD_HandleResume_ISR(USB_OTG_CORE_HANDLE *pdev);
static uint32_t DCD_HandleUSBSuspend_ISR(USB_OTG_CORE_HANDLE *pdev);
static uint32_t DCD_IsoINIncomplete_ISR(USB_OTG_CORE_HANDLE *pdev);
static uint32_t DCD_IsoOUTIncomplete_ISR(USB_OTG_CORE_HANDLE *pdev);
#ifdef VBUS_SENSING_ENABLED
static uint32_t DCD_SessionRequest_ISR(USB_OTG_CORE_HANDLE *pdev);
static uint32_t DCD_OTG_ISR(USB_OTG_CORE_HANDLE *pdev);
#endif
/**
* @}
*/
/** @defgroup USB_DCD_INT_Private_Functions
* @{
*/
#ifdef USB_OTG_HS_DEDICATED_EP1_ENABLED
/**
* @brief USBD_OTG_EP1OUT_ISR_Handler
* handles all USB Interrupts
* @param pdev: device instance
* @retval status
*/
uint32_t USBD_OTG_EP1OUT_ISR_Handler (USB_OTG_CORE_HANDLE *pdev)
{
USB_OTG_DOEPINTn_TypeDef doepint;
USB_OTG_DEPXFRSIZ_TypeDef deptsiz;
doepint.d32 = USB_OTG_READ_REG32(&pdev->regs.OUTEP_REGS[1]->DOEPINT);
doepint.d32&= USB_OTG_READ_REG32(&pdev->regs.DREGS->DOUTEP1MSK);
/* Transfer complete */
if ( doepint.b.xfercompl )
{
/* Clear the bit in DOEPINTn for this interrupt */
CLEAR_OUT_EP_INTR(1, xfercompl);
if (pdev->cfg.dma_enable == 1)
{
deptsiz.d32 = USB_OTG_READ_REG32(&(pdev->regs.OUTEP_REGS[1]->DOEPTSIZ));
/*ToDo : handle more than one single MPS size packet */
pdev->dev.out_ep[1].xfer_count = pdev->dev.out_ep[1].maxpacket - \
deptsiz.b.xfersize;
}
/* Inform upper layer: data ready */
/* RX COMPLETE */
USBD_DCD_INT_fops->DataOutStage(pdev , 1);
}
/* Endpoint disable */
if ( doepint.b.epdisabled )
{
/* Clear the bit in DOEPINTn for this interrupt */
CLEAR_OUT_EP_INTR(1, epdisabled);
}
return 1;
}
/**
* @brief USBD_OTG_EP1IN_ISR_Handler
* handles all USB Interrupts
* @param pdev: device instance
* @retval status
*/
uint32_t USBD_OTG_EP1IN_ISR_Handler (USB_OTG_CORE_HANDLE *pdev)
{
USB_OTG_DIEPINTn_TypeDef diepint;
uint32_t fifoemptymsk, msk, emp;
msk = USB_OTG_READ_REG32(&pdev->regs.DREGS->DINEP1MSK);
emp = USB_OTG_READ_REG32(&pdev->regs.DREGS->DIEPEMPMSK);
msk |= ((emp >> 1 ) & 0x1) << 7;
diepint.d32 = USB_OTG_READ_REG32(&pdev->regs.INEP_REGS[1]->DIEPINT) & msk;
if ( diepint.b.xfercompl )
{
fifoemptymsk = 0x1 << 1;
USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DIEPEMPMSK, fifoemptymsk, 0);
CLEAR_IN_EP_INTR(1, xfercompl);
/* TX COMPLETE */
USBD_DCD_INT_fops->DataInStage(pdev , 1);
}
if ( diepint.b.epdisabled )
{
CLEAR_IN_EP_INTR(1, epdisabled);
}
if ( diepint.b.timeout )
{
CLEAR_IN_EP_INTR(1, timeout);
}
if (diepint.b.intktxfemp)
{
CLEAR_IN_EP_INTR(1, intktxfemp);
}
if (diepint.b.inepnakeff)
{
CLEAR_IN_EP_INTR(1, inepnakeff);
}
if (diepint.b.emptyintr)
{
DCD_WriteEmptyTxFifo(pdev , 1);
CLEAR_IN_EP_INTR(1, emptyintr);
}
return 1;
}
#endif
/**
* @brief STM32_USBF_OTG_ISR_Handler
* handles all USB Interrupts
* @param pdev: device instance
* @retval status
*/
uint32_t USBD_OTG_ISR_Handler (USB_OTG_CORE_HANDLE *pdev)
{
USB_OTG_GINTSTS_TypeDef gintr_status;
uint32_t retval = 0;
if (USB_OTG_IsDeviceMode(pdev)) /* ensure that we are in device mode */
{
gintr_status.d32 = USB_OTG_ReadCoreItr(pdev);
if (!gintr_status.d32) /* avoid spurious interrupt */
{
return 0;
}
if (gintr_status.b.outepintr)
{
retval |= DCD_HandleOutEP_ISR(pdev);
}
if (gintr_status.b.inepint)
{
retval |= DCD_HandleInEP_ISR(pdev);
}
if (gintr_status.b.modemismatch)
{
USB_OTG_GINTSTS_TypeDef gintsts;
/* Clear interrupt */
gintsts.d32 = 0;
gintsts.b.modemismatch = 1;
USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32);
}
if (gintr_status.b.wkupintr)
{
retval |= DCD_HandleResume_ISR(pdev);
}
if (gintr_status.b.usbsuspend)
{
retval |= DCD_HandleUSBSuspend_ISR(pdev);
}
if (gintr_status.b.sofintr)
{
retval |= DCD_HandleSof_ISR(pdev);
}
if (gintr_status.b.rxstsqlvl)
{
retval |= DCD_HandleRxStatusQueueLevel_ISR(pdev);
}
if (gintr_status.b.usbreset)
{
retval |= DCD_HandleUsbReset_ISR(pdev);
}
if (gintr_status.b.enumdone)
{
retval |= DCD_HandleEnumDone_ISR(pdev);
}
if (gintr_status.b.incomplisoin)
{
retval |= DCD_IsoINIncomplete_ISR(pdev);
}
if (gintr_status.b.incomplisoout)
{
retval |= DCD_IsoOUTIncomplete_ISR(pdev);
}
#ifdef VBUS_SENSING_ENABLED
if (gintr_status.b.sessreqintr)
{
retval |= DCD_SessionRequest_ISR(pdev);
}
if (gintr_status.b.otgintr)
{
retval |= DCD_OTG_ISR(pdev);
}
#endif
}
return retval;
}
#ifdef VBUS_SENSING_ENABLED
/**
* @brief DCD_SessionRequest_ISR
* Indicates that the USB_OTG controller has detected a connection
* @param pdev: device instance
* @retval status
*/
static uint32_t DCD_SessionRequest_ISR(USB_OTG_CORE_HANDLE *pdev)
{
USB_OTG_GINTSTS_TypeDef gintsts;
USBD_DCD_INT_fops->DevConnected (pdev);
/* Clear interrupt */
gintsts.d32 = 0;
gintsts.b.sessreqintr = 1;
USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GINTSTS, gintsts.d32);
return 1;
}
/**
* @brief DCD_OTG_ISR
* Indicates that the USB_OTG controller has detected an OTG event:
* used to detect the end of session i.e. disconnection
* @param pdev: device instance
* @retval status
*/
static uint32_t DCD_OTG_ISR(USB_OTG_CORE_HANDLE *pdev)
{
USB_OTG_GOTGINT_TypeDef gotgint;
gotgint.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GOTGINT);
if (gotgint.b.sesenddet)
{
USBD_DCD_INT_fops->DevDisconnected (pdev);
}
/* Clear OTG interrupt */
USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GOTGINT, gotgint.d32);
return 1;
}
#endif
/**
* @brief DCD_HandleResume_ISR
* Indicates that the USB_OTG controller has detected a resume or
* remote Wake-up sequence
* @param pdev: device instance
* @retval status
*/
static uint32_t DCD_HandleResume_ISR(USB_OTG_CORE_HANDLE *pdev)
{
USB_OTG_GINTSTS_TypeDef gintsts;
USB_OTG_DCTL_TypeDef devctl;
USB_OTG_PCGCCTL_TypeDef power;
if(pdev->cfg.low_power)
{
/* un-gate USB Core clock */
power.d32 = USB_OTG_READ_REG32(&pdev->regs.PCGCCTL);
power.b.gatehclk = 0;
power.b.stoppclk = 0;
USB_OTG_WRITE_REG32(pdev->regs.PCGCCTL, power.d32);
}
/* Clear the Remote Wake-up Signaling */
devctl.d32 = 0;
devctl.b.rmtwkupsig = 1;
USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DCTL, devctl.d32, 0);
/* Inform upper layer by the Resume Event */
USBD_DCD_INT_fops->Resume (pdev);
/* Clear interrupt */
gintsts.d32 = 0;
gintsts.b.wkupintr = 1;
USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GINTSTS, gintsts.d32);
return 1;
}
/**
* @brief USB_OTG_HandleUSBSuspend_ISR
* Indicates that SUSPEND state has been detected on the USB
* @param pdev: device instance
* @retval status
*/
static uint32_t DCD_HandleUSBSuspend_ISR(USB_OTG_CORE_HANDLE *pdev)
{
USB_OTG_GINTSTS_TypeDef gintsts;
USB_OTG_PCGCCTL_TypeDef power;
USB_OTG_DSTS_TypeDef dsts;
__IO uint8_t prev_status = 0;
prev_status = pdev->dev.device_status;
USBD_DCD_INT_fops->Suspend (pdev);
dsts.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DSTS);
/* Clear interrupt */
gintsts.d32 = 0;
gintsts.b.usbsuspend = 1;
USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32);
if((pdev->cfg.low_power) && (dsts.b.suspsts == 1) &&
(pdev->dev.connection_status == 1) &&
(prev_status == USB_OTG_CONFIGURED))
{
/* switch-off the clocks */
power.d32 = 0;
power.b.stoppclk = 1;
USB_OTG_MODIFY_REG32(pdev->regs.PCGCCTL, 0, power.d32);
power.b.gatehclk = 1;
USB_OTG_MODIFY_REG32(pdev->regs.PCGCCTL, 0, power.d32);
/* Request to enter Sleep mode after exit from current ISR */
SCB->SCR |= (SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk);
}
return 1;
}
/**
* @brief DCD_HandleInEP_ISR
* Indicates that an IN EP has a pending Interrupt
* @param pdev: device instance
* @retval status
*/
static uint32_t DCD_HandleInEP_ISR(USB_OTG_CORE_HANDLE *pdev)
{
USB_OTG_DIEPINTn_TypeDef diepint;
uint32_t ep_intr;
uint32_t epnum = 0;
uint32_t fifoemptymsk;
diepint.d32 = 0;
ep_intr = USB_OTG_ReadDevAllInEPItr(pdev);
while ( ep_intr )
{
if (ep_intr&0x1) /* In ITR */
{
diepint.d32 = DCD_ReadDevInEP(pdev , epnum); /* Get In ITR status */
if ( diepint.b.xfercompl )
{
fifoemptymsk = 0x1 << epnum;
USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DIEPEMPMSK, fifoemptymsk, 0);
CLEAR_IN_EP_INTR(epnum, xfercompl);
/* TX COMPLETE */
USBD_DCD_INT_fops->DataInStage(pdev , epnum);
if (pdev->cfg.dma_enable == 1)
{
if((epnum == 0) && (pdev->dev.device_state == USB_OTG_EP0_STATUS_IN))
{
/* prepare to rx more setup packets */
USB_OTG_EP0_OutStart(pdev);
}
}
}
if ( diepint.b.timeout )
{
CLEAR_IN_EP_INTR(epnum, timeout);
}
if (diepint.b.intktxfemp)
{
CLEAR_IN_EP_INTR(epnum, intktxfemp);
}
if (diepint.b.inepnakeff)
{
CLEAR_IN_EP_INTR(epnum, inepnakeff);
}
if ( diepint.b.epdisabled )
{
CLEAR_IN_EP_INTR(epnum, epdisabled);
}
if (diepint.b.emptyintr)
{
DCD_WriteEmptyTxFifo(pdev , epnum);
CLEAR_IN_EP_INTR(epnum, emptyintr);
}
}
epnum++;
ep_intr >>= 1;
}
return 1;
}
/**
* @brief DCD_HandleOutEP_ISR
* Indicates that an OUT EP has a pending Interrupt
* @param pdev: device instance
* @retval status
*/
static uint32_t DCD_HandleOutEP_ISR(USB_OTG_CORE_HANDLE *pdev)
{
uint32_t ep_intr;
USB_OTG_DOEPINTn_TypeDef doepint;
USB_OTG_DEPXFRSIZ_TypeDef deptsiz;
uint32_t epnum = 0;
doepint.d32 = 0;
/* Read in the device interrupt bits */
ep_intr = USB_OTG_ReadDevAllOutEp_itr(pdev);
while ( ep_intr )
{
if (ep_intr&0x1)
{
doepint.d32 = USB_OTG_ReadDevOutEP_itr(pdev, epnum);
/* Transfer complete */
if ( doepint.b.xfercompl )
{
/* Clear the bit in DOEPINTn for this interrupt */
CLEAR_OUT_EP_INTR(epnum, xfercompl);
if (pdev->cfg.dma_enable == 1)
{
deptsiz.d32 = USB_OTG_READ_REG32(&(pdev->regs.OUTEP_REGS[epnum]->DOEPTSIZ));
/*ToDo : handle more than one single MPS size packet */
pdev->dev.out_ep[epnum].xfer_count = pdev->dev.out_ep[epnum].maxpacket - \
deptsiz.b.xfersize;
}
/* Inform upper layer: data ready */
/* RX COMPLETE */
USBD_DCD_INT_fops->DataOutStage(pdev , epnum);
if (pdev->cfg.dma_enable == 1)
{
if((epnum == 0) && (pdev->dev.device_state == USB_OTG_EP0_STATUS_OUT))
{
/* prepare to rx more setup packets */
USB_OTG_EP0_OutStart(pdev);
}
}
}
/* Endpoint disable */
if ( doepint.b.epdisabled )
{
/* Clear the bit in DOEPINTn for this interrupt */
CLEAR_OUT_EP_INTR(epnum, epdisabled);
}
/* Setup Phase Done (control EPs) */
if ( doepint.b.setup )
{
/* inform the upper layer that a setup packet is available */
/* SETUP COMPLETE */
USBD_DCD_INT_fops->SetupStage(pdev);
CLEAR_OUT_EP_INTR(epnum, setup);
}
}
epnum++;
ep_intr >>= 1;
}
return 1;
}
/**
* @brief DCD_HandleSof_ISR
* Handles the SOF Interrupts
* @param pdev: device instance
* @retval status
*/
static uint32_t DCD_HandleSof_ISR(USB_OTG_CORE_HANDLE *pdev)
{
USB_OTG_GINTSTS_TypeDef GINTSTS;
USBD_DCD_INT_fops->SOF(pdev);
/* Clear interrupt */
GINTSTS.d32 = 0;
GINTSTS.b.sofintr = 1;
USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GINTSTS, GINTSTS.d32);
return 1;
}
/**
* @brief DCD_HandleRxStatusQueueLevel_ISR
* Handles the Rx Status Queue Level Interrupt
* @param pdev: device instance
* @retval status
*/
static uint32_t DCD_HandleRxStatusQueueLevel_ISR(USB_OTG_CORE_HANDLE *pdev)
{
USB_OTG_GINTMSK_TypeDef int_mask;
USB_OTG_DRXSTS_TypeDef status;
USB_OTG_EP *ep;
/* Disable the Rx Status Queue Level interrupt */
int_mask.d32 = 0;
int_mask.b.rxstsqlvl = 1;
USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, int_mask.d32, 0);
/* Get the Status from the top of the FIFO */
status.d32 = USB_OTG_READ_REG32( &pdev->regs.GREGS->GRXSTSP );
ep = &pdev->dev.out_ep[status.b.epnum];
switch (status.b.pktsts)
{
case STS_GOUT_NAK:
break;
case STS_DATA_UPDT:
if (status.b.bcnt)
{
USB_OTG_ReadPacket(pdev,ep->xfer_buff, status.b.bcnt);
ep->xfer_buff += status.b.bcnt;
ep->xfer_count += status.b.bcnt;
}
break;
case STS_XFER_COMP:
break;
case STS_SETUP_COMP:
break;
case STS_SETUP_UPDT:
/* Copy the setup packet received in FIFO into the setup buffer in RAM */
USB_OTG_ReadPacket(pdev , pdev->dev.setup_packet, 8);
ep->xfer_count += status.b.bcnt;
break;
default:
break;
}
/* Enable the Rx Status Queue Level interrupt */
USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, 0, int_mask.d32);
return 1;
}
/**
* @brief DCD_WriteEmptyTxFifo
* check FIFO for the next packet to be loaded
* @param pdev: device instance
* @retval status
*/
static uint32_t DCD_WriteEmptyTxFifo(USB_OTG_CORE_HANDLE *pdev, uint32_t epnum)
{
USB_OTG_DTXFSTSn_TypeDef txstatus;
USB_OTG_EP *ep;
uint32_t len = 0;
uint32_t len32b;
txstatus.d32 = 0;
ep = &pdev->dev.in_ep[epnum];
len = ep->xfer_len - ep->xfer_count;
if (len > ep->maxpacket)
{
len = ep->maxpacket;
}
len32b = (len + 3) / 4;
txstatus.d32 = USB_OTG_READ_REG32( &pdev->regs.INEP_REGS[epnum]->DTXFSTS);
while (txstatus.b.txfspcavail > len32b &&
ep->xfer_count < ep->xfer_len &&
ep->xfer_len != 0)
{
/* Write the FIFO */
len = ep->xfer_len - ep->xfer_count;
if (len > ep->maxpacket)
{
len = ep->maxpacket;
}
len32b = (len + 3) / 4;
USB_OTG_WritePacket (pdev , ep->xfer_buff, epnum, len);
ep->xfer_buff += len;
ep->xfer_count += len;
txstatus.d32 = USB_OTG_READ_REG32(&pdev->regs.INEP_REGS[epnum]->DTXFSTS);
}
return 1;
}
/**
* @brief DCD_HandleUsbReset_ISR
* This interrupt occurs when a USB Reset is detected
* @param pdev: device instance
* @retval status
*/
static uint32_t DCD_HandleUsbReset_ISR(USB_OTG_CORE_HANDLE *pdev)
{
USB_OTG_DAINT_TypeDef daintmsk;
USB_OTG_DOEPMSK_TypeDef doepmsk;
USB_OTG_DIEPMSK_TypeDef diepmsk;
USB_OTG_DCFG_TypeDef dcfg;
USB_OTG_DCTL_TypeDef dctl;
USB_OTG_GINTSTS_TypeDef gintsts;
uint32_t i;
dctl.d32 = 0;
daintmsk.d32 = 0;
doepmsk.d32 = 0;
diepmsk.d32 = 0;
dcfg.d32 = 0;
gintsts.d32 = 0;
/* Clear the Remote Wake-up Signaling */
dctl.b.rmtwkupsig = 1;
USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DCTL, dctl.d32, 0 );
/* Flush the Tx FIFO */
USB_OTG_FlushTxFifo(pdev , 0 );
for (i = 0; i < pdev->cfg.dev_endpoints ; i++)
{
USB_OTG_WRITE_REG32( &pdev->regs.INEP_REGS[i]->DIEPINT, 0xFF);
USB_OTG_WRITE_REG32( &pdev->regs.OUTEP_REGS[i]->DOEPINT, 0xFF);
}
USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DAINT, 0xFFFFFFFF );
daintmsk.ep.in = 1;
daintmsk.ep.out = 1;
USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DAINTMSK, daintmsk.d32 );
doepmsk.b.setup = 1;
doepmsk.b.xfercompl = 1;
doepmsk.b.epdisabled = 1;
USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DOEPMSK, doepmsk.d32 );
#ifdef USB_OTG_HS_DEDICATED_EP1_ENABLED
USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DOUTEP1MSK, doepmsk.d32 );
#endif
diepmsk.b.xfercompl = 1;
diepmsk.b.timeout = 1;
diepmsk.b.epdisabled = 1;
USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DIEPMSK, diepmsk.d32 );
#ifdef USB_OTG_HS_DEDICATED_EP1_ENABLED
USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DINEP1MSK, diepmsk.d32 );
#endif
/* Reset Device Address */
dcfg.d32 = USB_OTG_READ_REG32( &pdev->regs.DREGS->DCFG);
dcfg.b.devaddr = 0;
USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DCFG, dcfg.d32);
/* setup EP0 to receive SETUP packets */
USB_OTG_EP0_OutStart(pdev);
/* Clear interrupt */
gintsts.d32 = 0;
gintsts.b.usbreset = 1;
USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GINTSTS, gintsts.d32);
/*Reset internal state machine */
USBD_DCD_INT_fops->Reset(pdev);
return 1;
}
/**
* @brief DCD_HandleEnumDone_ISR
* Read the device status register and set the device speed
* @param pdev: device instance
* @retval status
*/
static uint32_t DCD_HandleEnumDone_ISR(USB_OTG_CORE_HANDLE *pdev)
{
USB_OTG_GINTSTS_TypeDef gintsts;
USB_OTG_GUSBCFG_TypeDef gusbcfg;
USB_OTG_EP0Activate(pdev);
/* Set USB turn-around time based on device speed and PHY interface. */
gusbcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GUSBCFG);
/* Full or High speed */
if ( USB_OTG_GetDeviceSpeed(pdev) == USB_SPEED_HIGH)
{
pdev->cfg.speed = USB_OTG_SPEED_HIGH;
pdev->cfg.mps = USB_OTG_HS_MAX_PACKET_SIZE ;
gusbcfg.b.usbtrdtim = 9;
}
else
{
pdev->cfg.speed = USB_OTG_SPEED_FULL;
pdev->cfg.mps = USB_OTG_FS_MAX_PACKET_SIZE ;
gusbcfg.b.usbtrdtim = 5;
}
USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GUSBCFG, gusbcfg.d32);
/* Clear interrupt */
gintsts.d32 = 0;
gintsts.b.enumdone = 1;
USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GINTSTS, gintsts.d32 );
return 1;
}
/**
* @brief DCD_IsoINIncomplete_ISR
* handle the ISO IN incomplete interrupt
* @param pdev: device instance
* @retval status
*/
static uint32_t DCD_IsoINIncomplete_ISR(USB_OTG_CORE_HANDLE *pdev)
{
USB_OTG_GINTSTS_TypeDef gintsts;
gintsts.d32 = 0;
USBD_DCD_INT_fops->IsoINIncomplete (pdev);
/* Clear interrupt */
gintsts.b.incomplisoin = 1;
USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32);
return 1;
}
/**
* @brief DCD_IsoOUTIncomplete_ISR
* handle the ISO OUT incomplete interrupt
* @param pdev: device instance
* @retval status
*/
static uint32_t DCD_IsoOUTIncomplete_ISR(USB_OTG_CORE_HANDLE *pdev)
{
USB_OTG_GINTSTS_TypeDef gintsts;
gintsts.d32 = 0;
USBD_DCD_INT_fops->IsoOUTIncomplete (pdev);
/* Clear interrupt */
gintsts.b.incomplisoout = 1;
USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32);
return 1;
}
/**
* @brief DCD_ReadDevInEP
* Reads ep flags
* @param pdev: device instance
* @retval status
*/
static uint32_t DCD_ReadDevInEP (USB_OTG_CORE_HANDLE *pdev, uint8_t epnum)
{
uint32_t v, msk, emp;
msk = USB_OTG_READ_REG32(&pdev->regs.DREGS->DIEPMSK);
emp = USB_OTG_READ_REG32(&pdev->regs.DREGS->DIEPEMPMSK);
msk |= ((emp >> epnum) & 0x1) << 7;
v = USB_OTG_READ_REG32(&pdev->regs.INEP_REGS[epnum]->DIEPINT) & msk;
return v;
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,262 @@
/**
******************************************************************************
* @file usb_hcd.c
* @author MCD Application Team
* @version V2.1.0
* @date 19-March-2012
* @brief Host Interface Layer
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "usb_core.h"
#include "usb_hcd.h"
#include "usb_conf.h"
#include "usb_bsp.h"
/** @addtogroup USB_OTG_DRIVER
* @{
*/
/** @defgroup USB_HCD
* @brief This file is the interface between EFSL ans Host mass-storage class
* @{
*/
/** @defgroup USB_HCD_Private_Defines
* @{
*/
/**
* @}
*/
/** @defgroup USB_HCD_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @defgroup USB_HCD_Private_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USB_HCD_Private_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USB_HCD_Private_FunctionPrototypes
* @{
*/
/**
* @}
*/
/** @defgroup USB_HCD_Private_Functions
* @{
*/
/**
* @brief HCD_Init
* Initialize the HOST portion of the driver.
* @param pdev: Selected device
* @param base_address: OTG base address
* @retval Status
*/
uint32_t HCD_Init(USB_OTG_CORE_HANDLE *pdev ,
USB_OTG_CORE_ID_TypeDef coreID)
{
uint8_t i = 0;
pdev->host.ConnSts = 0;
for (i= 0; i< USB_OTG_MAX_TX_FIFOS; i++)
{
pdev->host.ErrCnt[i] = 0;
pdev->host.XferCnt[i] = 0;
pdev->host.HC_Status[i] = HC_IDLE;
}
pdev->host.hc[0].max_packet = 8;
USB_OTG_SelectCore(pdev, coreID);
#ifndef DUAL_ROLE_MODE_ENABLED
USB_OTG_DisableGlobalInt(pdev);
USB_OTG_CoreInit(pdev);
/* Force Host Mode*/
USB_OTG_SetCurrentMode(pdev , HOST_MODE);
USB_OTG_CoreInitHost(pdev);
USB_OTG_EnableGlobalInt(pdev);
#endif
return 0;
}
/**
* @brief HCD_GetCurrentSpeed
* Get Current device Speed.
* @param pdev : Selected device
* @retval Status
*/
uint32_t HCD_GetCurrentSpeed (USB_OTG_CORE_HANDLE *pdev)
{
USB_OTG_HPRT0_TypeDef HPRT0;
HPRT0.d32 = USB_OTG_READ_REG32(pdev->regs.HPRT0);
return HPRT0.b.prtspd;
}
/**
* @brief HCD_ResetPort
* Issues the reset command to device
* @param pdev : Selected device
* @retval Status
*/
uint32_t HCD_ResetPort(USB_OTG_CORE_HANDLE *pdev)
{
/*
Before starting to drive a USB reset, the application waits for the OTG
interrupt triggered by the debounce done bit (DBCDNE bit in OTG_FS_GOTGINT),
which indicates that the bus is stable again after the electrical debounce
caused by the attachment of a pull-up resistor on DP (FS) or DM (LS).
*/
USB_OTG_ResetPort(pdev);
return 0;
}
/**
* @brief HCD_IsDeviceConnected
* Check if the device is connected.
* @param pdev : Selected device
* @retval Device connection status. 1 -> connected and 0 -> disconnected
*
*/
uint32_t HCD_IsDeviceConnected(USB_OTG_CORE_HANDLE *pdev)
{
return (pdev->host.ConnSts);
}
/**
* @brief HCD_GetCurrentFrame
* This function returns the frame number for sof packet
* @param pdev : Selected device
* @retval Frame number
*
*/
uint32_t HCD_GetCurrentFrame (USB_OTG_CORE_HANDLE *pdev)
{
return (USB_OTG_READ_REG32(&pdev->regs.HREGS->HFNUM) & 0xFFFF) ;
}
/**
* @brief HCD_GetURB_State
* This function returns the last URBstate
* @param pdev: Selected device
* @retval URB_STATE
*
*/
URB_STATE HCD_GetURB_State (USB_OTG_CORE_HANDLE *pdev , uint8_t ch_num)
{
return pdev->host.URB_State[ch_num] ;
}
/**
* @brief HCD_GetXferCnt
* This function returns the last URBstate
* @param pdev: Selected device
* @retval No. of data bytes transferred
*
*/
uint32_t HCD_GetXferCnt (USB_OTG_CORE_HANDLE *pdev, uint8_t ch_num)
{
return pdev->host.XferCnt[ch_num] ;
}
/**
* @brief HCD_GetHCState
* This function returns the HC Status
* @param pdev: Selected device
* @retval HC_STATUS
*
*/
HC_STATUS HCD_GetHCState (USB_OTG_CORE_HANDLE *pdev , uint8_t ch_num)
{
return pdev->host.HC_Status[ch_num] ;
}
/**
* @brief HCD_HC_Init
* This function prepare a HC and start a transfer
* @param pdev: Selected device
* @param hc_num: Channel number
* @retval status
*/
uint32_t HCD_HC_Init (USB_OTG_CORE_HANDLE *pdev , uint8_t hc_num)
{
return USB_OTG_HC_Init(pdev, hc_num);
}
/**
* @brief HCD_SubmitRequest
* This function prepare a HC and start a transfer
* @param pdev: Selected device
* @param hc_num: Channel number
* @retval status
*/
uint32_t HCD_SubmitRequest (USB_OTG_CORE_HANDLE *pdev , uint8_t hc_num)
{
pdev->host.URB_State[hc_num] = URB_IDLE;
pdev->host.hc[hc_num].xfer_count = 0 ;
return USB_OTG_HC_StartXfer(pdev, hc_num);
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,858 @@
/**
******************************************************************************
* @file usb_hcd_int.c
* @author MCD Application Team
* @version V2.1.0
* @date 19-March-2012
* @brief Host driver interrupt subroutines
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "usb_core.h"
#include "usb_defines.h"
#include "usb_hcd_int.h"
#if defined (__CC_ARM) /*!< ARM Compiler */
#pragma O0
#elif defined (__GNUC__) /*!< GNU Compiler */
#pragma GCC optimize ("O0")
#elif defined (__TASKING__) /*!< TASKING Compiler */
#pragma optimize=0
#endif /* __CC_ARM */
/** @addtogroup USB_OTG_DRIVER
* @{
*/
/** @defgroup USB_HCD_INT
* @brief This file contains the interrupt subroutines for the Host mode.
* @{
*/
/** @defgroup USB_HCD_INT_Private_Defines
* @{
*/
/**
* @}
*/
/** @defgroup USB_HCD_INT_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @defgroup USB_HCD_INT_Private_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USB_HCD_INT_Private_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USB_HCD_INT_Private_FunctionPrototypes
* @{
*/
static uint32_t USB_OTG_USBH_handle_sof_ISR(USB_OTG_CORE_HANDLE *pdev);
static uint32_t USB_OTG_USBH_handle_port_ISR(USB_OTG_CORE_HANDLE *pdev);
static uint32_t USB_OTG_USBH_handle_hc_ISR (USB_OTG_CORE_HANDLE *pdev);
static uint32_t USB_OTG_USBH_handle_hc_n_In_ISR (USB_OTG_CORE_HANDLE *pdev ,
uint32_t num);
static uint32_t USB_OTG_USBH_handle_hc_n_Out_ISR (USB_OTG_CORE_HANDLE *pdev ,
uint32_t num);
static uint32_t USB_OTG_USBH_handle_rx_qlvl_ISR (USB_OTG_CORE_HANDLE *pdev);
static uint32_t USB_OTG_USBH_handle_nptxfempty_ISR (USB_OTG_CORE_HANDLE *pdev);
static uint32_t USB_OTG_USBH_handle_ptxfempty_ISR (USB_OTG_CORE_HANDLE *pdev);
static uint32_t USB_OTG_USBH_handle_Disconnect_ISR (USB_OTG_CORE_HANDLE *pdev);
static uint32_t USB_OTG_USBH_handle_IncompletePeriodicXfer_ISR (USB_OTG_CORE_HANDLE *pdev);
/**
* @}
*/
/** @defgroup USB_HCD_INT_Private_Functions
* @{
*/
/**
* @brief HOST_Handle_ISR
* This function handles all USB Host Interrupts
* @param pdev: Selected device
* @retval status
*/
uint32_t USBH_OTG_ISR_Handler (USB_OTG_CORE_HANDLE *pdev)
{
USB_OTG_GINTSTS_TypeDef gintsts;
uint32_t retval = 0;
gintsts.d32 = 0;
/* Check if HOST Mode */
if (USB_OTG_IsHostMode(pdev))
{
gintsts.d32 = USB_OTG_ReadCoreItr(pdev);
if (!gintsts.d32)
{
return 0;
}
if (gintsts.b.sofintr)
{
retval |= USB_OTG_USBH_handle_sof_ISR (pdev);
}
if (gintsts.b.rxstsqlvl)
{
retval |= USB_OTG_USBH_handle_rx_qlvl_ISR (pdev);
}
if (gintsts.b.nptxfempty)
{
retval |= USB_OTG_USBH_handle_nptxfempty_ISR (pdev);
}
if (gintsts.b.ptxfempty)
{
retval |= USB_OTG_USBH_handle_ptxfempty_ISR (pdev);
}
if (gintsts.b.hcintr)
{
retval |= USB_OTG_USBH_handle_hc_ISR (pdev);
}
if (gintsts.b.portintr)
{
retval |= USB_OTG_USBH_handle_port_ISR (pdev);
}
if (gintsts.b.disconnect)
{
retval |= USB_OTG_USBH_handle_Disconnect_ISR (pdev);
}
if (gintsts.b.incomplisoout)
{
retval |= USB_OTG_USBH_handle_IncompletePeriodicXfer_ISR (pdev);
}
}
return retval;
}
/**
* @brief USB_OTG_USBH_handle_hc_ISR
* This function indicates that one or more host channels has a pending
* @param pdev: Selected device
* @retval status
*/
static uint32_t USB_OTG_USBH_handle_hc_ISR (USB_OTG_CORE_HANDLE *pdev)
{
USB_OTG_HAINT_TypeDef haint;
USB_OTG_HCCHAR_TypeDef hcchar;
uint32_t i = 0;
uint32_t retval = 0;
/* Clear appropriate bits in HCINTn to clear the interrupt bit in
* GINTSTS */
haint.d32 = USB_OTG_ReadHostAllChannels_intr(pdev);
for (i = 0; i < pdev->cfg.host_channels ; i++)
{
if (haint.b.chint & (1 << i))
{
hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[i]->HCCHAR);
if (hcchar.b.epdir)
{
retval |= USB_OTG_USBH_handle_hc_n_In_ISR (pdev, i);
}
else
{
retval |= USB_OTG_USBH_handle_hc_n_Out_ISR (pdev, i);
}
}
}
return retval;
}
/**
* @brief USB_OTG_otg_hcd_handle_sof_intr
* Handles the start-of-frame interrupt in host mode.
* @param pdev: Selected device
* @retval status
*/
static uint32_t USB_OTG_USBH_handle_sof_ISR (USB_OTG_CORE_HANDLE *pdev)
{
USB_OTG_GINTSTS_TypeDef gintsts;
gintsts.d32 = 0;
USBH_HCD_INT_fops->SOF(pdev);
/* Clear interrupt */
gintsts.b.sofintr = 1;
USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32);
return 1;
}
/**
* @brief USB_OTG_USBH_handle_Disconnect_ISR
* Handles disconnect event.
* @param pdev: Selected device
* @retval status
*/
static uint32_t USB_OTG_USBH_handle_Disconnect_ISR (USB_OTG_CORE_HANDLE *pdev)
{
USB_OTG_GINTSTS_TypeDef gintsts;
gintsts.d32 = 0;
USBH_HCD_INT_fops->DevDisconnected(pdev);
/* Clear interrupt */
gintsts.b.disconnect = 1;
USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32);
return 1;
}
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma optimize = none
#endif /* __CC_ARM */
/**
* @brief USB_OTG_USBH_handle_nptxfempty_ISR
* Handles non periodic tx fifo empty.
* @param pdev: Selected device
* @retval status
*/
static uint32_t USB_OTG_USBH_handle_nptxfempty_ISR (USB_OTG_CORE_HANDLE *pdev)
{
USB_OTG_GINTMSK_TypeDef intmsk;
USB_OTG_HNPTXSTS_TypeDef hnptxsts;
uint16_t len_words , len;
hnptxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->HNPTXSTS);
len_words = (pdev->host.hc[hnptxsts.b.nptxqtop.chnum].xfer_len + 3) / 4;
while ((hnptxsts.b.nptxfspcavail > len_words)&&
(pdev->host.hc[hnptxsts.b.nptxqtop.chnum].xfer_len != 0))
{
len = hnptxsts.b.nptxfspcavail * 4;
if (len > pdev->host.hc[hnptxsts.b.nptxqtop.chnum].xfer_len)
{
/* Last packet */
len = pdev->host.hc[hnptxsts.b.nptxqtop.chnum].xfer_len;
intmsk.d32 = 0;
intmsk.b.nptxfempty = 1;
USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, intmsk.d32, 0);
}
len_words = (pdev->host.hc[hnptxsts.b.nptxqtop.chnum].xfer_len + 3) / 4;
USB_OTG_WritePacket (pdev , pdev->host.hc[hnptxsts.b.nptxqtop.chnum].xfer_buff, hnptxsts.b.nptxqtop.chnum, len);
pdev->host.hc[hnptxsts.b.nptxqtop.chnum].xfer_buff += len;
pdev->host.hc[hnptxsts.b.nptxqtop.chnum].xfer_len -= len;
pdev->host.hc[hnptxsts.b.nptxqtop.chnum].xfer_count += len;
hnptxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->HNPTXSTS);
}
return 1;
}
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma optimize = none
#endif /* __CC_ARM */
/**
* @brief USB_OTG_USBH_handle_ptxfempty_ISR
* Handles periodic tx fifo empty
* @param pdev: Selected device
* @retval status
*/
static uint32_t USB_OTG_USBH_handle_ptxfempty_ISR (USB_OTG_CORE_HANDLE *pdev)
{
USB_OTG_GINTMSK_TypeDef intmsk;
USB_OTG_HPTXSTS_TypeDef hptxsts;
uint16_t len_words , len;
hptxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.HREGS->HPTXSTS);
len_words = (pdev->host.hc[hptxsts.b.ptxqtop.chnum].xfer_len + 3) / 4;
while ((hptxsts.b.ptxfspcavail > len_words)&&
(pdev->host.hc[hptxsts.b.ptxqtop.chnum].xfer_len != 0))
{
len = hptxsts.b.ptxfspcavail * 4;
if (len > pdev->host.hc[hptxsts.b.ptxqtop.chnum].xfer_len)
{
len = pdev->host.hc[hptxsts.b.ptxqtop.chnum].xfer_len;
/* Last packet */
intmsk.d32 = 0;
intmsk.b.ptxfempty = 1;
USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, intmsk.d32, 0);
}
len_words = (pdev->host.hc[hptxsts.b.ptxqtop.chnum].xfer_len + 3) / 4;
USB_OTG_WritePacket (pdev , pdev->host.hc[hptxsts.b.ptxqtop.chnum].xfer_buff, hptxsts.b.ptxqtop.chnum, len);
pdev->host.hc[hptxsts.b.ptxqtop.chnum].xfer_buff += len;
pdev->host.hc[hptxsts.b.ptxqtop.chnum].xfer_len -= len;
pdev->host.hc[hptxsts.b.ptxqtop.chnum].xfer_count += len;
hptxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.HREGS->HPTXSTS);
}
return 1;
}
/**
* @brief USB_OTG_USBH_handle_port_ISR
* This function determines which interrupt conditions have occurred
* @param pdev: Selected device
* @retval status
*/
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma optimize = none
#endif /* __CC_ARM */
static uint32_t USB_OTG_USBH_handle_port_ISR (USB_OTG_CORE_HANDLE *pdev)
{
USB_OTG_HPRT0_TypeDef hprt0;
USB_OTG_HPRT0_TypeDef hprt0_dup;
USB_OTG_HCFG_TypeDef hcfg;
uint32_t do_reset = 0;
uint32_t retval = 0;
hcfg.d32 = 0;
hprt0.d32 = 0;
hprt0_dup.d32 = 0;
hprt0.d32 = USB_OTG_READ_REG32(pdev->regs.HPRT0);
hprt0_dup.d32 = USB_OTG_READ_REG32(pdev->regs.HPRT0);
/* Clear the interrupt bits in GINTSTS */
hprt0_dup.b.prtena = 0;
hprt0_dup.b.prtconndet = 0;
hprt0_dup.b.prtenchng = 0;
hprt0_dup.b.prtovrcurrchng = 0;
/* Port Connect Detected */
if (hprt0.b.prtconndet)
{
hprt0_dup.b.prtconndet = 1;
USBH_HCD_INT_fops->DevConnected(pdev);
retval |= 1;
}
/* Port Enable Changed */
if (hprt0.b.prtenchng)
{
hprt0_dup.b.prtenchng = 1;
if (hprt0.b.prtena == 1)
{
USBH_HCD_INT_fops->DevConnected(pdev);
if ((hprt0.b.prtspd == HPRT0_PRTSPD_LOW_SPEED) ||
(hprt0.b.prtspd == HPRT0_PRTSPD_FULL_SPEED))
{
hcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.HREGS->HCFG);
if (hprt0.b.prtspd == HPRT0_PRTSPD_LOW_SPEED)
{
USB_OTG_WRITE_REG32(&pdev->regs.HREGS->HFIR, 6000 );
if (hcfg.b.fslspclksel != HCFG_6_MHZ)
{
if(pdev->cfg.phy_itface == USB_OTG_EMBEDDED_PHY)
{
USB_OTG_InitFSLSPClkSel(pdev ,HCFG_6_MHZ );
}
do_reset = 1;
}
}
else
{
USB_OTG_WRITE_REG32(&pdev->regs.HREGS->HFIR, 48000 );
if (hcfg.b.fslspclksel != HCFG_48_MHZ)
{
USB_OTG_InitFSLSPClkSel(pdev ,HCFG_48_MHZ );
do_reset = 1;
}
}
}
else
{
do_reset = 1;
}
}
}
/* Overcurrent Change Interrupt */
if (hprt0.b.prtovrcurrchng)
{
hprt0_dup.b.prtovrcurrchng = 1;
retval |= 1;
}
if (do_reset)
{
USB_OTG_ResetPort(pdev);
}
/* Clear Port Interrupts */
USB_OTG_WRITE_REG32(pdev->regs.HPRT0, hprt0_dup.d32);
return retval;
}
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma optimize = none
#endif /* __CC_ARM */
/**
* @brief USB_OTG_USBH_handle_hc_n_Out_ISR
* Handles interrupt for a specific Host Channel
* @param pdev: Selected device
* @param hc_num: Channel number
* @retval status
*/
uint32_t USB_OTG_USBH_handle_hc_n_Out_ISR (USB_OTG_CORE_HANDLE *pdev , uint32_t num)
{
USB_OTG_HCINTn_TypeDef hcint;
USB_OTG_HCINTMSK_TypeDef hcintmsk;
USB_OTG_HC_REGS *hcreg;
USB_OTG_HCCHAR_TypeDef hcchar;
hcreg = pdev->regs.HC_REGS[num];
hcint.d32 = USB_OTG_READ_REG32(&hcreg->HCINT);
hcintmsk.d32 = USB_OTG_READ_REG32(&hcreg->HCINTMSK);
hcint.d32 = hcint.d32 & hcintmsk.d32;
hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[num]->HCCHAR);
if (hcint.b.ahberr)
{
CLEAR_HC_INT(hcreg ,ahberr);
UNMASK_HOST_INT_CHH (num);
}
else if (hcint.b.ack)
{
CLEAR_HC_INT(hcreg , ack);
}
else if (hcint.b.frmovrun)
{
UNMASK_HOST_INT_CHH (num);
USB_OTG_HC_Halt(pdev, num);
CLEAR_HC_INT(hcreg ,frmovrun);
}
else if (hcint.b.xfercompl)
{
pdev->host.ErrCnt[num] = 0;
UNMASK_HOST_INT_CHH (num);
USB_OTG_HC_Halt(pdev, num);
CLEAR_HC_INT(hcreg , xfercompl);
pdev->host.HC_Status[num] = HC_XFRC;
}
else if (hcint.b.stall)
{
CLEAR_HC_INT(hcreg , stall);
UNMASK_HOST_INT_CHH (num);
USB_OTG_HC_Halt(pdev, num);
pdev->host.HC_Status[num] = HC_STALL;
}
else if (hcint.b.nak)
{
pdev->host.ErrCnt[num] = 0;
UNMASK_HOST_INT_CHH (num);
USB_OTG_HC_Halt(pdev, num);
CLEAR_HC_INT(hcreg , nak);
pdev->host.HC_Status[num] = HC_NAK;
}
else if (hcint.b.xacterr)
{
UNMASK_HOST_INT_CHH (num);
USB_OTG_HC_Halt(pdev, num);
pdev->host.ErrCnt[num] ++;
pdev->host.HC_Status[num] = HC_XACTERR;
CLEAR_HC_INT(hcreg , xacterr);
}
else if (hcint.b.nyet)
{
pdev->host.ErrCnt[num] = 0;
UNMASK_HOST_INT_CHH (num);
USB_OTG_HC_Halt(pdev, num);
CLEAR_HC_INT(hcreg , nyet);
pdev->host.HC_Status[num] = HC_NYET;
}
else if (hcint.b.datatglerr)
{
UNMASK_HOST_INT_CHH (num);
USB_OTG_HC_Halt(pdev, num);
CLEAR_HC_INT(hcreg , nak);
pdev->host.HC_Status[num] = HC_DATATGLERR;
CLEAR_HC_INT(hcreg , datatglerr);
}
else if (hcint.b.chhltd)
{
MASK_HOST_INT_CHH (num);
if(pdev->host.HC_Status[num] == HC_XFRC)
{
pdev->host.URB_State[num] = URB_DONE;
if (hcchar.b.eptype == EP_TYPE_BULK)
{
pdev->host.hc[num].toggle_out ^= 1;
}
}
else if(pdev->host.HC_Status[num] == HC_NAK)
{
pdev->host.URB_State[num] = URB_NOTREADY;
}
else if(pdev->host.HC_Status[num] == HC_NYET)
{
if(pdev->host.hc[num].do_ping == 1)
{
USB_OTG_HC_DoPing(pdev, num);
}
pdev->host.URB_State[num] = URB_NOTREADY;
}
else if(pdev->host.HC_Status[num] == HC_STALL)
{
pdev->host.URB_State[num] = URB_STALL;
}
else if(pdev->host.HC_Status[num] == HC_XACTERR)
{
if (pdev->host.ErrCnt[num] == 3)
{
pdev->host.URB_State[num] = URB_ERROR;
pdev->host.ErrCnt[num] = 0;
}
}
CLEAR_HC_INT(hcreg , chhltd);
}
return 1;
}
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma optimize = none
#endif /* __CC_ARM */
/**
* @brief USB_OTG_USBH_handle_hc_n_In_ISR
* Handles interrupt for a specific Host Channel
* @param pdev: Selected device
* @param hc_num: Channel number
* @retval status
*/
uint32_t USB_OTG_USBH_handle_hc_n_In_ISR (USB_OTG_CORE_HANDLE *pdev , uint32_t num)
{
USB_OTG_HCINTn_TypeDef hcint;
USB_OTG_HCINTMSK_TypeDef hcintmsk;
USB_OTG_HCCHAR_TypeDef hcchar;
USB_OTG_HCTSIZn_TypeDef hctsiz;
USB_OTG_HC_REGS *hcreg;
hcreg = pdev->regs.HC_REGS[num];
hcint.d32 = USB_OTG_READ_REG32(&hcreg->HCINT);
hcintmsk.d32 = USB_OTG_READ_REG32(&hcreg->HCINTMSK);
hcint.d32 = hcint.d32 & hcintmsk.d32;
hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[num]->HCCHAR);
hcintmsk.d32 = 0;
if (hcint.b.ahberr)
{
CLEAR_HC_INT(hcreg ,ahberr);
UNMASK_HOST_INT_CHH (num);
}
else if (hcint.b.ack)
{
CLEAR_HC_INT(hcreg ,ack);
}
else if (hcint.b.stall)
{
UNMASK_HOST_INT_CHH (num);
pdev->host.HC_Status[num] = HC_STALL;
CLEAR_HC_INT(hcreg , nak); /* Clear the NAK Condition */
CLEAR_HC_INT(hcreg , stall); /* Clear the STALL Condition */
hcint.b.nak = 0; /* NOTE: When there is a 'stall', reset also nak,
else, the pdev->host.HC_Status = HC_STALL
will be overwritten by 'nak' in code below */
USB_OTG_HC_Halt(pdev, num);
}
else if (hcint.b.datatglerr)
{
UNMASK_HOST_INT_CHH (num);
USB_OTG_HC_Halt(pdev, num);
CLEAR_HC_INT(hcreg , nak);
pdev->host.HC_Status[num] = HC_DATATGLERR;
CLEAR_HC_INT(hcreg , datatglerr);
}
if (hcint.b.frmovrun)
{
UNMASK_HOST_INT_CHH (num);
USB_OTG_HC_Halt(pdev, num);
CLEAR_HC_INT(hcreg ,frmovrun);
}
else if (hcint.b.xfercompl)
{
if (pdev->cfg.dma_enable == 1)
{
hctsiz.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[num]->HCTSIZ);
pdev->host.XferCnt[num] = pdev->host.hc[num].xfer_len - hctsiz.b.xfersize;
}
pdev->host.HC_Status[num] = HC_XFRC;
pdev->host.ErrCnt [num]= 0;
CLEAR_HC_INT(hcreg , xfercompl);
if ((hcchar.b.eptype == EP_TYPE_CTRL)||
(hcchar.b.eptype == EP_TYPE_BULK))
{
UNMASK_HOST_INT_CHH (num);
USB_OTG_HC_Halt(pdev, num);
CLEAR_HC_INT(hcreg , nak);
pdev->host.hc[num].toggle_in ^= 1;
}
else if(hcchar.b.eptype == EP_TYPE_INTR)
{
hcchar.b.oddfrm = 1;
USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[num]->HCCHAR, hcchar.d32);
pdev->host.URB_State[num] = URB_DONE;
}
}
else if (hcint.b.chhltd)
{
MASK_HOST_INT_CHH (num);
if(pdev->host.HC_Status[num] == HC_XFRC)
{
pdev->host.URB_State[num] = URB_DONE;
}
else if (pdev->host.HC_Status[num] == HC_STALL)
{
pdev->host.URB_State[num] = URB_STALL;
}
else if((pdev->host.HC_Status[num] == HC_XACTERR) ||
(pdev->host.HC_Status[num] == HC_DATATGLERR))
{
pdev->host.ErrCnt[num] = 0;
pdev->host.URB_State[num] = URB_ERROR;
}
else if(hcchar.b.eptype == EP_TYPE_INTR)
{
pdev->host.hc[num].toggle_in ^= 1;
}
CLEAR_HC_INT(hcreg , chhltd);
}
else if (hcint.b.xacterr)
{
UNMASK_HOST_INT_CHH (num);
pdev->host.ErrCnt[num] ++;
pdev->host.HC_Status[num] = HC_XACTERR;
USB_OTG_HC_Halt(pdev, num);
CLEAR_HC_INT(hcreg , xacterr);
}
else if (hcint.b.nak)
{
if(hcchar.b.eptype == EP_TYPE_INTR)
{
UNMASK_HOST_INT_CHH (num);
USB_OTG_HC_Halt(pdev, num);
}
else if ((hcchar.b.eptype == EP_TYPE_CTRL)||
(hcchar.b.eptype == EP_TYPE_BULK))
{
/* re-activate the channel */
hcchar.b.chen = 1;
hcchar.b.chdis = 0;
USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[num]->HCCHAR, hcchar.d32);
}
pdev->host.HC_Status[num] = HC_NAK;
CLEAR_HC_INT(hcreg , nak);
}
return 1;
}
/**
* @brief USB_OTG_USBH_handle_rx_qlvl_ISR
* Handles the Rx Status Queue Level Interrupt
* @param pdev: Selected device
* @retval status
*/
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma optimize = none
#endif /* __CC_ARM */
static uint32_t USB_OTG_USBH_handle_rx_qlvl_ISR (USB_OTG_CORE_HANDLE *pdev)
{
USB_OTG_GRXFSTS_TypeDef grxsts;
USB_OTG_GINTMSK_TypeDef intmsk;
USB_OTG_HCTSIZn_TypeDef hctsiz;
USB_OTG_HCCHAR_TypeDef hcchar;
__IO uint8_t channelnum =0;
uint32_t count;
/* Disable the Rx Status Queue Level interrupt */
intmsk.d32 = 0;
intmsk.b.rxstsqlvl = 1;
USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, intmsk.d32, 0);
grxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GRXSTSP);
channelnum = grxsts.b.chnum;
hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[channelnum]->HCCHAR);
switch (grxsts.b.pktsts)
{
case GRXSTS_PKTSTS_IN:
/* Read the data into the host buffer. */
if ((grxsts.b.bcnt > 0) && (pdev->host.hc[channelnum].xfer_buff != (void *)0))
{
USB_OTG_ReadPacket(pdev, pdev->host.hc[channelnum].xfer_buff, grxsts.b.bcnt);
/*manage multiple Xfer */
pdev->host.hc[grxsts.b.chnum].xfer_buff += grxsts.b.bcnt;
pdev->host.hc[grxsts.b.chnum].xfer_count += grxsts.b.bcnt;
count = pdev->host.hc[channelnum].xfer_count;
pdev->host.XferCnt[channelnum] = count;
hctsiz.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[channelnum]->HCTSIZ);
if(hctsiz.b.pktcnt > 0)
{
/* re-activate the channel when more packets are expected */
hcchar.b.chen = 1;
hcchar.b.chdis = 0;
USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[channelnum]->HCCHAR, hcchar.d32);
}
}
break;
case GRXSTS_PKTSTS_IN_XFER_COMP:
case GRXSTS_PKTSTS_DATA_TOGGLE_ERR:
case GRXSTS_PKTSTS_CH_HALTED:
default:
break;
}
/* Enable the Rx Status Queue Level interrupt */
intmsk.b.rxstsqlvl = 1;
USB_OTG_MODIFY_REG32(&pdev->regs.GREGS->GINTMSK, 0, intmsk.d32);
return 1;
}
/**
* @brief USB_OTG_USBH_handle_IncompletePeriodicXfer_ISR
* Handles the incomplete Periodic transfer Interrupt
* @param pdev: Selected device
* @retval status
*/
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma optimize = none
#endif /* __CC_ARM */
static uint32_t USB_OTG_USBH_handle_IncompletePeriodicXfer_ISR (USB_OTG_CORE_HANDLE *pdev)
{
USB_OTG_GINTSTS_TypeDef gintsts;
USB_OTG_HCCHAR_TypeDef hcchar;
hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[0]->HCCHAR);
hcchar.b.chen = 1;
hcchar.b.chdis = 1;
USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[0]->HCCHAR, hcchar.d32);
gintsts.d32 = 0;
/* Clear interrupt */
gintsts.b.incomplisoout = 1;
USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32);
return 1;
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,418 @@
/**
******************************************************************************
* @file usb_otg.c
* @author MCD Application Team
* @version V2.1.0
* @date 19-March-2012
* @brief OTG Core Layer
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "usb_defines.h"
#include "usb_regs.h"
#include "usb_core.h"
#include "usb_otg.h"
/** @addtogroup USB_OTG_DRIVER
* @{
*/
/** @defgroup USB_OTG
* @brief This file is the interface between EFSL ans Host mass-storage class
* @{
*/
/** @defgroup USB_OTG_Private_Defines
* @{
*/
/**
* @}
*/
/** @defgroup USB_OTG_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @defgroup USB_OTG_Private_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USB_OTG_Private_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USB_OTG_Private_FunctionPrototypes
* @{
*/
uint32_t USB_OTG_HandleOTG_ISR(USB_OTG_CORE_HANDLE *pdev);
static uint32_t USB_OTG_HandleConnectorIDStatusChange_ISR(USB_OTG_CORE_HANDLE *pdev);
static uint32_t USB_OTG_HandleSessionRequest_ISR(USB_OTG_CORE_HANDLE *pdev);
static uint32_t USB_OTG_Read_itr(USB_OTG_CORE_HANDLE *pdev);
/**
* @}
*/
/** @defgroup USB_OTG_Private_Functions
* @{
*/
/* OTG Interrupt Handler */
/**
* @brief STM32_USBO_OTG_ISR_Handler
*
* @param None
* @retval : None
*/
uint32_t STM32_USBO_OTG_ISR_Handler(USB_OTG_CORE_HANDLE *pdev)
{
uint32_t retval = 0;
USB_OTG_GINTSTS_TypeDef gintsts ;
gintsts.d32 = 0;
gintsts.d32 = USB_OTG_Read_itr(pdev);
if (gintsts.d32 == 0)
{
return 0;
}
if (gintsts.b.otgintr)
{
retval |= USB_OTG_HandleOTG_ISR(pdev);
}
if (gintsts.b.conidstschng)
{
retval |= USB_OTG_HandleConnectorIDStatusChange_ISR(pdev);
}
if (gintsts.b.sessreqintr)
{
retval |= USB_OTG_HandleSessionRequest_ISR(pdev);
}
return retval;
}
/**
* @brief USB_OTG_Read_itr
* returns the Core Interrupt register
* @param None
* @retval : status
*/
static uint32_t USB_OTG_Read_itr(USB_OTG_CORE_HANDLE *pdev)
{
USB_OTG_GINTSTS_TypeDef gintsts;
USB_OTG_GINTMSK_TypeDef gintmsk;
USB_OTG_GINTMSK_TypeDef gintmsk_common;
gintsts.d32 = 0;
gintmsk.d32 = 0;
gintmsk_common.d32 = 0;
/* OTG interrupts */
gintmsk_common.b.sessreqintr = 1;
gintmsk_common.b.conidstschng = 1;
gintmsk_common.b.otgintr = 1;
gintsts.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GINTSTS);
gintmsk.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GINTMSK);
return ((gintsts.d32 & gintmsk.d32 ) & gintmsk_common.d32);
}
/**
* @brief USB_OTG_HandleOTG_ISR
* handles the OTG Interrupts
* @param None
* @retval : status
*/
static uint32_t USB_OTG_HandleOTG_ISR(USB_OTG_CORE_HANDLE *pdev)
{
USB_OTG_GOTGINT_TypeDef gotgint;
USB_OTG_GOTGCTL_TypeDef gotgctl;
gotgint.d32 = 0;
gotgctl.d32 = 0;
gotgint.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GOTGINT);
gotgctl.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GOTGCTL);
if (gotgint.b.sesenddet)
{
gotgctl.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GOTGCTL);
if (USB_OTG_IsDeviceMode(pdev))
{
}
else if (USB_OTG_IsHostMode(pdev))
{
}
}
/* ----> SRP SUCCESS or FAILURE INTERRUPT <---- */
if (gotgint.b.sesreqsucstschng)
{
gotgctl.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GOTGCTL);
if (gotgctl.b.sesreqscs) /* Session request success */
{
if (USB_OTG_IsDeviceMode(pdev))
{
}
/* Clear Session Request */
gotgctl.d32 = 0;
gotgctl.b.sesreq = 1;
USB_OTG_MODIFY_REG32(&pdev->regs.GREGS->GOTGCTL, gotgctl.d32, 0);
}
else /* Session request failure */
{
if (USB_OTG_IsDeviceMode(pdev))
{
}
}
}
/* ----> HNP SUCCESS or FAILURE INTERRUPT <---- */
if (gotgint.b.hstnegsucstschng)
{
gotgctl.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GOTGCTL);
if (gotgctl.b.hstnegscs) /* Host negotiation success */
{
if (USB_OTG_IsHostMode(pdev)) /* The core AUTOMATICALLY sets the Host mode */
{
}
}
else /* Host negotiation failure */
{
}
gotgint.b.hstnegsucstschng = 1; /* Ack "Host Negotiation Success Status Change" interrupt. */
}
/* ----> HOST NEGOTIATION DETECTED INTERRUPT <---- */
if (gotgint.b.hstnegdet)
{
if (USB_OTG_IsDeviceMode(pdev)) /* The core AUTOMATICALLY sets the Host mode */
{
}
else
{
}
}
if (gotgint.b.adevtoutchng)
{}
if (gotgint.b.debdone)
{
USB_OTG_ResetPort(pdev);
}
/* Clear OTG INT */
USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GOTGINT, gotgint.d32);
return 1;
}
/**
* @brief USB_OTG_HandleConnectorIDStatusChange_ISR
* handles the Connector ID Status Change Interrupt
* @param None
* @retval : status
*/
static uint32_t USB_OTG_HandleConnectorIDStatusChange_ISR(USB_OTG_CORE_HANDLE *pdev)
{
USB_OTG_GINTMSK_TypeDef gintmsk;
USB_OTG_GOTGCTL_TypeDef gotgctl;
USB_OTG_GINTSTS_TypeDef gintsts;
gintsts.d32 = 0 ;
gintmsk.d32 = 0 ;
gotgctl.d32 = 0 ;
gintmsk.b.sofintr = 1;
USB_OTG_MODIFY_REG32(&pdev->regs.GREGS->GINTMSK, gintmsk.d32, 0);
gotgctl.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GOTGCTL);
/* B-Device connector (Device Mode) */
if (gotgctl.b.conidsts)
{
USB_OTG_DisableGlobalInt(pdev);
USB_OTG_CoreInitDev(pdev);
USB_OTG_EnableGlobalInt(pdev);
pdev->otg.OTG_State = B_PERIPHERAL;
}
else
{
USB_OTG_DisableGlobalInt(pdev);
USB_OTG_CoreInitHost(pdev);
USB_OTG_EnableGlobalInt(pdev);
pdev->otg.OTG_State = A_HOST;
}
/* Set flag and clear interrupt */
gintsts.b.conidstschng = 1;
USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GINTSTS, gintsts.d32);
return 1;
}
/**
* @brief USB_OTG_HandleSessionRequest_ISR
* Initiating the Session Request Protocol
* @param None
* @retval : status
*/
static uint32_t USB_OTG_HandleSessionRequest_ISR(USB_OTG_CORE_HANDLE *pdev)
{
USB_OTG_GINTSTS_TypeDef gintsts;
USB_OTG_GOTGCTL_TypeDef gotgctl;
gotgctl.d32 = 0;
gintsts.d32 = 0;
gotgctl.d32 = USB_OTG_READ_REG32( &pdev->regs.GREGS->GOTGCTL );
if (USB_OTG_IsDeviceMode(pdev) && (gotgctl.b.bsesvld))
{
}
else if (gotgctl.b.asesvld)
{
}
/* Clear interrupt */
gintsts.d32 = 0;
gintsts.b.sessreqintr = 1;
USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GINTSTS, gintsts.d32);
return 1;
}
/**
* @brief USB_OTG_InitiateSRP
* Initiate an srp session
* @param None
* @retval : None
*/
void USB_OTG_InitiateSRP(USB_OTG_CORE_HANDLE *pdev)
{
USB_OTG_GOTGCTL_TypeDef otgctl;
otgctl.d32 = 0;
otgctl.d32 = USB_OTG_READ_REG32( &pdev->regs.GREGS->GOTGCTL );
if (otgctl.b.sesreq)
{
return; /* SRP in progress */
}
otgctl.b.sesreq = 1;
USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GOTGCTL, otgctl.d32);
}
/**
* @brief USB_OTG_InitiateHNP
* Initiate HNP
* @param None
* @retval : None
*/
void USB_OTG_InitiateHNP(USB_OTG_CORE_HANDLE *pdev , uint8_t state, uint8_t mode)
{
USB_OTG_GOTGCTL_TypeDef otgctl;
USB_OTG_HPRT0_TypeDef hprt0;
otgctl.d32 = 0;
hprt0.d32 = 0;
otgctl.d32 = USB_OTG_READ_REG32( &pdev->regs.GREGS->GOTGCTL );
if (mode)
{ /* Device mode */
if (state)
{
otgctl.b.devhnpen = 1; /* B-Dev has been enabled to perform HNP */
otgctl.b.hnpreq = 1; /* Initiate an HNP req. to the connected USB host*/
USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GOTGCTL, otgctl.d32);
}
}
else
{ /* Host mode */
if (state)
{
otgctl.b.hstsethnpen = 1; /* A-Dev has enabled B-device for HNP */
USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GOTGCTL, otgctl.d32);
/* Suspend the bus so that B-dev will disconnect indicating the initial condition for HNP to DWC_Core */
hprt0.d32 = USB_OTG_ReadHPRT0(pdev);
hprt0.b.prtsusp = 1; /* The core clear this bit when disconnect interrupt generated (GINTSTS.DisconnInt = '1') */
USB_OTG_WRITE_REG32(pdev->regs.HPRT0, hprt0.d32);
}
}
}
/**
* @brief USB_OTG_GetCurrentState
* Return current OTG State
* @param None
* @retval : None
*/
uint32_t USB_OTG_GetCurrentState (USB_OTG_CORE_HANDLE *pdev)
{
return pdev->otg.OTG_State;
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/