搜索
查看: 3691|回复: 7

[分享] STM32F7USB复合设备cube-MSC与CDC复合设备

[复制链接]

该用户从未签到

1

主题

64

帖子

5

蝴蝶豆

高级会员

最后登录
2023-3-19
发表于 2019-6-23 13:44:25 | 显示全部楼层 |阅读模式
本帖最后由 289466080 于 2019-6-23 15:56 编辑

    最近做个USB复合设备CDC+MSC,在网上找了好多基本都是F103做的复合设备,带OTG芯片USB复合设备网上很少可能是我搜索的关键字不够理想有的不够全面,官方给了一个视频教程但是没有参考代码,社区里面有分享到github我按照后也不能实现,后结合F1与github分享的+官方视频,实现了在STM32F730R8T6上面USB复合设备,分享下怎样用cube生成的代码实现USB复合设备(带OTG的芯片).

参考:
github分享
http://github.com/uwyciw/CDC_MSC
官方视频
https://www.stmcu.org.cn/video/index/detail/id-3988
F103
http://www.bbsmax.com/A/kjdwBXA5Np/


cube 5.2.1
hal  stm32cube_fw_f7_v1150.zip

USB为 USB_OTG_FS

1.先生成一个CDC工程下面配置图。
RCC如图箭头其他默认
RCC.png
USB_OTG_FS如图箭头其他默认
USB_OTG_FS.png
USB_Device
如图箭头其他默认
USB_Device.png
Clock如图箭头其他默认我用的16M晶振比8M便宜
Clock.PNG

Project如图箭头其他默认
Project.png
code如图箭头其他默认
code.png
2.同样生成一个新的MSC工程不可覆盖原本的工程只需修改下图与工程名其他一样

USB_Device-MSC.png


3.生成后把CDC工程下Src文件夹里的usbd_cdc_if.c与Inc下的usbd_cdc_if.h复制到MSC工程下Src与Inc文件夹里面,MSC工程下Src文件夹下新建usbd_composite.c与Inc下新建usbd_composite.h

h.png

4.把CDC工程\Middlewares\ST\STM32_USB_Device_Library\Class目录下的CDC文件夹复制到MSC工程下见图
cdc.png
5.添加CDC路径

CDC-PATHS.png

6.在工程中添加usbd_cdc.c usbd_cdc_if.c usbd_composite.c见图
keil-add.png

7. usbd_conf.h 把USBD_MAX_NUM_INTERFACES值 1修改为3
  1. /*---------- -----------*/
  2. #define USBD_MAX_NUM_INTERFACES     3U    //1U
  3. /*---------- -----------*/
复制代码
8. usbd_cdc.h 修改CDC_IN_EP CDC_OUT_EP CDC_CMD_EP
  1. //#define CDC_IN_EP                                   0x81U  /* EP1 for data IN */
  2. //#define CDC_OUT_EP                                  0x01U  /* EP1 for data OUT */
  3. //#define CDC_CMD_EP                                  0x82U  /* EP2 for CDC commands */
  4. #define CDC_IN_EP                                   0x83  /* EP1 for data IN */
  5. #define CDC_OUT_EP                                  0x03  /* EP1 for data OUT */
  6. #define CDC_CMD_EP                                  0x82  /* EP2 for CDC commands */
复制代码
9. usbd_conf.c  USBD_LL_Init中新增
  1.   HAL_PCDEx_SetRxFiFo(&hpcd_USB_OTG_FS, 0x80);
  2.   HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 0, 0x40);
  3.   HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 1, 0x80);
  4.   
  5.   HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 1, 0x40);   //新增
  6.   HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 3, 0x40);
复制代码
10. usb_device.c 修改MX_USB_DEVICE_Init与SER CODE BEGIN Includes中新增usbd_composite.h


  1. /* USER CODE BEGIN Includes */
  2. #include "usbd_composite.h"
  3. /* USER CODE END Includes */

  4. void MX_USB_DEVICE_Init(void)
  5. {
  6.   /* USER CODE BEGIN USB_DEVICE_Init_PreTreatment */
  7.   
  8.   /* USER CODE END USB_DEVICE_Init_PreTreatment */
  9.   
  10.   /* Init Device Library, add supported class and start the library. */
  11.   if (USBD_Init(&hUsbDeviceFS, &FS_Desc, DEVICE_FS) != USBD_OK)
  12.   {
  13.     Error_Handler();
  14.   }
  15.   if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_COMPOSITE) != USBD_OK)  //新增
  16.   {
  17.   Error_Handler();
  18.   }
  19. //  if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_MSC) != USBD_OK)
  20. //  {
  21. //    Error_Handler();
  22. //  }
  23. //  if (USBD_MSC_RegisterStorage(&hUsbDeviceFS, &USBD_Storage_Interface_fops_FS) != USBD_OK)
  24. //  {
  25. //    Error_Handler();
  26. //  }
  27.   if (USBD_Start(&hUsbDeviceFS) != USBD_OK)
  28.   {
  29.     Error_Handler();
  30.   }

  31.   /* USER CODE BEGIN USB_DEVICE_Init_PostTreatment */
  32. //  if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_COMPOSITE) != USBD_OK)  //新增
  33. //  {
  34. //  Error_Handler();
  35. //  }
  36.   /* USER CODE END USB_DEVICE_Init_PostTreatment */
  37. }
