From 75abee206d1a575aa98a486d043c94d64df432c1 Mon Sep 17 00:00:00 2001 From: Damien George Date: Sun, 26 Jan 2014 17:41:01 +0000 Subject: [PATCH] stm: USB host mode working! Restructure stm library directories. --- stm/Makefile | 57 +- stm/lcd.c | 8 +- stm/main.c | 44 +- stm/mpconfigport.h | 8 +- stm/stm32fxxx_it.c | 22 +- stm/{lib => stmperiph}/stm324x7i_eval.c | 0 stm/{lib => stmperiph}/stm324x7i_eval.h | 0 .../stm324x7i_eval_sdio_sd.c | 0 .../stm324x7i_eval_sdio_sd.h | 0 stm/{lib => stmperiph}/stm32f4xx.h | 0 stm/{lib => stmperiph}/stm32f4xx_adc.c | 0 stm/{lib => stmperiph}/stm32f4xx_adc.h | 0 stm/{lib => stmperiph}/stm32f4xx_conf.h | 0 stm/{lib => stmperiph}/stm32f4xx_dac.c | 0 stm/{lib => stmperiph}/stm32f4xx_dac.h | 0 stm/{lib => stmperiph}/stm32f4xx_dma.c | 0 stm/{lib => stmperiph}/stm32f4xx_dma.h | 0 stm/{lib => stmperiph}/stm32f4xx_exti.c | 0 stm/{lib => stmperiph}/stm32f4xx_exti.h | 0 stm/{lib => stmperiph}/stm32f4xx_flash.c | 0 stm/{lib => stmperiph}/stm32f4xx_flash.h | 0 stm/{lib => stmperiph}/stm32f4xx_gpio.c | 0 stm/{lib => stmperiph}/stm32f4xx_gpio.h | 0 stm/{lib => stmperiph}/stm32f4xx_i2c.c | 0 stm/{lib => stmperiph}/stm32f4xx_i2c.h | 0 stm/{lib => stmperiph}/stm32f4xx_pwr.c | 0 stm/{lib => stmperiph}/stm32f4xx_pwr.h | 0 stm/{lib => stmperiph}/stm32f4xx_rcc.c | 0 stm/{lib => stmperiph}/stm32f4xx_rcc.h | 0 stm/{lib => stmperiph}/stm32f4xx_rng.c | 0 stm/{lib => stmperiph}/stm32f4xx_rng.h | 0 stm/{lib => stmperiph}/stm32f4xx_rtc.c | 0 stm/{lib => stmperiph}/stm32f4xx_rtc.h | 0 stm/{lib => stmperiph}/stm32f4xx_sdio.c | 0 stm/{lib => stmperiph}/stm32f4xx_sdio.h | 0 stm/{lib => stmperiph}/stm32f4xx_spi.c | 0 stm/{lib => stmperiph}/stm32f4xx_spi.h | 0 stm/{lib => stmperiph}/stm32f4xx_syscfg.c | 0 stm/{lib => stmperiph}/stm32f4xx_syscfg.h | 0 stm/{lib => stmperiph}/stm32f4xx_tim.c | 0 stm/{lib => stmperiph}/stm32f4xx_tim.h | 0 stm/{lib => stmperiph}/stm32f4xx_usart.c | 0 stm/{lib => stmperiph}/stm32f4xx_usart.h | 0 stm/{lib => stmperiph}/stm_misc.c | 0 stm/{lib => stmperiph}/stm_misc.h | 0 stm/{lib => stmperiph}/system_stm32f4xx.h | 0 stm/{lib => stmusb}/usb_bsp.c | 12 +- stm/{lib => stmusb}/usb_bsp.h | 0 stm/{lib => stmusb}/usb_conf.h | 6 +- stm/{lib => stmusb}/usb_core.c | 0 stm/{lib => stmusb}/usb_core.h | 0 stm/{lib => stmusb}/usb_dcd.c | 0 stm/{lib => stmusb}/usb_dcd.h | 0 stm/{lib => stmusb}/usb_dcd_int.c | 0 stm/{lib => stmusb}/usb_dcd_int.h | 0 stm/{lib => stmusb}/usb_defines.h | 0 stm/stmusb/usb_hcd.c | 265 ++++++ stm/stmusb/usb_hcd.h | 108 +++ stm/stmusb/usb_hcd_int.c | 863 ++++++++++++++++++ stm/stmusb/usb_hcd_int.h | 141 +++ stm/stmusb/usb_otg.c | 418 +++++++++ stm/stmusb/usb_otg.h | 99 ++ stm/{lib => stmusb}/usb_regs.h | 2 +- stm/{lib => stmusbd}/usbd_cdc_core.h | 0 stm/{lib => stmusbd}/usbd_cdc_vcp.c | 1 - stm/{lib => stmusbd}/usbd_cdc_vcp.h | 0 stm/{lib => stmusbd}/usbd_conf.h | 0 stm/{lib => stmusbd}/usbd_core.c | 0 stm/{lib => stmusbd}/usbd_core.h | 0 stm/{lib => stmusbd}/usbd_def.h | 0 stm/{lib => stmusbd}/usbd_desc.c | 0 stm/{lib => stmusbd}/usbd_desc.h | 0 stm/{lib => stmusbd}/usbd_ioreq.c | 0 stm/{lib => stmusbd}/usbd_ioreq.h | 0 stm/{lib => stmusbd}/usbd_msc_bot.c | 0 stm/{lib => stmusbd}/usbd_msc_bot.h | 0 stm/{lib => stmusbd}/usbd_msc_data.c | 0 stm/{lib => stmusbd}/usbd_msc_data.h | 0 stm/{lib => stmusbd}/usbd_msc_mem.h | 0 stm/{lib => stmusbd}/usbd_msc_scsi.c | 0 stm/{lib => stmusbd}/usbd_msc_scsi.h | 0 stm/{lib => stmusbd}/usbd_pyb_core.c | 0 stm/{lib => stmusbd}/usbd_pyb_core.h | 0 stm/{lib => stmusbd}/usbd_pyb_core2.c | 0 stm/{lib => stmusbd}/usbd_req.c | 0 stm/{lib => stmusbd}/usbd_req.h | 0 stm/{lib => stmusbd}/usbd_storage_msd.c | 0 stm/{lib => stmusbd}/usbd_usr.c | 1 - stm/{lib => stmusbd}/usbd_usr.h | 0 stm/stmusbh/usbh_conf.h | 97 ++ stm/stmusbh/usbh_core.c | 857 +++++++++++++++++ stm/stmusbh/usbh_core.h | 295 ++++++ stm/stmusbh/usbh_def.h | 288 ++++++ stm/stmusbh/usbh_hcs.c | 259 ++++++ stm/stmusbh/usbh_hcs.h | 129 +++ stm/stmusbh/usbh_hid_core.c | 658 +++++++++++++ stm/stmusbh/usbh_hid_core.h | 203 ++++ stm/stmusbh/usbh_hid_keybd.c | 367 ++++++++ stm/stmusbh/usbh_hid_keybd.h | 128 +++ stm/stmusbh/usbh_hid_mouse.c | 161 ++++ stm/stmusbh/usbh_hid_mouse.h | 120 +++ stm/stmusbh/usbh_ioreq.c | 474 ++++++++++ stm/stmusbh/usbh_ioreq.h | 156 ++++ stm/stmusbh/usbh_stdreq.c | 607 ++++++++++++ stm/stmusbh/usbh_stdreq.h | 161 ++++ stm/stmusbh/usbh_usr.c | 386 ++++++++ stm/stmusbh/usbh_usr.h | 107 +++ stm/usb.c | 94 +- stm/usb.h | 9 +- 109 files changed, 7499 insertions(+), 112 deletions(-) rename stm/{lib => stmperiph}/stm324x7i_eval.c (100%) rename stm/{lib => stmperiph}/stm324x7i_eval.h (100%) rename stm/{lib => stmperiph}/stm324x7i_eval_sdio_sd.c (100%) rename stm/{lib => stmperiph}/stm324x7i_eval_sdio_sd.h (100%) rename stm/{lib => stmperiph}/stm32f4xx.h (100%) rename stm/{lib => stmperiph}/stm32f4xx_adc.c (100%) rename stm/{lib => stmperiph}/stm32f4xx_adc.h (100%) rename stm/{lib => stmperiph}/stm32f4xx_conf.h (100%) rename stm/{lib => stmperiph}/stm32f4xx_dac.c (100%) rename stm/{lib => stmperiph}/stm32f4xx_dac.h (100%) rename stm/{lib => stmperiph}/stm32f4xx_dma.c (100%) rename stm/{lib => stmperiph}/stm32f4xx_dma.h (100%) rename stm/{lib => stmperiph}/stm32f4xx_exti.c (100%) rename stm/{lib => stmperiph}/stm32f4xx_exti.h (100%) rename stm/{lib => stmperiph}/stm32f4xx_flash.c (100%) rename stm/{lib => stmperiph}/stm32f4xx_flash.h (100%) rename stm/{lib => stmperiph}/stm32f4xx_gpio.c (100%) rename stm/{lib => stmperiph}/stm32f4xx_gpio.h (100%) rename stm/{lib => stmperiph}/stm32f4xx_i2c.c (100%) rename stm/{lib => stmperiph}/stm32f4xx_i2c.h (100%) rename stm/{lib => stmperiph}/stm32f4xx_pwr.c (100%) rename stm/{lib => stmperiph}/stm32f4xx_pwr.h (100%) rename stm/{lib => stmperiph}/stm32f4xx_rcc.c (100%) rename stm/{lib => stmperiph}/stm32f4xx_rcc.h (100%) rename stm/{lib => stmperiph}/stm32f4xx_rng.c (100%) rename stm/{lib => stmperiph}/stm32f4xx_rng.h (100%) rename stm/{lib => stmperiph}/stm32f4xx_rtc.c (100%) rename stm/{lib => stmperiph}/stm32f4xx_rtc.h (100%) rename stm/{lib => stmperiph}/stm32f4xx_sdio.c (100%) rename stm/{lib => stmperiph}/stm32f4xx_sdio.h (100%) rename stm/{lib => stmperiph}/stm32f4xx_spi.c (100%) rename stm/{lib => stmperiph}/stm32f4xx_spi.h (100%) rename stm/{lib => stmperiph}/stm32f4xx_syscfg.c (100%) rename stm/{lib => stmperiph}/stm32f4xx_syscfg.h (100%) rename stm/{lib => stmperiph}/stm32f4xx_tim.c (100%) rename stm/{lib => stmperiph}/stm32f4xx_tim.h (100%) rename stm/{lib => stmperiph}/stm32f4xx_usart.c (100%) rename stm/{lib => stmperiph}/stm32f4xx_usart.h (100%) rename stm/{lib => stmperiph}/stm_misc.c (100%) rename stm/{lib => stmperiph}/stm_misc.h (100%) rename stm/{lib => stmperiph}/system_stm32f4xx.h (100%) rename stm/{lib => stmusb}/usb_bsp.c (93%) rename stm/{lib => stmusb}/usb_bsp.h (100%) rename stm/{lib => stmusb}/usb_conf.h (96%) rename stm/{lib => stmusb}/usb_core.c (100%) rename stm/{lib => stmusb}/usb_core.h (100%) rename stm/{lib => stmusb}/usb_dcd.c (100%) rename stm/{lib => stmusb}/usb_dcd.h (100%) rename stm/{lib => stmusb}/usb_dcd_int.c (100%) rename stm/{lib => stmusb}/usb_dcd_int.h (100%) rename stm/{lib => stmusb}/usb_defines.h (100%) create mode 100644 stm/stmusb/usb_hcd.c create mode 100644 stm/stmusb/usb_hcd.h create mode 100644 stm/stmusb/usb_hcd_int.c create mode 100644 stm/stmusb/usb_hcd_int.h create mode 100644 stm/stmusb/usb_otg.c create mode 100644 stm/stmusb/usb_otg.h rename stm/{lib => stmusb}/usb_regs.h (94%) rename stm/{lib => stmusbd}/usbd_cdc_core.h (100%) rename stm/{lib => stmusbd}/usbd_cdc_vcp.c (96%) rename stm/{lib => stmusbd}/usbd_cdc_vcp.h (100%) rename stm/{lib => stmusbd}/usbd_conf.h (100%) rename stm/{lib => stmusbd}/usbd_core.c (100%) rename stm/{lib => stmusbd}/usbd_core.h (100%) rename stm/{lib => stmusbd}/usbd_def.h (100%) rename stm/{lib => stmusbd}/usbd_desc.c (100%) rename stm/{lib => stmusbd}/usbd_desc.h (100%) rename stm/{lib => stmusbd}/usbd_ioreq.c (100%) rename stm/{lib => stmusbd}/usbd_ioreq.h (100%) rename stm/{lib => stmusbd}/usbd_msc_bot.c (100%) rename stm/{lib => stmusbd}/usbd_msc_bot.h (100%) rename stm/{lib => stmusbd}/usbd_msc_data.c (100%) rename stm/{lib => stmusbd}/usbd_msc_data.h (100%) rename stm/{lib => stmusbd}/usbd_msc_mem.h (100%) rename stm/{lib => stmusbd}/usbd_msc_scsi.c (100%) rename stm/{lib => stmusbd}/usbd_msc_scsi.h (100%) rename stm/{lib => stmusbd}/usbd_pyb_core.c (100%) rename stm/{lib => stmusbd}/usbd_pyb_core.h (100%) rename stm/{lib => stmusbd}/usbd_pyb_core2.c (100%) rename stm/{lib => stmusbd}/usbd_req.c (100%) rename stm/{lib => stmusbd}/usbd_req.h (100%) rename stm/{lib => stmusbd}/usbd_storage_msd.c (100%) rename stm/{lib => stmusbd}/usbd_usr.c (99%) rename stm/{lib => stmusbd}/usbd_usr.h (100%) create mode 100644 stm/stmusbh/usbh_conf.h create mode 100644 stm/stmusbh/usbh_core.c create mode 100644 stm/stmusbh/usbh_core.h create mode 100644 stm/stmusbh/usbh_def.h create mode 100644 stm/stmusbh/usbh_hcs.c create mode 100644 stm/stmusbh/usbh_hcs.h create mode 100644 stm/stmusbh/usbh_hid_core.c create mode 100644 stm/stmusbh/usbh_hid_core.h create mode 100644 stm/stmusbh/usbh_hid_keybd.c create mode 100644 stm/stmusbh/usbh_hid_keybd.h create mode 100644 stm/stmusbh/usbh_hid_mouse.c create mode 100644 stm/stmusbh/usbh_hid_mouse.h create mode 100644 stm/stmusbh/usbh_ioreq.c create mode 100644 stm/stmusbh/usbh_ioreq.h create mode 100644 stm/stmusbh/usbh_stdreq.c create mode 100644 stm/stmusbh/usbh_stdreq.h create mode 100644 stm/stmusbh/usbh_usr.c create mode 100644 stm/stmusbh/usbh_usr.h diff --git a/stm/Makefile b/stm/Makefile index c0ae6a89c0..12fd0d9662 100644 --- a/stm/Makefile +++ b/stm/Makefile @@ -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 - diff --git a/stm/lcd.c b/stm/lcd.c index e8553a69e3..dae4157a46 100644 --- a/stm/lcd.c +++ b/stm/lcd.c @@ -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); } } diff --git a/stm/main.c b/stm/main.c index 1388a1d900..90fdab3d22 100644 --- a/stm/main.c +++ b/stm/main.c @@ -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 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 diff --git a/stm/mpconfigport.h b/stm/mpconfigport.h index 028aea0f19..adf72a4d43 100644 --- a/stm/mpconfigport.h +++ b/stm/mpconfigport.h @@ -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 diff --git a/stm/stm32fxxx_it.c b/stm/stm32fxxx_it.c index 8e96a0121c..7b5030bc6e 100644 --- a/stm/stm32fxxx_it.c +++ b/stm/stm32fxxx_it.c @@ -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 diff --git a/stm/lib/stm324x7i_eval.c b/stm/stmperiph/stm324x7i_eval.c similarity index 100% rename from stm/lib/stm324x7i_eval.c rename to stm/stmperiph/stm324x7i_eval.c diff --git a/stm/lib/stm324x7i_eval.h b/stm/stmperiph/stm324x7i_eval.h similarity index 100% rename from stm/lib/stm324x7i_eval.h rename to stm/stmperiph/stm324x7i_eval.h diff --git a/stm/lib/stm324x7i_eval_sdio_sd.c b/stm/stmperiph/stm324x7i_eval_sdio_sd.c similarity index 100% rename from stm/lib/stm324x7i_eval_sdio_sd.c rename to stm/stmperiph/stm324x7i_eval_sdio_sd.c diff --git a/stm/lib/stm324x7i_eval_sdio_sd.h b/stm/stmperiph/stm324x7i_eval_sdio_sd.h similarity index 100% rename from stm/lib/stm324x7i_eval_sdio_sd.h rename to stm/stmperiph/stm324x7i_eval_sdio_sd.h diff --git a/stm/lib/stm32f4xx.h b/stm/stmperiph/stm32f4xx.h similarity index 100% rename from stm/lib/stm32f4xx.h rename to stm/stmperiph/stm32f4xx.h diff --git a/stm/lib/stm32f4xx_adc.c b/stm/stmperiph/stm32f4xx_adc.c similarity index 100% rename from stm/lib/stm32f4xx_adc.c rename to stm/stmperiph/stm32f4xx_adc.c diff --git a/stm/lib/stm32f4xx_adc.h b/stm/stmperiph/stm32f4xx_adc.h similarity index 100% rename from stm/lib/stm32f4xx_adc.h rename to stm/stmperiph/stm32f4xx_adc.h diff --git a/stm/lib/stm32f4xx_conf.h b/stm/stmperiph/stm32f4xx_conf.h similarity index 100% rename from stm/lib/stm32f4xx_conf.h rename to stm/stmperiph/stm32f4xx_conf.h diff --git a/stm/lib/stm32f4xx_dac.c b/stm/stmperiph/stm32f4xx_dac.c similarity index 100% rename from stm/lib/stm32f4xx_dac.c rename to stm/stmperiph/stm32f4xx_dac.c diff --git a/stm/lib/stm32f4xx_dac.h b/stm/stmperiph/stm32f4xx_dac.h similarity index 100% rename from stm/lib/stm32f4xx_dac.h rename to stm/stmperiph/stm32f4xx_dac.h diff --git a/stm/lib/stm32f4xx_dma.c b/stm/stmperiph/stm32f4xx_dma.c similarity index 100% rename from stm/lib/stm32f4xx_dma.c rename to stm/stmperiph/stm32f4xx_dma.c diff --git a/stm/lib/stm32f4xx_dma.h b/stm/stmperiph/stm32f4xx_dma.h similarity index 100% rename from stm/lib/stm32f4xx_dma.h rename to stm/stmperiph/stm32f4xx_dma.h diff --git a/stm/lib/stm32f4xx_exti.c b/stm/stmperiph/stm32f4xx_exti.c similarity index 100% rename from stm/lib/stm32f4xx_exti.c rename to stm/stmperiph/stm32f4xx_exti.c diff --git a/stm/lib/stm32f4xx_exti.h b/stm/stmperiph/stm32f4xx_exti.h similarity index 100% rename from stm/lib/stm32f4xx_exti.h rename to stm/stmperiph/stm32f4xx_exti.h diff --git a/stm/lib/stm32f4xx_flash.c b/stm/stmperiph/stm32f4xx_flash.c similarity index 100% rename from stm/lib/stm32f4xx_flash.c rename to stm/stmperiph/stm32f4xx_flash.c diff --git a/stm/lib/stm32f4xx_flash.h b/stm/stmperiph/stm32f4xx_flash.h similarity index 100% rename from stm/lib/stm32f4xx_flash.h rename to stm/stmperiph/stm32f4xx_flash.h diff --git a/stm/lib/stm32f4xx_gpio.c b/stm/stmperiph/stm32f4xx_gpio.c similarity index 100% rename from stm/lib/stm32f4xx_gpio.c rename to stm/stmperiph/stm32f4xx_gpio.c diff --git a/stm/lib/stm32f4xx_gpio.h b/stm/stmperiph/stm32f4xx_gpio.h similarity index 100% rename from stm/lib/stm32f4xx_gpio.h rename to stm/stmperiph/stm32f4xx_gpio.h diff --git a/stm/lib/stm32f4xx_i2c.c b/stm/stmperiph/stm32f4xx_i2c.c similarity index 100% rename from stm/lib/stm32f4xx_i2c.c rename to stm/stmperiph/stm32f4xx_i2c.c diff --git a/stm/lib/stm32f4xx_i2c.h b/stm/stmperiph/stm32f4xx_i2c.h similarity index 100% rename from stm/lib/stm32f4xx_i2c.h rename to stm/stmperiph/stm32f4xx_i2c.h diff --git a/stm/lib/stm32f4xx_pwr.c b/stm/stmperiph/stm32f4xx_pwr.c similarity index 100% rename from stm/lib/stm32f4xx_pwr.c rename to stm/stmperiph/stm32f4xx_pwr.c diff --git a/stm/lib/stm32f4xx_pwr.h b/stm/stmperiph/stm32f4xx_pwr.h similarity index 100% rename from stm/lib/stm32f4xx_pwr.h rename to stm/stmperiph/stm32f4xx_pwr.h diff --git a/stm/lib/stm32f4xx_rcc.c b/stm/stmperiph/stm32f4xx_rcc.c similarity index 100% rename from stm/lib/stm32f4xx_rcc.c rename to stm/stmperiph/stm32f4xx_rcc.c diff --git a/stm/lib/stm32f4xx_rcc.h b/stm/stmperiph/stm32f4xx_rcc.h similarity index 100% rename from stm/lib/stm32f4xx_rcc.h rename to stm/stmperiph/stm32f4xx_rcc.h diff --git a/stm/lib/stm32f4xx_rng.c b/stm/stmperiph/stm32f4xx_rng.c similarity index 100% rename from stm/lib/stm32f4xx_rng.c rename to stm/stmperiph/stm32f4xx_rng.c diff --git a/stm/lib/stm32f4xx_rng.h b/stm/stmperiph/stm32f4xx_rng.h similarity index 100% rename from stm/lib/stm32f4xx_rng.h rename to stm/stmperiph/stm32f4xx_rng.h diff --git a/stm/lib/stm32f4xx_rtc.c b/stm/stmperiph/stm32f4xx_rtc.c similarity index 100% rename from stm/lib/stm32f4xx_rtc.c rename to stm/stmperiph/stm32f4xx_rtc.c diff --git a/stm/lib/stm32f4xx_rtc.h b/stm/stmperiph/stm32f4xx_rtc.h similarity index 100% rename from stm/lib/stm32f4xx_rtc.h rename to stm/stmperiph/stm32f4xx_rtc.h diff --git a/stm/lib/stm32f4xx_sdio.c b/stm/stmperiph/stm32f4xx_sdio.c similarity index 100% rename from stm/lib/stm32f4xx_sdio.c rename to stm/stmperiph/stm32f4xx_sdio.c diff --git a/stm/lib/stm32f4xx_sdio.h b/stm/stmperiph/stm32f4xx_sdio.h similarity index 100% rename from stm/lib/stm32f4xx_sdio.h rename to stm/stmperiph/stm32f4xx_sdio.h diff --git a/stm/lib/stm32f4xx_spi.c b/stm/stmperiph/stm32f4xx_spi.c similarity index 100% rename from stm/lib/stm32f4xx_spi.c rename to stm/stmperiph/stm32f4xx_spi.c diff --git a/stm/lib/stm32f4xx_spi.h b/stm/stmperiph/stm32f4xx_spi.h similarity index 100% rename from stm/lib/stm32f4xx_spi.h rename to stm/stmperiph/stm32f4xx_spi.h diff --git a/stm/lib/stm32f4xx_syscfg.c b/stm/stmperiph/stm32f4xx_syscfg.c similarity index 100% rename from stm/lib/stm32f4xx_syscfg.c rename to stm/stmperiph/stm32f4xx_syscfg.c diff --git a/stm/lib/stm32f4xx_syscfg.h b/stm/stmperiph/stm32f4xx_syscfg.h similarity index 100% rename from stm/lib/stm32f4xx_syscfg.h rename to stm/stmperiph/stm32f4xx_syscfg.h diff --git a/stm/lib/stm32f4xx_tim.c b/stm/stmperiph/stm32f4xx_tim.c similarity index 100% rename from stm/lib/stm32f4xx_tim.c rename to stm/stmperiph/stm32f4xx_tim.c diff --git a/stm/lib/stm32f4xx_tim.h b/stm/stmperiph/stm32f4xx_tim.h similarity index 100% rename from stm/lib/stm32f4xx_tim.h rename to stm/stmperiph/stm32f4xx_tim.h diff --git a/stm/lib/stm32f4xx_usart.c b/stm/stmperiph/stm32f4xx_usart.c similarity index 100% rename from stm/lib/stm32f4xx_usart.c rename to stm/stmperiph/stm32f4xx_usart.c diff --git a/stm/lib/stm32f4xx_usart.h b/stm/stmperiph/stm32f4xx_usart.h similarity index 100% rename from stm/lib/stm32f4xx_usart.h rename to stm/stmperiph/stm32f4xx_usart.h diff --git a/stm/lib/stm_misc.c b/stm/stmperiph/stm_misc.c similarity index 100% rename from stm/lib/stm_misc.c rename to stm/stmperiph/stm_misc.c diff --git a/stm/lib/stm_misc.h b/stm/stmperiph/stm_misc.h similarity index 100% rename from stm/lib/stm_misc.h rename to stm/stmperiph/stm_misc.h diff --git a/stm/lib/system_stm32f4xx.h b/stm/stmperiph/system_stm32f4xx.h similarity index 100% rename from stm/lib/system_stm32f4xx.h rename to stm/stmperiph/system_stm32f4xx.h diff --git a/stm/lib/usb_bsp.c b/stm/stmusb/usb_bsp.c similarity index 93% rename from stm/lib/usb_bsp.c rename to stm/stmusb/usb_bsp.c index e88e31db0e..cf9d667c69 100644 --- a/stm/lib/usb_bsp.c +++ b/stm/stmusb/usb_bsp.c @@ -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 ) diff --git a/stm/lib/usb_bsp.h b/stm/stmusb/usb_bsp.h similarity index 100% rename from stm/lib/usb_bsp.h rename to stm/stmusb/usb_bsp.h diff --git a/stm/lib/usb_conf.h b/stm/stmusb/usb_conf.h similarity index 96% rename from stm/lib/usb_conf.h rename to stm/stmusb/usb_conf.h index a51a23a84e..5856899d59 100644 --- a/stm/lib/usb_conf.h +++ b/stm/stmusb/usb_conf.h @@ -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 diff --git a/stm/lib/usb_core.c b/stm/stmusb/usb_core.c similarity index 100% rename from stm/lib/usb_core.c rename to stm/stmusb/usb_core.c diff --git a/stm/lib/usb_core.h b/stm/stmusb/usb_core.h similarity index 100% rename from stm/lib/usb_core.h rename to stm/stmusb/usb_core.h diff --git a/stm/lib/usb_dcd.c b/stm/stmusb/usb_dcd.c similarity index 100% rename from stm/lib/usb_dcd.c rename to stm/stmusb/usb_dcd.c diff --git a/stm/lib/usb_dcd.h b/stm/stmusb/usb_dcd.h similarity index 100% rename from stm/lib/usb_dcd.h rename to stm/stmusb/usb_dcd.h diff --git a/stm/lib/usb_dcd_int.c b/stm/stmusb/usb_dcd_int.c similarity index 100% rename from stm/lib/usb_dcd_int.c rename to stm/stmusb/usb_dcd_int.c diff --git a/stm/lib/usb_dcd_int.h b/stm/stmusb/usb_dcd_int.h similarity index 100% rename from stm/lib/usb_dcd_int.h rename to stm/stmusb/usb_dcd_int.h diff --git a/stm/lib/usb_defines.h b/stm/stmusb/usb_defines.h similarity index 100% rename from stm/lib/usb_defines.h rename to stm/stmusb/usb_defines.h diff --git a/stm/stmusb/usb_hcd.c b/stm/stmusb/usb_hcd.c new file mode 100644 index 0000000000..060e123291 --- /dev/null +++ b/stm/stmusb/usb_hcd.c @@ -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 + * + *

