/
stm32f407xx.h
#define USB_OTG_HS_PERIPH_BASE 0x40040000UL
#define USB_OTG_HS ((USB_OTG_GlobalTypeDef *) USB_OTG_HS_PERIPH_BASE)
//
//
定义全局变量 USBD_HandleTypeDef hUsbDeviceHS;并默认全零初始化/* 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[USBD_MAX_SUPPORTED_CLASS];void *pClassData;void *pClassDataCmsit[USBD_MAX_SUPPORTED_CLASS];void *pUserData[USBD_MAX_SUPPORTED_CLASS];void *pData;void *pBosDesc;void *pConfDesc;uint32_t classId;uint32_t NumClasses;
#ifdef USE_USBD_COMPOSITEUSBD_CompositeElementTypeDef tclasslist[USBD_MAX_SUPPORTED_CLASS];
#endif /* USE_USBD_COMPOSITE */
} USBD_HandleTypeDef;
//
//
定义全局变量USBD_DescriptorsTypeDef HS_Desc,并赋值初始化
/** @defgroup USBD_DESC_Private_Variables USBD_DESC_Private_Variables* @brief Private variables.* @{*/USBD_DescriptorsTypeDef HS_Desc =
{USBD_HS_DeviceDescriptor
, USBD_HS_LangIDStrDescriptor
, USBD_HS_ManufacturerStrDescriptor
, USBD_HS_ProductStrDescriptor
, USBD_HS_SerialStrDescriptor
, USBD_HS_ConfigStrDescriptor
, USBD_HS_InterfaceStrDescriptor
#if (USBD_LPM_ENABLED == 1)
, USBD_HS_USR_BOSDescriptor
#endif /* (USBD_LPM_ENABLED == 1) */
};//=====================================================//
//=====================================================//
/* 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 /* USBD_CLASS_USER_STRING_DESC */
#if ((USBD_LPM_ENABLED == 1U) || (USBD_CLASS_BOS_ENABLED == 1))uint8_t *(*GetBOSDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length);
#endif /* (USBD_LPM_ENABLED == 1U) || (USBD_CLASS_BOS_ENABLED == 1) */
} USBD_DescriptorsTypeDef;//=====================================================//
//=====================================================//
/*** @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_HS_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{UNUSED(speed);*length = sizeof(USBD_HS_DeviceDesc);return USBD_HS_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_HS_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_HS_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{if(speed == 0){USBD_GetString((uint8_t *)USBD_PRODUCT_STRING_HS, USBD_StrDesc, length);}else{USBD_GetString((uint8_t *)USBD_PRODUCT_STRING_HS, 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_HS_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_HS_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_HS_SerialStrDescriptor *//* USER CODE END USBD_HS_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_HS_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{if(speed == USBD_SPEED_HIGH){USBD_GetString((uint8_t *)USBD_CONFIGURATION_STRING_HS, USBD_StrDesc, length);}else{USBD_GetString((uint8_t *)USBD_CONFIGURATION_STRING_HS, 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_HS_InterfaceStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{if(speed == 0){USBD_GetString((uint8_t *)USBD_INTERFACE_STRING_HS, USBD_StrDesc, length);}else{USBD_GetString((uint8_t *)USBD_INTERFACE_STRING_HS, USBD_StrDesc, length);}return USBD_StrDesc;
}#if (USBD_LPM_ENABLED == 1)
/*** @brief Return the BOS descriptor* @param speed : Current device speed* @param length : Pointer to data length variable* @retval Pointer to descriptor buffer*/
uint8_t * USBD_HS_USR_BOSDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{UNUSED(speed);*length = sizeof(USBD_HS_BOSDesc);return (uint8_t*)USBD_HS_BOSDesc;
}
#endif /* (USBD_LPM_ENABLED == 1) */
全局宏定义,区分高速和全速USB
/* #define for FS and HS identification */
#define DEVICE_FS 0
#define DEVICE_HS 1
//
//
定义全局变量USBD_CDC,并赋值初始化
/* 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,
#ifdef USE_USBD_COMPOSITENULL,NULL,NULL,NULL,
#elseUSBD_CDC_GetHSCfgDesc,USBD_CDC_GetFSCfgDesc,USBD_CDC_GetOtherSpeedCfgDesc,USBD_CDC_GetDeviceQualifierDescriptor,
#endif /* USE_USBD_COMPOSITE */
};//=====================================================//
//=====================================================//
/*** @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 /* (USBD_DEBUG_LEVEL > 1U) */return USBD_FAIL;}/* link the class to the USB Device handle */pdev->pClass[0] = pclass;/* Get Device Configuration Descriptor */
#ifdef USE_USB_HSif (pdev->pClass[pdev->classId]->GetHSConfigDescriptor != NULL){pdev->pConfDesc = (void *)pdev->pClass[pdev->classId]->GetHSConfigDescriptor(&len);}
#else /* Default USE_USB_FS */if (pdev->pClass[pdev->classId]->GetFSConfigDescriptor != NULL){pdev->pConfDesc = (void *)pdev->pClass[pdev->classId]->GetFSConfigDescriptor(&len);}
#endif /* USE_USB_FS *//* Increment the NumClasses */pdev->NumClasses ++;return USBD_OK;
}//=====================================================//
//=====================================================//
/*** @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 = USBD_OK;uint8_t idx;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{/* Find the class ID relative to the current request */switch (pdev->request.bmRequest & 0x1FU){case USB_REQ_RECIPIENT_DEVICE:/* Device requests must be managed by the first instantiated class(or duplicated by all classes for simplicity) */idx = 0U;break;case USB_REQ_RECIPIENT_INTERFACE:idx = USBD_CoreFindIF(pdev, LOBYTE(pdev->request.wIndex));break;case USB_REQ_RECIPIENT_ENDPOINT:idx = USBD_CoreFindEP(pdev, LOBYTE(pdev->request.wIndex));break;default:/* Back to the first class in case of doubt */idx = 0U;break;}if (idx < USBD_MAX_SUPPORTED_CLASS){/* Setup the class ID and route the request to the relative class function */if (pdev->dev_state == USBD_STATE_CONFIGURED){if (pdev->pClass[idx]->EP0_RxReady != NULL){pdev->classId = idx;pdev->pClass[idx]->EP0_RxReady(pdev);}}}(void)USBD_CtlSendStatus(pdev);}}else{
#if 0if (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}}//if (epnum == 0U)else{/* Get the class index relative to this interface */idx = USBD_CoreFindEP(pdev, (epnum & 0x7FU));if (((uint16_t)idx != 0xFFU) && (idx < USBD_MAX_SUPPORTED_CLASS)){/* Call the class data out function to manage the request */if (pdev->dev_state == USBD_STATE_CONFIGURED){if (pdev->pClass[idx]->DataOut != NULL){pdev->classId = idx;ret = (USBD_StatusTypeDef)pdev->pClass[idx]->DataOut(pdev, epnum);//***//}}if (ret != USBD_OK){return ret;}}}return USBD_OK;
}
/