29 changed files with 10767 additions and 48 deletions
File diff suppressed because one or more lines are too long
@ -0,0 +1,994 @@ |
|||
/**
|
|||
****************************************************************************** |
|||
* @file stm32wbxx_hal_pcd.h |
|||
* @author MCD Application Team |
|||
* @brief Header file of PCD HAL module. |
|||
****************************************************************************** |
|||
* @attention |
|||
* |
|||
* <h2><center>© Copyright (c) 2019 STMicroelectronics. |
|||
* All rights reserved.</center></h2> |
|||
* |
|||
* This software component is licensed by ST under BSD 3-Clause license, |
|||
* the "License"; You may not use this file except in compliance with the |
|||
* License. You may obtain a copy of the License at: |
|||
* opensource.org/licenses/BSD-3-Clause |
|||
* |
|||
****************************************************************************** |
|||
*/ |
|||
|
|||
/* Define to prevent recursive inclusion -------------------------------------*/ |
|||
#ifndef STM32WBxx_HAL_PCD_H |
|||
#define STM32WBxx_HAL_PCD_H |
|||
|
|||
#ifdef __cplusplus |
|||
extern "C" { |
|||
#endif |
|||
|
|||
/* Includes ------------------------------------------------------------------*/ |
|||
#include "stm32wbxx_ll_usb.h" |
|||
|
|||
#if defined (USB) |
|||
|
|||
/** @addtogroup STM32WBxx_HAL_Driver
|
|||
* @{ |
|||
*/ |
|||
|
|||
/** @addtogroup PCD
|
|||
* @{ |
|||
*/ |
|||
|
|||
/* Exported types ------------------------------------------------------------*/ |
|||
/** @defgroup PCD_Exported_Types PCD Exported Types
|
|||
* @{ |
|||
*/ |
|||
|
|||
/**
|
|||
* @brief PCD State structure definition |
|||
*/ |
|||
typedef enum |
|||
{ |
|||
HAL_PCD_STATE_RESET = 0x00, |
|||
HAL_PCD_STATE_READY = 0x01, |
|||
HAL_PCD_STATE_ERROR = 0x02, |
|||
HAL_PCD_STATE_BUSY = 0x03, |
|||
HAL_PCD_STATE_TIMEOUT = 0x04 |
|||
} PCD_StateTypeDef; |
|||
|
|||
/* Device LPM suspend state */ |
|||
typedef enum |
|||
{ |
|||
LPM_L0 = 0x00, /* on */ |
|||
LPM_L1 = 0x01, /* LPM L1 sleep */ |
|||
LPM_L2 = 0x02, /* suspend */ |
|||
LPM_L3 = 0x03, /* off */ |
|||
} PCD_LPM_StateTypeDef; |
|||
|
|||
typedef enum |
|||
{ |
|||
PCD_LPM_L0_ACTIVE = 0x00, /* on */ |
|||
PCD_LPM_L1_ACTIVE = 0x01, /* LPM L1 sleep */ |
|||
} PCD_LPM_MsgTypeDef; |
|||
|
|||
typedef enum |
|||
{ |
|||
PCD_BCD_ERROR = 0xFF, |
|||
PCD_BCD_CONTACT_DETECTION = 0xFE, |
|||
PCD_BCD_STD_DOWNSTREAM_PORT = 0xFD, |
|||
PCD_BCD_CHARGING_DOWNSTREAM_PORT = 0xFC, |
|||
PCD_BCD_DEDICATED_CHARGING_PORT = 0xFB, |
|||
PCD_BCD_DISCOVERY_COMPLETED = 0x00, |
|||
|
|||
} PCD_BCD_MsgTypeDef; |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
typedef USB_TypeDef PCD_TypeDef; |
|||
typedef USB_CfgTypeDef PCD_InitTypeDef; |
|||
typedef USB_EPTypeDef PCD_EPTypeDef; |
|||
|
|||
|
|||
/**
|
|||
* @brief PCD Handle Structure definition |
|||
*/ |
|||
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) |
|||
typedef struct __PCD_HandleTypeDef |
|||
#else |
|||
typedef struct |
|||
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ |
|||
{ |
|||
PCD_TypeDef *Instance; /*!< Register base address */ |
|||
PCD_InitTypeDef Init; /*!< PCD required parameters */ |
|||
__IO uint8_t USB_Address; /*!< USB Address */ |
|||
PCD_EPTypeDef IN_ep[8]; /*!< IN endpoint parameters */ |
|||
PCD_EPTypeDef OUT_ep[8]; /*!< OUT endpoint parameters */ |
|||
HAL_LockTypeDef Lock; /*!< PCD peripheral status */ |
|||
__IO PCD_StateTypeDef State; /*!< PCD communication state */ |
|||
__IO uint32_t ErrorCode; /*!< PCD Error code */ |
|||
uint32_t Setup[12]; /*!< Setup packet buffer */ |
|||
PCD_LPM_StateTypeDef LPM_State; /*!< LPM State */ |
|||
uint32_t BESL; |
|||
|
|||
|
|||
uint32_t lpm_active; /*!< Enable or disable the Link Power Management .
|
|||
This parameter can be set to ENABLE or DISABLE */ |
|||
|
|||
uint32_t battery_charging_active; /*!< Enable or disable Battery charging.
|
|||
This parameter can be set to ENABLE or DISABLE */ |
|||
void *pData; /*!< Pointer to upper stack Handler */ |
|||
|
|||
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) |
|||
void (* SOFCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD SOF callback */ |
|||
void (* SetupStageCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Setup Stage callback */ |
|||
void (* ResetCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Reset callback */ |
|||
void (* SuspendCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Suspend callback */ |
|||
void (* ResumeCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Resume callback */ |
|||
void (* ConnectCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Connect callback */ |
|||
void (* DisconnectCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Disconnect callback */ |
|||
|
|||
void (* DataOutStageCallback)(struct __PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< USB OTG PCD Data OUT Stage callback */ |
|||
void (* DataInStageCallback)(struct __PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< USB OTG PCD Data IN Stage callback */ |
|||
void (* ISOOUTIncompleteCallback)(struct __PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< USB OTG PCD ISO OUT Incomplete callback */ |
|||
void (* ISOINIncompleteCallback)(struct __PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< USB OTG PCD ISO IN Incomplete callback */ |
|||
void (* BCDCallback)(struct __PCD_HandleTypeDef *hpcd, PCD_BCD_MsgTypeDef msg); /*!< USB OTG PCD BCD callback */ |
|||
void (* LPMCallback)(struct __PCD_HandleTypeDef *hpcd, PCD_LPM_MsgTypeDef msg); /*!< USB OTG PCD LPM callback */ |
|||
|
|||
void (* MspInitCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Msp Init callback */ |
|||
void (* MspDeInitCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Msp DeInit callback */ |
|||
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ |
|||
} PCD_HandleTypeDef; |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/* Include PCD HAL Extended module */ |
|||
#include "stm32wbxx_hal_pcd_ex.h" |
|||
|
|||
/* Exported constants --------------------------------------------------------*/ |
|||
/** @defgroup PCD_Exported_Constants PCD Exported Constants
|
|||
* @{ |
|||
*/ |
|||
|
|||
/** @defgroup PCD_Speed PCD Speed
|
|||
* @{ |
|||
*/ |
|||
#define PCD_SPEED_FULL USBD_FS_SPEED |
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/** @defgroup PCD_PHY_Module PCD PHY Module
|
|||
* @{ |
|||
*/ |
|||
#define PCD_PHY_ULPI 1U |
|||
#define PCD_PHY_EMBEDDED 2U |
|||
#define PCD_PHY_UTMI 3U |
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/** @defgroup PCD_Error_Code_definition PCD Error Code definition
|
|||
* @brief PCD Error Code definition |
|||
* @{ |
|||
*/ |
|||
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) |
|||
#define HAL_PCD_ERROR_INVALID_CALLBACK (0x00000010U) /*!< Invalid Callback error */ |
|||
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/* Exported macros -----------------------------------------------------------*/ |
|||
/** @defgroup PCD_Exported_Macros PCD Exported Macros
|
|||
* @brief macros to handle interrupts and specific clock configurations |
|||
* @{ |
|||
*/ |
|||
|
|||
|
|||
#define __HAL_PCD_ENABLE(__HANDLE__) (void)USB_EnableGlobalInt ((__HANDLE__)->Instance) |
|||
#define __HAL_PCD_DISABLE(__HANDLE__) (void)USB_DisableGlobalInt ((__HANDLE__)->Instance) |
|||
#define __HAL_PCD_GET_FLAG(__HANDLE__, __INTERRUPT__) ((USB_ReadInterrupts((__HANDLE__)->Instance) & (__INTERRUPT__)) == (__INTERRUPT__)) |
|||
#define __HAL_PCD_CLEAR_FLAG(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->ISTR) &= (uint16_t)(~(__INTERRUPT__))) |
|||
|
|||
#define __HAL_USB_WAKEUP_EXTI_ENABLE_IT() EXTI->IMR1 |= USB_WAKEUP_EXTI_LINE |
|||
#define __HAL_USB_WAKEUP_EXTI_DISABLE_IT() EXTI->IMR1 &= ~(USB_WAKEUP_EXTI_LINE) |
|||
|
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/* Exported functions --------------------------------------------------------*/ |
|||
/** @addtogroup PCD_Exported_Functions PCD Exported Functions
|
|||
* @{ |
|||
*/ |
|||
|
|||
/* Initialization/de-initialization functions ********************************/ |
|||
/** @addtogroup PCD_Exported_Functions_Group1 Initialization and de-initialization functions
|
|||
* @{ |
|||
*/ |
|||
HAL_StatusTypeDef HAL_PCD_Init(PCD_HandleTypeDef *hpcd); |
|||
HAL_StatusTypeDef HAL_PCD_DeInit(PCD_HandleTypeDef *hpcd); |
|||
void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd); |
|||
void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd); |
|||
|
|||
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) |
|||
/** @defgroup HAL_PCD_Callback_ID_enumeration_definition HAL USB OTG PCD Callback ID enumeration definition
|
|||
* @brief HAL USB OTG PCD Callback ID enumeration definition |
|||
* @{ |
|||
*/ |
|||
typedef enum |
|||
{ |
|||
HAL_PCD_SOF_CB_ID = 0x01, /*!< USB PCD SOF callback ID */ |
|||
HAL_PCD_SETUPSTAGE_CB_ID = 0x02, /*!< USB PCD Setup Stage callback ID */ |
|||
HAL_PCD_RESET_CB_ID = 0x03, /*!< USB PCD Reset callback ID */ |
|||
HAL_PCD_SUSPEND_CB_ID = 0x04, /*!< USB PCD Suspend callback ID */ |
|||
HAL_PCD_RESUME_CB_ID = 0x05, /*!< USB PCD Resume callback ID */ |
|||
HAL_PCD_CONNECT_CB_ID = 0x06, /*!< USB PCD Connect callback ID */ |
|||
HAL_PCD_DISCONNECT_CB_ID = 0x07, /*!< USB PCD Disconnect callback ID */ |
|||
|
|||
HAL_PCD_MSPINIT_CB_ID = 0x08, /*!< USB PCD MspInit callback ID */ |
|||
HAL_PCD_MSPDEINIT_CB_ID = 0x09 /*!< USB PCD MspDeInit callback ID */ |
|||
|
|||
} HAL_PCD_CallbackIDTypeDef; |
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/** @defgroup HAL_PCD_Callback_pointer_definition HAL USB OTG PCD Callback pointer definition
|
|||
* @brief HAL USB OTG PCD Callback pointer definition |
|||
* @{ |
|||
*/ |
|||
|
|||
typedef void (*pPCD_CallbackTypeDef)(PCD_HandleTypeDef *hpcd); /*!< pointer to a common USB OTG PCD callback function */ |
|||
typedef void (*pPCD_DataOutStageCallbackTypeDef)(PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< pointer to USB OTG PCD Data OUT Stage callback */ |
|||
typedef void (*pPCD_DataInStageCallbackTypeDef)(PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< pointer to USB OTG PCD Data IN Stage callback */ |
|||
typedef void (*pPCD_IsoOutIncpltCallbackTypeDef)(PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< pointer to USB OTG PCD ISO OUT Incomplete callback */ |
|||
typedef void (*pPCD_IsoInIncpltCallbackTypeDef)(PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< pointer to USB OTG PCD ISO IN Incomplete callback */ |
|||
typedef void (*pPCD_LpmCallbackTypeDef)(PCD_HandleTypeDef *hpcd, PCD_LPM_MsgTypeDef msg); /*!< pointer to USB OTG PCD LPM callback */ |
|||
typedef void (*pPCD_BcdCallbackTypeDef)(PCD_HandleTypeDef *hpcd, PCD_BCD_MsgTypeDef msg); /*!< pointer to USB OTG PCD BCD callback */ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
HAL_StatusTypeDef HAL_PCD_RegisterCallback(PCD_HandleTypeDef *hpcd, |
|||
HAL_PCD_CallbackIDTypeDef CallbackID, |
|||
pPCD_CallbackTypeDef pCallback); |
|||
|
|||
HAL_StatusTypeDef HAL_PCD_UnRegisterCallback(PCD_HandleTypeDef *hpcd, |
|||
HAL_PCD_CallbackIDTypeDef CallbackID); |
|||
|
|||
HAL_StatusTypeDef HAL_PCD_RegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd, |
|||
pPCD_DataOutStageCallbackTypeDef pCallback); |
|||
|
|||
HAL_StatusTypeDef HAL_PCD_UnRegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd); |
|||
|
|||
HAL_StatusTypeDef HAL_PCD_RegisterDataInStageCallback(PCD_HandleTypeDef *hpcd, |
|||
pPCD_DataInStageCallbackTypeDef pCallback); |
|||
|
|||
HAL_StatusTypeDef HAL_PCD_UnRegisterDataInStageCallback(PCD_HandleTypeDef *hpcd); |
|||
|
|||
HAL_StatusTypeDef HAL_PCD_RegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd, |
|||
pPCD_IsoOutIncpltCallbackTypeDef pCallback); |
|||
|
|||
HAL_StatusTypeDef HAL_PCD_UnRegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd); |
|||
|
|||
HAL_StatusTypeDef HAL_PCD_RegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd, |
|||
pPCD_IsoInIncpltCallbackTypeDef pCallback); |
|||
|
|||
HAL_StatusTypeDef HAL_PCD_UnRegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd); |
|||
|
|||
HAL_StatusTypeDef HAL_PCD_RegisterBcdCallback(PCD_HandleTypeDef *hpcd, |
|||
pPCD_BcdCallbackTypeDef pCallback); |
|||
|
|||
HAL_StatusTypeDef HAL_PCD_UnRegisterBcdCallback(PCD_HandleTypeDef *hpcd); |
|||
|
|||
HAL_StatusTypeDef HAL_PCD_RegisterLpmCallback(PCD_HandleTypeDef *hpcd, |
|||
pPCD_LpmCallbackTypeDef pCallback); |
|||
|
|||
HAL_StatusTypeDef HAL_PCD_UnRegisterLpmCallback(PCD_HandleTypeDef *hpcd); |
|||
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ |
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/* I/O operation functions ***************************************************/ |
|||
/* Non-Blocking mode: Interrupt */ |
|||
/** @addtogroup PCD_Exported_Functions_Group2 Input and Output operation functions
|
|||
* @{ |
|||
*/ |
|||
HAL_StatusTypeDef HAL_PCD_Start(PCD_HandleTypeDef *hpcd); |
|||
HAL_StatusTypeDef HAL_PCD_Stop(PCD_HandleTypeDef *hpcd); |
|||
void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd); |
|||
|
|||
void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd); |
|||
void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd); |
|||
void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd); |
|||
void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd); |
|||
void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd); |
|||
void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd); |
|||
void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd); |
|||
|
|||
void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum); |
|||
void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum); |
|||
void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum); |
|||
void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum); |
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/* Peripheral Control functions **********************************************/ |
|||
/** @addtogroup PCD_Exported_Functions_Group3 Peripheral Control functions
|
|||
* @{ |
|||
*/ |
|||
HAL_StatusTypeDef HAL_PCD_DevConnect(PCD_HandleTypeDef *hpcd); |
|||
HAL_StatusTypeDef HAL_PCD_DevDisconnect(PCD_HandleTypeDef *hpcd); |
|||
HAL_StatusTypeDef HAL_PCD_SetAddress(PCD_HandleTypeDef *hpcd, uint8_t address); |
|||
HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, |
|||
uint16_t ep_mps, uint8_t ep_type); |
|||
|
|||
HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr); |
|||
HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, |
|||
uint8_t *pBuf, uint32_t len); |
|||
|
|||
HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, |
|||
uint8_t *pBuf, uint32_t len); |
|||
|
|||
|
|||
HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr); |
|||
HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr); |
|||
HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef *hpcd, uint8_t ep_addr); |
|||
HAL_StatusTypeDef HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef *hpcd); |
|||
HAL_StatusTypeDef HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef *hpcd); |
|||
|
|||
uint32_t HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef *hpcd, uint8_t ep_addr); |
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/* Peripheral State functions ************************************************/ |
|||
/** @addtogroup PCD_Exported_Functions_Group4 Peripheral State functions
|
|||
* @{ |
|||
*/ |
|||
PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef *hpcd); |
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/* Private constants ---------------------------------------------------------*/ |
|||
/** @defgroup PCD_Private_Constants PCD Private Constants
|
|||
* @{ |
|||
*/ |
|||
/** @defgroup USB_EXTI_Line_Interrupt USB EXTI line interrupt
|
|||
* @{ |
|||
*/ |
|||
|
|||
|
|||
#define USB_WAKEUP_EXTI_LINE (0x1U << 28) /*!< USB FS EXTI Line WakeUp Interrupt */ |
|||
|
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/** @defgroup PCD_EP0_MPS PCD EP0 MPS
|
|||
* @{ |
|||
*/ |
|||
#define PCD_EP0MPS_64 EP_MPS_64 |
|||
#define PCD_EP0MPS_32 EP_MPS_32 |
|||
#define PCD_EP0MPS_16 EP_MPS_16 |
|||
#define PCD_EP0MPS_08 EP_MPS_8 |
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/** @defgroup PCD_ENDP PCD ENDP
|
|||
* @{ |
|||
*/ |
|||
#define PCD_ENDP0 0U |
|||
#define PCD_ENDP1 1U |
|||
#define PCD_ENDP2 2U |
|||
#define PCD_ENDP3 3U |
|||
#define PCD_ENDP4 4U |
|||
#define PCD_ENDP5 5U |
|||
#define PCD_ENDP6 6U |
|||
#define PCD_ENDP7 7U |
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/** @defgroup PCD_ENDP_Kind PCD Endpoint Kind
|
|||
* @{ |
|||
*/ |
|||
#define PCD_SNG_BUF 0U |
|||
#define PCD_DBL_BUF 1U |
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/* Private macros ------------------------------------------------------------*/ |
|||
/** @defgroup PCD_Private_Macros PCD Private Macros
|
|||
* @{ |
|||
*/ |
|||
|
|||
/******************** Bit definition for USB_COUNTn_RX register *************/ |
|||
#define USB_CNTRX_NBLK_MSK (0x1FU << 10) |
|||
#define USB_CNTRX_BLSIZE (0x1U << 15) |
|||
|
|||
/* SetENDPOINT */ |
|||
#define PCD_SET_ENDPOINT(USBx, bEpNum, wRegValue) (*(__IO uint16_t *)(&(USBx)->EP0R + ((bEpNum) * 2U)) = (uint16_t)(wRegValue)) |
|||
|
|||
/* GetENDPOINT */ |
|||
#define PCD_GET_ENDPOINT(USBx, bEpNum) (*(__IO uint16_t *)(&(USBx)->EP0R + ((bEpNum) * 2U))) |
|||
|
|||
/* ENDPOINT transfer */ |
|||
#define USB_EP0StartXfer USB_EPStartXfer |
|||
|
|||
/**
|
|||
* @brief sets the type in the endpoint register(bits EP_TYPE[1:0]) |
|||
* @param USBx USB peripheral instance register address. |
|||
* @param bEpNum Endpoint Number. |
|||
* @param wType Endpoint Type. |
|||
* @retval None |
|||
*/ |
|||
#define PCD_SET_EPTYPE(USBx, bEpNum, wType) (PCD_SET_ENDPOINT((USBx), (bEpNum), ((PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EP_T_MASK) | (wType) | USB_EP_CTR_TX | USB_EP_CTR_RX))) |
|||
|
|||
/**
|
|||
* @brief gets the type in the endpoint register(bits EP_TYPE[1:0]) |
|||
* @param USBx USB peripheral instance register address. |
|||
* @param bEpNum Endpoint Number. |
|||
* @retval Endpoint Type |
|||
*/ |
|||
#define PCD_GET_EPTYPE(USBx, bEpNum) (PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EP_T_FIELD) |
|||
|
|||
/**
|
|||
* @brief free buffer used from the application realizing it to the line |
|||
* toggles bit SW_BUF in the double buffered endpoint register |
|||
* @param USBx USB device. |
|||
* @param bEpNum, bDir |
|||
* @retval None |
|||
*/ |
|||
#define PCD_FreeUserBuffer(USBx, bEpNum, bDir) \ |
|||
do { \ |
|||
if ((bDir) == 0U) \ |
|||
{ \ |
|||
/* OUT double buffered endpoint */ \ |
|||
PCD_TX_DTOG((USBx), (bEpNum)); \ |
|||
} \ |
|||
else if ((bDir) == 1U) \ |
|||
{ \ |
|||
/* IN double buffered endpoint */ \ |
|||
PCD_RX_DTOG((USBx), (bEpNum)); \ |
|||
} \ |
|||
} while(0) |
|||
|
|||
/**
|
|||
* @brief sets the status for tx transfer (bits STAT_TX[1:0]). |
|||
* @param USBx USB peripheral instance register address. |
|||
* @param bEpNum Endpoint Number. |
|||
* @param wState new state |
|||
* @retval None |
|||
*/ |
|||
#define PCD_SET_EP_TX_STATUS(USBx, bEpNum, wState) \ |
|||
do { \ |
|||
uint16_t _wRegVal; \ |
|||
\ |
|||
_wRegVal = PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPTX_DTOGMASK; \ |
|||
/* toggle first bit ? */ \ |
|||
if ((USB_EPTX_DTOG1 & (wState))!= 0U) \ |
|||
{ \ |
|||
_wRegVal ^= USB_EPTX_DTOG1; \ |
|||
} \ |
|||
/* toggle second bit ? */ \ |
|||
if ((USB_EPTX_DTOG2 & (wState))!= 0U) \ |
|||
{ \ |
|||
_wRegVal ^= USB_EPTX_DTOG2; \ |
|||
} \ |
|||
PCD_SET_ENDPOINT((USBx), (bEpNum), (_wRegVal | USB_EP_CTR_RX | USB_EP_CTR_TX)); \ |
|||
} while(0) /* PCD_SET_EP_TX_STATUS */ |
|||
|
|||
/**
|
|||
* @brief sets the status for rx transfer (bits STAT_TX[1:0]) |
|||
* @param USBx USB peripheral instance register address. |
|||
* @param bEpNum Endpoint Number. |
|||
* @param wState new state |
|||
* @retval None |
|||
*/ |
|||
#define PCD_SET_EP_RX_STATUS(USBx, bEpNum,wState) \ |
|||
do { \ |
|||
uint16_t _wRegVal; \ |
|||
\ |
|||
_wRegVal = PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPRX_DTOGMASK; \ |
|||
/* toggle first bit ? */ \ |
|||
if ((USB_EPRX_DTOG1 & (wState))!= 0U) \ |
|||
{ \ |
|||
_wRegVal ^= USB_EPRX_DTOG1; \ |
|||
} \ |
|||
/* toggle second bit ? */ \ |
|||
if ((USB_EPRX_DTOG2 & (wState))!= 0U) \ |
|||
{ \ |
|||
_wRegVal ^= USB_EPRX_DTOG2; \ |
|||
} \ |
|||
PCD_SET_ENDPOINT((USBx), (bEpNum), (_wRegVal | USB_EP_CTR_RX | USB_EP_CTR_TX)); \ |
|||
} while(0) /* PCD_SET_EP_RX_STATUS */ |
|||
|
|||
/**
|
|||
* @brief sets the status for rx & tx (bits STAT_TX[1:0] & STAT_RX[1:0]) |
|||
* @param USBx USB peripheral instance register address. |
|||
* @param bEpNum Endpoint Number. |
|||
* @param wStaterx new state. |
|||
* @param wStatetx new state. |
|||
* @retval None |
|||
*/ |
|||
#define PCD_SET_EP_TXRX_STATUS(USBx, bEpNum, wStaterx, wStatetx) \ |
|||
do { \ |
|||
uint16_t _wRegVal; \ |
|||
\ |
|||
_wRegVal = PCD_GET_ENDPOINT((USBx), (bEpNum)) & (USB_EPRX_DTOGMASK | USB_EPTX_STAT); \ |
|||
/* toggle first bit ? */ \ |
|||
if ((USB_EPRX_DTOG1 & (wStaterx))!= 0U) \ |
|||
{ \ |
|||
_wRegVal ^= USB_EPRX_DTOG1; \ |
|||
} \ |
|||
/* toggle second bit ? */ \ |
|||
if ((USB_EPRX_DTOG2 & (wStaterx))!= 0U) \ |
|||
{ \ |
|||
_wRegVal ^= USB_EPRX_DTOG2; \ |
|||
} \ |
|||
/* toggle first bit ? */ \ |
|||
if ((USB_EPTX_DTOG1 & (wStatetx))!= 0U) \ |
|||
{ \ |
|||
_wRegVal ^= USB_EPTX_DTOG1; \ |
|||
} \ |
|||
/* toggle second bit ? */ \ |
|||
if ((USB_EPTX_DTOG2 & (wStatetx))!= 0U) \ |
|||
{ \ |
|||
_wRegVal ^= USB_EPTX_DTOG2; \ |
|||
} \ |
|||
\ |
|||
PCD_SET_ENDPOINT((USBx), (bEpNum), (_wRegVal | USB_EP_CTR_RX | USB_EP_CTR_TX)); \ |
|||
} while(0) /* PCD_SET_EP_TXRX_STATUS */ |
|||
|
|||
/**
|
|||
* @brief gets the status for tx/rx transfer (bits STAT_TX[1:0] |
|||
* /STAT_RX[1:0]) |
|||
* @param USBx USB peripheral instance register address. |
|||
* @param bEpNum Endpoint Number. |
|||
* @retval status |
|||
*/ |
|||
#define PCD_GET_EP_TX_STATUS(USBx, bEpNum) ((uint16_t)PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPTX_STAT) |
|||
#define PCD_GET_EP_RX_STATUS(USBx, bEpNum) ((uint16_t)PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPRX_STAT) |
|||
|
|||
/**
|
|||
* @brief sets directly the VALID tx/rx-status into the endpoint register |
|||
* @param USBx USB peripheral instance register address. |
|||
* @param bEpNum Endpoint Number. |
|||
* @retval None |
|||
*/ |
|||
#define PCD_SET_EP_TX_VALID(USBx, bEpNum) (PCD_SET_EP_TX_STATUS((USBx), (bEpNum), USB_EP_TX_VALID)) |
|||
#define PCD_SET_EP_RX_VALID(USBx, bEpNum) (PCD_SET_EP_RX_STATUS((USBx), (bEpNum), USB_EP_RX_VALID)) |
|||
|
|||
/**
|
|||
* @brief checks stall condition in an endpoint. |
|||
* @param USBx USB peripheral instance register address. |
|||
* @param bEpNum Endpoint Number. |
|||
* @retval TRUE = endpoint in stall condition. |
|||
*/ |
|||
#define PCD_GET_EP_TX_STALL_STATUS(USBx, bEpNum) (PCD_GET_EP_TX_STATUS((USBx), (bEpNum)) == USB_EP_TX_STALL) |
|||
#define PCD_GET_EP_RX_STALL_STATUS(USBx, bEpNum) (PCD_GET_EP_RX_STATUS((USBx), (bEpNum)) == USB_EP_RX_STALL) |
|||
|
|||
/**
|
|||
* @brief set & clear EP_KIND bit. |
|||
* @param USBx USB peripheral instance register address. |
|||
* @param bEpNum Endpoint Number. |
|||
* @retval None |
|||
*/ |
|||
#define PCD_SET_EP_KIND(USBx, bEpNum) \ |
|||
do { \ |
|||
uint16_t _wRegVal; \ |
|||
\ |
|||
_wRegVal = PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPREG_MASK; \ |
|||
\ |
|||
PCD_SET_ENDPOINT((USBx), (bEpNum), (_wRegVal | USB_EP_CTR_RX | USB_EP_CTR_TX | USB_EP_KIND)); \ |
|||
} while(0) /* PCD_SET_EP_KIND */ |
|||
|
|||
#define PCD_CLEAR_EP_KIND(USBx, bEpNum) \ |
|||
do { \ |
|||
uint16_t _wRegVal; \ |
|||
\ |
|||
_wRegVal = PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPKIND_MASK; \ |
|||
\ |
|||
PCD_SET_ENDPOINT((USBx), (bEpNum), (_wRegVal | USB_EP_CTR_RX | USB_EP_CTR_TX)); \ |
|||
} while(0) /* PCD_CLEAR_EP_KIND */ |
|||
|
|||
/**
|
|||
* @brief Sets/clears directly STATUS_OUT bit in the endpoint register. |
|||
* @param USBx USB peripheral instance register address. |
|||
* @param bEpNum Endpoint Number. |
|||
* @retval None |
|||
*/ |
|||
#define PCD_SET_OUT_STATUS(USBx, bEpNum) PCD_SET_EP_KIND((USBx), (bEpNum)) |
|||
#define PCD_CLEAR_OUT_STATUS(USBx, bEpNum) PCD_CLEAR_EP_KIND((USBx), (bEpNum)) |
|||
|
|||
/**
|
|||
* @brief Sets/clears directly EP_KIND bit in the endpoint register. |
|||
* @param USBx USB peripheral instance register address. |
|||
* @param bEpNum Endpoint Number. |
|||
* @retval None |
|||
*/ |
|||
#define PCD_SET_EP_DBUF(USBx, bEpNum) PCD_SET_EP_KIND((USBx), (bEpNum)) |
|||
#define PCD_CLEAR_EP_DBUF(USBx, bEpNum) PCD_CLEAR_EP_KIND((USBx), (bEpNum)) |
|||
|
|||
/**
|
|||
* @brief Clears bit CTR_RX / CTR_TX in the endpoint register. |
|||
* @param USBx USB peripheral instance register address. |
|||
* @param bEpNum Endpoint Number. |
|||
* @retval None |
|||
*/ |
|||
#define PCD_CLEAR_RX_EP_CTR(USBx, bEpNum) \ |
|||
do { \ |
|||
uint16_t _wRegVal; \ |
|||
\ |
|||
_wRegVal = PCD_GET_ENDPOINT((USBx), (bEpNum)) & (0x7FFFU & USB_EPREG_MASK); \ |
|||
\ |
|||
PCD_SET_ENDPOINT((USBx), (bEpNum), (_wRegVal | USB_EP_CTR_TX)); \ |
|||
} while(0) /* PCD_CLEAR_RX_EP_CTR */ |
|||
|
|||
#define PCD_CLEAR_TX_EP_CTR(USBx, bEpNum) \ |
|||
do { \ |
|||
uint16_t _wRegVal; \ |
|||
\ |
|||
_wRegVal = PCD_GET_ENDPOINT((USBx), (bEpNum)) & (0xFF7FU & USB_EPREG_MASK); \ |
|||
\ |
|||
PCD_SET_ENDPOINT((USBx), (bEpNum), (_wRegVal | USB_EP_CTR_RX)); \ |
|||
} while(0) /* PCD_CLEAR_TX_EP_CTR */ |
|||
|
|||
/**
|
|||
* @brief Toggles DTOG_RX / DTOG_TX bit in the endpoint register. |
|||
* @param USBx USB peripheral instance register address. |
|||
* @param bEpNum Endpoint Number. |
|||
* @retval None |
|||
*/ |
|||
#define PCD_RX_DTOG(USBx, bEpNum) \ |
|||
do { \ |
|||
uint16_t _wEPVal; \ |
|||
\ |
|||
_wEPVal = PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPREG_MASK; \ |
|||
\ |
|||
PCD_SET_ENDPOINT((USBx), (bEpNum), (_wEPVal | USB_EP_CTR_RX | USB_EP_CTR_TX | USB_EP_DTOG_RX)); \ |
|||
} while(0) /* PCD_RX_DTOG */ |
|||
|
|||
#define PCD_TX_DTOG(USBx, bEpNum) \ |
|||
do { \ |
|||
uint16_t _wEPVal; \ |
|||
\ |
|||
_wEPVal = PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPREG_MASK; \ |
|||
\ |
|||
PCD_SET_ENDPOINT((USBx), (bEpNum), (_wEPVal | USB_EP_CTR_RX | USB_EP_CTR_TX | USB_EP_DTOG_TX)); \ |
|||
} while(0) /* PCD_TX_DTOG */ |
|||
/**
|
|||
* @brief Clears DTOG_RX / DTOG_TX bit in the endpoint register. |
|||
* @param USBx USB peripheral instance register address. |
|||
* @param bEpNum Endpoint Number. |
|||
* @retval None |
|||
*/ |
|||
#define PCD_CLEAR_RX_DTOG(USBx, bEpNum) \ |
|||
do { \ |
|||
uint16_t _wRegVal; \ |
|||
\ |
|||
_wRegVal = PCD_GET_ENDPOINT((USBx), (bEpNum)); \ |
|||
\ |
|||
if ((_wRegVal & USB_EP_DTOG_RX) != 0U)\ |
|||
{ \ |
|||
PCD_RX_DTOG((USBx), (bEpNum)); \ |
|||
} \ |
|||
} while(0) /* PCD_CLEAR_RX_DTOG */ |
|||
|
|||
#define PCD_CLEAR_TX_DTOG(USBx, bEpNum) \ |
|||
do { \ |
|||
uint16_t _wRegVal; \ |
|||
\ |
|||
_wRegVal = PCD_GET_ENDPOINT((USBx), (bEpNum)); \ |
|||
\ |
|||
if ((_wRegVal & USB_EP_DTOG_TX) != 0U)\ |
|||
{ \ |
|||
PCD_TX_DTOG((USBx), (bEpNum)); \ |
|||
} \ |
|||
} while(0) /* PCD_CLEAR_TX_DTOG */ |
|||
|
|||
/**
|
|||
* @brief Sets address in an endpoint register. |
|||
* @param USBx USB peripheral instance register address. |
|||
* @param bEpNum Endpoint Number. |
|||
* @param bAddr Address. |
|||
* @retval None |
|||
*/ |
|||
#define PCD_SET_EP_ADDRESS(USBx, bEpNum, bAddr) \ |
|||
do { \ |
|||
uint16_t _wRegVal; \ |
|||
\ |
|||
_wRegVal = (PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPREG_MASK) | (bAddr); \ |
|||
\ |
|||
PCD_SET_ENDPOINT((USBx), (bEpNum), (_wRegVal | USB_EP_CTR_RX | USB_EP_CTR_TX)); \ |
|||
} while(0) /* PCD_SET_EP_ADDRESS */ |
|||
|
|||
/**
|
|||
* @brief Gets address in an endpoint register. |
|||
* @param USBx USB peripheral instance register address. |
|||
* @param bEpNum Endpoint Number. |
|||
* @retval None |
|||
*/ |
|||
#define PCD_GET_EP_ADDRESS(USBx, bEpNum) ((uint8_t)(PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPADDR_FIELD)) |
|||
|
|||
#define PCD_EP_TX_CNT(USBx, bEpNum) ((uint16_t *)((((uint32_t)(USBx)->BTABLE + ((uint32_t)(bEpNum) * 8U) + 2U) * PMA_ACCESS) + ((uint32_t)(USBx) + 0x400U))) |
|||
#define PCD_EP_RX_CNT(USBx, bEpNum) ((uint16_t *)((((uint32_t)(USBx)->BTABLE + ((uint32_t)(bEpNum) * 8U) + 6U) * PMA_ACCESS) + ((uint32_t)(USBx) + 0x400U))) |
|||
|
|||
/**
|
|||
* @brief sets address of the tx/rx buffer. |
|||
* @param USBx USB peripheral instance register address. |
|||
* @param bEpNum Endpoint Number. |
|||
* @param wAddr address to be set (must be word aligned). |
|||
* @retval None |
|||
*/ |
|||
#define PCD_SET_EP_TX_ADDRESS(USBx, bEpNum, wAddr) \ |
|||
do { \ |
|||
__IO uint16_t *_wRegVal; \ |
|||
uint32_t _wRegBase = (uint32_t)USBx; \ |
|||
\ |
|||
_wRegBase += (uint32_t)(USBx)->BTABLE; \ |
|||
_wRegVal = (__IO uint16_t *)(_wRegBase + 0x400U + (((uint32_t)(bEpNum) * 8U) * PMA_ACCESS)); \ |
|||
*_wRegVal = ((wAddr) >> 1) << 1; \ |
|||
} while(0) /* PCD_SET_EP_TX_ADDRESS */ |
|||
|
|||
#define PCD_SET_EP_RX_ADDRESS(USBx, bEpNum, wAddr) \ |
|||
do { \ |
|||
__IO uint16_t *_wRegVal; \ |
|||
uint32_t _wRegBase = (uint32_t)USBx; \ |
|||
\ |
|||
_wRegBase += (uint32_t)(USBx)->BTABLE; \ |
|||
_wRegVal = (__IO uint16_t *)(_wRegBase + 0x400U + ((((uint32_t)(bEpNum) * 8U) + 4U) * PMA_ACCESS)); \ |
|||
*_wRegVal = ((wAddr) >> 1) << 1; \ |
|||
} while(0) /* PCD_SET_EP_RX_ADDRESS */ |
|||
|
|||
/**
|
|||
* @brief Gets address of the tx/rx buffer. |
|||
* @param USBx USB peripheral instance register address. |
|||
* @param bEpNum Endpoint Number. |
|||
* @retval address of the buffer. |
|||
*/ |
|||
#define PCD_GET_EP_TX_ADDRESS(USBx, bEpNum) ((uint16_t)*PCD_EP_TX_ADDRESS((USBx), (bEpNum))) |
|||
#define PCD_GET_EP_RX_ADDRESS(USBx, bEpNum) ((uint16_t)*PCD_EP_RX_ADDRESS((USBx), (bEpNum))) |
|||
|
|||
/**
|
|||
* @brief Sets counter of rx buffer with no. of blocks. |
|||
* @param pdwReg Register pointer |
|||
* @param wCount Counter. |
|||
* @param wNBlocks no. of Blocks. |
|||
* @retval None |
|||
*/ |
|||
#define PCD_CALC_BLK32(pdwReg, wCount, wNBlocks) \ |
|||
do { \ |
|||
(wNBlocks) = (wCount) >> 5; \ |
|||
if (((wCount) & 0x1fU) == 0U) \ |
|||
{ \ |
|||
(wNBlocks)--; \ |
|||
} \ |
|||
*(pdwReg) = (uint16_t)(((wNBlocks) << 10) | USB_CNTRX_BLSIZE); \ |
|||
} while(0) /* PCD_CALC_BLK32 */ |
|||
|
|||
#define PCD_CALC_BLK2(pdwReg, wCount, wNBlocks) \ |
|||
do { \ |
|||
(wNBlocks) = (wCount) >> 1; \ |
|||
if (((wCount) & 0x1U) != 0U) \ |
|||
{ \ |
|||
(wNBlocks)++; \ |
|||
} \ |
|||
*(pdwReg) = (uint16_t)((wNBlocks) << 10); \ |
|||
} while(0) /* PCD_CALC_BLK2 */ |
|||
|
|||
#define PCD_SET_EP_CNT_RX_REG(pdwReg, wCount) \ |
|||
do { \ |
|||
uint32_t wNBlocks; \ |
|||
if ((wCount) == 0U) \ |
|||
{ \ |
|||
*(pdwReg) &= (uint16_t)~USB_CNTRX_NBLK_MSK; \ |
|||
*(pdwReg) |= USB_CNTRX_BLSIZE; \ |
|||
} \ |
|||
else if((wCount) <= 62U) \ |
|||
{ \ |
|||
PCD_CALC_BLK2((pdwReg), (wCount), wNBlocks); \ |
|||
} \ |
|||
else \ |
|||
{ \ |
|||
PCD_CALC_BLK32((pdwReg), (wCount), wNBlocks); \ |
|||
} \ |
|||
} while(0) /* PCD_SET_EP_CNT_RX_REG */ |
|||
|
|||
#define PCD_SET_EP_RX_DBUF0_CNT(USBx, bEpNum, wCount) \ |
|||
do { \ |
|||
uint32_t _wRegBase = (uint32_t)(USBx); \ |
|||
__IO uint16_t *pdwReg; \ |
|||
\ |
|||
_wRegBase += (uint32_t)(USBx)->BTABLE; \ |
|||
pdwReg = (__IO uint16_t *)(_wRegBase + 0x400U + ((((uint32_t)(bEpNum) * 8U) + 2U) * PMA_ACCESS)); \ |
|||
PCD_SET_EP_CNT_RX_REG(pdwReg, (wCount)); \ |
|||
} while(0) |
|||
|
|||
/**
|
|||
* @brief sets counter for the tx/rx buffer. |
|||
* @param USBx USB peripheral instance register address. |
|||
* @param bEpNum Endpoint Number. |
|||
* @param wCount Counter value. |
|||
* @retval None |
|||
*/ |
|||
#define PCD_SET_EP_TX_CNT(USBx, bEpNum, wCount) \ |
|||
do { \ |
|||
uint32_t _wRegBase = (uint32_t)(USBx); \ |
|||
__IO uint16_t *_wRegVal; \ |
|||
\ |
|||
_wRegBase += (uint32_t)(USBx)->BTABLE; \ |
|||
_wRegVal = (__IO uint16_t *)(_wRegBase + 0x400U + ((((uint32_t)(bEpNum) * 8U) + 2U) * PMA_ACCESS)); \ |
|||
*_wRegVal = (uint16_t)(wCount); \ |
|||
} while(0) |
|||
|
|||
#define PCD_SET_EP_RX_CNT(USBx, bEpNum, wCount) \ |
|||
do { \ |
|||
uint32_t _wRegBase = (uint32_t)(USBx); \ |
|||
__IO uint16_t *_wRegVal; \ |
|||
\ |
|||
_wRegBase += (uint32_t)(USBx)->BTABLE; \ |
|||
_wRegVal = (__IO uint16_t *)(_wRegBase + 0x400U + ((((uint32_t)(bEpNum) * 8U) + 6U) * PMA_ACCESS)); \ |
|||
PCD_SET_EP_CNT_RX_REG(_wRegVal, (wCount)); \ |
|||
} while(0) |
|||
|
|||
/**
|
|||
* @brief gets counter of the tx buffer. |
|||
* @param USBx USB peripheral instance register address. |
|||
* @param bEpNum Endpoint Number. |
|||
* @retval Counter value |
|||
*/ |
|||
#define PCD_GET_EP_TX_CNT(USBx, bEpNum) ((uint32_t)(*PCD_EP_TX_CNT((USBx), (bEpNum))) & 0x3ffU) |
|||
#define PCD_GET_EP_RX_CNT(USBx, bEpNum) ((uint32_t)(*PCD_EP_RX_CNT((USBx), (bEpNum))) & 0x3ffU) |
|||
|
|||
/**
|
|||
* @brief Sets buffer 0/1 address in a double buffer endpoint. |
|||
* @param USBx USB peripheral instance register address. |
|||
* @param bEpNum Endpoint Number. |
|||
* @param wBuf0Addr buffer 0 address. |
|||
* @retval Counter value |
|||
*/ |
|||
#define PCD_SET_EP_DBUF0_ADDR(USBx, bEpNum, wBuf0Addr) \ |
|||
do { \ |
|||
PCD_SET_EP_TX_ADDRESS((USBx), (bEpNum), (wBuf0Addr)); \ |
|||
} while(0) /* PCD_SET_EP_DBUF0_ADDR */ |
|||
|
|||
#define PCD_SET_EP_DBUF1_ADDR(USBx, bEpNum, wBuf1Addr) \ |
|||
do { \ |
|||
PCD_SET_EP_RX_ADDRESS((USBx), (bEpNum), (wBuf1Addr)); \ |
|||
} while(0) /* PCD_SET_EP_DBUF1_ADDR */ |
|||
|
|||
/**
|
|||
* @brief Sets addresses in a double buffer endpoint. |
|||
* @param USBx USB peripheral instance register address. |
|||
* @param bEpNum Endpoint Number. |
|||
* @param wBuf0Addr: buffer 0 address. |
|||
* @param wBuf1Addr = buffer 1 address. |
|||
* @retval None |
|||
*/ |
|||
#define PCD_SET_EP_DBUF_ADDR(USBx, bEpNum, wBuf0Addr, wBuf1Addr) \ |
|||
do { \ |
|||
PCD_SET_EP_DBUF0_ADDR((USBx), (bEpNum), (wBuf0Addr)); \ |
|||
PCD_SET_EP_DBUF1_ADDR((USBx), (bEpNum), (wBuf1Addr)); \ |
|||
} while(0) /* PCD_SET_EP_DBUF_ADDR */ |
|||
|
|||
/**
|
|||
* @brief Gets buffer 0/1 address of a double buffer endpoint. |
|||
* @param USBx USB peripheral instance register address. |
|||
* @param bEpNum Endpoint Number. |
|||
* @retval None |
|||
*/ |
|||
#define PCD_GET_EP_DBUF0_ADDR(USBx, bEpNum) (PCD_GET_EP_TX_ADDRESS((USBx), (bEpNum))) |
|||
#define PCD_GET_EP_DBUF1_ADDR(USBx, bEpNum) (PCD_GET_EP_RX_ADDRESS((USBx), (bEpNum))) |
|||
|
|||
/**
|
|||
* @brief Gets buffer 0/1 address of a double buffer endpoint. |
|||
* @param USBx USB peripheral instance register address. |
|||
* @param bEpNum Endpoint Number. |
|||
* @param bDir endpoint dir EP_DBUF_OUT = OUT |
|||
* EP_DBUF_IN = IN |
|||
* @param wCount: Counter value |
|||
* @retval None |
|||
*/ |
|||
#define PCD_SET_EP_DBUF0_CNT(USBx, bEpNum, bDir, wCount) \ |
|||
do { \ |
|||
if ((bDir) == 0U) \ |
|||
/* OUT endpoint */ \ |
|||
{ \ |
|||
PCD_SET_EP_RX_DBUF0_CNT((USBx), (bEpNum), (wCount)); \ |
|||
} \ |
|||
else \ |
|||
{ \ |
|||
if ((bDir) == 1U) \ |
|||
{ \ |
|||
/* IN endpoint */ \ |
|||
PCD_SET_EP_TX_CNT((USBx), (bEpNum), (wCount)); \ |
|||
} \ |
|||
} \ |
|||
} while(0) /* SetEPDblBuf0Count*/ |
|||
|
|||
#define PCD_SET_EP_DBUF1_CNT(USBx, bEpNum, bDir, wCount) \ |
|||
do { \ |
|||
uint32_t _wBase = (uint32_t)(USBx); \ |
|||
__IO uint16_t *_wEPRegVal; \ |
|||
\ |
|||
if ((bDir) == 0U) \ |
|||
{ \ |
|||
/* OUT endpoint */ \ |
|||
PCD_SET_EP_RX_CNT((USBx), (bEpNum), (wCount)); \ |
|||
} \ |
|||
else \ |
|||
{ \ |
|||
if ((bDir) == 1U) \ |
|||
{ \ |
|||
/* IN endpoint */ \ |
|||
_wBase += (uint32_t)(USBx)->BTABLE; \ |
|||
_wEPRegVal = (__IO uint16_t *)(_wBase + 0x400U + ((((uint32_t)(bEpNum) * 8U) + 6U) * PMA_ACCESS)); \ |
|||
*_wEPRegVal = (uint16_t)(wCount); \ |
|||
} \ |
|||
} \ |
|||
} while(0) /* SetEPDblBuf1Count */ |
|||
|
|||
#define PCD_SET_EP_DBUF_CNT(USBx, bEpNum, bDir, wCount) \ |
|||
do { \ |
|||
PCD_SET_EP_DBUF0_CNT((USBx), (bEpNum), (bDir), (wCount)); \ |
|||
PCD_SET_EP_DBUF1_CNT((USBx), (bEpNum), (bDir), (wCount)); \ |
|||
} while(0) /* PCD_SET_EP_DBUF_CNT */ |
|||
|
|||
/**
|
|||
* @brief Gets buffer 0/1 rx/tx counter for double buffering. |
|||
* @param USBx USB peripheral instance register address. |
|||
* @param bEpNum Endpoint Number. |
|||
* @retval None |
|||
*/ |
|||
#define PCD_GET_EP_DBUF0_CNT(USBx, bEpNum) (PCD_GET_EP_TX_CNT((USBx), (bEpNum))) |
|||
#define PCD_GET_EP_DBUF1_CNT(USBx, bEpNum) (PCD_GET_EP_RX_CNT((USBx), (bEpNum))) |
|||
|
|||
|
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
#endif /* defined (USB) */ |
|||
|
|||
#ifdef __cplusplus |
|||
} |
|||
#endif |
|||
|
|||
#endif /* STM32WBxx_HAL_PCD_H */ |
|||
|
|||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
|||
@ -0,0 +1,91 @@ |
|||
/**
|
|||
****************************************************************************** |
|||
* @file stm32wbxx_hal_pcd_ex.h |
|||
* @author MCD Application Team |
|||
* @brief Header file of PCD HAL Extension module. |
|||
****************************************************************************** |
|||
* @attention |
|||
* |
|||
* <h2><center>© Copyright (c) 2019 STMicroelectronics. |
|||
* All rights reserved.</center></h2> |
|||
* |
|||
* This software component is licensed by ST under BSD 3-Clause license, |
|||
* the "License"; You may not use this file except in compliance with the |
|||
* License. You may obtain a copy of the License at: |
|||
* opensource.org/licenses/BSD-3-Clause |
|||
* |
|||
****************************************************************************** |
|||
*/ |
|||
|
|||
/* Define to prevent recursive inclusion -------------------------------------*/ |
|||
#ifndef STM32WBxx_HAL_PCD_EX_H |
|||
#define STM32WBxx_HAL_PCD_EX_H |
|||
|
|||
#ifdef __cplusplus |
|||
extern "C" { |
|||
#endif |
|||
|
|||
/* Includes ------------------------------------------------------------------*/ |
|||
#include "stm32wbxx_hal_def.h" |
|||
|
|||
#if defined (USB) |
|||
/** @addtogroup STM32WBxx_HAL_Driver
|
|||
* @{ |
|||
*/ |
|||
|
|||
/** @addtogroup PCDEx
|
|||
* @{ |
|||
*/ |
|||
/* Exported types ------------------------------------------------------------*/ |
|||
/* Exported constants --------------------------------------------------------*/ |
|||
/* Exported macros -----------------------------------------------------------*/ |
|||
/* Exported functions --------------------------------------------------------*/ |
|||
/** @addtogroup PCDEx_Exported_Functions PCDEx Exported Functions
|
|||
* @{ |
|||
*/ |
|||
/** @addtogroup PCDEx_Exported_Functions_Group1 Peripheral Control functions
|
|||
* @{ |
|||
*/ |
|||
|
|||
|
|||
|
|||
HAL_StatusTypeDef HAL_PCDEx_PMAConfig(PCD_HandleTypeDef *hpcd, uint16_t ep_addr, |
|||
uint16_t ep_kind, uint32_t pmaadress); |
|||
|
|||
|
|||
HAL_StatusTypeDef HAL_PCDEx_ActivateLPM(PCD_HandleTypeDef *hpcd); |
|||
HAL_StatusTypeDef HAL_PCDEx_DeActivateLPM(PCD_HandleTypeDef *hpcd); |
|||
|
|||
|
|||
HAL_StatusTypeDef HAL_PCDEx_ActivateBCD(PCD_HandleTypeDef *hpcd); |
|||
HAL_StatusTypeDef HAL_PCDEx_DeActivateBCD(PCD_HandleTypeDef *hpcd); |
|||
void HAL_PCDEx_BCD_VBUSDetect(PCD_HandleTypeDef *hpcd); |
|||
|
|||
void HAL_PCDEx_LPM_Callback(PCD_HandleTypeDef *hpcd, PCD_LPM_MsgTypeDef msg); |
|||
void HAL_PCDEx_BCD_Callback(PCD_HandleTypeDef *hpcd, PCD_BCD_MsgTypeDef msg); |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
#endif /* defined (USB) */ |
|||
|
|||
#ifdef __cplusplus |
|||
} |
|||
#endif |
|||
|
|||
|
|||
#endif /* STM32WBxx_HAL_PCD_EX_H */ |
|||
|
|||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
|||
@ -0,0 +1,237 @@ |
|||
/**
|
|||
****************************************************************************** |
|||
* @file stm32wbxx_ll_usb.h |
|||
* @author MCD Application Team |
|||
* @brief Header file of USB Low Layer HAL module. |
|||
****************************************************************************** |
|||
* @attention |
|||
* |
|||
* <h2><center>© Copyright (c) 2019 STMicroelectronics. |
|||
* All rights reserved.</center></h2> |
|||
* |
|||
* This software component is licensed by ST under BSD 3-Clause license, |
|||
* the "License"; You may not use this file except in compliance with the |
|||
* License. You may obtain a copy of the License at: |
|||
* opensource.org/licenses/BSD-3-Clause |
|||
* |
|||
****************************************************************************** |
|||
*/ |
|||
|
|||
/* Define to prevent recursive inclusion -------------------------------------*/ |
|||
#ifndef STM32WBxx_LL_USB_H |
|||
#define STM32WBxx_LL_USB_H |
|||
|
|||
#ifdef __cplusplus |
|||
extern "C" { |
|||
#endif |
|||
|
|||
/* Includes ------------------------------------------------------------------*/ |
|||
#include "stm32wbxx_hal_def.h" |
|||
|
|||
#if defined (USB) |
|||
/** @addtogroup STM32WBxx_HAL_Driver
|
|||
* @{ |
|||
*/ |
|||
|
|||
/** @addtogroup USB_LL
|
|||
* @{ |
|||
*/ |
|||
|
|||
/* Exported types ------------------------------------------------------------*/ |
|||
|
|||
/**
|
|||
* @brief USB Mode definition |
|||
*/ |
|||
|
|||
|
|||
|
|||
typedef enum |
|||
{ |
|||
USB_DEVICE_MODE = 0 |
|||
} USB_ModeTypeDef; |
|||
|
|||
/**
|
|||
* @brief USB Initialization Structure definition |
|||
*/ |
|||
typedef struct |
|||
{ |
|||
uint32_t dev_endpoints; /*!< Device Endpoints number.
|
|||
This parameter depends on the used USB core. |
|||
This parameter must be a number between Min_Data = 1 and Max_Data = 15 */ |
|||
|
|||
uint32_t speed; /*!< USB Core speed.
|
|||
This parameter can be any value of @ref USB_Core_Speed */ |
|||
|
|||
uint32_t ep0_mps; /*!< Set the Endpoint 0 Max Packet size. */ |
|||
|
|||
uint32_t phy_itface; /*!< Select the used PHY interface.
|
|||
This parameter can be any value of @ref USB_Core_PHY */ |
|||
|
|||
uint32_t Sof_enable; /*!< Enable or disable the output of the SOF signal. */ |
|||
|
|||
uint32_t low_power_enable; /*!< Enable or disable Low Power mode */ |
|||
|
|||
uint32_t lpm_enable; /*!< Enable or disable Battery charging. */ |
|||
|
|||
uint32_t battery_charging_enable; /*!< Enable or disable Battery charging. */ |
|||
} USB_CfgTypeDef; |
|||
|
|||
typedef struct |
|||
{ |
|||
uint8_t num; /*!< Endpoint number
|
|||
This parameter must be a number between Min_Data = 1 and Max_Data = 15 */ |
|||
|
|||
uint8_t is_in; /*!< Endpoint direction
|
|||
This parameter must be a number between Min_Data = 0 and Max_Data = 1 */ |
|||
|
|||
uint8_t is_stall; /*!< Endpoint stall condition
|
|||
This parameter must be a number between Min_Data = 0 and Max_Data = 1 */ |
|||
|
|||
uint8_t type; /*!< Endpoint type
|
|||
This parameter can be any value of @ref USB_EP_Type */ |
|||
|
|||
uint8_t data_pid_start; /*!< Initial data PID
|
|||
This parameter must be a number between Min_Data = 0 and Max_Data = 1 */ |
|||
|
|||
uint16_t pmaadress; /*!< PMA Address
|
|||
This parameter can be any value between Min_addr = 0 and Max_addr = 1K */ |
|||
|
|||
uint16_t pmaaddr0; /*!< PMA Address0
|
|||
This parameter can be any value between Min_addr = 0 and Max_addr = 1K */ |
|||
|
|||
uint16_t pmaaddr1; /*!< PMA Address1
|
|||
This parameter can be any value between Min_addr = 0 and Max_addr = 1K */ |
|||
|
|||
uint8_t doublebuffer; /*!< Double buffer enable
|
|||
This parameter can be 0 or 1 */ |
|||
|
|||
uint16_t tx_fifo_num; /*!< This parameter is not required by USB Device FS peripheral, it is used
|
|||
only by USB OTG FS peripheral |
|||
This parameter is added to ensure compatibility across USB peripherals */ |
|||
|
|||
uint32_t maxpacket; /*!< Endpoint Max packet size
|
|||
This parameter must be a number between Min_Data = 0 and Max_Data = 64KB */ |
|||
|
|||
uint8_t *xfer_buff; /*!< Pointer to transfer buffer */ |
|||
|
|||
uint32_t xfer_len; /*!< Current transfer length */ |
|||
|
|||
uint32_t xfer_count; /*!< Partial transfer length in case of multi packet transfer */ |
|||
|
|||
uint32_t xfer_len_db; /*!< double buffer transfer length used with bulk double buffer in */ |
|||
|
|||
uint8_t xfer_fill_db; /*!< double buffer Need to Fill new buffer used with bulk_in */ |
|||
|
|||
} USB_EPTypeDef; |
|||
|
|||
|
|||
/* Exported constants --------------------------------------------------------*/ |
|||
|
|||
/** @defgroup PCD_Exported_Constants PCD Exported Constants
|
|||
* @{ |
|||
*/ |
|||
|
|||
|
|||
/** @defgroup USB_LL_EP0_MPS USB Low Layer EP0 MPS
|
|||
* @{ |
|||
*/ |
|||
#define EP_MPS_64 0U |
|||
#define EP_MPS_32 1U |
|||
#define EP_MPS_16 2U |
|||
#define EP_MPS_8 3U |
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/** @defgroup USB_LL_EP_Type USB Low Layer EP Type
|
|||
* @{ |
|||
*/ |
|||
#define EP_TYPE_CTRL 0U |
|||
#define EP_TYPE_ISOC 1U |
|||
#define EP_TYPE_BULK 2U |
|||
#define EP_TYPE_INTR 3U |
|||
#define EP_TYPE_MSK 3U |
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/** @defgroup USB_LL Device Speed
|
|||
* @{ |
|||
*/ |
|||
#define USBD_FS_SPEED 2U |
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
#define BTABLE_ADDRESS 0x000U |
|||
#define PMA_ACCESS 1U |
|||
|
|||
#define EP_ADDR_MSK 0x7U |
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/* Exported macro ------------------------------------------------------------*/ |
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/* Exported functions --------------------------------------------------------*/ |
|||
/** @addtogroup USB_LL_Exported_Functions USB Low Layer Exported Functions
|
|||
* @{ |
|||
*/ |
|||
|
|||
|
|||
HAL_StatusTypeDef USB_CoreInit(USB_TypeDef *USBx, USB_CfgTypeDef cfg); |
|||
HAL_StatusTypeDef USB_DevInit(USB_TypeDef *USBx, USB_CfgTypeDef cfg); |
|||
HAL_StatusTypeDef USB_EnableGlobalInt(USB_TypeDef *USBx); |
|||
HAL_StatusTypeDef USB_DisableGlobalInt(USB_TypeDef *USBx); |
|||
HAL_StatusTypeDef USB_SetCurrentMode(USB_TypeDef *USBx, USB_ModeTypeDef mode); |
|||
|
|||
#if defined (HAL_PCD_MODULE_ENABLED) |
|||
HAL_StatusTypeDef USB_ActivateEndpoint(USB_TypeDef *USBx, USB_EPTypeDef *ep); |
|||
HAL_StatusTypeDef USB_DeactivateEndpoint(USB_TypeDef *USBx, USB_EPTypeDef *ep); |
|||
HAL_StatusTypeDef USB_EPStartXfer(USB_TypeDef *USBx, USB_EPTypeDef *ep); |
|||
HAL_StatusTypeDef USB_EPSetStall(USB_TypeDef *USBx, USB_EPTypeDef *ep); |
|||
HAL_StatusTypeDef USB_EPClearStall(USB_TypeDef *USBx, USB_EPTypeDef *ep); |
|||
#endif |
|||
|
|||
HAL_StatusTypeDef USB_SetDevAddress(USB_TypeDef *USBx, uint8_t address); |
|||
HAL_StatusTypeDef USB_DevConnect(USB_TypeDef *USBx); |
|||
HAL_StatusTypeDef USB_DevDisconnect(USB_TypeDef *USBx); |
|||
HAL_StatusTypeDef USB_StopDevice(USB_TypeDef *USBx); |
|||
uint32_t USB_ReadInterrupts(USB_TypeDef *USBx); |
|||
HAL_StatusTypeDef USB_ActivateRemoteWakeup(USB_TypeDef *USBx); |
|||
HAL_StatusTypeDef USB_DeActivateRemoteWakeup(USB_TypeDef *USBx); |
|||
|
|||
void USB_WritePMA(USB_TypeDef *USBx, uint8_t *pbUsrBuf, |
|||
uint16_t wPMABufAddr, uint16_t wNBytes); |
|||
|
|||
void USB_ReadPMA(USB_TypeDef *USBx, uint8_t *pbUsrBuf, |
|||
uint16_t wPMABufAddr, uint16_t wNBytes); |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
#endif /* defined (USB) */ |
|||
|
|||
#ifdef __cplusplus |
|||
} |
|||
#endif |
|||
|
|||
|
|||
#endif /* STM32WBxx_LL_USB_H */ |
|||
|
|||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
|||
File diff suppressed because it is too large
@ -0,0 +1,336 @@ |
|||
/**
|
|||
****************************************************************************** |
|||
* @file stm32wbxx_hal_pcd_ex.c |
|||
* @author MCD Application Team |
|||
* @brief PCD Extended HAL module driver. |
|||
* This file provides firmware functions to manage the following |
|||
* functionalities of the USB Peripheral Controller: |
|||
* + Extended features functions |
|||
* |
|||
****************************************************************************** |
|||
* @attention |
|||
* |
|||
* <h2><center>© Copyright (c) 2019 STMicroelectronics. |
|||
* All rights reserved.</center></h2> |
|||
* |
|||
* This software component is licensed by ST under BSD 3-Clause license, |
|||
* the "License"; You may not use this file except in compliance with the |
|||
* License. You may obtain a copy of the License at: |
|||
* opensource.org/licenses/BSD-3-Clause |
|||
* |
|||
****************************************************************************** |
|||
*/ |
|||
|
|||
/* Includes ------------------------------------------------------------------*/ |
|||
#include "stm32wbxx_hal.h" |
|||
|
|||
/** @addtogroup STM32WBxx_HAL_Driver
|
|||
* @{ |
|||
*/ |
|||
|
|||
/** @defgroup PCDEx PCDEx
|
|||
* @brief PCD Extended HAL module driver |
|||
* @{ |
|||
*/ |
|||
|
|||
#ifdef HAL_PCD_MODULE_ENABLED |
|||
|
|||
#if defined (USB) |
|||
/* Private types -------------------------------------------------------------*/ |
|||
/* Private variables ---------------------------------------------------------*/ |
|||
/* Private constants ---------------------------------------------------------*/ |
|||
/* Private macros ------------------------------------------------------------*/ |
|||
/* Private functions ---------------------------------------------------------*/ |
|||
/* Exported functions --------------------------------------------------------*/ |
|||
|
|||
/** @defgroup PCDEx_Exported_Functions PCDEx Exported Functions
|
|||
* @{ |
|||
*/ |
|||
|
|||
/** @defgroup PCDEx_Exported_Functions_Group1 Peripheral Control functions
|
|||
* @brief PCDEx control functions |
|||
* |
|||
@verbatim |
|||
=============================================================================== |
|||
##### Extended features functions ##### |
|||
=============================================================================== |
|||
[..] This section provides functions allowing to: |
|||
(+) Update FIFO configuration |
|||
|
|||
@endverbatim |
|||
* @{ |
|||
*/ |
|||
|
|||
/**
|
|||
* @brief Configure PMA for EP |
|||
* @param hpcd Device instance |
|||
* @param ep_addr endpoint address |
|||
* @param ep_kind endpoint Kind |
|||
* USB_SNG_BUF: Single Buffer used |
|||
* USB_DBL_BUF: Double Buffer used |
|||
* @param pmaadress: EP address in The PMA: In case of single buffer endpoint |
|||
* this parameter is 16-bit value providing the address |
|||
* in PMA allocated to endpoint. |
|||
* In case of double buffer endpoint this parameter |
|||
* is a 32-bit value providing the endpoint buffer 0 address |
|||
* in the LSB part of 32-bit value and endpoint buffer 1 address |
|||
* in the MSB part of 32-bit value. |
|||
* @retval HAL status |
|||
*/ |
|||
|
|||
HAL_StatusTypeDef HAL_PCDEx_PMAConfig(PCD_HandleTypeDef *hpcd, uint16_t ep_addr, |
|||
uint16_t ep_kind, uint32_t pmaadress) |
|||
{ |
|||
PCD_EPTypeDef *ep; |
|||
|
|||
/* initialize ep structure*/ |
|||
if ((0x80U & ep_addr) == 0x80U) |
|||
{ |
|||
ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; |
|||
} |
|||
else |
|||
{ |
|||
ep = &hpcd->OUT_ep[ep_addr]; |
|||
} |
|||
|
|||
/* Here we check if the endpoint is single or double Buffer*/ |
|||
if (ep_kind == PCD_SNG_BUF) |
|||
{ |
|||
/* Single Buffer */ |
|||
ep->doublebuffer = 0U; |
|||
/* Configure the PMA */ |
|||
ep->pmaadress = (uint16_t)pmaadress; |
|||
} |
|||
else /* USB_DBL_BUF */ |
|||
{ |
|||
/* Double Buffer Endpoint */ |
|||
ep->doublebuffer = 1U; |
|||
/* Configure the PMA */ |
|||
ep->pmaaddr0 = (uint16_t)(pmaadress & 0xFFFFU); |
|||
ep->pmaaddr1 = (uint16_t)((pmaadress & 0xFFFF0000U) >> 16); |
|||
} |
|||
|
|||
return HAL_OK; |
|||
} |
|||
|
|||
/**
|
|||
* @brief Activate BatteryCharging feature. |
|||
* @param hpcd PCD handle |
|||
* @retval HAL status |
|||
*/ |
|||
HAL_StatusTypeDef HAL_PCDEx_ActivateBCD(PCD_HandleTypeDef *hpcd) |
|||
{ |
|||
USB_TypeDef *USBx = hpcd->Instance; |
|||
hpcd->battery_charging_active = 1U; |
|||
|
|||
/* Enable BCD feature */ |
|||
USBx->BCDR |= USB_BCDR_BCDEN; |
|||
|
|||
/* Enable DCD : Data Contact Detect */ |
|||
USBx->BCDR &= ~(USB_BCDR_PDEN); |
|||
USBx->BCDR &= ~(USB_BCDR_SDEN); |
|||
USBx->BCDR |= USB_BCDR_DCDEN; |
|||
|
|||
return HAL_OK; |
|||
} |
|||
|
|||
/**
|
|||
* @brief Deactivate BatteryCharging feature. |
|||
* @param hpcd PCD handle |
|||
* @retval HAL status |
|||
*/ |
|||
HAL_StatusTypeDef HAL_PCDEx_DeActivateBCD(PCD_HandleTypeDef *hpcd) |
|||
{ |
|||
USB_TypeDef *USBx = hpcd->Instance; |
|||
hpcd->battery_charging_active = 0U; |
|||
|
|||
/* Disable BCD feature */ |
|||
USBx->BCDR &= ~(USB_BCDR_BCDEN); |
|||
|
|||
return HAL_OK; |
|||
} |
|||
|
|||
/**
|
|||
* @brief Handle BatteryCharging Process. |
|||
* @param hpcd PCD handle |
|||
* @retval HAL status |
|||
*/ |
|||
void HAL_PCDEx_BCD_VBUSDetect(PCD_HandleTypeDef *hpcd) |
|||
{ |
|||
USB_TypeDef *USBx = hpcd->Instance; |
|||
uint32_t tickstart = HAL_GetTick(); |
|||
|
|||
/* Wait Detect flag or a timeout is happen*/ |
|||
while ((USBx->BCDR & USB_BCDR_DCDET) == 0U) |
|||
{ |
|||
/* Check for the Timeout */ |
|||
if ((HAL_GetTick() - tickstart) > 1000U) |
|||
{ |
|||
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) |
|||
hpcd->BCDCallback(hpcd, PCD_BCD_ERROR); |
|||
#else |
|||
HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_ERROR); |
|||
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ |
|||
|
|||
return; |
|||
} |
|||
} |
|||
|
|||
HAL_Delay(200U); |
|||
|
|||
/* Data Pin Contact ? Check Detect flag */ |
|||
if ((USBx->BCDR & USB_BCDR_DCDET) == USB_BCDR_DCDET) |
|||
{ |
|||
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) |
|||
hpcd->BCDCallback(hpcd, PCD_BCD_CONTACT_DETECTION); |
|||
#else |
|||
HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_CONTACT_DETECTION); |
|||
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ |
|||
} |
|||
/* Primary detection: checks if connected to Standard Downstream Port
|
|||
(without charging capability) */ |
|||
USBx->BCDR &= ~(USB_BCDR_DCDEN); |
|||
HAL_Delay(50U); |
|||
USBx->BCDR |= (USB_BCDR_PDEN); |
|||
HAL_Delay(50U); |
|||
|
|||
/* If Charger detect ? */ |
|||
if ((USBx->BCDR & USB_BCDR_PDET) == USB_BCDR_PDET) |
|||
{ |
|||
/* Start secondary detection to check connection to Charging Downstream
|
|||
Port or Dedicated Charging Port */ |
|||
USBx->BCDR &= ~(USB_BCDR_PDEN); |
|||
HAL_Delay(50U); |
|||
USBx->BCDR |= (USB_BCDR_SDEN); |
|||
HAL_Delay(50U); |
|||
|
|||
/* If CDP ? */ |
|||
if ((USBx->BCDR & USB_BCDR_SDET) == USB_BCDR_SDET) |
|||
{ |
|||
/* Dedicated Downstream Port DCP */ |
|||
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) |
|||
hpcd->BCDCallback(hpcd, PCD_BCD_DEDICATED_CHARGING_PORT); |
|||
#else |
|||
HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_DEDICATED_CHARGING_PORT); |
|||
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ |
|||
} |
|||
else |
|||
{ |
|||
/* Charging Downstream Port CDP */ |
|||
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) |
|||
hpcd->BCDCallback(hpcd, PCD_BCD_CHARGING_DOWNSTREAM_PORT); |
|||
#else |
|||
HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_CHARGING_DOWNSTREAM_PORT); |
|||
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ |
|||
} |
|||
} |
|||
else /* NO */ |
|||
{ |
|||
/* Standard Downstream Port */ |
|||
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) |
|||
hpcd->BCDCallback(hpcd, PCD_BCD_STD_DOWNSTREAM_PORT); |
|||
#else |
|||
HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_STD_DOWNSTREAM_PORT); |
|||
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ |
|||
} |
|||
|
|||
/* Battery Charging capability discovery finished Start Enumeration */ |
|||
(void)HAL_PCDEx_DeActivateBCD(hpcd); |
|||
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) |
|||
hpcd->BCDCallback(hpcd, PCD_BCD_DISCOVERY_COMPLETED); |
|||
#else |
|||
HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_DISCOVERY_COMPLETED); |
|||
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ |
|||
} |
|||
|
|||
|
|||
/**
|
|||
* @brief Activate LPM feature. |
|||
* @param hpcd PCD handle |
|||
* @retval HAL status |
|||
*/ |
|||
HAL_StatusTypeDef HAL_PCDEx_ActivateLPM(PCD_HandleTypeDef *hpcd) |
|||
{ |
|||
|
|||
USB_TypeDef *USBx = hpcd->Instance; |
|||
hpcd->lpm_active = 1U; |
|||
hpcd->LPM_State = LPM_L0; |
|||
|
|||
USBx->LPMCSR |= USB_LPMCSR_LMPEN; |
|||
USBx->LPMCSR |= USB_LPMCSR_LPMACK; |
|||
|
|||
return HAL_OK; |
|||
} |
|||
|
|||
/**
|
|||
* @brief Deactivate LPM feature. |
|||
* @param hpcd PCD handle |
|||
* @retval HAL status |
|||
*/ |
|||
HAL_StatusTypeDef HAL_PCDEx_DeActivateLPM(PCD_HandleTypeDef *hpcd) |
|||
{ |
|||
USB_TypeDef *USBx = hpcd->Instance; |
|||
|
|||
hpcd->lpm_active = 0U; |
|||
|
|||
USBx->LPMCSR &= ~(USB_LPMCSR_LMPEN); |
|||
USBx->LPMCSR &= ~(USB_LPMCSR_LPMACK); |
|||
|
|||
return HAL_OK; |
|||
} |
|||
|
|||
|
|||
|
|||
/**
|
|||
* @brief Send LPM message to user layer callback. |
|||
* @param hpcd PCD handle |
|||
* @param msg LPM message |
|||
* @retval HAL status |
|||
*/ |
|||
__weak void HAL_PCDEx_LPM_Callback(PCD_HandleTypeDef *hpcd, PCD_LPM_MsgTypeDef msg) |
|||
{ |
|||
/* Prevent unused argument(s) compilation warning */ |
|||
UNUSED(hpcd); |
|||
UNUSED(msg); |
|||
|
|||
/* NOTE : This function should not be modified, when the callback is needed,
|
|||
the HAL_PCDEx_LPM_Callback could be implemented in the user file |
|||
*/ |
|||
} |
|||
|
|||
/**
|
|||
* @brief Send BatteryCharging message to user layer callback. |
|||
* @param hpcd PCD handle |
|||
* @param msg LPM message |
|||
* @retval HAL status |
|||
*/ |
|||
__weak void HAL_PCDEx_BCD_Callback(PCD_HandleTypeDef *hpcd, PCD_BCD_MsgTypeDef msg) |
|||
{ |
|||
/* Prevent unused argument(s) compilation warning */ |
|||
UNUSED(hpcd); |
|||
UNUSED(msg); |
|||
|
|||
/* NOTE : This function should not be modified, when the callback is needed,
|
|||
the HAL_PCDEx_BCD_Callback could be implemented in the user file |
|||
*/ |
|||
} |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
#endif /* defined (USB) */ |
|||
#endif /* HAL_PCD_MODULE_ENABLED */ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
|||
@ -0,0 +1,849 @@ |
|||
/**
|
|||
****************************************************************************** |
|||
* @file stm32wbxx_ll_usb.c |
|||
* @author MCD Application Team |
|||
* @brief USB Low Layer HAL module driver. |
|||
* |
|||
* This file provides firmware functions to manage the following |
|||
* functionalities of the USB Peripheral Controller: |
|||
* + Initialization/de-initialization functions |
|||
* + I/O operation functions |
|||
* + Peripheral Control functions |
|||
* + Peripheral State functions |
|||
* |
|||
@verbatim |
|||
============================================================================== |
|||
##### How to use this driver ##### |
|||
============================================================================== |
|||
[..] |
|||
(#) Fill parameters of Init structure in USB_OTG_CfgTypeDef structure. |
|||
|
|||
(#) Call USB_CoreInit() API to initialize the USB Core peripheral. |
|||
|
|||
(#) The upper HAL HCD/PCD driver will call the right routines for its internal processes. |
|||
|
|||
@endverbatim |
|||
****************************************************************************** |
|||
* @attention |
|||
* |
|||
* <h2><center>© Copyright (c) 2019 STMicroelectronics. |
|||
* All rights reserved.</center></h2> |
|||
* |
|||
* This software component is licensed by ST under BSD 3-Clause license, |
|||
* the "License"; You may not use this file except in compliance with the |
|||
* License. You may obtain a copy of the License at: |
|||
* opensource.org/licenses/BSD-3-Clause |
|||
* |
|||
****************************************************************************** |
|||
*/ |
|||
|
|||
/* Includes ------------------------------------------------------------------*/ |
|||
#include "stm32wbxx_hal.h" |
|||
|
|||
/** @addtogroup STM32WBxx_LL_USB_DRIVER
|
|||
* @{ |
|||
*/ |
|||
|
|||
#if defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED) |
|||
#if defined (USB) |
|||
/* Private typedef -----------------------------------------------------------*/ |
|||
/* Private define ------------------------------------------------------------*/ |
|||
/* Private macro -------------------------------------------------------------*/ |
|||
/* Private variables ---------------------------------------------------------*/ |
|||
/* Private function prototypes -----------------------------------------------*/ |
|||
/* Private functions ---------------------------------------------------------*/ |
|||
|
|||
|
|||
/**
|
|||
* @brief Initializes the USB Core |
|||
* @param USBx USB Instance |
|||
* @param cfg pointer to a USB_CfgTypeDef structure that contains |
|||
* the configuration information for the specified USBx peripheral. |
|||
* @retval HAL status |
|||
*/ |
|||
HAL_StatusTypeDef USB_CoreInit(USB_TypeDef *USBx, USB_CfgTypeDef cfg) |
|||
{ |
|||
/* Prevent unused argument(s) compilation warning */ |
|||
UNUSED(USBx); |
|||
UNUSED(cfg); |
|||
|
|||
/* NOTE : - This function is not required by USB Device FS peripheral, it is used
|
|||
only by USB OTG FS peripheral. |
|||
- This function is added to ensure compatibility across platforms. |
|||
*/ |
|||
|
|||
return HAL_OK; |
|||
} |
|||
|
|||
/**
|
|||
* @brief USB_EnableGlobalInt |
|||
* Enables the controller's Global Int in the AHB Config reg |
|||
* @param USBx Selected device |
|||
* @retval HAL status |
|||
*/ |
|||
HAL_StatusTypeDef USB_EnableGlobalInt(USB_TypeDef *USBx) |
|||
{ |
|||
uint32_t winterruptmask; |
|||
|
|||
/* Clear pending interrupts */ |
|||
USBx->ISTR = 0U; |
|||
|
|||
/* Set winterruptmask variable */ |
|||
winterruptmask = USB_CNTR_CTRM | USB_CNTR_WKUPM | |
|||
USB_CNTR_SUSPM | USB_CNTR_ERRM | |
|||
USB_CNTR_SOFM | USB_CNTR_ESOFM | |
|||
USB_CNTR_RESETM | USB_CNTR_L1REQM; |
|||
|
|||
/* Set interrupt mask */ |
|||
USBx->CNTR = (uint16_t)winterruptmask; |
|||
|
|||
return HAL_OK; |
|||
} |
|||
|
|||
/**
|
|||
* @brief USB_DisableGlobalInt |
|||
* Disable the controller's Global Int in the AHB Config reg |
|||
* @param USBx Selected device |
|||
* @retval HAL status |
|||
*/ |
|||
HAL_StatusTypeDef USB_DisableGlobalInt(USB_TypeDef *USBx) |
|||
{ |
|||
uint32_t winterruptmask; |
|||
|
|||
/* Set winterruptmask variable */ |
|||
winterruptmask = USB_CNTR_CTRM | USB_CNTR_WKUPM | |
|||
USB_CNTR_SUSPM | USB_CNTR_ERRM | |
|||
USB_CNTR_SOFM | USB_CNTR_ESOFM | |
|||
USB_CNTR_RESETM | USB_CNTR_L1REQM; |
|||
|
|||
/* Clear interrupt mask */ |
|||
USBx->CNTR &= (uint16_t)(~winterruptmask); |
|||
|
|||
return HAL_OK; |
|||
} |
|||
|
|||
/**
|
|||
* @brief USB_SetCurrentMode Set functional mode |
|||
* @param USBx Selected device |
|||
* @param mode current core mode |
|||
* This parameter can be one of the these values: |
|||
* @arg USB_DEVICE_MODE Peripheral mode |
|||
* @retval HAL status |
|||
*/ |
|||
HAL_StatusTypeDef USB_SetCurrentMode(USB_TypeDef *USBx, USB_ModeTypeDef mode) |
|||
{ |
|||
/* Prevent unused argument(s) compilation warning */ |
|||
UNUSED(USBx); |
|||
UNUSED(mode); |
|||
|
|||
/* NOTE : - This function is not required by USB Device FS peripheral, it is used
|
|||
only by USB OTG FS peripheral. |
|||
- This function is added to ensure compatibility across platforms. |
|||
*/ |
|||
return HAL_OK; |
|||
} |
|||
|
|||
/**
|
|||
* @brief USB_DevInit Initializes the USB controller registers |
|||
* for device mode |
|||
* @param USBx Selected device |
|||
* @param cfg pointer to a USB_CfgTypeDef structure that contains |
|||
* the configuration information for the specified USBx peripheral. |
|||
* @retval HAL status |
|||
*/ |
|||
HAL_StatusTypeDef USB_DevInit(USB_TypeDef *USBx, USB_CfgTypeDef cfg) |
|||
{ |
|||
/* Prevent unused argument(s) compilation warning */ |
|||
UNUSED(cfg); |
|||
|
|||
/* Init Device */ |
|||
/* CNTR_FRES = 1 */ |
|||
USBx->CNTR = (uint16_t)USB_CNTR_FRES; |
|||
|
|||
/* CNTR_FRES = 0 */ |
|||
USBx->CNTR = 0U; |
|||
|
|||
/* Clear pending interrupts */ |
|||
USBx->ISTR = 0U; |
|||
|
|||
/*Set Btable Address*/ |
|||
USBx->BTABLE = BTABLE_ADDRESS; |
|||
|
|||
return HAL_OK; |
|||
} |
|||
|
|||
#if defined (HAL_PCD_MODULE_ENABLED) |
|||
/**
|
|||
* @brief Activate and configure an endpoint |
|||
* @param USBx Selected device |
|||
* @param ep pointer to endpoint structure |
|||
* @retval HAL status |
|||
*/ |
|||
HAL_StatusTypeDef USB_ActivateEndpoint(USB_TypeDef *USBx, USB_EPTypeDef *ep) |
|||
{ |
|||
HAL_StatusTypeDef ret = HAL_OK; |
|||
uint16_t wEpRegVal; |
|||
|
|||
wEpRegVal = PCD_GET_ENDPOINT(USBx, ep->num) & USB_EP_T_MASK; |
|||
|
|||
/* initialize Endpoint */ |
|||
switch (ep->type) |
|||
{ |
|||
case EP_TYPE_CTRL: |
|||
wEpRegVal |= USB_EP_CONTROL; |
|||
break; |
|||
|
|||
case EP_TYPE_BULK: |
|||
wEpRegVal |= USB_EP_BULK; |
|||
break; |
|||
|
|||
case EP_TYPE_INTR: |
|||
wEpRegVal |= USB_EP_INTERRUPT; |
|||
break; |
|||
|
|||
case EP_TYPE_ISOC: |
|||
wEpRegVal |= USB_EP_ISOCHRONOUS; |
|||
break; |
|||
|
|||
default: |
|||
ret = HAL_ERROR; |
|||
break; |
|||
} |
|||
|
|||
PCD_SET_ENDPOINT(USBx, ep->num, (wEpRegVal | USB_EP_CTR_RX | USB_EP_CTR_TX)); |
|||
|
|||
PCD_SET_EP_ADDRESS(USBx, ep->num, ep->num); |
|||
|
|||
if (ep->doublebuffer == 0U) |
|||
{ |
|||
if (ep->is_in != 0U) |
|||
{ |
|||
/*Set the endpoint Transmit buffer address */ |
|||
PCD_SET_EP_TX_ADDRESS(USBx, ep->num, ep->pmaadress); |
|||
PCD_CLEAR_TX_DTOG(USBx, ep->num); |
|||
|
|||
if (ep->type != EP_TYPE_ISOC) |
|||
{ |
|||
/* Configure NAK status for the Endpoint */ |
|||
PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK); |
|||
} |
|||
else |
|||
{ |
|||
/* Configure TX Endpoint to disabled state */ |
|||
PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
/*Set the endpoint Receive buffer address */ |
|||
PCD_SET_EP_RX_ADDRESS(USBx, ep->num, ep->pmaadress); |
|||
|
|||
/*Set the endpoint Receive buffer counter*/ |
|||
PCD_SET_EP_RX_CNT(USBx, ep->num, ep->maxpacket); |
|||
PCD_CLEAR_RX_DTOG(USBx, ep->num); |
|||
|
|||
/* Configure VALID status for the Endpoint*/ |
|||
PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID); |
|||
} |
|||
} |
|||
/*Double Buffer*/ |
|||
else |
|||
{ |
|||
/* Set the endpoint as double buffered */ |
|||
PCD_SET_EP_DBUF(USBx, ep->num); |
|||
|
|||
/* Set buffer address for double buffered mode */ |
|||
PCD_SET_EP_DBUF_ADDR(USBx, ep->num, ep->pmaaddr0, ep->pmaaddr1); |
|||
|
|||
if (ep->is_in == 0U) |
|||
{ |
|||
/* Clear the data toggle bits for the endpoint IN/OUT */ |
|||
PCD_CLEAR_RX_DTOG(USBx, ep->num); |
|||
PCD_CLEAR_TX_DTOG(USBx, ep->num); |
|||
|
|||
PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID); |
|||
PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS); |
|||
} |
|||
else |
|||
{ |
|||
/* Clear the data toggle bits for the endpoint IN/OUT */ |
|||
PCD_CLEAR_RX_DTOG(USBx, ep->num); |
|||
PCD_CLEAR_TX_DTOG(USBx, ep->num); |
|||
|
|||
if (ep->type != EP_TYPE_ISOC) |
|||
{ |
|||
/* Configure NAK status for the Endpoint */ |
|||
PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK); |
|||
} |
|||
else |
|||
{ |
|||
/* Configure TX Endpoint to disabled state */ |
|||
PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS); |
|||
} |
|||
|
|||
PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS); |
|||
} |
|||
} |
|||
|
|||
return ret; |
|||
} |
|||
|
|||
/**
|
|||
* @brief De-activate and de-initialize an endpoint |
|||
* @param USBx Selected device |
|||
* @param ep pointer to endpoint structure |
|||
* @retval HAL status |
|||
*/ |
|||
HAL_StatusTypeDef USB_DeactivateEndpoint(USB_TypeDef *USBx, USB_EPTypeDef *ep) |
|||
{ |
|||
if (ep->doublebuffer == 0U) |
|||
{ |
|||
if (ep->is_in != 0U) |
|||
{ |
|||
PCD_CLEAR_TX_DTOG(USBx, ep->num); |
|||
|
|||
/* Configure DISABLE status for the Endpoint*/ |
|||
PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS); |
|||
} |
|||
else |
|||
{ |
|||
PCD_CLEAR_RX_DTOG(USBx, ep->num); |
|||
|
|||
/* Configure DISABLE status for the Endpoint*/ |
|||
PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS); |
|||
} |
|||
} |
|||
/*Double Buffer*/ |
|||
else |
|||
{ |
|||
if (ep->is_in == 0U) |
|||
{ |
|||
/* Clear the data toggle bits for the endpoint IN/OUT*/ |
|||
PCD_CLEAR_RX_DTOG(USBx, ep->num); |
|||
PCD_CLEAR_TX_DTOG(USBx, ep->num); |
|||
|
|||
/* Reset value of the data toggle bits for the endpoint out*/ |
|||
PCD_TX_DTOG(USBx, ep->num); |
|||
|
|||
PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS); |
|||
PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS); |
|||
} |
|||
else |
|||
{ |
|||
/* Clear the data toggle bits for the endpoint IN/OUT*/ |
|||
PCD_CLEAR_RX_DTOG(USBx, ep->num); |
|||
PCD_CLEAR_TX_DTOG(USBx, ep->num); |
|||
PCD_RX_DTOG(USBx, ep->num); |
|||
|
|||
/* Configure DISABLE status for the Endpoint*/ |
|||
PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS); |
|||
PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS); |
|||
} |
|||
} |
|||
|
|||
return HAL_OK; |
|||
} |
|||
|
|||
/**
|
|||
* @brief USB_EPStartXfer setup and starts a transfer over an EP |
|||
* @param USBx Selected device |
|||
* @param ep pointer to endpoint structure |
|||
* @retval HAL status |
|||
*/ |
|||
HAL_StatusTypeDef USB_EPStartXfer(USB_TypeDef *USBx, USB_EPTypeDef *ep) |
|||
{ |
|||
uint32_t len; |
|||
uint16_t pmabuffer; |
|||
uint16_t wEPVal; |
|||
|
|||
/* IN endpoint */ |
|||
if (ep->is_in == 1U) |
|||
{ |
|||
/*Multi packet transfer*/ |
|||
if (ep->xfer_len > ep->maxpacket) |
|||
{ |
|||
len = ep->maxpacket; |
|||
} |
|||
else |
|||
{ |
|||
len = ep->xfer_len; |
|||
} |
|||
|
|||
/* configure and validate Tx endpoint */ |
|||
if (ep->doublebuffer == 0U) |
|||
{ |
|||
USB_WritePMA(USBx, ep->xfer_buff, ep->pmaadress, (uint16_t)len); |
|||
PCD_SET_EP_TX_CNT(USBx, ep->num, len); |
|||
} |
|||
else |
|||
{ |
|||
/* double buffer bulk management */ |
|||
if (ep->type == EP_TYPE_BULK) |
|||
{ |
|||
if (ep->xfer_len_db > ep->maxpacket) |
|||
{ |
|||
/* enable double buffer */ |
|||
PCD_SET_EP_DBUF(USBx, ep->num); |
|||
|
|||
/* each Time to write in PMA xfer_len_db will */ |
|||
ep->xfer_len_db -= len; |
|||
|
|||
/* Fill the two first buffer in the Buffer0 & Buffer1 */ |
|||
if ((PCD_GET_ENDPOINT(USBx, ep->num) & USB_EP_DTOG_TX) != 0U) |
|||
{ |
|||
/* Set the Double buffer counter for pmabuffer1 */ |
|||
PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len); |
|||
pmabuffer = ep->pmaaddr1; |
|||
|
|||
/* Write the user buffer to USB PMA */ |
|||
USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len); |
|||
ep->xfer_buff += len; |
|||
|
|||
if (ep->xfer_len_db > ep->maxpacket) |
|||
{ |
|||
ep->xfer_len_db -= len; |
|||
} |
|||
else |
|||
{ |
|||
len = ep->xfer_len_db; |
|||
ep->xfer_len_db = 0U; |
|||
} |
|||
|
|||
/* Set the Double buffer counter for pmabuffer0 */ |
|||
PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len); |
|||
pmabuffer = ep->pmaaddr0; |
|||
|
|||
/* Write the user buffer to USB PMA */ |
|||
USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len); |
|||
} |
|||
else |
|||
{ |
|||
/* Set the Double buffer counter for pmabuffer0 */ |
|||
PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len); |
|||
pmabuffer = ep->pmaaddr0; |
|||
|
|||
/* Write the user buffer to USB PMA */ |
|||
USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len); |
|||
ep->xfer_buff += len; |
|||
|
|||
if (ep->xfer_len_db > ep->maxpacket) |
|||
{ |
|||
ep->xfer_len_db -= len; |
|||
} |
|||
else |
|||
{ |
|||
len = ep->xfer_len_db; |
|||
ep->xfer_len_db = 0U; |
|||
} |
|||
|
|||
/* Set the Double buffer counter for pmabuffer1 */ |
|||
PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len); |
|||
pmabuffer = ep->pmaaddr1; |
|||
|
|||
/* Write the user buffer to USB PMA */ |
|||
USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len); |
|||
} |
|||
} |
|||
/* auto Switch to single buffer mode when transfer <Mps no need to manage in double buffer */ |
|||
else |
|||
{ |
|||
len = ep->xfer_len_db; |
|||
|
|||
/* disable double buffer mode */ |
|||
PCD_CLEAR_EP_DBUF(USBx, ep->num); |
|||
|
|||
/* Set Tx count with nbre of byte to be transmitted */ |
|||
PCD_SET_EP_TX_CNT(USBx, ep->num, len); |
|||
pmabuffer = ep->pmaaddr0; |
|||
|
|||
/* Write the user buffer to USB PMA */ |
|||
USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len); |
|||
} |
|||
}/* end if bulk double buffer */ |
|||
|
|||
/* manage isochronous double buffer IN mode */ |
|||
else |
|||
{ |
|||
/* enable double buffer */ |
|||
PCD_SET_EP_DBUF(USBx, ep->num); |
|||
|
|||
/* each Time to write in PMA xfer_len_db will */ |
|||
ep->xfer_len_db -= len; |
|||
|
|||
/* Fill the data buffer */ |
|||
if ((PCD_GET_ENDPOINT(USBx, ep->num) & USB_EP_DTOG_TX) != 0U) |
|||
{ |
|||
/* Set the Double buffer counter for pmabuffer1 */ |
|||
PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len); |
|||
pmabuffer = ep->pmaaddr1; |
|||
|
|||
/* Write the user buffer to USB PMA */ |
|||
USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len); |
|||
ep->xfer_buff += len; |
|||
|
|||
if (ep->xfer_len_db > ep->maxpacket) |
|||
{ |
|||
ep->xfer_len_db -= len; |
|||
} |
|||
else |
|||
{ |
|||
len = ep->xfer_len_db; |
|||
ep->xfer_len_db = 0U; |
|||
} |
|||
|
|||
if (len > 0U) |
|||
{ |
|||
/* Set the Double buffer counter for pmabuffer0 */ |
|||
PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len); |
|||
pmabuffer = ep->pmaaddr0; |
|||
|
|||
/* Write the user buffer to USB PMA */ |
|||
USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
/* Set the Double buffer counter for pmabuffer0 */ |
|||
PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len); |
|||
pmabuffer = ep->pmaaddr0; |
|||
|
|||
/* Write the user buffer to USB PMA */ |
|||
USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len); |
|||
ep->xfer_buff += len; |
|||
|
|||
if (ep->xfer_len_db > ep->maxpacket) |
|||
{ |
|||
ep->xfer_len_db -= len; |
|||
} |
|||
else |
|||
{ |
|||
len = ep->xfer_len_db; |
|||
ep->xfer_len_db = 0U; |
|||
} |
|||
|
|||
if (len > 0U) |
|||
{ |
|||
/* Set the Double buffer counter for pmabuffer1 */ |
|||
PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len); |
|||
pmabuffer = ep->pmaaddr1; |
|||
|
|||
/* Write the user buffer to USB PMA */ |
|||
USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_VALID); |
|||
} |
|||
else /* OUT endpoint */ |
|||
{ |
|||
if (ep->doublebuffer == 0U) |
|||
{ |
|||
/* Multi packet transfer */ |
|||
if (ep->xfer_len > ep->maxpacket) |
|||
{ |
|||
len = ep->maxpacket; |
|||
ep->xfer_len -= len; |
|||
} |
|||
else |
|||
{ |
|||
len = ep->xfer_len; |
|||
ep->xfer_len = 0U; |
|||
} |
|||
/* configure and validate Rx endpoint */ |
|||
PCD_SET_EP_RX_CNT(USBx, ep->num, len); |
|||
} |
|||
else |
|||
{ |
|||
/* First Transfer Coming From HAL_PCD_EP_Receive & From ISR */ |
|||
/* Set the Double buffer counter */ |
|||
if (ep->type == EP_TYPE_BULK) |
|||
{ |
|||
PCD_SET_EP_DBUF_CNT(USBx, ep->num, ep->is_in, ep->maxpacket); |
|||
|
|||
/* Coming from ISR */ |
|||
if (ep->xfer_count != 0U) |
|||
{ |
|||
/* update last value to check if there is blocking state */ |
|||
wEPVal = PCD_GET_ENDPOINT(USBx, ep->num); |
|||
|
|||
/*Blocking State */ |
|||
if ((((wEPVal & USB_EP_DTOG_RX) != 0U) && ((wEPVal & USB_EP_DTOG_TX) != 0U)) || |
|||
(((wEPVal & USB_EP_DTOG_RX) == 0U) && ((wEPVal & USB_EP_DTOG_TX) == 0U))) |
|||
{ |
|||
PCD_FreeUserBuffer(USBx, ep->num, 0U); |
|||
} |
|||
} |
|||
} |
|||
/* iso out double */ |
|||
else if (ep->type == EP_TYPE_ISOC) |
|||
{ |
|||
/* Multi packet transfer */ |
|||
if (ep->xfer_len > ep->maxpacket) |
|||
{ |
|||
len = ep->maxpacket; |
|||
ep->xfer_len -= len; |
|||
} |
|||
else |
|||
{ |
|||
len = ep->xfer_len; |
|||
ep->xfer_len = 0U; |
|||
} |
|||
PCD_SET_EP_DBUF_CNT(USBx, ep->num, ep->is_in, len); |
|||
} |
|||
else |
|||
{ |
|||
return HAL_ERROR; |
|||
} |
|||
} |
|||
|
|||
PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID); |
|||
} |
|||
|
|||
return HAL_OK; |
|||
} |
|||
|
|||
|
|||
/**
|
|||
* @brief USB_EPSetStall set a stall condition over an EP |
|||
* @param USBx Selected device |
|||
* @param ep pointer to endpoint structure |
|||
* @retval HAL status |
|||
*/ |
|||
HAL_StatusTypeDef USB_EPSetStall(USB_TypeDef *USBx, USB_EPTypeDef *ep) |
|||
{ |
|||
if (ep->is_in != 0U) |
|||
{ |
|||
PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_STALL); |
|||
} |
|||
else |
|||
{ |
|||
PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_STALL); |
|||
} |
|||
|
|||
return HAL_OK; |
|||
} |
|||
|
|||
/**
|
|||
* @brief USB_EPClearStall Clear a stall condition over an EP |
|||
* @param USBx Selected device |
|||
* @param ep pointer to endpoint structure |
|||
* @retval HAL status |
|||
*/ |
|||
HAL_StatusTypeDef USB_EPClearStall(USB_TypeDef *USBx, USB_EPTypeDef *ep) |
|||
{ |
|||
if (ep->doublebuffer == 0U) |
|||
{ |
|||
if (ep->is_in != 0U) |
|||
{ |
|||
PCD_CLEAR_TX_DTOG(USBx, ep->num); |
|||
|
|||
if (ep->type != EP_TYPE_ISOC) |
|||
{ |
|||
/* Configure NAK status for the Endpoint */ |
|||
PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
PCD_CLEAR_RX_DTOG(USBx, ep->num); |
|||
|
|||
/* Configure VALID status for the Endpoint */ |
|||
PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID); |
|||
} |
|||
} |
|||
|
|||
return HAL_OK; |
|||
} |
|||
#endif |
|||
|
|||
/**
|
|||
* @brief USB_StopDevice Stop the usb device mode |
|||
* @param USBx Selected device |
|||
* @retval HAL status |
|||
*/ |
|||
HAL_StatusTypeDef USB_StopDevice(USB_TypeDef *USBx) |
|||
{ |
|||
/* disable all interrupts and force USB reset */ |
|||
USBx->CNTR = (uint16_t)USB_CNTR_FRES; |
|||
|
|||
/* clear interrupt status register */ |
|||
USBx->ISTR = 0U; |
|||
|
|||
/* switch-off device */ |
|||
USBx->CNTR = (uint16_t)(USB_CNTR_FRES | USB_CNTR_PDWN); |
|||
|
|||
return HAL_OK; |
|||
} |
|||
|
|||
/**
|
|||
* @brief USB_SetDevAddress Stop the usb device mode |
|||
* @param USBx Selected device |
|||
* @param address new device address to be assigned |
|||
* This parameter can be a value from 0 to 255 |
|||
* @retval HAL status |
|||
*/ |
|||
HAL_StatusTypeDef USB_SetDevAddress(USB_TypeDef *USBx, uint8_t address) |
|||
{ |
|||
if (address == 0U) |
|||
{ |
|||
/* set device address and enable function */ |
|||
USBx->DADDR = (uint16_t)USB_DADDR_EF; |
|||
} |
|||
|
|||
return HAL_OK; |
|||
} |
|||
|
|||
/**
|
|||
* @brief USB_DevConnect Connect the USB device by enabling the pull-up/pull-down |
|||
* @param USBx Selected device |
|||
* @retval HAL status |
|||
*/ |
|||
HAL_StatusTypeDef USB_DevConnect(USB_TypeDef *USBx) |
|||
{ |
|||
/* Enabling DP Pull-UP bit to Connect internal PU resistor on USB DP line */ |
|||
USBx->BCDR |= (uint16_t)USB_BCDR_DPPU; |
|||
|
|||
return HAL_OK; |
|||
} |
|||
|
|||
/**
|
|||
* @brief USB_DevDisconnect Disconnect the USB device by disabling the pull-up/pull-down |
|||
* @param USBx Selected device |
|||
* @retval HAL status |
|||
*/ |
|||
HAL_StatusTypeDef USB_DevDisconnect(USB_TypeDef *USBx) |
|||
{ |
|||
/* Disable DP Pull-Up bit to disconnect the Internal PU resistor on USB DP line */ |
|||
USBx->BCDR &= (uint16_t)(~(USB_BCDR_DPPU)); |
|||
|
|||
return HAL_OK; |
|||
} |
|||
|
|||
/**
|
|||
* @brief USB_ReadInterrupts return the global USB interrupt status |
|||
* @param USBx Selected device |
|||
* @retval HAL status |
|||
*/ |
|||
uint32_t USB_ReadInterrupts(USB_TypeDef *USBx) |
|||
{ |
|||
uint32_t tmpreg; |
|||
|
|||
tmpreg = USBx->ISTR; |
|||
return tmpreg; |
|||
} |
|||
|
|||
/**
|
|||
* @brief USB_ActivateRemoteWakeup : active remote wakeup signalling |
|||
* @param USBx Selected device |
|||
* @retval HAL status |
|||
*/ |
|||
HAL_StatusTypeDef USB_ActivateRemoteWakeup(USB_TypeDef *USBx) |
|||
{ |
|||
USBx->CNTR |= (uint16_t)USB_CNTR_RESUME; |
|||
|
|||
return HAL_OK; |
|||
} |
|||
|
|||
/**
|
|||
* @brief USB_DeActivateRemoteWakeup de-active remote wakeup signalling |
|||
* @param USBx Selected device |
|||
* @retval HAL status |
|||
*/ |
|||
HAL_StatusTypeDef USB_DeActivateRemoteWakeup(USB_TypeDef *USBx) |
|||
{ |
|||
USBx->CNTR &= (uint16_t)(~USB_CNTR_RESUME); |
|||
|
|||
return HAL_OK; |
|||
} |
|||
|
|||
/**
|
|||
* @brief Copy a buffer from user memory area to packet memory area (PMA) |
|||
* @param USBx USB peripheral instance register address. |
|||
* @param pbUsrBuf pointer to user memory area. |
|||
* @param wPMABufAddr address into PMA. |
|||
* @param wNBytes no. of bytes to be copied. |
|||
* @retval None |
|||
*/ |
|||
void USB_WritePMA(USB_TypeDef *USBx, uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes) |
|||
{ |
|||
uint32_t n = ((uint32_t)wNBytes + 1U) >> 1; |
|||
uint32_t BaseAddr = (uint32_t)USBx; |
|||
uint32_t i, temp1, temp2; |
|||
__IO uint16_t *pdwVal; |
|||
uint8_t *pBuf = pbUsrBuf; |
|||
|
|||
pdwVal = (__IO uint16_t *)(BaseAddr + 0x400U + ((uint32_t)wPMABufAddr * PMA_ACCESS)); |
|||
|
|||
for (i = n; i != 0U; i--) |
|||
{ |
|||
temp1 = *pBuf; |
|||
pBuf++; |
|||
temp2 = temp1 | ((uint16_t)((uint16_t) *pBuf << 8)); |
|||
*pdwVal = (uint16_t)temp2; |
|||
pdwVal++; |
|||
|
|||
#if PMA_ACCESS > 1U |
|||
pdwVal++; |
|||
#endif |
|||
|
|||
pBuf++; |
|||
} |
|||
} |
|||
|
|||
/**
|
|||
* @brief Copy data from packet memory area (PMA) to user memory buffer |
|||
* @param USBx USB peripheral instance register address. |
|||
* @param pbUsrBuf pointer to user memory area. |
|||
* @param wPMABufAddr address into PMA. |
|||
* @param wNBytes no. of bytes to be copied. |
|||
* @retval None |
|||
*/ |
|||
void USB_ReadPMA(USB_TypeDef *USBx, uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes) |
|||
{ |
|||
uint32_t n = (uint32_t)wNBytes >> 1; |
|||
uint32_t BaseAddr = (uint32_t)USBx; |
|||
uint32_t i, temp; |
|||
__IO uint16_t *pdwVal; |
|||
uint8_t *pBuf = pbUsrBuf; |
|||
|
|||
pdwVal = (__IO uint16_t *)(BaseAddr + 0x400U + ((uint32_t)wPMABufAddr * PMA_ACCESS)); |
|||
|
|||
for (i = n; i != 0U; i--) |
|||
{ |
|||
temp = *(__IO uint16_t *)pdwVal; |
|||
pdwVal++; |
|||
*pBuf = (uint8_t)((temp >> 0) & 0xFFU); |
|||
pBuf++; |
|||
*pBuf = (uint8_t)((temp >> 8) & 0xFFU); |
|||
pBuf++; |
|||
|
|||
#if PMA_ACCESS > 1U |
|||
pdwVal++; |
|||
#endif |
|||
} |
|||
|
|||
if ((wNBytes % 2U) != 0U) |
|||
{ |
|||
temp = *pdwVal; |
|||
*pBuf = (uint8_t)((temp >> 0) & 0xFFU); |
|||
} |
|||
} |
|||
|
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
#endif /* defined (USB) */ |
|||
#endif /* defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED) */ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
|||
@ -0,0 +1,175 @@ |
|||
/**
|
|||
****************************************************************************** |
|||
* @file usbd_cdc.h |
|||
* @author MCD Application Team |
|||
* @brief header file for the usbd_cdc.c file. |
|||
****************************************************************************** |
|||
* @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: |
|||
* www.st.com/SLA0044 |
|||
* |
|||
****************************************************************************** |
|||
*/ |
|||
|
|||
/* Define to prevent recursive inclusion -------------------------------------*/ |
|||
#ifndef __USB_CDC_H |
|||
#define __USB_CDC_H |
|||
|
|||
#ifdef __cplusplus |
|||
extern "C" { |
|||
#endif |
|||
|
|||
/* Includes ------------------------------------------------------------------*/ |
|||
#include "usbd_ioreq.h" |
|||
|
|||
/** @addtogroup STM32_USB_DEVICE_LIBRARY
|
|||
* @{ |
|||
*/ |
|||
|
|||
/** @defgroup usbd_cdc
|
|||
* @brief This file is the Header file for usbd_cdc.c |
|||
* @{ |
|||
*/ |
|||
|
|||
|
|||
/** @defgroup usbd_cdc_Exported_Defines
|
|||
* @{ |
|||
*/ |
|||
#define CDC_IN_EP 0x81U /* EP1 for data IN */ |
|||
#define CDC_OUT_EP 0x01U /* EP1 for data OUT */ |
|||
#define CDC_CMD_EP 0x82U /* EP2 for CDC commands */ |
|||
|
|||
#ifndef CDC_HS_BINTERVAL |
|||
#define CDC_HS_BINTERVAL 0x10U |
|||
#endif /* CDC_HS_BINTERVAL */ |
|||
|
|||
#ifndef CDC_FS_BINTERVAL |
|||
#define CDC_FS_BINTERVAL 0x10U |
|||
#endif /* CDC_FS_BINTERVAL */ |
|||
|
|||
/* CDC Endpoints parameters: you can fine tune these values depending on the needed baudrates and performance. */ |
|||
#define CDC_DATA_HS_MAX_PACKET_SIZE 512U /* Endpoint IN & OUT Packet size */ |
|||
#define CDC_DATA_FS_MAX_PACKET_SIZE 64U /* Endpoint IN & OUT Packet size */ |
|||
#define CDC_CMD_PACKET_SIZE 8U /* Control Endpoint Packet size */ |
|||
|
|||
#define USB_CDC_CONFIG_DESC_SIZ 67U |
|||
#define CDC_DATA_HS_IN_PACKET_SIZE CDC_DATA_HS_MAX_PACKET_SIZE |
|||
#define CDC_DATA_HS_OUT_PACKET_SIZE CDC_DATA_HS_MAX_PACKET_SIZE |
|||
|
|||
#define CDC_DATA_FS_IN_PACKET_SIZE CDC_DATA_FS_MAX_PACKET_SIZE |
|||
#define CDC_DATA_FS_OUT_PACKET_SIZE CDC_DATA_FS_MAX_PACKET_SIZE |
|||
|
|||
#define CDC_REQ_MAX_DATA_SIZE 0x7U |
|||
/*---------------------------------------------------------------------*/ |
|||
/* CDC definitions */ |
|||
/*---------------------------------------------------------------------*/ |
|||
#define CDC_SEND_ENCAPSULATED_COMMAND 0x00U |
|||
#define CDC_GET_ENCAPSULATED_RESPONSE 0x01U |
|||
#define CDC_SET_COMM_FEATURE 0x02U |
|||
#define CDC_GET_COMM_FEATURE 0x03U |
|||
#define CDC_CLEAR_COMM_FEATURE 0x04U |
|||
#define CDC_SET_LINE_CODING 0x20U |
|||
#define CDC_GET_LINE_CODING 0x21U |
|||
#define CDC_SET_CONTROL_LINE_STATE 0x22U |
|||
#define CDC_SEND_BREAK 0x23U |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
|
|||
/** @defgroup USBD_CORE_Exported_TypesDefinitions
|
|||
* @{ |
|||
*/ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
typedef struct |
|||
{ |
|||
uint32_t bitrate; |
|||
uint8_t format; |
|||
uint8_t paritytype; |
|||
uint8_t datatype; |
|||
} USBD_CDC_LineCodingTypeDef; |
|||
|
|||
typedef struct _USBD_CDC_Itf |
|||
{ |
|||
int8_t (* Init)(void); |
|||
int8_t (* DeInit)(void); |
|||
int8_t (* Control)(uint8_t cmd, uint8_t *pbuf, uint16_t length); |
|||
int8_t (* Receive)(uint8_t *Buf, uint32_t *Len); |
|||
int8_t (* TransmitCplt)(uint8_t *Buf, uint32_t *Len, uint8_t epnum); |
|||
} USBD_CDC_ItfTypeDef; |
|||
|
|||
|
|||
typedef struct |
|||
{ |
|||
uint32_t data[CDC_DATA_HS_MAX_PACKET_SIZE / 4U]; /* Force 32bits alignment */ |
|||
uint8_t CmdOpCode; |
|||
uint8_t CmdLength; |
|||
uint8_t *RxBuffer; |
|||
uint8_t *TxBuffer; |
|||
uint32_t RxLength; |
|||
uint32_t TxLength; |
|||
|
|||
__IO uint32_t TxState; |
|||
__IO uint32_t RxState; |
|||
} USBD_CDC_HandleTypeDef; |
|||
|
|||
|
|||
|
|||
/** @defgroup USBD_CORE_Exported_Macros
|
|||
* @{ |
|||
*/ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/** @defgroup USBD_CORE_Exported_Variables
|
|||
* @{ |
|||
*/ |
|||
|
|||
extern USBD_ClassTypeDef USBD_CDC; |
|||
#define USBD_CDC_CLASS &USBD_CDC |
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/** @defgroup USB_CORE_Exported_Functions
|
|||
* @{ |
|||
*/ |
|||
uint8_t USBD_CDC_RegisterInterface(USBD_HandleTypeDef *pdev, |
|||
USBD_CDC_ItfTypeDef *fops); |
|||
|
|||
uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff, |
|||
uint32_t length); |
|||
|
|||
uint8_t USBD_CDC_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff); |
|||
uint8_t USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev); |
|||
uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev); |
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
#ifdef __cplusplus |
|||
} |
|||
#endif |
|||
|
|||
#endif /* __USB_CDC_H */ |
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
|||
@ -0,0 +1,968 @@ |
|||
/**
|
|||
****************************************************************************** |
|||
* @file usbd_cdc.c |
|||
* @author MCD Application Team |
|||
* @brief This file provides the high layer firmware functions to manage the |
|||
* following functionalities of the USB CDC Class: |
|||
* - Initialization and Configuration of high and low layer |
|||
* - Enumeration as CDC Device (and enumeration for each implemented memory interface) |
|||
* - OUT/IN data transfer |
|||
* - Command IN transfer (class requests management) |
|||
* - Error management |
|||
* |
|||
* @verbatim |
|||
* |
|||
* =================================================================== |
|||
* CDC Class Driver Description |
|||
* =================================================================== |
|||
* This driver manages the "Universal Serial Bus Class Definitions for Communications Devices |
|||
* Revision 1.2 November 16, 2007" and the sub-protocol specification of "Universal Serial Bus |
|||
* Communications Class Subclass Specification for PSTN Devices Revision 1.2 February 9, 2007" |
|||
* This driver implements the following aspects of the specification: |
|||
* - Device descriptor management |
|||
* - Configuration descriptor management |
|||
* - Enumeration as CDC device with 2 data endpoints (IN and OUT) and 1 command endpoint (IN) |
|||
* - Requests management (as described in section 6.2 in specification) |
|||
* - Abstract Control Model compliant |
|||
* - Union Functional collection (using 1 IN endpoint for control) |
|||
* - Data interface class |
|||
* |
|||
* These aspects may be enriched or modified for a specific user application. |
|||
* |
|||
* This driver doesn't implement the following aspects of the specification |
|||
* (but it is possible to manage these features with some modifications on this driver): |
|||
* - Any class-specific aspect relative to communication classes should be managed by user application. |
|||
* - All communication classes other than PSTN are not managed |
|||
* |
|||
* @endverbatim |
|||
* |
|||
****************************************************************************** |
|||
* @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: |
|||
* www.st.com/SLA0044 |
|||
* |
|||
****************************************************************************** |
|||
*/ |
|||
|
|||
/* BSPDependencies
|
|||
- "stm32xxxxx_{eval}{discovery}{nucleo_144}.c" |
|||
- "stm32xxxxx_{eval}{discovery}_io.c" |
|||
EndBSPDependencies */ |
|||
|
|||
/* Includes ------------------------------------------------------------------*/ |
|||
#include "usbd_cdc.h" |
|||
#include "usbd_ctlreq.h" |
|||
|
|||
|
|||
/** @addtogroup STM32_USB_DEVICE_LIBRARY
|
|||
* @{ |
|||
*/ |
|||
|
|||
|
|||
/** @defgroup USBD_CDC
|
|||
* @brief usbd core module |
|||
* @{ |
|||
*/ |
|||
|
|||
/** @defgroup USBD_CDC_Private_TypesDefinitions
|
|||
* @{ |
|||
*/ |
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
|
|||
/** @defgroup USBD_CDC_Private_Defines
|
|||
* @{ |
|||
*/ |
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
|
|||
/** @defgroup USBD_CDC_Private_Macros
|
|||
* @{ |
|||
*/ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
|
|||
/** @defgroup USBD_CDC_Private_FunctionPrototypes
|
|||
* @{ |
|||
*/ |
|||
|
|||
static uint8_t USBD_CDC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx); |
|||
static uint8_t USBD_CDC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx); |
|||
static uint8_t USBD_CDC_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); |
|||
static uint8_t USBD_CDC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum); |
|||
static uint8_t USBD_CDC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum); |
|||
static uint8_t USBD_CDC_EP0_RxReady(USBD_HandleTypeDef *pdev); |
|||
|
|||
static uint8_t *USBD_CDC_GetFSCfgDesc(uint16_t *length); |
|||
static uint8_t *USBD_CDC_GetHSCfgDesc(uint16_t *length); |
|||
static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length); |
|||
static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length); |
|||
uint8_t *USBD_CDC_GetDeviceQualifierDescriptor(uint16_t *length); |
|||
|
|||
/* USB Standard Device Descriptor */ |
|||
__ALIGN_BEGIN static uint8_t USBD_CDC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END = |
|||
{ |
|||
USB_LEN_DEV_QUALIFIER_DESC, |
|||
USB_DESC_TYPE_DEVICE_QUALIFIER, |
|||
0x00, |
|||
0x02, |
|||
0x00, |
|||
0x00, |
|||
0x00, |
|||
0x40, |
|||
0x01, |
|||
0x00, |
|||
}; |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/** @defgroup USBD_CDC_Private_Variables
|
|||
* @{ |
|||
*/ |
|||
|
|||
|
|||
/* CDC interface class callbacks structure */ |
|||
USBD_ClassTypeDef USBD_CDC = |
|||
{ |
|||
USBD_CDC_Init, |
|||
USBD_CDC_DeInit, |
|||
USBD_CDC_Setup, |
|||
NULL, /* EP0_TxSent, */ |
|||
USBD_CDC_EP0_RxReady, |
|||
USBD_CDC_DataIn, |
|||
USBD_CDC_DataOut, |
|||
NULL, |
|||
NULL, |
|||
NULL, |
|||
USBD_CDC_GetHSCfgDesc, |
|||
USBD_CDC_GetFSCfgDesc, |
|||
USBD_CDC_GetOtherSpeedCfgDesc, |
|||
USBD_CDC_GetDeviceQualifierDescriptor, |
|||
}; |
|||
|
|||
/* USB CDC device Configuration Descriptor */ |
|||
__ALIGN_BEGIN static uint8_t USBD_CDC_CfgHSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END = |
|||
{ |
|||
/* Configuration Descriptor */ |
|||
0x09, /* bLength: Configuration Descriptor size */ |
|||
USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ |
|||
USB_CDC_CONFIG_DESC_SIZ, /* wTotalLength:no of returned bytes */ |
|||
0x00, |
|||
0x02, /* bNumInterfaces: 2 interface */ |
|||
0x01, /* bConfigurationValue: Configuration value */ |
|||
0x00, /* iConfiguration: Index of string descriptor describing the configuration */ |
|||
#if (USBD_SELF_POWERED == 1U) |
|||
0xC0, /* bmAttributes: Bus Powered according to user configuration */ |
|||
#else |
|||
0x80, /* bmAttributes: Bus Powered according to user configuration */ |
|||
#endif |
|||
USBD_MAX_POWER, /* MaxPower 100 mA */ |
|||
|
|||
/*---------------------------------------------------------------------------*/ |
|||
|
|||
/* Interface Descriptor */ |
|||
0x09, /* bLength: Interface Descriptor size */ |
|||
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */ |
|||
0x00, /* bInterfaceNumber: Number of Interface */ |
|||
0x00, /* bAlternateSetting: Alternate setting */ |
|||
0x01, /* bNumEndpoints: One endpoints used */ |
|||
0x02, /* bInterfaceClass: Communication Interface Class */ |
|||
0x02, /* bInterfaceSubClass: Abstract Control Model */ |
|||
0x01, /* bInterfaceProtocol: Common AT commands */ |
|||
0x00, /* iInterface: */ |
|||
|
|||
/* Header Functional Descriptor */ |
|||
0x05, /* bLength: Endpoint Descriptor size */ |
|||
0x24, /* bDescriptorType: CS_INTERFACE */ |
|||
0x00, /* bDescriptorSubtype: Header Func Desc */ |
|||
0x10, /* bcdCDC: spec release number */ |
|||
0x01, |
|||
|
|||
/* Call Management Functional Descriptor */ |
|||
0x05, /* bFunctionLength */ |
|||
0x24, /* bDescriptorType: CS_INTERFACE */ |
|||
0x01, /* bDescriptorSubtype: Call Management Func Desc */ |
|||
0x00, /* bmCapabilities: D0+D1 */ |
|||
0x01, /* bDataInterface: 1 */ |
|||
|
|||
/* ACM Functional Descriptor */ |
|||
0x04, /* bFunctionLength */ |
|||
0x24, /* bDescriptorType: CS_INTERFACE */ |
|||
0x02, /* bDescriptorSubtype: Abstract Control Management desc */ |
|||
0x02, /* bmCapabilities */ |
|||
|
|||
/* Union Functional Descriptor */ |
|||
0x05, /* bFunctionLength */ |
|||
0x24, /* bDescriptorType: CS_INTERFACE */ |
|||
0x06, /* bDescriptorSubtype: Union func desc */ |
|||
0x00, /* bMasterInterface: Communication class interface */ |
|||
0x01, /* bSlaveInterface0: Data Class Interface */ |
|||
|
|||
/* Endpoint 2 Descriptor */ |
|||
0x07, /* bLength: Endpoint Descriptor size */ |
|||
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ |
|||
CDC_CMD_EP, /* bEndpointAddress */ |
|||
0x03, /* bmAttributes: Interrupt */ |
|||
LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize: */ |
|||
HIBYTE(CDC_CMD_PACKET_SIZE), |
|||
CDC_HS_BINTERVAL, /* bInterval: */ |
|||
/*---------------------------------------------------------------------------*/ |
|||
|
|||
/* Data class interface descriptor */ |
|||
0x09, /* bLength: Endpoint Descriptor size */ |
|||
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */ |
|||
0x01, /* bInterfaceNumber: Number of Interface */ |
|||
0x00, /* bAlternateSetting: Alternate setting */ |
|||
0x02, /* bNumEndpoints: Two endpoints used */ |
|||
0x0A, /* bInterfaceClass: CDC */ |
|||
0x00, /* bInterfaceSubClass: */ |
|||
0x00, /* bInterfaceProtocol: */ |
|||
0x00, /* iInterface: */ |
|||
|
|||
/* Endpoint OUT Descriptor */ |
|||
0x07, /* bLength: Endpoint Descriptor size */ |
|||
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ |
|||
CDC_OUT_EP, /* bEndpointAddress */ |
|||
0x02, /* bmAttributes: Bulk */ |
|||
LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize: */ |
|||
HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), |
|||
0x00, /* bInterval: ignore for Bulk transfer */ |
|||
|
|||
/* Endpoint IN Descriptor */ |
|||
0x07, /* bLength: Endpoint Descriptor size */ |
|||
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ |
|||
CDC_IN_EP, /* bEndpointAddress */ |
|||
0x02, /* bmAttributes: Bulk */ |
|||
LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize: */ |
|||
HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), |
|||
0x00 /* bInterval: ignore for Bulk transfer */ |
|||
}; |
|||
|
|||
|
|||
/* USB CDC device Configuration Descriptor */ |
|||
__ALIGN_BEGIN static uint8_t USBD_CDC_CfgFSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END = |
|||
{ |
|||
/* Configuration Descriptor */ |
|||
0x09, /* bLength: Configuration Descriptor size */ |
|||
USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ |
|||
USB_CDC_CONFIG_DESC_SIZ, /* wTotalLength:no of returned bytes */ |
|||
0x00, |
|||
0x02, /* bNumInterfaces: 2 interface */ |
|||
0x01, /* bConfigurationValue: Configuration value */ |
|||
0x00, /* iConfiguration: Index of string descriptor describing the configuration */ |
|||
#if (USBD_SELF_POWERED == 1U) |
|||
0xC0, /* bmAttributes: Bus Powered according to user configuration */ |
|||
#else |
|||
0x80, /* bmAttributes: Bus Powered according to user configuration */ |
|||
#endif |
|||
USBD_MAX_POWER, /* MaxPower 100 mA */ |
|||
|
|||
/*---------------------------------------------------------------------------*/ |
|||
|
|||
/* Interface Descriptor */ |
|||
0x09, /* bLength: Interface Descriptor size */ |
|||
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */ |
|||
/* Interface descriptor type */ |
|||
0x00, /* bInterfaceNumber: Number of Interface */ |
|||
0x00, /* bAlternateSetting: Alternate setting */ |
|||
0x01, /* bNumEndpoints: One endpoints used */ |
|||
0x02, /* bInterfaceClass: Communication Interface Class */ |
|||
0x02, /* bInterfaceSubClass: Abstract Control Model */ |
|||
0x01, /* bInterfaceProtocol: Common AT commands */ |
|||
0x00, /* iInterface: */ |
|||
|
|||
/* Header Functional Descriptor */ |
|||
0x05, /* bLength: Endpoint Descriptor size */ |
|||
0x24, /* bDescriptorType: CS_INTERFACE */ |
|||
0x00, /* bDescriptorSubtype: Header Func Desc */ |
|||
0x10, /* bcdCDC: spec release number */ |
|||
0x01, |
|||
|
|||
/* Call Management Functional Descriptor */ |
|||
0x05, /* bFunctionLength */ |
|||
0x24, /* bDescriptorType: CS_INTERFACE */ |
|||
0x01, /* bDescriptorSubtype: Call Management Func Desc */ |
|||
0x00, /* bmCapabilities: D0+D1 */ |
|||
0x01, /* bDataInterface: 1 */ |
|||
|
|||
/* ACM Functional Descriptor */ |
|||
0x04, /* bFunctionLength */ |
|||
0x24, /* bDescriptorType: CS_INTERFACE */ |
|||
0x02, /* bDescriptorSubtype: Abstract Control Management desc */ |
|||
0x02, /* bmCapabilities */ |
|||
|
|||
/* Union Functional Descriptor */ |
|||
0x05, /* bFunctionLength */ |
|||
0x24, /* bDescriptorType: CS_INTERFACE */ |
|||
0x06, /* bDescriptorSubtype: Union func desc */ |
|||
0x00, /* bMasterInterface: Communication class interface */ |
|||
0x01, /* bSlaveInterface0: Data Class Interface */ |
|||
|
|||
/* Endpoint 2 Descriptor */ |
|||
0x07, /* bLength: Endpoint Descriptor size */ |
|||
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ |
|||
CDC_CMD_EP, /* bEndpointAddress */ |
|||
0x03, /* bmAttributes: Interrupt */ |
|||
LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize: */ |
|||
HIBYTE(CDC_CMD_PACKET_SIZE), |
|||
CDC_FS_BINTERVAL, /* bInterval: */ |
|||
/*---------------------------------------------------------------------------*/ |
|||
|
|||
/* Data class interface descriptor */ |
|||
0x09, /* bLength: Endpoint Descriptor size */ |
|||
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */ |
|||
0x01, /* bInterfaceNumber: Number of Interface */ |
|||
0x00, /* bAlternateSetting: Alternate setting */ |
|||
0x02, /* bNumEndpoints: Two endpoints used */ |
|||
0x0A, /* bInterfaceClass: CDC */ |
|||
0x00, /* bInterfaceSubClass: */ |
|||
0x00, /* bInterfaceProtocol: */ |
|||
0x00, /* iInterface: */ |
|||
|
|||
/* Endpoint OUT Descriptor */ |
|||
0x07, /* bLength: Endpoint Descriptor size */ |
|||
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ |
|||
CDC_OUT_EP, /* bEndpointAddress */ |
|||
0x02, /* bmAttributes: Bulk */ |
|||
LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */ |
|||
HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), |
|||
0x00, /* bInterval: ignore for Bulk transfer */ |
|||
|
|||
/* Endpoint IN Descriptor */ |
|||
0x07, /* bLength: Endpoint Descriptor size */ |
|||
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ |
|||
CDC_IN_EP, /* bEndpointAddress */ |
|||
0x02, /* bmAttributes: Bulk */ |
|||
LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */ |
|||
HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), |
|||
0x00 /* bInterval: ignore for Bulk transfer */ |
|||
}; |
|||
|
|||
__ALIGN_BEGIN static uint8_t USBD_CDC_OtherSpeedCfgDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END = |
|||
{ |
|||
0x09, /* bLength: Configuration Descriptor size */ |
|||
USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION, |
|||
USB_CDC_CONFIG_DESC_SIZ, |
|||
0x00, |
|||
0x02, /* bNumInterfaces: 2 interfaces */ |
|||
0x01, /* bConfigurationValue: */ |
|||
0x04, /* iConfiguration: */ |
|||
#if (USBD_SELF_POWERED == 1U) |
|||
0xC0, /* bmAttributes: Bus Powered according to user configuration */ |
|||
#else |
|||
0x80, /* bmAttributes: Bus Powered according to user configuration */ |
|||
#endif |
|||
USBD_MAX_POWER, /* MaxPower 100 mA */ |
|||
|
|||
/*Interface Descriptor */ |
|||
0x09, /* bLength: Interface Descriptor size */ |
|||
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */ |
|||
/* Interface descriptor type */ |
|||
0x00, /* bInterfaceNumber: Number of Interface */ |
|||
0x00, /* bAlternateSetting: Alternate setting */ |
|||
0x01, /* bNumEndpoints: One endpoints used */ |
|||
0x02, /* bInterfaceClass: Communication Interface Class */ |
|||
0x02, /* bInterfaceSubClass: Abstract Control Model */ |
|||
0x01, /* bInterfaceProtocol: Common AT commands */ |
|||
0x00, /* iInterface: */ |
|||
|
|||
/* Header Functional Descriptor */ |
|||
0x05, /* bLength: Endpoint Descriptor size */ |
|||
0x24, /* bDescriptorType: CS_INTERFACE */ |
|||
0x00, /* bDescriptorSubtype: Header Func Desc */ |
|||
0x10, /* bcdCDC: spec release number */ |
|||
0x01, |
|||
|
|||
/*Call Management Functional Descriptor*/ |
|||
0x05, /* bFunctionLength */ |
|||
0x24, /* bDescriptorType: CS_INTERFACE */ |
|||
0x01, /* bDescriptorSubtype: Call Management Func Desc */ |
|||
0x00, /* bmCapabilities: D0+D1 */ |
|||
0x01, /* bDataInterface: 1 */ |
|||
|
|||
/*ACM Functional Descriptor*/ |
|||
0x04, /* bFunctionLength */ |
|||
0x24, /* bDescriptorType: CS_INTERFACE */ |
|||
0x02, /* bDescriptorSubtype: Abstract Control Management desc */ |
|||
0x02, /* bmCapabilities */ |
|||
|
|||
/*Union Functional Descriptor*/ |
|||
0x05, /* bFunctionLength */ |
|||
0x24, /* bDescriptorType: CS_INTERFACE */ |
|||
0x06, /* bDescriptorSubtype: Union func desc */ |
|||
0x00, /* bMasterInterface: Communication class interface */ |
|||
0x01, /* bSlaveInterface0: Data Class Interface */ |
|||
|
|||
/*Endpoint 2 Descriptor*/ |
|||
0x07, /* bLength: Endpoint Descriptor size */ |
|||
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ |
|||
CDC_CMD_EP, /* bEndpointAddress */ |
|||
0x03, /* bmAttributes: Interrupt */ |
|||
LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize: */ |
|||
HIBYTE(CDC_CMD_PACKET_SIZE), |
|||
CDC_FS_BINTERVAL, /* bInterval: */ |
|||
|
|||
/*---------------------------------------------------------------------------*/ |
|||
|
|||
/*Data class interface descriptor*/ |
|||
0x09, /* bLength: Endpoint Descriptor size */ |
|||
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */ |
|||
0x01, /* bInterfaceNumber: Number of Interface */ |
|||
0x00, /* bAlternateSetting: Alternate setting */ |
|||
0x02, /* bNumEndpoints: Two endpoints used */ |
|||
0x0A, /* bInterfaceClass: CDC */ |
|||
0x00, /* bInterfaceSubClass: */ |
|||
0x00, /* bInterfaceProtocol: */ |
|||
0x00, /* iInterface: */ |
|||
|
|||
/*Endpoint OUT Descriptor*/ |
|||
0x07, /* bLength: Endpoint Descriptor size */ |
|||
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ |
|||
CDC_OUT_EP, /* bEndpointAddress */ |
|||
0x02, /* bmAttributes: Bulk */ |
|||
0x40, /* wMaxPacketSize: */ |
|||
0x00, |
|||
0x00, /* bInterval: ignore for Bulk transfer */ |
|||
|
|||
/*Endpoint IN Descriptor*/ |
|||
0x07, /* bLength: Endpoint Descriptor size */ |
|||
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ |
|||
CDC_IN_EP, /* bEndpointAddress */ |
|||
0x02, /* bmAttributes: Bulk */ |
|||
0x40, /* wMaxPacketSize: */ |
|||
0x00, |
|||
0x00 /* bInterval */ |
|||
}; |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/** @defgroup USBD_CDC_Private_Functions
|
|||
* @{ |
|||
*/ |
|||
|
|||
/**
|
|||
* @brief USBD_CDC_Init |
|||
* Initialize the CDC interface |
|||
* @param pdev: device instance |
|||
* @param cfgidx: Configuration index |
|||
* @retval status |
|||
*/ |
|||
static uint8_t USBD_CDC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) |
|||
{ |
|||
UNUSED(cfgidx); |
|||
USBD_CDC_HandleTypeDef *hcdc; |
|||
|
|||
hcdc = USBD_malloc(sizeof(USBD_CDC_HandleTypeDef)); |
|||
|
|||
if (hcdc == NULL) |
|||
{ |
|||
pdev->pClassData = NULL; |
|||
return (uint8_t)USBD_EMEM; |
|||
} |
|||
|
|||
pdev->pClassData = (void *)hcdc; |
|||
|
|||
if (pdev->dev_speed == USBD_SPEED_HIGH) |
|||
{ |
|||
/* Open EP IN */ |
|||
(void)USBD_LL_OpenEP(pdev, CDC_IN_EP, USBD_EP_TYPE_BULK, |
|||
CDC_DATA_HS_IN_PACKET_SIZE); |
|||
|
|||
pdev->ep_in[CDC_IN_EP & 0xFU].is_used = 1U; |
|||
|
|||
/* Open EP OUT */ |
|||
(void)USBD_LL_OpenEP(pdev, CDC_OUT_EP, USBD_EP_TYPE_BULK, |
|||
CDC_DATA_HS_OUT_PACKET_SIZE); |
|||
|
|||
pdev->ep_out[CDC_OUT_EP & 0xFU].is_used = 1U; |
|||
|
|||
/* Set bInterval for CDC CMD Endpoint */ |
|||
pdev->ep_in[CDC_CMD_EP & 0xFU].bInterval = CDC_HS_BINTERVAL; |
|||
} |
|||
else |
|||
{ |
|||
/* Open EP IN */ |
|||
(void)USBD_LL_OpenEP(pdev, CDC_IN_EP, USBD_EP_TYPE_BULK, |
|||
CDC_DATA_FS_IN_PACKET_SIZE); |
|||
|
|||
pdev->ep_in[CDC_IN_EP & 0xFU].is_used = 1U; |
|||
|
|||
/* Open EP OUT */ |
|||
(void)USBD_LL_OpenEP(pdev, CDC_OUT_EP, USBD_EP_TYPE_BULK, |
|||
CDC_DATA_FS_OUT_PACKET_SIZE); |
|||
|
|||
pdev->ep_out[CDC_OUT_EP & 0xFU].is_used = 1U; |
|||
|
|||
/* Set bInterval for CMD Endpoint */ |
|||
pdev->ep_in[CDC_CMD_EP & 0xFU].bInterval = CDC_FS_BINTERVAL; |
|||
} |
|||
|
|||
/* Open Command IN EP */ |
|||
(void)USBD_LL_OpenEP(pdev, CDC_CMD_EP, USBD_EP_TYPE_INTR, CDC_CMD_PACKET_SIZE); |
|||
pdev->ep_in[CDC_CMD_EP & 0xFU].is_used = 1U; |
|||
|
|||
/* Init physical Interface components */ |
|||
((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Init(); |
|||
|
|||
/* Init Xfer states */ |
|||
hcdc->TxState = 0U; |
|||
hcdc->RxState = 0U; |
|||
|
|||
if (pdev->dev_speed == USBD_SPEED_HIGH) |
|||
{ |
|||
/* Prepare Out endpoint to receive next packet */ |
|||
(void)USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, hcdc->RxBuffer, |
|||
CDC_DATA_HS_OUT_PACKET_SIZE); |
|||
} |
|||
else |
|||
{ |
|||
/* Prepare Out endpoint to receive next packet */ |
|||
(void)USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, hcdc->RxBuffer, |
|||
CDC_DATA_FS_OUT_PACKET_SIZE); |
|||
} |
|||
|
|||
return (uint8_t)USBD_OK; |
|||
} |
|||
|
|||
/**
|
|||
* @brief USBD_CDC_Init |
|||
* DeInitialize the CDC layer |
|||
* @param pdev: device instance |
|||
* @param cfgidx: Configuration index |
|||
* @retval status |
|||
*/ |
|||
static uint8_t USBD_CDC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) |
|||
{ |
|||
UNUSED(cfgidx); |
|||
|
|||
/* Close EP IN */ |
|||
(void)USBD_LL_CloseEP(pdev, CDC_IN_EP); |
|||
pdev->ep_in[CDC_IN_EP & 0xFU].is_used = 0U; |
|||
|
|||
/* Close EP OUT */ |
|||
(void)USBD_LL_CloseEP(pdev, CDC_OUT_EP); |
|||
pdev->ep_out[CDC_OUT_EP & 0xFU].is_used = 0U; |
|||
|
|||
/* Close Command IN EP */ |
|||
(void)USBD_LL_CloseEP(pdev, CDC_CMD_EP); |
|||
pdev->ep_in[CDC_CMD_EP & 0xFU].is_used = 0U; |
|||
pdev->ep_in[CDC_CMD_EP & 0xFU].bInterval = 0U; |
|||
|
|||
/* DeInit physical Interface components */ |
|||
if (pdev->pClassData != NULL) |
|||
{ |
|||
((USBD_CDC_ItfTypeDef *)pdev->pUserData)->DeInit(); |
|||
(void)USBD_free(pdev->pClassData); |
|||
pdev->pClassData = NULL; |
|||
} |
|||
|
|||
return (uint8_t)USBD_OK; |
|||
} |
|||
|
|||
/**
|
|||
* @brief USBD_CDC_Setup |
|||
* Handle the CDC specific requests |
|||
* @param pdev: instance |
|||
* @param req: usb requests |
|||
* @retval status |
|||
*/ |
|||
static uint8_t USBD_CDC_Setup(USBD_HandleTypeDef *pdev, |
|||
USBD_SetupReqTypedef *req) |
|||
{ |
|||
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData; |
|||
uint16_t len; |
|||
uint8_t ifalt = 0U; |
|||
uint16_t status_info = 0U; |
|||
USBD_StatusTypeDef ret = USBD_OK; |
|||
|
|||
if (hcdc == NULL) |
|||
{ |
|||
return (uint8_t)USBD_FAIL; |
|||
} |
|||
|
|||
switch (req->bmRequest & USB_REQ_TYPE_MASK) |
|||
{ |
|||
case USB_REQ_TYPE_CLASS: |
|||
if (req->wLength != 0U) |
|||
{ |
|||
if ((req->bmRequest & 0x80U) != 0U) |
|||
{ |
|||
((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest, |
|||
(uint8_t *)hcdc->data, |
|||
req->wLength); |
|||
|
|||
len = MIN(CDC_REQ_MAX_DATA_SIZE, req->wLength); |
|||
(void)USBD_CtlSendData(pdev, (uint8_t *)hcdc->data, len); |
|||
} |
|||
else |
|||
{ |
|||
hcdc->CmdOpCode = req->bRequest; |
|||
hcdc->CmdLength = (uint8_t)req->wLength; |
|||
|
|||
(void)USBD_CtlPrepareRx(pdev, (uint8_t *)hcdc->data, req->wLength); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest, |
|||
(uint8_t *)req, 0U); |
|||
} |
|||
break; |
|||
|
|||
case USB_REQ_TYPE_STANDARD: |
|||
switch (req->bRequest) |
|||
{ |
|||
case USB_REQ_GET_STATUS: |
|||
if (pdev->dev_state == USBD_STATE_CONFIGURED) |
|||
{ |
|||
(void)USBD_CtlSendData(pdev, (uint8_t *)&status_info, 2U); |
|||
} |
|||
else |
|||
{ |
|||
USBD_CtlError(pdev, req); |
|||
ret = USBD_FAIL; |
|||
} |
|||
break; |
|||
|
|||
case USB_REQ_GET_INTERFACE: |
|||
if (pdev->dev_state == USBD_STATE_CONFIGURED) |
|||
{ |
|||
(void)USBD_CtlSendData(pdev, &ifalt, 1U); |
|||
} |
|||
else |
|||
{ |
|||
USBD_CtlError(pdev, req); |
|||
ret = USBD_FAIL; |
|||
} |
|||
break; |
|||
|
|||
case USB_REQ_SET_INTERFACE: |
|||
if (pdev->dev_state != USBD_STATE_CONFIGURED) |
|||
{ |
|||
USBD_CtlError(pdev, req); |
|||
ret = USBD_FAIL; |
|||
} |
|||
break; |
|||
|
|||
case USB_REQ_CLEAR_FEATURE: |
|||
break; |
|||
|
|||
default: |
|||
USBD_CtlError(pdev, req); |
|||
ret = USBD_FAIL; |
|||
break; |
|||
} |
|||
break; |
|||
|
|||
default: |
|||
USBD_CtlError(pdev, req); |
|||
ret = USBD_FAIL; |
|||
break; |
|||
} |
|||
|
|||
return (uint8_t)ret; |
|||
} |
|||
|
|||
/**
|
|||
* @brief USBD_CDC_DataIn |
|||
* Data sent on non-control IN endpoint |
|||
* @param pdev: device instance |
|||
* @param epnum: endpoint number |
|||
* @retval status |
|||
*/ |
|||
static uint8_t USBD_CDC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) |
|||
{ |
|||
USBD_CDC_HandleTypeDef *hcdc; |
|||
PCD_HandleTypeDef *hpcd = pdev->pData; |
|||
|
|||
if (pdev->pClassData == NULL) |
|||
{ |
|||
return (uint8_t)USBD_FAIL; |
|||
} |
|||
|
|||
hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData; |
|||
|
|||
if ((pdev->ep_in[epnum].total_length > 0U) && |
|||
((pdev->ep_in[epnum].total_length % hpcd->IN_ep[epnum].maxpacket) == 0U)) |
|||
{ |
|||
/* Update the packet total length */ |
|||
pdev->ep_in[epnum].total_length = 0U; |
|||
|
|||
/* Send ZLP */ |
|||
(void)USBD_LL_Transmit(pdev, epnum, NULL, 0U); |
|||
} |
|||
else |
|||
{ |
|||
hcdc->TxState = 0U; |
|||
|
|||
if (((USBD_CDC_ItfTypeDef *)pdev->pUserData)->TransmitCplt != NULL) |
|||
{ |
|||
((USBD_CDC_ItfTypeDef *)pdev->pUserData)->TransmitCplt(hcdc->TxBuffer, &hcdc->TxLength, epnum); |
|||
} |
|||
} |
|||
|
|||
return (uint8_t)USBD_OK; |
|||
} |
|||
|
|||
/**
|
|||
* @brief USBD_CDC_DataOut |
|||
* Data received on non-control Out endpoint |
|||
* @param pdev: device instance |
|||
* @param epnum: endpoint number |
|||
* @retval status |
|||
*/ |
|||
static uint8_t USBD_CDC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) |
|||
{ |
|||
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData; |
|||
|
|||
if (pdev->pClassData == NULL) |
|||
{ |
|||
return (uint8_t)USBD_FAIL; |
|||
} |
|||
|
|||
/* Get the received data length */ |
|||
hcdc->RxLength = USBD_LL_GetRxDataSize(pdev, epnum); |
|||
|
|||
/* USB data will be immediately processed, this allow next USB traffic being
|
|||
NAKed till the end of the application Xfer */ |
|||
|
|||
((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Receive(hcdc->RxBuffer, &hcdc->RxLength); |
|||
|
|||
return (uint8_t)USBD_OK; |
|||
} |
|||
|
|||
/**
|
|||
* @brief USBD_CDC_EP0_RxReady |
|||
* Handle EP0 Rx Ready event |
|||
* @param pdev: device instance |
|||
* @retval status |
|||
*/ |
|||
static uint8_t USBD_CDC_EP0_RxReady(USBD_HandleTypeDef *pdev) |
|||
{ |
|||
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData; |
|||
|
|||
if (hcdc == NULL) |
|||
{ |
|||
return (uint8_t)USBD_FAIL; |
|||
} |
|||
|
|||
if ((pdev->pUserData != NULL) && (hcdc->CmdOpCode != 0xFFU)) |
|||
{ |
|||
((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(hcdc->CmdOpCode, |
|||
(uint8_t *)hcdc->data, |
|||
(uint16_t)hcdc->CmdLength); |
|||
hcdc->CmdOpCode = 0xFFU; |
|||
} |
|||
|
|||
return (uint8_t)USBD_OK; |
|||
} |
|||
|
|||
/**
|
|||
* @brief USBD_CDC_GetFSCfgDesc |
|||
* Return configuration descriptor |
|||
* @param speed : current device speed |
|||
* @param length : pointer data length |
|||
* @retval pointer to descriptor buffer |
|||
*/ |
|||
static uint8_t *USBD_CDC_GetFSCfgDesc(uint16_t *length) |
|||
{ |
|||
*length = (uint16_t)sizeof(USBD_CDC_CfgFSDesc); |
|||
|
|||
return USBD_CDC_CfgFSDesc; |
|||
} |
|||
|
|||
/**
|
|||
* @brief USBD_CDC_GetHSCfgDesc |
|||
* Return configuration descriptor |
|||
* @param speed : current device speed |
|||
* @param length : pointer data length |
|||
* @retval pointer to descriptor buffer |
|||
*/ |
|||
static uint8_t *USBD_CDC_GetHSCfgDesc(uint16_t *length) |
|||
{ |
|||
*length = (uint16_t)sizeof(USBD_CDC_CfgHSDesc); |
|||
|
|||
return USBD_CDC_CfgHSDesc; |
|||
} |
|||
|
|||
/**
|
|||
* @brief USBD_CDC_GetOtherSpeedCfgDesc |
|||
* Return configuration descriptor |
|||
* @param speed : current device speed |
|||
* @param length : pointer data length |
|||
* @retval pointer to descriptor buffer |
|||
*/ |
|||
static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length) |
|||
{ |
|||
*length = (uint16_t)sizeof(USBD_CDC_OtherSpeedCfgDesc); |
|||
|
|||
return USBD_CDC_OtherSpeedCfgDesc; |
|||
} |
|||
|
|||
/**
|
|||
* @brief USBD_CDC_GetDeviceQualifierDescriptor |
|||
* return Device Qualifier descriptor |
|||
* @param length : pointer data length |
|||
* @retval pointer to descriptor buffer |
|||
*/ |
|||
uint8_t *USBD_CDC_GetDeviceQualifierDescriptor(uint16_t *length) |
|||
{ |
|||
*length = (uint16_t)sizeof(USBD_CDC_DeviceQualifierDesc); |
|||
|
|||
return USBD_CDC_DeviceQualifierDesc; |
|||
} |
|||
|
|||
/**
|
|||
* @brief USBD_CDC_RegisterInterface |
|||
* @param pdev: device instance |
|||
* @param fops: CD Interface callback |
|||
* @retval status |
|||
*/ |
|||
uint8_t USBD_CDC_RegisterInterface(USBD_HandleTypeDef *pdev, |
|||
USBD_CDC_ItfTypeDef *fops) |
|||
{ |
|||
if (fops == NULL) |
|||
{ |
|||
return (uint8_t)USBD_FAIL; |
|||
} |
|||
|
|||
pdev->pUserData = fops; |
|||
|
|||
return (uint8_t)USBD_OK; |
|||
} |
|||
|
|||
/**
|
|||
* @brief USBD_CDC_SetTxBuffer |
|||
* @param pdev: device instance |
|||
* @param pbuff: Tx Buffer |
|||
* @retval status |
|||
*/ |
|||
uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev, |
|||
uint8_t *pbuff, uint32_t length) |
|||
{ |
|||
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData; |
|||
|
|||
if (hcdc == NULL) |
|||
{ |
|||
return (uint8_t)USBD_FAIL; |
|||
} |
|||
|
|||
hcdc->TxBuffer = pbuff; |
|||
hcdc->TxLength = length; |
|||
|
|||
return (uint8_t)USBD_OK; |
|||
} |
|||
|
|||
/**
|
|||
* @brief USBD_CDC_SetRxBuffer |
|||
* @param pdev: device instance |
|||
* @param pbuff: Rx Buffer |
|||
* @retval status |
|||
*/ |
|||
uint8_t USBD_CDC_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff) |
|||
{ |
|||
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData; |
|||
|
|||
if (hcdc == NULL) |
|||
{ |
|||
return (uint8_t)USBD_FAIL; |
|||
} |
|||
|
|||
hcdc->RxBuffer = pbuff; |
|||
|
|||
return (uint8_t)USBD_OK; |
|||
} |
|||
|
|||
/**
|
|||
* @brief USBD_CDC_TransmitPacket |
|||
* Transmit packet on IN endpoint |
|||
* @param pdev: device instance |
|||
* @retval status |
|||
*/ |
|||
uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev) |
|||
{ |
|||
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData; |
|||
USBD_StatusTypeDef ret = USBD_BUSY; |
|||
|
|||
if (pdev->pClassData == NULL) |
|||
{ |
|||
return (uint8_t)USBD_FAIL; |
|||
} |
|||
|
|||
if (hcdc->TxState == 0U) |
|||
{ |
|||
/* Tx Transfer in progress */ |
|||
hcdc->TxState = 1U; |
|||
|
|||
/* Update the packet total length */ |
|||
pdev->ep_in[CDC_IN_EP & 0xFU].total_length = hcdc->TxLength; |
|||
|
|||
/* Transmit next packet */ |
|||
(void)USBD_LL_Transmit(pdev, CDC_IN_EP, hcdc->TxBuffer, hcdc->TxLength); |
|||
|
|||
ret = USBD_OK; |
|||
} |
|||
|
|||
return (uint8_t)ret; |
|||
} |
|||
|
|||
/**
|
|||
* @brief USBD_CDC_ReceivePacket |
|||
* prepare OUT Endpoint for reception |
|||
* @param pdev: device instance |
|||
* @retval status |
|||
*/ |
|||
uint8_t USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev) |
|||
{ |
|||
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData; |
|||
|
|||
if (pdev->pClassData == NULL) |
|||
{ |
|||
return (uint8_t)USBD_FAIL; |
|||
} |
|||
|
|||
if (pdev->dev_speed == USBD_SPEED_HIGH) |
|||
{ |
|||
/* Prepare Out endpoint to receive next packet */ |
|||
(void)USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, hcdc->RxBuffer, |
|||
CDC_DATA_HS_OUT_PACKET_SIZE); |
|||
} |
|||
else |
|||
{ |
|||
/* Prepare Out endpoint to receive next packet */ |
|||
(void)USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, hcdc->RxBuffer, |
|||
CDC_DATA_FS_OUT_PACKET_SIZE); |
|||
} |
|||
|
|||
return (uint8_t)USBD_OK; |
|||
} |
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
|||
@ -0,0 +1,158 @@ |
|||
/**
|
|||
****************************************************************************** |
|||
* @file usbd_core.h |
|||
* @author MCD Application Team |
|||
* @brief Header file for usbd_core.c file |
|||
****************************************************************************** |
|||
* @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: |
|||
* www.st.com/SLA0044 |
|||
* |
|||
****************************************************************************** |
|||
*/ |
|||
|
|||
/* Define to prevent recursive inclusion -------------------------------------*/ |
|||
#ifndef __USBD_CORE_H |
|||
#define __USBD_CORE_H |
|||
|
|||
#ifdef __cplusplus |
|||
extern "C" { |
|||
#endif |
|||
|
|||
/* Includes ------------------------------------------------------------------*/ |
|||
#include "usbd_conf.h" |
|||
#include "usbd_def.h" |
|||
#include "usbd_ioreq.h" |
|||
#include "usbd_ctlreq.h" |
|||
|
|||
/** @addtogroup STM32_USB_DEVICE_LIBRARY
|
|||
* @{ |
|||
*/ |
|||
|
|||
/** @defgroup USBD_CORE
|
|||
* @brief This file is the Header file for usbd_core.c file |
|||
* @{ |
|||
*/ |
|||
|
|||
|
|||
/** @defgroup USBD_CORE_Exported_Defines
|
|||
* @{ |
|||
*/ |
|||
#ifndef USBD_DEBUG_LEVEL |
|||
#define USBD_DEBUG_LEVEL 0U |
|||
#endif /* USBD_DEBUG_LEVEL */ |
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
|
|||
/** @defgroup USBD_CORE_Exported_TypesDefinitions
|
|||
* @{ |
|||
*/ |
|||
|
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
|
|||
|
|||
/** @defgroup USBD_CORE_Exported_Macros
|
|||
* @{ |
|||
*/ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/** @defgroup USBD_CORE_Exported_Variables
|
|||
* @{ |
|||
*/ |
|||
#define USBD_SOF USBD_LL_SOF |
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/** @defgroup USBD_CORE_Exported_FunctionsPrototype
|
|||
* @{ |
|||
*/ |
|||
USBD_StatusTypeDef USBD_Init(USBD_HandleTypeDef *pdev, USBD_DescriptorsTypeDef *pdesc, uint8_t id); |
|||
USBD_StatusTypeDef USBD_DeInit(USBD_HandleTypeDef *pdev); |
|||
USBD_StatusTypeDef USBD_Start(USBD_HandleTypeDef *pdev); |
|||
USBD_StatusTypeDef USBD_Stop(USBD_HandleTypeDef *pdev); |
|||
USBD_StatusTypeDef USBD_RegisterClass(USBD_HandleTypeDef *pdev, USBD_ClassTypeDef *pclass); |
|||
|
|||
USBD_StatusTypeDef USBD_RunTestMode(USBD_HandleTypeDef *pdev); |
|||
USBD_StatusTypeDef USBD_SetClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx); |
|||
USBD_StatusTypeDef USBD_ClrClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx); |
|||
|
|||
USBD_StatusTypeDef USBD_LL_SetupStage(USBD_HandleTypeDef *pdev, uint8_t *psetup); |
|||
USBD_StatusTypeDef USBD_LL_DataOutStage(USBD_HandleTypeDef *pdev, uint8_t epnum, uint8_t *pdata); |
|||
USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev, uint8_t epnum, uint8_t *pdata); |
|||
|
|||
USBD_StatusTypeDef USBD_LL_Reset(USBD_HandleTypeDef *pdev); |
|||
USBD_StatusTypeDef USBD_LL_SetSpeed(USBD_HandleTypeDef *pdev, USBD_SpeedTypeDef speed); |
|||
USBD_StatusTypeDef USBD_LL_Suspend(USBD_HandleTypeDef *pdev); |
|||
USBD_StatusTypeDef USBD_LL_Resume(USBD_HandleTypeDef *pdev); |
|||
|
|||
USBD_StatusTypeDef USBD_LL_SOF(USBD_HandleTypeDef *pdev); |
|||
USBD_StatusTypeDef USBD_LL_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum); |
|||
USBD_StatusTypeDef USBD_LL_IsoOUTIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum); |
|||
|
|||
USBD_StatusTypeDef USBD_LL_DevConnected(USBD_HandleTypeDef *pdev); |
|||
USBD_StatusTypeDef USBD_LL_DevDisconnected(USBD_HandleTypeDef *pdev); |
|||
|
|||
/* USBD Low Level Driver */ |
|||
USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev); |
|||
USBD_StatusTypeDef USBD_LL_DeInit(USBD_HandleTypeDef *pdev); |
|||
USBD_StatusTypeDef USBD_LL_Start(USBD_HandleTypeDef *pdev); |
|||
USBD_StatusTypeDef USBD_LL_Stop(USBD_HandleTypeDef *pdev); |
|||
|
|||
USBD_StatusTypeDef USBD_LL_OpenEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr, |
|||
uint8_t ep_type, uint16_t ep_mps); |
|||
|
|||
USBD_StatusTypeDef USBD_LL_CloseEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr); |
|||
USBD_StatusTypeDef USBD_LL_FlushEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr); |
|||
USBD_StatusTypeDef USBD_LL_StallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr); |
|||
USBD_StatusTypeDef USBD_LL_ClearStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr); |
|||
USBD_StatusTypeDef USBD_LL_SetUSBAddress(USBD_HandleTypeDef *pdev, uint8_t dev_addr); |
|||
|
|||
USBD_StatusTypeDef USBD_LL_Transmit(USBD_HandleTypeDef *pdev, uint8_t ep_addr, |
|||
uint8_t *pbuf, uint32_t size); |
|||
|
|||
USBD_StatusTypeDef USBD_LL_PrepareReceive(USBD_HandleTypeDef *pdev, uint8_t ep_addr, |
|||
uint8_t *pbuf, uint32_t size); |
|||
|
|||
uint8_t USBD_LL_IsStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr); |
|||
uint32_t USBD_LL_GetRxDataSize(USBD_HandleTypeDef *pdev, uint8_t ep_addr); |
|||
|
|||
void USBD_LL_Delay(uint32_t Delay); |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
#ifdef __cplusplus |
|||
} |
|||
#endif |
|||
|
|||
#endif /* __USBD_CORE_H */ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
|||
|
|||
|
|||
|
|||
@ -0,0 +1,103 @@ |
|||
/**
|
|||
****************************************************************************** |
|||
* @file usbd_req.h |
|||
* @author MCD Application Team |
|||
* @brief Header file for the usbd_req.c file |
|||
****************************************************************************** |
|||
* @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: |
|||
* www.st.com/SLA0044 |
|||
* |
|||
****************************************************************************** |
|||
*/ |
|||
|
|||
/* Define to prevent recursive inclusion -------------------------------------*/ |
|||
#ifndef __USB_REQUEST_H |
|||
#define __USB_REQUEST_H |
|||
|
|||
#ifdef __cplusplus |
|||
extern "C" { |
|||
#endif |
|||
|
|||
/* Includes ------------------------------------------------------------------*/ |
|||
#include "usbd_def.h" |
|||
|
|||
|
|||
/** @addtogroup STM32_USB_DEVICE_LIBRARY
|
|||
* @{ |
|||
*/ |
|||
|
|||
/** @defgroup USBD_REQ
|
|||
* @brief header file for the usbd_req.c file |
|||
* @{ |
|||
*/ |
|||
|
|||
/** @defgroup USBD_REQ_Exported_Defines
|
|||
* @{ |
|||
*/ |
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
|
|||
/** @defgroup USBD_REQ_Exported_Types
|
|||
* @{ |
|||
*/ |
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
|
|||
|
|||
/** @defgroup USBD_REQ_Exported_Macros
|
|||
* @{ |
|||
*/ |
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/** @defgroup USBD_REQ_Exported_Variables
|
|||
* @{ |
|||
*/ |
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/** @defgroup USBD_REQ_Exported_FunctionsPrototype
|
|||
* @{ |
|||
*/ |
|||
|
|||
USBD_StatusTypeDef USBD_StdDevReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); |
|||
USBD_StatusTypeDef USBD_StdItfReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); |
|||
USBD_StatusTypeDef USBD_StdEPReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); |
|||
|
|||
void USBD_CtlError(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); |
|||
void USBD_ParseSetupRequest(USBD_SetupReqTypedef *req, uint8_t *pdata); |
|||
void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len); |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
#ifdef __cplusplus |
|||
} |
|||
#endif |
|||
|
|||
#endif /* __USB_REQUEST_H */ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
|
|||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
|||
@ -0,0 +1,420 @@ |
|||
/**
|
|||
****************************************************************************** |
|||
* @file usbd_def.h |
|||
* @author MCD Application Team |
|||
* @brief General defines for the usb device library |
|||
****************************************************************************** |
|||
* @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: |
|||
* www.st.com/SLA0044 |
|||
* |
|||
****************************************************************************** |
|||
*/ |
|||
|
|||
/* Define to prevent recursive inclusion -------------------------------------*/ |
|||
#ifndef __USBD_DEF_H |
|||
#define __USBD_DEF_H |
|||
|
|||
#ifdef __cplusplus |
|||
extern "C" { |
|||
#endif |
|||
|
|||
/* Includes ------------------------------------------------------------------*/ |
|||
#include "usbd_conf.h" |
|||
|
|||
/** @addtogroup STM32_USBD_DEVICE_LIBRARY
|
|||
* @{ |
|||
*/ |
|||
|
|||
/** @defgroup USB_DEF
|
|||
* @brief general defines for the usb device library file |
|||
* @{ |
|||
*/ |
|||
|
|||
/** @defgroup USB_DEF_Exported_Defines
|
|||
* @{ |
|||
*/ |
|||
|
|||
#ifndef NULL |
|||
#define NULL 0U |
|||
#endif /* NULL */ |
|||
|
|||
#ifndef USBD_MAX_NUM_INTERFACES |
|||
#define USBD_MAX_NUM_INTERFACES 1U |
|||
#endif /* USBD_MAX_NUM_CONFIGURATION */ |
|||
|
|||
#ifndef USBD_MAX_NUM_CONFIGURATION |
|||
#define USBD_MAX_NUM_CONFIGURATION 1U |
|||
#endif /* USBD_MAX_NUM_CONFIGURATION */ |
|||
|
|||
#ifndef USBD_LPM_ENABLED |
|||
#define USBD_LPM_ENABLED 0U |
|||
#endif /* USBD_LPM_ENABLED */ |
|||
|
|||
#ifndef USBD_SELF_POWERED |
|||
#define USBD_SELF_POWERED 1U |
|||
#endif /*USBD_SELF_POWERED */ |
|||
|
|||
#ifndef USBD_MAX_POWER |
|||
#define USBD_MAX_POWER 0x32U /* 100 mA */ |
|||
#endif /* USBD_MAX_POWER */ |
|||
|
|||
#ifndef USBD_SUPPORT_USER_STRING_DESC |
|||
#define USBD_SUPPORT_USER_STRING_DESC 0U |
|||
#endif /* USBD_SUPPORT_USER_STRING_DESC */ |
|||
|
|||
#ifndef USBD_CLASS_USER_STRING_DESC |
|||
#define USBD_CLASS_USER_STRING_DESC 0U |
|||
#endif /* USBD_CLASS_USER_STRING_DESC */ |
|||
|
|||
#define USB_LEN_DEV_QUALIFIER_DESC 0x0AU |
|||
#define USB_LEN_DEV_DESC 0x12U |
|||
#define USB_LEN_CFG_DESC 0x09U |
|||
#define USB_LEN_IF_DESC 0x09U |
|||
#define USB_LEN_EP_DESC 0x07U |
|||
#define USB_LEN_OTG_DESC 0x03U |
|||
#define USB_LEN_LANGID_STR_DESC 0x04U |
|||
#define USB_LEN_OTHER_SPEED_DESC_SIZ 0x09U |
|||
|
|||
#define USBD_IDX_LANGID_STR 0x00U |
|||
#define USBD_IDX_MFC_STR 0x01U |
|||
#define USBD_IDX_PRODUCT_STR 0x02U |
|||
#define USBD_IDX_SERIAL_STR 0x03U |
|||
#define USBD_IDX_CONFIG_STR 0x04U |
|||
#define USBD_IDX_INTERFACE_STR 0x05U |
|||
|
|||
#define USB_REQ_TYPE_STANDARD 0x00U |
|||
#define USB_REQ_TYPE_CLASS 0x20U |
|||
#define USB_REQ_TYPE_VENDOR 0x40U |
|||
#define USB_REQ_TYPE_MASK 0x60U |
|||
|
|||
#define USB_REQ_RECIPIENT_DEVICE 0x00U |
|||
#define USB_REQ_RECIPIENT_INTERFACE 0x01U |
|||
#define USB_REQ_RECIPIENT_ENDPOINT 0x02U |
|||
#define USB_REQ_RECIPIENT_MASK 0x03U |
|||
|
|||
#define USB_REQ_GET_STATUS 0x00U |
|||
#define USB_REQ_CLEAR_FEATURE 0x01U |
|||
#define USB_REQ_SET_FEATURE 0x03U |
|||
#define USB_REQ_SET_ADDRESS 0x05U |
|||
#define USB_REQ_GET_DESCRIPTOR 0x06U |
|||
#define USB_REQ_SET_DESCRIPTOR 0x07U |
|||
#define USB_REQ_GET_CONFIGURATION 0x08U |
|||
#define USB_REQ_SET_CONFIGURATION 0x09U |
|||
#define USB_REQ_GET_INTERFACE 0x0AU |
|||
#define USB_REQ_SET_INTERFACE 0x0BU |
|||
#define USB_REQ_SYNCH_FRAME 0x0CU |
|||
|
|||
#define USB_DESC_TYPE_DEVICE 0x01U |
|||
#define USB_DESC_TYPE_CONFIGURATION 0x02U |
|||
#define USB_DESC_TYPE_STRING 0x03U |
|||
#define USB_DESC_TYPE_INTERFACE 0x04U |
|||
#define USB_DESC_TYPE_ENDPOINT 0x05U |
|||
#define USB_DESC_TYPE_DEVICE_QUALIFIER 0x06U |
|||
#define USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION 0x07U |
|||
#define USB_DESC_TYPE_IAD 0x0BU |
|||
#define USB_DESC_TYPE_BOS 0x0FU |
|||
|
|||
#define USB_CONFIG_REMOTE_WAKEUP 0x02U |
|||
#define USB_CONFIG_SELF_POWERED 0x01U |
|||
|
|||
#define USB_FEATURE_EP_HALT 0x00U |
|||
#define USB_FEATURE_REMOTE_WAKEUP 0x01U |
|||
#define USB_FEATURE_TEST_MODE 0x02U |
|||
|
|||
#define USB_DEVICE_CAPABITY_TYPE 0x10U |
|||
|
|||
#define USB_CONF_DESC_SIZE 0x09U |
|||
#define USB_IF_DESC_SIZE 0x09U |
|||
#define USB_EP_DESC_SIZE 0x07U |
|||
#define USB_IAD_DESC_SIZE 0x08U |
|||
|
|||
#define USB_HS_MAX_PACKET_SIZE 512U |
|||
#define USB_FS_MAX_PACKET_SIZE 64U |
|||
#define USB_MAX_EP0_SIZE 64U |
|||
|
|||
/* Device Status */ |
|||
#define USBD_STATE_DEFAULT 0x01U |
|||
#define USBD_STATE_ADDRESSED 0x02U |
|||
#define USBD_STATE_CONFIGURED 0x03U |
|||
#define USBD_STATE_SUSPENDED 0x04U |
|||
|
|||
|
|||
/* EP0 State */ |
|||
#define USBD_EP0_IDLE 0x00U |
|||
#define USBD_EP0_SETUP 0x01U |
|||
#define USBD_EP0_DATA_IN 0x02U |
|||
#define USBD_EP0_DATA_OUT 0x03U |
|||
#define USBD_EP0_STATUS_IN 0x04U |
|||
#define USBD_EP0_STATUS_OUT 0x05U |
|||
#define USBD_EP0_STALL 0x06U |
|||
|
|||
#define USBD_EP_TYPE_CTRL 0x00U |
|||
#define USBD_EP_TYPE_ISOC 0x01U |
|||
#define USBD_EP_TYPE_BULK 0x02U |
|||
#define USBD_EP_TYPE_INTR 0x03U |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
|
|||
/** @defgroup USBD_DEF_Exported_TypesDefinitions
|
|||
* @{ |
|||
*/ |
|||
|
|||
typedef struct usb_setup_req |
|||
{ |
|||
uint8_t bmRequest; |
|||
uint8_t bRequest; |
|||
uint16_t wValue; |
|||
uint16_t wIndex; |
|||
uint16_t wLength; |
|||
} USBD_SetupReqTypedef; |
|||
|
|||
typedef struct |
|||
{ |
|||
uint8_t bLength; |
|||
uint8_t bDescriptorType; |
|||
uint16_t wTotalLength; |
|||
uint8_t bNumInterfaces; |
|||
uint8_t bConfigurationValue; |
|||
uint8_t iConfiguration; |
|||
uint8_t bmAttributes; |
|||
uint8_t bMaxPower; |
|||
} USBD_ConfigDescTypedef; |
|||
|
|||
typedef struct |
|||
{ |
|||
uint8_t bLength; |
|||
uint8_t bDescriptorType; |
|||
uint16_t wTotalLength; |
|||
uint8_t bNumDeviceCaps; |
|||
} USBD_BosDescTypedef; |
|||
|
|||
typedef struct |
|||
{ |
|||
uint8_t bLength; |
|||
uint8_t bDescriptorType; |
|||
uint8_t bEndpointAddress; |
|||
uint8_t bmAttributes; |
|||
uint16_t wMaxPacketSize; |
|||
uint8_t bInterval; |
|||
} USBD_EpDescTypedef; |
|||
|
|||
struct _USBD_HandleTypeDef; |
|||
|
|||
typedef struct _Device_cb |
|||
{ |
|||
uint8_t (*Init)(struct _USBD_HandleTypeDef *pdev, uint8_t cfgidx); |
|||
uint8_t (*DeInit)(struct _USBD_HandleTypeDef *pdev, uint8_t cfgidx); |
|||
/* Control Endpoints*/ |
|||
uint8_t (*Setup)(struct _USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); |
|||
uint8_t (*EP0_TxSent)(struct _USBD_HandleTypeDef *pdev); |
|||
uint8_t (*EP0_RxReady)(struct _USBD_HandleTypeDef *pdev); |
|||
/* Class Specific Endpoints*/ |
|||
uint8_t (*DataIn)(struct _USBD_HandleTypeDef *pdev, uint8_t epnum); |
|||
uint8_t (*DataOut)(struct _USBD_HandleTypeDef *pdev, uint8_t epnum); |
|||
uint8_t (*SOF)(struct _USBD_HandleTypeDef *pdev); |
|||
uint8_t (*IsoINIncomplete)(struct _USBD_HandleTypeDef *pdev, uint8_t epnum); |
|||
uint8_t (*IsoOUTIncomplete)(struct _USBD_HandleTypeDef *pdev, uint8_t epnum); |
|||
|
|||
uint8_t *(*GetHSConfigDescriptor)(uint16_t *length); |
|||
uint8_t *(*GetFSConfigDescriptor)(uint16_t *length); |
|||
uint8_t *(*GetOtherSpeedConfigDescriptor)(uint16_t *length); |
|||
uint8_t *(*GetDeviceQualifierDescriptor)(uint16_t *length); |
|||
#if (USBD_SUPPORT_USER_STRING_DESC == 1U) |
|||
uint8_t *(*GetUsrStrDescriptor)(struct _USBD_HandleTypeDef *pdev, uint8_t index, uint16_t *length); |
|||
#endif |
|||
|
|||
} USBD_ClassTypeDef; |
|||
|
|||
/* Following USB Device Speed */ |
|||
typedef enum |
|||
{ |
|||
USBD_SPEED_HIGH = 0U, |
|||
USBD_SPEED_FULL = 1U, |
|||
USBD_SPEED_LOW = 2U, |
|||
} USBD_SpeedTypeDef; |
|||
|
|||
/* Following USB Device status */ |
|||
typedef enum |
|||
{ |
|||
USBD_OK = 0U, |
|||
USBD_BUSY, |
|||
USBD_EMEM, |
|||
USBD_FAIL, |
|||
} USBD_StatusTypeDef; |
|||
|
|||
/* USB Device descriptors structure */ |
|||
typedef struct |
|||
{ |
|||
uint8_t *(*GetDeviceDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); |
|||
uint8_t *(*GetLangIDStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); |
|||
uint8_t *(*GetManufacturerStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); |
|||
uint8_t *(*GetProductStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); |
|||
uint8_t *(*GetSerialStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); |
|||
uint8_t *(*GetConfigurationStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); |
|||
uint8_t *(*GetInterfaceStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); |
|||
#if (USBD_CLASS_USER_STRING_DESC == 1) |
|||
uint8_t *(*GetUserStrDescriptor)(USBD_SpeedTypeDef speed, uint8_t idx, uint16_t *length); |
|||
#endif |
|||
#if ((USBD_LPM_ENABLED == 1U) || (USBD_CLASS_BOS_ENABLED == 1)) |
|||
uint8_t *(*GetBOSDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); |
|||
#endif |
|||
} USBD_DescriptorsTypeDef; |
|||
|
|||
/* USB Device handle structure */ |
|||
typedef struct |
|||
{ |
|||
uint32_t status; |
|||
uint32_t total_length; |
|||
uint32_t rem_length; |
|||
uint32_t maxpacket; |
|||
uint16_t is_used; |
|||
uint16_t bInterval; |
|||
} USBD_EndpointTypeDef; |
|||
|
|||
/* USB Device handle structure */ |
|||
typedef struct _USBD_HandleTypeDef |
|||
{ |
|||
uint8_t id; |
|||
uint32_t dev_config; |
|||
uint32_t dev_default_config; |
|||
uint32_t dev_config_status; |
|||
USBD_SpeedTypeDef dev_speed; |
|||
USBD_EndpointTypeDef ep_in[16]; |
|||
USBD_EndpointTypeDef ep_out[16]; |
|||
__IO uint32_t ep0_state; |
|||
uint32_t ep0_data_len; |
|||
__IO uint8_t dev_state; |
|||
__IO uint8_t dev_old_state; |
|||
uint8_t dev_address; |
|||
uint8_t dev_connection_status; |
|||
uint8_t dev_test_mode; |
|||
uint32_t dev_remote_wakeup; |
|||
uint8_t ConfIdx; |
|||
|
|||
USBD_SetupReqTypedef request; |
|||
USBD_DescriptorsTypeDef *pDesc; |
|||
USBD_ClassTypeDef *pClass; |
|||
void *pClassData; |
|||
void *pUserData; |
|||
void *pData; |
|||
void *pBosDesc; |
|||
void *pConfDesc; |
|||
} USBD_HandleTypeDef; |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
|
|||
|
|||
/** @defgroup USBD_DEF_Exported_Macros
|
|||
* @{ |
|||
*/ |
|||
__STATIC_INLINE uint16_t SWAPBYTE(uint8_t *addr) |
|||
{ |
|||
uint16_t _SwapVal, _Byte1, _Byte2; |
|||
uint8_t *_pbuff = addr; |
|||
|
|||
_Byte1 = *(uint8_t *)_pbuff; |
|||
_pbuff++; |
|||
_Byte2 = *(uint8_t *)_pbuff; |
|||
|
|||
_SwapVal = (_Byte2 << 8) | _Byte1; |
|||
|
|||
return _SwapVal; |
|||
} |
|||
|
|||
#ifndef LOBYTE |
|||
#define LOBYTE(x) ((uint8_t)((x) & 0x00FFU)) |
|||
#endif |
|||
|
|||
#ifndef HIBYTE |
|||
#define HIBYTE(x) ((uint8_t)(((x) & 0xFF00U) >> 8U)) |
|||
#endif |
|||
|
|||
#ifndef MIN |
|||
#define MIN(a, b) (((a) < (b)) ? (a) : (b)) |
|||
#endif |
|||
|
|||
#ifndef MAX |
|||
#define MAX(a, b) (((a) > (b)) ? (a) : (b)) |
|||
#endif |
|||
|
|||
#if defined ( __GNUC__ ) |
|||
#ifndef __weak |
|||
#define __weak __attribute__((weak)) |
|||
#endif /* __weak */ |
|||
#ifndef __packed |
|||
#define __packed __attribute__((__packed__)) |
|||
#endif /* __packed */ |
|||
#endif /* __GNUC__ */ |
|||
|
|||
|
|||
/* In HS mode and when the DMA is used, all variables and data structures dealing
|
|||
with the DMA during the transaction process should be 4-bytes aligned */ |
|||
|
|||
#if defined ( __GNUC__ ) && !defined (__CC_ARM) /* GNU Compiler */ |
|||
#ifndef __ALIGN_END |
|||
#define __ALIGN_END __attribute__ ((aligned (4U))) |
|||
#endif /* __ALIGN_END */ |
|||
#ifndef __ALIGN_BEGIN |
|||
#define __ALIGN_BEGIN |
|||
#endif /* __ALIGN_BEGIN */ |
|||
#else |
|||
#ifndef __ALIGN_END |
|||
#define __ALIGN_END |
|||
#endif /* __ALIGN_END */ |
|||
#ifndef __ALIGN_BEGIN |
|||
#if defined (__CC_ARM) /* ARM Compiler */ |
|||
#define __ALIGN_BEGIN __align(4U) |
|||
#elif defined (__ICCARM__) /* IAR Compiler */ |
|||
#define __ALIGN_BEGIN |
|||
#endif /* __CC_ARM */ |
|||
#endif /* __ALIGN_BEGIN */ |
|||
#endif /* __GNUC__ */ |
|||
|
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/** @defgroup USBD_DEF_Exported_Variables
|
|||
* @{ |
|||
*/ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/** @defgroup USBD_DEF_Exported_FunctionsPrototype
|
|||
* @{ |
|||
*/ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
#ifdef __cplusplus |
|||
} |
|||
#endif |
|||
|
|||
#endif /* __USBD_DEF_H */ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
|||
@ -0,0 +1,114 @@ |
|||
/**
|
|||
****************************************************************************** |
|||
* @file usbd_ioreq.h |
|||
* @author MCD Application Team |
|||
* @brief Header file for the usbd_ioreq.c file |
|||
****************************************************************************** |
|||
* @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: |
|||
* www.st.com/SLA0044 |
|||
* |
|||
****************************************************************************** |
|||
*/ |
|||
|
|||
/* Define to prevent recursive inclusion -------------------------------------*/ |
|||
#ifndef __USBD_IOREQ_H |
|||
#define __USBD_IOREQ_H |
|||
|
|||
#ifdef __cplusplus |
|||
extern "C" { |
|||
#endif |
|||
|
|||
/* Includes ------------------------------------------------------------------*/ |
|||
#include "usbd_def.h" |
|||
#include "usbd_core.h" |
|||
|
|||
/** @addtogroup STM32_USB_DEVICE_LIBRARY
|
|||
* @{ |
|||
*/ |
|||
|
|||
/** @defgroup USBD_IOREQ
|
|||
* @brief header file for the usbd_ioreq.c file |
|||
* @{ |
|||
*/ |
|||
|
|||
/** @defgroup USBD_IOREQ_Exported_Defines
|
|||
* @{ |
|||
*/ |
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
|
|||
/** @defgroup USBD_IOREQ_Exported_Types
|
|||
* @{ |
|||
*/ |
|||
|
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
|
|||
|
|||
/** @defgroup USBD_IOREQ_Exported_Macros
|
|||
* @{ |
|||
*/ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/** @defgroup USBD_IOREQ_Exported_Variables
|
|||
* @{ |
|||
*/ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/** @defgroup USBD_IOREQ_Exported_FunctionsPrototype
|
|||
* @{ |
|||
*/ |
|||
|
|||
USBD_StatusTypeDef USBD_CtlSendData(USBD_HandleTypeDef *pdev, |
|||
uint8_t *pbuf, uint32_t len); |
|||
|
|||
USBD_StatusTypeDef USBD_CtlContinueSendData(USBD_HandleTypeDef *pdev, |
|||
uint8_t *pbuf, uint32_t len); |
|||
|
|||
USBD_StatusTypeDef USBD_CtlPrepareRx(USBD_HandleTypeDef *pdev, |
|||
uint8_t *pbuf, uint32_t len); |
|||
|
|||
USBD_StatusTypeDef USBD_CtlContinueRx(USBD_HandleTypeDef *pdev, |
|||
uint8_t *pbuf, uint32_t len); |
|||
|
|||
USBD_StatusTypeDef USBD_CtlSendStatus(USBD_HandleTypeDef *pdev); |
|||
USBD_StatusTypeDef USBD_CtlReceiveStatus(USBD_HandleTypeDef *pdev); |
|||
|
|||
uint32_t USBD_GetRxCount(USBD_HandleTypeDef *pdev, uint8_t ep_addr); |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
#ifdef __cplusplus |
|||
} |
|||
#endif |
|||
|
|||
#endif /* __USBD_IOREQ_H */ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
|||
@ -0,0 +1,694 @@ |
|||
/**
|
|||
****************************************************************************** |
|||
* @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: |
|||
* 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) |
|||
{ |
|||
USBD_StatusTypeDef ret; |
|||
|
|||
/* 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 resources */ |
|||
pdev->pClass = NULL; |
|||
pdev->pUserData = NULL; |
|||
pdev->pConfDesc = 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 */ |
|||
ret = USBD_LL_Init(pdev); |
|||
|
|||
return ret; |
|||
} |
|||
|
|||
/**
|
|||
* @brief USBD_DeInit |
|||
* Re-Initialize the device library |
|||
* @param pdev: device instance |
|||
* @retval status: status |
|||
*/ |
|||
USBD_StatusTypeDef USBD_DeInit(USBD_HandleTypeDef *pdev) |
|||
{ |
|||
USBD_StatusTypeDef ret; |
|||
|
|||
/* Disconnect the USB Device */ |
|||
(void)USBD_LL_Stop(pdev); |
|||
|
|||
/* Set Default State */ |
|||
pdev->dev_state = USBD_STATE_DEFAULT; |
|||
|
|||
/* Free Class Resources */ |
|||
if (pdev->pClass != NULL) |
|||
{ |
|||
pdev->pClass->DeInit(pdev, (uint8_t)pdev->dev_config); |
|||
pdev->pClass = NULL; |
|||
pdev->pUserData = NULL; |
|||
} |
|||
|
|||
/* Free Device descriptors resources */ |
|||
pdev->pDesc = NULL; |
|||
pdev->pConfDesc = NULL; |
|||
|
|||
/* DeInitialize low level driver */ |
|||
ret = USBD_LL_DeInit(pdev); |
|||
|
|||
return ret; |
|||
} |
|||
|
|||
/**
|
|||
* @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) |
|||
{ |
|||
uint16_t len = 0U; |
|||
|
|||
if (pclass == NULL) |
|||
{ |
|||
#if (USBD_DEBUG_LEVEL > 1U) |
|||
USBD_ErrLog("Invalid Class handle"); |
|||
#endif |
|||
return USBD_FAIL; |
|||
} |
|||
|
|||
/* link the class to the USB Device handle */ |
|||
pdev->pClass = pclass; |
|||
|
|||
/* Get Device Configuration Descriptor */ |
|||
#ifdef USE_USB_HS |
|||
if (pdev->pClass->GetHSConfigDescriptor != NULL) |
|||
{ |
|||
pdev->pConfDesc = (void *)pdev->pClass->GetHSConfigDescriptor(&len); |
|||
} |
|||
#else /* Default USE_USB_FS */ |
|||
if (pdev->pClass->GetFSConfigDescriptor != NULL) |
|||
{ |
|||
pdev->pConfDesc = (void *)pdev->pClass->GetFSConfigDescriptor(&len); |
|||
} |
|||
#endif /* USE_USB_FS */ |
|||
|
|||
return USBD_OK; |
|||
} |
|||
|
|||
/**
|
|||
* @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 */ |
|||
return USBD_LL_Start(pdev); |
|||
} |
|||
|
|||
/**
|
|||
* @brief USBD_Stop |
|||
* Stop the USB Device Core. |
|||
* @param pdev: Device Handle |
|||
* @retval USBD Status |
|||
*/ |
|||
USBD_StatusTypeDef USBD_Stop(USBD_HandleTypeDef *pdev) |
|||
{ |
|||
/* Disconnect USB Device */ |
|||
(void)USBD_LL_Stop(pdev); |
|||
|
|||
/* Free Class Resources */ |
|||
if (pdev->pClass != NULL) |
|||
{ |
|||
(void)pdev->pClass->DeInit(pdev, (uint8_t)pdev->dev_config); |
|||
} |
|||
|
|||
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 */ |
|||
ret = (USBD_StatusTypeDef)pdev->pClass->Init(pdev, cfgidx); |
|||
} |
|||
|
|||
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 */ |
|||
if (pdev->pClass != NULL) |
|||
{ |
|||
pdev->pClass->DeInit(pdev, cfgidx); |
|||
} |
|||
|
|||
return USBD_OK; |
|||
} |
|||
|
|||
|
|||
/**
|
|||
* @brief USBD_LL_SetupStage |
|||
* Handle the setup stage |
|||
* @param pdev: device instance |
|||
* @retval status |
|||
*/ |
|||
USBD_StatusTypeDef USBD_LL_SetupStage(USBD_HandleTypeDef *pdev, uint8_t *psetup) |
|||
{ |
|||
USBD_StatusTypeDef ret; |
|||
|
|||
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: |
|||
ret = USBD_StdDevReq(pdev, &pdev->request); |
|||
break; |
|||
|
|||
case USB_REQ_RECIPIENT_INTERFACE: |
|||
ret = USBD_StdItfReq(pdev, &pdev->request); |
|||
break; |
|||
|
|||
case USB_REQ_RECIPIENT_ENDPOINT: |
|||
ret = USBD_StdEPReq(pdev, &pdev->request); |
|||
break; |
|||
|
|||
default: |
|||
ret = USBD_LL_StallEP(pdev, (pdev->request.bmRequest & 0x80U)); |
|||
break; |
|||
} |
|||
|
|||
return ret; |
|||
} |
|||
|
|||
/**
|
|||
* @brief USBD_LL_DataOutStage |
|||
* Handle data OUT stage |
|||
* @param pdev: device instance |
|||
* @param epnum: endpoint index |
|||
* @param pdata: data pointer |
|||
* @retval status |
|||
*/ |
|||
USBD_StatusTypeDef USBD_LL_DataOutStage(USBD_HandleTypeDef *pdev, |
|||
uint8_t epnum, uint8_t *pdata) |
|||
{ |
|||
USBD_EndpointTypeDef *pep; |
|||
USBD_StatusTypeDef ret; |
|||
|
|||
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; |
|||
|
|||
(void)USBD_CtlContinueRx(pdev, pdata, MIN(pep->rem_length, pep->maxpacket)); |
|||
} |
|||
else |
|||
{ |
|||
if (pdev->dev_state == USBD_STATE_CONFIGURED) |
|||
{ |
|||
if (pdev->pClass->EP0_RxReady != NULL) |
|||
{ |
|||
pdev->pClass->EP0_RxReady(pdev); |
|||
} |
|||
} |
|||
|
|||
(void)USBD_CtlSendStatus(pdev); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
#if 0 |
|||
if (pdev->ep0_state == USBD_EP0_STATUS_OUT) |
|||
{ |
|||
/*
|
|||
* STATUS PHASE completed, update ep0_state to idle |
|||
*/ |
|||
pdev->ep0_state = USBD_EP0_IDLE; |
|||
(void)USBD_LL_StallEP(pdev, 0U); |
|||
} |
|||
#endif |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
if (pdev->dev_state == USBD_STATE_CONFIGURED) |
|||
{ |
|||
if (pdev->pClass->DataOut != NULL) |
|||
{ |
|||
ret = (USBD_StatusTypeDef)pdev->pClass->DataOut(pdev, epnum); |
|||
|
|||
if (ret != USBD_OK) |
|||
{ |
|||
return ret; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
return USBD_OK; |
|||
} |
|||
|
|||
/**
|
|||
* @brief USBD_LL_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; |
|||
USBD_StatusTypeDef ret; |
|||
|
|||
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; |
|||
|
|||
(void)USBD_CtlContinueSendData(pdev, pdata, pep->rem_length); |
|||
|
|||
/* Prepare endpoint for premature end of transfer */ |
|||
(void)USBD_LL_PrepareReceive(pdev, 0U, NULL, 0U); |
|||
} |
|||
else |
|||
{ |
|||
/* last packet is MPS multiple, so send ZLP packet */ |
|||
if ((pep->maxpacket == pep->rem_length) && |
|||
(pep->total_length >= pep->maxpacket) && |
|||
(pep->total_length < pdev->ep0_data_len)) |
|||
{ |
|||
(void)USBD_CtlContinueSendData(pdev, NULL, 0U); |
|||
pdev->ep0_data_len = 0U; |
|||
|
|||
/* Prepare endpoint for premature end of transfer */ |
|||
(void)USBD_LL_PrepareReceive(pdev, 0U, NULL, 0U); |
|||
} |
|||
else |
|||
{ |
|||
if (pdev->dev_state == USBD_STATE_CONFIGURED) |
|||
{ |
|||
if (pdev->pClass->EP0_TxSent != NULL) |
|||
{ |
|||
pdev->pClass->EP0_TxSent(pdev); |
|||
} |
|||
} |
|||
(void)USBD_LL_StallEP(pdev, 0x80U); |
|||
(void)USBD_CtlReceiveStatus(pdev); |
|||
} |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
#if 0 |
|||
if ((pdev->ep0_state == USBD_EP0_STATUS_IN) || |
|||
(pdev->ep0_state == USBD_EP0_IDLE)) |
|||
{ |
|||
(void)USBD_LL_StallEP(pdev, 0x80U); |
|||
} |
|||
#endif |
|||
} |
|||
|
|||
if (pdev->dev_test_mode == 1U) |
|||
{ |
|||
(void)USBD_RunTestMode(pdev); |
|||
pdev->dev_test_mode = 0U; |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
if (pdev->dev_state == USBD_STATE_CONFIGURED) |
|||
{ |
|||
if (pdev->pClass->DataIn != NULL) |
|||
{ |
|||
ret = (USBD_StatusTypeDef)pdev->pClass->DataIn(pdev, epnum); |
|||
|
|||
if (ret != USBD_OK) |
|||
{ |
|||
return ret; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
return USBD_OK; |
|||
} |
|||
|
|||
/**
|
|||
* @brief USBD_LL_Reset |
|||
* Handle Reset event |
|||
* @param pdev: device instance |
|||
* @retval status |
|||
*/ |
|||
|
|||
USBD_StatusTypeDef USBD_LL_Reset(USBD_HandleTypeDef *pdev) |
|||
{ |
|||
/* 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->pClass == NULL) |
|||
{ |
|||
return USBD_FAIL; |
|||
} |
|||
|
|||
if (pdev->pClassData != NULL) |
|||
{ |
|||
if (pdev->pClass->DeInit != NULL) |
|||
{ |
|||
(void)pdev->pClass->DeInit(pdev, (uint8_t)pdev->dev_config); |
|||
} |
|||
} |
|||
|
|||
/* Open EP0 OUT */ |
|||
(void)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 */ |
|||
(void)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; |
|||
|
|||
return USBD_OK; |
|||
} |
|||
|
|||
/**
|
|||
* @brief USBD_LL_SetSpeed |
|||
* 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_LL_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_LL_Resume |
|||
* Handle Resume event |
|||
* @param pdev: device instance |
|||
* @retval status |
|||
*/ |
|||
|
|||
USBD_StatusTypeDef USBD_LL_Resume(USBD_HandleTypeDef *pdev) |
|||
{ |
|||
if (pdev->dev_state == USBD_STATE_SUSPENDED) |
|||
{ |
|||
pdev->dev_state = pdev->dev_old_state; |
|||
} |
|||
|
|||
return USBD_OK; |
|||
} |
|||
|
|||
/**
|
|||
* @brief USBD_LL_SOF |
|||
* Handle SOF event |
|||
* @param pdev: device instance |
|||
* @retval status |
|||
*/ |
|||
|
|||
USBD_StatusTypeDef USBD_LL_SOF(USBD_HandleTypeDef *pdev) |
|||
{ |
|||
if (pdev->pClass == NULL) |
|||
{ |
|||
return USBD_FAIL; |
|||
} |
|||
|
|||
if (pdev->dev_state == USBD_STATE_CONFIGURED) |
|||
{ |
|||
if (pdev->pClass->SOF != NULL) |
|||
{ |
|||
(void)pdev->pClass->SOF(pdev); |
|||
} |
|||
} |
|||
|
|||
return USBD_OK; |
|||
} |
|||
|
|||
/**
|
|||
* @brief USBD_LL_IsoINIncomplete |
|||
* Handle iso in incomplete event |
|||
* @param pdev: device instance |
|||
* @retval status |
|||
*/ |
|||
USBD_StatusTypeDef USBD_LL_IsoINIncomplete(USBD_HandleTypeDef *pdev, |
|||
uint8_t epnum) |
|||
{ |
|||
if (pdev->pClass == NULL) |
|||
{ |
|||
return USBD_FAIL; |
|||
} |
|||
|
|||
if (pdev->dev_state == USBD_STATE_CONFIGURED) |
|||
{ |
|||
if (pdev->pClass->IsoINIncomplete != NULL) |
|||
{ |
|||
(void)pdev->pClass->IsoINIncomplete(pdev, epnum); |
|||
} |
|||
} |
|||
|
|||
return USBD_OK; |
|||
} |
|||
|
|||
/**
|
|||
* @brief USBD_LL_IsoOUTIncomplete |
|||
* Handle iso out incomplete event |
|||
* @param pdev: device instance |
|||
* @retval status |
|||
*/ |
|||
USBD_StatusTypeDef USBD_LL_IsoOUTIncomplete(USBD_HandleTypeDef *pdev, |
|||
uint8_t epnum) |
|||
{ |
|||
if (pdev->pClass == NULL) |
|||
{ |
|||
return USBD_FAIL; |
|||
} |
|||
|
|||
if (pdev->dev_state == USBD_STATE_CONFIGURED) |
|||
{ |
|||
if (pdev->pClass->IsoOUTIncomplete != NULL) |
|||
{ |
|||
(void)pdev->pClass->IsoOUTIncomplete(pdev, epnum); |
|||
} |
|||
} |
|||
|
|||
return USBD_OK; |
|||
} |
|||
|
|||
/**
|
|||
* @brief USBD_LL_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_LL_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; |
|||
|
|||
if (pdev->pClass != NULL) |
|||
{ |
|||
(void)pdev->pClass->DeInit(pdev, (uint8_t)pdev->dev_config); |
|||
} |
|||
|
|||
return USBD_OK; |
|||
} |
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
|||
|
|||
@ -0,0 +1,948 @@ |
|||
/**
|
|||
****************************************************************************** |
|||
* @file usbd_req.c |
|||
* @author MCD Application Team |
|||
* @brief This file provides the standard USB requests following chapter 9. |
|||
****************************************************************************** |
|||
* @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: |
|||
* www.st.com/SLA0044 |
|||
* |
|||
****************************************************************************** |
|||
*/ |
|||
|
|||
/* Includes ------------------------------------------------------------------*/ |
|||
#include "usbd_ctlreq.h" |
|||
#include "usbd_ioreq.h" |
|||
|
|||
|
|||
/** @addtogroup STM32_USBD_STATE_DEVICE_LIBRARY
|
|||
* @{ |
|||
*/ |
|||
|
|||
|
|||
/** @defgroup USBD_REQ
|
|||
* @brief USB standard requests module |
|||
* @{ |
|||
*/ |
|||
|
|||
/** @defgroup USBD_REQ_Private_TypesDefinitions
|
|||
* @{ |
|||
*/ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
|
|||
/** @defgroup USBD_REQ_Private_Defines
|
|||
* @{ |
|||
*/ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
|
|||
/** @defgroup USBD_REQ_Private_Macros
|
|||
* @{ |
|||
*/ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
|
|||
/** @defgroup USBD_REQ_Private_Variables
|
|||
* @{ |
|||
*/ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
|
|||
/** @defgroup USBD_REQ_Private_FunctionPrototypes
|
|||
* @{ |
|||
*/ |
|||
static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); |
|||
static void USBD_SetAddress(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); |
|||
static USBD_StatusTypeDef USBD_SetConfig(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); |
|||
static void USBD_GetConfig(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); |
|||
static void USBD_GetStatus(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); |
|||
static void USBD_SetFeature(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); |
|||
static void USBD_ClrFeature(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); |
|||
static uint8_t USBD_GetLen(uint8_t *buf); |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
|
|||
/** @defgroup USBD_REQ_Private_Functions
|
|||
* @{ |
|||
*/ |
|||
|
|||
|
|||
/**
|
|||
* @brief USBD_StdDevReq |
|||
* Handle standard usb device requests |
|||
* @param pdev: device instance |
|||
* @param req: usb request |
|||
* @retval status |
|||
*/ |
|||
USBD_StatusTypeDef USBD_StdDevReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) |
|||
{ |
|||
USBD_StatusTypeDef ret = USBD_OK; |
|||
|
|||
switch (req->bmRequest & USB_REQ_TYPE_MASK) |
|||
{ |
|||
case USB_REQ_TYPE_CLASS: |
|||
case USB_REQ_TYPE_VENDOR: |
|||
ret = (USBD_StatusTypeDef)pdev->pClass->Setup(pdev, req); |
|||
break; |
|||
|
|||
case USB_REQ_TYPE_STANDARD: |
|||
switch (req->bRequest) |
|||
{ |
|||
case USB_REQ_GET_DESCRIPTOR: |
|||
USBD_GetDescriptor(pdev, req); |
|||
break; |
|||
|
|||
case USB_REQ_SET_ADDRESS: |
|||
USBD_SetAddress(pdev, req); |
|||
break; |
|||
|
|||
case USB_REQ_SET_CONFIGURATION: |
|||
ret = USBD_SetConfig(pdev, req); |
|||
break; |
|||
|
|||
case USB_REQ_GET_CONFIGURATION: |
|||
USBD_GetConfig(pdev, req); |
|||
break; |
|||
|
|||
case USB_REQ_GET_STATUS: |
|||
USBD_GetStatus(pdev, req); |
|||
break; |
|||
|
|||
case USB_REQ_SET_FEATURE: |
|||
USBD_SetFeature(pdev, req); |
|||
break; |
|||
|
|||
case USB_REQ_CLEAR_FEATURE: |
|||
USBD_ClrFeature(pdev, req); |
|||
break; |
|||
|
|||
default: |
|||
USBD_CtlError(pdev, req); |
|||
break; |
|||
} |
|||
break; |
|||
|
|||
default: |
|||
USBD_CtlError(pdev, req); |
|||
break; |
|||
} |
|||
|
|||
return ret; |
|||
} |
|||
|
|||
/**
|
|||
* @brief USBD_StdItfReq |
|||
* Handle standard usb interface requests |
|||
* @param pdev: device instance |
|||
* @param req: usb request |
|||
* @retval status |
|||
*/ |
|||
USBD_StatusTypeDef USBD_StdItfReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) |
|||
{ |
|||
USBD_StatusTypeDef ret = USBD_OK; |
|||
|
|||
switch (req->bmRequest & USB_REQ_TYPE_MASK) |
|||
{ |
|||
case USB_REQ_TYPE_CLASS: |
|||
case USB_REQ_TYPE_VENDOR: |
|||
case USB_REQ_TYPE_STANDARD: |
|||
switch (pdev->dev_state) |
|||
{ |
|||
case USBD_STATE_DEFAULT: |
|||
case USBD_STATE_ADDRESSED: |
|||
case USBD_STATE_CONFIGURED: |
|||
|
|||
if (LOBYTE(req->wIndex) <= USBD_MAX_NUM_INTERFACES) |
|||
{ |
|||
ret = (USBD_StatusTypeDef)pdev->pClass->Setup(pdev, req); |
|||
|
|||
if ((req->wLength == 0U) && (ret == USBD_OK)) |
|||
{ |
|||
(void)USBD_CtlSendStatus(pdev); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
USBD_CtlError(pdev, req); |
|||
} |
|||
break; |
|||
|
|||
default: |
|||
USBD_CtlError(pdev, req); |
|||
break; |
|||
} |
|||
break; |
|||
|
|||
default: |
|||
USBD_CtlError(pdev, req); |
|||
break; |
|||
} |
|||
|
|||
return ret; |
|||
} |
|||
|
|||
/**
|
|||
* @brief USBD_StdEPReq |
|||
* Handle standard usb endpoint requests |
|||
* @param pdev: device instance |
|||
* @param req: usb request |
|||
* @retval status |
|||
*/ |
|||
USBD_StatusTypeDef USBD_StdEPReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) |
|||
{ |
|||
USBD_EndpointTypeDef *pep; |
|||
uint8_t ep_addr; |
|||
USBD_StatusTypeDef ret = USBD_OK; |
|||
ep_addr = LOBYTE(req->wIndex); |
|||
|
|||
switch (req->bmRequest & USB_REQ_TYPE_MASK) |
|||
{ |
|||
case USB_REQ_TYPE_CLASS: |
|||
case USB_REQ_TYPE_VENDOR: |
|||
ret = (USBD_StatusTypeDef)pdev->pClass->Setup(pdev, req); |
|||
break; |
|||
|
|||
case USB_REQ_TYPE_STANDARD: |
|||
switch (req->bRequest) |
|||
{ |
|||
case USB_REQ_SET_FEATURE: |
|||
switch (pdev->dev_state) |
|||
{ |
|||
case USBD_STATE_ADDRESSED: |
|||
if ((ep_addr != 0x00U) && (ep_addr != 0x80U)) |
|||
{ |
|||
(void)USBD_LL_StallEP(pdev, ep_addr); |
|||
(void)USBD_LL_StallEP(pdev, 0x80U); |
|||
} |
|||
else |
|||
{ |
|||
USBD_CtlError(pdev, req); |
|||
} |
|||
break; |
|||
|
|||
case USBD_STATE_CONFIGURED: |
|||
if (req->wValue == USB_FEATURE_EP_HALT) |
|||
{ |
|||
if ((ep_addr != 0x00U) && (ep_addr != 0x80U) && (req->wLength == 0x00U)) |
|||
{ |
|||
(void)USBD_LL_StallEP(pdev, ep_addr); |
|||
} |
|||
} |
|||
(void)USBD_CtlSendStatus(pdev); |
|||
|
|||
break; |
|||
|
|||
default: |
|||
USBD_CtlError(pdev, req); |
|||
break; |
|||
} |
|||
break; |
|||
|
|||
case USB_REQ_CLEAR_FEATURE: |
|||
|
|||
switch (pdev->dev_state) |
|||
{ |
|||
case USBD_STATE_ADDRESSED: |
|||
if ((ep_addr != 0x00U) && (ep_addr != 0x80U)) |
|||
{ |
|||
(void)USBD_LL_StallEP(pdev, ep_addr); |
|||
(void)USBD_LL_StallEP(pdev, 0x80U); |
|||
} |
|||
else |
|||
{ |
|||
USBD_CtlError(pdev, req); |
|||
} |
|||
break; |
|||
|
|||
case USBD_STATE_CONFIGURED: |
|||
if (req->wValue == USB_FEATURE_EP_HALT) |
|||
{ |
|||
if ((ep_addr & 0x7FU) != 0x00U) |
|||
{ |
|||
(void)USBD_LL_ClearStallEP(pdev, ep_addr); |
|||
} |
|||
(void)USBD_CtlSendStatus(pdev); |
|||
ret = (USBD_StatusTypeDef)pdev->pClass->Setup(pdev, req); |
|||
} |
|||
break; |
|||
|
|||
default: |
|||
USBD_CtlError(pdev, req); |
|||
break; |
|||
} |
|||
break; |
|||
|
|||
case USB_REQ_GET_STATUS: |
|||
switch (pdev->dev_state) |
|||
{ |
|||
case USBD_STATE_ADDRESSED: |
|||
if ((ep_addr != 0x00U) && (ep_addr != 0x80U)) |
|||
{ |
|||
USBD_CtlError(pdev, req); |
|||
break; |
|||
} |
|||
pep = ((ep_addr & 0x80U) == 0x80U) ? &pdev->ep_in[ep_addr & 0x7FU] : \ |
|||
&pdev->ep_out[ep_addr & 0x7FU]; |
|||
|
|||
pep->status = 0x0000U; |
|||
|
|||
(void)USBD_CtlSendData(pdev, (uint8_t *)&pep->status, 2U); |
|||
break; |
|||
|
|||
case USBD_STATE_CONFIGURED: |
|||
if ((ep_addr & 0x80U) == 0x80U) |
|||
{ |
|||
if (pdev->ep_in[ep_addr & 0xFU].is_used == 0U) |
|||
{ |
|||
USBD_CtlError(pdev, req); |
|||
break; |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
if (pdev->ep_out[ep_addr & 0xFU].is_used == 0U) |
|||
{ |
|||
USBD_CtlError(pdev, req); |
|||
break; |
|||
} |
|||
} |
|||
|
|||
pep = ((ep_addr & 0x80U) == 0x80U) ? &pdev->ep_in[ep_addr & 0x7FU] : \ |
|||
&pdev->ep_out[ep_addr & 0x7FU]; |
|||
|
|||
if ((ep_addr == 0x00U) || (ep_addr == 0x80U)) |
|||
{ |
|||
pep->status = 0x0000U; |
|||
} |
|||
else if (USBD_LL_IsStallEP(pdev, ep_addr) != 0U) |
|||
{ |
|||
pep->status = 0x0001U; |
|||
} |
|||
else |
|||
{ |
|||
pep->status = 0x0000U; |
|||
} |
|||
|
|||
(void)USBD_CtlSendData(pdev, (uint8_t *)&pep->status, 2U); |
|||
break; |
|||
|
|||
default: |
|||
USBD_CtlError(pdev, req); |
|||
break; |
|||
} |
|||
break; |
|||
|
|||
default: |
|||
USBD_CtlError(pdev, req); |
|||
break; |
|||
} |
|||
break; |
|||
|
|||
default: |
|||
USBD_CtlError(pdev, req); |
|||
break; |
|||
} |
|||
|
|||
return ret; |
|||
} |
|||
|
|||
|
|||
/**
|
|||
* @brief USBD_GetDescriptor |
|||
* Handle Get Descriptor requests |
|||
* @param pdev: device instance |
|||
* @param req: usb request |
|||
* @retval status |
|||
*/ |
|||
static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) |
|||
{ |
|||
uint16_t len = 0U; |
|||
uint8_t *pbuf = NULL; |
|||
uint8_t err = 0U; |
|||
|
|||
switch (req->wValue >> 8) |
|||
{ |
|||
#if ((USBD_LPM_ENABLED == 1U) || (USBD_CLASS_BOS_ENABLED == 1U)) |
|||
case USB_DESC_TYPE_BOS: |
|||
if (pdev->pDesc->GetBOSDescriptor != NULL) |
|||
{ |
|||
pbuf = pdev->pDesc->GetBOSDescriptor(pdev->dev_speed, &len); |
|||
} |
|||
else |
|||
{ |
|||
USBD_CtlError(pdev, req); |
|||
err++; |
|||
} |
|||
break; |
|||
#endif |
|||
case USB_DESC_TYPE_DEVICE: |
|||
pbuf = pdev->pDesc->GetDeviceDescriptor(pdev->dev_speed, &len); |
|||
break; |
|||
|
|||
case USB_DESC_TYPE_CONFIGURATION: |
|||
if (pdev->dev_speed == USBD_SPEED_HIGH) |
|||
{ |
|||
pbuf = pdev->pClass->GetHSConfigDescriptor(&len); |
|||
pbuf[1] = USB_DESC_TYPE_CONFIGURATION; |
|||
} |
|||
else |
|||
{ |
|||
pbuf = pdev->pClass->GetFSConfigDescriptor(&len); |
|||
pbuf[1] = USB_DESC_TYPE_CONFIGURATION; |
|||
} |
|||
break; |
|||
|
|||
case USB_DESC_TYPE_STRING: |
|||
switch ((uint8_t)(req->wValue)) |
|||
{ |
|||
case USBD_IDX_LANGID_STR: |
|||
if (pdev->pDesc->GetLangIDStrDescriptor != NULL) |
|||
{ |
|||
pbuf = pdev->pDesc->GetLangIDStrDescriptor(pdev->dev_speed, &len); |
|||
} |
|||
else |
|||
{ |
|||
USBD_CtlError(pdev, req); |
|||
err++; |
|||
} |
|||
break; |
|||
|
|||
case USBD_IDX_MFC_STR: |
|||
if (pdev->pDesc->GetManufacturerStrDescriptor != NULL) |
|||
{ |
|||
pbuf = pdev->pDesc->GetManufacturerStrDescriptor(pdev->dev_speed, &len); |
|||
} |
|||
else |
|||
{ |
|||
USBD_CtlError(pdev, req); |
|||
err++; |
|||
} |
|||
break; |
|||
|
|||
case USBD_IDX_PRODUCT_STR: |
|||
if (pdev->pDesc->GetProductStrDescriptor != NULL) |
|||
{ |
|||
pbuf = pdev->pDesc->GetProductStrDescriptor(pdev->dev_speed, &len); |
|||
} |
|||
else |
|||
{ |
|||
USBD_CtlError(pdev, req); |
|||
err++; |
|||
} |
|||
break; |
|||
|
|||
case USBD_IDX_SERIAL_STR: |
|||
if (pdev->pDesc->GetSerialStrDescriptor != NULL) |
|||
{ |
|||
pbuf = pdev->pDesc->GetSerialStrDescriptor(pdev->dev_speed, &len); |
|||
} |
|||
else |
|||
{ |
|||
USBD_CtlError(pdev, req); |
|||
err++; |
|||
} |
|||
break; |
|||
|
|||
case USBD_IDX_CONFIG_STR: |
|||
if (pdev->pDesc->GetConfigurationStrDescriptor != NULL) |
|||
{ |
|||
pbuf = pdev->pDesc->GetConfigurationStrDescriptor(pdev->dev_speed, &len); |
|||
} |
|||
else |
|||
{ |
|||
USBD_CtlError(pdev, req); |
|||
err++; |
|||
} |
|||
break; |
|||
|
|||
case USBD_IDX_INTERFACE_STR: |
|||
if (pdev->pDesc->GetInterfaceStrDescriptor != NULL) |
|||
{ |
|||
pbuf = pdev->pDesc->GetInterfaceStrDescriptor(pdev->dev_speed, &len); |
|||
} |
|||
else |
|||
{ |
|||
USBD_CtlError(pdev, req); |
|||
err++; |
|||
} |
|||
break; |
|||
|
|||
default: |
|||
#if (USBD_SUPPORT_USER_STRING_DESC == 1U) |
|||
if (pdev->pClass->GetUsrStrDescriptor != NULL) |
|||
{ |
|||
pbuf = pdev->pClass->GetUsrStrDescriptor(pdev, (req->wValue), &len); |
|||
} |
|||
else |
|||
{ |
|||
USBD_CtlError(pdev, req); |
|||
err++; |
|||
} |
|||
#endif |
|||
|
|||
#if (USBD_CLASS_USER_STRING_DESC == 1U) |
|||
if (pdev->pDesc->GetUserStrDescriptor != NULL) |
|||
{ |
|||
pbuf = pdev->pDesc->GetUserStrDescriptor(pdev->dev_speed, (req->wValue), &len); |
|||
} |
|||
else |
|||
{ |
|||
USBD_CtlError(pdev, req); |
|||
err++; |
|||
} |
|||
#endif |
|||
|
|||
#if ((USBD_CLASS_USER_STRING_DESC == 0U) && (USBD_SUPPORT_USER_STRING_DESC == 0U)) |
|||
USBD_CtlError(pdev, req); |
|||
err++; |
|||
#endif |
|||
break; |
|||
} |
|||
break; |
|||
|
|||
case USB_DESC_TYPE_DEVICE_QUALIFIER: |
|||
if (pdev->dev_speed == USBD_SPEED_HIGH) |
|||
{ |
|||
pbuf = pdev->pClass->GetDeviceQualifierDescriptor(&len); |
|||
} |
|||
else |
|||
{ |
|||
USBD_CtlError(pdev, req); |
|||
err++; |
|||
} |
|||
break; |
|||
|
|||
case USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION: |
|||
if (pdev->dev_speed == USBD_SPEED_HIGH) |
|||
{ |
|||
pbuf = pdev->pClass->GetOtherSpeedConfigDescriptor(&len); |
|||
pbuf[1] = USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION; |
|||
} |
|||
else |
|||
{ |
|||
USBD_CtlError(pdev, req); |
|||
err++; |
|||
} |
|||
break; |
|||
|
|||
default: |
|||
USBD_CtlError(pdev, req); |
|||
err++; |
|||
break; |
|||
} |
|||
|
|||
if (err != 0U) |
|||
{ |
|||
return; |
|||
} |
|||
|
|||
if (req->wLength != 0U) |
|||
{ |
|||
if (len != 0U) |
|||
{ |
|||
len = MIN(len, req->wLength); |
|||
(void)USBD_CtlSendData(pdev, pbuf, len); |
|||
} |
|||
else |
|||
{ |
|||
USBD_CtlError(pdev, req); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
(void)USBD_CtlSendStatus(pdev); |
|||
} |
|||
} |
|||
|
|||
|
|||
/**
|
|||
* @brief USBD_SetAddress |
|||
* Set device address |
|||
* @param pdev: device instance |
|||
* @param req: usb request |
|||
* @retval status |
|||
*/ |
|||
static void USBD_SetAddress(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) |
|||
{ |
|||
uint8_t dev_addr; |
|||
|
|||
if ((req->wIndex == 0U) && (req->wLength == 0U) && (req->wValue < 128U)) |
|||
{ |
|||
dev_addr = (uint8_t)(req->wValue) & 0x7FU; |
|||
|
|||
if (pdev->dev_state == USBD_STATE_CONFIGURED) |
|||
{ |
|||
USBD_CtlError(pdev, req); |
|||
} |
|||
else |
|||
{ |
|||
pdev->dev_address = dev_addr; |
|||
(void)USBD_LL_SetUSBAddress(pdev, dev_addr); |
|||
(void)USBD_CtlSendStatus(pdev); |
|||
|
|||
if (dev_addr != 0U) |
|||
{ |
|||
pdev->dev_state = USBD_STATE_ADDRESSED; |
|||
} |
|||
else |
|||
{ |
|||
pdev->dev_state = USBD_STATE_DEFAULT; |
|||
} |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
USBD_CtlError(pdev, req); |
|||
} |
|||
} |
|||
|
|||
/**
|
|||
* @brief USBD_SetConfig |
|||
* Handle Set device configuration request |
|||
* @param pdev: device instance |
|||
* @param req: usb request |
|||
* @retval status |
|||
*/ |
|||
static USBD_StatusTypeDef USBD_SetConfig(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) |
|||
{ |
|||
USBD_StatusTypeDef ret = USBD_OK; |
|||
static uint8_t cfgidx; |
|||
|
|||
cfgidx = (uint8_t)(req->wValue); |
|||
|
|||
if (cfgidx > USBD_MAX_NUM_CONFIGURATION) |
|||
{ |
|||
USBD_CtlError(pdev, req); |
|||
return USBD_FAIL; |
|||
} |
|||
|
|||
switch (pdev->dev_state) |
|||
{ |
|||
case USBD_STATE_ADDRESSED: |
|||
if (cfgidx != 0U) |
|||
{ |
|||
pdev->dev_config = cfgidx; |
|||
|
|||
ret = USBD_SetClassConfig(pdev, cfgidx); |
|||
|
|||
if (ret != USBD_OK) |
|||
{ |
|||
USBD_CtlError(pdev, req); |
|||
} |
|||
else |
|||
{ |
|||
(void)USBD_CtlSendStatus(pdev); |
|||
pdev->dev_state = USBD_STATE_CONFIGURED; |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
(void)USBD_CtlSendStatus(pdev); |
|||
} |
|||
break; |
|||
|
|||
case USBD_STATE_CONFIGURED: |
|||
if (cfgidx == 0U) |
|||
{ |
|||
pdev->dev_state = USBD_STATE_ADDRESSED; |
|||
pdev->dev_config = cfgidx; |
|||
(void)USBD_ClrClassConfig(pdev, cfgidx); |
|||
(void)USBD_CtlSendStatus(pdev); |
|||
} |
|||
else if (cfgidx != pdev->dev_config) |
|||
{ |
|||
/* Clear old configuration */ |
|||
(void)USBD_ClrClassConfig(pdev, (uint8_t)pdev->dev_config); |
|||
|
|||
/* set new configuration */ |
|||
pdev->dev_config = cfgidx; |
|||
|
|||
ret = USBD_SetClassConfig(pdev, cfgidx); |
|||
|
|||
if (ret != USBD_OK) |
|||
{ |
|||
USBD_CtlError(pdev, req); |
|||
(void)USBD_ClrClassConfig(pdev, (uint8_t)pdev->dev_config); |
|||
pdev->dev_state = USBD_STATE_ADDRESSED; |
|||
} |
|||
else |
|||
{ |
|||
(void)USBD_CtlSendStatus(pdev); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
(void)USBD_CtlSendStatus(pdev); |
|||
} |
|||
break; |
|||
|
|||
default: |
|||
USBD_CtlError(pdev, req); |
|||
(void)USBD_ClrClassConfig(pdev, cfgidx); |
|||
ret = USBD_FAIL; |
|||
break; |
|||
} |
|||
|
|||
return ret; |
|||
} |
|||
|
|||
/**
|
|||
* @brief USBD_GetConfig |
|||
* Handle Get device configuration request |
|||
* @param pdev: device instance |
|||
* @param req: usb request |
|||
* @retval status |
|||
*/ |
|||
static void USBD_GetConfig(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) |
|||
{ |
|||
if (req->wLength != 1U) |
|||
{ |
|||
USBD_CtlError(pdev, req); |
|||
} |
|||
else |
|||
{ |
|||
switch (pdev->dev_state) |
|||
{ |
|||
case USBD_STATE_DEFAULT: |
|||
case USBD_STATE_ADDRESSED: |
|||
pdev->dev_default_config = 0U; |
|||
(void)USBD_CtlSendData(pdev, (uint8_t *)&pdev->dev_default_config, 1U); |
|||
break; |
|||
|
|||
case USBD_STATE_CONFIGURED: |
|||
(void)USBD_CtlSendData(pdev, (uint8_t *)&pdev->dev_config, 1U); |
|||
break; |
|||
|
|||
default: |
|||
USBD_CtlError(pdev, req); |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
|
|||
/**
|
|||
* @brief USBD_GetStatus |
|||
* Handle Get Status request |
|||
* @param pdev: device instance |
|||
* @param req: usb request |
|||
* @retval status |
|||
*/ |
|||
static void USBD_GetStatus(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) |
|||
{ |
|||
switch (pdev->dev_state) |
|||
{ |
|||
case USBD_STATE_DEFAULT: |
|||
case USBD_STATE_ADDRESSED: |
|||
case USBD_STATE_CONFIGURED: |
|||
if (req->wLength != 0x2U) |
|||
{ |
|||
USBD_CtlError(pdev, req); |
|||
break; |
|||
} |
|||
|
|||
#if (USBD_SELF_POWERED == 1U) |
|||
pdev->dev_config_status = USB_CONFIG_SELF_POWERED; |
|||
#else |
|||
pdev->dev_config_status = 0U; |
|||
#endif |
|||
|
|||
if (pdev->dev_remote_wakeup != 0U) |
|||
{ |
|||
pdev->dev_config_status |= USB_CONFIG_REMOTE_WAKEUP; |
|||
} |
|||
|
|||
(void)USBD_CtlSendData(pdev, (uint8_t *)&pdev->dev_config_status, 2U); |
|||
break; |
|||
|
|||
default: |
|||
USBD_CtlError(pdev, req); |
|||
break; |
|||
} |
|||
} |
|||
|
|||
|
|||
/**
|
|||
* @brief USBD_SetFeature |
|||
* Handle Set device feature request |
|||
* @param pdev: device instance |
|||
* @param req: usb request |
|||
* @retval status |
|||
*/ |
|||
static void USBD_SetFeature(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) |
|||
{ |
|||
if (req->wValue == USB_FEATURE_REMOTE_WAKEUP) |
|||
{ |
|||
pdev->dev_remote_wakeup = 1U; |
|||
(void)USBD_CtlSendStatus(pdev); |
|||
} |
|||
} |
|||
|
|||
|
|||
/**
|
|||
* @brief USBD_ClrFeature |
|||
* Handle clear device feature request |
|||
* @param pdev: device instance |
|||
* @param req: usb request |
|||
* @retval status |
|||
*/ |
|||
static void USBD_ClrFeature(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) |
|||
{ |
|||
switch (pdev->dev_state) |
|||
{ |
|||
case USBD_STATE_DEFAULT: |
|||
case USBD_STATE_ADDRESSED: |
|||
case USBD_STATE_CONFIGURED: |
|||
if (req->wValue == USB_FEATURE_REMOTE_WAKEUP) |
|||
{ |
|||
pdev->dev_remote_wakeup = 0U; |
|||
(void)USBD_CtlSendStatus(pdev); |
|||
} |
|||
break; |
|||
|
|||
default: |
|||
USBD_CtlError(pdev, req); |
|||
break; |
|||
} |
|||
} |
|||
|
|||
|
|||
/**
|
|||
* @brief USBD_ParseSetupRequest |
|||
* Copy buffer into setup structure |
|||
* @param pdev: device instance |
|||
* @param req: usb request |
|||
* @retval None |
|||
*/ |
|||
void USBD_ParseSetupRequest(USBD_SetupReqTypedef *req, uint8_t *pdata) |
|||
{ |
|||
uint8_t *pbuff = pdata; |
|||
|
|||
req->bmRequest = *(uint8_t *)(pbuff); |
|||
|
|||
pbuff++; |
|||
req->bRequest = *(uint8_t *)(pbuff); |
|||
|
|||
pbuff++; |
|||
req->wValue = SWAPBYTE(pbuff); |
|||
|
|||
pbuff++; |
|||
pbuff++; |
|||
req->wIndex = SWAPBYTE(pbuff); |
|||
|
|||
pbuff++; |
|||
pbuff++; |
|||
req->wLength = SWAPBYTE(pbuff); |
|||
} |
|||
|
|||
|
|||
/**
|
|||
* @brief USBD_CtlError |
|||
* Handle USB low level Error |
|||
* @param pdev: device instance |
|||
* @param req: usb request |
|||
* @retval None |
|||
*/ |
|||
void USBD_CtlError(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) |
|||
{ |
|||
UNUSED(req); |
|||
|
|||
(void)USBD_LL_StallEP(pdev, 0x80U); |
|||
(void)USBD_LL_StallEP(pdev, 0U); |
|||
} |
|||
|
|||
|
|||
/**
|
|||
* @brief USBD_GetString |
|||
* Convert Ascii string into unicode one |
|||
* @param desc : descriptor buffer |
|||
* @param unicode : Formatted string buffer (unicode) |
|||
* @param len : descriptor length |
|||
* @retval None |
|||
*/ |
|||
void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len) |
|||
{ |
|||
uint8_t idx = 0U; |
|||
uint8_t *pdesc; |
|||
|
|||
if (desc == NULL) |
|||
{ |
|||
return; |
|||
} |
|||
|
|||
pdesc = desc; |
|||
*len = ((uint16_t)USBD_GetLen(pdesc) * 2U) + 2U; |
|||
|
|||
unicode[idx] = *(uint8_t *)len; |
|||
idx++; |
|||
unicode[idx] = USB_DESC_TYPE_STRING; |
|||
idx++; |
|||
|
|||
while (*pdesc != (uint8_t)'\0') |
|||
{ |
|||
unicode[idx] = *pdesc; |
|||
pdesc++; |
|||
idx++; |
|||
|
|||
unicode[idx] = 0U; |
|||
idx++; |
|||
} |
|||
} |
|||
|
|||
|
|||
/**
|
|||
* @brief USBD_GetLen |
|||
* return the string length |
|||
* @param buf : pointer to the ascii string buffer |
|||
* @retval string length |
|||
*/ |
|||
static uint8_t USBD_GetLen(uint8_t *buf) |
|||
{ |
|||
uint8_t len = 0U; |
|||
uint8_t *pbuff = buf; |
|||
|
|||
while (*pbuff != (uint8_t)'\0') |
|||
{ |
|||
len++; |
|||
pbuff++; |
|||
} |
|||
|
|||
return len; |
|||
} |
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
|||
@ -0,0 +1,226 @@ |
|||
/**
|
|||
****************************************************************************** |
|||
* @file usbd_ioreq.c |
|||
* @author MCD Application Team |
|||
* @brief This file provides the IO requests APIs for control endpoints. |
|||
****************************************************************************** |
|||
* @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: |
|||
* www.st.com/SLA0044 |
|||
* |
|||
****************************************************************************** |
|||
*/ |
|||
|
|||
/* Includes ------------------------------------------------------------------*/ |
|||
#include "usbd_ioreq.h" |
|||
|
|||
/** @addtogroup STM32_USB_DEVICE_LIBRARY
|
|||
* @{ |
|||
*/ |
|||
|
|||
|
|||
/** @defgroup USBD_IOREQ
|
|||
* @brief control I/O requests module |
|||
* @{ |
|||
*/ |
|||
|
|||
/** @defgroup USBD_IOREQ_Private_TypesDefinitions
|
|||
* @{ |
|||
*/ |
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
|
|||
/** @defgroup USBD_IOREQ_Private_Defines
|
|||
* @{ |
|||
*/ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
|
|||
/** @defgroup USBD_IOREQ_Private_Macros
|
|||
* @{ |
|||
*/ |
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
|
|||
/** @defgroup USBD_IOREQ_Private_Variables
|
|||
* @{ |
|||
*/ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
|
|||
/** @defgroup USBD_IOREQ_Private_FunctionPrototypes
|
|||
* @{ |
|||
*/ |
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
|
|||
/** @defgroup USBD_IOREQ_Private_Functions
|
|||
* @{ |
|||
*/ |
|||
|
|||
/**
|
|||
* @brief USBD_CtlSendData |
|||
* send data on the ctl pipe |
|||
* @param pdev: device instance |
|||
* @param buff: pointer to data buffer |
|||
* @param len: length of data to be sent |
|||
* @retval status |
|||
*/ |
|||
USBD_StatusTypeDef USBD_CtlSendData(USBD_HandleTypeDef *pdev, |
|||
uint8_t *pbuf, uint32_t len) |
|||
{ |
|||
/* Set EP0 State */ |
|||
pdev->ep0_state = USBD_EP0_DATA_IN; |
|||
pdev->ep_in[0].total_length = len; |
|||
|
|||
#ifdef USBD_AVOID_PACKET_SPLIT_MPS |
|||
pdev->ep_in[0].rem_length = 0U; |
|||
#else |
|||
pdev->ep_in[0].rem_length = len; |
|||
#endif |
|||
|
|||
/* Start the transfer */ |
|||
(void)USBD_LL_Transmit(pdev, 0x00U, pbuf, len); |
|||
|
|||
return USBD_OK; |
|||
} |
|||
|
|||
/**
|
|||
* @brief USBD_CtlContinueSendData |
|||
* continue sending data on the ctl pipe |
|||
* @param pdev: device instance |
|||
* @param buff: pointer to data buffer |
|||
* @param len: length of data to be sent |
|||
* @retval status |
|||
*/ |
|||
USBD_StatusTypeDef USBD_CtlContinueSendData(USBD_HandleTypeDef *pdev, |
|||
uint8_t *pbuf, uint32_t len) |
|||
{ |
|||
/* Start the next transfer */ |
|||
(void)USBD_LL_Transmit(pdev, 0x00U, pbuf, len); |
|||
|
|||
return USBD_OK; |
|||
} |
|||
|
|||
/**
|
|||
* @brief USBD_CtlPrepareRx |
|||
* receive data on the ctl pipe |
|||
* @param pdev: device instance |
|||
* @param buff: pointer to data buffer |
|||
* @param len: length of data to be received |
|||
* @retval status |
|||
*/ |
|||
USBD_StatusTypeDef USBD_CtlPrepareRx(USBD_HandleTypeDef *pdev, |
|||
uint8_t *pbuf, uint32_t len) |
|||
{ |
|||
/* Set EP0 State */ |
|||
pdev->ep0_state = USBD_EP0_DATA_OUT; |
|||
pdev->ep_out[0].total_length = len; |
|||
|
|||
#ifdef USBD_AVOID_PACKET_SPLIT_MPS |
|||
pdev->ep_out[0].rem_length = 0U; |
|||
#else |
|||
pdev->ep_out[0].rem_length = len; |
|||
#endif |
|||
|
|||
/* Start the transfer */ |
|||
(void)USBD_LL_PrepareReceive(pdev, 0U, pbuf, len); |
|||
|
|||
return USBD_OK; |
|||
} |
|||
|
|||
/**
|
|||
* @brief USBD_CtlContinueRx |
|||
* continue receive data on the ctl pipe |
|||
* @param pdev: device instance |
|||
* @param buff: pointer to data buffer |
|||
* @param len: length of data to be received |
|||
* @retval status |
|||
*/ |
|||
USBD_StatusTypeDef USBD_CtlContinueRx(USBD_HandleTypeDef *pdev, |
|||
uint8_t *pbuf, uint32_t len) |
|||
{ |
|||
(void)USBD_LL_PrepareReceive(pdev, 0U, pbuf, len); |
|||
|
|||
return USBD_OK; |
|||
} |
|||
|
|||
/**
|
|||
* @brief USBD_CtlSendStatus |
|||
* send zero lzngth packet on the ctl pipe |
|||
* @param pdev: device instance |
|||
* @retval status |
|||
*/ |
|||
USBD_StatusTypeDef USBD_CtlSendStatus(USBD_HandleTypeDef *pdev) |
|||
{ |
|||
/* Set EP0 State */ |
|||
pdev->ep0_state = USBD_EP0_STATUS_IN; |
|||
|
|||
/* Start the transfer */ |
|||
(void)USBD_LL_Transmit(pdev, 0x00U, NULL, 0U); |
|||
|
|||
return USBD_OK; |
|||
} |
|||
|
|||
/**
|
|||
* @brief USBD_CtlReceiveStatus |
|||
* receive zero lzngth packet on the ctl pipe |
|||
* @param pdev: device instance |
|||
* @retval status |
|||
*/ |
|||
USBD_StatusTypeDef USBD_CtlReceiveStatus(USBD_HandleTypeDef *pdev) |
|||
{ |
|||
/* Set EP0 State */ |
|||
pdev->ep0_state = USBD_EP0_STATUS_OUT; |
|||
|
|||
/* Start the transfer */ |
|||
(void)USBD_LL_PrepareReceive(pdev, 0U, NULL, 0U); |
|||
|
|||
return USBD_OK; |
|||
} |
|||
|
|||
/**
|
|||
* @brief USBD_GetRxCount |
|||
* returns the received data length |
|||
* @param pdev: device instance |
|||
* @param ep_addr: endpoint address |
|||
* @retval Rx Data blength |
|||
*/ |
|||
uint32_t USBD_GetRxCount(USBD_HandleTypeDef *pdev, uint8_t ep_addr) |
|||
{ |
|||
return USBD_LL_GetRxDataSize(pdev, ep_addr); |
|||
} |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
|||
@ -0,0 +1,99 @@ |
|||
/* USER CODE BEGIN Header */ |
|||
/**
|
|||
****************************************************************************** |
|||
* @file : usb_device.c |
|||
* @version : v3.0_Cube |
|||
* @brief : This file implements the USB Device |
|||
****************************************************************************** |
|||
* @attention |
|||
* |
|||
* <h2><center>© Copyright (c) 2021 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: |
|||
* www.st.com/SLA0044 |
|||
* |
|||
****************************************************************************** |
|||
*/ |
|||
/* USER CODE END Header */ |
|||
|
|||
/* Includes ------------------------------------------------------------------*/ |
|||
|
|||
#include "usb_device.h" |
|||
#include "usbd_core.h" |
|||
#include "usbd_desc.h" |
|||
#include "usbd_cdc.h" |
|||
#include "usbd_cdc_if.h" |
|||
|
|||
/* USER CODE BEGIN Includes */ |
|||
|
|||
/* USER CODE END Includes */ |
|||
|
|||
/* USER CODE BEGIN PV */ |
|||
/* Private variables ---------------------------------------------------------*/ |
|||
|
|||
/* USER CODE END PV */ |
|||
|
|||
/* USER CODE BEGIN PFP */ |
|||
/* Private function prototypes -----------------------------------------------*/ |
|||
|
|||
/* USER CODE END PFP */ |
|||
|
|||
extern void Error_Handler(void); |
|||
/* USB Device Core handle declaration. */ |
|||
USBD_HandleTypeDef hUsbDeviceFS; |
|||
extern USBD_DescriptorsTypeDef CDC_Desc; |
|||
|
|||
/*
|
|||
* -- Insert your variables declaration here -- |
|||
*/ |
|||
/* USER CODE BEGIN 0 */ |
|||
|
|||
/* USER CODE END 0 */ |
|||
|
|||
/*
|
|||
* -- Insert your external function declaration here -- |
|||
*/ |
|||
/* USER CODE BEGIN 1 */ |
|||
|
|||
/* USER CODE END 1 */ |
|||
|
|||
/**
|
|||
* Init USB device Library, add supported class and start the library |
|||
* @retval None |
|||
*/ |
|||
void MX_USB_Device_Init(void) |
|||
{ |
|||
/* USER CODE BEGIN USB_Device_Init_PreTreatment */ |
|||
|
|||
/* USER CODE END USB_Device_Init_PreTreatment */ |
|||
|
|||
/* Init Device Library, add supported class and start the library. */ |
|||
if (USBD_Init(&hUsbDeviceFS, &CDC_Desc, DEVICE_FS) != USBD_OK) { |
|||
Error_Handler(); |
|||
} |
|||
if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_CDC) != USBD_OK) { |
|||
Error_Handler(); |
|||
} |
|||
if (USBD_CDC_RegisterInterface(&hUsbDeviceFS, &USBD_Interface_fops_FS) != USBD_OK) { |
|||
Error_Handler(); |
|||
} |
|||
if (USBD_Start(&hUsbDeviceFS) != USBD_OK) { |
|||
Error_Handler(); |
|||
} |
|||
/* USER CODE BEGIN USB_Device_Init_PostTreatment */ |
|||
|
|||
/* USER CODE END USB_Device_Init_PostTreatment */ |
|||
} |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
|||
@ -0,0 +1,105 @@ |
|||
/* USER CODE BEGIN Header */ |
|||
/**
|
|||
****************************************************************************** |
|||
* @file : usb_device.h |
|||
* @version : v3.0_Cube |
|||
* @brief : Header for usb_device.c file. |
|||
****************************************************************************** |
|||
* @attention |
|||
* |
|||
* <h2><center>© Copyright (c) 2021 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: |
|||
* www.st.com/SLA0044 |
|||
* |
|||
****************************************************************************** |
|||
*/ |
|||
/* USER CODE END Header */ |
|||
|
|||
/* Define to prevent recursive inclusion -------------------------------------*/ |
|||
#ifndef __USB_DEVICE__H__ |
|||
#define __USB_DEVICE__H__ |
|||
|
|||
#ifdef __cplusplus |
|||
extern "C" { |
|||
#endif |
|||
|
|||
/* Includes ------------------------------------------------------------------*/ |
|||
#include "stm32wbxx.h" |
|||
#include "stm32wbxx_hal.h" |
|||
#include "usbd_def.h" |
|||
|
|||
/* USER CODE BEGIN INCLUDE */ |
|||
|
|||
/* USER CODE END INCLUDE */ |
|||
|
|||
/** @addtogroup USBD_OTG_DRIVER
|
|||
* @{ |
|||
*/ |
|||
|
|||
/** @defgroup USBD_DEVICE USBD_DEVICE
|
|||
* @brief Device file for Usb otg low level driver. |
|||
* @{ |
|||
*/ |
|||
|
|||
/** @defgroup USBD_DEVICE_Exported_Variables USBD_DEVICE_Exported_Variables
|
|||
* @brief Public variables. |
|||
* @{ |
|||
*/ |
|||
|
|||
/* Private variables ---------------------------------------------------------*/ |
|||
/* USER CODE BEGIN PV */ |
|||
|
|||
/* USER CODE END PV */ |
|||
|
|||
/* Private function prototypes -----------------------------------------------*/ |
|||
/* USER CODE BEGIN PFP */ |
|||
|
|||
/* USER CODE END PFP */ |
|||
|
|||
/*
|
|||
* -- Insert your variables declaration here -- |
|||
*/ |
|||
/* USER CODE BEGIN VARIABLES */ |
|||
|
|||
/* USER CODE END VARIABLES */ |
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/** @defgroup USBD_DEVICE_Exported_FunctionsPrototype USBD_DEVICE_Exported_FunctionsPrototype
|
|||
* @brief Declaration of public functions for Usb device. |
|||
* @{ |
|||
*/ |
|||
|
|||
/** USB Device initialization function. */ |
|||
void MX_USB_Device_Init(void); |
|||
|
|||
/*
|
|||
* -- Insert functions declaration here -- |
|||
*/ |
|||
/* USER CODE BEGIN FD */ |
|||
|
|||
/* USER CODE END FD */ |
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
#ifdef __cplusplus |
|||
} |
|||
#endif |
|||
|
|||
#endif /* __USB_DEVICE__H__ */ |
|||
|
|||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
|||
@ -0,0 +1,331 @@ |
|||
/* USER CODE BEGIN Header */ |
|||
/**
|
|||
****************************************************************************** |
|||
* @file : usbd_cdc_if.c |
|||
* @version : v3.0_Cube |
|||
* @brief : Usb device for Virtual Com Port. |
|||
****************************************************************************** |
|||
* @attention |
|||
* |
|||
* <h2><center>© Copyright (c) 2021 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: |
|||
* www.st.com/SLA0044 |
|||
* |
|||
****************************************************************************** |
|||
*/ |
|||
/* USER CODE END Header */ |
|||
|
|||
/* Includes ------------------------------------------------------------------*/ |
|||
#include "usbd_cdc_if.h" |
|||
|
|||
/* USER CODE BEGIN INCLUDE */ |
|||
|
|||
/* USER CODE END INCLUDE */ |
|||
|
|||
/* Private typedef -----------------------------------------------------------*/ |
|||
/* Private define ------------------------------------------------------------*/ |
|||
/* Private macro -------------------------------------------------------------*/ |
|||
|
|||
/* USER CODE BEGIN PV */ |
|||
/* Private variables ---------------------------------------------------------*/ |
|||
|
|||
/* USER CODE END PV */ |
|||
|
|||
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
|
|||
* @brief Usb device library. |
|||
* @{ |
|||
*/ |
|||
|
|||
/** @addtogroup USBD_CDC_IF
|
|||
* @{ |
|||
*/ |
|||
|
|||
/** @defgroup USBD_CDC_IF_Private_TypesDefinitions USBD_CDC_IF_Private_TypesDefinitions
|
|||
* @brief Private types. |
|||
* @{ |
|||
*/ |
|||
|
|||
/* USER CODE BEGIN PRIVATE_TYPES */ |
|||
|
|||
/* USER CODE END PRIVATE_TYPES */ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/** @defgroup USBD_CDC_IF_Private_Defines USBD_CDC_IF_Private_Defines
|
|||
* @brief Private defines. |
|||
* @{ |
|||
*/ |
|||
|
|||
/* USER CODE BEGIN PRIVATE_DEFINES */ |
|||
/* USER CODE END PRIVATE_DEFINES */ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/** @defgroup USBD_CDC_IF_Private_Macros USBD_CDC_IF_Private_Macros
|
|||
* @brief Private macros. |
|||
* @{ |
|||
*/ |
|||
|
|||
/* USER CODE BEGIN PRIVATE_MACRO */ |
|||
|
|||
/* USER CODE END PRIVATE_MACRO */ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/** @defgroup USBD_CDC_IF_Private_Variables USBD_CDC_IF_Private_Variables
|
|||
* @brief Private variables. |
|||
* @{ |
|||
*/ |
|||
/* Create buffer for reception and transmission */ |
|||
/* It's up to user to redefine and/or remove those define */ |
|||
/** Received data over USB are stored in this buffer */ |
|||
uint8_t UserRxBufferFS[APP_RX_DATA_SIZE]; |
|||
|
|||
/** Data to send over USB CDC are stored in this buffer */ |
|||
uint8_t UserTxBufferFS[APP_TX_DATA_SIZE]; |
|||
|
|||
/* USER CODE BEGIN PRIVATE_VARIABLES */ |
|||
|
|||
/* USER CODE END PRIVATE_VARIABLES */ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/** @defgroup USBD_CDC_IF_Exported_Variables USBD_CDC_IF_Exported_Variables
|
|||
* @brief Public variables. |
|||
* @{ |
|||
*/ |
|||
|
|||
extern USBD_HandleTypeDef hUsbDeviceFS; |
|||
|
|||
/* USER CODE BEGIN EXPORTED_VARIABLES */ |
|||
|
|||
/* USER CODE END EXPORTED_VARIABLES */ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/** @defgroup USBD_CDC_IF_Private_FunctionPrototypes USBD_CDC_IF_Private_FunctionPrototypes
|
|||
* @brief Private functions declaration. |
|||
* @{ |
|||
*/ |
|||
|
|||
static int8_t CDC_Init_FS(void); |
|||
static int8_t CDC_DeInit_FS(void); |
|||
static int8_t CDC_Control_FS(uint8_t cmd, uint8_t* pbuf, uint16_t length); |
|||
static int8_t CDC_Receive_FS(uint8_t* pbuf, uint32_t *Len); |
|||
static int8_t CDC_TransmitCplt_FS(uint8_t *pbuf, uint32_t *Len, uint8_t epnum); |
|||
|
|||
/* USER CODE BEGIN PRIVATE_FUNCTIONS_DECLARATION */ |
|||
|
|||
/* USER CODE END PRIVATE_FUNCTIONS_DECLARATION */ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
USBD_CDC_ItfTypeDef USBD_Interface_fops_FS = |
|||
{ |
|||
CDC_Init_FS, |
|||
CDC_DeInit_FS, |
|||
CDC_Control_FS, |
|||
CDC_Receive_FS, |
|||
CDC_TransmitCplt_FS |
|||
}; |
|||
|
|||
/* Private functions ---------------------------------------------------------*/ |
|||
/**
|
|||
* @brief Initializes the CDC media low layer over the FS USB IP |
|||
* @retval USBD_OK if all operations are OK else USBD_FAIL |
|||
*/ |
|||
static int8_t CDC_Init_FS(void) |
|||
{ |
|||
/* USER CODE BEGIN 3 */ |
|||
/* Set Application Buffers */ |
|||
USBD_CDC_SetTxBuffer(&hUsbDeviceFS, UserTxBufferFS, 0); |
|||
USBD_CDC_SetRxBuffer(&hUsbDeviceFS, UserRxBufferFS); |
|||
return (USBD_OK); |
|||
/* USER CODE END 3 */ |
|||
} |
|||
|
|||
/**
|
|||
* @brief DeInitializes the CDC media low layer |
|||
* @retval USBD_OK if all operations are OK else USBD_FAIL |
|||
*/ |
|||
static int8_t CDC_DeInit_FS(void) |
|||
{ |
|||
/* USER CODE BEGIN 4 */ |
|||
return (USBD_OK); |
|||
/* USER CODE END 4 */ |
|||
} |
|||
|
|||
/**
|
|||
* @brief Manage the CDC class requests |
|||
* @param cmd: Command code |
|||
* @param pbuf: Buffer containing command data (request parameters) |
|||
* @param length: Number of data to be sent (in bytes) |
|||
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL |
|||
*/ |
|||
static int8_t CDC_Control_FS(uint8_t cmd, uint8_t* pbuf, uint16_t length) |
|||
{ |
|||
/* USER CODE BEGIN 5 */ |
|||
switch(cmd) |
|||
{ |
|||
case CDC_SEND_ENCAPSULATED_COMMAND: |
|||
|
|||
break; |
|||
|
|||
case CDC_GET_ENCAPSULATED_RESPONSE: |
|||
|
|||
break; |
|||
|
|||
case CDC_SET_COMM_FEATURE: |
|||
|
|||
break; |
|||
|
|||
case CDC_GET_COMM_FEATURE: |
|||
|
|||
break; |
|||
|
|||
case CDC_CLEAR_COMM_FEATURE: |
|||
|
|||
break; |
|||
|
|||
/*******************************************************************************/ |
|||
/* Line Coding Structure */ |
|||
/*-----------------------------------------------------------------------------*/ |
|||
/* Offset | Field | Size | Value | Description */ |
|||
/* 0 | dwDTERate | 4 | Number |Data terminal rate, in bits per second*/ |
|||
/* 4 | bCharFormat | 1 | Number | Stop bits */ |
|||
/* 0 - 1 Stop bit */ |
|||
/* 1 - 1.5 Stop bits */ |
|||
/* 2 - 2 Stop bits */ |
|||
/* 5 | bParityType | 1 | Number | Parity */ |
|||
/* 0 - None */ |
|||
/* 1 - Odd */ |
|||
/* 2 - Even */ |
|||
/* 3 - Mark */ |
|||
/* 4 - Space */ |
|||
/* 6 | bDataBits | 1 | Number Data bits (5, 6, 7, 8 or 16). */ |
|||
/*******************************************************************************/ |
|||
case CDC_SET_LINE_CODING: |
|||
|
|||
break; |
|||
|
|||
case CDC_GET_LINE_CODING: |
|||
|
|||
break; |
|||
|
|||
case CDC_SET_CONTROL_LINE_STATE: |
|||
|
|||
break; |
|||
|
|||
case CDC_SEND_BREAK: |
|||
|
|||
break; |
|||
|
|||
default: |
|||
break; |
|||
} |
|||
|
|||
return (USBD_OK); |
|||
/* USER CODE END 5 */ |
|||
} |
|||
|
|||
/**
|
|||
* @brief Data received over USB OUT endpoint are sent over CDC interface |
|||
* through this function. |
|||
* |
|||
* @note |
|||
* This function will issue a NAK packet on any OUT packet received on |
|||
* USB endpoint until exiting this function. If you exit this function |
|||
* before transfer is complete on CDC interface (ie. using DMA controller) |
|||
* it will result in receiving more data while previous ones are still |
|||
* not sent. |
|||
* |
|||
* @param Buf: Buffer of data to be received |
|||
* @param Len: Number of data received (in bytes) |
|||
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL |
|||
*/ |
|||
static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len) |
|||
{ |
|||
/* USER CODE BEGIN 6 */ |
|||
USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]); |
|||
USBD_CDC_ReceivePacket(&hUsbDeviceFS); |
|||
return (USBD_OK); |
|||
/* USER CODE END 6 */ |
|||
} |
|||
|
|||
/**
|
|||
* @brief CDC_Transmit_FS |
|||
* Data to send over USB IN endpoint are sent over CDC interface |
|||
* through this function. |
|||
* @note |
|||
* |
|||
* |
|||
* @param Buf: Buffer of data to be sent |
|||
* @param Len: Number of data to be sent (in bytes) |
|||
* @retval USBD_OK if all operations are OK else USBD_FAIL or USBD_BUSY |
|||
*/ |
|||
uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len) |
|||
{ |
|||
uint8_t result = USBD_OK; |
|||
/* USER CODE BEGIN 7 */ |
|||
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*)hUsbDeviceFS.pClassData; |
|||
if (hcdc->TxState != 0){ |
|||
return USBD_BUSY; |
|||
} |
|||
USBD_CDC_SetTxBuffer(&hUsbDeviceFS, Buf, Len); |
|||
result = USBD_CDC_TransmitPacket(&hUsbDeviceFS); |
|||
/* USER CODE END 7 */ |
|||
return result; |
|||
} |
|||
|
|||
/**
|
|||
* @brief CDC_TransmitCplt_FS |
|||
* Data transmited callback |
|||
* |
|||
* @note |
|||
* This function is IN transfer complete callback used to inform user that |
|||
* the submitted Data is successfully sent over USB. |
|||
* |
|||
* @param Buf: Buffer of data to be received |
|||
* @param Len: Number of data received (in bytes) |
|||
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL |
|||
*/ |
|||
static int8_t CDC_TransmitCplt_FS(uint8_t *Buf, uint32_t *Len, uint8_t epnum) |
|||
{ |
|||
uint8_t result = USBD_OK; |
|||
/* USER CODE BEGIN 13 */ |
|||
UNUSED(Buf); |
|||
UNUSED(Len); |
|||
UNUSED(epnum); |
|||
/* USER CODE END 13 */ |
|||
return result; |
|||
} |
|||
|
|||
/* USER CODE BEGIN PRIVATE_FUNCTIONS_IMPLEMENTATION */ |
|||
|
|||
/* USER CODE END PRIVATE_FUNCTIONS_IMPLEMENTATION */ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
|||
@ -0,0 +1,134 @@ |
|||
/* USER CODE BEGIN Header */ |
|||
/**
|
|||
****************************************************************************** |
|||
* @file : usbd_cdc_if.h |
|||
* @version : v3.0_Cube |
|||
* @brief : Header for usbd_cdc_if.c file. |
|||
****************************************************************************** |
|||
* @attention |
|||
* |
|||
* <h2><center>© Copyright (c) 2021 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: |
|||
* www.st.com/SLA0044 |
|||
* |
|||
****************************************************************************** |
|||
*/ |
|||
/* USER CODE END Header */ |
|||
|
|||
/* Define to prevent recursive inclusion -------------------------------------*/ |
|||
#ifndef __USBD_CDC_IF_H__ |
|||
#define __USBD_CDC_IF_H__ |
|||
|
|||
#ifdef __cplusplus |
|||
extern "C" { |
|||
#endif |
|||
|
|||
/* Includes ------------------------------------------------------------------*/ |
|||
#include "usbd_cdc.h" |
|||
|
|||
/* USER CODE BEGIN INCLUDE */ |
|||
|
|||
/* USER CODE END INCLUDE */ |
|||
|
|||
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
|
|||
* @brief For Usb device. |
|||
* @{ |
|||
*/ |
|||
|
|||
/** @defgroup USBD_CDC_IF USBD_CDC_IF
|
|||
* @brief Usb VCP device module |
|||
* @{ |
|||
*/ |
|||
|
|||
/** @defgroup USBD_CDC_IF_Exported_Defines USBD_CDC_IF_Exported_Defines
|
|||
* @brief Defines. |
|||
* @{ |
|||
*/ |
|||
/* USER CODE BEGIN EXPORTED_DEFINES */ |
|||
/* Define size for the receive and transmit buffer over CDC */ |
|||
/* It's up to user to redefine and/or remove those define */ |
|||
#define APP_RX_DATA_SIZE 2048 |
|||
#define APP_TX_DATA_SIZE 2048 |
|||
|
|||
/* USER CODE END EXPORTED_DEFINES */ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/** @defgroup USBD_CDC_IF_Exported_Types USBD_CDC_IF_Exported_Types
|
|||
* @brief Types. |
|||
* @{ |
|||
*/ |
|||
|
|||
/* USER CODE BEGIN EXPORTED_TYPES */ |
|||
|
|||
/* USER CODE END EXPORTED_TYPES */ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/** @defgroup USBD_CDC_IF_Exported_Macros USBD_CDC_IF_Exported_Macros
|
|||
* @brief Aliases. |
|||
* @{ |
|||
*/ |
|||
|
|||
/* USER CODE BEGIN EXPORTED_MACRO */ |
|||
|
|||
/* USER CODE END EXPORTED_MACRO */ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/** @defgroup USBD_CDC_IF_Exported_Variables USBD_CDC_IF_Exported_Variables
|
|||
* @brief Public variables. |
|||
* @{ |
|||
*/ |
|||
|
|||
/** CDC Interface callback. */ |
|||
extern USBD_CDC_ItfTypeDef USBD_Interface_fops_FS; |
|||
|
|||
/* USER CODE BEGIN EXPORTED_VARIABLES */ |
|||
|
|||
/* USER CODE END EXPORTED_VARIABLES */ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/** @defgroup USBD_CDC_IF_Exported_FunctionsPrototype USBD_CDC_IF_Exported_FunctionsPrototype
|
|||
* @brief Public functions declaration. |
|||
* @{ |
|||
*/ |
|||
|
|||
uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len); |
|||
|
|||
/* USER CODE BEGIN EXPORTED_FUNCTIONS */ |
|||
|
|||
/* USER CODE END EXPORTED_FUNCTIONS */ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
#ifdef __cplusplus |
|||
} |
|||
#endif |
|||
|
|||
#endif /* __USBD_CDC_IF_H__ */ |
|||
|
|||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
|||
@ -0,0 +1,396 @@ |
|||
/* USER CODE BEGIN Header */ |
|||
/**
|
|||
****************************************************************************** |
|||
* @file : App/usbd_desc.c |
|||
* @version : v3.0_Cube |
|||
* @brief : This file implements the USB device descriptors. |
|||
****************************************************************************** |
|||
* @attention |
|||
* |
|||
* <h2><center>© Copyright (c) 2021 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: |
|||
* www.st.com/SLA0044 |
|||
* |
|||
****************************************************************************** |
|||
*/ |
|||
/* USER CODE END Header */ |
|||
|
|||
/* Includes ------------------------------------------------------------------*/ |
|||
#include "usbd_core.h" |
|||
#include "usbd_desc.h" |
|||
#include "usbd_conf.h" |
|||
|
|||
/* USER CODE BEGIN INCLUDE */ |
|||
|
|||
/* USER CODE END INCLUDE */ |
|||
|
|||
/* Private typedef -----------------------------------------------------------*/ |
|||
/* Private define ------------------------------------------------------------*/ |
|||
/* Private macro -------------------------------------------------------------*/ |
|||
|
|||
/* USER CODE BEGIN PV */ |
|||
/* Private variables ---------------------------------------------------------*/ |
|||
|
|||
/* USER CODE END PV */ |
|||
|
|||
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
|
|||
* @{ |
|||
*/ |
|||
|
|||
/** @addtogroup USBD_DESC
|
|||
* @{ |
|||
*/ |
|||
|
|||
/** @defgroup USBD_DESC_Private_TypesDefinitions USBD_DESC_Private_TypesDefinitions
|
|||
* @brief Private types. |
|||
* @{ |
|||
*/ |
|||
|
|||
/* USER CODE BEGIN PRIVATE_TYPES */ |
|||
|
|||
/* USER CODE END PRIVATE_TYPES */ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/** @defgroup USBD_DESC_Private_Defines USBD_DESC_Private_Defines
|
|||
* @brief Private defines. |
|||
* @{ |
|||
*/ |
|||
|
|||
#define USBD_VID 1155 |
|||
#define USBD_LANGID_STRING 1033 |
|||
#define USBD_MANUFACTURER_STRING "STMicroelectronics" |
|||
#define USBD_PID 22336 |
|||
#define USBD_PRODUCT_STRING "STM32 Virtual ComPort" |
|||
#define USBD_CONFIGURATION_STRING "CDC Config" |
|||
#define USBD_INTERFACE_STRING "CDC Interface" |
|||
|
|||
/* USER CODE BEGIN PRIVATE_DEFINES */ |
|||
|
|||
/* USER CODE END PRIVATE_DEFINES */ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/* USER CODE BEGIN 0 */ |
|||
|
|||
/* USER CODE END 0 */ |
|||
|
|||
/** @defgroup USBD_DESC_Private_Macros USBD_DESC_Private_Macros
|
|||
* @brief Private macros. |
|||
* @{ |
|||
*/ |
|||
|
|||
/* USER CODE BEGIN PRIVATE_MACRO */ |
|||
|
|||
/* USER CODE END PRIVATE_MACRO */ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/** @defgroup USBD_DESC_Private_FunctionPrototypes USBD_DESC_Private_FunctionPrototypes
|
|||
* @brief Private functions declaration. |
|||
* @{ |
|||
*/ |
|||
|
|||
static void Get_SerialNum(void); |
|||
static void IntToUnicode(uint32_t value, uint8_t * pbuf, uint8_t len); |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/** @defgroup USBD_DESC_Private_FunctionPrototypes USBD_DESC_Private_FunctionPrototypes
|
|||
* @brief Private functions declaration. |
|||
* @{ |
|||
*/ |
|||
|
|||
uint8_t * USBD_CDC_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); |
|||
uint8_t * USBD_CDC_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); |
|||
uint8_t * USBD_CDC_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); |
|||
uint8_t * USBD_CDC_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); |
|||
uint8_t * USBD_CDC_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); |
|||
uint8_t * USBD_CDC_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); |
|||
uint8_t * USBD_CDC_InterfaceStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/** @defgroup USBD_DESC_Private_Variables USBD_DESC_Private_Variables
|
|||
* @brief Private variables. |
|||
* @{ |
|||
*/ |
|||
|
|||
USBD_DescriptorsTypeDef CDC_Desc = |
|||
{ |
|||
USBD_CDC_DeviceDescriptor, |
|||
USBD_CDC_LangIDStrDescriptor, |
|||
USBD_CDC_ManufacturerStrDescriptor, |
|||
USBD_CDC_ProductStrDescriptor, |
|||
USBD_CDC_SerialStrDescriptor, |
|||
USBD_CDC_ConfigStrDescriptor, |
|||
USBD_CDC_InterfaceStrDescriptor |
|||
}; |
|||
|
|||
#if defined ( __ICCARM__ ) /* IAR Compiler */ |
|||
#pragma data_alignment=4 |
|||
#endif /* defined ( __ICCARM__ ) */ |
|||
/** USB standard device descriptor. */ |
|||
__ALIGN_BEGIN uint8_t USBD_CDC_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = |
|||
{ |
|||
0x12, /*bLength */ |
|||
USB_DESC_TYPE_DEVICE, /*bDescriptorType*/ |
|||
0x00, /*bcdUSB */ |
|||
0x02, |
|||
0x02, /*bDeviceClass*/ |
|||
0x02, /*bDeviceSubClass*/ |
|||
0x00, /*bDeviceProtocol*/ |
|||
USB_MAX_EP0_SIZE, /*bMaxPacketSize*/ |
|||
LOBYTE(USBD_VID), /*idVendor*/ |
|||
HIBYTE(USBD_VID), /*idVendor*/ |
|||
LOBYTE(USBD_PID), /*idProduct*/ |
|||
HIBYTE(USBD_PID), /*idProduct*/ |
|||
0x00, /*bcdDevice rel. 2.00*/ |
|||
0x02, |
|||
USBD_IDX_MFC_STR, /*Index of manufacturer string*/ |
|||
USBD_IDX_PRODUCT_STR, /*Index of product string*/ |
|||
USBD_IDX_SERIAL_STR, /*Index of serial number string*/ |
|||
USBD_MAX_NUM_CONFIGURATION /*bNumConfigurations*/ |
|||
}; |
|||
|
|||
/* USB_DeviceDescriptor */ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/** @defgroup USBD_DESC_Private_Variables USBD_DESC_Private_Variables
|
|||
* @brief Private variables. |
|||
* @{ |
|||
*/ |
|||
|
|||
#if defined ( __ICCARM__ ) /* IAR Compiler */ |
|||
#pragma data_alignment=4 |
|||
#endif /* defined ( __ICCARM__ ) */ |
|||
|
|||
/** USB lang indentifier descriptor. */ |
|||
__ALIGN_BEGIN uint8_t USBD_LangIDDesc[USB_LEN_LANGID_STR_DESC] __ALIGN_END = |
|||
{ |
|||
USB_LEN_LANGID_STR_DESC, |
|||
USB_DESC_TYPE_STRING, |
|||
LOBYTE(USBD_LANGID_STRING), |
|||
HIBYTE(USBD_LANGID_STRING) |
|||
}; |
|||
|
|||
#if defined ( __ICCARM__ ) /* IAR Compiler */ |
|||
#pragma data_alignment=4 |
|||
#endif /* defined ( __ICCARM__ ) */ |
|||
/* Internal string descriptor. */ |
|||
__ALIGN_BEGIN uint8_t USBD_StrDesc[USBD_MAX_STR_DESC_SIZ] __ALIGN_END; |
|||
|
|||
#if defined ( __ICCARM__ ) /*!< IAR Compiler */ |
|||
#pragma data_alignment=4 |
|||
#endif |
|||
__ALIGN_BEGIN uint8_t USBD_StringSerial[USB_SIZ_STRING_SERIAL] __ALIGN_END = { |
|||
USB_SIZ_STRING_SERIAL, |
|||
USB_DESC_TYPE_STRING, |
|||
}; |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/** @defgroup USBD_DESC_Private_Functions USBD_DESC_Private_Functions
|
|||
* @brief Private functions. |
|||
* @{ |
|||
*/ |
|||
|
|||
/**
|
|||
* @brief Return the device descriptor |
|||
* @param speed : Current device speed |
|||
* @param length : Pointer to data length variable |
|||
* @retval Pointer to descriptor buffer |
|||
*/ |
|||
uint8_t * USBD_CDC_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) |
|||
{ |
|||
UNUSED(speed); |
|||
*length = sizeof(USBD_CDC_DeviceDesc); |
|||
return USBD_CDC_DeviceDesc; |
|||
} |
|||
|
|||
/**
|
|||
* @brief Return the LangID string descriptor |
|||
* @param speed : Current device speed |
|||
* @param length : Pointer to data length variable |
|||
* @retval Pointer to descriptor buffer |
|||
*/ |
|||
uint8_t * USBD_CDC_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) |
|||
{ |
|||
UNUSED(speed); |
|||
*length = sizeof(USBD_LangIDDesc); |
|||
return USBD_LangIDDesc; |
|||
} |
|||
|
|||
/**
|
|||
* @brief Return the product string descriptor |
|||
* @param speed : Current device speed |
|||
* @param length : Pointer to data length variable |
|||
* @retval Pointer to descriptor buffer |
|||
*/ |
|||
uint8_t * USBD_CDC_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) |
|||
{ |
|||
if(speed == 0) |
|||
{ |
|||
USBD_GetString((uint8_t *)USBD_PRODUCT_STRING, USBD_StrDesc, length); |
|||
} |
|||
else |
|||
{ |
|||
USBD_GetString((uint8_t *)USBD_PRODUCT_STRING, USBD_StrDesc, length); |
|||
} |
|||
return USBD_StrDesc; |
|||
} |
|||
|
|||
/**
|
|||
* @brief Return the manufacturer string descriptor |
|||
* @param speed : Current device speed |
|||
* @param length : Pointer to data length variable |
|||
* @retval Pointer to descriptor buffer |
|||
*/ |
|||
uint8_t * USBD_CDC_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) |
|||
{ |
|||
UNUSED(speed); |
|||
USBD_GetString((uint8_t *)USBD_MANUFACTURER_STRING, USBD_StrDesc, length); |
|||
return USBD_StrDesc; |
|||
} |
|||
|
|||
/**
|
|||
* @brief Return the serial number string descriptor |
|||
* @param speed : Current device speed |
|||
* @param length : Pointer to data length variable |
|||
* @retval Pointer to descriptor buffer |
|||
*/ |
|||
uint8_t * USBD_CDC_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) |
|||
{ |
|||
UNUSED(speed); |
|||
*length = USB_SIZ_STRING_SERIAL; |
|||
|
|||
/* Update the serial number string descriptor with the data from the unique
|
|||
* ID */ |
|||
Get_SerialNum(); |
|||
|
|||
/* USER CODE BEGIN USBD_CDC_SerialStrDescriptor */ |
|||
|
|||
/* USER CODE END USBD_CDC_SerialStrDescriptor */ |
|||
|
|||
return (uint8_t *) USBD_StringSerial; |
|||
} |
|||
|
|||
/**
|
|||
* @brief Return the configuration string descriptor |
|||
* @param speed : Current device speed |
|||
* @param length : Pointer to data length variable |
|||
* @retval Pointer to descriptor buffer |
|||
*/ |
|||
uint8_t * USBD_CDC_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) |
|||
{ |
|||
if(speed == USBD_SPEED_HIGH) |
|||
{ |
|||
USBD_GetString((uint8_t *)USBD_CONFIGURATION_STRING, USBD_StrDesc, length); |
|||
} |
|||
else |
|||
{ |
|||
USBD_GetString((uint8_t *)USBD_CONFIGURATION_STRING, USBD_StrDesc, length); |
|||
} |
|||
return USBD_StrDesc; |
|||
} |
|||
|
|||
/**
|
|||
* @brief Return the interface string descriptor |
|||
* @param speed : Current device speed |
|||
* @param length : Pointer to data length variable |
|||
* @retval Pointer to descriptor buffer |
|||
*/ |
|||
uint8_t * USBD_CDC_InterfaceStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) |
|||
{ |
|||
if(speed == 0) |
|||
{ |
|||
USBD_GetString((uint8_t *)USBD_INTERFACE_STRING, USBD_StrDesc, length); |
|||
} |
|||
else |
|||
{ |
|||
USBD_GetString((uint8_t *)USBD_INTERFACE_STRING, USBD_StrDesc, length); |
|||
} |
|||
return USBD_StrDesc; |
|||
} |
|||
|
|||
/**
|
|||
* @brief Create the serial number string descriptor |
|||
* @param None |
|||
* @retval None |
|||
*/ |
|||
static void Get_SerialNum(void) |
|||
{ |
|||
uint32_t deviceserial0, deviceserial1, deviceserial2; |
|||
|
|||
deviceserial0 = *(uint32_t *) DEVICE_ID1; |
|||
deviceserial1 = *(uint32_t *) DEVICE_ID2; |
|||
deviceserial2 = *(uint32_t *) DEVICE_ID3; |
|||
|
|||
deviceserial0 += deviceserial2; |
|||
|
|||
if (deviceserial0 != 0) |
|||
{ |
|||
IntToUnicode(deviceserial0, &USBD_StringSerial[2], 8); |
|||
IntToUnicode(deviceserial1, &USBD_StringSerial[18], 4); |
|||
} |
|||
} |
|||
|
|||
/**
|
|||
* @brief Convert Hex 32Bits value into char |
|||
* @param value: value to convert |
|||
* @param pbuf: pointer to the buffer |
|||
* @param len: buffer length |
|||
* @retval None |
|||
*/ |
|||
static void IntToUnicode(uint32_t value, uint8_t * pbuf, uint8_t len) |
|||
{ |
|||
uint8_t idx = 0; |
|||
|
|||
for (idx = 0; idx < len; idx++) |
|||
{ |
|||
if (((value >> 28)) < 0xA) |
|||
{ |
|||
pbuf[2 * idx] = (value >> 28) + '0'; |
|||
} |
|||
else |
|||
{ |
|||
pbuf[2 * idx] = (value >> 28) + 'A' - 10; |
|||
} |
|||
|
|||
value = value << 4; |
|||
|
|||
pbuf[2 * idx + 1] = 0; |
|||
} |
|||
} |
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
|||
@ -0,0 +1,145 @@ |
|||
/* USER CODE BEGIN Header */ |
|||
/**
|
|||
****************************************************************************** |
|||
* @file : usbd_desc.c |
|||
* @version : v3.0_Cube |
|||
* @brief : Header for usbd_conf.c file. |
|||
****************************************************************************** |
|||
* @attention |
|||
* |
|||
* <h2><center>© Copyright (c) 2021 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: |
|||
* www.st.com/SLA0044 |
|||
* |
|||
****************************************************************************** |
|||
*/ |
|||
/* USER CODE END Header */ |
|||
|
|||
/* Define to prevent recursive inclusion -------------------------------------*/ |
|||
#ifndef __USBD_DESC__C__ |
|||
#define __USBD_DESC__C__ |
|||
|
|||
#ifdef __cplusplus |
|||
extern "C" { |
|||
#endif |
|||
|
|||
/* Includes ------------------------------------------------------------------*/ |
|||
#include "usbd_def.h" |
|||
|
|||
/* USER CODE BEGIN INCLUDE */ |
|||
|
|||
/* USER CODE END INCLUDE */ |
|||
|
|||
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
|
|||
* @{ |
|||
*/ |
|||
|
|||
/** @defgroup USBD_DESC USBD_DESC
|
|||
* @brief Usb device descriptors module. |
|||
* @{ |
|||
*/ |
|||
|
|||
/** @defgroup USBD_DESC_Exported_Constants USBD_DESC_Exported_Constants
|
|||
* @brief Constants. |
|||
* @{ |
|||
*/ |
|||
#define DEVICE_ID1 (UID_BASE) |
|||
#define DEVICE_ID2 (UID_BASE + 0x4) |
|||
#define DEVICE_ID3 (UID_BASE + 0x8) |
|||
|
|||
#define USB_SIZ_STRING_SERIAL 0x1A |
|||
|
|||
/* USER CODE BEGIN EXPORTED_CONSTANTS */ |
|||
|
|||
/* USER CODE END EXPORTED_CONSTANTS */ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/** @defgroup USBD_DESC_Exported_Defines USBD_DESC_Exported_Defines
|
|||
* @brief Defines. |
|||
* @{ |
|||
*/ |
|||
|
|||
/* USER CODE BEGIN EXPORTED_DEFINES */ |
|||
|
|||
/* USER CODE END EXPORTED_DEFINES */ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/** @defgroup USBD_DESC_Exported_TypesDefinitions USBD_DESC_Exported_TypesDefinitions
|
|||
* @brief Types. |
|||
* @{ |
|||
*/ |
|||
|
|||
/* USER CODE BEGIN EXPORTED_TYPES */ |
|||
|
|||
/* USER CODE END EXPORTED_TYPES */ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/** @defgroup USBD_DESC_Exported_Macros USBD_DESC_Exported_Macros
|
|||
* @brief Aliases. |
|||
* @{ |
|||
*/ |
|||
|
|||
/* USER CODE BEGIN EXPORTED_MACRO */ |
|||
|
|||
/* USER CODE END EXPORTED_MACRO */ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/** @defgroup USBD_DESC_Exported_Variables USBD_DESC_Exported_Variables
|
|||
* @brief Public variables. |
|||
* @{ |
|||
*/ |
|||
|
|||
extern USBD_DescriptorsTypeDef CDC_Desc; |
|||
|
|||
/* USER CODE BEGIN EXPORTED_VARIABLES */ |
|||
|
|||
/* USER CODE END EXPORTED_VARIABLES */ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/** @defgroup USBD_DESC_Exported_FunctionsPrototype USBD_DESC_Exported_FunctionsPrototype
|
|||
* @brief Public functions declaration. |
|||
* @{ |
|||
*/ |
|||
|
|||
/* USER CODE BEGIN EXPORTED_FUNCTIONS */ |
|||
|
|||
/* USER CODE END EXPORTED_FUNCTIONS */ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
#ifdef __cplusplus |
|||
} |
|||
#endif |
|||
|
|||
#endif /* __USBD_DESC__C__ */ |
|||
|
|||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
|||
@ -0,0 +1,810 @@ |
|||
/* USER CODE BEGIN Header */ |
|||
/**
|
|||
****************************************************************************** |
|||
* @file : Target/usbd_conf.c |
|||
* @version : v3.0_Cube |
|||
* @brief : This file implements the board support package for the USB device library |
|||
****************************************************************************** |
|||
* @attention |
|||
* |
|||
* <h2><center>© Copyright (c) 2021 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: |
|||
* www.st.com/SLA0044 |
|||
* |
|||
****************************************************************************** |
|||
*/ |
|||
/* USER CODE END Header */ |
|||
|
|||
/* Includes ------------------------------------------------------------------*/ |
|||
#include "stm32wbxx.h" |
|||
#include "stm32wbxx_hal.h" |
|||
#include "usbd_def.h" |
|||
#include "usbd_core.h" |
|||
|
|||
#include "usbd_cdc.h" |
|||
|
|||
/* USER CODE BEGIN Includes */ |
|||
|
|||
/* USER CODE END Includes */ |
|||
|
|||
/* Private typedef -----------------------------------------------------------*/ |
|||
/* Private define ------------------------------------------------------------*/ |
|||
/* Private macro -------------------------------------------------------------*/ |
|||
|
|||
/* Private variables ---------------------------------------------------------*/ |
|||
/* USER CODE BEGIN PV */ |
|||
|
|||
/* USER CODE END PV */ |
|||
|
|||
PCD_HandleTypeDef hpcd_USB_FS; |
|||
void Error_Handler(void); |
|||
|
|||
/* USER CODE BEGIN 0 */ |
|||
|
|||
/* USER CODE END 0 */ |
|||
|
|||
/* Exported function prototypes ----------------------------------------------*/ |
|||
|
|||
/* USER CODE BEGIN PFP */ |
|||
/* Private function prototypes -----------------------------------------------*/ |
|||
|
|||
/* USER CODE END PFP */ |
|||
|
|||
/* Private functions ---------------------------------------------------------*/ |
|||
static USBD_StatusTypeDef USBD_Get_USB_Status(HAL_StatusTypeDef hal_status); |
|||
/* USER CODE BEGIN 1 */ |
|||
static void SystemClockConfig_Resume(void); |
|||
|
|||
/* USER CODE END 1 */ |
|||
extern void SystemClock_Config(void); |
|||
|
|||
/*******************************************************************************
|
|||
LL Driver Callbacks (PCD -> USB Device Library) |
|||
*******************************************************************************/ |
|||
/* MSP Init */ |
|||
|
|||
#if (USE_HAL_PCD_REGISTER_CALLBACK == 1U) |
|||
static void HAL_PCD_MspInit(PCD_HandleTypeDef* pcdHandle) |
|||
#else |
|||
void HAL_PCD_MspInit(PCD_HandleTypeDef* pcdHandle) |
|||
#endif /* USE_HAL_PCD_REGISTER_CALLBACK */ |
|||
{ |
|||
GPIO_InitTypeDef GPIO_InitStruct = {0}; |
|||
if(pcdHandle->Instance==USB) |
|||
{ |
|||
/* USER CODE BEGIN USB_MspInit 0 */ |
|||
|
|||
/* USER CODE END USB_MspInit 0 */ |
|||
|
|||
__HAL_RCC_GPIOA_CLK_ENABLE(); |
|||
/**USB GPIO Configuration
|
|||
PA11 ------> USB_DM |
|||
PA12 ------> USB_DP |
|||
*/ |
|||
GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12; |
|||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; |
|||
GPIO_InitStruct.Pull = GPIO_NOPULL; |
|||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; |
|||
GPIO_InitStruct.Alternate = GPIO_AF10_USB; |
|||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); |
|||
|
|||
/* Peripheral clock enable */ |
|||
__HAL_RCC_USB_CLK_ENABLE(); |
|||
|
|||
/* Peripheral interrupt init */ |
|||
HAL_NVIC_SetPriority(USB_LP_IRQn, 0, 0); |
|||
HAL_NVIC_EnableIRQ(USB_LP_IRQn); |
|||
/* USER CODE BEGIN USB_MspInit 1 */ |
|||
|
|||
/* USER CODE END USB_MspInit 1 */ |
|||
} |
|||
} |
|||
|
|||
#if (USE_HAL_PCD_REGISTER_CALLBACK == 1U) |
|||
static void HAL_PCD_MspDeInit(PCD_HandleTypeDef* pcdHandle) |
|||
#else |
|||
void HAL_PCD_MspDeInit(PCD_HandleTypeDef* pcdHandle) |
|||
#endif /* USE_HAL_PCD_REGISTER_CALLBACK */ |
|||
{ |
|||
if(pcdHandle->Instance==USB) |
|||
{ |
|||
/* USER CODE BEGIN USB_MspDeInit 0 */ |
|||
|
|||
/* USER CODE END USB_MspDeInit 0 */ |
|||
/* Peripheral clock disable */ |
|||
__HAL_RCC_USB_CLK_DISABLE(); |
|||
|
|||
/**USB GPIO Configuration
|
|||
PA11 ------> USB_DM |
|||
PA12 ------> USB_DP |
|||
*/ |
|||
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_11|GPIO_PIN_12); |
|||
|
|||
/* Peripheral interrupt Deinit*/ |
|||
HAL_NVIC_DisableIRQ(USB_LP_IRQn); |
|||
|
|||
/* USER CODE BEGIN USB_MspDeInit 1 */ |
|||
|
|||
/* USER CODE END USB_MspDeInit 1 */ |
|||
} |
|||
} |
|||
|
|||
/**
|
|||
* @brief Setup stage callback |
|||
* @param hpcd: PCD handle |
|||
* @retval None |
|||
*/ |
|||
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) |
|||
static void PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd) |
|||
#else |
|||
void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd) |
|||
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ |
|||
{ |
|||
/* USER CODE BEGIN HAL_PCD_SetupStageCallback_PreTreatment */ |
|||
|
|||
/* USER CODE END HAL_PCD_SetupStageCallback_PreTreatment */ |
|||
USBD_LL_SetupStage((USBD_HandleTypeDef*)hpcd->pData, (uint8_t *)hpcd->Setup); |
|||
/* USER CODE BEGIN HAL_PCD_SetupStageCallback_PostTreatment */ |
|||
|
|||
/* USER CODE END HAL_PCD_SetupStageCallback_PostTreatment */ |
|||
} |
|||
|
|||
/**
|
|||
* @brief Data Out stage callback. |
|||
* @param hpcd: PCD handle |
|||
* @param epnum: Endpoint number |
|||
* @retval None |
|||
*/ |
|||
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) |
|||
static void PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) |
|||
#else |
|||
void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) |
|||
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ |
|||
{ |
|||
/* USER CODE BEGIN HAL_PCD_DataOutStageCallback_PreTreatment */ |
|||
|
|||
/* USER CODE END HAL_PCD_DataOutStageCallback_PreTreatment */ |
|||
USBD_LL_DataOutStage((USBD_HandleTypeDef*)hpcd->pData, epnum, hpcd->OUT_ep[epnum].xfer_buff); |
|||
/* USER CODE BEGIN HAL_PCD_DataOutStageCallback_PostTreatment */ |
|||
|
|||
/* USER CODE END HAL_PCD_DataOutStageCallback_PostTreatment */ |
|||
} |
|||
|
|||
/**
|
|||
* @brief Data In stage callback. |
|||
* @param hpcd: PCD handle |
|||
* @param epnum: Endpoint number |
|||
* @retval None |
|||
*/ |
|||
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) |
|||
static void PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) |
|||
#else |
|||
void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) |
|||
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ |
|||
{ |
|||
/* USER CODE BEGIN HAL_PCD_DataInStageCallback_PreTreatment */ |
|||
|
|||
/* USER CODE END HAL_PCD_DataInStageCallback_PreTreatment */ |
|||
USBD_LL_DataInStage((USBD_HandleTypeDef*)hpcd->pData, epnum, hpcd->IN_ep[epnum].xfer_buff); |
|||
/* USER CODE BEGIN HAL_PCD_DataInStageCallback_PostTreatment */ |
|||
|
|||
/* USER CODE END HAL_PCD_DataInStageCallback_PostTreatment */ |
|||
} |
|||
|
|||
/**
|
|||
* @brief SOF callback. |
|||
* @param hpcd: PCD handle |
|||
* @retval None |
|||
*/ |
|||
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) |
|||
static void PCD_SOFCallback(PCD_HandleTypeDef *hpcd) |
|||
#else |
|||
void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd) |
|||
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ |
|||
{ |
|||
/* USER CODE BEGIN HAL_PCD_SOFCallback_PreTreatment */ |
|||
|
|||
/* USER CODE END HAL_PCD_SOFCallback_PreTreatment */ |
|||
USBD_LL_SOF((USBD_HandleTypeDef*)hpcd->pData); |
|||
/* USER CODE BEGIN HAL_PCD_SOFCallback_PostTreatment */ |
|||
|
|||
/* USER CODE END HAL_PCD_SOFCallback_PostTreatment */ |
|||
} |
|||
|
|||
/**
|
|||
* @brief Reset callback. |
|||
* @param hpcd: PCD handle |
|||
* @retval None |
|||
*/ |
|||
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) |
|||
static void PCD_ResetCallback(PCD_HandleTypeDef *hpcd) |
|||
#else |
|||
void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd) |
|||
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ |
|||
{ |
|||
/* USER CODE BEGIN HAL_PCD_ResetCallback_PreTreatment */ |
|||
|
|||
/* USER CODE END HAL_PCD_ResetCallback_PreTreatment */ |
|||
USBD_SpeedTypeDef speed = USBD_SPEED_FULL; |
|||
|
|||
if ( hpcd->Init.speed != PCD_SPEED_FULL) |
|||
{ |
|||
Error_Handler(); |
|||
} |
|||
/* Set Speed. */ |
|||
USBD_LL_SetSpeed((USBD_HandleTypeDef*)hpcd->pData, speed); |
|||
|
|||
/* Reset Device. */ |
|||
USBD_LL_Reset((USBD_HandleTypeDef*)hpcd->pData); |
|||
/* USER CODE BEGIN HAL_PCD_ResetCallback_PostTreatment */ |
|||
|
|||
/* USER CODE END HAL_PCD_ResetCallback_PostTreatment */ |
|||
} |
|||
|
|||
/**
|
|||
* @brief Suspend callback. |
|||
* When Low power mode is enabled the debug cannot be used (IAR, Keil doesn't support it) |
|||
* @param hpcd: PCD handle |
|||
* @retval None |
|||
*/ |
|||
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) |
|||
static void PCD_SuspendCallback(PCD_HandleTypeDef *hpcd) |
|||
#else |
|||
void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd) |
|||
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ |
|||
{ |
|||
/* USER CODE BEGIN HAL_PCD_SuspendCallback_PreTreatment */ |
|||
|
|||
/* USER CODE END HAL_PCD_SuspendCallback_PreTreatment */ |
|||
/* Inform USB library that core enters in suspend Mode. */ |
|||
USBD_LL_Suspend((USBD_HandleTypeDef*)hpcd->pData); |
|||
/* Enter in STOP mode. */ |
|||
/* USER CODE BEGIN 2 */ |
|||
if (hpcd->Init.low_power_enable) |
|||
{ |
|||
/* Set SLEEPDEEP bit and SleepOnExit of Cortex System Control Register. */ |
|||
SCB->SCR |= (uint32_t)((uint32_t)(SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk)); |
|||
} |
|||
/* USER CODE END 2 */ |
|||
/* USER CODE BEGIN HAL_PCD_SuspendCallback_PostTreatment */ |
|||
|
|||
/* USER CODE END HAL_PCD_SuspendCallback_PostTreatment */ |
|||
} |
|||
|
|||
/**
|
|||
* @brief Resume callback. |
|||
* When Low power mode is enabled the debug cannot be used (IAR, Keil doesn't support it) |
|||
* @param hpcd: PCD handle |
|||
* @retval None |
|||
*/ |
|||
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) |
|||
static void PCD_ResumeCallback(PCD_HandleTypeDef *hpcd) |
|||
#else |
|||
void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd) |
|||
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ |
|||
{ |
|||
/* USER CODE BEGIN HAL_PCD_ResumeCallback_PreTreatment */ |
|||
|
|||
/* USER CODE END HAL_PCD_ResumeCallback_PreTreatment */ |
|||
|
|||
/* USER CODE BEGIN 3 */ |
|||
if (hpcd->Init.low_power_enable) |
|||
{ |
|||
/* Reset SLEEPDEEP bit of Cortex System Control Register. */ |
|||
SCB->SCR &= (uint32_t)~((uint32_t)(SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk)); |
|||
SystemClockConfig_Resume(); |
|||
} |
|||
/* USER CODE END 3 */ |
|||
|
|||
USBD_LL_Resume((USBD_HandleTypeDef*)hpcd->pData); |
|||
/* USER CODE BEGIN HAL_PCD_ResumeCallback_PostTreatment */ |
|||
|
|||
/* USER CODE END HAL_PCD_ResumeCallback_PostTreatment */ |
|||
} |
|||
|
|||
/**
|
|||
* @brief ISOOUTIncomplete callback. |
|||
* @param hpcd: PCD handle |
|||
* @param epnum: Endpoint number |
|||
* @retval None |
|||
*/ |
|||
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) |
|||
static void PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) |
|||
#else |
|||
void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) |
|||
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ |
|||
{ |
|||
/* USER CODE BEGIN HAL_PCD_ISOOUTIncompleteCallback_PreTreatment */ |
|||
|
|||
/* USER CODE END HAL_PCD_ISOOUTIncompleteCallback_PreTreatment */ |
|||
USBD_LL_IsoOUTIncomplete((USBD_HandleTypeDef*)hpcd->pData, epnum); |
|||
/* USER CODE BEGIN HAL_PCD_ISOOUTIncompleteCallback_PostTreatment */ |
|||
|
|||
/* USER CODE END HAL_PCD_ISOOUTIncompleteCallback_PostTreatment */ |
|||
} |
|||
|
|||
/**
|
|||
* @brief ISOINIncomplete callback. |
|||
* @param hpcd: PCD handle |
|||
* @param epnum: Endpoint number |
|||
* @retval None |
|||
*/ |
|||
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) |
|||
static void PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) |
|||
#else |
|||
void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) |
|||
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ |
|||
{ |
|||
/* USER CODE BEGIN HAL_PCD_ISOINIncompleteCallback_PreTreatment */ |
|||
|
|||
/* USER CODE END HAL_PCD_ISOINIncompleteCallback_PreTreatment */ |
|||
USBD_LL_IsoINIncomplete((USBD_HandleTypeDef*)hpcd->pData, epnum); |
|||
/* USER CODE BEGIN HAL_PCD_ISOINIncompleteCallback_PostTreatment */ |
|||
|
|||
/* USER CODE END HAL_PCD_ISOINIncompleteCallback_PostTreatment */ |
|||
} |
|||
|
|||
/**
|
|||
* @brief Connect callback. |
|||
* @param hpcd: PCD handle |
|||
* @retval None |
|||
*/ |
|||
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) |
|||
static void PCD_ConnectCallback(PCD_HandleTypeDef *hpcd) |
|||
#else |
|||
void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd) |
|||
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ |
|||
{ |
|||
/* USER CODE BEGIN HAL_PCD_ConnectCallback_PreTreatment */ |
|||
|
|||
/* USER CODE END HAL_PCD_ConnectCallback_PreTreatment */ |
|||
USBD_LL_DevConnected((USBD_HandleTypeDef*)hpcd->pData); |
|||
/* USER CODE BEGIN HAL_PCD_ConnectCallback_PostTreatment */ |
|||
|
|||
/* USER CODE END HAL_PCD_ConnectCallback_PostTreatment */ |
|||
} |
|||
|
|||
/**
|
|||
* @brief Disconnect callback. |
|||
* @param hpcd: PCD handle |
|||
* @retval None |
|||
*/ |
|||
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) |
|||
static void PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd) |
|||
#else |
|||
void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd) |
|||
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ |
|||
{ |
|||
/* USER CODE BEGIN HAL_PCD_DisconnectCallback_PreTreatment */ |
|||
|
|||
/* USER CODE END HAL_PCD_DisconnectCallback_PreTreatment */ |
|||
USBD_LL_DevDisconnected((USBD_HandleTypeDef*)hpcd->pData); |
|||
/* USER CODE BEGIN HAL_PCD_DisconnectCallback_PostTreatment */ |
|||
|
|||
/* USER CODE END HAL_PCD_DisconnectCallback_PostTreatment */ |
|||
} |
|||
|
|||
/* USER CODE BEGIN LowLevelInterface */ |
|||
|
|||
/* USER CODE END LowLevelInterface */ |
|||
|
|||
/*******************************************************************************
|
|||
LL Driver Interface (USB Device Library --> PCD) |
|||
*******************************************************************************/ |
|||
|
|||
/**
|
|||
* @brief Initializes the low level portion of the device driver. |
|||
* @param pdev: Device handle |
|||
* @retval USBD status |
|||
*/ |
|||
USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev) |
|||
{ |
|||
/* Init USB Ip. */ |
|||
hpcd_USB_FS.pData = pdev; |
|||
/* Link the driver to the stack. */ |
|||
pdev->pData = &hpcd_USB_FS; |
|||
/* Enable USB power on Pwrctrl CR2 register. */ |
|||
HAL_PWREx_EnableVddUSB(); |
|||
|
|||
hpcd_USB_FS.Instance = USB; |
|||
hpcd_USB_FS.Init.dev_endpoints = 8; |
|||
hpcd_USB_FS.Init.speed = PCD_SPEED_FULL; |
|||
hpcd_USB_FS.Init.phy_itface = PCD_PHY_EMBEDDED; |
|||
hpcd_USB_FS.Init.Sof_enable = DISABLE; |
|||
hpcd_USB_FS.Init.low_power_enable = DISABLE; |
|||
hpcd_USB_FS.Init.lpm_enable = DISABLE; |
|||
hpcd_USB_FS.Init.battery_charging_enable = DISABLE; |
|||
|
|||
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) |
|||
/* register Msp Callbacks (before the Init) */ |
|||
HAL_PCD_RegisterCallback(&hpcd_USB_FS, HAL_PCD_MSPINIT_CB_ID, PCD_MspInit); |
|||
HAL_PCD_RegisterCallback(&hpcd_USB_FS, HAL_PCD_MSPDEINIT_CB_ID, PCD_MspDeInit); |
|||
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ |
|||
|
|||
if (HAL_PCD_Init(&hpcd_USB_FS) != HAL_OK) |
|||
{ |
|||
Error_Handler( ); |
|||
} |
|||
|
|||
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) |
|||
/* Register USB PCD CallBacks */ |
|||
HAL_PCD_RegisterCallback(&hpcd_USB_FS, HAL_PCD_SOF_CB_ID, PCD_SOFCallback); |
|||
HAL_PCD_RegisterCallback(&hpcd_USB_FS, HAL_PCD_SETUPSTAGE_CB_ID, PCD_SetupStageCallback); |
|||
HAL_PCD_RegisterCallback(&hpcd_USB_FS, HAL_PCD_RESET_CB_ID, PCD_ResetCallback); |
|||
HAL_PCD_RegisterCallback(&hpcd_USB_FS, HAL_PCD_SUSPEND_CB_ID, PCD_SuspendCallback); |
|||
HAL_PCD_RegisterCallback(&hpcd_USB_FS, HAL_PCD_RESUME_CB_ID, PCD_ResumeCallback); |
|||
HAL_PCD_RegisterCallback(&hpcd_USB_FS, HAL_PCD_CONNECT_CB_ID, PCD_ConnectCallback); |
|||
HAL_PCD_RegisterCallback(&hpcd_USB_FS, HAL_PCD_DISCONNECT_CB_ID, PCD_DisconnectCallback); |
|||
/* USER CODE BEGIN RegisterCallBackFirstPart */ |
|||
|
|||
/* USER CODE END RegisterCallBackFirstPart */ |
|||
HAL_PCD_RegisterLpmCallback(&hpcd_USB_FS, PCDEx_LPM_Callback); |
|||
HAL_PCD_RegisterDataOutStageCallback(&hpcd_USB_FS, PCD_DataOutStageCallback); |
|||
HAL_PCD_RegisterDataInStageCallback(&hpcd_USB_FS, PCD_DataInStageCallback); |
|||
HAL_PCD_RegisterIsoOutIncpltCallback(&hpcd_USB_FS, PCD_ISOOUTIncompleteCallback); |
|||
HAL_PCD_RegisterIsoInIncpltCallback(&hpcd_USB_FS, PCD_ISOINIncompleteCallback); |
|||
/* USER CODE BEGIN RegisterCallBackSecondPart */ |
|||
|
|||
/* USER CODE END RegisterCallBackSecondPart */ |
|||
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ |
|||
/* USER CODE BEGIN EndPoint_Configuration */ |
|||
HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x00 , PCD_SNG_BUF, 0x18); |
|||
HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x80 , PCD_SNG_BUF, 0x58); |
|||
/* USER CODE END EndPoint_Configuration */ |
|||
/* USER CODE BEGIN EndPoint_Configuration_CDC */ |
|||
HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x81 , PCD_SNG_BUF, 0xC0); |
|||
HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x01 , PCD_SNG_BUF, 0x110); |
|||
HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x82 , PCD_SNG_BUF, 0x100); |
|||
/* USER CODE END EndPoint_Configuration_CDC */ |
|||
return USBD_OK; |
|||
} |
|||
|
|||
/**
|
|||
* @brief De-Initializes the low level portion of the device driver. |
|||
* @param pdev: Device handle |
|||
* @retval USBD status |
|||
*/ |
|||
USBD_StatusTypeDef USBD_LL_DeInit(USBD_HandleTypeDef *pdev) |
|||
{ |
|||
HAL_StatusTypeDef hal_status = HAL_OK; |
|||
USBD_StatusTypeDef usb_status = USBD_OK; |
|||
|
|||
hal_status = HAL_PCD_DeInit(pdev->pData); |
|||
|
|||
usb_status = USBD_Get_USB_Status(hal_status); |
|||
|
|||
return usb_status; |
|||
} |
|||
|
|||
/**
|
|||
* @brief Starts the low level portion of the device driver. |
|||
* @param pdev: Device handle |
|||
* @retval USBD status |
|||
*/ |
|||
USBD_StatusTypeDef USBD_LL_Start(USBD_HandleTypeDef *pdev) |
|||
{ |
|||
HAL_StatusTypeDef hal_status = HAL_OK; |
|||
USBD_StatusTypeDef usb_status = USBD_OK; |
|||
|
|||
hal_status = HAL_PCD_Start(pdev->pData); |
|||
|
|||
usb_status = USBD_Get_USB_Status(hal_status); |
|||
|
|||
return usb_status; |
|||
} |
|||
|
|||
/**
|
|||
* @brief Stops the low level portion of the device driver. |
|||
* @param pdev: Device handle |
|||
* @retval USBD status |
|||
*/ |
|||
USBD_StatusTypeDef USBD_LL_Stop(USBD_HandleTypeDef *pdev) |
|||
{ |
|||
HAL_StatusTypeDef hal_status = HAL_OK; |
|||
USBD_StatusTypeDef usb_status = USBD_OK; |
|||
|
|||
hal_status = HAL_PCD_Stop(pdev->pData); |
|||
|
|||
usb_status = USBD_Get_USB_Status(hal_status); |
|||
|
|||
return usb_status; |
|||
} |
|||
|
|||
/**
|
|||
* @brief Opens an endpoint of the low level driver. |
|||
* @param pdev: Device handle |
|||
* @param ep_addr: Endpoint number |
|||
* @param ep_type: Endpoint type |
|||
* @param ep_mps: Endpoint max packet size |
|||
* @retval USBD status |
|||
*/ |
|||
USBD_StatusTypeDef USBD_LL_OpenEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr, uint8_t ep_type, uint16_t ep_mps) |
|||
{ |
|||
HAL_StatusTypeDef hal_status = HAL_OK; |
|||
USBD_StatusTypeDef usb_status = USBD_OK; |
|||
|
|||
hal_status = HAL_PCD_EP_Open(pdev->pData, ep_addr, ep_mps, ep_type); |
|||
|
|||
usb_status = USBD_Get_USB_Status(hal_status); |
|||
|
|||
return usb_status; |
|||
} |
|||
|
|||
/**
|
|||
* @brief Closes an endpoint of the low level driver. |
|||
* @param pdev: Device handle |
|||
* @param ep_addr: Endpoint number |
|||
* @retval USBD status |
|||
*/ |
|||
USBD_StatusTypeDef USBD_LL_CloseEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) |
|||
{ |
|||
HAL_StatusTypeDef hal_status = HAL_OK; |
|||
USBD_StatusTypeDef usb_status = USBD_OK; |
|||
|
|||
hal_status = HAL_PCD_EP_Close(pdev->pData, ep_addr); |
|||
|
|||
usb_status = USBD_Get_USB_Status(hal_status); |
|||
|
|||
return usb_status; |
|||
} |
|||
|
|||
/**
|
|||
* @brief Flushes an endpoint of the Low Level Driver. |
|||
* @param pdev: Device handle |
|||
* @param ep_addr: Endpoint number |
|||
* @retval USBD status |
|||
*/ |
|||
USBD_StatusTypeDef USBD_LL_FlushEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) |
|||
{ |
|||
HAL_StatusTypeDef hal_status = HAL_OK; |
|||
USBD_StatusTypeDef usb_status = USBD_OK; |
|||
|
|||
hal_status = HAL_PCD_EP_Flush(pdev->pData, ep_addr); |
|||
|
|||
usb_status = USBD_Get_USB_Status(hal_status); |
|||
|
|||
return usb_status; |
|||
} |
|||
|
|||
/**
|
|||
* @brief Sets a Stall condition on an endpoint of the Low Level Driver. |
|||
* @param pdev: Device handle |
|||
* @param ep_addr: Endpoint number |
|||
* @retval USBD status |
|||
*/ |
|||
USBD_StatusTypeDef USBD_LL_StallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) |
|||
{ |
|||
HAL_StatusTypeDef hal_status = HAL_OK; |
|||
USBD_StatusTypeDef usb_status = USBD_OK; |
|||
|
|||
hal_status = HAL_PCD_EP_SetStall(pdev->pData, ep_addr); |
|||
|
|||
usb_status = USBD_Get_USB_Status(hal_status); |
|||
|
|||
return usb_status; |
|||
} |
|||
|
|||
/**
|
|||
* @brief Clears a Stall condition on an endpoint of the Low Level Driver. |
|||
* @param pdev: Device handle |
|||
* @param ep_addr: Endpoint number |
|||
* @retval USBD status |
|||
*/ |
|||
USBD_StatusTypeDef USBD_LL_ClearStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) |
|||
{ |
|||
HAL_StatusTypeDef hal_status = HAL_OK; |
|||
USBD_StatusTypeDef usb_status = USBD_OK; |
|||
|
|||
hal_status = HAL_PCD_EP_ClrStall(pdev->pData, ep_addr); |
|||
|
|||
usb_status = USBD_Get_USB_Status(hal_status); |
|||
|
|||
return usb_status; |
|||
} |
|||
|
|||
/**
|
|||
* @brief Returns Stall condition. |
|||
* @param pdev: Device handle |
|||
* @param ep_addr: Endpoint number |
|||
* @retval Stall (1: Yes, 0: No) |
|||
*/ |
|||
uint8_t USBD_LL_IsStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) |
|||
{ |
|||
PCD_HandleTypeDef *hpcd = (PCD_HandleTypeDef*) pdev->pData; |
|||
|
|||
if((ep_addr & 0x80) == 0x80) |
|||
{ |
|||
return hpcd->IN_ep[ep_addr & 0x7F].is_stall; |
|||
} |
|||
else |
|||
{ |
|||
return hpcd->OUT_ep[ep_addr & 0x7F].is_stall; |
|||
} |
|||
} |
|||
|
|||
/**
|
|||
* @brief Assigns a USB address to the device. |
|||
* @param pdev: Device handle |
|||
* @param dev_addr: Device address |
|||
* @retval USBD status |
|||
*/ |
|||
USBD_StatusTypeDef USBD_LL_SetUSBAddress(USBD_HandleTypeDef *pdev, uint8_t dev_addr) |
|||
{ |
|||
HAL_StatusTypeDef hal_status = HAL_OK; |
|||
USBD_StatusTypeDef usb_status = USBD_OK; |
|||
|
|||
hal_status = HAL_PCD_SetAddress(pdev->pData, dev_addr); |
|||
|
|||
usb_status = USBD_Get_USB_Status(hal_status); |
|||
|
|||
return usb_status; |
|||
} |
|||
|
|||
/**
|
|||
* @brief Transmits data over an endpoint. |
|||
* @param pdev: Device handle |
|||
* @param ep_addr: Endpoint number |
|||
* @param pbuf: Pointer to data to be sent |
|||
* @param size: Data size |
|||
* @retval USBD status |
|||
*/ |
|||
USBD_StatusTypeDef USBD_LL_Transmit(USBD_HandleTypeDef *pdev, uint8_t ep_addr, uint8_t *pbuf, uint32_t size) |
|||
{ |
|||
HAL_StatusTypeDef hal_status = HAL_OK; |
|||
USBD_StatusTypeDef usb_status = USBD_OK; |
|||
|
|||
hal_status = HAL_PCD_EP_Transmit(pdev->pData, ep_addr, pbuf, size); |
|||
|
|||
usb_status = USBD_Get_USB_Status(hal_status); |
|||
|
|||
return usb_status; |
|||
} |
|||
|
|||
/**
|
|||
* @brief Prepares an endpoint for reception. |
|||
* @param pdev: Device handle |
|||
* @param ep_addr: Endpoint number |
|||
* @param pbuf: Pointer to data to be received |
|||
* @param size: Data size |
|||
* @retval USBD status |
|||
*/ |
|||
USBD_StatusTypeDef USBD_LL_PrepareReceive(USBD_HandleTypeDef *pdev, uint8_t ep_addr, uint8_t *pbuf, uint32_t size) |
|||
{ |
|||
HAL_StatusTypeDef hal_status = HAL_OK; |
|||
USBD_StatusTypeDef usb_status = USBD_OK; |
|||
|
|||
hal_status = HAL_PCD_EP_Receive(pdev->pData, ep_addr, pbuf, size); |
|||
|
|||
usb_status = USBD_Get_USB_Status(hal_status); |
|||
|
|||
return usb_status; |
|||
} |
|||
|
|||
/**
|
|||
* @brief Returns the last transfered packet size. |
|||
* @param pdev: Device handle |
|||
* @param ep_addr: Endpoint number |
|||
* @retval Recived Data Size |
|||
*/ |
|||
uint32_t USBD_LL_GetRxDataSize(USBD_HandleTypeDef *pdev, uint8_t ep_addr) |
|||
{ |
|||
return HAL_PCD_EP_GetRxCount((PCD_HandleTypeDef*) pdev->pData, ep_addr); |
|||
} |
|||
|
|||
/**
|
|||
* @brief Send LPM message to user layer |
|||
* @param hpcd: PCD handle |
|||
* @param msg: LPM message |
|||
* @retval None |
|||
*/ |
|||
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) |
|||
static void PCDEx_LPM_Callback(PCD_HandleTypeDef *hpcd, PCD_LPM_MsgTypeDef msg) |
|||
#else |
|||
void HAL_PCDEx_LPM_Callback(PCD_HandleTypeDef *hpcd, PCD_LPM_MsgTypeDef msg) |
|||
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ |
|||
{ |
|||
/* USER CODE BEGIN LPM_Callback */ |
|||
switch (msg) |
|||
{ |
|||
case PCD_LPM_L0_ACTIVE: |
|||
if (hpcd->Init.low_power_enable) |
|||
{ |
|||
SystemClockConfig_Resume(); |
|||
|
|||
/* Reset SLEEPDEEP bit of Cortex System Control Register. */ |
|||
SCB->SCR &= (uint32_t)~((uint32_t)(SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk)); |
|||
} |
|||
USBD_LL_Resume(hpcd->pData); |
|||
break; |
|||
|
|||
case PCD_LPM_L1_ACTIVE: |
|||
USBD_LL_Suspend(hpcd->pData); |
|||
|
|||
/* Enter in STOP mode. */ |
|||
if (hpcd->Init.low_power_enable) |
|||
{ |
|||
/* Set SLEEPDEEP bit and SleepOnExit of Cortex System Control Register. */ |
|||
SCB->SCR |= (uint32_t)((uint32_t)(SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk)); |
|||
} |
|||
break; |
|||
} |
|||
/* USER CODE END LPM_Callback */ |
|||
} |
|||
|
|||
/**
|
|||
* @brief Delays routine for the USB Device Library. |
|||
* @param Delay: Delay in ms |
|||
* @retval None |
|||
*/ |
|||
void USBD_LL_Delay(uint32_t Delay) |
|||
{ |
|||
HAL_Delay(Delay); |
|||
} |
|||
|
|||
/**
|
|||
* @brief Static single allocation. |
|||
* @param size: Size of allocated memory |
|||
* @retval None |
|||
*/ |
|||
void *USBD_static_malloc(uint32_t size) |
|||
{ |
|||
static uint32_t mem[(sizeof(USBD_CDC_HandleTypeDef)/4)+1];/* On 32-bit boundary */ |
|||
return mem; |
|||
} |
|||
|
|||
/**
|
|||
* @brief Dummy memory free |
|||
* @param p: Pointer to allocated memory address |
|||
* @retval None |
|||
*/ |
|||
void USBD_static_free(void *p) |
|||
{ |
|||
|
|||
} |
|||
|
|||
/* USER CODE BEGIN 5 */ |
|||
/**
|
|||
* @brief Configures system clock after wake-up from USB resume callBack: |
|||
* enable HSI, PLL and select PLL as system clock source. |
|||
* @retval None |
|||
*/ |
|||
static void SystemClockConfig_Resume(void) |
|||
{ |
|||
SystemClock_Config(); |
|||
} |
|||
/* USER CODE END 5 */ |
|||
|
|||
/**
|
|||
* @brief Retuns the USB status depending on the HAL status: |
|||
* @param hal_status: HAL status |
|||
* @retval USB status |
|||
*/ |
|||
USBD_StatusTypeDef USBD_Get_USB_Status(HAL_StatusTypeDef hal_status) |
|||
{ |
|||
USBD_StatusTypeDef usb_status = USBD_OK; |
|||
|
|||
switch (hal_status) |
|||
{ |
|||
case HAL_OK : |
|||
usb_status = USBD_OK; |
|||
break; |
|||
case HAL_ERROR : |
|||
usb_status = USBD_FAIL; |
|||
break; |
|||
case HAL_BUSY : |
|||
usb_status = USBD_BUSY; |
|||
break; |
|||
case HAL_TIMEOUT : |
|||
usb_status = USBD_FAIL; |
|||
break; |
|||
default : |
|||
usb_status = USBD_FAIL; |
|||
break; |
|||
} |
|||
return usb_status; |
|||
} |
|||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
|||
@ -0,0 +1,176 @@ |
|||
/* USER CODE BEGIN Header */ |
|||
/**
|
|||
****************************************************************************** |
|||
* @file : usbd_conf.h |
|||
* @version : v3.0_Cube |
|||
* @brief : Header for usbd_conf.c file. |
|||
****************************************************************************** |
|||
* @attention |
|||
* |
|||
* <h2><center>© Copyright (c) 2021 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: |
|||
* www.st.com/SLA0044 |
|||
* |
|||
****************************************************************************** |
|||
*/ |
|||
/* USER CODE END Header */ |
|||
|
|||
/* Define to prevent recursive inclusion -------------------------------------*/ |
|||
#ifndef __USBD_CONF__H__ |
|||
#define __USBD_CONF__H__ |
|||
|
|||
#ifdef __cplusplus |
|||
extern "C" { |
|||
#endif |
|||
|
|||
/* Includes ------------------------------------------------------------------*/ |
|||
#include <stdio.h> |
|||
#include <stdlib.h> |
|||
#include <string.h> |
|||
#include "stm32wbxx.h" |
|||
#include "stm32wbxx_hal.h" |
|||
|
|||
/* USER CODE BEGIN INCLUDE */ |
|||
|
|||
/* USER CODE END INCLUDE */ |
|||
|
|||
/** @addtogroup USBD_OTG_DRIVER
|
|||
* @brief Driver for Usb device. |
|||
* @{ |
|||
*/ |
|||
|
|||
/** @defgroup USBD_CONF USBD_CONF
|
|||
* @brief Configuration file for Usb otg low level driver. |
|||
* @{ |
|||
*/ |
|||
|
|||
/** @defgroup USBD_CONF_Exported_Variables USBD_CONF_Exported_Variables
|
|||
* @brief Public variables. |
|||
* @{ |
|||
*/ |
|||
|
|||
/* Private variables ---------------------------------------------------------*/ |
|||
/* USER CODE BEGIN PV */ |
|||
/* USER CODE END PV */ |
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/** @defgroup USBD_CONF_Exported_Defines USBD_CONF_Exported_Defines
|
|||
* @brief Defines for configuration of the Usb device. |
|||
* @{ |
|||
*/ |
|||
|
|||
/*---------- -----------*/ |
|||
#define USBD_MAX_NUM_INTERFACES 1U |
|||
/*---------- -----------*/ |
|||
#define USBD_MAX_NUM_CONFIGURATION 1U |
|||
/*---------- -----------*/ |
|||
#define USBD_MAX_STR_DESC_SIZ 512U |
|||
/*---------- -----------*/ |
|||
#define USBD_DEBUG_LEVEL 0U |
|||
/*---------- -----------*/ |
|||
#define USBD_LPM_ENABLED 1U |
|||
/*---------- -----------*/ |
|||
#define USBD_SELF_POWERED 1U |
|||
|
|||
/****************************************/ |
|||
/* #define for FS and HS identification */ |
|||
#define DEVICE_FS 0 |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/** @defgroup USBD_CONF_Exported_Macros USBD_CONF_Exported_Macros
|
|||
* @brief Aliases. |
|||
* @{ |
|||
*/ |
|||
|
|||
/* Memory management macros */ |
|||
|
|||
/** Alias for memory allocation. */ |
|||
#define USBD_malloc (void *)USBD_static_malloc |
|||
|
|||
/** Alias for memory release. */ |
|||
#define USBD_free USBD_static_free |
|||
|
|||
/** Alias for memory set. */ |
|||
#define USBD_memset memset |
|||
|
|||
/** Alias for memory copy. */ |
|||
#define USBD_memcpy memcpy |
|||
|
|||
/** Alias for delay. */ |
|||
#define USBD_Delay HAL_Delay |
|||
/* DEBUG macros */ |
|||
|
|||
#if (USBD_DEBUG_LEVEL > 0) |
|||
#define USBD_UsrLog(...) printf(__VA_ARGS__);\ |
|||
printf("\n"); |
|||
#else |
|||
#define USBD_UsrLog(...) |
|||
#endif |
|||
|
|||
#if (USBD_DEBUG_LEVEL > 1) |
|||
|
|||
#define USBD_ErrLog(...) printf("ERROR: ") ;\ |
|||
printf(__VA_ARGS__);\ |
|||
printf("\n"); |
|||
#else |
|||
#define USBD_ErrLog(...) |
|||
#endif |
|||
|
|||
#if (USBD_DEBUG_LEVEL > 2) |
|||
#define USBD_DbgLog(...) printf("DEBUG : ") ;\ |
|||
printf(__VA_ARGS__);\ |
|||
printf("\n"); |
|||
#else |
|||
#define USBD_DbgLog(...) |
|||
#endif |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/** @defgroup USBD_CONF_Exported_Types USBD_CONF_Exported_Types
|
|||
* @brief Types. |
|||
* @{ |
|||
*/ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/** @defgroup USBD_CONF_Exported_FunctionsPrototype USBD_CONF_Exported_FunctionsPrototype
|
|||
* @brief Declaration of public functions for Usb device. |
|||
* @{ |
|||
*/ |
|||
|
|||
/* Exported functions -------------------------------------------------------*/ |
|||
void *USBD_static_malloc(uint32_t size); |
|||
void USBD_static_free(void *p); |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
#ifdef __cplusplus |
|||
} |
|||
#endif |
|||
|
|||
#endif /* __USBD_CONF__H__ */ |
|||
|
|||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
|||
Loading…
Reference in new issue