From f78d9b1a721bbe56b9049f33a8ec610f811011e5 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 20 Mar 2014 23:33:30 +0000 Subject: stmhal: Add accelerometer driver; fix bug with LFN. --- stmhal/Makefile | 3 +- stmhal/accel.c | 137 +++++++++++++++++++++++++++++++++++++++++++++++++++++ stmhal/accel.h | 11 +++++ stmhal/import.c | 9 ++-- stmhal/led.c | 8 ++++ stmhal/led.h | 1 + stmhal/main.c | 37 +++++---------- stmhal/pybmodule.c | 8 ++-- 8 files changed, 179 insertions(+), 35 deletions(-) create mode 100644 stmhal/accel.c create mode 100644 stmhal/accel.h diff --git a/stmhal/Makefile b/stmhal/Makefile index 9f3e365a1..a1a5a1db6 100644 --- a/stmhal/Makefile +++ b/stmhal/Makefile @@ -84,9 +84,9 @@ SRC_C = \ sdcard.c \ diskio.c \ lcd.c \ + accel.c \ # servo.c \ -# accel.c \ # timer.c \ # audio.c \ # i2c.c \ @@ -104,6 +104,7 @@ SRC_HAL = $(addprefix $(HAL_DIR)/src/,\ stm32f4xx_hal_flash.c \ stm32f4xx_hal_flash_ex.c \ stm32f4xx_hal_gpio.c \ + stm32f4xx_hal_i2c.c \ stm32f4xx_hal_pcd.c \ stm32f4xx_hal_rcc.c \ stm32f4xx_hal_rcc_ex.c \ diff --git a/stmhal/accel.c b/stmhal/accel.c new file mode 100644 index 000000000..f380242bf --- /dev/null +++ b/stmhal/accel.c @@ -0,0 +1,137 @@ +#include +#include + +#include + +#include "misc.h" +#include "mpconfig.h" +#include "qstr.h" +#include "obj.h" +#include "runtime.h" +#include "accel.h" + +#define MMA_ADDR (0x98) +#define MMA_REG_MODE (7) + +STATIC I2C_HandleTypeDef I2cHandle; + +void accel_init(void) { + GPIO_InitTypeDef GPIO_InitStructure; + + // PB5 is connected to AVDD; pull high to enable MMA accel device + GPIOB->BSRRH = GPIO_PIN_5; // turn off AVDD + GPIO_InitStructure.Pin = GPIO_PIN_5; + GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStructure.Speed = GPIO_SPEED_LOW; + GPIO_InitStructure.Pull = GPIO_NOPULL; + HAL_GPIO_Init(GPIOB, &GPIO_InitStructure); + + // wait 20ms, then turn on AVDD, then wait 20ms again + HAL_Delay(20); + GPIOB->BSRRL = GPIO_PIN_5; + HAL_Delay(20); + + // PB6=SCL, PB7=SDA + GPIO_InitStructure.Pin = GPIO_PIN_6 | GPIO_PIN_7; + GPIO_InitStructure.Mode = GPIO_MODE_AF_OD; + GPIO_InitStructure.Speed = GPIO_SPEED_FAST; + GPIO_InitStructure.Pull = GPIO_NOPULL; // have external pull-up resistors on both lines + GPIO_InitStructure.Alternate = GPIO_AF4_I2C1; + HAL_GPIO_Init(GPIOB, &GPIO_InitStructure); + + // enable the I2C1 clock + __I2C1_CLK_ENABLE(); + + // set up the I2C1 device + memset(&I2cHandle, 0, sizeof(I2C_HandleTypeDef)); + I2cHandle.Instance = I2C1; + I2cHandle.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; + I2cHandle.Init.ClockSpeed = 400000; + I2cHandle.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED; + I2cHandle.Init.DutyCycle = I2C_DUTYCYCLE_16_9; + I2cHandle.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED; + I2cHandle.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED; + I2cHandle.Init.OwnAddress1 = 0xfe; // unused + I2cHandle.Init.OwnAddress2 = 0xfe; // unused + + if (HAL_I2C_Init(&I2cHandle) != HAL_OK) { + // init error + printf("accel_init: HAL_I2C_Init failed\n"); + return; + } + + HAL_StatusTypeDef status; + + //printf("IsDeviceReady\n"); + for (int i = 0; i < 10; i++) { + status = HAL_I2C_IsDeviceReady(&I2cHandle, MMA_ADDR, 10, 200); + //printf(" got %d\n", status); + if (status == HAL_OK) { + break; + } + } + + //printf("MemWrite\n"); + uint8_t data[1]; + data[0] = 1; // active mode + status = HAL_I2C_Mem_Write(&I2cHandle, MMA_ADDR, MMA_REG_MODE, I2C_MEMADD_SIZE_8BIT, data, 1, 200); + //printf(" got %d\n", status); +} + +/******************************************************************************/ +/* Micro Python bindings */ + +int accel_buf[12]; + +mp_obj_t pyb_accel_read(void) { + for (int i = 0; i <= 6; i += 3) { + accel_buf[0 + i] = accel_buf[0 + i + 3]; + accel_buf[1 + i] = accel_buf[1 + i + 3]; + accel_buf[2 + i] = accel_buf[2 + i + 3]; + } + + uint8_t data_[4]; + HAL_I2C_Mem_Read(&I2cHandle, MMA_ADDR, 0, I2C_MEMADD_SIZE_8BIT, data_, 4, 200); + accel_buf[9] = data_[0] & 0x3f; if (accel_buf[9] & 0x20) accel_buf[9] |= ~0x1f; + accel_buf[10] = data_[1] & 0x3f; if (accel_buf[10] & 0x20) accel_buf[10] |= ~0x1f; + accel_buf[11] = data_[2] & 0x3f; if (accel_buf[11] & 0x20) accel_buf[11] |= ~0x1f; + int jolt_info = data_[3]; + + mp_obj_t data[4]; + data[0] = mp_obj_new_int(accel_buf[0] + accel_buf[3] + accel_buf[6] + accel_buf[9]); + data[1] = mp_obj_new_int(accel_buf[1] + accel_buf[4] + accel_buf[7] + accel_buf[10]); + data[2] = mp_obj_new_int(accel_buf[2] + accel_buf[5] + accel_buf[8] + accel_buf[11]); + data[3] = mp_obj_new_int(jolt_info); + + return rt_build_tuple(4, data); +} + +MP_DEFINE_CONST_FUN_OBJ_0(pyb_accel_read_obj, pyb_accel_read); + +/* +mp_obj_t pyb_accel_read_all(void) { + mp_obj_t data[11]; + accel_start(MMA_ADDR, 1); + accel_send_byte(0); + accel_restart(MMA_ADDR, 0); + for (int i = 0; i <= 9; i++) { + data[i] = mp_obj_new_int(accel_read_ack()); + } + data[10] = mp_obj_new_int(accel_read_nack()); + + return rt_build_tuple(11, data); +} + +MP_DEFINE_CONST_FUN_OBJ_0(pyb_accel_read_all_obj, pyb_accel_read_all); + +mp_obj_t pyb_accel_write_mode(mp_obj_t o_int, mp_obj_t o_mode) { + accel_start(MMA_ADDR, 1); + accel_send_byte(6); // start at int + accel_send_byte(mp_obj_get_int(o_int)); + accel_send_byte(mp_obj_get_int(o_mode)); + accel_stop(); + return mp_const_none; +} + +MP_DEFINE_CONST_FUN_OBJ_2(pyb_accel_write_mode_obj, pyb_accel_write_mode); +*/ diff --git a/stmhal/accel.h b/stmhal/accel.h new file mode 100644 index 000000000..c2320f1a4 --- /dev/null +++ b/stmhal/accel.h @@ -0,0 +1,11 @@ +void accel_init(void); +void accel_restart(uint8_t addr, int write); +void accel_start(uint8_t addr, int write); +void accel_send_byte(uint8_t data); +uint8_t accel_read_ack(void); +uint8_t accel_read_nack(void); +void accel_stop(void); + +MP_DECLARE_CONST_FUN_OBJ(pyb_accel_read_obj); +MP_DECLARE_CONST_FUN_OBJ(pyb_accel_read_all_obj); +MP_DECLARE_CONST_FUN_OBJ(pyb_accel_write_mode_obj); diff --git a/stmhal/import.c b/stmhal/import.c index f2fd3b3de..c977dcf2e 100644 --- a/stmhal/import.c +++ b/stmhal/import.c @@ -1,16 +1,18 @@ +#include #include #include "misc.h" #include "mpconfig.h" #include "qstr.h" #include "lexer.h" -#if 0 #include "ff.h" -#endif mp_import_stat_t mp_import_stat(const char *path) { -#if 0 FILINFO fno; +#if _USE_LFN + fno.lfname = NULL; + fno.lfsize = 0; +#endif FRESULT res = f_stat(path, &fno); if (res == FR_OK) { if ((fno.fattrib & AM_DIR) != 0) { @@ -19,6 +21,5 @@ mp_import_stat_t mp_import_stat(const char *path) { return MP_IMPORT_STAT_FILE; } } -#endif return MP_IMPORT_STAT_NO_EXIST; } diff --git a/stmhal/led.c b/stmhal/led.c index 677c151b3..80c1e145f 100644 --- a/stmhal/led.c +++ b/stmhal/led.c @@ -73,6 +73,14 @@ void led_toggle(pyb_led_t led) { } } +void led_debug(int n, int delay) { + led_state(1, n & 1); + led_state(2, n & 2); + led_state(3, n & 4); + led_state(4, n & 8); + HAL_Delay(delay); +} + /******************************************************************************/ /* Micro Python bindings */ diff --git a/stmhal/led.h b/stmhal/led.h index 44c68d4eb..b3762271c 100644 --- a/stmhal/led.h +++ b/stmhal/led.h @@ -19,5 +19,6 @@ typedef enum { void led_init(void); void led_state(pyb_led_t led, int state); void led_toggle(pyb_led_t led); +void led_debug(int value, int delay); MP_DECLARE_CONST_FUN_OBJ(pyb_Led_obj); diff --git a/stmhal/main.c b/stmhal/main.c index d77733429..522ebfa6b 100644 --- a/stmhal/main.c +++ b/stmhal/main.c @@ -33,9 +33,9 @@ #include "sdcard.h" #include "ff.h" #include "lcd.h" +#include "accel.h" #if 0 #include "servo.h" -#include "accel.h" #include "timer.h" #include "pybwlan.h" #include "pin.h" @@ -170,22 +170,6 @@ int main(void) { // enable the CCM RAM __CCMDATARAMEN_CLK_ENABLE(); - // some test code to flash LEDs - led_init(); - - led_state(0, 1); - led_state(1, 0); - led_state(2, 1); - -#if 0 - for (;;) { - HAL_Delay(500); - led_state(1, 1); - HAL_Delay(500); - led_state(1, 0); - } -#endif - #if 0 #if defined(NETDUINO_PLUS_2) { @@ -348,6 +332,11 @@ soft_reset: // make sure we have a /boot.py { FILINFO fno; +#if _USE_LFN + 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) { @@ -382,15 +371,6 @@ soft_reset: flash_error(4); } - if (first_soft_reset) { -#if 0 -#if MICROPY_HW_HAS_MMA7660 - // MMA accel: init and reset address to zero - accel_init(); -#endif -#endif - } - // turn boot-up LED off led_state(PYB_LED_GREEN, 0); @@ -419,6 +399,11 @@ soft_reset: pyb_usb_dev_init(PYB_USB_DEV_VCP_MSC); #endif +#if MICROPY_HW_HAS_MMA7660 + // MMA accel: init and reset + accel_init(); +#endif + // run main script { vstr_t *vstr = vstr_new(); diff --git a/stmhal/pybmodule.c b/stmhal/pybmodule.c index b6b269b06..3db23dc6d 100644 --- a/stmhal/pybmodule.c +++ b/stmhal/pybmodule.c @@ -21,10 +21,10 @@ #include "usart.h" #include "storage.h" #include "sdcard.h" +#include "accel.h" #if 0 #include "servo.h" #include "usb.h" -#include "accel.h" #include "i2c.h" #include "adc.h" #include "audio.h" @@ -256,13 +256,13 @@ STATIC const mp_map_elem_t pyb_module_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_SD), (mp_obj_t)&pyb_sdcard_obj }, #endif -#if 0 #if MICROPY_HW_HAS_MMA7660 { MP_OBJ_NEW_QSTR(MP_QSTR_accel), (mp_obj_t)&pyb_accel_read_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_accel_read), (mp_obj_t)&pyb_accel_read_all_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_accel_mode), (mp_obj_t)&pyb_accel_write_mode_obj }, + //{ MP_OBJ_NEW_QSTR(MP_QSTR_accel_read), (mp_obj_t)&pyb_accel_read_all_obj }, + //{ MP_OBJ_NEW_QSTR(MP_QSTR_accel_mode), (mp_obj_t)&pyb_accel_write_mode_obj }, #endif +#if 0 { MP_OBJ_NEW_QSTR(MP_QSTR_hid), (mp_obj_t)&pyb_hid_send_report_obj }, #endif { MP_OBJ_NEW_QSTR(MP_QSTR_Led), (mp_obj_t)&pyb_Led_obj }, -- cgit v1.2.3 From 1609f855828d2b932542b3a46158619a7c574555 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 20 Mar 2014 23:41:04 +0000 Subject: Rename test so that it doesn't clash with Python math module. --- tests/basics/math-fun.py | 49 ++++++++++++++++++++++++++++++++++++++++++++++++ tests/basics/math.py | 49 ------------------------------------------------ 2 files changed, 49 insertions(+), 49 deletions(-) create mode 100644 tests/basics/math-fun.py delete mode 100644 tests/basics/math.py diff --git a/tests/basics/math-fun.py b/tests/basics/math-fun.py new file mode 100644 index 000000000..f5ffbf40d --- /dev/null +++ b/tests/basics/math-fun.py @@ -0,0 +1,49 @@ +# Tests the functions imported from math + +from math import * + +test_values = [-100., -1.23456, -1, -0.5, 0.0, 0.5, 1.23456, 100.] +p_test_values = [0.1, 0.5, 1.23456] +unit_range_test_values = [-1., -0.75, -0.5, -0.25, 0., 0.25, 0.5, 0.75, 1.] +#IEEE_test_values = [1, 0, float('NaN'), float('Inf'), -float('NaN'), -float('Inf')] +#TODO: float('NaN') + +functions = [(sqrt, p_test_values), + (exp, test_values), + (expm1, test_values), + (log, p_test_values), + (log2, p_test_values), + (log10, p_test_values), + (cosh, test_values), + (sinh, test_values), + (tanh, test_values), + (acosh, [1.0, 5.0, 1.0]), + (asinh, test_values), + (atanh, [-0.99, -0.5, 0.0, 0.5, 0.99]), + (cos, test_values), + (sin, test_values), + (tan, test_values), + (acos, unit_range_test_values), + (asin, unit_range_test_values), + (atan, test_values), + (ceil, test_values), + (fabs, test_values), + (floor, test_values), + #(frexp, test_values), + #(isfinite, [1, 0, float('NaN'), float('Inf')]) + (trunc, test_values) + ] + +for function, test_vals in functions: + for value in test_vals: + print("{:8.7f}".format(function(value))) + +binary_functions = [(copysign, [(23., 42.), (-23., 42.), (23., -42.), + (-23., -42.), (1., 0.0), (1., -0.0)]) + ] + +#for function, test_vals in binary_functions: +# for value1, value2 in test_vals: +# print("{:8.7f}".format(function(value1, value2))) + + diff --git a/tests/basics/math.py b/tests/basics/math.py deleted file mode 100644 index f5ffbf40d..000000000 --- a/tests/basics/math.py +++ /dev/null @@ -1,49 +0,0 @@ -# Tests the functions imported from math - -from math import * - -test_values = [-100., -1.23456, -1, -0.5, 0.0, 0.5, 1.23456, 100.] -p_test_values = [0.1, 0.5, 1.23456] -unit_range_test_values = [-1., -0.75, -0.5, -0.25, 0., 0.25, 0.5, 0.75, 1.] -#IEEE_test_values = [1, 0, float('NaN'), float('Inf'), -float('NaN'), -float('Inf')] -#TODO: float('NaN') - -functions = [(sqrt, p_test_values), - (exp, test_values), - (expm1, test_values), - (log, p_test_values), - (log2, p_test_values), - (log10, p_test_values), - (cosh, test_values), - (sinh, test_values), - (tanh, test_values), - (acosh, [1.0, 5.0, 1.0]), - (asinh, test_values), - (atanh, [-0.99, -0.5, 0.0, 0.5, 0.99]), - (cos, test_values), - (sin, test_values), - (tan, test_values), - (acos, unit_range_test_values), - (asin, unit_range_test_values), - (atan, test_values), - (ceil, test_values), - (fabs, test_values), - (floor, test_values), - #(frexp, test_values), - #(isfinite, [1, 0, float('NaN'), float('Inf')]) - (trunc, test_values) - ] - -for function, test_vals in functions: - for value in test_vals: - print("{:8.7f}".format(function(value))) - -binary_functions = [(copysign, [(23., 42.), (-23., 42.), (23., -42.), - (-23., -42.), (1., 0.0), (1., -0.0)]) - ] - -#for function, test_vals in binary_functions: -# for value1, value2 in test_vals: -# print("{:8.7f}".format(function(value1, value2))) - - -- cgit v1.2.3 From 613a8e3edf078c284bd981426cc5a256eabb2323 Mon Sep 17 00:00:00 2001 From: xbe Date: Tue, 18 Mar 2014 00:06:29 -0700 Subject: Implement str.partition and add tests for it. --- py/objstr.c | 27 +++++++++++++++++++++++++++ tests/basics/string_partition.py | 29 +++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 tests/basics/string_partition.py diff --git a/py/objstr.c b/py/objstr.c index d660bf952..03711debb 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -520,6 +520,31 @@ STATIC mp_obj_t str_count(uint n_args, const mp_obj_t *args) { return MP_OBJ_NEW_SMALL_INT(num_occurrences); } +STATIC mp_obj_t str_partition(mp_obj_t self_in, mp_obj_t arg) { + assert(MP_OBJ_IS_STR(self_in)); + if (!MP_OBJ_IS_STR(arg)) { + nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_TypeError, + "Can't convert '%s' object to str implicitly", mp_obj_get_type_str(arg))); + } + + GET_STR_DATA_LEN(self_in, str, str_len); + GET_STR_DATA_LEN(arg, sep, sep_len); + + if (sep_len == 0) { + nlr_jump(mp_obj_new_exception_msg(&mp_type_ValueError, "empty separator")); + } + + for (machine_uint_t str_index = 0; str_index + sep_len <= str_len; str_index++) { + if (memcmp(&str[str_index], sep, sep_len) == 0) { + mp_obj_t items[] = {mp_obj_new_str(str, str_index, false), arg, + mp_obj_new_str(str + str_index + sep_len, str_len - str_index - sep_len, false)}; + return mp_obj_new_tuple(3, items); + } + } + mp_obj_t items[] = {mp_obj_new_str(str, str_len, false), MP_OBJ_NEW_QSTR(MP_QSTR_), MP_OBJ_NEW_QSTR(MP_QSTR_)}; + return mp_obj_new_tuple(3, items); +} + STATIC machine_int_t str_get_buffer(mp_obj_t self_in, buffer_info_t *bufinfo, int flags) { if (flags == BUFFER_READ) { GET_STR_DATA_LEN(self_in, str_data, str_len); @@ -542,6 +567,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_strip_obj, 1, 2, str_strip); STATIC MP_DEFINE_CONST_FUN_OBJ_VAR(str_format_obj, 1, str_format); STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_replace_obj, 3, 4, str_replace); STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_count_obj, 2, 4, str_count); +STATIC MP_DEFINE_CONST_FUN_OBJ_2(str_partition_obj, str_partition); STATIC const mp_method_t str_type_methods[] = { { "find", &str_find_obj }, @@ -552,6 +578,7 @@ STATIC const mp_method_t str_type_methods[] = { { "format", &str_format_obj }, { "replace", &str_replace_obj }, { "count", &str_count_obj }, + { "partition", &str_partition_obj }, { NULL, NULL }, // end-of-list sentinel }; diff --git a/tests/basics/string_partition.py b/tests/basics/string_partition.py new file mode 100644 index 000000000..ad70d0250 --- /dev/null +++ b/tests/basics/string_partition.py @@ -0,0 +1,29 @@ +print("asdf".partition('g')) +print("asdf".partition('a')) +print("asdf".partition('s')) +print("asdf".partition('f')) +print("asdf".partition('d')) +print("asdf".partition('asd')) +print("asdf".partition('sdf')) +print("asdf".partition('as')) +print("asdf".partition('df')) +print("asdf".partition('asdf')) +print("asdf".partition('asdfa')) +print("asdf".partition('fasdf')) +print("asdf".partition('fasdfa')) +print("abba".partition('a')) +print("abba".partition('b')) + +try: + print("asdf".partition(1)) +except TypeError: + print("Raised TypeError") +else: + print("Did not raise TypeError") + +try: + print("asdf".partition('')) +except ValueError: + print("Raised ValueError") +else: + print("Did not raise ValueError") -- cgit v1.2.3 From 4504ea8007bbc97aef51ced20a9ff3f460cd7caf Mon Sep 17 00:00:00 2001 From: xbe Date: Wed, 19 Mar 2014 00:46:14 -0700 Subject: Implement str.rpartition and add tests for it. --- py/objstr.c | 36 ++++++++++++++++++++++++++++++++++++ tests/basics/string_rpartition.py | 29 +++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 tests/basics/string_rpartition.py diff --git a/py/objstr.c b/py/objstr.c index 03711debb..c71993578 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -545,6 +545,40 @@ STATIC mp_obj_t str_partition(mp_obj_t self_in, mp_obj_t arg) { return mp_obj_new_tuple(3, items); } +STATIC mp_obj_t str_rpartition(mp_obj_t self_in, mp_obj_t arg) { + assert(MP_OBJ_IS_STR(self_in)); + if (!MP_OBJ_IS_STR(arg)) { + nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_TypeError, + "Can't convert '%s' object to str implicitly", mp_obj_get_type_str(arg))); + } + + GET_STR_DATA_LEN(self_in, str, str_len); + GET_STR_DATA_LEN(arg, sep, sep_len); + + if (sep_len == 0) { + nlr_jump(mp_obj_new_exception_msg(&mp_type_ValueError, "empty separator")); + } + + if (sep_len > str_len) { + goto not_found; + } + + for (machine_uint_t str_index = str_len; ; str_index--) { + if (memcmp(&str[str_index - sep_len], sep, sep_len) == 0) { + mp_obj_t items[] = {mp_obj_new_str(str, str_index - sep_len, false), arg, + mp_obj_new_str(str + str_index, str_len - str_index, false)}; + return mp_obj_new_tuple(3, items); + } + if (str_index - sep_len == 0) { + break; + } + } + +not_found: ; + mp_obj_t items[] = {MP_OBJ_NEW_QSTR(MP_QSTR_), MP_OBJ_NEW_QSTR(MP_QSTR_), mp_obj_new_str(str, str_len, false)}; + return mp_obj_new_tuple(3, items); +} + STATIC machine_int_t str_get_buffer(mp_obj_t self_in, buffer_info_t *bufinfo, int flags) { if (flags == BUFFER_READ) { GET_STR_DATA_LEN(self_in, str_data, str_len); @@ -568,6 +602,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR(str_format_obj, 1, str_format); STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_replace_obj, 3, 4, str_replace); STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_count_obj, 2, 4, str_count); STATIC MP_DEFINE_CONST_FUN_OBJ_2(str_partition_obj, str_partition); +STATIC MP_DEFINE_CONST_FUN_OBJ_2(str_rpartition_obj, str_rpartition); STATIC const mp_method_t str_type_methods[] = { { "find", &str_find_obj }, @@ -579,6 +614,7 @@ STATIC const mp_method_t str_type_methods[] = { { "replace", &str_replace_obj }, { "count", &str_count_obj }, { "partition", &str_partition_obj }, + { "rpartition", &str_rpartition_obj }, { NULL, NULL }, // end-of-list sentinel }; diff --git a/tests/basics/string_rpartition.py b/tests/basics/string_rpartition.py new file mode 100644 index 000000000..656121c94 --- /dev/null +++ b/tests/basics/string_rpartition.py @@ -0,0 +1,29 @@ +print("asdf".rpartition('g')) +print("asdf".rpartition('a')) +print("asdf".rpartition('s')) +print("asdf".rpartition('f')) +print("asdf".rpartition('d')) +print("asdf".rpartition('asd')) +print("asdf".rpartition('sdf')) +print("asdf".rpartition('as')) +print("asdf".rpartition('df')) +print("asdf".rpartition('asdf')) +print("asdf".rpartition('asdfa')) +print("asdf".rpartition('fasdf')) +print("asdf".rpartition('fasdfa')) +print("abba".rpartition('a')) +print("abba".rpartition('b')) + +try: + print("asdf".rpartition(1)) +except TypeError: + print("Raised TypeError") +else: + print("Did not raise TypeError") + +try: + print("asdf".rpartition('')) +except ValueError: + print("Raised ValueError") +else: + print("Did not raise ValueError") -- cgit v1.2.3 From 0a6894c24b0d760755253c10a59824c68a40701e Mon Sep 17 00:00:00 2001 From: xbe Date: Fri, 21 Mar 2014 01:12:26 -0700 Subject: str.(r)partition: factor out duplicate code. Switch str.rpartition to search from left to right. Factor the duplicate code into one helper function. --- py/objstr.c | 57 +++++++++++++++++++-------------------------------------- 1 file changed, 19 insertions(+), 38 deletions(-) diff --git a/py/objstr.c b/py/objstr.c index c71993578..c2b3f8d4c 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -520,63 +520,44 @@ STATIC mp_obj_t str_count(uint n_args, const mp_obj_t *args) { return MP_OBJ_NEW_SMALL_INT(num_occurrences); } -STATIC mp_obj_t str_partition(mp_obj_t self_in, mp_obj_t arg) { +STATIC mp_obj_t str_partitioner(mp_obj_t self_in, mp_obj_t arg, bool rpartition) { assert(MP_OBJ_IS_STR(self_in)); if (!MP_OBJ_IS_STR(arg)) { nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "Can't convert '%s' object to str implicitly", mp_obj_get_type_str(arg))); } - GET_STR_DATA_LEN(self_in, str, str_len); GET_STR_DATA_LEN(arg, sep, sep_len); + mp_obj_t result[] = {MP_OBJ_NEW_QSTR(MP_QSTR_), MP_OBJ_NEW_QSTR(MP_QSTR_), MP_OBJ_NEW_QSTR(MP_QSTR_)}; if (sep_len == 0) { nlr_jump(mp_obj_new_exception_msg(&mp_type_ValueError, "empty separator")); } + if (rpartition) { + result[2] = mp_obj_new_str(str, str_len, false); + } else { + result[0] = mp_obj_new_str(str, str_len, false); + } for (machine_uint_t str_index = 0; str_index + sep_len <= str_len; str_index++) { if (memcmp(&str[str_index], sep, sep_len) == 0) { - mp_obj_t items[] = {mp_obj_new_str(str, str_index, false), arg, - mp_obj_new_str(str + str_index + sep_len, str_len - str_index - sep_len, false)}; - return mp_obj_new_tuple(3, items); + result[0] = mp_obj_new_str(str, str_index, false); + result[1] = arg; + result[2] = mp_obj_new_str(str + str_index + sep_len, str_len - str_index - sep_len, false); + if (!rpartition) { + break; + } } } - mp_obj_t items[] = {mp_obj_new_str(str, str_len, false), MP_OBJ_NEW_QSTR(MP_QSTR_), MP_OBJ_NEW_QSTR(MP_QSTR_)}; - return mp_obj_new_tuple(3, items); + return mp_obj_new_tuple(3, result); } -STATIC mp_obj_t str_rpartition(mp_obj_t self_in, mp_obj_t arg) { - assert(MP_OBJ_IS_STR(self_in)); - if (!MP_OBJ_IS_STR(arg)) { - nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_TypeError, - "Can't convert '%s' object to str implicitly", mp_obj_get_type_str(arg))); - } - - GET_STR_DATA_LEN(self_in, str, str_len); - GET_STR_DATA_LEN(arg, sep, sep_len); - - if (sep_len == 0) { - nlr_jump(mp_obj_new_exception_msg(&mp_type_ValueError, "empty separator")); - } - - if (sep_len > str_len) { - goto not_found; - } - - for (machine_uint_t str_index = str_len; ; str_index--) { - if (memcmp(&str[str_index - sep_len], sep, sep_len) == 0) { - mp_obj_t items[] = {mp_obj_new_str(str, str_index - sep_len, false), arg, - mp_obj_new_str(str + str_index, str_len - str_index, false)}; - return mp_obj_new_tuple(3, items); - } - if (str_index - sep_len == 0) { - break; - } - } +STATIC mp_obj_t str_partition(mp_obj_t self_in, mp_obj_t arg, bool partition) { + return str_partitioner(self_in, arg, false); +} -not_found: ; - mp_obj_t items[] = {MP_OBJ_NEW_QSTR(MP_QSTR_), MP_OBJ_NEW_QSTR(MP_QSTR_), mp_obj_new_str(str, str_len, false)}; - return mp_obj_new_tuple(3, items); +STATIC mp_obj_t str_rpartition(mp_obj_t self_in, mp_obj_t arg, bool partition) { + return str_partitioner(self_in, arg, true); } STATIC machine_int_t str_get_buffer(mp_obj_t self_in, buffer_info_t *bufinfo, int flags) { -- cgit v1.2.3 From c06ea7abf249765bf93595fc42656eed585d7a47 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 21 Mar 2014 10:55:08 +0000 Subject: py: Implement parsing of infinity and nan for floats. --- py/objfloat.c | 2 +- py/parsenum.c | 144 +++++++++++++++++++++++++++++++++++++++++----------------- py/parsenum.h | 2 +- py/runtime.c | 2 +- 4 files changed, 105 insertions(+), 45 deletions(-) diff --git a/py/objfloat.c b/py/objfloat.c index 401c1145e..65dafa607 100644 --- a/py/objfloat.c +++ b/py/objfloat.c @@ -38,7 +38,7 @@ STATIC mp_obj_t float_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const m // a string, parse it uint l; const char *s = mp_obj_str_get_data(args[0], &l); - return mp_parse_num_decimal(s, l); + return mp_parse_num_decimal(s, l, false); } else if (MP_OBJ_IS_TYPE(args[0], &mp_type_float)) { return args[0]; } else { diff --git a/py/parsenum.c b/py/parsenum.c index c9cef5fcd..b1a70c352 100644 --- a/py/parsenum.c +++ b/py/parsenum.c @@ -9,6 +9,10 @@ #include "parsenumbase.h" #include "parsenum.h" +#if MICROPY_ENABLE_FLOAT +#include +#endif + #if defined(UNIX) #include @@ -84,64 +88,120 @@ mp_obj_t mp_parse_num_integer(const char *restrict str, uint len, int base) { #define PARSE_DEC_IN_FRAC (2) #define PARSE_DEC_IN_EXP (3) -mp_obj_t mp_parse_num_decimal(const char *str, uint len) { +mp_obj_t mp_parse_num_decimal(const char *str, uint len, bool allow_imag) { #if MICROPY_ENABLE_FLOAT - int in = PARSE_DEC_IN_INTG; + const char *top = str + len; mp_float_t dec_val = 0; - bool exp_neg = false; - int exp_val = 0; - int exp_extra = 0; + bool dec_neg = false; bool imag = false; - const char *top = str + len; - for (; str < top; str++) { - int dig = *str; - if ('0' <= dig && dig <= '9') { - dig -= '0'; - if (in == PARSE_DEC_IN_EXP) { - exp_val = 10 * exp_val + dig; - } else { - dec_val = 10 * dec_val + dig; - if (in == PARSE_DEC_IN_FRAC) { - exp_extra -= 1; - } + + // skip leading space + for (; str < top && isspace(*str); str++) { + } + + // get optional sign + if (str < top) { + if (*str == '+') { + str++; + } else if (*str == '-') { + str++; + dec_neg = true; + } + } + + // determine what the string is + if (str < top && (str[0] | 0x20) == 'i') { + // string starts with 'i', should be 'inf' or 'infinity' (case insensitive) + if (str + 2 < top && (str[1] | 0x20) == 'n' && (str[2] | 0x20) == 'f') { + // inf + str += 3; + dec_val = INFINITY; + if (str + 4 < top && (str[0] | 0x20) == 'i' && (str[1] | 0x20) == 'n' && (str[2] | 0x20) == 'i' && (str[3] | 0x20) == 't' && (str[4] | 0x20) == 'y') { + // infinity + str += 5; } - } else if (in == PARSE_DEC_IN_INTG && dig == '.') { - in = PARSE_DEC_IN_FRAC; - } else if (in != PARSE_DEC_IN_EXP && (dig == 'E' || dig == 'e')) { - in = PARSE_DEC_IN_EXP; - if (str[1] == '+') { - str++; - } else if (str[1] == '-') { + } + } else if (str < top && (str[0] | 0x20) == 'n') { + // string starts with 'n', should be 'nan' (case insensitive) + if (str + 2 < top && (str[1] | 0x20) == 'a' && (str[2] | 0x20) == 'n') { + // NaN + str += 3; + dec_val = MICROPY_FLOAT_C_FUN(nan)(""); + } + } else { + // parse the digits + int in = PARSE_DEC_IN_INTG; + bool exp_neg = false; + int exp_val = 0; + int exp_extra = 0; + for (; str < top; str++) { + int dig = *str; + if ('0' <= dig && dig <= '9') { + dig -= '0'; + if (in == PARSE_DEC_IN_EXP) { + exp_val = 10 * exp_val + dig; + } else { + dec_val = 10 * dec_val + dig; + if (in == PARSE_DEC_IN_FRAC) { + exp_extra -= 1; + } + } + } else if (in == PARSE_DEC_IN_INTG && dig == '.') { + in = PARSE_DEC_IN_FRAC; + } else if (in != PARSE_DEC_IN_EXP && ((dig | 0x20) == 'e')) { + in = PARSE_DEC_IN_EXP; + if (str[1] == '+') { + str++; + } else if (str[1] == '-') { + str++; + exp_neg = true; + } + } else if (allow_imag && (dig | 0x20) == 'j') { str++; - exp_neg = true; + imag = true; + break; + } else { + // unknown character + break; } - } else if (dig == 'J' || dig == 'j') { - str++; - imag = true; - break; - } else { - // unknown character - break; + } + + // work out the exponent + if (exp_neg) { + exp_val = -exp_val; + } + exp_val += exp_extra; + + // apply the exponent + for (; exp_val > 0; exp_val--) { + dec_val *= 10; + } + for (; exp_val < 0; exp_val++) { + dec_val *= 0.1; } } - if (*str != 0) { - nlr_jump(mp_obj_new_exception_msg(&mp_type_SyntaxError, "invalid syntax for number")); - } - if (exp_neg) { - exp_val = -exp_val; + + // negate value if needed + if (dec_neg) { + dec_val = -dec_val; } - exp_val += exp_extra; - for (; exp_val > 0; exp_val--) { - dec_val *= 10; + + // skip trailing space + for (; str < top && isspace(*str); str++) { } - for (; exp_val < 0; exp_val++) { - dec_val *= 0.1; + + // check we reached the end of the string + if (str != top) { + nlr_jump(mp_obj_new_exception_msg(&mp_type_SyntaxError, "invalid syntax for number")); } + + // return the object if (imag) { return mp_obj_new_complex(0, dec_val); } else { return mp_obj_new_float(dec_val); } + #else nlr_jump(mp_obj_new_exception_msg(&mp_type_SyntaxError, "decimal numbers not supported")); #endif diff --git a/py/parsenum.h b/py/parsenum.h index 5a2e42da5..f87fefbe7 100644 --- a/py/parsenum.h +++ b/py/parsenum.h @@ -1,2 +1,2 @@ mp_obj_t mp_parse_num_integer(const char *restrict str, uint len, int base); -mp_obj_t mp_parse_num_decimal(const char *str, uint len); +mp_obj_t mp_parse_num_decimal(const char *str, uint len, bool allow_imag); diff --git a/py/runtime.c b/py/runtime.c index 9c8ba636c..5604e1a94 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -375,7 +375,7 @@ mp_obj_t rt_load_const_dec(qstr qstr) { DEBUG_OP_printf("load '%s'\n", qstr_str(qstr)); uint len; const byte* data = qstr_data(qstr, &len); - return mp_parse_num_decimal((const char*)data, len); + return mp_parse_num_decimal((const char*)data, len, true); } mp_obj_t rt_load_const_str(qstr qstr) { -- cgit v1.2.3 From 6e48f7fa856e4acaf085dfc8876c4e3772d979c2 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 21 Mar 2014 11:45:46 +0000 Subject: py: Allow 'complex()' to take a string as first argument. --- py/objcomplex.c | 14 ++++++++++---- py/objfloat.c | 4 +++- py/parsenum.c | 6 ++++-- py/parsenum.h | 2 +- py/runtime.c | 2 +- 5 files changed, 19 insertions(+), 9 deletions(-) diff --git a/py/objcomplex.c b/py/objcomplex.c index 65957cbf6..2ba522615 100644 --- a/py/objcomplex.c +++ b/py/objcomplex.c @@ -6,6 +6,7 @@ #include "mpconfig.h" #include "qstr.h" #include "obj.h" +#include "parsenum.h" #include "runtime0.h" #include "map.h" @@ -36,15 +37,20 @@ STATIC mp_obj_t complex_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const return mp_obj_new_complex(0, 0); case 1: - // TODO allow string as first arg and parse it - if (MP_OBJ_IS_TYPE(args[0], &mp_type_complex)) { + if (MP_OBJ_IS_STR(args[0])) { + // a string, parse it + uint l; + const char *s = mp_obj_str_get_data(args[0], &l); + return mp_parse_num_decimal(s, l, true, true); + } else if (MP_OBJ_IS_TYPE(args[0], &mp_type_complex)) { + // a complex, just return it return args[0]; } else { + // something else, try to cast it to a complex return mp_obj_new_complex(mp_obj_get_float(args[0]), 0); } - case 2: - { + case 2: { mp_float_t real, imag; if (MP_OBJ_IS_TYPE(args[0], &mp_type_complex)) { mp_obj_complex_get(args[0], &real, &imag); diff --git a/py/objfloat.c b/py/objfloat.c index 65dafa607..c51e13e7a 100644 --- a/py/objfloat.c +++ b/py/objfloat.c @@ -38,10 +38,12 @@ STATIC mp_obj_t float_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const m // a string, parse it uint l; const char *s = mp_obj_str_get_data(args[0], &l); - return mp_parse_num_decimal(s, l, false); + return mp_parse_num_decimal(s, l, false, false); } else if (MP_OBJ_IS_TYPE(args[0], &mp_type_float)) { + // a float, just return it return args[0]; } else { + // something else, try to cast it to a float return mp_obj_new_float(mp_obj_get_float(args[0])); } diff --git a/py/parsenum.c b/py/parsenum.c index b1a70c352..77f00957c 100644 --- a/py/parsenum.c +++ b/py/parsenum.c @@ -88,7 +88,7 @@ mp_obj_t mp_parse_num_integer(const char *restrict str, uint len, int base) { #define PARSE_DEC_IN_FRAC (2) #define PARSE_DEC_IN_EXP (3) -mp_obj_t mp_parse_num_decimal(const char *str, uint len, bool allow_imag) { +mp_obj_t mp_parse_num_decimal(const char *str, uint len, bool allow_imag, bool force_complex) { #if MICROPY_ENABLE_FLOAT const char *top = str + len; mp_float_t dec_val = 0; @@ -129,7 +129,7 @@ mp_obj_t mp_parse_num_decimal(const char *str, uint len, bool allow_imag) { dec_val = MICROPY_FLOAT_C_FUN(nan)(""); } } else { - // parse the digits + // string should be a decimal number int in = PARSE_DEC_IN_INTG; bool exp_neg = false; int exp_val = 0; @@ -198,6 +198,8 @@ mp_obj_t mp_parse_num_decimal(const char *str, uint len, bool allow_imag) { // return the object if (imag) { return mp_obj_new_complex(0, dec_val); + } else if (force_complex) { + return mp_obj_new_complex(dec_val, 0); } else { return mp_obj_new_float(dec_val); } diff --git a/py/parsenum.h b/py/parsenum.h index f87fefbe7..97578423c 100644 --- a/py/parsenum.h +++ b/py/parsenum.h @@ -1,2 +1,2 @@ mp_obj_t mp_parse_num_integer(const char *restrict str, uint len, int base); -mp_obj_t mp_parse_num_decimal(const char *str, uint len, bool allow_imag); +mp_obj_t mp_parse_num_decimal(const char *str, uint len, bool allow_imag, bool force_complex); diff --git a/py/runtime.c b/py/runtime.c index 5604e1a94..c268fd546 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -375,7 +375,7 @@ mp_obj_t rt_load_const_dec(qstr qstr) { DEBUG_OP_printf("load '%s'\n", qstr_str(qstr)); uint len; const byte* data = qstr_data(qstr, &len); - return mp_parse_num_decimal((const char*)data, len, true); + return mp_parse_num_decimal((const char*)data, len, true, false); } mp_obj_t rt_load_const_str(qstr qstr) { -- cgit v1.2.3 From dfbafabf6ffd230ef7165c8df62c58dd912d41e4 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 21 Mar 2014 12:15:59 +0000 Subject: py: Improve mp_parse_num_integer; make it self contained. --- py/parsenum.c | 119 +++++++++++++++++++++++++++++++--------------------------- 1 file changed, 63 insertions(+), 56 deletions(-) diff --git a/py/parsenum.c b/py/parsenum.c index 77f00957c..6be042fe8 100644 --- a/py/parsenum.c +++ b/py/parsenum.c @@ -13,76 +13,83 @@ #include #endif -#if defined(UNIX) - -#include -#include - mp_obj_t mp_parse_num_integer(const char *restrict str, uint len, int base) { - // TODO at the moment we ignore len; we should honour it! - // TODO detect integer overflow and return bignum - - int c, neg = 0; - const char *p = str; - char *num; - long found; + const char *restrict top = str + len; + bool neg = false; // check radix base if ((base != 0 && base < 2) || base > 36) { nlr_jump(mp_obj_new_exception_msg(&mp_type_ValueError, "ValueError: int() arg 2 must be >=2 and <= 36")); } - // skip surrounded whitespace - while (isspace((c = *(p++)))); - if (c == 0) { - goto value_error; - } - // preced sign - if (c == '+' || c == '-') { - neg = - (c == '-'); - } else { - p--; + + // skip leading space + for (; str < top && unichar_isspace(*str); str++) { } - len -= p - str; - int skip = mp_parse_num_base(p, len, &base); - p += skip; - len -= skip; - - errno = 0; - found = strtol(p, &num, base); - if (errno) { - goto value_error; - } else if (found && *(num) == 0) { - goto done; - } else if (found || num != p) { - goto check_tail_space; - } else { - goto value_error; + // parse optional sign + if (str < top) { + if (*str == '+') { + str++; + } else if (*str == '-') { + str++; + neg = true; + } } -check_tail_space: - if (*(num) != 0) { - while (isspace((c = *(num++)))); - if (c != 0) { - goto value_error; + // parse optional base prefix + str += mp_parse_num_base(str, top - str, &base); + + // string should be an integer number + machine_int_t int_val = 0; + for (; str < top; str++) { + machine_int_t old_val = int_val; + int dig = *str; + if (unichar_isdigit(dig) && dig - '0' < base) { + // 0-9 digit + int_val = base * int_val + dig - '0'; + } else if (base == 16) { + dig |= 0x20; + if ('a' <= dig && dig <= 'f') { + // a-f hex digit + int_val = base * int_val + dig - 'a' + 10; + } else { + // unknown character + break; + } + } else { + // unknown character + break; + } + if (int_val < old_val) { + // If new value became less than previous, it's overflow + goto overflow; + } else if ((old_val ^ int_val) & WORD_MSBIT_HIGH) { + // If signed number changed sign - it's overflow + goto overflow; } } -done: - return MP_OBJ_NEW_SMALL_INT((found ^ neg) - neg); + // negate value if needed + if (neg) { + int_val = -int_val; + } -value_error: - nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "invalid literal for int() with base %d: '%s'", base, str)); -} + // skip trailing space + for (; str < top && unichar_isspace(*str); str++) { + } -#else /* defined(UNIX) */ + // check we reached the end of the string + if (str != top) { + nlr_jump(mp_obj_new_exception_msg(&mp_type_SyntaxError, "invalid syntax for number")); + } -mp_obj_t mp_parse_num_integer(const char *restrict str, uint len, int base) { - // TODO port strtol to stm - return MP_OBJ_NEW_SMALL_INT(0); -} + // return the object + return MP_OBJ_NEW_SMALL_INT(int_val); -#endif /* defined(UNIX) */ +overflow: + // TODO reparse using bignum + nlr_jump(mp_obj_new_exception_msg(&mp_type_ValueError, "overflow parsing integer")); +} #define PARSE_DEC_IN_INTG (1) #define PARSE_DEC_IN_FRAC (2) @@ -96,10 +103,10 @@ mp_obj_t mp_parse_num_decimal(const char *str, uint len, bool allow_imag, bool f bool imag = false; // skip leading space - for (; str < top && isspace(*str); str++) { + for (; str < top && unichar_isspace(*str); str++) { } - // get optional sign + // parse optional sign if (str < top) { if (*str == '+') { str++; @@ -187,7 +194,7 @@ mp_obj_t mp_parse_num_decimal(const char *str, uint len, bool allow_imag, bool f } // skip trailing space - for (; str < top && isspace(*str); str++) { + for (; str < top && unichar_isspace(*str); str++) { } // check we reached the end of the string -- cgit v1.2.3 From b035db355a995222588635d937585a7f5ab7dc93 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 21 Mar 2014 20:39:40 +0000 Subject: py: Make str.[r]partition more efficient. --- py/objstr.c | 46 +++++++++++++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/py/objstr.c b/py/objstr.c index c2b3f8d4c..77cefa82b 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -520,44 +520,60 @@ STATIC mp_obj_t str_count(uint n_args, const mp_obj_t *args) { return MP_OBJ_NEW_SMALL_INT(num_occurrences); } -STATIC mp_obj_t str_partitioner(mp_obj_t self_in, mp_obj_t arg, bool rpartition) { +STATIC mp_obj_t str_partitioner(mp_obj_t self_in, mp_obj_t arg, machine_int_t direction) { assert(MP_OBJ_IS_STR(self_in)); if (!MP_OBJ_IS_STR(arg)) { nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "Can't convert '%s' object to str implicitly", mp_obj_get_type_str(arg))); } + GET_STR_DATA_LEN(self_in, str, str_len); GET_STR_DATA_LEN(arg, sep, sep_len); - mp_obj_t result[] = {MP_OBJ_NEW_QSTR(MP_QSTR_), MP_OBJ_NEW_QSTR(MP_QSTR_), MP_OBJ_NEW_QSTR(MP_QSTR_)}; if (sep_len == 0) { nlr_jump(mp_obj_new_exception_msg(&mp_type_ValueError, "empty separator")); } - if (rpartition) { - result[2] = mp_obj_new_str(str, str_len, false); + + mp_obj_t result[] = {MP_OBJ_NEW_QSTR(MP_QSTR_), MP_OBJ_NEW_QSTR(MP_QSTR_), MP_OBJ_NEW_QSTR(MP_QSTR_)}; + + if (direction > 0) { + result[0] = self_in; } else { - result[0] = mp_obj_new_str(str, str_len, false); + result[2] = self_in; } - for (machine_uint_t str_index = 0; str_index + sep_len <= str_len; str_index++) { - if (memcmp(&str[str_index], sep, sep_len) == 0) { - result[0] = mp_obj_new_str(str, str_index, false); - result[1] = arg; - result[2] = mp_obj_new_str(str + str_index + sep_len, str_len - str_index - sep_len, false); - if (!rpartition) { + if (str_len >= sep_len) { + machine_uint_t str_index, str_index_end; + if (direction > 0) { + str_index = 0; + str_index_end = str_len - sep_len; + } else { + str_index = str_len - sep_len; + str_index_end = 0; + } + for (;;) { + if (memcmp(&str[str_index], sep, sep_len) == 0) { + result[0] = mp_obj_new_str(str, str_index, false); + result[1] = arg; + result[2] = mp_obj_new_str(str + str_index + sep_len, str_len - str_index - sep_len, false); break; } + if (str_index == str_index_end) { + break; + } + str_index += direction; } } + return mp_obj_new_tuple(3, result); } -STATIC mp_obj_t str_partition(mp_obj_t self_in, mp_obj_t arg, bool partition) { - return str_partitioner(self_in, arg, false); +STATIC mp_obj_t str_partition(mp_obj_t self_in, mp_obj_t arg) { + return str_partitioner(self_in, arg, 1); } -STATIC mp_obj_t str_rpartition(mp_obj_t self_in, mp_obj_t arg, bool partition) { - return str_partitioner(self_in, arg, true); +STATIC mp_obj_t str_rpartition(mp_obj_t self_in, mp_obj_t arg) { + return str_partitioner(self_in, arg, -1); } STATIC machine_int_t str_get_buffer(mp_obj_t self_in, buffer_info_t *bufinfo, int flags) { -- cgit v1.2.3 From 7b4b78bc33fdb9b0007060877fd7c1ca2392bceb Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 21 Mar 2014 20:46:38 +0000 Subject: py: Put back proper ValueError for badly parsed integers. --- py/parsenum.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/py/parsenum.c b/py/parsenum.c index 6be042fe8..7be53897a 100644 --- a/py/parsenum.c +++ b/py/parsenum.c @@ -41,6 +41,7 @@ mp_obj_t mp_parse_num_integer(const char *restrict str, uint len, int base) { // string should be an integer number machine_int_t int_val = 0; + const char *restrict str_val_start = str; for (; str < top; str++) { machine_int_t old_val = int_val; int dig = *str; @@ -69,6 +70,11 @@ mp_obj_t mp_parse_num_integer(const char *restrict str, uint len, int base) { } } + // check we parsed something + if (str == str_val_start) { + goto value_error; + } + // negate value if needed if (neg) { int_val = -int_val; @@ -80,12 +86,15 @@ mp_obj_t mp_parse_num_integer(const char *restrict str, uint len, int base) { // check we reached the end of the string if (str != top) { - nlr_jump(mp_obj_new_exception_msg(&mp_type_SyntaxError, "invalid syntax for number")); + goto value_error; } // return the object return MP_OBJ_NEW_SMALL_INT(int_val); +value_error: + nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "invalid literal for int() with base %d: '%s'", base, str)); + overflow: // TODO reparse using bignum nlr_jump(mp_obj_new_exception_msg(&mp_type_ValueError, "overflow parsing integer")); -- cgit v1.2.3 From c070ff24a950cb764c8d51fa69f5a002e49fb3e4 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 21 Mar 2014 20:52:54 +0000 Subject: Disable some math functions until they work correctly. --- py/builtinmath.c | 12 ++++++------ stm/math.c | 4 ++++ stmhal/math.c | 4 ++++ 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/py/builtinmath.c b/py/builtinmath.c index fd1368ce3..59af5a021 100644 --- a/py/builtinmath.c +++ b/py/builtinmath.c @@ -46,9 +46,9 @@ MATH_FUN_1(fabs, fabs) MATH_FUN_1(floor, floor) //TODO: delegate to x.__floor__() if x is not a float MATH_FUN_2(fmod, fmod) //MATH_FUN_1(frexp, frexp) -MATH_FUN_1(isfinite, isfinite) -MATH_FUN_1(isinf, isinf) -MATH_FUN_1(isnan, isnan) +//MATH_FUN_1(isfinite, isfinite) +//MATH_FUN_1(isinf, isinf) +//MATH_FUN_1(isnan, isnan) MATH_FUN_1(trunc, trunc) //TODO: factorial, fsum, frexp, ldexp, modf @@ -83,9 +83,9 @@ STATIC const mp_map_elem_t mp_module_math_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_floor), (mp_obj_t)&mp_math_floor_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_fmod), (mp_obj_t)&mp_math_fmod_obj }, //{ MP_OBJ_NEW_QSTR(MP_QSTR_frexp), (mp_obj_t)&mp_math_frexp_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_isfinite), (mp_obj_t)&mp_math_isfinite_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_isinf), (mp_obj_t)&mp_math_isinf_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_isnan), (mp_obj_t)&mp_math_isnan_obj }, + //{ MP_OBJ_NEW_QSTR(MP_QSTR_isfinite), (mp_obj_t)&mp_math_isfinite_obj }, + //{ MP_OBJ_NEW_QSTR(MP_QSTR_isinf), (mp_obj_t)&mp_math_isinf_obj }, + //{ MP_OBJ_NEW_QSTR(MP_QSTR_isnan), (mp_obj_t)&mp_math_isnan_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_trunc), (mp_obj_t)&mp_math_trunc_obj }, }; diff --git a/stm/math.c b/stm/math.c index 8e2c6fc75..0809a3f2c 100644 --- a/stm/math.c +++ b/stm/math.c @@ -44,6 +44,10 @@ float acosf(float x) { return 0.0; } float asinf(float x) { return 0.0; } float atanf(float x) { return 0.0; } float atan2f(float x, float y) { return 0.0; } +float ceilf(float x) { return 0.0; } +float floorf(float x) { return 0.0; } +float truncf(float x) { return 0.0; } +float fmodf(float x, float y) { return 0.0; } /*****************************************************************************/ // from musl-0.9.15 libm.h diff --git a/stmhal/math.c b/stmhal/math.c index 8e2c6fc75..0809a3f2c 100644 --- a/stmhal/math.c +++ b/stmhal/math.c @@ -44,6 +44,10 @@ float acosf(float x) { return 0.0; } float asinf(float x) { return 0.0; } float atanf(float x) { return 0.0; } float atan2f(float x, float y) { return 0.0; } +float ceilf(float x) { return 0.0; } +float floorf(float x) { return 0.0; } +float truncf(float x) { return 0.0; } +float fmodf(float x, float y) { return 0.0; } /*****************************************************************************/ // from musl-0.9.15 libm.h -- cgit v1.2.3 From 42901554db49cd1204054ea695cea6ee4e368b1e Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Sat, 22 Mar 2014 00:02:32 +0200 Subject: objint_longlong: Add regression test for improper inplace op implementation. --- tests/basics/int-long.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/basics/int-long.py b/tests/basics/int-long.py index f867d8037..3567e08b2 100644 --- a/tests/basics/int-long.py +++ b/tests/basics/int-long.py @@ -37,3 +37,10 @@ a <<= 5 print(a) a >>= 1 print(a) + +# Test referential integrity of long ints +a = 0x1ffffffff +b = a +a += 1 +print(a) +print(b) -- cgit v1.2.3 From 5972b4c05ffe6973820d24161f604ae8db0d299b Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Thu, 20 Mar 2014 16:47:44 +0200 Subject: objstr: Switch from in-object string data to ptr to separate memory area. This is pre-requisite for having efficient implementation of str<->bytes conversion, and having that efficient is required with unfortunare str vs bytes dichotomy in Python3. --- py/objstr.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/py/objstr.c b/py/objstr.c index 77cefa82b..3c5cabe05 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -14,7 +14,7 @@ typedef struct _mp_obj_str_t { mp_obj_base_t base; machine_uint_t hash : 16; // XXX here we assume the hash size is 16 bits (it is at the moment; see qstr.c) machine_uint_t len : 16; // len == number of bytes used in data, alloc = len + 1 because (at the moment) we also append a null byte - byte data[]; + const byte *data; } mp_obj_str_t; // use this macro to extract the string hash @@ -636,10 +636,12 @@ const mp_obj_type_t bytes_type = { }; mp_obj_t mp_obj_str_builder_start(const mp_obj_type_t *type, uint len, byte **data) { - mp_obj_str_t *o = m_new_obj_var(mp_obj_str_t, byte, len + 1); + mp_obj_str_t *o = m_new_obj(mp_obj_str_t); o->base.type = type; o->len = len; - *data = o->data; + byte *p = m_new(byte, len + 1); + o->data = p; + *data = p; return o; } @@ -647,17 +649,22 @@ mp_obj_t mp_obj_str_builder_end(mp_obj_t o_in) { assert(MP_OBJ_IS_STR(o_in)); mp_obj_str_t *o = o_in; o->hash = qstr_compute_hash(o->data, o->len); - o->data[o->len] = '\0'; // for now we add null for compatibility with C ASCIIZ strings + byte *p = (byte*)o->data; + p[o->len] = '\0'; // for now we add null for compatibility with C ASCIIZ strings return o; } STATIC mp_obj_t str_new(const mp_obj_type_t *type, const byte* data, uint len) { - mp_obj_str_t *o = m_new_obj_var(mp_obj_str_t, byte, len + 1); + mp_obj_str_t *o = m_new_obj(mp_obj_str_t); o->base.type = type; - o->hash = qstr_compute_hash(data, len); o->len = len; - memcpy(o->data, data, len * sizeof(byte)); - o->data[len] = '\0'; // for now we add null for compatibility with C ASCIIZ strings + if (data) { + o->hash = qstr_compute_hash(data, len); + byte *p = m_new(byte, len + 1); + o->data = p; + memcpy(p, data, len * sizeof(byte)); + p[len] = '\0'; // for now we add null for compatibility with C ASCIIZ strings + } return o; } -- cgit v1.2.3 From be020c27a870feff9773c348fa04be8c54873f70 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Fri, 21 Mar 2014 11:39:01 +0200 Subject: py: Make 'str' be a proper type, support standard constructor args. --- py/builtin.c | 10 ---------- py/objstr.c | 36 ++++++++++++++++++++++++++++++++++++ py/runtime.c | 2 +- 3 files changed, 37 insertions(+), 11 deletions(-) diff --git a/py/builtin.c b/py/builtin.c index 2e0627fa5..11b86111e 100644 --- a/py/builtin.c +++ b/py/builtin.c @@ -375,16 +375,6 @@ STATIC mp_obj_t mp_builtin_sorted(uint n_args, const mp_obj_t *args, mp_map_t *k MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_sorted_obj, 1, mp_builtin_sorted); -STATIC mp_obj_t mp_builtin_str(mp_obj_t o_in) { - vstr_t *vstr = vstr_new(); - mp_obj_print_helper((void (*)(void*, const char*, ...))vstr_printf, vstr, o_in, PRINT_STR); - mp_obj_t s = mp_obj_new_str((byte*)vstr->buf, vstr->len, false); - vstr_free(vstr); - return s; -} - -MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_str_obj, mp_builtin_str); - // TODO: This should be type, this is just quick CPython compat hack STATIC mp_obj_t mp_builtin_bytes(uint n_args, const mp_obj_t *args) { if (!MP_OBJ_IS_QSTR(args[0]) && !MP_OBJ_IS_TYPE(args[0], &str_type)) { diff --git a/py/objstr.c b/py/objstr.c index 3c5cabe05..44e84d709 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -28,6 +28,7 @@ typedef struct _mp_obj_str_t { STATIC mp_obj_t mp_obj_new_str_iterator(mp_obj_t str); STATIC mp_obj_t mp_obj_new_bytes_iterator(mp_obj_t str); +STATIC mp_obj_t str_new(const mp_obj_type_t *type, const byte* data, uint len); /******************************************************************************/ /* str */ @@ -78,6 +79,40 @@ STATIC void str_print(void (*print)(void *env, const char *fmt, ...), void *env, } } +STATIC mp_obj_t str_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) { + switch (n_args) { + case 0: + return MP_OBJ_NEW_QSTR(MP_QSTR_); + + case 1: + { + vstr_t *vstr = vstr_new(); + mp_obj_print_helper((void (*)(void*, const char*, ...))vstr_printf, vstr, args[0], PRINT_STR); + mp_obj_t s = mp_obj_new_str((byte*)vstr->buf, vstr->len, false); + vstr_free(vstr); + return s; + } + + case 2: + case 3: + { + // TODO: validate 2nd/3rd args + if (!MP_OBJ_IS_TYPE(args[0], &bytes_type)) { + nlr_jump(mp_obj_new_exception_msg(&mp_type_TypeError, "bytes expected")); + } + GET_STR_DATA_LEN(args[0], str_data, str_len); + GET_STR_HASH(args[0], str_hash); + mp_obj_str_t *o = str_new(&str_type, NULL, str_len); + o->data = str_data; + o->hash = str_hash; + return o; + } + + default: + nlr_jump(mp_obj_new_exception_msg(&mp_type_TypeError, "str takes at most 3 arguments")); + } +} + // like strstr but with specified length and allows \0 bytes // TODO replace with something more efficient/standard STATIC const byte *find_subbytes(const byte *haystack, uint hlen, const byte *needle, uint nlen) { @@ -619,6 +654,7 @@ const mp_obj_type_t str_type = { { &mp_type_type }, .name = MP_QSTR_str, .print = str_print, + .make_new = str_make_new, .binary_op = str_binary_op, .getiter = mp_obj_new_str_iterator, .methods = str_type_methods, diff --git a/py/runtime.c b/py/runtime.c index c268fd546..2ab97ed18 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -102,6 +102,7 @@ STATIC const mp_builtin_elem_t builtin_table[] = { { MP_QSTR_list, (mp_obj_t)&list_type }, { MP_QSTR_map, (mp_obj_t)&map_type }, { MP_QSTR_set, (mp_obj_t)&set_type }, + { MP_QSTR_str, (mp_obj_t)&str_type }, { MP_QSTR_super, (mp_obj_t)&super_type }, { MP_QSTR_tuple, (mp_obj_t)&tuple_type }, { MP_QSTR_type, (mp_obj_t)&mp_type_type }, @@ -137,7 +138,6 @@ STATIC const mp_builtin_elem_t builtin_table[] = { { MP_QSTR_repr, (mp_obj_t)&mp_builtin_repr_obj }, { MP_QSTR_sorted, (mp_obj_t)&mp_builtin_sorted_obj }, { MP_QSTR_sum, (mp_obj_t)&mp_builtin_sum_obj }, - { MP_QSTR_str, (mp_obj_t)&mp_builtin_str_obj }, { MP_QSTR_bytearray, (mp_obj_t)&mp_builtin_bytearray_obj }, // built-in exceptions -- cgit v1.2.3 From 1ecea7c7539e73f105fef25da8a3bde7783da755 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Fri, 21 Mar 2014 23:46:59 +0200 Subject: py: Make 'bytes' be a proper type, support standard constructor args. --- py/builtin.c | 12 -------- py/objstr.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++- py/runtime.c | 2 +- tests/basics/bytes.py | 28 +++++++++++++++++++ 4 files changed, 105 insertions(+), 14 deletions(-) diff --git a/py/builtin.c b/py/builtin.c index 11b86111e..93e91072c 100644 --- a/py/builtin.c +++ b/py/builtin.c @@ -375,18 +375,6 @@ STATIC mp_obj_t mp_builtin_sorted(uint n_args, const mp_obj_t *args, mp_map_t *k MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_sorted_obj, 1, mp_builtin_sorted); -// TODO: This should be type, this is just quick CPython compat hack -STATIC mp_obj_t mp_builtin_bytes(uint n_args, const mp_obj_t *args) { - if (!MP_OBJ_IS_QSTR(args[0]) && !MP_OBJ_IS_TYPE(args[0], &str_type)) { - assert(0); - } - // Currently, MicroPython strings are mix between CPython byte and unicode - // strings. So, conversion is null so far. - return args[0]; -} - -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_bytes_obj, 1, 3, mp_builtin_bytes); - STATIC mp_obj_t mp_builtin_id(mp_obj_t o_in) { return mp_obj_new_int((machine_int_t)o_in); } diff --git a/py/objstr.c b/py/objstr.c index 44e84d709..35a948700 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -17,6 +17,8 @@ typedef struct _mp_obj_str_t { const byte *data; } mp_obj_str_t; +const mp_obj_t mp_const_empty_bytes; + // use this macro to extract the string hash #define GET_STR_HASH(str_obj_in, str_hash) uint str_hash; if (MP_OBJ_IS_QSTR(str_obj_in)) { str_hash = qstr_hash(MP_OBJ_QSTR_VALUE(str_obj_in)); } else { str_hash = ((mp_obj_str_t*)str_obj_in)->hash; } @@ -113,6 +115,75 @@ STATIC mp_obj_t str_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_ } } +STATIC mp_obj_t bytes_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) { + if (n_args == 0) { + return mp_const_empty_bytes; + } + + if (MP_OBJ_IS_STR(args[0])) { + if (n_args < 2 || n_args > 3) { + goto wrong_args; + } + GET_STR_DATA_LEN(args[0], str_data, str_len); + GET_STR_HASH(args[0], str_hash); + mp_obj_str_t *o = str_new(&bytes_type, NULL, str_len); + o->data = str_data; + o->hash = str_hash; + return o; + } + + if (n_args > 1) { + goto wrong_args; + } + + if (MP_OBJ_IS_SMALL_INT(args[0])) { + uint len = MP_OBJ_SMALL_INT_VALUE(args[0]); + byte *data; + + mp_obj_t o = mp_obj_str_builder_start(&bytes_type, len, &data); + memset(data, 0, len); + return mp_obj_str_builder_end(o); + } + + int len; + byte *data; + vstr_t *vstr = NULL; + mp_obj_t o = NULL; + // Try to create array of exact len if initializer len is known + mp_obj_t len_in = mp_obj_len_maybe(args[0]); + if (len_in == MP_OBJ_NULL) { + len = -1; + vstr = vstr_new(); + } else { + len = MP_OBJ_SMALL_INT_VALUE(len_in); + o = mp_obj_str_builder_start(&bytes_type, len, &data); + } + + mp_obj_t iterable = rt_getiter(args[0]); + mp_obj_t item; + while ((item = rt_iternext(iterable)) != mp_const_stop_iteration) { + if (len == -1) { + vstr_add_char(vstr, MP_OBJ_SMALL_INT_VALUE(item)); + } else { + *data++ = MP_OBJ_SMALL_INT_VALUE(item); + } + } + + if (len == -1) { + vstr_shrink(vstr); + // TODO: Optimize, borrow buffer from vstr + len = vstr_len(vstr); + o = mp_obj_str_builder_start(&bytes_type, len, &data); + memcpy(data, vstr_str(vstr), len); + vstr_free(vstr); + } + + return mp_obj_str_builder_end(o); + +wrong_args: + nlr_jump(mp_obj_new_exception_msg(&mp_type_TypeError, "wrong number of arguments")); +} + // like strstr but with specified length and allows \0 bytes // TODO replace with something more efficient/standard STATIC const byte *find_subbytes(const byte *haystack, uint hlen, const byte *needle, uint nlen) { @@ -666,11 +737,16 @@ const mp_obj_type_t bytes_type = { { &mp_type_type }, .name = MP_QSTR_bytes, .print = str_print, + .make_new = bytes_make_new, .binary_op = str_binary_op, .getiter = mp_obj_new_bytes_iterator, .methods = str_type_methods, }; +// the zero-length bytes +STATIC const mp_obj_str_t empty_bytes_obj = {{&bytes_type}, 0, 0, NULL}; +const mp_obj_t mp_const_empty_bytes = (mp_obj_t)&empty_bytes_obj; + mp_obj_t mp_obj_str_builder_start(const mp_obj_type_t *type, uint len, byte **data) { mp_obj_str_t *o = m_new_obj(mp_obj_str_t); o->base.type = type; @@ -682,7 +758,6 @@ mp_obj_t mp_obj_str_builder_start(const mp_obj_type_t *type, uint len, byte **da } mp_obj_t mp_obj_str_builder_end(mp_obj_t o_in) { - assert(MP_OBJ_IS_STR(o_in)); mp_obj_str_t *o = o_in; o->hash = qstr_compute_hash(o->data, o->len); byte *p = (byte*)o->data; diff --git a/py/runtime.c b/py/runtime.c index 2ab97ed18..4bcb91c54 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -89,6 +89,7 @@ STATIC const mp_builtin_elem_t builtin_table[] = { // built-in types { MP_QSTR_bool, (mp_obj_t)&bool_type }, + { MP_QSTR_bytes, (mp_obj_t)&bytes_type }, #if MICROPY_ENABLE_FLOAT { MP_QSTR_complex, (mp_obj_t)&mp_type_complex }, #endif @@ -115,7 +116,6 @@ STATIC const mp_builtin_elem_t builtin_table[] = { { MP_QSTR_abs, (mp_obj_t)&mp_builtin_abs_obj }, { MP_QSTR_all, (mp_obj_t)&mp_builtin_all_obj }, { MP_QSTR_any, (mp_obj_t)&mp_builtin_any_obj }, - { MP_QSTR_bytes, (mp_obj_t)&mp_builtin_bytes_obj }, { MP_QSTR_callable, (mp_obj_t)&mp_builtin_callable_obj }, { MP_QSTR_chr, (mp_obj_t)&mp_builtin_chr_obj }, { MP_QSTR_dir, (mp_obj_t)&mp_builtin_dir_obj }, diff --git a/tests/basics/bytes.py b/tests/basics/bytes.py index 7d0cf22d4..a084bc399 100644 --- a/tests/basics/bytes.py +++ b/tests/basics/bytes.py @@ -4,8 +4,36 @@ print(str(a)) print(repr(a)) print(a[0], a[2]) print(a[-1]) +print(str(a, "utf-8")) +print(str(a, "utf-8", "ignore")) +try: + str(a, "utf-8", "ignore", "toomuch") +except TypeError: + print("TypeError") s = 0 for i in a: s += i print(s) + + +print(bytes("abc", "utf-8")) +print(bytes("abc", "utf-8", "replace")) +try: + bytes("abc") +except TypeError: + print("TypeError") +try: + bytes("abc", "utf-8", "replace", "toomuch") +except TypeError: + print("TypeError") + +print(bytes(3)) + +print(bytes([3, 2, 1])) +print(bytes(range(5))) + +def gen(): + for i in range(4): + yield i +print(bytes(gen())) -- cgit v1.2.3 From 8913c04831c94d2bcb82b0447ab7ccf6b2e346a6 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 21 Mar 2014 23:32:01 +0000 Subject: stmhal: Add support for USB MSC device. This gives a functioning, independent MSC device. --- stmhal/Makefile | 10 +- stmhal/main.c | 10 +- stmhal/usb.c | 30 +- stmhal/usb.h | 14 +- stmhal/usbd_conf.h | 3 + stmhal/usbd_desc.c | 228 ------ stmhal/usbd_desc.h | 45 +- stmhal/usbd_desc_msc.c | 227 ++++++ stmhal/usbd_desc_vcp.c | 228 ++++++ stmhal/usbd_msc_storage.c | 320 +++++++++ stmhal/usbd_msc_storage.h | 2 + stmhal/usbdev/class/MSC/Inc/usbd_msc.h | 121 ---- stmhal/usbdev/class/MSC/Inc/usbd_msc_bot.h | 151 ---- stmhal/usbdev/class/MSC/Inc/usbd_msc_data.h | 104 --- stmhal/usbdev/class/MSC/Inc/usbd_msc_scsi.h | 193 ------ .../class/MSC/Inc/usbd_msc_storage_template.h | 98 --- stmhal/usbdev/class/MSC/Src/usbd_msc.c | 609 ---------------- stmhal/usbdev/class/MSC/Src/usbd_msc_bot.c | 407 ----------- stmhal/usbdev/class/MSC/Src/usbd_msc_data.c | 134 ---- stmhal/usbdev/class/MSC/Src/usbd_msc_scsi.c | 770 --------------------- .../class/MSC/Src/usbd_msc_storage_template.c | 188 ----- stmhal/usbdev/class/msc/inc/usbd_msc.h | 121 ++++ stmhal/usbdev/class/msc/inc/usbd_msc_bot.h | 151 ++++ stmhal/usbdev/class/msc/inc/usbd_msc_data.h | 104 +++ stmhal/usbdev/class/msc/inc/usbd_msc_scsi.h | 193 ++++++ .../class/msc/inc/usbd_msc_storage_template.h | 98 +++ stmhal/usbdev/class/msc/src/usbd_msc.c | 609 ++++++++++++++++ stmhal/usbdev/class/msc/src/usbd_msc_bot.c | 407 +++++++++++ stmhal/usbdev/class/msc/src/usbd_msc_data.c | 134 ++++ stmhal/usbdev/class/msc/src/usbd_msc_scsi.c | 770 +++++++++++++++++++++ .../class/msc/src/usbd_msc_storage_template.c | 188 +++++ 31 files changed, 3602 insertions(+), 3065 deletions(-) delete mode 100644 stmhal/usbd_desc.c create mode 100644 stmhal/usbd_desc_msc.c create mode 100644 stmhal/usbd_desc_vcp.c create mode 100644 stmhal/usbd_msc_storage.c create mode 100644 stmhal/usbd_msc_storage.h delete mode 100644 stmhal/usbdev/class/MSC/Inc/usbd_msc.h delete mode 100644 stmhal/usbdev/class/MSC/Inc/usbd_msc_bot.h delete mode 100644 stmhal/usbdev/class/MSC/Inc/usbd_msc_data.h delete mode 100644 stmhal/usbdev/class/MSC/Inc/usbd_msc_scsi.h delete mode 100644 stmhal/usbdev/class/MSC/Inc/usbd_msc_storage_template.h delete mode 100644 stmhal/usbdev/class/MSC/Src/usbd_msc.c delete mode 100644 stmhal/usbdev/class/MSC/Src/usbd_msc_bot.c delete mode 100644 stmhal/usbdev/class/MSC/Src/usbd_msc_data.c delete mode 100644 stmhal/usbdev/class/MSC/Src/usbd_msc_scsi.c delete mode 100644 stmhal/usbdev/class/MSC/Src/usbd_msc_storage_template.c create mode 100644 stmhal/usbdev/class/msc/inc/usbd_msc.h create mode 100644 stmhal/usbdev/class/msc/inc/usbd_msc_bot.h create mode 100644 stmhal/usbdev/class/msc/inc/usbd_msc_data.h create mode 100644 stmhal/usbdev/class/msc/inc/usbd_msc_scsi.h create mode 100644 stmhal/usbdev/class/msc/inc/usbd_msc_storage_template.h create mode 100644 stmhal/usbdev/class/msc/src/usbd_msc.c create mode 100644 stmhal/usbdev/class/msc/src/usbd_msc_bot.c create mode 100644 stmhal/usbdev/class/msc/src/usbd_msc_data.c create mode 100644 stmhal/usbdev/class/msc/src/usbd_msc_scsi.c create mode 100644 stmhal/usbdev/class/msc/src/usbd_msc_storage_template.c diff --git a/stmhal/Makefile b/stmhal/Makefile index a1a5a1db6..86791607a 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 +INC += -I$(USBDEV_DIR)/core/inc -I$(USBDEV_DIR)/class/cdc/inc -I$(USBDEV_DIR)/class/msc/inc #INC += -I$(USBHOST_DIR) INC += -I$(FATFS_DIR)/src #INC += -I$(CC3K_DIR) @@ -56,8 +56,10 @@ SRC_C = \ stm32f4xx_it.c \ stm32f4xx_hal_msp.c \ usbd_conf.c \ - usbd_desc.c \ + usbd_desc_vcp.c \ usbd_cdc_interface.c \ + usbd_desc_msc.c \ + usbd_msc_storage.c \ pendsv.c \ systick.c \ led.c \ @@ -123,6 +125,10 @@ SRC_USBDEV = $(addprefix $(USBDEV_DIR)/,\ 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 \ ) # usbd_core.c \ diff --git a/stmhal/main.c b/stmhal/main.c index 522ebfa6b..d92ccdd5b 100644 --- a/stmhal/main.c +++ b/stmhal/main.c @@ -374,6 +374,10 @@ soft_reset: // turn boot-up LED off led_state(PYB_LED_GREEN, 0); +#if defined(USE_DEVICE_MODE) + usbd_storage_medium_kind_t usbd_medium_kind = USBD_STORAGE_MEDIUM_FLASH; +#endif + #if MICROPY_HW_HAS_SDCARD // if an SD card is present then mount it on 1:/ if (sdcard_is_present()) { @@ -383,8 +387,8 @@ soft_reset: } else { if (first_soft_reset) { // use SD card as medium for the USB MSD -#if 0 - usbd_storage_select_medium(USBD_STORAGE_MEDIUM_SDCARD); +#if defined(USE_DEVICE_MODE) + usbd_medium_kind = USBD_STORAGE_MEDIUM_SDCARD; #endif } } @@ -396,7 +400,7 @@ soft_reset: pyb_usb_host_init(); #elif defined(USE_DEVICE_MODE) // USB device - pyb_usb_dev_init(PYB_USB_DEV_VCP_MSC); + pyb_usb_dev_init(USBD_DEVICE_MSC, usbd_medium_kind); #endif #if MICROPY_HW_HAS_MMA7660 diff --git a/stmhal/usb.c b/stmhal/usb.c index 5cf7b5f32..c14a5ad68 100644 --- a/stmhal/usb.c +++ b/stmhal/usb.c @@ -1,21 +1,16 @@ #include -/* -#include "usb_core.h" -#include "usbd_cdc_core.h" -#include "usbd_pyb_core.h" -#include "usbd_usr.h" -*/ #include "usbd_core.h" #include "usbd_desc.h" #include "usbd_cdc.h" #include "usbd_cdc_interface.h" +#include "usbd_msc.h" +#include "usbd_msc_storage.h" #include "misc.h" #include "mpconfig.h" #include "qstr.h" #include "obj.h" -//#include "pendsv.h" #include "usb.h" #ifdef USE_DEVICE_MODE @@ -26,12 +21,12 @@ 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(int usb_dev_type) { +void pyb_usb_dev_init(usbd_device_kind_t device_kind, usbd_storage_medium_kind_t medium_kind) { #ifdef USE_DEVICE_MODE if (!dev_is_enabled) { // only init USB once in the device's power-lifetime - switch (usb_dev_type) { - case PYB_USB_DEV_VCP_MSC: + 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). USBD_Init(&hUSBDDevice, &VCP_Desc, 0); @@ -41,7 +36,20 @@ void pyb_usb_dev_init(int usb_dev_type) { //USBD_Init(&USB_OTG_Core, USB_OTG_FS_CORE_ID, &USR_desc, &USBD_PYB_cb, &USR_cb); break; - case PYB_USB_DEV_HID: + 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 { + USBD_MSC_RegisterStorage(&hUSBDDevice, (USBD_StorageTypeDef*)&USBD_SDCARD_STORAGE_fops); + } + USBD_Start(&hUSBDDevice); + break; + + case USBD_DEVICE_HID: //USBD_Init(&USB_OTG_Core, USB_OTG_FS_CORE_ID, &USR_desc, &USBD_PYB_HID_cb, &USR_cb); // TODO break; diff --git a/stmhal/usb.h b/stmhal/usb.h index 3e6bdccec..bb6283c89 100644 --- a/stmhal/usb.h +++ b/stmhal/usb.h @@ -4,10 +4,18 @@ #define VCP_CHAR_CTRL_C (3) #define VCP_CHAR_CTRL_D (4) -#define PYB_USB_DEV_VCP_MSC (0) -#define PYB_USB_DEV_HID (1) +typedef enum { + USBD_DEVICE_CDC, + USBD_DEVICE_MSC, + USBD_DEVICE_HID, +} usbd_device_kind_t; -void pyb_usb_dev_init(int usb_dev_type); +typedef enum { + USBD_STORAGE_MEDIUM_FLASH, + USBD_STORAGE_MEDIUM_SDCARD, +} usbd_storage_medium_kind_t; + +void pyb_usb_dev_init(usbd_device_kind_t device_kind, usbd_storage_medium_kind_t medium_kind); bool usb_vcp_is_enabled(void); bool usb_vcp_is_connected(void); void usb_vcp_set_interrupt_char(int c); diff --git a/stmhal/usbd_conf.h b/stmhal/usbd_conf.h index 8c02ad0ec..cc3ad73f9 100644 --- a/stmhal/usbd_conf.h +++ b/stmhal/usbd_conf.h @@ -48,6 +48,9 @@ #define USBD_SELF_POWERED 0 #define USBD_DEBUG_LEVEL 0 +// for MSC device +#define MSC_MEDIA_PACKET 8192 + /* Exported macro ------------------------------------------------------------*/ /* Memory management macros */ #define USBD_malloc gc_alloc diff --git a/stmhal/usbd_desc.c b/stmhal/usbd_desc.c deleted file mode 100644 index ca9ea487d..000000000 --- a/stmhal/usbd_desc.c +++ /dev/null @@ -1,228 +0,0 @@ -/** - ****************************************************************************** - * @file USB_Device/CDC_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 - * - *

