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

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

[复制链接]
289466080 发布时间:2019-6-23 13:44
本帖最后由 289466080 于 2019-6-23 15:56 编辑
' ?, B: ?% t1 D7 j
2 w4 Z/ \/ g' Y2 Y    最近做个USB复合设备CDC+MSC,在网上找了好多基本都是F103做的复合设备,带OTG芯片USB复合设备网上很少可能是我搜索的关键字不够理想有的不够全面,官方给了一个视频教程但是没有参考代码,社区里面有分享到github我按照后也不能实现,后结合F1与github分享的+官方视频,实现了在STM32F730R8T6上面USB复合设备,分享下怎样用cube生成的代码实现USB复合设备(带OTG的芯片).
6 H, f5 u8 Q  t8 }9 ~$ O) c7 ]: X0 @& \, ^, b, W
参考:* l! f  C# \. M4 n+ [
github分享0 m7 E" y; g% \/ G
http://github.com/uwyciw/CDC_MSC7 z9 Y- z1 z- p+ x& D, q& U
官方视频
5 I) e/ e' X  G+ @! X& ohttps://www.stmcu.org.cn/video/index/detail/id-3988
# O: |0 c& B8 @- c6 k3 @F103
8 M0 s1 x& `# ~3 _8 I* v  v6 xhttp://www.bbsmax.com/A/kjdwBXA5Np/7 m1 T9 W: b9 p/ ]0 Y9 _& x8 \5 _, d
; {! z. P8 I5 O

" l- a# G3 B$ Q: `: B4 T3 T& Y" icube 5.2.1+ `$ Q5 g. G6 k/ |; N, l4 l) s: \
hal  stm32cube_fw_f7_v1150.zip' c0 `( s5 E7 l5 d

( `4 R# P, y1 ]% gUSB为 USB_OTG_FS" {% V5 C% {8 h, |7 g

1 `- ^0 x. v8 P8 J1 k- g% o1.先生成一个CDC工程下面配置图。
& W2 I" \1 }2 v/ i* MRCC如图箭头其他默认
  |0 U$ |  I# m4 u  E# v9 E RCC.png
; s% h8 q4 g; h+ H% H+ {USB_OTG_FS如图箭头其他默认9 c& d7 @, @: n8 l/ ^6 t5 X
USB_OTG_FS.png
- w6 }6 O1 V% ^4 xUSB_Device
如图箭头其他默认
( A6 L- f/ Y+ z& v# Z USB_Device.png   w* F4 z# Z7 Z5 t- l5 \8 V
Clock如图箭头其他默认我用的16M晶振比8M便宜
4 f# d& X/ n; C5 b4 A* { Clock.PNG % H; `" |0 r- \: B
; C' L! g- K  c5 }! e0 u
Project如图箭头其他默认& u3 `$ {4 r# {/ h; X
Project.png
1 Z1 h% K1 [% b8 U6 F6 ycode如图箭头其他默认$ a0 H2 S) s" R" I' f# q
code.png - J. V0 U: ]% ^2 \0 L6 H# d% _
2.同样生成一个新的MSC工程不可覆盖原本的工程只需修改下图与工程名其他一样
! a" H/ m& h7 y! D- `' v' _; z2 _
8 z3 p' m; V, w) F5 p USB_Device-MSC.png . g* e( ~4 I4 Q+ K, o
, k6 k5 R% J* D! P

' |" Y+ \! k. ?& v* {7 {2 V3.生成后把CDC工程下Src文件夹里的usbd_cdc_if.c与Inc下的usbd_cdc_if.h复制到MSC工程下Src与Inc文件夹里面,MSC工程下Src文件夹下新建usbd_composite.c与Inc下新建usbd_composite.h
- K9 \/ \/ s. A/ D9 p& l# G* h. g3 @2 ?
h.png
1 K6 B, B* G( H8 F# w
. e! ?5 I) v5 b* c- l8 N% a$ m4.把CDC工程\Middlewares\ST\STM32_USB_Device_Library\Class目录下的CDC文件夹复制到MSC工程下见图
# h2 f2 d) X* G cdc.png
& {# I# C- t; n! l! i2 A$ s5.添加CDC路径
; v4 G: |* S% k- L( v' z2 u5 `+ s3 ]' P) A
CDC-PATHS.png
0 Z! s5 j( Z6 o
1 }" W1 j" i' Q0 Y% u6.在工程中添加usbd_cdc.c usbd_cdc_if.c usbd_composite.c见图. O0 P3 F& o+ i1 X9 W9 s
keil-add.png
" _: |- q/ O& R: b( ^: U$ c" @* @) g1 ^+ J5 V7 R7 m
7. usbd_conf.h 把USBD_MAX_NUM_INTERFACES值 1修改为3
* z' \3 s  r2 j) M$ g. E
  1. /*---------- -----------*/' t7 W& a! D) ^! Y$ }7 p( P
  2. #define USBD_MAX_NUM_INTERFACES     3U    //1U  j) j( r& H, }  S) E6 i/ U
  3. /*---------- -----------*/
复制代码
8. usbd_cdc.h 修改CDC_IN_EP CDC_OUT_EP CDC_CMD_EP2 V% l7 X4 [( Y5 z* `% h. P
  1. //#define CDC_IN_EP                                   0x81U  /* EP1 for data IN */
    & q! |3 P$ r3 S! v2 Y
  2. //#define CDC_OUT_EP                                  0x01U  /* EP1 for data OUT */$ [8 v0 ?, z5 B
  3. //#define CDC_CMD_EP                                  0x82U  /* EP2 for CDC commands */
    % @. G: T8 T6 @3 d8 z
  4. #define CDC_IN_EP                                   0x83  /* EP1 for data IN */  z  j; X# ^5 `( X
  5. #define CDC_OUT_EP                                  0x03  /* EP1 for data OUT */% y( ~* y  M' V8 b/ s6 H$ W
  6. #define CDC_CMD_EP                                  0x82  /* EP2 for CDC commands */
复制代码
9. usbd_conf.c  USBD_LL_Init中新增6 `% `, i# Y! f! X$ g( L6 \6 M
  1.   HAL_PCDEx_SetRxFiFo(&hpcd_USB_OTG_FS, 0x80);: h. n  L6 l5 ~) d" r
  2.   HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 0, 0x40);1 ]+ q6 {, K# B
  3.   HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 1, 0x80);/ X) ]$ X7 }" e
  4.   
    # O9 Y/ F- W3 [9 c
  5.   HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 1, 0x40);   //新增
    + K: q; n' \, n/ |' z4 E8 p' W
  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
$ v4 B! q" }' ]) G. c- B/ d# |* D
% R: I7 n2 o5 g) D0 ]' b, ^

  1. 6 r# o  s! ]- x; k
  2. /* USER CODE BEGIN Includes */4 k2 f* S" J3 o, M& u1 g( p
  3. #include "usbd_composite.h"' G* t& t" c. }) {
  4. /* USER CODE END Includes */9 o& w  X8 Z0 H0 Q+ e" c

  5. . I: ]" r/ P* A" b, ]. G
  6. void MX_USB_DEVICE_Init(void): c1 y5 R" g3 w! R: v6 U/ e& k
  7. {
    ; K- H" _" u  c2 `# q  R; `+ K/ W8 v
  8.   /* USER CODE BEGIN USB_DEVICE_Init_PreTreatment */
    & Y& \1 a5 q  O+ k: g6 \
  9.   ' ~7 ?( f' g" P
  10.   /* USER CODE END USB_DEVICE_Init_PreTreatment */
    ) |  i. Q5 _$ S9 G7 x4 P; X9 k5 }
  11.   
    1 |  Y% d( r9 Q: l& c9 _2 ]
  12.   /* Init Device Library, add supported class and start the library. */
    5 N4 S9 I3 l9 w% ]
  13.   if (USBD_Init(&hUsbDeviceFS, &FS_Desc, DEVICE_FS) != USBD_OK)9 l  Z- H4 q) O
  14.   {
    : M) E8 u" I" B: W0 N- h' p2 N
  15.     Error_Handler();6 O  [7 g; e, l: d: Q, O  L5 e, [
  16.   }* e% p) I5 E; {  e) _
  17.   if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_COMPOSITE) != USBD_OK)  //新增
    ( z: H: @7 }4 j  S
  18.   {" L  ]+ X0 R  R5 b. M1 w: _
  19.   Error_Handler();7 Q% g: o. E! g; S
  20.   }5 l' {, i  k& J
  21. //  if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_MSC) != USBD_OK)
    6 v9 g5 n  r. y' x( ?4 L
  22. //  {8 j( ?" Y+ H. ]( {& f
  23. //    Error_Handler();7 z, J3 B* a0 b3 J* C6 t! U
  24. //  }
    ! q2 Q' J. X0 c& k, S
  25. //  if (USBD_MSC_RegisterStorage(&hUsbDeviceFS, &USBD_Storage_Interface_fops_FS) != USBD_OK)
    ! k* q3 W' D5 O  j7 J
  26. //  {# d- ]. _2 Q( x+ g& b
  27. //    Error_Handler();
    0 T/ o9 Z; n1 I2 h# T, M
  28. //  }0 b2 ?% D$ r- B2 U, |2 M) K. Q- S
  29.   if (USBD_Start(&hUsbDeviceFS) != USBD_OK)' L' O1 ^2 R$ ?' l2 s2 |$ w
  30.   {
    / @. o; A2 B7 t9 V4 f2 d, T  Z
  31.     Error_Handler();1 O2 E. v$ r: R) S; [8 M6 ]! o6 c
  32.   }; T) l, l" z+ B' l
  33. 2 R* x4 U1 O' Q1 R
  34.   /* USER CODE BEGIN USB_DEVICE_Init_PostTreatment */3 X' x0 l  \8 h" S4 _1 Y. B) S
  35. //  if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_COMPOSITE) != USBD_OK)  //新增
    # u/ s3 |1 ]+ s
  36. //  {2 ?1 H- J/ j; G% m. d8 o
  37. //  Error_Handler();
    - n* s) F+ M. L+ ^6 Q/ [
  38. //  }4 s0 V' I* n$ E' J
  39.   /* USER CODE END USB_DEVICE_Init_PostTreatment */
    4 K& H% G. v6 p6 i
  40. }
