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

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

[复制链接]
289466080 发布时间:2019-6-23 13:44
本帖最后由 289466080 于 2019-6-23 15:56 编辑
9 }) A; D/ v. p1 F: A' m7 q3 z# z
$ ?- ?( ^* P6 Y) t    最近做个USB复合设备CDC+MSC,在网上找了好多基本都是F103做的复合设备,带OTG芯片USB复合设备网上很少可能是我搜索的关键字不够理想有的不够全面,官方给了一个视频教程但是没有参考代码,社区里面有分享到github我按照后也不能实现,后结合F1与github分享的+官方视频,实现了在STM32F730R8T6上面USB复合设备,分享下怎样用cube生成的代码实现USB复合设备(带OTG的芯片).
- X& Q  V) o* }
" ~4 m  y9 A, p参考:
! B. H7 J: J0 O) Egithub分享
0 D/ ]2 ~2 e7 O2 Y& q1 B' shttp://github.com/uwyciw/CDC_MSC
9 p! S& `5 D7 C; Y9 i' C* Z官方视频" _0 s1 i  S1 I
https://www.stmcu.org.cn/video/index/detail/id-3988
0 i, ^- N' J6 W& a) T' RF1037 c+ V6 R$ \0 d; j8 Y: S
http://www.bbsmax.com/A/kjdwBXA5Np/
+ y; L. _( v1 V6 E# p$ X& N* P" j* u2 y8 i
5 G! F  C- X! L5 y
cube 5.2.1, P" @- x1 }& n( K8 }% z/ S; K8 u
hal  stm32cube_fw_f7_v1150.zip9 ~6 E+ K$ T, D0 h  i& i5 j" d

3 G3 E* n! D2 Q! EUSB为 USB_OTG_FS
0 }" [3 q% P  A- b- G5 M
& j( _: G" g2 t3 i1.先生成一个CDC工程下面配置图。1 J5 F7 {' N; w/ g) w* U
RCC如图箭头其他默认
4 `1 M$ k' \* } RCC.png
/ k7 C6 o* U# o$ fUSB_OTG_FS如图箭头其他默认1 N) S" ]: f# X5 \) G
USB_OTG_FS.png
1 u2 K6 q0 z9 ?, F9 |; u) Z" UUSB_Device
如图箭头其他默认3 P# o8 n7 T% C# |( h" l/ w3 m
USB_Device.png + S+ X+ I/ R( d6 Z$ i
Clock如图箭头其他默认我用的16M晶振比8M便宜$ d+ Q6 V/ ?7 c( W/ J6 d
Clock.PNG
9 G/ n! f0 z7 L' W
1 Y  y6 f$ D* c) O6 j: bProject如图箭头其他默认+ h' }8 c& A+ _6 o
Project.png ) a( z4 [( |$ P4 l5 J2 _' ^
code如图箭头其他默认: s4 G/ R( @5 M  T
code.png
2 V# C1 m+ n4 G6 q; O2.同样生成一个新的MSC工程不可覆盖原本的工程只需修改下图与工程名其他一样+ A0 z& v- s' q8 i( N2 m

# R' [' P1 S+ X USB_Device-MSC.png ! V% B" b9 y. f
6 T% A/ E: K! ^4 ?% W

, d/ s8 B7 {2 }& z5 z) |3.生成后把CDC工程下Src文件夹里的usbd_cdc_if.c与Inc下的usbd_cdc_if.h复制到MSC工程下Src与Inc文件夹里面,MSC工程下Src文件夹下新建usbd_composite.c与Inc下新建usbd_composite.h
7 n7 ?' ~5 i) ?; G+ |* \: P
# y+ l! y4 N, Y) g& T$ I h.png 3 B8 y6 ~3 ?+ g, |' W
9 F% N) i/ l) S9 A" P7 m
4.把CDC工程\Middlewares\ST\STM32_USB_Device_Library\Class目录下的CDC文件夹复制到MSC工程下见图* Z3 P+ P# ^+ _3 l
cdc.png
- g5 C. T2 t9 U- L2 e1 J5.添加CDC路径, \" b) ]4 j2 N7 D; q: ^
. n0 Q1 n, [1 t# M
CDC-PATHS.png 4 [/ N1 A% `, {1 l8 p% r0 H# J
7 C2 r! ~* k4 u1 ~# T* I2 |
6.在工程中添加usbd_cdc.c usbd_cdc_if.c usbd_composite.c见图& \) b7 g3 c  n6 G+ D) X- P
keil-add.png
( y# X  m  F5 y8 S
, H* a; h: X: _0 T7. usbd_conf.h 把USBD_MAX_NUM_INTERFACES值 1修改为3
/ {7 y  X* a# X9 ~. O
  1. /*---------- -----------*/
    4 F1 [# R5 J& B, w. y/ E0 M% Y
  2. #define USBD_MAX_NUM_INTERFACES     3U    //1U
    : ?& {- a4 \! o# I
  3. /*---------- -----------*/
复制代码
8. usbd_cdc.h 修改CDC_IN_EP CDC_OUT_EP CDC_CMD_EP) _4 c7 S3 i# r* x3 S: u) n
  1. //#define CDC_IN_EP                                   0x81U  /* EP1 for data IN */: x6 F. K0 ?  F; _% ^9 E
  2. //#define CDC_OUT_EP                                  0x01U  /* EP1 for data OUT */- u; Q1 U& x# u, I
  3. //#define CDC_CMD_EP                                  0x82U  /* EP2 for CDC commands */9 B, X3 K$ m& D! B" G0 r
  4. #define CDC_IN_EP                                   0x83  /* EP1 for data IN */
    , [% [  F( ]5 D- S: x- J% l$ _9 }
  5. #define CDC_OUT_EP                                  0x03  /* EP1 for data OUT */" }  x3 U& Y) F
  6. #define CDC_CMD_EP                                  0x82  /* EP2 for CDC commands */
复制代码
9. usbd_conf.c  USBD_LL_Init中新增: g9 r# o- ~) _9 x
  1.   HAL_PCDEx_SetRxFiFo(&hpcd_USB_OTG_FS, 0x80);
    + v( @' d5 x4 U* j
  2.   HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 0, 0x40);& ^; S$ [9 l% w' o1 F
  3.   HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 1, 0x80);  J- j& H3 ]+ b5 N2 r
  4.   
    1 G3 h# w8 @1 A) w0 O+ z1 N
  5.   HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 1, 0x40);   //新增- W: h( x: `& ?# {$ }- V  e; j
  6.   HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 3, 0x40);
复制代码
10. usb_device.c 修改MX_USB_DEVICE_Init与SER CODE BEGIN Includes中新增usbd_composite.h2 I- m7 D9 [: {* m# @; g

' @  J8 ?6 S" B0 s$ g6 [
  1. 5 x3 w( a* x/ M
  2. /* USER CODE BEGIN Includes */3 G9 |( W! f' U7 n
  3. #include "usbd_composite.h"
    8 s+ L8 C8 E& p7 ?4 @
  4. /* USER CODE END Includes */
    ; e5 P4 Y" _/ F

  5.   L  o7 |3 t: ]) T7 [3 F' ~
  6. void MX_USB_DEVICE_Init(void)* e% s: [" G. U/ J
  7. {6 _! t1 Q4 x" H
  8.   /* USER CODE BEGIN USB_DEVICE_Init_PreTreatment */
    7 A4 t9 T# z6 g# C( O6 t# C
  9.   
    - `4 B7 b% H5 I5 a2 d
  10.   /* USER CODE END USB_DEVICE_Init_PreTreatment */
    2 o% T/ z* A8 }+ p1 U4 f" ~
  11.   
    , o9 E( I1 \, _7 [
  12.   /* Init Device Library, add supported class and start the library. */
    * h+ S* D: o( w9 C4 y* |3 V7 U
  13.   if (USBD_Init(&hUsbDeviceFS, &FS_Desc, DEVICE_FS) != USBD_OK)3 W- F3 N6 P2 V) |5 i+ D5 ^
  14.   {
    7 W$ m3 m4 M- g4 v8 X
  15.     Error_Handler();
    * Q/ L# H8 j6 U9 B
  16.   }
    " ]9 y; a2 Q; f
  17.   if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_COMPOSITE) != USBD_OK)  //新增
    ) c% C7 \" H. @9 w9 z6 h
  18.   {+ ^9 _& B$ Y/ ~
  19.   Error_Handler();
      l7 j7 T' B4 H& }
  20.   }6 l4 ~- D2 t0 B  S1 K& E* P+ Y
  21. //  if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_MSC) != USBD_OK)
    - x0 W1 m: ]4 J+ B" ]* q
  22. //  {7 C4 f* h: f; S6 H& p
  23. //    Error_Handler();
    + {9 U/ W+ o( p* R1 k
  24. //  }: {* g! D! t' d- X! _+ H6 H
  25. //  if (USBD_MSC_RegisterStorage(&hUsbDeviceFS, &USBD_Storage_Interface_fops_FS) != USBD_OK)
    & n# M/ p' Z* r
  26. //  {+ t" J' N1 J1 s
  27. //    Error_Handler();
    - o; G# i# f- W, p( |/ a# W7 [
  28. //  }
    1 ?, r# |) V3 o) E0 d# p0 Y5 |
  29.   if (USBD_Start(&hUsbDeviceFS) != USBD_OK)
    " m7 l6 `/ ~2 ^2 F! C. N( d* |7 z
  30.   {
      H; Q( `3 ]/ B5 P, P
  31.     Error_Handler();* o* y  m# k8 y+ V" K8 h, K
  32.   }
    - b9 j. w2 \. B5 ~& t" |# Q

  33. , x, \5 D: g( I) M. F
  34.   /* USER CODE BEGIN USB_DEVICE_Init_PostTreatment */
    0 ?6 {/ C* ?6 K7 t- h( f" u8 d6 _
  35. //  if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_COMPOSITE) != USBD_OK)  //新增8 W, h. @" `& `
  36. //  {
    3 a$ Q5 V, B2 w* z: ^
  37. //  Error_Handler();: t0 t% \8 o7 Z6 v  m/ ]) X5 c9 a8 V
  38. //  }# L, }6 x" c# ?5 h% ]! i
  39.   /* USER CODE END USB_DEVICE_Init_PostTreatment */# w# p9 M, w  q+ Q2 X4 O0 y0 ~
  40. }
复制代码
8 B! s$ j3 [: Y' d7 o0 p- T& X

4 ~4 C, c9 |/ A- ~11.在usbd_composite.h中新增代码+ u: }8 C3 @% r! p  P! w' s
  1. ! z) q1 |) P% l. X7 }
  2. #ifndef __USBD_COMPOSITE_H
    ( a) j: L% l5 y, Y* x  S
  3. #define __USBD_COMPOSITE_H
    8 k# J0 i9 E- @' u4 h
  4. + y) C- W/ v( J2 E4 ?3 Q9 L1 P
  5. #include  "usbd_ioreq.h"
    0 m( X1 t) W; k+ H, d5 K( I% M
  6. #include "usbd_cdc.h"
    , @" P9 @+ `7 W; J; ?+ w
  7. #include "usbd_msc.h"! G" `# Q8 J/ ~9 d
  8. 1 I% T& A# N& [# P
  9. #define MC_MAX_FS_PACKET            0x40
    9 x, M  T! }3 S; e6 O8 f
  10. & u2 U+ V. I/ x$ _" t% D9 t) _
  11. #define USB_MC_CONFIG_DESC_SIZ      106
    8 P* A5 C1 ~5 _: J
  12. % F! \/ ^) z2 N6 P: p
  13. #define MC_MSC_EPIN_ADDR                MSC_EPIN_ADDR
    - Q9 j6 P$ {  W9 Y" ]# }
  14. #define MC_MSC_EPOUT_ADDR               MSC_EPOUT_ADDR - ~7 B" E5 `% {, }0 @. Z4 J9 l
  15. ' _; \# \- d1 V( v  m+ x. }
  16. #define MC_CDC_IN_EP                   CDC_IN_EP
    1 x& f4 X+ s: Q) ~- i+ v9 D+ }8 H
  17. #define MC_CDC_OUT_EP                  CDC_OUT_EP  * `  A) e; H, W1 p/ h1 A( S
  18. #define MC_CDC_CMD_EP                  CDC_CMD_EP
    , t0 g6 k, ~  _

  19. 0 c/ `" W1 D- T4 I
  20. extern USBD_ClassTypeDef  USBD_COMPOSITE;3 Q) G- Q& n1 M( F" ~- x
  21. / V& d; f$ ^# t1 }# T& u
  22. #endif  /* __USBD_MC_H */& `" L. z) z4 J( b4 K$ o/ f

  23. * [! t7 A" F) y% m4 J9 |
复制代码
: j+ s% `3 s/ T3 Z. V
4 |4 P0 }( E/ ?8 R0 u9 s
12.在usbd_composite.c中新增代码
% G8 L, |. s6 Y2 w7 S
+ z. b) R/ P% u

  1. + i9 J5 q% T! M7 u
  2. #include "usbd_composite.h"
    / U* A- I& D" h) K# B
  3. #include "usbd_def.h"6 O* v$ B! o; y
  4. #include "usbd_msc.h"* A' E. W% S$ V5 n  d- m
  5. #include "usbd_cdc.h"
    4 E) i+ [9 A) t. q7 f, W8 F
  6. #include "usbd_storage_if.h"
    # `6 Z; {+ {. h) `3 V3 _+ n& a4 e5 D
  7. #include "usbd_cdc_if.h"
    % i. u8 C9 g$ ^( }
  8. # x+ _2 r( h5 V: b* r( f
  9. /** @defgroup MC_CORE_Private_FunctionPrototypes, }$ ^. c1 [" g$ i" N* D
  10.   * @{+ J) ]0 @' _1 H" O3 D
  11.   */
    / w6 ~' v  u# P
  12.   ( J/ U# y0 ^) Z: w- }/ @  U" m
  13. USBD_CDC_HandleTypeDef     *pCDCData;0 k# P+ F0 K: G
  14. USBD_MSC_BOT_HandleTypeDef *pMSCData;) _( n) v8 t# u0 d4 Z% q
  15.   
    / z. |0 h" I+ Q
  16. uint8_t  USBD_MC_Init (USBD_HandleTypeDef *pdev, ' Y3 A1 H. T2 `4 b
  17.                             uint8_t cfgidx);+ `" Y/ u3 r  ~9 a: }8 w

  18. ) R  w: c9 ^. |* p/ l% i+ D0 h
  19. uint8_t  USBD_MC_DeInit (USBD_HandleTypeDef *pdev,
    ) S# i1 s* c% D/ F% V; g
  20.                               uint8_t cfgidx);
    2 c" ?+ D. k/ R% u: ]

  21. ! C% J/ b3 V. P
  22. uint8_t  USBD_MC_Setup (USBD_HandleTypeDef *pdev,
    ) e+ N; F5 N) \9 I. m
  23.                              USBD_SetupReqTypedef *req);
    8 ]- q: O% Z0 y. B
  24. : b+ u9 n7 ?4 V7 Q9 W
  25. uint8_t  USBD_MC_DataIn (USBD_HandleTypeDef *pdev, ( m4 G* S4 K4 V: }. w; K7 g2 K+ ^
  26.                               uint8_t epnum);3 @9 U7 ]+ ], k1 I* W1 x, }$ @" f
  27. - U* J9 d3 A: T- }8 f
  28. $ v4 g4 V5 b, v! B$ n
  29. uint8_t  USBD_MC_DataOut (USBD_HandleTypeDef *pdev, 5 Q- P% s3 @# `- w# c6 n) n% e* o
  30.                                uint8_t epnum);
    % h& x. V  W3 J4 `

  31. 7 h9 v. Q* T8 F4 P' P+ k; T# @/ v
  32. uint8_t  *USBD_MC_GetHSCfgDesc (uint16_t *length);- @7 s) a- P4 \5 f+ @7 G- r- C
  33. ( N2 f5 j4 S* F  ^9 ~
  34. uint8_t  *USBD_MC_GetFSCfgDesc (uint16_t *length);  p, Y5 k- |- u; @- g

  35. 6 S9 ^8 Q4 A" m) g" f
  36. uint8_t  *USBD_MC_GetOtherSpeedCfgDesc (uint16_t *length);1 _8 l* }8 x3 p) y+ e  H

  37. 4 l3 ^8 w# A, @$ T
  38. uint8_t  *USBD_MC_GetDeviceQualifierDescriptor (uint16_t *length);
    3 N% W$ P7 Q' R2 A. c
  39. 7 ]: J7 z1 S. Z' b% R. k0 s
  40. static uint8_t  USBD_MC_RxReady (USBD_HandleTypeDef *pdev);) Y9 p; [) |/ P7 o& S
  41. static void MC_Switch_MSC(USBD_HandleTypeDef *pdev);/ @2 ]. T. ~# a
  42. static void MC_Switch_CDC(USBD_HandleTypeDef *pdev);
    3 Z' L( T0 m6 ]* j
  43. , s- t" @' e# t% J7 ~/ ?
  44. /**; N" S4 i2 |4 s* j
  45.   * @}# G" N/ r2 _6 m- S; ?: B
  46.   */ 7 P- O( R; n% }9 Q1 U3 p- ~. L
  47. extern USBD_HandleTypeDef hUsbDeviceFS;' B/ I+ D7 w+ h) @2 b/ [2 ^4 Z
  48. : m" S$ G, p3 ~4 \% m9 E: f7 h

  49. * {4 B* {4 m% }+ t3 x' M8 Y
  50. /** @defgroup MC_CORE_Private_Variables
    * S2 E5 w$ F) a' c& U7 W& x+ O8 C
  51.   * @{9 b1 b) O* f; `" p& F
  52.   */
    : G5 u7 v2 b) N" E9 C/ N' Z! n
  53. USBD_ClassTypeDef  USBD_COMPOSITE = 7 ], l- r' e; K2 j/ ~: f
  54. {
    / L- \& a9 J) m0 b, w3 s# s
  55.   USBD_MC_Init,
    1 d5 N- E5 L7 t& E7 T4 D  ?
  56.   USBD_MC_DeInit,* w! d" S+ a7 G" k1 s5 y
  57.   USBD_MC_Setup,9 q# A8 m& g$ r  l
  58.   NULL, /*EP0_TxSent*/  
    . o, b4 d1 J0 i: J
  59.   USBD_MC_RxReady, /*EP0_RxReady*/
    ; B; p6 s$ u  @5 f
  60.   USBD_MC_DataIn,
    0 r% t, M) b& w: O9 ~$ K4 w
  61.   USBD_MC_DataOut,& F  n) \8 |0 d2 T( S4 t) M5 ^
  62.   NULL, /*SOF */
    - Q3 h, h1 F" p" d
  63.   NULL,  
    ! _! M) @% x/ i2 ], ]
  64.   NULL,     ; B" [- N. l: Y4 x3 ^/ b; K
  65.   USBD_MC_GetHSCfgDesc,. j; y4 F6 @7 C' J8 B' z
  66.   USBD_MC_GetFSCfgDesc,  3 b7 \) U& [$ p" }. {7 t1 e
  67.   USBD_MC_GetOtherSpeedCfgDesc,
    ' S) F) W, e/ d( b& |# }
  68.   USBD_MC_GetDeviceQualifierDescriptor,
    : }6 N. W6 x$ x1 \4 u, `" U
  69. };& H$ A. x; }# t# ]/ K/ e% M) @
  70. 2 }1 L6 s, W8 x& F, M! M
  71. /* USB Mass storage device Configuration Descriptor */
    1 g( Q0 {) F) u4 _0 v
  72. /*   All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */; a" B$ p( d) ]% ~2 B. z# }: s" P
  73. uint8_t USBD_MC_CfgDesc[USB_MC_CONFIG_DESC_SIZ] =
    7 w, b. d+ p$ W: y6 s" ]; Z9 @
  74. {& c% \4 Q# F- l3 h2 Y' {% W/ H
  75.   /*Configuration Descriptor*/4 a% h6 P2 F0 e' K: [: C
  76.   0x09,   /* bLength: Configuration Descriptor size */7 ^8 J. X# `! n* N; Q- a
  77.   USB_DESC_TYPE_CONFIGURATION,      /* bDescriptorType: Configuration */% H6 L) l% E( s7 I" l# C; t
  78.   USB_MC_CONFIG_DESC_SIZ,                /* wTotalLength:no of returned bytes */
    ! t. o% {; F2 x& J" I- F* n* O
  79.   0x00,9 l$ f- D& n' O6 R
  80.   0x03,   /* bNumInterfaces: 3 interface */' l  i& L0 ?/ |
  81.   0x01,   /* bConfigurationValue: Configuration value */
    4 R4 h4 \: B, Y5 H# [. H
  82.   0x00,   /* iConfiguration: Index of string descriptor describing the configuration */
    & e. n, i5 ]: n0 R7 A$ m
  83.   0xC0,   /* bmAttributes: self powered */0 X* C0 z  `4 K7 }, K$ a$ t
  84.   0x32,   /* MaxPower 0 mA */  j# L* y/ k9 P
  85.   6 x8 k+ S) R* `: n3 o
  86.   /*---------------------------------------------------------------------------*/1 k7 E% U1 {. x3 |; `1 _
  87.   // IAD
    & ?4 f6 X% O# n9 z6 w5 ?+ J: F
  88.   0x08,        //描述符大小! {) f4 S$ a$ q) j- R1 F1 P
  89.   0x0B,        //IAD描述符类型
    . A$ q  `0 X% o7 ~+ {
  90.   0x00,        // bFirstInterface
    # @6 P, Y# b: l6 p+ [
  91.   0x02,        // bInterfaceCount
    % Y& I9 x5 V7 E' T6 \" e. S( I6 I
  92.   0x02,        // bFunctionClass: CDC Class
    : t  N6 O6 S+ V8 `$ I$ Q5 `* W3 ^
  93.   0x02,        // bFunctionSubClass% W8 C4 W$ A# Y; R: o9 e7 Y1 X
  94.   0x01,        // bFunctionProtocol
    + g! }( F8 C+ C* C5 P4 g
  95.   0x00,        // iFunction      
    & N6 z, B3 l8 {
  96.   ' T+ `; F/ U- M5 ?5 q
  97.   /*---------------------------------------------------------------------------*/
    9 a1 g* _4 y) N
  98.   /*Interface Descriptor */& G7 b! X1 H& `* Q; O4 @. f. C
  99.   0x09,   /* bLength: Interface Descriptor size */$ r6 R  X% T* `% V) E
  100.   USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: Interface */
    ; X  ]# u8 j$ U0 m! o6 L! Y' [9 {
  101.   /* Interface descriptor type */5 {& |& J8 `& J( \
  102.   0x00,   /* bInterfaceNumber: Number of Interface */& o& Q' o' q5 D' q( p
  103.   0x00,   /* bAlternateSetting: Alternate setting */
    . ^/ v! c3 ]" R( S; m3 S
  104.   0x01,   /* bNumEndpoints: One endpoints used */
    $ O9 g6 Z5 D, X: Z" P6 H
  105.   0x02,   /* bInterfaceClass: Communication Interface Class */0 l( ?( q5 Q8 N4 [
  106.   0x02,   /* bInterfaceSubClass: Abstract Control Model */
    4 ?* @0 Z/ o! v, L8 U. n% q% ^
  107.   0x01,   /* bInterfaceProtocol: Common AT commands */
    8 w% a# t1 ]1 B' \! s
  108.   0x00,   /* iInterface: *// ?0 [: C, Q: u/ g
  109.   
    : w  Y$ S  Q3 Q+ n9 p, P
  110.   /*Header Functional Descriptor*/
    . L+ Z0 j# Z  D+ A8 J; j+ [
  111.   0x05,   /* bLength: Endpoint Descriptor size */# L$ J$ T- L% u7 x/ J& `' x, W
  112.   0x24,   /* bDescriptorType: CS_INTERFACE */. x% L# W0 W( Y' [+ I0 i. K
  113.   0x00,   /* bDescriptorSubtype: Header Func Desc */
    $ y0 Z$ |/ l8 a0 y) J
  114.   0x10,   /* bcdCDC: spec release number */
    ! U! ^9 B% Z- d9 ?( W6 j
  115.   0x01,$ U) f6 c3 @# B( O
  116.   
    2 a; Y5 D6 @; V! d5 n( ]
  117.   /*Call Management Functional Descriptor*/. {% y/ ~  |$ j( Y5 m
  118.   0x05,   /* bFunctionLength */
    0 ~  b* Y: ^7 B
  119.   0x24,   /* bDescriptorType: CS_INTERFACE */& y$ O' f  }2 O8 j3 k+ s0 O
  120.   0x01,   /* bDescriptorSubtype: Call Management Func Desc */
    0 r4 P! c3 X) E1 A
  121.   0x00,   /* bmCapabilities: D0+D1 */4 W+ F' u, J2 i  m
  122.   0x01,   /* bDataInterface: 1 */
    / ~' z) r' f# `  t& M( A6 o
  123.   - D, e, m: W! ?; l  j) ~
  124.   /*ACM Functional Descriptor*/
    3 T- D: ?, W, X  i# M# F
  125.   0x04,   /* bFunctionLength */8 r+ g, k0 |$ e5 y7 i
  126.   0x24,   /* bDescriptorType: CS_INTERFACE */
    2 b3 c1 l6 u* r5 p/ k7 }' X1 J
  127.   0x02,   /* bDescriptorSubtype: Abstract Control Management desc */
    4 m* n0 j4 u4 E4 W
  128.   0x02,   /* bmCapabilities */6 r7 L- {( g3 F' ]
  129.   
    . z3 @9 @3 W1 g# I; |+ N0 s
  130.   /*Union Functional Descriptor*/
    & I: }* a; o+ `1 b) c
  131.   0x05,   /* bFunctionLength */
    , B# c# x+ l: F) g: A) Z  H8 {
  132.   0x24,   /* bDescriptorType: CS_INTERFACE */
    6 {" q) a0 B: h6 J( ~
  133.   0x06,   /* bDescriptorSubtype: Union func desc */
    ( w7 Y5 P) A5 g; L
  134.   0x00,   /* bMasterInterface: Communication class interface */! p+ h# k) u6 t. T& i9 ^
  135.   0x01,   /* bSlaveInterface0: Data Class Interface */* Q5 ]* P# e7 X9 j/ E) C
  136.   $ x, y: {$ l9 F# g9 m9 H
  137.   /*Endpoint 2 Descriptor*/4 s2 ]3 A1 `% _* j- S0 Q+ A3 `
  138.   0x07,                           /* bLength: Endpoint Descriptor size */
    # _8 N# x/ Q  W. {5 S3 N$ B4 J! r
  139.   USB_DESC_TYPE_ENDPOINT,   /* bDescriptorType: Endpoint */7 Q* l4 n" c7 F
  140.   MC_CDC_CMD_EP,                     /* bEndpointAddress *// h3 Q- D& P) p( e& G
  141.   0x03,                           /* bmAttributes: Interrupt */1 m$ s6 A* ?- D4 D* Q9 |+ T; d
  142.   LOBYTE(CDC_CMD_PACKET_SIZE),     /* wMaxPacketSize: */
    0 H$ t2 a8 l  P
  143.   HIBYTE(CDC_CMD_PACKET_SIZE),
    9 @: @2 D0 |0 u9 C
  144.   0x10,                           /* bInterval: */ $ d) D, f% g. _1 V
  145.   
    : o/ C: @, u4 y
  146.   /*Data class interface descriptor*/
    ! w; n; ?) I. [" R0 q6 V8 ?
  147.   0x09,   /* bLength: Endpoint Descriptor size */% Z+ ~4 x: l- M+ \# p
  148.   USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: */
    & q8 U  s: d; m4 O" n1 e. T
  149.   0x01,   /* bInterfaceNumber: Number of Interface */. o4 |! `2 c! W1 |
  150.   0x00,   /* bAlternateSetting: Alternate setting */
    " \! \1 \- d# y1 {
  151.   0x02,   /* bNumEndpoints: Two endpoints used */
    " }' f, x) N: U
  152.   0x0A,   /* bInterfaceClass: CDC */6 E8 g! N# ^) a" p0 M
  153.   0x00,   /* bInterfaceSubClass: */  z- s1 E  u" b( B
  154.   0x00,   /* bInterfaceProtocol: */
    " n/ N& m8 g9 g  `$ Q2 s; a
  155.   0x00,   /* iInterface: */; J, ]: H  ?4 }8 q
  156.   7 y, A, f% F0 N
  157.   /*Endpoint OUT Descriptor*/0 |, s$ a3 w- n
  158.   0x07,   /* bLength: Endpoint Descriptor size */+ m; z% r" @. h: i
  159.   USB_DESC_TYPE_ENDPOINT,      /* bDescriptorType: Endpoint *// k/ V3 v# g/ r; a8 t
  160.   MC_CDC_OUT_EP,                        /* bEndpointAddress */
    5 a. A' q( a' a% K
  161.   0x02,                              /* bmAttributes: Bulk */
    ; o! H% w+ n! I+ Q; i; O
  162.   LOBYTE(MC_MAX_FS_PACKET),  /* wMaxPacketSize: */* c/ u! p; I' g" }+ ~
  163.   HIBYTE(MC_MAX_FS_PACKET),
    - D$ A% W  \7 i$ ~
  164.   0x00,                              /* bInterval: ignore for Bulk transfer */
    " b) E0 H9 o8 j" {
  165.   
    . N& n9 `1 p* H$ t3 G* {# h
  166.   /*Endpoint IN Descriptor*/
    * m0 a+ S8 [( N1 Q7 i
  167.   0x07,   /* bLength: Endpoint Descriptor size */* p' H  L0 C$ y
  168.   USB_DESC_TYPE_ENDPOINT,      /* bDescriptorType: Endpoint */7 Y0 [0 `) a) S+ `- S( g6 |9 x
  169.   MC_CDC_IN_EP,                         /* bEndpointAddress */" d, \0 ?0 p0 z  y1 n( M
  170.   0x02,                              /* bmAttributes: Bulk */% b3 x' Z( d- E% z: `/ L2 t8 |) b
  171.   LOBYTE(MC_MAX_FS_PACKET),  /* wMaxPacketSize: */+ ~9 |- m. c# D
  172.   HIBYTE(MC_MAX_FS_PACKET),  @$ J" o: |8 I( w1 L
  173.   0x00,                               /* bInterval: ignore for Bulk transfer */& K! E0 p2 Z. |) |! K- a

  174. * I$ S2 |, N8 c! l  n* q
  175.   /*---------------------------------------------------------------------------*/
    4 r. p6 q2 k4 ?# g4 k9 p
  176.   // IAD
    / r3 H/ q! P7 l# X7 F  p
  177.   0x08,        //描述符大小
    ' A5 c2 l3 _5 N2 h1 U3 Z, r4 _
  178.   0x0B,        //IAD描述符类型4 P# p7 T( L( G7 G
  179.   0x02,        // bFirstInterface1 S1 s  \# \! f; q7 h+ I3 j
  180.   0x01,        // bInterfaceCount
    ! z2 N& _- q0 r
  181.   0x08,        // bFunctionClass: MASS STORAGE Class1 G4 C, h( d/ S
  182.   0x06,        // bFunctionSubClass
    7 h( E' J# U! D$ g0 Y# b
  183.   0x50,        // bFunctionProtocol
    ; p9 y0 E3 K9 W
  184.   0x01,        // iFunction    & K' E& e. m" I1 ]5 v6 y

  185. 8 K* H! S- I4 `. l$ Y
  186.   /********************  Mass Storage interface ********************/5 L* v4 |5 r8 `3 Z) W
  187.   0x09,   /* bLength: Interface Descriptor size */
    1 q' i! d+ ^; v* ]" m* D
  188.   0x04,   /* bDescriptorType: */' z0 R4 C- P$ y) M1 ?* @& ~
  189.   0x02,   /* bInterfaceNumber: Number of Interface */
    - Y+ a( d4 Z# l9 k0 x
  190.   0x00,   /* bAlternateSetting: Alternate setting */
    % s4 U! l, S8 }( R0 O2 D$ X! ]
  191.   0x02,   /* bNumEndpoints*/
    * ]  f: I5 h. K* m% S% `% W" d
  192.   0x08,   /* bInterfaceClass: MSC Class */' E! p& `$ H6 P4 _0 z$ E  o
  193.   0x06,   /* bInterfaceSubClass : SCSI transparent*/
    ! }# B. v6 j8 [# H" ^" G
  194.   0x50,   /* nInterfaceProtocol */
    1 @0 Q* I% s* [# G) i& M
  195.   0x05,          /* iInterface: */1 k* O; F) ?0 P/ b. f5 }9 q3 z
  196.   /********************  Mass Storage Endpoints ********************// O' E  O- a: A* I
  197.   0x07,   /*Endpoint descriptor length = 7*/" k( n9 S* B  O$ _! k. V8 u$ H
  198.   0x05,   /*Endpoint descriptor type */
    ) a( B( }# q& o, U: t
  199.   MC_MSC_EPIN_ADDR,   /*Endpoint address (IN, address 1) */
    & a7 C' ^2 n' b& n
  200.   0x02,   /*Bulk endpoint type */
    ) [- o1 b9 h! ~: d( I8 o2 p- l; O
  201.   LOBYTE(MC_MAX_FS_PACKET),( d6 U' T! ^& Z( j. }
  202.   HIBYTE(MC_MAX_FS_PACKET),; b, q$ I9 n$ x4 e3 {
  203.   0x00,   /*Polling interval in milliseconds */: T. q  U) b4 Y
  204.   : c- S0 G. }) m( e
  205.   0x07,   /*Endpoint descriptor length = 7 */
    % i/ q, E5 c7 J" i3 V
  206.   0x05,   /*Endpoint descriptor type */
    0 E6 A) J0 N& a
  207.   MC_MSC_EPOUT_ADDR,   /*Endpoint address (OUT, address 1) */6 ~; o+ o. G/ ~( n; y' f& k- g9 `# H
  208.   0x02,   /*Bulk endpoint type */, D% a) e" ?8 E4 w' z, m
  209.   LOBYTE(MC_MAX_FS_PACKET),
    ; M; H" v7 c5 }  X
  210.   HIBYTE(MC_MAX_FS_PACKET),
    / `6 I5 v* X3 J; v8 E% _
  211.   0x00     /*Polling interval in milliseconds*/$ z: j9 T5 t7 Y" G" g  n
  212. };; r4 O+ n+ v4 W8 I/ A  }
  213.   
    5 P8 N; B! K' k$ l
  214. uint8_t USBD_MC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] =
    2 l1 J3 [1 R4 e. Z/ I) x
  215. {
    4 T5 h# x# ]/ h& j9 y3 @3 _
  216.   USB_LEN_DEV_QUALIFIER_DESC,
    $ q5 u' j* V3 |9 O1 E$ T
  217.   USB_DESC_TYPE_DEVICE_QUALIFIER,2 G/ y& }# W/ W2 n* S
  218.   0x00,/ h6 E( H$ V& L1 S2 h. {( t
  219.   0x02,/ V6 F) J1 E2 V3 C: u
  220.   0x00,5 q" g4 l6 x* l* T
  221.   0x00,
    / b) b8 _, ?! T4 M
  222.   0x00,
    & s! F6 u# A; |. j
  223.   MC_MAX_FS_PACKET,
    0 U% W. `, J+ ^
  224.   0x01,
    + V1 l7 V* k8 q9 L
  225.   0x00,8 J3 k" {6 o+ j; N1 u4 W* l
  226. };8 Q' K( c- ^+ D  s' f, \
  227. ! |3 o, N6 P% w  Y: y
  228. /**1 ]6 f% @4 M' ?- w! k
  229.   * @brief  USBD_MC_Init
    ; k1 I  h$ H' f, n& J
  230.   *         Initialize  the mass storage configuration
    ! b0 T* }- \2 G7 ~# S5 B
  231.   * @param  pdev: device instance
    / ^# Q. i6 c' P! }
  232.   * @param  cfgidx: configuration index
    & C1 B( U, F; l/ a: ?0 Q
  233.   * @retval status
    / B* D; F+ N$ o! o- Q
  234.   */' X8 p  W1 u; v1 c' c. N2 x
  235. uint8_t  USBD_MC_Init (USBD_HandleTypeDef *pdev, uint8_t cfgidx)1 H- s5 }# j8 m* Q$ Q5 z! s
  236. {
    - D2 N3 x4 w$ d. }% n  x& P$ p) D
  237.   uint8_t ret = 0U;
    ! i/ J3 r, h, F1 R. R+ z! B( y5 Q
  238. + Q- n3 f& B8 G7 w6 C6 z. W
  239.   9 i# d  P& ~! c! @9 @# M
  240.   USBD_CDC_HandleTypeDef      * hcdc;
    ' x& }1 E# H+ [; ^
  241.     3 x" S9 b6 Z, b5 I; G* F
  242.   MC_Switch_CDC(pdev);
    6 Q' v0 g! R* Q; @
  243.   
    4 s/ ]& C2 G: a. c2 c/ ]
  244.   USBD_LL_OpenEP(pdev,
    $ o# \4 e0 [8 |
  245.                  MC_CDC_IN_EP,
      [5 u* A4 G0 |9 ?/ ^
  246.                  USBD_EP_TYPE_BULK,$ T& A1 q/ A' {/ N7 P1 J0 O7 w5 b* [
  247.                  MC_MAX_FS_PACKET);5 o& K- ]. U1 L1 J- m
  248.   
    " z& d1 U5 Z+ b7 _! Q
  249.   USBD_LL_OpenEP(pdev,+ Z0 F5 W; k' \1 d; ?. @' c' s, D0 V
  250.                  MC_CDC_OUT_EP,
    $ l3 B3 J& M# v
  251.                  USBD_EP_TYPE_BULK,  I- q, y5 W* G4 R( T/ G
  252.                  MC_MAX_FS_PACKET);7 D2 W' x4 {/ g$ n5 B6 F
  253.   
    # Z  q5 A& `$ b- d7 m% r
  254.   USBD_LL_OpenEP(pdev,
    8 j! K) ^. s: @6 p: K$ z% Q
  255.                  MC_CDC_CMD_EP,6 b& `  F& A* s1 D
  256.                  USBD_EP_TYPE_INTR,
    + d5 X4 _0 |2 g3 o
  257.                  CDC_CMD_PACKET_SIZE);) d" A  M* b. m/ r) {9 v  {+ t* e

  258. / Y! S9 O, n6 y) w) ?5 x# b& g
  259.   hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;/ {8 z4 s8 b4 ?! h- h

  260. $ n% u  G7 Y1 w# c8 u
  261.   ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Init();6 n3 i7 g3 Z7 ]2 D
  262.   $ F9 v: W6 v7 T- D# m: \6 H0 h
  263.   hcdc->TxState =0;9 }# K# |. p$ E) V. e( m
  264.   hcdc->RxState =0;* }2 |, ]% V. x# F& y& G
  265.   - a' @. s0 a: B6 K
  266.   USBD_LL_PrepareReceive(pdev,3 O) V. c" ?8 Z5 w- Q
  267.                          MC_CDC_OUT_EP,0 I; O  K$ x8 t7 F7 o; o  ?" K# J" N; C$ N
  268.                          hcdc->RxBuffer,  G$ M3 C* M0 Y$ o
  269.                          MC_MAX_FS_PACKET);$ x! C: q9 |) M* B& P6 w  N

  270. 1 V9 D. V' w- h+ O0 E5 ]
  271.   pCDCData = pdev->pClassData;( \0 n* X- a( x& s
  272. . c0 S- l) ]$ x" B6 \7 x
  273.   MC_Switch_MSC(pdev);$ h- W) J. d: {: ^+ Y5 ~
  274.   
    2 \' {% a- R) Y- C) F
  275.   USBD_LL_OpenEP(pdev,$ J) o( D/ e6 [$ `
  276.                  MC_MSC_EPOUT_ADDR,
    & u! g/ ~; S2 U: Q( `+ z
  277.                  USBD_EP_TYPE_BULK,1 M( Z$ X% }* B: G
  278.                  MC_MAX_FS_PACKET);1 C9 r* i3 H: I. Q0 n4 M  ?
  279.   1 b* |/ ]2 K- Q" j
  280.   USBD_LL_OpenEP(pdev,
    - n9 |7 w8 |$ L
  281.                  MC_MSC_EPIN_ADDR,
    ' \; T0 H' f3 y  V
  282.                  USBD_EP_TYPE_BULK,
    ( K, I/ B# w: K% ]; a, ?
  283.                  MC_MAX_FS_PACKET);6 k+ u) m  W- p& s
  284.   9 F9 v  |1 D- f4 N3 ?  z1 c
  285.   MSC_BOT_Init(pdev);) r6 n/ T; S+ K! c: N( B% L
  286.   5 m! G5 n0 `5 O0 a! Q1 i/ X
  287.   pMSCData = pdev->pClassData;
    4 H# @4 G$ @( `7 t1 ~7 S
  288.   4 L  J9 E% i. F/ e' K! F" j
  289.   if(pdev->pClassData == NULL)5 @3 _3 z+ v  Z
  290.   {4 ]+ [$ Q3 \5 l  o$ Z( n# q
  291.     ret = USBD_FAIL;: G0 h2 R5 ~6 Q1 @
  292.   }
    * {  ]; l5 |5 Z" ^
  293. & U* K/ V0 ?# R1 ^; [9 _8 L$ z+ G& a
  294.   return ret;
    6 f: z* V; T* C
  295. }4 O2 a* d! @. B7 }! s4 R
  296. / U. t! H  n& @: @: A' x
  297. /**
    8 C/ W6 _9 J7 C; \( Q( a
  298.   * @brief  USBD_MC_DeInit
    & s/ v! E; U2 k2 \4 m3 [( h
  299.   *         DeInitilaize  the mass storage configuration. D9 s/ |, k) R. j; ?. {6 |  r
  300.   * @param  pdev: device instance. g0 I5 \) d  p8 C9 c
  301.   * @param  cfgidx: configuration index1 X9 I* M* {% N
  302.   * @retval status
    : E9 U! |$ N$ q+ v! K. _8 \
  303.   */
    8 @6 V7 b2 _, T/ ^7 I
  304. uint8_t  USBD_MC_DeInit (USBD_HandleTypeDef *pdev, + Q- i6 G2 u5 z- m. M
  305.                               uint8_t cfgidx)
    1 F' n/ d9 S) v  l/ Y2 D; I0 R
  306. {8 m0 ?' {: w! |/ J9 [7 l  a" B. _
  307.   return USBD_OK;$ T" b3 R) X4 ~# q1 u! X
  308. }
    5 }3 S4 I' E/ z$ i
  309. /**
    9 P$ W1 Q; V/ V3 o' N2 n4 j: F
  310. * @brief  USBD_MC_Setup
    0 Q' L8 b8 M' E; d7 p( g
  311. *         Handle the MC specific requests
    9 h( Y1 O5 m8 E6 C5 Q7 h/ f
  312. * @param  pdev: device instance
    8 S: }, `" Q7 Y7 h7 O1 i
  313. * @param  req: USB request
    ) _3 C9 f1 r# O% [
  314. * @retval status
    % r( `: o3 H" X. r* ~5 ]
  315. */% V8 x/ _1 W8 h0 b# {5 f' n
  316. uint8_t  USBD_MC_Setup (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); U0 f/ v; d; H5 a  ~
  317. {' l" k1 A) z  n& E; ~  u
  318.   if(req->wIndex == 0x0002)$ L1 T$ u+ f2 l& [
  319.   {
    7 _, u" D2 j, U+ T4 I1 _
  320.     MC_Switch_MSC(pdev);
    3 `. l, P* n3 t7 V
  321.     USBD_MSC_BOT_HandleTypeDef     *hmsc = (USBD_MSC_BOT_HandleTypeDef*) pdev->pClassData;   
    7 c4 u6 T- V- e5 A4 N, ~" i
  322.     9 X+ A5 @; K- H, U
  323.     switch (req->bmRequest & USB_REQ_TYPE_MASK)
    ) A3 R5 k2 \8 p, Y
  324.     {
    / ?0 W# B+ H/ G3 p/ Q
  325. * R! D( t- E6 H5 n% p2 U! r( [
  326.     /* Class request */
    4 ?% v. ]6 l1 Q9 }3 c) U( w
  327.     case USB_REQ_TYPE_CLASS :1 e0 F2 i* ?7 Q' o  J  f" z
  328.       switch (req->bRequest)
    $ o3 O5 b( \2 ~; b1 v
  329.       {
    7 U7 }* r8 f2 d! I6 ^; o
  330.       case BOT_GET_MAX_LUN :/ P0 m- U3 i( G
  331. + `- D5 x/ X# l9 s0 Q
  332.         if((req->wValue  == 0) &&
    ) Y9 ]$ F- I" x8 g" f+ R1 T: [' V
  333.            (req->wLength == 1) &&2 _9 [2 Y" x* O0 i9 y
  334.            ((req->bmRequest & 0x80) == 0x80))
    2 J5 F4 U2 i8 \9 {( i  J0 C" j; j; I
  335.         {( ^9 A( n6 y. O0 ?# G3 X
  336.           hmsc->max_lun = ((USBD_StorageTypeDef *)pdev->pUserData)->GetMaxLun();
    3 |0 Z! T% E& w  \* s! l
  337.           USBD_CtlSendData (pdev,
    & o- g  }% A9 `! {9 B
  338.                             (uint8_t *)&hmsc->max_lun,9 l4 L1 ~0 _" R# I% l7 g5 D
  339.                             1);. Z$ T( I' f. Q  U2 _
  340.         }
    2 O$ A0 k+ @5 f& F% p* m9 X. h
  341.         else
    ) e3 s* I- l: @' q' W. ~; I
  342.         {. }, A; y- K8 {9 J6 d3 M
  343.            USBD_CtlError(pdev , req);. x& C! e5 o; D) f
  344.            return USBD_FAIL; . y4 ^7 P1 ]2 R% u0 k/ l
  345.         }  s/ a* C# |+ o; [
  346.         break;: h, C( Q& v6 t
  347.         2 i" {2 s0 K+ @, _1 H# X
  348.       case BOT_RESET :2 v% _7 K7 D/ Z2 \8 }( z
  349.         if((req->wValue  == 0) &&
    5 I/ W+ q  t# d
  350.            (req->wLength == 0) &&
    7 _+ q5 o) ^6 L* r: o& h
  351.           ((req->bmRequest & 0x80) != 0x80))" s+ e7 V6 M: J5 U; @5 Y
  352.         {      
    ! q6 }' x: t, C8 C
  353.            MSC_BOT_Reset(pdev);4 @& a3 Q: F% q' ~: j! i/ b* @' f
  354.         }* ?, r- F- @2 [$ R
  355.         else
    / h% h, L, Z/ [
  356.         {
    2 T2 P& R  ~! z' K/ G! ?
  357.            USBD_CtlError(pdev , req);$ ]& `! Y" O0 g
  358.            return USBD_FAIL;
      }2 c0 F" ?" Q+ {0 B, y7 k! l
  359.         }
    # A+ o& @! F; T5 x: x4 e
  360.         break;
    % ]! ~5 V! q4 B- S

  361. & Q9 f7 m3 Y& _9 c: A7 R
  362.       default:
    ) V* @3 @: z' E+ j
  363.          USBD_CtlError(pdev , req);9 N, E1 v* V! H* W$ G% r) g% f8 k2 Q
  364.          return USBD_FAIL;
    - [: @( p$ U: I0 U4 g8 Q9 J& x2 }$ c, `
  365.       }. |( d3 k8 [1 T- l
  366.       break;6 K' A( [* b: t( [
  367.     /* Interface & Endpoint request */) ?& C" v3 I( H; `4 o/ H4 c8 q( A
  368.     case USB_REQ_TYPE_STANDARD:
    ; T; _! i/ _/ w" r4 r
  369.       switch (req->bRequest)
    5 z/ \+ z! g" e( {$ r. a. B
  370.       {/ q  y# w; P4 y& G
  371.       case USB_REQ_GET_INTERFACE :
    : O& a% B" Z9 R: n6 _8 Z
  372.         USBD_CtlSendData (pdev," e1 m2 F& N! v
  373.                           (uint8_t *)&hmsc->interface,
    % V, A, l+ {1 v7 i' a
  374.                           1);$ j* [6 G; Z2 d9 }
  375.         break;
    ' t. e+ x0 t! H* c2 h$ X$ g0 ^
  376.         
    6 m4 o6 W$ Y6 a- k
  377.       case USB_REQ_SET_INTERFACE :
    , n1 h5 Y+ S9 A% S& h
  378.         hmsc->interface = (uint8_t)(req->wValue);- i% R- t/ T$ W3 R
  379.         break;3 o, m5 S- h& j8 f' B% B5 Y6 D
  380.       9 P- L* N! A6 |
  381.       case USB_REQ_CLEAR_FEATURE:  5 M( z9 Z5 q4 p$ C
  382.         9 G! [1 [3 a. |/ Q7 X' x- [! s
  383.         /* Flush the FIFO and Clear the stall status */   
    9 r+ c- ?- I' F
  384.         USBD_LL_FlushEP(pdev, (uint8_t)req->wIndex);
    9 V2 c# m5 Y/ ^9 y7 l9 F% d* W/ ~' b2 ?
  385.         1 K4 m/ S5 g2 W- r- G5 a
  386.         /* Reactivate the EP */      
    $ _* c7 ~: W$ r6 s3 l/ A, I3 e
  387.         USBD_LL_CloseEP (pdev , (uint8_t)req->wIndex);$ }1 `- _2 i9 E! O) w
  388.         if((((uint8_t)req->wIndex) & 0x80) == 0x80), H6 r5 w: @" E* ~+ [0 b- b. D! ?
  389.         {
    9 F5 \" f$ L1 n1 E: U+ i9 Y
  390.           if(pdev->dev_speed == USBD_SPEED_HIGH  )
    7 e1 q) I+ [2 O- H. d
  391.           {
    6 ]' M- D1 c/ ^* z- v! D' W1 C
  392.             /* Open EP IN */
    / K/ J# J# ?, V' I8 H
  393.             USBD_LL_OpenEP(pdev,. N" Y* I/ t) p& A
  394.                            MC_MSC_EPIN_ADDR,. M7 X5 p; D- `9 B' y! ?; s# a! ~9 p
  395.                            USBD_EP_TYPE_BULK,
    + A9 Q  O( x+ ]9 O2 a& k
  396.                            MSC_MAX_HS_PACKET);  ; X5 G) T8 u# G" G, S
  397.           }
    1 [& N  t5 W/ c: ]5 m6 ]
  398.           else
    & x) q9 t/ {( A) d
  399.           {   
    3 d- Y" X% h9 d2 K* w2 y
  400.             /* Open EP IN */
    + A9 Q* a! \* w$ r) q. o
  401.             USBD_LL_OpenEP(pdev,
    8 R8 S2 J/ X. U5 v/ `6 K) {" S/ ]
  402.                            MC_MSC_EPIN_ADDR,
    ; m/ R" |+ @8 |/ M! a6 N
  403.                            USBD_EP_TYPE_BULK,
    - f0 J5 ?; L3 H0 M3 I
  404.                            MSC_MAX_FS_PACKET);  5 G/ U8 ^& T" q5 h  e
  405.           }) y! u" W" H* e$ O8 X  c
  406.         }- P' D3 M0 ^& |" T5 n9 C( q
  407.         else
    7 ^8 ?2 R. [" F3 F
  408.         {
    : U1 l" Q3 c+ i# N
  409.           if(pdev->dev_speed == USBD_SPEED_HIGH  )
    % k& Y, V$ S- ]$ L+ L4 `+ t9 `. S) r
  410.           {
    6 G, f3 g) z. i( m4 |$ G
  411.             /* Open EP IN */: W  V; [: `( Q4 q! A
  412.             USBD_LL_OpenEP(pdev,- e6 n$ k! h: P2 y$ M1 T& R
  413.                            MC_MSC_EPOUT_ADDR,
    - b5 _, D/ Q) |1 B/ s
  414.                            USBD_EP_TYPE_BULK,5 h$ V% s( Y" H( S* p4 ~% m9 I
  415.                            MSC_MAX_HS_PACKET);  2 @9 K+ D% ?5 r; z0 ]5 f; Q# t& J1 |
  416.           }
    6 ]0 W& {7 c) w, L+ f  i8 B
  417.           else
    * N* ~' K) X; q) b! U
  418.           {   8 P0 t4 z4 x! l0 l# L! ]9 m
  419.             /* Open EP IN */* k$ ?9 d- E/ \3 F3 Q! t: X
  420.             USBD_LL_OpenEP(pdev,
    : w' c9 Q, l" q2 \' |
  421.                            MC_MSC_EPOUT_ADDR,& N7 U9 K" |- L8 `% k" x5 v* p
  422.                            USBD_EP_TYPE_BULK,
    ' g- |1 h: b, o9 R$ J
  423.                            MSC_MAX_FS_PACKET);  
    " V1 t3 i2 e+ V* x
  424.           }
    ) x& [1 \( R# n2 S
  425.         }+ i3 k2 v* \' Z7 V
  426.         
    6 `% M; K+ C# \! a
  427.         /* Handle BOT error */
    6 C* R5 T, }4 o' N' i) o4 [
  428.         MSC_BOT_CplClrFeature(pdev, (uint8_t)req->wIndex);3 _1 j& L6 A% P1 W6 [
  429.         break;+ H! R. W* u6 o1 c+ ^
  430.         
    2 E# o% q6 F" ]! `3 b2 @
  431.       }  
    4 j" p. x8 t; C4 ~! g
  432.       break;
    , _9 t6 Q6 B# y& {8 Y
  433.      
    + K' ]) V/ n) B- G2 G  P$ j1 D: x  l  L
  434.     default:
    9 \  _# U3 t" K9 q) P
  435.       break;8 ~/ ~& I2 Q) _7 J/ m
  436.     }
    & c1 D+ k* R! o% J
  437.   }' A: G* @7 ]  f% E
  438.   else
    ! d$ ]+ Y9 z5 R! Y2 O3 m. S
  439.   {, L; \8 X1 b, D: j
  440.     MC_Switch_CDC(pdev);
    1 I! T/ ?" D% a/ r& D5 `7 r. Q
  441.     static uint8_t ifalt = 0;
    ( t6 v7 c3 `# v6 k6 X$ q0 M
  442.     USBD_CDC_HandleTypeDef * hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData;   
    + Z5 N4 c3 F9 \; \; P; U
  443. # c' P3 Y9 _( k" H3 S
  444.     switch (req->bmRequest & USB_REQ_TYPE_MASK)
    " r, c1 O. G3 m2 }
  445.     {& x" \3 Q5 N2 j' f# S- d
  446.     case USB_REQ_TYPE_CLASS :& @' d' ?3 D8 K6 k* s" x* @  M
  447.       if (req->wLength)  ~$ E3 h, F! m! k- J
  448.       {" N& }- |% d, s
  449.         if (req->bmRequest & 0x80)
    7 j$ u( n4 C- m7 b/ S% m1 p
  450.         {
    6 D4 J  L4 D% d. ^- `1 {* r. T8 Z
  451.           ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest,
    6 U! ?1 t8 W* q: W& V
  452.                                                             (uint8_t *)hcdc->data,
    + f& u  g" V- w6 E
  453.                                                             req->wLength);
    , c& L$ }  f7 E" A4 A
  454.             USBD_CtlSendData (pdev, 0 ]3 d7 W- i, E; V5 N
  455.                               (uint8_t *)hcdc->data,
    7 c$ k3 ?+ e/ i; X- Z1 ~
  456.                               req->wLength);
    + s7 `" O+ j3 X4 z* T5 H
  457.         }) p4 L3 e( R2 B2 M' ?' @4 c
  458.         else
    $ {4 S( c3 l- O1 Z: b9 [
  459.         {- P5 Y: s" _0 Z* W8 |0 R* T" o7 k
  460.           hcdc->CmdOpCode = req->bRequest;
    1 O5 O6 y1 l0 e, k5 S
  461.           hcdc->CmdLength = req->wLength;
    * Q; D5 @) v+ W& \* K: |
  462.          
    # ]; p+ X8 v+ R2 Q7 v( [" N8 G$ R/ M
  463.           USBD_CtlPrepareRx (pdev,
    5 n6 M- u* U) r
  464.                              (uint8_t *)hcdc->data,& e" _2 `" ?4 J$ I: \4 `
  465.                              req->wLength);
    % C. Y! c+ T! g) Q# m; s
  466.         }
    5 i6 o3 R# A+ a7 s1 w
  467.         ( b( {: {( h" x2 O* S5 B
  468.       }( y7 X. \  t5 Q
  469.       else. B3 g' X: ], d6 r1 ~7 d, c
  470.       {
    . l1 X8 D! p; m: N5 o% F
  471.         ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest,5 C  G* X1 }) f4 L( g
  472.                                                           (uint8_t*)req,
    ! Z3 y! u! R/ x, E3 D/ r
  473.                                                           0);
    6 C' x9 n5 v3 y  s/ T& ]" X! H
  474.       }
    5 T& J( x& N$ G* ^+ V4 M
  475.       break;# `$ V* S9 x# n* }" n) G6 ?& X) c6 W
  476.    
    6 X& Q$ M  x& e# Z9 i
  477.     case USB_REQ_TYPE_STANDARD:
    8 g! _% Q# m$ W4 N! U+ H
  478.       switch (req->bRequest)
    7 Y: j) K" h6 A" T2 }4 U$ f
  479.       {      1 `. m9 ?  h5 v; x1 w/ |8 u
  480.       case USB_REQ_GET_INTERFACE :
    0 R: T6 C- y" }$ n; D$ W% t
  481.         USBD_CtlSendData (pdev,1 \1 f" r  a! R; @0 R
  482.                           &ifalt,
    4 p, X: O$ g" ?* h7 n
  483.                           1);
    0 {1 J) L  _% g( t" ^
  484.         break;2 D1 a* M& W3 J  U9 d
  485.         3 `+ H" }) K* z
  486.       case USB_REQ_SET_INTERFACE :5 ?: O6 P; P' M( J
  487.         break;, I1 H. \" c! x6 ]
  488.       }  {+ x. i! @. I" i9 A2 I( ]
  489.    
    / [' y! r( s- a* N
  490.     default:
    . R% a% V1 Q( m  U" }: o
  491.       break;5 C+ X' N3 ~- m: W$ @8 q4 A
  492.     }  ' ?9 Z9 G5 J. b( w- |' u
  493.   }7 g; W, w& _3 A8 l( _6 u# p
  494.   4 }- w" W* i/ H7 M) J$ j
  495.   return USBD_OK;
    ; J/ K: O2 e) e- U' y
  496. }
    . @: O/ e6 P3 x6 b
  497. 3 d9 O: s$ ?6 x3 Z
  498. /**; p% f5 s2 R+ O8 H  y' \5 N2 x
  499. * @brief  USBD_MC_DataIn
    4 b1 m5 U2 t, Z" Q9 f0 o
  500. *         handle data IN Stage+ Z0 m/ }& H+ Z- d$ N4 a! k) E
  501. * @param  pdev: device instance9 h: }4 w  ]/ a' p& i" g  D- g+ s
  502. * @param  epnum: endpoint index- }4 u+ ^, i5 K
  503. * @retval status3 `1 j; z( Z3 G7 u0 ?7 Z
  504. */$ Y4 t9 j3 d: Y: g; Z& K+ p% y
  505. uint8_t  USBD_MC_DataIn (USBD_HandleTypeDef *pdev,
    . P& `* [1 x. ^6 Y
  506.                               uint8_t epnum)9 E7 K& |  e  B3 y1 v$ V
  507. {% M$ @/ T" f; H: S4 d
  508.   if(epnum == (MC_MSC_EPIN_ADDR & 0x7f))
    4 m" N9 I: r: g  Z7 M# L
  509.   {
    8 C9 H3 \/ m) }" w: M8 A
  510.     MC_Switch_MSC(pdev);
    / h5 t% A+ k) F& t+ x
  511.     MSC_BOT_DataIn(pdev , epnum);& D5 z- G) o" \6 _4 b9 t1 U
  512.   }
    0 |3 M! ?1 q7 M! k; l& G
  513.   else if(epnum == (MC_CDC_IN_EP & 0x7f))) u1 Y6 @( ], U4 Y
  514.   {
    2 x. F$ U# C+ u* g" S$ C2 ^( a# N
  515.     USBD_CDC_HandleTypeDef   *hcdc;8 a- @  Z0 g  D9 p; |
  516.     ! B1 c1 M" |7 g+ d; S2 l/ j. D( v# s
  517.     MC_Switch_CDC(pdev);# z- }6 O  x) Y5 t7 G
  518.     hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;8 }8 S) y4 h" l+ W, p0 `& w8 n
  519.     hcdc->TxState = 0;   
    8 I5 z3 F: U- k3 j9 Y8 V
  520.   }! k- M  u$ o7 \. ?! Z# P. ?/ U
  521.   
    : f1 c1 W& J0 f6 z" W
  522.   return USBD_OK;
    ' f, N6 o& a- E  U% m
  523. }
    " M2 z* _7 l# H' ~4 Y
  524. ) D7 ]9 U# p1 u5 ^3 [
  525. /**( y+ N9 {, [8 M( o9 g
  526. * @brief  USBD_MC_DataOut+ I7 c0 g6 W  n6 ?6 t
  527. *         handle data OUT Stage$ @: L5 R5 v& y/ |
  528. * @param  pdev: device instance
    7 J; N+ g3 f+ [* d9 I
  529. * @param  epnum: endpoint index' Z& N7 U( B1 D+ {# P+ p" f
  530. * @retval status
    . o. r* \7 b  J2 q& q4 ?& @
  531. */
    : l$ `. f+ X7 Q/ {" z2 V: S" c% ^6 L
  532. uint8_t  USBD_MC_DataOut (USBD_HandleTypeDef *pdev, * ?% Y; U1 Y0 ?# c
  533.                                uint8_t epnum)! b$ @; d0 `/ @8 S& B, y/ K; \" M) M
  534. {+ o; l  c1 a  D7 |5 V
  535.   if(epnum == MC_MSC_EPOUT_ADDR)
    # `) V" `. m. \( c, {6 @9 s
  536.   {
    4 O3 q4 b6 _$ |
  537.     MC_Switch_MSC(pdev);
    # ~: q2 x3 e- V& d  _$ \& L# j
  538.     MSC_BOT_DataOut(pdev , epnum);
    " @$ H1 s2 i9 R7 w; R6 y
  539.   }5 Z7 q6 B3 o. \
  540.   else if(epnum == MC_CDC_OUT_EP)
    - s+ z, f% l# ]' ]) M  s# y
  541.   {2 [5 d6 ^5 A; J6 o+ r/ N+ J" ^
  542.     USBD_CDC_HandleTypeDef   *hcdc;, \4 `2 A: U2 x5 c1 [' _( E
  543.    
    . n3 H% j6 M6 Q% g7 i0 P8 f7 _
  544.     MC_Switch_CDC(pdev);& V2 P; ?( l. E- @5 O) y
  545.     hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;7 f$ t  k  m" k
  546.     8 H8 V4 D2 S- E/ m
  547.     hcdc->RxLength = USBD_LL_GetRxDataSize (pdev, epnum);
    , y- y9 |, h1 }; A# R  x0 i
  548.     ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Receive(hcdc->RxBuffer, &hcdc->RxLength);
    * C! F. F/ i# X
  549.   }
    & U( B: z# V" Q& d' m6 Y5 J
  550.   4 t- Z' I+ T/ o$ I' U. r
  551.   return USBD_OK;
    3 C) F" k$ ?: @7 r
  552. }: l7 [) p% c: b) \6 \4 K# y

  553. 3 g! D% K* \- W3 O
  554. /**9 f3 E$ v1 ?& K' z" n
  555. * @brief  USBD_MC_GetHSCfgDesc ; S4 u* S+ x; z
  556. *         return configuration descriptor
    5 z+ j) J# Q% J7 [6 }( v
  557. * @param  length : pointer data length
    " C: H* Z9 A: M0 O! i
  558. * @retval pointer to descriptor buffer$ H' d& N8 b) d# P2 ^& U8 [/ e/ g
  559. */
    5 S7 V4 w1 x7 m: R% Q
  560. uint8_t  *USBD_MC_GetHSCfgDesc (uint16_t *length)
    , ?$ m) }, R3 Z* O3 C6 L8 t# U0 T
  561. {
    * g7 S9 I# ^8 ~' [( t9 p
  562.   *length = sizeof (USBD_MC_CfgDesc);
    " I7 A) h+ L5 t# q. Q, z
  563.   return USBD_MC_CfgDesc;
    6 W1 j& H5 I0 q* l4 ^
  564. }
    2 L# I  E2 g& G2 O. T
  565. + ^* w: v. @" x% ~
  566. /**' @; X  D+ W. d9 {: Z( R. ~, D+ K
  567. * @brief  USBD_MC_GetFSCfgDesc 2 h; z# E7 _' X/ j
  568. *         return configuration descriptor! ?- D3 D% {. d  P7 Z/ V0 ^  \
  569. * @param  length : pointer data length- u. p5 f2 y0 U* c, l# q& }
  570. * @retval pointer to descriptor buffer
    + ~+ j3 M6 Z9 L6 d6 |+ l/ B
  571. */% c1 [( E' F. d0 U$ R
  572. uint8_t  *USBD_MC_GetFSCfgDesc (uint16_t *length)
    , O. h" s, C: o* E, [
  573. {
    + k4 V* }- u3 m7 c, P% s
  574.   *length = sizeof (USBD_MC_CfgDesc);- L: {  \. j9 H
  575.   return USBD_MC_CfgDesc;- |, J1 l0 s! Z/ v8 G7 y
  576. }
    " D, c( i, N; Y) {" z5 T" b

  577. / R/ S: x1 Z! \* N/ W  U
  578. /**8 u! i( V- U) U. @4 L
  579. * @brief  USBD_MC_GetOtherSpeedCfgDesc
    $ m# m7 }: F( B0 Y' F
  580. *         return other speed configuration descriptor
    8 k1 H+ O3 _) @4 T9 o: q
  581. * @param  length : pointer data length
    $ h4 p; _* Y+ Z. Q) C# |
  582. * @retval pointer to descriptor buffer
    / e, ~  i- O& h
  583. */- g+ p; }9 ^% f) j6 b! q! t
  584. uint8_t  *USBD_MC_GetOtherSpeedCfgDesc (uint16_t *length)
    ( q$ h0 V2 v2 t$ G3 w
  585. {7 q1 c. ]  E) X% ~
  586.   *length = sizeof (USBD_MC_CfgDesc);; q5 {7 R0 M, g' F% s
  587.   return USBD_MC_CfgDesc;8 V, a+ V9 `0 e4 \+ C5 _
  588. }
    & {" \0 _" g% W, \
  589. /**
    ' D4 ~! ^* Y7 x
  590. * @brief  DeviceQualifierDescriptor ' y8 r  q7 G6 J) N. G8 x
  591. *         return Device Qualifier descriptor
    4 c1 g# B+ I7 |7 p3 r
  592. * @param  length : pointer data length
    + \6 J+ v) T( ^
  593. * @retval pointer to descriptor buffer8 v  z7 x: d  A, @9 k4 c
  594. */
    + D5 F% W" C0 b5 g
  595. uint8_t  *USBD_MC_GetDeviceQualifierDescriptor (uint16_t *length)
    7 q/ c; s5 _, k5 A; r5 b+ B8 A
  596. {$ J' r0 Y6 c* I7 q
  597.   *length = sizeof (USBD_MC_DeviceQualifierDesc);
    % H2 o" j" Y. H* Q
  598.   return USBD_MC_DeviceQualifierDesc;9 n. D: b5 r! [# ~4 N
  599. }
    ) E0 `) K2 t9 }  X+ h

  600. ; _6 }+ B0 A. @/ D. ]: Y
  601. /**5 N' Q* P2 s# K) Z' x- I
  602. * @brief  USBD_MC_RegisterStorage
    0 t6 a% d% U/ }% c4 h4 _
  603. * @param  fops: storage callback' }8 [* ]3 z$ z4 S0 R) B
  604. * @retval status2 r3 S$ e; O* s8 C) E
  605. */
    7 f. m9 ^' ?, m, s4 c( w. {
  606. / |0 t) v7 V2 f3 t1 z9 g
  607. static uint8_t  USBD_MC_RxReady (USBD_HandleTypeDef *pdev)
    ; k( l. A( [5 b! F/ y( \2 E
  608. {+ @. Z1 ]8 ~! o8 D
  609.   USBD_CDC_HandleTypeDef   *hcdc;
    3 T# ?5 H9 O. b0 ?2 z
  610.   ' \% R/ I2 F* G# T
  611.   MC_Switch_CDC(pdev);
    + i$ _7 O; ]+ h: e9 c
  612.   hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;& y& W% J, I% l) f7 t
  613.   $ q( {" v; Q# e( r0 d
  614.   if((pdev->pUserData != NULL) && (hcdc->CmdOpCode != 0xFF))
    3 J) S- v) ]" F8 t9 P2 }" I4 Y
  615.   {
      a* |& {7 G) ?
  616.     ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(hcdc->CmdOpCode,: t2 Q- S  t9 s+ M
  617.                                                       (uint8_t *)hcdc->data,
    5 i5 D" J2 K9 R4 U
  618.                                                       hcdc->CmdLength);. w6 \' J3 r- U' ~3 K
  619.       hcdc->CmdOpCode = 0xFF;
    ) f4 q' a8 G( @9 c
  620.       0 E9 T4 b+ I3 s( m
  621.   }
    0 ^6 G5 [, j% j" \7 a" A. e) R0 S
  622.   : U* P* m3 y0 c% b, J# p- E
  623.   return USBD_OK;2 {# H+ O8 H, ^2 a& {4 \
  624. }
    2 t# M) X# t, J0 I( l# B
  625. 4 I* |/ o# z/ ]- E
  626. static void MC_Switch_MSC(USBD_HandleTypeDef *pdev)( q( G) T' R1 {; \
  627. {
    - p* j! d& G. L: K
  628.   static USBD_MSC_BOT_HandleTypeDef msc_handle;
    0 i) n) [1 D4 K8 x7 e. m
  629.   
    ' ]1 t( `. F1 z, O! K; u' H/ k
  630.   USBD_MSC_RegisterStorage(pdev, &USBD_Storage_Interface_fops_FS);
    # ?3 r& {( ^5 O% E' y9 {$ f& @
  631.   pdev->pClassData = &msc_handle;
      K9 G) o6 C# ]3 E7 u" p8 d
  632. }8 v; f4 m' b: O: N% s) {
  633. 9 W5 @# i6 Z, k/ I; S+ i. v" A
  634. static void MC_Switch_CDC(USBD_HandleTypeDef *pdev), A) i( I7 s% S6 f% y% ?
  635. {/ ?' f3 M5 q& S  s$ q3 ]2 f
  636.   static USBD_CDC_HandleTypeDef cdc_handle;
    ' i6 S! g3 c/ H/ l( Z6 }
  637.   
    ( l' J9 G; T, b: F# X3 v
  638.   USBD_CDC_RegisterInterface(pdev, &USBD_Interface_fops_FS);$ {# j  [/ e% q9 [' {7 M( y
  639.   pdev->pClassData = &cdc_handle;  n8 t8 e4 X: G) w# r; j
  640. }7 p# U8 O# S% |( ^! F+ E+ N
  641. ! ~7 ?; e  Z( G* v# X4 v* u9 ~
  642. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/* l! K& X+ t0 n# J
复制代码
( P: e( P# r5 m0 \* G* @6 u7 |; m
通过以上修改后电脑电脑端显示USB复合设备MSC+CDC; L% u' J5 H% V9 |- U; r6 _
msc cdc.png
5 u  ^% Y$ ~- T8 `
4 j8 @, [) b$ X4 |0 W13.在usbd_cdc_if.c  CDC_Receive_FS   /* USER CODE BEGIN 6 */ 增加发送测试
7 y/ s# \- p1 f' E+ a# W% C: ~/ t+ M- K; S) j# v0 ?
  1. static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)
    : z& v) R+ W# [; G
  2. {: T, m2 \! t; \, ^" n
  3.   /* USER CODE BEGIN 6 */( \+ O1 L6 D' R+ A$ {# G" t
  4.   USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);! y5 {; @- i7 S# U- S0 z; \/ Q
  5.   USBD_CDC_ReceivePacket(&hUsbDeviceFS);
    % Q& }* A$ p* C$ _  T
  6.   1 V! U( B. [+ R' v' w) N% k
  7.   CDC_Transmit_FS(UserRxBufferFS, *Len);      //把接收的返回$ i0 u; S5 t" d% f$ w( h. [
  8.     y% q' {8 r5 T2 h3 c
  9.   
    ' d  X5 k* A7 _4 D; I
  10.   return (USBD_OK);* ^5 i" ^4 E" o0 r3 o
  11.   /* USER CODE END 6 */) s2 `, W8 S6 @1 j# G% U
  12. }
复制代码
* m9 D2 r0 N, p/ ~4 B+ G0 N
测试串口收发
+ h  X% a$ V3 |7 E test.png ( ?2 J5 `0 f0 `0 f$ s9 o
& Z9 R9 }/ E3 Z6 I5 `

! ^% Q% ?. H- E* `! q% d" W
1 c$ d; b3 t0 A% B0 j3 m1 p; {6 j8 X8 Z; ^1 Q. q

评分

参与人数 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
非常好的资料,对初学者很有帮助;
( p1 F2 e0 s2 W4 T) G+ Q8 X8 [希望楼主多多分享,赠人玫瑰,手有余香,念念不忘,必有回响;
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# }3 d. w6 s. W5 x8 W" d; y: F+ ]
完全按照楼主做法,在win10环境下U盘和串口都可以实现功能,在win7环境下,串口错误识别为mass storage ...

. \" b) m. V% u7 k是不是驱动问题,我电脑Win10
电子ai好者 回答时间:2020-11-19 12:57:48
hds1988 发表于 2020-6-29 09:52$ N% w) [9 |( D; S! W
完全按照楼主做法,在win10环境下U盘和串口都可以实现功能,在win7环境下,串口错误识别为mass storage ...
4 G4 X7 a5 y: m+ g( a% N$ t
微信图片编辑_20201119125724.jpg 我现在就是win7系统,和你一样的现象。请问你找到解决办法了吗?! V6 m# l; s" G% A. ^9 T, Q
js123456 回答时间:2021-8-10 15:34:43
用stm32cubemx生成的项目cdc,在文件usbd_conf.c中,USBD_static_malloc申请内存是以USBD_CDC_HandleTypeDef为准,函数如下:
& _% w/ n$ y% B3 pvoid *USBD_static_malloc(uint32_t size)) ^3 q7 q; J; L% K2 [, I$ B
{) K' @3 R0 r4 H# X4 @; A0 \  W
  static uint32_t mem[(sizeof(USBD_CDC_HandleTypeDef)/4)+1];/* On 32-bit boundary */
; s: B; c$ o8 f, `) j7 G: ]2 H. [  return mem;
( M% P2 A! P$ u0 Z8 B}  a, R2 K2 }* R, V; _  ?% Z
5 U" Y2 `. q9 D  G
那么在组合设备中,USBD_MSC_BOT_HandleTypeDef和USBD_CDC_HandleTypeDef都需要申请内存,怎么操作?7 |( s& Q+ `* @. P" }! D7 r% \! n0 D- d

6 G  z- e% V3 l
js123456 回答时间:2021-8-10 15:35:35
hds1988 发表于 2020-6-28 23:47
+ ~4 s& P3 w4 x& V9 u3 v" p" X# h完全按照楼主的说明操作一顿后,不能识别出CDC,但是能识别MSC。MCU是F407VE

( z3 {) f1 X' j( D7 @+ f有可能是函数USBD_static_malloc的问题' i; c0 a! [2 u2 }& H" d" }

所属标签

相似分享

官网相关资源

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