© COPYRIGHT(c) 2014 STMicroelectronics

- * - * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); - * You may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.st.com/software_license_agreement_liberty_v2 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_core.h" -#include "usbd_desc.h" -#include "usbd_conf.h" - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -#define USBD_VID 0x0483 -#define USBD_PID 0x5740 -#define USBD_LANGID_STRING 0x409 -#define USBD_MANUFACTURER_STRING "STMicroelectronics" -#define USBD_PRODUCT_HS_STRING "STM32 Virtual ComPort in HS Mode" -#define USBD_SERIALNUMBER_HS_STRING "00000000001A" -#define USBD_PRODUCT_FS_STRING "STM32 Virtual ComPort in FS Mode" -#define USBD_SERIALNUMBER_FS_STRING "00000000001B" -#define USBD_CONFIGURATION_HS_STRING "VCP Config" -#define USBD_INTERFACE_HS_STRING "VCP Interface" -#define USBD_CONFIGURATION_FS_STRING "VCP Config" -#define USBD_INTERFACE_FS_STRING "VCP Interface" - -/* Private macro -------------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -uint8_t *USBD_VCP_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); -uint8_t *USBD_VCP_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); -uint8_t *USBD_VCP_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); -uint8_t *USBD_VCP_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); -uint8_t *USBD_VCP_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); -uint8_t *USBD_VCP_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); -uint8_t *USBD_VCP_InterfaceStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); -#ifdef USB_SUPPORT_USER_STRING_DESC -uint8_t *USBD_VCP_USRStringDesc (USBD_SpeedTypeDef speed, uint8_t idx, uint16_t *length); -#endif /* USB_SUPPORT_USER_STRING_DESC */ - -/* Private variables ---------------------------------------------------------*/ -USBD_DescriptorsTypeDef VCP_Desc = { - USBD_VCP_DeviceDescriptor, - USBD_VCP_LangIDStrDescriptor, - USBD_VCP_ManufacturerStrDescriptor, - USBD_VCP_ProductStrDescriptor, - USBD_VCP_SerialStrDescriptor, - USBD_VCP_ConfigStrDescriptor, - USBD_VCP_InterfaceStrDescriptor, -}; - -/* USB Standard Device Descriptor */ -#if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 -#endif -__ALIGN_BEGIN uint8_t hUSBDDeviceDesc[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 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 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_VCP_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) -{ - *length = sizeof(hUSBDDeviceDesc); - return hUSBDDeviceDesc; -} - -/** - * @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_VCP_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_VCP_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) -{ - if(speed == 0) - { - USBD_GetString((uint8_t *)USBD_PRODUCT_HS_STRING, USBD_StrDesc, length); - } - else - { - USBD_GetString((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_VCP_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) -{ - USBD_GetString((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_VCP_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) -{ - if(speed == USBD_SPEED_HIGH) - { - USBD_GetString((uint8_t *)USBD_SERIALNUMBER_HS_STRING, USBD_StrDesc, length); - } - else - { - USBD_GetString((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_VCP_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) -{ - if(speed == USBD_SPEED_HIGH) - { - USBD_GetString((uint8_t *)USBD_CONFIGURATION_HS_STRING, USBD_StrDesc, length); - } - else - { - USBD_GetString((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_VCP_InterfaceStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) -{ - if(speed == 0) - { - USBD_GetString((uint8_t *)USBD_INTERFACE_HS_STRING, USBD_StrDesc, length); - } - else - { - USBD_GetString((uint8_t *)USBD_INTERFACE_FS_STRING, USBD_StrDesc, length); - } - return USBD_StrDesc; -} - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ - diff --git a/stmhal/usbd_desc.h b/stmhal/usbd_desc.h index 8b2d8f103..a54e427e3 100644 --- a/stmhal/usbd_desc.h +++ b/stmhal/usbd_desc.h @@ -1,43 +1,2 @@ -/** - ****************************************************************************** - * @file USB_Device/CDC_Standalone/Inc/usbd_desc.h - * @author MCD Application Team - * @version V1.0.1 - * @date 26-February-2014 - * @brief Header for usbd_desc.c module - ****************************************************************************** - * @attention - * - *