复制代码

9 S7 H9 T2 [% T( E$ _

2 q% z4 J& z! u) n  y* m! L% m& R9 ]11.在usbd_composite.h中新增代码
1 U2 E) z- I$ ?' Y5 ]' D

  1. " Z0 N, D4 e5 {9 [6 G9 A( e2 @# B% v
  2. #ifndef __USBD_COMPOSITE_H
    ) S- q# y4 `0 N
  3. #define __USBD_COMPOSITE_H
    9 _& k' H' d7 j* l4 b5 Z
  4. ) p; v; X1 A" {5 T6 u; Y3 k
  5. #include  "usbd_ioreq.h". ~4 G3 W) P+ E  u0 j+ g/ r
  6. #include "usbd_cdc.h"
    - \9 D( \- y4 [1 g, P
  7. #include "usbd_msc.h"
      Y! e. y* M- c% p' w

  8. 0 k5 v* a- T; C( _; J" T0 I6 k0 u
  9. #define MC_MAX_FS_PACKET            0x40
    - D' U/ D# n, X3 \2 t' ?0 j/ e
  10. - W5 ]: c" D! k. M! o
  11. #define USB_MC_CONFIG_DESC_SIZ      106 6 k* y' a: L: P; w/ v0 a
  12. & d2 K% S/ l3 Z/ T3 L- I
  13. #define MC_MSC_EPIN_ADDR                MSC_EPIN_ADDR
    2 m# Z# l- H) A3 j( v
  14. #define MC_MSC_EPOUT_ADDR               MSC_EPOUT_ADDR
    0 g1 A" B! ^1 q6 W6 ?& |

  15. ! F2 M/ J+ i& z  s& _: D
  16. #define MC_CDC_IN_EP                   CDC_IN_EP
    ) X/ T- l( f8 F$ _# g! R4 Z! D8 {
  17. #define MC_CDC_OUT_EP                  CDC_OUT_EP    R7 Y* [# z0 a3 }6 j. \
  18. #define MC_CDC_CMD_EP                  CDC_CMD_EP
    ) @" e! |+ ~% L1 b
  19. 7 d- |; c! E# F, O" B9 t
  20. extern USBD_ClassTypeDef  USBD_COMPOSITE;
    5 P& z% S& L3 ^6 F; r. g! u0 ~
  21. 4 y" i% g# P2 j: K6 |; N
  22. #endif  /* __USBD_MC_H */
    , e: h/ F* y. j# o9 u
  23. : ?# U# l; v# @( p* `% r* g- I
复制代码

$ L, H* x- w7 _$ M+ A+ c5 G2 G; J
12.在usbd_composite.c中新增代码
3 Y% @4 u; b. @  \  R0 Q: A) W+ F4 y" a: k& q( E5 @
  1. 5 _0 c( {9 D9 [- ?1 f, \+ L
  2. #include "usbd_composite.h"
    4 h8 [' y: S/ y2 o5 h% k! D0 ?
  3. #include "usbd_def.h"
    ' B/ u# j  Z, v
  4. #include "usbd_msc.h"
    - t6 g+ E$ i! @1 X
  5. #include "usbd_cdc.h"# d& ?5 z. F, F) R4 B
  6. #include "usbd_storage_if.h"& B0 K8 L9 d  z  Z3 f# G/ M
  7. #include "usbd_cdc_if.h"0 K- r, z5 ~- V2 d: j7 z# b) g
  8. : M5 R* [, k) U. f* |
  9. /** @defgroup MC_CORE_Private_FunctionPrototypes( n- A/ E; o+ c% Q/ g/ U
  10.   * @{  f5 ~2 ]  ?( U
  11.   *// z9 E6 B. _( C# e- t7 V
  12.   
    " S& R. r8 Y: o0 Q6 |
  13. USBD_CDC_HandleTypeDef     *pCDCData;
    3 K, s7 H5 X" U0 N* f) ]3 f7 G
  14. USBD_MSC_BOT_HandleTypeDef *pMSCData;% y! B7 B9 t/ P; X* S
  15.   2 |3 V; Y" L( E( B7 E6 X# P5 {
  16. uint8_t  USBD_MC_Init (USBD_HandleTypeDef *pdev, * Y4 |: K7 }( I1 |- K  E: n
  17.                             uint8_t cfgidx);
    * P- @/ G+ }3 @
  18. - e% X* I& F, c. T0 W! V' u3 U
  19. uint8_t  USBD_MC_DeInit (USBD_HandleTypeDef *pdev, . M# e! L! W, `+ f+ G/ I
  20.                               uint8_t cfgidx);  z( y' a, w+ |
  21. + W/ D; S( j% ?
  22. uint8_t  USBD_MC_Setup (USBD_HandleTypeDef *pdev,
    / ^. T7 e8 T/ I! b0 M
  23.                              USBD_SetupReqTypedef *req);
    ) M# C3 @4 A2 k( ~+ A
  24. & h. B0 }: C4 A8 P
  25. uint8_t  USBD_MC_DataIn (USBD_HandleTypeDef *pdev, 0 y$ L+ R7 Y! ]3 B
  26.                               uint8_t epnum);
    . V( d& z* i, q' T
  27. / Y% Q0 T5 p6 e* l; |

  28. ) W1 Z, P% r* K, Q8 M* a
  29. uint8_t  USBD_MC_DataOut (USBD_HandleTypeDef *pdev, . C* U' t0 k4 Q5 l: x7 e& {: w. n. A
  30.                                uint8_t epnum);
    ' I" J  _0 q4 {1 B) [  S& s4 ~
  31. : y  G( L- ^. O' N) G! d8 v2 h
  32. uint8_t  *USBD_MC_GetHSCfgDesc (uint16_t *length);7 L* p8 H2 Q  g7 O6 s/ }

  33. : z, c3 Y' z( H) `3 F9 K8 g, w
  34. uint8_t  *USBD_MC_GetFSCfgDesc (uint16_t *length);* U! v3 ]6 d' [
  35. , `5 ^. Q/ J4 J( ~& S
  36. uint8_t  *USBD_MC_GetOtherSpeedCfgDesc (uint16_t *length);
    5 f" U& W. ~$ j9 L8 N
  37. & |* d! t9 z8 X2 S8 \. u
  38. uint8_t  *USBD_MC_GetDeviceQualifierDescriptor (uint16_t *length);  K& |; I0 f) n* ^4 @

  39. ; u2 t& F% ?( s. o( U  a
  40. static uint8_t  USBD_MC_RxReady (USBD_HandleTypeDef *pdev);  s& d) v  [' y$ k- A2 P
  41. static void MC_Switch_MSC(USBD_HandleTypeDef *pdev);
    ; Y; M' g% U1 G( g0 d1 W4 |1 w) ?
  42. static void MC_Switch_CDC(USBD_HandleTypeDef *pdev);$ p8 a$ C: ~( Z" J9 M; C) \
  43. - n0 z2 W3 `8 j# A" W- ~3 `0 s" t
  44. /**
    8 O/ j! l" L3 t1 C, @
  45.   * @}
    0 }) ^7 f6 a) i8 \1 c
  46.   */
    9 H5 z8 m/ |2 Y4 d) h; ]
  47. extern USBD_HandleTypeDef hUsbDeviceFS;
    4 a+ W  G, J" W
  48. 6 F6 j9 r7 o& z8 j

  49. , X4 c+ P! Z/ D! z
  50. /** @defgroup MC_CORE_Private_Variables9 p1 f/ m0 h, ^+ x7 V) M( C: n
  51.   * @{
    : K3 r3 X2 Y; [/ B! h
  52.   */
    2 `; B0 b0 d( i2 c6 d. K( s
  53. USBD_ClassTypeDef  USBD_COMPOSITE =
    0 K0 }% k2 F1 v! j
  54. {" F' n# \+ t8 `7 ^! U: X8 h
  55.   USBD_MC_Init,
    5 m) h, s0 H/ m6 M: i
  56.   USBD_MC_DeInit,% r! U) x4 a* |) @
  57.   USBD_MC_Setup,4 C: B- B/ L/ g. }5 ]. E, B
  58.   NULL, /*EP0_TxSent*/  # k) y7 D8 g/ {) o# D
  59.   USBD_MC_RxReady, /*EP0_RxReady*/8 |: ~  b* G2 K7 R) {5 H$ |
  60.   USBD_MC_DataIn,! A. c2 b+ F/ C
  61.   USBD_MC_DataOut,
    5 ~2 P' h; Z- a9 C  Z+ l% g1 W
  62.   NULL, /*SOF */ : |3 n0 \- |+ k8 ]2 _* ~9 z
  63.   NULL,  
    5 |9 Q3 C( i  g4 i1 t2 g7 S- o
  64.   NULL,     
    2 j) x+ F& l" y- a* _- U1 ^
  65.   USBD_MC_GetHSCfgDesc,$ K( V; |4 m- F) ]$ ^
  66.   USBD_MC_GetFSCfgDesc,  + N4 w  j! D& i/ O
  67.   USBD_MC_GetOtherSpeedCfgDesc,
    * j3 a" m5 b, K& b3 N; p
  68.   USBD_MC_GetDeviceQualifierDescriptor,
    ! Q3 w. p/ Z8 C7 i. u
  69. };4 r# L/ O& }0 b8 I7 z6 x+ \  Q& q8 ~

  70. ) S0 q' _; Z8 D7 J, W! G) O" |6 Y
  71. /* USB Mass storage device Configuration Descriptor */% k$ }  S" f+ a, B# |
  72. /*   All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */: k# z( b0 B- A+ N1 V
  73. uint8_t USBD_MC_CfgDesc[USB_MC_CONFIG_DESC_SIZ] =
    * W- L( _2 r; v) C# n5 L
  74. {; x9 C$ z& q+ W7 D, x: f1 F8 r: q' Y
  75.   /*Configuration Descriptor*/- }' ~- D0 x+ L& S! f3 A1 U
  76.   0x09,   /* bLength: Configuration Descriptor size */3 X" e* U6 F7 I1 g! o
  77.   USB_DESC_TYPE_CONFIGURATION,      /* bDescriptorType: Configuration */
    % \' U, w! t! j3 P/ |7 u) t
  78.   USB_MC_CONFIG_DESC_SIZ,                /* wTotalLength:no of returned bytes */* P! G" O7 u$ B7 h/ T6 l% {/ c
  79.   0x00,) y0 X- F2 S4 G6 \; v, Q: P
  80.   0x03,   /* bNumInterfaces: 3 interface */
    & d; m/ O! x. F4 [% G; r
  81.   0x01,   /* bConfigurationValue: Configuration value */
    9 u2 c! ^6 _  w, y+ ~7 }
  82.   0x00,   /* iConfiguration: Index of string descriptor describing the configuration */
    # _# S3 N8 N7 w) L7 y; d
  83.   0xC0,   /* bmAttributes: self powered */4 `5 ]- p5 d# L* G
  84.   0x32,   /* MaxPower 0 mA */
    ( y1 a1 W/ \1 h
  85.   2 n( E" V1 `. j* `$ }
  86.   /*---------------------------------------------------------------------------*/
      J$ c* ]% d" H' ]4 U
  87.   // IAD
    0 O. ?+ e2 j3 l
  88.   0x08,        //描述符大小) `8 ^# u9 S& I, \
  89.   0x0B,        //IAD描述符类型: m* ]6 ?% C' V6 Z7 Q
  90.   0x00,        // bFirstInterface
    & f  o6 v; Q" b6 P
  91.   0x02,        // bInterfaceCount
    & y; H- E. ^) e
  92.   0x02,        // bFunctionClass: CDC Class
    / W$ l: x6 m- P2 e
  93.   0x02,        // bFunctionSubClass
    - `! Q" W) s2 Q% }: [
  94.   0x01,        // bFunctionProtocol. L4 ^& Z4 t! s2 x
  95.   0x00,        // iFunction       ( u# `" Z' d- t) K1 }6 b
  96.   
      I5 S' s4 n* ^
  97.   /*---------------------------------------------------------------------------*/
    ( q; |& A& o! Q* ^4 G) D# O
  98.   /*Interface Descriptor *// w8 N, f0 C9 c* X9 q  L- M! ?
  99.   0x09,   /* bLength: Interface Descriptor size */+ e1 ~2 p4 b: t) j8 t
  100.   USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: Interface */5 a; t, \1 f* I9 a& c+ x
  101.   /* Interface descriptor type */
    3 i6 _+ E- A4 ~; ^7 j5 l2 f) B2 v
  102.   0x00,   /* bInterfaceNumber: Number of Interface */
    7 u" d  O) y$ w# p6 l( M6 i- n
  103.   0x00,   /* bAlternateSetting: Alternate setting */$ e$ @2 h$ O9 Z) r' j4 V
  104.   0x01,   /* bNumEndpoints: One endpoints used *// \7 X" x! J2 V6 W5 k  F8 o) R. p% {
  105.   0x02,   /* bInterfaceClass: Communication Interface Class */& o) N0 S6 N" K/ ~% X
  106.   0x02,   /* bInterfaceSubClass: Abstract Control Model */' q& \: S) ?8 K
  107.   0x01,   /* bInterfaceProtocol: Common AT commands */0 k" ~# h# j" q- _& c
  108.   0x00,   /* iInterface: */* r: v' E# R8 J7 Z' J
  109.   
    0 Q% u3 x( h( a. t8 L/ a) I
  110.   /*Header Functional Descriptor*/2 |- h( |- r; Y1 F" I" \  G
  111.   0x05,   /* bLength: Endpoint Descriptor size */
    0 t/ K8 F% r: I, @$ U
  112.   0x24,   /* bDescriptorType: CS_INTERFACE */5 v( J' w1 J  k" i
  113.   0x00,   /* bDescriptorSubtype: Header Func Desc */
    / L, [4 i- W, D+ F" M
  114.   0x10,   /* bcdCDC: spec release number */
    1 _2 y6 a& S- @
  115.   0x01,
    2 y0 t( a: a. R4 R9 ^& ?
  116.   ! q. ~0 ~8 |! D
  117.   /*Call Management Functional Descriptor*/
    8 C& K6 |: U' H2 ^8 E9 v2 @
  118.   0x05,   /* bFunctionLength */8 z4 P% E5 Y& V3 r5 P0 I
  119.   0x24,   /* bDescriptorType: CS_INTERFACE */
    4 I' j( J' ?! h$ v& Z/ y
  120.   0x01,   /* bDescriptorSubtype: Call Management Func Desc */0 w' A) @6 p2 k& B4 Q
  121.   0x00,   /* bmCapabilities: D0+D1 */. E  X0 D" n9 M9 [  Y
  122.   0x01,   /* bDataInterface: 1 */
    - o) I1 [5 x* u6 h2 T& U% C
  123.   
    ) P$ b9 z' P3 M8 ~5 h
  124.   /*ACM Functional Descriptor*/6 F6 n% L% c) R
  125.   0x04,   /* bFunctionLength */
    6 \% k! ?% b, N" ~2 F8 T
  126.   0x24,   /* bDescriptorType: CS_INTERFACE */: \1 W8 g% A1 D# S& m
  127.   0x02,   /* bDescriptorSubtype: Abstract Control Management desc */
    ) Z# M0 |  Y% y4 ^" u# p
  128.   0x02,   /* bmCapabilities */4 @0 m; R" K0 I: x2 h4 L9 P
  129.   
    5 `3 B- M$ x3 P" }+ \
  130.   /*Union Functional Descriptor*/+ k7 }2 k  j+ \2 ^4 `: j
  131.   0x05,   /* bFunctionLength */
    ) K9 I% i" J( T1 v/ n. {. }( H
  132.   0x24,   /* bDescriptorType: CS_INTERFACE */0 [% g  ]1 i4 h; H% j4 z0 x' c
  133.   0x06,   /* bDescriptorSubtype: Union func desc */4 k( {$ h" ~* _* |7 d2 w0 @
  134.   0x00,   /* bMasterInterface: Communication class interface */
    * v  v& Y- b: }5 Y9 e9 k
  135.   0x01,   /* bSlaveInterface0: Data Class Interface */+ D$ V# Z1 T' O' x" u7 D
  136.   
    5 ]" \8 f; u7 q, Y3 N
  137.   /*Endpoint 2 Descriptor*/
    " ?. y& F& e  o6 Q! [4 p/ F
  138.   0x07,                           /* bLength: Endpoint Descriptor size */+ A' \& U( E7 R. M* e! h
  139.   USB_DESC_TYPE_ENDPOINT,   /* bDescriptorType: Endpoint */7 O6 Q; o9 p4 _" \4 r$ G( V
  140.   MC_CDC_CMD_EP,                     /* bEndpointAddress */
    . x1 G1 I1 b4 @* W" y/ [
  141.   0x03,                           /* bmAttributes: Interrupt */2 {, V, j1 f- ]: k) d* t* Z! t% c& [
  142.   LOBYTE(CDC_CMD_PACKET_SIZE),     /* wMaxPacketSize: */' y* A% ~# K- I. w' q5 U! T: {
  143.   HIBYTE(CDC_CMD_PACKET_SIZE),8 N1 z  J# i9 @* e$ g# f
  144.   0x10,                           /* bInterval: */
    ( A8 c# }1 y* r3 f9 x. A
  145.   
    3 f) E9 u# f5 K. D# ?
  146.   /*Data class interface descriptor*/: ]6 K" q+ F3 g: z1 \, D. ?
  147.   0x09,   /* bLength: Endpoint Descriptor size */
    9 j1 A/ w" ^8 ^1 o) a
  148.   USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: */+ H, {# u$ Z$ y+ w) h! p; k
  149.   0x01,   /* bInterfaceNumber: Number of Interface */. V. U1 l; m! S! C% I; v
  150.   0x00,   /* bAlternateSetting: Alternate setting */5 B/ h: f" @  s: G1 {2 [8 s4 o6 d
  151.   0x02,   /* bNumEndpoints: Two endpoints used */' m, Q1 S8 |. t5 Y( P. d  f5 }
  152.   0x0A,   /* bInterfaceClass: CDC */
    % T* S) T6 z7 r% F# O' K& _; _. O
  153.   0x00,   /* bInterfaceSubClass: */
    $ @# H2 |- j: z# D9 ^7 v% T- z
  154.   0x00,   /* bInterfaceProtocol: */- X* n2 Z+ J, \9 H. O! y# ^/ k
  155.   0x00,   /* iInterface: */- ~5 k) E5 `! }" r9 G  Y$ [* [% p
  156.   ! R) o! W. c) y( r) G) R
  157.   /*Endpoint OUT Descriptor*// \8 \/ E9 e% M  i, u
  158.   0x07,   /* bLength: Endpoint Descriptor size */
    9 \. D5 \# q! X' {
  159.   USB_DESC_TYPE_ENDPOINT,      /* bDescriptorType: Endpoint */+ z! H; X7 d6 I4 B2 Z3 J* ^; ?
  160.   MC_CDC_OUT_EP,                        /* bEndpointAddress */# T: j( \" C; F. [, W
  161.   0x02,                              /* bmAttributes: Bulk */
    # z) l; k- ]' c6 @8 R6 J! J. x: f( Z
  162.   LOBYTE(MC_MAX_FS_PACKET),  /* wMaxPacketSize: */, A. Y: p, g* y) V; @, w4 l
  163.   HIBYTE(MC_MAX_FS_PACKET),
    $ u9 g' X, y5 B4 M2 Z: k
  164.   0x00,                              /* bInterval: ignore for Bulk transfer */
    " m+ F/ o' O! A& s" ?* T
  165.   
    . U+ W4 @# @* U6 C! }- p
  166.   /*Endpoint IN Descriptor*/% Y7 P* B1 J5 d; O) |& O' x
  167.   0x07,   /* bLength: Endpoint Descriptor size */
    & S: d, M$ D- V* w2 X$ t
  168.   USB_DESC_TYPE_ENDPOINT,      /* bDescriptorType: Endpoint */" t/ U" ?! P) P6 m
  169.   MC_CDC_IN_EP,                         /* bEndpointAddress */1 X, B4 u" E3 n! B+ l% e: e
  170.   0x02,                              /* bmAttributes: Bulk */" Y  c" B+ g! `  h
  171.   LOBYTE(MC_MAX_FS_PACKET),  /* wMaxPacketSize: */
    2 m. O9 F% }/ L2 w% _
  172.   HIBYTE(MC_MAX_FS_PACKET)," \4 }9 j# [; b) g! c+ d+ P! e, R
  173.   0x00,                               /* bInterval: ignore for Bulk transfer */
    - ^4 ^' r$ [. s0 j' Z( X

  174. ( \4 L1 B3 u  ?$ g  k9 P5 a
  175.   /*---------------------------------------------------------------------------*/
    , C. s4 p8 ]7 C/ }
  176.   // IAD
    " e( |) D  D: B' e5 q. A$ l
  177.   0x08,        //描述符大小1 E, X8 N! `- A/ w# ~' z* O
  178.   0x0B,        //IAD描述符类型
    ; s, S" e. ~) O, v- e6 C
  179.   0x02,        // bFirstInterface9 B9 J9 D& d: N, b
  180.   0x01,        // bInterfaceCount* n0 m* F+ S% \- A
  181.   0x08,        // bFunctionClass: MASS STORAGE Class$ [  N+ e( ]+ F$ f
  182.   0x06,        // bFunctionSubClass7 c) a$ E9 K% D9 [7 O2 ]$ ?9 B
  183.   0x50,        // bFunctionProtocol
    % ?2 d/ s) l- a& ^( W6 W
  184.   0x01,        // iFunction   
    % E4 r8 ~$ K0 C& w* Z. M* V; N

  185. . [* _9 d; @1 [# p4 ?
  186.   /********************  Mass Storage interface ********************/
    / Z+ D4 A3 I6 Y9 R
  187.   0x09,   /* bLength: Interface Descriptor size */& u4 f. c" D' y9 A4 V" C
  188.   0x04,   /* bDescriptorType: */
    * m+ |& J2 f3 m2 g& A
  189.   0x02,   /* bInterfaceNumber: Number of Interface */# p4 e% l6 f9 R" U
  190.   0x00,   /* bAlternateSetting: Alternate setting */7 i  a6 T6 ~3 H/ l( Y" V2 P' E
  191.   0x02,   /* bNumEndpoints*/
    & [2 Q) r/ h6 z7 B' x: D' a
  192.   0x08,   /* bInterfaceClass: MSC Class */6 E( J0 ?" w( G/ ~" Z$ ~6 p  w
  193.   0x06,   /* bInterfaceSubClass : SCSI transparent*/7 r. }$ J( N+ o1 T! c' F
  194.   0x50,   /* nInterfaceProtocol */, x: F6 L4 C" r2 V% P
  195.   0x05,          /* iInterface: */
    . C0 r5 B' B6 N" B2 \/ t# V/ e8 K
  196.   /********************  Mass Storage Endpoints ********************// u) ~$ a; L# p2 V8 R, Z
  197.   0x07,   /*Endpoint descriptor length = 7*/& i) [; Z0 g$ r+ X4 N
  198.   0x05,   /*Endpoint descriptor type */
    3 M5 V7 f6 _4 B0 ~; _+ l$ T
  199.   MC_MSC_EPIN_ADDR,   /*Endpoint address (IN, address 1) */
    ! c( U9 d. e0 N8 ]5 C7 G
  200.   0x02,   /*Bulk endpoint type */. s3 D, b0 X# @( O! m9 C; k
  201.   LOBYTE(MC_MAX_FS_PACKET),
    6 j; q+ V" P& d& {6 k) ]# u
  202.   HIBYTE(MC_MAX_FS_PACKET),: C5 O0 ?, j! `+ G, W# f
  203.   0x00,   /*Polling interval in milliseconds */
    0 E3 V; C2 ~- l: x
  204.   
    2 |8 Q3 d! S: y5 w) ~
  205.   0x07,   /*Endpoint descriptor length = 7 */
      }$ |1 _2 @! s" I
  206.   0x05,   /*Endpoint descriptor type */
    2 u( a% U% X) U
  207.   MC_MSC_EPOUT_ADDR,   /*Endpoint address (OUT, address 1) *// z# r  _$ q3 I5 m; b. A9 _) D3 g
  208.   0x02,   /*Bulk endpoint type */" ~8 [) D$ b1 I, w- K& w$ C$ a4 x
  209.   LOBYTE(MC_MAX_FS_PACKET),
    $ `+ W3 p0 M: F
  210.   HIBYTE(MC_MAX_FS_PACKET),$ N8 r  I; w5 a- P% `% e
  211.   0x00     /*Polling interval in milliseconds*/  {6 Z2 L3 E$ q$ x2 K/ j4 A7 d0 `
  212. };/ n$ k9 V8 e/ F8 }7 o
  213.   9 M: ~, @; t3 p
  214. uint8_t USBD_MC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] =
    1 b8 ?$ P, h" G* i! ]+ Y/ y
  215. {
    $ P" d0 d5 |5 P1 s
  216.   USB_LEN_DEV_QUALIFIER_DESC,& i8 d; a% X: E* ^
  217.   USB_DESC_TYPE_DEVICE_QUALIFIER,6 f) a: u$ U) F1 ?
  218.   0x00,6 A) f8 j( _( d* w" X4 Y2 E6 a
  219.   0x02,
    % n/ j" C/ q8 \! C6 b9 I: {) `' g
  220.   0x00,3 T/ g4 Q9 D2 i, V$ g: U1 u
  221.   0x00,
    4 R0 j; T7 v  \" C5 i0 q2 ~
  222.   0x00,
    $ }* s" @. |0 n. z' v8 |
  223.   MC_MAX_FS_PACKET,
    ) c, b* [4 Q0 q) r
  224.   0x01,
    & r0 m  _+ j. J' \! k
  225.   0x00,
    ; F- Q6 b; X4 `* q
  226. };
    3 s4 b1 F$ U% F. a& O* V
  227. + s; z; B% w$ a5 t. \* A5 I/ J
  228. /**
      B2 C9 y& o, m- p" ~. [% s
  229.   * @brief  USBD_MC_Init$ I. Q( O- q1 s( Y
  230.   *         Initialize  the mass storage configuration
    1 a! X* p/ T: W8 B$ S, S
  231.   * @param  pdev: device instance  G: o" b! A' B7 A# M# |
  232.   * @param  cfgidx: configuration index( A$ t% e. |+ i6 ~$ h
  233.   * @retval status7 ]% }" J. R; H  [( Y
  234.   */$ x8 Z  G. w/ q6 U$ N
  235. uint8_t  USBD_MC_Init (USBD_HandleTypeDef *pdev, uint8_t cfgidx)9 m% @$ z  u; \" L6 U' P
  236. {$ ^2 ~  b$ Y2 s. i5 M3 U
  237.   uint8_t ret = 0U;
    ( c( D' T- c3 D: U8 F1 n
  238.   D: Z% N$ ~# K+ x* k
  239.   
    , N' G0 L0 ?' s6 W# |# c1 i
  240.   USBD_CDC_HandleTypeDef      * hcdc;( V9 W7 T  N/ c& S4 D- Z$ G
  241.    
    $ P3 m8 R7 ?0 {2 M& K  I6 u. D5 C. E
  242.   MC_Switch_CDC(pdev);
    # a, ^  I  \8 w) b( v8 Q
  243.   
    1 `# `+ \6 _2 N, y2 N: g
  244.   USBD_LL_OpenEP(pdev,6 A! W* v' {/ w
  245.                  MC_CDC_IN_EP,7 h  W# l" p/ ?% s* N
  246.                  USBD_EP_TYPE_BULK,3 ~, ]/ r* D$ J  `2 K( [
  247.                  MC_MAX_FS_PACKET);' N( t7 k1 K- x. Z+ c
  248.   " n' e" h* e% M3 u& F7 K7 i
  249.   USBD_LL_OpenEP(pdev," H& E" `3 P8 c$ w
  250.                  MC_CDC_OUT_EP,
    6 j$ S1 w0 b: N( N% H) L. |- Y
  251.                  USBD_EP_TYPE_BULK,* G( I2 W% X( _7 n8 W: p
  252.                  MC_MAX_FS_PACKET);: C' R" p" A6 V4 I7 ~
  253.   
    . J% Y  y2 b. P8 H% k- J. Q9 Z  p
  254.   USBD_LL_OpenEP(pdev,
    : [  c: y# O) F0 C: E: T
  255.                  MC_CDC_CMD_EP,
    ) s# X, a9 @+ u/ l7 p2 L9 o& I
  256.                  USBD_EP_TYPE_INTR,& F& p0 n. `0 s6 T# @
  257.                  CDC_CMD_PACKET_SIZE);
    0 s7 A9 L7 O: \- d

  258. 3 j) p$ {6 K4 a) L4 \' ?' y5 g- E
  259.   hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
    . G/ F& |+ w9 W' k4 H, f3 w, i

  260. 8 ?% E$ \* i; ]" a$ O- d4 V  U0 n0 o
  261.   ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Init();  I# i4 j7 c$ X- E, v
  262.   
    2 v% [, S9 r& s0 x6 {+ u' k; w2 E2 w
  263.   hcdc->TxState =0;
      Z$ @) E5 E) u( t$ f% T9 l8 x
  264.   hcdc->RxState =0;
    ' h, |1 s, ]8 j
  265.   % |, C# ]# I5 Q# O
  266.   USBD_LL_PrepareReceive(pdev,
    ; \/ W% |0 P  A. S
  267.                          MC_CDC_OUT_EP,
    2 M- m8 L- C" @
  268.                          hcdc->RxBuffer,
    4 U2 l; r/ m) F& {' E
  269.                          MC_MAX_FS_PACKET);0 \( H; f# W% B6 ]0 _
  270.   t/ b  W& |( i! S
  271.   pCDCData = pdev->pClassData;' u' A' R- q0 A

  272. 9 G. n2 N3 }' U" d
  273.   MC_Switch_MSC(pdev);
    ; H$ K7 v* N- m4 v% x
  274.   3 r* w3 o0 w" B  I( e5 k
  275.   USBD_LL_OpenEP(pdev,
    # [% z$ y$ \4 m
  276.                  MC_MSC_EPOUT_ADDR,
    % i- ?# T% \& C1 p2 A9 z
  277.                  USBD_EP_TYPE_BULK,
    4 l. ~8 [. r" J+ T9 \' w, e
  278.                  MC_MAX_FS_PACKET);
    / X! Q5 Y3 M& _6 e% l2 Z  w
  279.     e3 I! c# y4 J2 N
  280.   USBD_LL_OpenEP(pdev,3 T& `& Y7 Y; j
  281.                  MC_MSC_EPIN_ADDR,& E4 p) e. s' w5 o
  282.                  USBD_EP_TYPE_BULK,1 S/ q# g; D' ~! @
  283.                  MC_MAX_FS_PACKET);; u1 Z* A* I) }
  284.   
    . B4 r1 L. m$ K) S- l
  285.   MSC_BOT_Init(pdev);+ v+ }  y+ Z2 b$ o4 b
  286.   
    . @" b. s& d- m& Q  u% M+ x
  287.   pMSCData = pdev->pClassData;: ^9 d6 z# m4 v* v# I; D
  288.   ( J$ h8 O4 i4 i- i. K
  289.   if(pdev->pClassData == NULL)& j6 J% @+ o4 t& G/ v+ l
  290.   {7 p+ e' ?$ a$ t/ \9 j( t7 U
  291.     ret = USBD_FAIL;* a* ~) @; N& k8 |1 i. K
  292.   }0 ?; s% v6 Q; ~$ v! y
  293. ( d) U1 Q! D2 k) L
  294.   return ret;
    1 p+ d* {# H, A$ N6 v* [) o2 T9 F2 ?
  295. }0 o+ D, a4 k2 N# g( M1 X+ z& a1 ?
  296. ) @# }9 V! K+ N4 a) P
  297. /**
    , b( u8 n: W2 s$ n" C5 a
  298.   * @brief  USBD_MC_DeInit
    $ [' \% G" [  w4 `' Y# U
  299.   *         DeInitilaize  the mass storage configuration
    ( L3 u3 ~+ h  R& e
  300.   * @param  pdev: device instance
    - _2 g# @, z. K$ b3 X
  301.   * @param  cfgidx: configuration index
    + Y  X/ e3 L7 [! K, _7 [/ [0 w
  302.   * @retval status! `1 T$ S; |% P9 S
  303.   */
    9 k1 ?2 U& R: }2 C  @4 y
  304. uint8_t  USBD_MC_DeInit (USBD_HandleTypeDef *pdev,
    $ |5 h% q) S  [: ?, L6 G' k0 d
  305.                               uint8_t cfgidx)
    2 D1 Q9 v9 S, M$ a, }
  306. {
    9 c( E, X- @& q
  307.   return USBD_OK;1 f  B  }- j$ _( D% i
  308. }
    9 W( D' `4 B! @! a
  309. /**
    % H! M6 N9 M5 \1 E  M
  310. * @brief  USBD_MC_Setup
    9 I- E0 m2 ^0 D" A
  311. *         Handle the MC specific requests
    + K4 Y; [0 B0 z" m; a
  312. * @param  pdev: device instance. F- O1 x: f6 K; L7 s' i% t# V
  313. * @param  req: USB request
    # D$ ]+ g1 V0 h9 [  U. O
  314. * @retval status
      D0 K8 b0 X$ R; W' k
  315. */# r% q- n( w' V' u  f( w, o" m9 }
  316. uint8_t  USBD_MC_Setup (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
    % w; A4 a8 |# X5 ?$ q+ d
  317. {
    . W, X3 g& S' F. q
  318.   if(req->wIndex == 0x0002)0 G! j+ y: Z5 B) t, q! i# M
  319.   {! ~+ d& O6 I" k! j3 Q* f4 s
  320.     MC_Switch_MSC(pdev);
    , E8 @& l4 [2 L1 I4 k+ i- |0 W. l
  321.     USBD_MSC_BOT_HandleTypeDef     *hmsc = (USBD_MSC_BOT_HandleTypeDef*) pdev->pClassData;   
    # J+ a+ A, h4 D+ Q. F: V
  322.     ( q8 n! Y8 J; j* U- i8 y5 u0 J$ N
  323.     switch (req->bmRequest & USB_REQ_TYPE_MASK)
    ; f# W! O4 W5 B) R0 |
  324.     {7 E: C* A: |8 S
  325. % }* ~7 l: w+ x0 [8 c- a
  326.     /* Class request */! ?2 t* n+ M! N# E
  327.     case USB_REQ_TYPE_CLASS :
    ; R4 N: O1 x# m* y
  328.       switch (req->bRequest)5 z* Y) T  Y4 P- l
  329.       {1 }1 j& {; D) u2 x2 n# K9 c( q
  330.       case BOT_GET_MAX_LUN :
    ' ]: \7 E: W9 |5 c5 ?  c/ \/ s

  331. 3 V- c3 C, B' ?$ }/ e
  332.         if((req->wValue  == 0) &&
    2 M' [; U7 ~+ c! X
  333.            (req->wLength == 1) &&& X0 _0 ^4 {6 c1 ]% J$ ]7 d+ m
  334.            ((req->bmRequest & 0x80) == 0x80))+ M0 w% U, H' Y8 }5 Z" \5 ?, Q
  335.         {
    ( _' p+ L& }* Y: s8 I
  336.           hmsc->max_lun = ((USBD_StorageTypeDef *)pdev->pUserData)->GetMaxLun();
    . c8 k1 R- @& I
  337.           USBD_CtlSendData (pdev,
    ) B) X# k& v1 Y1 y, }
  338.                             (uint8_t *)&hmsc->max_lun,
    2 \6 B! X' |/ o) t$ l
  339.                             1);' V# ~5 M/ Q: o
  340.         }
    ) P4 y$ [% B1 o! @# c
  341.         else
    & a7 ~( ?$ g( z+ Z! J2 I- j8 H
  342.         {! f# d/ ]4 D/ a  v8 ]; l# }
  343.            USBD_CtlError(pdev , req);
    / O9 v, _3 [" _9 g6 ~" L* d
  344.            return USBD_FAIL;
    - m" D8 P. ~( M( d. q# L( R
  345.         }
    : _1 m0 _) w6 @3 K0 b  Z
  346.         break;
    : O. J% [* c$ R* o4 m+ u- `
  347.         ) `4 E* r2 x! p$ N9 g% W
  348.       case BOT_RESET :
    & b7 A9 N$ m3 K* [2 `9 O/ ~3 D
  349.         if((req->wValue  == 0) && 4 h5 e$ `4 A& B
  350.            (req->wLength == 0) &&
    1 m- @! }, V' C4 x; T2 Q! S
  351.           ((req->bmRequest & 0x80) != 0x80))
    ; n. x9 H) Y& g7 I/ W- c
  352.         {      1 E! ?( l9 j& K& M8 ]. E  I
  353.            MSC_BOT_Reset(pdev);
    * V6 }0 f  J8 L& U. b
  354.         }& F7 ?6 h- u. c: n) P
  355.         else( X1 D0 ~+ X& h0 m+ L: v
  356.         {& @* r$ i$ g& N0 |/ ?6 B9 w
  357.            USBD_CtlError(pdev , req);
    3 i% k: X6 H- e( G. H6 B" h5 Q8 S
  358.            return USBD_FAIL; 9 l; L; C2 a6 G: u7 x2 H0 {( r! t
  359.         }
    2 s0 ]8 A) f% _# @
  360.         break;
    % A  M* Q; q* o4 M% W
  361. 8 D, W. \/ h; d4 V  i" i
  362.       default:- d1 f2 L. K: w+ H
  363.          USBD_CtlError(pdev , req);
    4 f5 Y3 `; Q( J; D7 a4 ~: Z
  364.          return USBD_FAIL; 3 p% H) G$ m' J* s. `
  365.       }
    # J% `$ H* \& D* O* |3 A
  366.       break;- t7 L5 M  |# q) Z- o
  367.     /* Interface & Endpoint request */% N& o; S& R7 T' O
  368.     case USB_REQ_TYPE_STANDARD:
    3 v/ G# p  t2 R/ `. k5 y4 ^& \
  369.       switch (req->bRequest)- g" j& W/ G* t" f6 \- q
  370.       {
    ( a* C& b( C. B# p
  371.       case USB_REQ_GET_INTERFACE :
    2 D# J% @: x* y  R" r# u
  372.         USBD_CtlSendData (pdev,7 h. ^" K* T4 a+ K6 M: b
  373.                           (uint8_t *)&hmsc->interface,3 w( Z5 l9 T& Z0 l8 i8 n
  374.                           1);( i9 L& c/ M" |, K5 O* E
  375.         break;, i, o5 K. l$ t6 n
  376.         
    0 X* K, q8 ^. k- c! `, t" `0 R
  377.       case USB_REQ_SET_INTERFACE :- |, E4 V+ k1 I4 w) c( ^  i
  378.         hmsc->interface = (uint8_t)(req->wValue);
    % Z4 ]8 l' d7 g! z9 i2 U' s
  379.         break;
    ; j" _+ c  j9 o! A' i
  380.       
    ' v9 i8 U% i2 O  H+ B3 N' S
  381.       case USB_REQ_CLEAR_FEATURE:    a- ~. J$ P  {$ u7 {
  382.         4 R7 H& j# E( X8 J# @* L
  383.         /* Flush the FIFO and Clear the stall status */    * L2 }% ~! ~3 ?' R% G& r
  384.         USBD_LL_FlushEP(pdev, (uint8_t)req->wIndex);* l$ a! i6 m0 \  L: O
  385.         
    7 h" k6 n- k/ F+ F  c2 b$ g
  386.         /* Reactivate the EP */        F; g" K3 y9 B3 c+ w# h
  387.         USBD_LL_CloseEP (pdev , (uint8_t)req->wIndex);
    9 u2 D# v1 _% G
  388.         if((((uint8_t)req->wIndex) & 0x80) == 0x80)7 [$ p, l7 d/ _$ M
  389.         {
    ( B0 k2 r' d( L# n
  390.           if(pdev->dev_speed == USBD_SPEED_HIGH  )
    . ~- v# d+ g3 [# K0 T* e$ ?+ e4 Y
  391.           {
    ( |' m/ N" \; e  {. p2 X* G+ R
  392.             /* Open EP IN */" E+ N- t5 G" e  Y0 P
  393.             USBD_LL_OpenEP(pdev,5 @' w7 J- ?! F5 k: H
  394.                            MC_MSC_EPIN_ADDR,
    6 w# C0 X4 F  o& n
  395.                            USBD_EP_TYPE_BULK,
      C% E  M& ]8 H# B; N0 I2 Y7 p
  396.                            MSC_MAX_HS_PACKET);  $ L  `* N# Q9 F. G; }# G
  397.           }
    ( h8 l1 o: W! f( C6 a3 @
  398.           else
    1 A4 C% t4 m5 j4 l* x; n7 u
  399.           {   + ?7 T, c9 n3 Q% ?- b* T) k! B& l
  400.             /* Open EP IN */
    ' C" I4 N0 {: |# ?
  401.             USBD_LL_OpenEP(pdev,, }9 z7 A7 \4 N3 L) W) l. C; S+ y; J0 }+ \
  402.                            MC_MSC_EPIN_ADDR,* g5 F+ R/ {0 E# v) w
  403.                            USBD_EP_TYPE_BULK,
    % ?$ y* G6 S4 O: X. R7 U
  404.                            MSC_MAX_FS_PACKET);  
    # N+ N, s9 C0 N3 x8 `* Q1 Q7 H( a% G
  405.           }# J' n" R! T  Q- U, h
  406.         }. j1 J3 c) Q6 I' u' k% T
  407.         else3 }' v  A1 h' L0 `* W
  408.         {
    ( q/ A4 ~6 A' k& F! k/ |
  409.           if(pdev->dev_speed == USBD_SPEED_HIGH  ) ; ~9 A5 |& L+ D0 R) ~/ [
  410.           {
    ! Y& \6 z$ H: E! u; t* U! K
  411.             /* Open EP IN */
    9 l6 v8 Q! _6 |9 Q; F
  412.             USBD_LL_OpenEP(pdev,
    2 `: n0 K: Y) u# C1 I2 D; C
  413.                            MC_MSC_EPOUT_ADDR,
    9 O, @: A- U* B1 U( ~9 @4 ?
  414.                            USBD_EP_TYPE_BULK,
    0 [' _, Y3 X, O# N  P
  415.                            MSC_MAX_HS_PACKET);    C1 E% w  M" X2 `* _( C$ Q: @
  416.           }- J1 q0 o4 y  U9 {1 \
  417.           else0 O5 i% _6 ^/ ~  u  _
  418.           {   & Y8 D# ]+ m4 c- ]& l1 J
  419.             /* Open EP IN */
    + y( U/ H( W. M+ f* |/ r; |% @
  420.             USBD_LL_OpenEP(pdev,- Z; L- f. h/ l9 b+ A
  421.                            MC_MSC_EPOUT_ADDR,. ~( @3 Q  \) r2 K2 N# a
  422.                            USBD_EP_TYPE_BULK,: K" F1 Z3 j3 o1 U5 l
  423.                            MSC_MAX_FS_PACKET);  
    4 x, J% p: }  D3 A( Q; _5 X
  424.           }
    / J& Y7 \9 N; k6 L
  425.         }0 X+ q/ t; i4 a: o
  426.         
    % @) ^" j3 T4 c4 N# i6 P" R
  427.         /* Handle BOT error */4 T( ?# U3 C1 _. H+ `6 [" \9 q
  428.         MSC_BOT_CplClrFeature(pdev, (uint8_t)req->wIndex);7 t6 E! U0 \' C$ g) W
  429.         break;6 i% ?8 p9 X% M. ?$ s, y7 E# N- e1 l
  430.         
    . g3 q) ]% m. R: X' A, X& @
  431.       }  
    , z# D% P3 G. C2 b9 O$ {1 r1 b; \' u
  432.       break;
    ' T2 `0 L; R2 G  a- P# F8 ]
  433.      
    & k, H# b! {% |) `0 o! N2 Z2 y, h
  434.     default:
    1 m+ E& d5 X! s
  435.       break;' S' y6 _! H- U/ a: n
  436.     }: w5 o/ X/ V8 R; |3 Q3 H1 x9 f$ m
  437.   }$ a  e/ O3 I" h! R, n
  438.   else# z& B, |  q) S
  439.   {
    , u, y* j$ h) \5 v2 u
  440.     MC_Switch_CDC(pdev);  B; i9 l) O- n- n: {
  441.     static uint8_t ifalt = 0;
    2 L; D6 c! Z# I) C' v3 B
  442.     USBD_CDC_HandleTypeDef * hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData;   
    # Q) ?/ Z( D1 f3 {. R  \
  443. 7 _) X3 q: v! Q$ M+ u' b
  444.     switch (req->bmRequest & USB_REQ_TYPE_MASK)
    5 ]; u$ o# w0 X" j% c( \, w5 M8 X
  445.     {) t) Q  d5 B+ e. u6 R* T) y, L: m
  446.     case USB_REQ_TYPE_CLASS :; }" G' p7 ~+ `3 X0 E7 ^4 p( P
  447.       if (req->wLength)
    % v  C+ O; j. F
  448.       {. W- i. l0 }5 c3 l. R- ~7 Y
  449.         if (req->bmRequest & 0x80); T% w# X6 E2 g/ r) w0 `6 b
  450.         {4 a+ Q9 g. t) d# ~8 z4 E
  451.           ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest,
    3 I! a$ w+ {9 I; w" q
  452.                                                             (uint8_t *)hcdc->data,# b/ j' w7 c! X& \" F3 w( {
  453.                                                             req->wLength);
    6 c9 u3 T0 _4 U/ ^2 o
  454.             USBD_CtlSendData (pdev, 9 F1 ]2 ^( M0 q2 E4 [
  455.                               (uint8_t *)hcdc->data,7 d0 s6 v  G" @. ~/ M9 c
  456.                               req->wLength);/ t! h4 `1 |" v1 ~( G
  457.         }
    $ B; c/ w! l! c- y# y
  458.         else- |8 x, W" ~* `; a- |! b' c
  459.         {
    4 C$ F9 s2 K. Y
  460.           hcdc->CmdOpCode = req->bRequest;5 S+ B: k  B( x, V1 T1 x$ i: n6 e
  461.           hcdc->CmdLength = req->wLength;5 b7 ]3 o2 a: G5 P
  462.           # B$ D  r4 e# u3 @8 K. `2 m
  463.           USBD_CtlPrepareRx (pdev,
    + \/ Y; Y+ P/ y9 M9 k& E
  464.                              (uint8_t *)hcdc->data,
    7 d2 ^3 ]5 \8 H" N& a5 o
  465.                              req->wLength);! T% I7 M7 v) q' ]# M2 v+ n3 X4 n
  466.         }6 P7 V# X$ ~; B+ g* G5 d" Y8 ~
  467.         
    3 l! I+ ~3 [% s( u+ y& L( b
  468.       }' {: k7 g' |! J# J5 y6 Z5 }$ i
  469.       else: i$ C8 F  e+ T2 Q2 \
  470.       {( t6 P1 n1 f( ]5 j2 L
  471.         ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest,
    & K+ {8 o5 ?! s% ]
  472.                                                           (uint8_t*)req,
    + W. F' _7 f2 p
  473.                                                           0);8 K  J. ?+ A- e6 y* x0 {0 t# n% M
  474.       }& J$ e& n, v2 g' S3 y
  475.       break;, N5 T/ u* W% F$ K0 K/ x9 I
  476.    
    7 P9 A1 o) u& d4 c; s4 L
  477.     case USB_REQ_TYPE_STANDARD:
    ( d6 {( B  |; y' |. Z2 C
  478.       switch (req->bRequest)
    8 k4 p7 k) e* t9 p0 e
  479.       {      ; D% s1 f0 u8 T$ e6 z) r
  480.       case USB_REQ_GET_INTERFACE :
    % m3 \  r( z& E) X4 A# g
  481.         USBD_CtlSendData (pdev,
    ) ]5 u) b" e2 N( h  l' s
  482.                           &ifalt,: Y; G' R, x% u, Z' |# x4 L' a7 A
  483.                           1);. b" t% v# M& d! k- [
  484.         break;! K! n( u8 h( |! V2 \2 i& M
  485.         
    5 z$ r8 `/ I4 B$ a0 U; y, Y, q
  486.       case USB_REQ_SET_INTERFACE :% I, _" ^" ^" m9 X0 e, L
  487.         break;
    & q6 K% S( p5 ?& u9 D
  488.       }4 ~5 Y5 j* l3 u  b
  489.    
    + f' P' L7 m) y$ w9 t) p
  490.     default:
    + u  Y1 g2 }% L' B
  491.       break;7 @' ^  s4 G  ~2 T0 U6 H+ Y9 h
  492.     }    t) ^. S4 I2 ]' i
  493.   }, \5 h8 x* w4 m9 f. {- W
  494.   
    ' ?3 j! ?& }- F& d
  495.   return USBD_OK;8 ^. q* @- Z& u
  496. }
    4 Q3 F& y  d5 f8 q" A$ M! {
  497. " t, a5 m4 l& V  w8 [0 S5 D  D
  498. /**
    ! r# I4 p( {7 H* V: |* m
  499. * @brief  USBD_MC_DataIn
    , ?: ]/ W+ \% L3 q! r' x
  500. *         handle data IN Stage
    1 Z; S/ g  a6 a+ ?; l- _
  501. * @param  pdev: device instance
    ; `9 v% _3 `, l) E0 M
  502. * @param  epnum: endpoint index  C1 h* d7 B# {. r) `) v* d- |" i
  503. * @retval status
    1 c! r/ w" s! |
  504. */
      j% r1 W. W9 N, o
  505. uint8_t  USBD_MC_DataIn (USBD_HandleTypeDef *pdev, 4 @. S/ R3 L8 D. s" K# f' E
  506.                               uint8_t epnum)
    ! j' M0 G: {0 o+ q: z
  507. {9 W0 @3 K# S' O
  508.   if(epnum == (MC_MSC_EPIN_ADDR & 0x7f))
      M/ F9 U0 M) Y5 @: X
  509.   {
    # F/ f) K7 X) ~5 R
  510.     MC_Switch_MSC(pdev);" U, N/ u5 c9 J
  511.     MSC_BOT_DataIn(pdev , epnum);
    $ `: W) }/ ]2 V- Q) P
  512.   }
    ( w! m  M8 {. i
  513.   else if(epnum == (MC_CDC_IN_EP & 0x7f))
    + [! M2 ^- u8 w. S
  514.   {
    - i" V; d& X& ^& W
  515.     USBD_CDC_HandleTypeDef   *hcdc;
    5 o/ [4 K/ S  @
  516.    
    8 z/ `& }/ i# B/ L; T* g
  517.     MC_Switch_CDC(pdev);
    9 |1 @- H7 w3 m4 F3 D. O
  518.     hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
    ; i5 o; g6 A$ W) m( P. r. n  U
  519.     hcdc->TxState = 0;    ! Z. H8 n6 F% v* j
  520.   }
    5 N8 V2 f' p: \: g2 m: }8 O
  521.   
    3 r0 w9 ^5 M! Y4 a( K# ]
  522.   return USBD_OK;* t4 J8 Q" U' G- Z
  523. }
    / E  T) x7 |  h9 T
  524. 8 `8 ]  R  @* S
  525. /**8 v7 ]1 W, @$ N" o
  526. * @brief  USBD_MC_DataOut
    9 E5 C* Z) x' C/ t2 X: [% e' }- H
  527. *         handle data OUT Stage
    1 ~5 t1 a" C* \5 K8 `# Q% I
  528. * @param  pdev: device instance
    3 Z, e5 y+ W6 i# }) w/ ^* U0 a
  529. * @param  epnum: endpoint index
      E: b4 c8 H3 }0 i2 y. S
  530. * @retval status! k4 u) H' \; D/ G
  531. */+ ?1 K  t  n. \. A9 k
  532. uint8_t  USBD_MC_DataOut (USBD_HandleTypeDef *pdev,
    8 }/ h+ @# G  V  y. U. ?) q& ?
  533.                                uint8_t epnum)
    ! D: W; O0 t" Q) D5 }3 d
  534. {
    2 ?% X2 O2 a1 n' @1 s
  535.   if(epnum == MC_MSC_EPOUT_ADDR), V1 T* _' V# _' f6 g
  536.   {+ w4 S1 C" q( O' s' k
  537.     MC_Switch_MSC(pdev);9 X' B: v6 a# T" f# |' H
  538.     MSC_BOT_DataOut(pdev , epnum);
    : G& _8 x. G6 {0 ]
  539.   }. k5 l7 w3 ~7 b2 X1 r& `9 H, ^5 w- r
  540.   else if(epnum == MC_CDC_OUT_EP)
    - v! A1 F) _$ y, `
  541.   {
    1 [& L3 M0 T$ E. ~
  542.     USBD_CDC_HandleTypeDef   *hcdc;4 N6 ^4 f5 c4 u9 _
  543.    
    % _- B& I! e, Z4 O7 \8 g3 U
  544.     MC_Switch_CDC(pdev);
    ; F& e2 L2 ?/ A8 j
  545.     hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
    0 D7 f" N  l+ h/ l) z, L
  546.     8 K( b9 x( n$ Q
  547.     hcdc->RxLength = USBD_LL_GetRxDataSize (pdev, epnum);
    / R! Q( Z; x* t; L/ N
  548.     ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Receive(hcdc->RxBuffer, &hcdc->RxLength);
    9 a6 l' w. C% ~2 Q( Z# u* s% h
  549.   }
    % V' o3 g$ C0 p' y" [) V
  550.   $ |4 ~" W! h9 h6 k7 e* G5 y
  551.   return USBD_OK;0 w' R0 O* n/ d$ C( Q
  552. }- T( i6 _" h: G% C: Q8 Z

  553. & `: y: u, q/ |1 p% j
  554. /**# r% L) I; Z. B' z: V& I
  555. * @brief  USBD_MC_GetHSCfgDesc
    0 `' W6 ]( D; r) d( b6 N8 v- S
  556. *         return configuration descriptor- h1 T( J: r( a
  557. * @param  length : pointer data length: {. i" J1 E0 c) `; R8 x
  558. * @retval pointer to descriptor buffer! Q. U, `& T4 ?9 T. w) ]
  559. */6 }% _$ ~# b9 O: z
  560. uint8_t  *USBD_MC_GetHSCfgDesc (uint16_t *length)
    ( W2 Y& p$ D! j/ f6 `
  561. {/ p7 n* c5 y. N# r% C
  562.   *length = sizeof (USBD_MC_CfgDesc);
    1 g, o( Y; {: o- ~
  563.   return USBD_MC_CfgDesc;% W/ r" m! M7 y* w. s
  564. }
    * S$ N+ O3 _* c6 V1 |
  565. # B% Y+ u8 @, P8 r; |
  566. /**
    - E* N3 D& ]& \) E3 `; w  v5 |
  567. * @brief  USBD_MC_GetFSCfgDesc 6 F0 r0 u+ u9 T5 w) F0 I$ }
  568. *         return configuration descriptor
    9 S& ]2 e  _: T; X
  569. * @param  length : pointer data length
    ! @2 U7 i! [+ d/ [$ a0 _: e
  570. * @retval pointer to descriptor buffer6 A2 g! R+ i/ i0 e& s, J  H( W
  571. */
    3 a9 T4 k' O4 ~4 J
  572. uint8_t  *USBD_MC_GetFSCfgDesc (uint16_t *length)/ \* k; D2 v& K1 i( z4 {, Z8 m
  573. {
    " w- P7 q7 w- e) A
  574.   *length = sizeof (USBD_MC_CfgDesc);' d/ U4 U8 Z6 Q
  575.   return USBD_MC_CfgDesc;
    - R% M( b, G: O/ U) i4 H
  576. }
    0 q0 Z$ b2 F: F3 F2 w+ _
  577. % r0 J0 C% r' ]2 j" ^
  578. /**5 y9 B' o" ^. W2 H
  579. * @brief  USBD_MC_GetOtherSpeedCfgDesc / @- r# N" C' C6 c- i2 d
  580. *         return other speed configuration descriptor3 y9 y. C/ m1 U' b- t  `! M
  581. * @param  length : pointer data length7 }" N5 d; b- [1 r
  582. * @retval pointer to descriptor buffer# \2 Q# O2 H. h/ p, d
  583. */8 _8 v9 g. y( T: ~5 v
  584. uint8_t  *USBD_MC_GetOtherSpeedCfgDesc (uint16_t *length)3 b3 c' M# c$ Y, D* T2 N
  585. {
    3 l2 x0 O+ \8 i2 |! I  k
  586.   *length = sizeof (USBD_MC_CfgDesc);1 a( A! N, d: r. l
  587.   return USBD_MC_CfgDesc;/ S4 F) ^& z4 a1 a' D- h" x( K
  588. }2 X- |7 {5 F- W* U6 _( Y
  589. /**
    0 O3 W3 v5 D, E3 t6 H5 u' I5 W6 `
  590. * @brief  DeviceQualifierDescriptor
    # y' d% x1 ^7 H
  591. *         return Device Qualifier descriptor4 v% M$ g" y8 r; _9 w8 R- M9 u! t
  592. * @param  length : pointer data length4 M( o" Y6 G' I) S7 a# b% Y& @
  593. * @retval pointer to descriptor buffer3 O5 g2 I# T( |# _
  594. */
    8 \2 u0 _  E9 G
  595. uint8_t  *USBD_MC_GetDeviceQualifierDescriptor (uint16_t *length): M9 r* T0 L6 x+ |6 \
  596. {+ e3 R$ A" j4 W! U
  597.   *length = sizeof (USBD_MC_DeviceQualifierDesc);) x0 O: t4 G# j7 C
  598.   return USBD_MC_DeviceQualifierDesc;
    8 T, n7 Z! V6 t3 d& N
  599. }
    4 `7 R+ b5 U7 k! @) u! h
  600. 8 d# o6 C% L' ]# R  K
  601. /**
    # T( i3 r8 w/ k8 v6 \3 }) j8 O
  602. * @brief  USBD_MC_RegisterStorage
    " Q8 h  @. r, g) `3 a% i0 [
  603. * @param  fops: storage callback7 ]" y; a1 w$ u6 \! |, @( E, X" `
  604. * @retval status
    % m: ^# B5 U9 D4 V1 l. \
  605. */. a& U% ~. a7 E4 v# l' F; W
  606. 5 r6 X9 {" Q5 A4 ]7 d' D
  607. static uint8_t  USBD_MC_RxReady (USBD_HandleTypeDef *pdev)* y: k2 a$ Z* w
  608. {
    ) R) D( e4 P! P, E8 {
  609.   USBD_CDC_HandleTypeDef   *hcdc;
    7 J! v1 y5 A- E) f2 q( D8 w
  610.   
    8 O4 {* V4 i2 v3 }5 p% g. F) X; C. [
  611.   MC_Switch_CDC(pdev);
    + N: R( i$ p) g: h, F! l3 B
  612.   hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;; Q+ x1 D, i+ i$ j
  613.   2 C& w% J; I9 `
  614.   if((pdev->pUserData != NULL) && (hcdc->CmdOpCode != 0xFF))- }5 ]! `  o! X  b+ Y) y
  615.   {! e( S7 W$ l$ k5 b
  616.     ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(hcdc->CmdOpCode,4 ]3 d' L5 l* d" J( h
  617.                                                       (uint8_t *)hcdc->data,) q; u( ~& k5 I9 G  L% {! N1 Q
  618.                                                       hcdc->CmdLength);1 J) P$ X; Q( y" i) k
  619.       hcdc->CmdOpCode = 0xFF; 9 M  x3 k! ]7 `+ @! r% W
  620.       
    ; b2 d+ P) G  J, p( l  ]. g8 l4 }1 d" q
  621.   }
    ( o& l3 I! d$ c, l2 I; _: H3 v
  622.   
    5 [* h# l  G' M' ]! c6 u3 I
  623.   return USBD_OK;
    $ b/ u; m/ z3 M, z1 _( Y9 N
  624. }
    . w7 T$ }/ r% w; D
  625. 7 A9 R& H9 C+ x* o
  626. static void MC_Switch_MSC(USBD_HandleTypeDef *pdev)
    0 n2 {% f( ~0 E- E, u
  627. {! m1 {8 S5 @) ~% V, D; m' v% W
  628.   static USBD_MSC_BOT_HandleTypeDef msc_handle;6 |: h3 U8 w. ?5 X' z  R
  629.   
    # C; T2 H& p+ j! e; Z
  630.   USBD_MSC_RegisterStorage(pdev, &USBD_Storage_Interface_fops_FS);' P: P5 \' P. }6 E8 m9 t
  631.   pdev->pClassData = &msc_handle;) r; a3 |  T) B
  632. }& F1 }$ ^# g) l& n8 U- A, i

  633. 0 e! O  `4 v* ~
  634. static void MC_Switch_CDC(USBD_HandleTypeDef *pdev)
    1 M( Q3 w# @2 _$ f  g$ Q
  635. {: d3 h2 p2 {+ v5 w
  636.   static USBD_CDC_HandleTypeDef cdc_handle;+ K+ H! T+ p& @9 e  u0 J
  637.   
    $ y" \- q7 b# p* J! p
  638.   USBD_CDC_RegisterInterface(pdev, &USBD_Interface_fops_FS);
    ( j3 Q" n' _% h' b7 _4 e
  639.   pdev->pClassData = &cdc_handle;% _; B  x' P7 z, ~" ?4 b
  640. }
    / F$ B3 I( i* d9 l( l% K

  641. : v( u2 j9 {  T
  642. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/+ B8 B5 s) x& |  @& d$ N
复制代码

, c! D: S6 `9 M: ?3 q. e9 ?通过以上修改后电脑电脑端显示USB复合设备MSC+CDC
6 q; U! O! E: e0 U/ X msc cdc.png - q& X) z/ J+ j+ r+ V( ?0 ^5 j
$ Q# u+ D8 O2 [
13.在usbd_cdc_if.c  CDC_Receive_FS   /* USER CODE BEGIN 6 */ 增加发送测试" x. p  [/ _0 c! y, z6 f8 o$ z

* r7 F& Y$ ?( R# @% \$ |, E0 N
  1. static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)
    , a# Q- i6 A% d+ W( Y  }
  2. {
    5 \& p7 P, v# G2 Y
  3.   /* USER CODE BEGIN 6 */: f' m' t. T5 P; Z6 @
  4.   USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);
    ( m% ?; h( V' G3 |' e7 m( i
  5.   USBD_CDC_ReceivePacket(&hUsbDeviceFS);
    , t2 g" E; L' |& A+ W
  6.   
    - j5 s% E# p. `: O& @
  7.   CDC_Transmit_FS(UserRxBufferFS, *Len);      //把接收的返回$ p* T3 z! P3 D/ T/ @
  8.   + G! {% T5 Z/ j  E) {9 f
  9.   
    1 M+ u. \5 y) t- a  M! t
  10.   return (USBD_OK);
    5 `; J- I$ g+ J' A
  11.   /* USER CODE END 6 */
    & n' ?3 ~( s7 v; |0 i
  12. }
复制代码
( P9 N. ]9 @! k/ c( b  F& V: {( X
测试串口收发. i  y& ]+ o6 x, D$ [$ g3 w
test.png 5 |# \$ k) X, R# ]5 i0 l' _
# m: S1 x3 F* M' A3 M1 f# O. Q: R

" R/ ?6 z0 z9 _( Y% \8 L& e
7 K- s7 |2 O: T" @. E
% `- a" Z/ o. `9 @2 e& N- S% d' P

评分

参与人数 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
非常好的资料,对初学者很有帮助;5 ^9 @+ ~2 r8 t& R: t! J# }
希望楼主多多分享,赠人玫瑰,手有余香,念念不忘,必有回响;
hds1988 回答时间:2020-6-29 09:52:41
完全按照楼主做法,在win10环境下U盘和串口都可以实现功能,在win7环境下,串口错误识别为mass storage
289466080 回答时间:2020-7-15 09:54:26
hds1988 发表于 2020-6-29 09:52* w4 K  i1 [- O, j' x
完全按照楼主做法,在win10环境下U盘和串口都可以实现功能,在win7环境下,串口错误识别为mass storage ...

- D4 t2 p- ?' x& ^- Z% c. l6 h是不是驱动问题,我电脑Win10
电子ai好者 回答时间:2020-11-19 12:57:48
hds1988 发表于 2020-6-29 09:52
3 V, y( ]9 p6 n! O1 i完全按照楼主做法,在win10环境下U盘和串口都可以实现功能,在win7环境下,串口错误识别为mass storage ...

5 J" Q. e0 k& ~5 \8 F: W8 d9 w7 T 微信图片编辑_20201119125724.jpg 我现在就是win7系统,和你一样的现象。请问你找到解决办法了吗?
# J) \  t& c% G
js123456 回答时间:2021-8-10 15:34:43
用stm32cubemx生成的项目cdc,在文件usbd_conf.c中,USBD_static_malloc申请内存是以USBD_CDC_HandleTypeDef为准,函数如下:- t; V% H4 S3 @
void *USBD_static_malloc(uint32_t size)
8 t2 h  B3 _+ m/ Z6 _, W{
# j- L6 _  i) G  static uint32_t mem[(sizeof(USBD_CDC_HandleTypeDef)/4)+1];/* On 32-bit boundary */
) ?1 k; `8 k# J3 Y# Z) f( h7 }8 I! A+ Z  return mem;
0 t+ ]" y8 l: k5 s}! E. T% l0 H5 n' p0 s

% e& @9 z% c) E( j8 N3 x5 V那么在组合设备中,USBD_MSC_BOT_HandleTypeDef和USBD_CDC_HandleTypeDef都需要申请内存,怎么操作?
- z+ N6 C4 F6 c/ l5 W- s9 a$ U0 I/ [$ d. S  i
js123456 回答时间:2021-8-10 15:35:35
hds1988 发表于 2020-6-28 23:47# @; g( [' m8 u) u# F
完全按照楼主的说明操作一顿后,不能识别出CDC,但是能识别MSC。MCU是F407VE

0 b8 C/ W  x, Z3 a* ?$ @6 F7 e有可能是函数USBD_static_malloc的问题
+ D8 c9 w, v" t$ _! a/ }

所属标签

相似技术帖

官网相关资源

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