© COPYRIGHT 2012 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "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****/ diff --git a/stm/stmusb/usb_hcd.h b/stm/stmusb/usb_hcd.h new file mode 100644 index 0000000000..ca2ba3c374 --- /dev/null +++ b/stm/stmusb/usb_hcd.h @@ -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 + * + *

© COPYRIGHT 2012 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __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****/ + diff --git a/stm/stmusb/usb_hcd_int.c b/stm/stmusb/usb_hcd_int.c new file mode 100644 index 0000000000..545818d465 --- /dev/null +++ b/stm/stmusb/usb_hcd_int.c @@ -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 + * + *

© COPYRIGHT 2012 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "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****/ + diff --git a/stm/stmusb/usb_hcd_int.h b/stm/stmusb/usb_hcd_int.h new file mode 100644 index 0000000000..5bc5b8a882 --- /dev/null +++ b/stm/stmusb/usb_hcd_int.h @@ -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 + * + *

© COPYRIGHT 2012 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __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****/ + diff --git a/stm/stmusb/usb_otg.c b/stm/stmusb/usb_otg.c new file mode 100644 index 0000000000..bb421ae914 --- /dev/null +++ b/stm/stmusb/usb_otg.c @@ -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 + * + *

© COPYRIGHT 2012 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "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****/ diff --git a/stm/stmusb/usb_otg.h b/stm/stmusb/usb_otg.h new file mode 100644 index 0000000000..2f378dc168 --- /dev/null +++ b/stm/stmusb/usb_otg.h @@ -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 + * + *