© COPYRIGHT(c) 2014 STMicroelectronics

- * - * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); - * You may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.st.com/software_license_agreement_liberty_v2 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USBD_DESC_H -#define __USBD_DESC_H - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_def.h" - -/* Exported types ------------------------------------------------------------*/ -/* Exported constants --------------------------------------------------------*/ -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ -extern USBD_DescriptorsTypeDef VCP_Desc; - -#endif /* __USBD_DESC_H */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +extern USBD_DescriptorsTypeDef VCP_Desc; +extern USBD_DescriptorsTypeDef MSC_Desc; diff --git a/stmhal/usbd_desc_msc.c b/stmhal/usbd_desc_msc.c new file mode 100644 index 000000000..7d0911e82 --- /dev/null +++ b/stmhal/usbd_desc_msc.c @@ -0,0 +1,227 @@ +/** + ****************************************************************************** + * @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 + * + *

© COPYRIGHT(c) 2014 STMicroelectronics

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

© COPYRIGHT(c) 2014 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_core.h" +#include "usbd_desc.h" +#include "usbd_conf.h" + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +#define USBD_VID 0x0483 +#define USBD_PID 0x5740 +#define USBD_LANGID_STRING 0x409 +#define USBD_MANUFACTURER_STRING "STMicroelectronics" +#define USBD_PRODUCT_HS_STRING "STM32 Virtual ComPort in HS Mode" +#define USBD_SERIALNUMBER_HS_STRING "00000000001A" +#define USBD_PRODUCT_FS_STRING "STM32 Virtual ComPort in FS Mode" +#define USBD_SERIALNUMBER_FS_STRING "00000000001B" +#define USBD_CONFIGURATION_HS_STRING "VCP Config" +#define USBD_INTERFACE_HS_STRING "VCP Interface" +#define USBD_CONFIGURATION_FS_STRING "VCP Config" +#define USBD_INTERFACE_FS_STRING "VCP Interface" + +/* Private macro -------------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +uint8_t *USBD_VCP_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); +uint8_t *USBD_VCP_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); +uint8_t *USBD_VCP_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); +uint8_t *USBD_VCP_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); +uint8_t *USBD_VCP_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); +uint8_t *USBD_VCP_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); +uint8_t *USBD_VCP_InterfaceStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); +#ifdef USB_SUPPORT_USER_STRING_DESC +uint8_t *USBD_VCP_USRStringDesc (USBD_SpeedTypeDef speed, uint8_t idx, uint16_t *length); +#endif /* USB_SUPPORT_USER_STRING_DESC */ + +/* Private variables ---------------------------------------------------------*/ +USBD_DescriptorsTypeDef VCP_Desc = { + USBD_VCP_DeviceDescriptor, + USBD_VCP_LangIDStrDescriptor, + USBD_VCP_ManufacturerStrDescriptor, + USBD_VCP_ProductStrDescriptor, + USBD_VCP_SerialStrDescriptor, + USBD_VCP_ConfigStrDescriptor, + USBD_VCP_InterfaceStrDescriptor, +}; + +/* USB Standard Device Descriptor */ +#if defined ( __ICCARM__ ) /*!< IAR Compiler */ + #pragma data_alignment=4 +#endif +__ALIGN_BEGIN static uint8_t hUSBDDeviceDesc[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_VCP_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) +{ + *length = sizeof(hUSBDDeviceDesc); + return hUSBDDeviceDesc; +} + +/** + * @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_VCP_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_VCP_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) +{ + if(speed == 0) + { + USBD_GetString((uint8_t *)USBD_PRODUCT_HS_STRING, USBD_StrDesc, length); + } + else + { + USBD_GetString((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_VCP_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) +{ + USBD_GetString((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_VCP_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) +{ + if(speed == USBD_SPEED_HIGH) + { + USBD_GetString((uint8_t *)USBD_SERIALNUMBER_HS_STRING, USBD_StrDesc, length); + } + else + { + USBD_GetString((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_VCP_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) +{ + if(speed == USBD_SPEED_HIGH) + { + USBD_GetString((uint8_t *)USBD_CONFIGURATION_HS_STRING, USBD_StrDesc, length); + } + else + { + USBD_GetString((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_VCP_InterfaceStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) +{ + if(speed == 0) + { + USBD_GetString((uint8_t *)USBD_INTERFACE_HS_STRING, USBD_StrDesc, length); + } + else + { + USBD_GetString((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 new file mode 100644 index 000000000..e5c75e27c --- /dev/null +++ b/stmhal/usbd_msc_storage.c @@ -0,0 +1,320 @@ +/** + ****************************************************************************** + * @file usbd_storage_msd.c + * @author MCD application Team + * @version V1.1.0 + * @date 19-March-2012 + * @brief This file provides the disk operations functions. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2012 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Heavily modified by dpgeorge for Micro Python. + * + ****************************************************************************** + */ + +#include "usbd_msc.h" +#include "usbd_msc_storage.h" + +#include "misc.h" +#include "storage.h" +#include "diskio.h" +#include "sdcard.h" + +/******************************************************************************/ +// Callback functions for when the internal flash is the mass storage device + +static const int8_t FLASH_STORAGE_Inquirydata[] = { // 36 bytes + // LUN 0 + 0x00, + 0x00, // 0x00 for a fixed drive, 0x80 for a removable drive + 0x02, + 0x02, + (STANDARD_INQUIRY_DATA_LEN - 5), + 0x00, + 0x00, + 0x00, + 'u', 'P', 'y', ' ', ' ', ' ', ' ', ' ', // Manufacturer : 8 bytes + 'm', 'i', 'c', 'r', 'o', 'S', 'D', ' ', // Product : 16 Bytes + 'F', 'l', 'a', 's', 'h', ' ', ' ', ' ', + '1', '.', '0' ,'0', // Version : 4 Bytes +}; + +/** + * @brief Initialize the storage medium + * @param lun : logical unit number + * @retval Status + */ +int8_t FLASH_STORAGE_Init(uint8_t lun) { + storage_init(); + return 0; +} + +/** + * @brief return medium capacity and block size + * @param lun : logical unit number + * @param block_num : number of physical block + * @param block_size : size of a physical block + * @retval Status + */ +int8_t FLASH_STORAGE_GetCapacity(uint8_t lun, uint32_t *block_num, uint16_t *block_size) { + *block_size = storage_get_block_size(); + *block_num = storage_get_block_count(); + return 0; +} + +/** + * @brief check whether the medium is ready + * @param lun : logical unit number + * @retval Status + */ +int8_t FLASH_STORAGE_IsReady(uint8_t lun) { + return 0; +} + +/** + * @brief check whether the medium is write-protected + * @param lun : logical unit number + * @retval Status + */ +int8_t FLASH_STORAGE_IsWriteProtected(uint8_t lun) { + return 0; +} + +/** + * @brief Read data from the medium + * @param lun : logical unit number + * @param buf : Pointer to the buffer to save data + * @param blk_addr : address of 1st block to be read + * @param blk_len : nmber of blocks to be read + * @retval Status + */ +int8_t FLASH_STORAGE_Read(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len) { + disk_read(0, buf, blk_addr, blk_len); + /* + for (int i = 0; i < blk_len; i++) { + if (!storage_read_block(buf + i * FLASH_BLOCK_SIZE, blk_addr + i)) { + return -1; + } + } + */ + return 0; +} + +/** + * @brief Write data to the medium + * @param lun : logical unit number + * @param buf : Pointer to the buffer to write from + * @param blk_addr : address of 1st block to be written + * @param blk_len : nmber of blocks to be read + * @retval Status + */ +int8_t FLASH_STORAGE_Write (uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len) { + disk_write(0, buf, blk_addr, blk_len); + /* + for (int i = 0; i < blk_len; i++) { + if (!storage_write_block(buf + i * FLASH_BLOCK_SIZE, blk_addr + i)) { + return -1; + } + } + */ + storage_flush(); // XXX hack for now so that the cache is always flushed + return 0; +} + +/** + * @brief Return number of supported logical unit + * @param None + * @retval number of logical unit + */ +int8_t FLASH_STORAGE_GetMaxLun(void) { + return 0; +} + +const USBD_StorageTypeDef USBD_FLASH_STORAGE_fops = { + FLASH_STORAGE_Init, + FLASH_STORAGE_GetCapacity, + FLASH_STORAGE_IsReady, + FLASH_STORAGE_IsWriteProtected, + FLASH_STORAGE_Read, + FLASH_STORAGE_Write, + FLASH_STORAGE_GetMaxLun, + (int8_t *)FLASH_STORAGE_Inquirydata, +}; + +/******************************************************************************/ +// Callback functions for when the SD card is the mass storage device + +static const int8_t SDCARD_STORAGE_Inquirydata[] = { // 36 bytes + // LUN 0 + 0x00, + 0x80, // 0x00 for a fixed drive, 0x80 for a removable drive + 0x02, + 0x02, + (STANDARD_INQUIRY_DATA_LEN - 5), + 0x00, + 0x00, + 0x00, + 'u', 'P', 'y', ' ', ' ', ' ', ' ', ' ', // Manufacturer : 8 bytes + 'm', 'i', 'c', 'r', 'o', 'S', 'D', ' ', // Product : 16 Bytes + 'S', 'D', ' ', 'c', 'a', 'r', 'd', ' ', + '1', '.', '0' ,'0', // Version : 4 Bytes +}; + +/** + * @brief Initialize the storage medium + * @param lun : logical unit number + * @retval Status + */ +int8_t SDCARD_STORAGE_Init(uint8_t lun) { + /* +#ifndef USE_STM3210C_EVAL + NVIC_InitTypeDef NVIC_InitStructure; + NVIC_InitStructure.NVIC_IRQChannel = SDIO_IRQn; + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =0; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&NVIC_InitStructure); +#endif + if( SD_Init() != 0) + { + return (-1); + } + */ + if (!sdcard_power_on()) { + return -1; + } + + return 0; + +} + +/** + * @brief return medium capacity and block size + * @param lun : logical unit number + * @param block_num : number of physical block + * @param block_size : size of a physical block + * @retval Status + */ +int8_t SDCARD_STORAGE_GetCapacity(uint8_t lun, uint32_t *block_num, uint16_t *block_size) { +/* +#ifdef USE_STM3210C_EVAL + SD_CardInfo SDCardInfo; + SD_GetCardInfo(&SDCardInfo); +#else + if(SD_GetStatus() != 0 ) { + return (-1); + } +#endif + */ + + *block_size = SDCARD_BLOCK_SIZE; + *block_num = sdcard_get_capacity_in_bytes() / SDCARD_BLOCK_SIZE; + + return 0; +} + +/** + * @brief check whether the medium is ready + * @param lun : logical unit number + * @retval Status + */ +int8_t SDCARD_STORAGE_IsReady(uint8_t lun) { + /* +#ifndef USE_STM3210C_EVAL + + static int8_t last_status = 0; + + if(last_status < 0) + { + SD_Init(); + last_status = 0; + } + + if(SD_GetStatus() != 0) + { + last_status = -1; + return (-1); + } +#else + if( SD_Init() != 0) + { + return (-1); + } +#endif +*/ + return 0; +} + +/** + * @brief check whether the medium is write-protected + * @param lun : logical unit number + * @retval Status + */ +int8_t SDCARD_STORAGE_IsWriteProtected(uint8_t lun) { + return 0; +} + +/** + * @brief Read data from the medium + * @param lun : logical unit number + * @param buf : Pointer to the buffer to save data + * @param blk_addr : address of 1st block to be read + * @param blk_len : nmber of blocks to be read + * @retval Status + */ +int8_t SDCARD_STORAGE_Read(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len) { + if (!sdcard_read_blocks(buf, blk_addr, blk_len)) { + return -1; + } + return 0; +} + +/** + * @brief Write data to the medium + * @param lun : logical unit number + * @param buf : Pointer to the buffer to write from + * @param blk_addr : address of 1st block to be written + * @param blk_len : nmber of blocks to be read + * @retval Status + */ +int8_t SDCARD_STORAGE_Write(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len) { + if (!sdcard_write_blocks(buf, blk_addr, blk_len)) { + return -1; + } + return 0; +} + +/** + * @brief Return number of supported logical unit + * @param None + * @retval number of logical unit + */ +int8_t SDCARD_STORAGE_GetMaxLun(void) { + return 0; +} + +const USBD_StorageTypeDef USBD_SDCARD_STORAGE_fops = { + SDCARD_STORAGE_Init, + SDCARD_STORAGE_GetCapacity, + SDCARD_STORAGE_IsReady, + SDCARD_STORAGE_IsWriteProtected, + SDCARD_STORAGE_Read, + SDCARD_STORAGE_Write, + SDCARD_STORAGE_GetMaxLun, + (int8_t *)SDCARD_STORAGE_Inquirydata, +}; diff --git a/stmhal/usbd_msc_storage.h b/stmhal/usbd_msc_storage.h new file mode 100644 index 000000000..7cc79ca79 --- /dev/null +++ b/stmhal/usbd_msc_storage.h @@ -0,0 +1,2 @@ +extern const USBD_StorageTypeDef USBD_FLASH_STORAGE_fops; +extern const USBD_StorageTypeDef USBD_SDCARD_STORAGE_fops; diff --git a/stmhal/usbdev/class/MSC/Inc/usbd_msc.h b/stmhal/usbdev/class/MSC/Inc/usbd_msc.h deleted file mode 100644 index 9329278de..000000000 --- a/stmhal/usbdev/class/MSC/Inc/usbd_msc.h +++ /dev/null @@ -1,121 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_msc_core.h - * @author MCD Application Team - * @version V2.0.0 - * @date 18-February-2014 - * @brief header for the usbd_msc_core.c file - ****************************************************************************** - * @attention - * - *

