summaryrefslogtreecommitdiffstatshomepage
path: root/stmhal
diff options
context:
space:
mode:
Diffstat (limited to 'stmhal')
-rw-r--r--stmhal/Makefile13
-rw-r--r--stmhal/accel.c137
-rw-r--r--stmhal/accel.h11
-rw-r--r--stmhal/import.c9
-rw-r--r--stmhal/led.c8
-rw-r--r--stmhal/led.h1
-rw-r--r--stmhal/main.c47
-rw-r--r--stmhal/math.c4
-rw-r--r--stmhal/pybmodule.c8
-rw-r--r--stmhal/usb.c30
-rw-r--r--stmhal/usb.h14
-rw-r--r--stmhal/usbd_conf.h3
-rw-r--r--stmhal/usbd_desc.h45
-rw-r--r--stmhal/usbd_desc_msc.c227
-rw-r--r--stmhal/usbd_desc_vcp.c (renamed from stmhal/usbd_desc.c)6
-rw-r--r--stmhal/usbd_msc_storage.c320
-rw-r--r--stmhal/usbd_msc_storage.h2
-rw-r--r--stmhal/usbdev/class/msc/inc/usbd_msc.h (renamed from stmhal/usbdev/class/MSC/Inc/usbd_msc.h)0
-rw-r--r--stmhal/usbdev/class/msc/inc/usbd_msc_bot.h (renamed from stmhal/usbdev/class/MSC/Inc/usbd_msc_bot.h)0
-rw-r--r--stmhal/usbdev/class/msc/inc/usbd_msc_data.h (renamed from stmhal/usbdev/class/MSC/Inc/usbd_msc_data.h)0
-rw-r--r--stmhal/usbdev/class/msc/inc/usbd_msc_scsi.h (renamed from stmhal/usbdev/class/MSC/Inc/usbd_msc_scsi.h)0
-rw-r--r--stmhal/usbdev/class/msc/inc/usbd_msc_storage_template.h (renamed from stmhal/usbdev/class/MSC/Inc/usbd_msc_storage_template.h)0
-rw-r--r--stmhal/usbdev/class/msc/src/usbd_msc.c (renamed from stmhal/usbdev/class/MSC/Src/usbd_msc.c)0
-rw-r--r--stmhal/usbdev/class/msc/src/usbd_msc_bot.c (renamed from stmhal/usbdev/class/MSC/Src/usbd_msc_bot.c)0
-rw-r--r--stmhal/usbdev/class/msc/src/usbd_msc_data.c (renamed from stmhal/usbdev/class/MSC/Src/usbd_msc_data.c)0
-rw-r--r--stmhal/usbdev/class/msc/src/usbd_msc_scsi.c (renamed from stmhal/usbdev/class/MSC/Src/usbd_msc_scsi.c)0
-rw-r--r--stmhal/usbdev/class/msc/src/usbd_msc_storage_template.c (renamed from stmhal/usbdev/class/MSC/Src/usbd_msc_storage_template.c)0
27 files changed, 785 insertions, 100 deletions
diff --git a/stmhal/Makefile b/stmhal/Makefile
index 9f3e365a19..86791607a9 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 \
@@ -84,9 +86,9 @@ SRC_C = \
sdcard.c \
diskio.c \
lcd.c \
+ accel.c \
# servo.c \
-# accel.c \
# timer.c \
# audio.c \
# i2c.c \
@@ -104,6 +106,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 \
@@ -122,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/accel.c b/stmhal/accel.c
new file mode 100644
index 0000000000..f380242bf6
--- /dev/null
+++ b/stmhal/accel.c
@@ -0,0 +1,137 @@
+#include <stdio.h>
+#include <string.h>
+
+#include <stm32f4xx_hal.h>
+
+#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 0000000000..c2320f1a4e
--- /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 f2fd3b3dee..c977dcf2ec 100644
--- a/stmhal/import.c
+++ b/stmhal/import.c
@@ -1,16 +1,18 @@
+#include <stdio.h>
#include <stdint.h>
#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 677c151b33..80c1e145f1 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 44c68d4ebe..b3762271c1 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 d77733429b..d92ccdd5b1 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,18 +371,13 @@ 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);
+#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()) {
@@ -403,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
}
}
@@ -416,7 +400,12 @@ 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
+ // MMA accel: init and reset
+ accel_init();
#endif
// run main script
diff --git a/stmhal/math.c b/stmhal/math.c
index 8e2c6fc753..0809a3f2c5 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
diff --git a/stmhal/pybmodule.c b/stmhal/pybmodule.c
index b6b269b065..3db23dc6de 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 },
diff --git a/stmhal/usb.c b/stmhal/usb.c
index 5cf7b5f32c..c14a5ad688 100644
--- a/stmhal/usb.c
+++ b/stmhal/usb.c
@@ -1,21 +1,16 @@
#include <string.h>
-/*
-#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 3e6bdccec2..bb6283c89a 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 8c02ad0ec2..cc3ad73f98 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.h b/stmhal/usbd_desc.h
index 8b2d8f1034..a54e427e31 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
- *
- * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
- *
- * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
- * You may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.st.com/software_license_agreement_liberty_v2
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- ******************************************************************************
- */
-
-/* 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 0000000000..7d0911e82c
--- /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
+ *
+ * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_core.h"
+#include "usbd_desc.h"
+#include "usbd_conf.h"
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+#define USBD_VID 0x0483
+#define USBD_PID 0x5720
+#define USBD_LANGID_STRING 0x409
+#define USBD_MANUFACTURER_STRING "STMicroelectronics"
+#define USBD_PRODUCT_HS_STRING "Mass Storage in HS Mode"
+#define USBD_SERIALNUMBER_HS_STRING "00000000001A"
+#define USBD_PRODUCT_FS_STRING "Mass Storage in FS Mode"
+#define USBD_SERIALNUMBER_FS_STRING "00000000001B"
+#define USBD_CONFIGURATION_HS_STRING "MSC Config"
+#define USBD_INTERFACE_HS_STRING "MSC Interface"
+#define USBD_CONFIGURATION_FS_STRING "MSC Config"
+#define USBD_INTERFACE_FS_STRING "MSC Interface"
+
+/* Private macro -------------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+uint8_t *USBD_MSC_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
+uint8_t *USBD_MSC_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
+uint8_t *USBD_MSC_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
+uint8_t *USBD_MSC_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
+uint8_t *USBD_MSC_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
+uint8_t *USBD_MSC_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
+uint8_t *USBD_MSC_InterfaceStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
+#ifdef USB_SUPPORT_USER_STRING_DESC
+uint8_t *USBD_MSC_USRStringDesc(USBD_SpeedTypeDef speed, uint8_t idx, uint16_t *length);
+#endif /* USB_SUPPORT_USER_STRING_DESC */
+
+/* Private variables ---------------------------------------------------------*/
+USBD_DescriptorsTypeDef MSC_Desc = {
+ USBD_MSC_DeviceDescriptor,
+ USBD_MSC_LangIDStrDescriptor,
+ USBD_MSC_ManufacturerStrDescriptor,
+ USBD_MSC_ProductStrDescriptor,
+ USBD_MSC_SerialStrDescriptor,
+ USBD_MSC_ConfigStrDescriptor,
+ USBD_MSC_InterfaceStrDescriptor,
+};
+
+/* USB Standard Device Descriptor */
+#if defined ( __ICCARM__ ) /*!< IAR Compiler */
+ #pragma data_alignment=4
+#endif
+__ALIGN_BEGIN static uint8_t USBD_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = {
+ 0x12, /* bLength */
+ USB_DESC_TYPE_DEVICE, /* bDescriptorType */
+ 0x00, /* bcdUSB */
+ 0x02,
+ 0x00, /* bDeviceClass */
+ 0x00, /* bDeviceSubClass */
+ 0x00, /* bDeviceProtocol */
+ USB_MAX_EP0_SIZE, /* bMaxPacketSize */
+ LOBYTE(USBD_VID), /* idVendor */
+ HIBYTE(USBD_VID), /* idVendor */
+ LOBYTE(USBD_PID), /* idVendor */
+ HIBYTE(USBD_PID), /* idVendor */
+ 0x00, /* bcdDevice rel. 2.00 */
+ 0x02,
+ USBD_IDX_MFC_STR, /* Index of manufacturer string */
+ USBD_IDX_PRODUCT_STR, /* Index of product string */
+ USBD_IDX_SERIAL_STR, /* Index of serial number string */
+ USBD_MAX_NUM_CONFIGURATION /* bNumConfigurations */
+}; /* USB_DeviceDescriptor */
+
+/* USB Standard Device Descriptor */
+#if defined ( __ICCARM__ ) /*!< IAR Compiler */
+ #pragma data_alignment=4
+#endif
+__ALIGN_BEGIN static uint8_t USBD_LangIDDesc[USB_LEN_LANGID_STR_DESC] __ALIGN_END = {
+ USB_LEN_LANGID_STR_DESC,
+ USB_DESC_TYPE_STRING,
+ LOBYTE(USBD_LANGID_STRING),
+ HIBYTE(USBD_LANGID_STRING),
+};
+
+#if defined ( __ICCARM__ ) /*!< IAR Compiler */
+ #pragma data_alignment=4
+#endif
+__ALIGN_BEGIN static uint8_t USBD_StrDesc[USBD_MAX_STR_DESC_SIZ] __ALIGN_END;
+
+/* Private functions ---------------------------------------------------------*/
+
+/**
+ * @brief Returns the device descriptor.
+ * @param speed: Current device speed
+ * @param length: Pointer to data length variable
+ * @retval Pointer to descriptor buffer
+ */
+uint8_t *USBD_MSC_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
+{
+ *length = sizeof(USBD_DeviceDesc);
+ return USBD_DeviceDesc;
+}
+
+/**
+ * @brief Returns the LangID string descriptor.
+ * @param speed: Current device speed
+ * @param length: Pointer to data length variable
+ * @retval Pointer to descriptor buffer
+ */
+uint8_t *USBD_MSC_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
+{
+ *length = sizeof(USBD_LangIDDesc);
+ return USBD_LangIDDesc;
+}
+
+/**
+ * @brief Returns the product string descriptor.
+ * @param speed: Current device speed
+ * @param length: Pointer to data length variable
+ * @retval Pointer to descriptor buffer
+ */
+uint8_t *USBD_MSC_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
+{
+ if(speed == 0)
+ {
+ USBD_GetString((uint8_t *)(uint8_t *)USBD_PRODUCT_HS_STRING, USBD_StrDesc, length);
+ }
+ else
+ {
+ USBD_GetString((uint8_t *)(uint8_t *)USBD_PRODUCT_FS_STRING, USBD_StrDesc, length);
+ }
+ return USBD_StrDesc;
+}
+
+/**
+ * @brief Returns the manufacturer string descriptor.
+ * @param speed: Current device speed
+ * @param length: Pointer to data length variable
+ * @retval Pointer to descriptor buffer
+ */
+uint8_t *USBD_MSC_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
+{
+ USBD_GetString((uint8_t *)(uint8_t *)USBD_MANUFACTURER_STRING, USBD_StrDesc, length);
+ return USBD_StrDesc;
+}
+
+/**
+ * @brief Returns the serial number string descriptor.
+ * @param speed: Current device speed
+ * @param length: Pointer to data length variable
+ * @retval Pointer to descriptor buffer
+ */
+uint8_t *USBD_MSC_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
+{
+ if(speed == USBD_SPEED_HIGH)
+ {
+ USBD_GetString((uint8_t *)(uint8_t *)USBD_SERIALNUMBER_HS_STRING, USBD_StrDesc, length);
+ }
+ else
+ {
+ USBD_GetString((uint8_t *)(uint8_t *)USBD_SERIALNUMBER_FS_STRING, USBD_StrDesc, length);
+ }
+ return USBD_StrDesc;
+}
+
+/**
+ * @brief Returns the configuration string descriptor.
+ * @param speed: Current device speed
+ * @param length: Pointer to data length variable
+ * @retval Pointer to descriptor buffer
+ */
+uint8_t *USBD_MSC_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
+{
+ if(speed == USBD_SPEED_HIGH)
+ {
+ USBD_GetString((uint8_t *)(uint8_t *)USBD_CONFIGURATION_HS_STRING, USBD_StrDesc, length);
+ }
+ else
+ {
+ USBD_GetString((uint8_t *)(uint8_t *)USBD_CONFIGURATION_FS_STRING, USBD_StrDesc, length);
+ }
+ return USBD_StrDesc;
+}
+
+/**
+ * @brief Returns the interface string descriptor.
+ * @param speed: Current device speed
+ * @param length: Pointer to data length variable
+ * @retval Pointer to descriptor buffer
+ */
+uint8_t *USBD_MSC_InterfaceStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
+{
+ if(speed == 0)
+ {
+ USBD_GetString((uint8_t *)(uint8_t *)USBD_INTERFACE_HS_STRING, USBD_StrDesc, length);
+ }
+ else
+ {
+ USBD_GetString((uint8_t *)(uint8_t *)USBD_INTERFACE_FS_STRING, USBD_StrDesc, length);
+ }
+ return USBD_StrDesc;
+}
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/stmhal/usbd_desc.c b/stmhal/usbd_desc_vcp.c
index ca9ea487d9..edcb4b3431 100644
--- a/stmhal/usbd_desc.c
+++ b/stmhal/usbd_desc_vcp.c
@@ -73,7 +73,7 @@ USBD_DescriptorsTypeDef VCP_Desc = {
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
-__ALIGN_BEGIN uint8_t hUSBDDeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = {
+__ALIGN_BEGIN static uint8_t hUSBDDeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = {
0x12, /* bLength */
USB_DESC_TYPE_DEVICE, /* bDescriptorType */
0x00, /* bcdUSB */
@@ -98,7 +98,7 @@ __ALIGN_BEGIN uint8_t hUSBDDeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = {
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
-__ALIGN_BEGIN uint8_t USBD_LangIDDesc[USB_LEN_LANGID_STR_DESC] __ALIGN_END = {
+__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),
@@ -108,7 +108,7 @@ __ALIGN_BEGIN uint8_t USBD_LangIDDesc[USB_LEN_LANGID_STR_DESC] __ALIGN_END = {
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
-__ALIGN_BEGIN uint8_t USBD_StrDesc[USBD_MAX_STR_DESC_SIZ] __ALIGN_END;
+__ALIGN_BEGIN static uint8_t USBD_StrDesc[USBD_MAX_STR_DESC_SIZ] __ALIGN_END;
/* Private functions ---------------------------------------------------------*/
diff --git a/stmhal/usbd_msc_storage.c b/stmhal/usbd_msc_storage.c
new file mode 100644
index 0000000000..e5c75e27c7
--- /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
+ *
+ * <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * 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 0000000000..7cc79ca793
--- /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
index 9329278ded..9329278ded 100644
--- a/stmhal/usbdev/class/MSC/Inc/usbd_msc.h
+++ b/stmhal/usbdev/class/msc/inc/usbd_msc.h
diff --git a/stmhal/usbdev/class/MSC/Inc/usbd_msc_bot.h b/stmhal/usbdev/class/msc/inc/usbd_msc_bot.h
index 41f8ab5a53..41f8ab5a53 100644
--- a/stmhal/usbdev/class/MSC/Inc/usbd_msc_bot.h
+++ b/stmhal/usbdev/class/msc/inc/usbd_msc_bot.h
diff --git a/stmhal/usbdev/class/MSC/Inc/usbd_msc_data.h b/stmhal/usbdev/class/msc/inc/usbd_msc_data.h
index f468267f43..f468267f43 100644
--- a/stmhal/usbdev/class/MSC/Inc/usbd_msc_data.h
+++ b/stmhal/usbdev/class/msc/inc/usbd_msc_data.h
diff --git a/stmhal/usbdev/class/MSC/Inc/usbd_msc_scsi.h b/stmhal/usbdev/class/msc/inc/usbd_msc_scsi.h
index dea247bca8..dea247bca8 100644
--- a/stmhal/usbdev/class/MSC/Inc/usbd_msc_scsi.h
+++ b/stmhal/usbdev/class/msc/inc/usbd_msc_scsi.h
diff --git a/stmhal/usbdev/class/MSC/Inc/usbd_msc_storage_template.h b/stmhal/usbdev/class/msc/inc/usbd_msc_storage_template.h
index 1fc030eea6..1fc030eea6 100644
--- a/stmhal/usbdev/class/MSC/Inc/usbd_msc_storage_template.h
+++ b/stmhal/usbdev/class/msc/inc/usbd_msc_storage_template.h
diff --git a/stmhal/usbdev/class/MSC/Src/usbd_msc.c b/stmhal/usbdev/class/msc/src/usbd_msc.c
index 7817c98b1c..7817c98b1c 100644
--- a/stmhal/usbdev/class/MSC/Src/usbd_msc.c
+++ b/stmhal/usbdev/class/msc/src/usbd_msc.c
diff --git a/stmhal/usbdev/class/MSC/Src/usbd_msc_bot.c b/stmhal/usbdev/class/msc/src/usbd_msc_bot.c
index a430ce7709..a430ce7709 100644
--- a/stmhal/usbdev/class/MSC/Src/usbd_msc_bot.c
+++ b/stmhal/usbdev/class/msc/src/usbd_msc_bot.c
diff --git a/stmhal/usbdev/class/MSC/Src/usbd_msc_data.c b/stmhal/usbdev/class/msc/src/usbd_msc_data.c
index 4d72bd5fce..4d72bd5fce 100644
--- a/stmhal/usbdev/class/MSC/Src/usbd_msc_data.c
+++ b/stmhal/usbdev/class/msc/src/usbd_msc_data.c
diff --git a/stmhal/usbdev/class/MSC/Src/usbd_msc_scsi.c b/stmhal/usbdev/class/msc/src/usbd_msc_scsi.c
index ab94d89665..ab94d89665 100644
--- a/stmhal/usbdev/class/MSC/Src/usbd_msc_scsi.c
+++ b/stmhal/usbdev/class/msc/src/usbd_msc_scsi.c
diff --git a/stmhal/usbdev/class/MSC/Src/usbd_msc_storage_template.c b/stmhal/usbdev/class/msc/src/usbd_msc_storage_template.c
index f75f11a9e5..f75f11a9e5 100644
--- a/stmhal/usbdev/class/MSC/Src/usbd_msc_storage_template.c
+++ b/stmhal/usbdev/class/msc/src/usbd_msc_storage_template.c