© COPYRIGHT 2012 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __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****/ + diff --git a/stm/lib/usb_regs.h b/stm/stmusb/usb_regs.h similarity index 94% rename from stm/lib/usb_regs.h rename to stm/stmusb/usb_regs.h index d3ea8d821a..323e870560 100644 --- a/stm/lib/usb_regs.h +++ b/stm/stmusb/usb_regs.h @@ -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 diff --git a/stm/lib/usbd_cdc_core.h b/stm/stmusbd/usbd_cdc_core.h similarity index 100% rename from stm/lib/usbd_cdc_core.h rename to stm/stmusbd/usbd_cdc_core.h diff --git a/stm/lib/usbd_cdc_vcp.c b/stm/stmusbd/usbd_cdc_vcp.c similarity index 96% rename from stm/lib/usbd_cdc_vcp.c rename to stm/stmusbd/usbd_cdc_vcp.c index 985b0b4fd9..fc2bbc4589 100644 --- a/stm/lib/usbd_cdc_vcp.c +++ b/stm/stmusbd/usbd_cdc_vcp.c @@ -32,7 +32,6 @@ /* Includes ------------------------------------------------------------------*/ #include "usbd_conf.h" #include "usbd_cdc_vcp.h" -#include "std.h" /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ diff --git a/stm/lib/usbd_cdc_vcp.h b/stm/stmusbd/usbd_cdc_vcp.h similarity index 100% rename from stm/lib/usbd_cdc_vcp.h rename to stm/stmusbd/usbd_cdc_vcp.h diff --git a/stm/lib/usbd_conf.h b/stm/stmusbd/usbd_conf.h similarity index 100% rename from stm/lib/usbd_conf.h rename to stm/stmusbd/usbd_conf.h diff --git a/stm/lib/usbd_core.c b/stm/stmusbd/usbd_core.c similarity index 100% rename from stm/lib/usbd_core.c rename to stm/stmusbd/usbd_core.c diff --git a/stm/lib/usbd_core.h b/stm/stmusbd/usbd_core.h similarity index 100% rename from stm/lib/usbd_core.h rename to stm/stmusbd/usbd_core.h diff --git a/stm/lib/usbd_def.h b/stm/stmusbd/usbd_def.h similarity index 100% rename from stm/lib/usbd_def.h rename to stm/stmusbd/usbd_def.h diff --git a/stm/lib/usbd_desc.c b/stm/stmusbd/usbd_desc.c similarity index 100% rename from stm/lib/usbd_desc.c rename to stm/stmusbd/usbd_desc.c diff --git a/stm/lib/usbd_desc.h b/stm/stmusbd/usbd_desc.h similarity index 100% rename from stm/lib/usbd_desc.h rename to stm/stmusbd/usbd_desc.h diff --git a/stm/lib/usbd_ioreq.c b/stm/stmusbd/usbd_ioreq.c similarity index 100% rename from stm/lib/usbd_ioreq.c rename to stm/stmusbd/usbd_ioreq.c diff --git a/stm/lib/usbd_ioreq.h b/stm/stmusbd/usbd_ioreq.h similarity index 100% rename from stm/lib/usbd_ioreq.h rename to stm/stmusbd/usbd_ioreq.h diff --git a/stm/lib/usbd_msc_bot.c b/stm/stmusbd/usbd_msc_bot.c similarity index 100% rename from stm/lib/usbd_msc_bot.c rename to stm/stmusbd/usbd_msc_bot.c diff --git a/stm/lib/usbd_msc_bot.h b/stm/stmusbd/usbd_msc_bot.h similarity index 100% rename from stm/lib/usbd_msc_bot.h rename to stm/stmusbd/usbd_msc_bot.h diff --git a/stm/lib/usbd_msc_data.c b/stm/stmusbd/usbd_msc_data.c similarity index 100% rename from stm/lib/usbd_msc_data.c rename to stm/stmusbd/usbd_msc_data.c diff --git a/stm/lib/usbd_msc_data.h b/stm/stmusbd/usbd_msc_data.h similarity index 100% rename from stm/lib/usbd_msc_data.h rename to stm/stmusbd/usbd_msc_data.h diff --git a/stm/lib/usbd_msc_mem.h b/stm/stmusbd/usbd_msc_mem.h similarity index 100% rename from stm/lib/usbd_msc_mem.h rename to stm/stmusbd/usbd_msc_mem.h diff --git a/stm/lib/usbd_msc_scsi.c b/stm/stmusbd/usbd_msc_scsi.c similarity index 100% rename from stm/lib/usbd_msc_scsi.c rename to stm/stmusbd/usbd_msc_scsi.c diff --git a/stm/lib/usbd_msc_scsi.h b/stm/stmusbd/usbd_msc_scsi.h similarity index 100% rename from stm/lib/usbd_msc_scsi.h rename to stm/stmusbd/usbd_msc_scsi.h diff --git a/stm/lib/usbd_pyb_core.c b/stm/stmusbd/usbd_pyb_core.c similarity index 100% rename from stm/lib/usbd_pyb_core.c rename to stm/stmusbd/usbd_pyb_core.c diff --git a/stm/lib/usbd_pyb_core.h b/stm/stmusbd/usbd_pyb_core.h similarity index 100% rename from stm/lib/usbd_pyb_core.h rename to stm/stmusbd/usbd_pyb_core.h diff --git a/stm/lib/usbd_pyb_core2.c b/stm/stmusbd/usbd_pyb_core2.c similarity index 100% rename from stm/lib/usbd_pyb_core2.c rename to stm/stmusbd/usbd_pyb_core2.c diff --git a/stm/lib/usbd_req.c b/stm/stmusbd/usbd_req.c similarity index 100% rename from stm/lib/usbd_req.c rename to stm/stmusbd/usbd_req.c diff --git a/stm/lib/usbd_req.h b/stm/stmusbd/usbd_req.h similarity index 100% rename from stm/lib/usbd_req.h rename to stm/stmusbd/usbd_req.h diff --git a/stm/lib/usbd_storage_msd.c b/stm/stmusbd/usbd_storage_msd.c similarity index 100% rename from stm/lib/usbd_storage_msd.c rename to stm/stmusbd/usbd_storage_msd.c diff --git a/stm/lib/usbd_usr.c b/stm/stmusbd/usbd_usr.c similarity index 99% rename from stm/lib/usbd_usr.c rename to stm/stmusbd/usbd_usr.c index a5a7fb7ffb..daa2ddbcbd 100644 --- a/stm/lib/usbd_usr.c +++ b/stm/stmusbd/usbd_usr.c @@ -27,7 +27,6 @@ #include "usbd_usr.h" #include "usbd_ioreq.h" -#include "std.h" USBD_Usr_cb_TypeDef USR_cb = { USBD_USR_Init, diff --git a/stm/lib/usbd_usr.h b/stm/stmusbd/usbd_usr.h similarity index 100% rename from stm/lib/usbd_usr.h rename to stm/stmusbd/usbd_usr.h diff --git a/stm/stmusbh/usbh_conf.h b/stm/stmusbh/usbh_conf.h new file mode 100644 index 0000000000..51a780ae4b --- /dev/null +++ b/stm/stmusbh/usbh_conf.h @@ -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 + * + *