© COPYRIGHT 2014 STMicroelectronics

- * - * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); - * You may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.st.com/software_license_agreement_liberty_v2 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef _USB_MSC_CORE_H_ -#define _USB_MSC_CORE_H_ - -#include "usbd_msc_bot.h" -#include "usbd_msc_scsi.h" -#include "usbd_ioreq.h" - -/** @addtogroup USBD_MSC_BOT - * @{ - */ - -/** @defgroup USBD_MSC - * @brief This file is the Header file for USBD_msc.c - * @{ - */ - - -/** @defgroup USBD_BOT_Exported_Defines - * @{ - */ -#define MSC_MAX_FS_PACKET 0x40 -#define MSC_MAX_HS_PACKET 0x200 - -#define BOT_GET_MAX_LUN 0xFE -#define BOT_RESET 0xFF -#define USB_MSC_CONFIG_DESC_SIZ 32 - - -#define MSC_EPIN_ADDR 0x81 -#define MSC_EPOUT_ADDR 0x01 - -/** - * @} - */ - -/** @defgroup USB_CORE_Exported_Types - * @{ - */ -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; - -/* Structure for MSC process */ -extern USBD_ClassTypeDef USBD_MSC; - -uint8_t USBD_MSC_RegisterStorage (USBD_HandleTypeDef *pdev, - USBD_StorageTypeDef *fops); -/** - * @} - */ - -/** - * @} - */ -#endif // _USB_MSC_CORE_H_ -/** - * @} - */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/stmhal/usbdev/class/MSC/Inc/usbd_msc_bot.h b/stmhal/usbdev/class/MSC/Inc/usbd_msc_bot.h deleted file mode 100644 index 41f8ab5a5..000000000 --- a/stmhal/usbdev/class/MSC/Inc/usbd_msc_bot.h +++ /dev/null @@ -1,151 +0,0 @@ -/** - ****************************************************************************** - * @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 - * - *

