2 ******************************************************************************
3 * @file usbd_msc_core.c
4 * @author MCD Application Team
7 * @brief This file provides all the MSC core functions.
11 * ===================================================================
12 * MSC Class Description
13 * ===================================================================
14 * This module manages the MSC class V1.0 following the "Universal
15 * Serial Bus Mass Storage Class (MSC) Bulk-Only Transport (BOT) Version 1.0
17 * This driver implements the following aspects of the specification:
18 * - Bulk-Only Transport protocol
19 * - Subclass : SCSI transparent command set (ref. SCSI Primary Commands - 3 (SPC-3))
23 ******************************************************************************
26 * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
27 * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
28 * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
29 * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
30 * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
31 * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
33 * <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
34 ******************************************************************************
37 /* Includes ------------------------------------------------------------------*/
38 #include "usbd_msc_mem.h"
39 #include "usbd_msc_core.h"
40 #include "usbd_msc_bot.h"
44 /** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
49 /** @defgroup MSC_CORE
50 * @brief Mass storage core module
54 /** @defgroup MSC_CORE_Private_TypesDefinitions
62 /** @defgroup MSC_CORE_Private_Defines
71 /** @defgroup MSC_CORE_Private_Macros
79 /** @defgroup MSC_CORE_Private_FunctionPrototypes
82 uint8_t USBD_MSC_Init (void *pdev,
85 uint8_t USBD_MSC_DeInit (void *pdev,
88 uint8_t USBD_MSC_Setup (void *pdev,
91 uint8_t USBD_MSC_DataIn (void *pdev,
95 uint8_t USBD_MSC_DataOut (void *pdev,
98 uint8_t *USBD_MSC_GetCfgDesc (uint8_t speed,
101 #ifdef USB_OTG_HS_CORE
102 uint8_t *USBD_MSC_GetOtherCfgDesc (uint8_t speed,
107 uint8_t USBD_MSC_CfgDesc[USB_MSC_CONFIG_DESC_SIZ];
117 /** @defgroup MSC_CORE_Private_Variables
122 USBD_Class_cb_TypeDef USBD_MSC_cb =
128 NULL, /*EP0_RxReady*/
135 #ifdef USB_OTG_HS_CORE
136 USBD_MSC_GetOtherCfgDesc,
140 #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
141 #if defined ( __ICCARM__ ) /*!< IAR Compiler */
142 #pragma data_alignment=4
144 #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
145 /* USB Mass storage device Configuration Descriptor */
146 /* All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */
147 __ALIGN_BEGIN uint8_t USBD_MSC_CfgDesc[USB_MSC_CONFIG_DESC_SIZ] __ALIGN_END =
150 0x09, /* bLength: Configuation Descriptor size */
151 USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
152 USB_MSC_CONFIG_DESC_SIZ,
155 0x01, /* bNumInterfaces: 1 interface */
156 0x01, /* bConfigurationValue: */
157 0x04, /* iConfiguration: */
158 0xC0, /* bmAttributes: */
159 0x32, /* MaxPower 100 mA */
161 /******************** Mass Storage interface ********************/
162 0x09, /* bLength: Interface Descriptor size */
163 0x04, /* bDescriptorType: */
164 0x00, /* bInterfaceNumber: Number of Interface */
165 0x00, /* bAlternateSetting: Alternate setting */
166 0x02, /* bNumEndpoints*/
167 0x08, /* bInterfaceClass: MSC Class */
168 0x06, /* bInterfaceSubClass : SCSI transparent*/
169 0x50, /* nInterfaceProtocol */
170 0x05, /* iInterface: */
171 /******************** Mass Storage Endpoints ********************/
172 0x07, /*Endpoint descriptor length = 7*/
173 0x05, /*Endpoint descriptor type */
174 MSC_IN_EP, /*Endpoint address (IN, address 1) */
175 0x02, /*Bulk endpoint type */
176 LOBYTE(MSC_MAX_PACKET),
177 HIBYTE(MSC_MAX_PACKET),
178 0x00, /*Polling interval in milliseconds */
180 0x07, /*Endpoint descriptor length = 7 */
181 0x05, /*Endpoint descriptor type */
182 MSC_OUT_EP, /*Endpoint address (OUT, address 1) */
183 0x02, /*Bulk endpoint type */
184 LOBYTE(MSC_MAX_PACKET),
185 HIBYTE(MSC_MAX_PACKET),
186 0x00 /*Polling interval in milliseconds*/
188 #ifdef USB_OTG_HS_CORE
189 #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
190 #if defined ( __ICCARM__ ) /*!< IAR Compiler */
191 #pragma data_alignment=4
193 #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
194 __ALIGN_BEGIN uint8_t USBD_MSC_OtherCfgDesc[USB_MSC_CONFIG_DESC_SIZ] __ALIGN_END =
197 0x09, /* bLength: Configuation Descriptor size */
198 USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION,
199 USB_MSC_CONFIG_DESC_SIZ,
202 0x01, /* bNumInterfaces: 1 interface */
203 0x01, /* bConfigurationValue: */
204 0x04, /* iConfiguration: */
205 0xC0, /* bmAttributes: */
206 0x32, /* MaxPower 100 mA */
208 /******************** Mass Storage interface ********************/
209 0x09, /* bLength: Interface Descriptor size */
210 0x04, /* bDescriptorType: */
211 0x00, /* bInterfaceNumber: Number of Interface */
212 0x00, /* bAlternateSetting: Alternate setting */
213 0x02, /* bNumEndpoints*/
214 0x08, /* bInterfaceClass: MSC Class */
215 0x06, /* bInterfaceSubClass : SCSI transparent command set*/
216 0x50, /* nInterfaceProtocol */
217 0x05, /* iInterface: */
218 /******************** Mass Storage Endpoints ********************/
219 0x07, /*Endpoint descriptor length = 7*/
220 0x05, /*Endpoint descriptor type */
221 MSC_IN_EP, /*Endpoint address (IN, address 1) */
222 0x02, /*Bulk endpoint type */
225 0x00, /*Polling interval in milliseconds */
227 0x07, /*Endpoint descriptor length = 7 */
228 0x05, /*Endpoint descriptor type */
229 MSC_OUT_EP, /*Endpoint address (OUT, address 1) */
230 0x02, /*Bulk endpoint type */
233 0x00 /*Polling interval in milliseconds*/
237 #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
238 #if defined ( __ICCARM__ ) /*!< IAR Compiler */
239 #pragma data_alignment=4
241 #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
242 __ALIGN_BEGIN static uint8_t USBD_MSC_MaxLun __ALIGN_END = 0;
244 #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
245 #if defined ( __ICCARM__ ) /*!< IAR Compiler */
246 #pragma data_alignment=4
248 #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
249 __ALIGN_BEGIN static uint8_t USBD_MSC_AltSet __ALIGN_END = 0;
256 /** @defgroup MSC_CORE_Private_Functions
261 * @brief USBD_MSC_Init
262 * Initialize the mass storage configuration
263 * @param pdev: device instance
264 * @param cfgidx: configuration index
267 uint8_t USBD_MSC_Init (void *pdev,
270 USBD_MSC_DeInit(pdev , cfgidx );
284 /* Init the BOT layer */
291 * @brief USBD_MSC_DeInit
292 * DeInitilaize the mass storage configuration
293 * @param pdev: device instance
294 * @param cfgidx: configuration index
297 uint8_t USBD_MSC_DeInit (void *pdev,
301 DCD_EP_Close (pdev , MSC_IN_EP);
302 DCD_EP_Close (pdev , MSC_OUT_EP);
304 /* Un Init the BOT layer */
305 MSC_BOT_DeInit(pdev);
309 * @brief USBD_MSC_Setup
310 * Handle the MSC specific requests
311 * @param pdev: device instance
312 * @param req: USB request
315 uint8_t USBD_MSC_Setup (void *pdev, USB_SETUP_REQ *req)
318 switch (req->bmRequest & USB_REQ_TYPE_MASK)
322 case USB_REQ_TYPE_CLASS :
323 switch (req->bRequest)
325 case BOT_GET_MAX_LUN :
327 if((req->wValue == 0) &&
328 (req->wLength == 1) &&
329 ((req->bmRequest & 0x80) == 0x80))
331 USBD_MSC_MaxLun = USBD_STORAGE_fops->GetMaxLun();
332 if(USBD_MSC_MaxLun > 0)
334 USBD_CtlSendData (pdev,
340 USBD_CtlError(pdev , req);
347 USBD_CtlError(pdev , req);
353 if((req->wValue == 0) &&
354 (req->wLength == 0) &&
355 ((req->bmRequest & 0x80) != 0x80))
361 USBD_CtlError(pdev , req);
367 USBD_CtlError(pdev , req);
371 /* Interface & Endpoint request */
372 case USB_REQ_TYPE_STANDARD:
373 switch (req->bRequest)
375 case USB_REQ_GET_INTERFACE :
376 USBD_CtlSendData (pdev,
381 case USB_REQ_SET_INTERFACE :
382 USBD_MSC_AltSet = (uint8_t)(req->wValue);
385 case USB_REQ_CLEAR_FEATURE:
387 /* Flush the FIFO and Clear the stall status */
388 DCD_EP_Flush(pdev, (uint8_t)req->wIndex);
390 /* Re-activate the EP */
391 DCD_EP_Close (pdev , (uint8_t)req->wIndex);
392 if((((uint8_t)req->wIndex) & 0x80) == 0x80)
395 ((uint8_t)req->wIndex),
402 ((uint8_t)req->wIndex),
407 /* Handle BOT error */
408 MSC_BOT_CplClrFeature(pdev, (uint8_t)req->wIndex);
421 * @brief USBD_MSC_DataIn
422 * handle data IN Stage
423 * @param pdev: device instance
424 * @param epnum: endpoint index
427 uint8_t USBD_MSC_DataIn (void *pdev,
430 MSC_BOT_DataIn(pdev , epnum);
435 * @brief USBD_MSC_DataOut
436 * handle data OUT Stage
437 * @param pdev: device instance
438 * @param epnum: endpoint index
441 uint8_t USBD_MSC_DataOut (void *pdev,
444 MSC_BOT_DataOut(pdev , epnum);
449 * @brief USBD_MSC_GetCfgDesc
450 * return configuration descriptor
451 * @param speed : current device speed
452 * @param length : pointer data length
453 * @retval pointer to descriptor buffer
455 uint8_t *USBD_MSC_GetCfgDesc (uint8_t speed, uint16_t *length)
457 *length = sizeof (USBD_MSC_CfgDesc);
458 return USBD_MSC_CfgDesc;
462 * @brief USBD_MSC_GetOtherCfgDesc
463 * return other speed configuration descriptor
464 * @param speed : current device speed
465 * @param length : pointer data length
466 * @retval pointer to descriptor buffer
468 #ifdef USB_OTG_HS_CORE
469 uint8_t *USBD_MSC_GetOtherCfgDesc (uint8_t speed,
472 *length = sizeof (USBD_MSC_OtherCfgDesc);
473 return USBD_MSC_OtherCfgDesc;
490 /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/