© COPYRIGHT 2012 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USBH_CONF__H__ +#define __USBH_CONF__H__ + +/* 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****/ + diff --git a/stm/stmusbh/usbh_core.c b/stm/stmusbh/usbh_core.c new file mode 100644 index 0000000000..a90851ccb5 --- /dev/null +++ b/stm/stmusbh/usbh_core.c @@ -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 + * + *

© COPYRIGHT 2012 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ +/* Includes ------------------------------------------------------------------*/ + +#include "usbh_ioreq.h" +#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****/ + + + + diff --git a/stm/stmusbh/usbh_core.h b/stm/stmusbh/usbh_core.h new file mode 100644 index 0000000000..c73ba612b3 --- /dev/null +++ b/stm/stmusbh/usbh_core.h @@ -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 + * + *

© COPYRIGHT 2012 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Define to prevent recursive ----------------------------------------------*/ +#ifndef __USBH_CORE_H +#define __USBH_CORE_H + +/* Includes ------------------------------------------------------------------*/ +#include "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****/ + + + diff --git a/stm/stmusbh/usbh_def.h b/stm/stmusbh/usbh_def.h new file mode 100644 index 0000000000..27a102a0e7 --- /dev/null +++ b/stm/stmusbh/usbh_def.h @@ -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 + * + *