© COPYRIGHT 2014 STMicroelectronics

- * - * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); - * You may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.st.com/software_license_agreement_liberty_v2 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ - -#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/MSC/Inc/usbd_msc_data.h b/stmhal/usbdev/class/MSC/Inc/usbd_msc_data.h deleted file mode 100644 index f468267f4..000000000 --- a/stmhal/usbdev/class/MSC/Inc/usbd_msc_data.h +++ /dev/null @@ -1,104 +0,0 @@ -/** - ****************************************************************************** - * @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 - * - *

© COPYRIGHT 2014 STMicroelectronics

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

© COPYRIGHT 2014 STMicroelectronics

- * - * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); - * You may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.st.com/software_license_agreement_liberty_v2 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __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/MSC/Inc/usbd_msc_storage_template.h b/stmhal/usbdev/class/MSC/Inc/usbd_msc_storage_template.h deleted file mode 100644 index 1fc030eea..000000000 --- a/stmhal/usbdev/class/MSC/Inc/usbd_msc_storage_template.h +++ /dev/null @@ -1,98 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_msc_storage.h - * @author MCD Application Team - * @version V2.0.0 - * @date 18-February-2014 - * @brief header file for the usbd_msc_storage.c file - ****************************************************************************** - * @attention - * - *

© COPYRIGHT 2014 STMicroelectronics

- * - * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); - * You may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.st.com/software_license_agreement_liberty_v2 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ - -#ifndef __USBD_MSC_STORAGE_H_ -#define __USBD_MSC_STORAGE_H_ - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_msc.h" - -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY - * @{ - */ - -/** @defgroup USBD_STORAGE - * @brief header file for the USBD_STORAGE.c file - * @{ - */ - -/** @defgroup USBD_STORAGE_Exported_Defines - * @{ - */ -/** - * @} - */ - - -/** @defgroup USBD_STORAGE_Exported_Types - * @{ - */ - - -/** - * @} - */ - - - -/** @defgroup USBD_STORAGE_Exported_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup USBD_STORAGE_Exported_Variables - * @{ - */ -extern USBD_StorageTypeDef USBD_MSC_Template_fops; -/** - * @} - */ - -/** @defgroup USBD_STORAGE_Exported_FunctionsPrototype - * @{ - */ - - -/** - * @} - */ - -#endif /* __USBD_MSC_STORAGE_H_ */ - -/** - * @} - */ - -/** -* @} -*/ -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/stmhal/usbdev/class/MSC/Src/usbd_msc.c b/stmhal/usbdev/class/MSC/Src/usbd_msc.c deleted file mode 100644 index 7817c98b1..000000000 --- a/stmhal/usbdev/class/MSC/Src/usbd_msc.c +++ /dev/null @@ -1,609 +0,0 @@ -/** - ****************************************************************************** - * @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 - * - *

