基于cubemx H750 的 MSC与CDC复合设备
参考:STM32F7USB复合设备cube-MSC与CDC复合设备
首先得保证MSC作为单独设备时,可以在PC被正确识别。
USB为 USB_OTG_FS
-
RCC使用外部高速时钟
-
先生成一个CDC工程下面配置图。
-
USB_OTG_FS如图
-
USB_Device如图箭头其他默认
-
修改堆栈大小:
按需求设置,HeapSize 应大于 4k -
同样生成一个新的MSC工程不可覆盖原本的工程,MSC配置入下:
-
生成后把CDC工程下Src文件夹里的usbd_cdc_if.c与Inc下的usbd_cdc_if.h复制到MSC工程下Src与Inc文件夹里面,MSC工程下Src文件夹下新建usbd_composite.c与Inc下新建usbd_composite.h
8. 把CDC工程\Middlewares\ST\STM32_USB_Device_Library\Class目录下的CDC文件夹复制到MSC工程下见图
-
添加CDC路径
-
在工程中添加usbd_cdc.c usbd_cdc_if.c usbd_composite.c见图
-
usbd_conf.h 把USBD_MAX_NUM_INTERFACES值 1修改为3
#define USBD_MAX_NUM_INTERFACES 3U//1U
- usbd_cdc.h 修改CDC_IN_EP CDC_OUT_EP CDC_CMD_EP
//#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 */
//替换
#define CDC_IN_EP 0x83 /* EP1 for data IN */
#define CDC_OUT_EP 0x03 /* EP1 for data OUT */
#define CDC_CMD_EP 0x82 /* EP2 for CDC commands */
- usbd_conf.c USBD_LL_Init中新增
USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev)
{
/* Init USB Ip. */
if (pdev->id == DEVICE_FS) {
/* Link the driver to the stack. */
hpcd_USB_OTG_FS.pData = pdev;
pdev->pData = &hpcd_USB_OTG_FS;
hpcd_USB_OTG_FS.Instance = USB_OTG_FS;
hpcd_USB_OTG_FS.Init.dev_endpoints = 9;
hpcd_USB_OTG_FS.Init.speed = PCD_SPEED_FULL;
hpcd_USB_OTG_FS.Init.dma_enable = DISABLE;
hpcd_USB_OTG_FS.Init.phy_itface = PCD_PHY_EMBEDDED;
hpcd_USB_OTG_FS.Init.Sof_enable = DISABLE;
hpcd_USB_OTG_FS.Init.low_power_enable = DISABLE;
hpcd_USB_OTG_FS.Init.lpm_enable = DISABLE;
hpcd_USB_OTG_FS.Init.battery_charging_enable = DISABLE;
hpcd_USB_OTG_FS.Init.vbus_sensing_enable = DISABLE;
hpcd_USB_OTG_FS.Init.use_dedicated_ep1 = DISABLE;
if (HAL_PCD_Init(&hpcd_USB_OTG_FS) != HAL_OK)
{
Error_Handler( );
}
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
/* Register USB PCD CallBacks */
HAL_PCD_RegisterCallback(&hpcd_USB_OTG_FS, HAL_PCD_SOF_CB_ID, PCD_SOFCallback);
HAL_PCD_RegisterCallback(&hpcd_USB_OTG_FS, HAL_PCD_SETUPSTAGE_CB_ID, PCD_SetupStageCallback);
HAL_PCD_RegisterCallback(&hpcd_USB_OTG_FS, HAL_PCD_RESET_CB_ID, PCD_ResetCallback);
HAL_PCD_RegisterCallback(&hpcd_USB_OTG_FS, HAL_PCD_SUSPEND_CB_ID, PCD_SuspendCallback);
HAL_PCD_RegisterCallback(&hpcd_USB_OTG_FS, HAL_PCD_RESUME_CB_ID, PCD_ResumeCallback);
HAL_PCD_RegisterCallback(&hpcd_USB_OTG_FS, HAL_PCD_CONNECT_CB_ID, PCD_ConnectCallback);
HAL_PCD_RegisterCallback(&hpcd_USB_OTG_FS, HAL_PCD_DISCONNECT_CB_ID, PCD_DisconnectCallback);
HAL_PCD_RegisterDataOutStageCallback(&hpcd_USB_OTG_FS, PCD_DataOutStageCallback);
HAL_PCD_RegisterDataInStageCallback(&hpcd_USB_OTG_FS, PCD_DataInStageCallback);
HAL_PCD_RegisterIsoOutIncpltCallback(&hpcd_USB_OTG_FS, PCD_ISOOUTIncompleteCallback);
HAL_PCD_RegisterIsoInIncpltCallback(&hpcd_USB_OTG_FS, PCD_ISOINIncompleteCallback);
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
HAL_PCDEx_SetRxFiFo(&hpcd_USB_OTG_FS, 0x80);
HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 0, 0x40);
HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 1, 0x80);
HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 1, 0x40); //新增
HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 3, 0x40);
}
return USBD_OK;
}
- usb_device.c 修改MX_USB_DEVICE_Init与SER CODE BEGIN Includes中新增usbd_composite.h
/* USER CODE BEGIN Includes */
#include "usbd_composite.h"
/* USER CODE END Includes */
void MX_USB_DEVICE_Init(void)
{
/* USER CODE BEGIN USB_DEVICE_Init_PreTreatment */
#if 0
/* USER CODE END USB_DEVICE_Init_PreTreatment */
/* Init Device Library, add supported class and start the library. */
if (USBD_Init(&hUsbDeviceFS, &FS_Desc, DEVICE_FS) != USBD_OK)
{
Error_Handler();
}
if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_MSC) != USBD_OK)
{
Error_Handler();
}
if (USBD_MSC_RegisterStorage(&hUsbDeviceFS, &USBD_Storage_Interface_fops_FS) != USBD_OK)
{
Error_Handler();
}
if (USBD_Start(&hUsbDeviceFS) != USBD_OK)
{
Error_Handler();
}
/* USER CODE BEGIN USB_DEVICE_Init_PostTreatment */
#endif
if (USBD_Init(&hUsbDeviceFS, &FS_Desc, DEVICE_FS) != USBD_OK)
{
Error_Handler();
}
if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_COMPOSITE) != USBD_OK)
{
Error_Handler();
}
if (USBD_Start(&hUsbDeviceFS) != USBD_OK)
{
Error_Handler();
}
HAL_PWREx_EnableUSBVoltageDetector();
/* USER CODE END USB_DEVICE_Init_PostTreatment */
}
15.在usbd_composite.h中新增代码
#ifndef __USBD_COMPOSITE_H
#define __USBD_COMPOSITE_H
#include "usbd_ioreq.h"
#include "usbd_cdc.h"
#include "usbd_msc.h"
#define MC_MAX_FS_PACKET 0x40
#define USB_MC_CONFIG_DESC_SIZ 106
#define MC_MSC_EPIN_ADDR MSC_EPIN_ADDR
#define MC_MSC_EPOUT_ADDR MSC_EPOUT_ADDR
#define MC_CDC_IN_EP CDC_IN_EP
#define MC_CDC_OUT_EP CDC_OUT_EP
#define MC_CDC_CMD_EP CDC_CMD_EP
extern USBD_ClassTypeDef USBD_COMPOSITE;
#endif /* __USBD_MC_H */
16.在usbd_composite.c中新增代码
#include "usbd_composite.h"
#include "usbd_def.h"
#include "usbd_msc.h"
#include "usbd_cdc.h"
#include "usbd_storage_if.h"
#include "usbd_cdc_if.h"
/** @defgroup MC_CORE_Private_FunctionPrototypes
* @{
*/
USBD_CDC_HandleTypeDef *pCDCData;
USBD_MSC_BOT_HandleTypeDef *pMSCData;
uint8_t USBD_MC_Init (USBD_HandleTypeDef *pdev,
uint8_t cfgidx);
uint8_t USBD_MC_DeInit (USBD_HandleTypeDef *pdev,
uint8_t cfgidx);
uint8_t USBD_MC_Setup (USBD_HandleTypeDef *pdev,
USBD_SetupReqTypedef *req);
uint8_t USBD_MC_DataIn (USBD_HandleTypeDef *pdev,
uint8_t epnum);
uint8_t USBD_MC_DataOut (USBD_HandleTypeDef *pdev,
uint8_t epnum);
uint8_t *USBD_MC_GetHSCfgDesc (uint16_t *length);
uint8_t *USBD_MC_GetFSCfgDesc (uint16_t *length);
uint8_t *USBD_MC_GetOtherSpeedCfgDesc (uint16_t *length);
uint8_t *USBD_MC_GetDeviceQualifierDescriptor (uint16_t *length);
static uint8_t USBD_MC_RxReady (USBD_HandleTypeDef *pdev);
static void MC_Switch_MSC(USBD_HandleTypeDef *pdev);
static void MC_Switch_CDC(USBD_HandleTypeDef *pdev);
/**
* @}
*/
extern USBD_HandleTypeDef hUsbDeviceFS;
/** @defgroup MC_CORE_Private_Variables
* @{
*/
USBD_ClassTypeDef USBD_COMPOSITE =
{
USBD_MC_Init,
USBD_MC_DeInit,
USBD_MC_Setup,
NULL, /*EP0_TxSent*/
USBD_MC_RxReady, /*EP0_RxReady*/
USBD_MC_DataIn,
USBD_MC_DataOut,
NULL, /*SOF */
NULL,
NULL,
USBD_MC_GetHSCfgDesc,
USBD_MC_GetFSCfgDesc,
USBD_MC_GetOtherSpeedCfgDesc,
USBD_MC_GetDeviceQualifierDescriptor,
};
/* USB Mass storage device Configuration Descriptor */
/* All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */
uint8_t USBD_MC_CfgDesc[USB_MC_CONFIG_DESC_SIZ] =
{
/*Configuration Descriptor*/
0x09, /* bLength: Configuration Descriptor size */
USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
USB_MC_CONFIG_DESC_SIZ, /* wTotalLength:no of returned bytes */
0x00,
0x03, /* bNumInterfaces: 3 interface */
0x01, /* bConfigurationValue: Configuration value */
0x00, /* iConfiguration: Index of string descriptor describing the configuration */
0xC0, /* bmAttributes: self powered */
0x32, /* MaxPower 0 mA */
/*---------------------------------------------------------------------------*/
// IAD
0x08, //描述符大小
0x0B, //IAD描述符类型
0x00, // bFirstInterface
0x02, // bInterfaceCount
0x02, // bFunctionClass: CDC Class
0x02, // bFunctionSubClass
0x01, // bFunctionProtocol
0x00, // iFunction
/*---------------------------------------------------------------------------*/
/*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 */
MC_CDC_CMD_EP, /* bEndpointAddress */
0x03, /* bmAttributes: Interrupt */
LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize: */
HIBYTE(CDC_CMD_PACKET_SIZE),
0x10, /* 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 */
MC_CDC_OUT_EP, /* bEndpointAddress */
0x02, /* bmAttributes: Bulk */
LOBYTE(MC_MAX_FS_PACKET), /* wMaxPacketSize: */
HIBYTE(MC_MAX_FS_PACKET),
0x00, /* bInterval: ignore for Bulk transfer */
/*Endpoint IN Descriptor*/
0x07, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
MC_CDC_IN_EP, /* bEndpointAddress */
0x02, /* bmAttributes: Bulk */
LOBYTE(MC_MAX_FS_PACKET), /* wMaxPacketSize: */
HIBYTE(MC_MAX_FS_PACKET),
0x00, /* bInterval: ignore for Bulk transfer */
/*---------------------------------------------------------------------------*/
// IAD
0x08, //描述符大小
0x0B, //IAD描述符类型
0x02, // bFirstInterface
0x01, // bInterfaceCount
0x08, // bFunctionClass: MASS STORAGE Class
0x06, // bFunctionSubClass
0x50, // bFunctionProtocol
0x01, // iFunction
/******************** Mass Storage interface ********************/
0x09, /* bLength: Interface Descriptor size */
0x04, /* bDescriptorType: */
0x02, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x02, /* bNumEndpoints*/
0x08, /* bInterfaceClass: MSC Class */
0x06, /* bInterfaceSubClass : SCSI transparent*/
0x50, /* nInterfaceProtocol */
0x05, /* iInterface: */
/******************** Mass Storage Endpoints ********************/
0x07, /*Endpoint descriptor length = 7*/
0x05, /*Endpoint descriptor type */
MC_MSC_EPIN_ADDR, /*Endpoint address (IN, address 1) */
0x02, /*Bulk endpoint type */
LOBYTE(MC_MAX_FS_PACKET),
HIBYTE(MC_MAX_FS_PACKET),
0x00, /*Polling interval in milliseconds */
0x07, /*Endpoint descriptor length = 7 */
0x05, /*Endpoint descriptor type */
MC_MSC_EPOUT_ADDR, /*Endpoint address (OUT, address 1) */
0x02, /*Bulk endpoint type */
LOBYTE(MC_MAX_FS_PACKET),
HIBYTE(MC_MAX_FS_PACKET),
0x00 /*Polling interval in milliseconds*/
};
uint8_t USBD_MC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] =
{
USB_LEN_DEV_QUALIFIER_DESC,
USB_DESC_TYPE_DEVICE_QUALIFIER,
0x00,
0x02,
0x00,
0x00,
0x00,
MC_MAX_FS_PACKET,
0x01,
0x00,
};
/**
* @brief USBD_MC_Init
* Initialize the mass storage configuration
* @param pdev: device instance
* @param cfgidx: configuration index
* @retval status
*/
uint8_t USBD_MC_Init (USBD_HandleTypeDef *pdev, uint8_t cfgidx)
{
uint8_t ret = 0U;
USBD_CDC_HandleTypeDef * hcdc;
MC_Switch_CDC(pdev);
USBD_LL_OpenEP(pdev,
MC_CDC_IN_EP,
USBD_EP_TYPE_BULK,
MC_MAX_FS_PACKET);
USBD_LL_OpenEP(pdev,
MC_CDC_OUT_EP,
USBD_EP_TYPE_BULK,
MC_MAX_FS_PACKET);
USBD_LL_OpenEP(pdev,
MC_CDC_CMD_EP,
USBD_EP_TYPE_INTR,
CDC_CMD_PACKET_SIZE);
hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Init();
hcdc->TxState =0;
hcdc->RxState =0;
USBD_LL_PrepareReceive(pdev,
MC_CDC_OUT_EP,
hcdc->RxBuffer,
MC_MAX_FS_PACKET);
pCDCData = pdev->pClassData;
MC_Switch_MSC(pdev);
USBD_LL_OpenEP(pdev,
MC_MSC_EPOUT_ADDR,
USBD_EP_TYPE_BULK,
MC_MAX_FS_PACKET);
USBD_LL_OpenEP(pdev,
MC_MSC_EPIN_ADDR,
USBD_EP_TYPE_BULK,
MC_MAX_FS_PACKET);
MSC_BOT_Init(pdev);
pMSCData = pdev->pClassData;
if(pdev->pClassData == NULL)
{
ret = USBD_FAIL;
}
return ret;
}
/**
* @brief USBD_MC_DeInit
* DeInitilaize the mass storage configuration
* @param pdev: device instance
* @param cfgidx: configuration index
* @retval status
*/
uint8_t USBD_MC_DeInit (USBD_HandleTypeDef *pdev,
uint8_t cfgidx)
{
return USBD_OK;
}
/**
* @brief USBD_MC_Setup
* Handle the MC specific requests
* @param pdev: device instance
* @param req: USB request
* @retval status
*/
uint8_t USBD_MC_Setup (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
{
if(req->wIndex == 0x0002)
{
MC_Switch_MSC(pdev);
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef*) pdev->pClassData;
switch (req->bmRequest & USB_REQ_TYPE_MASK)
{
/* Class request */
case USB_REQ_TYPE_CLASS :
switch (req->bRequest)
{
case BOT_GET_MAX_LUN :
if((req->wValue == 0) &&
(req->wLength == 1) &&
((req->bmRequest & 0x80) == 0x80))
{
hmsc->max_lun = ((USBD_StorageTypeDef *)pdev->pUserData)->GetMaxLun();
USBD_CtlSendData (pdev,
(uint8_t *)&hmsc->max_lun,
1);
}
else
{
USBD_CtlError(pdev , req);
return USBD_FAIL;
}
break;
case BOT_RESET :
if((req->wValue == 0) &&
(req->wLength == 0) &&
((req->bmRequest & 0x80) != 0x80))
{
MSC_BOT_Reset(pdev);
}
else
{
USBD_CtlError(pdev , req);
return USBD_FAIL;
}
break;
default:
USBD_CtlError(pdev , req);
return USBD_FAIL;
}
break;
/* Interface & Endpoint request */
case USB_REQ_TYPE_STANDARD:
switch (req->bRequest)
{
case USB_REQ_GET_INTERFACE :
USBD_CtlSendData (pdev,
(uint8_t *)&hmsc->interface,
1);
break;
case USB_REQ_SET_INTERFACE :
hmsc->interface = (uint8_t)(req->wValue);
break;
case USB_REQ_CLEAR_FEATURE:
/* Flush the FIFO and Clear the stall status */
USBD_LL_FlushEP(pdev, (uint8_t)req->wIndex);
/* Reactivate the EP */
USBD_LL_CloseEP (pdev , (uint8_t)req->wIndex);
if((((uint8_t)req->wIndex) & 0x80) == 0x80)
{
if(pdev->dev_speed == USBD_SPEED_HIGH )
{
/* Open EP IN */
USBD_LL_OpenEP(pdev,
MC_MSC_EPIN_ADDR,
USBD_EP_TYPE_BULK,
MSC_MAX_HS_PACKET);
}
else
{
/* Open EP IN */
USBD_LL_OpenEP(pdev,
MC_MSC_EPIN_ADDR,
USBD_EP_TYPE_BULK,
MSC_MAX_FS_PACKET);
}
}
else
{
if(pdev->dev_speed == USBD_SPEED_HIGH )
{
/* Open EP IN */
USBD_LL_OpenEP(pdev,
MC_MSC_EPOUT_ADDR,
USBD_EP_TYPE_BULK,
MSC_MAX_HS_PACKET);
}
else
{
/* Open EP IN */
USBD_LL_OpenEP(pdev,
MC_MSC_EPOUT_ADDR,
USBD_EP_TYPE_BULK,
MSC_MAX_FS_PACKET);
}
}
/* Handle BOT error */
MSC_BOT_CplClrFeature(pdev, (uint8_t)req->wIndex);
break;
}
break;
default:
break;
}
}
else
{
MC_Switch_CDC(pdev);
static uint8_t ifalt = 0;
USBD_CDC_HandleTypeDef * hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData;
switch (req->bmRequest & USB_REQ_TYPE_MASK)
{
case USB_REQ_TYPE_CLASS :
if (req->wLength)
{
if (req->bmRequest & 0x80)
{
((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest,
(uint8_t *)hcdc->data,
req->wLength);
USBD_CtlSendData (pdev,
(uint8_t *)hcdc->data,
req->wLength);
}
else
{
hcdc->CmdOpCode = req->bRequest;
hcdc->CmdLength = req->wLength;
USBD_CtlPrepareRx (pdev,
(uint8_t *)hcdc->data,
req->wLength);
}
}
else
{
((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest,
(uint8_t*)req,
0);
}
break;
case USB_REQ_TYPE_STANDARD:
switch (req->bRequest)
{
case USB_REQ_GET_INTERFACE :
USBD_CtlSendData (pdev,
&ifalt,
1);
break;
case USB_REQ_SET_INTERFACE :
break;
}
default:
break;
}
}
return USBD_OK;
}
/**
* @brief USBD_MC_DataIn
* handle data IN Stage
* @param pdev: device instance
* @param epnum: endpoint index
* @retval status
*/
uint8_t USBD_MC_DataIn (USBD_HandleTypeDef *pdev,
uint8_t epnum)
{
if(epnum == (MC_MSC_EPIN_ADDR & 0x7f))
{
MC_Switch_MSC(pdev);
MSC_BOT_DataIn(pdev , epnum);
}
else if(epnum == (MC_CDC_IN_EP & 0x7f))
{
USBD_CDC_HandleTypeDef *hcdc;
MC_Switch_CDC(pdev);
hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
hcdc->TxState = 0;
}
return USBD_OK;
}
/**
* @brief USBD_MC_DataOut
* handle data OUT Stage
* @param pdev: device instance
* @param epnum: endpoint index
* @retval status
*/
uint8_t USBD_MC_DataOut (USBD_HandleTypeDef *pdev,
uint8_t epnum)
{
if(epnum == MC_MSC_EPOUT_ADDR)
{
MC_Switch_MSC(pdev);
MSC_BOT_DataOut(pdev , epnum);
}
else if(epnum == MC_CDC_OUT_EP)
{
USBD_CDC_HandleTypeDef *hcdc;
MC_Switch_CDC(pdev);
hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
hcdc->RxLength = USBD_LL_GetRxDataSize (pdev, epnum);
((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Receive(hcdc->RxBuffer, &hcdc->RxLength);
}
return USBD_OK;
}
/**
* @brief USBD_MC_GetHSCfgDesc
* return configuration descriptor
* @param length : pointer data length
* @retval pointer to descriptor buffer
*/
uint8_t *USBD_MC_GetHSCfgDesc (uint16_t *length)
{
*length = sizeof (USBD_MC_CfgDesc);
return USBD_MC_CfgDesc;
}
/**
* @brief USBD_MC_GetFSCfgDesc
* return configuration descriptor
* @param length : pointer data length
* @retval pointer to descriptor buffer
*/
uint8_t *USBD_MC_GetFSCfgDesc (uint16_t *length)
{
*length = sizeof (USBD_MC_CfgDesc);
return USBD_MC_CfgDesc;
}
/**
* @brief USBD_MC_GetOtherSpeedCfgDesc
* return other speed configuration descriptor
* @param length : pointer data length
* @retval pointer to descriptor buffer
*/
uint8_t *USBD_MC_GetOtherSpeedCfgDesc (uint16_t *length)
{
*length = sizeof (USBD_MC_CfgDesc);
return USBD_MC_CfgDesc;
}
/**
* @brief DeviceQualifierDescriptor
* return Device Qualifier descriptor
* @param length : pointer data length
* @retval pointer to descriptor buffer
*/
uint8_t *USBD_MC_GetDeviceQualifierDescriptor (uint16_t *length)
{
*length = sizeof (USBD_MC_DeviceQualifierDesc);
return USBD_MC_DeviceQualifierDesc;
}
/**
* @brief USBD_MC_RegisterStorage
* @param fops: storage callback
* @retval status
*/
static uint8_t USBD_MC_RxReady (USBD_HandleTypeDef *pdev)
{
USBD_CDC_HandleTypeDef *hcdc;
MC_Switch_CDC(pdev);
hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
if((pdev->pUserData != NULL) && (hcdc->CmdOpCode != 0xFF))
{
((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(hcdc->CmdOpCode,
(uint8_t *)hcdc->data,
hcdc->CmdLength);
hcdc->CmdOpCode = 0xFF;
}
return USBD_OK;
}
static void MC_Switch_MSC(USBD_HandleTypeDef *pdev)
{
static USBD_MSC_BOT_HandleTypeDef msc_handle;
USBD_MSC_RegisterStorage(pdev, &USBD_Storage_Interface_fops_FS);
pdev->pClassData = &msc_handle;
}
static void MC_Switch_CDC(USBD_HandleTypeDef *pdev)
{
static USBD_CDC_HandleTypeDef cdc_handle;
USBD_CDC_RegisterInterface(pdev, &USBD_Interface_fops_FS);
pdev->pClassData = &cdc_handle;
}
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
通过以上修改后电脑电脑端显示USB复合设备MSC+CDC
17.在usbd_cdc_if.c CDC_Receive_FS /* USER CODE BEGIN 6 */ 增加发送测试
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);
CDC_Transmit_FS(UserRxBufferFS, *Len); //把接收的返回
return (USBD_OK);
/* USER CODE END 6 */
}