IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 基于cubemx H750 的 MSC与CDC复合设备 -> 正文阅读

[嵌入式]基于cubemx H750 的 MSC与CDC复合设备

基于cubemx H750 的 MSC与CDC复合设备

参考:STM32F7USB复合设备cube-MSC与CDC复合设备

首先得保证MSC作为单独设备时,可以在PC被正确识别。

USB为 USB_OTG_FS

  1. RCC使用外部高速时钟

  2. 先生成一个CDC工程下面配置图。
    在这里插入图片描述

  3. USB_OTG_FS如图
    在这里插入图片描述

  4. USB_Device如图箭头其他默认
    在这里插入图片描述

  5. 修改堆栈大小:
    在这里插入图片描述
    按需求设置,HeapSize 应大于 4k

  6. 同样生成一个新的MSC工程不可覆盖原本的工程,MSC配置入下:
    在这里插入图片描述

  7. 生成后把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工程下见图
在这里插入图片描述

  1. 添加CDC路径
    在这里插入图片描述

  2. 在工程中添加usbd_cdc.c usbd_cdc_if.c usbd_composite.c见图
    在这里插入图片描述

  3. usbd_conf.h 把USBD_MAX_NUM_INTERFACES值 1修改为3

#define USBD_MAX_NUM_INTERFACES        3U//1U
  1. 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 */
  1. 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;
}
  1. 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 */
}
  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-08-04 11:22:45  更:2021-08-04 11:23:30 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年4日历 -2024/4/29 2:08:02-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码