© COPYRIGHT 2014 STMicroelectronics

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

© COPYRIGHT 2014 STMicroelectronics

- * - * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); - * You may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.st.com/software_license_agreement_liberty_v2 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_msc_bot.h" -#include "usbd_msc.h" -#include "usbd_msc_scsi.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_EPOUT_ADDR); - USBD_LL_FlushEP(pdev, MSC_EPIN_ADDR); - - /* Prapare EP to Receive First BOT Cmd */ - USBD_LL_PrepareReceive (pdev, - MSC_EPOUT_ADDR, - (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_EPOUT_ADDR, - (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_EPOUT_ADDR) != 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_EPIN_ADDR, 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_EPIN_ADDR, - (uint8_t *)&hmsc->csw, - USBD_BOT_CSW_LENGTH); - - /* Prapare EP to Receive next Cmd */ - USBD_LL_PrepareReceive (pdev, - MSC_EPOUT_ADDR, - (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_EPOUT_ADDR ); - } - USBD_LL_StallEP(pdev, MSC_EPIN_ADDR); - - if(hmsc->bot_status == USBD_BOT_STATUS_ERROR) - { - USBD_LL_PrepareReceive (pdev, - MSC_EPOUT_ADDR, - (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_EPIN_ADDR); - 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/MSC/Src/usbd_msc_data.c b/stmhal/usbdev/class/MSC/Src/usbd_msc_data.c deleted file mode 100644 index 4d72bd5fc..000000000 --- a/stmhal/usbdev/class/MSC/Src/usbd_msc_data.c +++ /dev/null @@ -1,134 +0,0 @@ -/** - ****************************************************************************** - * @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 - * - *

© COPYRIGHT 2014 STMicroelectronics

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

© COPYRIGHT 2014 STMicroelectronics

- * - * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); - * You may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.st.com/software_license_agreement_liberty_v2 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_msc_bot.h" -#include "usbd_msc_scsi.h" -#include "usbd_msc.h" -#include "usbd_msc_data.h" - - - -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY - * @{ - */ - - -/** @defgroup MSC_SCSI - * @brief Mass storage SCSI layer module - * @{ - */ - -/** @defgroup MSC_SCSI_Private_TypesDefinitions - * @{ - */ -/** - * @} - */ - - -/** @defgroup MSC_SCSI_Private_Defines - * @{ - */ - -/** - * @} - */ - - -/** @defgroup MSC_SCSI_Private_Macros - * @{ - */ -/** - * @} - */ - - -/** @defgroup MSC_SCSI_Private_Variables - * @{ - */ - -/** - * @} - */ - - -/** @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_EPOUT_ADDR, - 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_EPIN_ADDR, - 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_EPOUT_ADDR, - hmsc->bot_data, - MIN (hmsc->scsi_blk_len, MSC_MEDIA_PACKET)); - } - - return 0; -} -/** - * @} - */ - - -/** - * @} - */ - - -/** - * @} - */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/stmhal/usbdev/class/MSC/Src/usbd_msc_storage_template.c b/stmhal/usbdev/class/MSC/Src/usbd_msc_storage_template.c deleted file mode 100644 index f75f11a9e..000000000 --- a/stmhal/usbdev/class/MSC/Src/usbd_msc_storage_template.c +++ /dev/null @@ -1,188 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_msc_storage_template.c - * @author MCD Application Team - * @version V2.0.0 - * @date 18-February-2014 - * @brief Memory management layer - ****************************************************************************** - * @attention - * - *

© COPYRIGHT 2014 STMicroelectronics

- * - * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); - * You may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.st.com/software_license_agreement_liberty_v2 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ****************************************************************************** - */ - - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_msc_storage_template.h" - - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Extern function prototypes ------------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - -#define STORAGE_LUN_NBR 1 -#define STORAGE_BLK_NBR 0x10000 -#define STORAGE_BLK_SIZ 0x200 - -int8_t STORAGE_Init (uint8_t lun); - -int8_t STORAGE_GetCapacity (uint8_t lun, - uint32_t *block_num, - uint16_t *block_size); - -int8_t STORAGE_IsReady (uint8_t lun); - -int8_t STORAGE_IsWriteProtected (uint8_t lun); - -int8_t STORAGE_Read (uint8_t lun, - uint8_t *buf, - uint32_t blk_addr, - uint16_t blk_len); - -int8_t STORAGE_Write (uint8_t lun, - uint8_t *buf, - uint32_t blk_addr, - uint16_t blk_len); - -int8_t STORAGE_GetMaxLun (void); - -/* USB Mass storage Standard Inquiry Data */ -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_MSC_Template_fops = -{ - STORAGE_Init, - STORAGE_GetCapacity, - STORAGE_IsReady, - STORAGE_IsWriteProtected, - STORAGE_Read, - STORAGE_Write, - STORAGE_GetMaxLun, - STORAGE_Inquirydata, - -}; -/******************************************************************************* -* Function Name : Read_Memory -* Description : Handle the Read operation from the microSD card. -* Input : None. -* Output : None. -* Return : None. -*******************************************************************************/ -int8_t STORAGE_Init (uint8_t lun) -{ - return (0); -} - -/******************************************************************************* -* Function Name : Read_Memory -* Description : Handle the Read operation from the STORAGE card. -* Input : None. -* Output : None. -* Return : None. -*******************************************************************************/ -int8_t STORAGE_GetCapacity (uint8_t lun, uint32_t *block_num, uint16_t *block_size) -{ - *block_num = STORAGE_BLK_NBR; - *block_size = STORAGE_BLK_SIZ; - return (0); -} - -/******************************************************************************* -* Function Name : Read_Memory -* Description : Handle the Read operation from the STORAGE card. -* Input : None. -* Output : None. -* Return : None. -*******************************************************************************/ -int8_t STORAGE_IsReady (uint8_t lun) -{ - return (0); -} - -/******************************************************************************* -* Function Name : Read_Memory -* Description : Handle the Read operation from the STORAGE card. -* Input : None. -* Output : None. -* Return : None. -*******************************************************************************/ -int8_t STORAGE_IsWriteProtected (uint8_t lun) -{ - return 0; -} - -/******************************************************************************* -* Function Name : Read_Memory -* Description : Handle the Read operation from the STORAGE card. -* Input : None. -* Output : None. -* Return : None. -*******************************************************************************/ -int8_t STORAGE_Read (uint8_t lun, - uint8_t *buf, - uint32_t blk_addr, - uint16_t blk_len) -{ - return 0; -} -/******************************************************************************* -* Function Name : Write_Memory -* Description : Handle the Write operation to the STORAGE card. -* Input : None. -* Output : None. -* Return : None. -*******************************************************************************/ -int8_t STORAGE_Write (uint8_t lun, - uint8_t *buf, - uint32_t blk_addr, - uint16_t blk_len) -{ - return (0); -} -/******************************************************************************* -* Function Name : Write_Memory -* Description : Handle the Write operation to the STORAGE card. -* Input : None. -* Output : None. -* Return : None. -*******************************************************************************/ -int8_t STORAGE_GetMaxLun (void) -{ - return (STORAGE_LUN_NBR - 1); -} - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ - diff --git a/stmhal/usbdev/class/msc/inc/usbd_msc.h b/stmhal/usbdev/class/msc/inc/usbd_msc.h new file mode 100644 index 000000000..9329278de --- /dev/null +++ b/stmhal/usbdev/class/msc/inc/usbd_msc.h @@ -0,0 +1,121 @@ +/** + ****************************************************************************** + * @file usbd_msc_core.h + * @author MCD Application Team + * @version V2.0.0 + * @date 18-February-2014 + * @brief header for the usbd_msc_core.c file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2014 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef _USB_MSC_CORE_H_ +#define _USB_MSC_CORE_H_ + +#include "usbd_msc_bot.h" +#include "usbd_msc_scsi.h" +#include "usbd_ioreq.h" + +/** @addtogroup USBD_MSC_BOT + * @{ + */ + +/** @defgroup USBD_MSC + * @brief This file is the Header file for USBD_msc.c + * @{ + */ + + +/** @defgroup USBD_BOT_Exported_Defines + * @{ + */ +#define MSC_MAX_FS_PACKET 0x40 +#define MSC_MAX_HS_PACKET 0x200 + +#define BOT_GET_MAX_LUN 0xFE +#define BOT_RESET 0xFF +#define USB_MSC_CONFIG_DESC_SIZ 32 + + +#define MSC_EPIN_ADDR 0x81 +#define MSC_EPOUT_ADDR 0x01 + +/** + * @} + */ + +/** @defgroup USB_CORE_Exported_Types + * @{ + */ +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; + +/* Structure for MSC process */ +extern USBD_ClassTypeDef USBD_MSC; + +uint8_t USBD_MSC_RegisterStorage (USBD_HandleTypeDef *pdev, + USBD_StorageTypeDef *fops); +/** + * @} + */ + +/** + * @} + */ +#endif // _USB_MSC_CORE_H_ +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/stmhal/usbdev/class/msc/inc/usbd_msc_bot.h b/stmhal/usbdev/class/msc/inc/usbd_msc_bot.h new file mode 100644 index 000000000..41f8ab5a5 --- /dev/null +++ b/stmhal/usbdev/class/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 + * + *

© COPYRIGHT 2014 STMicroelectronics

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

© COPYRIGHT 2014 STMicroelectronics

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

© COPYRIGHT 2014 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __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/msc/inc/usbd_msc_storage_template.h b/stmhal/usbdev/class/msc/inc/usbd_msc_storage_template.h new file mode 100644 index 000000000..1fc030eea --- /dev/null +++ b/stmhal/usbdev/class/msc/inc/usbd_msc_storage_template.h @@ -0,0 +1,98 @@ +/** + ****************************************************************************** + * @file usbd_msc_storage.h + * @author MCD Application Team + * @version V2.0.0 + * @date 18-February-2014 + * @brief header file for the usbd_msc_storage.c file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2014 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ + +#ifndef __USBD_MSC_STORAGE_H_ +#define __USBD_MSC_STORAGE_H_ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_msc.h" + +/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup USBD_STORAGE + * @brief header file for the USBD_STORAGE.c file + * @{ + */ + +/** @defgroup USBD_STORAGE_Exported_Defines + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_STORAGE_Exported_Types + * @{ + */ + + +/** + * @} + */ + + + +/** @defgroup USBD_STORAGE_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_STORAGE_Exported_Variables + * @{ + */ +extern USBD_StorageTypeDef USBD_MSC_Template_fops; +/** + * @} + */ + +/** @defgroup USBD_STORAGE_Exported_FunctionsPrototype + * @{ + */ + + +/** + * @} + */ + +#endif /* __USBD_MSC_STORAGE_H_ */ + +/** + * @} + */ + +/** +* @} +*/ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/stmhal/usbdev/class/msc/src/usbd_msc.c b/stmhal/usbdev/class/msc/src/usbd_msc.c new file mode 100644 index 000000000..7817c98b1 --- /dev/null +++ b/stmhal/usbdev/class/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 + * + *

© COPYRIGHT 2014 STMicroelectronics

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

© COPYRIGHT 2014 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_msc_bot.h" +#include "usbd_msc.h" +#include "usbd_msc_scsi.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_EPOUT_ADDR); + USBD_LL_FlushEP(pdev, MSC_EPIN_ADDR); + + /* Prapare EP to Receive First BOT Cmd */ + USBD_LL_PrepareReceive (pdev, + MSC_EPOUT_ADDR, + (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_EPOUT_ADDR, + (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_EPOUT_ADDR) != 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_EPIN_ADDR, 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_EPIN_ADDR, + (uint8_t *)&hmsc->csw, + USBD_BOT_CSW_LENGTH); + + /* Prapare EP to Receive next Cmd */ + USBD_LL_PrepareReceive (pdev, + MSC_EPOUT_ADDR, + (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_EPOUT_ADDR ); + } + USBD_LL_StallEP(pdev, MSC_EPIN_ADDR); + + if(hmsc->bot_status == USBD_BOT_STATUS_ERROR) + { + USBD_LL_PrepareReceive (pdev, + MSC_EPOUT_ADDR, + (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_EPIN_ADDR); + 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/msc/src/usbd_msc_data.c b/stmhal/usbdev/class/msc/src/usbd_msc_data.c new file mode 100644 index 000000000..4d72bd5fc --- /dev/null +++ b/stmhal/usbdev/class/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 + * + *

© COPYRIGHT 2014 STMicroelectronics

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

© COPYRIGHT 2014 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_msc_bot.h" +#include "usbd_msc_scsi.h" +#include "usbd_msc.h" +#include "usbd_msc_data.h" + + + +/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY + * @{ + */ + + +/** @defgroup MSC_SCSI + * @brief Mass storage SCSI layer module + * @{ + */ + +/** @defgroup MSC_SCSI_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + + +/** @defgroup MSC_SCSI_Private_Defines + * @{ + */ + +/** + * @} + */ + + +/** @defgroup MSC_SCSI_Private_Macros + * @{ + */ +/** + * @} + */ + + +/** @defgroup MSC_SCSI_Private_Variables + * @{ + */ + +/** + * @} + */ + + +/** @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_EPOUT_ADDR, + 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_EPIN_ADDR, + 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_EPOUT_ADDR, + hmsc->bot_data, + MIN (hmsc->scsi_blk_len, MSC_MEDIA_PACKET)); + } + + return 0; +} +/** + * @} + */ + + +/** + * @} + */ + + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/stmhal/usbdev/class/msc/src/usbd_msc_storage_template.c b/stmhal/usbdev/class/msc/src/usbd_msc_storage_template.c new file mode 100644 index 000000000..f75f11a9e --- /dev/null +++ b/stmhal/usbdev/class/msc/src/usbd_msc_storage_template.c @@ -0,0 +1,188 @@ +/** + ****************************************************************************** + * @file usbd_msc_storage_template.c + * @author MCD Application Team + * @version V2.0.0 + * @date 18-February-2014 + * @brief Memory management layer + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2014 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_msc_storage_template.h" + + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Extern function prototypes ------------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +#define STORAGE_LUN_NBR 1 +#define STORAGE_BLK_NBR 0x10000 +#define STORAGE_BLK_SIZ 0x200 + +int8_t STORAGE_Init (uint8_t lun); + +int8_t STORAGE_GetCapacity (uint8_t lun, + uint32_t *block_num, + uint16_t *block_size); + +int8_t STORAGE_IsReady (uint8_t lun); + +int8_t STORAGE_IsWriteProtected (uint8_t lun); + +int8_t STORAGE_Read (uint8_t lun, + uint8_t *buf, + uint32_t blk_addr, + uint16_t blk_len); + +int8_t STORAGE_Write (uint8_t lun, + uint8_t *buf, + uint32_t blk_addr, + uint16_t blk_len); + +int8_t STORAGE_GetMaxLun (void); + +/* USB Mass storage Standard Inquiry Data */ +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_MSC_Template_fops = +{ + STORAGE_Init, + STORAGE_GetCapacity, + STORAGE_IsReady, + STORAGE_IsWriteProtected, + STORAGE_Read, + STORAGE_Write, + STORAGE_GetMaxLun, + STORAGE_Inquirydata, + +}; +/******************************************************************************* +* Function Name : Read_Memory +* Description : Handle the Read operation from the microSD card. +* Input : None. +* Output : None. +* Return : None. +*******************************************************************************/ +int8_t STORAGE_Init (uint8_t lun) +{ + return (0); +} + +/******************************************************************************* +* Function Name : Read_Memory +* Description : Handle the Read operation from the STORAGE card. +* Input : None. +* Output : None. +* Return : None. +*******************************************************************************/ +int8_t STORAGE_GetCapacity (uint8_t lun, uint32_t *block_num, uint16_t *block_size) +{ + *block_num = STORAGE_BLK_NBR; + *block_size = STORAGE_BLK_SIZ; + return (0); +} + +/******************************************************************************* +* Function Name : Read_Memory +* Description : Handle the Read operation from the STORAGE card. +* Input : None. +* Output : None. +* Return : None. +*******************************************************************************/ +int8_t STORAGE_IsReady (uint8_t lun) +{ + return (0); +} + +/******************************************************************************* +* Function Name : Read_Memory +* Description : Handle the Read operation from the STORAGE card. +* Input : None. +* Output : None. +* Return : None. +*******************************************************************************/ +int8_t STORAGE_IsWriteProtected (uint8_t lun) +{ + return 0; +} + +/******************************************************************************* +* Function Name : Read_Memory +* Description : Handle the Read operation from the STORAGE card. +* Input : None. +* Output : None. +* Return : None. +*******************************************************************************/ +int8_t STORAGE_Read (uint8_t lun, + uint8_t *buf, + uint32_t blk_addr, + uint16_t blk_len) +{ + return 0; +} +/******************************************************************************* +* Function Name : Write_Memory +* Description : Handle the Write operation to the STORAGE card. +* Input : None. +* Output : None. +* Return : None. +*******************************************************************************/ +int8_t STORAGE_Write (uint8_t lun, + uint8_t *buf, + uint32_t blk_addr, + uint16_t blk_len) +{ + return (0); +} +/******************************************************************************* +* Function Name : Write_Memory +* Description : Handle the Write operation to the STORAGE card. +* Input : None. +* Output : None. +* Return : None. +*******************************************************************************/ +int8_t STORAGE_GetMaxLun (void) +{ + return (STORAGE_LUN_NBR - 1); +} + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + -- cgit v1.2.3 From da8d21e0dd236ae5e31bfac4ff8d5b73ddd49282 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Sat, 22 Mar 2014 13:47:06 +0200 Subject: showbc: Dump YIELD_FROM. --- py/showbc.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/py/showbc.c b/py/showbc.c index bc81086c7..9bdf811d9 100644 --- a/py/showbc.c +++ b/py/showbc.c @@ -394,6 +394,10 @@ void mp_byte_code_print(const byte *ip, int len) { printf("YIELD_VALUE"); break; + case MP_BC_YIELD_FROM: + printf("YIELD_FROM"); + break; + case MP_BC_IMPORT_NAME: DECODE_QSTR; printf("IMPORT_NAME %s", qstr_str(qstr)); -- cgit v1.2.3