复制代码


11.在usbd_composite.h中新增代码

  1. #ifndef __USBD_COMPOSITE_H
  2. #define __USBD_COMPOSITE_H

  3. #include  "usbd_ioreq.h"
  4. #include "usbd_cdc.h"
  5. #include "usbd_msc.h"

  6. #define MC_MAX_FS_PACKET            0x40

  7. #define USB_MC_CONFIG_DESC_SIZ      106

  8. #define MC_MSC_EPIN_ADDR                MSC_EPIN_ADDR
  9. #define MC_MSC_EPOUT_ADDR               MSC_EPOUT_ADDR

  10. #define MC_CDC_IN_EP                   CDC_IN_EP
  11. #define MC_CDC_OUT_EP                  CDC_OUT_EP  
  12. #define MC_CDC_CMD_EP                  CDC_CMD_EP

  13. extern USBD_ClassTypeDef  USBD_COMPOSITE;

  14. #endif  /* __USBD_MC_H */

复制代码


12.在usbd_composite.c中新增代码


  1. #include "usbd_composite.h"
  2. #include "usbd_def.h"
  3. #include "usbd_msc.h"
  4. #include "usbd_cdc.h"
  5. #include "usbd_storage_if.h"
  6. #include "usbd_cdc_if.h"

  7. /** @defgroup MC_CORE_Private_FunctionPrototypes
  8.   * @{
  9.   */
  10.   
  11. USBD_CDC_HandleTypeDef     *pCDCData;
  12. USBD_MSC_BOT_HandleTypeDef *pMSCData;
  13.   
  14. uint8_t  USBD_MC_Init (USBD_HandleTypeDef *pdev,
  15.                             uint8_t cfgidx);

  16. uint8_t  USBD_MC_DeInit (USBD_HandleTypeDef *pdev,
  17.                               uint8_t cfgidx);

  18. uint8_t  USBD_MC_Setup (USBD_HandleTypeDef *pdev,
  19.                              USBD_SetupReqTypedef *req);

  20. uint8_t  USBD_MC_DataIn (USBD_HandleTypeDef *pdev,
  21.                               uint8_t epnum);


  22. uint8_t  USBD_MC_DataOut (USBD_HandleTypeDef *pdev,
  23.                                uint8_t epnum);

  24. uint8_t  *USBD_MC_GetHSCfgDesc (uint16_t *length);

  25. uint8_t  *USBD_MC_GetFSCfgDesc (uint16_t *length);

  26. uint8_t  *USBD_MC_GetOtherSpeedCfgDesc (uint16_t *length);

  27. uint8_t  *USBD_MC_GetDeviceQualifierDescriptor (uint16_t *length);

  28. static uint8_t  USBD_MC_RxReady (USBD_HandleTypeDef *pdev);
  29. static void MC_Switch_MSC(USBD_HandleTypeDef *pdev);
  30. static void MC_Switch_CDC(USBD_HandleTypeDef *pdev);

  31. /**
  32.   * @}
  33.   */
  34. extern USBD_HandleTypeDef hUsbDeviceFS;


  35. /** @defgroup MC_CORE_Private_Variables
  36.   * @{
  37.   */
  38. USBD_ClassTypeDef  USBD_COMPOSITE =
  39. {
  40.   USBD_MC_Init,
  41.   USBD_MC_DeInit,
  42.   USBD_MC_Setup,
  43.   NULL, /*EP0_TxSent*/  
  44.   USBD_MC_RxReady, /*EP0_RxReady*/
  45.   USBD_MC_DataIn,
  46.   USBD_MC_DataOut,
  47.   NULL, /*SOF */
  48.   NULL,  
  49.   NULL,     
  50.   USBD_MC_GetHSCfgDesc,
  51.   USBD_MC_GetFSCfgDesc,  
  52.   USBD_MC_GetOtherSpeedCfgDesc,
  53.   USBD_MC_GetDeviceQualifierDescriptor,
  54. };

  55. /* USB Mass storage device Configuration Descriptor */
  56. /*   All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */
  57. uint8_t USBD_MC_CfgDesc[USB_MC_CONFIG_DESC_SIZ] =
  58. {
  59.   /*Configuration Descriptor*/
  60.   0x09,   /* bLength: Configuration Descriptor size */
  61.   USB_DESC_TYPE_CONFIGURATION,      /* bDescriptorType: Configuration */
  62.   USB_MC_CONFIG_DESC_SIZ,                /* wTotalLength:no of returned bytes */
  63.   0x00,
  64.   0x03,   /* bNumInterfaces: 3 interface */
  65.   0x01,   /* bConfigurationValue: Configuration value */
  66.   0x00,   /* iConfiguration: Index of string descriptor describing the configuration */
  67.   0xC0,   /* bmAttributes: self powered */
  68.   0x32,   /* MaxPower 0 mA */
  69.   
  70.   /*---------------------------------------------------------------------------*/
  71.   // IAD
  72.   0x08,        //描述符大小
  73.   0x0B,        //IAD描述符类型
  74.   0x00,        // bFirstInterface
  75.   0x02,        // bInterfaceCount
  76.   0x02,        // bFunctionClass: CDC Class
  77.   0x02,        // bFunctionSubClass
  78.   0x01,        // bFunctionProtocol
  79.   0x00,        // iFunction      
  80.   
  81.   /*---------------------------------------------------------------------------*/
  82.   /*Interface Descriptor */
  83.   0x09,   /* bLength: Interface Descriptor size */
  84.   USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: Interface */
  85.   /* Interface descriptor type */
  86.   0x00,   /* bInterfaceNumber: Number of Interface */
  87.   0x00,   /* bAlternateSetting: Alternate setting */
  88.   0x01,   /* bNumEndpoints: One endpoints used */
  89.   0x02,   /* bInterfaceClass: Communication Interface Class */
  90.   0x02,   /* bInterfaceSubClass: Abstract Control Model */
  91.   0x01,   /* bInterfaceProtocol: Common AT commands */
  92.   0x00,   /* iInterface: */
  93.   
  94.   /*Header Functional Descriptor*/
  95.   0x05,   /* bLength: Endpoint Descriptor size */
  96.   0x24,   /* bDescriptorType: CS_INTERFACE */
  97.   0x00,   /* bDescriptorSubtype: Header Func Desc */
  98.   0x10,   /* bcdCDC: spec release number */
  99.   0x01,
  100.   
  101.   /*Call Management Functional Descriptor*/
  102.   0x05,   /* bFunctionLength */
  103.   0x24,   /* bDescriptorType: CS_INTERFACE */
  104.   0x01,   /* bDescriptorSubtype: Call Management Func Desc */
  105.   0x00,   /* bmCapabilities: D0+D1 */
  106.   0x01,   /* bDataInterface: 1 */
  107.   
  108.   /*ACM Functional Descriptor*/
  109.   0x04,   /* bFunctionLength */
  110.   0x24,   /* bDescriptorType: CS_INTERFACE */
  111.   0x02,   /* bDescriptorSubtype: Abstract Control Management desc */
  112.   0x02,   /* bmCapabilities */
  113.   
  114.   /*Union Functional Descriptor*/
  115.   0x05,   /* bFunctionLength */
  116.   0x24,   /* bDescriptorType: CS_INTERFACE */
  117.   0x06,   /* bDescriptorSubtype: Union func desc */
  118.   0x00,   /* bMasterInterface: Communication class interface */
  119.   0x01,   /* bSlaveInterface0: Data Class Interface */
  120.   
  121.   /*Endpoint 2 Descriptor*/
  122.   0x07,                           /* bLength: Endpoint Descriptor size */
  123.   USB_DESC_TYPE_ENDPOINT,   /* bDescriptorType: Endpoint */
  124.   MC_CDC_CMD_EP,                     /* bEndpointAddress */
  125.   0x03,                           /* bmAttributes: Interrupt */
  126.   LOBYTE(CDC_CMD_PACKET_SIZE),     /* wMaxPacketSize: */
  127.   HIBYTE(CDC_CMD_PACKET_SIZE),
  128.   0x10,                           /* bInterval: */
  129.   
  130.   /*Data class interface descriptor*/
  131.   0x09,   /* bLength: Endpoint Descriptor size */
  132.   USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: */
  133.   0x01,   /* bInterfaceNumber: Number of Interface */
  134.   0x00,   /* bAlternateSetting: Alternate setting */
  135.   0x02,   /* bNumEndpoints: Two endpoints used */
  136.   0x0A,   /* bInterfaceClass: CDC */
  137.   0x00,   /* bInterfaceSubClass: */
  138.   0x00,   /* bInterfaceProtocol: */
  139.   0x00,   /* iInterface: */
  140.   
  141.   /*Endpoint OUT Descriptor*/
  142.   0x07,   /* bLength: Endpoint Descriptor size */
  143.   USB_DESC_TYPE_ENDPOINT,      /* bDescriptorType: Endpoint */
  144.   MC_CDC_OUT_EP,                        /* bEndpointAddress */
  145.   0x02,                              /* bmAttributes: Bulk */
  146.   LOBYTE(MC_MAX_FS_PACKET),  /* wMaxPacketSize: */
  147.   HIBYTE(MC_MAX_FS_PACKET),
  148.   0x00,                              /* bInterval: ignore for Bulk transfer */
  149.   
  150.   /*Endpoint IN Descriptor*/
  151.   0x07,   /* bLength: Endpoint Descriptor size */
  152.   USB_DESC_TYPE_ENDPOINT,      /* bDescriptorType: Endpoint */
  153.   MC_CDC_IN_EP,                         /* bEndpointAddress */
  154.   0x02,                              /* bmAttributes: Bulk */
  155.   LOBYTE(MC_MAX_FS_PACKET),  /* wMaxPacketSize: */
  156.   HIBYTE(MC_MAX_FS_PACKET),
  157.   0x00,                               /* bInterval: ignore for Bulk transfer */

  158.   /*---------------------------------------------------------------------------*/
  159.   // IAD
  160.   0x08,        //描述符大小
  161.   0x0B,        //IAD描述符类型
  162.   0x02,        // bFirstInterface
  163.   0x01,        // bInterfaceCount
  164.   0x08,        // bFunctionClass: MASS STORAGE Class
  165.   0x06,        // bFunctionSubClass
  166.   0x50,        // bFunctionProtocol
  167.   0x01,        // iFunction   

  168.   /********************  Mass Storage interface ********************/
  169.   0x09,   /* bLength: Interface Descriptor size */
  170.   0x04,   /* bDescriptorType: */
  171.   0x02,   /* bInterfaceNumber: Number of Interface */
  172.   0x00,   /* bAlternateSetting: Alternate setting */
  173.   0x02,   /* bNumEndpoints*/
  174.   0x08,   /* bInterfaceClass: MSC Class */
  175.   0x06,   /* bInterfaceSubClass : SCSI transparent*/
  176.   0x50,   /* nInterfaceProtocol */
  177.   0x05,          /* iInterface: */
  178.   /********************  Mass Storage Endpoints ********************/
  179.   0x07,   /*Endpoint descriptor length = 7*/
  180.   0x05,   /*Endpoint descriptor type */
  181.   MC_MSC_EPIN_ADDR,   /*Endpoint address (IN, address 1) */
  182.   0x02,   /*Bulk endpoint type */
  183.   LOBYTE(MC_MAX_FS_PACKET),
  184.   HIBYTE(MC_MAX_FS_PACKET),
  185.   0x00,   /*Polling interval in milliseconds */
  186.   
  187.   0x07,   /*Endpoint descriptor length = 7 */
  188.   0x05,   /*Endpoint descriptor type */
  189.   MC_MSC_EPOUT_ADDR,   /*Endpoint address (OUT, address 1) */
  190.   0x02,   /*Bulk endpoint type */
  191.   LOBYTE(MC_MAX_FS_PACKET),
  192.   HIBYTE(MC_MAX_FS_PACKET),
  193.   0x00     /*Polling interval in milliseconds*/
  194. };
  195.   
  196. uint8_t USBD_MC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] =
  197. {
  198.   USB_LEN_DEV_QUALIFIER_DESC,
  199.   USB_DESC_TYPE_DEVICE_QUALIFIER,
  200.   0x00,
  201.   0x02,
  202.   0x00,
  203.   0x00,
  204.   0x00,
  205.   MC_MAX_FS_PACKET,
  206.   0x01,
  207.   0x00,
  208. };

  209. /**
  210.   * @brief  USBD_MC_Init
  211.   *         Initialize  the mass storage configuration
  212.   * @param  pdev: device instance
  213.   * @param  cfgidx: configuration index
  214.   * @retval status
  215.   */
  216. uint8_t  USBD_MC_Init (USBD_HandleTypeDef *pdev, uint8_t cfgidx)
  217. {
  218.   uint8_t ret = 0U;

  219.   
  220.   USBD_CDC_HandleTypeDef      * hcdc;
  221.    
  222.   MC_Switch_CDC(pdev);
  223.   
  224.   USBD_LL_OpenEP(pdev,
  225.                  MC_CDC_IN_EP,
  226.                  USBD_EP_TYPE_BULK,
  227.                  MC_MAX_FS_PACKET);
  228.   
  229.   USBD_LL_OpenEP(pdev,
  230.                  MC_CDC_OUT_EP,
  231.                  USBD_EP_TYPE_BULK,
  232.                  MC_MAX_FS_PACKET);
  233.   
  234.   USBD_LL_OpenEP(pdev,
  235.                  MC_CDC_CMD_EP,
  236.                  USBD_EP_TYPE_INTR,
  237.                  CDC_CMD_PACKET_SIZE);

  238.   hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;

  239.   ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Init();
  240.   
  241.   hcdc->TxState =0;
  242.   hcdc->RxState =0;
  243.   
  244.   USBD_LL_PrepareReceive(pdev,
  245.                          MC_CDC_OUT_EP,
  246.                          hcdc->RxBuffer,
  247.                          MC_MAX_FS_PACKET);

  248.   pCDCData = pdev->pClassData;

  249.   MC_Switch_MSC(pdev);
  250.   
  251.   USBD_LL_OpenEP(pdev,
  252.                  MC_MSC_EPOUT_ADDR,
  253.                  USBD_EP_TYPE_BULK,
  254.                  MC_MAX_FS_PACKET);
  255.   
  256.   USBD_LL_OpenEP(pdev,
  257.                  MC_MSC_EPIN_ADDR,
  258.                  USBD_EP_TYPE_BULK,
  259.                  MC_MAX_FS_PACKET);
  260.   
  261.   MSC_BOT_Init(pdev);
  262.   
  263.   pMSCData = pdev->pClassData;
  264.   
  265.   if(pdev->pClassData == NULL)
  266.   {
  267.     ret = USBD_FAIL;
  268.   }

  269.   return ret;
  270. }

  271. /**
  272.   * @brief  USBD_MC_DeInit
  273.   *         DeInitilaize  the mass storage configuration
  274.   * @param  pdev: device instance
  275.   * @param  cfgidx: configuration index
  276.   * @retval status
  277.   */
  278. uint8_t  USBD_MC_DeInit (USBD_HandleTypeDef *pdev,
  279.                               uint8_t cfgidx)
  280. {
  281.   return USBD_OK;
  282. }
  283. /**
  284. * @brief  USBD_MC_Setup
  285. *         Handle the MC specific requests
  286. * @param  pdev: device instance
  287. * @param  req: USB request
  288. * @retval status
  289. */
  290. uint8_t  USBD_MC_Setup (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
  291. {
  292.   if(req->wIndex == 0x0002)
  293.   {
  294.     MC_Switch_MSC(pdev);
  295.     USBD_MSC_BOT_HandleTypeDef     *hmsc = (USBD_MSC_BOT_HandleTypeDef*) pdev->pClassData;   
  296.    
  297.     switch (req->bmRequest & USB_REQ_TYPE_MASK)
  298.     {

  299.     /* Class request */
  300.     case USB_REQ_TYPE_CLASS :
  301.       switch (req->bRequest)
  302.       {
  303.       case BOT_GET_MAX_LUN :

  304.         if((req->wValue  == 0) &&
  305.            (req->wLength == 1) &&
  306.            ((req->bmRequest & 0x80) == 0x80))
  307.         {
  308.           hmsc->max_lun = ((USBD_StorageTypeDef *)pdev->pUserData)->GetMaxLun();
  309.           USBD_CtlSendData (pdev,
  310.                             (uint8_t *)&hmsc->max_lun,
  311.                             1);
  312.         }
  313.         else
  314.         {
  315.            USBD_CtlError(pdev , req);
  316.            return USBD_FAIL;
  317.         }
  318.         break;
  319.         
  320.       case BOT_RESET :
  321.         if((req->wValue  == 0) &&
  322.            (req->wLength == 0) &&
  323.           ((req->bmRequest & 0x80) != 0x80))
  324.         {      
  325.            MSC_BOT_Reset(pdev);
  326.         }
  327.         else
  328.         {
  329.            USBD_CtlError(pdev , req);
  330.            return USBD_FAIL;
  331.         }
  332.         break;

  333.       default:
  334.          USBD_CtlError(pdev , req);
  335.          return USBD_FAIL;
  336.       }
  337.       break;
  338.     /* Interface & Endpoint request */
  339.     case USB_REQ_TYPE_STANDARD:
  340.       switch (req->bRequest)
  341.       {
  342.       case USB_REQ_GET_INTERFACE :
  343.         USBD_CtlSendData (pdev,
  344.                           (uint8_t *)&hmsc->interface,
  345.                           1);
  346.         break;
  347.         
  348.       case USB_REQ_SET_INTERFACE :
  349.         hmsc->interface = (uint8_t)(req->wValue);
  350.         break;
  351.       
  352.       case USB_REQ_CLEAR_FEATURE:  
  353.         
  354.         /* Flush the FIFO and Clear the stall status */   
  355.         USBD_LL_FlushEP(pdev, (uint8_t)req->wIndex);
  356.         
  357.         /* Reactivate the EP */      
  358.         USBD_LL_CloseEP (pdev , (uint8_t)req->wIndex);
  359.         if((((uint8_t)req->wIndex) & 0x80) == 0x80)
  360.         {
  361.           if(pdev->dev_speed == USBD_SPEED_HIGH  )
  362.           {
  363.             /* Open EP IN */
  364.             USBD_LL_OpenEP(pdev,
  365.                            MC_MSC_EPIN_ADDR,
  366.                            USBD_EP_TYPE_BULK,
  367.                            MSC_MAX_HS_PACKET);  
  368.           }
  369.           else
  370.           {   
  371.             /* Open EP IN */
  372.             USBD_LL_OpenEP(pdev,
  373.                            MC_MSC_EPIN_ADDR,
  374.                            USBD_EP_TYPE_BULK,
  375.                            MSC_MAX_FS_PACKET);  
  376.           }
  377.         }
  378.         else
  379.         {
  380.           if(pdev->dev_speed == USBD_SPEED_HIGH  )
  381.           {
  382.             /* Open EP IN */
  383.             USBD_LL_OpenEP(pdev,
  384.                            MC_MSC_EPOUT_ADDR,
  385.                            USBD_EP_TYPE_BULK,
  386.                            MSC_MAX_HS_PACKET);  
  387.           }
  388.           else
  389.           {   
  390.             /* Open EP IN */
  391.             USBD_LL_OpenEP(pdev,
  392.                            MC_MSC_EPOUT_ADDR,
  393.                            USBD_EP_TYPE_BULK,
  394.                            MSC_MAX_FS_PACKET);  
  395.           }
  396.         }
  397.         
  398.         /* Handle BOT error */
  399.         MSC_BOT_CplClrFeature(pdev, (uint8_t)req->wIndex);
  400.         break;
  401.         
  402.       }  
  403.       break;
  404.      
  405.     default:
  406.       break;
  407.     }
  408.   }
  409.   else
  410.   {
  411.     MC_Switch_CDC(pdev);
  412.     static uint8_t ifalt = 0;
  413.     USBD_CDC_HandleTypeDef * hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData;   

  414.     switch (req->bmRequest & USB_REQ_TYPE_MASK)
  415.     {
  416.     case USB_REQ_TYPE_CLASS :
  417.       if (req->wLength)
  418.       {
  419.         if (req->bmRequest & 0x80)
  420.         {
  421.           ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest,
  422.                                                             (uint8_t *)hcdc->data,
  423.                                                             req->wLength);
  424.             USBD_CtlSendData (pdev,
  425.                               (uint8_t *)hcdc->data,
  426.                               req->wLength);
  427.         }
  428.         else
  429.         {
  430.           hcdc->CmdOpCode = req->bRequest;
  431.           hcdc->CmdLength = req->wLength;
  432.          
  433.           USBD_CtlPrepareRx (pdev,
  434.                              (uint8_t *)hcdc->data,
  435.                              req->wLength);
  436.         }
  437.         
  438.       }
  439.       else
  440.       {
  441.         ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest,
  442.                                                           (uint8_t*)req,
  443.                                                           0);
  444.       }
  445.       break;
  446.    
  447.     case USB_REQ_TYPE_STANDARD:
  448.       switch (req->bRequest)
  449.       {      
  450.       case USB_REQ_GET_INTERFACE :
  451.         USBD_CtlSendData (pdev,
  452.                           &ifalt,
  453.                           1);
  454.         break;
  455.         
  456.       case USB_REQ_SET_INTERFACE :
  457.         break;
  458.       }
  459.    
  460.     default:
  461.       break;
  462.     }  
  463.   }
  464.   
  465.   return USBD_OK;
  466. }

  467. /**
  468. * @brief  USBD_MC_DataIn
  469. *         handle data IN Stage
  470. * @param  pdev: device instance
  471. * @param  epnum: endpoint index
  472. * @retval status
  473. */
  474. uint8_t  USBD_MC_DataIn (USBD_HandleTypeDef *pdev,
  475.                               uint8_t epnum)
  476. {
  477.   if(epnum == (MC_MSC_EPIN_ADDR & 0x7f))
  478.   {
  479.     MC_Switch_MSC(pdev);
  480.     MSC_BOT_DataIn(pdev , epnum);
  481.   }
  482.   else if(epnum == (MC_CDC_IN_EP & 0x7f))
  483.   {
  484.     USBD_CDC_HandleTypeDef   *hcdc;
  485.    
  486.     MC_Switch_CDC(pdev);
  487.     hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
  488.     hcdc->TxState = 0;   
  489.   }
  490.   
  491.   return USBD_OK;
  492. }

  493. /**
  494. * @brief  USBD_MC_DataOut
  495. *         handle data OUT Stage
  496. * @param  pdev: device instance
  497. * @param  epnum: endpoint index
  498. * @retval status
  499. */
  500. uint8_t  USBD_MC_DataOut (USBD_HandleTypeDef *pdev,
  501.                                uint8_t epnum)
  502. {
  503.   if(epnum == MC_MSC_EPOUT_ADDR)
  504.   {
  505.     MC_Switch_MSC(pdev);
  506.     MSC_BOT_DataOut(pdev , epnum);
  507.   }
  508.   else if(epnum == MC_CDC_OUT_EP)
  509.   {
  510.     USBD_CDC_HandleTypeDef   *hcdc;
  511.    
  512.     MC_Switch_CDC(pdev);
  513.     hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
  514.    
  515.     hcdc->RxLength = USBD_LL_GetRxDataSize (pdev, epnum);
  516.     ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Receive(hcdc->RxBuffer, &hcdc->RxLength);
  517.   }
  518.   
  519.   return USBD_OK;
  520. }

  521. /**
  522. * @brief  USBD_MC_GetHSCfgDesc
  523. *         return configuration descriptor
  524. * @param  length : pointer data length
  525. * @retval pointer to descriptor buffer
  526. */
  527. uint8_t  *USBD_MC_GetHSCfgDesc (uint16_t *length)
  528. {
  529.   *length = sizeof (USBD_MC_CfgDesc);
  530.   return USBD_MC_CfgDesc;
  531. }

  532. /**
  533. * @brief  USBD_MC_GetFSCfgDesc
  534. *         return configuration descriptor
  535. * @param  length : pointer data length
  536. * @retval pointer to descriptor buffer
  537. */
  538. uint8_t  *USBD_MC_GetFSCfgDesc (uint16_t *length)
  539. {
  540.   *length = sizeof (USBD_MC_CfgDesc);
  541.   return USBD_MC_CfgDesc;
  542. }

  543. /**
  544. * @brief  USBD_MC_GetOtherSpeedCfgDesc
  545. *         return other speed configuration descriptor
  546. * @param  length : pointer data length
  547. * @retval pointer to descriptor buffer
  548. */
  549. uint8_t  *USBD_MC_GetOtherSpeedCfgDesc (uint16_t *length)
  550. {
  551.   *length = sizeof (USBD_MC_CfgDesc);
  552.   return USBD_MC_CfgDesc;
  553. }
  554. /**
  555. * @brief  DeviceQualifierDescriptor
  556. *         return Device Qualifier descriptor
  557. * @param  length : pointer data length
  558. * @retval pointer to descriptor buffer
  559. */
  560. uint8_t  *USBD_MC_GetDeviceQualifierDescriptor (uint16_t *length)
  561. {
  562.   *length = sizeof (USBD_MC_DeviceQualifierDesc);
  563.   return USBD_MC_DeviceQualifierDesc;
  564. }

  565. /**
  566. * @brief  USBD_MC_RegisterStorage
  567. * @param  fops: storage callback
  568. * @retval status
  569. */

  570. static uint8_t  USBD_MC_RxReady (USBD_HandleTypeDef *pdev)
  571. {
  572.   USBD_CDC_HandleTypeDef   *hcdc;
  573.   
  574.   MC_Switch_CDC(pdev);
  575.   hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
  576.   
  577.   if((pdev->pUserData != NULL) && (hcdc->CmdOpCode != 0xFF))
  578.   {
  579.     ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(hcdc->CmdOpCode,
  580.                                                       (uint8_t *)hcdc->data,
  581.                                                       hcdc->CmdLength);
  582.       hcdc->CmdOpCode = 0xFF;
  583.       
  584.   }
  585.   
  586.   return USBD_OK;
  587. }

  588. static void MC_Switch_MSC(USBD_HandleTypeDef *pdev)
  589. {
  590.   static USBD_MSC_BOT_HandleTypeDef msc_handle;
  591.   
  592.   USBD_MSC_RegisterStorage(pdev, &USBD_Storage_Interface_fops_FS);
  593.   pdev->pClassData = &msc_handle;
  594. }

  595. static void MC_Switch_CDC(USBD_HandleTypeDef *pdev)
  596. {
  597.   static USBD_CDC_HandleTypeDef cdc_handle;
  598.   
  599.   USBD_CDC_RegisterInterface(pdev, &USBD_Interface_fops_FS);
  600.   pdev->pClassData = &cdc_handle;
  601. }

  602. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