© COPYRIGHT 2012 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/** @addtogroup USBH_LIB + * @{ + */ + +/** @addtogroup USBH_LIB_CORE +* @{ +*/ + +/** @defgroup USBH_DEF + * @brief This file is includes USB descriptors + * @{ + */ + +#ifndef USBH_DEF_H +#define USBH_DEF_H + +#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****/ + diff --git a/stm/stmusbh/usbh_hcs.c b/stm/stmusbh/usbh_hcs.c new file mode 100644 index 0000000000..fd53df6f69 --- /dev/null +++ b/stm/stmusbh/usbh_hcs.c @@ -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 + * + *

© COPYRIGHT 2012 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbh_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****/ + + diff --git a/stm/stmusbh/usbh_hcs.h b/stm/stmusbh/usbh_hcs.h new file mode 100644 index 0000000000..af264017d0 --- /dev/null +++ b/stm/stmusbh/usbh_hcs.h @@ -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 + * + *

© COPYRIGHT 2012 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Define to prevent recursive ----------------------------------------------*/ +#ifndef __USBH_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****/ + + diff --git a/stm/stmusbh/usbh_hid_core.c b/stm/stmusbh/usbh_hid_core.c new file mode 100644 index 0000000000..a60038d2bc --- /dev/null +++ b/stm/stmusbh/usbh_hid_core.c @@ -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 + * + *

© COPYRIGHT 2012 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbh_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****/ diff --git a/stm/stmusbh/usbh_hid_core.h b/stm/stmusbh/usbh_hid_core.h new file mode 100644 index 0000000000..d2e8fb8475 --- /dev/null +++ b/stm/stmusbh/usbh_hid_core.h @@ -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 + * + *

© COPYRIGHT 2012 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Define to prevent recursive ----------------------------------------------*/ +#ifndef __USBH_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****/ + diff --git a/stm/stmusbh/usbh_hid_keybd.c b/stm/stmusbh/usbh_hid_keybd.c new file mode 100644 index 0000000000..089362a34c --- /dev/null +++ b/stm/stmusbh/usbh_hid_keybd.c @@ -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 + * + *

© COPYRIGHT 2012 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + + +/* Includes ------------------------------------------------------------------*/ +#include "usbh_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****/ + diff --git a/stm/stmusbh/usbh_hid_keybd.h b/stm/stmusbh/usbh_hid_keybd.h new file mode 100644 index 0000000000..a8b34dab2a --- /dev/null +++ b/stm/stmusbh/usbh_hid_keybd.h @@ -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 + * + *

