stm: USB host mode working! Restructure stm library directories.

pull/228/head
Damien George 2014-01-26 17:41:01 +00:00
rodzic 8fcf7b858d
commit 75abee206d
109 zmienionych plików z 7499 dodań i 112 usunięć

Wyświetl plik

@ -6,18 +6,23 @@ QSTR_DEFS = qstrdefsport.h
# include py core make definitions
include ../py/py.mk
CMSIS=cmsis
STMSRC=lib
#STMOTGSRC=usbhost
FATFSSRC=fatfs
CC3KSRC=cc3k
CMSIS_DIR=cmsis
STMPERIPH_DIR=stmperiph
STMUSB_DIR=stmusb
STMUSBD_DIR=stmusbd
STMUSBH_DIR=stmusbh
FATFS_DIR=fatfs
CC3K_DIR=cc3k
DFU=../tools/dfu.py
CROSS_COMPILE = arm-none-eabi-
CFLAGS_CORTEX_M4 = -mthumb -mtune=cortex-m4 -mabi=aapcs-linux -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -fsingle-precision-constant -Wdouble-promotion
CFLAGS = -I. -I$(PY_SRC) -I$(FATFSSRC) -I$(CMSIS) -I$(STMSRC) -Wall -ansi -std=gnu99 $(CFLAGS_CORTEX_M4)
#CFLAGS += -I$(STMOTGSRC) -DUSE_HOST_MODE #-DUSE_OTG_MODE
CFLAGS = -I. -I$(PY_SRC) -I$(CMSIS_DIR) -I$(STMPERIPH_DIR) -I$(STMUSB_DIR) -Wall -ansi -std=gnu99 $(CFLAGS_CORTEX_M4)
CFLAGS += -I$(STMUSBD_DIR)
CFLAGS += -I$(STMUSBH_DIR)
CFLAGS += -I$(FATFS_DIR)
#CFLAGS += -I$(CC3K_DIR)
#Debugging/Optimization
ifeq ($(DEBUG), 1)
@ -64,15 +69,10 @@ SRC_S = \
startup_stm32f40xx.s \
gchelper.s \
SRC_FATFS = $(addprefix $(FATFSSRC)/,\
ff.c \
diskio.c \
)
SRC_STM = $(addprefix $(STMSRC)/,\
SRC_STMPERIPH = $(addprefix $(STMPERIPH_DIR)/,\
stm_misc.c \
stm32f4xx_rcc.c \
stm32f4xx_syscfg.c \
stm_misc.c \
stm32f4xx_flash.c \
stm32f4xx_dma.c \
stm32f4xx_gpio.c \
@ -89,10 +89,19 @@ SRC_STM = $(addprefix $(STMSRC)/,\
stm32f4xx_adc.c \
stm324x7i_eval.c \
stm324x7i_eval_sdio_sd.c \
)
SRC_STMUSB = $(addprefix $(STMUSB_DIR)/,\
usb_core.c \
usb_bsp.c \
usb_dcd.c \
usb_dcd_int.c \
usb_hcd.c \
usb_hcd_int.c \
)
# usb_otg.c \
SRC_STMUSBD = $(addprefix $(STMUSBD_DIR)/,\
usbd_core.c \
usbd_ioreq.c \
usbd_req.c \
@ -107,9 +116,7 @@ SRC_STM = $(addprefix $(STMSRC)/,\
usbd_storage_msd.c \
)
#SRC_STM_OTG = $(addprefix $(STMSRC)/,\
usb_hcd.c \
usb_hcd_int.c \
SRC_STMUSBH = $(addprefix $(STMUSBH_DIR)/,\
usbh_core.c \
usbh_hcs.c \
usbh_stdreq.c \
@ -118,10 +125,14 @@ SRC_STM = $(addprefix $(STMSRC)/,\
usbh_hid_core.c \
usbh_hid_mouse.c \
usbh_hid_keybd.c \
# usb_otg.c \
)
SRC_CC3K = $(addprefix $(CC3KSRC)/,\
SRC_FATFS = $(addprefix $(FATFS_DIR)/,\
ff.c \
diskio.c \
)
SRC_CC3K = $(addprefix $(CC3K_DIR)/,\
cc3000_common.c \
evnt_handler.c \
hci.c \
@ -134,8 +145,11 @@ SRC_CC3K = $(addprefix $(CC3KSRC)/,\
pybcc3k.c \
)
OBJ = $(PY_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o) $(SRC_S:.s=.o) $(SRC_FATFS:.c=.o) $(SRC_STM:.c=.o)) # $(SRC_CC3K:.c=.o))
#OBJ += $(addprefix $(BUILD)/, $(SRC_STM_OTG:.c=.o))
OBJ = $(PY_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o) $(SRC_S:.s=.o) $(SRC_STMPERIPH:.c=.o) $(SRC_STMUSB:.c=.o))
OBJ += $(addprefix $(BUILD)/, $(SRC_STMUSBD:.c=.o))
#OBJ += $(addprefix $(BUILD)/, $(SRC_STMUSBH:.c=.o))
OBJ += $(addprefix $(BUILD)/, $(SRC_FATFS:.c=.o))
#OBJ += $(addprefix $(BUILD)/, $(SRC_CC3K:.c=.o))
all: $(BUILD) $(BUILD)/flash.dfu
@ -155,4 +169,3 @@ $(BUILD)/flash.elf: $(OBJ)
$(Q)$(SIZE) $@
include ../py/mkrules.mk

Wyświetl plik

@ -324,6 +324,12 @@ void lcd_print_strn(const char *str, unsigned int len) {
}
if (*str == '\n') {
lcd_next_line = 1;
} else if (*str == '\r') {
lcd_column = 0;
} else if (*str == '\b') {
if (lcd_column > 0) {
lcd_column--;
}
} else if (lcd_column >= LCD_BUF_W) {
lcd_next_line = 1;
str -= 1;
@ -359,6 +365,6 @@ void lcd_print_strn(const char *str, unsigned int len) {
}
if (did_new_line) {
sys_tick_delay_ms(200);
sys_tick_delay_ms(50);
}
}

Wyświetl plik

@ -274,6 +274,9 @@ void stdout_tx_str(const char *str) {
if (pyb_usart_global_debug != PYB_USART_NONE) {
usart_tx_str(pyb_usart_global_debug, str);
}
#if defined(USE_HOST_MODE) && MICROPY_HW_HAS_LCD
lcd_print_str(str);
#endif
usb_vcp_send_str(str);
}
@ -285,6 +288,13 @@ int readline(vstr_t *line, const char *prompt) {
for (;;) {
char c;
for (;;) {
#ifdef USE_HOST_MODE
pyb_usb_host_process();
c = pyb_usb_host_get_keyboard();
if (c != 0) {
break;
}
#endif
if (usb_vcp_rx_any() != 0) {
c = usb_vcp_rx_get();
break;
@ -350,6 +360,12 @@ int readline(vstr_t *line, const char *prompt) {
}
void do_repl(void) {
#if defined(USE_HOST_MODE) && MICROPY_HW_HAS_LCD
// in host mode, we enable the LCD for the repl
mp_obj_t lcd_o = rt_call_function_0(rt_load_name(qstr_from_str("LCD")));
rt_call_function_1(rt_load_attr(lcd_o, qstr_from_str("light")), mp_const_true);
#endif
stdout_tx_str("Micro Python build <git hash> on 25/1/2014; " MICROPY_HW_BOARD_NAME " with STM32F405RG\r\n");
stdout_tx_str("Type \"help()\" for more information.\r\n");
@ -532,11 +548,7 @@ int main(void) {
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
// enable the CCM RAM and the GPIO's
RCC->AHB1ENR |= RCC_AHB1ENR_CCMDATARAMEN | RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN | RCC_AHB1ENR_GPIOCEN
#if defined(STM32F4DISC)
| RCC_AHB1ENR_GPIODEN
#endif
;
RCC->AHB1ENR |= RCC_AHB1ENR_CCMDATARAMEN | RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN | RCC_AHB1ENR_GPIOCEN | RCC_AHB1ENR_GPIODEN;
#if MICROPY_HW_HAS_SDCARD
{
@ -589,7 +601,7 @@ soft_reset:
rt_init();
#if MICROPY_HW_HAS_LCD
// LCD init (create in with LCD())
// LCD init (just creates class, init hardware by calling LCD())
lcd_init();
#endif
@ -663,11 +675,6 @@ soft_reset:
rt_store_name(MP_QSTR_open, rt_make_function_n(2, pyb_io_open));
}
#if MICROPY_HW_HAS_LCD
// print a message to the LCD
lcd_print_str(" micro py board\n");
#endif
// check if user switch held (initiates reset of filesystem)
bool reset_filesystem = false;
#if MICROPY_HW_HAS_SWITCH
@ -760,14 +767,13 @@ soft_reset:
flash_error(4);
}
// USB
usb_init();
// USB host; not working!
//pyb_usbh_init();
//rt_store_name(qstr_from_str("u_p"), rt_make_function_n(0, pyb_usbh_process));
//rt_store_name(qstr_from_str("u_c"), rt_make_function_n(0, pyb_usbh_connect));
//rt_store_name(qstr_from_str("u_i"), rt_make_function_n(0, pyb_usbh_info));
#ifdef USE_HOST_MODE
// USB host
pyb_usb_host_init();
#elif defined(USE_DEVICE_MODE)
// USB device
pyb_usb_dev_init();
#endif
if (first_soft_reset) {
#if MICROPY_HW_HAS_MMA7660

Wyświetl plik

@ -23,8 +23,8 @@ machine_float_t machine_sqrt(machine_float_t x);
// board specific definitions
// choose 1 of these boards
#define PYBOARD3
//#define PYBOARD4
//#define PYBOARD3
#define PYBOARD4
//#define STM32F4DISC
#if defined (PYBOARD3)
@ -76,7 +76,7 @@ machine_float_t machine_sqrt(machine_float_t x);
#define MICROPY_HW_HAS_SDCARD (1)
#define MICROPY_HW_HAS_MMA7660 (1)
#define MICROPY_HW_HAS_LIS3DSH (0)
#define MICROPY_HW_HAS_LCD (0)
#define MICROPY_HW_HAS_LCD (1)
#define MICROPY_HW_HAS_WLAN (0)
#define MICROPY_HW_ENABLE_RNG (1)
#define MICROPY_HW_ENABLE_RTC (1)
@ -158,3 +158,5 @@ machine_float_t machine_sqrt(machine_float_t x);
#define STM32F40_41xxx
#define USE_STDPERIPH_DRIVER
#define HSE_VALUE (8000000)
#define USE_DEVICE_MODE
//#define USE_HOST_MODE

Wyświetl plik

@ -41,7 +41,7 @@
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
extern USB_OTG_CORE_HANDLE USB_OTG_dev;
extern USB_OTG_CORE_HANDLE USB_OTG_Core;
/* Private function prototypes -----------------------------------------------*/
extern uint32_t USBD_OTG_ISR_Handler (USB_OTG_CORE_HANDLE *pdev);
@ -161,12 +161,12 @@ void PendSV_Handler(void)
#ifdef USE_USB_OTG_FS
void OTG_FS_WKUP_IRQHandler(void)
{
if(USB_OTG_dev.cfg.low_power)
if(USB_OTG_Core.cfg.low_power)
{
*(uint32_t *)(0xE000ED10) &= 0xFFFFFFF9 ;
SystemInit();
#ifdef USE_DEVICE_MODE
USB_OTG_UngateClock(&USB_OTG_dev);
USB_OTG_UngateClock(&USB_OTG_Core);
#endif
}
EXTI_ClearITPendingBit(EXTI_Line18);
@ -181,11 +181,11 @@ void OTG_FS_WKUP_IRQHandler(void)
#ifdef USE_USB_OTG_HS
void OTG_HS_WKUP_IRQHandler(void)
{
if(USB_OTG_dev.cfg.low_power)
if(USB_OTG_Core.cfg.low_power)
{
*(uint32_t *)(0xE000ED10) &= 0xFFFFFFF9 ;
SystemInit();
USB_OTG_UngateClock(&USB_OTG_dev);
USB_OTG_UngateClock(&USB_OTG_Core);
}
EXTI_ClearITPendingBit(EXTI_Line20);
}
@ -202,16 +202,16 @@ void OTG_HS_IRQHandler(void)
void OTG_FS_IRQHandler(void)
#endif
{
if (USB_OTG_IsHostMode(&USB_OTG_dev)) {
if (USB_OTG_IsHostMode(&USB_OTG_Core)) {
// host mode
#ifdef USE_HOST_MODE
USBH_OTG_ISR_Handler(&USB_OTG_dev);
USBH_OTG_ISR_Handler(&USB_OTG_Core);
#endif
//STM32_USBO_OTG_ISR_Handler(&USB_OTG_dev); // USE_OTG_MODE
//STM32_USBO_OTG_ISR_Handler(&USB_OTG_Core); // USE_OTG_MODE
} else {
// device mode
#ifdef USE_DEVICE_MODE
USBD_OTG_ISR_Handler(&USB_OTG_dev);
USBD_OTG_ISR_Handler(&USB_OTG_Core);
#endif
}
}
@ -224,7 +224,7 @@ void OTG_FS_IRQHandler(void)
*/
void OTG_HS_EP1_IN_IRQHandler(void)
{
USBD_OTG_EP1IN_ISR_Handler (&USB_OTG_dev);
USBD_OTG_EP1IN_ISR_Handler (&USB_OTG_Core);
}
/**
@ -234,7 +234,7 @@ void OTG_HS_EP1_IN_IRQHandler(void)
*/
void OTG_HS_EP1_OUT_IRQHandler(void)
{
USBD_OTG_EP1OUT_ISR_Handler (&USB_OTG_dev);
USBD_OTG_EP1OUT_ISR_Handler (&USB_OTG_Core);
}
#endif

Wyświetl plik

@ -27,9 +27,9 @@
*/
/* Includes ------------------------------------------------------------------*/
#include "stm_misc.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_rcc.h"
#include "stm_misc.h"
#include "usb_bsp.h"
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
@ -97,7 +97,7 @@
void USB_OTG_BSP_Init(USB_OTG_CORE_HANDLE *pdev) {
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
/* Configure DM DP Pins */
/* Configure DM DP Pins on PA11 and PA12 */
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
@ -109,7 +109,7 @@ void USB_OTG_BSP_Init(USB_OTG_CORE_HANDLE *pdev) {
GPIO_PinAFConfig(GPIOA, GPIO_PinSource11, GPIO_AF_OTG_FS);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource12, GPIO_AF_OTG_FS);
/* Configure VBUS Pin (or disable VBUS_SENSING_ENABLED) */
/* Configure VBUS Pin on PA9 (or disable VBUS_SENSING_ENABLED) */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
@ -117,8 +117,7 @@ void USB_OTG_BSP_Init(USB_OTG_CORE_HANDLE *pdev) {
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/*
// Configure ID pin (only in host mode)
// Configure ID pin on PA10
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
@ -126,7 +125,6 @@ void USB_OTG_BSP_Init(USB_OTG_CORE_HANDLE *pdev) {
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_OTG_FS);
*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_OTG_FS, ENABLE);
@ -235,7 +233,7 @@ void USB_OTG_BSP_ConfigVBUS(USB_OTG_CORE_HANDLE *pdev) {
void USB_OTG_BSP_uDelay (const uint32_t usec)
{
uint32_t count = 0;
const uint32_t utime = (160 * usec / 5);
const uint32_t utime = (168 * usec / 5);
do
{
if ( ++count > utime )

Wyświetl plik

@ -237,9 +237,9 @@
/* END host specific stuff */
/****************** USB OTG MODE CONFIGURATION ********************************/
//#define USE_HOST_MODE // set in Makefile
#define USE_DEVICE_MODE
//#define USE_OTG_MODE // set in Makefile
//#define USE_HOST_MODE // set in mpconfigport.h
//#define USE_DEVICE_MODE // set in mpconfigport.h
//#define USE_OTG_MODE // set in mpconfigport.h
#ifndef USB_OTG_FS_CORE
#ifndef USB_OTG_HS_CORE

Wyświetl plik

@ -0,0 +1,265 @@
/**
******************************************************************************
* @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"
#ifdef USE_HOST_MODE
/** @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);
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
#endif // USE_HOST_MODE
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

Wyświetl plik

@ -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****/

Wyświetl plik

@ -0,0 +1,863 @@
/**
******************************************************************************
* @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"
#ifdef USE_HOST_MODE
#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;
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
#endif // USE_HOST_MODE
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

Wyświetl plik

@ -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****/

Wyświetl plik

@ -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
* @{
*/
static 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****/

Wyświetl plik

@ -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(USB_OTG_CORE_HANDLE *pdev);
void USB_OTG_InitiateHNP(USB_OTG_CORE_HANDLE *pdev, uint8_t state, uint8_t mode);
void USB_OTG_Switchback (USB_OTG_CORE_HANDLE *pdev);
uint32_t USB_OTG_GetCurrentState (USB_OTG_CORE_HANDLE *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****/

Wyświetl plik

@ -64,7 +64,7 @@
#define USB_OTG_DATA_FIFO_SIZE 0x1000
#define USB_OTG_MAX_TX_FIFOS 4 // XXX check we can make it this small!
#define USB_OTG_MAX_TX_FIFOS 15
#define USB_OTG_HS_MAX_PACKET_SIZE 512
#define USB_OTG_FS_MAX_PACKET_SIZE 64

Wyświetl plik

@ -32,7 +32,6 @@
/* Includes ------------------------------------------------------------------*/
#include "usbd_conf.h"
#include "usbd_cdc_vcp.h"
#include "std.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/

Wyświetl plik

@ -27,7 +27,6 @@
#include "usbd_usr.h"
#include "usbd_ioreq.h"
#include "std.h"
USBD_Usr_cb_TypeDef USR_cb = {
USBD_USR_Init,

Wyświetl plik

@ -0,0 +1,97 @@
/**
******************************************************************************
* @file USBH_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 __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
#define USBH_MSC_MPS_SIZE 0x200
/**
* @}
*/
/** @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****/

Wyświetl plik

@ -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****/

Wyświetl plik

@ -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****/

Wyświetl plik

@ -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****/

Wyświetl plik

@ -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****/

Wyświetl plik

@ -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****/

Wyświetl plik

@ -0,0 +1,658 @@
/**
******************************************************************************
* @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;
//printf("USBH_HID_InterfaceInit\n");
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;
}
//printf("USBH_HID_InterfaceInit %x %x\n", pphost->device_prop.Itf_Desc[0].bInterfaceSubClass, pphost->device_prop.Itf_Desc[0].bInterfaceProtocol);
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****/

Wyświetl plik

@ -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****/

Wyświetl plik

@ -0,0 +1,367 @@
/**
******************************************************************************
* @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', 127, // dpgeorge 127 used to be \r (it's backspace)
'\t', 'q', 'w', 'e', 'r', 't', 'y', 'u',
'i', 'o', 'p', '[', ']', '\\',
'\0', 'a', 's', 'd', 'f', 'g', 'h', 'j',
'k', 'l', ';', '\'', '\0', '\r', // dpgeorge \r used to be \n (it's enter)
'\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', '\r', '\0', '\0', 'Z', 'X', // dpgeorge \r used to be \n (it's enter)
'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'
};
static const int8_t HID_KEYBRD_CtrlKey[] = {
'\0', '~', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')',
'_', '+', '\0', '\0', '\0', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U',
'I', 'O', 'P', '{', '}', '|', '\0', 'A', 'S', 4, 'F', 'G',
'H', 'J', 'K', 'L', ':', '"', '\0', '\r', '\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 ctrl;
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;
}
/* Check if Ctrl key is pressed */
if ((pbuf[0] == KBD_LEFT_CTRL) || (pbuf[0] == KBD_RIGHT_CTRL)) {
ctrl = TRUE;
} else {
ctrl = 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 (ctrl == TRUE) {
output = HID_KEYBRD_CtrlKey[HID_KEYBRD_Codes[key_newest]];
} else 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****/

Wyświetl plik

@ -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****/

Wyświetl plik

@ -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****/

Some files were not shown because too many files have changed in this diff Show More