复制代码

通过以上修改后电脑电脑端显示USB复合设备MSC+CDC
msc cdc.png

13.在usbd_cdc_if.c  CDC_Receive_FS   /* USER CODE BEGIN 6 */ 增加发送测试

  1. static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)
  2. {
  3.   /* USER CODE BEGIN 6 */
  4.   USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);
  5.   USBD_CDC_ReceivePacket(&hUsbDeviceFS);
  6.   
  7.   CDC_Transmit_FS(UserRxBufferFS, *Len);      //把接收的返回
  8.   
  9.   
  10.   return (USBD_OK);
  11.   /* USER CODE END 6 */
  12. }
复制代码

测试串口收发
test.png




评分

参与人数 1ST金币 +20 收起 理由
creep + 20 赞一个!

查看全部评分

回复

使用道具 举报

该用户从未签到

10

主题

1665

帖子

65

蝴蝶豆

论坛元老

最后登录
2021-5-10
发表于 2019-6-24 11:42:56 | 显示全部楼层
学习了
回复

使用道具 举报

该用户从未签到

6

主题

1029

帖子

133

蝴蝶豆

金牌会员

最后登录
2021-4-24
发表于 2019-6-25 10:04:19 | 显示全部楼层
赞一个~
回复

使用道具 举报

该用户从未签到

