diff options
| author | Damien <damien.p.george@gmail.com> | 2013-10-13 00:42:20 +0100 |
|---|---|---|
| committer | Damien <damien.p.george@gmail.com> | 2013-10-13 00:42:20 +0100 |
| commit | ed65605edc5c1376947a34723b9c750400b5a028 (patch) | |
| tree | d0317e867c4286ec7c889fc9ed18591a1d9990dd /stm/lib/usbd_core.c | |
| parent | 3ef4abb446dfcbdbc426a0921a33e0883607e677 (diff) | |
Inital commit of stm32f4xx framework.
Diffstat (limited to 'stm/lib/usbd_core.c')
| -rw-r--r-- | stm/lib/usbd_core.c | 506 |
1 files changed, 506 insertions, 0 deletions
diff --git a/stm/lib/usbd_core.c b/stm/lib/usbd_core.c new file mode 100644 index 000000000..fa647eb0f --- /dev/null +++ b/stm/lib/usbd_core.c @@ -0,0 +1,506 @@ +/**
+ ******************************************************************************
+ * @file usbd_core.c
+ * @author MCD Application Team
+ * @version V1.1.0
+ * @date 19-March-2012
+ * @brief This file provides all the USBD core functions.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT 2012 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (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/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_core.h"
+#include "usbd_req.h"
+#include "usbd_ioreq.h"
+#include "usb_dcd_int.h"
+#include "usb_bsp.h"
+
+/** @addtogroup STM32_USB_OTG_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
+* @{
+*/
+static uint8_t USBD_SetupStage(USB_OTG_CORE_HANDLE *pdev);
+static uint8_t USBD_DataOutStage(USB_OTG_CORE_HANDLE *pdev , uint8_t epnum);
+static uint8_t USBD_DataInStage(USB_OTG_CORE_HANDLE *pdev , uint8_t epnum);
+static uint8_t USBD_SOF(USB_OTG_CORE_HANDLE *pdev);
+static uint8_t USBD_Reset(USB_OTG_CORE_HANDLE *pdev);
+static uint8_t USBD_Suspend(USB_OTG_CORE_HANDLE *pdev);
+static uint8_t USBD_Resume(USB_OTG_CORE_HANDLE *pdev);
+#ifdef VBUS_SENSING_ENABLED
+static uint8_t USBD_DevConnected(USB_OTG_CORE_HANDLE *pdev);
+static uint8_t USBD_DevDisconnected(USB_OTG_CORE_HANDLE *pdev);
+#endif
+static uint8_t USBD_IsoINIncomplete(USB_OTG_CORE_HANDLE *pdev);
+static uint8_t USBD_IsoOUTIncomplete(USB_OTG_CORE_HANDLE *pdev);
+static uint8_t USBD_RunTestMode (USB_OTG_CORE_HANDLE *pdev) ;
+/**
+* @}
+*/
+
+/** @defgroup USBD_CORE_Private_Variables
+* @{
+*/
+
+__IO USB_OTG_DCTL_TypeDef SET_TEST_MODE;
+
+USBD_DCD_INT_cb_TypeDef USBD_DCD_INT_cb =
+{
+ USBD_DataOutStage,
+ USBD_DataInStage,
+ USBD_SetupStage,
+ USBD_SOF,
+ USBD_Reset,
+ USBD_Suspend,
+ USBD_Resume,
+ USBD_IsoINIncomplete,
+ USBD_IsoOUTIncomplete,
+#ifdef VBUS_SENSING_ENABLED
+USBD_DevConnected,
+USBD_DevDisconnected,
+#endif
+};
+
+USBD_DCD_INT_cb_TypeDef *USBD_DCD_INT_fops = &USBD_DCD_INT_cb;
+/**
+* @}
+*/
+
+/** @defgroup USBD_CORE_Private_Functions
+* @{
+*/
+
+/**
+* @brief USBD_Init
+* Initailizes the device stack and load the class driver
+* @param pdev: device instance
+* @param core_address: USB OTG core ID
+* @param class_cb: Class callback structure address
+* @param usr_cb: User callback structure address
+* @retval None
+*/
+void USBD_Init(USB_OTG_CORE_HANDLE *pdev,
+ USB_OTG_CORE_ID_TypeDef coreID,
+ USBD_DEVICE *pDevice,
+ USBD_Class_cb_TypeDef *class_cb,
+ USBD_Usr_cb_TypeDef *usr_cb)
+{
+ /* Hardware Init */
+ USB_OTG_BSP_Init(pdev);
+
+ USBD_DeInit(pdev);
+
+ /*Register class and user callbacks */
+ pdev->dev.class_cb = class_cb;
+ pdev->dev.usr_cb = usr_cb;
+ pdev->dev.usr_device = pDevice;
+
+ /* set USB OTG core params */
+ DCD_Init(pdev , coreID);
+
+ /* Upon Init call usr callback */
+ pdev->dev.usr_cb->Init();
+
+ /* Enable Interrupts */
+ USB_OTG_BSP_EnableInterrupt(pdev);
+}
+
+/**
+* @brief USBD_DeInit
+* Re-Initialize th device library
+* @param pdev: device instance
+* @retval status: status
+*/
+USBD_Status USBD_DeInit(USB_OTG_CORE_HANDLE *pdev)
+{
+ /* Software Init */
+
+ return USBD_OK;
+}
+
+/**
+* @brief USBD_SetupStage
+* Handle the setup stage
+* @param pdev: device instance
+* @retval status
+*/
+static uint8_t USBD_SetupStage(USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_SETUP_REQ req;
+
+ USBD_ParseSetupRequest(pdev , &req);
+
+ switch (req.bmRequest & 0x1F)
+ {
+ case USB_REQ_RECIPIENT_DEVICE:
+ USBD_StdDevReq (pdev, &req);
+ break;
+
+ case USB_REQ_RECIPIENT_INTERFACE:
+ USBD_StdItfReq(pdev, &req);
+ break;
+
+ case USB_REQ_RECIPIENT_ENDPOINT:
+ USBD_StdEPReq(pdev, &req);
+ break;
+
+ default:
+ DCD_EP_Stall(pdev , req.bmRequest & 0x80);
+ break;
+ }
+ return USBD_OK;
+}
+
+/**
+* @brief USBD_DataOutStage
+* Handle data out stage
+* @param pdev: device instance
+* @param epnum: endpoint index
+* @retval status
+*/
+static uint8_t USBD_DataOutStage(USB_OTG_CORE_HANDLE *pdev , uint8_t epnum)
+{
+ USB_OTG_EP *ep;
+
+ if(epnum == 0)
+ {
+ ep = &pdev->dev.out_ep[0];
+ if ( pdev->dev.device_state == USB_OTG_EP0_DATA_OUT)
+ {
+ if(ep->rem_data_len > ep->maxpacket)
+ {
+ ep->rem_data_len -= ep->maxpacket;
+
+ if(pdev->cfg.dma_enable == 1)
+ {
+ /* in slave mode this, is handled by the RxSTSQLvl ISR */
+ ep->xfer_buff += ep->maxpacket;
+ }
+ USBD_CtlContinueRx (pdev,
+ ep->xfer_buff,
+ MIN(ep->rem_data_len ,ep->maxpacket));
+ }
+ else
+ {
+ if((pdev->dev.class_cb->EP0_RxReady != NULL)&&
+ (pdev->dev.device_status == USB_OTG_CONFIGURED))
+ {
+ pdev->dev.class_cb->EP0_RxReady(pdev);
+ }
+ USBD_CtlSendStatus(pdev);
+ }
+ }
+ }
+ else if((pdev->dev.class_cb->DataOut != NULL)&&
+ (pdev->dev.device_status == USB_OTG_CONFIGURED))
+ {
+ pdev->dev.class_cb->DataOut(pdev, epnum);
+ }
+ return USBD_OK;
+}
+
+/**
+* @brief USBD_DataInStage
+* Handle data in stage
+* @param pdev: device instance
+* @param epnum: endpoint index
+* @retval status
+*/
+static uint8_t USBD_DataInStage(USB_OTG_CORE_HANDLE *pdev , uint8_t epnum)
+{
+ USB_OTG_EP *ep;
+
+ if(epnum == 0)
+ {
+ ep = &pdev->dev.in_ep[0];
+ if ( pdev->dev.device_state == USB_OTG_EP0_DATA_IN)
+ {
+ if(ep->rem_data_len > ep->maxpacket)
+ {
+ ep->rem_data_len -= ep->maxpacket;
+ if(pdev->cfg.dma_enable == 1)
+ {
+ /* in slave mode this, is handled by the TxFifoEmpty ISR */
+ ep->xfer_buff += ep->maxpacket;
+ }
+ USBD_CtlContinueSendData (pdev,
+ ep->xfer_buff,
+ ep->rem_data_len);
+ }
+ else
+ { /* last packet is MPS multiple, so send ZLP packet */
+ if((ep->total_data_len % ep->maxpacket == 0) &&
+ (ep->total_data_len >= ep->maxpacket) &&
+ (ep->total_data_len < ep->ctl_data_len ))
+ {
+
+ USBD_CtlContinueSendData(pdev , NULL, 0);
+ ep->ctl_data_len = 0;
+ }
+ else
+ {
+ if((pdev->dev.class_cb->EP0_TxSent != NULL)&&
+ (pdev->dev.device_status == USB_OTG_CONFIGURED))
+ {
+ pdev->dev.class_cb->EP0_TxSent(pdev);
+ }
+ USBD_CtlReceiveStatus(pdev);
+ }
+ }
+ }
+ if (pdev->dev.test_mode == 1)
+ {
+ USBD_RunTestMode(pdev);
+ pdev->dev.test_mode = 0;
+ }
+ }
+ else if((pdev->dev.class_cb->DataIn != NULL)&&
+ (pdev->dev.device_status == USB_OTG_CONFIGURED))
+ {
+ pdev->dev.class_cb->DataIn(pdev, epnum);
+ }
+ return USBD_OK;
+}
+
+
+
+
+/**
+* @brief USBD_RunTestMode
+* Launch test mode process
+* @param pdev: device instance
+* @retval status
+*/
+static uint8_t USBD_RunTestMode (USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_WRITE_REG32(&pdev->regs.DREGS->DCTL, SET_TEST_MODE.d32);
+ return USBD_OK;
+}
+
+/**
+* @brief USBD_Reset
+* Handle Reset event
+* @param pdev: device instance
+* @retval status
+*/
+
+static uint8_t USBD_Reset(USB_OTG_CORE_HANDLE *pdev)
+{
+ /* Open EP0 OUT */
+ DCD_EP_Open(pdev,
+ 0x00,
+ USB_OTG_MAX_EP0_SIZE,
+ EP_TYPE_CTRL);
+
+ /* Open EP0 IN */
+ DCD_EP_Open(pdev,
+ 0x80,
+ USB_OTG_MAX_EP0_SIZE,
+ EP_TYPE_CTRL);
+
+ /* Upon Reset call usr call back */
+ pdev->dev.device_status = USB_OTG_DEFAULT;
+ pdev->dev.usr_cb->DeviceReset(pdev->cfg.speed);
+
+ return USBD_OK;
+}
+
+/**
+* @brief USBD_Resume
+* Handle Resume event
+* @param pdev: device instance
+* @retval status
+*/
+
+static uint8_t USBD_Resume(USB_OTG_CORE_HANDLE *pdev)
+{
+ /* Upon Resume call usr call back */
+ pdev->dev.usr_cb->DeviceResumed();
+ pdev->dev.device_status = pdev->dev.device_old_status;
+ pdev->dev.device_status = USB_OTG_CONFIGURED;
+ return USBD_OK;
+}
+
+
+/**
+* @brief USBD_Suspend
+* Handle Suspend event
+* @param pdev: device instance
+* @retval status
+*/
+
+static uint8_t USBD_Suspend(USB_OTG_CORE_HANDLE *pdev)
+{
+ pdev->dev.device_old_status = pdev->dev.device_status;
+ pdev->dev.device_status = USB_OTG_SUSPENDED;
+ /* Upon Resume call usr call back */
+ pdev->dev.usr_cb->DeviceSuspended();
+ return USBD_OK;
+}
+
+
+/**
+* @brief USBD_SOF
+* Handle SOF event
+* @param pdev: device instance
+* @retval status
+*/
+
+static uint8_t USBD_SOF(USB_OTG_CORE_HANDLE *pdev)
+{
+ if(pdev->dev.class_cb->SOF)
+ {
+ pdev->dev.class_cb->SOF(pdev);
+ }
+ return USBD_OK;
+}
+/**
+* @brief USBD_SetCfg
+* Configure device and start the interface
+* @param pdev: device instance
+* @param cfgidx: configuration index
+* @retval status
+*/
+
+USBD_Status USBD_SetCfg(USB_OTG_CORE_HANDLE *pdev, uint8_t cfgidx)
+{
+ pdev->dev.class_cb->Init(pdev, cfgidx);
+
+ /* Upon set config call usr call back */
+ pdev->dev.usr_cb->DeviceConfigured();
+ return USBD_OK;
+}
+
+/**
+* @brief USBD_ClrCfg
+* Clear current configuration
+* @param pdev: device instance
+* @param cfgidx: configuration index
+* @retval status: USBD_Status
+*/
+USBD_Status USBD_ClrCfg(USB_OTG_CORE_HANDLE *pdev, uint8_t cfgidx)
+{
+ pdev->dev.class_cb->DeInit(pdev, cfgidx);
+ return USBD_OK;
+}
+
+/**
+* @brief USBD_IsoINIncomplete
+* Handle iso in incomplete event
+* @param pdev: device instance
+* @retval status
+*/
+static uint8_t USBD_IsoINIncomplete(USB_OTG_CORE_HANDLE *pdev)
+{
+ pdev->dev.class_cb->IsoINIncomplete(pdev);
+ return USBD_OK;
+}
+
+/**
+* @brief USBD_IsoOUTIncomplete
+* Handle iso out incomplete event
+* @param pdev: device instance
+* @retval status
+*/
+static uint8_t USBD_IsoOUTIncomplete(USB_OTG_CORE_HANDLE *pdev)
+{
+ pdev->dev.class_cb->IsoOUTIncomplete(pdev);
+ return USBD_OK;
+}
+
+#ifdef VBUS_SENSING_ENABLED
+/**
+* @brief USBD_DevConnected
+* Handle device connection event
+* @param pdev: device instance
+* @retval status
+*/
+static uint8_t USBD_DevConnected(USB_OTG_CORE_HANDLE *pdev)
+{
+ pdev->dev.usr_cb->DeviceConnected();
+ pdev->dev.connection_status = 1;
+ return USBD_OK;
+}
+
+/**
+* @brief USBD_DevDisconnected
+* Handle device disconnection event
+* @param pdev: device instance
+* @retval status
+*/
+static uint8_t USBD_DevDisconnected(USB_OTG_CORE_HANDLE *pdev)
+{
+ pdev->dev.usr_cb->DeviceDisconnected();
+ pdev->dev.class_cb->DeInit(pdev, 0);
+ pdev->dev.connection_status = 0;
+ return USBD_OK;
+}
+#endif
+/**
+* @}
+*/
+
+
+/**
+* @}
+*/
+
+
+/**
+* @}
+*/
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
|
