2 ******************************************************************************
4 * @author MCD Application Team
7 * @brief This file provides all the USBD core functions.
8 ******************************************************************************
11 * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
12 * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
13 * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
14 * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
15 * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
16 * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
18 * <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
19 ******************************************************************************
22 /* Includes ------------------------------------------------------------------*/
23 #include "usbd_core.h"
25 #include "usbd_ioreq.h"
26 #include "usb_dcd_int.h"
29 /** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
34 /** @defgroup USBD_CORE
35 * @brief usbd core module
39 /** @defgroup USBD_CORE_Private_TypesDefinitions
47 /** @defgroup USBD_CORE_Private_Defines
56 /** @defgroup USBD_CORE_Private_Macros
66 /** @defgroup USBD_CORE_Private_FunctionPrototypes
69 static uint8_t USBD_SetupStage(USB_OTG_CORE_HANDLE *pdev);
70 static uint8_t USBD_DataOutStage(USB_OTG_CORE_HANDLE *pdev , uint8_t epnum);
71 static uint8_t USBD_DataInStage(USB_OTG_CORE_HANDLE *pdev , uint8_t epnum);
72 static uint8_t USBD_SOF(USB_OTG_CORE_HANDLE *pdev);
73 static uint8_t USBD_Reset(USB_OTG_CORE_HANDLE *pdev);
74 static uint8_t USBD_Suspend(USB_OTG_CORE_HANDLE *pdev);
75 static uint8_t USBD_Resume(USB_OTG_CORE_HANDLE *pdev);
76 #ifdef VBUS_SENSING_ENABLED
77 static uint8_t USBD_DevConnected(USB_OTG_CORE_HANDLE *pdev);
78 static uint8_t USBD_DevDisconnected(USB_OTG_CORE_HANDLE *pdev);
80 static uint8_t USBD_IsoINIncomplete(USB_OTG_CORE_HANDLE *pdev);
81 static uint8_t USBD_IsoOUTIncomplete(USB_OTG_CORE_HANDLE *pdev);
86 /** @defgroup USBD_CORE_Private_Variables
92 USBD_DCD_INT_cb_TypeDef USBD_DCD_INT_cb =
101 USBD_IsoINIncomplete,
102 USBD_IsoOUTIncomplete,
103 #ifdef VBUS_SENSING_ENABLED
105 USBD_DevDisconnected,
109 USBD_DCD_INT_cb_TypeDef *USBD_DCD_INT_fops = &USBD_DCD_INT_cb;
114 /** @defgroup USBD_CORE_Private_Functions
120 * Initailizes the device stack and load the class driver
121 * @param pdev: device instance
122 * @param core_address: USB OTG core ID
123 * @param class_cb: Class callback structure address
124 * @param usr_cb: User callback structure address
127 void USBD_Init(USB_OTG_CORE_HANDLE *pdev,
128 USB_OTG_CORE_ID_TypeDef coreID,
129 USBD_DEVICE *pDevice,
130 USBD_Class_cb_TypeDef *class_cb,
131 USBD_Usr_cb_TypeDef *usr_cb)
134 USB_OTG_BSP_Init(pdev);
138 /*Register class and user callbacks */
139 pdev->dev.class_cb = class_cb;
140 pdev->dev.usr_cb = usr_cb;
141 pdev->dev.usr_device = pDevice;
143 /* set USB OTG core params */
144 DCD_Init(pdev , coreID);
146 /* Upon Init call usr callback */
147 pdev->dev.usr_cb->Init();
149 /* Enable Interrupts */
150 USB_OTG_BSP_EnableInterrupt(pdev);
155 * Re-Initialize th deviuce library
156 * @param pdev: device instance
157 * @retval status: status
159 USBD_Status USBD_DeInit(USB_OTG_CORE_HANDLE *pdev)
167 * @brief USBD_SetupStage
168 * Handle the setup stage
169 * @param pdev: device instance
172 static uint8_t USBD_SetupStage(USB_OTG_CORE_HANDLE *pdev)
176 USBD_ParseSetupRequest(pdev , &req);
178 switch (req.bmRequest & 0x1F)
180 case USB_REQ_RECIPIENT_DEVICE:
181 USBD_StdDevReq (pdev, &req);
184 case USB_REQ_RECIPIENT_INTERFACE:
185 USBD_StdItfReq(pdev, &req);
188 case USB_REQ_RECIPIENT_ENDPOINT:
189 USBD_StdEPReq(pdev, &req);
193 DCD_EP_Stall(pdev , req.bmRequest & 0x80);
200 * @brief USBD_DataOutStage
201 * Handle data out stage
202 * @param pdev: device instance
203 * @param epnum: endpoint index
206 static uint8_t USBD_DataOutStage(USB_OTG_CORE_HANDLE *pdev , uint8_t epnum)
212 ep = &pdev->dev.out_ep[0];
213 if ( pdev->dev.device_state == USB_OTG_EP0_DATA_OUT)
215 if(ep->rem_data_len > ep->maxpacket)
217 ep->rem_data_len -= ep->maxpacket;
219 if(pdev->cfg.dma_enable == 1)
221 /* in slave mode this, is handled by the RxSTSQLvl ISR */
222 ep->xfer_buff += ep->maxpacket;
224 USBD_CtlContinueRx (pdev,
226 MIN(ep->rem_data_len ,ep->maxpacket));
230 if((pdev->dev.class_cb->EP0_RxReady != NULL)&&
231 (pdev->dev.device_status == USB_OTG_CONFIGURED))
233 pdev->dev.class_cb->EP0_RxReady(pdev);
235 USBD_CtlSendStatus(pdev);
239 else if((pdev->dev.class_cb->DataOut != NULL)&&
240 (pdev->dev.device_status == USB_OTG_CONFIGURED))
242 pdev->dev.class_cb->DataOut(pdev, epnum);
248 * @brief USBD_DataInStage
249 * Handle data in stage
250 * @param pdev: device instance
251 * @param epnum: endpoint index
254 static uint8_t USBD_DataInStage(USB_OTG_CORE_HANDLE *pdev , uint8_t epnum)
260 ep = &pdev->dev.in_ep[0];
261 if ( pdev->dev.device_state == USB_OTG_EP0_DATA_IN)
263 if(ep->rem_data_len > ep->maxpacket)
265 ep->rem_data_len -= ep->maxpacket;
266 if(pdev->cfg.dma_enable == 1)
268 /* in slave mode this, is handled by the TxFifoEmpty ISR */
269 ep->xfer_buff += ep->maxpacket;
271 USBD_CtlContinueSendData (pdev,
276 { /* last packet is MPS multiple, so send ZLP packet */
277 if((ep->total_data_len % ep->maxpacket == 0) &&
278 (ep->total_data_len >= ep->maxpacket) &&
279 (ep->total_data_len < ep->ctl_data_len ))
282 USBD_CtlContinueSendData(pdev , NULL, 0);
283 ep->ctl_data_len = 0;
287 if((pdev->dev.class_cb->EP0_TxSent != NULL)&&
288 (pdev->dev.device_status == USB_OTG_CONFIGURED))
290 pdev->dev.class_cb->EP0_TxSent(pdev);
292 USBD_CtlReceiveStatus(pdev);
297 else if((pdev->dev.class_cb->DataIn != NULL)&&
298 (pdev->dev.device_status == USB_OTG_CONFIGURED))
300 pdev->dev.class_cb->DataIn(pdev, epnum);
308 * @param pdev: device instance
312 static uint8_t USBD_Reset(USB_OTG_CORE_HANDLE *pdev)
317 USB_OTG_MAX_EP0_SIZE,
323 USB_OTG_MAX_EP0_SIZE,
326 /* Upon Reset call usr call back */
327 pdev->dev.device_status = USB_OTG_DEFAULT;
328 pdev->dev.usr_cb->DeviceReset(pdev->cfg.speed);
335 * Handle Resume event
336 * @param pdev: device instance
340 static uint8_t USBD_Resume(USB_OTG_CORE_HANDLE *pdev)
342 /* Upon Resume call usr call back */
343 pdev->dev.usr_cb->DeviceResumed();
344 pdev->dev.device_status = USB_OTG_CONFIGURED;
350 * @brief USBD_Suspend
351 * Handle Suspend event
352 * @param pdev: device instance
356 static uint8_t USBD_Suspend(USB_OTG_CORE_HANDLE *pdev)
359 pdev->dev.device_status = USB_OTG_SUSPENDED;
360 /* Upon Resume call usr call back */
361 pdev->dev.usr_cb->DeviceSuspended();
369 * @param pdev: device instance
373 static uint8_t USBD_SOF(USB_OTG_CORE_HANDLE *pdev)
375 if(pdev->dev.class_cb->SOF)
377 pdev->dev.class_cb->SOF(pdev);
383 * Configure device and start the interface
384 * @param pdev: device instance
385 * @param cfgidx: configuration index
389 USBD_Status USBD_SetCfg(USB_OTG_CORE_HANDLE *pdev, uint8_t cfgidx)
391 pdev->dev.class_cb->Init(pdev, cfgidx);
393 /* Upon set config call usr call back */
394 pdev->dev.usr_cb->DeviceConfigured();
400 * Clear current configuration
401 * @param pdev: device instance
402 * @param cfgidx: configuration index
403 * @retval status: USBD_Status
405 USBD_Status USBD_ClrCfg(USB_OTG_CORE_HANDLE *pdev, uint8_t cfgidx)
407 pdev->dev.class_cb->DeInit(pdev, cfgidx);
412 * @brief USBD_IsoINIncomplete
413 * Handle iso in incomplete event
414 * @param pdev: device instance
417 static uint8_t USBD_IsoINIncomplete(USB_OTG_CORE_HANDLE *pdev)
419 pdev->dev.class_cb->IsoINIncomplete(pdev);
424 * @brief USBD_IsoOUTIncomplete
425 * Handle iso out incomplete event
426 * @param pdev: device instance
429 static uint8_t USBD_IsoOUTIncomplete(USB_OTG_CORE_HANDLE *pdev)
431 pdev->dev.class_cb->IsoOUTIncomplete(pdev);
435 #ifdef VBUS_SENSING_ENABLED
437 * @brief USBD_DevConnected
438 * Handle device connection event
439 * @param pdev: device instance
442 static uint8_t USBD_DevConnected(USB_OTG_CORE_HANDLE *pdev)
444 pdev->dev.usr_cb->DeviceConnected();
449 * @brief USBD_DevDisconnected
450 * Handle device disconnection event
451 * @param pdev: device instance
454 static uint8_t USBD_DevDisconnected(USB_OTG_CORE_HANDLE *pdev)
456 pdev->dev.usr_cb->DeviceDisconnected();
457 pdev->dev.class_cb->DeInit(pdev, 0);
475 /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/