© COPYRIGHT 2012 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Define to prevent recursive -----------------------------------------------*/ +#ifndef __USBH_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****/ + diff --git a/stm/stmusbh/usbh_hid_mouse.c b/stm/stmusbh/usbh_hid_mouse.c new file mode 100644 index 0000000000..ffb9f5f267 --- /dev/null +++ b/stm/stmusbh/usbh_hid_mouse.c @@ -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 + * + *

© COPYRIGHT 2012 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbh_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****/ diff --git a/stm/stmusbh/usbh_hid_mouse.h b/stm/stmusbh/usbh_hid_mouse.h new file mode 100644 index 0000000000..93ed6bed2c --- /dev/null +++ b/stm/stmusbh/usbh_hid_mouse.h @@ -0,0 +1,120 @@ +/** + ****************************************************************************** + * @file usbh_hid_mouse.h + * @author MCD Application Team + * @version V2.1.0 + * @date 19-March-2012 + * @brief This file contains all the prototypes for the usbh_hid_mouse.c + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2012 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + + +/* Define to prevent recursive ----------------------------------------------*/ +#ifndef __USBH_HID_MOUSE_H +#define __USBH_HID_MOUSE_H + +/* Includes ------------------------------------------------------------------*/ +#include "usbh_hid_core.h" + +/** @addtogroup USBH_LIB + * @{ + */ + +/** @addtogroup USBH_CLASS + * @{ + */ + +/** @addtogroup USBH_HID_CLASS + * @{ + */ + +/** @defgroup USBH_HID_MOUSE + * @brief This file is the Header file for USBH_HID_MOUSE.c + * @{ + */ + + +/** @defgroup USBH_HID_MOUSE_Exported_Types + * @{ + */ +typedef struct _HID_MOUSE_Data +{ + uint8_t x; + uint8_t y; + uint8_t z; /* Not Supported */ + uint8_t button; +} +HID_MOUSE_Data_TypeDef; + +/** + * @} + */ + +/** @defgroup USBH_HID_MOUSE_Exported_Defines + * @{ + */ +/** + * @} + */ + +/** @defgroup USBH_HID_MOUSE_Exported_Macros + * @{ + */ +/** + * @} + */ + +/** @defgroup USBH_HID_MOUSE_Exported_Variables + * @{ + */ + +extern HID_cb_TypeDef HID_MOUSE_cb; +extern HID_MOUSE_Data_TypeDef HID_MOUSE_Data; +/** + * @} + */ + +/** @defgroup USBH_HID_MOUSE_Exported_FunctionsPrototype + * @{ + */ +void USR_MOUSE_Init (void); +void USR_MOUSE_ProcessData (HID_MOUSE_Data_TypeDef *data); +/** + * @} + */ + +#endif /* __USBH_HID_MOUSE_H */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/stm/stmusbh/usbh_ioreq.c b/stm/stmusbh/usbh_ioreq.c new file mode 100644 index 0000000000..21f480d7bc --- /dev/null +++ b/stm/stmusbh/usbh_ioreq.c @@ -0,0 +1,474 @@ +/** + ****************************************************************************** + * @file usbh_ioreq.c + * @author MCD Application Team + * @version V2.1.0 + * @date 19-March-2012 + * @brief This file handles the issuing of the USB transactions + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2012 STMicroelectronics

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

© COPYRIGHT 2012 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Define to prevent recursive ----------------------------------------------*/ +#ifndef __USBH_IOREQ_H +#define __USBH_IOREQ_H + +/* Includes ------------------------------------------------------------------*/ +#include "usb_conf.h" +#include "usbh_core.h" +#include "usbh_def.h" + +/** @addtogroup USBH_LIB + * @{ + */ + +/** @addtogroup USBH_LIB_CORE +* @{ +*/ + +/** @defgroup USBH_IOREQ + * @brief This file is the header file for usbh_ioreq.c + * @{ + */ + + +/** @defgroup USBH_IOREQ_Exported_Defines + * @{ + */ +#define USBH_SETUP_PKT_SIZE 8 +#define USBH_EP0_EP_NUM 0 +#define USBH_MAX_PACKET_SIZE 0x40 +/** + * @} + */ + + +/** @defgroup USBH_IOREQ_Exported_Types + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBH_IOREQ_Exported_Macros + * @{ + */ +/** + * @} + */ + +/** @defgroup USBH_IOREQ_Exported_Variables + * @{ + */ +/** + * @} + */ + +/** @defgroup USBH_IOREQ_Exported_FunctionsPrototype + * @{ + */ +USBH_Status USBH_CtlSendSetup ( USB_OTG_CORE_HANDLE *pdev, + uint8_t *buff, + uint8_t hc_num); + +USBH_Status USBH_CtlSendData ( USB_OTG_CORE_HANDLE *pdev, + uint8_t *buff, + uint16_t length, + uint8_t hc_num); + +USBH_Status USBH_CtlReceiveData( USB_OTG_CORE_HANDLE *pdev, + uint8_t *buff, + uint16_t length, + uint8_t hc_num); + +USBH_Status USBH_BulkReceiveData( USB_OTG_CORE_HANDLE *pdev, + uint8_t *buff, + uint16_t length, + uint8_t hc_num); + +USBH_Status USBH_BulkSendData ( USB_OTG_CORE_HANDLE *pdev, + uint8_t *buff, + uint16_t length, + uint8_t hc_num); + +USBH_Status USBH_InterruptReceiveData( USB_OTG_CORE_HANDLE *pdev, + uint8_t *buff, + uint8_t length, + uint8_t hc_num); + +USBH_Status USBH_InterruptSendData( USB_OTG_CORE_HANDLE *pdev, + uint8_t *buff, + uint8_t length, + uint8_t hc_num); + +USBH_Status USBH_CtlReq (USB_OTG_CORE_HANDLE *pdev, + USBH_HOST *phost, + uint8_t *buff, + uint16_t length); + +USBH_Status USBH_IsocReceiveData( USB_OTG_CORE_HANDLE *pdev, + uint8_t *buff, + uint32_t length, + uint8_t hc_num); + + +USBH_Status USBH_IsocSendData( USB_OTG_CORE_HANDLE *pdev, + uint8_t *buff, + uint32_t length, + uint8_t hc_num); +/** + * @} + */ + +#endif /* __USBH_IOREQ_H */ + +/** + * @} + */ + +/** + * @} + */ + +/** +* @} +*/ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + + diff --git a/stm/stmusbh/usbh_stdreq.c b/stm/stmusbh/usbh_stdreq.c new file mode 100644 index 0000000000..9b134fa024 --- /dev/null +++ b/stm/stmusbh/usbh_stdreq.c @@ -0,0 +1,607 @@ +/** + ****************************************************************************** + * @file usbh_stdreq.c + * @author MCD Application Team + * @version V2.1.0 + * @date 19-March-2012 + * @brief This file implements the standard requests for device enumeration + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2012 STMicroelectronics

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

© COPYRIGHT 2012 STMicroelectronics

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