0

主题

2

帖子

0

蝴蝶豆

初级会员

最后登录
2020-7-20
发表于 2020-6-28 23:47:20 | 显示全部楼层
完全按照楼主的说明操作一顿后,不能识别出CDC,但是能识别MSC。MCU是F407VE
回复 支持 反对

使用道具 举报

该用户从未签到

2

主题

356

帖子

0

蝴蝶豆

金牌会员

最后登录
2024-4-4
发表于 2020-6-29 09:48:11 | 显示全部楼层
非常好的资料,对初学者很有帮助;
希望楼主多多分享,赠人玫瑰,手有余香,念念不忘,必有回响;
回复 支持 反对

使用道具 举报

该用户从未签到

0

主题

2

帖子

0

蝴蝶豆

初级会员

最后登录
2020-7-20
发表于 2020-6-29 09:52:41 | 显示全部楼层
完全按照楼主做法,在win10环境下U盘和串口都可以实现功能,在win7环境下,串口错误识别为mass storage
回复 支持 反对

使用道具 举报

该用户从未签到

1

主题

64

帖子

5

蝴蝶豆

高级会员

最后登录
2023-3-19
 楼主| 发表于 2020-7-15 09:54:26 | 显示全部楼层
hds1988 发表于 2020-6-29 09:52
完全按照楼主做法,在win10环境下U盘和串口都可以实现功能,在win7环境下,串口错误识别为mass storage ...

是不是驱动问题,我电脑Win10
回复 支持 反对

使用道具 举报

该用户从未签到

0

主题

1

帖子

0

蝴蝶豆

新手上路

最后登录
2021-4-28
发表于 2020-11-19 12:57:48 | 显示全部楼层
hds1988 发表于 2020-6-29 09:52
完全按照楼主做法,在win10环境下U盘和串口都可以实现功能,在win7环境下,串口错误识别为mass storage ...

微信图片编辑_20201119125724.jpg 我现在就是win7系统,和你一样的现象。请问你找到解决办法了吗?
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /3 下一条

Archiver|手机版|小黑屋|论坛-意法半导体STM32/STM8技术社区

GMT+8, 2024-5-14 17:44 , Processed in 1.202522 second(s), 41 queries .

Powered by Discuz! X3.4

Copyright © 2001-2024, Tencent Cloud.

快速回复 返回顶部 返回列表