你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32F7USB复合设备cube-MSC与CDC复合设备

[复制链接]
289466080 发布时间:2019-6-23 13:44
本帖最后由 289466080 于 2019-6-23 15:56 编辑
  {: e6 m6 W3 K4 d, S8 [! l  ~* N* a! \/ _7 q, Z8 Y
    最近做个USB复合设备CDC+MSC,在网上找了好多基本都是F103做的复合设备,带OTG芯片USB复合设备网上很少可能是我搜索的关键字不够理想有的不够全面,官方给了一个视频教程但是没有参考代码,社区里面有分享到github我按照后也不能实现,后结合F1与github分享的+官方视频,实现了在STM32F730R8T6上面USB复合设备,分享下怎样用cube生成的代码实现USB复合设备(带OTG的芯片).
% E% _/ j- Y% O! E# D5 s+ U& s8 x6 ?- }8 x
参考:+ \3 y/ \1 C, k/ Z: H1 U. v
github分享2 f. `9 c4 ]1 x  v% U# n* Z
http://github.com/uwyciw/CDC_MSC7 F' `* ?/ |$ o4 Z! @
官方视频
; G$ D2 N& U4 Q/ q, P( S2 shttps://www.stmcu.org.cn/video/index/detail/id-3988
; ~1 _! h( X9 Y) ^* ]F1034 A* Z( C: d. J, e% R: i
http://www.bbsmax.com/A/kjdwBXA5Np/. z- b  G; u& c, ~$ N, }0 Z1 i

, t* a- g" ?" R! s" [' @) G
* D2 d1 ~% w: b. Kcube 5.2.1
: J$ u+ k, V; |: W& {' Vhal  stm32cube_fw_f7_v1150.zip2 f  p( B# `( q+ K' k$ q% t

* B9 I" Q( l8 @USB为 USB_OTG_FS
1 ]. J! ]: B3 |  K
* T) M4 t* c( P4 i9 A1 M0 V! q3 D1.先生成一个CDC工程下面配置图。
; @5 K- Y$ h" p& pRCC如图箭头其他默认
5 ?% Q$ Q6 Q, a4 X RCC.png . |/ [# K5 @5 M- W( c
USB_OTG_FS如图箭头其他默认1 w% |: ?- a1 o0 {" Q. ^- \+ w
USB_OTG_FS.png   m( ^- ]) ]6 N
USB_Device
如图箭头其他默认
" k0 C5 W6 o) F8 E: o USB_Device.png : ?/ ]  ]" l1 @+ R7 j0 Z. g
Clock如图箭头其他默认我用的16M晶振比8M便宜
% k0 z& z  i! J% C- B6 G8 [ Clock.PNG
/ T% ]1 d: L% a% G2 z5 ~
3 V+ w  P, d; P& Q3 j0 ]2 XProject如图箭头其他默认
' e/ P1 J# E5 z( I- G Project.png , `& |. l) U. l: C# w: D
code如图箭头其他默认
: B( `! S7 W9 g+ p3 t9 u; N; j code.png ) C; C8 S$ J9 ?
2.同样生成一个新的MSC工程不可覆盖原本的工程只需修改下图与工程名其他一样- ?" p6 h& t2 K& c
! i' C) o3 R, f- K& r2 Z
USB_Device-MSC.png ( {! n( O- b, w. B4 ^2 g

! J  l5 W$ K6 M6 d$ g2 Q" k  y
8 f5 ~6 e) n) u  v9 e. C3.生成后把CDC工程下Src文件夹里的usbd_cdc_if.c与Inc下的usbd_cdc_if.h复制到MSC工程下Src与Inc文件夹里面,MSC工程下Src文件夹下新建usbd_composite.c与Inc下新建usbd_composite.h
$ u; f3 {* q# Y/ Z- H
% G$ r! s* z" O, a. f3 d, d h.png ; l6 Q# \) E* w% ~& C

" x! ]$ A9 A' a* L4.把CDC工程\Middlewares\ST\STM32_USB_Device_Library\Class目录下的CDC文件夹复制到MSC工程下见图
& h% x0 c+ v  b% ?4 J7 }- S: C1 ] cdc.png   t1 `. q, d: b4 M, K' H
5.添加CDC路径5 C. Y( i( O9 Y3 p8 V

2 |4 ]) G0 d' B4 j9 H+ t6 u" f% Z/ [ CDC-PATHS.png # c' y# p  _6 V8 B& x, W" g
9 f4 m8 ~( x" y" D+ s6 i9 i
6.在工程中添加usbd_cdc.c usbd_cdc_if.c usbd_composite.c见图5 B7 E1 d+ P0 Q0 Q
keil-add.png 1 t! Q! e  O( F- _
5 s% P  e: s5 v2 I
7. usbd_conf.h 把USBD_MAX_NUM_INTERFACES值 1修改为3
; X' ]! `1 N0 `
  1. /*---------- -----------*/5 M- G1 Y& U( j. |' r: J) u/ K
  2. #define USBD_MAX_NUM_INTERFACES     3U    //1U; v2 H8 c7 r6 E1 e7 V: }+ K
  3. /*---------- -----------*/
复制代码
8. usbd_cdc.h 修改CDC_IN_EP CDC_OUT_EP CDC_CMD_EP
7 [" g4 H4 l  S" y! n4 z
  1. //#define CDC_IN_EP                                   0x81U  /* EP1 for data IN */
    8 ?7 {/ o/ ~. M5 W  v4 M/ J
  2. //#define CDC_OUT_EP                                  0x01U  /* EP1 for data OUT */: ^# c4 R6 D+ j6 H# g7 `
  3. //#define CDC_CMD_EP                                  0x82U  /* EP2 for CDC commands */; d% G& v) t! O8 m' Z
  4. #define CDC_IN_EP                                   0x83  /* EP1 for data IN */  W- d  {. U2 t: Z; f; A$ ^% d8 \
  5. #define CDC_OUT_EP                                  0x03  /* EP1 for data OUT */+ v. O% r: z! q! o1 q
  6. #define CDC_CMD_EP                                  0x82  /* EP2 for CDC commands */
复制代码
9. usbd_conf.c  USBD_LL_Init中新增  H$ s7 g) X% y* l5 |9 G+ U
  1.   HAL_PCDEx_SetRxFiFo(&hpcd_USB_OTG_FS, 0x80);
    , m( _0 c, G% ~0 c  E" e) Y
  2.   HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 0, 0x40);
    : \) K$ t1 G7 q5 V1 _
  3.   HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 1, 0x80);3 B; |6 C6 m$ k/ r
  4.   - _+ X3 O4 u  Y2 D  T
  5.   HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 1, 0x40);   //新增
    2 O  I1 x0 [$ `5 S
  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
6 V8 u5 e  f9 R: t

$ h& C8 ~8 G* R& d6 ~: u
  1. $ {7 l& J" o. A2 \# i
  2. /* USER CODE BEGIN Includes */+ l5 t8 Y; K% G- N; C) t. B
  3. #include "usbd_composite.h"! d7 v3 ?9 n/ ~! Z
  4. /* USER CODE END Includes */3 ?3 R+ ~% W  m' L9 t$ R

  5. 7 H4 W; r3 _% u; |/ N  y) j! e
  6. void MX_USB_DEVICE_Init(void)
    2 I$ o: \0 }& c2 w6 h6 N
  7. {) ?+ d6 m$ X) @( M( [5 V
  8.   /* USER CODE BEGIN USB_DEVICE_Init_PreTreatment */
    8 D  a+ E- |: e1 p" Y- \. _* H
  9.   
    # c1 a4 `! ?; h" w- a" \
  10.   /* USER CODE END USB_DEVICE_Init_PreTreatment */
      z- i/ ?+ R4 E9 R/ H6 _7 }# _
  11.   $ e, y! w6 z0 y" `! c7 w1 J0 F
  12.   /* Init Device Library, add supported class and start the library. */. x4 G+ K$ x  Q  f" H0 [  [
  13.   if (USBD_Init(&hUsbDeviceFS, &FS_Desc, DEVICE_FS) != USBD_OK)
    $ [" {% _- z4 X5 ~6 k
  14.   {
    " D: _3 M" Q0 K8 y" ]& E
  15.     Error_Handler();
    0 ~1 c5 R8 u7 y1 t
  16.   }  y' {/ M$ L: ?( {: @, U; _( }
  17.   if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_COMPOSITE) != USBD_OK)  //新增" z' C  H' q/ V/ Q- {
  18.   {, F) g! K0 G# O6 r) `
  19.   Error_Handler();; M7 P+ R5 b4 ?9 j( }! X3 U$ k( ~+ M9 `
  20.   }
    * K1 H& x) t4 r- n4 E. p
  21. //  if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_MSC) != USBD_OK)7 n3 d' D" f+ |6 c1 V7 A
  22. //  {
    # ^. H6 L0 ~8 v; R* e
  23. //    Error_Handler();
    1 _6 f) v+ X5 _6 N
  24. //  }
    ; u6 K6 ~; C: @0 l; y
  25. //  if (USBD_MSC_RegisterStorage(&hUsbDeviceFS, &USBD_Storage_Interface_fops_FS) != USBD_OK)
    $ m0 H/ i* {; e9 ^
  26. //  {
    ) g5 L6 I$ h5 U( N
  27. //    Error_Handler();
    : q6 L" P% I7 W0 a) c9 u
  28. //  }
    + a8 G- e5 q, _: R- m. N9 i" l3 R
  29.   if (USBD_Start(&hUsbDeviceFS) != USBD_OK)8 Q* F  U& o9 b2 f: p- J5 T
  30.   {' W+ k3 _! N) S0 n0 }. V
  31.     Error_Handler();3 T) r% d; [( _; s3 t( P' D
  32.   }4 v/ l  ^5 N; s- z! K

  33. ) X8 D" t. E& @" t
  34.   /* USER CODE BEGIN USB_DEVICE_Init_PostTreatment */5 D. k3 ^' r+ w" S5 {
  35. //  if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_COMPOSITE) != USBD_OK)  //新增: v1 ~3 T: R  i0 y, m: j
  36. //  {! U- E" T$ q1 J. z9 e# N7 y2 G
  37. //  Error_Handler();
    % g9 y  ^* u7 m  a
  38. //  }
    0 Y: D, d& _& D$ g  x$ Z4 b
  39.   /* USER CODE END USB_DEVICE_Init_PostTreatment */
    5 F: A3 e! L1 G5 J
  40. }
复制代码
! l; O+ Y' d& ~% _+ u+ E# m* e
0 w1 X3 J2 a. u! Y/ F! m1 @: X. v; H
11.在usbd_composite.h中新增代码
1 u- ], x; m+ p, Y' d: e+ k3 u

  1. 4 `: Q. d% f0 K6 x0 |
  2. #ifndef __USBD_COMPOSITE_H5 d( H( C. D9 e& C1 P" [; V/ q
  3. #define __USBD_COMPOSITE_H
    3 e4 S7 c  {/ `! F1 ~4 v% s  V
  4. 9 N- L7 s! \) V: J7 t& j
  5. #include  "usbd_ioreq.h"
    # E: v  C+ r' h5 V+ m9 w7 p
  6. #include "usbd_cdc.h"$ ?& I; w, x& m& e, ?* o( L
  7. #include "usbd_msc.h"
    ; ]$ E( b4 X& S8 S& R

  8.   b, ], ~8 E4 ]
  9. #define MC_MAX_FS_PACKET            0x40
    # ^4 T( ?7 k. O# H$ a

  10. ) J+ j5 k) W. g: Y1 U
  11. #define USB_MC_CONFIG_DESC_SIZ      106
    9 K2 M/ o0 |0 \4 ~) X& ^# I' z

  12. # s) @* c! Z+ a2 k0 b  G
  13. #define MC_MSC_EPIN_ADDR                MSC_EPIN_ADDR
    9 g  ~- e+ ?& d! {. f( N& d
  14. #define MC_MSC_EPOUT_ADDR               MSC_EPOUT_ADDR
    ; n4 j: B+ I+ R9 v$ a2 k
  15. - X8 O& v5 X/ K  _
  16. #define MC_CDC_IN_EP                   CDC_IN_EP
    : G4 q$ \* {8 x& o
  17. #define MC_CDC_OUT_EP                  CDC_OUT_EP  6 V/ P4 ?& U  a7 v# x1 O. m+ N9 x
  18. #define MC_CDC_CMD_EP                  CDC_CMD_EP # q+ l+ f& c) @4 c

  19. + L& S- U( F" |: _0 s0 D
  20. extern USBD_ClassTypeDef  USBD_COMPOSITE;+ q0 k1 v% ^( P* Y1 K
  21. 7 C- t) i* e# ]% [, \" G
  22. #endif  /* __USBD_MC_H */; U" U' C' X+ I2 m9 r" y. L* \
  23. 5 n7 Z9 L6 c+ x  {& K2 M- i0 _0 p0 _
复制代码
  Z. A+ Z5 |0 s6 L% o
% M" N9 V0 ^( @" I' M5 H' L  f& t
12.在usbd_composite.c中新增代码. j: j) g. Y$ Z' I' c. O

: S6 g2 s: `9 m) Y( o9 x

  1. % |9 J  {, \( x$ e
  2. #include "usbd_composite.h"0 X2 W5 g) I# g  R* x( i
  3. #include "usbd_def.h"
    # c$ T; @, d1 G8 s8 E# E! \  Q" y
  4. #include "usbd_msc.h"
    2 b, m# f) B* u; ^; o4 n
  5. #include "usbd_cdc.h"5 j" d, f: @( s+ C, g' o6 a
  6. #include "usbd_storage_if.h"/ O& ?( O3 M: ~6 G, v' G/ g& u
  7. #include "usbd_cdc_if.h"
    5 ^' t. ^) a/ `: p. b

  8. : f' K. P8 x/ j& q; e
  9. /** @defgroup MC_CORE_Private_FunctionPrototypes3 A4 m9 j" S$ \7 l7 q3 J
  10.   * @{2 ]; b4 N" l9 w. k5 H% v
  11.   */
    : e# R( i$ Z( o) A
  12.   - p, r7 u8 H1 Z( L4 W4 N
  13. USBD_CDC_HandleTypeDef     *pCDCData;, H  I3 A8 ?+ _# \" @
  14. USBD_MSC_BOT_HandleTypeDef *pMSCData;
    " x! B; M. p7 P. M
  15.   ! ~1 X1 E+ _) J
  16. uint8_t  USBD_MC_Init (USBD_HandleTypeDef *pdev,
    & U4 T3 J4 k& ~2 K( h' R/ n2 p9 Y
  17.                             uint8_t cfgidx);5 e) B8 ~# g2 e" O

  18. % P/ y* y  X9 J6 f: E
  19. uint8_t  USBD_MC_DeInit (USBD_HandleTypeDef *pdev, 6 p8 X% F+ o/ u5 L) u; w* @& O
  20.                               uint8_t cfgidx);2 Z: d- ~  g, E

  21. 0 V# d; u3 J2 \: u/ D6 j
  22. uint8_t  USBD_MC_Setup (USBD_HandleTypeDef *pdev,
    " q1 o; M+ \; g. h6 ~8 {, n
  23.                              USBD_SetupReqTypedef *req);
    " C( F7 U2 Y2 Y% ]  D- W9 Y
  24. + c8 H8 r* r, g, Q' i. [
  25. uint8_t  USBD_MC_DataIn (USBD_HandleTypeDef *pdev, 8 I7 [3 D- R2 ?* X! m5 [! l, X% M
  26.                               uint8_t epnum);, n+ h2 N5 d9 |  E9 y

  27. 0 n5 ?0 V- Y* c. W4 B1 w

  28.   Z0 C& i1 W- O. P1 r* M
  29. uint8_t  USBD_MC_DataOut (USBD_HandleTypeDef *pdev, 3 y8 h& _0 l. R; q( [6 B
  30.                                uint8_t epnum);
    " F* p8 `: n3 x( O: o& l9 }# Y5 q
  31. 1 i; n% Y: k! K/ C* S
  32. uint8_t  *USBD_MC_GetHSCfgDesc (uint16_t *length);- k6 J$ H1 M) L; S
  33. ; l* N1 c: b" o6 P0 v: I
  34. uint8_t  *USBD_MC_GetFSCfgDesc (uint16_t *length);% u; N' h" I; ]5 W3 ?! m6 I
  35. 7 w. W6 i% D) ]4 C& U. A
  36. uint8_t  *USBD_MC_GetOtherSpeedCfgDesc (uint16_t *length);
    4 p. {+ g" d: O2 ^. Q
  37. . ~4 U. F  i$ _" t
  38. uint8_t  *USBD_MC_GetDeviceQualifierDescriptor (uint16_t *length);
    9 F' \6 O  i4 [& Z4 K( E6 G
  39. ' P+ c0 A& ]2 _8 ~9 E4 y! r
  40. static uint8_t  USBD_MC_RxReady (USBD_HandleTypeDef *pdev);5 a' \. U9 H5 Z
  41. static void MC_Switch_MSC(USBD_HandleTypeDef *pdev);# M/ N1 |% ~0 b% k* W; n6 J, T$ T
  42. static void MC_Switch_CDC(USBD_HandleTypeDef *pdev);
    ' K* M: z) ?! h2 y- N
  43. 8 G, p4 b5 B  _1 Y, S: z8 N% U
  44. /**) G5 M- a3 J: @
  45.   * @}
    / Y7 W/ h# G1 Y0 ]6 Z* R9 L; Y1 L
  46.   */
    ) r3 {8 o; |7 v" F$ y3 j! ?* a
  47. extern USBD_HandleTypeDef hUsbDeviceFS;
    " l8 K; Y; d" M- p2 Q
  48. , a! g" U$ A+ I0 b! \) ?2 E" z: o
  49. ; a3 M8 \' s7 r: T) v( j
  50. /** @defgroup MC_CORE_Private_Variables
    + w- J; }) b3 c" `9 {; N
  51.   * @{
    7 t' f9 I: q0 x' U1 N; y
  52.   */ + x, d; z1 D& @
  53. USBD_ClassTypeDef  USBD_COMPOSITE =
    / U+ ]. ]/ r8 e4 x. k& h! j
  54. {# d/ L1 f3 [6 V- R( Q; Z) x3 F8 K
  55.   USBD_MC_Init,8 ~0 B; W( P( h% \& n9 d% ^" T8 j
  56.   USBD_MC_DeInit,/ p# c1 X# m9 i1 _, }  x& h8 m% Y
  57.   USBD_MC_Setup,5 s  c! c1 I3 g* f9 o
  58.   NULL, /*EP0_TxSent*/  
    * ?* C8 ?8 U' P# r
  59.   USBD_MC_RxReady, /*EP0_RxReady*/
    1 I" o" E; H/ z( v0 n9 Y' }
  60.   USBD_MC_DataIn,' p, ]. g/ r3 b7 e6 D
  61.   USBD_MC_DataOut,
    ' g- d$ }; B% }( s" o0 G
  62.   NULL, /*SOF */ ; L- z! b+ L8 q  z
  63.   NULL,  
    4 K) z; p0 X# |) S# j1 B
  64.   NULL,     
      |. m3 X* l' H2 m& `! b5 k5 v
  65.   USBD_MC_GetHSCfgDesc," t' B6 S- X2 r8 D1 S! S
  66.   USBD_MC_GetFSCfgDesc,  ' D7 b: f% A4 c/ L; J# w+ X
  67.   USBD_MC_GetOtherSpeedCfgDesc,' V' ~1 @& c5 ]- P& W: P7 h4 j% T
  68.   USBD_MC_GetDeviceQualifierDescriptor,
    1 q0 Q! ?# P1 q: C+ \4 L; d
  69. };- ]1 k7 W8 y# y4 |% r' w
  70. 9 T/ x7 b: i& b4 {( v* Y
  71. /* USB Mass storage device Configuration Descriptor */
    - o- h: U! `8 `
  72. /*   All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */+ u# x2 [# ]8 x. U% B
  73. uint8_t USBD_MC_CfgDesc[USB_MC_CONFIG_DESC_SIZ] =
    % [6 m! u& b/ }3 T1 T+ C
  74. {
    ! u- H  A" \6 Z: q# G
  75.   /*Configuration Descriptor*/
    5 g4 u/ U1 }5 k9 [! M) R  y9 ~
  76.   0x09,   /* bLength: Configuration Descriptor size */, s/ s+ _+ I! P  e
  77.   USB_DESC_TYPE_CONFIGURATION,      /* bDescriptorType: Configuration */; c& P1 x- m3 W2 [& v- t9 [; Z
  78.   USB_MC_CONFIG_DESC_SIZ,                /* wTotalLength:no of returned bytes */
    8 z0 U1 B4 |5 u: H
  79.   0x00,5 e! d' |" {* g9 h  B
  80.   0x03,   /* bNumInterfaces: 3 interface */6 J* r+ m$ F4 ]) S' }: n
  81.   0x01,   /* bConfigurationValue: Configuration value */
    & D, p- T+ p# d. N3 b$ D4 t& j. r
  82.   0x00,   /* iConfiguration: Index of string descriptor describing the configuration */
    ; s6 L) E8 k( S5 X8 j
  83.   0xC0,   /* bmAttributes: self powered */; T8 M4 Q4 O' d  r, d
  84.   0x32,   /* MaxPower 0 mA */
    : B. y: L; ^- l+ ?
  85.   
    " @4 h3 C+ `0 E0 l. O. ~
  86.   /*---------------------------------------------------------------------------*/
    + E% {" e" Y% d# b# o0 Q
  87.   // IAD8 U- i+ V5 ~* Q7 Q5 e8 j  k0 q
  88.   0x08,        //描述符大小8 Y; ?5 y7 y8 W$ }
  89.   0x0B,        //IAD描述符类型
    5 }# Z/ L* Q, H& a5 A/ w- o
  90.   0x00,        // bFirstInterface
    . {& \% P( h& \( j; z' B! Z3 `
  91.   0x02,        // bInterfaceCount" T; W8 N0 T2 K. R$ L
  92.   0x02,        // bFunctionClass: CDC Class( }2 [. Q) d7 j1 r/ X9 e
  93.   0x02,        // bFunctionSubClass+ {+ N0 [+ ]' Y
  94.   0x01,        // bFunctionProtocol
    " E- V: T# s3 z/ D0 i) F5 n
  95.   0x00,        // iFunction       ' P! |0 Z. ^0 _' I
  96.   $ D# i4 m% U' ?& ?
  97.   /*---------------------------------------------------------------------------*/$ p# H' T& r( X3 M
  98.   /*Interface Descriptor */; y; H( ~/ R& ]* Q2 Q
  99.   0x09,   /* bLength: Interface Descriptor size */5 u7 B3 o% ?; o, q$ A$ G; g
  100.   USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: Interface */# z9 K: N6 y# h  B1 c- {' q
  101.   /* Interface descriptor type */0 w) C0 p7 G' C# t/ _. N
  102.   0x00,   /* bInterfaceNumber: Number of Interface */  b/ [( y6 T% p8 g: p; ~
  103.   0x00,   /* bAlternateSetting: Alternate setting */
    - S" i5 E5 G! D7 h" U* v5 c
  104.   0x01,   /* bNumEndpoints: One endpoints used */6 D8 B% J( Z& E
  105.   0x02,   /* bInterfaceClass: Communication Interface Class */, r: q; W4 a; O3 F' Y+ s+ A" X  P: ~
  106.   0x02,   /* bInterfaceSubClass: Abstract Control Model */# E- j" K& a8 O2 N8 D
  107.   0x01,   /* bInterfaceProtocol: Common AT commands */1 z0 n( F# g3 [
  108.   0x00,   /* iInterface: */
    9 [3 x- c% ?/ |) r8 l5 n
  109.   
    - {9 c6 y3 m2 G0 K) B6 Y
  110.   /*Header Functional Descriptor*/
    / D( Y, A* O& h/ _# |/ U0 k
  111.   0x05,   /* bLength: Endpoint Descriptor size */
    , f, h+ p0 S2 e, T
  112.   0x24,   /* bDescriptorType: CS_INTERFACE */( Z2 b( h2 |) i  D- G0 u; H
  113.   0x00,   /* bDescriptorSubtype: Header Func Desc */
    $ x! Q& x# Z, b# g4 g
  114.   0x10,   /* bcdCDC: spec release number */# D0 W$ T9 h+ F) z$ R5 Y
  115.   0x01,
    & |1 t2 Z( R- x* K1 R1 b2 B9 a
  116.   7 `2 D. K) C( f6 Y+ O1 ~0 U7 A
  117.   /*Call Management Functional Descriptor*/
    % J* R9 b9 F" t$ m* w& H, {0 J
  118.   0x05,   /* bFunctionLength */8 f" _( I  T7 }/ V- u! z, r: v
  119.   0x24,   /* bDescriptorType: CS_INTERFACE */
    ' D  k" w0 J& T# u  V/ N# x; _0 k
  120.   0x01,   /* bDescriptorSubtype: Call Management Func Desc */  l0 F* m6 f2 O2 D  i
  121.   0x00,   /* bmCapabilities: D0+D1 */
    % \1 B6 Y3 C8 S
  122.   0x01,   /* bDataInterface: 1 */
    ) \7 ]& x, F4 }( N, f
  123.   
    9 R+ F% {2 H: ^
  124.   /*ACM Functional Descriptor*/" ?: ]3 O- T9 e7 X  p
  125.   0x04,   /* bFunctionLength */
    - c3 o6 f) I- @  L0 f! w
  126.   0x24,   /* bDescriptorType: CS_INTERFACE */
    : `& @' O' ^( p! R, y
  127.   0x02,   /* bDescriptorSubtype: Abstract Control Management desc */) p+ K  w, _6 B: Y! N% c/ k; x7 N
  128.   0x02,   /* bmCapabilities */
      X- Z4 b) y! p* R( G8 u6 p
  129.   
    - E# h# [7 ]9 T! y7 G' ?
  130.   /*Union Functional Descriptor*/; G$ k6 l; x0 b& Q3 p  O
  131.   0x05,   /* bFunctionLength */# U- {1 }4 d+ I
  132.   0x24,   /* bDescriptorType: CS_INTERFACE */
    ' n4 g. r9 X0 G8 q( i! |& \. a: e2 d
  133.   0x06,   /* bDescriptorSubtype: Union func desc */- t* F' r2 O- E% F
  134.   0x00,   /* bMasterInterface: Communication class interface */
    4 m5 `) Q1 S$ E$ Y8 z
  135.   0x01,   /* bSlaveInterface0: Data Class Interface */
    3 p& {) w! t7 u, H. O! G6 p% F7 F
  136.   
    6 Q* h5 ~, R0 e! T4 d/ ^. n
  137.   /*Endpoint 2 Descriptor*/
    ) O! Y( ?7 `$ X+ e
  138.   0x07,                           /* bLength: Endpoint Descriptor size */
    ) @6 @" [' B( I7 [7 \
  139.   USB_DESC_TYPE_ENDPOINT,   /* bDescriptorType: Endpoint */: b( x( `' |, ~% Z" k+ {/ I
  140.   MC_CDC_CMD_EP,                     /* bEndpointAddress */! G  g# ?# C/ {3 ]; Z
  141.   0x03,                           /* bmAttributes: Interrupt */
    8 D. O" t. |% g) W8 c, b
  142.   LOBYTE(CDC_CMD_PACKET_SIZE),     /* wMaxPacketSize: */1 I8 K) b* f2 X# g( Q
  143.   HIBYTE(CDC_CMD_PACKET_SIZE),  W7 P  ?* x# x' }# h% E
  144.   0x10,                           /* bInterval: */ & a2 l- S! q4 z9 c. d6 L0 Q
  145.   
    " B* x& H: ]7 s: m/ o5 R
  146.   /*Data class interface descriptor*/
    # a# S0 W* r  ^$ X6 I0 t# @) s
  147.   0x09,   /* bLength: Endpoint Descriptor size */
    6 w- q' r4 d' \) N2 `! \
  148.   USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: */
    8 k" N8 J; r* Z+ W
  149.   0x01,   /* bInterfaceNumber: Number of Interface */
    ( j% k. K# d- e7 t9 G% O
  150.   0x00,   /* bAlternateSetting: Alternate setting */; P7 r# q% u* \. K
  151.   0x02,   /* bNumEndpoints: Two endpoints used */0 F  Y! y$ k% d3 O  {, q
  152.   0x0A,   /* bInterfaceClass: CDC */2 |% J# D- D  J2 j, }
  153.   0x00,   /* bInterfaceSubClass: */' l2 O5 a# }9 v
  154.   0x00,   /* bInterfaceProtocol: */
    1 S% k; `7 ?5 b$ H
  155.   0x00,   /* iInterface: */7 q, f5 M) J: E: p
  156.   
    , _1 J1 m' z5 z1 ?" j: I5 `7 j
  157.   /*Endpoint OUT Descriptor*/
      X, C4 v5 V5 p% ~, l. b3 x
  158.   0x07,   /* bLength: Endpoint Descriptor size */
    % G4 y+ B; Y7 u3 r" B" ]. @& @
  159.   USB_DESC_TYPE_ENDPOINT,      /* bDescriptorType: Endpoint */
    ' w# Q# l$ S* S, `5 B
  160.   MC_CDC_OUT_EP,                        /* bEndpointAddress */; H. Q* g" c% l( e! F
  161.   0x02,                              /* bmAttributes: Bulk */
    % w9 p3 C7 a' w7 w6 f" I. H, w( A
  162.   LOBYTE(MC_MAX_FS_PACKET),  /* wMaxPacketSize: */
    , ]6 ~/ |/ b; f3 ]" Z
  163.   HIBYTE(MC_MAX_FS_PACKET),5 f  d% k( C) P3 Q5 b" Y6 O8 N5 @
  164.   0x00,                              /* bInterval: ignore for Bulk transfer */: B9 I% S8 G1 _8 {- d
  165.   , j, x8 H4 P. z+ E7 g
  166.   /*Endpoint IN Descriptor*/
    2 c7 f  O, g' y& J2 V2 e
  167.   0x07,   /* bLength: Endpoint Descriptor size */8 r( g" b' G: l% M
  168.   USB_DESC_TYPE_ENDPOINT,      /* bDescriptorType: Endpoint */
    0 Y: D0 Q3 C8 ]0 g7 b6 J
  169.   MC_CDC_IN_EP,                         /* bEndpointAddress */2 ^& z8 m; c$ O# Y) k
  170.   0x02,                              /* bmAttributes: Bulk */
    4 o5 c/ ^2 c" B# ?- W" m# `
  171.   LOBYTE(MC_MAX_FS_PACKET),  /* wMaxPacketSize: */
    % K' u& V! c$ b
  172.   HIBYTE(MC_MAX_FS_PACKET),
    ( c& J: E) T$ I0 j/ ?8 T
  173.   0x00,                               /* bInterval: ignore for Bulk transfer */' d" a3 \. R* Q9 |, r2 @( T4 R
  174. * G/ X; p, ?$ x* ~
  175.   /*---------------------------------------------------------------------------*/
    # t+ ?: p. p& {! H) I7 N
  176.   // IAD* h6 m1 |8 ?/ C1 D' H
  177.   0x08,        //描述符大小4 ]6 S) l% G% R' E; q
  178.   0x0B,        //IAD描述符类型1 f/ o& A9 h+ V, O! S' Y/ t* @& {$ T
  179.   0x02,        // bFirstInterface
    % I0 p( \( B( ^0 I
  180.   0x01,        // bInterfaceCount
    ' `$ g4 L& x( l; u; v
  181.   0x08,        // bFunctionClass: MASS STORAGE Class8 @2 S$ @# x- Y5 t. D
  182.   0x06,        // bFunctionSubClass
    4 X; n3 M! s2 `1 N% T
  183.   0x50,        // bFunctionProtocol3 q3 c6 v! d% z! j0 C" G- f9 s
  184.   0x01,        // iFunction   
      U* w6 K' b' g& x+ @
  185. 5 f9 M* b; L5 x" s; I
  186.   /********************  Mass Storage interface ********************/  Z5 D! s- |2 G' c" O
  187.   0x09,   /* bLength: Interface Descriptor size */
    & y! i3 T3 h1 ]& E8 P$ |9 I
  188.   0x04,   /* bDescriptorType: */
    9 M( q3 P* I& d7 y
  189.   0x02,   /* bInterfaceNumber: Number of Interface */
    ! q; q4 }; s+ E4 f& V
  190.   0x00,   /* bAlternateSetting: Alternate setting */
    ; r0 z4 r# o$ t' F% ?0 P, _. S
  191.   0x02,   /* bNumEndpoints*/
    7 n1 H( N) I# _- i3 U( m* a
  192.   0x08,   /* bInterfaceClass: MSC Class */
    5 V; J2 k. h$ l- Q0 T
  193.   0x06,   /* bInterfaceSubClass : SCSI transparent*// J7 c) t# I! c$ G
  194.   0x50,   /* nInterfaceProtocol */
    5 X' T- ]/ d* }- W0 Y' a) X& a1 }
  195.   0x05,          /* iInterface: */
    6 o1 J$ b, R( m9 L5 X
  196.   /********************  Mass Storage Endpoints ********************/, _% @4 w! Y6 T& c
  197.   0x07,   /*Endpoint descriptor length = 7*/
    ! `" P$ O9 e! ?' q( o$ @
  198.   0x05,   /*Endpoint descriptor type */9 T0 b/ W& B: e# S
  199.   MC_MSC_EPIN_ADDR,   /*Endpoint address (IN, address 1) */
    ( s0 O/ k6 p/ F* P0 m$ o3 V# l
  200.   0x02,   /*Bulk endpoint type */
    4 }5 f, Q4 W6 |/ v8 F5 L
  201.   LOBYTE(MC_MAX_FS_PACKET),
    7 @! X" Z' J: T$ o2 X2 Y
  202.   HIBYTE(MC_MAX_FS_PACKET),7 r* x$ G  `+ m% s$ d7 M
  203.   0x00,   /*Polling interval in milliseconds */
    , K! G7 |; G9 }( K# H+ P* x, ^
  204.   2 c/ e3 a9 }- \
  205.   0x07,   /*Endpoint descriptor length = 7 */
    2 J2 z7 @, _/ K7 E/ |) q( k
  206.   0x05,   /*Endpoint descriptor type */
    5 a0 R* P+ U6 R: ^; d
  207.   MC_MSC_EPOUT_ADDR,   /*Endpoint address (OUT, address 1) */! N( q* p* y% H* X7 ?4 P
  208.   0x02,   /*Bulk endpoint type */- Q# f* M! m$ r( }1 L- \# U9 n+ G/ l% r
  209.   LOBYTE(MC_MAX_FS_PACKET),
    + N: G( }+ p/ X* {9 P+ c
  210.   HIBYTE(MC_MAX_FS_PACKET),
    8 }/ d" k& {$ H8 z8 K
  211.   0x00     /*Polling interval in milliseconds*/5 A8 x9 y9 Y; @! x' X! c! N
  212. };) y* ]8 S( |4 O( `% U5 ^* F; Z
  213.   ( p& B' ^+ h  k! q
  214. uint8_t USBD_MC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] =
    . u6 k  k3 s" z  W: p
  215. {
    " @/ t) p& M) z( ?
  216.   USB_LEN_DEV_QUALIFIER_DESC,) D1 }% L. w: R
  217.   USB_DESC_TYPE_DEVICE_QUALIFIER,# Y$ b( Y7 x; \+ j: W
  218.   0x00,
    : f6 C, L) ]( f" a
  219.   0x02,/ Z- ]% g5 c- o8 i, }
  220.   0x00,+ K7 D  z9 ?- y' h
  221.   0x00," ~% H; f% g& p, _: Z
  222.   0x00,
    # }* \, D. f- }. d+ ?- n* M, A* O$ Z
  223.   MC_MAX_FS_PACKET,
    6 J4 l/ A7 S9 u$ [
  224.   0x01,
    0 ]- ^% [. i  R! X% }) B; i
  225.   0x00,- J* W4 V+ P  H7 D' l
  226. };
    $ P2 N+ o. a; T
  227. 1 @9 _/ L0 ?1 X
  228. /**
    4 D# O" B! j3 G7 e' h# V- q1 M- ?7 Y
  229.   * @brief  USBD_MC_Init9 i$ h% d. ~' P: k4 S* U# Q7 |4 y
  230.   *         Initialize  the mass storage configuration3 S3 W1 g. c! O4 }* Z7 d7 f/ r
  231.   * @param  pdev: device instance6 C1 B  l" H: j, d
  232.   * @param  cfgidx: configuration index
    ; s2 @  d4 C. F6 o4 Y
  233.   * @retval status
    0 u- x% u8 x1 }& @
  234.   */
    1 M8 p) v: W! I6 U
  235. uint8_t  USBD_MC_Init (USBD_HandleTypeDef *pdev, uint8_t cfgidx)
    2 L5 P6 k- P. m0 w5 r
  236. {% U( Q0 q/ d% @
  237.   uint8_t ret = 0U;% `! k7 l# x! B9 p: `- s

  238. 7 Q" T) n9 C; Z! j) m4 |9 ~
  239.     T( g/ S3 b4 N4 G
  240.   USBD_CDC_HandleTypeDef      * hcdc;
    , n7 z: b7 T4 j9 u# v
  241.    
    / ]% A+ e; K5 b4 P1 w" g
  242.   MC_Switch_CDC(pdev);
    8 r" j* x2 V4 y5 N% y' O* J, R# H: |
  243.   & M, a) Q$ X8 t: i) V
  244.   USBD_LL_OpenEP(pdev,4 {1 W' N. d* ~' T( v& B7 D7 \
  245.                  MC_CDC_IN_EP,
    % S  Y' Y8 T) {( Z
  246.                  USBD_EP_TYPE_BULK,$ g* d5 O+ a0 v
  247.                  MC_MAX_FS_PACKET);  S, \8 p/ l" X6 n7 h( h0 H8 K
  248.   . k- V2 s2 _0 H1 N! ~* y
  249.   USBD_LL_OpenEP(pdev,. q% k$ }0 A0 }, {2 u
  250.                  MC_CDC_OUT_EP,
    + l1 }. F( x' z1 G& H# \
  251.                  USBD_EP_TYPE_BULK,  ?( K" n( _1 b+ M5 g
  252.                  MC_MAX_FS_PACKET);# ^  ^: k* [& c7 g0 [, j
  253.   
    $ S: ?! J8 q5 M
  254.   USBD_LL_OpenEP(pdev,; Q7 s1 K9 A# g( W
  255.                  MC_CDC_CMD_EP,( Q9 o1 n) c8 N8 u& X
  256.                  USBD_EP_TYPE_INTR,1 T; W! l5 U* y5 v& G" @
  257.                  CDC_CMD_PACKET_SIZE);* y( Q. o! I5 c4 ~2 S# `5 c

  258. 4 @9 S7 a, B& O' J' Z
  259.   hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;& X# {+ _8 Z) Q1 \

  260. % Q. m$ O9 C0 t) Y; z- e
  261.   ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Init();+ h8 d! c/ u2 b: g9 X4 v. z# y
  262.   $ c5 Q# q# U$ ^  T( Z# L  F
  263.   hcdc->TxState =0;2 C5 P5 G7 t* [
  264.   hcdc->RxState =0;
    ! O0 e, }: E. z0 h8 \* A0 f8 `
  265.   
    # V. m# M. D5 ?6 c7 Z' G' g. o
  266.   USBD_LL_PrepareReceive(pdev,
    + X3 Z: F4 E6 W1 n0 R
  267.                          MC_CDC_OUT_EP,' j/ ~: j9 @4 {
  268.                          hcdc->RxBuffer,& v6 N1 E" q9 x' u; O9 M
  269.                          MC_MAX_FS_PACKET);0 s- W' ?/ {5 g% Z# z& D8 Z  y

  270. $ @4 Q7 C- I/ U( `) F
  271.   pCDCData = pdev->pClassData;
    # m; G& s2 N7 X
  272. * m7 J3 ~8 ]7 E. M
  273.   MC_Switch_MSC(pdev);
    $ Y$ ]% Q1 Y5 Q- ~; p: `9 u
  274.   $ m6 t2 L+ R/ p8 ]" b
  275.   USBD_LL_OpenEP(pdev,3 H$ Z' F, _- G( d1 z1 F& A
  276.                  MC_MSC_EPOUT_ADDR," Y) P% a& N! c% j) r# ]) M
  277.                  USBD_EP_TYPE_BULK,# e! q8 E% G; ]5 u  [" Q
  278.                  MC_MAX_FS_PACKET);' r! o7 _; z; h, O: o
  279.   
    : t" j4 C2 R: i/ ]: T
  280.   USBD_LL_OpenEP(pdev,: t% Q9 g8 N3 T! g
  281.                  MC_MSC_EPIN_ADDR,$ b, P( Z6 H; i& T( c, W% k
  282.                  USBD_EP_TYPE_BULK,( t) |, ^6 w* c* K
  283.                  MC_MAX_FS_PACKET);1 R$ k* [! _- ^. |- h" T1 x
  284.   
    0 n6 B" w" v: z: ?6 g- i9 a* x
  285.   MSC_BOT_Init(pdev);
    7 u  w+ A3 e* |2 ]
  286.   
    # ]6 J$ b, X2 ^1 Q
  287.   pMSCData = pdev->pClassData;" @" y# X3 G# o( I
  288.   ) _  g/ u6 g, R9 P7 l6 w* H
  289.   if(pdev->pClassData == NULL)
    3 N6 c$ f, j# i6 p7 B) w) A4 G
  290.   {$ }# ], `- r6 g1 _
  291.     ret = USBD_FAIL;
    0 ~$ u; `% `. T$ w6 l) f
  292.   }9 U% Z; P7 s* C6 h; _

  293. 0 P3 x, D% t% U+ [" x
  294.   return ret;& Q- M0 m( F4 }. @
  295. }# z8 ^6 r- e  X

  296. 3 t. x  N+ @, @7 f2 g- T. y
  297. /**- @5 }# B/ y4 D  V; E& p
  298.   * @brief  USBD_MC_DeInit
    % u+ v# V6 N- c! Z
  299.   *         DeInitilaize  the mass storage configuration- d$ N2 X+ Y1 _5 k5 C
  300.   * @param  pdev: device instance$ |4 ]5 _! E2 u
  301.   * @param  cfgidx: configuration index
    ; C  }8 X7 G! z
  302.   * @retval status0 x1 ?0 a2 N! R0 g# y) M6 a
  303.   */) g, V$ ?7 H; x# n) Z; [- m9 `
  304. uint8_t  USBD_MC_DeInit (USBD_HandleTypeDef *pdev, ! p4 a; L! c1 a7 y% k6 B- d# y
  305.                               uint8_t cfgidx)
    " z. M5 d4 k# b6 H7 I3 K* Y
  306. {4 V$ h; L$ @: _0 K5 z
  307.   return USBD_OK;
    , K) ~# ^  {; a( O( `
  308. }" L, f" W# W3 C. h% F. t& O
  309. /**4 Y  n" h- A/ ]/ K$ k
  310. * @brief  USBD_MC_Setup
    , r' ~* p: b" C: S
  311. *         Handle the MC specific requests
    3 B- a/ S  W/ {, a; r9 k; n, ~
  312. * @param  pdev: device instance0 n- V# j7 a1 `, H, c
  313. * @param  req: USB request) {5 p' ^: s9 A0 C7 s
  314. * @retval status  J6 H% M% U* N- r
  315. */
    % ^4 N# U; w7 n! J
  316. uint8_t  USBD_MC_Setup (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)" u8 F( w2 k' w# s  W
  317. {) [" }9 G6 g$ R7 |1 w, R
  318.   if(req->wIndex == 0x0002)
    / [% F% I- }9 C2 z
  319.   {, W. Z+ F: p3 r/ N( z; \/ }4 u# \
  320.     MC_Switch_MSC(pdev);3 x" G! g6 I5 b4 ?4 O; i
  321.     USBD_MSC_BOT_HandleTypeDef     *hmsc = (USBD_MSC_BOT_HandleTypeDef*) pdev->pClassData;   
    4 P6 _! q% ?( j& _- m& x& j
  322.    
    ( e+ M) l3 q0 C: D3 ^$ ]. ~1 J3 O
  323.     switch (req->bmRequest & USB_REQ_TYPE_MASK)
    - l& a' [% F/ x9 c# s
  324.     {
    4 `  R/ t. f, U4 ]  e* E
  325. - U7 S# V+ }  F6 ~2 q0 e
  326.     /* Class request */( ^& c9 H* e8 S: b! G7 H* M; V
  327.     case USB_REQ_TYPE_CLASS :& |) E. T6 w5 ?8 v( B# e) O0 Z' Z- v5 J
  328.       switch (req->bRequest)
    : k  `; z7 g; \4 Q% n. O
  329.       {+ k% U7 v# f6 K; w; }; l3 `, a! R/ Z
  330.       case BOT_GET_MAX_LUN :
    9 U: t& n. m( l* y
  331. " M2 w+ m0 Y- `: t4 _# l4 Z& _7 Z, f3 Z
  332.         if((req->wValue  == 0) &&
    " H: G  A7 O, a: \
  333.            (req->wLength == 1) &&
    # l# ^- w) A( l# C- f  Z
  334.            ((req->bmRequest & 0x80) == 0x80))& y" _* ]. h9 C
  335.         {
    $ i% p' c* u+ N$ {2 `4 J2 F4 D
  336.           hmsc->max_lun = ((USBD_StorageTypeDef *)pdev->pUserData)->GetMaxLun();4 K7 B6 I1 b6 o' `
  337.           USBD_CtlSendData (pdev,8 P4 O1 V! W6 V
  338.                             (uint8_t *)&hmsc->max_lun,
    8 G' E2 }! v* D' D6 V
  339.                             1);: |6 k3 j" u6 C+ P3 |. U' N% a
  340.         }3 \( r2 r3 L' T0 o" w
  341.         else
    0 \8 r* j  ]: w3 U. d# e
  342.         {
    - l, q1 f6 ]4 d- W
  343.            USBD_CtlError(pdev , req);
    9 y1 g# y- D8 P
  344.            return USBD_FAIL;
    1 S5 i# b2 V+ G) g, J3 w1 a7 `
  345.         }
    + j8 }+ F9 L9 }; e
  346.         break;5 G$ n" g/ K) W4 Z* S/ V  N
  347.         & Q. ]* I$ M: u' G( m1 p* ]  K; D
  348.       case BOT_RESET :/ p5 E  }. }7 l% Q7 r0 U& c5 A! g
  349.         if((req->wValue  == 0) && 3 H% ]4 q- h) r8 N
  350.            (req->wLength == 0) &&& b9 }4 `0 t  D5 F$ a
  351.           ((req->bmRequest & 0x80) != 0x80))
      n( a5 l! a; q" |! w2 L
  352.         {      
    ! {5 K: D) l- ^$ T
  353.            MSC_BOT_Reset(pdev);* Q. K* j. ?2 N% d
  354.         }
    3 ^2 g, ]* m1 N/ @
  355.         else
    / F- c2 B* W/ x9 L! N0 J/ Y
  356.         {  e' k) @) o  j! N% |* ^  E0 \
  357.            USBD_CtlError(pdev , req);
    " J! ^3 `  S( @& s' y
  358.            return USBD_FAIL;
    2 s8 a" H. r! y4 J5 y6 M. y
  359.         }& e" H) ?+ y/ f) y" i1 k
  360.         break;* ]! O8 w/ |9 h+ x- o  \

  361. : P9 |$ j5 O* U2 t% W. f  w
  362.       default:
    4 @. S+ D' |2 p( w: }7 x, n
  363.          USBD_CtlError(pdev , req);" y% {; w5 M( ?
  364.          return USBD_FAIL; / R% v# @9 M# @- o( ?+ c. p/ {
  365.       }" f/ I8 I7 p. o. z8 P8 L  e8 s
  366.       break;# s9 T! b5 v% x
  367.     /* Interface & Endpoint request */
    & N9 q! u# y8 h$ F* _# @  s2 R
  368.     case USB_REQ_TYPE_STANDARD:
    ) ~0 w+ w5 \; |8 L6 |6 @
  369.       switch (req->bRequest)
    6 i/ z# A( g8 p( Y% O. n
  370.       {, E, F# Y: X* `; i3 X0 c
  371.       case USB_REQ_GET_INTERFACE :8 v3 t- F0 w! C
  372.         USBD_CtlSendData (pdev,# v3 J, l, k" l- p' t. Z
  373.                           (uint8_t *)&hmsc->interface,
    / Z  z* r3 q& S% c! v
  374.                           1);8 r5 q8 ~9 T- n) u5 F
  375.         break;
    ) B1 |2 K4 F0 f# R3 V( E
  376.         
    5 C, U9 Q2 v; M9 S
  377.       case USB_REQ_SET_INTERFACE :
    / ]8 v1 E8 c( |
  378.         hmsc->interface = (uint8_t)(req->wValue);
    6 Q7 R$ p  j& M  L/ v# G
  379.         break;
      ~* W) F' |) X0 _
  380.       
    * c- v2 n8 f1 T4 Z
  381.       case USB_REQ_CLEAR_FEATURE:  
    & X' N% |  s6 c) k+ r
  382.         9 u" z3 A& V4 f9 D
  383.         /* Flush the FIFO and Clear the stall status */    7 j0 C2 {$ s6 a; p2 ?! v& V! Y
  384.         USBD_LL_FlushEP(pdev, (uint8_t)req->wIndex);
      l$ M: j- }& X
  385.         # S# v, C6 P# q8 f# o$ V
  386.         /* Reactivate the EP */      
    ) u. q; m/ E& o1 d
  387.         USBD_LL_CloseEP (pdev , (uint8_t)req->wIndex);# U# ]+ j3 r5 `
  388.         if((((uint8_t)req->wIndex) & 0x80) == 0x80)$ Z' {: v% A- ^5 q* _8 R$ h9 N! D; o
  389.         {
    + N/ f# [$ }2 T+ O4 V( L2 a
  390.           if(pdev->dev_speed == USBD_SPEED_HIGH  )
    3 ^7 D4 F$ ]; {6 Y4 ^4 ^$ ^9 j  _
  391.           {
      R+ n1 U/ W* ~+ }, A
  392.             /* Open EP IN */
    0 Y# Y& t" D" w1 [) t( T* ~" Z  j- h
  393.             USBD_LL_OpenEP(pdev,
    7 o  g4 W: D" u* C% y
  394.                            MC_MSC_EPIN_ADDR,
    . L9 L2 q; q  z% @
  395.                            USBD_EP_TYPE_BULK,4 U# @( M0 T* \  M. C
  396.                            MSC_MAX_HS_PACKET);  
    - y: L/ W& a& b) _% X0 U7 p
  397.           }/ m7 i( ]& _1 D$ L0 y7 _! X6 Z* S$ S9 G0 f
  398.           else) X% ?1 P! {: ^- ~
  399.           {   
    % w4 ]) l' u& E9 o7 ^
  400.             /* Open EP IN */
    * w% p) P2 S6 T/ b+ w- \# i4 I
  401.             USBD_LL_OpenEP(pdev,
    - k0 y9 K* J6 v6 s8 B' C
  402.                            MC_MSC_EPIN_ADDR,
    3 D/ F0 K, S5 Y( W; ?
  403.                            USBD_EP_TYPE_BULK,
    7 C, q9 U$ f% i2 s7 H0 E0 S
  404.                            MSC_MAX_FS_PACKET);  
    1 ^5 U* A1 t1 H& y& k$ r" }" @# k
  405.           }, |: b) j6 z4 G0 y$ ~
  406.         }
    & W' d* H  M! H( S+ Y3 d2 Y
  407.         else! f$ I/ y2 R, d# A/ M: d
  408.         {
    ; \  d& p; |, J2 P
  409.           if(pdev->dev_speed == USBD_SPEED_HIGH  ) & f: R6 ~0 e, u4 M
  410.           {
    - h" j1 D" Z; F, ^" l" L& G
  411.             /* Open EP IN */  ]# X! I$ K+ ^+ P1 C2 o, n
  412.             USBD_LL_OpenEP(pdev,
    ! N" M) \# }0 E, x) D
  413.                            MC_MSC_EPOUT_ADDR,) Z( G) n& a+ N6 V9 a6 D1 G
  414.                            USBD_EP_TYPE_BULK,
    ' Q* G  ?5 @  m- U1 g) |4 T* T
  415.                            MSC_MAX_HS_PACKET);  % |4 a' |+ f1 N: A+ A
  416.           }
    9 V4 j, F; o+ H5 M( J
  417.           else0 L* K; X5 g: I4 B3 F) Y
  418.           {   . a2 o0 L- a3 N4 q3 b
  419.             /* Open EP IN */% |: {" M3 d* Q( q5 A: A" d8 Y
  420.             USBD_LL_OpenEP(pdev,: z; w7 M; a2 y% d" [
  421.                            MC_MSC_EPOUT_ADDR,
    4 [! [# |" W+ s
  422.                            USBD_EP_TYPE_BULK,
    ! c. l+ [1 ?' D4 \* ~* y5 G
  423.                            MSC_MAX_FS_PACKET);  
      l3 p4 e/ e* J! o' I
  424.           }: R4 a+ t  n# v6 p
  425.         }! F. B/ v8 I' Q; @
  426.         ! Z8 B5 J9 p) r4 ~
  427.         /* Handle BOT error */
    , X& k1 I; t. ?$ {6 u
  428.         MSC_BOT_CplClrFeature(pdev, (uint8_t)req->wIndex);
    . r, s5 R$ d, g* J7 x
  429.         break;6 a4 B. q" K  W1 y- f
  430.         
    1 q6 }# y. T- ~* K+ |! L5 N
  431.       }  8 R( d" M6 M8 V/ W, y) z8 D
  432.       break;
    7 D! o) S' E" M5 p$ X2 I8 d( [! D
  433.      
    $ K. R7 Y9 x- w
  434.     default:
    . T# T- Z- g& U' f  l5 R
  435.       break;3 L: v2 q  N9 D$ k3 q5 ~; n/ ]8 F
  436.     }$ X  b5 E( w8 b. }
  437.   }/ U0 T7 ?4 M8 R$ J
  438.   else7 Z3 F; q; x$ F. b
  439.   {
    5 r" F6 t  B- a) ?: C/ g
  440.     MC_Switch_CDC(pdev);
    ' w: }2 J2 d( T. y) J8 _
  441.     static uint8_t ifalt = 0;( J( i% ^. Y- n# \
  442.     USBD_CDC_HandleTypeDef * hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData;   * y5 W9 }+ d3 D' W
  443. ; _% c! i8 U' w3 ]: t# z& \
  444.     switch (req->bmRequest & USB_REQ_TYPE_MASK)# U4 C4 i$ L0 c
  445.     {
    . L. k9 @" o" o  |
  446.     case USB_REQ_TYPE_CLASS :
    ' ^( B0 Z4 E: O; Y
  447.       if (req->wLength)
    3 f5 X3 U4 u% R; p0 h8 s
  448.       {
    : W1 a2 I8 r1 a& R$ i3 X* y
  449.         if (req->bmRequest & 0x80)- j5 r* A2 f) R
  450.         {
    2 E& z8 x) Q4 _4 _1 B- A: N+ |( Z
  451.           ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest,
    1 K. H1 R* b6 L: ?6 X6 {1 L' o
  452.                                                             (uint8_t *)hcdc->data,4 a- }! G0 G+ g: h( Z0 m
  453.                                                             req->wLength);: c* h7 @6 i) P% y( j
  454.             USBD_CtlSendData (pdev, 7 d9 p" c7 l) L; i
  455.                               (uint8_t *)hcdc->data,
    9 S6 m# o& F$ `, ]. \
  456.                               req->wLength);
    7 B' l" ^* I8 [2 |
  457.         }
    % H. T8 y; y7 c6 A* l* B. D3 C
  458.         else0 ?5 H# x5 C' M2 E4 I/ B. d3 n1 H! ~
  459.         {2 `. v# J# P. d) Y$ o
  460.           hcdc->CmdOpCode = req->bRequest;
    1 R2 R8 h9 l. H) Z
  461.           hcdc->CmdLength = req->wLength;
    5 Y! [' s& P& [+ M! x0 Z
  462.           % u. e+ n. O: a! u. \9 y# J
  463.           USBD_CtlPrepareRx (pdev,
    ( q* `; [2 q1 S5 c# J' Z) U
  464.                              (uint8_t *)hcdc->data,/ t* w' i& U: C3 C7 b- ~
  465.                              req->wLength);( c% E) f* Y( E+ Z; X
  466.         }
    ' X. c( O. |6 o
  467.         6 h* _3 |. r0 _6 K
  468.       }
    - ^! C) j% L- J' V" }7 c
  469.       else
    7 e( E8 `7 Q4 w  y& s  T% K- |) j
  470.       {6 S3 e( g/ |+ k3 ~7 G2 v
  471.         ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest,& Q, S! E. G( k1 T2 ~
  472.                                                           (uint8_t*)req,
    # e- H: w3 N9 p2 a9 w
  473.                                                           0);( ]# E/ {- o2 d6 x
  474.       }2 Z# T) a, s+ _" S7 |5 j
  475.       break;
    5 ~; p- u9 ^/ z- C# Y
  476.    
    6 l+ K- V! e, e% S5 L: C2 J
  477.     case USB_REQ_TYPE_STANDARD:! D& c/ @) {7 ]
  478.       switch (req->bRequest)8 f( \+ |1 {# ?3 V; B4 ]
  479.       {      
    - W( A$ y8 H& d9 q% |' S7 u
  480.       case USB_REQ_GET_INTERFACE :& s: \' E' g, v% n9 ?& j
  481.         USBD_CtlSendData (pdev,
    / h8 B) e# c( ~3 N( z+ @
  482.                           &ifalt,
    $ {7 [# d" l$ ^$ Z; [6 o, J
  483.                           1);5 j' L' h( a$ U0 F( N% p
  484.         break;  q' K7 v. |" _% ^0 }
  485.         
    7 p) z6 f: X( v: Q
  486.       case USB_REQ_SET_INTERFACE :
    4 Y0 E; V" `2 r2 @
  487.         break;
    $ ?1 t8 E% T! Y) E1 \4 @- |# F
  488.       }
    # B: a2 J2 C: H7 t) R' o( U
  489.     $ e; Q7 X8 Y$ a; v# X' V: o
  490.     default: ' G0 ^& Z# j) [/ q( M/ z
  491.       break;" l' N* h# p- m. [
  492.     }  
    - [+ G  i. B+ q, s4 ?" v
  493.   }
    1 }; J7 N" \: X% t! O
  494.   8 |7 j1 k/ k7 n9 H- H0 I
  495.   return USBD_OK;' x, m; i" J1 o' s( [- q0 m
  496. }
    ; D" E* I# N5 [# Q0 k( t- V

  497. / l  c1 [& f, ?* l9 {
  498. /**
    2 E- w. M: A4 \
  499. * @brief  USBD_MC_DataIn
    ' `# a0 {. ?# w! z1 B
  500. *         handle data IN Stage7 w" ]* u$ o; h5 R% S% C
  501. * @param  pdev: device instance
    9 l6 `' k6 w& C1 W9 f1 f
  502. * @param  epnum: endpoint index5 c/ j, l6 R+ i6 U$ }/ S$ g
  503. * @retval status+ s* I6 E0 X" l/ E% A( K
  504. */, L' I2 |2 B5 |4 L9 m6 d
  505. uint8_t  USBD_MC_DataIn (USBD_HandleTypeDef *pdev, * z+ Q! V. j5 Y, M; l
  506.                               uint8_t epnum)
      B" L2 _1 N5 o0 U. }
  507. {7 D: |6 S& \9 [1 s
  508.   if(epnum == (MC_MSC_EPIN_ADDR & 0x7f))
    / j% U" B: e0 f1 H% ?% L
  509.   {( o4 P' N( Y# A6 {: Y" C
  510.     MC_Switch_MSC(pdev);7 |3 n! W2 O" v$ d
  511.     MSC_BOT_DataIn(pdev , epnum);
    0 v; `+ M, v+ I2 r, W: W" Y- c( K6 I
  512.   }/ |; J1 o5 q0 G
  513.   else if(epnum == (MC_CDC_IN_EP & 0x7f))& U- s- t  C% O& j. j
  514.   {
    + N; J6 N8 Y3 G+ {
  515.     USBD_CDC_HandleTypeDef   *hcdc;
    * a; z8 ^" r: l' V2 v
  516.    
    7 A# f% s( ~& I3 Y/ Z2 }
  517.     MC_Switch_CDC(pdev);. |; k- p& k9 j5 Y
  518.     hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;( I4 u) L: J, c7 d! c
  519.     hcdc->TxState = 0;      O9 L' h, S0 N
  520.   }
    ! ?& t- p( N: E! _6 z4 o1 F# U
  521.   1 B) }+ Q! m/ p- S+ ]
  522.   return USBD_OK;
    " B1 f. o8 V5 x9 u: o
  523. }
    ; b7 X/ A5 d* x1 ~: o( [4 Y
  524. ' ^2 T( S5 |; z, ?3 ]: }
  525. /**) e. ~2 L, ^; o4 g" H
  526. * @brief  USBD_MC_DataOut
    " [" u6 Z( m5 `; F- T" ~$ X' K
  527. *         handle data OUT Stage
    2 R2 q- L- U. _/ q. V' p: b
  528. * @param  pdev: device instance& l+ e8 R5 j+ f8 `6 l3 X, j7 f1 S
  529. * @param  epnum: endpoint index9 c- x) R$ X+ R* m
  530. * @retval status. F6 [9 k7 O2 I, X7 D
  531. */8 w& r1 s3 G% X, k/ p
  532. uint8_t  USBD_MC_DataOut (USBD_HandleTypeDef *pdev, / Y( t+ N5 J3 Z8 @8 J, t$ ]
  533.                                uint8_t epnum)/ V* k* h$ c( b+ A0 P5 F; ^- o( L
  534. {2 h, o6 S; E/ e- C7 \" L
  535.   if(epnum == MC_MSC_EPOUT_ADDR)
    " [" t1 t2 V  Y3 l7 O" M
  536.   {
    0 A' F* W$ n# _2 ]9 Q2 a/ g5 ]
  537.     MC_Switch_MSC(pdev);
    + p# f# k4 U2 {, A8 Y5 y- u
  538.     MSC_BOT_DataOut(pdev , epnum);
      R, M$ T  e( S/ H4 I+ y: ^# B
  539.   }
    . x! T0 p3 C# R% ]: c( U& @
  540.   else if(epnum == MC_CDC_OUT_EP)
    ; E  r3 o; j/ ?$ h  N4 f9 }
  541.   {) V; T& c4 S- x" s8 R$ ?5 W$ Y
  542.     USBD_CDC_HandleTypeDef   *hcdc;
    ) ]; g: t& q/ P5 [9 V4 P( B
  543.    
    1 h; L- \5 L2 Y+ m' }) R
  544.     MC_Switch_CDC(pdev);
    3 A5 @5 `3 o4 y  S5 H/ J
  545.     hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
    6 L- t4 R2 w! N0 r6 O" y
  546.     ( ~3 G6 a. G7 X! c# u
  547.     hcdc->RxLength = USBD_LL_GetRxDataSize (pdev, epnum);% G) A$ t( `! l) |: v) |- J6 g
  548.     ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Receive(hcdc->RxBuffer, &hcdc->RxLength);
    3 b6 Q/ Z$ Z+ V% `
  549.   }
    7 p" @# [; f+ G9 c+ E0 c
  550.   ( o. o6 e2 t6 Q4 P8 t% e
  551.   return USBD_OK;
    * p* q# L/ O" p! E& O: j3 t0 g9 E) P3 i
  552. }
    ! _% `# M  f3 g( n) F6 ?( v7 n+ g

  553. / d( A! A" b9 a% q# w  n/ l
  554. /**
    : b) z9 @# L8 U& S0 g
  555. * @brief  USBD_MC_GetHSCfgDesc + H3 c. u9 }% E% M5 X- f; L) a
  556. *         return configuration descriptor9 H/ t; b7 g$ s3 j+ h
  557. * @param  length : pointer data length
    ' a1 t9 `/ b& A7 T+ r0 I5 m
  558. * @retval pointer to descriptor buffer
    1 T! r% D1 i$ @; h) }
  559. */+ q$ ?3 t% i$ Q& s' n# p
  560. uint8_t  *USBD_MC_GetHSCfgDesc (uint16_t *length)! h' @/ l' l% [( o: O! I
  561. {
    % ^1 x) N! v! c' o4 ~6 [' u* V4 w
  562.   *length = sizeof (USBD_MC_CfgDesc);# A7 K! A0 A( {, o0 f! t! [$ z
  563.   return USBD_MC_CfgDesc;
    " R& Q' t. q- ^' h" b
  564. }
    * F( e; ?& A  m  m5 d% s
  565. ( w- n3 `3 O4 W) W8 c) |9 ~
  566. /**- A5 [& r9 U9 Z/ @$ a$ S# w; |
  567. * @brief  USBD_MC_GetFSCfgDesc - ^+ U0 h5 E/ S+ y! B, `* Z
  568. *         return configuration descriptor+ N8 Z/ N7 D4 W
  569. * @param  length : pointer data length
    9 e$ W1 g" l% @: ]  A6 v( g
  570. * @retval pointer to descriptor buffer3 t9 a& M9 K: d% ]5 [0 s0 }
  571. */
    2 w, u3 r$ ]2 I$ V
  572. uint8_t  *USBD_MC_GetFSCfgDesc (uint16_t *length)
    9 p) x; L1 b; o7 S6 h
  573. {
    3 r% n" _; B9 [; ]* {% s3 R
  574.   *length = sizeof (USBD_MC_CfgDesc);) l; x7 O" `% J8 c2 V
  575.   return USBD_MC_CfgDesc;
    $ E9 {* a- G  P; P( ^% t
  576. }% g7 k) t2 @' A
  577. / j; y" H% y; }4 O, ]9 q
  578. /**, H* o& J' p1 M, y7 J7 Q, f
  579. * @brief  USBD_MC_GetOtherSpeedCfgDesc
    0 M+ ~/ x: `9 q8 h, T
  580. *         return other speed configuration descriptor
    9 }: n: t0 ^8 C+ W- l" t
  581. * @param  length : pointer data length0 b& v4 g  q& |2 E* Y
  582. * @retval pointer to descriptor buffer
    3 Y3 l! u6 C$ O5 c: K% W: t$ y  D
  583. */
    ! m$ o" |4 M3 X: M9 o+ x
  584. uint8_t  *USBD_MC_GetOtherSpeedCfgDesc (uint16_t *length)
    + [3 Q$ ]4 `& j/ P6 X8 c
  585. {$ I8 a3 p0 z8 Y  ^
  586.   *length = sizeof (USBD_MC_CfgDesc);/ p, B+ Y/ `. m2 w
  587.   return USBD_MC_CfgDesc;
    + ^$ q1 d+ {7 \1 }7 c- V
  588. }+ e6 I, E, D& A4 c1 U0 I: O
  589. /**+ Y: f) s, q  |
  590. * @brief  DeviceQualifierDescriptor
    $ U0 M1 P3 i+ L
  591. *         return Device Qualifier descriptor6 g9 D0 L5 X* x6 |
  592. * @param  length : pointer data length
    * [9 Z; A  v, ~2 x) w
  593. * @retval pointer to descriptor buffer! @) A1 X2 h+ x) ^9 |
  594. */
    - w" u$ g9 v- v1 s: B4 M& h) X  R
  595. uint8_t  *USBD_MC_GetDeviceQualifierDescriptor (uint16_t *length). i8 E5 |4 {; ^' X
  596. {
    % X5 Q% I: M0 f; y
  597.   *length = sizeof (USBD_MC_DeviceQualifierDesc);
    % E) N+ W: f7 j/ n3 b2 j  S
  598.   return USBD_MC_DeviceQualifierDesc;
    ; [1 A! A( y  Y6 V
  599. }' Z! ^9 H! o  p9 g, `( D  I
  600. % T# B! e+ F( ~! L
  601. /**
      P! t+ U4 x. u6 Q
  602. * @brief  USBD_MC_RegisterStorage
    7 F# K- v0 l( U6 ?) \: x0 a
  603. * @param  fops: storage callback
    ! o9 c/ ^4 N6 ?
  604. * @retval status
    0 z. U( t) J8 F" R3 `  M0 W
  605. */6 y" F4 g2 M; }3 A
  606. 2 D; R$ T* w0 A/ H% F
  607. static uint8_t  USBD_MC_RxReady (USBD_HandleTypeDef *pdev)$ Z8 c# Z) X2 c7 f9 b+ Y
  608. {$ h: t6 g4 r1 R
  609.   USBD_CDC_HandleTypeDef   *hcdc;% b/ Z% Y8 {% C2 H  h; k6 P$ R+ j
  610.   
    & C2 O; A& o* ~% R7 F
  611.   MC_Switch_CDC(pdev);' x: K: l- h0 w0 z# W3 y- ^
  612.   hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;+ S8 a8 |7 ?6 A# t  \9 z) Y
  613.   
    ; g. f# b3 o- N  b
  614.   if((pdev->pUserData != NULL) && (hcdc->CmdOpCode != 0xFF))# n: b3 N/ O" W
  615.   {
    5 A/ L5 H/ W1 @5 O* X) |$ q
  616.     ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(hcdc->CmdOpCode,
      o+ A8 ^  P% c5 E- b6 r3 d. k
  617.                                                       (uint8_t *)hcdc->data,
    7 E2 r& i8 Z4 \3 ^7 h* w
  618.                                                       hcdc->CmdLength);
    ; U' x, s; {3 j0 [
  619.       hcdc->CmdOpCode = 0xFF; 9 c% ]& w6 N- W
  620.       
    # _. N0 z4 r5 @, B5 g1 l
  621.   }
    7 w* e4 {; Q& O6 D1 X
  622.   
    / T3 H0 b8 Q; {* E5 w" P8 @
  623.   return USBD_OK;+ S  T$ E( \" z, A
  624. }
    0 @2 D2 Q( `. a- L- v

  625. - V, n: P$ H9 r( @, D. R& P0 t
  626. static void MC_Switch_MSC(USBD_HandleTypeDef *pdev)' Q2 P- K! k/ D+ w) l; S
  627. {
    2 t, z& `: k1 S: m
  628.   static USBD_MSC_BOT_HandleTypeDef msc_handle;
    6 }* y3 C* ~* ^+ T
  629.   
    3 v/ N% v6 m  f
  630.   USBD_MSC_RegisterStorage(pdev, &USBD_Storage_Interface_fops_FS);7 I. j* F: b% s- h
  631.   pdev->pClassData = &msc_handle;
    $ |7 {' J" G& s6 s. N
  632. }
    $ G( ^" C: x2 b5 ?- G- U- U

  633. & u. u/ e4 l6 b9 r* |
  634. static void MC_Switch_CDC(USBD_HandleTypeDef *pdev)$ e0 y  j4 a7 @3 s" o- l
  635. {
    # b6 A- i- r  m8 C: `( \  H4 a
  636.   static USBD_CDC_HandleTypeDef cdc_handle;" J* U5 [% e: G2 \) w4 l
  637.   : g4 w" J" d3 U. h" g
  638.   USBD_CDC_RegisterInterface(pdev, &USBD_Interface_fops_FS);
    4 ^  W# i; |" Q. j5 j0 a2 Y
  639.   pdev->pClassData = &cdc_handle;  x; `" A/ U7 p, n" l2 D. f
  640. }7 U/ |, [+ a. P* ^& F3 x
  641. ' J  U! _+ }6 \1 e9 Y9 g( h
  642. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
    " z5 I2 C( O. w7 s
复制代码
9 ^- N( ?% _' J0 u, P( g: Z% s
通过以上修改后电脑电脑端显示USB复合设备MSC+CDC( H7 {; F* Z& s1 C" ^
msc cdc.png
+ F5 V# C+ H$ y: o- |+ s0 J2 O, O
13.在usbd_cdc_if.c  CDC_Receive_FS   /* USER CODE BEGIN 6 */ 增加发送测试# x$ ~7 j3 g1 Y8 J' T
8 v9 U. ?0 S. F, f& a1 U3 V$ U1 @* B% p
  1. static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)" A# ?& _$ ]5 r, U( m3 J- E
  2. {& o6 K0 m3 z' d7 s8 j' U
  3.   /* USER CODE BEGIN 6 */
    " A- p/ I- d8 m+ \( y$ ?$ b% M; M
  4.   USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);5 @$ t2 f; G1 \3 s
  5.   USBD_CDC_ReceivePacket(&hUsbDeviceFS);
    6 s  T! R% l0 E( A  f9 Q: F" D
  6.   , x  D# G; @) P) ?  \; @+ v: C
  7.   CDC_Transmit_FS(UserRxBufferFS, *Len);      //把接收的返回" m0 K. ^2 e$ m9 p4 X: h& T
  8.     @7 V4 e, f: _1 v
  9.   . c( v3 D; r, t* F7 S. n
  10.   return (USBD_OK);( j/ B9 V' G$ U" d+ T
  11.   /* USER CODE END 6 */
    & @5 Q- q( L  W8 c& d
  12. }
复制代码

) q; B% Y! m2 J6 m测试串口收发* o( G* {# W- P4 G8 V
test.png
. r4 K% J6 |2 Q
: y, ^3 ^% ^) z7 M% Y  {: S7 @
& D0 x1 }4 T8 y$ J) l: E
0 W3 p( u6 E3 s6 }0 j. F
, d6 W& ?: B6 Y1 J% U& u( F

评分

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

查看全部评分

收藏 4 评论9 发布时间:2019-6-23 13:44

举报

9个回答
STMWoodData 回答时间:2019-6-24 11:42:56
提示: 作者被禁止或删除 内容自动屏蔽
Kevin_G 回答时间:2019-6-25 10:04:19
赞一个~
hds1988 回答时间:2020-6-28 23:47:20
完全按照楼主的说明操作一顿后,不能识别出CDC,但是能识别MSC。MCU是F407VE
desk1983 回答时间:2020-6-29 09:48:11
非常好的资料,对初学者很有帮助;
2 V8 A# k) n* f( k4 W希望楼主多多分享,赠人玫瑰,手有余香,念念不忘,必有回响;
hds1988 回答时间:2020-6-29 09:52:41
完全按照楼主做法,在win10环境下U盘和串口都可以实现功能,在win7环境下,串口错误识别为mass storage
289466080 回答时间:2020-7-15 09:54:26
hds1988 发表于 2020-6-29 09:528 h) `2 g( r* S6 U7 q! L  D6 M4 g
完全按照楼主做法,在win10环境下U盘和串口都可以实现功能,在win7环境下,串口错误识别为mass storage ...
7 d+ {7 z& E# C6 S+ Y9 X% f; t( U
是不是驱动问题,我电脑Win10
电子ai好者 回答时间:2020-11-19 12:57:48
hds1988 发表于 2020-6-29 09:52
; N. M5 ^% u5 j+ b* t8 V7 o完全按照楼主做法,在win10环境下U盘和串口都可以实现功能,在win7环境下,串口错误识别为mass storage ...

8 \, y4 S5 X4 R6 h5 I 微信图片编辑_20201119125724.jpg 我现在就是win7系统,和你一样的现象。请问你找到解决办法了吗?
, G. ]/ j& }$ p6 |( k
js123456 回答时间:2021-8-10 15:34:43
用stm32cubemx生成的项目cdc,在文件usbd_conf.c中,USBD_static_malloc申请内存是以USBD_CDC_HandleTypeDef为准,函数如下:
0 V  z, u  y3 D3 S1 L  gvoid *USBD_static_malloc(uint32_t size)9 o3 D3 f2 ^) x* Y
{; [4 {4 w( M. L) }6 p
  static uint32_t mem[(sizeof(USBD_CDC_HandleTypeDef)/4)+1];/* On 32-bit boundary */
$ B9 b2 s- P1 E0 A" V1 t  return mem;, l) G8 {5 q* ]0 E& y2 N4 ]  _
}6 y- ^+ k, f: x- ~) v
0 }3 N  b( H% E0 e7 w( [
那么在组合设备中,USBD_MSC_BOT_HandleTypeDef和USBD_CDC_HandleTypeDef都需要申请内存,怎么操作?" o: q& S) P6 f- H6 U

- ?- d6 c$ x1 o! N
js123456 回答时间:2021-8-10 15:35:35
hds1988 发表于 2020-6-28 23:47
3 G8 k) Z$ ?, _7 r/ V完全按照楼主的说明操作一顿后,不能识别出CDC,但是能识别MSC。MCU是F407VE
3 j4 V6 I8 E: u4 t2 Y7 |# ^
有可能是函数USBD_static_malloc的问题
9 `: V& I. @$ u' C6 O

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版