diff options
40 files changed, 4217 insertions, 813 deletions
@@ -4,6 +4,16 @@ typedef enum { MP_VM_RETURN_EXCEPTION, } mp_vm_return_kind_t; +// Exception stack entry +typedef struct _mp_exc_stack { + const byte *handler; + // bit 0 is saved currently_in_except_block value + machine_uint_t val_sp; + // We might only have 2 interesting cases here: SETUP_EXCEPT & SETUP_FINALLY, + // consider storing it in bit 1 of val_sp. TODO: SETUP_WITH? + byte opcode; +} mp_exc_stack; + mp_vm_return_kind_t mp_execute_byte_code(const byte *code, const mp_obj_t *args, uint n_args, const mp_obj_t *args2, uint n_args2, uint n_state, mp_obj_t *ret); -mp_vm_return_kind_t mp_execute_byte_code_2(const byte *code_info, const byte **ip_in_out, mp_obj_t *fastn, mp_obj_t **sp_in_out); +mp_vm_return_kind_t mp_execute_byte_code_2(const byte *code_info, const byte **ip_in_out, mp_obj_t *fastn, mp_obj_t **sp_in_out, mp_exc_stack *exc_stack, mp_exc_stack **exc_sp_in_out, volatile mp_obj_t inject_exc); void mp_byte_code_print(const byte *code, int len); diff --git a/py/objgenerator.c b/py/objgenerator.c index 8c4bb595f1..2db04ad742 100644 --- a/py/objgenerator.c +++ b/py/objgenerator.c @@ -56,8 +56,10 @@ typedef struct _mp_obj_gen_instance_t { const byte *code_info; const byte *ip; mp_obj_t *sp; + mp_exc_stack *exc_sp; uint n_state; - mp_obj_t state[]; + mp_obj_t state[0]; // Variable-length + mp_exc_stack exc_state[0]; // Variable-length } mp_obj_gen_instance_t; void gen_instance_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) { @@ -68,7 +70,7 @@ mp_obj_t gen_instance_getiter(mp_obj_t self_in) { return self_in; } -STATIC mp_obj_t gen_next_send(mp_obj_t self_in, mp_obj_t send_value) { +STATIC mp_obj_t gen_resume(mp_obj_t self_in, mp_obj_t send_value, mp_obj_t throw_value) { mp_obj_gen_instance_t *self = self_in; if (self->ip == 0) { return mp_const_stop_iteration; @@ -80,7 +82,9 @@ STATIC mp_obj_t gen_next_send(mp_obj_t self_in, mp_obj_t send_value) { } else { *self->sp = send_value; } - mp_vm_return_kind_t vm_return_kind = mp_execute_byte_code_2(self->code_info, &self->ip, &self->state[self->n_state - 1], &self->sp); + mp_vm_return_kind_t vm_return_kind = mp_execute_byte_code_2(self->code_info, &self->ip, + &self->state[self->n_state - 1], &self->sp, (mp_exc_stack*)(self->state + self->n_state), + &self->exc_sp, throw_value); switch (vm_return_kind) { case MP_VM_RETURN_NORMAL: // Explicitly mark generator as completed. If we don't do this, @@ -100,19 +104,21 @@ STATIC mp_obj_t gen_next_send(mp_obj_t self_in, mp_obj_t send_value) { return *self->sp; case MP_VM_RETURN_EXCEPTION: + self->ip = 0; + nlr_jump(self->state[self->n_state - 1]); + default: - // TODO assert(0); return mp_const_none; } } mp_obj_t gen_instance_iternext(mp_obj_t self_in) { - return gen_next_send(self_in, mp_const_none); + return gen_resume(self_in, mp_const_none, MP_OBJ_NULL); } STATIC mp_obj_t gen_instance_send(mp_obj_t self_in, mp_obj_t send_value) { - mp_obj_t ret = gen_next_send(self_in, send_value); + mp_obj_t ret = gen_resume(self_in, send_value, MP_OBJ_NULL); if (ret == mp_const_stop_iteration) { nlr_jump(mp_obj_new_exception(&mp_type_StopIteration)); } else { @@ -122,8 +128,21 @@ STATIC mp_obj_t gen_instance_send(mp_obj_t self_in, mp_obj_t send_value) { STATIC MP_DEFINE_CONST_FUN_OBJ_2(gen_instance_send_obj, gen_instance_send); +STATIC mp_obj_t gen_instance_throw(uint n_args, const mp_obj_t *args) { + mp_obj_t ret = gen_resume(args[0], mp_const_none, n_args == 2 ? args[1] : args[2]); + if (ret == mp_const_stop_iteration) { + nlr_jump(mp_obj_new_exception(&mp_type_StopIteration)); + } else { + return ret; + } +} + +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(gen_instance_throw_obj, 2, 4, gen_instance_throw); + + STATIC const mp_method_t gen_type_methods[] = { { "send", &gen_instance_send_obj }, + { "throw", &gen_instance_throw_obj }, { NULL, NULL }, // end-of-list sentinel }; @@ -137,11 +156,13 @@ const mp_obj_type_t gen_instance_type = { }; mp_obj_t mp_obj_new_gen_instance(const byte *bytecode, uint n_state, int n_args, const mp_obj_t *args) { - mp_obj_gen_instance_t *o = m_new_obj_var(mp_obj_gen_instance_t, mp_obj_t, n_state); + // TODO: 4 is hardcoded number from vm.c, calc exc stack size instead. + mp_obj_gen_instance_t *o = m_new_obj_var(mp_obj_gen_instance_t, byte, n_state * sizeof(mp_obj_t) + 4 * sizeof(mp_exc_stack)); o->base.type = &gen_instance_type; o->code_info = bytecode; o->ip = bytecode; o->sp = &o->state[0] - 1; // sp points to top of stack, which starts off 1 below the state + o->exc_sp = (mp_exc_stack*)(o->state + n_state) - 1; o->n_state = n_state; // copy args to end of state array, in reverse (that's how mp_execute_byte_code_2 needs it) @@ -17,16 +17,6 @@ // top element. // Exception stack also grows up, top element is also pointed at. -// Exception stack entry -typedef struct _mp_exc_stack { - const byte *handler; - // bit 0 is saved currently_in_except_block value - machine_uint_t val_sp; - // We might only have 2 interesting cases here: SETUP_EXCEPT & SETUP_FINALLY, - // consider storing it in bit 1 of val_sp. TODO: SETUP_WITH? - byte opcode; -} mp_exc_stack; - // Exception stack unwind reasons (WHY_* in CPython-speak) // TODO perhaps compress this to RETURN=0, JUMP>0, with number of unwinds // left to do encoded in the JUMP number @@ -89,8 +79,10 @@ mp_vm_return_kind_t mp_execute_byte_code(const byte *code, const mp_obj_t *args, } } + mp_exc_stack exc_stack[4]; + mp_exc_stack *exc_sp = &exc_stack[0] - 1; // execute the byte code - mp_vm_return_kind_t vm_return_kind = mp_execute_byte_code_2(code, &ip, &state[n_state - 1], &sp); + mp_vm_return_kind_t vm_return_kind = mp_execute_byte_code_2(code, &ip, &state[n_state - 1], &sp, exc_stack, &exc_sp, MP_OBJ_NULL); switch (vm_return_kind) { case MP_VM_RETURN_NORMAL: @@ -113,7 +105,10 @@ mp_vm_return_kind_t mp_execute_byte_code(const byte *code, const mp_obj_t *args, // MP_VM_RETURN_NORMAL, sp valid, return value in *sp // MP_VM_RETURN_YIELD, ip, sp valid, yielded value in *sp // MP_VM_RETURN_EXCEPTION, exception in fastn[0] -mp_vm_return_kind_t mp_execute_byte_code_2(const byte *code_info, const byte **ip_in_out, mp_obj_t *fastn, mp_obj_t **sp_in_out) { +mp_vm_return_kind_t mp_execute_byte_code_2(const byte *code_info, const byte **ip_in_out, + mp_obj_t *fastn, mp_obj_t **sp_in_out, + mp_exc_stack *exc_stack, mp_exc_stack **exc_sp_in_out, + volatile mp_obj_t inject_exc) { // careful: be sure to declare volatile any variables read in the exception handler (written is ok, I think) const byte *ip = *ip_in_out; @@ -123,14 +118,21 @@ mp_vm_return_kind_t mp_execute_byte_code_2(const byte *code_info, const byte **i mp_obj_t obj1, obj2; nlr_buf_t nlr; - volatile machine_uint_t currently_in_except_block = 0; // 0 or 1, to detect nested exceptions - mp_exc_stack exc_stack[4]; - mp_exc_stack *volatile exc_sp = &exc_stack[0] - 1; // stack grows up, exc_sp points to top of stack + volatile machine_uint_t currently_in_except_block = (int)*exc_sp_in_out & 1; // 0 or 1, to detect nested exceptions + mp_exc_stack *volatile exc_sp = (void*)((int)*exc_sp_in_out & ~1); // stack grows up, exc_sp points to top of stack const byte *volatile save_ip = ip; // this is so we can access ip in the exception handler without making ip volatile (which means the compiler can't keep it in a register in the main loop) // outer exception handling loop for (;;) { if (nlr_push(&nlr) == 0) { + // If we have exception to inject, now that we finish setting up + // execution context, raise it. This works as if RAISE_VARARGS + // bytecode was executed. + if (inject_exc != MP_OBJ_NULL) { + mp_obj_t t = inject_exc; + inject_exc = MP_OBJ_NULL; + nlr_jump(rt_make_raise_obj(t)); + } // loop to execute byte code for (;;) { dispatch_loop: @@ -434,7 +436,7 @@ unwind_jump: // matched against: SETUP_EXCEPT, SETUP_FINALLY, SETUP_WITH case MP_BC_POP_BLOCK: // we are exiting an exception handler, so pop the last one of the exception-stack - assert(exc_sp >= &exc_stack[0]); + assert(exc_sp >= exc_stack); currently_in_except_block = (exc_sp->val_sp & 1); // restore previous state exc_sp--; // pop back to previous exception handler break; @@ -443,7 +445,7 @@ unwind_jump: case MP_BC_POP_EXCEPT: // TODO need to work out how blocks work etc // pops block, checks it's an exception block, and restores the stack, saving the 3 exception values to local threadstate - assert(exc_sp >= &exc_stack[0]); + assert(exc_sp >= exc_stack); assert(currently_in_except_block); //sp = (mp_obj_t*)(*exc_sp--); //exc_sp--; // discard ip @@ -592,7 +594,7 @@ unwind_return: } nlr_pop(); *sp_in_out = sp; - assert(exc_sp == &exc_stack[0] - 1); + assert(exc_sp == exc_stack - 1); return MP_VM_RETURN_NORMAL; case MP_BC_RAISE_VARARGS: @@ -605,6 +607,7 @@ unwind_return: nlr_pop(); *ip_in_out = ip; *sp_in_out = sp; + *exc_sp_in_out = (void*)((int)exc_sp | currently_in_except_block); return MP_VM_RETURN_YIELD; case MP_BC_IMPORT_NAME: @@ -654,7 +657,7 @@ unwind_return: while (currently_in_except_block) { // nested exception - assert(exc_sp >= &exc_stack[0]); + assert(exc_sp >= exc_stack); // TODO make a proper message for nested exception // at the moment we are just raising the very last exception (the one that caused the nested exception) @@ -664,7 +667,7 @@ unwind_return: exc_sp--; // pop back to previous exception handler } - if (exc_sp >= &exc_stack[0]) { + if (exc_sp >= exc_stack) { // set flag to indicate that we are now handling an exception currently_in_except_block = 1; diff --git a/stmhal/Makefile b/stmhal/Makefile index 86791607a9..938871aefb 100644 --- a/stmhal/Makefile +++ b/stmhal/Makefile @@ -21,7 +21,7 @@ INC += -I$(PY_SRC) INC += -I$(CMSIS_DIR)/inc INC += -I$(CMSIS_DIR)/devinc INC += -I$(HAL_DIR)/inc -INC += -I$(USBDEV_DIR)/core/inc -I$(USBDEV_DIR)/class/cdc/inc -I$(USBDEV_DIR)/class/msc/inc +INC += -I$(USBDEV_DIR)/core/inc -I$(USBDEV_DIR)/class/cdc_msc/inc #INC += -I$(USBHOST_DIR) INC += -I$(FATFS_DIR)/src #INC += -I$(CC3K_DIR) @@ -29,7 +29,7 @@ INC += -I$(FATFS_DIR)/src 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 = $(INC) -Wall -Werror -ansi -std=gnu99 $(CFLAGS_CORTEX_M4) $(COPT) -BOARD ?= PYBOARD4 +BOARD ?= PYBv10 ifeq ($(wildcard boards/$(BOARD)/.),) $(error Invalid BOARD specified) endif @@ -56,9 +56,8 @@ SRC_C = \ stm32f4xx_it.c \ stm32f4xx_hal_msp.c \ usbd_conf.c \ - usbd_desc_vcp.c \ + usbd_desc_cdc_msc.c \ usbd_cdc_interface.c \ - usbd_desc_msc.c \ usbd_msc_storage.c \ pendsv.c \ systick.c \ @@ -74,11 +73,14 @@ SRC_C = \ gccollect.c \ pyexec.c \ pybmodule.c \ + osmodule.c \ + timemodule.c \ import.c \ lexerfatfs.c \ gpio.c \ exti.c \ usrsw.c \ + rng.c \ rtc.c \ flash.c \ storage.c \ @@ -87,8 +89,8 @@ SRC_C = \ diskio.c \ lcd.c \ accel.c \ + servo.c \ -# servo.c \ # timer.c \ # audio.c \ # i2c.c \ @@ -110,6 +112,7 @@ SRC_HAL = $(addprefix $(HAL_DIR)/src/,\ stm32f4xx_hal_pcd.c \ stm32f4xx_hal_rcc.c \ stm32f4xx_hal_rcc_ex.c \ + stm32f4xx_hal_rng.c \ stm32f4xx_hal_rtc.c \ stm32f4xx_hal_rtc_ex.c \ stm32f4xx_hal_sd.c \ @@ -124,13 +127,14 @@ SRC_USBDEV = $(addprefix $(USBDEV_DIR)/,\ core/src/usbd_core.c \ core/src/usbd_ctlreq.c \ core/src/usbd_ioreq.c \ - class/cdc/src/usbd_cdc.c \ - class/msc/src/usbd_msc.c \ - class/msc/src/usbd_msc_bot.c \ - class/msc/src/usbd_msc_scsi.c \ - class/msc/src/usbd_msc_data.c \ + class/cdc_msc/src/usbd_cdc_msc.c \ + class/cdc_msc/src/usbd_msc_bot.c \ + class/cdc_msc/src/usbd_msc_scsi.c \ + class/cdc_msc/src/usbd_msc_data.c \ ) +# class/cdc/src/usbd_cdc.c \ + class/msc/src/usbd_msc.c \ # usbd_core.c \ usbd_ioreq.c \ usbd_req.c \ diff --git a/stmhal/boards/PYBv10/mpconfigboard.h b/stmhal/boards/PYBv10/mpconfigboard.h new file mode 100644 index 0000000000..b7b0259440 --- /dev/null +++ b/stmhal/boards/PYBv10/mpconfigboard.h @@ -0,0 +1,33 @@ +#define PYBOARD4 + +#define MICROPY_HW_BOARD_NAME "PYBv1.0" + +#define MICROPY_HW_HAS_SWITCH (1) +#define MICROPY_HW_HAS_SDCARD (1) +#define MICROPY_HW_HAS_MMA7660 (1) +#define MICROPY_HW_HAS_LIS3DSH (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) +#define MICROPY_HW_ENABLE_TIMER (1) +#define MICROPY_HW_ENABLE_SERVO (1) +#define MICROPY_HW_ENABLE_AUDIO (1) + +// USRSW has no pullup or pulldown, and pressing the switch makes the input go low +#define USRSW_PIN (pin_B3) +#define USRSW_PULL (GPIO_PULLUP) +#define USRSW_EXTI_MODE (GPIO_MODE_IT_FALLING) +#define USRSW_PRESSED (0) + +/* LED */ +#define PYB_LED1 (pin_A13) // red +#define PYB_LED2 (pin_A14) // green +#define PYB_LED3 (pin_A15) // yellow +#define PYB_LED4 (pin_B4) // blue + +#define PYB_OTYPE (GPIO_MODE_OUTPUT_PP) + +#define PYB_LED_ON(pin) (pin->gpio->BSRRL = pin->pin_mask) +#define PYB_LED_OFF(pin) (pin->gpio->BSRRH = pin->pin_mask) + diff --git a/stmhal/boards/PYBv10/pins.csv b/stmhal/boards/PYBv10/pins.csv new file mode 100644 index 0000000000..2ca7fef184 --- /dev/null +++ b/stmhal/boards/PYBv10/pins.csv @@ -0,0 +1,45 @@ +X1,PA0 +X2,PA1 +X3,PA2 +X4,PA3 +X5,PA4 +X6,PA5 +X7,PA6 +X8,PA7 +X9,PB6 +X10,PB7 +X11,PC4 +X12,PC5 +X13,Reset +X14,GND +X15,3.3V +X16,VIN +X17,PB3 +X18,PC13 +X19,PC0 +X20,PC1 +X21,PC2 +X22,PC3 +X23,A3.3V +X24,AGND +Y1,PC6 +Y2,PC7 +Y3,PB8 +Y4,PB9 +Y5,PB12 +Y6,PB13 +Y7,PB14 +Y8,PB15 +Y9,PB10 +Y10,PB11 +Y11,PB0 +Y12,PB1 +Y13,Reset +Y14,GND +Y15,3.3V +Y16,VIN +LED_BLUE,PB4 +LED_RED,PA13 +LED_GREEN,PA14 +LED_YELLOW,PA15 +SW,PB3 diff --git a/stmhal/boards/PYBv10/stm32f4xx_hal_conf.h b/stmhal/boards/PYBv10/stm32f4xx_hal_conf.h new file mode 100644 index 0000000000..315c24dc67 --- /dev/null +++ b/stmhal/boards/PYBv10/stm32f4xx_hal_conf.h @@ -0,0 +1,393 @@ +/**
+ ******************************************************************************
+ * @file stm32f4xx_hal_conf.h
+ * @author MCD Application Team
+ * @version V1.0.1
+ * @date 26-February-2014
+ * @brief HAL configuration file.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F4xx_HAL_CONF_H
+#define __STM32F4xx_HAL_CONF_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+
+#define STM32F405xx
+#define USE_USB_FS
+
+/* ########################## Module Selection ############################## */
+/**
+ * @brief This is the list of modules to be used in the HAL driver
+ */
+#define HAL_MODULE_ENABLED
+#define HAL_ADC_MODULE_ENABLED
+#define HAL_CAN_MODULE_ENABLED
+#define HAL_CRC_MODULE_ENABLED
+#define HAL_CRYP_MODULE_ENABLED
+#define HAL_DAC_MODULE_ENABLED
+#define HAL_DCMI_MODULE_ENABLED
+#define HAL_DMA_MODULE_ENABLED
+/* #define HAL_DMA2D_MODULE_ENABLED */
+#define HAL_ETH_MODULE_ENABLED
+#define HAL_FLASH_MODULE_ENABLED
+#define HAL_NAND_MODULE_ENABLED
+#define HAL_NOR_MODULE_ENABLED
+#define HAL_PCCARD_MODULE_ENABLED
+#define HAL_SRAM_MODULE_ENABLED
+/* #define HAL_SDRAM_MODULE_ENABLED */
+#define HAL_HASH_MODULE_ENABLED
+#define HAL_GPIO_MODULE_ENABLED
+#define HAL_I2C_MODULE_ENABLED
+#define HAL_I2S_MODULE_ENABLED
+#define HAL_IWDG_MODULE_ENABLED
+#define HAL_LTDC_MODULE_ENABLED
+#define HAL_PWR_MODULE_ENABLED
+#define HAL_RCC_MODULE_ENABLED
+#define HAL_RNG_MODULE_ENABLED
+#define HAL_RTC_MODULE_ENABLED
+/* #define HAL_SAI_MODULE_ENABLED */
+#define HAL_SD_MODULE_ENABLED
+#define HAL_SPI_MODULE_ENABLED
+#define HAL_TIM_MODULE_ENABLED
+#define HAL_UART_MODULE_ENABLED
+#define HAL_USART_MODULE_ENABLED
+#define HAL_IRDA_MODULE_ENABLED
+#define HAL_SMARTCARD_MODULE_ENABLED
+#define HAL_WWDG_MODULE_ENABLED
+#define HAL_CORTEX_MODULE_ENABLED
+#define HAL_PCD_MODULE_ENABLED
+#define HAL_HCD_MODULE_ENABLED
+
+
+/* ########################## HSE/HSI Values adaptation ##################### */
+/**
+ * @brief Adjust the value of External High Speed oscillator (HSE) used in your application.
+ * This value is used by the RCC HAL module to compute the system frequency
+ * (when HSE is used as system clock source, directly or through the PLL).
+ */
+#if !defined (HSE_VALUE)
+ #define HSE_VALUE ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */
+#endif /* HSE_VALUE */
+
+#if !defined (HSE_STARTUP_TIMEOUT)
+ #define HSE_STARTUP_TIMEOUT ((uint32_t)5000) /*!< Time out for HSE start up, in ms */
+#endif /* HSE_STARTUP_TIMEOUT */
+
+/**
+ * @brief Internal High Speed oscillator (HSI) value.
+ * This value is used by the RCC HAL module to compute the system frequency
+ * (when HSI is used as system clock source, directly or through the PLL).
+ */
+#if !defined (HSI_VALUE)
+ #define HSI_VALUE ((uint32_t)16000000) /*!< Value of the Internal oscillator in Hz*/
+#endif /* HSI_VALUE */
+
+/**
+ * @brief External clock source for I2S peripheral
+ * This value is used by the I2S HAL module to compute the I2S clock source
+ * frequency, this source is inserted directly through I2S_CKIN pad.
+ */
+#if !defined (EXTERNAL_CLOCK_VALUE)
+ #define EXTERNAL_CLOCK_VALUE ((uint32_t)12288000) /*!< Value of the Internal oscillator in Hz*/
+#endif /* EXTERNAL_CLOCK_VALUE */
+
+/* Tip: To avoid modifying this file each time you need to use different HSE,
+ === you can define the HSE value in your toolchain compiler preprocessor. */
+
+/* ########################### System Configuration ######################### */
+/**
+ * @brief This is the HAL system configuration section
+ */
+#define VDD_VALUE ((uint32_t)3300) /*!< Value of VDD in mv */
+#define USE_RTOS 0
+#define PREFETCH_ENABLE 1
+#define INSTRUCTION_CACHE_ENABLE 1
+#define DATA_CACHE_ENABLE 1
+
+/* ########################## Assert Selection ############################## */
+/**
+ * @brief Uncomment the line below to expanse the "assert_param" macro in the
+ * HAL drivers code
+ */
+/* #define USE_FULL_ASSERT 1 */
+
+/* ################## Ethernet peripheral configuration ##################### */
+
+/* Section 1 : Ethernet peripheral configuration */
+
+/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */
+#define MAC_ADDR0 2
+#define MAC_ADDR1 0
+#define MAC_ADDR2 0
+#define MAC_ADDR3 0
+#define MAC_ADDR4 0
+#define MAC_ADDR5 0
+
+/* Definition of the Ethernet driver buffers size and count */
+#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */
+#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */
+#define ETH_RXBUFNB ((uint32_t)4) /* 4 Rx buffers of size ETH_RX_BUF_SIZE */
+#define ETH_TXBUFNB ((uint32_t)4) /* 4 Tx buffers of size ETH_TX_BUF_SIZE */
+
+/* Section 2: PHY configuration section */
+
+/* DP83848 PHY Address*/
+#define DP83848_PHY_ADDRESS 0x01
+/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/
+#define PHY_RESET_DELAY ((uint32_t)0x000000FF)
+/* PHY Configuration delay */
+#define PHY_CONFIG_DELAY ((uint32_t)0x00000FFF)
+
+#define PHY_READ_TO ((uint32_t)0x0000FFFF)
+#define PHY_WRITE_TO ((uint32_t)0x0000FFFF)
+
+/* Section 3: Common PHY Registers */
+
+#define PHY_BCR ((uint16_t)0x00) /*!< Transceiver Basic Control Register */
+#define PHY_BSR ((uint16_t)0x01) /*!< Transceiver Basic Status Register */
+
+#define PHY_RESET ((uint16_t)0x8000) /*!< PHY Reset */
+#define PHY_LOOPBACK ((uint16_t)0x4000) /*!< Select loop-back mode */
+#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100) /*!< Set the full-duplex mode at 100 Mb/s */
+#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000) /*!< Set the half-duplex mode at 100 Mb/s */
+#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100) /*!< Set the full-duplex mode at 10 Mb/s */
+#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000) /*!< Set the half-duplex mode at 10 Mb/s */
+#define PHY_AUTONEGOTIATION ((uint16_t)0x1000) /*!< Enable auto-negotiation function */
+#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200) /*!< Restart auto-negotiation function */
+#define PHY_POWERDOWN ((uint16_t)0x0800) /*!< Select the power down mode */
+#define PHY_ISOLATE ((uint16_t)0x0400) /*!< Isolate PHY from MII */
+
+#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020) /*!< Auto-Negotiation process completed */
+#define PHY_LINKED_STATUS ((uint16_t)0x0004) /*!< Valid link established */
+#define PHY_JABBER_DETECTION ((uint16_t)0x0002) /*!< Jabber condition detected */
+
+/* Section 4: Extended PHY Registers */
+
+#define PHY_SR ((uint16_t)0x10) /*!< PHY status register Offset */
+#define PHY_MICR ((uint16_t)0x11) /*!< MII Interrupt Control Register */
+#define PHY_MISR ((uint16_t)0x12) /*!< MII Interrupt Status and Misc. Control Register */
+
+#define PHY_LINK_STATUS ((uint16_t)0x0001) /*!< PHY Link mask */
+#define PHY_SPEED_STATUS ((uint16_t)0x0002) /*!< PHY Speed mask */
+#define PHY_DUPLEX_STATUS ((uint16_t)0x0004) /*!< PHY Duplex mask */
+
+#define PHY_MICR_INT_EN ((uint16_t)0x0002) /*!< PHY Enable interrupts */
+#define PHY_MICR_INT_OE ((uint16_t)0x0001) /*!< PHY Enable output interrupt events */
+
+#define PHY_MISR_LINK_INT_EN ((uint16_t)0x0020) /*!< Enable Interrupt on change of link status */
+#define PHY_LINK_INTERRUPT ((uint16_t)0x2000) /*!< PHY link status interrupt mask */
+
+/* Includes ------------------------------------------------------------------*/
+/**
+ * @brief Include module's header file
+ */
+
+#ifdef HAL_RCC_MODULE_ENABLED
+ #include "stm32f4xx_hal_rcc.h"
+#endif /* HAL_RCC_MODULE_ENABLED */
+
+#ifdef HAL_GPIO_MODULE_ENABLED
+ #include "stm32f4xx_hal_gpio.h"
+#endif /* HAL_GPIO_MODULE_ENABLED */
+
+#ifdef HAL_DMA_MODULE_ENABLED
+ #include "stm32f4xx_hal_dma.h"
+#endif /* HAL_DMA_MODULE_ENABLED */
+
+#ifdef HAL_CORTEX_MODULE_ENABLED
+ #include "stm32f4xx_hal_cortex.h"
+#endif /* HAL_CORTEX_MODULE_ENABLED */
+
+#ifdef HAL_ADC_MODULE_ENABLED
+ #include "stm32f4xx_hal_adc.h"
+#endif /* HAL_ADC_MODULE_ENABLED */
+
+#ifdef HAL_CAN_MODULE_ENABLED
+ #include "stm32f4xx_hal_can.h"
+#endif /* HAL_CAN_MODULE_ENABLED */
+
+#ifdef HAL_CRC_MODULE_ENABLED
+ #include "stm32f4xx_hal_crc.h"
+#endif /* HAL_CRC_MODULE_ENABLED */
+
+#ifdef HAL_CRYP_MODULE_ENABLED
+ #include "stm32f4xx_hal_cryp.h"
+#endif /* HAL_CRYP_MODULE_ENABLED */
+
+#ifdef HAL_DMA2D_MODULE_ENABLED
+ #include "stm32f4xx_hal_dma2d.h"
+#endif /* HAL_DMA2D_MODULE_ENABLED */
+
+#ifdef HAL_DAC_MODULE_ENABLED
+ #include "stm32f4xx_hal_dac.h"
+#endif /* HAL_DAC_MODULE_ENABLED */
+
+#ifdef HAL_DCMI_MODULE_ENABLED
+ #include "stm32f4xx_hal_dcmi.h"
+#endif /* HAL_DCMI_MODULE_ENABLED */
+
+#ifdef HAL_ETH_MODULE_ENABLED
+ #include "stm32f4xx_hal_eth.h"
+#endif /* HAL_ETH_MODULE_ENABLED */
+
+#ifdef HAL_FLASH_MODULE_ENABLED
+ #include "stm32f4xx_hal_flash.h"
+#endif /* HAL_FLASH_MODULE_ENABLED */
+
+#ifdef HAL_SRAM_MODULE_ENABLED
+ #include "stm32f4xx_hal_sram.h"
+#endif /* HAL_SRAM_MODULE_ENABLED */
+
+#ifdef HAL_NOR_MODULE_ENABLED
+ #include "stm32f4xx_hal_nor.h"
+#endif /* HAL_NOR_MODULE_ENABLED */
+
+#ifdef HAL_NAND_MODULE_ENABLED
+ #include "stm32f4xx_hal_nand.h"
+#endif /* HAL_NAND_MODULE_ENABLED */
+
+#ifdef HAL_PCCARD_MODULE_ENABLED
+ #include "stm32f4xx_hal_pccard.h"
+#endif /* HAL_PCCARD_MODULE_ENABLED */
+
+#ifdef HAL_SDRAM_MODULE_ENABLED
+ #include "stm32f4xx_hal_sdram.h"
+#endif /* HAL_SDRAM_MODULE_ENABLED */
+
+#ifdef HAL_HASH_MODULE_ENABLED
+ #include "stm32f4xx_hal_hash.h"
+#endif /* HAL_HASH_MODULE_ENABLED */
+
+#ifdef HAL_I2C_MODULE_ENABLED
+ #include "stm32f4xx_hal_i2c.h"
+#endif /* HAL_I2C_MODULE_ENABLED */
+
+#ifdef HAL_I2S_MODULE_ENABLED
+ #include "stm32f4xx_hal_i2s.h"
+#endif /* HAL_I2S_MODULE_ENABLED */
+
+#ifdef HAL_IWDG_MODULE_ENABLED
+ #include "stm32f4xx_hal_iwdg.h"
+#endif /* HAL_IWDG_MODULE_ENABLED */
+
+#ifdef HAL_LTDC_MODULE_ENABLED
+ #include "stm32f4xx_hal_ltdc.h"
+#endif /* HAL_LTDC_MODULE_ENABLED */
+
+#ifdef HAL_PWR_MODULE_ENABLED
+ #include "stm32f4xx_hal_pwr.h"
+#endif /* HAL_PWR_MODULE_ENABLED */
+
+#ifdef HAL_RNG_MODULE_ENABLED
+ #include "stm32f4xx_hal_rng.h"
+#endif /* HAL_RNG_MODULE_ENABLED */
+
+#ifdef HAL_RTC_MODULE_ENABLED
+ #include "stm32f4xx_hal_rtc.h"
+#endif /* HAL_RTC_MODULE_ENABLED */
+
+#ifdef HAL_SAI_MODULE_ENABLED
+ #include "stm32f4xx_hal_sai.h"
+#endif /* HAL_SAI_MODULE_ENABLED */
+
+#ifdef HAL_SD_MODULE_ENABLED
+ #include "stm32f4xx_hal_sd.h"
+#endif /* HAL_SD_MODULE_ENABLED */
+
+#ifdef HAL_SPI_MODULE_ENABLED
+ #include "stm32f4xx_hal_spi.h"
+#endif /* HAL_SPI_MODULE_ENABLED */
+
+#ifdef HAL_TIM_MODULE_ENABLED
+ #include "stm32f4xx_hal_tim.h"
+#endif /* HAL_TIM_MODULE_ENABLED */
+
+#ifdef HAL_UART_MODULE_ENABLED
+ #include "stm32f4xx_hal_uart.h"
+#endif /* HAL_UART_MODULE_ENABLED */
+
+#ifdef HAL_USART_MODULE_ENABLED
+ #include "stm32f4xx_hal_usart.h"
+#endif /* HAL_USART_MODULE_ENABLED */
+
+#ifdef HAL_IRDA_MODULE_ENABLED
+ #include "stm32f4xx_hal_irda.h"
+#endif /* HAL_IRDA_MODULE_ENABLED */
+
+#ifdef HAL_SMARTCARD_MODULE_ENABLED
+ #include "stm32f4xx_hal_smartcard.h"
+#endif /* HAL_SMARTCARD_MODULE_ENABLED */
+
+#ifdef HAL_WWDG_MODULE_ENABLED
+ #include "stm32f4xx_hal_wwdg.h"
+#endif /* HAL_WWDG_MODULE_ENABLED */
+
+#ifdef HAL_PCD_MODULE_ENABLED
+ #include "stm32f4xx_hal_pcd.h"
+#endif /* HAL_PCD_MODULE_ENABLED */
+
+#ifdef HAL_HCD_MODULE_ENABLED
+ #include "stm32f4xx_hal_hcd.h"
+#endif /* HAL_HCD_MODULE_ENABLED */
+
+/* Exported macro ------------------------------------------------------------*/
+#ifdef USE_FULL_ASSERT
+/**
+ * @brief The assert_param macro is used for function's parameters check.
+ * @param expr: If expr is false, it calls assert_failed function
+ * which reports the name of the source file and the source
+ * line number of the call that failed.
+ * If expr is true, it returns no value.
+ * @retval None
+ */
+ #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))
+/* Exported functions ------------------------------------------------------- */
+ void assert_failed(uint8_t* file, uint32_t line);
+#else
+ #define assert_param(expr) ((void)0)
+#endif /* USE_FULL_ASSERT */
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F4xx_HAL_CONF_H */
+
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/stmhal/main.c b/stmhal/main.c index d92ccdd5b1..6511891a1b 100644 --- a/stmhal/main.c +++ b/stmhal/main.c @@ -10,7 +10,6 @@ #include "pendsv.h" #include "mpconfig.h" #include "qstr.h" -#include "nlr.h" #include "misc.h" #include "lexer.h" #include "parse.h" @@ -23,19 +22,22 @@ #include "gccollect.h" #include "pyexec.h" #include "pybmodule.h" +#include "osmodule.h" +#include "timemodule.h" #include "usart.h" #include "led.h" #include "exti.h" #include "usrsw.h" #include "usb.h" +#include "rng.h" #include "rtc.h" #include "storage.h" #include "sdcard.h" #include "ff.h" #include "lcd.h" #include "accel.h" -#if 0 #include "servo.h" +#if 0 #include "timer.h" #include "pybwlan.h" #include "pin.h" @@ -247,23 +249,24 @@ soft_reset: lcd_init(); #endif -#if 0 +#if MICROPY_HW_ENABLE_RNG + // RNG + rng_init(); +#endif + #if MICROPY_HW_ENABLE_SERVO // servo servo_init(); #endif +#if 0 #if MICROPY_HW_ENABLE_TIMER // timer timer_init(); #endif - -#if MICROPY_HW_ENABLE_RNG - // RNG - RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_RNG, ENABLE); - RNG_Cmd(ENABLE); #endif +#if 0 pin_map_init(); #endif @@ -274,6 +277,11 @@ soft_reset: // probably shouldn't do this, so we are compatible with CPython rt_store_name(MP_QSTR_pyb, (mp_obj_t)&pyb_module); + // pre-import the os and time modules + // TODO don't do this! (need a way of registering builtin modules...) + rt_store_name(MP_QSTR_os, (mp_obj_t)&os_module); + rt_store_name(MP_QSTR_time, (mp_obj_t)&time_module); + // check if user switch held (initiates reset of filesystem) bool reset_filesystem = false; #if MICROPY_HW_HAS_SWITCH @@ -336,7 +344,6 @@ soft_reset: fno.lfname = NULL; fno.lfsize = 0; #endif - led_debug(0, 500); FRESULT res = f_stat("0:/boot.py", &fno); if (res == FR_OK) { if (fno.fattrib & AM_DIR) { @@ -400,7 +407,7 @@ soft_reset: pyb_usb_host_init(); #elif defined(USE_DEVICE_MODE) // USB device - pyb_usb_dev_init(USBD_DEVICE_MSC, usbd_medium_kind); + pyb_usb_dev_init(USBD_DEVICE_CDC_MSC, usbd_medium_kind); #endif #if MICROPY_HW_HAS_MMA7660 @@ -474,10 +481,8 @@ soft_reset: pyexec_repl(); -#if 0 printf("PYB: sync filesystems\n"); storage_flush(); -#endif printf("PYB: soft reboot\n"); diff --git a/stmhal/osmodule.c b/stmhal/osmodule.c new file mode 100644 index 0000000000..7f32fe6749 --- /dev/null +++ b/stmhal/osmodule.c @@ -0,0 +1,178 @@ +#include <string.h> + +#include "nlr.h" +#include "misc.h" +#include "mpconfig.h" +#include "qstr.h" +#include "obj.h" +#include "map.h" +#include "systick.h" +#include "rng.h" +#include "storage.h" +#include "ff.h" +#include "osmodule.h" + +#if _USE_LFN +static char lfn[_MAX_LFN + 1]; /* Buffer to store the LFN */ +#endif + +STATIC mp_obj_t os_listdir(uint n_args, const mp_obj_t *args) { + const mp_obj_type_t *local_str_type = &str_type; + const char *path; + if (n_args == 1) { + if (mp_obj_get_type(args[0]) == &bytes_type) { + local_str_type = &bytes_type; + } + path = mp_obj_str_get_str(args[0]); + } else { + path = "0:"; + } + + FRESULT res; + FILINFO fno; + DIR dir; +#if _USE_LFN + fno.lfname = lfn; + fno.lfsize = sizeof lfn; +#endif + + res = f_opendir(&dir, path); /* Open the directory */ + if (res != FR_OK) { + // TODO should be mp_type_FileNotFoundError + nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_OSError, "No such file or directory: '%s'", path)); + } + + mp_obj_t dir_list = mp_obj_new_list(0, NULL); + + uint path_len = strlen(path); + if (path[path_len - 1] == '/') { + path_len--; + } + + for (;;) { + res = f_readdir(&dir, &fno); /* Read a directory item */ + if (res != FR_OK || fno.fname[0] == 0) break; /* Break on error or end of dir */ + if (fno.fname[0] == '.' && fno.fname[1] == 0) continue; /* Ignore . entry */ + if (fno.fname[0] == '.' && fno.fname[1] == '.' && fno.fname[2] == 0) continue; /* Ignore .. entry */ + +#if _USE_LFN + char *fn = *fno.lfname ? fno.lfname : fno.fname; +#else + char *fn = fno.fname; +#endif + + if (fno.fattrib & AM_DIR) { /* It is a directory */ + } else { /* It is a file. */ + } + + // make a string object for this entry + byte *data; + uint fn_len = strlen(fn); + mp_obj_t entry_o = mp_obj_str_builder_start(local_str_type, path_len + 1 + fn_len, &data); + memcpy(data, path, path_len); + data[path_len] = '/'; + memcpy(data + path_len + 1, fn, fn_len); + + // add the entry to the list + mp_obj_list_append(dir_list, mp_obj_str_builder_end(entry_o)); + } + + f_closedir(&dir); + + return dir_list; +} + +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(os_listdir_obj, 0, 1, os_listdir); + +STATIC mp_obj_t os_mkdir(mp_obj_t path_o) { + const char *path = mp_obj_str_get_str(path_o); + FRESULT res = f_mkdir(path); + switch (res) { + case FR_OK: + return mp_const_none; + case FR_EXIST: + // TODO should be FileExistsError + nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_OSError, "File exists: '%s'", path)); + default: + nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_OSError, "Error creating directory '%s'", path)); + } +} + +MP_DEFINE_CONST_FUN_OBJ_1(os_mkdir_obj, os_mkdir); + +STATIC mp_obj_t os_remove(mp_obj_t path_o) { + const char *path = mp_obj_str_get_str(path_o); + // TODO check that path is actually a file before trying to unlink it + FRESULT res = f_unlink(path); + switch (res) { + case FR_OK: + return mp_const_none; + default: + nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_OSError, "Error removing file '%s'", path)); + } +} + +MP_DEFINE_CONST_FUN_OBJ_1(os_remove_obj, os_remove); + +STATIC mp_obj_t os_rmdir(mp_obj_t path_o) { + const char *path = mp_obj_str_get_str(path_o); + // TODO check that path is actually a directory before trying to unlink it + FRESULT res = f_unlink(path); + switch (res) { + case FR_OK: + return mp_const_none; + default: + nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_OSError, "Error removing directory '%s'", path)); + } +} + +MP_DEFINE_CONST_FUN_OBJ_1(os_rmdir_obj, os_rmdir); + +STATIC mp_obj_t os_sync(void) { + storage_flush(); + return mp_const_none; +} + +MP_DEFINE_CONST_FUN_OBJ_0(os_sync_obj, os_sync); + +STATIC mp_obj_t os_urandom(mp_obj_t num) { + machine_int_t n = mp_obj_get_int(num); + byte *data; + mp_obj_t o = mp_obj_str_builder_start(&bytes_type, n, &data); + for (int i = 0; i < n; i++) { + data[i] = rng_get(); + } + return mp_obj_str_builder_end(o); +} + +MP_DEFINE_CONST_FUN_OBJ_1(os_urandom_obj, os_urandom); + +STATIC const mp_map_elem_t os_module_globals_table[] = { + { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_os) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_listdir), (mp_obj_t)&os_listdir_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_mkdir), (mp_obj_t)&os_mkdir_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_remove), (mp_obj_t)&os_remove_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_rmdir), (mp_obj_t)&os_rmdir_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_unlink), (mp_obj_t)&os_remove_obj }, // unlink aliases to remove + + { MP_OBJ_NEW_QSTR(MP_QSTR_sync), (mp_obj_t)&os_sync_obj }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_sep), MP_OBJ_NEW_QSTR(MP_QSTR__slash_) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_urandom), (mp_obj_t)&os_urandom_obj }, +}; + +STATIC const mp_map_t os_module_globals = { + .all_keys_are_qstrs = 1, + .table_is_fixed_array = 1, + .used = sizeof(os_module_globals_table) / sizeof(mp_map_elem_t), + .alloc = sizeof(os_module_globals_table) / sizeof(mp_map_elem_t), + .table = (mp_map_elem_t*)os_module_globals_table, +}; + +const mp_obj_module_t os_module = { + .base = { &mp_type_module }, + .name = MP_QSTR_os, + .globals = (mp_map_t*)&os_module_globals, +}; diff --git a/stmhal/osmodule.h b/stmhal/osmodule.h new file mode 100644 index 0000000000..e3c13f756e --- /dev/null +++ b/stmhal/osmodule.h @@ -0,0 +1 @@ +extern const mp_obj_module_t os_module; diff --git a/stmhal/pybmodule.c b/stmhal/pybmodule.c index 3db23dc6de..09cdf83b8a 100644 --- a/stmhal/pybmodule.c +++ b/stmhal/pybmodule.c @@ -17,13 +17,14 @@ #include "pin.h" #include "exti.h" #include "usrsw.h" +#include "rng.h" #include "rtc.h" #include "usart.h" #include "storage.h" #include "sdcard.h" #include "accel.h" -#if 0 #include "servo.h" +#if 0 #include "usb.h" #include "i2c.h" #include "adc.h" @@ -128,16 +129,6 @@ STATIC mp_obj_t pyb_udelay(mp_obj_t usec) { STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_udelay_obj, pyb_udelay); -STATIC mp_obj_t pyb_rng_get(void) { -#if 0 - return mp_obj_new_int(RNG_GetRandomNumber() >> 16); -#else - return mp_obj_new_int(0); -#endif -} - -STATIC MP_DEFINE_CONST_FUN_OBJ_0(pyb_rng_get_obj, pyb_rng_get); - #if 0 STATIC void SYSCLKConfig_STOP(void) { /* After wake-up from STOP reconfigure the system clock */ @@ -232,7 +223,7 @@ STATIC const mp_map_elem_t pyb_module_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_sync), (mp_obj_t)&pyb_sync_obj }, #if MICROPY_HW_ENABLE_RNG - { MP_OBJ_NEW_QSTR(MP_QSTR_rand), (mp_obj_t)&pyb_rng_get_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_rng), (mp_obj_t)&pyb_rng_get_obj }, #endif #if MICROPY_HW_ENABLE_RTC @@ -240,13 +231,11 @@ STATIC const mp_map_elem_t pyb_module_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_rtc_info), (mp_obj_t)&pyb_rtc_info_obj }, #endif -#if 0 #if MICROPY_HW_ENABLE_SERVO { MP_OBJ_NEW_QSTR(MP_QSTR_pwm), (mp_obj_t)&pyb_pwm_set_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_servo), (mp_obj_t)&pyb_servo_set_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_Servo), (mp_obj_t)&pyb_Servo_obj }, #endif -#endif #if MICROPY_HW_HAS_SWITCH { MP_OBJ_NEW_QSTR(MP_QSTR_switch), (mp_obj_t)&pyb_switch_obj }, diff --git a/stmhal/qstrdefsport.h b/stmhal/qstrdefsport.h index 13532892a7..9961102a35 100644 --- a/stmhal/qstrdefsport.h +++ b/stmhal/qstrdefsport.h @@ -22,7 +22,7 @@ Q(accel_read) Q(accel_mode) Q(hid) Q(time) -Q(rand) +Q(rng) Q(Led) Q(LCD) Q(Servo) @@ -55,3 +55,18 @@ Q(PULL_UP) Q(PULL_DOWN) Q(PUSH_PULL) Q(OPEN_DRAIN) + +// for os module +Q(os) +Q(/) +Q(listdir) +Q(mkdir) +Q(remove) +Q(rmdir) +Q(unlink) +Q(sep) +Q(urandom) + +// for time module +Q(time) +Q(sleep) diff --git a/stmhal/rng.c b/stmhal/rng.c new file mode 100644 index 0000000000..f0d14fe975 --- /dev/null +++ b/stmhal/rng.c @@ -0,0 +1,25 @@ +#include "stm32f4xx_hal.h" + +#include "misc.h" +#include "mpconfig.h" +#include "qstr.h" +#include "obj.h" +#include "rng.h" + +STATIC RNG_HandleTypeDef RngHandle; + +void rng_init(void) { + __RNG_CLK_ENABLE(); + RngHandle.Instance = RNG; + HAL_RNG_Init(&RngHandle); +} + +uint32_t rng_get(void) { + return HAL_RNG_GetRandomNumber(&RngHandle); +} + +STATIC mp_obj_t pyb_rng_get(void) { + return mp_obj_new_int(HAL_RNG_GetRandomNumber(&RngHandle) >> 2); +} + +MP_DEFINE_CONST_FUN_OBJ_0(pyb_rng_get_obj, pyb_rng_get); diff --git a/stmhal/rng.h b/stmhal/rng.h new file mode 100644 index 0000000000..5442d453c2 --- /dev/null +++ b/stmhal/rng.h @@ -0,0 +1,4 @@ +void rng_init(void); +uint32_t rng_get(void); + +MP_DECLARE_CONST_FUN_OBJ(pyb_rng_get_obj); diff --git a/stmhal/servo.c b/stmhal/servo.c new file mode 100644 index 0000000000..1be18b8a4e --- /dev/null +++ b/stmhal/servo.c @@ -0,0 +1,142 @@ +#include <stdio.h> + +#include "stm32f4xx_hal.h" + +#include "misc.h" +#include "mpconfig.h" +#include "qstr.h" +#include "obj.h" +#include "servo.h" + +// this servo driver uses hardware PWM to drive servos on PA0, PA1, PA2, PA3 = X1, X2, X3, X4 +// TIM2 and TIM5 have CH1, CH2, CH3, CH4 on PA0-PA3 respectively +// they are both 32-bit counters with 16-bit prescaler +// we use TIM2 + +STATIC TIM_HandleTypeDef servo_TimHandle; + +void servo_init(void) { + // TIM2 clock enable + __TIM2_CLK_ENABLE(); + + // PWM clock configuration + servo_TimHandle.Instance = TIM2; + servo_TimHandle.Init.Period = 2000; // timer cycles at 50Hz + servo_TimHandle.Init.Prescaler = ((SystemCoreClock / 2) / 100000) - 1; // timer runs at 100kHz + servo_TimHandle.Init.ClockDivision = 0; + servo_TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP; + HAL_TIM_PWM_Init(&servo_TimHandle); +} + +STATIC void servo_init_channel(int channel_in) { + uint32_t pin; + uint32_t channel; + switch (channel_in) { + case 1: pin = GPIO_PIN_0; channel = TIM_CHANNEL_1; break; + case 2: pin = GPIO_PIN_1; channel = TIM_CHANNEL_2; break; + case 3: pin = GPIO_PIN_2; channel = TIM_CHANNEL_3; break; + case 4: pin = GPIO_PIN_3; channel = TIM_CHANNEL_4; break; + default: return; + } + + // GPIO configuration + GPIO_InitTypeDef GPIO_InitStructure; + GPIO_InitStructure.Pin = pin; + GPIO_InitStructure.Mode = GPIO_MODE_AF_PP; + GPIO_InitStructure.Speed = GPIO_SPEED_FAST; + GPIO_InitStructure.Pull = GPIO_NOPULL; + GPIO_InitStructure.Alternate = GPIO_AF1_TIM2; + HAL_GPIO_Init(GPIOA, &GPIO_InitStructure); + + // PWM mode configuration + TIM_OC_InitTypeDef oc_init; + oc_init.OCMode = TIM_OCMODE_PWM1; + oc_init.Pulse = 150; // units of 10us + oc_init.OCPolarity = TIM_OCPOLARITY_HIGH; + oc_init.OCFastMode = TIM_OCFAST_DISABLE; + HAL_TIM_PWM_ConfigChannel(&servo_TimHandle, &oc_init, channel); + + // start PWM + HAL_TIM_PWM_Start(&servo_TimHandle, channel); +} + +/******************************************************************************/ +// Micro Python bindings + +STATIC mp_obj_t pyb_servo_set(mp_obj_t port, mp_obj_t value) { + int p = mp_obj_get_int(port); + int v = mp_obj_get_int(value); + if (v < 50) { v = 50; } + if (v > 250) { v = 250; } + switch (p) { + case 1: TIM2->CCR1 = v; break; + case 2: TIM2->CCR2 = v; break; + case 3: TIM2->CCR3 = v; break; + case 4: TIM2->CCR4 = v; break; + } + return mp_const_none; +} + +MP_DEFINE_CONST_FUN_OBJ_2(pyb_servo_set_obj, pyb_servo_set); + +STATIC mp_obj_t pyb_pwm_set(mp_obj_t period, mp_obj_t pulse) { + int pe = mp_obj_get_int(period); + int pu = mp_obj_get_int(pulse); + TIM2->ARR = pe; + TIM2->CCR3 = pu; + return mp_const_none; +} + +MP_DEFINE_CONST_FUN_OBJ_2(pyb_pwm_set_obj, pyb_pwm_set); + +typedef struct _pyb_servo_obj_t { + mp_obj_base_t base; + uint servo_id; +} pyb_servo_obj_t; + +STATIC void servo_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) { + pyb_servo_obj_t *self = self_in; + print(env, "<Servo %lu>", self->servo_id); +} + +STATIC mp_obj_t servo_obj_angle(mp_obj_t self_in, mp_obj_t angle) { + pyb_servo_obj_t *self = self_in; +#if MICROPY_ENABLE_FLOAT + machine_int_t v = 152 + 85.0 * mp_obj_get_float(angle) / 90.0; +#else + machine_int_t v = 152 + 85 * mp_obj_get_int(angle) / 90; +#endif + if (v < 65) { v = 65; } + if (v > 210) { v = 210; } + switch (self->servo_id) { + case 1: TIM2->CCR1 = v; break; + case 2: TIM2->CCR2 = v; break; + case 3: TIM2->CCR3 = v; break; + case 4: TIM2->CCR4 = v; break; + } + return mp_const_none; +} + +STATIC MP_DEFINE_CONST_FUN_OBJ_2(servo_obj_angle_obj, servo_obj_angle); + +STATIC const mp_method_t servo_methods[] = { + { "angle", &servo_obj_angle_obj }, + { NULL, NULL }, +}; + +STATIC const mp_obj_type_t servo_obj_type = { + { &mp_type_type }, + .name = MP_QSTR_Servo, + .print = servo_obj_print, + .methods = servo_methods, +}; + +STATIC mp_obj_t pyb_Servo(mp_obj_t servo_id) { + pyb_servo_obj_t *o = m_new_obj(pyb_servo_obj_t); + o->base.type = &servo_obj_type; + o->servo_id = mp_obj_get_int(servo_id); + servo_init_channel(o->servo_id); + return o; +} + +MP_DEFINE_CONST_FUN_OBJ_1(pyb_Servo_obj, pyb_Servo); diff --git a/stmhal/servo.h b/stmhal/servo.h new file mode 100644 index 0000000000..bb3edd97a2 --- /dev/null +++ b/stmhal/servo.h @@ -0,0 +1,5 @@ +void servo_init(void); + +MP_DECLARE_CONST_FUN_OBJ(pyb_servo_set_obj); +MP_DECLARE_CONST_FUN_OBJ(pyb_pwm_set_obj); +MP_DECLARE_CONST_FUN_OBJ(pyb_Servo_obj); diff --git a/stmhal/stm32f4xx_hal_msp.c b/stmhal/stm32f4xx_hal_msp.c index f5611e1082..816b1427e9 100644 --- a/stmhal/stm32f4xx_hal_msp.c +++ b/stmhal/stm32f4xx_hal_msp.c @@ -47,7 +47,7 @@ /* Includes ------------------------------------------------------------------*/
#include "stm32f4xx_hal.h"
-#include "usbd_cdc.h"
+#include "usbd_cdc_msc.h"
#include "usbd_cdc_interface.h"
/** @addtogroup STM32F4xx_HAL_Driver
diff --git a/stmhal/timemodule.c b/stmhal/timemodule.c new file mode 100644 index 0000000000..b2dac6a54c --- /dev/null +++ b/stmhal/timemodule.c @@ -0,0 +1,44 @@ +#include <stm32f4xx_hal.h> + +#include "nlr.h" +#include "misc.h" +#include "mpconfig.h" +#include "qstr.h" +#include "obj.h" +#include "map.h" +#include "timemodule.h" + +STATIC mp_obj_t time_sleep(mp_obj_t seconds_o) { +#if MICROPY_ENABLE_FLOAT + if (MP_OBJ_IS_INT(seconds_o)) { +#endif + HAL_Delay(1000 * mp_obj_get_int(seconds_o)); +#if MICROPY_ENABLE_FLOAT + } else { + HAL_Delay((uint32_t)(1000 * mp_obj_get_float(seconds_o))); + } +#endif + return mp_const_none; +} + +MP_DEFINE_CONST_FUN_OBJ_1(time_sleep_obj, time_sleep); + +STATIC const mp_map_elem_t time_module_globals_table[] = { + { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_time) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_sleep), (mp_obj_t)&time_sleep_obj }, +}; + +STATIC const mp_map_t time_module_globals = { + .all_keys_are_qstrs = 1, + .table_is_fixed_array = 1, + .used = sizeof(time_module_globals_table) / sizeof(mp_map_elem_t), + .alloc = sizeof(time_module_globals_table) / sizeof(mp_map_elem_t), + .table = (mp_map_elem_t*)time_module_globals_table, +}; + +const mp_obj_module_t time_module = { + .base = { &mp_type_module }, + .name = MP_QSTR_time, + .globals = (mp_map_t*)&time_module_globals, +}; diff --git a/stmhal/timemodule.h b/stmhal/timemodule.h new file mode 100644 index 0000000000..70e35b1fde --- /dev/null +++ b/stmhal/timemodule.h @@ -0,0 +1 @@ +extern const mp_obj_module_t time_module; diff --git a/stmhal/usb.c b/stmhal/usb.c index c14a5ad688..aa006b8b8f 100644 --- a/stmhal/usb.c +++ b/stmhal/usb.c @@ -2,9 +2,8 @@ #include "usbd_core.h" #include "usbd_desc.h" -#include "usbd_cdc.h" +#include "usbd_cdc_msc.h" #include "usbd_cdc_interface.h" -#include "usbd_msc.h" #include "usbd_msc_storage.h" #include "misc.h" @@ -18,7 +17,6 @@ USBD_HandleTypeDef hUSBDDevice; #endif static int dev_is_enabled = 0; -uint32_t APP_dev_is_connected = 0; /* used by usbd_cdc_vcp */ mp_obj_t mp_const_vcp_interrupt = MP_OBJ_NULL; void pyb_usb_dev_init(usbd_device_kind_t device_kind, usbd_storage_medium_kind_t medium_kind) { @@ -26,21 +24,10 @@ void pyb_usb_dev_init(usbd_device_kind_t device_kind, usbd_storage_medium_kind_t if (!dev_is_enabled) { // only init USB once in the device's power-lifetime switch (device_kind) { - case USBD_DEVICE_CDC: - // XXX USBD_CDC_Init (called by one of these functions below) uses malloc, - // so the memory is invalid after a soft reset (which resets the GC). + case USBD_DEVICE_CDC_MSC: USBD_Init(&hUSBDDevice, &VCP_Desc, 0); - USBD_RegisterClass(&hUSBDDevice, &USBD_CDC); + USBD_RegisterClass(&hUSBDDevice, &USBD_CDC_MSC); USBD_CDC_RegisterInterface(&hUSBDDevice, (USBD_CDC_ItfTypeDef*)&USBD_CDC_fops); - USBD_Start(&hUSBDDevice); - //USBD_Init(&USB_OTG_Core, USB_OTG_FS_CORE_ID, &USR_desc, &USBD_PYB_cb, &USR_cb); - break; - - case USBD_DEVICE_MSC: - // XXX USBD_CDC_Init (called by one of these functions below) uses malloc, - // so the memory is invalid after a soft reset (which resets the GC). - USBD_Init(&hUSBDDevice, &MSC_Desc, 0); - USBD_RegisterClass(&hUSBDDevice, &USBD_MSC); if (medium_kind == USBD_STORAGE_MEDIUM_FLASH) { USBD_MSC_RegisterStorage(&hUSBDDevice, (USBD_StorageTypeDef*)&USBD_FLASH_STORAGE_fops); } else { @@ -67,7 +54,7 @@ bool usb_vcp_is_enabled(void) { } bool usb_vcp_is_connected(void) { - return APP_dev_is_connected; + return USBD_CDC_IsConnected(); } void usb_vcp_set_interrupt_char(int c) { diff --git a/stmhal/usb.h b/stmhal/usb.h index bb6283c89a..e30b1364f9 100644 --- a/stmhal/usb.h +++ b/stmhal/usb.h @@ -5,8 +5,7 @@ #define VCP_CHAR_CTRL_D (4) typedef enum { - USBD_DEVICE_CDC, - USBD_DEVICE_MSC, + USBD_DEVICE_CDC_MSC, USBD_DEVICE_HID, } usbd_device_kind_t; diff --git a/stmhal/usbd_cdc_interface.c b/stmhal/usbd_cdc_interface.c index e0f387eb7e..5116ce860e 100644 --- a/stmhal/usbd_cdc_interface.c +++ b/stmhal/usbd_cdc_interface.c @@ -28,11 +28,22 @@ /* Includes ------------------------------------------------------------------*/ #include <stdbool.h> #include "stm32f4xx_hal.h" -#include "usbd_cdc.h" +#include "usbd_cdc_msc.h" #include "usbd_cdc_interface.h" #include "pendsv.h" #include "usb.h" +// CDC control commands +#define CDC_SEND_ENCAPSULATED_COMMAND 0x00 +#define CDC_GET_ENCAPSULATED_RESPONSE 0x01 +#define CDC_SET_COMM_FEATURE 0x02 +#define CDC_GET_COMM_FEATURE 0x03 +#define CDC_CLEAR_COMM_FEATURE 0x04 +#define CDC_SET_LINE_CODING 0x20 +#define CDC_GET_LINE_CODING 0x21 +#define CDC_SET_CONTROL_LINE_STATE 0x22 +#define CDC_SEND_BREAK 0x23 + /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ #define APP_RX_DATA_SIZE 1024 // I think this must be at least CDC_DATA_FS_OUT_PACKET_SIZE (was 2048) @@ -41,6 +52,8 @@ /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ +static uint8_t dev_is_connected = 0; // indicates if we are connected + static uint8_t UserRxBuffer[APP_RX_DATA_SIZE]; // received data from USB OUT endpoint is stored in this buffer static uint16_t UserRxBufCur = 0; // points to next available character in UserRxBuffer static uint16_t UserRxBufLen = 0; // counts number of valid characters in UserRxBuffer @@ -163,76 +176,73 @@ static int8_t CDC_Itf_DeInit(void) * @param Len: Number of data to be sent (in bytes) * @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL */ -static int8_t CDC_Itf_Control (uint8_t cmd, uint8_t* pbuf, uint16_t length) -{ - switch (cmd) - { - case CDC_SEND_ENCAPSULATED_COMMAND: - /* Add your code here */ - break; - - case CDC_GET_ENCAPSULATED_RESPONSE: - /* Add your code here */ - break; - - case CDC_SET_COMM_FEATURE: - /* Add your code here */ - break; - - case CDC_GET_COMM_FEATURE: - /* Add your code here */ - break; - - case CDC_CLEAR_COMM_FEATURE: - /* Add your code here */ - break; - - case CDC_SET_LINE_CODING: - #if 0 - LineCoding.bitrate = (uint32_t)(pbuf[0] | (pbuf[1] << 8) |\ - (pbuf[2] << 16) | (pbuf[3] << 24)); - LineCoding.format = pbuf[4]; - LineCoding.paritytype = pbuf[5]; - LineCoding.datatype = pbuf[6]; - - /* Set the new configuration */ - #endif - break; - - case CDC_GET_LINE_CODING: - #if 0 - pbuf[0] = (uint8_t)(LineCoding.bitrate); - pbuf[1] = (uint8_t)(LineCoding.bitrate >> 8); - pbuf[2] = (uint8_t)(LineCoding.bitrate >> 16); - pbuf[3] = (uint8_t)(LineCoding.bitrate >> 24); - pbuf[4] = LineCoding.format; - pbuf[5] = LineCoding.paritytype; - pbuf[6] = LineCoding.datatype; - #endif - - /* Add your code here */ - pbuf[0] = (uint8_t)(115200); - pbuf[1] = (uint8_t)(115200 >> 8); - pbuf[2] = (uint8_t)(115200 >> 16); - pbuf[3] = (uint8_t)(115200 >> 24); - pbuf[4] = 0; // stop bits (1) - pbuf[5] = 0; // parity (none) - pbuf[6] = 8; // number of bits (8) - break; - - case CDC_SET_CONTROL_LINE_STATE: - /* Add your code here */ - break; - - case CDC_SEND_BREAK: - /* Add your code here */ - break; - - default: - break; - } - - return (USBD_OK); +static int8_t CDC_Itf_Control(uint8_t cmd, uint8_t* pbuf, uint16_t length) { + switch (cmd) { + case CDC_SEND_ENCAPSULATED_COMMAND: + /* Add your code here */ + break; + + case CDC_GET_ENCAPSULATED_RESPONSE: + /* Add your code here */ + break; + + case CDC_SET_COMM_FEATURE: + /* Add your code here */ + break; + + case CDC_GET_COMM_FEATURE: + /* Add your code here */ + break; + + case CDC_CLEAR_COMM_FEATURE: + /* Add your code here */ + break; + + case CDC_SET_LINE_CODING: + #if 0 + LineCoding.bitrate = (uint32_t)(pbuf[0] | (pbuf[1] << 8) |\ + (pbuf[2] << 16) | (pbuf[3] << 24)); + LineCoding.format = pbuf[4]; + LineCoding.paritytype = pbuf[5]; + LineCoding.datatype = pbuf[6]; + /* Set the new configuration */ + #endif + break; + + case CDC_GET_LINE_CODING: + #if 0 + pbuf[0] = (uint8_t)(LineCoding.bitrate); + pbuf[1] = (uint8_t)(LineCoding.bitrate >> 8); + pbuf[2] = (uint8_t)(LineCoding.bitrate >> 16); + pbuf[3] = (uint8_t)(LineCoding.bitrate >> 24); + pbuf[4] = LineCoding.format; + pbuf[5] = LineCoding.paritytype; + pbuf[6] = LineCoding.datatype; + #endif + + /* Add your code here */ + pbuf[0] = (uint8_t)(115200); + pbuf[1] = (uint8_t)(115200 >> 8); + pbuf[2] = (uint8_t)(115200 >> 16); + pbuf[3] = (uint8_t)(115200 >> 24); + pbuf[4] = 0; // stop bits (1) + pbuf[5] = 0; // parity (none) + pbuf[6] = 8; // number of bits (8) + break; + + case CDC_SET_CONTROL_LINE_STATE: + dev_is_connected = length & 1; // wValue is passed in Len (bit of a hack) + break; + + case CDC_SEND_BREAK: + /* Add your code here */ + break; + + default: + break; + } + + return USBD_OK; } /** @@ -328,6 +338,10 @@ static int8_t CDC_Itf_Receive(uint8_t* Buf, uint32_t *Len) { return (USBD_OK); } +int USBD_CDC_IsConnected(void) { + return dev_is_connected; +} + void USBD_CDC_SetInterrupt(int chr, void *data) { user_interrupt_char = chr; user_interrupt_data = data; diff --git a/stmhal/usbd_cdc_interface.h b/stmhal/usbd_cdc_interface.h index b50cbf4c29..bcb6333a6a 100644 --- a/stmhal/usbd_cdc_interface.h +++ b/stmhal/usbd_cdc_interface.h @@ -49,6 +49,7 @@ extern const USBD_CDC_ItfTypeDef USBD_CDC_fops;
+int USBD_CDC_IsConnected(void);
void USBD_CDC_SetInterrupt(int chr, void *data);
void USBD_CDC_Tx(const char *str, uint32_t len);
int USBD_CDC_RxNum(void);
diff --git a/stmhal/usbd_conf.c b/stmhal/usbd_conf.c index 4a4414afe2..9df3b673c3 100644 --- a/stmhal/usbd_conf.c +++ b/stmhal/usbd_conf.c @@ -342,10 +342,12 @@ USBD_StatusTypeDef USBD_LL_Init (USBD_HandleTypeDef *pdev) pdev->pData = &hpcd;
/*Initialize LL Driver */
HAL_PCD_Init(&hpcd);
-
+
HAL_PCD_SetRxFiFo(&hpcd, 0x80);
- HAL_PCD_SetTxFiFo(&hpcd, 0, 0x40);
- HAL_PCD_SetTxFiFo(&hpcd, 1, 0x80);
+ HAL_PCD_SetTxFiFo(&hpcd, 0, 0x20);
+ HAL_PCD_SetTxFiFo(&hpcd, 1, 0x40);
+ HAL_PCD_SetTxFiFo(&hpcd, 2, 0x20);
+ HAL_PCD_SetTxFiFo(&hpcd, 3, 0x40);
#endif
diff --git a/stmhal/usbd_conf.h b/stmhal/usbd_conf.h index cc3ad73f98..d37cd4a8ba 100644 --- a/stmhal/usbd_conf.h +++ b/stmhal/usbd_conf.h @@ -36,7 +36,6 @@ #include <string.h>
#include "mpconfig.h"
-#include "gc.h" // for gc_alloc and gc_free
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
@@ -47,17 +46,18 @@ #define USBD_SUPPORT_USER_STRING 0
#define USBD_SELF_POWERED 0
#define USBD_DEBUG_LEVEL 0
-
-// for MSC device
-#define MSC_MEDIA_PACKET 8192
/* Exported macro ------------------------------------------------------------*/
/* Memory management macros */
+/*
+these should not be used because the GC is reset on a soft reset but the usb is not
+#include "gc.h"
#define USBD_malloc gc_alloc
#define USBD_free gc_free
#define USBD_memset memset
#define USBD_memcpy memcpy
-
+*/
+
/* DEBUG macros */
#if (USBD_DEBUG_LEVEL > 0)
#define USBD_UsrLog(...) printf(__VA_ARGS__);\
diff --git a/stmhal/usbd_desc_vcp.c b/stmhal/usbd_desc_cdc_msc.c index edcb4b3431..edcb4b3431 100644 --- a/stmhal/usbd_desc_vcp.c +++ b/stmhal/usbd_desc_cdc_msc.c diff --git a/stmhal/usbd_desc_msc.c b/stmhal/usbd_desc_msc.c deleted file mode 100644 index 7d0911e82c..0000000000 --- a/stmhal/usbd_desc_msc.c +++ /dev/null @@ -1,227 +0,0 @@ -/**
- ******************************************************************************
- * @file USB_Device/MSC_Standalone/Src/usbd_desc.c
- * @author MCD Application Team
- * @version V1.0.1
- * @date 26-February-2014
- * @brief This file provides the USBD descriptors and string formating method.
- ******************************************************************************
- * @attention
- *
- * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
- *
- * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
- * You may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.st.com/software_license_agreement_liberty_v2
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- ******************************************************************************
- */
-
-/* Includes ------------------------------------------------------------------*/
-#include "usbd_core.h"
-#include "usbd_desc.h"
-#include "usbd_conf.h"
-
-/* Private typedef -----------------------------------------------------------*/
-/* Private define ------------------------------------------------------------*/
-#define USBD_VID 0x0483
-#define USBD_PID 0x5720
-#define USBD_LANGID_STRING 0x409
-#define USBD_MANUFACTURER_STRING "STMicroelectronics"
-#define USBD_PRODUCT_HS_STRING "Mass Storage in HS Mode"
-#define USBD_SERIALNUMBER_HS_STRING "00000000001A"
-#define USBD_PRODUCT_FS_STRING "Mass Storage in FS Mode"
-#define USBD_SERIALNUMBER_FS_STRING "00000000001B"
-#define USBD_CONFIGURATION_HS_STRING "MSC Config"
-#define USBD_INTERFACE_HS_STRING "MSC Interface"
-#define USBD_CONFIGURATION_FS_STRING "MSC Config"
-#define USBD_INTERFACE_FS_STRING "MSC Interface"
-
-/* Private macro -------------------------------------------------------------*/
-/* Private function prototypes -----------------------------------------------*/
-uint8_t *USBD_MSC_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
-uint8_t *USBD_MSC_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
-uint8_t *USBD_MSC_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
-uint8_t *USBD_MSC_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
-uint8_t *USBD_MSC_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
-uint8_t *USBD_MSC_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
-uint8_t *USBD_MSC_InterfaceStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
-#ifdef USB_SUPPORT_USER_STRING_DESC
-uint8_t *USBD_MSC_USRStringDesc(USBD_SpeedTypeDef speed, uint8_t idx, uint16_t *length);
-#endif /* USB_SUPPORT_USER_STRING_DESC */
-
-/* Private variables ---------------------------------------------------------*/
-USBD_DescriptorsTypeDef MSC_Desc = {
- USBD_MSC_DeviceDescriptor,
- USBD_MSC_LangIDStrDescriptor,
- USBD_MSC_ManufacturerStrDescriptor,
- USBD_MSC_ProductStrDescriptor,
- USBD_MSC_SerialStrDescriptor,
- USBD_MSC_ConfigStrDescriptor,
- USBD_MSC_InterfaceStrDescriptor,
-};
-
-/* USB Standard Device Descriptor */
-#if defined ( __ICCARM__ ) /*!< IAR Compiler */
- #pragma data_alignment=4
-#endif
-__ALIGN_BEGIN static uint8_t USBD_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = {
- 0x12, /* bLength */
- USB_DESC_TYPE_DEVICE, /* bDescriptorType */
- 0x00, /* bcdUSB */
- 0x02,
- 0x00, /* bDeviceClass */
- 0x00, /* bDeviceSubClass */
- 0x00, /* bDeviceProtocol */
- USB_MAX_EP0_SIZE, /* bMaxPacketSize */
- LOBYTE(USBD_VID), /* idVendor */
- HIBYTE(USBD_VID), /* idVendor */
- LOBYTE(USBD_PID), /* idVendor */
- HIBYTE(USBD_PID), /* idVendor */
- 0x00, /* bcdDevice rel. 2.00 */
- 0x02,
- USBD_IDX_MFC_STR, /* Index of manufacturer string */
- USBD_IDX_PRODUCT_STR, /* Index of product string */
- USBD_IDX_SERIAL_STR, /* Index of serial number string */
- USBD_MAX_NUM_CONFIGURATION /* bNumConfigurations */
-}; /* USB_DeviceDescriptor */
-
-/* USB Standard Device Descriptor */
-#if defined ( __ICCARM__ ) /*!< IAR Compiler */
- #pragma data_alignment=4
-#endif
-__ALIGN_BEGIN static uint8_t USBD_LangIDDesc[USB_LEN_LANGID_STR_DESC] __ALIGN_END = {
- USB_LEN_LANGID_STR_DESC,
- USB_DESC_TYPE_STRING,
- LOBYTE(USBD_LANGID_STRING),
- HIBYTE(USBD_LANGID_STRING),
-};
-
-#if defined ( __ICCARM__ ) /*!< IAR Compiler */
- #pragma data_alignment=4
-#endif
-__ALIGN_BEGIN static uint8_t USBD_StrDesc[USBD_MAX_STR_DESC_SIZ] __ALIGN_END;
-
-/* Private functions ---------------------------------------------------------*/
-
-/**
- * @brief Returns the device descriptor.
- * @param speed: Current device speed
- * @param length: Pointer to data length variable
- * @retval Pointer to descriptor buffer
- */
-uint8_t *USBD_MSC_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
-{
- *length = sizeof(USBD_DeviceDesc);
- return USBD_DeviceDesc;
-}
-
-/**
- * @brief Returns the LangID string descriptor.
- * @param speed: Current device speed
- * @param length: Pointer to data length variable
- * @retval Pointer to descriptor buffer
- */
-uint8_t *USBD_MSC_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
-{
- *length = sizeof(USBD_LangIDDesc);
- return USBD_LangIDDesc;
-}
-
-/**
- * @brief Returns the product string descriptor.
- * @param speed: Current device speed
- * @param length: Pointer to data length variable
- * @retval Pointer to descriptor buffer
- */
-uint8_t *USBD_MSC_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
-{
- if(speed == 0)
- {
- USBD_GetString((uint8_t *)(uint8_t *)USBD_PRODUCT_HS_STRING, USBD_StrDesc, length);
- }
- else
- {
- USBD_GetString((uint8_t *)(uint8_t *)USBD_PRODUCT_FS_STRING, USBD_StrDesc, length);
- }
- return USBD_StrDesc;
-}
-
-/**
- * @brief Returns the manufacturer string descriptor.
- * @param speed: Current device speed
- * @param length: Pointer to data length variable
- * @retval Pointer to descriptor buffer
- */
-uint8_t *USBD_MSC_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
-{
- USBD_GetString((uint8_t *)(uint8_t *)USBD_MANUFACTURER_STRING, USBD_StrDesc, length);
- return USBD_StrDesc;
-}
-
-/**
- * @brief Returns the serial number string descriptor.
- * @param speed: Current device speed
- * @param length: Pointer to data length variable
- * @retval Pointer to descriptor buffer
- */
-uint8_t *USBD_MSC_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
-{
- if(speed == USBD_SPEED_HIGH)
- {
- USBD_GetString((uint8_t *)(uint8_t *)USBD_SERIALNUMBER_HS_STRING, USBD_StrDesc, length);
- }
- else
- {
- USBD_GetString((uint8_t *)(uint8_t *)USBD_SERIALNUMBER_FS_STRING, USBD_StrDesc, length);
- }
- return USBD_StrDesc;
-}
-
-/**
- * @brief Returns the configuration string descriptor.
- * @param speed: Current device speed
- * @param length: Pointer to data length variable
- * @retval Pointer to descriptor buffer
- */
-uint8_t *USBD_MSC_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
-{
- if(speed == USBD_SPEED_HIGH)
- {
- USBD_GetString((uint8_t *)(uint8_t *)USBD_CONFIGURATION_HS_STRING, USBD_StrDesc, length);
- }
- else
- {
- USBD_GetString((uint8_t *)(uint8_t *)USBD_CONFIGURATION_FS_STRING, USBD_StrDesc, length);
- }
- return USBD_StrDesc;
-}
-
-/**
- * @brief Returns the interface string descriptor.
- * @param speed: Current device speed
- * @param length: Pointer to data length variable
- * @retval Pointer to descriptor buffer
- */
-uint8_t *USBD_MSC_InterfaceStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
-{
- if(speed == 0)
- {
- USBD_GetString((uint8_t *)(uint8_t *)USBD_INTERFACE_HS_STRING, USBD_StrDesc, length);
- }
- else
- {
- USBD_GetString((uint8_t *)(uint8_t *)USBD_INTERFACE_FS_STRING, USBD_StrDesc, length);
- }
- return USBD_StrDesc;
-}
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/stmhal/usbd_msc_storage.c b/stmhal/usbd_msc_storage.c index e5c75e27c7..ce6d3a5608 100644 --- a/stmhal/usbd_msc_storage.c +++ b/stmhal/usbd_msc_storage.c @@ -27,7 +27,7 @@ ****************************************************************************** */ -#include "usbd_msc.h" +#include "usbd_cdc_msc.h" #include "usbd_msc_storage.h" #include "misc.h" diff --git a/stmhal/usbdev/class/cdc_msc/inc/usbd_cdc_msc.h b/stmhal/usbdev/class/cdc_msc/inc/usbd_cdc_msc.h new file mode 100644 index 0000000000..5299f31e96 --- /dev/null +++ b/stmhal/usbdev/class/cdc_msc/inc/usbd_cdc_msc.h @@ -0,0 +1,132 @@ +#ifndef _USB_CDC_MSC_CORE_H_ +#define _USB_CDC_MSC_CORE_H_ + +#include "usbd_msc_bot.h" +#include "usbd_msc_scsi.h" +#include "usbd_ioreq.h" + +// CDC and MSC packet sizes +#define CDC_DATA_FS_MAX_PACKET_SIZE (64) // endpoint IN & OUT packet size +#define MSC_MEDIA_PACKET (2048) // was 8192; how low can it go whilst still working? + +#if 0 +// CDC +#define USB_CDC_MSC_CONFIG_DESC_SIZ (75) +#define NUM_INTERFACES (2) +#define USE_CDC (1) +#define USE_MSC (0) +#define CDC_IN_EP 0x81 /* EP1 for data IN */ +#define CDC_OUT_EP 0x01 /* EP1 for data OUT */ +#define CDC_CMD_EP 0x82 /* EP2 for CDC commands */ +#define MSC_IN_EP (0x83) +#define MSC_OUT_EP (0x03) +#elif 0 +// MSC +#define USB_CDC_MSC_CONFIG_DESC_SIZ (32) +#define NUM_INTERFACES (1) +#define USE_CDC (0) +#define USE_MSC (1) +#define CDC_IN_EP 0x81 /* EP1 for data IN */ +#define CDC_OUT_EP 0x01 /* EP1 for data OUT */ +#define CDC_CMD_EP 0x82 /* EP2 for CDC commands */ +#define MSC_IFACE_NUM (0) +#define MSC_IN_EP (0x81) +#define MSC_OUT_EP (0x01) +#elif 1 +// CDC + MSC +#define USB_CDC_MSC_CONFIG_DESC_SIZ (98) +#define NUM_INTERFACES (3) +#define USE_CDC (1) +#define USE_MSC (1) +#define CDC_IFACE_NUM (0) +#define CDC_IN_EP 0x81 /* EP1 for data IN */ +#define CDC_OUT_EP 0x01 /* EP1 for data OUT */ +#define CDC_CMD_EP 0x82 /* EP2 for CDC commands */ +#define MSC_IFACE_NUM (2) +#define MSC_IN_EP (0x83) +#define MSC_OUT_EP (0x03) +#else +// MSC + CDC +#define USB_CDC_MSC_CONFIG_DESC_SIZ (98) +#define NUM_INTERFACES (3) +#define USE_CDC (1) +#define USE_MSC (1) +#define CDC_IFACE_NUM (1) +#define CDC_IN_EP 0x83 /* EP1 for data IN */ +#define CDC_OUT_EP 0x03 /* EP1 for data OUT */ +#define CDC_CMD_EP 0x82 /* EP2 for CDC commands */ +#define MSC_IFACE_NUM (0) +#define MSC_IN_EP (0x81) +#define MSC_OUT_EP (0x01) +#endif + +typedef struct { + uint32_t bitrate; + uint8_t format; + uint8_t paritytype; + uint8_t datatype; +} USBD_CDC_LineCodingTypeDef; + +typedef struct _USBD_CDC_Itf { + int8_t (* Init) (void); + int8_t (* DeInit) (void); + int8_t (* Control) (uint8_t, uint8_t * , uint16_t); + int8_t (* Receive) (uint8_t *, uint32_t *); +} USBD_CDC_ItfTypeDef; + +typedef struct { + uint32_t data[CDC_DATA_FS_MAX_PACKET_SIZE/4]; /* Force 32bits alignment */ + uint8_t CmdOpCode; + uint8_t CmdLength; + uint8_t *RxBuffer; + uint8_t *TxBuffer; + uint32_t RxLength; + uint32_t TxLength; + + __IO uint32_t TxState; + __IO uint32_t RxState; +} USBD_CDC_HandleTypeDef; + +typedef struct _USBD_STORAGE { + int8_t (* Init) (uint8_t lun); + int8_t (* GetCapacity) (uint8_t lun, uint32_t *block_num, uint16_t *block_size); + int8_t (* IsReady) (uint8_t lun); + int8_t (* IsWriteProtected) (uint8_t lun); + int8_t (* Read) (uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len); + int8_t (* Write)(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len); + int8_t (* GetMaxLun)(void); + int8_t *pInquiry; +} USBD_StorageTypeDef; + +typedef struct { + uint32_t max_lun; + uint32_t interface; + uint8_t bot_state; + uint8_t bot_status; + uint16_t bot_data_length; + uint8_t bot_data[MSC_MEDIA_PACKET]; + USBD_MSC_BOT_CBWTypeDef cbw; + USBD_MSC_BOT_CSWTypeDef csw; + + USBD_SCSI_SenseTypeDef scsi_sense [SENSE_LIST_DEEPTH]; + uint8_t scsi_sense_head; + uint8_t scsi_sense_tail; + + uint16_t scsi_blk_size; + uint32_t scsi_blk_nbr; + + uint32_t scsi_blk_addr; + uint32_t scsi_blk_len; +} USBD_MSC_BOT_HandleTypeDef; + +extern USBD_ClassTypeDef USBD_CDC_MSC; + +uint8_t USBD_CDC_RegisterInterface (USBD_HandleTypeDef *pdev, USBD_CDC_ItfTypeDef *fops); +uint8_t USBD_CDC_SetTxBuffer (USBD_HandleTypeDef *pdev, uint8_t *pbuff, uint16_t length); +uint8_t USBD_CDC_SetRxBuffer (USBD_HandleTypeDef *pdev, uint8_t *pbuff); +uint8_t USBD_CDC_ReceivePacket (USBD_HandleTypeDef *pdev); +uint8_t USBD_CDC_TransmitPacket (USBD_HandleTypeDef *pdev); + +uint8_t USBD_MSC_RegisterStorage(USBD_HandleTypeDef *pdev, USBD_StorageTypeDef *fops); + +#endif // _USB_CDC_MSC_CORE_H_ diff --git a/stmhal/usbdev/class/cdc_msc/inc/usbd_msc_bot.h b/stmhal/usbdev/class/cdc_msc/inc/usbd_msc_bot.h new file mode 100644 index 0000000000..41f8ab5a53 --- /dev/null +++ b/stmhal/usbdev/class/cdc_msc/inc/usbd_msc_bot.h @@ -0,0 +1,151 @@ +/**
+ ******************************************************************************
+ * @file usbd_msc_bot.h
+ * @author MCD Application Team
+ * @version V2.0.0
+ * @date 18-February-2014
+ * @brief header for the usbd_msc_bot.c file
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+
+#include "usbd_core.h"
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USBD_MSC_BOT_H
+#define __USBD_MSC_BOT_H
+
+/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
+ * @{
+ */
+
+/** @defgroup MSC_BOT
+ * @brief This file is the Header file for usbd_bot.c
+ * @{
+ */
+
+
+/** @defgroup USBD_CORE_Exported_Defines
+ * @{
+ */
+#define USBD_BOT_IDLE 0 /* Idle state */
+#define USBD_BOT_DATA_OUT 1 /* Data Out state */
+#define USBD_BOT_DATA_IN 2 /* Data In state */
+#define USBD_BOT_LAST_DATA_IN 3 /* Last Data In Last */
+#define USBD_BOT_SEND_DATA 4 /* Send Immediate data */
+#define USBD_BOT_NO_DATA 5 /* No data Stage */
+
+#define USBD_BOT_CBW_SIGNATURE 0x43425355
+#define USBD_BOT_CSW_SIGNATURE 0x53425355
+#define USBD_BOT_CBW_LENGTH 31
+#define USBD_BOT_CSW_LENGTH 13
+#define USBD_BOT_MAX_DATA 256
+
+/* CSW Status Definitions */
+#define USBD_CSW_CMD_PASSED 0x00
+#define USBD_CSW_CMD_FAILED 0x01
+#define USBD_CSW_PHASE_ERROR 0x02
+
+/* BOT Status */
+#define USBD_BOT_STATUS_NORMAL 0
+#define USBD_BOT_STATUS_RECOVERY 1
+#define USBD_BOT_STATUS_ERROR 2
+
+
+#define USBD_DIR_IN 0
+#define USBD_DIR_OUT 1
+#define USBD_BOTH_DIR 2
+
+/**
+ * @}
+ */
+
+/** @defgroup MSC_CORE_Private_TypesDefinitions
+ * @{
+ */
+
+typedef struct
+{
+ uint32_t dSignature;
+ uint32_t dTag;
+ uint32_t dDataLength;
+ uint8_t bmFlags;
+ uint8_t bLUN;
+ uint8_t bCBLength;
+ uint8_t CB[16];
+ uint8_t ReservedForAlign;
+}
+USBD_MSC_BOT_CBWTypeDef;
+
+
+typedef struct
+{
+ uint32_t dSignature;
+ uint32_t dTag;
+ uint32_t dDataResidue;
+ uint8_t bStatus;
+ uint8_t ReservedForAlign[3];
+}
+USBD_MSC_BOT_CSWTypeDef;
+
+/**
+ * @}
+ */
+
+
+/** @defgroup USBD_CORE_Exported_Types
+ * @{
+ */
+
+/**
+ * @}
+ */
+/** @defgroup USBD_CORE_Exported_FunctionsPrototypes
+ * @{
+ */
+void MSC_BOT_Init (USBD_HandleTypeDef *pdev);
+void MSC_BOT_Reset (USBD_HandleTypeDef *pdev);
+void MSC_BOT_DeInit (USBD_HandleTypeDef *pdev);
+void MSC_BOT_DataIn (USBD_HandleTypeDef *pdev,
+ uint8_t epnum);
+
+void MSC_BOT_DataOut (USBD_HandleTypeDef *pdev,
+ uint8_t epnum);
+
+void MSC_BOT_SendCSW (USBD_HandleTypeDef *pdev,
+ uint8_t CSW_Status);
+
+void MSC_BOT_CplClrFeature (USBD_HandleTypeDef *pdev,
+ uint8_t epnum);
+/**
+ * @}
+ */
+
+#endif /* __USBD_MSC_BOT_H */
+/**
+ * @}
+ */
+
+/**
+* @}
+*/
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/stmhal/usbdev/class/cdc_msc/inc/usbd_msc_data.h b/stmhal/usbdev/class/cdc_msc/inc/usbd_msc_data.h new file mode 100644 index 0000000000..f468267f43 --- /dev/null +++ b/stmhal/usbdev/class/cdc_msc/inc/usbd_msc_data.h @@ -0,0 +1,104 @@ +/**
+ ******************************************************************************
+ * @file usbd_msc_data.h
+ * @author MCD Application Team
+ * @version V2.0.0
+ * @date 18-February-2014
+ * @brief header for the usbd_msc_data.c file
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+
+#ifndef _USBD_MSC_DATA_H_
+#define _USBD_MSC_DATA_H_
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_conf.h"
+
+/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
+ * @{
+ */
+
+/** @defgroup USB_INFO
+ * @brief general defines for the usb device library file
+ * @{
+ */
+
+/** @defgroup USB_INFO_Exported_Defines
+ * @{
+ */
+#define MODE_SENSE6_LEN 8
+#define MODE_SENSE10_LEN 8
+#define LENGTH_INQUIRY_PAGE00 7
+#define LENGTH_FORMAT_CAPACITIES 20
+
+/**
+ * @}
+ */
+
+
+/** @defgroup USBD_INFO_Exported_TypesDefinitions
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+
+/** @defgroup USBD_INFO_Exported_Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_INFO_Exported_Variables
+ * @{
+ */
+extern const uint8_t MSC_Page00_Inquiry_Data[];
+extern const uint8_t MSC_Mode_Sense6_data[];
+extern const uint8_t MSC_Mode_Sense10_data[] ;
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_INFO_Exported_FunctionsPrototype
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+#endif /* _USBD_MSC_DATA_H_ */
+
+/**
+ * @}
+ */
+
+/**
+* @}
+*/
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/stmhal/usbdev/class/cdc_msc/inc/usbd_msc_scsi.h b/stmhal/usbdev/class/cdc_msc/inc/usbd_msc_scsi.h new file mode 100644 index 0000000000..dea247bca8 --- /dev/null +++ b/stmhal/usbdev/class/cdc_msc/inc/usbd_msc_scsi.h @@ -0,0 +1,193 @@ +/**
+ ******************************************************************************
+ * @file usbd_msc_scsi.h
+ * @author MCD Application Team
+ * @version V2.0.0
+ * @date 18-February-2014
+ * @brief header for the usbd_msc_scsi.c file
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USBD_MSC_SCSI_H
+#define __USBD_MSC_SCSI_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_def.h"
+
+/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
+ * @{
+ */
+
+/** @defgroup USBD_SCSI
+ * @brief header file for the storage disk file
+ * @{
+ */
+
+/** @defgroup USBD_SCSI_Exported_Defines
+ * @{
+ */
+
+#define SENSE_LIST_DEEPTH 4
+
+/* SCSI Commands */
+#define SCSI_FORMAT_UNIT 0x04
+#define SCSI_INQUIRY 0x12
+#define SCSI_MODE_SELECT6 0x15
+#define SCSI_MODE_SELECT10 0x55
+#define SCSI_MODE_SENSE6 0x1A
+#define SCSI_MODE_SENSE10 0x5A
+#define SCSI_ALLOW_MEDIUM_REMOVAL 0x1E
+#define SCSI_READ6 0x08
+#define SCSI_READ10 0x28
+#define SCSI_READ12 0xA8
+#define SCSI_READ16 0x88
+
+#define SCSI_READ_CAPACITY10 0x25
+#define SCSI_READ_CAPACITY16 0x9E
+
+#define SCSI_REQUEST_SENSE 0x03
+#define SCSI_START_STOP_UNIT 0x1B
+#define SCSI_TEST_UNIT_READY 0x00
+#define SCSI_WRITE6 0x0A
+#define SCSI_WRITE10 0x2A
+#define SCSI_WRITE12 0xAA
+#define SCSI_WRITE16 0x8A
+
+#define SCSI_VERIFY10 0x2F
+#define SCSI_VERIFY12 0xAF
+#define SCSI_VERIFY16 0x8F
+
+#define SCSI_SEND_DIAGNOSTIC 0x1D
+#define SCSI_READ_FORMAT_CAPACITIES 0x23
+
+#define NO_SENSE 0
+#define RECOVERED_ERROR 1
+#define NOT_READY 2
+#define MEDIUM_ERROR 3
+#define HARDWARE_ERROR 4
+#define ILLEGAL_REQUEST 5
+#define UNIT_ATTENTION 6
+#define DATA_PROTECT 7
+#define BLANK_CHECK 8
+#define VENDOR_SPECIFIC 9
+#define COPY_ABORTED 10
+#define ABORTED_COMMAND 11
+#define VOLUME_OVERFLOW 13
+#define MISCOMPARE 14
+
+
+#define INVALID_CDB 0x20
+#define INVALID_FIELED_IN_COMMAND 0x24
+#define PARAMETER_LIST_LENGTH_ERROR 0x1A
+#define INVALID_FIELD_IN_PARAMETER_LIST 0x26
+#define ADDRESS_OUT_OF_RANGE 0x21
+#define MEDIUM_NOT_PRESENT 0x3A
+#define MEDIUM_HAVE_CHANGED 0x28
+#define WRITE_PROTECTED 0x27
+#define UNRECOVERED_READ_ERROR 0x11
+#define WRITE_FAULT 0x03
+
+#define READ_FORMAT_CAPACITY_DATA_LEN 0x0C
+#define READ_CAPACITY10_DATA_LEN 0x08
+#define MODE_SENSE10_DATA_LEN 0x08
+#define MODE_SENSE6_DATA_LEN 0x04
+#define REQUEST_SENSE_DATA_LEN 0x12
+#define STANDARD_INQUIRY_DATA_LEN 0x24
+#define BLKVFY 0x04
+
+extern uint8_t Page00_Inquiry_Data[];
+extern uint8_t Standard_Inquiry_Data[];
+extern uint8_t Standard_Inquiry_Data2[];
+extern uint8_t Mode_Sense6_data[];
+extern uint8_t Mode_Sense10_data[];
+extern uint8_t Scsi_Sense_Data[];
+extern uint8_t ReadCapacity10_Data[];
+extern uint8_t ReadFormatCapacity_Data [];
+/**
+ * @}
+ */
+
+
+/** @defgroup USBD_SCSI_Exported_TypesDefinitions
+ * @{
+ */
+
+typedef struct _SENSE_ITEM {
+ char Skey;
+ union {
+ struct _ASCs {
+ char ASC;
+ char ASCQ;
+ }b;
+ unsigned int ASC;
+ char *pData;
+ } w;
+} USBD_SCSI_SenseTypeDef;
+/**
+ * @}
+ */
+
+/** @defgroup USBD_SCSI_Exported_Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_SCSI_Exported_Variables
+ * @{
+ */
+
+/**
+ * @}
+ */
+/** @defgroup USBD_SCSI_Exported_FunctionsPrototype
+ * @{
+ */
+int8_t SCSI_ProcessCmd(USBD_HandleTypeDef *pdev,
+ uint8_t lun,
+ uint8_t *cmd);
+
+void SCSI_SenseCode(USBD_HandleTypeDef *pdev,
+ uint8_t lun,
+ uint8_t sKey,
+ uint8_t ASC);
+
+/**
+ * @}
+ */
+
+#endif /* __USBD_MSC_SCSI_H */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+* @}
+*/
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/stmhal/usbdev/class/cdc_msc/src/usbd_cdc_msc.c b/stmhal/usbdev/class/cdc_msc/src/usbd_cdc_msc.c new file mode 100644 index 0000000000..07e801e9bd --- /dev/null +++ b/stmhal/usbdev/class/cdc_msc/src/usbd_cdc_msc.c @@ -0,0 +1,578 @@ +#include "usbd_ioreq.h" +#include "usbd_cdc_msc.h" + +#define USB_DESC_TYPE_ASSOCIATION (0x0b) + +#define CDC_CMD_PACKET_SIZE 8 // Control Endpoint Packet size +#define CDC_DATA_FS_IN_PACKET_SIZE CDC_DATA_FS_MAX_PACKET_SIZE +#define CDC_DATA_FS_OUT_PACKET_SIZE CDC_DATA_FS_MAX_PACKET_SIZE + +#define BOT_GET_MAX_LUN 0xFE +#define BOT_RESET 0xFF +#define USB_MSC_CONFIG_DESC_SIZ 32 + +#define MSC_MAX_FS_PACKET 0x40 + +static USBD_CDC_ItfTypeDef *CDC_fops; +static USBD_StorageTypeDef *MSC_fops; + +static USBD_CDC_HandleTypeDef CDC_ClassData; +static USBD_MSC_BOT_HandleTypeDef MSC_BOT_ClassData; + +// I don't think we can make these descriptors constant because they are +// modified (perhaps unnecessarily) by the USB driver. + +// USB Standard Device Descriptor +__ALIGN_BEGIN static uint8_t USBD_CDC_MSC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END = { + USB_LEN_DEV_QUALIFIER_DESC, + USB_DESC_TYPE_DEVICE_QUALIFIER, + 0x00, + 0x02, + 0x00, + 0x00, + 0x00, + 0x40, // same for CDC and MSC (latter being MSC_MAX_FS_PACKET) + 0x01, + 0x00, +}; + +// USB CDC MSC device Configuration Descriptor +__ALIGN_BEGIN static uint8_t USBD_CDC_MSC_CfgFSDesc[USB_CDC_MSC_CONFIG_DESC_SIZ] __ALIGN_END = { + //-------------------------------------------------------------------------- + // Configuration Descriptor + 0x09, // bLength: Configuration Descriptor size + USB_DESC_TYPE_CONFIGURATION, // bDescriptorType: Configuration + LOBYTE(USB_CDC_MSC_CONFIG_DESC_SIZ), // wTotalLength: no of returned bytes + HIBYTE(USB_CDC_MSC_CONFIG_DESC_SIZ), + NUM_INTERFACES, // bNumInterfaces: 3 interfaces + 0x01, // bConfigurationValue: Configuration value + 0x00, // iConfiguration: Index of string descriptor describing the configuration + 0x80, // bmAttributes: bus powered; 0xc0 for self powered + 0xfa, // bMaxPower: in units of 2mA + +#if USE_CDC + //========================================================================== + // Interface Association for CDC VCP + 0x08, // bLength: 8 bytes + USB_DESC_TYPE_ASSOCIATION, // bDescriptorType: IAD + CDC_IFACE_NUM, // bFirstInterface: first interface for this association + 0x02, // bInterfaceCount: nummber of interfaces for this association + 0x00, // bFunctionClass: ? + 0x00, // bFunctionSubClass: ? + 0x00, // bFunctionProtocol: ? + 0x00, // iFunction: index of string for this function + + //-------------------------------------------------------------------------- + // Interface Descriptor + 0x09, // bLength: Interface Descriptor size + USB_DESC_TYPE_INTERFACE, // bDescriptorType: Interface + CDC_IFACE_NUM, // bInterfaceNumber: Number of Interface + 0x00, // bAlternateSetting: Alternate setting + 0x01, // bNumEndpoints: One endpoints used + 0x02, // bInterfaceClass: Communication Interface Class + 0x02, // bInterfaceSubClass: Abstract Control Model + 0x01, // bInterfaceProtocol: Common AT commands + 0x00, // iInterface: + + // Header Functional Descriptor + 0x05, // bLength: Endpoint Descriptor size + 0x24, // bDescriptorType: CS_INTERFACE + 0x00, // bDescriptorSubtype: Header Func Desc + 0x10, // bcdCDC: spec release number + 0x01, // ? + + // Call Management Functional Descriptor + 0x05, // bFunctionLength + 0x24, // bDescriptorType: CS_INTERFACE + 0x01, // bDescriptorSubtype: Call Management Func Desc + 0x00, // bmCapabilities: D0+D1 + CDC_IFACE_NUM + 1, // bDataInterface: 1 + + // ACM Functional Descriptor + 0x04, // bFunctionLength + 0x24, // bDescriptorType: CS_INTERFACE + 0x02, // bDescriptorSubtype: Abstract Control Management desc + 0x02, // bmCapabilities + + // Union Functional Descriptor + 0x05, // bFunctionLength + 0x24, // bDescriptorType: CS_INTERFACE + 0x06, // bDescriptorSubtype: Union func desc + CDC_IFACE_NUM + 0, // bMasterInterface: Communication class interface + CDC_IFACE_NUM + 1, // bSlaveInterface0: Data Class Interface + + // Endpoint 2 Descriptor + 0x07, // bLength: Endpoint Descriptor size + USB_DESC_TYPE_ENDPOINT, // bDescriptorType: Endpoint + CDC_CMD_EP, // bEndpointAddress + 0x03, // bmAttributes: Interrupt + LOBYTE(CDC_CMD_PACKET_SIZE), // wMaxPacketSize: + HIBYTE(CDC_CMD_PACKET_SIZE), + 0x20, // bInterval: polling interval in frames of 1ms + + //-------------------------------------------------------------------------- + // Data class interface descriptor + 0x09, // bLength: Endpoint Descriptor size + USB_DESC_TYPE_INTERFACE, // bDescriptorType: interface + CDC_IFACE_NUM + 1, // bInterfaceNumber: Number of Interface + 0x00, // bAlternateSetting: Alternate setting + 0x02, // bNumEndpoints: Two endpoints used + 0x0A, // bInterfaceClass: CDC + 0x00, // bInterfaceSubClass: ? + 0x00, // bInterfaceProtocol: ? + 0x00, // iInterface: + + // Endpoint OUT Descriptor + 0x07, // bLength: Endpoint Descriptor size + USB_DESC_TYPE_ENDPOINT, // bDescriptorType: Endpoint + CDC_OUT_EP, // bEndpointAddress + 0x02, // bmAttributes: Bulk + LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),// wMaxPacketSize: + HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), + 0x00, // bInterval: ignore for Bulk transfer + + // Endpoint IN Descriptor + 0x07, // bLength: Endpoint Descriptor size + USB_DESC_TYPE_ENDPOINT, // bDescriptorType: Endpoint + CDC_IN_EP, // bEndpointAddress + 0x02, // bmAttributes: Bulk + LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),// wMaxPacketSize: + HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), + 0x00, // bInterval: ignore for Bulk transfer +#endif + +#if USE_MSC + //========================================================================== + // MSC only has 1 interface so doesn't need an IAD + + //-------------------------------------------------------------------------- + // Interface Descriptor + 0x09, // bLength: Interface Descriptor size + USB_DESC_TYPE_INTERFACE, // bDescriptorType: interface descriptor + MSC_IFACE_NUM, // bInterfaceNumber: Number of Interface + 0x00, // bAlternateSetting: Alternate setting + 0x02, // bNumEndpoints + 0x08, // bInterfaceClass: MSC Class + 0x06, // bInterfaceSubClass : SCSI transparent + 0x50, // nInterfaceProtocol + 0x00, // iInterface: + + // Endpoint IN descriptor + 0x07, // bLength: Endpoint descriptor length + USB_DESC_TYPE_ENDPOINT, // bDescriptorType: Endpoint descriptor type + MSC_IN_EP, // bEndpointAddress: IN, address 3 + 0x02, // bmAttributes: Bulk endpoint type + LOBYTE(MSC_MAX_FS_PACKET), // wMaxPacketSize + HIBYTE(MSC_MAX_FS_PACKET), + 0x00, // bInterval: ignore for Bulk transfer + + // Endpoint OUT descriptor + 0x07, // bLength: Endpoint descriptor length + USB_DESC_TYPE_ENDPOINT, // bDescriptorType: Endpoint descriptor type + MSC_OUT_EP, // bEndpointAddress: OUT, address 3 + 0x02, // bmAttributes: Bulk endpoint type + LOBYTE(MSC_MAX_FS_PACKET), // wMaxPacketSize + HIBYTE(MSC_MAX_FS_PACKET), + 0x00, // bInterval: ignore for Bulk transfer +#endif +}; + +static uint8_t USBD_CDC_MSC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) { + if (pdev->dev_speed == USBD_SPEED_HIGH) { + // can't handle high speed + return 1; + } + +#if USE_CDC + //---------------------------------- + // CDC VCP component + + // Open EP IN + USBD_LL_OpenEP(pdev, + CDC_IN_EP, + USBD_EP_TYPE_BULK, + CDC_DATA_FS_IN_PACKET_SIZE); + + // Open EP OUT + USBD_LL_OpenEP(pdev, + CDC_OUT_EP, + USBD_EP_TYPE_BULK, + CDC_DATA_FS_OUT_PACKET_SIZE); + + // Open Command IN EP + USBD_LL_OpenEP(pdev, + CDC_CMD_EP, + USBD_EP_TYPE_INTR, + CDC_CMD_PACKET_SIZE); + + // Init physical Interface components + CDC_fops->Init(); + + // Init Xfer states + CDC_ClassData.TxState =0; + CDC_ClassData.RxState =0; + + // Prepare Out endpoint to receive next packet + USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, CDC_ClassData.RxBuffer, CDC_DATA_FS_OUT_PACKET_SIZE); +#endif + +#if USE_MSC + //---------------------------------- + // MSC component + + // Open EP OUT + USBD_LL_OpenEP(pdev, + MSC_OUT_EP, + USBD_EP_TYPE_BULK, + MSC_MAX_FS_PACKET); + + // Open EP IN + USBD_LL_OpenEP(pdev, + MSC_IN_EP, + USBD_EP_TYPE_BULK, + MSC_MAX_FS_PACKET); + + // MSC uses the pClassData pointer because SCSI and BOT reference it + pdev->pClassData = &MSC_BOT_ClassData; + + // Init the BOT layer + MSC_BOT_Init(pdev); +#endif + + return 0; +} + +static uint8_t USBD_CDC_MSC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) { +#if USD_CDC + //---------------------------------- + // CDC VCP component + + // close endpoints + USBD_LL_CloseEP(pdev, CDC_IN_EP); + USBD_LL_CloseEP(pdev, CDC_OUT_EP); + USBD_LL_CloseEP(pdev, CDC_CMD_EP); + + // DeInit physical Interface components + CDC_fops->DeInit(); +#endif + +#if USE_MSC + //---------------------------------- + // MSC component + + // close endpoints + USBD_LL_CloseEP(pdev, MSC_OUT_EP); + USBD_LL_CloseEP(pdev, MSC_IN_EP); + + // DeInit the BOT layer + MSC_BOT_DeInit(pdev); + + // clear the pointer + pdev->pClassData = NULL; +#endif + + return 0; +} + +static uint8_t USBD_CDC_MSC_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { + + /* + printf("SU: %x %x %x %x\n", req->bmRequest, req->bRequest, req->wValue, req->wIndex); + This is what we get when MSC is IFACE=0 and CDC is IFACE=1,2: + SU: 21 22 0 1 -- USB_REQ_TYPE_CLASS | USB_REQ_RECIPIENT_INTERFACE; CDC_SET_CONTROL_LINE_STATE + SU: 21 20 0 1 -- USB_REQ_TYPE_CLASS | USB_REQ_RECIPIENT_INTERFACE; CDC_SET_LINE_CODING + SU: a1 fe 0 0 -- 0x80 | USB_REQ_TYPE_CLASS | USB_REQ_RECIPIENT_INTERFACE; BOT_GET_MAX_LUN; 0; 0 + SU: 21 22 3 1 -- USB_REQ_TYPE_CLASS | USB_REQ_RECIPIENT_INTERFACE; CDC_SET_CONTROL_LINE_STATE + */ + + switch (req->bmRequest & USB_REQ_TYPE_MASK) { + + // Class request + case USB_REQ_TYPE_CLASS: + // req->wIndex is the recipient interface number + if (0) { +#if USE_CDC + } else if (req->wIndex == CDC_IFACE_NUM) { + // CDC component + if (req->wLength) { + if (req->bmRequest & 0x80) { + // device-to-host request + CDC_fops->Control(req->bRequest, (uint8_t*)CDC_ClassData.data, req->wLength); + USBD_CtlSendData(pdev, (uint8_t*)CDC_ClassData.data, req->wLength); + } else { + // host-to-device request + CDC_ClassData.CmdOpCode = req->bRequest; + CDC_ClassData.CmdLength = req->wLength; + USBD_CtlPrepareRx(pdev, (uint8_t*)CDC_ClassData.data, req->wLength); + } + } else { + // Not a Data request + // Transfer the command to the interface layer + return CDC_fops->Control(req->bRequest, NULL, req->wValue); + } + break; +#endif +#if USE_MSC + } else if (req->wIndex == MSC_IFACE_NUM) { + // MSC component + switch (req->bRequest) { + case BOT_GET_MAX_LUN : + + if((req->wValue == 0) && + (req->wLength == 1) && + ((req->bmRequest & 0x80) == 0x80)) + { + MSC_BOT_ClassData.max_lun = MSC_fops->GetMaxLun(); + USBD_CtlSendData (pdev, (uint8_t *)&MSC_BOT_ClassData.max_lun, 1); + } + else + { + USBD_CtlError(pdev , req); + return USBD_FAIL; + } + break; + + case BOT_RESET : + if((req->wValue == 0) && + (req->wLength == 0) && + ((req->bmRequest & 0x80) != 0x80)) + { + MSC_BOT_Reset(pdev); + } + else + { + USBD_CtlError(pdev , req); + return USBD_FAIL; + } + break; + + default: + USBD_CtlError(pdev , req); + return USBD_FAIL; + } + break; + } +#endif + break; + + /* Interface & Endpoint request */ + case USB_REQ_TYPE_STANDARD: +#if USE_MSC + // MSC only + switch (req->bRequest) { + case USB_REQ_GET_INTERFACE : + USBD_CtlSendData(pdev, (uint8_t *)&MSC_BOT_ClassData.interface, 1); + break; + + case USB_REQ_SET_INTERFACE : + MSC_BOT_ClassData.interface = (uint8_t)(req->wValue); + break; + + case USB_REQ_CLEAR_FEATURE: + /* Flush the FIFO and Clear the stall status */ + USBD_LL_FlushEP(pdev, (uint8_t)req->wIndex); + + /* Re-activate the EP */ + USBD_LL_CloseEP (pdev , (uint8_t)req->wIndex); + if((((uint8_t)req->wIndex) & 0x80) == 0x80) { + /* Open EP IN */ + USBD_LL_OpenEP(pdev, MSC_IN_EP, USBD_EP_TYPE_BULK, MSC_MAX_FS_PACKET); + } else { + /* Open EP OUT */ + USBD_LL_OpenEP(pdev, MSC_OUT_EP, USBD_EP_TYPE_BULK, MSC_MAX_FS_PACKET); + } + /* Handle BOT error */ + MSC_BOT_CplClrFeature(pdev, (uint8_t)req->wIndex); + break; + } +#endif + break; + } + return USBD_OK; +} + +static uint8_t USBD_CDC_MSC_EP0_RxReady(USBD_HandleTypeDef *pdev) { + if((CDC_fops != NULL) && (CDC_ClassData.CmdOpCode != 0xFF)) { + CDC_fops->Control(CDC_ClassData.CmdOpCode, + (uint8_t *)CDC_ClassData.data, + CDC_ClassData.CmdLength); + CDC_ClassData.CmdOpCode = 0xFF; + + } + return USBD_OK; +} + +static uint8_t USBD_CDC_MSC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) { + switch (epnum) { +#if USE_CDC + case (CDC_IN_EP & 0x7f): + case (CDC_CMD_EP & 0x7f): + CDC_ClassData.TxState = 0; + return USBD_OK; +#endif + + case (MSC_IN_EP & 0x7f): + MSC_BOT_DataIn(pdev, epnum); + return USBD_OK; + } + + return USBD_OK; +} + +static uint8_t USBD_CDC_MSC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) { + switch (epnum) { +#if USE_CDC + case (CDC_OUT_EP & 0x7f): + /* Get the received data length */ + CDC_ClassData.RxLength = USBD_LL_GetRxDataSize (pdev, epnum); + + /* USB data will be immediately processed, this allow next USB traffic being + NAKed till the end of the application Xfer */ + CDC_fops->Receive(CDC_ClassData.RxBuffer, &CDC_ClassData.RxLength); + + return USBD_OK; +#endif + + case (MSC_OUT_EP & 0x7f): + MSC_BOT_DataOut(pdev, epnum); + return USBD_OK; + } + + return USBD_OK; +} + +static uint8_t *USBD_CDC_MSC_GetFSCfgDesc(uint16_t *length) { + *length = sizeof(USBD_CDC_MSC_CfgFSDesc); + return USBD_CDC_MSC_CfgFSDesc; +} + +static uint8_t *USBD_CDC_MSC_GetHSCfgDesc(uint16_t *length) { + *length = 0; + return USBD_CDC_MSC_CfgFSDesc; // need to return something because the USB driver writes bytes to the result +} + +static uint8_t *USBD_CDC_MSC_GetOtherSpeedCfgDesc (uint16_t *length) { + *length = 0; + return USBD_CDC_MSC_CfgFSDesc; // need to return something because the USB driver writes bytes to the result +} + +uint8_t *USBD_CDC_MSC_GetDeviceQualifierDescriptor (uint16_t *length) { + *length = sizeof(USBD_CDC_MSC_DeviceQualifierDesc); + return USBD_CDC_MSC_DeviceQualifierDesc; +} + +uint8_t USBD_CDC_RegisterInterface(USBD_HandleTypeDef *pdev, USBD_CDC_ItfTypeDef *fops) { + if (fops == NULL) { + return USBD_FAIL; + } else { + CDC_fops = fops; + return USBD_OK; + } +} + +/** + * @brief USBD_CDC_SetTxBuffer + * @param pdev: device instance + * @param pbuff: Tx Buffer + * @retval status + */ +uint8_t USBD_CDC_SetTxBuffer (USBD_HandleTypeDef *pdev, + uint8_t *pbuff, + uint16_t length) +{ + CDC_ClassData.TxBuffer = pbuff; + CDC_ClassData.TxLength = length; + + return USBD_OK; +} + + +/** + * @brief USBD_CDC_SetRxBuffer + * @param pdev: device instance + * @param pbuff: Rx Buffer + * @retval status + */ +uint8_t USBD_CDC_SetRxBuffer (USBD_HandleTypeDef *pdev, + uint8_t *pbuff) +{ + CDC_ClassData.RxBuffer = pbuff; + + return USBD_OK; +} + +/** + * @brief USBD_CDC_DataOut + * Data received on non-control Out endpoint + * @param pdev: device instance + * @param epnum: endpoint number + * @retval status + */ +uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev) { + if(CDC_ClassData.TxState == 0) { + + /* Transmit next packet */ + USBD_LL_Transmit(pdev, + CDC_IN_EP, + CDC_ClassData.TxBuffer, + CDC_ClassData.TxLength); + + /* Tx Transfer in progress */ + CDC_ClassData.TxState = 1; + return USBD_OK; + } + else + { + return USBD_BUSY; + } +} + + +/** + * @brief USBD_CDC_ReceivePacket + * prepare OUT Endpoint for reception + * @param pdev: device instance + * @retval status + */ +uint8_t USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev) { + // Suspend or Resume USB Out process + if (pdev->dev_speed == USBD_SPEED_HIGH) { + return USBD_FAIL; + } + + // Prepare Out endpoint to receive next packet */ + USBD_LL_PrepareReceive(pdev, + CDC_OUT_EP, + CDC_ClassData.RxBuffer, + CDC_DATA_FS_OUT_PACKET_SIZE); + + return USBD_OK; +} + +uint8_t USBD_MSC_RegisterStorage(USBD_HandleTypeDef *pdev, USBD_StorageTypeDef *fops) { + if (fops == NULL) { + return USBD_FAIL; + } else { + MSC_fops = fops; + pdev->pUserData = fops; // MSC uses pUserData because SCSI and BOT reference it + return USBD_OK; + } +} + +// CDC + MSC interface class callbacks structure +USBD_ClassTypeDef USBD_CDC_MSC = { + USBD_CDC_MSC_Init, + USBD_CDC_MSC_DeInit, + USBD_CDC_MSC_Setup, + NULL, // EP0_TxSent + USBD_CDC_MSC_EP0_RxReady, + USBD_CDC_MSC_DataIn, + USBD_CDC_MSC_DataOut, + NULL, // SOF + NULL, + NULL, + USBD_CDC_MSC_GetHSCfgDesc, + USBD_CDC_MSC_GetFSCfgDesc, + USBD_CDC_MSC_GetOtherSpeedCfgDesc, + USBD_CDC_MSC_GetDeviceQualifierDescriptor, +}; diff --git a/stmhal/usbdev/class/cdc_msc/src/usbd_msc.c b/stmhal/usbdev/class/cdc_msc/src/usbd_msc.c new file mode 100644 index 0000000000..7817c98b1c --- /dev/null +++ b/stmhal/usbdev/class/cdc_msc/src/usbd_msc.c @@ -0,0 +1,609 @@ +/**
+ ******************************************************************************
+ * @file usbd_msc_core.c
+ * @author MCD Application Team
+ * @version V2.0.0
+ * @date 18-February-2014
+ * @brief This file provides all the MSC core functions.
+ *
+ * @verbatim
+ *
+ * ===================================================================
+ * MSC Class Description
+ * ===================================================================
+ * This module manages the MSC class V1.0 following the "Universal
+ * Serial Bus Mass Storage Class (MSC) Bulk-Only Transport (BOT) Version 1.0
+ * Sep. 31, 1999".
+ * This driver implements the following aspects of the specification:
+ * - Bulk-Only Transport protocol
+ * - Subclass : SCSI transparent command set (ref. SCSI Primary Commands - 3 (SPC-3))
+ *
+ * @endverbatim
+ *
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_msc.h"
+
+
+/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
+ * @{
+ */
+
+
+/** @defgroup MSC_CORE
+ * @brief Mass storage core module
+ * @{
+ */
+
+/** @defgroup MSC_CORE_Private_TypesDefinitions
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup MSC_CORE_Private_Defines
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+
+/** @defgroup MSC_CORE_Private_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup MSC_CORE_Private_FunctionPrototypes
+ * @{
+ */
+uint8_t USBD_MSC_Init (USBD_HandleTypeDef *pdev,
+ uint8_t cfgidx);
+
+uint8_t USBD_MSC_DeInit (USBD_HandleTypeDef *pdev,
+ uint8_t cfgidx);
+
+uint8_t USBD_MSC_Setup (USBD_HandleTypeDef *pdev,
+ USBD_SetupReqTypedef *req);
+
+uint8_t USBD_MSC_DataIn (USBD_HandleTypeDef *pdev,
+ uint8_t epnum);
+
+
+uint8_t USBD_MSC_DataOut (USBD_HandleTypeDef *pdev,
+ uint8_t epnum);
+
+uint8_t *USBD_MSC_GetHSCfgDesc (uint16_t *length);
+
+uint8_t *USBD_MSC_GetFSCfgDesc (uint16_t *length);
+
+uint8_t *USBD_MSC_GetOtherSpeedCfgDesc (uint16_t *length);
+
+uint8_t *USBD_MSC_GetDeviceQualifierDescriptor (uint16_t *length);
+
+
+/**
+ * @}
+ */
+
+
+/** @defgroup MSC_CORE_Private_Variables
+ * @{
+ */
+
+
+USBD_ClassTypeDef USBD_MSC =
+{
+ USBD_MSC_Init,
+ USBD_MSC_DeInit,
+ USBD_MSC_Setup,
+ NULL, /*EP0_TxSent*/
+ NULL, /*EP0_RxReady*/
+ USBD_MSC_DataIn,
+ USBD_MSC_DataOut,
+ NULL, /*SOF */
+ NULL,
+ NULL,
+ USBD_MSC_GetHSCfgDesc,
+ USBD_MSC_GetFSCfgDesc,
+ USBD_MSC_GetOtherSpeedCfgDesc,
+ USBD_MSC_GetDeviceQualifierDescriptor,
+};
+
+/* USB Mass storage device Configuration Descriptor */
+/* All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */
+__ALIGN_BEGIN uint8_t USBD_MSC_CfgHSDesc[USB_MSC_CONFIG_DESC_SIZ] __ALIGN_END =
+{
+
+ 0x09, /* bLength: Configuation Descriptor size */
+ USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
+ USB_MSC_CONFIG_DESC_SIZ,
+
+ 0x00,
+ 0x01, /* bNumInterfaces: 1 interface */
+ 0x01, /* bConfigurationValue: */
+ 0x04, /* iConfiguration: */
+ 0xC0, /* bmAttributes: */
+ 0x32, /* MaxPower 100 mA */
+
+ /******************** Mass Storage interface ********************/
+ 0x09, /* bLength: Interface Descriptor size */
+ 0x04, /* bDescriptorType: */
+ 0x00, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x02, /* bNumEndpoints*/
+ 0x08, /* bInterfaceClass: MSC Class */
+ 0x06, /* bInterfaceSubClass : SCSI transparent*/
+ 0x50, /* nInterfaceProtocol */
+ 0x05, /* iInterface: */
+ /******************** Mass Storage Endpoints ********************/
+ 0x07, /*Endpoint descriptor length = 7*/
+ 0x05, /*Endpoint descriptor type */
+ MSC_EPIN_ADDR, /*Endpoint address (IN, address 1) */
+ 0x02, /*Bulk endpoint type */
+ LOBYTE(MSC_MAX_HS_PACKET),
+ HIBYTE(MSC_MAX_HS_PACKET),
+ 0x00, /*Polling interval in milliseconds */
+
+ 0x07, /*Endpoint descriptor length = 7 */
+ 0x05, /*Endpoint descriptor type */
+ MSC_EPOUT_ADDR, /*Endpoint address (OUT, address 1) */
+ 0x02, /*Bulk endpoint type */
+ LOBYTE(MSC_MAX_HS_PACKET),
+ HIBYTE(MSC_MAX_HS_PACKET),
+ 0x00 /*Polling interval in milliseconds*/
+};
+
+/* USB Mass storage device Configuration Descriptor */
+/* All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */
+uint8_t USBD_MSC_CfgFSDesc[USB_MSC_CONFIG_DESC_SIZ] __ALIGN_END =
+{
+
+ 0x09, /* bLength: Configuation Descriptor size */
+ USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
+ USB_MSC_CONFIG_DESC_SIZ,
+
+ 0x00,
+ 0x01, /* bNumInterfaces: 1 interface */
+ 0x01, /* bConfigurationValue: */
+ 0x04, /* iConfiguration: */
+ 0xC0, /* bmAttributes: */
+ 0x32, /* MaxPower 100 mA */
+
+ /******************** Mass Storage interface ********************/
+ 0x09, /* bLength: Interface Descriptor size */
+ 0x04, /* bDescriptorType: */
+ 0x00, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x02, /* bNumEndpoints*/
+ 0x08, /* bInterfaceClass: MSC Class */
+ 0x06, /* bInterfaceSubClass : SCSI transparent*/
+ 0x50, /* nInterfaceProtocol */
+ 0x05, /* iInterface: */
+ /******************** Mass Storage Endpoints ********************/
+ 0x07, /*Endpoint descriptor length = 7*/
+ 0x05, /*Endpoint descriptor type */
+ MSC_EPIN_ADDR, /*Endpoint address (IN, address 1) */
+ 0x02, /*Bulk endpoint type */
+ LOBYTE(MSC_MAX_FS_PACKET),
+ HIBYTE(MSC_MAX_FS_PACKET),
+ 0x00, /*Polling interval in milliseconds */
+
+ 0x07, /*Endpoint descriptor length = 7 */
+ 0x05, /*Endpoint descriptor type */
+ MSC_EPOUT_ADDR, /*Endpoint address (OUT, address 1) */
+ 0x02, /*Bulk endpoint type */
+ LOBYTE(MSC_MAX_FS_PACKET),
+ HIBYTE(MSC_MAX_FS_PACKET),
+ 0x00 /*Polling interval in milliseconds*/
+};
+
+__ALIGN_BEGIN uint8_t USBD_MSC_OtherSpeedCfgDesc[USB_MSC_CONFIG_DESC_SIZ] __ALIGN_END =
+{
+
+ 0x09, /* bLength: Configuation Descriptor size */
+ USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION,
+ USB_MSC_CONFIG_DESC_SIZ,
+
+ 0x00,
+ 0x01, /* bNumInterfaces: 1 interface */
+ 0x01, /* bConfigurationValue: */
+ 0x04, /* iConfiguration: */
+ 0xC0, /* bmAttributes: */
+ 0x32, /* MaxPower 100 mA */
+
+ /******************** Mass Storage interface ********************/
+ 0x09, /* bLength: Interface Descriptor size */
+ 0x04, /* bDescriptorType: */
+ 0x00, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x02, /* bNumEndpoints*/
+ 0x08, /* bInterfaceClass: MSC Class */
+ 0x06, /* bInterfaceSubClass : SCSI transparent command set*/
+ 0x50, /* nInterfaceProtocol */
+ 0x05, /* iInterface: */
+ /******************** Mass Storage Endpoints ********************/
+ 0x07, /*Endpoint descriptor length = 7*/
+ 0x05, /*Endpoint descriptor type */
+ MSC_EPIN_ADDR, /*Endpoint address (IN, address 1) */
+ 0x02, /*Bulk endpoint type */
+ 0x40,
+ 0x00,
+ 0x00, /*Polling interval in milliseconds */
+
+ 0x07, /*Endpoint descriptor length = 7 */
+ 0x05, /*Endpoint descriptor type */
+ MSC_EPOUT_ADDR, /*Endpoint address (OUT, address 1) */
+ 0x02, /*Bulk endpoint type */
+ 0x40,
+ 0x00,
+ 0x00 /*Polling interval in milliseconds*/
+};
+
+/* USB Standard Device Descriptor */
+__ALIGN_BEGIN uint8_t USBD_MSC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END =
+{
+ USB_LEN_DEV_QUALIFIER_DESC,
+ USB_DESC_TYPE_DEVICE_QUALIFIER,
+ 0x00,
+ 0x02,
+ 0x00,
+ 0x00,
+ 0x00,
+ MSC_MAX_FS_PACKET,
+ 0x01,
+ 0x00,
+};
+/**
+ * @}
+ */
+
+
+/** @defgroup MSC_CORE_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief USBD_MSC_Init
+ * Initialize the mass storage configuration
+ * @param pdev: device instance
+ * @param cfgidx: configuration index
+ * @retval status
+ */
+uint8_t USBD_MSC_Init (USBD_HandleTypeDef *pdev,
+ uint8_t cfgidx)
+{
+ int16_t ret = 0;
+
+ if(pdev->dev_speed == USBD_SPEED_HIGH )
+ {
+ /* Open EP OUT */
+ USBD_LL_OpenEP(pdev,
+ MSC_EPOUT_ADDR,
+ USBD_EP_TYPE_BULK,
+ MSC_MAX_HS_PACKET);
+
+ /* Open EP IN */
+ USBD_LL_OpenEP(pdev,
+ MSC_EPIN_ADDR,
+ USBD_EP_TYPE_BULK,
+ MSC_MAX_HS_PACKET);
+ }
+ else
+ {
+ /* Open EP OUT */
+ USBD_LL_OpenEP(pdev,
+ MSC_EPOUT_ADDR,
+ USBD_EP_TYPE_BULK,
+ MSC_MAX_FS_PACKET);
+
+ /* Open EP IN */
+ USBD_LL_OpenEP(pdev,
+ MSC_EPIN_ADDR,
+ USBD_EP_TYPE_BULK,
+ MSC_MAX_FS_PACKET);
+ }
+ pdev->pClassData = USBD_malloc(sizeof (USBD_MSC_BOT_HandleTypeDef));
+
+ if(pdev->pClassData == NULL)
+ {
+ ret = 1;
+ }
+ else
+ {
+ /* Init the BOT layer */
+ MSC_BOT_Init(pdev);
+ ret = 0;
+ }
+
+ return ret;
+}
+
+/**
+ * @brief USBD_MSC_DeInit
+ * DeInitilaize the mass storage configuration
+ * @param pdev: device instance
+ * @param cfgidx: configuration index
+ * @retval status
+ */
+uint8_t USBD_MSC_DeInit (USBD_HandleTypeDef *pdev,
+ uint8_t cfgidx)
+{
+ /* Close MSC EPs */
+ USBD_LL_CloseEP(pdev,
+ MSC_EPOUT_ADDR);
+
+ /* Open EP IN */
+ USBD_LL_CloseEP(pdev,
+ MSC_EPIN_ADDR);
+
+
+ /* D-Init the BOT layer */
+ MSC_BOT_DeInit(pdev);
+
+ /* Free MSC Class Resources */
+ if(pdev->pClassData != NULL)
+ {
+ USBD_free(pdev->pClassData);
+ pdev->pClassData = NULL;
+ }
+ return 0;
+}
+/**
+* @brief USBD_MSC_Setup
+* Handle the MSC specific requests
+* @param pdev: device instance
+* @param req: USB request
+* @retval status
+*/
+uint8_t USBD_MSC_Setup (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
+{
+ USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassData;
+
+ switch (req->bmRequest & USB_REQ_TYPE_MASK)
+ {
+
+ /* Class request */
+ case USB_REQ_TYPE_CLASS :
+ switch (req->bRequest)
+ {
+ case BOT_GET_MAX_LUN :
+
+ if((req->wValue == 0) &&
+ (req->wLength == 1) &&
+ ((req->bmRequest & 0x80) == 0x80))
+ {
+ hmsc->max_lun = ((USBD_StorageTypeDef *)pdev->pUserData)->GetMaxLun();
+ USBD_CtlSendData (pdev,
+ (uint8_t *)&hmsc->max_lun,
+ 1);
+ }
+ else
+ {
+ USBD_CtlError(pdev , req);
+ return USBD_FAIL;
+ }
+ break;
+
+ case BOT_RESET :
+ if((req->wValue == 0) &&
+ (req->wLength == 0) &&
+ ((req->bmRequest & 0x80) != 0x80))
+ {
+ MSC_BOT_Reset(pdev);
+ }
+ else
+ {
+ USBD_CtlError(pdev , req);
+ return USBD_FAIL;
+ }
+ break;
+
+ default:
+ USBD_CtlError(pdev , req);
+ return USBD_FAIL;
+ }
+ break;
+ /* Interface & Endpoint request */
+ case USB_REQ_TYPE_STANDARD:
+ switch (req->bRequest)
+ {
+ case USB_REQ_GET_INTERFACE :
+ USBD_CtlSendData (pdev,
+ (uint8_t *)&hmsc->interface,
+ 1);
+ break;
+
+ case USB_REQ_SET_INTERFACE :
+ hmsc->interface = (uint8_t)(req->wValue);
+ break;
+
+ case USB_REQ_CLEAR_FEATURE:
+
+ /* Flush the FIFO and Clear the stall status */
+ USBD_LL_FlushEP(pdev, (uint8_t)req->wIndex);
+
+ /* Re-activate the EP */
+ USBD_LL_CloseEP (pdev , (uint8_t)req->wIndex);
+ if((((uint8_t)req->wIndex) & 0x80) == 0x80)
+ {
+ if(pdev->dev_speed == USBD_SPEED_HIGH )
+ {
+ /* Open EP IN */
+ USBD_LL_OpenEP(pdev,
+ MSC_EPIN_ADDR,
+ USBD_EP_TYPE_BULK,
+ MSC_MAX_HS_PACKET);
+ }
+ else
+ {
+ /* Open EP IN */
+ USBD_LL_OpenEP(pdev,
+ MSC_EPIN_ADDR,
+ USBD_EP_TYPE_BULK,
+ MSC_MAX_FS_PACKET);
+ }
+ }
+ else
+ {
+ if(pdev->dev_speed == USBD_SPEED_HIGH )
+ {
+ /* Open EP IN */
+ USBD_LL_OpenEP(pdev,
+ MSC_EPOUT_ADDR,
+ USBD_EP_TYPE_BULK,
+ MSC_MAX_HS_PACKET);
+ }
+ else
+ {
+ /* Open EP IN */
+ USBD_LL_OpenEP(pdev,
+ MSC_EPOUT_ADDR,
+ USBD_EP_TYPE_BULK,
+ MSC_MAX_FS_PACKET);
+ }
+ }
+
+ /* Handle BOT error */
+ MSC_BOT_CplClrFeature(pdev, (uint8_t)req->wIndex);
+ break;
+
+ }
+ break;
+
+ default:
+ break;
+ }
+ return 0;
+}
+
+/**
+* @brief USBD_MSC_DataIn
+* handle data IN Stage
+* @param pdev: device instance
+* @param epnum: endpoint index
+* @retval status
+*/
+uint8_t USBD_MSC_DataIn (USBD_HandleTypeDef *pdev,
+ uint8_t epnum)
+{
+ MSC_BOT_DataIn(pdev , epnum);
+ return 0;
+}
+
+/**
+* @brief USBD_MSC_DataOut
+* handle data OUT Stage
+* @param pdev: device instance
+* @param epnum: endpoint index
+* @retval status
+*/
+uint8_t USBD_MSC_DataOut (USBD_HandleTypeDef *pdev,
+ uint8_t epnum)
+{
+ MSC_BOT_DataOut(pdev , epnum);
+ return 0;
+}
+
+/**
+* @brief USBD_MSC_GetHSCfgDesc
+* return configuration descriptor
+* @param length : pointer data length
+* @retval pointer to descriptor buffer
+*/
+uint8_t *USBD_MSC_GetHSCfgDesc (uint16_t *length)
+{
+ *length = sizeof (USBD_MSC_CfgHSDesc);
+ return USBD_MSC_CfgHSDesc;
+}
+
+/**
+* @brief USBD_MSC_GetFSCfgDesc
+* return configuration descriptor
+* @param length : pointer data length
+* @retval pointer to descriptor buffer
+*/
+uint8_t *USBD_MSC_GetFSCfgDesc (uint16_t *length)
+{
+ *length = sizeof (USBD_MSC_CfgFSDesc);
+ return USBD_MSC_CfgFSDesc;
+}
+
+/**
+* @brief USBD_MSC_GetOtherSpeedCfgDesc
+* return other speed configuration descriptor
+* @param length : pointer data length
+* @retval pointer to descriptor buffer
+*/
+uint8_t *USBD_MSC_GetOtherSpeedCfgDesc (uint16_t *length)
+{
+ *length = sizeof (USBD_MSC_OtherSpeedCfgDesc);
+ return USBD_MSC_OtherSpeedCfgDesc;
+}
+/**
+* @brief DeviceQualifierDescriptor
+* return Device Qualifier descriptor
+* @param length : pointer data length
+* @retval pointer to descriptor buffer
+*/
+uint8_t *USBD_MSC_GetDeviceQualifierDescriptor (uint16_t *length)
+{
+ *length = sizeof (USBD_MSC_DeviceQualifierDesc);
+ return USBD_MSC_DeviceQualifierDesc;
+}
+
+/**
+* @brief USBD_MSC_RegisterStorage
+* @param fops: storage callback
+* @retval status
+*/
+uint8_t USBD_MSC_RegisterStorage (USBD_HandleTypeDef *pdev,
+ USBD_StorageTypeDef *fops)
+{
+ if(fops != NULL)
+ {
+ pdev->pUserData= fops;
+ }
+ return 0;
+}
+
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/stmhal/usbdev/class/cdc_msc/src/usbd_msc_bot.c b/stmhal/usbdev/class/cdc_msc/src/usbd_msc_bot.c new file mode 100644 index 0000000000..69c34a5838 --- /dev/null +++ b/stmhal/usbdev/class/cdc_msc/src/usbd_msc_bot.c @@ -0,0 +1,407 @@ +/**
+ ******************************************************************************
+ * @file usbd_msc_bot.c
+ * @author MCD Application Team
+ * @version V2.0.0
+ * @date 18-February-2014
+ * @brief This file provides all the BOT protocol core functions.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_msc_bot.h"
+#include "usbd_msc_scsi.h"
+#include "usbd_cdc_msc.h"
+#include "usbd_ioreq.h"
+
+/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
+ * @{
+ */
+
+
+/** @defgroup MSC_BOT
+ * @brief BOT protocol module
+ * @{
+ */
+
+/** @defgroup MSC_BOT_Private_TypesDefinitions
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup MSC_BOT_Private_Defines
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+
+/** @defgroup MSC_BOT_Private_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup MSC_BOT_Private_Variables
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+
+/** @defgroup MSC_BOT_Private_FunctionPrototypes
+ * @{
+ */
+static void MSC_BOT_CBW_Decode (USBD_HandleTypeDef *pdev);
+
+static void MSC_BOT_SendData (USBD_HandleTypeDef *pdev,
+ uint8_t* pbuf,
+ uint16_t len);
+
+static void MSC_BOT_Abort(USBD_HandleTypeDef *pdev);
+/**
+ * @}
+ */
+
+
+/** @defgroup MSC_BOT_Private_Functions
+ * @{
+ */
+
+
+
+/**
+* @brief MSC_BOT_Init
+* Initialize the BOT Process
+* @param pdev: device instance
+* @retval None
+*/
+void MSC_BOT_Init (USBD_HandleTypeDef *pdev)
+{
+ USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassData;
+
+ hmsc->bot_state = USBD_BOT_IDLE;
+ hmsc->bot_status = USBD_BOT_STATUS_NORMAL;
+
+ hmsc->scsi_sense_tail = 0;
+ hmsc->scsi_sense_head = 0;
+
+ ((USBD_StorageTypeDef *)pdev->pUserData)->Init(0);
+
+ USBD_LL_FlushEP(pdev, MSC_OUT_EP);
+ USBD_LL_FlushEP(pdev, MSC_IN_EP);
+
+ /* Prapare EP to Receive First BOT Cmd */
+ USBD_LL_PrepareReceive (pdev,
+ MSC_OUT_EP,
+ (uint8_t *)&hmsc->cbw,
+ USBD_BOT_CBW_LENGTH);
+}
+
+/**
+* @brief MSC_BOT_Reset
+* Reset the BOT Machine
+* @param pdev: device instance
+* @retval None
+*/
+void MSC_BOT_Reset (USBD_HandleTypeDef *pdev)
+{
+ USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassData;
+
+ hmsc->bot_state = USBD_BOT_IDLE;
+ hmsc->bot_status = USBD_BOT_STATUS_RECOVERY;
+
+ /* Prapare EP to Receive First BOT Cmd */
+ USBD_LL_PrepareReceive (pdev,
+ MSC_OUT_EP,
+ (uint8_t *)&hmsc->cbw,
+ USBD_BOT_CBW_LENGTH);
+}
+
+/**
+* @brief MSC_BOT_DeInit
+* Uninitialize the BOT Machine
+* @param pdev: device instance
+* @retval None
+*/
+void MSC_BOT_DeInit (USBD_HandleTypeDef *pdev)
+{
+ USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassData;
+ hmsc->bot_state = USBD_BOT_IDLE;
+}
+
+/**
+* @brief MSC_BOT_DataIn
+* Handle BOT IN data stage
+* @param pdev: device instance
+* @param epnum: endpoint index
+* @retval None
+*/
+void MSC_BOT_DataIn (USBD_HandleTypeDef *pdev,
+ uint8_t epnum)
+{
+ USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassData;
+
+ switch (hmsc->bot_state)
+ {
+ case USBD_BOT_DATA_IN:
+ if(SCSI_ProcessCmd(pdev,
+ hmsc->cbw.bLUN,
+ &hmsc->cbw.CB[0]) < 0)
+ {
+ MSC_BOT_SendCSW (pdev, USBD_CSW_CMD_FAILED);
+ }
+ break;
+
+ case USBD_BOT_SEND_DATA:
+ case USBD_BOT_LAST_DATA_IN:
+ MSC_BOT_SendCSW (pdev, USBD_CSW_CMD_PASSED);
+
+ break;
+
+ default:
+ break;
+ }
+}
+/**
+* @brief MSC_BOT_DataOut
+* Proccess MSC OUT data
+* @param pdev: device instance
+* @param epnum: endpoint index
+* @retval None
+*/
+void MSC_BOT_DataOut (USBD_HandleTypeDef *pdev,
+ uint8_t epnum)
+{
+ USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassData;
+
+ switch (hmsc->bot_state)
+ {
+ case USBD_BOT_IDLE:
+ MSC_BOT_CBW_Decode(pdev);
+ break;
+
+ case USBD_BOT_DATA_OUT:
+
+ if(SCSI_ProcessCmd(pdev,
+ hmsc->cbw.bLUN,
+ &hmsc->cbw.CB[0]) < 0)
+ {
+ MSC_BOT_SendCSW (pdev, USBD_CSW_CMD_FAILED);
+ }
+
+ break;
+
+ default:
+ break;
+ }
+}
+
+/**
+* @brief MSC_BOT_CBW_Decode
+* Decode the CBW command and set the BOT state machine accordingtly
+* @param pdev: device instance
+* @retval None
+*/
+static void MSC_BOT_CBW_Decode (USBD_HandleTypeDef *pdev)
+{
+ USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassData;
+
+ hmsc->csw.dTag = hmsc->cbw.dTag;
+ hmsc->csw.dDataResidue = hmsc->cbw.dDataLength;
+
+ if ((USBD_LL_GetRxDataSize (pdev ,MSC_OUT_EP) != USBD_BOT_CBW_LENGTH) ||
+ (hmsc->cbw.dSignature != USBD_BOT_CBW_SIGNATURE)||
+ (hmsc->cbw.bLUN > 1) ||
+ (hmsc->cbw.bCBLength < 1) ||
+ (hmsc->cbw.bCBLength > 16))
+ {
+
+ SCSI_SenseCode(pdev,
+ hmsc->cbw.bLUN,
+ ILLEGAL_REQUEST,
+ INVALID_CDB);
+
+ hmsc->bot_status = USBD_BOT_STATUS_ERROR;
+ MSC_BOT_Abort(pdev);
+
+ }
+ else
+ {
+ if(SCSI_ProcessCmd(pdev,
+ hmsc->cbw.bLUN,
+ &hmsc->cbw.CB[0]) < 0)
+ {
+ if(hmsc->bot_state == USBD_BOT_NO_DATA)
+ {
+ MSC_BOT_SendCSW (pdev,
+ USBD_CSW_CMD_FAILED);
+ }
+ else
+ {
+ MSC_BOT_Abort(pdev);
+ }
+ }
+ /*Burst xfer handled internally*/
+ else if ((hmsc->bot_state != USBD_BOT_DATA_IN) &&
+ (hmsc->bot_state != USBD_BOT_DATA_OUT) &&
+ (hmsc->bot_state != USBD_BOT_LAST_DATA_IN))
+ {
+ if (hmsc->bot_data_length > 0)
+ {
+ MSC_BOT_SendData(pdev,
+ hmsc->bot_data,
+ hmsc->bot_data_length);
+ }
+ else if (hmsc->bot_data_length == 0)
+ {
+ MSC_BOT_SendCSW (pdev,
+ USBD_CSW_CMD_PASSED);
+ }
+ }
+ }
+}
+
+/**
+* @brief MSC_BOT_SendData
+* Send the requested data
+* @param pdev: device instance
+* @param buf: pointer to data buffer
+* @param len: Data Length
+* @retval None
+*/
+static void MSC_BOT_SendData(USBD_HandleTypeDef *pdev,
+ uint8_t* buf,
+ uint16_t len)
+{
+ USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassData;
+
+ len = MIN (hmsc->cbw.dDataLength, len);
+ hmsc->csw.dDataResidue -= len;
+ hmsc->csw.bStatus = USBD_CSW_CMD_PASSED;
+ hmsc->bot_state = USBD_BOT_SEND_DATA;
+
+ USBD_LL_Transmit (pdev, MSC_IN_EP, buf, len);
+}
+
+/**
+* @brief MSC_BOT_SendCSW
+* Send the Command Status Wrapper
+* @param pdev: device instance
+* @param status : CSW status
+* @retval None
+*/
+void MSC_BOT_SendCSW (USBD_HandleTypeDef *pdev,
+ uint8_t CSW_Status)
+{
+ USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassData;
+
+ hmsc->csw.dSignature = USBD_BOT_CSW_SIGNATURE;
+ hmsc->csw.bStatus = CSW_Status;
+ hmsc->bot_state = USBD_BOT_IDLE;
+
+ USBD_LL_Transmit (pdev,
+ MSC_IN_EP,
+ (uint8_t *)&hmsc->csw,
+ USBD_BOT_CSW_LENGTH);
+
+ /* Prapare EP to Receive next Cmd */
+ USBD_LL_PrepareReceive (pdev,
+ MSC_OUT_EP,
+ (uint8_t *)&hmsc->cbw,
+ USBD_BOT_CBW_LENGTH);
+
+}
+
+/**
+* @brief MSC_BOT_Abort
+* Abort the current transfer
+* @param pdev: device instance
+* @retval status
+*/
+
+static void MSC_BOT_Abort (USBD_HandleTypeDef *pdev)
+{
+ USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassData;
+
+ if ((hmsc->cbw.bmFlags == 0) &&
+ (hmsc->cbw.dDataLength != 0) &&
+ (hmsc->bot_status == USBD_BOT_STATUS_NORMAL) )
+ {
+ USBD_LL_StallEP(pdev, MSC_OUT_EP );
+ }
+ USBD_LL_StallEP(pdev, MSC_IN_EP);
+
+ if(hmsc->bot_status == USBD_BOT_STATUS_ERROR)
+ {
+ USBD_LL_PrepareReceive (pdev,
+ MSC_OUT_EP,
+ (uint8_t *)&hmsc->cbw,
+ USBD_BOT_CBW_LENGTH);
+ }
+}
+
+/**
+* @brief MSC_BOT_CplClrFeature
+* Complete the clear feature request
+* @param pdev: device instance
+* @param epnum: endpoint index
+* @retval None
+*/
+
+void MSC_BOT_CplClrFeature (USBD_HandleTypeDef *pdev, uint8_t epnum)
+{
+ USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassData;
+
+ if(hmsc->bot_status == USBD_BOT_STATUS_ERROR )/* Bad CBW Signature */
+ {
+ USBD_LL_StallEP(pdev, MSC_IN_EP);
+ hmsc->bot_status = USBD_BOT_STATUS_NORMAL;
+ }
+ else if(((epnum & 0x80) == 0x80) && ( hmsc->bot_status != USBD_BOT_STATUS_RECOVERY))
+ {
+ MSC_BOT_SendCSW (pdev, USBD_CSW_CMD_FAILED);
+ }
+
+}
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/stmhal/usbdev/class/cdc_msc/src/usbd_msc_data.c b/stmhal/usbdev/class/cdc_msc/src/usbd_msc_data.c new file mode 100644 index 0000000000..4d72bd5fce --- /dev/null +++ b/stmhal/usbdev/class/cdc_msc/src/usbd_msc_data.c @@ -0,0 +1,134 @@ +/**
+ ******************************************************************************
+ * @file usbd_msc_data.c
+ * @author MCD Application Team
+ * @version V2.0.0
+ * @date 18-February-2014
+ * @brief This file provides all the vital inquiry pages and sense data.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_msc_data.h"
+
+
+/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
+ * @{
+ */
+
+
+/** @defgroup MSC_DATA
+ * @brief Mass storage info/data module
+ * @{
+ */
+
+/** @defgroup MSC_DATA_Private_TypesDefinitions
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup MSC_DATA_Private_Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup MSC_DATA_Private_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup MSC_DATA_Private_Variables
+ * @{
+ */
+
+
+/* USB Mass storage Page 0 Inquiry Data */
+const uint8_t MSC_Page00_Inquiry_Data[] = {//7
+ 0x00,
+ 0x00,
+ 0x00,
+ (LENGTH_INQUIRY_PAGE00 - 4),
+ 0x00,
+ 0x80,
+ 0x83
+};
+/* USB Mass storage sense 6 Data */
+const uint8_t MSC_Mode_Sense6_data[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+/* USB Mass storage sense 10 Data */
+const uint8_t MSC_Mode_Sense10_data[] = {
+ 0x00,
+ 0x06,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+/**
+ * @}
+ */
+
+
+/** @defgroup MSC_DATA_Private_FunctionPrototypes
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup MSC_DATA_Private_Functions
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/stmhal/usbdev/class/cdc_msc/src/usbd_msc_scsi.c b/stmhal/usbdev/class/cdc_msc/src/usbd_msc_scsi.c new file mode 100644 index 0000000000..dd3de90feb --- /dev/null +++ b/stmhal/usbdev/class/cdc_msc/src/usbd_msc_scsi.c @@ -0,0 +1,770 @@ +/**
+ ******************************************************************************
+ * @file usbd_msc_scsi.c
+ * @author MCD Application Team
+ * @version V2.0.0
+ * @date 18-February-2014
+ * @brief This file provides all the USBD SCSI layer functions.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_msc_bot.h"
+#include "usbd_msc_scsi.h"
+#include "usbd_msc_data.h"
+#include "usbd_cdc_msc.h"
+
+
+
+/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
+ * @{
+ */
+
+
+/** @defgroup MSC_SCSI
+ * @brief Mass storage SCSI layer module
+ * @{
+ */
+
+/** @defgroup MSC_SCSI_Private_TypesDefinitions
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup MSC_SCSI_Private_Defines
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+
+/** @defgroup MSC_SCSI_Private_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup MSC_SCSI_Private_Variables
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+
+/** @defgroup MSC_SCSI_Private_FunctionPrototypes
+ * @{
+ */
+static int8_t SCSI_TestUnitReady(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
+static int8_t SCSI_Inquiry(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
+static int8_t SCSI_ReadFormatCapacity(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
+static int8_t SCSI_ReadCapacity10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
+static int8_t SCSI_RequestSense (USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
+static int8_t SCSI_StartStopUnit(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
+static int8_t SCSI_ModeSense6 (USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
+static int8_t SCSI_ModeSense10 (USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
+static int8_t SCSI_Write10(USBD_HandleTypeDef *pdev, uint8_t lun , uint8_t *params);
+static int8_t SCSI_Read10(USBD_HandleTypeDef *pdev, uint8_t lun , uint8_t *params);
+static int8_t SCSI_Verify10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
+static int8_t SCSI_CheckAddressRange (USBD_HandleTypeDef *pdev,
+ uint8_t lun ,
+ uint32_t blk_offset ,
+ uint16_t blk_nbr);
+static int8_t SCSI_ProcessRead (USBD_HandleTypeDef *pdev,
+ uint8_t lun);
+
+static int8_t SCSI_ProcessWrite (USBD_HandleTypeDef *pdev,
+ uint8_t lun);
+/**
+ * @}
+ */
+
+
+/** @defgroup MSC_SCSI_Private_Functions
+ * @{
+ */
+
+
+/**
+* @brief SCSI_ProcessCmd
+* Process SCSI commands
+* @param pdev: device instance
+* @param lun: Logical unit number
+* @param params: Command parameters
+* @retval status
+*/
+int8_t SCSI_ProcessCmd(USBD_HandleTypeDef *pdev,
+ uint8_t lun,
+ uint8_t *params)
+{
+
+ switch (params[0])
+ {
+ case SCSI_TEST_UNIT_READY:
+ return SCSI_TestUnitReady(pdev, lun, params);
+
+ case SCSI_REQUEST_SENSE:
+ return SCSI_RequestSense (pdev, lun, params);
+ case SCSI_INQUIRY:
+ return SCSI_Inquiry(pdev, lun, params);
+
+ case SCSI_START_STOP_UNIT:
+ return SCSI_StartStopUnit(pdev, lun, params);
+
+ case SCSI_ALLOW_MEDIUM_REMOVAL:
+ return SCSI_StartStopUnit(pdev, lun, params);
+
+ case SCSI_MODE_SENSE6:
+ return SCSI_ModeSense6 (pdev, lun, params);
+
+ case SCSI_MODE_SENSE10:
+ return SCSI_ModeSense10 (pdev, lun, params);
+
+ case SCSI_READ_FORMAT_CAPACITIES:
+ return SCSI_ReadFormatCapacity(pdev, lun, params);
+
+ case SCSI_READ_CAPACITY10:
+ return SCSI_ReadCapacity10(pdev, lun, params);
+
+ case SCSI_READ10:
+ return SCSI_Read10(pdev, lun, params);
+
+ case SCSI_WRITE10:
+ return SCSI_Write10(pdev, lun, params);
+
+ case SCSI_VERIFY10:
+ return SCSI_Verify10(pdev, lun, params);
+
+ default:
+ SCSI_SenseCode(pdev,
+ lun,
+ ILLEGAL_REQUEST,
+ INVALID_CDB);
+ return -1;
+ }
+}
+
+
+/**
+* @brief SCSI_TestUnitReady
+* Process SCSI Test Unit Ready Command
+* @param lun: Logical unit number
+* @param params: Command parameters
+* @retval status
+*/
+static int8_t SCSI_TestUnitReady(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
+{
+ USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassData;
+
+ /* case 9 : Hi > D0 */
+ if (hmsc->cbw.dDataLength != 0)
+ {
+ SCSI_SenseCode(pdev,
+ hmsc->cbw.bLUN,
+ ILLEGAL_REQUEST,
+ INVALID_CDB);
+ return -1;
+ }
+
+ if(((USBD_StorageTypeDef *)pdev->pUserData)->IsReady(lun) !=0 )
+ {
+ SCSI_SenseCode(pdev,
+ lun,
+ NOT_READY,
+ MEDIUM_NOT_PRESENT);
+
+ hmsc->bot_state = USBD_BOT_NO_DATA;
+ return -1;
+ }
+ hmsc->bot_data_length = 0;
+ return 0;
+}
+
+/**
+* @brief SCSI_Inquiry
+* Process Inquiry command
+* @param lun: Logical unit number
+* @param params: Command parameters
+* @retval status
+*/
+static int8_t SCSI_Inquiry(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
+{
+ uint8_t* pPage;
+ uint16_t len;
+ USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassData;
+
+ if (params[1] & 0x01)/*Evpd is set*/
+ {
+ pPage = (uint8_t *)MSC_Page00_Inquiry_Data;
+ len = LENGTH_INQUIRY_PAGE00;
+ }
+ else
+ {
+
+ pPage = (uint8_t *)&((USBD_StorageTypeDef *)pdev->pUserData)->pInquiry[lun * STANDARD_INQUIRY_DATA_LEN];
+ len = pPage[4] + 5;
+
+ if (params[4] <= len)
+ {
+ len = params[4];
+ }
+ }
+ hmsc->bot_data_length = len;
+
+ while (len)
+ {
+ len--;
+ hmsc->bot_data[len] = pPage[len];
+ }
+ return 0;
+}
+
+/**
+* @brief SCSI_ReadCapacity10
+* Process Read Capacity 10 command
+* @param lun: Logical unit number
+* @param params: Command parameters
+* @retval status
+*/
+static int8_t SCSI_ReadCapacity10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
+{
+ USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassData;
+
+ if(((USBD_StorageTypeDef *)pdev->pUserData)->GetCapacity(lun, &hmsc->scsi_blk_nbr, &hmsc->scsi_blk_size) != 0)
+ {
+ SCSI_SenseCode(pdev,
+ lun,
+ NOT_READY,
+ MEDIUM_NOT_PRESENT);
+ return -1;
+ }
+ else
+ {
+
+ hmsc->bot_data[0] = (uint8_t)((hmsc->scsi_blk_nbr - 1) >> 24);
+ hmsc->bot_data[1] = (uint8_t)((hmsc->scsi_blk_nbr - 1) >> 16);
+ hmsc->bot_data[2] = (uint8_t)((hmsc->scsi_blk_nbr - 1) >> 8);
+ hmsc->bot_data[3] = (uint8_t)(hmsc->scsi_blk_nbr - 1);
+
+ hmsc->bot_data[4] = (uint8_t)(hmsc->scsi_blk_size >> 24);
+ hmsc->bot_data[5] = (uint8_t)(hmsc->scsi_blk_size >> 16);
+ hmsc->bot_data[6] = (uint8_t)(hmsc->scsi_blk_size >> 8);
+ hmsc->bot_data[7] = (uint8_t)(hmsc->scsi_blk_size);
+
+ hmsc->bot_data_length = 8;
+ return 0;
+ }
+}
+/**
+* @brief SCSI_ReadFormatCapacity
+* Process Read Format Capacity command
+* @param lun: Logical unit number
+* @param params: Command parameters
+* @retval status
+*/
+static int8_t SCSI_ReadFormatCapacity(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
+{
+ USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassData;
+
+ uint16_t blk_size;
+ uint32_t blk_nbr;
+ uint16_t i;
+
+ for(i=0 ; i < 12 ; i++)
+ {
+ hmsc->bot_data[i] = 0;
+ }
+
+ if(((USBD_StorageTypeDef *)pdev->pUserData)->GetCapacity(lun, &blk_nbr, &blk_size) != 0)
+ {
+ SCSI_SenseCode(pdev,
+ lun,
+ NOT_READY,
+ MEDIUM_NOT_PRESENT);
+ return -1;
+ }
+ else
+ {
+ hmsc->bot_data[3] = 0x08;
+ hmsc->bot_data[4] = (uint8_t)((blk_nbr - 1) >> 24);
+ hmsc->bot_data[5] = (uint8_t)((blk_nbr - 1) >> 16);
+ hmsc->bot_data[6] = (uint8_t)((blk_nbr - 1) >> 8);
+ hmsc->bot_data[7] = (uint8_t)(blk_nbr - 1);
+
+ hmsc->bot_data[8] = 0x02;
+ hmsc->bot_data[9] = (uint8_t)(blk_size >> 16);
+ hmsc->bot_data[10] = (uint8_t)(blk_size >> 8);
+ hmsc->bot_data[11] = (uint8_t)(blk_size);
+
+ hmsc->bot_data_length = 12;
+ return 0;
+ }
+}
+/**
+* @brief SCSI_ModeSense6
+* Process Mode Sense6 command
+* @param lun: Logical unit number
+* @param params: Command parameters
+* @retval status
+*/
+static int8_t SCSI_ModeSense6 (USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
+{
+ USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassData;
+ uint16_t len = 8 ;
+ hmsc->bot_data_length = len;
+
+ while (len)
+ {
+ len--;
+ hmsc->bot_data[len] = MSC_Mode_Sense6_data[len];
+ }
+ return 0;
+}
+
+/**
+* @brief SCSI_ModeSense10
+* Process Mode Sense10 command
+* @param lun: Logical unit number
+* @param params: Command parameters
+* @retval status
+*/
+static int8_t SCSI_ModeSense10 (USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
+{
+ uint16_t len = 8;
+ USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassData;
+
+ hmsc->bot_data_length = len;
+
+ while (len)
+ {
+ len--;
+ hmsc->bot_data[len] = MSC_Mode_Sense10_data[len];
+ }
+ return 0;
+}
+
+/**
+* @brief SCSI_RequestSense
+* Process Request Sense command
+* @param lun: Logical unit number
+* @param params: Command parameters
+* @retval status
+*/
+
+static int8_t SCSI_RequestSense (USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
+{
+ uint8_t i;
+ USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassData;
+
+ for(i=0 ; i < REQUEST_SENSE_DATA_LEN ; i++)
+ {
+ hmsc->bot_data[i] = 0;
+ }
+
+ hmsc->bot_data[0] = 0x70;
+ hmsc->bot_data[7] = REQUEST_SENSE_DATA_LEN - 6;
+
+ if((hmsc->scsi_sense_head != hmsc->scsi_sense_tail)) {
+
+ hmsc->bot_data[2] = hmsc->scsi_sense[hmsc->scsi_sense_head].Skey;
+ hmsc->bot_data[12] = hmsc->scsi_sense[hmsc->scsi_sense_head].w.b.ASCQ;
+ hmsc->bot_data[13] = hmsc->scsi_sense[hmsc->scsi_sense_head].w.b.ASC;
+ hmsc->scsi_sense_head++;
+
+ if (hmsc->scsi_sense_head == SENSE_LIST_DEEPTH)
+ {
+ hmsc->scsi_sense_head = 0;
+ }
+ }
+ hmsc->bot_data_length = REQUEST_SENSE_DATA_LEN;
+
+ if (params[4] <= REQUEST_SENSE_DATA_LEN)
+ {
+ hmsc->bot_data_length = params[4];
+ }
+ return 0;
+}
+
+/**
+* @brief SCSI_SenseCode
+* Load the last error code in the error list
+* @param lun: Logical unit number
+* @param sKey: Sense Key
+* @param ASC: Additional Sense Key
+* @retval none
+
+*/
+void SCSI_SenseCode(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t sKey, uint8_t ASC)
+{
+ USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassData;
+
+ hmsc->scsi_sense[hmsc->scsi_sense_tail].Skey = sKey;
+ hmsc->scsi_sense[hmsc->scsi_sense_tail].w.ASC = ASC << 8;
+ hmsc->scsi_sense_tail++;
+ if (hmsc->scsi_sense_tail == SENSE_LIST_DEEPTH)
+ {
+ hmsc->scsi_sense_tail = 0;
+ }
+}
+/**
+* @brief SCSI_StartStopUnit
+* Process Start Stop Unit command
+* @param lun: Logical unit number
+* @param params: Command parameters
+* @retval status
+*/
+static int8_t SCSI_StartStopUnit(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
+{
+ USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassData;
+ hmsc->bot_data_length = 0;
+ return 0;
+}
+
+/**
+* @brief SCSI_Read10
+* Process Read10 command
+* @param lun: Logical unit number
+* @param params: Command parameters
+* @retval status
+*/
+static int8_t SCSI_Read10(USBD_HandleTypeDef *pdev, uint8_t lun , uint8_t *params)
+{
+ USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassData;
+
+ if(hmsc->bot_state == USBD_BOT_IDLE) /* Idle */
+ {
+
+ /* case 10 : Ho <> Di */
+
+ if ((hmsc->cbw.bmFlags & 0x80) != 0x80)
+ {
+ SCSI_SenseCode(pdev,
+ hmsc->cbw.bLUN,
+ ILLEGAL_REQUEST,
+ INVALID_CDB);
+ return -1;
+ }
+
+ if(((USBD_StorageTypeDef *)pdev->pUserData)->IsReady(lun) !=0 )
+ {
+ SCSI_SenseCode(pdev,
+ lun,
+ NOT_READY,
+ MEDIUM_NOT_PRESENT);
+ return -1;
+ }
+
+ hmsc->scsi_blk_addr = (params[2] << 24) | \
+ (params[3] << 16) | \
+ (params[4] << 8) | \
+ params[5];
+
+ hmsc->scsi_blk_len = (params[7] << 8) | \
+ params[8];
+
+
+
+ if( SCSI_CheckAddressRange(pdev, lun, hmsc->scsi_blk_addr, hmsc->scsi_blk_len) < 0)
+ {
+ return -1; /* error */
+ }
+
+ hmsc->bot_state = USBD_BOT_DATA_IN;
+ hmsc->scsi_blk_addr *= hmsc->scsi_blk_size;
+ hmsc->scsi_blk_len *= hmsc->scsi_blk_size;
+
+ /* cases 4,5 : Hi <> Dn */
+ if (hmsc->cbw.dDataLength != hmsc->scsi_blk_len)
+ {
+ SCSI_SenseCode(pdev,
+ hmsc->cbw.bLUN,
+ ILLEGAL_REQUEST,
+ INVALID_CDB);
+ return -1;
+ }
+ }
+ hmsc->bot_data_length = MSC_MEDIA_PACKET;
+
+ return SCSI_ProcessRead(pdev, lun);
+}
+
+/**
+* @brief SCSI_Write10
+* Process Write10 command
+* @param lun: Logical unit number
+* @param params: Command parameters
+* @retval status
+*/
+
+static int8_t SCSI_Write10 (USBD_HandleTypeDef *pdev, uint8_t lun , uint8_t *params)
+{
+ USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassData;
+
+ if (hmsc->bot_state == USBD_BOT_IDLE) /* Idle */
+ {
+
+ /* case 8 : Hi <> Do */
+
+ if ((hmsc->cbw.bmFlags & 0x80) == 0x80)
+ {
+ SCSI_SenseCode(pdev,
+ hmsc->cbw.bLUN,
+ ILLEGAL_REQUEST,
+ INVALID_CDB);
+ return -1;
+ }
+
+ /* Check whether Media is ready */
+ if(((USBD_StorageTypeDef *)pdev->pUserData)->IsReady(lun) !=0 )
+ {
+ SCSI_SenseCode(pdev,
+ lun,
+ NOT_READY,
+ MEDIUM_NOT_PRESENT);
+ return -1;
+ }
+
+ /* Check If media is write-protected */
+ if(((USBD_StorageTypeDef *)pdev->pUserData)->IsWriteProtected(lun) !=0 )
+ {
+ SCSI_SenseCode(pdev,
+ lun,
+ NOT_READY,
+ WRITE_PROTECTED);
+ return -1;
+ }
+
+
+ hmsc->scsi_blk_addr = (params[2] << 24) | \
+ (params[3] << 16) | \
+ (params[4] << 8) | \
+ params[5];
+ hmsc->scsi_blk_len = (params[7] << 8) | \
+ params[8];
+
+ /* check if LBA address is in the right range */
+ if(SCSI_CheckAddressRange(pdev,
+ lun,
+ hmsc->scsi_blk_addr,
+ hmsc->scsi_blk_len) < 0)
+ {
+ return -1; /* error */
+ }
+
+ hmsc->scsi_blk_addr *= hmsc->scsi_blk_size;
+ hmsc->scsi_blk_len *= hmsc->scsi_blk_size;
+
+ /* cases 3,11,13 : Hn,Ho <> D0 */
+ if (hmsc->cbw.dDataLength != hmsc->scsi_blk_len)
+ {
+ SCSI_SenseCode(pdev,
+ hmsc->cbw.bLUN,
+ ILLEGAL_REQUEST,
+ INVALID_CDB);
+ return -1;
+ }
+
+ /* Prepare EP to receive first data packet */
+ hmsc->bot_state = USBD_BOT_DATA_OUT;
+ USBD_LL_PrepareReceive (pdev,
+ MSC_OUT_EP,
+ hmsc->bot_data,
+ MIN (hmsc->scsi_blk_len, MSC_MEDIA_PACKET));
+ }
+ else /* Write Process ongoing */
+ {
+ return SCSI_ProcessWrite(pdev, lun);
+ }
+ return 0;
+}
+
+
+/**
+* @brief SCSI_Verify10
+* Process Verify10 command
+* @param lun: Logical unit number
+* @param params: Command parameters
+* @retval status
+*/
+
+static int8_t SCSI_Verify10(USBD_HandleTypeDef *pdev, uint8_t lun , uint8_t *params)
+{
+ USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassData;
+
+ if ((params[1]& 0x02) == 0x02)
+ {
+ SCSI_SenseCode (pdev,
+ lun,
+ ILLEGAL_REQUEST,
+ INVALID_FIELED_IN_COMMAND);
+ return -1; /* Error, Verify Mode Not supported*/
+ }
+
+ if(SCSI_CheckAddressRange(pdev,
+ lun,
+ hmsc->scsi_blk_addr,
+ hmsc->scsi_blk_len) < 0)
+ {
+ return -1; /* error */
+ }
+ hmsc->bot_data_length = 0;
+ return 0;
+}
+
+/**
+* @brief SCSI_CheckAddressRange
+* Check address range
+* @param lun: Logical unit number
+* @param blk_offset: first block address
+* @param blk_nbr: number of block to be processed
+* @retval status
+*/
+static int8_t SCSI_CheckAddressRange (USBD_HandleTypeDef *pdev, uint8_t lun , uint32_t blk_offset , uint16_t blk_nbr)
+{
+ USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassData;
+
+ if ((blk_offset + blk_nbr) > hmsc->scsi_blk_nbr )
+ {
+ SCSI_SenseCode(pdev,
+ lun,
+ ILLEGAL_REQUEST,
+ ADDRESS_OUT_OF_RANGE);
+ return -1;
+ }
+ return 0;
+}
+
+/**
+* @brief SCSI_ProcessRead
+* Handle Read Process
+* @param lun: Logical unit number
+* @retval status
+*/
+static int8_t SCSI_ProcessRead (USBD_HandleTypeDef *pdev, uint8_t lun)
+{
+ USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassData;
+ uint32_t len;
+
+ len = MIN(hmsc->scsi_blk_len , MSC_MEDIA_PACKET);
+
+ if( ((USBD_StorageTypeDef *)pdev->pUserData)->Read(lun ,
+ hmsc->bot_data,
+ hmsc->scsi_blk_addr / hmsc->scsi_blk_size,
+ len / hmsc->scsi_blk_size) < 0)
+ {
+
+ SCSI_SenseCode(pdev,
+ lun,
+ HARDWARE_ERROR,
+ UNRECOVERED_READ_ERROR);
+ return -1;
+ }
+
+
+ USBD_LL_Transmit (pdev,
+ MSC_IN_EP,
+ hmsc->bot_data,
+ len);
+
+
+ hmsc->scsi_blk_addr += len;
+ hmsc->scsi_blk_len -= len;
+
+ /* case 6 : Hi = Di */
+ hmsc->csw.dDataResidue -= len;
+
+ if (hmsc->scsi_blk_len == 0)
+ {
+ hmsc->bot_state = USBD_BOT_LAST_DATA_IN;
+ }
+ return 0;
+}
+
+/**
+* @brief SCSI_ProcessWrite
+* Handle Write Process
+* @param lun: Logical unit number
+* @retval status
+*/
+
+static int8_t SCSI_ProcessWrite (USBD_HandleTypeDef *pdev, uint8_t lun)
+{
+ uint32_t len;
+ USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassData;
+
+ len = MIN(hmsc->scsi_blk_len , MSC_MEDIA_PACKET);
+
+ if(((USBD_StorageTypeDef *)pdev->pUserData)->Write(lun ,
+ hmsc->bot_data,
+ hmsc->scsi_blk_addr / hmsc->scsi_blk_size,
+ len / hmsc->scsi_blk_size) < 0)
+ {
+ SCSI_SenseCode(pdev,
+ lun,
+ HARDWARE_ERROR,
+ WRITE_FAULT);
+ return -1;
+ }
+
+
+ hmsc->scsi_blk_addr += len;
+ hmsc->scsi_blk_len -= len;
+
+ /* case 12 : Ho = Do */
+ hmsc->csw.dDataResidue -= len;
+
+ if (hmsc->scsi_blk_len == 0)
+ {
+ MSC_BOT_SendCSW (pdev, USBD_CSW_CMD_PASSED);
+ }
+ else
+ {
+ /* Prapare EP to Receive next packet */
+ USBD_LL_PrepareReceive (pdev,
+ MSC_OUT_EP,
+ hmsc->bot_data,
+ MIN (hmsc->scsi_blk_len, MSC_MEDIA_PACKET));
+ }
+
+ return 0;
+}
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/stmhal/usbdev/core/inc/usbd_conf_template.h b/stmhal/usbdev/core/inc/usbd_conf_template.h deleted file mode 100644 index d80c1da61b..0000000000 --- a/stmhal/usbdev/core/inc/usbd_conf_template.h +++ /dev/null @@ -1,163 +0,0 @@ -/**
- ******************************************************************************
- * @file usbd_conf_template.h
- * @author MCD Application Team
- * @version V2.0.0
- * @date 18-February-2014
- * @brief General low level driver configuration
- ******************************************************************************
- * @attention
- *
- * <h2><center>© COPYRIGHT 2014 STMicroelectronics</center></h2>
- *
- * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
- * You may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.st.com/software_license_agreement_liberty_v2
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __USBD_CONF__H__
-#define __USBD_CONF__H__
-
-#include "stm32f4xx.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-/* Includes ------------------------------------------------------------------*/
-
-/** @addtogroup USBD_OTG_DRIVER
- * @{
- */
-
-/** @defgroup USBD_CONF
- * @brief usb otg low level driver configuration file
- * @{
- */
-
-/** @defgroup USBD_CONF_Exported_Defines
- * @{
- */
-
-#define USBD_MAX_NUM_INTERFACES 1
-#define USBD_MAX_NUM_CONFIGURATION 1
-#define USBD_MAX_STR_DESC_SIZ 0x100
-#define USBD_SUPPORT_USER_STRING 0
-#define USBD_SELF_POWERED 1
-#define USBD_DEBUG_LEVEL 2
-
-/* MSC Class Config */
-#define MSC_MEDIA_PACKET 8192
-
-/* CDC Class Config */
-#define USBD_CDC_INTERVAL 2000
-
- /* DFU Class Config */
-#define USBD_DFU_MAX_ITF_NUM 1
-#define USBD_DFU_XFERS_IZE 1024
-
- /* AUDIO Class Config */
-#define USBD_AUDIO_FREQ 22100
-
-/** @defgroup USBD_Exported_Macros
- * @{
- */
-
- /* Memory management macros */
-#define USBD_malloc malloc
-#define USBD_free free
-#define USBD_memset memset
-#define USBD_memcpy memcpy
-
- /* DEBUG macros */
-
-
-#if (USBD_DEBUG_LEVEL > 0)
-#define USBD_UsrLog(...) printf(__VA_ARGS__);\
- printf("\n");
-#else
-#define USBD_UsrLog(...)
-#endif
-
-
-#if (USBD_DEBUG_LEVEL > 1)
-
-#define USBD_ErrLog(...) printf("ERROR: ") ;\
- printf(__VA_ARGS__);\
- printf("\n");
-#else
-#define USBD_ErrLog(...)
-#endif
-
-
-#if (USBD_DEBUG_LEVEL > 2)
-#define USBD_DbgLog(...) printf("DEBUG : ") ;\
- printf(__VA_ARGS__);\
- printf("\n");
-#else
-#define USBD_DbgLog(...)
-#endif
-
-/**
- * @}
- */
-
-
-
-/**
- * @}
- */
-
-
-/** @defgroup USBD_CONF_Exported_Types
- * @{
- */
-/**
- * @}
- */
-
-
-/** @defgroup USBD_CONF_Exported_Macros
- * @{
- */
-/**
- * @}
- */
-
-/** @defgroup USBD_CONF_Exported_Variables
- * @{
- */
-/**
- * @}
- */
-
-/** @defgroup USBD_CONF_Exported_FunctionsPrototype
- * @{
- */
-/**
- * @}
- */
-
-
-#endif //__USBD_CONF__H__
-
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
-
diff --git a/stmhal/usbdev/core/src/usbd_conf_template.c b/stmhal/usbdev/core/src/usbd_conf_template.c deleted file mode 100644 index 8f4608d1f0..0000000000 --- a/stmhal/usbdev/core/src/usbd_conf_template.c +++ /dev/null @@ -1,258 +0,0 @@ -/**
- ******************************************************************************
- * @file usbd_storage_template.c
- * @author MCD Application Team
- * @version V2.0.0
- * @date 18-February-2014
- * @brief Memory management layer
- ******************************************************************************
- * @attention
- *
- * <h2><center>© COPYRIGHT 2014 STMicroelectronics</center></h2>
- *
- * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
- * You may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.st.com/software_license_agreement_liberty_v2
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- ******************************************************************************
- */
-
-/* Includes ------------------------------------------------------------------*/
-#include "usbd_storage.h"
-
-
-/** @addtogroup STM32_USBD_DEVICE_LIBRARY
-* @{
-*/
-
-
-/** @defgroup USBD_STORAGE
-* @brief usbd core module
-* @{
-*/
-
-/** @defgroup USBD_STORAGE_Private_TypesDefinitions
-* @{
-*/
-/**
-* @}
-*/
-
-
-/** @defgroup USBD_STORAGE_Private_Defines
-* @{
-*/
-#define STORAGE_LUN_NBR 1
-#define STORAGE_BLK_NBR 0x10000
-#define STORAGE_BLK_SIZ 0x200
-/**
-* @}
-*/
-
-
-/** @defgroup USBD_STORAGE_Private_Macros
-* @{
-*/
-/**
-* @}
-*/
-
-
-
-
-/** @defgroup USBD_STORAGE_Private_FunctionPrototypes
-* @{
-*/
-
-/**
-* @}
-*/
-
-
-/** @defgroup USBD_STORAGE_Private_Functions
-* @{
-*/
-
-int8_t STORAGE_Init (uint8_t lun);
-
-int8_t STORAGE_GetCapacity (uint8_t lun,
- uint32_t *block_num,
- uint16_t *block_size);
-
-int8_t STORAGE_IsReady (uint8_t lun);
-
-int8_t STORAGE_IsWriteProtected (uint8_t lun);
-
-int8_t STORAGE_Read (uint8_t lun,
- uint8_t *buf,
- uint32_t blk_addr,
- uint16_t blk_len);
-
-int8_t STORAGE_Write (uint8_t lun,
- uint8_t *buf,
- uint32_t blk_addr,
- uint16_t blk_len);
-
-int8_t STORAGE_GetMaxLun (void);
-
-/** @defgroup USBD_STORAGE_Private_Variables
-* @{
-*/
-
-/* USB Mass storage Standard Inquiry Data */
-int8_t STORAGE_Inquirydata[] = {//36
-
- /* LUN 0 */
- 0x00,
- 0x80,
- 0x02,
- 0x02,
- (STANDARD_INQUIRY_DATA_LEN - 5),
- 0x00,
- 0x00,
- 0x00,
- 'S', 'T', 'M', ' ', ' ', ' ', ' ', ' ', /* Manufacturer : 8 bytes */
- 'P', 'r', 'o', 'd', 'u', 'c', 't', ' ', /* Product : 16 Bytes */
- ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
- '0', '.', '0' ,'1', /* Version : 4 Bytes */
-};
-
-USBD_StorageTypeDef USBD_MSD_fops =
-{
- STORAGE_Init,
- STORAGE_GetCapacity,
- STORAGE_IsReady,
- STORAGE_IsWriteProtected,
- STORAGE_Read,
- STORAGE_Write,
- STORAGE_GetMaxLun,
- STORAGE_Inquirydata,
-
-};
-/**
- * @}
- */
-
-/** @defgroup USBD_CORE_Private_Functions
- * @{
- */
-
-/**
- * @brief STORAGE_Init
- * Initailizes the storage unit (medium)
- * @param lun: logical unit number
- * @retval status (0 : Ok / -1 : Error)
- */
-
-int8_t STORAGE_Init (uint8_t lun)
-{
- return (0);
-}
-
-/**
- * @brief STORAGE_GetCapacity
- * return medium capacity
- * @param lun: logical unit number
- * @param block_num: number of total block number
- * @param block_size: block size
- * @retval status (0 : Ok / -1 : Error)
- */
-int8_t STORAGE_GetCapacity (uint8_t lun, uint32_t *block_num, uint16_t *block_size)
-{
-
- *block_num = STORAGE_BLK_NBR - 1;
- *block_size = STORAGE_BLK_SIZ;
-
- return (0);
-}
-
-/**
- * @brief STORAGE_IsReady
- * check whether the medium is ready
- * @param lun: logical unit number
- * @retval status (0 : Ok / -1 : Error)
- */
-int8_t STORAGE_IsReady (uint8_t lun)
-{
-
- return (0);
-}
-
-/**
- * @brief STORAGE_IsWriteProtected
- * check whether the medium is write protected
- * @param lun: logical unit number
- * @retval status (0 : write enabled / -1 : otherwise)
- */
-int8_t STORAGE_IsWriteProtected (uint8_t lun)
-{
- return 0;
-}
-
-/**
- * @brief STORAGE_Read
- * Read data from the medium
- * @param lun: logical unit number
- * @param blk_addr: logical block address
- * @param blk_len: blocks number
- * @retval status (0 : Ok / -1 : Error)
- */
-int8_t STORAGE_Read (uint8_t lun,
- uint8_t *buf,
- uint32_t blk_addr,
- uint16_t blk_len)
-{
- return (0);
-}
-
-/**
- * @brief STORAGE_Write
- * Write data into the medium
- * @param lun: logical unit number
- * @param blk_addr: logical block address
- * @param blk_len: blocks number
- * @retval status (0 : Ok / -1 : Error)
- */
-int8_t STORAGE_Write (uint8_t lun,
- uint8_t *buf,
- uint32_t blk_addr,
- uint16_t blk_len)
-{
- return (0);
-}
-
-
-/**
- * @brief STORAGE_GetMaxLun
- * return the Max Supported LUNs
- * @param none
- * @retval lun(s) number
- */
-int8_t STORAGE_GetMaxLun (void)
-{
- return (STORAGE_LUN_NBR - 1);
-}
-/**
-* @}
-*/
-
-
-/**
-* @}
-*/
-
-
-/**
-* @}
-*/
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
-
diff --git a/tests/basics/generator-exc.py b/tests/basics/generator-exc.py new file mode 100644 index 0000000000..09aca5d9a0 --- /dev/null +++ b/tests/basics/generator-exc.py @@ -0,0 +1,53 @@ +# Test proper handling of exceptions within generator across yield +def gen(): + try: + yield 1 + raise ValueError + except ValueError: + print("Caught") + yield 2 + +for i in gen(): + print(i) + + +# Test throwing exceptions out of generator +def gen2(): + yield 1 + raise ValueError + yield 2 + yield 3 + +g = gen2() +print(next(g)) +try: + print(next(g)) +except ValueError: + print("ValueError") + +try: + print(next(g)) +except StopIteration: + print("StopIteration") + + +# Test throwing exception into generator +def gen3(): + yield 1 + try: + yield 2 + except ValueError: + print("ValueError received") + yield 3 + yield 4 + yield 5 + +g = gen3() +print(next(g)) +print(next(g)) +print("out of throw:", g.throw(ValueError)) +print(next(g)) +try: + print("out of throw2:", g.throw(ValueError)) +except ValueError: + print("Boomerang ValueError caught") |