|
- /**
- ******************************************************************************
- * @file usbd_core.c
- * @author MCD Application Team
- * @brief This file provides all the USBD core functions.
- ******************************************************************************
- * @attention
- *
- * <h2><center>© Copyright (c) 2015 STMicroelectronics.
- * All rights reserved.</center></h2>
- *
- * 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:
- * http://www.st.com/SLA0044
- *
- ******************************************************************************
- */
-
- /* Includes ------------------------------------------------------------------*/
- #include "usbd_core.h"
-
- /** @addtogroup STM32_USBD_DEVICE_LIBRARY
- * @{
- */
-
-
- /** @defgroup USBD_CORE
- * @brief usbd core module
- * @{
- */
-
- /** @defgroup USBD_CORE_Private_TypesDefinitions
- * @{
- */
- /**
- * @}
- */
-
-
- /** @defgroup USBD_CORE_Private_Defines
- * @{
- */
-
- /**
- * @}
- */
-
-
- /** @defgroup USBD_CORE_Private_Macros
- * @{
- */
- /**
- * @}
- */
-
-
-
-
- /** @defgroup USBD_CORE_Private_FunctionPrototypes
- * @{
- */
-
- /**
- * @}
- */
-
- /** @defgroup USBD_CORE_Private_Variables
- * @{
- */
-
- /**
- * @}
- */
-
- /** @defgroup USBD_CORE_Private_Functions
- * @{
- */
-
- /**
- * @brief USBD_Init
- * Initializes the device stack and load the class driver
- * @param pdev: device instance
- * @param pdesc: Descriptor structure address
- * @param id: Low level core index
- * @retval None
- */
- USBD_StatusTypeDef USBD_Init(USBD_HandleTypeDef *pdev, USBD_DescriptorsTypeDef *pdesc, uint8_t id)
- {
- /* Check whether the USB Host handle is valid */
- if(pdev == NULL)
- {
- #if (USBD_DEBUG_LEVEL > 1U)
- USBD_ErrLog("Invalid Device handle");
- #endif
- return USBD_FAIL;
- }
-
- /* Unlink previous class*/
- if(pdev->pClass != NULL)
- {
- pdev->pClass = NULL;
- }
-
- /* Assign USBD Descriptors */
- if(pdesc != NULL)
- {
- pdev->pDesc = pdesc;
- }
-
- /* Set Device initial State */
- pdev->dev_state = USBD_STATE_DEFAULT;
- pdev->id = id;
- /* Initialize low level driver */
- USBD_LL_Init(pdev);
-
- return USBD_OK;
- }
-
- /**
- * @brief USBD_DeInit
- * Re-Initialize th device library
- * @param pdev: device instance
- * @retval status: status
- */
- USBD_StatusTypeDef USBD_DeInit(USBD_HandleTypeDef *pdev)
- {
- /* Set Default State */
- pdev->dev_state = USBD_STATE_DEFAULT;
-
- /* Free Class Resources */
- pdev->pClass->DeInit(pdev, (uint8_t)pdev->dev_config);
-
- /* Stop the low level driver */
- USBD_LL_Stop(pdev);
-
- /* Initialize low level driver */
- USBD_LL_DeInit(pdev);
-
- return USBD_OK;
- }
-
- /**
- * @brief USBD_RegisterClass
- * Link class driver to Device Core.
- * @param pDevice : Device Handle
- * @param pclass: Class handle
- * @retval USBD Status
- */
- USBD_StatusTypeDef USBD_RegisterClass(USBD_HandleTypeDef *pdev, USBD_ClassTypeDef *pclass)
- {
- USBD_StatusTypeDef status = USBD_OK;
- if(pclass != 0)
- {
- /* link the class to the USB Device handle */
- pdev->pClass = pclass;
- status = USBD_OK;
- }
- else
- {
- #if (USBD_DEBUG_LEVEL > 1U)
- USBD_ErrLog("Invalid Class handle");
- #endif
- status = USBD_FAIL;
- }
-
- return status;
- }
-
- /**
- * @brief USBD_Start
- * Start the USB Device Core.
- * @param pdev: Device Handle
- * @retval USBD Status
- */
- USBD_StatusTypeDef USBD_Start (USBD_HandleTypeDef *pdev)
- {
-
- /* Start the low level driver */
- USBD_LL_Start(pdev);
-
- return USBD_OK;
- }
-
- /**
- * @brief USBD_Stop
- * Stop the USB Device Core.
- * @param pdev: Device Handle
- * @retval USBD Status
- */
- USBD_StatusTypeDef USBD_Stop (USBD_HandleTypeDef *pdev)
- {
- /* Free Class Resources */
- pdev->pClass->DeInit(pdev, (uint8_t)pdev->dev_config);
-
- /* Stop the low level driver */
- USBD_LL_Stop(pdev);
-
- return USBD_OK;
- }
-
- /**
- * @brief USBD_RunTestMode
- * Launch test mode process
- * @param pdev: device instance
- * @retval status
- */
- USBD_StatusTypeDef USBD_RunTestMode (USBD_HandleTypeDef *pdev)
- {
- /* Prevent unused argument compilation warning */
- UNUSED(pdev);
-
- return USBD_OK;
- }
-
- /**
- * @brief USBD_SetClassConfig
- * Configure device and start the interface
- * @param pdev: device instance
- * @param cfgidx: configuration index
- * @retval status
- */
-
- USBD_StatusTypeDef USBD_SetClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
- {
- USBD_StatusTypeDef ret = USBD_FAIL;
-
- if(pdev->pClass != NULL)
- {
- /* Set configuration and Start the Class*/
- if(pdev->pClass->Init(pdev, cfgidx) == 0U)
- {
- ret = USBD_OK;
- }
- }
-
- return ret;
- }
-
- /**
- * @brief USBD_ClrClassConfig
- * Clear current configuration
- * @param pdev: device instance
- * @param cfgidx: configuration index
- * @retval status: USBD_StatusTypeDef
- */
- USBD_StatusTypeDef USBD_ClrClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
- {
- /* Clear configuration and De-initialize the Class process*/
- pdev->pClass->DeInit(pdev, cfgidx);
- return USBD_OK;
- }
-
-
- /**
- * @brief USBD_SetupStage
- * Handle the setup stage
- * @param pdev: device instance
- * @retval status
- */
- USBD_StatusTypeDef USBD_LL_SetupStage(USBD_HandleTypeDef *pdev, uint8_t *psetup)
- {
- USBD_ParseSetupRequest(&pdev->request, psetup);
-
- pdev->ep0_state = USBD_EP0_SETUP;
-
- pdev->ep0_data_len = pdev->request.wLength;
-
- switch (pdev->request.bmRequest & 0x1FU)
- {
- case USB_REQ_RECIPIENT_DEVICE:
- USBD_StdDevReq (pdev, &pdev->request);
- break;
-
- case USB_REQ_RECIPIENT_INTERFACE:
- USBD_StdItfReq(pdev, &pdev->request);
- break;
-
- case USB_REQ_RECIPIENT_ENDPOINT:
- USBD_StdEPReq(pdev, &pdev->request);
- break;
-
- default:
- USBD_LL_StallEP(pdev, (pdev->request.bmRequest & 0x80U));
- break;
- }
-
- return USBD_OK;
- }
-
- /**
- * @brief USBD_DataOutStage
- * Handle data OUT stage
- * @param pdev: device instance
- * @param epnum: endpoint index
- * @retval status
- */
- USBD_StatusTypeDef USBD_LL_DataOutStage(USBD_HandleTypeDef *pdev,
- uint8_t epnum, uint8_t *pdata)
- {
- USBD_EndpointTypeDef *pep;
-
- if(epnum == 0U)
- {
- pep = &pdev->ep_out[0];
-
- if ( pdev->ep0_state == USBD_EP0_DATA_OUT)
- {
- if(pep->rem_length > pep->maxpacket)
- {
- pep->rem_length -= pep->maxpacket;
-
- USBD_CtlContinueRx (pdev,
- pdata,
- (uint16_t)MIN(pep->rem_length, pep->maxpacket));
- }
- else
- {
- if((pdev->pClass->EP0_RxReady != NULL)&&
- (pdev->dev_state == USBD_STATE_CONFIGURED))
- {
- pdev->pClass->EP0_RxReady(pdev);
- }
- USBD_CtlSendStatus(pdev);
- }
- }
- else
- {
- if (pdev->ep0_state == USBD_EP0_STATUS_OUT)
- {
- /*
- * STATUS PHASE completed, update ep0_state to idle
- */
- pdev->ep0_state = USBD_EP0_IDLE;
- USBD_LL_StallEP(pdev, 0U);
- }
- }
- }
- else if((pdev->pClass->DataOut != NULL) &&
- (pdev->dev_state == USBD_STATE_CONFIGURED))
- {
- pdev->pClass->DataOut(pdev, epnum);
- }
- else
- {
- /* should never be in this condition */
- return USBD_FAIL;
- }
-
- return USBD_OK;
- }
-
- /**
- * @brief USBD_DataInStage
- * Handle data in stage
- * @param pdev: device instance
- * @param epnum: endpoint index
- * @retval status
- */
- USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev, uint8_t epnum,
- uint8_t *pdata)
- {
- USBD_EndpointTypeDef *pep;
-
- if(epnum == 0U)
- {
- pep = &pdev->ep_in[0];
-
- if ( pdev->ep0_state == USBD_EP0_DATA_IN)
- {
- if(pep->rem_length > pep->maxpacket)
- {
- pep->rem_length -= pep->maxpacket;
-
- USBD_CtlContinueSendData (pdev, pdata, (uint16_t)pep->rem_length);
-
- /* Prepare endpoint for premature end of transfer */
- USBD_LL_PrepareReceive (pdev, 0U, NULL, 0U);
- }
- else
- { /* last packet is MPS multiple, so send ZLP packet */
- if((pep->total_length % pep->maxpacket == 0U) &&
- (pep->total_length >= pep->maxpacket) &&
- (pep->total_length < pdev->ep0_data_len))
- {
- USBD_CtlContinueSendData(pdev, NULL, 0U);
- pdev->ep0_data_len = 0U;
-
- /* Prepare endpoint for premature end of transfer */
- USBD_LL_PrepareReceive (pdev, 0U, NULL, 0U);
- }
- else
- {
- if((pdev->pClass->EP0_TxSent != NULL)&&
- (pdev->dev_state == USBD_STATE_CONFIGURED))
- {
- pdev->pClass->EP0_TxSent(pdev);
- }
- USBD_LL_StallEP(pdev, 0x80U);
- USBD_CtlReceiveStatus(pdev);
- }
- }
- }
- else
- {
- if ((pdev->ep0_state == USBD_EP0_STATUS_IN) ||
- (pdev->ep0_state == USBD_EP0_IDLE))
- {
- USBD_LL_StallEP(pdev, 0x80U);
- }
- }
-
- if (pdev->dev_test_mode == 1U)
- {
- USBD_RunTestMode(pdev);
- pdev->dev_test_mode = 0U;
- }
- }
- else if((pdev->pClass->DataIn != NULL) &&
- (pdev->dev_state == USBD_STATE_CONFIGURED))
- {
- pdev->pClass->DataIn(pdev, epnum);
- }
- else
- {
- /* should never be in this condition */
- return USBD_FAIL;
- }
-
- return USBD_OK;
- }
-
- /**
- * @brief USBD_LL_Reset
- * Handle Reset event
- * @param pdev: device instance
- * @retval status
- */
-
- USBD_StatusTypeDef USBD_LL_Reset(USBD_HandleTypeDef *pdev)
- {
- /* Open EP0 OUT */
- USBD_LL_OpenEP(pdev, 0x00U, USBD_EP_TYPE_CTRL, USB_MAX_EP0_SIZE);
- pdev->ep_out[0x00U & 0xFU].is_used = 1U;
-
- pdev->ep_out[0].maxpacket = USB_MAX_EP0_SIZE;
-
- /* Open EP0 IN */
- USBD_LL_OpenEP(pdev, 0x80U, USBD_EP_TYPE_CTRL, USB_MAX_EP0_SIZE);
- pdev->ep_in[0x80U & 0xFU].is_used = 1U;
-
- pdev->ep_in[0].maxpacket = USB_MAX_EP0_SIZE;
- /* Upon Reset call user call back */
- pdev->dev_state = USBD_STATE_DEFAULT;
- pdev->ep0_state = USBD_EP0_IDLE;
- pdev->dev_config= 0U;
- pdev->dev_remote_wakeup = 0U;
-
- if (pdev->pClassData)
- {
- pdev->pClass->DeInit(pdev, (uint8_t)pdev->dev_config);
- }
-
- return USBD_OK;
- }
-
- /**
- * @brief USBD_LL_Reset
- * Handle Reset event
- * @param pdev: device instance
- * @retval status
- */
- USBD_StatusTypeDef USBD_LL_SetSpeed(USBD_HandleTypeDef *pdev, USBD_SpeedTypeDef speed)
- {
- pdev->dev_speed = speed;
- return USBD_OK;
- }
-
- /**
- * @brief USBD_Suspend
- * Handle Suspend event
- * @param pdev: device instance
- * @retval status
- */
-
- USBD_StatusTypeDef USBD_LL_Suspend(USBD_HandleTypeDef *pdev)
- {
- pdev->dev_old_state = pdev->dev_state;
- pdev->dev_state = USBD_STATE_SUSPENDED;
- return USBD_OK;
- }
-
- /**
- * @brief USBD_Resume
- * Handle Resume event
- * @param pdev: device instance
- * @retval status
- */
-
- USBD_StatusTypeDef USBD_LL_Resume(USBD_HandleTypeDef *pdev)
- {
- pdev->dev_state = pdev->dev_old_state;
- return USBD_OK;
- }
-
- /**
- * @brief USBD_SOF
- * Handle SOF event
- * @param pdev: device instance
- * @retval status
- */
-
- USBD_StatusTypeDef USBD_LL_SOF(USBD_HandleTypeDef *pdev)
- {
- if(pdev->dev_state == USBD_STATE_CONFIGURED)
- {
- if(pdev->pClass->SOF != NULL)
- {
- pdev->pClass->SOF(pdev);
- }
- }
- return USBD_OK;
- }
-
- /**
- * @brief USBD_IsoINIncomplete
- * Handle iso in incomplete event
- * @param pdev: device instance
- * @retval status
- */
- USBD_StatusTypeDef USBD_LL_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum)
- {
- /* Prevent unused arguments compilation warning */
- UNUSED(pdev);
- UNUSED(epnum);
-
- return USBD_OK;
- }
-
- /**
- * @brief USBD_IsoOUTIncomplete
- * Handle iso out incomplete event
- * @param pdev: device instance
- * @retval status
- */
- USBD_StatusTypeDef USBD_LL_IsoOUTIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum)
- {
- /* Prevent unused arguments compilation warning */
- UNUSED(pdev);
- UNUSED(epnum);
-
- return USBD_OK;
- }
-
- /**
- * @brief USBD_DevConnected
- * Handle device connection event
- * @param pdev: device instance
- * @retval status
- */
- USBD_StatusTypeDef USBD_LL_DevConnected(USBD_HandleTypeDef *pdev)
- {
- /* Prevent unused argument compilation warning */
- UNUSED(pdev);
-
- return USBD_OK;
- }
-
- /**
- * @brief USBD_DevDisconnected
- * Handle device disconnection event
- * @param pdev: device instance
- * @retval status
- */
- USBD_StatusTypeDef USBD_LL_DevDisconnected(USBD_HandleTypeDef *pdev)
- {
- /* Free Class Resources */
- pdev->dev_state = USBD_STATE_DEFAULT;
- pdev->pClass->DeInit(pdev, (uint8_t)pdev->dev_config);
-
- return USBD_OK;
- }
- /**
- * @}
- */
-
-
- /**
- * @}
- */
-
-
- /**
- * @}
- */
-
- /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|