Subversion Repositories dashGPS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /**
  2.   ******************************************************************************
  3.   * @file    usbd_core.c
  4.   * @author  MCD Application Team
  5.   * @brief   This file provides all the USBD core functions.
  6.   ******************************************************************************
  7.   * @attention
  8.   *
  9.   * <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
  10.   * All rights reserved.</center></h2>
  11.   *
  12.   * This software component is licensed by ST under Ultimate Liberty license
  13.   * SLA0044, the "License"; You may not use this file except in compliance with
  14.   * the License. You may obtain a copy of the License at:
  15.   *                      www.st.com/SLA0044
  16.   *
  17.   ******************************************************************************
  18.   */
  19.  
  20. /* Includes ------------------------------------------------------------------*/
  21. #include "usbd_core.h"
  22.  
  23. /** @addtogroup STM32_USBD_DEVICE_LIBRARY
  24. * @{
  25. */
  26.  
  27.  
  28. /** @defgroup USBD_CORE
  29. * @brief usbd core module
  30. * @{
  31. */
  32.  
  33. /** @defgroup USBD_CORE_Private_TypesDefinitions
  34. * @{
  35. */
  36.  
  37. /**
  38. * @}
  39. */
  40.  
  41.  
  42. /** @defgroup USBD_CORE_Private_Defines
  43. * @{
  44. */
  45.  
  46. /**
  47. * @}
  48. */
  49.  
  50.  
  51. /** @defgroup USBD_CORE_Private_Macros
  52. * @{
  53. */
  54.  
  55. /**
  56. * @}
  57. */
  58.  
  59.  
  60. /** @defgroup USBD_CORE_Private_FunctionPrototypes
  61. * @{
  62. */
  63.  
  64. /**
  65. * @}
  66. */
  67.  
  68. /** @defgroup USBD_CORE_Private_Variables
  69. * @{
  70. */
  71.  
  72. /**
  73. * @}
  74. */
  75.  
  76.  
  77. /** @defgroup USBD_CORE_Private_Functions
  78. * @{
  79. */
  80.  
  81. /**
  82. * @brief  USBD_Init
  83. *         Initializes the device stack and load the class driver
  84. * @param  pdev: device instance
  85. * @param  pdesc: Descriptor structure address
  86. * @param  id: Low level core index
  87. * @retval None
  88. */
  89. USBD_StatusTypeDef USBD_Init(USBD_HandleTypeDef *pdev,
  90.                              USBD_DescriptorsTypeDef *pdesc, uint8_t id)
  91. {
  92.   /* Check whether the USB Host handle is valid */
  93.   if (pdev == NULL)
  94.   {
  95. #if (USBD_DEBUG_LEVEL > 1U)
  96.     USBD_ErrLog("Invalid Device handle");
  97. #endif
  98.     return USBD_FAIL;
  99.   }
  100.  
  101.   /* Unlink previous class*/
  102.   if (pdev->pClass != NULL)
  103.   {
  104.     pdev->pClass = NULL;
  105.   }
  106.  
  107.   /* Assign USBD Descriptors */
  108.   if (pdesc != NULL)
  109.   {
  110.     pdev->pDesc = pdesc;
  111.   }
  112.  
  113.   /* Set Device initial State */
  114.   pdev->dev_state = USBD_STATE_DEFAULT;
  115.   pdev->id = id;
  116.   /* Initialize low level driver */
  117.   USBD_LL_Init(pdev);
  118.  
  119.   return USBD_OK;
  120. }
  121.  
  122. /**
  123. * @brief  USBD_DeInit
  124. *         Re-Initialize th device library
  125. * @param  pdev: device instance
  126. * @retval status: status
  127. */
  128. USBD_StatusTypeDef USBD_DeInit(USBD_HandleTypeDef *pdev)
  129. {
  130.   /* Set Default State */
  131.   pdev->dev_state = USBD_STATE_DEFAULT;
  132.  
  133.   /* Free Class Resources */
  134.   pdev->pClass->DeInit(pdev, (uint8_t)pdev->dev_config);
  135.  
  136.   /* Stop the low level driver  */
  137.   USBD_LL_Stop(pdev);
  138.  
  139.   /* Initialize low level driver */
  140.   USBD_LL_DeInit(pdev);
  141.  
  142.   return USBD_OK;
  143. }
  144.  
  145. /**
  146.   * @brief  USBD_RegisterClass
  147.   *         Link class driver to Device Core.
  148.   * @param  pDevice : Device Handle
  149.   * @param  pclass: Class handle
  150.   * @retval USBD Status
  151.   */
  152. USBD_StatusTypeDef  USBD_RegisterClass(USBD_HandleTypeDef *pdev, USBD_ClassTypeDef *pclass)
  153. {
  154.   USBD_StatusTypeDef status = USBD_OK;
  155.   if (pclass != NULL)
  156.   {
  157.     /* link the class to the USB Device handle */
  158.     pdev->pClass = pclass;
  159.     status = USBD_OK;
  160.   }
  161.   else
  162.   {
  163. #if (USBD_DEBUG_LEVEL > 1U)
  164.     USBD_ErrLog("Invalid Class handle");
  165. #endif
  166.     status = USBD_FAIL;
  167.   }
  168.  
  169.   return status;
  170. }
  171.  
  172. /**
  173.   * @brief  USBD_Start
  174.   *         Start the USB Device Core.
  175.   * @param  pdev: Device Handle
  176.   * @retval USBD Status
  177.   */
  178. USBD_StatusTypeDef  USBD_Start(USBD_HandleTypeDef *pdev)
  179. {
  180.   /* Start the low level driver  */
  181.   USBD_LL_Start(pdev);
  182.  
  183.   return USBD_OK;
  184. }
  185.  
  186. /**
  187.   * @brief  USBD_Stop
  188.   *         Stop the USB Device Core.
  189.   * @param  pdev: Device Handle
  190.   * @retval USBD Status
  191.   */
  192. USBD_StatusTypeDef  USBD_Stop(USBD_HandleTypeDef *pdev)
  193. {
  194.   /* Free Class Resources */
  195.   pdev->pClass->DeInit(pdev, (uint8_t)pdev->dev_config);
  196.  
  197.   /* Stop the low level driver */
  198.   USBD_LL_Stop(pdev);
  199.  
  200.   return USBD_OK;
  201. }
  202.  
  203. /**
  204. * @brief  USBD_RunTestMode
  205. *         Launch test mode process
  206. * @param  pdev: device instance
  207. * @retval status
  208. */
  209. USBD_StatusTypeDef  USBD_RunTestMode(USBD_HandleTypeDef  *pdev)
  210. {
  211.   /* Prevent unused argument compilation warning */
  212.   UNUSED(pdev);
  213.  
  214.   return USBD_OK;
  215. }
  216.  
  217. /**
  218. * @brief  USBD_SetClassConfig
  219. *        Configure device and start the interface
  220. * @param  pdev: device instance
  221. * @param  cfgidx: configuration index
  222. * @retval status
  223. */
  224.  
  225. USBD_StatusTypeDef USBD_SetClassConfig(USBD_HandleTypeDef  *pdev, uint8_t cfgidx)
  226. {
  227.   USBD_StatusTypeDef ret = USBD_FAIL;
  228.  
  229.   if (pdev->pClass != NULL)
  230.   {
  231.     /* Set configuration  and Start the Class*/
  232.     if (pdev->pClass->Init(pdev, cfgidx) == 0U)
  233.     {
  234.       ret = USBD_OK;
  235.     }
  236.   }
  237.  
  238.   return ret;
  239. }
  240.  
  241. /**
  242. * @brief  USBD_ClrClassConfig
  243. *         Clear current configuration
  244. * @param  pdev: device instance
  245. * @param  cfgidx: configuration index
  246. * @retval status: USBD_StatusTypeDef
  247. */
  248. USBD_StatusTypeDef USBD_ClrClassConfig(USBD_HandleTypeDef  *pdev, uint8_t cfgidx)
  249. {
  250.   /* Clear configuration  and De-initialize the Class process*/
  251.   pdev->pClass->DeInit(pdev, cfgidx);
  252.  
  253.   return USBD_OK;
  254. }
  255.  
  256.  
  257. /**
  258. * @brief  USBD_SetupStage
  259. *         Handle the setup stage
  260. * @param  pdev: device instance
  261. * @retval status
  262. */
  263. USBD_StatusTypeDef USBD_LL_SetupStage(USBD_HandleTypeDef *pdev, uint8_t *psetup)
  264. {
  265.   USBD_ParseSetupRequest(&pdev->request, psetup);
  266.  
  267.   pdev->ep0_state = USBD_EP0_SETUP;
  268.  
  269.   pdev->ep0_data_len = pdev->request.wLength;
  270.  
  271.   switch (pdev->request.bmRequest & 0x1FU)
  272.   {
  273.     case USB_REQ_RECIPIENT_DEVICE:
  274.       USBD_StdDevReq(pdev, &pdev->request);
  275.       break;
  276.  
  277.     case USB_REQ_RECIPIENT_INTERFACE:
  278.       USBD_StdItfReq(pdev, &pdev->request);
  279.       break;
  280.  
  281.     case USB_REQ_RECIPIENT_ENDPOINT:
  282.       USBD_StdEPReq(pdev, &pdev->request);
  283.       break;
  284.  
  285.     default:
  286.       USBD_LL_StallEP(pdev, (pdev->request.bmRequest & 0x80U));
  287.       break;
  288.   }
  289.  
  290.   return USBD_OK;
  291. }
  292.  
  293. /**
  294. * @brief  USBD_DataOutStage
  295. *         Handle data OUT stage
  296. * @param  pdev: device instance
  297. * @param  epnum: endpoint index
  298. * @retval status
  299. */
  300. USBD_StatusTypeDef USBD_LL_DataOutStage(USBD_HandleTypeDef *pdev,
  301.                                         uint8_t epnum, uint8_t *pdata)
  302. {
  303.   USBD_EndpointTypeDef *pep;
  304.  
  305.   if (epnum == 0U)
  306.   {
  307.     pep = &pdev->ep_out[0];
  308.  
  309.     if (pdev->ep0_state == USBD_EP0_DATA_OUT)
  310.     {
  311.       if (pep->rem_length > pep->maxpacket)
  312.       {
  313.         pep->rem_length -= pep->maxpacket;
  314.  
  315.         USBD_CtlContinueRx(pdev, pdata,
  316.                            (uint16_t)MIN(pep->rem_length, pep->maxpacket));
  317.       }
  318.       else
  319.       {
  320.         if ((pdev->pClass->EP0_RxReady != NULL) &&
  321.             (pdev->dev_state == USBD_STATE_CONFIGURED))
  322.         {
  323.           pdev->pClass->EP0_RxReady(pdev);
  324.         }
  325.         USBD_CtlSendStatus(pdev);
  326.       }
  327.     }
  328.     else
  329.     {
  330.       if (pdev->ep0_state == USBD_EP0_STATUS_OUT)
  331.       {
  332.         /*
  333.          * STATUS PHASE completed, update ep0_state to idle
  334.          */
  335.         pdev->ep0_state = USBD_EP0_IDLE;
  336.         USBD_LL_StallEP(pdev, 0U);
  337.       }
  338.     }
  339.   }
  340.   else if ((pdev->pClass->DataOut != NULL) &&
  341.            (pdev->dev_state == USBD_STATE_CONFIGURED))
  342.   {
  343.     pdev->pClass->DataOut(pdev, epnum);
  344.   }
  345.   else
  346.   {
  347.     /* should never be in this condition */
  348.     return USBD_FAIL;
  349.   }
  350.  
  351.   return USBD_OK;
  352. }
  353.  
  354. /**
  355. * @brief  USBD_DataInStage
  356. *         Handle data in stage
  357. * @param  pdev: device instance
  358. * @param  epnum: endpoint index
  359. * @retval status
  360. */
  361. USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev,
  362.                                        uint8_t epnum, uint8_t *pdata)
  363. {
  364.   USBD_EndpointTypeDef *pep;
  365.  
  366.   if (epnum == 0U)
  367.   {
  368.     pep = &pdev->ep_in[0];
  369.  
  370.     if (pdev->ep0_state == USBD_EP0_DATA_IN)
  371.     {
  372.       if (pep->rem_length > pep->maxpacket)
  373.       {
  374.         pep->rem_length -= pep->maxpacket;
  375.  
  376.         USBD_CtlContinueSendData(pdev, pdata, (uint16_t)pep->rem_length);
  377.  
  378.         /* Prepare endpoint for premature end of transfer */
  379.         USBD_LL_PrepareReceive(pdev, 0U, NULL, 0U);
  380.       }
  381.       else
  382.       {
  383.         /* last packet is MPS multiple, so send ZLP packet */
  384.         if ((pep->total_length % pep->maxpacket == 0U) &&
  385.             (pep->total_length >= pep->maxpacket) &&
  386.             (pep->total_length < pdev->ep0_data_len))
  387.         {
  388.           USBD_CtlContinueSendData(pdev, NULL, 0U);
  389.           pdev->ep0_data_len = 0U;
  390.  
  391.           /* Prepare endpoint for premature end of transfer */
  392.           USBD_LL_PrepareReceive(pdev, 0U, NULL, 0U);
  393.         }
  394.         else
  395.         {
  396.           if ((pdev->pClass->EP0_TxSent != NULL) &&
  397.               (pdev->dev_state == USBD_STATE_CONFIGURED))
  398.           {
  399.             pdev->pClass->EP0_TxSent(pdev);
  400.           }
  401.           USBD_LL_StallEP(pdev, 0x80U);
  402.           USBD_CtlReceiveStatus(pdev);
  403.         }
  404.       }
  405.     }
  406.     else
  407.     {
  408.       if ((pdev->ep0_state == USBD_EP0_STATUS_IN) ||
  409.           (pdev->ep0_state == USBD_EP0_IDLE))
  410.       {
  411.         USBD_LL_StallEP(pdev, 0x80U);
  412.       }
  413.     }
  414.  
  415.     if (pdev->dev_test_mode == 1U)
  416.     {
  417.       USBD_RunTestMode(pdev);
  418.       pdev->dev_test_mode = 0U;
  419.     }
  420.   }
  421.   else if ((pdev->pClass->DataIn != NULL) &&
  422.            (pdev->dev_state == USBD_STATE_CONFIGURED))
  423.   {
  424.     pdev->pClass->DataIn(pdev, epnum);
  425.   }
  426.   else
  427.   {
  428.     /* should never be in this condition */
  429.     return USBD_FAIL;
  430.   }
  431.  
  432.   return USBD_OK;
  433. }
  434.  
  435. /**
  436. * @brief  USBD_LL_Reset
  437. *         Handle Reset event
  438. * @param  pdev: device instance
  439. * @retval status
  440. */
  441.  
  442. USBD_StatusTypeDef USBD_LL_Reset(USBD_HandleTypeDef *pdev)
  443. {
  444.   /* Open EP0 OUT */
  445.   USBD_LL_OpenEP(pdev, 0x00U, USBD_EP_TYPE_CTRL, USB_MAX_EP0_SIZE);
  446.   pdev->ep_out[0x00U & 0xFU].is_used = 1U;
  447.  
  448.   pdev->ep_out[0].maxpacket = USB_MAX_EP0_SIZE;
  449.  
  450.   /* Open EP0 IN */
  451.   USBD_LL_OpenEP(pdev, 0x80U, USBD_EP_TYPE_CTRL, USB_MAX_EP0_SIZE);
  452.   pdev->ep_in[0x80U & 0xFU].is_used = 1U;
  453.  
  454.   pdev->ep_in[0].maxpacket = USB_MAX_EP0_SIZE;
  455.  
  456.   /* Upon Reset call user call back */
  457.   pdev->dev_state = USBD_STATE_DEFAULT;
  458.   pdev->ep0_state = USBD_EP0_IDLE;
  459.   pdev->dev_config = 0U;
  460.   pdev->dev_remote_wakeup = 0U;
  461.  
  462.   if (pdev->pClassData)
  463.   {
  464.     pdev->pClass->DeInit(pdev, (uint8_t)pdev->dev_config);
  465.   }
  466.  
  467.   return USBD_OK;
  468. }
  469.  
  470. /**
  471. * @brief  USBD_LL_Reset
  472. *         Handle Reset event
  473. * @param  pdev: device instance
  474. * @retval status
  475. */
  476. USBD_StatusTypeDef USBD_LL_SetSpeed(USBD_HandleTypeDef *pdev,
  477.                                     USBD_SpeedTypeDef speed)
  478. {
  479.   pdev->dev_speed = speed;
  480.  
  481.   return USBD_OK;
  482. }
  483.  
  484. /**
  485. * @brief  USBD_Suspend
  486. *         Handle Suspend event
  487. * @param  pdev: device instance
  488. * @retval status
  489. */
  490.  
  491. USBD_StatusTypeDef USBD_LL_Suspend(USBD_HandleTypeDef *pdev)
  492. {
  493.   pdev->dev_old_state =  pdev->dev_state;
  494.   pdev->dev_state  = USBD_STATE_SUSPENDED;
  495.  
  496.   return USBD_OK;
  497. }
  498.  
  499. /**
  500. * @brief  USBD_Resume
  501. *         Handle Resume event
  502. * @param  pdev: device instance
  503. * @retval status
  504. */
  505.  
  506. USBD_StatusTypeDef USBD_LL_Resume(USBD_HandleTypeDef *pdev)
  507. {
  508.   if (pdev->dev_state == USBD_STATE_SUSPENDED)
  509.   {
  510.     pdev->dev_state = pdev->dev_old_state;
  511.   }
  512.  
  513.   return USBD_OK;
  514. }
  515.  
  516. /**
  517. * @brief  USBD_SOF
  518. *         Handle SOF event
  519. * @param  pdev: device instance
  520. * @retval status
  521. */
  522.  
  523. USBD_StatusTypeDef USBD_LL_SOF(USBD_HandleTypeDef *pdev)
  524. {
  525.   if (pdev->dev_state == USBD_STATE_CONFIGURED)
  526.   {
  527.     if (pdev->pClass->SOF != NULL)
  528.     {
  529.       pdev->pClass->SOF(pdev);
  530.     }
  531.   }
  532.  
  533.   return USBD_OK;
  534. }
  535.  
  536. /**
  537. * @brief  USBD_IsoINIncomplete
  538. *         Handle iso in incomplete event
  539. * @param  pdev: device instance
  540. * @retval status
  541. */
  542. USBD_StatusTypeDef USBD_LL_IsoINIncomplete(USBD_HandleTypeDef *pdev,
  543.                                            uint8_t epnum)
  544. {
  545.   /* Prevent unused arguments compilation warning */
  546.   UNUSED(pdev);
  547.   UNUSED(epnum);
  548.  
  549.   return USBD_OK;
  550. }
  551.  
  552. /**
  553. * @brief  USBD_IsoOUTIncomplete
  554. *         Handle iso out incomplete event
  555. * @param  pdev: device instance
  556. * @retval status
  557. */
  558. USBD_StatusTypeDef USBD_LL_IsoOUTIncomplete(USBD_HandleTypeDef *pdev,
  559.                                             uint8_t epnum)
  560. {
  561.   /* Prevent unused arguments compilation warning */
  562.   UNUSED(pdev);
  563.   UNUSED(epnum);
  564.  
  565.   return USBD_OK;
  566. }
  567.  
  568. /**
  569. * @brief  USBD_DevConnected
  570. *         Handle device connection event
  571. * @param  pdev: device instance
  572. * @retval status
  573. */
  574. USBD_StatusTypeDef USBD_LL_DevConnected(USBD_HandleTypeDef *pdev)
  575. {
  576.   /* Prevent unused argument compilation warning */
  577.   UNUSED(pdev);
  578.  
  579.   return USBD_OK;
  580. }
  581.  
  582. /**
  583. * @brief  USBD_DevDisconnected
  584. *         Handle device disconnection event
  585. * @param  pdev: device instance
  586. * @retval status
  587. */
  588. USBD_StatusTypeDef USBD_LL_DevDisconnected(USBD_HandleTypeDef *pdev)
  589. {
  590.   /* Free Class Resources */
  591.   pdev->dev_state = USBD_STATE_DEFAULT;
  592.   pdev->pClass->DeInit(pdev, (uint8_t)pdev->dev_config);
  593.  
  594.   return USBD_OK;
  595. }
  596. /**
  597. * @}
  598. */
  599.  
  600.  
  601. /**
  602. * @}
  603. */
  604.  
  605.  
  606. /**
  607. * @}
  608. */
  609.  
  610. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
  611.  
  612.