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

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

[复制链接]
289466080 发布时间:2019-6-23 13:44
本帖最后由 289466080 于 2019-6-23 15:56 编辑 % f4 B# n; R' z

& m4 d4 c0 r4 w6 l( f# A    最近做个USB复合设备CDC+MSC,在网上找了好多基本都是F103做的复合设备,带OTG芯片USB复合设备网上很少可能是我搜索的关键字不够理想有的不够全面,官方给了一个视频教程但是没有参考代码,社区里面有分享到github我按照后也不能实现,后结合F1与github分享的+官方视频,实现了在STM32F730R8T6上面USB复合设备,分享下怎样用cube生成的代码实现USB复合设备(带OTG的芯片).
1 {" p! @! w8 F0 g2 t" P, l( S% L$ ^$ t& Q4 x% B
参考:4 d" L7 ]4 N' m6 a3 n: W" ]
github分享
: c0 ~& J. T; z( v# w7 t0 Q' ]http://github.com/uwyciw/CDC_MSC
* z0 u: G( V( X$ j2 {官方视频3 G# N1 W6 l1 y/ Y7 B
https://www.stmcu.org.cn/video/index/detail/id-3988
" C$ u: a& ]% `F103
5 {& r: ~) w6 f- Vhttp://www.bbsmax.com/A/kjdwBXA5Np/
5 x, o; W3 B" y( N5 i! d: V  }0 k  {& z& {& F
5 Q' o. p$ ?9 n2 O$ d+ @
cube 5.2.10 G0 ]% G4 {- @1 a
hal  stm32cube_fw_f7_v1150.zip, s* [3 L( z6 l; V3 p5 b
; K, a: _( I1 J2 Y/ Q8 n
USB为 USB_OTG_FS& |* Z' q1 P0 N3 s! _, r
" U' \  l7 J. E: O: h
1.先生成一个CDC工程下面配置图。4 p$ l  ~- V6 r4 f% Z' }2 ^
RCC如图箭头其他默认8 C1 K* Q4 a6 `' `* l
RCC.png
; d0 d2 h6 X, g! B( NUSB_OTG_FS如图箭头其他默认
$ _+ H' i. G6 B7 L7 v5 G USB_OTG_FS.png * T- |+ J; C2 ?. O
USB_Device
如图箭头其他默认9 K' J; U- c( |+ I+ g
USB_Device.png
6 p4 U: y0 O% d' W) @, eClock如图箭头其他默认我用的16M晶振比8M便宜
% E% ~; v# z( K3 V# P) d Clock.PNG 2 L5 K6 |( R; K9 Q

3 ]3 K% b- G+ f8 IProject如图箭头其他默认
; E4 f0 |% J9 V/ u( O7 r8 B. s Project.png
$ [9 @. ~0 X1 i6 N4 ]) Pcode如图箭头其他默认
: Q. t1 d( w% ]  d2 s code.png
! X7 G2 E/ U9 G6 Z( e2.同样生成一个新的MSC工程不可覆盖原本的工程只需修改下图与工程名其他一样4 m( J1 _: u3 N: B/ G; h9 A

$ }# _# V, p& C0 A7 C) u( P+ x USB_Device-MSC.png
* D# Q' j3 C& G$ @( ]' x/ [& E6 N1 n. t, o
8 w! Z- t9 a' t# q
3.生成后把CDC工程下Src文件夹里的usbd_cdc_if.c与Inc下的usbd_cdc_if.h复制到MSC工程下Src与Inc文件夹里面,MSC工程下Src文件夹下新建usbd_composite.c与Inc下新建usbd_composite.h
  d7 N9 j& C# `' O' D  V  w
1 U& q" x8 K; I' U2 [4 l h.png
8 z% Y8 p: b" Y0 T) \
( c! z) A2 J! _) v# k4.把CDC工程\Middlewares\ST\STM32_USB_Device_Library\Class目录下的CDC文件夹复制到MSC工程下见图
7 [* w' H! z& M5 u, F% g. k cdc.png
( i) m( k$ g! p" ?1 }7 K5.添加CDC路径
0 S! o' e: b' x: P7 F2 S
6 u- U2 z6 p, T CDC-PATHS.png
& [  e$ q/ e' j% U
% O+ o$ b7 e- O! \5 W( |6.在工程中添加usbd_cdc.c usbd_cdc_if.c usbd_composite.c见图$ }! c/ D2 @5 W) P2 W
keil-add.png
, B. N4 Y7 d+ ?1 {3 f4 @$ g) R( g6 G$ h: c+ N
7. usbd_conf.h 把USBD_MAX_NUM_INTERFACES值 1修改为3
5 x, u: t: [! c$ _) S+ s
  1. /*---------- -----------*/* E+ M' o$ ~. [8 G$ r% I' v
  2. #define USBD_MAX_NUM_INTERFACES     3U    //1U, V6 ~! `2 [2 K5 ~; \$ e( Z/ ^# {
  3. /*---------- -----------*/
复制代码
8. usbd_cdc.h 修改CDC_IN_EP CDC_OUT_EP CDC_CMD_EP  j& S' a8 n0 X- y* ?* E
  1. //#define CDC_IN_EP                                   0x81U  /* EP1 for data IN */
    3 J* d6 C0 g: B+ ~
  2. //#define CDC_OUT_EP                                  0x01U  /* EP1 for data OUT */; n# m! G* b0 y5 i2 T% N
  3. //#define CDC_CMD_EP                                  0x82U  /* EP2 for CDC commands */
    3 h/ @' ]2 P0 K* q! `, y8 u
  4. #define CDC_IN_EP                                   0x83  /* EP1 for data IN */. ?/ {6 |/ ?0 }
  5. #define CDC_OUT_EP                                  0x03  /* EP1 for data OUT */
    ( s# e. ]' A  f! ?7 o
  6. #define CDC_CMD_EP                                  0x82  /* EP2 for CDC commands */
复制代码
9. usbd_conf.c  USBD_LL_Init中新增8 D- g- |7 O  |
  1.   HAL_PCDEx_SetRxFiFo(&hpcd_USB_OTG_FS, 0x80);6 g2 A5 H( B' m+ f# \
  2.   HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 0, 0x40);
    ( P2 n$ X8 }& B0 ?; J6 g  v$ n
  3.   HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 1, 0x80);& e) B8 L5 g, D$ F
  4.   8 [, M: B) |" P  X0 h( c3 k: K4 Q
  5.   HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 1, 0x40);   //新增/ D  h: t  I9 J* q
  6.   HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 3, 0x40);
复制代码
10. usb_device.c 修改MX_USB_DEVICE_Init与SER CODE BEGIN Includes中新增usbd_composite.h1 ]* Y# @$ T+ A7 G1 t

+ m, V( M, p. X- c$ j) W" H

  1. : G, \' `" M9 W
  2. /* USER CODE BEGIN Includes */
    % P* ~6 |$ q' Z& W4 ?7 j
  3. #include "usbd_composite.h"
    , N/ d8 h  f0 |. G; m6 ]  S9 V6 ^. W" t
  4. /* USER CODE END Includes */4 T9 T( y$ {- s4 ~5 Z$ O1 @

  5. 2 T9 j6 e5 m% ~) B7 e
  6. void MX_USB_DEVICE_Init(void)4 L! h* V( M; Z* C  o6 u3 `7 b
  7. {* ]& o0 b3 W( l) q
  8.   /* USER CODE BEGIN USB_DEVICE_Init_PreTreatment */
    : H$ Y5 J" N8 i
  9.   
    $ w5 j+ T2 l. J
  10.   /* USER CODE END USB_DEVICE_Init_PreTreatment */1 `8 `5 l( r7 n" P6 l
  11.     B- G/ ^7 \' H4 I3 J
  12.   /* Init Device Library, add supported class and start the library. */
    6 L. e& E$ @' d7 I' }  B
  13.   if (USBD_Init(&hUsbDeviceFS, &FS_Desc, DEVICE_FS) != USBD_OK)
    ! _0 j  r% N& r) h% u: U
  14.   {; B' j4 \  V, _' Z' X# r
  15.     Error_Handler();
    - o' Q; t  g$ G9 l+ w; U9 ?6 ]9 ]' C- L
  16.   }7 [; \, C; E1 W: U6 U
  17.   if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_COMPOSITE) != USBD_OK)  //新增
    ; X: r5 f2 N! V# j" h; a$ k
  18.   {
    % p, O  _1 n! f: F
  19.   Error_Handler();& e; E% b1 w* a1 ?9 L9 I, G9 ^
  20.   }5 y- z9 ^. U4 O& d0 t7 F
  21. //  if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_MSC) != USBD_OK), s" M. D, {6 r& {! R1 C, [
  22. //  {
    . M# r$ B$ x" e9 k
  23. //    Error_Handler();: M1 K5 G! L% o8 {" {! v5 z. P% F
  24. //  }
    ' d) L; X+ x& w
  25. //  if (USBD_MSC_RegisterStorage(&hUsbDeviceFS, &USBD_Storage_Interface_fops_FS) != USBD_OK)
    6 @+ l1 a5 W0 K, e: T
  26. //  {+ `3 U3 C( c! |! [5 u+ L
  27. //    Error_Handler();
    % n7 L8 b+ ]" I+ y( v
  28. //  }* p4 z1 S( r3 s1 ]0 D. P, u9 N3 Q
  29.   if (USBD_Start(&hUsbDeviceFS) != USBD_OK)
    5 o1 X$ i) c1 |
  30.   {
    9 k$ x; X1 t/ z8 e  |+ c  c+ u
  31.     Error_Handler();" S" w2 Z( }/ ~! }* W9 r' I
  32.   }% R3 ]  r* C  l9 t

  33. ' M8 w% O' A) [9 L
  34.   /* USER CODE BEGIN USB_DEVICE_Init_PostTreatment */8 D, l* F, ?8 W7 I
  35. //  if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_COMPOSITE) != USBD_OK)  //新增
    : N8 Q" [* A, X( v* R; I9 d8 i( v
  36. //  {
    ( _! H2 _2 G$ g" Q
  37. //  Error_Handler();) _! M5 ~5 A. V$ H3 J. f- X2 S  F
  38. //  }
    , u  F. U5 i! i6 b$ q4 W
  39.   /* USER CODE END USB_DEVICE_Init_PostTreatment */
    . W, d7 T* |) ^( g0 c; r. F
  40. }
复制代码

! x- y$ f# [1 c  `

  a5 v0 y2 w# j/ Y" I11.在usbd_composite.h中新增代码* c" M# f3 h9 V, ]" @7 F4 m

  1. 2 o2 a9 i# n6 z; X. c6 S' \" r0 l
  2. #ifndef __USBD_COMPOSITE_H6 q( F2 ]6 J1 j4 W, Q
  3. #define __USBD_COMPOSITE_H% R' p% B5 ^7 t4 J# R

  4. 1 q. d6 o+ w# Q0 m; H+ X6 v1 h9 x$ N
  5. #include  "usbd_ioreq.h"
    ( Y6 M- x+ F. J  ~% M1 \
  6. #include "usbd_cdc.h"+ ~5 s) J; e6 t- A$ w
  7. #include "usbd_msc.h"
    * k2 w" t3 Y0 c# O; q& d2 F
  8. 7 K. }" r5 k9 }; F: ^
  9. #define MC_MAX_FS_PACKET            0x404 @* d# S+ S3 ~( P4 z1 x) u' m
  10. % ~: J1 Z. b# Y( _  D' i
  11. #define USB_MC_CONFIG_DESC_SIZ      106
    5 s+ o5 q7 C( r$ t( |- T* ^- F

  12. 4 R2 [2 ?7 M1 _' g5 I* [& s* b1 o0 r
  13. #define MC_MSC_EPIN_ADDR                MSC_EPIN_ADDR $ A3 ^1 m1 a% T7 d& g
  14. #define MC_MSC_EPOUT_ADDR               MSC_EPOUT_ADDR 7 U6 e3 Z! }' ?2 d& G

  15. 5 T/ v; T' v5 ^4 X  X
  16. #define MC_CDC_IN_EP                   CDC_IN_EP
    , O1 v1 Q; r# X; w* `7 Z
  17. #define MC_CDC_OUT_EP                  CDC_OUT_EP  # S  e/ J; G4 K8 S
  18. #define MC_CDC_CMD_EP                  CDC_CMD_EP + m% F/ X0 U4 P7 u) \
  19. % _; t! K1 H0 K4 D6 s1 W
  20. extern USBD_ClassTypeDef  USBD_COMPOSITE;8 i" y5 L+ g' p7 L
  21. 6 u3 ~! S  u  s# _& a
  22. #endif  /* __USBD_MC_H */
    8 e4 C  b: x$ c7 m
  23. : ~- J; {  e, I% q3 |
复制代码

) M6 U5 o6 `! |
  J& G" E# r9 T4 K6 O12.在usbd_composite.c中新增代码
. U3 o- T' |% U" l1 @  A# ^
4 G2 s% e" `1 I, }$ g
  1. : l" e" L8 H. b8 s5 \% ?# o. o
  2. #include "usbd_composite.h"; |4 x; Y  K3 a! G. n. G! v& s/ {
  3. #include "usbd_def.h"  p5 C' g/ @) V! D( u
  4. #include "usbd_msc.h"+ f5 \( O0 ^+ q" T
  5. #include "usbd_cdc.h"
    5 N- H% d; |1 V" t: C7 H+ d
  6. #include "usbd_storage_if.h"
    & b) E  p5 |6 ]9 W
  7. #include "usbd_cdc_if.h"
    6 V% h. i- q6 d% Y! P) e+ i

  8. 2 M! E5 B+ R+ s% N" u, l, H
  9. /** @defgroup MC_CORE_Private_FunctionPrototypes. |$ V6 p7 s5 b0 H6 R2 K
  10.   * @{
    * S; i9 l5 M+ K( f
  11.   *// E& g' p$ Y' w5 K; s
  12.   ' W0 d- N. @* V$ n. r
  13. USBD_CDC_HandleTypeDef     *pCDCData;; `, w, T( i$ a3 A$ J6 l
  14. USBD_MSC_BOT_HandleTypeDef *pMSCData;
    1 P/ Q  M  p! n( W( u
  15.   % K0 g$ w; ~% E$ A
  16. uint8_t  USBD_MC_Init (USBD_HandleTypeDef *pdev, 8 E( v* W6 I7 m( \. w  h) k5 c
  17.                             uint8_t cfgidx);6 H; P6 f$ h) I- ^: z+ F0 m1 N

  18. # v: }9 Y( ], R6 i, u6 I2 G
  19. uint8_t  USBD_MC_DeInit (USBD_HandleTypeDef *pdev, 5 C2 l3 |) V" m, `1 B
  20.                               uint8_t cfgidx);
    ( V0 x% r+ {& j% e
  21. $ b( P# L2 z, @
  22. uint8_t  USBD_MC_Setup (USBD_HandleTypeDef *pdev,
    6 u/ \% a* @; Y. m# a9 e5 a) W
  23.                              USBD_SetupReqTypedef *req);
    9 E% I0 E$ ]8 t! a
  24. 1 G0 }( @  z! y1 S
  25. uint8_t  USBD_MC_DataIn (USBD_HandleTypeDef *pdev, ' K; v# `% Q2 b3 l& g
  26.                               uint8_t epnum);
    0 L) y6 F. m# K

  27. $ O0 D: ~5 Q' f& t  G* |

  28. 8 @9 Q3 ]: d3 Q& W; Q+ s1 A
  29. uint8_t  USBD_MC_DataOut (USBD_HandleTypeDef *pdev,
    / }; h* e3 n2 \& }5 B  F9 f2 j3 x
  30.                                uint8_t epnum);8 j2 }$ L0 g5 \) K: W+ S7 x

  31. ; z" h7 z2 z$ k' z% |* s
  32. uint8_t  *USBD_MC_GetHSCfgDesc (uint16_t *length);2 O& S- p) @- r% z
  33. . t, E7 y7 ^' I; D4 {  N5 W' A2 g; T0 G
  34. uint8_t  *USBD_MC_GetFSCfgDesc (uint16_t *length);' u1 L! O# ~% W# a/ [2 D
  35. : }+ f: k7 M. o5 u, K9 U# F
  36. uint8_t  *USBD_MC_GetOtherSpeedCfgDesc (uint16_t *length);! Z% `' ?7 @, {& }* {9 u

  37. 3 a7 z4 A% K/ @' b( y8 s
  38. uint8_t  *USBD_MC_GetDeviceQualifierDescriptor (uint16_t *length);
    2 W+ ~5 H: j, q2 V' m: ?

  39. ) U! ]3 E, h- L3 I. ]6 v# [. p8 [
  40. static uint8_t  USBD_MC_RxReady (USBD_HandleTypeDef *pdev);/ [$ P; x, i0 B3 C8 o8 K
  41. static void MC_Switch_MSC(USBD_HandleTypeDef *pdev);: L# ~+ a5 _8 N) g1 P0 ~) W
  42. static void MC_Switch_CDC(USBD_HandleTypeDef *pdev);
    9 K0 y7 D# `* ?, }3 k
  43. 7 l/ U, n8 l! _& |/ f' m3 B
  44. /**
    : s, j  O! h2 x8 f
  45.   * @}
    - z" e. g3 R, h, m
  46.   */
    + q& C  w5 i8 }5 K
  47. extern USBD_HandleTypeDef hUsbDeviceFS;
    ( O! Q) }. @7 l7 m, f! [9 ?' \
  48. 6 s& {9 j, ]$ u% ?+ Z# ~6 ^! e

  49. ( S, o/ A# t- p
  50. /** @defgroup MC_CORE_Private_Variables
    6 P( I5 O! b7 O) U9 R
  51.   * @{2 O9 ?0 ^+ s. e3 E
  52.   */ / M/ F. i5 O/ g" l3 [
  53. USBD_ClassTypeDef  USBD_COMPOSITE =
    0 c. g4 a* |$ m7 S3 B) F
  54. {. D5 d) s& t0 a) X7 a( d7 M
  55.   USBD_MC_Init,- ?3 D% J/ {- v/ @. I- F
  56.   USBD_MC_DeInit,
      ~: E/ l# T. s5 ?
  57.   USBD_MC_Setup,
    # \0 L" O  K4 W6 v% |1 B+ R7 ~8 z6 T
  58.   NULL, /*EP0_TxSent*/  
    + F8 f! O( k+ C% R1 I5 U# J
  59.   USBD_MC_RxReady, /*EP0_RxReady*// c- k( e6 V$ w$ O8 u7 A- y
  60.   USBD_MC_DataIn,
    * U  B2 k. A( j
  61.   USBD_MC_DataOut,
    : ~2 [) v+ O3 _5 @6 v
  62.   NULL, /*SOF */ ' ~: f+ r0 U4 V  v# W7 g
  63.   NULL,  
    . T; D0 w# B, d; n
  64.   NULL,     
    / B/ z7 ?6 _+ T9 @: Y0 P
  65.   USBD_MC_GetHSCfgDesc,
    ; \; I7 L' ^' ]
  66.   USBD_MC_GetFSCfgDesc,  
    * P$ s: `" z4 O6 ^, I& p( b/ I. G
  67.   USBD_MC_GetOtherSpeedCfgDesc,/ u; P* s  V3 I
  68.   USBD_MC_GetDeviceQualifierDescriptor,6 a3 ?9 s# _) o, r6 g1 E9 p
  69. };# v% U  |& [4 {* n# y8 y* ~1 L

  70. - J1 I2 U) G3 J9 I7 ^; R3 R
  71. /* USB Mass storage device Configuration Descriptor */
    % C: x0 J% g, n! w5 V, q
  72. /*   All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */' [: c7 M+ I$ W, m  p7 a
  73. uint8_t USBD_MC_CfgDesc[USB_MC_CONFIG_DESC_SIZ] =
    & T0 x( a3 ~( Y/ m$ ~. d; o
  74. {" |7 h: P& G+ m  K
  75.   /*Configuration Descriptor*/3 y7 u7 J3 X. V0 T. F
  76.   0x09,   /* bLength: Configuration Descriptor size */! ?1 j+ G7 L: G$ u$ Q! ~
  77.   USB_DESC_TYPE_CONFIGURATION,      /* bDescriptorType: Configuration */( L: f  i; }, P, `6 Z, @
  78.   USB_MC_CONFIG_DESC_SIZ,                /* wTotalLength:no of returned bytes */0 m2 W6 F$ Y1 \# Q6 A7 y8 s0 n0 P" T
  79.   0x00,9 W; V( g3 _# |! G' A
  80.   0x03,   /* bNumInterfaces: 3 interface */) h, |' y/ ]. r4 v# k& g2 Q  U/ H0 |( d
  81.   0x01,   /* bConfigurationValue: Configuration value */
    , Y2 J, O1 ?( x( G$ N* W& i
  82.   0x00,   /* iConfiguration: Index of string descriptor describing the configuration */7 z( ^8 O% {/ U7 \% m) ?5 s
  83.   0xC0,   /* bmAttributes: self powered */# S0 q4 V4 w9 @& U
  84.   0x32,   /* MaxPower 0 mA */( M* f- R0 a; h8 T5 `: G7 J
  85.   " |# o' h5 }. \/ R9 f7 A' V5 D
  86.   /*---------------------------------------------------------------------------*/
    8 q- A: X9 l- {7 X9 c; Z: z
  87.   // IAD( ^, E2 t, Y9 T# T- `! x% j/ {1 f- q  R
  88.   0x08,        //描述符大小
    ' W  ~3 g' ]. f4 g
  89.   0x0B,        //IAD描述符类型
    4 u: Q- }- u! a+ Y9 E6 z3 l& k
  90.   0x00,        // bFirstInterface " p5 e! i# e* l' M9 X
  91.   0x02,        // bInterfaceCount
    $ D2 N, p6 P! x' X1 y4 ?/ W- O7 u
  92.   0x02,        // bFunctionClass: CDC Class
    : D1 E1 t3 ^1 U% k! P
  93.   0x02,        // bFunctionSubClass8 n2 H' ^! r; s7 e* c! E3 Y1 S
  94.   0x01,        // bFunctionProtocol
    * x, A- T. p4 [/ t1 s, ~. n
  95.   0x00,        // iFunction      
    ' }' u4 }% ~" B9 |; @" ~
  96.   
    . U4 _" y% }* N: u" D
  97.   /*---------------------------------------------------------------------------*/
    " R, p1 z, b7 x% o
  98.   /*Interface Descriptor */& }% r$ l3 ^, ~: J. d0 F
  99.   0x09,   /* bLength: Interface Descriptor size */
    $ ~+ |  u) ~! Y  O
  100.   USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: Interface */1 A; H2 u, z7 b- c6 B
  101.   /* Interface descriptor type */9 |* V" C0 Y8 |) K9 [
  102.   0x00,   /* bInterfaceNumber: Number of Interface */
    9 k. Q/ o& W" U" @* \
  103.   0x00,   /* bAlternateSetting: Alternate setting */
    5 B# p8 p& j" N( k! n" I
  104.   0x01,   /* bNumEndpoints: One endpoints used */
      l  ~5 ^- l8 r& V8 D7 g( A- _
  105.   0x02,   /* bInterfaceClass: Communication Interface Class */
    & L& o: D, x: f6 \: ~/ ~: b4 ]9 S4 O
  106.   0x02,   /* bInterfaceSubClass: Abstract Control Model */
    5 P! {# z9 C2 k7 {; n" D
  107.   0x01,   /* bInterfaceProtocol: Common AT commands */) [) D5 n; J# J/ V0 |
  108.   0x00,   /* iInterface: */
    9 H5 Q6 M5 B3 a9 ]+ W& t1 l
  109.   ' X8 ?2 O6 i) x; }, S7 i
  110.   /*Header Functional Descriptor*/
    ( c$ A7 z1 H" s: f, h+ w+ Z* p8 i8 D" G! [
  111.   0x05,   /* bLength: Endpoint Descriptor size */
      s* X5 I. Z2 B- j- X/ F. x4 y
  112.   0x24,   /* bDescriptorType: CS_INTERFACE */7 }! c, t6 U$ ]. k% S- J1 ]1 W
  113.   0x00,   /* bDescriptorSubtype: Header Func Desc */, W; u1 b$ V/ F8 n
  114.   0x10,   /* bcdCDC: spec release number */
    + f$ s2 ]  H5 G4 M
  115.   0x01,7 r, Y( X, U9 w- I2 b
  116.   
    7 k) q$ \9 g& g6 ]/ f; L, N
  117.   /*Call Management Functional Descriptor*/0 m/ _* C) `: `$ v" F
  118.   0x05,   /* bFunctionLength */% M: L  ~" T5 M# s
  119.   0x24,   /* bDescriptorType: CS_INTERFACE */5 r9 i( V) {( f( p
  120.   0x01,   /* bDescriptorSubtype: Call Management Func Desc */, K3 g7 z6 c* R
  121.   0x00,   /* bmCapabilities: D0+D1 */2 I" P' f  G& B- _
  122.   0x01,   /* bDataInterface: 1 */5 n, g8 t- a( @9 ?; d7 H; @
  123.   - f0 ^1 q/ u. G3 U: D5 q0 Y/ _
  124.   /*ACM Functional Descriptor*/
    1 [/ a. w% I1 w2 P( m; A
  125.   0x04,   /* bFunctionLength */
      t2 q; K+ i3 r- w- d; r4 v$ V% F
  126.   0x24,   /* bDescriptorType: CS_INTERFACE */
    7 ]3 r' Z: A! G0 s
  127.   0x02,   /* bDescriptorSubtype: Abstract Control Management desc */5 Q5 a6 V0 ^# M9 j
  128.   0x02,   /* bmCapabilities */
    # p0 J% t/ C) J( L) f
  129.   9 \+ w7 Z# j- R7 y) M
  130.   /*Union Functional Descriptor*/( G# `8 e; h% f8 m, p
  131.   0x05,   /* bFunctionLength */0 W6 c9 {1 W8 C
  132.   0x24,   /* bDescriptorType: CS_INTERFACE */
    # y! I, z, ]5 Q0 T# R: D! b! B
  133.   0x06,   /* bDescriptorSubtype: Union func desc */' b7 Y" N" ]% `+ f
  134.   0x00,   /* bMasterInterface: Communication class interface */6 B+ ^& d8 F% w/ a7 {
  135.   0x01,   /* bSlaveInterface0: Data Class Interface */  }. T& L; z1 s+ g
  136.   ) r! a; V$ ^+ _. n1 p( H
  137.   /*Endpoint 2 Descriptor*/
    7 `% N0 r; E) J0 v8 j- o$ H
  138.   0x07,                           /* bLength: Endpoint Descriptor size */
      \) G' z; T! X! R* [9 K
  139.   USB_DESC_TYPE_ENDPOINT,   /* bDescriptorType: Endpoint */) U9 F# G2 B0 y: C3 W
  140.   MC_CDC_CMD_EP,                     /* bEndpointAddress */
    # c) @! d3 F! k/ O, P
  141.   0x03,                           /* bmAttributes: Interrupt */- q' D& E1 j% K9 `9 S/ e+ O) H
  142.   LOBYTE(CDC_CMD_PACKET_SIZE),     /* wMaxPacketSize: */
    / H0 t9 O, x+ X' N6 g% N
  143.   HIBYTE(CDC_CMD_PACKET_SIZE),
    0 m  N, a' a" z; s
  144.   0x10,                           /* bInterval: */
    " j# l- S$ x: V! n" \9 G, y: C
  145.   % N0 _2 e6 m: O1 H5 y" Q1 _" v
  146.   /*Data class interface descriptor*/9 B# Y. `: R. k8 G2 D
  147.   0x09,   /* bLength: Endpoint Descriptor size */
    ! v- E  V) h0 T9 u/ j! m
  148.   USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: */1 q  W% X( H" N/ L  @: N
  149.   0x01,   /* bInterfaceNumber: Number of Interface */) m( B" K% @) }; H$ [: @
  150.   0x00,   /* bAlternateSetting: Alternate setting */
    9 R+ |, B8 F) H8 n4 ^
  151.   0x02,   /* bNumEndpoints: Two endpoints used */4 t( k6 N- X% _- L- H
  152.   0x0A,   /* bInterfaceClass: CDC */  B4 R2 I5 r7 k  v; O; }% N
  153.   0x00,   /* bInterfaceSubClass: */
    % X7 M) ?8 O( X7 O0 E
  154.   0x00,   /* bInterfaceProtocol: */
    ' d2 r" J+ l; Y2 Y
  155.   0x00,   /* iInterface: */
    $ _# R$ s; `: ^4 G
  156.   
    8 m2 F1 u0 |9 V  f" t$ }1 o
  157.   /*Endpoint OUT Descriptor*/2 W- _  R$ x  y5 q! h- [; |
  158.   0x07,   /* bLength: Endpoint Descriptor size */: M7 T: ^, V! G0 ]" Y
  159.   USB_DESC_TYPE_ENDPOINT,      /* bDescriptorType: Endpoint */2 q5 F" W9 L: ]1 b
  160.   MC_CDC_OUT_EP,                        /* bEndpointAddress */
    9 p& m( B+ Z. Z6 Y% w4 N7 j
  161.   0x02,                              /* bmAttributes: Bulk */
      O& Q  P0 i: q/ x7 H
  162.   LOBYTE(MC_MAX_FS_PACKET),  /* wMaxPacketSize: */6 k+ T# x" i/ y. n- s
  163.   HIBYTE(MC_MAX_FS_PACKET),
    6 [) B1 A! e8 j: z. E* }
  164.   0x00,                              /* bInterval: ignore for Bulk transfer */
    9 q3 {9 P& c. }( X) j8 T  s
  165.   
    5 `6 A" y. f2 r
  166.   /*Endpoint IN Descriptor*/' W( q. R4 Q; v: k& D4 R
  167.   0x07,   /* bLength: Endpoint Descriptor size */$ @: p7 f8 F' G3 D" y) n
  168.   USB_DESC_TYPE_ENDPOINT,      /* bDescriptorType: Endpoint */6 l" p8 I: a* E5 Y
  169.   MC_CDC_IN_EP,                         /* bEndpointAddress */" s: N7 u1 g) f; G* c, I$ Q& @1 [( O
  170.   0x02,                              /* bmAttributes: Bulk */
    1 [' ~0 X6 E3 Z1 @
  171.   LOBYTE(MC_MAX_FS_PACKET),  /* wMaxPacketSize: */
    - ^# N2 E2 u, Z0 o. }9 f" t
  172.   HIBYTE(MC_MAX_FS_PACKET),2 }8 f/ x9 e8 f( z# F
  173.   0x00,                               /* bInterval: ignore for Bulk transfer */
    1 }% h  C/ Q4 i3 C
  174. $ n; P# R7 p4 T0 `# s( f: K( u0 U9 J
  175.   /*---------------------------------------------------------------------------*/3 Q! D" z3 x2 n0 \# P$ p/ M; J# F4 }
  176.   // IAD
    7 `9 Q0 g2 F, t
  177.   0x08,        //描述符大小
    % R/ T+ n6 I9 }5 j8 |, |
  178.   0x0B,        //IAD描述符类型
    ; M$ M* T4 a. K( e
  179.   0x02,        // bFirstInterface: H+ c* `* r( C6 u  d, t
  180.   0x01,        // bInterfaceCount
    ' R3 A# T1 `7 X( H& s, P
  181.   0x08,        // bFunctionClass: MASS STORAGE Class
    % h& C, a3 L( a' b4 i4 o
  182.   0x06,        // bFunctionSubClass
    $ d7 |" u# z6 ?& A5 [: [9 x& W
  183.   0x50,        // bFunctionProtocol
    6 B; N  F/ O* I$ H8 P! Y, }
  184.   0x01,        // iFunction   
    4 t9 C4 l/ S% A8 s& ^

  185. 4 b% t! L9 X1 P2 [( b, G
  186.   /********************  Mass Storage interface ********************/2 L  k: [, I3 Q  Q& ^% P# ~; V, d1 B
  187.   0x09,   /* bLength: Interface Descriptor size */
    9 N) ^5 A# ^1 M7 z" M1 `
  188.   0x04,   /* bDescriptorType: */
    * k. ~" r; m2 M. _
  189.   0x02,   /* bInterfaceNumber: Number of Interface */" i$ N# ^3 Q- C* N
  190.   0x00,   /* bAlternateSetting: Alternate setting */
    1 c+ I0 z1 p" e* B$ |
  191.   0x02,   /* bNumEndpoints*/
      {  t! }! m% X6 O/ {
  192.   0x08,   /* bInterfaceClass: MSC Class */
    $ _9 G& U! y4 x) }% p7 h& Z6 H1 K
  193.   0x06,   /* bInterfaceSubClass : SCSI transparent*/
    , |' [' e; B( O2 ^0 ?( A" G
  194.   0x50,   /* nInterfaceProtocol */
    5 @7 @0 _8 b& t/ B* i! n; v+ w3 \
  195.   0x05,          /* iInterface: */
    ; I+ K7 [6 ~8 m" \. U! R4 O
  196.   /********************  Mass Storage Endpoints ********************/
    - j. O. X" @7 w" m: g
  197.   0x07,   /*Endpoint descriptor length = 7*/5 {9 H* C  d* n
  198.   0x05,   /*Endpoint descriptor type */
    $ G3 E/ G3 Q1 ^3 b: x
  199.   MC_MSC_EPIN_ADDR,   /*Endpoint address (IN, address 1) */
    ) q& ?3 I) t) k# g3 _4 {1 O
  200.   0x02,   /*Bulk endpoint type */* R& K2 R3 M8 |- W+ |  N
  201.   LOBYTE(MC_MAX_FS_PACKET),8 M" [/ `! M/ i4 k
  202.   HIBYTE(MC_MAX_FS_PACKET),, @, c! K# R5 f, g
  203.   0x00,   /*Polling interval in milliseconds */% R9 G/ X* W* x  ?
  204.   ' J; U: N8 R; g# T$ a9 q# [; H! \
  205.   0x07,   /*Endpoint descriptor length = 7 */
    * p! g5 ~6 C9 X6 v, W1 V# E
  206.   0x05,   /*Endpoint descriptor type */( M9 z9 m9 X+ V& M  G. _  I" W
  207.   MC_MSC_EPOUT_ADDR,   /*Endpoint address (OUT, address 1) */
    - V6 S6 d) f# r: w1 r* J) b2 o
  208.   0x02,   /*Bulk endpoint type */& Y( P  @! V7 t! b% `
  209.   LOBYTE(MC_MAX_FS_PACKET),
    : B, ~3 W% m' ~, _6 E$ `+ b* v
  210.   HIBYTE(MC_MAX_FS_PACKET),
    5 M, {3 v3 N2 ~1 H5 H7 I
  211.   0x00     /*Polling interval in milliseconds*/
    9 Z! i& k+ B. o+ ~2 ]( h8 n
  212. };+ x+ e6 O7 b% p
  213.   9 B+ l; ]8 n; P* b9 K9 p1 s) Z
  214. uint8_t USBD_MC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] =
    + T9 o5 E* o  |9 f. D: a  B2 Y$ S
  215. {$ x+ C$ S/ B2 D
  216.   USB_LEN_DEV_QUALIFIER_DESC,
    : O2 B/ u- s3 |
  217.   USB_DESC_TYPE_DEVICE_QUALIFIER,
    7 n$ v6 Z1 w3 B% V* d
  218.   0x00,
    4 i$ i4 G0 Y7 l9 P* U7 u
  219.   0x02,
    6 v# H& b1 C  u, ^8 z; v* B6 d
  220.   0x00,
    / {1 y; V8 b8 M/ r% ]1 \
  221.   0x00,! E% Y/ z. C2 C( P2 T0 @( K
  222.   0x00,& K7 W! n8 s+ e
  223.   MC_MAX_FS_PACKET,! C3 g- O  F6 [3 H# \
  224.   0x01,
    8 }) r* |( z$ N& m% g
  225.   0x00,
    $ R$ O7 D& O2 S- ~* E
  226. };
    4 H) E% j. L1 F
  227.   ^) c9 ~. z  D% j6 t( r% F+ x& D
  228. /**
    7 j9 q! D( b1 S1 A
  229.   * @brief  USBD_MC_Init
    ; h4 x# v' |/ I3 W% k' i
  230.   *         Initialize  the mass storage configuration
    9 r2 [$ l1 R$ L4 J  V0 _% ?" C
  231.   * @param  pdev: device instance8 V& h+ q8 T1 b5 o4 t- @6 e1 A
  232.   * @param  cfgidx: configuration index4 x; l* s, p0 e+ o% p/ d
  233.   * @retval status
    7 s, g9 a5 u9 o1 y9 c+ k$ H
  234.   */9 }  r" d- w. |" S
  235. uint8_t  USBD_MC_Init (USBD_HandleTypeDef *pdev, uint8_t cfgidx)2 D; [0 B* v: N+ p: T) o
  236. {
    8 J! I( _3 G1 o5 `. i
  237.   uint8_t ret = 0U;* ~# K# Y; I1 P8 o# J/ {7 i7 O

  238. ! \/ o% }% B1 Z( m9 e0 Y9 Q
  239.   
    ) X1 R/ W( [- n
  240.   USBD_CDC_HandleTypeDef      * hcdc;
    7 g" W) |! ~- T; ?' @
  241.     0 J7 h: o+ w" s. j, e  Q; W
  242.   MC_Switch_CDC(pdev);
    ' T( Z5 ]6 U$ f. T0 w
  243.   
    2 |! m6 w; G6 w9 L: @& f
  244.   USBD_LL_OpenEP(pdev,( }& N. J$ I* S7 I
  245.                  MC_CDC_IN_EP,) H8 B" s* A* J3 k8 E
  246.                  USBD_EP_TYPE_BULK,
    + ]3 y! Z, m/ P
  247.                  MC_MAX_FS_PACKET);
    ( g/ _' k9 q4 T. e  F' I
  248.   
    1 Y- t3 F5 v0 H) i0 d- T
  249.   USBD_LL_OpenEP(pdev,
    . f  b4 f7 j. b  @) |" i) T
  250.                  MC_CDC_OUT_EP," {6 k& S: h7 f: V. D! b
  251.                  USBD_EP_TYPE_BULK,
    # M) H8 e1 X' F! [! N, s
  252.                  MC_MAX_FS_PACKET);5 ~0 F3 G$ U; J7 _4 N
  253.   
    # r- j4 L8 b' F( ~  r% f
  254.   USBD_LL_OpenEP(pdev,5 }. J* ?3 c1 c5 s
  255.                  MC_CDC_CMD_EP,! o: q9 s! W6 ^. s; w
  256.                  USBD_EP_TYPE_INTR,
    : G! f) {# r- G$ Q
  257.                  CDC_CMD_PACKET_SIZE);* k! w4 l+ I: G
  258. ! G  M5 _" [+ f, q* U8 X0 J
  259.   hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
    0 L) U+ C3 w( L, x% A

  260. - x* z  P+ @& N  r9 ^" r' x9 k2 [  O
  261.   ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Init();( b' S+ d- |$ M) e" I1 V" @5 L
  262.   
    + H0 ~: z8 H" Z7 e+ p" ~
  263.   hcdc->TxState =0;
      @! z) t/ `) ]
  264.   hcdc->RxState =0;( G- \- @* l0 L
  265.   ; R1 Y# u4 Y6 z0 W
  266.   USBD_LL_PrepareReceive(pdev,. P3 W2 Y+ G$ b: j5 q4 i
  267.                          MC_CDC_OUT_EP,. Q! H% w  l5 j  \
  268.                          hcdc->RxBuffer,: z* f; B. g0 t3 j7 G
  269.                          MC_MAX_FS_PACKET);. S% s2 k+ s) Y4 Y1 @% E

  270. . g: t7 {6 w! m! ~
  271.   pCDCData = pdev->pClassData;: }$ t1 r2 @6 \3 N

  272. : H2 g9 y  c) K5 X6 K
  273.   MC_Switch_MSC(pdev);  T1 f8 U/ i5 z# F+ f/ N
  274.   ' \; y! f" q$ E% e, v! S
  275.   USBD_LL_OpenEP(pdev,
    # v- @. |- J2 L. P9 Q
  276.                  MC_MSC_EPOUT_ADDR,
    + P( D# d# o* p( V" y( D2 v4 T
  277.                  USBD_EP_TYPE_BULK,
    / p( k0 n, R, o5 m! q! \# R# ~: f
  278.                  MC_MAX_FS_PACKET);
    ; c6 G) M% v) I2 v3 U) K
  279.   3 ^6 b4 J1 ~5 w2 @+ W
  280.   USBD_LL_OpenEP(pdev,
    * E0 w  E7 O( I$ G( |1 ]6 \" L+ m
  281.                  MC_MSC_EPIN_ADDR,
    . m: q* a: h5 w+ s, T  N* G6 r
  282.                  USBD_EP_TYPE_BULK,
    & L, R$ i9 W9 g9 ?8 x
  283.                  MC_MAX_FS_PACKET);
    ' C- h/ a" ]$ V" c' ^2 S2 I
  284.   / \# K& ?1 ^. h- |- t
  285.   MSC_BOT_Init(pdev);
    4 S" Y; I+ q7 f; q* z/ z0 r
  286.   % s+ E- d, [& k3 ]. N
  287.   pMSCData = pdev->pClassData;8 T3 G+ K# N3 p7 _' [& V4 g* }
  288.   6 }: p' a: D; b* I
  289.   if(pdev->pClassData == NULL)
    / v8 t+ @! s# F
  290.   {: S4 M3 z2 r# a8 `. `5 l3 w% I
  291.     ret = USBD_FAIL;
    ( k- @5 K( n3 v1 c  t: h; z
  292.   }+ J2 s0 z" |/ ?! B

  293. . P( p. Q- [6 x6 t1 B3 ~, N
  294.   return ret;
    6 _9 X. h# r2 g+ H, A4 g
  295. }" X% d  Y4 Z5 ?

  296. & {4 [: q. n0 \# P! X9 _+ |
  297. /**
    8 u' q+ I( s+ r# X) L! v' |4 L
  298.   * @brief  USBD_MC_DeInit
    , c: L- @) P. {' O
  299.   *         DeInitilaize  the mass storage configuration
    1 l  d, Y5 j- e0 o5 @+ T
  300.   * @param  pdev: device instance; M% C0 h% R6 I2 v4 V
  301.   * @param  cfgidx: configuration index
    , C: e, ?5 e' h- ~; \4 t  K
  302.   * @retval status
    5 w3 U' [$ J9 K, n# m: H7 S; l
  303.   */) O4 ?  y3 F8 {0 Q
  304. uint8_t  USBD_MC_DeInit (USBD_HandleTypeDef *pdev,
    7 n! a6 H  y4 U4 a* K- ?; R0 q
  305.                               uint8_t cfgidx)* q( |# V  o- R) {9 ]7 ?
  306. {# Q2 N4 Y0 _/ K+ C) p8 g
  307.   return USBD_OK;' d# e; W* _+ R) Z6 _
  308. }1 f* y5 y3 Q1 ?- `) |  r' V
  309. /**
    / ^* U3 x$ S# J3 N/ j" ]$ W
  310. * @brief  USBD_MC_Setup# x& Y; j  W; P# }1 g5 [
  311. *         Handle the MC specific requests. }' m5 Z5 E) r" K4 u
  312. * @param  pdev: device instance
    " q3 @/ r* J6 L- s0 ~& ~
  313. * @param  req: USB request) P' `2 c5 j5 R+ o- G
  314. * @retval status* W, y- o7 c$ r6 }( k2 N. D2 y. i
  315. */
    1 x- Y' Z: j9 w" k" }1 s; _( U, a3 A
  316. uint8_t  USBD_MC_Setup (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
    4 m' b2 L+ v, e. A$ d6 m* k  t7 ^
  317. {
    * H* |* w6 Q  t) e8 h( g% Q" H9 ?5 l
  318.   if(req->wIndex == 0x0002)0 s; k1 J& X0 N* ^
  319.   {
    4 V1 r1 v2 I0 y- b1 i6 }
  320.     MC_Switch_MSC(pdev);
    , ?7 C* b# t0 }% Q# o9 h. Z1 T
  321.     USBD_MSC_BOT_HandleTypeDef     *hmsc = (USBD_MSC_BOT_HandleTypeDef*) pdev->pClassData;   
    - O5 [, L  W1 i1 ]
  322.    
    , v. }$ z) ^* [; _) X
  323.     switch (req->bmRequest & USB_REQ_TYPE_MASK)5 i) c/ M+ Z# o, K
  324.     {1 z9 d4 b0 x" ^7 l! T1 q& U( _) m
  325. % C3 w1 E" E0 [
  326.     /* Class request */8 I/ V- E! _! u, v0 q" I
  327.     case USB_REQ_TYPE_CLASS :
    % S2 b* N  i: f; B( ]" `7 T  v/ M
  328.       switch (req->bRequest)$ W! b2 [; A/ o; K- _) K
  329.       {( z; {) c. f; j! ^! o+ U7 ?$ h; S  F- I
  330.       case BOT_GET_MAX_LUN :
    , U) k) I- c8 m/ a; k/ p
  331. ( z9 ]: d6 q; e5 Z3 ^
  332.         if((req->wValue  == 0) &&
    5 G. H7 U" \. L$ r* |
  333.            (req->wLength == 1) &&' _" h3 H) I" B( o- V( F
  334.            ((req->bmRequest & 0x80) == 0x80))
    0 M4 |( n1 ~5 h0 y; O" x/ W
  335.         {
    ( _. H$ W& F. M8 K
  336.           hmsc->max_lun = ((USBD_StorageTypeDef *)pdev->pUserData)->GetMaxLun();
    1 y5 N! `# j: m0 a* H$ F+ b2 J
  337.           USBD_CtlSendData (pdev,
    ' a3 F  S5 U' k1 z8 z
  338.                             (uint8_t *)&hmsc->max_lun,% n  G' R0 s$ Z4 f6 s/ a; F$ Z
  339.                             1);) H5 _& [+ X$ [1 l, p- m  l
  340.         }& f; [3 [. ?& Z& M, t% r2 U$ t
  341.         else/ b5 Y8 R# g, z: O) E/ h
  342.         {
    # n, F! i- J! ]! u* F, x
  343.            USBD_CtlError(pdev , req);6 ^) S5 h( B( h3 r, i" b0 a$ Z
  344.            return USBD_FAIL; 6 n2 B0 p4 F) E  M% c! }
  345.         }  a% G( I0 |0 \1 r. W+ M
  346.         break;0 k+ `  k  C1 d8 a* M: {: r; I
  347.         
    - S$ y" ]5 h! H5 r4 ?
  348.       case BOT_RESET :, l& Z4 s. C) Z( w( Q: n
  349.         if((req->wValue  == 0) && % s% W% f/ v5 T2 A& @# c
  350.            (req->wLength == 0) &&9 f  R, I/ M$ D
  351.           ((req->bmRequest & 0x80) != 0x80))
    $ w1 Q/ p& d( g/ ]: g
  352.         {      7 G9 V  c' i& y" C- L, z% _+ E) v
  353.            MSC_BOT_Reset(pdev);  j6 Y) u" T: L1 x2 J
  354.         }3 M2 W7 i+ _  }% H' S
  355.         else; ?& {# h  z7 |* N7 l
  356.         {
    ) P2 F# T) U, B! S
  357.            USBD_CtlError(pdev , req);
    ; t7 a1 v2 q8 i1 O# p1 h( s
  358.            return USBD_FAIL; 8 K; q$ ~; e, P
  359.         }- x8 b  j1 S% c7 U4 T7 p
  360.         break;
    ( d/ e* a  s7 l( H

  361. + \9 z2 j5 H" L0 x: p) `! C& y
  362.       default:1 t; A7 Y7 ]! x, P
  363.          USBD_CtlError(pdev , req);  G% ~) W! t) z) S" }
  364.          return USBD_FAIL;
    % K0 O* z$ }1 {% K( M+ ~! {/ E% w
  365.       }/ P2 t% C0 G; x* ~4 q6 k7 G8 m
  366.       break;
    5 H7 M$ N& B' y
  367.     /* Interface & Endpoint request */
    6 Z* U( z6 Q# K8 R( b! M- Z
  368.     case USB_REQ_TYPE_STANDARD:
    ! q( Q' |  A( I
  369.       switch (req->bRequest)
    * _1 _$ C0 `; W$ D: i
  370.       {
    ! O% J- P! |- `9 @: F; p' @
  371.       case USB_REQ_GET_INTERFACE :6 [7 a: U0 Q  e8 ~6 h$ k2 F
  372.         USBD_CtlSendData (pdev,
    . m1 L+ a$ ]' ~! h9 y- S
  373.                           (uint8_t *)&hmsc->interface,- _: x  S1 `* R! Z
  374.                           1);
    & O6 s4 W- J& x* T1 d! v
  375.         break;* x# _& Y/ D5 r" H5 T: v
  376.         5 j2 l0 U$ y4 I7 s& [! ^/ b0 T
  377.       case USB_REQ_SET_INTERFACE :
    8 n: a% m* j1 p7 @! F9 g! j
  378.         hmsc->interface = (uint8_t)(req->wValue);
    . E# c7 |7 O# t: U, a! E2 T; |! B  D
  379.         break;5 h' {( o3 d; |6 I7 [4 z" K$ \
  380.       5 {0 m) N! `. }$ T- B3 ^- m+ U
  381.       case USB_REQ_CLEAR_FEATURE:  4 \6 F; U) `' c0 _6 l
  382.         
    8 [2 k/ f" i' ^2 T/ V1 w
  383.         /* Flush the FIFO and Clear the stall status */    : c/ M, [: y+ e# W
  384.         USBD_LL_FlushEP(pdev, (uint8_t)req->wIndex);' P$ I) ]0 P0 S9 W! h# S9 C! A. `
  385.         # l& \' i1 u' [5 E$ f) N+ M
  386.         /* Reactivate the EP */      # u7 X9 A3 K" v5 q) e
  387.         USBD_LL_CloseEP (pdev , (uint8_t)req->wIndex);2 D. ]  }1 t3 q
  388.         if((((uint8_t)req->wIndex) & 0x80) == 0x80)
    6 D2 [6 }6 G2 T8 }
  389.         {
    ) q2 [. y% Y* ^  k# U& y+ b) E
  390.           if(pdev->dev_speed == USBD_SPEED_HIGH  )
    ( C0 _  ~& ]" @. X3 x
  391.           {
    0 d3 g$ g- A% ~
  392.             /* Open EP IN */" t0 }, S% d/ I0 A
  393.             USBD_LL_OpenEP(pdev,
    / Z  Z* T5 W2 k) c# L0 @6 C% {+ a. |
  394.                            MC_MSC_EPIN_ADDR,( M& m# I- t6 k& O( A  o6 [" q% C
  395.                            USBD_EP_TYPE_BULK,8 A. y! Y' A9 z/ E2 Z: K9 b
  396.                            MSC_MAX_HS_PACKET);  , t7 @, W) V. m5 w* d( E! K
  397.           }* p& D$ U* W4 C7 C8 E' [
  398.           else: O1 g0 L$ ~9 K: I& u' ^
  399.           {   
    2 _9 g- y) e0 {: l! r( R4 e
  400.             /* Open EP IN */
    # |2 H9 K* t2 n! q2 c: i
  401.             USBD_LL_OpenEP(pdev,
    & H9 s0 F* N; M" I: t/ Q( D# C
  402.                            MC_MSC_EPIN_ADDR,2 A2 y) R6 v* |, n0 E. Q1 e  o5 h
  403.                            USBD_EP_TYPE_BULK,9 b3 o% v% A7 }
  404.                            MSC_MAX_FS_PACKET);  
    2 Y& R5 b4 |6 S
  405.           }
    2 T4 t" {% W+ Q" x& y" `/ m( [& A
  406.         }
      u! W) t+ s# }' j5 z4 w' b5 ^
  407.         else
    & U3 M* ^  `9 P0 \4 e+ Q
  408.         {6 ^: R7 Z& c  ~- E1 Y1 z
  409.           if(pdev->dev_speed == USBD_SPEED_HIGH  ) 7 C* n' m0 a1 j: b: P
  410.           {. \' G9 A) a& T: J2 O" b8 \
  411.             /* Open EP IN */
      }1 Y4 c$ p# e# O$ C; p% W% |- ]
  412.             USBD_LL_OpenEP(pdev,
    5 v- o: R6 a; `5 Z! N  n5 a
  413.                            MC_MSC_EPOUT_ADDR,
    ; r: y# _4 M3 a% g+ v5 Q
  414.                            USBD_EP_TYPE_BULK,2 Z: [# z4 q. m1 p8 L: E
  415.                            MSC_MAX_HS_PACKET);  % |7 c; x! X5 c* W) o
  416.           }, e, C3 k5 i0 u" [5 _7 \1 g; W; b
  417.           else
    1 z+ B& s" u' z- a1 C6 r0 g
  418.           {   
    & Z4 J( U+ n% V" \9 F7 H8 }$ f
  419.             /* Open EP IN */
    0 S0 w5 g. h* ]( x- R+ n
  420.             USBD_LL_OpenEP(pdev,
    5 B& M7 |* s8 j1 H, w
  421.                            MC_MSC_EPOUT_ADDR,& u& m3 l" E. z& n& }
  422.                            USBD_EP_TYPE_BULK,( J2 E' n$ G) e
  423.                            MSC_MAX_FS_PACKET);  ; U# ]; N, W6 n. `* F
  424.           }
    % P, b/ S- }* H9 v; F
  425.         }0 T; W7 I  E. b' Y1 W  o
  426.         
    : S2 P* `* B8 {5 [- R
  427.         /* Handle BOT error */
    8 ?3 O5 v2 j& s+ {+ x# d
  428.         MSC_BOT_CplClrFeature(pdev, (uint8_t)req->wIndex);. i& @; |6 c5 I& @$ N3 @7 `5 i
  429.         break;
    - y3 X) V3 P8 d7 ?3 E/ q
  430.         
    # y$ W7 `" K, g& Y) I
  431.       }    j: {: u1 ]+ R3 {& _
  432.       break;
    9 Z+ P/ s( h1 m
  433.      
    * S! Z- A; o- l( `) E2 c
  434.     default:) j' P/ r8 S- I2 L
  435.       break;
    ) `( q2 y! c, g: x
  436.     }" v. B% n5 J6 V9 I
  437.   }# Q2 u! c$ p+ L2 {# Q! O3 P" z8 }8 o
  438.   else
    ' K2 Y$ Z0 {* P; l
  439.   {8 I  x# T' E2 w, S; l0 T  G
  440.     MC_Switch_CDC(pdev);
    6 H! i. l+ J. k8 O# T; `
  441.     static uint8_t ifalt = 0;1 u# G' h* E3 `
  442.     USBD_CDC_HandleTypeDef * hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData;   3 r2 c2 u1 B0 Q; `

  443. $ r8 L2 ~$ y( E) P) J- V1 O
  444.     switch (req->bmRequest & USB_REQ_TYPE_MASK)
    9 G: ^* X( S+ Y6 k' U& H5 e* s5 h
  445.     {7 k- }) W$ U: _$ n9 F( N
  446.     case USB_REQ_TYPE_CLASS :
    & {9 F6 F) T% }# N# ~
  447.       if (req->wLength)+ u8 E% x6 f- }5 o
  448.       {
    5 A0 C4 B3 x. ]% L
  449.         if (req->bmRequest & 0x80)
      A2 E+ S7 J3 ]/ c6 w# A3 {
  450.         {8 K6 C! T! d% [1 e$ q+ J
  451.           ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest,
    , p2 l* r: {7 y9 z0 E: P+ E: g* {
  452.                                                             (uint8_t *)hcdc->data,+ Y: r* A$ X2 Q: W. ~- \, t
  453.                                                             req->wLength);
    3 H. G7 [- a6 \4 F9 J9 `2 ^1 a
  454.             USBD_CtlSendData (pdev, / N: A$ h9 v4 f
  455.                               (uint8_t *)hcdc->data,
    4 n* B# d4 T# v8 f
  456.                               req->wLength);# P5 g% L  r5 t! L
  457.         }. \7 u* @" X) M- h* n
  458.         else8 T2 J; p$ ?- \2 V" S$ C
  459.         {
    0 U) ^# T' @& X5 w7 S
  460.           hcdc->CmdOpCode = req->bRequest;! N3 c! F) d) L" P& A0 E7 ~8 _
  461.           hcdc->CmdLength = req->wLength;: y( W3 `8 ~, o4 g3 x
  462.          
    5 g) t3 a( [" b
  463.           USBD_CtlPrepareRx (pdev, 7 _; {6 n3 F# i# T* p. a" J
  464.                              (uint8_t *)hcdc->data,
    & N2 n7 w( X5 i2 P. K1 S
  465.                              req->wLength);
    ( h" D5 m9 d+ o( ?% @! G8 C
  466.         }
      ?2 E$ s7 r  C) h: k6 ]
  467.         
    , P/ E2 W' R3 o  W7 X/ |
  468.       }# I* F8 }( i: g2 J- i
  469.       else- h! Y0 s4 l, F# O5 t% E
  470.       {- r$ S' g6 q$ K$ e# Y6 ~; [
  471.         ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest,1 W, |0 D% d7 I* O% n* H% k
  472.                                                           (uint8_t*)req,6 T" M$ d0 Z+ {$ n* G% W
  473.                                                           0);5 P- H) ?! D% B7 f" S( W
  474.       }( s0 S/ x* g2 |* X+ j
  475.       break;- m: G2 m' M& U4 p/ X5 n1 t# j
  476.     2 N. ^( S8 j/ b/ q8 j" R
  477.     case USB_REQ_TYPE_STANDARD:
    1 S  p3 @* L- G  D
  478.       switch (req->bRequest)
    ' E7 s, D& n% C1 d
  479.       {      . |% h0 }0 w& o$ k/ e' ~' Y+ s/ A
  480.       case USB_REQ_GET_INTERFACE :2 |8 A0 z, j3 B" o6 e" |3 Q
  481.         USBD_CtlSendData (pdev,
    ' q( X: |! h% A$ C* G+ l
  482.                           &ifalt,& l& g7 x2 b% _8 q# V1 S, M" R
  483.                           1);4 S" x3 k5 ]0 Q7 t  l# T1 }
  484.         break;* r5 h. C. B. e# a. j6 ^9 S2 P' t
  485.         4 P* `% n+ |5 ]2 b# `, u3 u
  486.       case USB_REQ_SET_INTERFACE :2 i; q. U4 L( k
  487.         break;: I0 x6 F% _0 _& G) t" R8 U
  488.       }
    $ l, M, s# o! J" Y' u; U) a
  489.     * e  C8 ?$ _0 S* I+ q4 l; r
  490.     default:   E5 P. j, F  j
  491.       break;! O1 c7 M) v  \/ V5 w
  492.     }  . j  C/ S0 \4 I% C! e
  493.   }
    8 d& f! u. d: w: N# f2 f
  494.   * N2 F: ~( ]4 c3 v  V4 S: G+ T
  495.   return USBD_OK;/ Y5 T6 @+ q5 o  r3 X" g# n" Y9 g
  496. }
    & a" u' g, N; w: b. q

  497. # F! i) Z% d; _5 }
  498. /**
    ! @  W* \$ s; A0 |* C: L' n" R
  499. * @brief  USBD_MC_DataIn
    # @& e# x) p4 y2 q
  500. *         handle data IN Stage' w# D& t4 i7 E) x' O
  501. * @param  pdev: device instance
    9 L5 e; P! U& _  A: N* H
  502. * @param  epnum: endpoint index/ [( F, }, L2 E7 S; k0 U
  503. * @retval status
    # x! {0 s3 Q. t9 b
  504. */0 o# d  q9 D. W8 B3 l
  505. uint8_t  USBD_MC_DataIn (USBD_HandleTypeDef *pdev,   j0 D7 D" U" d* m) p" a2 x: t
  506.                               uint8_t epnum), G2 D0 }" P6 I' ^4 n
  507. {( @* O, J7 c  z: j1 ^. p' C2 I
  508.   if(epnum == (MC_MSC_EPIN_ADDR & 0x7f))% e4 T" N, \6 e3 ~1 I
  509.   {
    4 C" L5 W3 s1 t2 v7 W7 \
  510.     MC_Switch_MSC(pdev);3 {4 `- w& w( O  I9 E
  511.     MSC_BOT_DataIn(pdev , epnum);$ H/ p; q, |' A0 a% B3 f
  512.   }: S# I/ y  B7 ^9 x$ P! l& g
  513.   else if(epnum == (MC_CDC_IN_EP & 0x7f))/ \8 n* G' U$ T$ k& n/ D2 Z
  514.   {
    4 T. l2 `1 E2 y, M: L% p9 K# [
  515.     USBD_CDC_HandleTypeDef   *hcdc;
    4 O  u- A6 I6 X, \5 ?1 V
  516.     * b6 V  F  B5 {9 S2 D0 ]- Q
  517.     MC_Switch_CDC(pdev);
    # C& x; w" k" g1 T' D
  518.     hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
    5 i$ m5 P+ g) A8 w
  519.     hcdc->TxState = 0;   
    5 m  F* g0 K& J" a! C
  520.   }
    " K$ x* u8 `# H8 N
  521.   
    ) _- |' u0 Q$ R$ Q/ d' L0 Y: O! w
  522.   return USBD_OK;
    1 u9 }( }: K7 [+ W- O& ?
  523. }& A- e  }2 b. Q* _/ E
  524. " k# `! d( w* \7 n* D9 x
  525. /**4 l# M4 p9 B# ?( W# i' @- ~) I& O9 {: ~
  526. * @brief  USBD_MC_DataOut
    8 d: k5 ^/ A) B& ?( @
  527. *         handle data OUT Stage
    5 u, u1 T( z; T: p  v1 {
  528. * @param  pdev: device instance
    4 G+ |% K: i' O0 l2 l
  529. * @param  epnum: endpoint index
    , p1 f* D: u7 k2 s7 S9 u
  530. * @retval status
    7 Y8 l8 C- `7 U7 y# N# ?& T
  531. */
    ' Q; o+ C) r$ s8 d! I3 V! f
  532. uint8_t  USBD_MC_DataOut (USBD_HandleTypeDef *pdev,
      u! S0 }* g+ R- x
  533.                                uint8_t epnum)
    7 Y! E9 X) c: y2 i4 n' N- Q) p7 w# [
  534. {; B/ {" P: V* u
  535.   if(epnum == MC_MSC_EPOUT_ADDR)* ]/ E$ K0 R* N7 v
  536.   {& H9 b3 T( W+ @* _
  537.     MC_Switch_MSC(pdev);
    : F$ l# ~, V7 n: f5 x2 d
  538.     MSC_BOT_DataOut(pdev , epnum);; X6 k! C0 A  D9 P. _2 v
  539.   }1 i1 }$ K! I. u% Y1 z
  540.   else if(epnum == MC_CDC_OUT_EP)
    ' E7 D/ O7 `* W) [0 e5 }
  541.   {3 b4 M" D/ l' x$ B% b2 h6 e! \
  542.     USBD_CDC_HandleTypeDef   *hcdc;1 M' g; ^$ E3 y7 T1 s. |1 y
  543.     . Q  M+ P, S, V* Q
  544.     MC_Switch_CDC(pdev);
    0 I& f6 a' K3 S" L5 a
  545.     hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;/ t! H" c+ U# |2 n, S
  546.     + e" G- A( H& a. l* b+ q- P9 A
  547.     hcdc->RxLength = USBD_LL_GetRxDataSize (pdev, epnum);; u) ?/ {& R& o0 I' i
  548.     ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Receive(hcdc->RxBuffer, &hcdc->RxLength);
    - o2 d! c5 k3 F9 {3 E
  549.   }: g& \1 L3 ?. ?) N( O
  550.   & Q2 i3 S4 n. `. i; k
  551.   return USBD_OK;4 G% l  A* F. p1 f1 v. p
  552. }3 q) u8 R1 z. F& `! P. Z1 a; M

  553. . \9 b3 G0 f7 X! ?4 [1 O
  554. /**: r3 F3 I  K7 A' `( r  L
  555. * @brief  USBD_MC_GetHSCfgDesc
    ! {: m' I/ s+ Z# p
  556. *         return configuration descriptor
    % V* Y' v. o* |( Y( p
  557. * @param  length : pointer data length7 V0 z( Y# ^" v' B$ |2 l- B
  558. * @retval pointer to descriptor buffer( c4 N6 g3 n6 ]1 T. x  t
  559. */
    1 U/ {' d& K$ T% P) Y( v
  560. uint8_t  *USBD_MC_GetHSCfgDesc (uint16_t *length)
    , x8 W( t& t: `0 L) e" i0 ?
  561. {6 ~  j5 @, }$ b- t- ]
  562.   *length = sizeof (USBD_MC_CfgDesc);- @8 @/ W8 p, A/ b$ g% J0 [
  563.   return USBD_MC_CfgDesc;
    * |! i0 H8 Y0 X* e9 H  V& }
  564. }8 R+ T9 J) t. `0 g' N* x

  565. ( o! E* u; J* [  F
  566. /**" [% ]3 }9 j4 l* A$ W
  567. * @brief  USBD_MC_GetFSCfgDesc
    . q5 D* }& N  K) o2 v+ @* N; g
  568. *         return configuration descriptor% {/ |8 U1 w, |/ w: V
  569. * @param  length : pointer data length5 O" J% }( x3 @  i
  570. * @retval pointer to descriptor buffer
    # C* p% `2 I; L& ^. T
  571. */, \4 c4 f; o0 J# k1 Y: D7 ^4 X: A
  572. uint8_t  *USBD_MC_GetFSCfgDesc (uint16_t *length)& j# k* Q+ {' Y/ B5 ?
  573. {" C# U/ T' \, g- p; A
  574.   *length = sizeof (USBD_MC_CfgDesc);
    + {$ R2 f4 G$ r! m4 S
  575.   return USBD_MC_CfgDesc;
    : F+ F, _5 m- ]
  576. }* u8 X$ K! z) b
  577. 0 O- B& f4 }# q& Y3 P# B
  578. /**
    3 R9 f! I- h9 `' }
  579. * @brief  USBD_MC_GetOtherSpeedCfgDesc
    % @1 ^4 k7 i: Q' h* [- [0 k
  580. *         return other speed configuration descriptor
    ; A" [0 N# Y" u. B' J
  581. * @param  length : pointer data length6 B4 K9 x# R# s/ e5 r6 N1 e
  582. * @retval pointer to descriptor buffer
    $ o; Q3 z! \/ x! x4 I
  583. */
    , I7 g* X3 E! C+ h0 R( X
  584. uint8_t  *USBD_MC_GetOtherSpeedCfgDesc (uint16_t *length)7 \1 k# f- s; M5 B% X7 F
  585. {5 V# D5 [3 n7 H, w9 R$ w
  586.   *length = sizeof (USBD_MC_CfgDesc);
    1 Q3 b+ Y( E8 }9 w7 \1 \/ K
  587.   return USBD_MC_CfgDesc;0 ]4 V4 M4 ], j9 _8 n# w/ r9 Q
  588. }! Z' Y! ?/ F' H. J& i* d# ~
  589. /**6 O  n$ F* e, j0 A- M! ~) [, o2 m4 u: S
  590. * @brief  DeviceQualifierDescriptor . J6 E; F, p+ b/ j2 K
  591. *         return Device Qualifier descriptor
    / ^0 h2 m( C& f' R5 g
  592. * @param  length : pointer data length  Q$ ^3 m% x( W% P
  593. * @retval pointer to descriptor buffer
    $ Q) X. q# o3 h, i
  594. */. }* V3 d9 h$ s3 S
  595. uint8_t  *USBD_MC_GetDeviceQualifierDescriptor (uint16_t *length)9 A$ B) a2 r2 @6 h' v7 ?
  596. {
    / l" a( d& r4 d) D% D, k
  597.   *length = sizeof (USBD_MC_DeviceQualifierDesc);
    1 t; d5 t! y6 g( a
  598.   return USBD_MC_DeviceQualifierDesc;
    ' J7 L9 o' K2 d, J- H& t
  599. }( `5 Y3 i& I" ^2 J5 n! k, l) D6 g
  600. 2 P! [0 U% P- h( q' O0 x3 f9 _. C1 _  q
  601. /**2 L+ R8 a; x; D6 [, W; L8 z- m' T
  602. * @brief  USBD_MC_RegisterStorage, E7 _; h- s8 v4 F
  603. * @param  fops: storage callback2 w) ~3 v/ l" Y. E& ]
  604. * @retval status# k% w  n6 B3 H; Q! n: Q" k
  605. */9 e- S4 L/ V+ u) Y* Y( r
  606. 4 i4 O$ \+ _- {7 |& l# j
  607. static uint8_t  USBD_MC_RxReady (USBD_HandleTypeDef *pdev)( s0 |0 a9 b# x; n' k7 I( e' G
  608. {- o1 a/ ]; z' M! {: Q& Y, C7 ~* a4 E
  609.   USBD_CDC_HandleTypeDef   *hcdc;
    " U+ T( I% y: }/ W4 ]8 I
  610.   
    & g# Q! H4 ?7 d6 v$ W' l+ b- s
  611.   MC_Switch_CDC(pdev);
    ) E1 R& @- T: ]
  612.   hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;1 A  `1 k  U5 O. C. x7 i
  613.   
    , V, @) g# X4 T" m/ M: l
  614.   if((pdev->pUserData != NULL) && (hcdc->CmdOpCode != 0xFF))
    + y/ [3 }: u3 ~+ Y8 @
  615.   {& i. X* I" z0 g8 F, y
  616.     ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(hcdc->CmdOpCode,+ R3 l3 b+ R1 W% a1 n" s
  617.                                                       (uint8_t *)hcdc->data,9 U# k- ~+ {* H! {) P
  618.                                                       hcdc->CmdLength);1 ~1 t4 \! H% r' U' X
  619.       hcdc->CmdOpCode = 0xFF; ( y- n* f* z& A; r) U" i
  620.       
    7 K7 }* `/ y0 V) c2 D
  621.   }6 `* y* c( a. N: q9 R# X* ?! X
  622.   
    ( x1 p" t' p: P$ ~. |: w2 B
  623.   return USBD_OK;* D" x% ~$ l0 e0 w( {
  624. }
    3 ?# E2 B( m* G+ j
  625. # U' a" c5 F1 }$ Z- K2 u
  626. static void MC_Switch_MSC(USBD_HandleTypeDef *pdev)
    5 S( Q( @. @9 u6 s8 G4 H3 |; v7 ^1 i
  627. {9 G5 L/ x7 Q7 K' e& F9 R* _
  628.   static USBD_MSC_BOT_HandleTypeDef msc_handle;' l/ A4 O9 u3 s3 U6 T4 o
  629.   
    + U  ]& d% o, H6 N- h. }
  630.   USBD_MSC_RegisterStorage(pdev, &USBD_Storage_Interface_fops_FS);
    ; K3 |0 L1 }. F1 d$ o) h( y
  631.   pdev->pClassData = &msc_handle;# Y& \" f- V3 Q1 G
  632. }; L) R. P& z' Q# ?  }
  633. ; g/ I( i/ H: {2 u
  634. static void MC_Switch_CDC(USBD_HandleTypeDef *pdev); K4 K  j2 k* I9 q4 V
  635. {
    # \  x9 o6 w+ c2 o& r
  636.   static USBD_CDC_HandleTypeDef cdc_handle;
    4 y* `* p( d: ?6 }# c
  637.   
    # @- G2 m. d% W7 R% p
  638.   USBD_CDC_RegisterInterface(pdev, &USBD_Interface_fops_FS);) x* O3 s' d( @9 l
  639.   pdev->pClassData = &cdc_handle;) Z8 _$ y& h: x
  640. }
    3 E: D2 r, q" Y9 |$ y2 |5 l4 `

  641. ' D6 r4 b. {7 |$ s* E
  642. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
    * K" X# t7 N1 u
复制代码

; |" ^; u0 {) p通过以上修改后电脑电脑端显示USB复合设备MSC+CDC
% L3 i: m% m7 j( s2 M( g msc cdc.png
, Y3 c8 l* P/ P; Z/ |- u# z( \! m
13.在usbd_cdc_if.c  CDC_Receive_FS   /* USER CODE BEGIN 6 */ 增加发送测试" j0 {! k! f9 E9 q
; O0 H$ ~0 A1 M3 J( T
  1. static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)5 S5 C  T4 b8 a/ O! U$ r4 Y
  2. {0 y0 i" `$ z- p2 d: C. q
  3.   /* USER CODE BEGIN 6 */
    , F6 u2 P! n( u$ P% Z. F
  4.   USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);
    8 e# x9 t1 M: k) M' R
  5.   USBD_CDC_ReceivePacket(&hUsbDeviceFS);
    - V) o* B# Y& z0 o8 Y0 [* l
  6.   , H9 d( o" S' A" l
  7.   CDC_Transmit_FS(UserRxBufferFS, *Len);      //把接收的返回2 h' }) W# i9 l2 |0 J
  8.   
    - }! x; [( t) U; E
  9.   5 x0 K3 {& ^7 d
  10.   return (USBD_OK);
    . t+ m' O8 {# w' `0 k9 d
  11.   /* USER CODE END 6 */
    5 B5 c9 G8 x7 G- J7 Y4 W
  12. }
复制代码

$ `6 a. E* t+ @2 H0 x测试串口收发8 F# ~7 d0 g6 m
test.png ; j# ]) f0 _+ g5 F8 E

9 e; d: D0 _4 z7 P! ^8 c+ g3 _; q9 [
% k* Y' i; ^* h2 n

9 }$ i' Z0 G* a6 R! Z! U

评分

参与人数 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
非常好的资料,对初学者很有帮助;
+ _9 S4 w1 e4 P6 P) U0 r希望楼主多多分享,赠人玫瑰,手有余香,念念不忘,必有回响;
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
7 N/ P: o' W- T1 e0 U完全按照楼主做法,在win10环境下U盘和串口都可以实现功能,在win7环境下,串口错误识别为mass storage ...

# ?# i! P; u7 t( c% O/ _是不是驱动问题,我电脑Win10
电子ai好者 回答时间:2020-11-19 12:57:48
hds1988 发表于 2020-6-29 09:52( U5 O( ]3 X% V6 |- q
完全按照楼主做法,在win10环境下U盘和串口都可以实现功能,在win7环境下,串口错误识别为mass storage ...

5 p% d4 H4 |" e( ^' Y1 D% `4 @2 ? 微信图片编辑_20201119125724.jpg 我现在就是win7系统,和你一样的现象。请问你找到解决办法了吗?
2 p$ H5 K( n  G! |+ h. n: y- w. D$ b4 ~
js123456 回答时间:2021-8-10 15:34:43
用stm32cubemx生成的项目cdc,在文件usbd_conf.c中,USBD_static_malloc申请内存是以USBD_CDC_HandleTypeDef为准,函数如下:! c! M# S( }8 q" ]  q
void *USBD_static_malloc(uint32_t size)  ~8 T/ d0 w8 i  B4 ]% b  ]/ A2 N/ I
{
( A" U; q1 O) I9 |0 {8 A  static uint32_t mem[(sizeof(USBD_CDC_HandleTypeDef)/4)+1];/* On 32-bit boundary */
3 j+ Z/ V( _* t' f; g  return mem;
+ A7 P! x9 |1 |. Y}7 W& v- S9 `7 w8 h2 U1 T% C; A

8 n' e7 w1 i, t- Z7 R  Z那么在组合设备中,USBD_MSC_BOT_HandleTypeDef和USBD_CDC_HandleTypeDef都需要申请内存,怎么操作?
6 u0 Z' p' ]. w% C2 Y) H
# R( m6 _9 n7 u+ K
js123456 回答时间:2021-8-10 15:35:35
hds1988 发表于 2020-6-28 23:47
( z4 i! d: F) Q+ d完全按照楼主的说明操作一顿后,不能识别出CDC,但是能识别MSC。MCU是F407VE

/ L* a: ?1 l: o有可能是函数USBD_static_malloc的问题
3 X/ f% E% l8 k9 N

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版