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

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

[复制链接]
289466080 发布时间:2019-6-23 13:44
本帖最后由 289466080 于 2019-6-23 15:56 编辑 " R% [( w4 O5 V0 a  U0 d

2 }$ |3 B9 W$ D    最近做个USB复合设备CDC+MSC,在网上找了好多基本都是F103做的复合设备,带OTG芯片USB复合设备网上很少可能是我搜索的关键字不够理想有的不够全面,官方给了一个视频教程但是没有参考代码,社区里面有分享到github我按照后也不能实现,后结合F1与github分享的+官方视频,实现了在STM32F730R8T6上面USB复合设备,分享下怎样用cube生成的代码实现USB复合设备(带OTG的芯片).
9 U6 @( B9 E- b3 P
6 s4 n1 N5 B1 e3 ]- ^$ h. g参考:
* V, P1 I: b# \1 e) h0 Agithub分享, M% S1 G: h" j# X: Q5 B
http://github.com/uwyciw/CDC_MSC
* }% A: ?- c5 _; E6 p$ D官方视频# V/ J! n& M8 D1 s9 t
https://www.stmcu.org.cn/video/index/detail/id-39888 Y, L+ P- O- y- o% L
F103( p' v0 X' w$ H9 `( W5 b$ v: N# W
http://www.bbsmax.com/A/kjdwBXA5Np/
$ U6 d* u" C. l2 k
, f# s4 q6 z/ ^1 `5 z  f2 _% a
/ b# Z) S8 U8 F" jcube 5.2.18 G4 s0 |$ m+ O9 @, z" W
hal  stm32cube_fw_f7_v1150.zip' l- r4 e( u. y6 v5 ?2 \
9 {. m( v+ Q4 z5 A: Z  q
USB为 USB_OTG_FS
0 J9 @5 Y; {5 e+ k+ o9 g
. w6 w' w8 h/ E0 ?0 J0 P) L! o$ F1.先生成一个CDC工程下面配置图。7 h3 W4 I: I3 ~; J
RCC如图箭头其他默认6 e  T' d9 d$ l* L) w3 b* W
RCC.png
5 H3 _3 p  q, K! V! O" D. VUSB_OTG_FS如图箭头其他默认
4 @) Y1 i1 ^* K USB_OTG_FS.png " a2 c6 q0 n$ T" u
USB_Device
如图箭头其他默认- q/ I' K; z8 d& f
USB_Device.png
% N( h5 ~' r8 m- ~8 SClock如图箭头其他默认我用的16M晶振比8M便宜
# D) O3 X+ O* ]% l8 ~ Clock.PNG
! f& I; s6 o% B# }
1 U( c9 D3 m5 U; tProject如图箭头其他默认
, ?" Z' o! B6 t8 u; }: N, U8 S. } Project.png
' M  X( f% V0 L. [5 ~: l( w1 ^" O' pcode如图箭头其他默认
$ j. y) @* j: u* |" j, H, F code.png   L8 h# Y3 u* L/ x4 r& T+ r5 m! M# L0 F
2.同样生成一个新的MSC工程不可覆盖原本的工程只需修改下图与工程名其他一样
5 c: h) S$ Q3 N' @, V
" J; {+ D- P% {6 ^( X, a6 a! }6 v/ d USB_Device-MSC.png
8 N- `* {. S; r; r: O
' Q8 J: _) O9 u% l9 S6 \( V" T6 V; z! Q$ r* {
3.生成后把CDC工程下Src文件夹里的usbd_cdc_if.c与Inc下的usbd_cdc_if.h复制到MSC工程下Src与Inc文件夹里面,MSC工程下Src文件夹下新建usbd_composite.c与Inc下新建usbd_composite.h$ n3 _# ^2 q. U; }0 {

* v2 D& m8 Y7 X: O6 [ h.png 5 H1 C/ n6 P! D3 [7 L  r* D) U
7 Z) e% q, L- V7 v
4.把CDC工程\Middlewares\ST\STM32_USB_Device_Library\Class目录下的CDC文件夹复制到MSC工程下见图. z5 `: m/ a7 G1 m- `
cdc.png
/ k+ ~0 u4 I4 \! m+ c5.添加CDC路径7 e! h$ }- s7 o' P3 @3 K5 a9 }

5 x5 r- |: P" l+ m- R CDC-PATHS.png 3 E$ J) w1 {% h; S5 ?0 v9 ?
8 I+ f! j% W' H
6.在工程中添加usbd_cdc.c usbd_cdc_if.c usbd_composite.c见图/ ]# V9 b/ S6 w0 r
keil-add.png
" M- j; A& G  Z7 H. G* q* N* o2 [& L: r* s: l$ S
7. usbd_conf.h 把USBD_MAX_NUM_INTERFACES值 1修改为3
! q, u5 m3 h# {  Z; a2 v
  1. /*---------- -----------*/5 @; w% @6 ]" h( c: S, o
  2. #define USBD_MAX_NUM_INTERFACES     3U    //1U
    + }: Y8 Q+ D6 ?7 W1 w) N! l
  3. /*---------- -----------*/
复制代码
8. usbd_cdc.h 修改CDC_IN_EP CDC_OUT_EP CDC_CMD_EP2 _; l6 }, j& z# v$ u& J
  1. //#define CDC_IN_EP                                   0x81U  /* EP1 for data IN */
    # f' W* F" y+ e1 Y$ `- f* D
  2. //#define CDC_OUT_EP                                  0x01U  /* EP1 for data OUT */( J) X5 i; U9 q" d; Q+ c
  3. //#define CDC_CMD_EP                                  0x82U  /* EP2 for CDC commands */3 F& u9 `) s7 N0 }& X
  4. #define CDC_IN_EP                                   0x83  /* EP1 for data IN */
    + n% ?, N' C1 l* s% l7 B1 e" T9 Y9 w
  5. #define CDC_OUT_EP                                  0x03  /* EP1 for data OUT */  U. Q: d  i# {
  6. #define CDC_CMD_EP                                  0x82  /* EP2 for CDC commands */
复制代码
9. usbd_conf.c  USBD_LL_Init中新增
0 s+ w) u/ R- ]5 C! U
  1.   HAL_PCDEx_SetRxFiFo(&hpcd_USB_OTG_FS, 0x80);2 N1 L; T8 C1 ~  [; V1 ]
  2.   HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 0, 0x40);5 m+ `$ [- _* P
  3.   HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 1, 0x80);) j/ O. ^" P1 t4 l$ E* m
  4.   / O1 P9 b- X! x5 D5 g- k  U5 W$ Y
  5.   HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 1, 0x40);   //新增
    ( T8 O3 G/ o9 V
  6.   HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 3, 0x40);
复制代码
10. usb_device.c 修改MX_USB_DEVICE_Init与SER CODE BEGIN Includes中新增usbd_composite.h8 L) w: n% t! j( d

% i' i# b0 S' T7 I
  1. , m. q, n  V( p& x( [
  2. /* USER CODE BEGIN Includes */1 k9 _8 n7 C1 O2 a
  3. #include "usbd_composite.h"# D. q( q- G' Q  c
  4. /* USER CODE END Includes */9 y& n. i  t# B. z  a

  5. & c) }$ F6 y0 F) r6 X" `" h
  6. void MX_USB_DEVICE_Init(void)
    . O- F: M3 |- l
  7. {9 y( ]( V8 w7 y' f
  8.   /* USER CODE BEGIN USB_DEVICE_Init_PreTreatment */
    6 a, o! Q) d  G, S9 _6 ~- M
  9.   
    0 z7 U9 L4 L: r1 m' Y% r- z2 G
  10.   /* USER CODE END USB_DEVICE_Init_PreTreatment */  I4 n7 O6 [/ I, A' O0 Z$ n
  11.   ; Y- C+ v; p% J' k; r1 e5 D
  12.   /* Init Device Library, add supported class and start the library. */
    ( G: L" l. }  E& P6 g: a
  13.   if (USBD_Init(&hUsbDeviceFS, &FS_Desc, DEVICE_FS) != USBD_OK)# q6 I. B$ H, f* P# d
  14.   {
    8 F- W3 h  [& p8 X) q# i
  15.     Error_Handler();
    ' {: c2 v. }3 G+ ?4 u; Y( w2 ^
  16.   }. O( f( v6 J2 l
  17.   if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_COMPOSITE) != USBD_OK)  //新增7 e/ R+ e) z1 c4 S8 b3 \
  18.   {
    8 W6 k) Z$ K; J, Z8 M) [& [/ c
  19.   Error_Handler();
    3 U6 i, l4 G) w
  20.   }
    1 l2 C: M6 W7 X9 o
  21. //  if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_MSC) != USBD_OK)
    : p7 {; V7 o+ Y) P, s
  22. //  {
    ! P# T9 a+ z4 k1 o2 \
  23. //    Error_Handler();# Y3 ~9 L, @$ @/ u2 U, ]
  24. //  }/ Q+ v* u3 W2 x8 o. U9 K9 r% r
  25. //  if (USBD_MSC_RegisterStorage(&hUsbDeviceFS, &USBD_Storage_Interface_fops_FS) != USBD_OK); n+ m) r2 X! q
  26. //  {5 M* K, I1 |' |9 C- G
  27. //    Error_Handler();0 I+ E2 A. t( K3 o! @% a
  28. //  }: }: g3 Z; V+ x  F) Q" k) |. E
  29.   if (USBD_Start(&hUsbDeviceFS) != USBD_OK)
    2 K5 t+ ~2 Q; F& `' m1 c) P
  30.   {3 d; a1 I9 R2 Y! a6 W  ^. C
  31.     Error_Handler();
    6 q3 }- ^1 e! l  S! W% b
  32.   }
    9 Y" }* a- x  O+ Y- d% [; d

  33. - }) R1 V- J7 J( P4 M
  34.   /* USER CODE BEGIN USB_DEVICE_Init_PostTreatment */
    9 ~/ c& c" n6 C2 k9 `' G/ B0 z& |
  35. //  if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_COMPOSITE) != USBD_OK)  //新增  @( q* D3 e: ^* M, L: ^
  36. //  {
    ( j$ b" r$ X+ d) y1 ]
  37. //  Error_Handler();& j2 ^" a* A. X3 p% d. o4 |
  38. //  }
    % v, V0 z# E) ?) ^: `9 r/ e
  39.   /* USER CODE END USB_DEVICE_Init_PostTreatment */, w* Q4 s' g! E
  40. }
复制代码

7 Y; f! O2 X: h; q+ m& V5 V* G
+ N0 r# A" T6 k; `) W
11.在usbd_composite.h中新增代码
! Q; D5 ]" d! c% L4 @% z
  1. ( g; J+ J3 k, E* A$ K. {
  2. #ifndef __USBD_COMPOSITE_H* h+ |  N8 @4 `6 J. o( r
  3. #define __USBD_COMPOSITE_H
    3 t' M; E4 L; N1 C% u  v

  4. 7 @/ b! x( Z9 A8 B! D) j. l3 E+ L
  5. #include  "usbd_ioreq.h", N) c* Z5 g5 g$ u" z$ L
  6. #include "usbd_cdc.h"
    ; w. [; V4 [- h
  7. #include "usbd_msc.h"
    9 R4 V/ {9 G; Y" g8 u
  8. 6 S; \1 s( S5 F9 j/ a
  9. #define MC_MAX_FS_PACKET            0x40
    ! w3 u! s$ [* V+ v' r5 s

  10. 9 x8 I  j. m% ^: P( V; m8 l7 x. n
  11. #define USB_MC_CONFIG_DESC_SIZ      106 5 e# \0 n) h- i3 e
  12. 9 a" b7 C" U. f& c  U
  13. #define MC_MSC_EPIN_ADDR                MSC_EPIN_ADDR
    ( t: I6 \5 W; t0 h
  14. #define MC_MSC_EPOUT_ADDR               MSC_EPOUT_ADDR
    ) @$ V& Z4 w* Z6 T6 e

  15. 2 N. m+ ~6 S* T# h; g' D0 e7 C
  16. #define MC_CDC_IN_EP                   CDC_IN_EP
    $ t- y6 ?# p8 v  r+ \* x/ L
  17. #define MC_CDC_OUT_EP                  CDC_OUT_EP  4 T& a& w- M0 y  H; w$ {
  18. #define MC_CDC_CMD_EP                  CDC_CMD_EP
    ! j/ c  ^) c3 l! ^; S

  19. 5 ]5 `, l  F$ Z; C
  20. extern USBD_ClassTypeDef  USBD_COMPOSITE;5 [, _/ e5 R2 _

  21. # O  ]% m) P! Q- n/ ~1 e& n/ C2 B
  22. #endif  /* __USBD_MC_H */
    ( a0 @! ]/ W$ u. b/ A/ u3 h: y
  23. 5 |+ _6 W8 l" v: {' n/ x& A- L  p
复制代码

& n1 ~( V& o' H- b" S3 E/ j/ X( v. g8 u+ L  X9 X2 M
12.在usbd_composite.c中新增代码
& T; B" i! I5 A) p9 |' ]. \# t- k- `4 c* _7 z! a+ J; O

  1. 2 K5 i/ e" [( ?; j6 c
  2. #include "usbd_composite.h"  H4 B+ m( z& w  l
  3. #include "usbd_def.h"
      Z5 Z: @6 C( u* r# s- V- l3 S+ j
  4. #include "usbd_msc.h"0 F0 D' C7 k8 E) l% R  b& l; E
  5. #include "usbd_cdc.h"  [7 P3 a8 G8 h; B! \8 g: y
  6. #include "usbd_storage_if.h"! B0 l; O" s/ J" Y; }
  7. #include "usbd_cdc_if.h"4 k- H$ l2 ~# J; T8 ?* f" K1 }
  8. 2 @1 G8 E( v4 c+ @; d0 z  n( v7 @; n$ v
  9. /** @defgroup MC_CORE_Private_FunctionPrototypes
    5 U" d4 [* C0 @5 t' X4 {+ U; t3 u
  10.   * @{
    % F  P9 }9 g. J7 Z) O
  11.   *// F- B% H% z; |$ E
  12.   , H' I: M, e9 H
  13. USBD_CDC_HandleTypeDef     *pCDCData;6 Z/ h$ m0 [! }! Q6 w) `# R
  14. USBD_MSC_BOT_HandleTypeDef *pMSCData;
    9 I' B$ G# n2 h/ _; k
  15.   
    4 @( |+ g$ H; ?  g4 y3 N" g
  16. uint8_t  USBD_MC_Init (USBD_HandleTypeDef *pdev, " i: g" m; `* R+ A
  17.                             uint8_t cfgidx);
    8 F% L7 F. Z( |2 u
  18. * D5 [; A; q$ b
  19. uint8_t  USBD_MC_DeInit (USBD_HandleTypeDef *pdev, : |+ `* T* x6 D" X1 q, a
  20.                               uint8_t cfgidx);8 Y4 `. ?8 d) P7 g

  21. 7 `5 |% t0 `" E# ]* g2 V
  22. uint8_t  USBD_MC_Setup (USBD_HandleTypeDef *pdev,
    ; [" I8 B$ K. F! N" G" ^) O
  23.                              USBD_SetupReqTypedef *req);
      Q& v) b- `* K1 P9 w# ]
  24. 2 }7 ]6 e: H7 o( I" o; K
  25. uint8_t  USBD_MC_DataIn (USBD_HandleTypeDef *pdev, # i! `# u) ]( P" ]/ X. J
  26.                               uint8_t epnum);
    5 c) ^, X3 G1 O. E( }% J9 h
  27. 2 D) Q1 o: t7 w9 j) ?) J& t/ ~% D

  28. ! H# D9 a* W; p# f  }1 {1 k
  29. uint8_t  USBD_MC_DataOut (USBD_HandleTypeDef *pdev,
    : A, E* A; v( b2 k/ d
  30.                                uint8_t epnum);
    " g8 V* U# `4 a* K
  31. 8 W+ ^% Z2 `1 u- p7 U4 S
  32. uint8_t  *USBD_MC_GetHSCfgDesc (uint16_t *length);
      S5 j4 [! H. Z  g. G$ E

  33. % t. @4 O7 _; T& g2 l& v
  34. uint8_t  *USBD_MC_GetFSCfgDesc (uint16_t *length);6 N2 Q3 G4 `4 ]1 H. ]! s- M

  35. 5 D* X' \& g! ?' C, u0 [
  36. uint8_t  *USBD_MC_GetOtherSpeedCfgDesc (uint16_t *length);
    9 f, ^8 X* C! h6 P# v% \- B
  37. 6 j* B. s% @4 F  i3 q1 @2 u
  38. uint8_t  *USBD_MC_GetDeviceQualifierDescriptor (uint16_t *length);
    9 k; u  }' t' W+ D* ~. F
  39. " i! \. g' y: c" ^( W# W/ [( x
  40. static uint8_t  USBD_MC_RxReady (USBD_HandleTypeDef *pdev);
    7 g# f6 `; {; K" \7 d
  41. static void MC_Switch_MSC(USBD_HandleTypeDef *pdev);
    % I& l2 J. U' \
  42. static void MC_Switch_CDC(USBD_HandleTypeDef *pdev);
      ^" K; @2 k& D, ~( _  |  B, B( }
  43. ! P& k! U0 a0 v  K
  44. /**
    4 y( S- x& F, G3 N$ B3 G. H+ I" |
  45.   * @}
    & z3 E" v, E' r# {0 _
  46.   */ 2 d) x4 h2 M' y' J) }/ L
  47. extern USBD_HandleTypeDef hUsbDeviceFS;
    / {- {4 X- w, ?: [

  48. . Z; d" N$ B+ i9 S6 X: J
  49. ' a( I& V3 N- v" ^/ a5 x
  50. /** @defgroup MC_CORE_Private_Variables
    3 D7 D) I" @6 Y! q6 K
  51.   * @{
    3 m- j& x, Y: F5 r/ V( T+ Y- R0 U
  52.   */ ) |7 s7 J$ [! U
  53. USBD_ClassTypeDef  USBD_COMPOSITE = ( C+ Q$ Z9 Z% |3 n# x! `
  54. {" @3 C9 J/ F% y% A
  55.   USBD_MC_Init,
    ( [7 o; M7 X9 R5 e: M; \* F2 R; x
  56.   USBD_MC_DeInit,0 r5 H( N3 Q. e4 `. d: ^5 O
  57.   USBD_MC_Setup,1 ~+ V' r1 v4 S4 Z" o
  58.   NULL, /*EP0_TxSent*/  0 C" {& s5 Y( z3 l+ v: b
  59.   USBD_MC_RxReady, /*EP0_RxReady*/
    " `* M! J" J3 C. \
  60.   USBD_MC_DataIn,
    # T6 L  X* m1 t, ]& {
  61.   USBD_MC_DataOut,
    1 z9 Q9 L( O# J2 H9 v# l7 ?
  62.   NULL, /*SOF */ " c4 ?+ F; d- O# s' e
  63.   NULL,  
    . |! y* k& x& j/ [
  64.   NULL,     
    ! m. X" R+ u, Q3 R  m: \
  65.   USBD_MC_GetHSCfgDesc,% l/ ~: t* x9 C( f
  66.   USBD_MC_GetFSCfgDesc,  
    $ \' ~8 u/ H2 g- @3 o" R
  67.   USBD_MC_GetOtherSpeedCfgDesc,+ I/ K0 x, ]- N3 w4 h" G
  68.   USBD_MC_GetDeviceQualifierDescriptor,7 |/ V$ J$ t1 R) A
  69. };! [2 N0 e6 q/ s! Z1 v8 S6 t
  70. 8 P; b  _3 k, `' @; a; r
  71. /* USB Mass storage device Configuration Descriptor */9 d3 [4 t1 }/ v, E+ w/ ~: J
  72. /*   All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */
    ; `8 ?% k; C/ s; }, e7 \: @
  73. uint8_t USBD_MC_CfgDesc[USB_MC_CONFIG_DESC_SIZ] =6 E5 Z7 v& u0 T$ p# I( ?9 ?* J
  74. {
    ; Y1 u3 D0 d8 i  J, Z# g
  75.   /*Configuration Descriptor*/$ ]2 _( B6 n  \6 A" x5 }
  76.   0x09,   /* bLength: Configuration Descriptor size */, t) k3 c7 o# I. V" ?8 U' |# v5 ]" F
  77.   USB_DESC_TYPE_CONFIGURATION,      /* bDescriptorType: Configuration */0 t/ e$ G1 h+ u+ E
  78.   USB_MC_CONFIG_DESC_SIZ,                /* wTotalLength:no of returned bytes */
    ; Q0 P; X+ c6 n! i- F  B
  79.   0x00,
    : Y# _( k, f+ Y$ c8 Y& j/ C" M
  80.   0x03,   /* bNumInterfaces: 3 interface */
    : C5 F; }& A7 o+ Q! D- F  P- w0 p
  81.   0x01,   /* bConfigurationValue: Configuration value */
    5 q; p6 S  i3 N8 v2 p
  82.   0x00,   /* iConfiguration: Index of string descriptor describing the configuration */
    1 T% [$ I% o1 `, F+ Z
  83.   0xC0,   /* bmAttributes: self powered */2 z3 m/ Y7 a" E6 U4 c1 s
  84.   0x32,   /* MaxPower 0 mA */1 n& E8 O; ~/ C  o
  85.   
    ; U0 z( n: E1 B
  86.   /*---------------------------------------------------------------------------*/1 c. Q% M9 @8 C' M( t! O
  87.   // IAD
    + x8 z8 @3 q. U& W6 J5 U
  88.   0x08,        //描述符大小" s0 m. b$ ]9 N4 r8 S
  89.   0x0B,        //IAD描述符类型8 e4 E7 o& y( q0 H
  90.   0x00,        // bFirstInterface
    4 a8 S. r* M3 u0 ^6 A
  91.   0x02,        // bInterfaceCount) n$ w) Z& h: X  p- z
  92.   0x02,        // bFunctionClass: CDC Class
    5 t* x6 i  o( N2 _
  93.   0x02,        // bFunctionSubClass1 x6 a7 W: x4 t- n! H* ~/ x* E
  94.   0x01,        // bFunctionProtocol
    4 I/ J' ?$ J# f4 s9 P& g
  95.   0x00,        // iFunction      
    ) v4 w+ i' Z3 E, ~' `; B$ t
  96.   ! n  Q# O2 E- r1 d+ K' k: S
  97.   /*---------------------------------------------------------------------------*/4 f8 o- {4 k( D) Q" b
  98.   /*Interface Descriptor */9 O$ I1 `, \# d3 e9 z; [
  99.   0x09,   /* bLength: Interface Descriptor size */7 Y; ?' j1 ]/ c4 W6 @9 X7 s  ?
  100.   USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: Interface */$ p6 t) J6 U- g7 I% h2 m1 r" h
  101.   /* Interface descriptor type */
    5 Q; A$ ~1 B* t, ]) y1 o8 S; t
  102.   0x00,   /* bInterfaceNumber: Number of Interface */% A5 u; y, Q) R+ H% B
  103.   0x00,   /* bAlternateSetting: Alternate setting */
    6 o# ]$ X9 n7 c8 d
  104.   0x01,   /* bNumEndpoints: One endpoints used */
    , c5 }3 B- i! i4 u% F7 D7 y3 h# [; J
  105.   0x02,   /* bInterfaceClass: Communication Interface Class */
    , g- x3 ]! M& N
  106.   0x02,   /* bInterfaceSubClass: Abstract Control Model */4 }( h% C. R# u/ H- Z3 U  Q' t' a
  107.   0x01,   /* bInterfaceProtocol: Common AT commands */0 l0 [# V0 B6 A/ J
  108.   0x00,   /* iInterface: */
    % @# t5 U2 D4 d5 H- F, N( l
  109.   5 k) k9 ]# I! i, m* m
  110.   /*Header Functional Descriptor*/8 T* d. H; k8 _3 L
  111.   0x05,   /* bLength: Endpoint Descriptor size */: J8 ^" Y3 |( l+ M
  112.   0x24,   /* bDescriptorType: CS_INTERFACE */! D3 O3 G  Y$ f0 S+ C# }, \
  113.   0x00,   /* bDescriptorSubtype: Header Func Desc */7 v% `3 G. U  [1 J
  114.   0x10,   /* bcdCDC: spec release number */7 X) P$ c- j( P& x3 A
  115.   0x01,
    2 s# N6 p) g! J  ?
  116.   
    / q' X. i& E  P" V8 a. ?$ [0 X
  117.   /*Call Management Functional Descriptor*/& l& z& E8 R6 `( p
  118.   0x05,   /* bFunctionLength */0 ]+ M& {3 j: i6 t$ G7 i
  119.   0x24,   /* bDescriptorType: CS_INTERFACE */
    , b# o, M7 T% u" C" @
  120.   0x01,   /* bDescriptorSubtype: Call Management Func Desc */
      M) M8 P! l3 N# B
  121.   0x00,   /* bmCapabilities: D0+D1 */
    1 T  U1 Q6 o8 L+ K2 ?
  122.   0x01,   /* bDataInterface: 1 */
    # f/ C5 T6 m/ q: V1 H$ s2 L) U4 h
  123.   
    . `' S7 r# {7 b; ]% N" h8 J2 y; }
  124.   /*ACM Functional Descriptor*/, l$ p, n9 f7 k) ]' h9 B( q. ^
  125.   0x04,   /* bFunctionLength */% S6 r; h- @# T
  126.   0x24,   /* bDescriptorType: CS_INTERFACE */
    1 R3 c( E8 C. Y7 s3 n
  127.   0x02,   /* bDescriptorSubtype: Abstract Control Management desc */3 }5 S( \- J- V9 P; i
  128.   0x02,   /* bmCapabilities */
    3 C# z- `8 J. h& ~/ J
  129.   
    % x& i# N- _, ]1 m
  130.   /*Union Functional Descriptor*/
    7 ^) f; R& R* y+ `4 I: A2 O, i, S
  131.   0x05,   /* bFunctionLength */
    $ \; L( b2 d" T2 k4 j' d. y
  132.   0x24,   /* bDescriptorType: CS_INTERFACE */
    2 i$ c0 a2 F& @, T
  133.   0x06,   /* bDescriptorSubtype: Union func desc */$ d* b# N) I/ ^4 W  o
  134.   0x00,   /* bMasterInterface: Communication class interface */' l, N* e: H% }7 m, e8 ^2 L
  135.   0x01,   /* bSlaveInterface0: Data Class Interface */
    ; ]8 i! H# C  G# _
  136.   
    6 S2 W+ y% g* E
  137.   /*Endpoint 2 Descriptor*/
    7 M3 K+ U7 o1 L# {- ]! n" D
  138.   0x07,                           /* bLength: Endpoint Descriptor size */" q( C% F5 r. `7 m0 T6 x
  139.   USB_DESC_TYPE_ENDPOINT,   /* bDescriptorType: Endpoint */
    + {% d; x; @# H! d* Z
  140.   MC_CDC_CMD_EP,                     /* bEndpointAddress */: T, @. `: ~3 ^. x
  141.   0x03,                           /* bmAttributes: Interrupt */4 |$ n( P; E; ~* T
  142.   LOBYTE(CDC_CMD_PACKET_SIZE),     /* wMaxPacketSize: */
    8 \; T) Z+ I1 b  x! ?; P
  143.   HIBYTE(CDC_CMD_PACKET_SIZE),3 g# v- V8 E, K
  144.   0x10,                           /* bInterval: */ 8 Q- O- x' c$ e" R
  145.   ' D3 u+ C9 ?" e' c- u
  146.   /*Data class interface descriptor*/" _) R% {+ h9 a7 H' k
  147.   0x09,   /* bLength: Endpoint Descriptor size */* n8 I1 |9 q' y/ t+ a- s  x- ^
  148.   USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: */! x3 {0 e: n) i2 P1 G3 C* f1 c
  149.   0x01,   /* bInterfaceNumber: Number of Interface */
      s3 e* @( C# `! {$ p/ y
  150.   0x00,   /* bAlternateSetting: Alternate setting */7 i% O% `5 j" j2 o
  151.   0x02,   /* bNumEndpoints: Two endpoints used */6 Y* k0 }6 i# \) i- Q# k$ m& s
  152.   0x0A,   /* bInterfaceClass: CDC */
    & A+ b- {& I$ `# L, P3 Q
  153.   0x00,   /* bInterfaceSubClass: */
    6 s- I& o: Z2 W
  154.   0x00,   /* bInterfaceProtocol: */
    7 {3 j. K  m2 E! v7 u" ]) S
  155.   0x00,   /* iInterface: */
    6 D. ~- f0 ~7 c" j$ W! F" X$ X
  156.   7 h! P; a% D  V1 ^
  157.   /*Endpoint OUT Descriptor*/. l( S0 l, X. }5 Y7 U3 k; R% U
  158.   0x07,   /* bLength: Endpoint Descriptor size */
    * f+ W/ \( e; N8 W
  159.   USB_DESC_TYPE_ENDPOINT,      /* bDescriptorType: Endpoint */; H# u2 x, }; i1 u1 `  n7 }
  160.   MC_CDC_OUT_EP,                        /* bEndpointAddress */
      E& A1 y# _' C
  161.   0x02,                              /* bmAttributes: Bulk */6 E! P# [6 p% \6 l0 d8 H% w
  162.   LOBYTE(MC_MAX_FS_PACKET),  /* wMaxPacketSize: */( X1 H! `! B3 {1 a) F6 ?
  163.   HIBYTE(MC_MAX_FS_PACKET),5 e1 J! |! b% G3 k3 \- V- w- F' E
  164.   0x00,                              /* bInterval: ignore for Bulk transfer */
    9 E2 k" a8 h. U' H/ e" W( A
  165.   
    . Q% v' a2 Z8 {+ ^
  166.   /*Endpoint IN Descriptor*/
    2 d1 d4 m* g7 c1 z  G+ z5 W
  167.   0x07,   /* bLength: Endpoint Descriptor size */( b  ^* h: ~* \: A
  168.   USB_DESC_TYPE_ENDPOINT,      /* bDescriptorType: Endpoint */
    8 Y/ c) q# k9 G5 i! _. m
  169.   MC_CDC_IN_EP,                         /* bEndpointAddress */+ D! q+ g0 S6 e7 S' U6 W! L
  170.   0x02,                              /* bmAttributes: Bulk *// `5 C: o) I  u/ O1 _% v' s) A
  171.   LOBYTE(MC_MAX_FS_PACKET),  /* wMaxPacketSize: */9 e$ \  h8 r9 ~) ~. N9 z0 d8 y
  172.   HIBYTE(MC_MAX_FS_PACKET),
    % i/ O' p1 q) \5 B3 p
  173.   0x00,                               /* bInterval: ignore for Bulk transfer */
    + R- G* [6 l6 ?3 b1 b. N, F

  174. 8 i  s5 b# K: l5 z0 C7 n
  175.   /*---------------------------------------------------------------------------*/3 k" [  B5 t  ^; I  M
  176.   // IAD1 k3 U* q/ o2 ~! n# y
  177.   0x08,        //描述符大小
    / n! s' K! J. K3 S5 T8 ^
  178.   0x0B,        //IAD描述符类型
    6 n* G. B. Z' F" a
  179.   0x02,        // bFirstInterface
    , M; j5 N4 S. w% ~& T- ?* Q. S5 }
  180.   0x01,        // bInterfaceCount0 l3 E9 I9 I+ H
  181.   0x08,        // bFunctionClass: MASS STORAGE Class
    : g) F; i; n! B; t
  182.   0x06,        // bFunctionSubClass
    - q! o6 K/ e5 o1 ^0 T! z- v2 S! Z
  183.   0x50,        // bFunctionProtocol
    0 A# @- B- n0 y: O
  184.   0x01,        // iFunction   
    ' _8 _; z9 K- E4 w8 c

  185. 0 p% @# h$ F1 H
  186.   /********************  Mass Storage interface ********************/
    " @0 e8 j! r+ V* `" @1 I6 ]
  187.   0x09,   /* bLength: Interface Descriptor size */2 J/ y% L+ c3 y+ q$ Q* Y
  188.   0x04,   /* bDescriptorType: */
    ' Y" O& S+ D0 d# k1 c
  189.   0x02,   /* bInterfaceNumber: Number of Interface */
    , m2 N* Y; S2 Z! l- {3 c! p# x1 q3 f
  190.   0x00,   /* bAlternateSetting: Alternate setting */
    , G; n! b% E- p* d/ j
  191.   0x02,   /* bNumEndpoints*/
    & x0 D& f% t- Y
  192.   0x08,   /* bInterfaceClass: MSC Class */
    0 p/ ?. q+ D: D* h2 q7 n
  193.   0x06,   /* bInterfaceSubClass : SCSI transparent*/
    & L7 y3 [  N7 r' y7 H9 C
  194.   0x50,   /* nInterfaceProtocol */
    4 p' m3 ^1 v% e. N. F) J( d
  195.   0x05,          /* iInterface: */
    $ q' d  O4 f. T6 i/ _9 h8 Z
  196.   /********************  Mass Storage Endpoints ********************/
    . I5 q' A4 O" e0 X( ^( L
  197.   0x07,   /*Endpoint descriptor length = 7*/! j6 m( P2 C! W6 S! l8 U( g; X8 T
  198.   0x05,   /*Endpoint descriptor type */
    5 ], t" l( b0 `* l4 o( t5 n( d
  199.   MC_MSC_EPIN_ADDR,   /*Endpoint address (IN, address 1) */
    ' G6 C0 p! X+ d  k+ g2 }
  200.   0x02,   /*Bulk endpoint type */8 V4 C/ x7 q. }0 c2 l1 L# h2 s0 g
  201.   LOBYTE(MC_MAX_FS_PACKET),9 V# ?( u# z/ G9 D( q  ~
  202.   HIBYTE(MC_MAX_FS_PACKET),# E. o% l3 {$ ]! ]( J, S0 u
  203.   0x00,   /*Polling interval in milliseconds */
    , x4 s  m# h; ^7 V# o* j
  204.   
    , b# K* ]- x, c* V% i) u( N
  205.   0x07,   /*Endpoint descriptor length = 7 */5 t* E; d4 U0 d. v7 `
  206.   0x05,   /*Endpoint descriptor type */' S/ ~: d4 a3 b( h; A' H
  207.   MC_MSC_EPOUT_ADDR,   /*Endpoint address (OUT, address 1) */
    # `0 ~" [# g. C9 Y/ Y+ s
  208.   0x02,   /*Bulk endpoint type */" k5 @& O6 |1 g5 h9 a. X
  209.   LOBYTE(MC_MAX_FS_PACKET),/ v  j! s5 V# C) N) t6 Q
  210.   HIBYTE(MC_MAX_FS_PACKET),: V* a5 b: s6 A/ z1 o2 ^/ o
  211.   0x00     /*Polling interval in milliseconds*/& P6 e, {5 n5 [5 u# x
  212. };" u( e( F/ J$ G2 l$ \1 W# V+ Q
  213.   ' g. J6 y5 h) X# H. i" U2 S
  214. uint8_t USBD_MC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] =* t6 d# X7 r* K8 Z+ Z( A
  215. {
    7 p9 M8 K/ N. w. B
  216.   USB_LEN_DEV_QUALIFIER_DESC,( t5 h6 l. ]  k
  217.   USB_DESC_TYPE_DEVICE_QUALIFIER,4 h, w/ z5 W! K
  218.   0x00,5 \3 ]- c9 U& f5 j) X9 G
  219.   0x02,
    " Y, ~- g6 o7 n
  220.   0x00,
    3 o1 p2 \8 N, |0 Y' g
  221.   0x00,
    % R) D5 z5 s% Z! Z2 w
  222.   0x00,5 m7 [7 o& m$ |8 [  W3 T6 p
  223.   MC_MAX_FS_PACKET,
    ! e$ ]( ~! Z$ B5 e0 g! h# d
  224.   0x01,# O+ j/ w: {2 f3 k1 G" Y
  225.   0x00,3 _1 p! ?; b6 i9 J0 q' u
  226. };* S/ ^2 A5 o' k' I* K4 Y
  227. 1 I# e$ ]5 D1 x# S  E
  228. /**
    8 z! B8 [6 `2 z- e3 _) ~+ ^
  229.   * @brief  USBD_MC_Init4 r( ]6 u5 n0 j- L4 K
  230.   *         Initialize  the mass storage configuration; h% b! r4 \9 `# D) F: L; ^0 M$ t5 h
  231.   * @param  pdev: device instance
    " D3 B! Y; t' i$ |
  232.   * @param  cfgidx: configuration index5 z! V8 U6 H- r0 }. `; }8 S. K
  233.   * @retval status4 b" }' z; {/ g2 D# s
  234.   */
    : [/ f6 P: D6 |2 i
  235. uint8_t  USBD_MC_Init (USBD_HandleTypeDef *pdev, uint8_t cfgidx)' K0 L. q2 [& x% O, E* }* J5 E
  236. {- ?& y6 D. s& C$ m5 Y
  237.   uint8_t ret = 0U;
    , H0 d# j4 A, Y+ K& ]& U" E4 M

  238. ; e' \0 X* d  B7 K! ], ]# @/ @
  239.   8 B, q) f/ T' D6 [  M3 k
  240.   USBD_CDC_HandleTypeDef      * hcdc;0 P% R$ i+ V; h$ x7 Q
  241.    
    6 a1 I& ]+ I5 m  W2 F; E
  242.   MC_Switch_CDC(pdev);, Q/ s! B& j9 D
  243.   ( q! U5 @& V! Y. u: g3 V
  244.   USBD_LL_OpenEP(pdev,, {3 F1 ?( A, h* e3 r
  245.                  MC_CDC_IN_EP,
    2 x$ l, o: a: f  v6 o& t
  246.                  USBD_EP_TYPE_BULK,  ^% T, J2 U$ U
  247.                  MC_MAX_FS_PACKET);2 m2 H+ I, G' i' F. v, X2 F# ?/ T
  248.   - w+ Z4 @- h  c# {
  249.   USBD_LL_OpenEP(pdev,
    : Q( D, ]; d9 C/ ~
  250.                  MC_CDC_OUT_EP,1 a' l* M  D3 G6 R) A  @* C
  251.                  USBD_EP_TYPE_BULK,
    % K& I: `5 a0 k& c% {; V! D
  252.                  MC_MAX_FS_PACKET);
      R1 ?. h. W1 O
  253.   4 w3 S% x7 @* s  J! m* x. F
  254.   USBD_LL_OpenEP(pdev,
    0 j. o" @, ~3 f' k: C( s
  255.                  MC_CDC_CMD_EP,% C: C2 m6 R  ^3 a$ i* L9 Z, d* z' l
  256.                  USBD_EP_TYPE_INTR,, x4 F: M8 L4 t* e5 O$ U! X
  257.                  CDC_CMD_PACKET_SIZE);; R% I3 z4 [2 U/ ^' \2 x: u
  258. 5 m7 q8 F0 a1 k: W: z1 a) {
  259.   hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;! E( b+ E, v. y$ s, F% s
  260. 1 S( _' [9 Z3 H8 X7 a, G
  261.   ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Init();! @/ A3 x' p6 Q, q' V6 E
  262.   
    6 ~: l; O" S" w
  263.   hcdc->TxState =0;
    0 J$ @: ]' i3 u; T, b
  264.   hcdc->RxState =0;
    ; r' s6 E" w& M" U; E2 l
  265.   7 b; f% g: J! X2 b* X
  266.   USBD_LL_PrepareReceive(pdev,$ q# n0 b7 s7 V' m
  267.                          MC_CDC_OUT_EP,  n; ]" N0 s# ^& s- {/ R
  268.                          hcdc->RxBuffer,
    4 `2 m7 x3 q& }  ]; O
  269.                          MC_MAX_FS_PACKET);
    $ G/ i4 d1 ]. D# v1 d' p) [
  270. * ]8 U; Z9 P  R* w
  271.   pCDCData = pdev->pClassData;: ^8 o; s6 H3 k
  272. 0 s& X8 U" {6 K7 M
  273.   MC_Switch_MSC(pdev);( {: r2 ^$ S& Y% `
  274.   % T! e/ d6 q! Q. W, @0 H# v
  275.   USBD_LL_OpenEP(pdev,
    . T" Z5 ~" o/ L3 h# c# ?
  276.                  MC_MSC_EPOUT_ADDR,+ Z# O7 X, x; ?( C* f" B0 B4 o- R
  277.                  USBD_EP_TYPE_BULK,
    ' B0 i3 Y. R; B. K
  278.                  MC_MAX_FS_PACKET);  J0 ^( G( ]  {9 M& g- a' p+ U
  279.   
    ) P) |8 t8 @7 T: y! T
  280.   USBD_LL_OpenEP(pdev,4 Q+ j$ w( s4 F
  281.                  MC_MSC_EPIN_ADDR,# i& [( g, s* P0 [8 E
  282.                  USBD_EP_TYPE_BULK,
    ) i4 `% S$ j# D" R' I7 a: r
  283.                  MC_MAX_FS_PACKET);9 @8 t: }4 M' t! p: V6 _8 Y
  284.   ; J: i5 f9 V- g- @7 z. I, m' |  _
  285.   MSC_BOT_Init(pdev);+ k' H9 e' X0 a& e- i/ F' L# n# [
  286.   
    8 j. R) l/ i2 ^$ s, n
  287.   pMSCData = pdev->pClassData;
    / S# j2 x7 P! M3 D0 ~0 }, @' \2 E
  288.   * T: N' p& y$ j$ u, @$ i& a4 c! g
  289.   if(pdev->pClassData == NULL)5 X* q$ s6 x- O) s
  290.   {
    3 I) ]7 g& d$ r6 F8 v+ O. ?
  291.     ret = USBD_FAIL;! b: C1 t  v. K0 K: v
  292.   }' R7 V3 |& h& j4 @* i" u4 e

  293. 6 k. ]6 q# u& e, w
  294.   return ret;( W. }7 T( o3 Z* P/ G3 v! R
  295. }2 n* e# [: ~, Z/ ~2 k5 R( U3 N
  296. ) d3 V6 E/ a7 h- U# Z" f
  297. /**; d- S+ \: b' t. E4 {/ \
  298.   * @brief  USBD_MC_DeInit2 c- ]' R* K/ Y! \
  299.   *         DeInitilaize  the mass storage configuration4 T' O# h! n$ h
  300.   * @param  pdev: device instance
    " W4 q6 C/ H/ F) ]# n2 [
  301.   * @param  cfgidx: configuration index
    9 o9 z2 q, m! ?! M. t
  302.   * @retval status$ F7 B- k5 A% V9 k+ G. v$ Z  o
  303.   */
    * Q" R* c' V; i8 K" @
  304. uint8_t  USBD_MC_DeInit (USBD_HandleTypeDef *pdev,
    / q7 x: {; d  A5 s
  305.                               uint8_t cfgidx)
    4 G$ b( T. M/ W, _6 d& W. V2 W
  306. {
    7 P/ E- J' M7 A, a. m3 w4 D) {
  307.   return USBD_OK;
    ) P( V" f" _' v6 }; p
  308. }: @: L/ Q- g: S) m' q# U# B
  309. /**
    : f0 o. r# i% v2 x
  310. * @brief  USBD_MC_Setup
    1 U+ @2 p4 L1 x$ C* K, `  }
  311. *         Handle the MC specific requests1 @( l; N# m8 a+ L3 ^, K& {
  312. * @param  pdev: device instance
    * V0 B! ^" `8 _# D* c
  313. * @param  req: USB request
    . q4 D6 Q( l% N3 F% q( ?
  314. * @retval status1 z1 W7 n4 N9 r0 i5 S6 @( a2 |
  315. */
    * ~, V0 |" _2 K1 C5 x8 M
  316. uint8_t  USBD_MC_Setup (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)( X* o! p3 Y. }4 B3 m
  317. {0 }- W: B5 c& d. D+ a" T! S: D+ l
  318.   if(req->wIndex == 0x0002)
    * `, b* a- N. S0 _4 R
  319.   {
    # W4 \. W) T3 B
  320.     MC_Switch_MSC(pdev);8 f2 @: _) e; z2 \# t
  321.     USBD_MSC_BOT_HandleTypeDef     *hmsc = (USBD_MSC_BOT_HandleTypeDef*) pdev->pClassData;   
    # o# A& y+ W5 b% [; g
  322.    
    8 c/ n4 _/ m( r9 B
  323.     switch (req->bmRequest & USB_REQ_TYPE_MASK)
    , p; \% _( d2 y% }' a
  324.     {
    . h+ ~) l5 t9 Q! R. O

  325. 1 y; V, w" z' p
  326.     /* Class request */
    3 W- T. c# [" H/ n2 b
  327.     case USB_REQ_TYPE_CLASS :" N& m3 @& X/ k' o1 z
  328.       switch (req->bRequest)
    $ P5 M( \3 Y: S: s, v: G
  329.       {
    / k/ `5 v1 [0 `( Y( Z# u3 t
  330.       case BOT_GET_MAX_LUN :
    ( M3 @5 O- o: F

  331. % [3 P0 n/ R7 u. h( q
  332.         if((req->wValue  == 0) && , t( Q# X/ {: T$ F: a8 E
  333.            (req->wLength == 1) &&3 {' W+ }* a: u& H1 W
  334.            ((req->bmRequest & 0x80) == 0x80))
    - u! G0 F, z1 S& M0 O; y
  335.         {$ M: K0 V' P5 U4 P6 d# w0 G
  336.           hmsc->max_lun = ((USBD_StorageTypeDef *)pdev->pUserData)->GetMaxLun();
    $ O: Z1 b) ~% r! N7 g# Q& N; G
  337.           USBD_CtlSendData (pdev,- q4 v6 c. C- x5 v. q6 F
  338.                             (uint8_t *)&hmsc->max_lun,
    9 H" a" I7 n: m" E* Z( W
  339.                             1);5 x- {5 j2 X# T9 h  T& X
  340.         }% ?9 Z: H2 V2 `: ]6 J% H2 H  Z3 a
  341.         else
    8 h, U. W0 a# A( \; W# z& C
  342.         {* m  Z" _! u' u7 s. g1 L
  343.            USBD_CtlError(pdev , req);
    % e" F1 ^: i/ [9 x5 v/ A% [& f
  344.            return USBD_FAIL;
    : d, }4 j4 P, V, u0 N+ e9 Z5 e" C
  345.         }' o$ W4 g; s, O4 R( u& w' R4 X
  346.         break;
    " W. v8 R7 f; F
  347.         / z( i# e6 }6 j3 K: O
  348.       case BOT_RESET :* Z5 L7 @2 z$ b2 w4 ]# M) f% E
  349.         if((req->wValue  == 0) && 5 i1 O2 v: t* p
  350.            (req->wLength == 0) &&
    , P5 V3 B( m- ]
  351.           ((req->bmRequest & 0x80) != 0x80))
    3 M0 t8 V* ~& J. j! {8 y* \
  352.         {      3 \8 V! v7 L7 Y( F: |6 C2 Z8 @
  353.            MSC_BOT_Reset(pdev);  S: ~( f3 [2 j) c/ o
  354.         }
    , h. J! y7 [" V% G; G7 L6 h) n& t
  355.         else5 B, _) \& _5 i) [3 f$ ?
  356.         {
    1 s/ f- x$ O1 X9 g; G- X* |/ j  ?
  357.            USBD_CtlError(pdev , req);( ]  U2 z2 ~4 t" h( t
  358.            return USBD_FAIL; , i! r) d+ G( ~$ r
  359.         }
    & D) C* h# b2 A' k  Q$ y
  360.         break;4 O$ _4 c  }% f/ ?) f

  361. , N) W  i" P- x! [
  362.       default:
    4 D1 M/ Z7 S9 e/ Q! m
  363.          USBD_CtlError(pdev , req);* ~" `2 b; k5 c' _- e
  364.          return USBD_FAIL;
    2 u7 ]1 s, S+ q: A7 s
  365.       }
    2 B5 W6 c+ T5 l6 j, C
  366.       break;$ @9 j- l- A% G
  367.     /* Interface & Endpoint request */
    % u  U. T( v9 P. P( U9 o
  368.     case USB_REQ_TYPE_STANDARD:
    # u; o6 g+ B! @& t% P' _1 y
  369.       switch (req->bRequest)
    4 l; a) c7 j8 f8 J& N8 ?4 `
  370.       {
    . y) d. m6 C& x# \8 q
  371.       case USB_REQ_GET_INTERFACE :' w% f; A% ?9 J1 _3 V; A
  372.         USBD_CtlSendData (pdev,4 J5 w, A- Q' p# k+ L/ s
  373.                           (uint8_t *)&hmsc->interface,
    8 w2 |- i( [6 Z) j) I4 e
  374.                           1);
    1 E' c' v$ u1 ?& t
  375.         break;
    * R* l; S- K4 f" c- ]8 ^# e* Y+ A
  376.         
    & c/ Y: N. l! Z
  377.       case USB_REQ_SET_INTERFACE :
    $ W* h7 S3 t: `
  378.         hmsc->interface = (uint8_t)(req->wValue);
    0 J0 g. F4 V9 Z, s) n5 M
  379.         break;7 ~5 [! h7 _6 D5 d
  380.       - i0 k5 ]0 A8 x8 g8 k/ n; L
  381.       case USB_REQ_CLEAR_FEATURE:  & I) ]% Z1 l3 w. I; A
  382.         
    2 z' \5 {. A7 N% J6 U
  383.         /* Flush the FIFO and Clear the stall status */   
    8 E0 }6 ~0 F% c/ g
  384.         USBD_LL_FlushEP(pdev, (uint8_t)req->wIndex);0 p: L4 ^8 ]2 Z7 k" ^
  385.         ) K" Y9 D4 S' W
  386.         /* Reactivate the EP */      * }9 e8 E6 p1 ^" @* L2 K9 f% `
  387.         USBD_LL_CloseEP (pdev , (uint8_t)req->wIndex);
    , x# ?$ |/ q1 J9 n) T6 [
  388.         if((((uint8_t)req->wIndex) & 0x80) == 0x80)
    # l, S. \1 l" s. G( @
  389.         {
    7 {# N4 f7 k$ K$ b9 T8 p
  390.           if(pdev->dev_speed == USBD_SPEED_HIGH  )
    % ]* v( |9 u/ T% g% h% Z. T% ]3 A
  391.           {- V$ K& H# i) x- q
  392.             /* Open EP IN */
    # O7 C9 E" E% p  N
  393.             USBD_LL_OpenEP(pdev,
    0 B4 w+ d3 g4 `4 [4 U* Q& r
  394.                            MC_MSC_EPIN_ADDR,
    7 d5 A7 n- Z, n- u# k6 _
  395.                            USBD_EP_TYPE_BULK,  u2 g' ^) ^3 u; U
  396.                            MSC_MAX_HS_PACKET);  
    6 y; z; A0 C- x4 d0 j
  397.           }
    4 Z1 o& X5 n# }
  398.           else
    $ R3 ]* @: X& N$ s/ R4 K+ V
  399.           {   ( c0 v6 t3 N5 j. d+ a, a$ b
  400.             /* Open EP IN */
    1 {" R8 F# C2 u' P' ?! I% d' r0 N0 p
  401.             USBD_LL_OpenEP(pdev,5 ?  Y( ?3 ]" C9 T, @0 W  z$ b
  402.                            MC_MSC_EPIN_ADDR,
    : G! G% k( n/ u# W. b* o6 O6 G( v3 z+ B
  403.                            USBD_EP_TYPE_BULK,
    ; a$ n3 o( f( x
  404.                            MSC_MAX_FS_PACKET);  
    $ ^, o, T0 ]4 x1 R2 O8 H; O* E
  405.           }8 u5 `9 q0 X- p6 |2 R; J3 o
  406.         }. r( A+ p( U6 B3 I2 |
  407.         else! R7 r4 E! J7 p, @+ R3 F( u
  408.         {
    * S& @3 U. K$ M" J" ?
  409.           if(pdev->dev_speed == USBD_SPEED_HIGH  )
    ) h7 a! y  S, ?( J. m; X, `! I
  410.           {" z1 u8 k5 W( K; a( {: v
  411.             /* Open EP IN */0 t6 |4 @. ?+ v, ?" H% I$ N
  412.             USBD_LL_OpenEP(pdev,
    ( Z$ [6 `* @3 E- a! a
  413.                            MC_MSC_EPOUT_ADDR,- k1 F6 z! l# g6 p- q
  414.                            USBD_EP_TYPE_BULK,2 R3 N4 E/ y& Z+ ^7 \' u9 Y2 T% ]& W
  415.                            MSC_MAX_HS_PACKET);  
    : `" A* l4 f8 H& u& V
  416.           }3 P- \  B3 o0 ?0 R5 g
  417.           else
    9 W% h/ \$ P# m6 }$ e! z
  418.           {   / H% ]& c$ U' a! ?
  419.             /* Open EP IN */
    6 J% ]) d8 q6 J5 {6 {- S8 S
  420.             USBD_LL_OpenEP(pdev,: A" ^! y. z! L: ~
  421.                            MC_MSC_EPOUT_ADDR,* }2 v5 ]$ E" l# A" Z
  422.                            USBD_EP_TYPE_BULK,9 F* E. ^9 R2 @8 J- r  ?  w
  423.                            MSC_MAX_FS_PACKET);  ; |# ]1 u$ ?1 H1 x5 }, ]8 K5 D
  424.           }  }5 @, M) e7 b- W
  425.         }2 r( P& S# A4 u6 O+ \) s* F
  426.         
    ; N( V! Y3 o9 ~( L$ Q
  427.         /* Handle BOT error */! p, n+ p- A# r
  428.         MSC_BOT_CplClrFeature(pdev, (uint8_t)req->wIndex);3 j* k) Z7 A! a2 `! {, l
  429.         break;9 F* ]8 Q; m. t) F7 B3 U
  430.         + G8 F+ V* G$ t1 q- _  h
  431.       }  7 f9 z& r  R8 k5 c$ L7 ?
  432.       break;
    % x5 P! T' q) U- f' q5 y; \6 Y/ K2 I
  433.      8 V# K% Y% G; z8 o
  434.     default:
    * g3 }, w# o8 {# i2 v/ b% W
  435.       break;. n  E7 M8 u* d2 @
  436.     }
    7 B/ I; t* t9 x% @3 y, u
  437.   }& k9 b4 H$ E+ p4 h
  438.   else
    $ m1 D  B' B- r  w& u7 m0 h
  439.   {4 H: ?9 ]6 N9 _: k; ?
  440.     MC_Switch_CDC(pdev);/ V; j  K4 c' V; {6 |( A2 m
  441.     static uint8_t ifalt = 0;6 b. ]" r. n; t: ^
  442.     USBD_CDC_HandleTypeDef * hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData;   1 z6 |8 a; A0 h9 c0 R6 K! j+ Q

  443. % `- s- Z( x# u3 H7 L  H7 e
  444.     switch (req->bmRequest & USB_REQ_TYPE_MASK)
    2 F5 `0 o$ i: {& W% j( U
  445.     {
      J. @. `8 ?; |- b1 Z& i
  446.     case USB_REQ_TYPE_CLASS :3 u* u4 C9 ~9 G" ?/ ^! Y$ J( \
  447.       if (req->wLength)
    + ?: r, C" q( a8 v
  448.       {* {' D0 V) H7 ?
  449.         if (req->bmRequest & 0x80)
    * G4 y# {0 r. h3 Y( S
  450.         {
    ; ]8 M: S4 k* C& Y( {( Z. j; [
  451.           ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest,9 \- v7 q9 I7 z
  452.                                                             (uint8_t *)hcdc->data,6 B1 F! B. K  a2 _
  453.                                                             req->wLength);
    . M1 k, A! B  D+ G
  454.             USBD_CtlSendData (pdev,
    ) _2 i( [! B: q( v$ M
  455.                               (uint8_t *)hcdc->data,
    2 S9 A. g# L; U( L# E1 Q! _
  456.                               req->wLength);. l9 j2 x- q+ {  n; T1 T5 {/ l
  457.         }
    9 L8 X' t" x& R
  458.         else
    * ?& Z4 B. f! P0 p6 u6 V
  459.         {
    7 F7 b8 @, q, p* m# f) R
  460.           hcdc->CmdOpCode = req->bRequest;
    7 P# n; V- E( O) o
  461.           hcdc->CmdLength = req->wLength;
    9 G* s1 u# l5 B+ b6 M
  462.          
    / |0 i$ {% x9 P
  463.           USBD_CtlPrepareRx (pdev,
    : x9 b/ X( c3 A4 |3 e9 W& G) H4 E3 Y" \
  464.                              (uint8_t *)hcdc->data,
    ' @! m% N4 u; s- l
  465.                              req->wLength);
    ; V+ N% k! Q% r  X8 M+ v: m
  466.         }9 C3 p' t3 I- {+ d( Q; |) {2 S# \
  467.         / {8 J/ q2 t5 m+ G
  468.       }4 Q- z4 z0 e; u2 O0 g4 n% \1 `
  469.       else  x! O# K6 h( m+ s" x2 I$ o/ v
  470.       {
    + S; L$ g5 e# _9 ?
  471.         ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest,
    - S6 w/ f$ W6 E5 ?
  472.                                                           (uint8_t*)req,( @' g7 R0 z/ H1 S
  473.                                                           0);( I& w( _' P, H4 Y9 z" \- m. E
  474.       }
    2 Z7 {; q3 n* Y
  475.       break;4 y3 O: J+ P+ n0 o9 A% {7 s
  476.    
    5 s/ ^% `6 g' }: }( b9 o' t! Q
  477.     case USB_REQ_TYPE_STANDARD:
    3 M% h3 w; x& i9 T# d/ M% N
  478.       switch (req->bRequest)
    / C1 ^* J" J, d( H' E
  479.       {      
    / s( O3 `: N. `% i
  480.       case USB_REQ_GET_INTERFACE :2 F6 u3 ]* p) r+ ]( {8 c/ n
  481.         USBD_CtlSendData (pdev,
    : F6 j5 Y+ Y- i* Q8 q0 }' E
  482.                           &ifalt,! c' b: M+ O1 S4 y
  483.                           1);  i+ V* o6 {& d4 J( e7 |3 N  ]
  484.         break;" u) l; d& u' D# X' j& I% q7 |. m4 {3 W
  485.         
    - [: n; r% K& n0 y5 T) `3 m8 X0 Z
  486.       case USB_REQ_SET_INTERFACE :8 s6 ^8 \$ z# b3 @
  487.         break;
    9 ]  |; ~0 R6 ]$ F/ Q9 R
  488.       }+ `* J% R5 {. N" O
  489.    
    / C; h' `+ r/ w; Q
  490.     default: / h% u& X( g  Q
  491.       break;( \) y) T% k" |1 i
  492.     }  
    3 [3 s$ f) }- T
  493.   }
    5 g2 u  |) {+ m0 x$ z
  494.   ( ?* w7 s: y" j+ K
  495.   return USBD_OK;! S& `/ p5 \& ^5 E' b
  496. }' Y) F8 U! n; U8 R% R
  497. , E+ H) B  X# Z# a. b( x: x3 h$ D
  498. /**1 d9 ~- p5 }" D; U2 O
  499. * @brief  USBD_MC_DataIn
    ) @9 U2 M; C0 K- u
  500. *         handle data IN Stage
    7 x& M" o( {: G% p
  501. * @param  pdev: device instance
    8 e1 E- F  `5 F: d8 Q
  502. * @param  epnum: endpoint index
    $ j9 a4 l0 v2 F3 p5 f
  503. * @retval status
    / W) B; W6 g, @/ h. h' t
  504. */% {$ N8 {# J9 s
  505. uint8_t  USBD_MC_DataIn (USBD_HandleTypeDef *pdev, 5 V3 v! v* M+ W$ O" G& k
  506.                               uint8_t epnum)
    5 s9 ]% d- P$ O% d( I* @
  507. {$ R; R) D4 q# H% ?
  508.   if(epnum == (MC_MSC_EPIN_ADDR & 0x7f))
    0 V  H( z2 p9 j9 g9 R  ~
  509.   {
    9 m5 c! j6 ~( L- a4 K
  510.     MC_Switch_MSC(pdev);3 s0 U% b" W" w" V+ [, j
  511.     MSC_BOT_DataIn(pdev , epnum);
    8 ]* f  G# Z4 F8 F) j& K9 l
  512.   }" b9 E8 Y  l  k7 |; r
  513.   else if(epnum == (MC_CDC_IN_EP & 0x7f))& u( s7 Y0 q5 ^. r7 R# T. q  ?
  514.   {
    7 X% p+ w$ J* m1 `, q
  515.     USBD_CDC_HandleTypeDef   *hcdc;
    3 @0 B/ B# ^, @
  516.    
    7 }. ?, y0 E- B4 v2 P
  517.     MC_Switch_CDC(pdev);1 X! w' `! [" b- j
  518.     hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
    9 B7 P: p+ f: g9 u  t. F) J
  519.     hcdc->TxState = 0;    ; C# w, ], G6 G6 j* E, o
  520.   }
    % x! X6 @3 L% T/ Y
  521.   
    / ~/ [9 D4 s2 K; k& s, c' U
  522.   return USBD_OK;
    : V. L  m5 ^# S& m+ }2 ]* H3 p# {
  523. }) L  f3 h: E0 P4 H
  524. 5 ?! k) J$ \5 ~% ~
  525. /**# z! m# f* j' G: ]3 f
  526. * @brief  USBD_MC_DataOut
    ; o/ }" s, P/ C: R1 |
  527. *         handle data OUT Stage3 E4 g4 I! I' ]
  528. * @param  pdev: device instance" O+ y7 Z6 V) n# R# a" ~) x3 q
  529. * @param  epnum: endpoint index! x! G1 W6 E" }' E
  530. * @retval status
    ( w6 @' d, {3 c
  531. */
    $ n/ R/ m+ k0 \
  532. uint8_t  USBD_MC_DataOut (USBD_HandleTypeDef *pdev,
    4 c6 a( u8 [# S% h
  533.                                uint8_t epnum)) f( Y8 u) S4 t/ J, b4 f  I7 w
  534. {
    . ?. w  _+ O- C. d. s
  535.   if(epnum == MC_MSC_EPOUT_ADDR)
    ' |- r- k. t1 h+ f3 b/ V1 i+ y
  536.   {, L& {, I4 j' P6 n8 L
  537.     MC_Switch_MSC(pdev);
    # f$ t4 M& E$ h# C' l; i& A
  538.     MSC_BOT_DataOut(pdev , epnum);
    ! B; H/ J5 v4 X4 V1 G
  539.   }
    ( e0 I4 J; I4 O3 a1 p
  540.   else if(epnum == MC_CDC_OUT_EP)
    $ F% @% L$ ?/ q2 }" y* D; s) O! L5 i
  541.   {* V( F0 O- l% z
  542.     USBD_CDC_HandleTypeDef   *hcdc;
    : J$ |3 Z3 w6 x1 S
  543.     6 A: n; ]8 ?. j" S# K6 s
  544.     MC_Switch_CDC(pdev);9 X, `- J7 k- U. R% t* Q; N4 O
  545.     hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;$ @1 x# R9 J2 F7 g
  546.    
    " H6 H# \- c% _
  547.     hcdc->RxLength = USBD_LL_GetRxDataSize (pdev, epnum);0 B, b# I2 e5 U
  548.     ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Receive(hcdc->RxBuffer, &hcdc->RxLength);
    3 h2 I# u; A- a9 m; R0 b7 H, _
  549.   }
    ) L% j( X: }4 ~% z6 |
  550.   
    9 k1 @" Q2 b8 K( s
  551.   return USBD_OK;% {  Y- `) R3 Q: F. s* M
  552. }
    * c: J3 Y; r: v# U; V+ ~9 D. T
  553. ) ]8 |% f! E( k1 @; g( m
  554. /**
      z' j1 {  o, `) s1 \, w
  555. * @brief  USBD_MC_GetHSCfgDesc
    $ O  d) n& M' [+ Q* E
  556. *         return configuration descriptor
    : ^: {+ H; o4 U; T* i
  557. * @param  length : pointer data length' z3 J- M6 b' ~! ~6 x- A- S
  558. * @retval pointer to descriptor buffer
    $ O# E; b' q7 `
  559. */- t: T" G$ [8 M/ c
  560. uint8_t  *USBD_MC_GetHSCfgDesc (uint16_t *length)
    0 R, L5 H7 P* b% ?/ n) l" V
  561. {/ ]" [5 R! ~( f! a
  562.   *length = sizeof (USBD_MC_CfgDesc);
    9 c3 b& Q1 M5 y9 N2 Q) G
  563.   return USBD_MC_CfgDesc;
    - B8 M1 C. G8 e9 y6 ^, k
  564. }
    5 s4 J2 f; D* s7 m% K$ n9 R
  565. - m2 m8 b- I! D2 b3 |# t1 l
  566. /**; R8 t4 X9 {) h! w# I
  567. * @brief  USBD_MC_GetFSCfgDesc ( |, J5 ~! y% z4 w
  568. *         return configuration descriptor
    1 E, S1 }( Q; D- `9 x
  569. * @param  length : pointer data length
    % p3 d- m  V3 C1 Y$ N: ~  `
  570. * @retval pointer to descriptor buffer' w$ d* Z5 h( c
  571. */' e, D4 q9 D7 d: Z9 C: F* j/ G' B
  572. uint8_t  *USBD_MC_GetFSCfgDesc (uint16_t *length)
    5 v& I  c- H7 j  [5 I
  573. {
    6 G' t, o2 f! Z( y6 T3 A' ?
  574.   *length = sizeof (USBD_MC_CfgDesc);& \+ k- E# [) c; _/ k1 `
  575.   return USBD_MC_CfgDesc;1 }; [* _7 W! q- @
  576. }
    ; a4 X' a# K) }( C

  577. 1 p9 L$ J0 q. ]3 d5 I6 Y
  578. /**
    + X7 M- l# e2 s5 C. ~6 ~
  579. * @brief  USBD_MC_GetOtherSpeedCfgDesc
    . k9 m4 I9 W& `
  580. *         return other speed configuration descriptor6 P7 f0 v; e$ f* `6 v
  581. * @param  length : pointer data length' d6 B; h+ J4 v& ~$ J' r* n! E
  582. * @retval pointer to descriptor buffer8 \8 r# y1 k7 p: v9 ^- `
  583. */
    ! _  A, q" ]4 w* o/ k
  584. uint8_t  *USBD_MC_GetOtherSpeedCfgDesc (uint16_t *length)5 W5 W' v: B* f- C6 [8 a0 u+ F
  585. {
    * p# i1 P/ h- G/ f) E: ?+ E
  586.   *length = sizeof (USBD_MC_CfgDesc);8 ~$ e$ y! q/ L2 ^( k. P6 |
  587.   return USBD_MC_CfgDesc;, T* f: O  [! `7 D2 U& [% R
  588. }' h" d2 u. b) A- B/ ~
  589. /**
    2 o7 K* o* u; b4 r+ ~. N- ?$ S2 ~
  590. * @brief  DeviceQualifierDescriptor
    ! c- G! F# K. a8 m& n" z
  591. *         return Device Qualifier descriptor
      i# p4 X/ _! t
  592. * @param  length : pointer data length
    % r. k$ h% c, V2 K; P+ E: `# R; U
  593. * @retval pointer to descriptor buffer8 {+ O9 W; Y5 w* `% K
  594. */  O- T! D3 `; B+ w2 l4 P
  595. uint8_t  *USBD_MC_GetDeviceQualifierDescriptor (uint16_t *length)
    * B$ m4 B5 I1 r6 N2 j' l; Y
  596. {
    9 D3 ?$ X3 w5 M1 S! t
  597.   *length = sizeof (USBD_MC_DeviceQualifierDesc);
    + D0 h% M" j5 ?' W! W; t* U
  598.   return USBD_MC_DeviceQualifierDesc;
      Q7 w6 R7 a, f
  599. }: D3 D4 h3 G) }1 A6 _* K( b: m, j

  600. / q3 j0 z" y" H& ]/ k: Z
  601. /**7 G, Y' x* ?6 R% R. T+ |7 [
  602. * @brief  USBD_MC_RegisterStorage) Y; @7 M1 U/ X5 w  V
  603. * @param  fops: storage callback+ K! H# o+ s& Z% J! A  N
  604. * @retval status, y1 n3 O1 u* Q* A& s; ~, q# g
  605. */
    # j* i1 \5 U% n5 ^8 k6 G
  606. , x. N& q: M! Y& }. O$ @& W
  607. static uint8_t  USBD_MC_RxReady (USBD_HandleTypeDef *pdev)! M- Z  G1 N! V( A7 c
  608. {
    9 e# `2 y5 g5 c3 u; N7 X
  609.   USBD_CDC_HandleTypeDef   *hcdc;! X! ]7 ]3 F, P& E" ?% |4 Z& H1 `
  610.   ! z2 J% P& z0 C: G+ `
  611.   MC_Switch_CDC(pdev);
    . [0 n! F# Z# F- c+ w5 ^4 i
  612.   hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;2 k: n! P3 t8 e: Y/ o
  613.   , d, \) W: `3 {
  614.   if((pdev->pUserData != NULL) && (hcdc->CmdOpCode != 0xFF))* ^; S7 \. p) k3 A& B5 ~1 C
  615.   {* V0 r4 N3 q" O& k# P' O
  616.     ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(hcdc->CmdOpCode,9 M2 A) ~+ ^! ~
  617.                                                       (uint8_t *)hcdc->data,
    ( M& }/ O! Y. r7 P" n
  618.                                                       hcdc->CmdLength);0 J& A9 f/ l1 D
  619.       hcdc->CmdOpCode = 0xFF;
    ; U% `7 Y2 [, \* I9 ~8 M9 K( l* U
  620.       
    , S6 }( W) B: w/ V8 Y
  621.   }
    9 H! y9 l3 B, {' i: H' Z
  622.   1 ^1 A9 F0 K6 N1 H3 w7 e
  623.   return USBD_OK;  X  @3 Y6 F7 [$ p/ A; U
  624. }
    0 X$ |7 b- Y) R0 j+ r  Q

  625. ! ?( R) A$ q, u2 j+ m: D( z# R
  626. static void MC_Switch_MSC(USBD_HandleTypeDef *pdev)8 N# y2 \, e9 Y# Z
  627. {4 M0 @5 c# ?- y
  628.   static USBD_MSC_BOT_HandleTypeDef msc_handle;
    0 K) x0 h/ k$ [; h1 N
  629.   
    ' R% I- \/ l" f! X( S
  630.   USBD_MSC_RegisterStorage(pdev, &USBD_Storage_Interface_fops_FS);
    4 n% S2 K+ m. e$ k. U( i: E
  631.   pdev->pClassData = &msc_handle;; I$ b0 H5 u" M4 ]( M. H$ T
  632. }
    - Z; K1 L  H+ X" ^
  633. + H2 x; V9 [" w' A
  634. static void MC_Switch_CDC(USBD_HandleTypeDef *pdev)2 X7 q' c- q8 g
  635. {0 ]4 C4 T) x5 L) |) H. J6 N
  636.   static USBD_CDC_HandleTypeDef cdc_handle;
      O; h/ Q- B  f. ?
  637.   ' k" A4 e9 e- ~! e, B7 s
  638.   USBD_CDC_RegisterInterface(pdev, &USBD_Interface_fops_FS);
    + |. K" u$ H" b) R4 h+ a# M
  639.   pdev->pClassData = &cdc_handle;  h( o, T+ ~9 o5 w
  640. }
    2 x% ~- y- |) P. ~

  641. + |5 y+ k. c3 j4 a
  642. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
    ' B9 X7 u) j4 U, F% Q* Z( O' P, j" _
复制代码

" I! f) e0 l8 b/ ?$ g; ]. z' Y1 b通过以上修改后电脑电脑端显示USB复合设备MSC+CDC
: \/ c0 ?7 v$ o8 A7 h msc cdc.png . p' B( G# }- p# n. ^
( m5 T" c/ I7 j; b7 L
13.在usbd_cdc_if.c  CDC_Receive_FS   /* USER CODE BEGIN 6 */ 增加发送测试
# d$ O. b) d: p2 a4 [5 {" @) j
3 m1 J. i4 Q' J  Z1 D+ c
  1. static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)
    " Y) M( s; x0 O& [
  2. {
    $ r; j9 X, s1 W: v( g1 _
  3.   /* USER CODE BEGIN 6 */
    / S. u0 w+ l: Z+ U$ ~, V7 t' s) w
  4.   USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);
    " w% B8 x! b. ^! R
  5.   USBD_CDC_ReceivePacket(&hUsbDeviceFS);& ~# I( n' T3 v: {
  6.   
    $ v1 K+ [1 q, [+ C
  7.   CDC_Transmit_FS(UserRxBufferFS, *Len);      //把接收的返回( Y, I+ N4 N% }4 _2 e8 j, t
  8.   - S7 l4 d$ o. F+ n
  9.   8 ~- x  o2 D! P+ A- B& O
  10.   return (USBD_OK);' v+ l9 y' ~# O( _# E+ O0 t, d
  11.   /* USER CODE END 6 */& s0 \3 a! ~5 I
  12. }
复制代码

# ^  G6 R+ D7 T# {测试串口收发
' o+ ?4 T( o" C+ u6 G test.png
9 N1 o) s0 O# y  M5 t' Q
* |% d5 e) B& x% D5 m( z7 Z5 t4 W, w: O4 G* @
" p" `; [9 p6 p% z4 r  S
/ P: l6 v% u9 H, t

评分

参与人数 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
非常好的资料,对初学者很有帮助;
! Y: d; K7 L! l8 {5 f# j. l希望楼主多多分享,赠人玫瑰,手有余香,念念不忘,必有回响;
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
' t) q" K: e8 V, i- j完全按照楼主做法,在win10环境下U盘和串口都可以实现功能,在win7环境下,串口错误识别为mass storage ...

0 P. S8 U4 b& I' T, q是不是驱动问题,我电脑Win10
电子ai好者 回答时间:2020-11-19 12:57:48
hds1988 发表于 2020-6-29 09:52
7 x5 N  [& D! \( F% }) y' w完全按照楼主做法,在win10环境下U盘和串口都可以实现功能,在win7环境下,串口错误识别为mass storage ...
8 _1 ~5 t8 l5 n! R) B, {
微信图片编辑_20201119125724.jpg 我现在就是win7系统,和你一样的现象。请问你找到解决办法了吗?
( \; p$ X3 O2 p! N+ ~/ O! F- J% b
js123456 回答时间:2021-8-10 15:34:43
用stm32cubemx生成的项目cdc,在文件usbd_conf.c中,USBD_static_malloc申请内存是以USBD_CDC_HandleTypeDef为准,函数如下:
. u+ @& W( m  K) a. Hvoid *USBD_static_malloc(uint32_t size)
$ p1 |1 {) k  v" E2 \0 o# S! `9 f{
, A; X$ O: V7 @9 I+ j9 q& K( F& b6 S  static uint32_t mem[(sizeof(USBD_CDC_HandleTypeDef)/4)+1];/* On 32-bit boundary */
0 Z, e! I5 r! t, W) n" z- r, z  return mem;
5 s7 M; Z" _2 [% z1 F) u}2 g$ g3 }2 U+ P+ C

# X5 P: k- d; h$ x4 ~% n那么在组合设备中,USBD_MSC_BOT_HandleTypeDef和USBD_CDC_HandleTypeDef都需要申请内存,怎么操作?
! g. @/ s$ O0 y" j# @4 e3 {4 a3 Y5 s9 t8 c/ |8 I
js123456 回答时间:2021-8-10 15:35:35
hds1988 发表于 2020-6-28 23:47
  E( H. J% d" x$ e完全按照楼主的说明操作一顿后,不能识别出CDC,但是能识别MSC。MCU是F407VE
: F! B+ V& {" Q8 F0 I. @
有可能是函数USBD_static_malloc的问题
3 I) V% \! ^( K( l! f( j# L5 O! S

所属标签

相似技术帖

官网相关资源

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