Added all the F4 libraries to the project
[fw/stlink] / exampleF4 / STM32_USB_Device_Library / Class / msc / src / usbd_msc_core.c
1 /**
2   ******************************************************************************
3   * @file    usbd_msc_core.c
4   * @author  MCD Application Team
5   * @version V1.0.0
6   * @date    22-July-2011
7   * @brief   This file provides all the MSC core functions.
8   *
9   * @verbatim
10   *      
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
16   *           Sep. 31, 1999".
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))
20   *      
21   *  @endverbatim
22   *
23   ******************************************************************************
24   * @attention
25   *
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.
32   *
33   * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
34   ******************************************************************************
35   */ 
36
37 /* Includes ------------------------------------------------------------------*/
38 #include "usbd_msc_mem.h"
39 #include "usbd_msc_core.h"
40 #include "usbd_msc_bot.h"
41 #include "usbd_req.h"
42
43
44 /** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
45   * @{
46   */
47
48
49 /** @defgroup MSC_CORE 
50   * @brief Mass storage core module
51   * @{
52   */ 
53
54 /** @defgroup MSC_CORE_Private_TypesDefinitions
55   * @{
56   */ 
57 /**
58   * @}
59   */ 
60
61
62 /** @defgroup MSC_CORE_Private_Defines
63   * @{
64   */ 
65
66 /**
67   * @}
68   */ 
69
70
71 /** @defgroup MSC_CORE_Private_Macros
72   * @{
73   */ 
74 /**
75   * @}
76   */ 
77
78
79 /** @defgroup MSC_CORE_Private_FunctionPrototypes
80   * @{
81   */ 
82 uint8_t  USBD_MSC_Init (void  *pdev, 
83                             uint8_t cfgidx);
84
85 uint8_t  USBD_MSC_DeInit (void  *pdev, 
86                               uint8_t cfgidx);
87
88 uint8_t  USBD_MSC_Setup (void  *pdev, 
89                              USB_SETUP_REQ *req);
90
91 uint8_t  USBD_MSC_DataIn (void  *pdev, 
92                               uint8_t epnum);
93
94
95 uint8_t  USBD_MSC_DataOut (void  *pdev, 
96                                uint8_t epnum);
97
98 uint8_t  *USBD_MSC_GetCfgDesc (uint8_t speed, 
99                                       uint16_t *length);
100
101 #ifdef USB_OTG_HS_CORE  
102 uint8_t  *USBD_MSC_GetOtherCfgDesc (uint8_t speed, 
103                                       uint16_t *length);
104 #endif
105
106
107 uint8_t USBD_MSC_CfgDesc[USB_MSC_CONFIG_DESC_SIZ];
108
109
110
111
112 /**
113   * @}
114   */ 
115
116
117 /** @defgroup MSC_CORE_Private_Variables
118   * @{
119   */ 
120
121
122 USBD_Class_cb_TypeDef  USBD_MSC_cb = 
123 {
124   USBD_MSC_Init,
125   USBD_MSC_DeInit,
126   USBD_MSC_Setup,
127   NULL, /*EP0_TxSent*/  
128   NULL, /*EP0_RxReady*/
129   USBD_MSC_DataIn,
130   USBD_MSC_DataOut,
131   NULL, /*SOF */ 
132   NULL,  
133   NULL,     
134   USBD_MSC_GetCfgDesc,
135 #ifdef USB_OTG_HS_CORE  
136   USBD_MSC_GetOtherCfgDesc,
137 #endif
138 };
139
140 #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
141   #if defined ( __ICCARM__ ) /*!< IAR Compiler */
142     #pragma data_alignment=4   
143   #endif
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 =
148 {
149   
150   0x09,   /* bLength: Configuation Descriptor size */
151   USB_DESC_TYPE_CONFIGURATION,   /* bDescriptorType: Configuration */
152   USB_MSC_CONFIG_DESC_SIZ,
153   
154   0x00,
155   0x01,   /* bNumInterfaces: 1 interface */
156   0x01,   /* bConfigurationValue: */
157   0x04,   /* iConfiguration: */
158   0xC0,   /* bmAttributes: */
159   0x32,   /* MaxPower 100 mA */
160   
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 */
179   
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*/
187 };
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   
192    #endif
193  #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
194 __ALIGN_BEGIN uint8_t USBD_MSC_OtherCfgDesc[USB_MSC_CONFIG_DESC_SIZ] __ALIGN_END =
195 {
196   
197   0x09,   /* bLength: Configuation Descriptor size */
198   USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION,   
199   USB_MSC_CONFIG_DESC_SIZ,
200   
201   0x00,
202   0x01,   /* bNumInterfaces: 1 interface */
203   0x01,   /* bConfigurationValue: */
204   0x04,   /* iConfiguration: */
205   0xC0,   /* bmAttributes: */
206   0x32,   /* MaxPower 100 mA */
207   
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 */
223   0x40,
224   0x00,
225   0x00,   /*Polling interval in milliseconds */
226   
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 */
231   0x40,
232   0x00,
233   0x00     /*Polling interval in milliseconds*/
234 };
235 #endif 
236
237 #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
238   #if defined ( __ICCARM__ ) /*!< IAR Compiler */
239     #pragma data_alignment=4   
240   #endif
241 #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
242 __ALIGN_BEGIN static uint8_t  USBD_MSC_MaxLun  __ALIGN_END = 0;
243
244 #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
245   #if defined ( __ICCARM__ ) /*!< IAR Compiler */
246     #pragma data_alignment=4   
247   #endif
248 #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
249 __ALIGN_BEGIN static uint8_t  USBD_MSC_AltSet  __ALIGN_END = 0;
250
251 /**
252   * @}
253   */ 
254
255
256 /** @defgroup MSC_CORE_Private_Functions
257   * @{
258   */ 
259
260 /**
261 * @brief  USBD_MSC_Init
262 *         Initialize  the mass storage configuration
263 * @param  pdev: device instance
264 * @param  cfgidx: configuration index
265 * @retval status
266 */
267 uint8_t  USBD_MSC_Init (void  *pdev, 
268                             uint8_t cfgidx)
269 {
270   USBD_MSC_DeInit(pdev , cfgidx );
271   
272   /* Open EP IN */
273   DCD_EP_Open(pdev,
274               MSC_IN_EP,
275               MSC_EPIN_SIZE,
276               USB_OTG_EP_BULK);
277   
278   /* Open EP OUT */
279   DCD_EP_Open(pdev,
280               MSC_OUT_EP,
281               MSC_EPOUT_SIZE,
282               USB_OTG_EP_BULK);
283  
284   /* Init the BOT  layer */
285   MSC_BOT_Init(pdev); 
286   
287   return USBD_OK;
288 }
289
290 /**
291 * @brief  USBD_MSC_DeInit
292 *         DeInitilaize  the mass storage configuration
293 * @param  pdev: device instance
294 * @param  cfgidx: configuration index
295 * @retval status
296 */
297 uint8_t  USBD_MSC_DeInit (void  *pdev, 
298                               uint8_t cfgidx)
299 {
300   /* Close MSC EPs */
301   DCD_EP_Close (pdev , MSC_IN_EP);
302   DCD_EP_Close (pdev , MSC_OUT_EP);
303   
304   /* Un Init the BOT layer */
305   MSC_BOT_DeInit(pdev);   
306   return USBD_OK;
307 }
308 /**
309 * @brief  USBD_MSC_Setup
310 *         Handle the MSC specific requests
311 * @param  pdev: device instance
312 * @param  req: USB request
313 * @retval status
314 */
315 uint8_t  USBD_MSC_Setup (void  *pdev, USB_SETUP_REQ *req)
316 {
317   
318   switch (req->bmRequest & USB_REQ_TYPE_MASK)
319   {
320
321   /* Class request */
322   case USB_REQ_TYPE_CLASS :
323     switch (req->bRequest)
324     {
325     case BOT_GET_MAX_LUN :
326
327       if((req->wValue  == 0) && 
328          (req->wLength == 1) &&
329          ((req->bmRequest & 0x80) == 0x80))
330       {
331         USBD_MSC_MaxLun = USBD_STORAGE_fops->GetMaxLun();
332         if(USBD_MSC_MaxLun > 0)
333         {
334            USBD_CtlSendData (pdev,
335                              &USBD_MSC_MaxLun,
336                               1);
337         }
338         else
339         {
340           USBD_CtlError(pdev , req);
341           return USBD_FAIL; 
342           
343         }
344       }
345       else
346       {
347          USBD_CtlError(pdev , req);
348          return USBD_FAIL; 
349       }
350       break;
351       
352     case BOT_RESET :
353       if((req->wValue  == 0) && 
354          (req->wLength == 0) &&
355         ((req->bmRequest & 0x80) != 0x80))
356       {      
357          MSC_BOT_Reset(pdev);
358       }
359       else
360       {
361          USBD_CtlError(pdev , req);
362          return USBD_FAIL; 
363       }
364       break;
365
366     default:
367        USBD_CtlError(pdev , req);
368        return USBD_FAIL; 
369     }
370     break;
371   /* Interface & Endpoint request */
372   case USB_REQ_TYPE_STANDARD:
373     switch (req->bRequest)
374     {
375     case USB_REQ_GET_INTERFACE :
376       USBD_CtlSendData (pdev,
377                         &USBD_MSC_AltSet,
378                         1);
379       break;
380       
381     case USB_REQ_SET_INTERFACE :
382       USBD_MSC_AltSet = (uint8_t)(req->wValue);
383       break;
384     
385     case USB_REQ_CLEAR_FEATURE:  
386       
387       /* Flush the FIFO and Clear the stall status */    
388       DCD_EP_Flush(pdev, (uint8_t)req->wIndex);
389       
390       /* Re-activate the EP */      
391       DCD_EP_Close (pdev , (uint8_t)req->wIndex);
392       if((((uint8_t)req->wIndex) & 0x80) == 0x80)
393       {
394         DCD_EP_Open(pdev,
395                     ((uint8_t)req->wIndex),
396                     MSC_EPIN_SIZE,
397                     USB_OTG_EP_BULK);
398       }
399       else
400       {
401         DCD_EP_Open(pdev,
402                     ((uint8_t)req->wIndex),
403                     MSC_EPOUT_SIZE,
404                     USB_OTG_EP_BULK);
405       }
406       
407       /* Handle BOT error */
408       MSC_BOT_CplClrFeature(pdev, (uint8_t)req->wIndex);
409       break;
410       
411     }  
412     break;
413    
414   default:
415     break;
416   }
417   return USBD_OK;
418 }
419
420 /**
421 * @brief  USBD_MSC_DataIn
422 *         handle data IN Stage
423 * @param  pdev: device instance
424 * @param  epnum: endpoint index
425 * @retval status
426 */
427 uint8_t  USBD_MSC_DataIn (void  *pdev, 
428                               uint8_t epnum)
429 {
430   MSC_BOT_DataIn(pdev , epnum);
431   return USBD_OK;
432 }
433
434 /**
435 * @brief  USBD_MSC_DataOut
436 *         handle data OUT Stage
437 * @param  pdev: device instance
438 * @param  epnum: endpoint index
439 * @retval status
440 */
441 uint8_t  USBD_MSC_DataOut (void  *pdev, 
442                                uint8_t epnum)
443 {
444   MSC_BOT_DataOut(pdev , epnum);
445   return USBD_OK;
446 }
447
448 /**
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
454 */
455 uint8_t  *USBD_MSC_GetCfgDesc (uint8_t speed, uint16_t *length)
456 {
457   *length = sizeof (USBD_MSC_CfgDesc);
458   return USBD_MSC_CfgDesc;
459 }
460
461 /**
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
467 */
468 #ifdef USB_OTG_HS_CORE  
469 uint8_t  *USBD_MSC_GetOtherCfgDesc (uint8_t speed, 
470                                       uint16_t *length)
471 {
472   *length = sizeof (USBD_MSC_OtherCfgDesc);
473   return USBD_MSC_OtherCfgDesc;
474 }
475 #endif
476 /**
477   * @}
478   */ 
479
480
481 /**
482   * @}
483   */ 
484
485
486 /**
487   * @}
488   */ 
489
490 /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/