© COPYRIGHT 2012 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include + +#include "usbh_usr.h" +#include "usbh_hid_mouse.h" +#include "usbh_hid_keybd.h" + +extern void led_state(int, int); + +/** @addtogroup USBH_USER +* @{ +*/ + +/** @addtogroup USBH_HID_DEMO_USER_CALLBACKS +* @{ +*/ + +/** @defgroup USBH_USR +* @brief This file is the Header file for usbh_usr.c +* @{ +*/ + + +/** +* @} +*/ + +/** @addtogroup USER +* @{ +*/ + +/** @defgroup USBH_USR +* @brief This file includes the user application layer +* @{ +*/ + +/** @defgroup USBH_CORE_Exported_Types +* @{ +*/ + + + +/** @defgroup USBH_USR_Private_Defines +* @{ +*/ +/** +* @} +*/ + + +/** @defgroup USBH_USR_Private_Macros +* @{ +*/ +/** +* @} +*/ + +/** @defgroup USBH_USR_Private_Variables +* @{ +*/ +/* Points to the DEVICE_PROP structure of current device */ +/* The purpose of this register is to speed up the execution */ + +USBH_Usr_cb_TypeDef USR_Callbacks = +{ + USBH_USR_Init, + USBH_USR_DeInit, + USBH_USR_DeviceAttached, + USBH_USR_ResetDevice, + USBH_USR_DeviceDisconnected, + USBH_USR_OverCurrentDetected, + USBH_USR_DeviceSpeedDetected, + USBH_USR_Device_DescAvailable, + USBH_USR_DeviceAddressAssigned, + USBH_USR_Configuration_DescAvailable, + USBH_USR_Manufacturer_String, + USBH_USR_Product_String, + USBH_USR_SerialNum_String, + USBH_USR_EnumerationDone, + USBH_USR_UserInput, + NULL, + USBH_USR_DeviceNotSupported, + USBH_USR_UnrecoveredError +}; + +/** +* @} +*/ + +/** @defgroup USBH_USR_Private_Constants +* @{ +*/ + +/** +* @} +*/ + + + +/** @defgroup USBH_USR_Private_FunctionPrototypes +* @{ +*/ +/** +* @} +*/ + + +/** @defgroup USBH_USR_Private_Functions +* @{ +*/ + + + + + +/** +* @brief USBH_USR_Init +* Displays the message on LCD for host lib initialization +* @param None +* @retval None +*/ +void USBH_USR_Init(void) +{ + static uint8_t startup = 0; + + if (startup == 0) { + startup = 1; + + printf("USB Host library started.\n"); + } +} + +/** +* @brief USBH_USR_DeviceAttached +* Displays the message on LCD on device attached +* @param None +* @retval None +*/ +void USBH_USR_DeviceAttached(void) { + led_state(1, 1); + USB_OTG_BSP_mDelay(900); +} + +/** +* @brief USBH_USR_UnrecoveredError +* @param None +* @retval None +*/ +void USBH_USR_UnrecoveredError(void) { +} + +/** +* @brief USBH_DisconnectEvent +* Device disconnect event +* @param None +* @retval None +*/ +void USBH_USR_DeviceDisconnected (void) +{ + led_state(1, 0); + led_state(2, 0); + led_state(3, 0); + led_state(4, 0); + USB_OTG_BSP_mDelay(100); +} + +/** +* @brief USBH_USR_ResetUSBDevice +* Reset USB Device +* @param None +* @retval None +*/ +void USBH_USR_ResetDevice(void) +{ + /* Users can do their application actions here for the USB-Reset */ + led_state(3, 1); + USB_OTG_BSP_mDelay(100); + led_state(3, 0); +} + + +/** +* @brief USBH_USR_DeviceSpeedDetected +* Displays the message on LCD for device speed +* @param Devicespeed : Device Speed +* @retval None +*/ +void USBH_USR_DeviceSpeedDetected(uint8_t DeviceSpeed) +{ + /* + if(DeviceSpeed == HPRT0_PRTSPD_HIGH_SPEED) + { + printf(MSG_DEV_HIGHSPEED); + } + else if(DeviceSpeed == HPRT0_PRTSPD_FULL_SPEED) + { + printf(MSG_DEV_FULLSPEED); + } + else if(DeviceSpeed == HPRT0_PRTSPD_LOW_SPEED) + { + printf(MSG_DEV_LOWSPEED); + } + else + { + printf(MSG_DEV_ERROR); + } + */ +} + +/** +* @brief USBH_USR_Device_DescAvailable +* Displays the message on LCD for device descriptor +* @param DeviceDesc : device descriptor +* @retval None +*/ +void USBH_USR_Device_DescAvailable(void *DeviceDesc) +{ + /* + USBH_DevDesc_TypeDef *hs; + hs = DeviceDesc; + + printf("VID : %04Xh\n" , (unsigned int)(*hs).idVendor); + printf("PID : %04Xh\n" , (unsigned int)(*hs).idProduct); + */ +} + +/** +* @brief USBH_USR_DeviceAddressAssigned +* USB device is successfully assigned the Address +* @param None +* @retval None +*/ +void USBH_USR_DeviceAddressAssigned(void) +{ + +} + + +/** +* @brief USBH_USR_Conf_Desc +* Displays the message on LCD for configuration descriptor +* @param ConfDesc : Configuration descriptor +* @retval None +*/ +void USBH_USR_Configuration_DescAvailable(USBH_CfgDesc_TypeDef * cfgDesc, + USBH_InterfaceDesc_TypeDef *itfDesc, + USBH_EpDesc_TypeDef *epDesc) +{ + /* + USBH_InterfaceDesc_TypeDef *id; + + id = itfDesc; + + if((*id).bInterfaceClass == 0x08) + { + printf(MSG_MSC_CLASS); + } + else if((*id).bInterfaceClass == 0x03) + { + printf(MSG_HID_CLASS); + } + */ +} + +/** +* @brief USBH_USR_Manufacturer_String +* Displays the message on LCD for Manufacturer String +* @param ManufacturerString : Manufacturer String of Device +* @retval None +*/ +void USBH_USR_Manufacturer_String(void *ManufacturerString) { +} + +/** +* @brief USBH_USR_Product_String +* Displays the message on LCD for Product String +* @param ProductString : Product String of Device +* @retval None +*/ +void USBH_USR_Product_String(void *ProductString) { +} + +/** +* @brief USBH_USR_SerialNum_String +* Displays the message on LCD for SerialNum_String +* @param SerialNumString : SerialNum_String of device +* @retval None +*/ +void USBH_USR_SerialNum_String(void *SerialNumString) { +} + +/** +* @brief EnumerationDone +* User response request is displayed to ask for +* application jump to class +* @param None +* @retval None +*/ +void USBH_USR_EnumerationDone(void) { + /* Enumeration complete */ + led_state(2, 1); + USB_OTG_BSP_mDelay(500); +} + +/** +* @brief USBH_USR_DeviceNotSupported +* Device is not supported +* @param None +* @retval None +*/ +void USBH_USR_DeviceNotSupported(void){ +} + + +/** +* @brief USBH_USR_UserInput +* User Action for application state entry +* @param None +* @retval USBH_USR_Status : User response for key button +*/ +USBH_USR_Status USBH_USR_UserInput(void) { + return USBH_USR_RESP_OK; +} + +/** +* @brief USBH_USR_OverCurrentDetected +* Device Overcurrent detection event +* @param None +* @retval None +*/ +void USBH_USR_OverCurrentDetected(void) { +} + +/** +* @brief USBH_USR_DeInit +* Deint User state and associated variables +* @param None +* @retval None +*/ +void USBH_USR_DeInit(void) +{ +} + +/** +* @} +*/ + +/** +* @} +*/ + +/** +* @} +*/ + +/** +* @} +*/ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/stm/stmusbh/usbh_usr.h b/stm/stmusbh/usbh_usr.h new file mode 100644 index 0000000000..fa8201ad3c --- /dev/null +++ b/stm/stmusbh/usbh_usr.h @@ -0,0 +1,107 @@ +/** + ****************************************************************************** + * @file usbh_usr.h + * @author MCD Application Team + * @version V2.1.0 + * @date 19-March-2012 + * @brief This file is the header file for usb usr file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2012 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USH_USR_H__ +#define __USH_USR_H__ + + +/* Includes ------------------------------------------------------------------*/ +#include "usbh_core.h" +#include "usb_conf.h" +#include + +/** @addtogroup USBH_USER +* @{ +*/ + +/** @addtogroup USBH_HID_DEMO_USER_CALLBACKS +* @{ +*/ + +/** @defgroup USBH_USR + * @brief This file is the header file for user action + * @{ + */ + + +/** @defgroup USBH_CORE_Exported_Variables + * @{ + */ + + +extern USBH_Usr_cb_TypeDef USR_Callbacks; + + +/** + * @} + */ + + +/** @defgroup USBH_CORE_Exported_FunctionsPrototype + * @{ + */ + +void USBH_USR_ApplicationSelected(void); +void USBH_USR_Init(void); +void USBH_USR_DeInit(void); +void USBH_USR_DeviceAttached(void); +void USBH_USR_ResetDevice(void); +void USBH_USR_DeviceDisconnected (void); +void USBH_USR_OverCurrentDetected (void); +void USBH_USR_DeviceSpeedDetected(uint8_t DeviceSpeed); +void USBH_USR_Device_DescAvailable(void *); +void USBH_USR_DeviceAddressAssigned(void); +void USBH_USR_Configuration_DescAvailable(USBH_CfgDesc_TypeDef * cfgDesc, + USBH_InterfaceDesc_TypeDef *itfDesc, + USBH_EpDesc_TypeDef *epDesc); +void USBH_USR_Manufacturer_String(void *); +void USBH_USR_Product_String(void *); +void USBH_USR_SerialNum_String(void *); +void USBH_USR_EnumerationDone(void); +USBH_USR_Status USBH_USR_UserInput(void); +void USBH_USR_DeInit(void); +void USBH_USR_DeviceNotSupported(void); +void USBH_USR_UnrecoveredError(void); +/** + * @} + */ + +#endif /* __USBH_USR_H */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/stm/usb.c b/stm/usb.c index 769e6a53aa..802a70c6d0 100644 --- a/stm/usb.c +++ b/stm/usb.c @@ -17,32 +17,32 @@ extern CDC_IF_Prop_TypeDef VCP_fops; #endif -USB_OTG_CORE_HANDLE USB_OTG_dev; +USB_OTG_CORE_HANDLE USB_OTG_Core; -static int is_enabled = 0; +static int dev_is_enabled = 0; static char rx_buf[64]; static int rx_buf_in; static int rx_buf_out; -void usb_init(void) { - if (!is_enabled) { - // only init USB once in the device's power-lifetime +void pyb_usb_dev_init(void) { #ifdef USE_DEVICE_MODE - USBD_Init(&USB_OTG_dev, USB_OTG_FS_CORE_ID, &USR_desc, &USBD_PYB_cb, &USR_cb); - //USBD_Init(&USB_OTG_dev, USB_OTG_FS_CORE_ID, &USR_desc, &USBD_PYB_HID_cb, &USR_cb); -#endif + if (!dev_is_enabled) { + // only init USB once in the device's power-lifetime + USBD_Init(&USB_OTG_Core, USB_OTG_FS_CORE_ID, &USR_desc, &USBD_PYB_cb, &USR_cb); + //USBD_Init(&USB_OTG_Core, USB_OTG_FS_CORE_ID, &USR_desc, &USBD_PYB_HID_cb, &USR_cb); } rx_buf_in = 0; rx_buf_out = 0; - is_enabled = 1; + dev_is_enabled = 1; +#endif } bool usb_vcp_is_enabled(void) { - return is_enabled; + return dev_is_enabled; } void usb_vcp_receive(const char *buf, uint32_t len) { - if (is_enabled) { + if (dev_is_enabled) { for (int i = 0; i < len; i++) { rx_buf[rx_buf_in++] = buf[i]; if (rx_buf_in >= sizeof(rx_buf)) { @@ -82,11 +82,11 @@ void usb_vcp_send_str(const char *str) { } void usb_vcp_send_strn(const char *str, int len) { - if (is_enabled) { #ifdef USE_DEVICE_MODE + if (dev_is_enabled) { VCP_fops.pIf_DataTx((const uint8_t*)str, len); -#endif } +#endif } #include "usbd_conf.h" @@ -117,7 +117,7 @@ void usb_vcp_send_strn_cooked(const char *str, int len) { void usb_hid_send_report(uint8_t *buf) { #ifdef USE_DEVICE_MODE - USBD_HID_SendReport(&USB_OTG_dev, buf, 4); + USBD_HID_SendReport(&USB_OTG_Core, buf, 4); #endif } @@ -126,45 +126,63 @@ void usb_hid_send_report(uint8_t *buf) { #ifdef USE_HOST_MODE -#include "lib-otg/usbh_core.h" -#include "lib-otg/usbh_usr.h" -#include "lib-otg/usbh_hid_core.h" -#include "lib-otg/usb_hcd_int.h" +#include "led.h" +#include "usbh_core.h" +#include "usbh_usr.h" +#include "usbh_hid_core.h" +#include "usbh_hid_keybd.h" +#include "usbh_hid_mouse.h" __ALIGN_BEGIN USBH_HOST USB_Host __ALIGN_END ; static int host_is_enabled = 0; -void pyb_usbh_init(void) { + +void pyb_usb_host_init(void) { if (!host_is_enabled) { // only init USBH once in the device's power-lifetime /* Init Host Library */ - USBH_Init(&USB_OTG_dev, USB_OTG_FS_CORE_ID, &USB_Host, &HID_cb, &USR_Callbacks); + USBH_Init(&USB_OTG_Core, USB_OTG_FS_CORE_ID, &USB_Host, &HID_cb, &USR_Callbacks); } host_is_enabled = 1; } -mp_obj_t pyb_usbh_process(void) { - USBH_Process(&USB_OTG_dev, &USB_Host); - return mp_const_none; +void pyb_usb_host_process(void) { + USBH_Process(&USB_OTG_Core, &USB_Host); } -mp_obj_t pyb_usbh_connect(void) { - USBH_HCD_INT_fops->DevConnected(&USB_OTG_dev); - return mp_const_none; +uint8_t usb_keyboard_key = 0; + +// TODO this is an ugly hack to get key presses +uint pyb_usb_host_get_keyboard(void) { + uint key = usb_keyboard_key; + usb_keyboard_key = 0; + return key; } -mp_obj_t pyb_usbh_info(void) { - printf("GOTGCTL:%08x\n", (unsigned int)USB_OTG_dev.regs.GREGS->GOTGCTL); - printf("GOTGINT:%08x\n", (unsigned int)USB_OTG_dev.regs.GREGS->GOTGINT); - printf("GAHBCFG:%08x\n", (unsigned int)USB_OTG_dev.regs.GREGS->GAHBCFG); - printf("GUSBCFG:%08x\n", (unsigned int)USB_OTG_dev.regs.GREGS->GUSBCFG); - printf("GRSTCTL:%08x\n", (unsigned int)USB_OTG_dev.regs.GREGS->GRSTCTL); - printf("GINTSTS:%08x\n", (unsigned int)USB_OTG_dev.regs.GREGS->GINTSTS); - printf("GINTMSK:%08x\n", (unsigned int)USB_OTG_dev.regs.GREGS->GINTMSK); - //printf("GRXSTSR:%08x\n", (unsigned int)USB_OTG_dev.regs.GREGS->GRXSTSR); - //printf("GRXSTSP:%08x\n", (unsigned int)USB_OTG_dev.regs.GREGS->GRXSTSP); - //printf("GRXFSIZ:%08x\n", (unsigned int)USB_OTG_dev.regs.GREGS->GRXFSIZ); - return mp_const_none; +void USR_MOUSE_Init(void) { + led_state(4, 1); + USB_OTG_BSP_mDelay(100); + led_state(4, 0); +} + +void USR_MOUSE_ProcessData(HID_MOUSE_Data_TypeDef *data) { + led_state(4, 1); + USB_OTG_BSP_mDelay(50); + led_state(4, 0); +} + +void USR_KEYBRD_Init(void) { + led_state(4, 1); + USB_OTG_BSP_mDelay(100); + led_state(4, 0); +} + +void USR_KEYBRD_ProcessData(uint8_t pbuf) { + led_state(4, 1); + USB_OTG_BSP_mDelay(50); + led_state(4, 0); + //lcd_print_strn((char*)&pbuf, 1); + usb_keyboard_key = pbuf; } #endif // USE_HOST_MODE diff --git a/stm/usb.h b/stm/usb.h index 68954af636..c3b39ca846 100644 --- a/stm/usb.h +++ b/stm/usb.h @@ -1,4 +1,4 @@ -void usb_init(void); +void pyb_usb_dev_init(void); bool usb_vcp_is_enabled(void); int usb_vcp_rx_any(void); char usb_vcp_rx_get(void); @@ -7,7 +7,6 @@ void usb_vcp_send_strn(const char* str, int len); void usb_vcp_send_strn_cooked(const char *str, int len); void usb_hid_send_report(uint8_t *buf); // 4 bytes for mouse: ?, x, y, ? -void pyb_usbh_init(void); -mp_obj_t pyb_usbh_process(void); -mp_obj_t pyb_usbh_connect(void); -mp_obj_t pyb_usbh_info(void); +void pyb_usb_host_init(void); +void pyb_usb_host_process(void); +uint pyb_usb_host_get_keyboard(void);