diff --git a/boards.txt b/boards.txt
index 65074d3a9f..a91fa61206 100644
--- a/boards.txt
+++ b/boards.txt
@@ -2325,6 +2325,8 @@ Nucleo_144.menu.usb.CDCgen=CDC (generic 'Serial' supersede U(S)ART)
Nucleo_144.menu.usb.CDCgen.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC
Nucleo_144.menu.usb.CDC=CDC (no generic 'Serial')
Nucleo_144.menu.usb.CDC.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC -DDISABLE_GENERIC_SERIALUSB
+Nucleo_144.menu.usb.CDC_MSC=CDC + MSC
+Nucleo_144.menu.usb.CDC_MSC.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC_MSC
Nucleo_144.menu.usb.HID=HID (keyboard and mouse)
Nucleo_144.menu.usb.HID.build.enable_usb={build.usb_flags} -DUSBD_USE_HID_COMPOSITE
Nucleo_144.menu.xusb.FS=Low/Full Speed
@@ -2338,6 +2340,8 @@ Nucleo_64.menu.usb.CDCgen=CDC (generic 'Serial' supersede U(S)ART)
Nucleo_64.menu.usb.CDCgen.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC
Nucleo_64.menu.usb.CDC=CDC (no generic 'Serial')
Nucleo_64.menu.usb.CDC.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC -DDISABLE_GENERIC_SERIALUSB
+Nucleo_64.menu.usb.CDC_MSC=CDC + MSC
+Nucleo_64.menu.usb.CDC_MSC.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC_MSC
Nucleo_64.menu.usb.HID=HID (keyboard and mouse)
Nucleo_64.menu.usb.HID.build.enable_usb={build.usb_flags} -DUSBD_USE_HID_COMPOSITE
Nucleo_64.menu.xusb.FS=Low/Full Speed
@@ -2351,6 +2355,8 @@ Nucleo_32.menu.usb.CDCgen=CDC (generic 'Serial' supersede U(S)ART)
Nucleo_32.menu.usb.CDCgen.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC
Nucleo_32.menu.usb.CDC=CDC (no generic 'Serial')
Nucleo_32.menu.usb.CDC.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC -DDISABLE_GENERIC_SERIALUSB
+Nucleo_32.menu.usb.CDC_MSC=CDC + MSC
+Nucleo_32.menu.usb.CDC_MSC.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC_MSC
Nucleo_32.menu.usb.HID=HID (keyboard and mouse)
Nucleo_32.menu.usb.HID.build.enable_usb={build.usb_flags} -DUSBD_USE_HID_COMPOSITE
Nucleo_32.menu.xusb.FS=Low/Full Speed
@@ -2364,6 +2370,8 @@ Disco.menu.usb.CDCgen=CDC (generic 'Serial' supersede U(S)ART)
Disco.menu.usb.CDCgen.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC
Disco.menu.usb.CDC=CDC (no generic 'Serial')
Disco.menu.usb.CDC.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC -DDISABLE_GENERIC_SERIALUSB
+Disco.menu.usb.CDC_MSC=CDC + MSC
+Disco.menu.usb.CDC_MSC.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC_MSC
Disco.menu.usb.HID=HID (keyboard and mouse)
Disco.menu.usb.HID.build.enable_usb={build.usb_flags} -DUSBD_USE_HID_COMPOSITE
Disco.menu.xusb.FS=Low/Full Speed
@@ -2377,6 +2385,8 @@ Eval.menu.usb.CDCgen=CDC (generic 'Serial' supersede U(S)ART)
Eval.menu.usb.CDCgen.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC
Eval.menu.usb.CDC=CDC (no generic 'Serial')
Eval.menu.usb.CDC.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC -DDISABLE_GENERIC_SERIALUSB
+Eval.menu.usb.CDC_MSC=CDC + MSC
+Eval.menu.usb.CDC_MSC.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC_MSC
Eval.menu.usb.HID=HID (keyboard and mouse)
Eval.menu.usb.HID.build.enable_usb={build.usb_flags} -DUSBD_USE_HID_COMPOSITE
Eval.menu.xusb.FS=Low/Full Speed
@@ -2390,6 +2400,8 @@ GenF1.menu.usb.CDCgen=CDC (generic 'Serial' supersede U(S)ART)
GenF1.menu.usb.CDCgen.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC
GenF1.menu.usb.CDC=CDC (no generic 'Serial')
GenF1.menu.usb.CDC.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC -DDISABLE_GENERIC_SERIALUSB
+GenF1.menu.usb.CDC_MSC=CDC + MSC
+GenF1.menu.usb.CDC_MSC.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC_MSC
GenF1.menu.usb.HID=HID (keyboard and mouse)
GenF1.menu.usb.HID.build.enable_usb={build.usb_flags} -DUSBD_USE_HID_COMPOSITE
GenF1.menu.xusb.FS=Low/Full Speed
@@ -2403,6 +2415,8 @@ GenF3.menu.usb.CDCgen=CDC (generic 'Serial' supersede U(S)ART)
GenF3.menu.usb.CDCgen.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC
GenF3.menu.usb.CDC=CDC (no generic 'Serial')
GenF3.menu.usb.CDC.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC -DDISABLE_GENERIC_SERIALUSB
+GenF3.menu.usb.CDC_MSC=CDC + MSC
+GenF3.menu.usb.CDC_MSC.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC_MSC
GenF3.menu.usb.HID=HID (keyboard and mouse)
GenF3.menu.usb.HID.build.enable_usb={build.usb_flags} -DUSBD_USE_HID_COMPOSITE
GenF3.menu.xusb.FS=Low/Full Speed
@@ -2416,6 +2430,8 @@ GenF4.menu.usb.CDCgen=CDC (generic 'Serial' supersede U(S)ART)
GenF4.menu.usb.CDCgen.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC
GenF4.menu.usb.CDC=CDC (no generic 'Serial')
GenF4.menu.usb.CDC.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC -DDISABLE_GENERIC_SERIALUSB
+GenF4.menu.usb.CDC_MSC=CDC + MSC
+GenF4.menu.usb.CDC_MSC.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC_MSC
GenF4.menu.usb.HID=HID (keyboard and mouse)
GenF4.menu.usb.HID.build.enable_usb={build.usb_flags} -DUSBD_USE_HID_COMPOSITE
GenF4.menu.xusb.FS=Low/Full Speed
@@ -2429,6 +2445,8 @@ GenH7.menu.usb.CDCgen=CDC (generic 'Serial' supersede U(S)ART)
GenH7.menu.usb.CDCgen.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC
GenH7.menu.usb.CDC=CDC (no generic 'Serial')
GenH7.menu.usb.CDC.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC -DDISABLE_GENERIC_SERIALUSB
+GenH7.menu.usb.CDC_MSC=CDC + MSC
+GenH7.menu.usb.CDC_MSC.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC_MSC
GenH7.menu.usb.HID=HID (keyboard and mouse)
GenH7.menu.usb.HID.build.enable_usb={build.usb_flags} -DUSBD_USE_HID_COMPOSITE
GenH7.menu.xusb.FS=Low/Full Speed
@@ -2440,6 +2458,8 @@ GenL0.menu.usb.CDCgen=CDC (generic 'Serial' supersede U(S)ART)
GenL0.menu.usb.CDCgen.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC
GenL0.menu.usb.CDC=CDC (no generic 'Serial')
GenL0.menu.usb.CDC.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC -DDISABLE_GENERIC_SERIALUSB
+GenL0.menu.usb.CDC_MSC=CDC + MSC
+GenL0.menu.usb.CDC_MSC.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC_MSC
GenL0.menu.usb.HID=HID (keyboard and mouse)
GenL0.menu.usb.HID.build.enable_usb={build.usb_flags} -DUSBD_USE_HID_COMPOSITE
@@ -2448,6 +2468,8 @@ GenL0.menu.usb.HID.build.enable_usb={build.usb_flags} -DUSBD_USE_HID_COMPOSITE
3dprinter.menu.usb.CDCgen.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC
3dprinter.menu.usb.CDC=CDC (no generic 'Serial')
3dprinter.menu.usb.CDC.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC -DDISABLE_GENERIC_SERIALUSB
+3dprinter.menu.usb.CDC_MSC=CDC + MSC
+3dprinter.menu.usb.CDC_MSC.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC_MSC
3dprinter.menu.xusb.FS=Low/Full Speed
3dprinter.menu.xusb.HS=High Speed
3dprinter.menu.xusb.HS.build.usb_speed=-DUSE_USB_HS
@@ -2459,6 +2481,8 @@ Genericflight.menu.usb.CDCgen=CDC (generic 'Serial' supersede U(S)ART)
Genericflight.menu.usb.CDCgen.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC
Genericflight.menu.usb.CDC=CDC (no generic 'Serial')
Genericflight.menu.usb.CDC.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC -DDISABLE_GENERIC_SERIALUSB
+Genericflight.menu.usb.CDC_MSC=CDC + MSC
+Genericflight.menu.usb.CDC_MSC.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC_MSC
Genericflight.menu.usb.HID=HID (keyboard and mouse)
Genericflight.menu.usb.HID.build.enable_usb={build.usb_flags} -DUSBD_USE_HID_COMPOSITE
Genericflight.menu.xusb.FS=Low/Full Speed
@@ -2472,6 +2496,8 @@ Garatronic.menu.usb.CDCgen=CDC (generic 'Serial' supersede U(S)ART)
Garatronic.menu.usb.CDCgen.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC
Garatronic.menu.usb.CDC=CDC (no generic 'Serial')
Garatronic.menu.usb.CDC.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC -DDISABLE_GENERIC_SERIALUSB
+Garatronic.menu.usb.CDC_MSC=CDC + MSC
+Garatronic.menu.usb.CDC_MSC.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC_MSC
Garatronic.menu.usb.HID=HID (keyboard and mouse)
Garatronic.menu.usb.HID.build.enable_usb={build.usb_flags} -DUSBD_USE_HID_COMPOSITE
@@ -2480,6 +2506,8 @@ Midatronics.menu.usb.CDCgen=CDC (generic 'Serial' supersede U(S)ART)
Midatronics.menu.usb.CDCgen.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC
Midatronics.menu.usb.CDC=CDC (no generic 'Serial')
Midatronics.menu.usb.CDC.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC -DDISABLE_GENERIC_SERIALUSB
+Midatronics.menu.usb.CDC_MSC=CDC + MSC
+Midatronics.menu.usb.CDC_MSC.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC_MSC
Midatronics.menu.usb.HID=HID (keyboard and mouse)
Midatronics.menu.usb.HID.build.enable_usb={build.usb_flags} -DUSBD_USE_HID_COMPOSITE
Midatronics.menu.xusb.FS=Low/Full Speed
diff --git a/cores/arduino/USB.cpp b/cores/arduino/USB.cpp
new file mode 100644
index 0000000000..1b2dfaca24
--- /dev/null
+++ b/cores/arduino/USB.cpp
@@ -0,0 +1,126 @@
+/*
+ Copyright (c) 2015 Arduino LLC. All right reserved.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#ifdef USBCON
+
+#include "usbd_desc.h"
+#include "USB.h"
+#include "wiring.h"
+
+#ifdef USBD_USE_CDC_CLASS
+ #include "usbd_cdc.h"
+ #include "usbd_cdc_msc.h"
+ #include "usbd_cdc_if.h"
+#endif
+
+#ifdef USBD_USE_MSC_CLASS
+ #include "usbd_msc.h"
+ #include "usbd_msc_storage_if.h"
+#endif
+
+USB USBDevice;
+
+void USB::begin()
+{
+ if (!initialized) {
+ initialize();
+ }
+}
+
+#ifdef USBD_USE_MSC_CLASS
+DummyUSBMscHandler dummyHandler;
+
+void USB::registerMscHandler(USBMscHandler &handler)
+{
+ pSingleMscHandler = &handler;
+ registerMscHandlers(1, &pSingleMscHandler, USBD_MSC_fops.pInquiry);
+}
+
+void USB::registerMscHandlers(uint8_t count, USBMscHandler **ppHandlers, uint8_t *pInquiryData)
+{
+ if (count == 0) {
+ registerMscHandler(dummyHandler);
+ } else {
+ ppUsbMscHandlers = ppHandlers;
+ usbMscMaxLun = count - 1;
+ USBD_MSC_fops.pInquiry = pInquiryData;
+ }
+}
+#endif
+
+void USB::initialize()
+{
+ hUSBD_Device_CDC = &hUSBD_Device;
+
+
+ /* Init Device Library */
+ if (USBD_Init(&hUSBD_Device, &USBD_Desc, 0) != USBD_OK) {
+ return;
+ }
+
+ /* Add Supported Class and register interface */
+#ifdef USBD_USE_CDC
+ if (USBD_RegisterClass(&hUSBD_Device, &USBD_CDC) != USBD_OK) {
+ return;
+ }
+#elif USBD_USE_CDC_MSC
+ if (USBD_RegisterClass(&hUSBD_Device, &USBD_CDC_MSC) != USBD_OK) {
+ return;
+ }
+#elif USBD_USE_MSC
+ if (USBD_RegisterClass(&hUSBD_Device, &USBD_CDC_MSC) != USBD_OK) {
+ return;
+ }
+#endif
+
+#ifdef USBD_USE_CDC_CLASS
+ hUSBD_Device_CDC = &hUSBD_Device;
+ if (USBD_CDC_RegisterInterface(&hUSBD_Device, &USBD_CDC_fops) != USBD_OK) {
+ return;
+ }
+#endif
+
+#ifdef USBD_USE_MSC_CLASS
+ if (ppUsbMscHandlers == nullptr) {
+ registerMscHandler(dummyHandler);
+ }
+ if (USBD_MSC_RegisterStorage(&hUSBD_Device, &USBD_MSC_fops) != USBD_OK) {
+ return;
+ }
+#endif
+
+ /* Start Device Process */
+ USBD_Start(&hUSBD_Device);
+ initialized = true;
+}
+
+void USB::end()
+{
+ if (initialized) {
+ deinitialize();
+ }
+}
+
+void USB::deinitialize()
+{
+ USBD_Stop(&hUSBD_Device);
+ USBD_DeInit(&hUSBD_Device);
+ initialized = false;
+}
+
+#endif // USBCON
diff --git a/cores/arduino/USB.h b/cores/arduino/USB.h
new file mode 100644
index 0000000000..1c06240d27
--- /dev/null
+++ b/cores/arduino/USB.h
@@ -0,0 +1,58 @@
+/*
+ Copyright (c) 2015 Arduino LLC. All right reserved.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#ifndef _USB_H_
+#define _USB_H_
+
+#ifdef USBCON
+
+#include "usbd_core.h"
+#include "usbd_ep_conf.h"
+
+#ifdef USBD_USE_MSC_CLASS
+ #include "USBMscHandler.h"
+#endif
+
+class USB {
+ public:
+#ifdef USBD_USE_MSC_CLASS
+ void registerMscHandler(USBMscHandler &pHandler);
+ void registerMscHandlers(uint8_t count, USBMscHandler **pHandlers, uint8_t *pInquiryData);
+#endif
+
+ void begin(void);
+
+ void end(void);
+
+ protected:
+ void initialize();
+ void deinitialize();
+
+ bool initialized;
+
+ USBD_HandleTypeDef hUSBD_Device;
+
+#ifdef USBD_USE_MSC_CLASS
+ USBMscHandler *pSingleMscHandler;
+#endif
+};
+
+extern USB USBDevice;
+
+#endif // USBCON
+#endif // _USB_H_
\ No newline at end of file
diff --git a/cores/arduino/USBMscHandler.h b/cores/arduino/USBMscHandler.h
new file mode 100644
index 0000000000..9f8afea1e1
--- /dev/null
+++ b/cores/arduino/USBMscHandler.h
@@ -0,0 +1,89 @@
+/*
+ Copyright (c) 2015 Arduino LLC. All right reserved.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+
+#ifndef _USB_MSC_HANDLER_H_
+#define _USB_MSC_HANDLER_H_
+
+#if defined(USBCON) && defined(USBD_USE_MSC_CLASS)
+
+#include "usbd_core.h"
+#include "usbd_msc.h"
+
+/* Handler for mass storage devices */
+class USBMscHandler {
+ public:
+ // Example: A 128 MB SD card has 245760 blocks, at a block size of 512 bytes
+ // Returns true if successful, otherwise false.
+ virtual bool GetCapacity(uint32_t *pBlockNum, uint16_t *pBlockSize) = 0;
+
+ // Read [blk_len] blocks, starting at [blk_addr] into [buf].
+ // Returns true if successful, otherwise false.
+ virtual bool Read(uint8_t *pBuf, uint32_t blkAddr, uint16_t blkLen) = 0;
+
+ // Write [blk_len] blocks, starting at [blk_addr] into [buf].
+ // Returns true if successful, otherwise false.
+ virtual bool Write(uint8_t *pBuf, uint32_t blkAddr, uint16_t blkLen) = 0;
+
+ /** Optional functions **/
+
+ virtual bool Init()
+ {
+ return true;
+ }
+
+ // Return false if the mass storage device has not been connected or initialized yet.
+ virtual bool IsReady()
+ {
+ return true;
+ }
+
+ // If the device should be read-only then this function should return true.
+ virtual bool IsWriteProtected()
+ {
+ return false;
+ }
+};
+
+class DummyUSBMscHandler : public USBMscHandler {
+ public:
+ // Any call to one of these functions always fails.
+ bool GetCapacity(uint32_t *pBlockNum, uint16_t *pBlockSize)
+ {
+ return false;
+ }
+
+ bool Read(uint8_t *pBuf, uint32_t blockAddr, uint16_t blkLen)
+ {
+ return false;
+ }
+
+ bool Write(uint8_t *pBuf, uint32_t blockAddr, uint16_t blkLen)
+ {
+ return false;
+ }
+
+ // The dummy handler is never ready.
+ bool IsReady()
+ {
+ return false;
+ }
+};
+
+#endif
+#endif
\ No newline at end of file
diff --git a/cores/arduino/USBSerial.cpp b/cores/arduino/USBSerial.cpp
index 256b5a1df8..741f57ce9c 100644
--- a/cores/arduino/USBSerial.cpp
+++ b/cores/arduino/USBSerial.cpp
@@ -16,8 +16,11 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#if defined (USBCON) && defined(USBD_USE_CDC)
+#include "usbd_ep_conf.h"
+#if defined (USBCON) && defined(USBD_USE_CDC_CLASS)
+
+#include "USB.h"
#include "USBSerial.h"
#include "usbd_cdc.h"
#include "usbd_cdc_if.h"
@@ -31,7 +34,7 @@ void serialEventUSB() __attribute__((weak));
void USBSerial::begin(void)
{
- CDC_init();
+ USBDevice.begin();
}
void USBSerial::begin(uint32_t /* baud_count */)
@@ -48,7 +51,7 @@ void USBSerial::begin(uint32_t /* baud_count */, uint8_t /* config */)
void USBSerial::end()
{
- CDC_deInit();
+ USBDevice.end();
}
int USBSerial::availableForWrite()
diff --git a/cores/arduino/USBSerial.h b/cores/arduino/USBSerial.h
index 1628eef358..6ff78af907 100644
--- a/cores/arduino/USBSerial.h
+++ b/cores/arduino/USBSerial.h
@@ -19,9 +19,11 @@
#ifndef _USBSERIAL_H_
#define _USBSERIAL_H_
-#if defined (USBCON) && defined(USBD_USE_CDC)
-#include "Stream.h"
+#include "usbd_ep_conf.h"
+
+#if defined (USBCON) && defined(USBD_USE_CDC_CLASS)
#include "usbd_core.h"
+#include "Stream.h"
//================================================================================
// Serial over CDC
diff --git a/cores/arduino/stm32/usb/cdc/cdc_queue.c b/cores/arduino/stm32/usb/cdc/cdc_queue.c
index 2d2330c195..3209341d42 100644
--- a/cores/arduino/stm32/usb/cdc/cdc_queue.c
+++ b/cores/arduino/stm32/usb/cdc/cdc_queue.c
@@ -35,8 +35,10 @@
******************************************************************************
*/
+#include "usbd_ep_conf.h"
+
#ifdef USBCON
-#ifdef USBD_USE_CDC
+#ifdef USBD_USE_CDC_CLASS
#include "cdc_queue.h"
diff --git a/cores/arduino/stm32/usb/cdc/usbd_cdc.c b/cores/arduino/stm32/usb/cdc/usbd_cdc.c
index 9ee0d7885a..f76e248bb4 100644
--- a/cores/arduino/stm32/usb/cdc/usbd_cdc.c
+++ b/cores/arduino/stm32/usb/cdc/usbd_cdc.c
@@ -50,8 +50,10 @@
******************************************************************************
*/
+#include "usbd_ep_conf.h"
+
#ifdef USBCON
-#ifdef USBD_USE_CDC
+#ifdef USBD_USE_CDC_CLASS
/* Includes ------------------------------------------------------------------*/
#include "usbd_cdc.h"
@@ -108,7 +110,7 @@ static uint8_t *USBD_CDC_GetFSCfgDesc(uint16_t *length);
static uint8_t *USBD_CDC_GetHSCfgDesc(uint16_t *length);
static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length);
static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length);
-uint8_t *USBD_CDC_GetDeviceQualifierDescriptor(uint16_t *length);
+uint8_t *USBD_CDC_GetDeviceQualifierDescriptor(uint16_t *length);
/* USB Standard Device Descriptor */
__ALIGN_BEGIN static uint8_t USBD_CDC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END = {
@@ -402,6 +404,15 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_OtherSpeedCfgDesc[USB_CDC_CONFIG_DESC_SIZ]
0x00 /* bInterval */
};
+
+
+USBD_CDC_HandleTypeDef cdc_handle_dat;
+USBD_CDC_HandleTypeDef *cdc_handle = &cdc_handle_dat;
+
+USBD_CDC_ItfTypeDef *cdc_itf = NULL; /* TODO */
+
+int cdcInitialized;
+
/**
* @}
*/
@@ -417,19 +428,13 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_OtherSpeedCfgDesc[USB_CDC_CONFIG_DESC_SIZ]
* @param cfgidx: Configuration index
* @retval status
*/
-static uint8_t USBD_CDC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
+static uint8_t USBD_CDC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
{
UNUSED(cfgidx);
- USBD_CDC_HandleTypeDef *hcdc;
- hcdc = USBD_malloc(sizeof(USBD_CDC_HandleTypeDef));
+ USBD_CDC_HandleTypeDef *hcdc = cdc_handle;
- if (hcdc == NULL) {
- pdev->pClassData = NULL;
- return (uint8_t)USBD_EMEM;
- }
-
- pdev->pClassData = (void *)hcdc;
+ pdev->pClassData = &cdcInitialized;
if (pdev->dev_speed == USBD_SPEED_HIGH) {
/* Open EP IN */
@@ -468,7 +473,7 @@ static uint8_t USBD_CDC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
pdev->ep_in[CDC_CMD_EP & 0xFU].is_used = 1U;
/* Init physical Interface components */
- ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Init();
+ cdc_itf->Init();
/* Init Xfer states */
hcdc->TxState = 0U;
@@ -494,7 +499,7 @@ static uint8_t USBD_CDC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
* @param cfgidx: Configuration index
* @retval status
*/
-static uint8_t USBD_CDC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
+static uint8_t USBD_CDC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
{
UNUSED(cfgidx);
uint8_t ret = 0U;
@@ -514,8 +519,12 @@ static uint8_t USBD_CDC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
/* DeInit physical Interface components */
if (pdev->pClassData != NULL) {
- ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->DeInit();
- (void)USBD_free(pdev->pClassData);
+ /* DeInit physical Interface components */
+ cdc_itf->DeInit();
+ }
+
+ if (pdev->pClassData == &cdcInitialized) {
+ // only mark as uninitialised if we own the initialisation
pdev->pClassData = NULL;
}
@@ -529,10 +538,10 @@ static uint8_t USBD_CDC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
* @param req: usb requests
* @retval status
*/
-static uint8_t USBD_CDC_Setup(USBD_HandleTypeDef *pdev,
- USBD_SetupReqTypedef *req)
+static uint8_t USBD_CDC_Setup(USBD_HandleTypeDef *pdev,
+ USBD_SetupReqTypedef *req)
{
- USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *) pdev->pClassData;
+ USBD_CDC_HandleTypeDef *hcdc = cdc_handle;
uint8_t ifalt = 0U;
uint16_t status_info = 0U;
USBD_StatusTypeDef ret = USBD_OK;
@@ -541,9 +550,9 @@ static uint8_t USBD_CDC_Setup(USBD_HandleTypeDef *pdev,
case USB_REQ_TYPE_CLASS:
if (req->wLength != 0U) {
if ((req->bmRequest & 0x80U) != 0U) {
- ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest,
- (uint8_t *)hcdc->data,
- req->wLength);
+ cdc_itf->Control(req->bRequest,
+ (uint8_t *)hcdc->data,
+ req->wLength);
(void)USBD_CtlSendData(pdev, (uint8_t *)hcdc->data, req->wLength);
} else {
@@ -553,8 +562,8 @@ static uint8_t USBD_CDC_Setup(USBD_HandleTypeDef *pdev,
(void)USBD_CtlPrepareRx(pdev, (uint8_t *)hcdc->data, req->wLength);
}
} else {
- ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest,
- (uint8_t *)req, 0U);
+ cdc_itf->Control(req->bRequest,
+ (uint8_t *)req, 0U);
}
break;
@@ -611,17 +620,18 @@ static uint8_t USBD_CDC_Setup(USBD_HandleTypeDef *pdev,
* @param epnum: endpoint number
* @retval status
*/
-static uint8_t USBD_CDC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
+static uint8_t USBD_CDC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
{
- USBD_CDC_HandleTypeDef *hcdc;
+ USBD_CDC_HandleTypeDef *hcdc = cdc_handle;
PCD_HandleTypeDef *hpcd = pdev->pData;
+ USBD_CDC_ItfTypeDef *ctrl = cdc_itf;
if (pdev->pClassData == NULL) {
return (uint8_t)USBD_FAIL;
}
- hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData;
- if ((pdev->ep_in[epnum].total_length > 0U) && ((pdev->ep_in[epnum].total_length % hpcd->IN_ep[epnum].maxpacket) == 0U)) {
+ if ((pdev->ep_in[epnum].total_length > 0U) &&
+ ((pdev->ep_in[epnum].total_length % hpcd->IN_ep[epnum].maxpacket) == 0U)) {
/* Update the packet total length */
pdev->ep_in[epnum].total_length = 0U;
@@ -629,7 +639,7 @@ static uint8_t USBD_CDC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
(void)USBD_LL_Transmit(pdev, epnum, NULL, 0U);
} else {
hcdc->TxState = 0U;
- ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->TransmitCplt(hcdc->TxBuffer, &hcdc->TxLength, epnum);
+ ctrl->TransmitCplt(hcdc->TxBuffer, &hcdc->TxLength, epnum);
}
return (uint8_t)USBD_OK;
@@ -642,10 +652,9 @@ static uint8_t USBD_CDC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
* @param epnum: endpoint number
* @retval status
*/
-static uint8_t USBD_CDC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
+static uint8_t USBD_CDC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
{
- USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData;
-
+ USBD_CDC_HandleTypeDef *hcdc = cdc_handle;
if (pdev->pClassData == NULL) {
return (uint8_t)USBD_FAIL;
}
@@ -656,7 +665,7 @@ static uint8_t USBD_CDC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
/* USB data will be immediately processed, this allow next USB traffic being
NAKed till the end of the application Xfer */
- ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Receive(hcdc->RxBuffer, &hcdc->RxLength);
+ cdc_itf->Receive(hcdc->RxBuffer, &hcdc->RxLength);
return (uint8_t)USBD_OK;
}
@@ -667,14 +676,14 @@ static uint8_t USBD_CDC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
* @param pdev: device instance
* @retval status
*/
-static uint8_t USBD_CDC_EP0_RxReady(USBD_HandleTypeDef *pdev)
+static uint8_t USBD_CDC_EP0_RxReady(USBD_HandleTypeDef *pdev)
{
- USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData;
+ USBD_CDC_HandleTypeDef *hcdc = cdc_handle;
- if ((pdev->pUserData != NULL) && (hcdc->CmdOpCode != 0xFFU)) {
- ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(hcdc->CmdOpCode,
- (uint8_t *)hcdc->data,
- (uint16_t)hcdc->CmdLength);
+ if ((hcdc->CmdOpCode != 0xFFU)) {
+ cdc_itf->Control(hcdc->CmdOpCode,
+ (uint8_t *)hcdc->data,
+ (uint16_t)hcdc->CmdLength);
hcdc->CmdOpCode = 0xFFU;
}
@@ -689,7 +698,7 @@ static uint8_t USBD_CDC_EP0_RxReady(USBD_HandleTypeDef *pdev)
* @param length : pointer data length
* @retval pointer to descriptor buffer
*/
-static uint8_t *USBD_CDC_GetFSCfgDesc(uint16_t *length)
+static uint8_t *USBD_CDC_GetFSCfgDesc(uint16_t *length)
{
*length = (uint16_t)sizeof(USBD_CDC_CfgFSDesc);
@@ -703,7 +712,7 @@ static uint8_t *USBD_CDC_GetFSCfgDesc(uint16_t *length)
* @param length : pointer data length
* @retval pointer to descriptor buffer
*/
-static uint8_t *USBD_CDC_GetHSCfgDesc(uint16_t *length)
+static uint8_t *USBD_CDC_GetHSCfgDesc(uint16_t *length)
{
*length = (uint16_t)sizeof(USBD_CDC_CfgHSDesc);
@@ -717,7 +726,7 @@ static uint8_t *USBD_CDC_GetHSCfgDesc(uint16_t *length)
* @param length : pointer data length
* @retval pointer to descriptor buffer
*/
-static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length)
+static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length)
{
*length = (uint16_t)sizeof(USBD_CDC_OtherSpeedCfgDesc);
@@ -730,7 +739,7 @@ static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length)
* @param length : pointer data length
* @retval pointer to descriptor buffer
*/
-uint8_t *USBD_CDC_GetDeviceQualifierDescriptor(uint16_t *length)
+uint8_t *USBD_CDC_GetDeviceQualifierDescriptor(uint16_t *length)
{
*length = (uint16_t)sizeof(USBD_CDC_DeviceQualifierDesc);
@@ -743,14 +752,14 @@ uint8_t *USBD_CDC_GetDeviceQualifierDescriptor(uint16_t *length)
* @param fops: CD Interface callback
* @retval status
*/
-uint8_t USBD_CDC_RegisterInterface(USBD_HandleTypeDef *pdev,
- USBD_CDC_ItfTypeDef *fops)
+uint8_t USBD_CDC_RegisterInterface(USBD_HandleTypeDef *pdev,
+ USBD_CDC_ItfTypeDef *fops)
{
if (fops == NULL) {
return (uint8_t)USBD_FAIL;
}
- pdev->pUserData = fops;
+ cdc_itf = fops;
return (uint8_t)USBD_OK;
}
@@ -761,10 +770,10 @@ uint8_t USBD_CDC_RegisterInterface(USBD_HandleTypeDef *pdev,
* @param pbuff: Tx Buffer
* @retval status
*/
-uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev,
- uint8_t *pbuff, uint32_t length)
+uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev,
+ uint8_t *pbuff, uint32_t length)
{
- USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData;
+ USBD_CDC_HandleTypeDef *hcdc = cdc_handle;
hcdc->TxBuffer = pbuff;
hcdc->TxLength = length;
@@ -779,9 +788,9 @@ uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev,
* @param pbuff: Rx Buffer
* @retval status
*/
-uint8_t USBD_CDC_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff)
+uint8_t USBD_CDC_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff)
{
- USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData;
+ USBD_CDC_HandleTypeDef *hcdc = cdc_handle;
hcdc->RxBuffer = pbuff;
@@ -794,9 +803,9 @@ uint8_t USBD_CDC_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff)
* @param pdev: device instance
* @retval status
*/
-uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev)
+uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev)
{
- USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData;
+ USBD_CDC_HandleTypeDef *hcdc = cdc_handle;
USBD_StatusTypeDef ret = USBD_BUSY;
if (pdev->pClassData == NULL) {
@@ -826,9 +835,9 @@ uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev)
* @param pdev: device instance
* @retval status
*/
-uint8_t USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev)
+uint8_t USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev)
{
- USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData;
+ USBD_CDC_HandleTypeDef *hcdc = cdc_handle;
if (pdev->pClassData == NULL) {
return (uint8_t)USBD_FAIL;
@@ -859,6 +868,6 @@ uint8_t USBD_CDC_ClearBuffer(USBD_HandleTypeDef *pdev)
}
}
-#endif /* USBD_USE_CDC */
+#endif /* USBD_USE_CDC_CLASS */
#endif /* USBCON */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/cores/arduino/stm32/usb/cdc/usbd_cdc.h b/cores/arduino/stm32/usb/cdc/usbd_cdc.h
index 5395708c06..5a9bce8606 100644
--- a/cores/arduino/stm32/usb/cdc/usbd_cdc.h
+++ b/cores/arduino/stm32/usb/cdc/usbd_cdc.h
@@ -38,6 +38,7 @@ extern "C" {
* @{
*/
+
/** @defgroup usbd_cdc_Exported_Defines
* @{
*/
@@ -126,8 +127,13 @@ typedef struct {
* @{
*/
+
extern USBD_ClassTypeDef USBD_CDC;
-#define USBD_CDC_CLASS &USBD_CDC
+
+extern USBD_CDC_HandleTypeDef *cdc_handle;
+
+extern USBD_CDC_ItfTypeDef *cdc_itf;
+
/**
* @}
*/
@@ -135,16 +141,17 @@ extern USBD_ClassTypeDef USBD_CDC;
/** @defgroup USB_CORE_Exported_Functions
* @{
*/
-uint8_t USBD_CDC_RegisterInterface(USBD_HandleTypeDef *pdev,
- USBD_CDC_ItfTypeDef *fops);
+uint8_t USBD_CDC_RegisterInterface(USBD_HandleTypeDef *pdev,
+ USBD_CDC_ItfTypeDef *fops);
+
+uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff,
+ uint32_t length);
-uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff,
- uint32_t length);
+uint8_t USBD_CDC_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff);
+uint8_t USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev);
+uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev);
+uint8_t USBD_CDC_ClearBuffer(USBD_HandleTypeDef *pdev);
-uint8_t USBD_CDC_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff);
-uint8_t USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev);
-uint8_t USBD_CDC_ClearBuffer(USBD_HandleTypeDef *pdev);
-uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev);
/**
* @}
*/
diff --git a/cores/arduino/stm32/usb/cdc/usbd_cdc_if.c b/cores/arduino/stm32/usb/cdc/usbd_cdc_if.c
index c09675f95e..6b731641b4 100644
--- a/cores/arduino/stm32/usb/cdc/usbd_cdc_if.c
+++ b/cores/arduino/stm32/usb/cdc/usbd_cdc_if.c
@@ -17,8 +17,10 @@
******************************************************************************
*/
+#include "usbd_ep_conf.h"
+
#ifdef USBCON
-#ifdef USBD_USE_CDC
+#ifdef USBD_USE_CDC_CLASS
/* Includes ------------------------------------------------------------------*/
#include "usbd_desc.h"
@@ -44,9 +46,7 @@
/* USBD_CDC Private Variables */
/* USB Device Core CDC handle declaration */
-USBD_HandleTypeDef hUSBD_Device_CDC;
-
-static bool CDC_initialized = false;
+USBD_HandleTypeDef *hUSBD_Device_CDC;
/* Received Data over USB are stored in this buffer */
CDC_TransmitQueue_TypeDef TransmitQueue;
@@ -98,7 +98,7 @@ static int8_t USBD_CDC_Init(void)
CDC_TransmitQueue_Init(&TransmitQueue);
CDC_ReceiveQueue_Init(&ReceiveQueue);
receivePended = true;
- USBD_CDC_SetRxBuffer(&hUSBD_Device_CDC, CDC_ReceiveQueue_ReserveBlock(&ReceiveQueue));
+ USBD_CDC_SetRxBuffer(hUSBD_Device_CDC, CDC_ReceiveQueue_ReserveBlock(&ReceiveQueue));
return ((int8_t)USBD_OK);
}
@@ -235,7 +235,7 @@ static int8_t USBD_CDC_Receive(uint8_t *Buf, uint32_t *Len)
receivePended = false;
/* If enough space in the queue for a full buffer then continue receive */
if (!CDC_resume_receive()) {
- USBD_CDC_ClearBuffer(&hUSBD_Device_CDC);
+ USBD_CDC_ClearBuffer(hUSBD_Device_CDC);
}
return ((int8_t)USBD_OK);
}
@@ -264,34 +264,6 @@ static int8_t USBD_CDC_TransmitCplt(uint8_t *Buf, uint32_t *Len, uint8_t epnum)
return ((int8_t)USBD_OK);
}
-void CDC_init(void)
-{
- if (!CDC_initialized) {
- /* Init Device Library */
- if (USBD_Init(&hUSBD_Device_CDC, &USBD_Desc, 0) == USBD_OK) {
- /* Add Supported Class */
- if (USBD_RegisterClass(&hUSBD_Device_CDC, USBD_CDC_CLASS) == USBD_OK) {
- /* Add CDC Interface Class */
- if (USBD_CDC_RegisterInterface(&hUSBD_Device_CDC, &USBD_CDC_fops) == USBD_OK) {
- /* Start Device Process */
- USBD_Start(&hUSBD_Device_CDC);
- CDC_initialized = true;
- }
- }
- }
- }
-}
-
-void CDC_deInit(void)
-{
- if (CDC_initialized) {
- USBD_Stop(&hUSBD_Device_CDC);
- USBD_CDC_DeInit();
- USBD_DeInit(&hUSBD_Device_CDC);
- CDC_initialized = false;
- }
-}
-
bool CDC_connected()
{
/* Save the transmitStart value in a local variable to avoid twice reading - fix #478 */
@@ -299,16 +271,16 @@ bool CDC_connected()
if (transmitTime) {
transmitTime = HAL_GetTick() - transmitTime;
}
- return ((hUSBD_Device_CDC.dev_state == USBD_STATE_CONFIGURED)
- && (transmitTime < USB_CDC_TRANSMIT_TIMEOUT)
- && lineState);
+ return hUSBD_Device_CDC->dev_state == USBD_STATE_CONFIGURED
+ && transmitTime < USB_CDC_TRANSMIT_TIMEOUT
+ && lineState;
}
void CDC_continue_transmit(void)
{
uint16_t size;
uint8_t *buffer;
- USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *) hUSBD_Device_CDC.pClassData;
+ USBD_CDC_HandleTypeDef *hcdc = cdc_handle;
/*
* TS: This method can be called both in the main thread
* (via USBSerial::write) and in the IRQ stream (via USBD_CDC_TransmistCplt),
@@ -321,12 +293,12 @@ void CDC_continue_transmit(void)
buffer = CDC_TransmitQueue_ReadBlock(&TransmitQueue, &size);
if (size > 0) {
transmitStart = HAL_GetTick();
- USBD_CDC_SetTxBuffer(&hUSBD_Device_CDC, buffer, size);
+ USBD_CDC_SetTxBuffer(hUSBD_Device_CDC, buffer, size);
/*
* size never exceed PMA buffer and USBD_CDC_TransmitPacket make full
* copy of block in PMA, so no need to worry about buffer damage
*/
- USBD_CDC_TransmitPacket(&hUSBD_Device_CDC);
+ USBD_CDC_TransmitPacket(hUSBD_Device_CDC);
}
}
}
@@ -342,8 +314,8 @@ bool CDC_resume_receive(void)
if (block != NULL) {
receivePended = true;
/* Set new buffer */
- USBD_CDC_SetRxBuffer(&hUSBD_Device_CDC, block);
- USBD_CDC_ReceivePacket(&hUSBD_Device_CDC);
+ USBD_CDC_SetRxBuffer(hUSBD_Device_CDC, block);
+ USBD_CDC_ReceivePacket(hUSBD_Device_CDC);
return true;
}
}
diff --git a/cores/arduino/stm32/usb/cdc/usbd_cdc_if.h b/cores/arduino/stm32/usb/cdc/usbd_cdc_if.h
index b415ac16de..1f2e311471 100644
--- a/cores/arduino/stm32/usb/cdc/usbd_cdc_if.h
+++ b/cores/arduino/stm32/usb/cdc/usbd_cdc_if.h
@@ -22,7 +22,7 @@
#define __USBD_CDC_IF_H
#ifdef USBCON
-#ifdef USBD_USE_CDC
+#ifdef USBD_USE_CDC_CLASS
#ifdef __cplusplus
extern "C" {
@@ -39,6 +39,7 @@ extern "C" {
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
+extern USBD_HandleTypeDef *hUSBD_Device_CDC;
extern USBD_CDC_ItfTypeDef USBD_CDC_fops;
extern CDC_TransmitQueue_TypeDef TransmitQueue;
extern CDC_ReceiveQueue_TypeDef ReceiveQueue;
@@ -48,8 +49,6 @@ extern CDC_ReceiveQueue_TypeDef ReceiveQueue;
/* Exported functions ------------------------------------------------------- */
void CDC_continue_transmit(void);
bool CDC_resume_receive(void);
-void CDC_init(void);
-void CDC_deInit(void);
bool CDC_connected(void);
#ifdef __cplusplus
diff --git a/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp b/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp
new file mode 100644
index 0000000000..d846a4a965
--- /dev/null
+++ b/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp
@@ -0,0 +1,514 @@
+/**
+ ******************************************************************************
+ * @file usbd_template.c
+ * @author MCD Application Team
+ * @brief This file provides the HID core functions.
+ *
+ * @verbatim
+ *
+ * ===================================================================
+ * COMPOSITE Class Description
+ * ===================================================================
+ *
+ *
+ *
+ *
+ *
+ *
+ * @note In HS mode and when the DMA is used, all variables and data structures
+ * dealing with the DMA during the transaction process should be 32-bit aligned.
+ *
+ *
+ * @endverbatim
+ *
+ ******************************************************************************
+ * @attention
+ *
+ *
© Copyright (c) 2015 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+
+#include "usbd_ep_conf.h"
+
+#ifdef USBCON
+#ifdef USBD_USE_CDC_MSC
+
+#include "usbd_cdc_msc.h"
+#include "usbd_ctlreq.h"
+
+static uint8_t USBD_COMPOSITE_Init(USBD_HandleTypeDef *pdev,
+ uint8_t cfgidx);
+
+static uint8_t USBD_COMPOSITE_DeInit(USBD_HandleTypeDef *pdev,
+ uint8_t cfgidx);
+
+static uint8_t USBD_COMPOSITE_Setup(USBD_HandleTypeDef *pdev,
+ USBD_SetupReqTypedef *req);
+
+static uint8_t *USBD_COMPOSITE_GetHSCfgDesc(uint16_t *length);
+
+static uint8_t *USBD_COMPOSITE_GetFSCfgDesc(uint16_t *length);
+
+static uint8_t *USBD_COMPOSITE_GetOtherSpeedCfgDesc(uint16_t *length);
+
+static uint8_t *USBD_COMPOSITE_GetDeviceQualifierDesc(uint16_t *length);
+
+static uint8_t USBD_COMPOSITE_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum);
+
+static uint8_t USBD_COMPOSITE_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum);
+
+static uint8_t USBD_COMPOSITE_EP0_RxReady(USBD_HandleTypeDef *pdev);
+
+
+USBD_ClassTypeDef USBD_CDC_MSC = {
+ USBD_COMPOSITE_Init,
+ USBD_COMPOSITE_DeInit,
+ USBD_COMPOSITE_Setup,
+ nullptr,
+ USBD_COMPOSITE_EP0_RxReady,
+ USBD_COMPOSITE_DataIn,
+ USBD_COMPOSITE_DataOut,
+ nullptr,
+ nullptr,
+ nullptr,
+ USBD_COMPOSITE_GetHSCfgDesc,
+ USBD_COMPOSITE_GetFSCfgDesc,
+ USBD_COMPOSITE_GetOtherSpeedCfgDesc,
+ USBD_COMPOSITE_GetDeviceQualifierDesc,
+};
+
+
+#define EP_ATTR_BULK 0x02
+#define EP_ATTR_INTERRUPT 0x03
+
+#define IF_CLASS_COMM 0x02
+#define IF_CLASS_CDC 0x0A
+#define IF_CLASS_MSC 0x08
+
+#define IF_SUBCLASS_NONE 0x00
+#define IF_SUBCLASS_ACM 0x02
+#define IF_SUBCLASS_SCSI_TRANSPARENT 0x06
+
+#define ENDPOINT_DESCRIPTOR(_EP_ADDR, _ATTR, _PACKET_SIZE, _BINTERVAL) \
+ 0x07, /* bLength: Endpoint Descriptor size */ \
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ \
+ _EP_ADDR, /* bEndpointAddress */ \
+ _ATTR, /* bmAttributes: Interrupt */ \
+ LOBYTE(_PACKET_SIZE), /* wMaxPacketSize: */ \
+ HIBYTE(_PACKET_SIZE), \
+ _BINTERVAL /* bInterval: */
+
+
+/* ACM Interface Descriptor */
+#define INTERFACE_DESCRIPTOR(_IF_NUM, _EP_COUNT, _CLASS, _SUBCLASS, _PROT) \
+ 0x09, /* bLength: Interface Descriptor size */ \
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */ \
+ /* Interface descriptor type */ \
+ _IF_NUM, /* bInterfaceNumber: Number of Interface */ \
+ 0x00, /* bAlternateSetting: Alternate setting */ \
+ _EP_COUNT, /* bNumEndpoints: One endpoints used */ \
+ _CLASS, /* bInterfaceClass: Communication Interface Class */ \
+ _SUBCLASS, /* bInterfaceSubClass: Abstract Control Model */ \
+ _PROT, /* bInterfaceProtocol: Common AT commands */ \
+ 0x05 /* iInterface: */
+
+
+
+#define USB_DESC_TYPE_INTERFACE_ASSOC_DESC 0x0B
+
+#define CONFIGURATION_DESCRIPTOR() \
+ 0x09, /* bLength: Configuation Descriptor size */ \
+ USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ \
+ USB_CDC_MSC_CONFIG_DESC_SIZ, /* wTotalLength: Bytes returned */ \
+ 0x00, \
+ 0x03, /*bNumInterfaces: 3 interface*/ \
+ 0x01, /*bConfigurationValue: Configuration value*/ \
+ 0x02, /*iConfiguration: Index of string descriptor describing the configuration*/ \
+ 0xC0, /*bmAttributes: bus powered and Supports Remote Wakeup */ \
+ 0x32 /*MaxPower 100 mA: this current is used for detecting Vbus*/
+/* 09 */
+
+/******** IAD should be positioned just before the CDC interfaces ******
+ IAD to associate the two CDC interfaces */
+#define IAD_DESCRIPTOR() \
+ 0x08, /* bLength: Interface Descriptor size */ \
+ USB_DESC_TYPE_INTERFACE_ASSOC_DESC, /* bDescriptorType: Interface */ \
+ 0x00, /* bFirstInterface */ \
+ 0x02, /* bInterfaceCount */ \
+ 0x02, /* bFunctionClass */ \
+ 0x02, /* bFunctionSubClass */ \
+ 0x01, /* bFunctionProtocol */ \
+ 0x04 /* iFunction (Index of string descriptor describing this function) */
+/* 08 */
+
+/* ACM Interface Descriptor */
+#define ACM_INTERFACE_DESCRIPTOR() INTERFACE_DESCRIPTOR(CDC_ACM_INTERFACE, 0x01, IF_CLASS_COMM, IF_SUBCLASS_ACM, 0x01)
+
+/* Header Functional Descriptor */
+#define ACM_HEADER_FUNCTIONAL_DESCRIPTOR() \
+ 0x05, /* bLength: Endpoint Descriptor size */ \
+ 0x24, /* bDescriptorType: CS_INTERFACE */ \
+ 0x00, /* bDescriptorSubtype: Header Func Desc */ \
+ 0x10, /* bcdCDC: spec release number */ \
+ 0x01
+
+/* ACM Call Management Functional Descriptor */
+#define ACM_CALL_MANAGEMENT_FUNCTIONAL_DESCRIPTOR() \
+ 0x05, /* bFunctionLength */ \
+ 0x24, /* bDescriptorType: CS_INTERFACE */ \
+ 0x01, /* bDescriptorSubtype: Call Management Func Desc */ \
+ 0x00, /* bmCapabilities: D0+D1 */ \
+ CDC_COM_INTERFACE /* bDataInterface: 1 */ \
+
+/* ACM Functional Descriptor */
+#define ACM_FUNCTIONAL_DESCRIPTOR() \
+ 0x04, /* bFunctionLength */ \
+ 0x24, /* bDescriptorType: CS_INTERFACE */ \
+ 0x02, /* bDescriptorSubtype: Abstract Control Management desc */ \
+ 0x02 /* bmCapabilities */
+
+#define ACM_UNION_FUNCTIONAL_DESCRIPTOR() \
+ 0x05, /* bFunctionLength */ \
+ 0x24, /* bDescriptorType: CS_INTERFACE */ \
+ 0x06, /* bDescriptorSubtype: Union func desc */ \
+ CDC_ACM_INTERFACE, /* bMasterInterface: Communication class interface */ \
+ CDC_COM_INTERFACE /* bSlaveInterface0: Data Class Interface */
+
+#define ACM_EP_DESCRIPTOR(_BINTERVAL) ENDPOINT_DESCRIPTOR(CDC_CMD_EP, EP_ATTR_INTERRUPT, CDC_CMD_PACKET_SIZE, _BINTERVAL)
+
+#define CDC_INTERFACE_DESCRIPTOR() INTERFACE_DESCRIPTOR(CDC_COM_INTERFACE, 0x02, IF_CLASS_CDC, IF_SUBCLASS_NONE, 0x00)
+#define CDC_EP_OUT_DESCRIPTOR(_PACKET_SIZE) ENDPOINT_DESCRIPTOR(CDC_OUT_EP, EP_ATTR_BULK, _PACKET_SIZE, 0x00)
+#define CDC_EP_IN_DESCRIPTOR(_PACKET_SIZE) ENDPOINT_DESCRIPTOR(CDC_IN_EP, EP_ATTR_BULK, _PACKET_SIZE, 0x00)
+
+#define MSC_INTERFACE_DESCRIPTOR() INTERFACE_DESCRIPTOR(MSC_INTERFACE, 0x02, IF_CLASS_MSC, IF_SUBCLASS_SCSI_TRANSPARENT, 0x50)
+#define MSC_EP_IN_DESCRIPTOR(_PACKET_SIZE) ENDPOINT_DESCRIPTOR(MSC_EPIN_ADDR, EP_ATTR_BULK, _PACKET_SIZE, 0x00)
+#define MSC_EP_OUT_DESCRIPTOR(_PACKET_SIZE) ENDPOINT_DESCRIPTOR(MSC_EPOUT_ADDR, EP_ATTR_BULK, _PACKET_SIZE, 0x00)
+
+
+#if defined ( __ICCARM__ ) /*!< IAR Compiler */
+ #pragma data_alignment=4
+#endif
+
+
+/* USB COMPOSITE device Configuration Descriptor */
+#if defined ( __ICCARM__ ) /*!< IAR Compiler */
+ #pragma data_alignment=4
+#endif
+static uint8_t USBD_COMPOSITE_HSCfgDesc[USB_CDC_MSC_CONFIG_DESC_SIZ] = {
+ CONFIGURATION_DESCRIPTOR(),
+ IAD_DESCRIPTOR(),
+
+ ACM_INTERFACE_DESCRIPTOR(),
+ ACM_HEADER_FUNCTIONAL_DESCRIPTOR(),
+ ACM_CALL_MANAGEMENT_FUNCTIONAL_DESCRIPTOR(),
+ ACM_FUNCTIONAL_DESCRIPTOR(),
+ ACM_UNION_FUNCTIONAL_DESCRIPTOR(),
+ ACM_EP_DESCRIPTOR(CDC_HS_BINTERVAL),
+
+ CDC_INTERFACE_DESCRIPTOR(),
+ CDC_EP_OUT_DESCRIPTOR(CDC_DATA_HS_MAX_PACKET_SIZE),
+ CDC_EP_IN_DESCRIPTOR(CDC_DATA_HS_MAX_PACKET_SIZE),
+
+ MSC_INTERFACE_DESCRIPTOR(),
+ MSC_EP_IN_DESCRIPTOR(MSC_MAX_HS_PACKET),
+ MSC_EP_OUT_DESCRIPTOR(MSC_MAX_HS_PACKET)
+};
+
+#if defined ( __ICCARM__ ) /*!< IAR Compiler */
+ #pragma data_alignment=4
+#endif
+/* USB COMPOSITE device Configuration Descriptor */
+static uint8_t USBD_COMPOSITE_FSCfgDesc[USB_CDC_MSC_CONFIG_DESC_SIZ] = {
+ CONFIGURATION_DESCRIPTOR(),
+ IAD_DESCRIPTOR(),
+
+ ACM_INTERFACE_DESCRIPTOR(),
+ ACM_HEADER_FUNCTIONAL_DESCRIPTOR(),
+ ACM_CALL_MANAGEMENT_FUNCTIONAL_DESCRIPTOR(),
+ ACM_FUNCTIONAL_DESCRIPTOR(),
+ ACM_UNION_FUNCTIONAL_DESCRIPTOR(),
+ ACM_EP_DESCRIPTOR(CDC_FS_BINTERVAL),
+
+ CDC_INTERFACE_DESCRIPTOR(),
+ CDC_EP_OUT_DESCRIPTOR(CDC_DATA_FS_MAX_PACKET_SIZE),
+ CDC_EP_IN_DESCRIPTOR(CDC_DATA_FS_MAX_PACKET_SIZE),
+
+ MSC_INTERFACE_DESCRIPTOR(),
+ MSC_EP_IN_DESCRIPTOR(MSC_MAX_FS_PACKET),
+ MSC_EP_OUT_DESCRIPTOR(MSC_MAX_FS_PACKET)
+};
+
+
+#if defined ( __ICCARM__ ) /*!< IAR Compiler */
+ #pragma data_alignment=4
+#endif
+/* USB COMPOSITE device Configuration Descriptor */
+static uint8_t USBD_COMPOSITE_OtherSpeedCfgDesc[USB_CDC_MSC_CONFIG_DESC_SIZ] = {
+ CONFIGURATION_DESCRIPTOR(),
+ IAD_DESCRIPTOR(),
+
+ ACM_INTERFACE_DESCRIPTOR(),
+ ACM_HEADER_FUNCTIONAL_DESCRIPTOR(),
+ ACM_CALL_MANAGEMENT_FUNCTIONAL_DESCRIPTOR(),
+ ACM_FUNCTIONAL_DESCRIPTOR(),
+ ACM_UNION_FUNCTIONAL_DESCRIPTOR(),
+ ACM_EP_DESCRIPTOR(CDC_FS_BINTERVAL),
+
+ CDC_INTERFACE_DESCRIPTOR(),
+ CDC_EP_OUT_DESCRIPTOR(CDC_DATA_FS_MAX_PACKET_SIZE),
+ CDC_EP_IN_DESCRIPTOR(CDC_DATA_FS_MAX_PACKET_SIZE),
+
+ MSC_INTERFACE_DESCRIPTOR(),
+ MSC_EP_IN_DESCRIPTOR(MSC_MAX_FS_PACKET),
+ MSC_EP_OUT_DESCRIPTOR(MSC_MAX_FS_PACKET)
+};
+
+
+#if defined ( __ICCARM__ ) /*!< IAR Compiler */
+ #pragma data_alignment=4
+#endif
+/* USB Standard Device Descriptor */
+static uint8_t USBD_COMPOSITE_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] = {
+ USB_LEN_DEV_QUALIFIER_DESC,
+ USB_DESC_TYPE_DEVICE_QUALIFIER,
+ 0x00,
+ 0x02,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x40,
+ 0x01,
+ 0x00,
+};
+
+int cdcMscInitialised;
+
+/**
+ * @brief USBD_COMPOSITE_Init
+ * Initialize the COMPOSITE interface
+ * @param pdev: device instance
+ * @param cfgidx: Configuration index
+ * @retval status
+ */
+static uint8_t USBD_COMPOSITE_Init(USBD_HandleTypeDef *pdev,
+ uint8_t cfgidx)
+{
+ USBD_MSC.Init(pdev, cfgidx);
+
+ USBD_CDC.Init(pdev, cfgidx);
+
+ pdev->pClassData = &cdcMscInitialised;
+
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_COMPOSITE_Init
+ * DeInitialize the COMPOSITE layer
+ * @param pdev: device instance
+ * @param cfgidx: Configuration index
+ * @retval status
+ */
+static uint8_t USBD_COMPOSITE_DeInit(USBD_HandleTypeDef *pdev,
+ uint8_t cfgidx)
+{
+ USBD_MSC.DeInit(pdev, cfgidx);
+
+ USBD_CDC.DeInit(pdev, cfgidx);
+
+ if (pdev->pClassData == &cdcMscInitialised) {
+ pdev->pClassData = nullptr;
+ }
+
+ return USBD_OK;
+}
+
+/**
+ * @brief USBD_COMPOSITE_Setup
+ * Handle the COMPOSITE specific requests
+ * @param pdev: instance
+ * @param req: usb requests
+ * @retval status
+ */
+static uint8_t USBD_COMPOSITE_Setup(USBD_HandleTypeDef *pdev,
+ USBD_SetupReqTypedef *req)
+{
+ switch (req->bmRequest & USB_REQ_RECIPIENT_MASK) {
+ case USB_REQ_RECIPIENT_INTERFACE:
+ switch (req->wIndex) {
+ case CDC_ACM_INTERFACE:
+ case CDC_COM_INTERFACE:
+ return USBD_CDC.Setup(pdev, req);
+ break;
+
+ case MSC_INTERFACE:
+ return USBD_MSC.Setup(pdev, req);
+ break;
+
+ // invalid interface
+ default:
+ return USBD_FAIL;
+ }
+ break;
+
+ case USB_REQ_RECIPIENT_ENDPOINT:
+ switch (req->wIndex) {
+ case CDC_IN_EP:
+ case CDC_OUT_EP:
+ case CDC_CMD_EP:
+ return USBD_CDC.Setup(pdev, req);
+
+ case MSC_EPIN_ADDR:
+ case MSC_EPOUT_ADDR:
+ return USBD_MSC.Setup(pdev, req);
+
+ // invalid endpoint
+ default:
+ return USBD_FAIL;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return USBD_OK;
+}
+
+
+/**
+ * @brief USBD_COMPOSITE_GetHSCfgDesc
+ * return configuration descriptor
+ * @param length : pointer data length
+ * @retval pointer to descriptor buffer
+ */
+static uint8_t *USBD_COMPOSITE_GetHSCfgDesc(uint16_t *length)
+{
+ *length = sizeof(USBD_COMPOSITE_HSCfgDesc);
+ return USBD_COMPOSITE_HSCfgDesc;
+}
+
+/**
+ * @brief USBD_COMPOSITE_GetFSCfgDesc
+ * return configuration descriptor
+ * @param length : pointer data length
+ * @retval pointer to descriptor buffer
+ */
+static uint8_t *USBD_COMPOSITE_GetFSCfgDesc(uint16_t *length)
+{
+ *length = sizeof(USBD_COMPOSITE_FSCfgDesc);
+ return USBD_COMPOSITE_FSCfgDesc;
+}
+
+/**
+ * @brief USBD_COMPOSITE_GetOtherSpeedCfgDesc
+ * return configuration descriptor
+ * @param length : pointer data length
+ * @retval pointer to descriptor buffer
+ */
+static uint8_t *USBD_COMPOSITE_GetOtherSpeedCfgDesc(uint16_t *length)
+{
+ *length = sizeof(USBD_COMPOSITE_OtherSpeedCfgDesc);
+ return USBD_COMPOSITE_OtherSpeedCfgDesc;
+}
+
+/**
+* @brief DeviceQualifierDescriptor
+* return Device Qualifier descriptor
+* @param length : pointer data length
+* @retval pointer to descriptor buffer
+*/
+uint8_t *USBD_COMPOSITE_DeviceQualifierDescriptor(uint16_t *length)
+{
+ *length = sizeof(USBD_COMPOSITE_DeviceQualifierDesc);
+ return USBD_COMPOSITE_DeviceQualifierDesc;
+}
+
+
+/**
+ * @brief USBD_COMPOSITE_DataIn
+ * handle data IN Stage
+ * @param pdev: device instance
+ * @param epnum: endpoint index
+ * @retval status
+ */
+static uint8_t USBD_COMPOSITE_DataIn(USBD_HandleTypeDef *pdev,
+ uint8_t epnum)
+{
+ switch (epnum) {
+ case CDC_IN_EP:
+ case CDC_CMD_EP:
+ case CDC_OUT_EP:
+ return USBD_CDC.DataIn(pdev, epnum);
+
+ case MSC_EPIN_ADDR:
+ case MSC_EPOUT_ADDR:
+ return USBD_MSC.DataIn(pdev, epnum);
+
+ // invalid endpoint
+ default:
+ return USBD_FAIL;
+ }
+}
+
+/**
+ * @brief USBD_COMPOSITE_EP0_RxReady
+ * handle EP0 Rx Ready event
+ * @param pdev: device instance
+ * @retval status
+ */
+static uint8_t USBD_COMPOSITE_EP0_RxReady(USBD_HandleTypeDef *pdev)
+{
+ // only needed by CDC
+ return USBD_CDC.EP0_RxReady(pdev);
+}
+
+/**
+ * @brief USBD_COMPOSITE_DataOut
+ * handle data OUT Stage
+ * @param pdev: device instance
+ * @param epnum: endpoint index
+ * @retval status
+ */
+static uint8_t USBD_COMPOSITE_DataOut(USBD_HandleTypeDef *pdev,
+ uint8_t epnum)
+{
+ switch (epnum) {
+ case CDC_IN_EP:
+ case CDC_CMD_EP:
+ case CDC_OUT_EP:
+ return USBD_CDC.DataOut(pdev, epnum);
+
+ case MSC_EPIN_ADDR:
+ case MSC_EPOUT_ADDR:
+ return USBD_MSC.DataOut(pdev, epnum);
+
+ // invalid endpoint
+ default:
+ return USBD_FAIL;
+ }
+}
+
+/**
+* @brief DeviceQualifierDescriptor
+* return Device Qualifier descriptor
+* @param length : pointer data length
+* @retval pointer to descriptor buffer
+*/
+uint8_t *USBD_COMPOSITE_GetDeviceQualifierDesc(uint16_t *length)
+{
+ *length = sizeof(USBD_COMPOSITE_DeviceQualifierDesc);
+ return USBD_COMPOSITE_DeviceQualifierDesc;
+}
+
+#endif /* USBD_USE_MSC_CLASS */
+#endif /* USBCON */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.h b/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.h
new file mode 100644
index 0000000000..e8110535d8
--- /dev/null
+++ b/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.h
@@ -0,0 +1,39 @@
+/**
+ ******************************************************************************
+ * @file usbd_cdc_msc_core.h
+ * @author MCD Application Team
+ * @version V1.2.1
+ * @date 17-March-2018
+ * @brief header file for the usbd_cdc_msc_core.c file.
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2015 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ *
+ *
+ ******************************************************************************
+ */
+
+#ifndef __USB_CDC_MSC_CORE_H_
+#define __USB_CDC_MSC_CORE_H_
+
+#include "usbd_cdc.h"
+#include "usbd_msc.h"
+#include "usbd_ioreq.h"
+
+#define CDC_ACM_INTERFACE 0x0
+#define CDC_COM_INTERFACE 0x1
+#define MSC_INTERFACE 0x2
+
+#define USB_CDC_MSC_CONFIG_DESC_SIZ (USB_CDC_CONFIG_DESC_SIZ - 9 + 8 + USB_MSC_CONFIG_DESC_SIZ)
+
+extern USBD_ClassTypeDef USBD_CDC_MSC;
+
+#endif /* __USB_CDC_MSC_CORE_H_ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc.c b/cores/arduino/stm32/usb/msc/usbd_msc.c
new file mode 100644
index 0000000000..742d747c30
--- /dev/null
+++ b/cores/arduino/stm32/usb/msc/usbd_msc.c
@@ -0,0 +1,494 @@
+/**
+ ******************************************************************************
+ * @file usbd_msc.c
+ * @author MCD Application Team
+ * @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 (c) 2015 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+
+/* BSPDependencies
+- "stm32xxxxx_{eval}{discovery}{nucleo_144}.c"
+- "stm32xxxxx_{eval}{discovery}_io.c"
+- "stm32xxxxx_{eval}{discovery}{adafruit}_sd.c"
+EndBSPDependencies */
+
+#include "usbd_ep_conf.h"
+
+#ifdef USBCON
+#ifdef USBD_USE_MSC_CLASS
+
+#include "usbd_msc.h"
+#include "usbd_msc_storage_if.h"
+
+
+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);
+
+
+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 static 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 */
+__ALIGN_BEGIN static 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 static 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 static 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,
+};
+/**
+ * @}
+ */
+
+USBD_MSC_BOT_HandleTypeDef msc_handle_dat;
+USBD_MSC_BOT_HandleTypeDef *msc_handle = &msc_handle_dat;
+
+USBD_StorageTypeDef *msc_storage = &USBD_MSC_fops;
+
+int mscInitialized;
+
+/**
+ * @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)
+{
+ UNUSED(cfgidx);
+ pdev->pClassData = &mscInitialized;
+
+ if (pdev->dev_speed == USBD_SPEED_HIGH) {
+ /* Open EP OUT */
+ (void)USBD_LL_OpenEP(pdev, MSC_EPOUT_ADDR, USBD_EP_TYPE_BULK, MSC_MAX_HS_PACKET);
+ pdev->ep_out[MSC_EPOUT_ADDR & 0xFU].is_used = 1U;
+
+ /* Open EP IN */
+ (void)USBD_LL_OpenEP(pdev, MSC_EPIN_ADDR, USBD_EP_TYPE_BULK, MSC_MAX_HS_PACKET);
+ pdev->ep_in[MSC_EPIN_ADDR & 0xFU].is_used = 1U;
+ } else {
+ /* Open EP OUT */
+ (void)USBD_LL_OpenEP(pdev, MSC_EPOUT_ADDR, USBD_EP_TYPE_BULK, MSC_MAX_FS_PACKET);
+ pdev->ep_out[MSC_EPOUT_ADDR & 0xFU].is_used = 1U;
+
+ /* Open EP IN */
+ (void)USBD_LL_OpenEP(pdev, MSC_EPIN_ADDR, USBD_EP_TYPE_BULK, MSC_MAX_FS_PACKET);
+ pdev->ep_in[MSC_EPIN_ADDR & 0xFU].is_used = 1U;
+ }
+
+ /* Init the BOT layer */
+ MSC_BOT_Init(pdev);
+
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_MSC_DeInit
+ * DeInitialize 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)
+{
+ UNUSED(cfgidx);
+
+ /* Close MSC EPs */
+ (void)USBD_LL_CloseEP(pdev, MSC_EPOUT_ADDR);
+ pdev->ep_out[MSC_EPOUT_ADDR & 0xFU].is_used = 0U;
+
+ /* Close EP IN */
+ (void)USBD_LL_CloseEP(pdev, MSC_EPIN_ADDR);
+ pdev->ep_in[MSC_EPIN_ADDR & 0xFU].is_used = 0U;
+
+ /* De-Init the BOT layer */
+ MSC_BOT_DeInit(pdev);
+
+ if (pdev->pClassData == &mscInitialized) {
+ // only mark as uninitialised if we own the initialisation
+ pdev->pClassData = NULL;
+ }
+
+ return (uint8_t)USBD_OK;
+}
+
+/**
+* @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 = msc_handle;
+ uint8_t ret = USBD_OK;
+ uint16_t status_info = 0U;
+
+ 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 == 0U) && (req->wLength == 1U) &&
+ ((req->bmRequest & 0x80U) == 0x80U)) {
+ hmsc->max_lun = (uint32_t)msc_storage->GetMaxLun();
+ (void)USBD_CtlSendData(pdev, (uint8_t *)&hmsc->max_lun, 1U);
+ } else {
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ }
+ break;
+
+ case BOT_RESET:
+ if ((req->wValue == 0U) && (req->wLength == 0U) &&
+ ((req->bmRequest & 0x80U) != 0x80U)) {
+ MSC_BOT_Reset(pdev);
+ } else {
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ }
+ break;
+
+ default:
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ break;
+ }
+ break;
+ /* Interface & Endpoint request */
+ case USB_REQ_TYPE_STANDARD:
+ switch (req->bRequest) {
+ case USB_REQ_GET_STATUS:
+ if (pdev->dev_state == USBD_STATE_CONFIGURED) {
+ (void)USBD_CtlSendData(pdev, (uint8_t *)&status_info, 2U);
+ } else {
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ }
+ break;
+
+ case USB_REQ_GET_INTERFACE:
+ if (pdev->dev_state == USBD_STATE_CONFIGURED) {
+ (void)USBD_CtlSendData(pdev, (uint8_t *)&hmsc->interface, 1U);
+ } else {
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ }
+ break;
+
+ case USB_REQ_SET_INTERFACE:
+ if (pdev->dev_state == USBD_STATE_CONFIGURED) {
+ hmsc->interface = (uint8_t)(req->wValue);
+ } else {
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ }
+ break;
+
+ case USB_REQ_CLEAR_FEATURE:
+ if (pdev->dev_state == USBD_STATE_CONFIGURED) {
+ if (req->wValue == USB_FEATURE_EP_HALT) {
+ /* Flush the FIFO */
+ (void)USBD_LL_FlushEP(pdev, (uint8_t)req->wIndex);
+
+ /* Handle BOT error */
+ MSC_BOT_CplClrFeature(pdev, (uint8_t)req->wIndex);
+ }
+ }
+ break;
+
+ default:
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ break;
+ }
+ break;
+
+ default:
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ break;
+ }
+
+ return (uint8_t)ret;
+}
+
+/**
+* @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 (uint8_t)USBD_OK;
+}
+
+/**
+* @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 (uint8_t)USBD_OK;
+}
+
+/**
+* @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 = (uint16_t)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 = (uint16_t)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 = (uint16_t)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 = (uint16_t)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) {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ msc_storage = fops;
+
+ return (uint8_t)USBD_OK;
+}
+
+#endif /* USBD_USE_MSC_CLASS */
+#endif /* USBCON */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc.h b/cores/arduino/stm32/usb/msc/usbd_msc.h
new file mode 100644
index 0000000000..a3001d570c
--- /dev/null
+++ b/cores/arduino/stm32/usb/msc/usbd_msc.h
@@ -0,0 +1,100 @@
+/**
+ ******************************************************************************
+ * @file usbd_msc.h
+ * @author MCD Application Team
+ * @brief Header for the usbd_msc.c file
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2015 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USBD_MSC_H
+#define __USBD_MSC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "usbd_msc_bot.h"
+#include "usbd_msc_scsi.h"
+#include "usbd_ioreq.h"
+
+/* MSC Class Config */
+#ifndef MSC_MEDIA_PACKET
+#define MSC_MEDIA_PACKET 512U
+#endif /* MSC_MEDIA_PACKET */
+
+#define MSC_MAX_FS_PACKET 0x40U
+#define MSC_MAX_HS_PACKET 0x200U
+
+#define BOT_GET_MAX_LUN 0xFE
+#define BOT_RESET 0xFF
+#define USB_MSC_CONFIG_DESC_SIZ 32
+
+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);
+ uint8_t *pInquiry;
+
+} USBD_StorageTypeDef;
+
+
+typedef struct {
+ uint32_t max_lun;
+ uint32_t interface;
+ uint8_t bot_state;
+ uint8_t bot_status;
+ uint32_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;
+ uint8_t scsi_medium_state;
+
+ 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;
+#define USBD_MSC_CLASS &USBD_MSC
+
+/* Handle */
+extern USBD_MSC_BOT_HandleTypeDef *msc_handle;
+extern USBD_StorageTypeDef *msc_storage;
+
+uint8_t USBD_MSC_RegisterStorage(USBD_HandleTypeDef *pdev,
+ USBD_StorageTypeDef *fops);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __USBD_MSC_H */
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc_bot.c b/cores/arduino/stm32/usb/msc/usbd_msc_bot.c
new file mode 100644
index 0000000000..d3338d2292
--- /dev/null
+++ b/cores/arduino/stm32/usb/msc/usbd_msc_bot.c
@@ -0,0 +1,301 @@
+/**
+ ******************************************************************************
+ * @file usbd_msc_bot.c
+ * @author MCD Application Team
+ * @brief This file provides all the BOT protocol core functions.
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2015 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+
+/* BSPDependencies
+- "stm32xxxxx_{eval}{discovery}{nucleo_144}.c"
+- "stm32xxxxx_{eval}{discovery}_io.c"
+- "stm32xxxxx_{eval}{discovery}{adafruit}_sd.c"
+EndBSPDependencies */
+
+#include "usbd_ep_conf.h"
+
+#ifdef USBCON
+#ifdef USBD_USE_MSC_CLASS
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_msc_bot.h"
+#include "usbd_msc.h"
+#include "usbd_msc_scsi.h"
+#include "usbd_ioreq.h"
+
+static void MSC_BOT_SendData(USBD_HandleTypeDef *pdev, uint8_t *pbuf, uint32_t len);
+static void MSC_BOT_CBW_Decode(USBD_HandleTypeDef *pdev);
+static void MSC_BOT_Abort(USBD_HandleTypeDef *pdev);
+
+
+/**
+* @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 = msc_handle;
+
+ hmsc->bot_state = USBD_BOT_IDLE;
+ hmsc->bot_status = USBD_BOT_STATUS_NORMAL;
+
+ hmsc->scsi_sense_tail = 0U;
+ hmsc->scsi_sense_head = 0U;
+ hmsc->scsi_medium_state = SCSI_MEDIUM_UNLOCKED;
+
+ msc_storage->Init(0U);
+
+ (void)USBD_LL_FlushEP(pdev, MSC_EPOUT_ADDR);
+ (void)USBD_LL_FlushEP(pdev, MSC_EPIN_ADDR);
+
+ /* Prapare EP to Receive First BOT Cmd */
+ (void)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 = msc_handle;
+
+ hmsc->bot_state = USBD_BOT_IDLE;
+ hmsc->bot_status = USBD_BOT_STATUS_RECOVERY;
+
+ (void)USBD_LL_ClearStallEP(pdev, MSC_EPIN_ADDR);
+ (void)USBD_LL_ClearStallEP(pdev, MSC_EPOUT_ADDR);
+
+ /* Prapare EP to Receive First BOT Cmd */
+ (void)USBD_LL_PrepareReceive(pdev, MSC_EPOUT_ADDR, (uint8_t *)&hmsc->cbw,
+ USBD_BOT_CBW_LENGTH);
+}
+
+/**
+* @brief MSC_BOT_DeInit
+* Deinitialize the BOT Machine
+* @param pdev: device instance
+* @retval None
+*/
+void MSC_BOT_DeInit(USBD_HandleTypeDef *pdev)
+{
+ USBD_MSC_BOT_HandleTypeDef *hmsc = msc_handle;
+ 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)
+{
+ UNUSED(epnum);
+
+ USBD_MSC_BOT_HandleTypeDef *hmsc = msc_handle;
+
+ 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
+* Process MSC OUT data
+* @param pdev: device instance
+* @param epnum: endpoint index
+* @retval None
+*/
+void MSC_BOT_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
+{
+ UNUSED(epnum);
+
+ USBD_MSC_BOT_HandleTypeDef *hmsc = msc_handle;
+
+ 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 accordingly
+* @param pdev: device instance
+* @retval None
+*/
+static void MSC_BOT_CBW_Decode(USBD_HandleTypeDef *pdev)
+{
+ USBD_MSC_BOT_HandleTypeDef *hmsc = msc_handle;
+
+ 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 > 1U) || (hmsc->cbw.bCBLength < 1U) ||
+ (hmsc->cbw.bCBLength > 16U)) {
+ 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 > 0U) {
+ MSC_BOT_SendData(pdev, hmsc->bot_data, hmsc->bot_data_length);
+ } else if (hmsc->bot_data_length == 0U) {
+ MSC_BOT_SendCSW(pdev, USBD_CSW_CMD_PASSED);
+ } else {
+ MSC_BOT_Abort(pdev);
+ }
+ } else {
+ return;
+ }
+ }
+}
+
+/**
+* @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 *pbuf, uint32_t len)
+{
+ USBD_MSC_BOT_HandleTypeDef *hmsc = msc_handle;
+
+ uint32_t length = MIN(hmsc->cbw.dDataLength, len);
+
+ hmsc->csw.dDataResidue -= len;
+ hmsc->csw.bStatus = USBD_CSW_CMD_PASSED;
+ hmsc->bot_state = USBD_BOT_SEND_DATA;
+
+ (void)USBD_LL_Transmit(pdev, MSC_EPIN_ADDR, pbuf, length);
+}
+
+/**
+* @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 = msc_handle;
+
+ hmsc->csw.dSignature = USBD_BOT_CSW_SIGNATURE;
+ hmsc->csw.bStatus = CSW_Status;
+ hmsc->bot_state = USBD_BOT_IDLE;
+
+ (void)USBD_LL_Transmit(pdev, MSC_EPIN_ADDR, (uint8_t *)&hmsc->csw,
+ USBD_BOT_CSW_LENGTH);
+
+ /* Prepare EP to Receive next Cmd */
+ (void)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 = msc_handle;
+
+ if ((hmsc->cbw.bmFlags == 0U) &&
+ (hmsc->cbw.dDataLength != 0U) &&
+ (hmsc->bot_status == USBD_BOT_STATUS_NORMAL)) {
+ (void)USBD_LL_StallEP(pdev, MSC_EPOUT_ADDR);
+ }
+
+ (void)USBD_LL_StallEP(pdev, MSC_EPIN_ADDR);
+
+ if (hmsc->bot_status == USBD_BOT_STATUS_ERROR) {
+ (void)USBD_LL_StallEP(pdev, MSC_EPIN_ADDR);
+ (void)USBD_LL_StallEP(pdev, MSC_EPOUT_ADDR);
+ }
+}
+
+/**
+* @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 = msc_handle;
+
+ if (hmsc->bot_status == USBD_BOT_STATUS_ERROR) {
+ /* Bad CBW Signature */
+ (void)USBD_LL_StallEP(pdev, MSC_EPIN_ADDR);
+ (void)USBD_LL_StallEP(pdev, MSC_EPOUT_ADDR);
+ } else if (((epnum & 0x80U) == 0x80U) && (hmsc->bot_status != USBD_BOT_STATUS_RECOVERY)) {
+ MSC_BOT_SendCSW(pdev, USBD_CSW_CMD_FAILED);
+ } else {
+ return;
+ }
+}
+
+#endif /* USBD_USE_MSC_CLASS */
+#endif /* USBCON */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc_bot.h b/cores/arduino/stm32/usb/msc/usbd_msc_bot.h
new file mode 100644
index 0000000000..de1af53223
--- /dev/null
+++ b/cores/arduino/stm32/usb/msc/usbd_msc_bot.h
@@ -0,0 +1,104 @@
+/**
+ ******************************************************************************
+ * @file usbd_msc_bot.h
+ * @author MCD Application Team
+ * @brief Header for the usbd_msc_bot.c file
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2015 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USBD_MSC_BOT_H
+#define __USBD_MSC_BOT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_core.h"
+
+#define USBD_BOT_IDLE 0U /* Idle state */
+#define USBD_BOT_DATA_OUT 1U /* Data Out state */
+#define USBD_BOT_DATA_IN 2U /* Data In state */
+#define USBD_BOT_LAST_DATA_IN 3U /* Last Data In Last */
+#define USBD_BOT_SEND_DATA 4U /* Send Immediate data */
+#define USBD_BOT_NO_DATA 5U /* No data Stage */
+
+#define USBD_BOT_CBW_SIGNATURE 0x43425355U
+#define USBD_BOT_CSW_SIGNATURE 0x53425355U
+#define USBD_BOT_CBW_LENGTH 31U
+#define USBD_BOT_CSW_LENGTH 13U
+#define USBD_BOT_MAX_DATA 256U
+
+/* CSW Status Definitions */
+#define USBD_CSW_CMD_PASSED 0x00U
+#define USBD_CSW_CMD_FAILED 0x01U
+#define USBD_CSW_PHASE_ERROR 0x02U
+
+/* BOT Status */
+#define USBD_BOT_STATUS_NORMAL 0U
+#define USBD_BOT_STATUS_RECOVERY 1U
+#define USBD_BOT_STATUS_ERROR 2U
+
+
+#define USBD_DIR_IN 0U
+#define USBD_DIR_OUT 1U
+#define USBD_BOTH_DIR 2U
+
+
+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;
+
+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);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __USBD_MSC_BOT_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc_data.c b/cores/arduino/stm32/usb/msc/usbd_msc_data.c
new file mode 100644
index 0000000000..a2ae3c0f31
--- /dev/null
+++ b/cores/arduino/stm32/usb/msc/usbd_msc_data.c
@@ -0,0 +1,120 @@
+/**
+ ******************************************************************************
+ * @file usbd_msc_data.c
+ * @author MCD Application Team
+ * @brief This file provides all the vital inquiry pages and sense data.
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2015 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+
+/* BSPDependencies
+- "stm32xxxxx_{eval}{discovery}{nucleo_144}.c"
+- "stm32xxxxx_{eval}{discovery}_io.c"
+- "stm32xxxxx_{eval}{discovery}{adafruit}_sd.c"
+EndBSPDependencies */
+
+#include "usbd_ep_conf.h"
+
+#ifdef USBCON
+#ifdef USBD_USE_MSC_CLASS
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_msc_data.h"
+
+
+/* USB Mass storage Page 0 Inquiry Data */
+uint8_t MSC_Page00_Inquiry_Data[LENGTH_INQUIRY_PAGE00] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ (LENGTH_INQUIRY_PAGE00 - 4U),
+ 0x00,
+ 0x80
+};
+
+/* USB Mass storage VPD Page 0x80 Inquiry Data for Unit Serial Number */
+uint8_t MSC_Page80_Inquiry_Data[LENGTH_INQUIRY_PAGE80] = {
+ 0x00,
+ 0x80,
+ 0x00,
+ LENGTH_INQUIRY_PAGE80,
+ 0x20, /* Put Product Serial number */
+ 0x20,
+ 0x20,
+ 0x20
+};
+
+/* USB Mass storage sense 6 Data */
+uint8_t MSC_Mode_Sense6_data[MODE_SENSE6_LEN] = {
+ 0x22,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x08,
+ 0x12,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+
+/* USB Mass storage sense 10 Data */
+uint8_t MSC_Mode_Sense10_data[MODE_SENSE10_LEN] = {
+ 0x00,
+ 0x26,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x08,
+ 0x12,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+
+#endif /* USBD_USE_MSC_CLASS */
+#endif /* USBCON */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc_data.h b/cores/arduino/stm32/usb/msc/usbd_msc_data.h
new file mode 100644
index 0000000000..24ab8cf1a2
--- /dev/null
+++ b/cores/arduino/stm32/usb/msc/usbd_msc_data.h
@@ -0,0 +1,51 @@
+/**
+ ******************************************************************************
+ * @file usbd_msc_data.h
+ * @author MCD Application Team
+ * @brief Header for the usbd_msc_data.c file
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2015 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USBD_MSC_DATA_H
+#define __USBD_MSC_DATA_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_conf.h"
+
+
+#define MODE_SENSE6_LEN 0x17U
+#define MODE_SENSE10_LEN 0x1BU
+#define LENGTH_INQUIRY_PAGE00 0x06U
+#define LENGTH_INQUIRY_PAGE80 0x08U
+#define LENGTH_FORMAT_CAPACITIES 0x14U
+
+
+extern uint8_t MSC_Page00_Inquiry_Data[LENGTH_INQUIRY_PAGE00];
+extern uint8_t MSC_Page80_Inquiry_Data[LENGTH_INQUIRY_PAGE80];
+extern uint8_t MSC_Mode_Sense6_data[MODE_SENSE6_LEN];
+extern uint8_t MSC_Mode_Sense10_data[MODE_SENSE10_LEN];
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __USBD_MSC_DATA_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc_scsi.c b/cores/arduino/stm32/usb/msc/usbd_msc_scsi.c
new file mode 100644
index 0000000000..269bc30ff4
--- /dev/null
+++ b/cores/arduino/stm32/usb/msc/usbd_msc_scsi.c
@@ -0,0 +1,953 @@
+/**
+ ******************************************************************************
+ * @file usbd_msc_scsi.c
+ * @author MCD Application Team
+ * @brief This file provides all the USBD SCSI layer functions.
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2015 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+
+/* BSPDependencies
+- "stm32xxxxx_{eval}{discovery}{nucleo_144}.c"
+- "stm32xxxxx_{eval}{discovery}_io.c"
+- "stm32xxxxx_{eval}{discovery}{adafruit}_sd.c"
+EndBSPDependencies */
+
+#include "usbd_ep_conf.h"
+
+#ifdef USBCON
+#ifdef USBD_USE_MSC_CLASS
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_msc_bot.h"
+#include "usbd_msc_scsi.h"
+#include "usbd_msc.h"
+#include "usbd_msc_data.h"
+
+
+
+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_ReadCapacity16(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_AllowPreventRemovable(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_Write12(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_Read12(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, uint32_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);
+
+static int8_t SCSI_UpdateBotData(USBD_MSC_BOT_HandleTypeDef *hmsc,
+ uint8_t *pBuff, uint16_t length);
+
+/**
+* @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 *cmd)
+{
+ int8_t ret;
+ USBD_MSC_BOT_HandleTypeDef *hmsc = msc_handle;
+
+ switch (cmd[0]) {
+ case SCSI_TEST_UNIT_READY:
+ ret = SCSI_TestUnitReady(pdev, lun, cmd);
+ break;
+
+ case SCSI_REQUEST_SENSE:
+ ret = SCSI_RequestSense(pdev, lun, cmd);
+ break;
+
+ case SCSI_INQUIRY:
+ ret = SCSI_Inquiry(pdev, lun, cmd);
+ break;
+
+ case SCSI_START_STOP_UNIT:
+ ret = SCSI_StartStopUnit(pdev, lun, cmd);
+ break;
+
+ case SCSI_ALLOW_MEDIUM_REMOVAL:
+ ret = SCSI_AllowPreventRemovable(pdev, lun, cmd);
+ break;
+
+ case SCSI_MODE_SENSE6:
+ ret = SCSI_ModeSense6(pdev, lun, cmd);
+ break;
+
+ case SCSI_MODE_SENSE10:
+ ret = SCSI_ModeSense10(pdev, lun, cmd);
+ break;
+
+ case SCSI_READ_FORMAT_CAPACITIES:
+ ret = SCSI_ReadFormatCapacity(pdev, lun, cmd);
+ break;
+
+ case SCSI_READ_CAPACITY10:
+ ret = SCSI_ReadCapacity10(pdev, lun, cmd);
+ break;
+
+ case SCSI_READ_CAPACITY16:
+ ret = SCSI_ReadCapacity16(pdev, lun, cmd);
+ break;
+
+ case SCSI_READ10:
+ ret = SCSI_Read10(pdev, lun, cmd);
+ break;
+
+ case SCSI_READ12:
+ ret = SCSI_Read12(pdev, lun, cmd);
+ break;
+
+ case SCSI_WRITE10:
+ ret = SCSI_Write10(pdev, lun, cmd);
+ break;
+
+ case SCSI_WRITE12:
+ ret = SCSI_Write12(pdev, lun, cmd);
+ break;
+
+ case SCSI_VERIFY10:
+ ret = SCSI_Verify10(pdev, lun, cmd);
+ break;
+
+ default:
+ SCSI_SenseCode(pdev, lun, ILLEGAL_REQUEST, INVALID_CDB);
+ hmsc->bot_status = USBD_BOT_STATUS_ERROR;
+ ret = -1;
+ break;
+ }
+
+ return ret;
+}
+
+
+/**
+* @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)
+{
+ UNUSED(params);
+ USBD_MSC_BOT_HandleTypeDef *hmsc = msc_handle;
+
+ /* case 9 : Hi > D0 */
+ if (hmsc->cbw.dDataLength != 0U) {
+ SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB);
+
+ return -1;
+ }
+
+ if (hmsc->scsi_medium_state == SCSI_MEDIUM_EJECTED) {
+ SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT);
+ hmsc->bot_state = USBD_BOT_NO_DATA;
+ return -1;
+ }
+
+ if (msc_storage->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 = 0U;
+
+ 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 = msc_handle;
+
+ if (hmsc->cbw.dDataLength == 0U) {
+ SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB);
+ return -1;
+ }
+
+ if ((params[1] & 0x01U) != 0U) {
+ /* Evpd is set */
+ if (params[2] == 0U) {
+ /* Request for Supported Vital Product Data Pages*/
+ (void)SCSI_UpdateBotData(hmsc, MSC_Page00_Inquiry_Data, LENGTH_INQUIRY_PAGE00);
+ } else if (params[2] == 0x80U) {
+ /* Request for VPD page 0x80 Unit Serial Number */
+ (void)SCSI_UpdateBotData(hmsc, MSC_Page80_Inquiry_Data, LENGTH_INQUIRY_PAGE80);
+ } else {
+ /* Request Not supported */
+ SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST,
+ INVALID_FIELED_IN_COMMAND);
+
+ return -1;
+ }
+ } else {
+ pPage = &msc_storage->pInquiry[lun * STANDARD_INQUIRY_DATA_LEN];
+ len = (uint16_t)pPage[4] + 5U;
+
+ if (params[4] <= len) {
+ len = params[4];
+ }
+
+ (void)SCSI_UpdateBotData(hmsc, 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)
+{
+ UNUSED(params);
+ int8_t ret;
+ USBD_MSC_BOT_HandleTypeDef *hmsc = msc_handle;
+
+ ret = msc_storage->GetCapacity(lun, &hmsc->scsi_blk_nbr, &hmsc->scsi_blk_size);
+
+ if ((ret != 0) || (hmsc->scsi_medium_state == SCSI_MEDIUM_EJECTED)) {
+ SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT);
+ return -1;
+ }
+
+ hmsc->bot_data[0] = (uint8_t)((hmsc->scsi_blk_nbr - 1U) >> 24);
+ hmsc->bot_data[1] = (uint8_t)((hmsc->scsi_blk_nbr - 1U) >> 16);
+ hmsc->bot_data[2] = (uint8_t)((hmsc->scsi_blk_nbr - 1U) >> 8);
+ hmsc->bot_data[3] = (uint8_t)(hmsc->scsi_blk_nbr - 1U);
+
+ 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 = 8U;
+
+ return 0;
+
+}
+
+
+/**
+* @brief SCSI_ReadCapacity16
+* Process Read Capacity 16 command
+* @param lun: Logical unit number
+* @param params: Command parameters
+* @retval status
+*/
+static int8_t SCSI_ReadCapacity16(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
+{
+ UNUSED(params);
+ uint8_t idx;
+ int8_t ret;
+ USBD_MSC_BOT_HandleTypeDef *hmsc = msc_handle;
+
+ ret = msc_storage->GetCapacity(lun, &hmsc->scsi_blk_nbr, &hmsc->scsi_blk_size);
+
+ if ((ret != 0) || (hmsc->scsi_medium_state == SCSI_MEDIUM_EJECTED)) {
+ SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT);
+ return -1;
+ }
+
+ hmsc->bot_data_length = ((uint32_t)params[10] << 24) |
+ ((uint32_t)params[11] << 16) |
+ ((uint32_t)params[12] << 8) |
+ (uint32_t)params[13];
+
+ for (idx = 0U; idx < hmsc->bot_data_length; idx++) {
+ hmsc->bot_data[idx] = 0U;
+ }
+
+ hmsc->bot_data[4] = (uint8_t)((hmsc->scsi_blk_nbr - 1U) >> 24);
+ hmsc->bot_data[5] = (uint8_t)((hmsc->scsi_blk_nbr - 1U) >> 16);
+ hmsc->bot_data[6] = (uint8_t)((hmsc->scsi_blk_nbr - 1U) >> 8);
+ hmsc->bot_data[7] = (uint8_t)(hmsc->scsi_blk_nbr - 1U);
+
+ hmsc->bot_data[8] = (uint8_t)(hmsc->scsi_blk_size >> 24);
+ hmsc->bot_data[9] = (uint8_t)(hmsc->scsi_blk_size >> 16);
+ hmsc->bot_data[10] = (uint8_t)(hmsc->scsi_blk_size >> 8);
+ hmsc->bot_data[11] = (uint8_t)(hmsc->scsi_blk_size);
+
+ hmsc->bot_data_length = ((uint32_t)params[10] << 24) |
+ ((uint32_t)params[11] << 16) |
+ ((uint32_t)params[12] << 8) |
+ (uint32_t)params[13];
+
+ 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)
+{
+ UNUSED(params);
+ uint16_t blk_size;
+ uint32_t blk_nbr;
+ uint16_t i;
+ int8_t ret;
+ USBD_MSC_BOT_HandleTypeDef *hmsc = msc_handle;
+
+ ret = msc_storage->GetCapacity(lun, &blk_nbr, &blk_size);
+
+ if ((ret != 0) || (hmsc->scsi_medium_state == SCSI_MEDIUM_EJECTED)) {
+ SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT);
+ return -1;
+ }
+
+ for (i = 0U; i < 12U ; i++) {
+ hmsc->bot_data[i] = 0U;
+ }
+
+ hmsc->bot_data[3] = 0x08U;
+ hmsc->bot_data[4] = (uint8_t)((blk_nbr - 1U) >> 24);
+ hmsc->bot_data[5] = (uint8_t)((blk_nbr - 1U) >> 16);
+ hmsc->bot_data[6] = (uint8_t)((blk_nbr - 1U) >> 8);
+ hmsc->bot_data[7] = (uint8_t)(blk_nbr - 1U);
+
+ hmsc->bot_data[8] = 0x02U;
+ 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 = 12U;
+
+ 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)
+{
+ UNUSED(lun);
+ USBD_MSC_BOT_HandleTypeDef *hmsc = msc_handle;
+ uint16_t len = MODE_SENSE6_LEN;
+
+ if (params[4] <= len) {
+ len = params[4];
+ }
+
+ (void)SCSI_UpdateBotData(hmsc, 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)
+{
+ UNUSED(lun);
+ USBD_MSC_BOT_HandleTypeDef *hmsc = msc_handle;
+ uint16_t len = MODE_SENSE10_LEN;
+
+ if (params[8] <= len) {
+ len = params[8];
+ }
+
+ (void)SCSI_UpdateBotData(hmsc, 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)
+{
+ UNUSED(lun);
+ uint8_t i;
+ USBD_MSC_BOT_HandleTypeDef *hmsc = msc_handle;
+
+ if (hmsc->cbw.dDataLength == 0U) {
+ SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB);
+ return -1;
+ }
+
+ for (i = 0U; i < REQUEST_SENSE_DATA_LEN; i++) {
+ hmsc->bot_data[i] = 0U;
+ }
+
+ hmsc->bot_data[0] = 0x70U;
+ hmsc->bot_data[7] = REQUEST_SENSE_DATA_LEN - 6U;
+
+ if ((hmsc->scsi_sense_head != hmsc->scsi_sense_tail)) {
+ hmsc->bot_data[2] = (uint8_t)hmsc->scsi_sense[hmsc->scsi_sense_head].Skey;
+ hmsc->bot_data[12] = (uint8_t)hmsc->scsi_sense[hmsc->scsi_sense_head].w.b.ASC;
+ hmsc->bot_data[13] = (uint8_t)hmsc->scsi_sense[hmsc->scsi_sense_head].w.b.ASCQ;
+ hmsc->scsi_sense_head++;
+
+ if (hmsc->scsi_sense_head == SENSE_LIST_DEEPTH) {
+ hmsc->scsi_sense_head = 0U;
+ }
+ }
+
+ 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 Code
+* @retval none
+
+*/
+void SCSI_SenseCode(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t sKey, uint8_t ASC)
+{
+ UNUSED(lun);
+ USBD_MSC_BOT_HandleTypeDef *hmsc = msc_handle;
+
+ hmsc->scsi_sense[hmsc->scsi_sense_tail].Skey = sKey;
+ hmsc->scsi_sense[hmsc->scsi_sense_tail].w.b.ASC = ASC;
+ hmsc->scsi_sense[hmsc->scsi_sense_tail].w.b.ASCQ = 0U;
+ hmsc->scsi_sense_tail++;
+
+ if (hmsc->scsi_sense_tail == SENSE_LIST_DEEPTH) {
+ hmsc->scsi_sense_tail = 0U;
+ }
+}
+
+
+/**
+* @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)
+{
+ UNUSED(lun);
+ USBD_MSC_BOT_HandleTypeDef *hmsc = msc_handle;
+
+ if ((hmsc->scsi_medium_state == SCSI_MEDIUM_LOCKED) && ((params[4] & 0x3U) == 2U)) {
+ SCSI_SenseCode(pdev, lun, ILLEGAL_REQUEST, INVALID_FIELED_IN_COMMAND);
+
+ return -1;
+ }
+
+ if ((params[4] & 0x3U) == 0x1U) {
+ /* START=1 */
+ hmsc->scsi_medium_state = SCSI_MEDIUM_UNLOCKED;
+ } else if ((params[4] & 0x3U) == 0x2U) {
+ /* START=0 and LOEJ Load Eject=1 */
+ hmsc->scsi_medium_state = SCSI_MEDIUM_EJECTED;
+ } else if ((params[4] & 0x3U) == 0x3U) {
+ /* START=1 and LOEJ Load Eject=1 */
+ hmsc->scsi_medium_state = SCSI_MEDIUM_UNLOCKED;
+ } else {
+ /* .. */
+ }
+ hmsc->bot_data_length = 0U;
+
+ return 0;
+}
+
+
+/**
+* @brief SCSI_AllowPreventRemovable
+* Process Allow Prevent Removable medium command
+* @param lun: Logical unit number
+* @param params: Command parameters
+* @retval status
+*/
+static int8_t SCSI_AllowPreventRemovable(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
+{
+ UNUSED(lun);
+ USBD_MSC_BOT_HandleTypeDef *hmsc = msc_handle;
+
+ if (params[4] == 0U) {
+ hmsc->scsi_medium_state = SCSI_MEDIUM_UNLOCKED;
+ } else {
+ hmsc->scsi_medium_state = SCSI_MEDIUM_LOCKED;
+ }
+
+ hmsc->bot_data_length = 0U;
+
+ 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 = msc_handle;
+
+ if (hmsc->bot_state == USBD_BOT_IDLE) {
+ /* Idle */
+ /* case 10 : Ho <> Di */
+ if ((hmsc->cbw.bmFlags & 0x80U) != 0x80U) {
+ SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB);
+ return -1;
+ }
+
+ if (hmsc->scsi_medium_state == SCSI_MEDIUM_EJECTED) {
+ SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT);
+
+ return -1;
+ }
+
+ if (msc_storage->IsReady(lun) != 0) {
+ SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT);
+ return -1;
+ }
+
+ hmsc->scsi_blk_addr = ((uint32_t)params[2] << 24) |
+ ((uint32_t)params[3] << 16) |
+ ((uint32_t)params[4] << 8) |
+ (uint32_t)params[5];
+
+ hmsc->scsi_blk_len = ((uint32_t)params[7] << 8) | (uint32_t)params[8];
+
+ if (SCSI_CheckAddressRange(pdev, lun, hmsc->scsi_blk_addr,
+ hmsc->scsi_blk_len) < 0) {
+ return -1; /* error */
+ }
+
+ /* cases 4,5 : Hi <> Dn */
+ if (hmsc->cbw.dDataLength != (hmsc->scsi_blk_len * hmsc->scsi_blk_size)) {
+ SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB);
+ return -1;
+ }
+
+ hmsc->bot_state = USBD_BOT_DATA_IN;
+ }
+ hmsc->bot_data_length = MSC_MEDIA_PACKET;
+
+ return SCSI_ProcessRead(pdev, lun);
+}
+
+
+/**
+* @brief SCSI_Read12
+* Process Read12 command
+* @param lun: Logical unit number
+* @param params: Command parameters
+* @retval status
+*/
+static int8_t SCSI_Read12(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
+{
+ USBD_MSC_BOT_HandleTypeDef *hmsc = msc_handle;
+
+ if (hmsc->bot_state == USBD_BOT_IDLE) {
+ /* Idle */
+ /* case 10 : Ho <> Di */
+ if ((hmsc->cbw.bmFlags & 0x80U) != 0x80U) {
+ SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB);
+ return -1;
+ }
+
+ if (hmsc->scsi_medium_state == SCSI_MEDIUM_EJECTED) {
+ SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT);
+ return -1;
+ }
+
+ if (msc_storage->IsReady(lun) != 0) {
+ SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT);
+ return -1;
+ }
+
+ hmsc->scsi_blk_addr = ((uint32_t)params[2] << 24) |
+ ((uint32_t)params[3] << 16) |
+ ((uint32_t)params[4] << 8) |
+ (uint32_t)params[5];
+
+ hmsc->scsi_blk_len = ((uint32_t)params[6] << 24) |
+ ((uint32_t)params[7] << 16) |
+ ((uint32_t)params[8] << 8) |
+ (uint32_t)params[9];
+
+ if (SCSI_CheckAddressRange(pdev, lun, hmsc->scsi_blk_addr,
+ hmsc->scsi_blk_len) < 0) {
+ return -1; /* error */
+ }
+
+ /* cases 4,5 : Hi <> Dn */
+ if (hmsc->cbw.dDataLength != (hmsc->scsi_blk_len * hmsc->scsi_blk_size)) {
+ SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB);
+ return -1;
+ }
+
+ hmsc->bot_state = USBD_BOT_DATA_IN;
+ }
+ 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 = msc_handle;
+ uint32_t len;
+
+ if (hmsc->bot_state == USBD_BOT_IDLE) {
+ /* Idle */
+ if (hmsc->cbw.dDataLength == 0U) {
+ SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB);
+ return -1;
+ }
+
+ /* case 8 : Hi <> Do */
+ if ((hmsc->cbw.bmFlags & 0x80U) == 0x80U) {
+ SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB);
+ return -1;
+ }
+
+ /* Check whether Media is ready */
+ if (msc_storage->IsReady(lun) != 0) {
+ SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT);
+ return -1;
+ }
+
+ /* Check If media is write-protected */
+ if (msc_storage->IsWriteProtected(lun) != 0) {
+ SCSI_SenseCode(pdev, lun, NOT_READY, WRITE_PROTECTED);
+ return -1;
+ }
+
+ hmsc->scsi_blk_addr = ((uint32_t)params[2] << 24) |
+ ((uint32_t)params[3] << 16) |
+ ((uint32_t)params[4] << 8) |
+ (uint32_t)params[5];
+
+ hmsc->scsi_blk_len = ((uint32_t)params[7] << 8) |
+ (uint32_t)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 */
+ }
+
+ len = hmsc->scsi_blk_len * hmsc->scsi_blk_size;
+
+ /* cases 3,11,13 : Hn,Ho <> D0 */
+ if (hmsc->cbw.dDataLength != len) {
+ SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB);
+ return -1;
+ }
+
+ len = MIN(len, MSC_MEDIA_PACKET);
+
+ /* Prepare EP to receive first data packet */
+ hmsc->bot_state = USBD_BOT_DATA_OUT;
+ (void)USBD_LL_PrepareReceive(pdev, MSC_EPOUT_ADDR, hmsc->bot_data, len);
+ } else {
+ /* Write Process ongoing */
+ return SCSI_ProcessWrite(pdev, lun);
+ }
+
+ return 0;
+}
+
+
+/**
+* @brief SCSI_Write12
+* Process Write12 command
+* @param lun: Logical unit number
+* @param params: Command parameters
+* @retval status
+*/
+static int8_t SCSI_Write12(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
+{
+ USBD_MSC_BOT_HandleTypeDef *hmsc = msc_handle;
+ uint32_t len;
+
+ if (hmsc->bot_state == USBD_BOT_IDLE) {
+ /* Idle */
+ if (hmsc->cbw.dDataLength == 0U) {
+ SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB);
+ return -1;
+ }
+
+ /* case 8 : Hi <> Do */
+ if ((hmsc->cbw.bmFlags & 0x80U) == 0x80U) {
+ SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB);
+ return -1;
+ }
+
+ /* Check whether Media is ready */
+ if (msc_storage->IsReady(lun) != 0) {
+ SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT);
+ hmsc->bot_state = USBD_BOT_NO_DATA;
+ return -1;
+ }
+
+ /* Check If media is write-protected */
+ if (msc_storage->IsWriteProtected(lun) != 0) {
+ SCSI_SenseCode(pdev, lun, NOT_READY, WRITE_PROTECTED);
+ hmsc->bot_state = USBD_BOT_NO_DATA;
+ return -1;
+ }
+
+ hmsc->scsi_blk_addr = ((uint32_t)params[2] << 24) |
+ ((uint32_t)params[3] << 16) |
+ ((uint32_t)params[4] << 8) |
+ (uint32_t)params[5];
+
+ hmsc->scsi_blk_len = ((uint32_t)params[6] << 24) |
+ ((uint32_t)params[7] << 16) |
+ ((uint32_t)params[8] << 8) |
+ (uint32_t)params[9];
+
+ /* 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 */
+ }
+
+ len = hmsc->scsi_blk_len * hmsc->scsi_blk_size;
+
+ /* cases 3,11,13 : Hn,Ho <> D0 */
+ if (hmsc->cbw.dDataLength != len) {
+ SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB);
+ return -1;
+ }
+
+ len = MIN(len, MSC_MEDIA_PACKET);
+
+ /* Prepare EP to receive first data packet */
+ hmsc->bot_state = USBD_BOT_DATA_OUT;
+ (void)USBD_LL_PrepareReceive(pdev, MSC_EPOUT_ADDR, hmsc->bot_data, len);
+ } 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 = msc_handle;
+
+ if ((params[1] & 0x02U) == 0x02U) {
+ 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 = 0U;
+
+ 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, uint32_t blk_nbr)
+{
+ USBD_MSC_BOT_HandleTypeDef *hmsc = msc_handle;
+
+ 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 = msc_handle;
+ uint32_t len = hmsc->scsi_blk_len * hmsc->scsi_blk_size;
+
+ len = MIN(len, MSC_MEDIA_PACKET);
+
+ if (msc_storage->Read(lun,
+ hmsc->bot_data,
+ hmsc->scsi_blk_addr,
+ (len / hmsc->scsi_blk_size)) < 0) {
+ SCSI_SenseCode(pdev, lun, HARDWARE_ERROR, UNRECOVERED_READ_ERROR);
+ return -1;
+ }
+
+ (void)USBD_LL_Transmit(pdev, MSC_EPIN_ADDR, hmsc->bot_data, len);
+
+ hmsc->scsi_blk_addr += (len / hmsc->scsi_blk_size);
+ hmsc->scsi_blk_len -= (len / hmsc->scsi_blk_size);
+
+ /* case 6 : Hi = Di */
+ hmsc->csw.dDataResidue -= len;
+
+ if (hmsc->scsi_blk_len == 0U) {
+ 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)
+{
+ USBD_MSC_BOT_HandleTypeDef *hmsc = msc_handle;
+ uint32_t len = hmsc->scsi_blk_len * hmsc->scsi_blk_size;
+
+ len = MIN(len, MSC_MEDIA_PACKET);
+
+ if (msc_storage->Write(lun, hmsc->bot_data,
+ hmsc->scsi_blk_addr,
+ (len / hmsc->scsi_blk_size)) < 0) {
+ SCSI_SenseCode(pdev, lun, HARDWARE_ERROR, WRITE_FAULT);
+ return -1;
+ }
+
+ hmsc->scsi_blk_addr += (len / hmsc->scsi_blk_size);
+ hmsc->scsi_blk_len -= (len / hmsc->scsi_blk_size);
+
+ /* case 12 : Ho = Do */
+ hmsc->csw.dDataResidue -= len;
+
+ if (hmsc->scsi_blk_len == 0U) {
+ MSC_BOT_SendCSW(pdev, USBD_CSW_CMD_PASSED);
+ } else {
+ len = MIN((hmsc->scsi_blk_len * hmsc->scsi_blk_size), MSC_MEDIA_PACKET);
+
+ /* Prepare EP to Receive next packet */
+ (void)USBD_LL_PrepareReceive(pdev, MSC_EPOUT_ADDR, hmsc->bot_data, len);
+ }
+
+ return 0;
+}
+
+
+/**
+* @brief SCSI_UpdateBotData
+* fill the requested Data to transmit buffer
+* @param hmsc handler
+* @param params: Data buffer
+* @param length: Data length
+* @retval status
+*/
+static int8_t SCSI_UpdateBotData(USBD_MSC_BOT_HandleTypeDef *hmsc,
+ uint8_t *pBuff, uint16_t length)
+{
+ uint16_t len = length;
+
+ hmsc->bot_data_length = len;
+
+ while (len != 0U) {
+ len--;
+ hmsc->bot_data[len] = pBuff[len];
+ }
+
+ return 0;
+}
+
+
+#endif /* USBD_USE_MSC_CLASS */
+#endif /* USBCON */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc_scsi.h b/cores/arduino/stm32/usb/msc/usbd_msc_scsi.h
new file mode 100644
index 0000000000..b39ad35c44
--- /dev/null
+++ b/cores/arduino/stm32/usb/msc/usbd_msc_scsi.h
@@ -0,0 +1,128 @@
+/**
+ ******************************************************************************
+ * @file usbd_msc_scsi.h
+ * @author MCD Application Team
+ * @brief Header for the usbd_msc_scsi.c file
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2015 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USBD_MSC_SCSI_H
+#define __USBD_MSC_SCSI_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_def.h"
+
+#define SENSE_LIST_DEEPTH 4U
+
+/* SCSI Commands */
+#define SCSI_FORMAT_UNIT 0x04U
+#define SCSI_INQUIRY 0x12U
+#define SCSI_MODE_SELECT6 0x15U
+#define SCSI_MODE_SELECT10 0x55U
+#define SCSI_MODE_SENSE6 0x1AU
+#define SCSI_MODE_SENSE10 0x5AU
+#define SCSI_ALLOW_MEDIUM_REMOVAL 0x1EU
+#define SCSI_READ6 0x08U
+#define SCSI_READ10 0x28U
+#define SCSI_READ12 0xA8U
+#define SCSI_READ16 0x88U
+
+#define SCSI_READ_CAPACITY10 0x25U
+#define SCSI_READ_CAPACITY16 0x9EU
+
+#define SCSI_REQUEST_SENSE 0x03U
+#define SCSI_START_STOP_UNIT 0x1BU
+#define SCSI_TEST_UNIT_READY 0x00U
+#define SCSI_WRITE6 0x0AU
+#define SCSI_WRITE10 0x2AU
+#define SCSI_WRITE12 0xAAU
+#define SCSI_WRITE16 0x8AU
+
+#define SCSI_VERIFY10 0x2FU
+#define SCSI_VERIFY12 0xAFU
+#define SCSI_VERIFY16 0x8FU
+
+#define SCSI_SEND_DIAGNOSTIC 0x1DU
+#define SCSI_READ_FORMAT_CAPACITIES 0x23U
+
+#define NO_SENSE 0U
+#define RECOVERED_ERROR 1U
+#define NOT_READY 2U
+#define MEDIUM_ERROR 3U
+#define HARDWARE_ERROR 4U
+#define ILLEGAL_REQUEST 5U
+#define UNIT_ATTENTION 6U
+#define DATA_PROTECT 7U
+#define BLANK_CHECK 8U
+#define VENDOR_SPECIFIC 9U
+#define COPY_ABORTED 10U
+#define ABORTED_COMMAND 11U
+#define VOLUME_OVERFLOW 13U
+#define MISCOMPARE 14U
+
+
+#define INVALID_CDB 0x20U
+#define INVALID_FIELED_IN_COMMAND 0x24U
+#define PARAMETER_LIST_LENGTH_ERROR 0x1AU
+#define INVALID_FIELD_IN_PARAMETER_LIST 0x26U
+#define ADDRESS_OUT_OF_RANGE 0x21U
+#define MEDIUM_NOT_PRESENT 0x3AU
+#define MEDIUM_HAVE_CHANGED 0x28U
+#define WRITE_PROTECTED 0x27U
+#define UNRECOVERED_READ_ERROR 0x11U
+#define WRITE_FAULT 0x03U
+
+#define READ_FORMAT_CAPACITY_DATA_LEN 0x0CU
+#define READ_CAPACITY10_DATA_LEN 0x08U
+#define MODE_SENSE10_DATA_LEN 0x08U
+#define MODE_SENSE6_DATA_LEN 0x04U
+#define REQUEST_SENSE_DATA_LEN 0x12U
+#define STANDARD_INQUIRY_DATA_LEN 0x24U
+#define BLKVFY 0x04U
+
+#define SCSI_MEDIUM_UNLOCKED 0x00U
+#define SCSI_MEDIUM_LOCKED 0x01U
+#define SCSI_MEDIUM_EJECTED 0x02U
+
+typedef struct _SENSE_ITEM {
+ uint8_t Skey;
+ union {
+ struct _ASCs {
+ uint8_t ASC;
+ uint8_t ASCQ;
+ } b;
+ uint8_t ASC;
+ uint8_t *pData;
+ } w;
+} USBD_SCSI_SenseTypeDef;
+
+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);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __USBD_MSC_SCSI_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc_storage_if.cpp b/cores/arduino/stm32/usb/msc/usbd_msc_storage_if.cpp
new file mode 100644
index 0000000000..a614bfe288
--- /dev/null
+++ b/cores/arduino/stm32/usb/msc/usbd_msc_storage_if.cpp
@@ -0,0 +1,189 @@
+/**
+ ******************************************************************************
+ * @file usbd_msc_storage_template.c
+ * @author MCD Application Team
+ * @brief Memory management layer
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2015 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+
+#include "usbd_ep_conf.h"
+
+#ifdef USBCON
+#ifdef USBD_USE_MSC_CLASS
+
+/* BSPDependencies
+- "stm32xxxxx_{eval}{discovery}{nucleo_144}.c"
+- "stm32xxxxx_{eval}{discovery}_io.c"
+- "stm32xxxxx_{eval}{discovery}{adafruit}_sd.c"
+EndBSPDependencies */
+
+#include "USBMscHandler.h"
+#include "usbd_msc_storage_if.h"
+
+uint8_t usbMscMaxLun = 0;
+USBMscHandler **ppUsbMscHandlers = nullptr;
+
+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 */
+uint8_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_fops = {
+ STORAGE_Init,
+ STORAGE_GetCapacity,
+ STORAGE_IsReady,
+ STORAGE_IsWriteProtected,
+ STORAGE_Read,
+ STORAGE_Write,
+ STORAGE_GetMaxLun,
+ STORAGE_Inquirydata,
+};
+
+#define HANDLER_LUN_CHECK \
+ if (lun > usbMscMaxLun) { \
+ return 1; \
+ }
+
+/*******************************************************************************
+* 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)
+{
+ HANDLER_LUN_CHECK
+
+ return !ppUsbMscHandlers[lun]->Init();
+}
+
+/*******************************************************************************
+* 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)
+{
+ HANDLER_LUN_CHECK
+
+ return !ppUsbMscHandlers[lun]->GetCapacity(block_num, block_size);
+}
+
+/*******************************************************************************
+* Function Name : Read_Memory
+* Description : Handle the Read operation from the STORAGE card.
+* Input : None.
+* Output : None.
+* Return : 0 if device is ready, otherwise not ready
+*******************************************************************************/
+int8_t STORAGE_IsReady(uint8_t lun)
+{
+ HANDLER_LUN_CHECK
+
+ return !ppUsbMscHandlers[lun]->IsReady();
+}
+
+/*******************************************************************************
+* 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)
+{
+ HANDLER_LUN_CHECK
+
+ return ppUsbMscHandlers[lun]->IsWriteProtected();
+}
+
+/*******************************************************************************
+* 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)
+{
+ HANDLER_LUN_CHECK
+
+ return !ppUsbMscHandlers[lun]->Read(buf, blk_addr, blk_len);
+}
+
+/*******************************************************************************
+* 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)
+{
+ HANDLER_LUN_CHECK
+
+ return !ppUsbMscHandlers[lun]->Write(buf, blk_addr, blk_len);
+}
+
+/*******************************************************************************
+* 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 usbMscMaxLun;
+}
+
+#endif /* USBD_USE_MSC_CLASS */
+#endif /* USBCON */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc_storage_if.h b/cores/arduino/stm32/usb/msc/usbd_msc_storage_if.h
new file mode 100644
index 0000000000..cddadecda0
--- /dev/null
+++ b/cores/arduino/stm32/usb/msc/usbd_msc_storage_if.h
@@ -0,0 +1,45 @@
+/**
+ ******************************************************************************
+ * @file usbd_msc_storage.h
+ * @author MCD Application Team
+ * @brief Header file for the usbd_msc_storage.c file
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2015 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USBD_MSC_STORAGE_H
+#define __USBD_MSC_STORAGE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "usbd_msc.h"
+
+extern USBD_StorageTypeDef USBD_MSC_fops;
+
+#ifdef __cplusplus
+#include "USBMscHandler.h"
+
+extern uint8_t usbMscMaxLun;
+extern USBMscHandler **ppUsbMscHandlers;
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __USBD_MSC_STORAGE_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/cores/arduino/stm32/usb/usbd_conf.c b/cores/arduino/stm32/usb/usbd_conf.c
index 109f2f56f5..3094d3a331 100644
--- a/cores/arduino/stm32/usb/usbd_conf.c
+++ b/cores/arduino/stm32/usb/usbd_conf.c
@@ -514,13 +514,25 @@ USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev)
/* configure EPs FIFOs */
HAL_PCDEx_SetRxFiFo(&g_hpcd, ep_def[0].ep_size);
for (uint32_t i = 1; i < (DEV_NUM_EP + 1); i++) {
- HAL_PCDEx_SetTxFiFo(&g_hpcd, ep_def[i].ep_adress & 0xF, ep_def[i].ep_size);
+ if (ep_def[i].ep_adress & 0xF0U) {
+ HAL_PCDEx_SetTxFiFo(&g_hpcd, ep_def[i].ep_adress & 0xF, ep_def[i].ep_size);
+ }
}
#else
+ uint32_t offset = PMA_BASE_OFFSET;
for (uint32_t i = 0; i < (DEV_NUM_EP + 1); i++) {
- HAL_PCDEx_PMAConfig(&g_hpcd, ep_def[i].ep_adress, ep_def[i].ep_kind, ep_def[i].ep_size);
+ ep_desc_t *pDesc = &ep_dep[i];
+ uint32_t size = pDesc->ep_size;
+ uint32_t address = offset;
+ if (pDesc->ep_kind == PCD_DBL_BUF) {
+ address = address | ((address + size) << 16U);
+ size *= 2;
+ }
+ HAL_PCDEx_PMAConfig(&g_hpcd, pDesc->ep_adress, pDesc->ep_kind, address);
+ offset += size;
}
#endif /* USE_USB_HS */
+
return USBD_OK;
}
diff --git a/cores/arduino/stm32/usb/usbd_conf.h b/cores/arduino/stm32/usb/usbd_conf.h
index c1a4808380..01ef078aa3 100644
--- a/cores/arduino/stm32/usb/usbd_conf.h
+++ b/cores/arduino/stm32/usb/usbd_conf.h
@@ -40,6 +40,7 @@ extern "C" {
#include
#include
+
#if defined(USB_BASE)
#if defined(STM32F1xx)
diff --git a/cores/arduino/stm32/usb/usbd_desc.c b/cores/arduino/stm32/usb/usbd_desc.c
index 229112ea5f..3d48f046ed 100644
--- a/cores/arduino/stm32/usb/usbd_desc.c
+++ b/cores/arduino/stm32/usb/usbd_desc.c
@@ -37,7 +37,7 @@
#define USBD_VID 0x0483
#if defined(USBD_USE_HID_COMPOSITE)
#define USBD_PID 0x5711
- #elif defined(USBD_USE_CDC)
+ #elif defined(USBD_USE_CDC) || defined(USBD_USE_CDC_MSC)
#define USBD_PID 0x5740
#endif
#endif /* !USBD_PID && !USBD_VID */
@@ -70,7 +70,7 @@
#elif defined(USBD_USE_HID_COMPOSITE)
#define USBD_CLASS_PRODUCT_HS_STRING CONCATS(BOARD_NAME, "HID in HS Mode")
#define USBD_CLASS_PRODUCT_FS_STRING CONCATS(BOARD_NAME, "HID in FS Mode")
-#elif defined(USBD_USE_CDC)
+#elif defined(USBD_USE_CDC) || defined(USBD_USE_CDC_MSC)
#define USBD_CLASS_PRODUCT_HS_STRING CONCATS(BOARD_NAME, "CDC in HS Mode")
#define USBD_CLASS_PRODUCT_FS_STRING CONCATS(BOARD_NAME, "CDC in FS Mode")
#else
@@ -85,7 +85,7 @@
#define USBD_CLASS_INTERFACE_FS_STRING CONCATS(BOARD_NAME, "HID Interface")
#endif /* USBD_USE_HID_COMPOSITE */
-#ifdef USBD_USE_CDC
+#if defined(USBD_USE_CDC) || defined(USBD_USE_CDC_MSC)
#define USBD_CLASS_CONFIGURATION_HS_STRING CONCATS(BOARD_NAME, "CDC Config")
#define USBD_CLASS_INTERFACE_HS_STRING CONCATS(BOARD_NAME, "CDC Interface")
#define USBD_CLASS_CONFIGURATION_FS_STRING CONCATS(BOARD_NAME, "CDC Config")
@@ -129,81 +129,51 @@ USBD_DescriptorsTypeDef USBD_Desc = {
#endif
};
-#ifdef USBD_USE_HID_COMPOSITE
-/* USB Standard Device Descriptor */
-__ALIGN_BEGIN uint8_t USBD_Class_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = {
- 0x12, /* bLength */
- USB_DESC_TYPE_DEVICE, /* bDescriptorType */
+
+#define USB_CDC_CLASS_MULTI 0xEF
+#define CDC_SUBCLASS_ACM 0x02
+#define CDC_PROTOCOL_V25TER 0x01 // Common AT commands
+
+
#if ((USBD_LPM_ENABLED == 1) || (USBD_CLASS_BOS_ENABLED == 1))
- 0x01, /*bcdUSB */ /* changed to USB version 2.01
- in order to support BOS Desc */
+ #define BCD_USB_FLAG 0x01
#else
- 0x00, /* bcdUSB */
+ #define BCD_USB_FLAG 0x00
+#endif
+
+
+#define USBD_CLASS_DEVICE_DESCRIPTOR(_CLASS, _SUBCLASS, _PROTO) \
+__ALIGN_BEGIN uint8_t USBD_Class_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = { \
+ 0x12, /* bLength */ \
+ USB_DESC_TYPE_DEVICE, /* bDescriptorType */ \
+ BCD_USB_FLAG, /* bcdUSB */ \
+ 0x02, \
+ _CLASS, /* bDeviceClass */ \
+ _SUBCLASS, /* bDeviceSubClass */ \
+ _PROTO, /* bDeviceProtocol */ \
+ USB_MAX_EP0_SIZE, /* bMaxPacketSize */ \
+ LOBYTE(USBD_VID), /* idVendor */ \
+ HIBYTE(USBD_VID), /* idVendor */ \
+ LOBYTE(USBD_PID), /* idProduct */ \
+ HIBYTE(USBD_PID), /* idProduct */ \
+ 0x00, /* bcdDevice rel. 0.00 */ \
+ 0x00, \
+ 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 */ \
+}
+
+#ifdef USBD_USE_HID_COMPOSITE
+ USBD_CLASS_DEVICE_DESCRIPTOR(0x00, 0x00, 0x00);
#endif
- 0x02,
- 0x00, /* bDeviceClass */
- 0x00, /* bDeviceSubClass */
- 0x00, /* bDeviceProtocol */
- USB_MAX_EP0_SIZE, /* bMaxPacketSize */
- LOBYTE(USBD_VID), /* idVendor */
- HIBYTE(USBD_VID), /* idVendor */
- LOBYTE(USBD_PID), /* idProduct */
- HIBYTE(USBD_PID), /* idProduct */
- 0x00, /* bcdDevice rel. 0.00 */
- 0x00,
- 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 */
-#endif /* USBD_USE_HID_COMPOSITE */
#ifdef USBD_USE_CDC
-/* USB Standard Device Descriptor */
-__ALIGN_BEGIN uint8_t USBD_Class_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = {
- 0x12, /* bLength */
- USB_DESC_TYPE_DEVICE, /* bDescriptorType */
-#if ((USBD_LPM_ENABLED == 1) || (USBD_CLASS_BOS_ENABLED == 1))
- 0x01, /*bcdUSB */ /* changed to USB version 2.01
- in order to support BOS Desc */
-#else
- 0x00, /* bcdUSB */
+ USBD_CLASS_DEVICE_DESCRIPTOR(0x02, 0x02, 0x00);
#endif
- 0x02,
- 0x02, /* bDeviceClass */
- 0x02, /* bDeviceSubClass */
- 0x00, /* bDeviceProtocol */
- USB_MAX_EP0_SIZE, /* bMaxPacketSize */
- LOBYTE(USBD_VID), /* idVendor */
- HIBYTE(USBD_VID), /* idVendor */
- LOBYTE(USBD_PID), /* idProduct */
- HIBYTE(USBD_PID), /* idProduct */
- 0x00, /* bcdDevice rel. 0.00 */
- 0x00,
- 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 */
-#endif /* USBD_USE_CDC */
-/* USB Device LPM BOS descriptor */
-#if (USBD_LPM_ENABLED == 1)
-__ALIGN_BEGIN uint8_t USBD_BOSDesc[USB_SIZ_BOS_DESC] __ALIGN_END = {
- 0x5,
- USB_DESC_TYPE_BOS,
- 0xC,
- 0x0,
- 0x1, /* 1 device capability */
- /* device capability */
- 0x7,
- USB_DEVICE_CAPABITY_TYPE,
- 0x2,
- 0x6, /*LPM capability bit set */
- 0x0,
- 0x0,
- 0x0
-};
+#ifdef USBD_USE_CDC_MSC
+ USBD_CLASS_DEVICE_DESCRIPTOR(USB_CDC_CLASS_MULTI, CDC_SUBCLASS_ACM, CDC_PROTOCOL_V25TER);
#endif
/* USB Device Billboard BOS descriptor Template */
diff --git a/cores/arduino/stm32/usb/usbd_ep_conf.c b/cores/arduino/stm32/usb/usbd_ep_conf.c
index 455afe5ecd..2e72855e5d 100644
--- a/cores/arduino/stm32/usb/usbd_ep_conf.c
+++ b/cores/arduino/stm32/usb/usbd_ep_conf.c
@@ -19,53 +19,86 @@
/* Includes ------------------------------------------------------------------*/
#include "usbd_ep_conf.h"
-#ifdef USBD_USE_CDC
-const ep_desc_t ep_def[] = {
-#ifdef USE_USB_HS
- {0x00, CDC_DATA_HS_MAX_PACKET_SIZE},
- {0x80, CDC_DATA_HS_MAX_PACKET_SIZE},
- {CDC_OUT_EP, CDC_DATA_HS_MAX_PACKET_SIZE},
- {CDC_IN_EP, CDC_DATA_HS_MAX_PACKET_SIZE},
- {CDC_CMD_EP, CDC_CMD_PACKET_SIZE}
-#else /* USE_USB_FS */
-#ifdef USB_OTG_FS
- {0x00, CDC_DATA_FS_MAX_PACKET_SIZE},
- {0x80, CDC_DATA_FS_MAX_PACKET_SIZE},
- {CDC_OUT_EP, CDC_DATA_FS_MAX_PACKET_SIZE},
- {CDC_IN_EP, CDC_DATA_FS_MAX_PACKET_SIZE},
- {CDC_CMD_EP, CDC_CMD_PACKET_SIZE}
+#if defined(USB_OTG_FS) || defined(USE_USB_HS)
+ #define EP_DESC(ADDR, SIZE, KIND_TYP) {ADDR, SIZE}
#else
- {0x00, PMA_EP0_OUT_ADDR, PCD_SNG_BUF},
- {0x80, PMA_EP0_IN_ADDR, PCD_SNG_BUF},
- {CDC_OUT_EP, PMA_CDC_OUT_ADDR, PCD_DBL_BUF},
- {CDC_IN_EP, PMA_CDC_IN_ADDR, PCD_SNG_BUF},
- {CDC_CMD_EP, PMA_CDC_CMD_ADDR, PCD_SNG_BUF}
-#endif
+ #define EP_DESC(ADDR, SIZE, KIND_TYP) {ADDR, SIZE, KIND_TYP}
#endif
-};
+
+// *INDENT-OFF*
+
+#ifdef USBD_USE_CDC
+ #ifdef USE_USB_HS
+ #define CDC_DATA_MAX_PACKET_SIZE CDC_DATA_HS_MAX_PACKET_SIZE
+ #else /* USE_USB_FS */
+ #define CDC_DATA_MAX_PACKET_SIZE CDC_DATA_FS_MAX_PACKET_SIZE
+ #endif
+
+
+ const ep_desc_t ep_def[] = {
+ EP_DESC(0x00, CDC_DATA_MAX_PACKET_SIZE, PCD_SNG_BUF),
+ EP_DESC(0x80, CDC_DATA_MAX_PACKET_SIZE, PCD_SNG_BUF),
+ EP_DESC(CDC_OUT_EP, CDC_DATA_MAX_PACKET_SIZE, PCD_DBL_BUF),
+ EP_DESC(CDC_IN_EP, CDC_DATA_MAX_PACKET_SIZE, PCD_SNG_BUF),
+ EP_DESC(CDC_CMD_EP, CDC_CMD_PACKET_SIZE, PCD_SNG_BUF)
+ };
#endif /* USBD_USE_CDC */
+#ifdef USBD_USE_MSC
+ #ifdef USE_USB_HS
+ #define MSC_DATA_MAX_PACKET_SIZE MSC_DATA_HS_MAX_PACKET_SIZE
+ #else /* USE_USB_FS */
+ #define MSC_DATA_MAX_PACKET_SIZE MSC_DATA_FS_MAX_PACKET_SIZE
+ #endif
+
+
+ const ep_desc_t ep_def[] = {
+ EP_DESC(0x00, CDC_DATA_MAX_PACKET_SIZE, PCD_SNG_BUF),
+ EP_DESC(0x80, CDC_DATA_MAX_PACKET_SIZE, PCD_SNG_BUF),
+ EP_DESC(MSC_EPIN_ADDR, MSC_DATA_MAX_PACKET_SIZE, PCD_SNG_BUF),
+ EP_DESC(MSC_EPOUT_ADDR, MSC_DATA_MAX_PACKET_SIZE, PCD_SNG_BUF)
+ };
+#endif /* USBD_USE_MSC */
+
+#ifdef USBD_USE_CDC_MSC
+ #ifdef USE_USB_HS
+ #define CDC_DATA_MAX_PACKET_SIZE CDC_DATA_HS_MAX_PACKET_SIZE
+ #define MSC_DATA_MAX_PACKET_SIZE MSC_DATA_HS_MAX_PACKET_SIZE
+ #else /* USE_USB_FS */
+ #define CDC_DATA_MAX_PACKET_SIZE CDC_DATA_FS_MAX_PACKET_SIZE
+ #define MSC_DATA_MAX_PACKET_SIZE MSC_DATA_FS_MAX_PACKET_SIZE
+ #endif
+
+
+ const ep_desc_t ep_def[] = {
+ EP_DESC(0x00, CDC_DATA_MAX_PACKET_SIZE, PCD_SNG_BUF),
+ EP_DESC(0x80, CDC_DATA_MAX_PACKET_SIZE, PCD_SNG_BUF),
+ EP_DESC(CDC_OUT_EP, CDC_DATA_MAX_PACKET_SIZE, PCD_DBL_BUF),
+ EP_DESC(CDC_IN_EP, CDC_DATA_MAX_PACKET_SIZE, PCD_SNG_BUF),
+ EP_DESC(CDC_CMD_EP, CDC_CMD_PACKET_SIZE, PCD_SNG_BUF),
+ EP_DESC(MSC_EPIN_ADDR, MSC_DATA_MAX_PACKET_SIZE, PCD_SNG_BUF),
+ EP_DESC(MSC_EPOUT_ADDR, MSC_DATA_MAX_PACKET_SIZE, PCD_SNG_BUF)
+ };
+#endif /* USBD_USE_CDC */
+
+
#ifdef USBD_USE_HID_COMPOSITE
-const ep_desc_t ep_def[] = {
-#if !defined (USB)
-#ifdef USE_USB_HS
- {0x00, USB_HS_MAX_PACKET_SIZE},
- {0x80, USB_HS_MAX_PACKET_SIZE},
-#else
- {0x00, USB_FS_MAX_PACKET_SIZE},
- {0x80, USB_FS_MAX_PACKET_SIZE},
-#endif
- {HID_MOUSE_EPIN_ADDR, HID_MOUSE_EPIN_SIZE},
- {HID_KEYBOARD_EPIN_ADDR, HID_KEYBOARD_EPIN_SIZE},
-#else
- {0x00, PMA_EP0_OUT_ADDR, PCD_SNG_BUF},
- {0x80, PMA_EP0_IN_ADDR, PCD_SNG_BUF},
- {HID_MOUSE_EPIN_ADDR, PMA_MOUSE_IN_ADDR, PCD_SNG_BUF},
- {HID_KEYBOARD_EPIN_ADDR, PMA_KEYBOARD_IN_ADDR, PCD_SNG_BUF},
-#endif
-};
+ #ifdef USE_USB_HS
+ #define HID_MAX_PACKET_SIZE USB_HS_MAX_PACKET_SIZE
+ #else /* USE_USB_FS */
+ #define HID_MAX_PACKET_SIZE USB_FS_MAX_PACKET_SIZE
+ #endif
+
+ const ep_desc_t ep_def[] = {
+ EP_DESC(0x00, HID_MAX_PACKET_SIZE, PCD_SNG_BUF),
+ EP_DESC(0x80, HID_MAX_PACKET_SIZE, PCD_SNG_BUF),
+ EP_DESC(HID_MOUSE_EPIN_ADDR, HID_MOUSE_EPIN_SIZE, PCD_SNG_BUF),
+ EP_DESC(HID_KEYBOARD_EPIN_ADDR, HID_MOUSE_EPIN_SIZE, PCD_SNG_BUF)
+ };
#endif /* USBD_USE_HID_COMPOSITE */
+// *INDENT-OFF*
+
#endif /* HAL_PCD_MODULE_ENABLED && USBCON */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/cores/arduino/stm32/usb/usbd_ep_conf.h b/cores/arduino/stm32/usb/usbd_ep_conf.h
index 354b6f4d0c..75a458b4d1 100644
--- a/cores/arduino/stm32/usb/usbd_ep_conf.h
+++ b/cores/arduino/stm32/usb/usbd_ep_conf.h
@@ -33,9 +33,11 @@ typedef struct {
#endif
} ep_desc_t;
+// *INDENT-OFF*
/* CDC Endpoints Configurations */
#ifdef USBD_USE_CDC
+ #define USBD_USE_CDC_CLASS
#define CDC_OUT_EP 0x01U /* EP1 for data OUT */
#define CDC_IN_EP 0x82U /* EP1 for data IN */
@@ -49,6 +51,40 @@ typedef struct {
#define CDC_CMD_PACKET_SIZE 8U /* Control Endpoint Packet size */
#endif /* USBD_USE_CDC */
+#ifdef USBD_USE_MSC
+ #define USBD_USE_MSC_CLASS
+
+ #define MSC_EPOUT_ADDR 0x01U /* EP1 for MSC data IN */
+ #define MSC_EPIN_ADDR 0x81U /* EP1 for MSC data IN */
+
+ #define DEV_NUM_EP 0x04U /* Device Endpoints number including EP0 IN and EP0 OUT */
+
+ /* MSC Endpoints parameters*/
+ #define MSC_DATA_HS_MAX_PACKET_SIZE USB_HS_MAX_PACKET_SIZE /* Endpoint IN & OUT Packet size */
+ #define MSC_DATA_FS_MAX_PACKET_SIZE USB_FS_MAX_PACKET_SIZE /* Endpoint IN & OUT Packet size */
+#endif
+
+#ifdef USBD_USE_CDC_MSC
+ #define USBD_USE_CDC_CLASS
+ #define USBD_USE_MSC_CLASS
+
+ #define CDC_OUT_EP 0x01U /* EP1 for CDC data OUT */
+ #define CDC_IN_EP 0x81U /* EP1 for CDC data IN */
+ #define CDC_CMD_EP 0x82U /* EP2 for CDC commands */
+
+ #define MSC_EPOUT_ADDR 0x03U /* EP3 for MSC data IN */
+ #define MSC_EPIN_ADDR 0x83U /* EP3 for MSC data IN */
+
+ #define DEV_NUM_EP 0x07U /* Device Endpoints number including EP0 */
+
+ /* CDC Endpoints parameters*/
+ #define CDC_DATA_HS_MAX_PACKET_SIZE USB_HS_MAX_PACKET_SIZE /* Endpoint IN & OUT Packet size */
+ #define CDC_DATA_FS_MAX_PACKET_SIZE USB_FS_MAX_PACKET_SIZE /* Endpoint IN & OUT Packet size */
+ #define CDC_CMD_PACKET_SIZE 8U /* Control Endpoint Packet size */
+ /* MSC Endpoints parameters*/
+ #define MSC_DATA_HS_MAX_PACKET_SIZE USB_HS_MAX_PACKET_SIZE /* Endpoint IN & OUT Packet size */
+ #define MSC_DATA_FS_MAX_PACKET_SIZE USB_FS_MAX_PACKET_SIZE /* Endpoint IN & OUT Packet size */
+#endif
/* HID composite (Mouse + Keyboard) Endpoints Configurations */
#ifdef USBD_USE_HID_COMPOSITE
@@ -61,29 +97,19 @@ typedef struct {
#define DEV_NUM_EP 0x03U /* Device Endpoints number including EP0 */
#endif /* USBD_USE_HID_COMPOSITE */
+
/* Require DEV_NUM_EP to be defined */
#if defined (USB)
-/* Size in words, byte size divided by 2 */
-#define PMA_EP0_OUT_ADDR (8 * DEV_NUM_EP)
-#define PMA_EP0_IN_ADDR (PMA_EP0_OUT_ADDR + USB_MAX_EP0_SIZE)
-
-#ifdef USBD_USE_CDC
-#define PMA_CDC_OUT_BASE (PMA_EP0_IN_ADDR + USB_MAX_EP0_SIZE)
-#define PMA_CDC_OUT_ADDR ((PMA_CDC_OUT_BASE + USB_FS_MAX_PACKET_SIZE) | \
- (PMA_CDC_OUT_BASE << 16U))
-#define PMA_CDC_IN_ADDR (PMA_CDC_OUT_BASE + USB_FS_MAX_PACKET_SIZE * 2)
-#define PMA_CDC_CMD_ADDR (PMA_CDC_IN_ADDR + CDC_CMD_PACKET_SIZE)
-#endif /* USBD_USE_CDC */
-#ifdef USBD_USE_HID_COMPOSITE
- #define PMA_MOUSE_IN_ADDR (PMA_EP0_IN_ADDR + HID_MOUSE_EPIN_SIZE)
- #define PMA_KEYBOARD_IN_ADDR (PMA_MOUSE_IN_ADDR + HID_KEYBOARD_EPIN_SIZE)
-#endif /* USBD_USE_HID_COMPOSITE */
+ /* Size in words, byte size divided by 2 */
+ #define PMA_BASE_OFFSET (8 * DEV_NUM_EP)
#endif /* USB */
+// *INDENT-ON*
+
extern const ep_desc_t ep_def[DEV_NUM_EP + 1];
#endif /* USBCON */
#endif /* __USBD_EP_CONF_H */
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
\ No newline at end of file
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/cores/arduino/stm32/usb/usbd_if.c b/cores/arduino/stm32/usb/usbd_if.c
index e579140f72..0ea854909e 100644
--- a/cores/arduino/stm32/usb/usbd_if.c
+++ b/cores/arduino/stm32/usb/usbd_if.c
@@ -155,11 +155,4 @@ WEAK void USBD_reenumerate(void)
#else /* !defined(USBD_REENUM_DISABLED) */
WEAK void USBD_reenumerate(void) { }
#endif
-
-#ifdef USBD_USE_CDC
-void USBD_CDC_init(void)
-{
- CDC_init();
-}
-#endif /* USBD_USE_CDC */
#endif /* USBCON */
diff --git a/cores/arduino/stm32/usb/usbd_if.h b/cores/arduino/stm32/usb/usbd_if.h
index dc026240fe..bcd54020e6 100644
--- a/cores/arduino/stm32/usb/usbd_if.h
+++ b/cores/arduino/stm32/usb/usbd_if.h
@@ -24,9 +24,7 @@ extern "C" {
#endif
void USBD_reenumerate(void);
-#ifdef USBD_USE_CDC
-void USBD_CDC_init(void);
-#endif
+
#ifdef __cplusplus
}
#endif
diff --git a/libraries/SrcWrapper/src/stm32/hw_config.c b/libraries/SrcWrapper/src/stm32/hw_config.cpp
similarity index 95%
rename from libraries/SrcWrapper/src/stm32/hw_config.c
rename to libraries/SrcWrapper/src/stm32/hw_config.cpp
index 3434d6da96..6bec1f76f0 100644
--- a/libraries/SrcWrapper/src/stm32/hw_config.c
+++ b/libraries/SrcWrapper/src/stm32/hw_config.cpp
@@ -37,7 +37,8 @@
*/
#include "stm32_def.h"
#include "hw_config.h"
-#include "usbd_if.h"
+#include "usbd_ep_conf.h"
+#include "USBSerial.h"
#include "dwt.h"
#ifdef __cplusplus
@@ -62,8 +63,8 @@ void hw_config_init(void)
/* Configure the system clock */
SystemClock_Config();
-#if defined (USBCON) && defined(USBD_USE_CDC)
- USBD_CDC_init();
+#if defined (USBCON) && defined(USBD_USE_CDC_CLASS)
+ SerialUSB.begin();
#endif
#if defined (STM32MP1xx)
diff --git a/platform.txt b/platform.txt
index 3674dfe7d2..925aa620ea 100644
--- a/platform.txt
+++ b/platform.txt
@@ -9,7 +9,7 @@ version=1.0.0
# STM compile variables
# ----------------------
-compiler.stm.extra_include="-I{build.source.path}" "-I{build.core.path}/avr" "-I{build.core.path}/stm32" "-I{build.core.path}/stm32/LL" "-I{build.core.path}/stm32/usb" "-I{build.core.path}/stm32/OpenAMP" "-I{build.core.path}/stm32/usb/hid" "-I{build.core.path}/stm32/usb/cdc" "-I{build.system.path}/Drivers/{build.series}_HAL_Driver/Inc" "-I{build.system.path}/Drivers/{build.series}_HAL_Driver/Src" "-I{build.system.path}/{build.series}" "-I{build.system.path}/Middlewares/ST/STM32_USB_Device_Library/Core/Inc" "-I{build.system.path}/Middlewares/ST/STM32_USB_Device_Library/Core/Src" {build.virtio_extra_include}
+compiler.stm.extra_include="-I{build.source.path}" "-I{build.core.path}/avr" "-I{build.core.path}/stm32" "-I{build.core.path}/stm32/LL" "-I{build.core.path}/stm32/usb" "-I{build.core.path}/stm32/OpenAMP" "-I{build.core.path}/stm32/usb/hid" "-I{build.core.path}/stm32/usb/cdc" "-I{build.core.path}/stm32/usb/msc" "-I{build.core.path}/stm32/usb/cdc_msc" "-I{build.system.path}/Drivers/{build.series}_HAL_Driver/Inc" "-I{build.system.path}/Drivers/{build.series}_HAL_Driver/Src" "-I{build.system.path}/{build.series}" "-I{build.system.path}/Middlewares/ST/STM32_USB_Device_Library/Core/Inc" "-I{build.system.path}/Middlewares/ST/STM32_USB_Device_Library/Core/Src" {build.virtio_extra_include}
compiler.warning_flags=-w
compiler.warning_flags.none=-w
diff --git a/tools/platformio-build.py b/tools/platformio-build.py
index 68b0dfc01c..7bdc40d781 100644
--- a/tools/platformio-build.py
+++ b/tools/platformio-build.py
@@ -86,7 +86,7 @@ def process_usb_configuration(cpp_defines):
elif "PIO_FRAMEWORK_ARDUINO_ENABLE_HID" in cpp_defines:
env.Append(CPPDEFINES=["USBD_USE_HID_COMPOSITE"])
- if any(f in env["CPPDEFINES"] for f in ("USBD_USE_CDC", "USBD_USE_HID_COMPOSITE")):
+ if any(f in env["CPPDEFINES"] for f in ["USBCON"]):
env.Append(CPPDEFINES=["HAL_PCD_MODULE_ENABLED"])
@@ -170,6 +170,8 @@ def configure_application_offset(mcu, upload_protocol):
join(FRAMEWORK_DIR, "cores", "arduino", "stm32", "usb"),
join(FRAMEWORK_DIR, "cores", "arduino", "stm32", "usb", "hid"),
join(FRAMEWORK_DIR, "cores", "arduino", "stm32", "usb", "cdc"),
+ join(FRAMEWORK_DIR, "cores", "arduino", "stm32", "usb", "msc"),
+ join(FRAMEWORK_DIR, "cores", "arduino", "stm32", "usb", "cdc_msc"),
join(FRAMEWORK_DIR, "system", "Drivers", series + "_HAL_Driver", "Inc"),
join(FRAMEWORK_DIR, "system", "Drivers", series + "_HAL_Driver", "Src"),
join(FRAMEWORK_DIR, "system", series),
pFad - Phonifier reborn
Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies:
Alternative Proxy
pFad Proxy
pFad v3 Proxy
pFad v4 Proxy