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

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

[复制链接]
289466080 发布时间:2019-6-23 13:44
本帖最后由 289466080 于 2019-6-23 15:56 编辑 * G/ f8 z1 q2 G$ `: i
' \$ ^! |6 C- M6 P! i9 F1 c0 @
    最近做个USB复合设备CDC+MSC,在网上找了好多基本都是F103做的复合设备,带OTG芯片USB复合设备网上很少可能是我搜索的关键字不够理想有的不够全面,官方给了一个视频教程但是没有参考代码,社区里面有分享到github我按照后也不能实现,后结合F1与github分享的+官方视频,实现了在STM32F730R8T6上面USB复合设备,分享下怎样用cube生成的代码实现USB复合设备(带OTG的芯片).% }; J* y  f1 {. M+ A+ A: L
  D+ q% O3 n+ M  V7 R
参考:: _* _: s4 K! r% |
github分享
. I0 \( U) Z, `: U8 Thttp://github.com/uwyciw/CDC_MSC
6 A- ]4 U+ p$ F" F, i5 u1 D官方视频  m  B1 ]3 `- [6 d3 |
https://www.stmcu.org.cn/video/index/detail/id-3988/ D$ d) l  T3 @
F1032 ?% `4 T9 |1 b% F' b2 W
http://www.bbsmax.com/A/kjdwBXA5Np/
: C+ T4 d' F3 j  a0 ~3 ~; ]  _) F- U4 w9 k* q( G0 r- `- d
( p3 E4 @5 q: W* G
cube 5.2.1
" [7 t6 h  M5 fhal  stm32cube_fw_f7_v1150.zip
: D8 S- U. }/ ]' _  @: D9 ]1 h$ N# T4 e& n& f$ r4 u
USB为 USB_OTG_FS4 b7 k5 R2 O1 ]# S  m

4 K, d$ a5 [5 f8 G& N2 e1.先生成一个CDC工程下面配置图。- a) r7 w" F; z' w/ Z* t
RCC如图箭头其他默认
- h/ E; E/ l3 \% L- F RCC.png
) N/ _+ }' M  X, g) w5 ?USB_OTG_FS如图箭头其他默认
# ~8 G3 D6 P5 M+ w! y1 W USB_OTG_FS.png $ D) g( P3 Z4 }4 k9 n+ n, w
USB_Device
如图箭头其他默认1 Y7 C1 q" h8 o9 [5 K, ?' A5 ~
USB_Device.png 5 b7 ?* Y% L; g! E  [( L" U2 c2 J
Clock如图箭头其他默认我用的16M晶振比8M便宜+ v3 L+ }* N7 p
Clock.PNG
  r  o- Z2 U  W9 S6 s/ h; z
6 O& [; q  [" S  R! g1 `5 cProject如图箭头其他默认
; G$ k( w7 |: x* _$ d Project.png + |7 Q1 E) g/ L$ d& ?8 e+ z7 c
code如图箭头其他默认
! U' k( o" Z3 [$ Z; D& H! D  U code.png ( I% B2 j, x; i# c& R
2.同样生成一个新的MSC工程不可覆盖原本的工程只需修改下图与工程名其他一样, v: R3 g: E/ n1 |
' ]1 b" ?) H. G9 [% u
USB_Device-MSC.png . L" a$ P4 R. a$ w% Z
' f2 ?/ B" w. {; Y$ l

4 K. k9 W6 Z! `! z' ~# L( P8 E3.生成后把CDC工程下Src文件夹里的usbd_cdc_if.c与Inc下的usbd_cdc_if.h复制到MSC工程下Src与Inc文件夹里面,MSC工程下Src文件夹下新建usbd_composite.c与Inc下新建usbd_composite.h/ w- I) [  b4 |9 Y: k. y( E$ U
! ]: i" `2 z! w- `! a/ R9 L
h.png / J: T$ M; G# A& c+ V  z
/ v" r! K$ Z/ X# O! v6 Z
4.把CDC工程\Middlewares\ST\STM32_USB_Device_Library\Class目录下的CDC文件夹复制到MSC工程下见图
" W* _  f6 ]6 L  t" G; J! [ cdc.png
8 m- Z2 I5 [4 L. u8 h1 `5.添加CDC路径; h6 R5 R, J# B! \% }
; f5 d, h2 |0 d$ o# Q% e3 v; c
CDC-PATHS.png , m, ?+ Z) E3 |# K1 `8 _
1 ^- |, T8 T0 c. T. h! d
6.在工程中添加usbd_cdc.c usbd_cdc_if.c usbd_composite.c见图! Z. O+ w' ?" c! d
keil-add.png ; i- n0 V" s$ |9 ~+ P, P
, n8 ?3 K9 W  r# \+ \
7. usbd_conf.h 把USBD_MAX_NUM_INTERFACES值 1修改为3! t5 Q, z% c' c8 w* k- w3 D: k
  1. /*---------- -----------*/
    ; l3 ^& t4 f0 g7 p; c+ S: X
  2. #define USBD_MAX_NUM_INTERFACES     3U    //1U
    7 t4 Y& B0 t5 R/ N* |' y% T3 l
  3. /*---------- -----------*/
复制代码
8. usbd_cdc.h 修改CDC_IN_EP CDC_OUT_EP CDC_CMD_EP
1 O7 g% s! t4 J3 V" T! W, S
  1. //#define CDC_IN_EP                                   0x81U  /* EP1 for data IN */: d7 @. Z( o' w
  2. //#define CDC_OUT_EP                                  0x01U  /* EP1 for data OUT */
    2 u. ~' x. s; c! W% ^$ _
  3. //#define CDC_CMD_EP                                  0x82U  /* EP2 for CDC commands */
    2 I9 h. D8 ?5 ^) s, X6 z
  4. #define CDC_IN_EP                                   0x83  /* EP1 for data IN */
    + z: l6 g/ z; i  q6 n
  5. #define CDC_OUT_EP                                  0x03  /* EP1 for data OUT */3 t3 b7 u6 s  n- v7 T+ G
  6. #define CDC_CMD_EP                                  0x82  /* EP2 for CDC commands */
复制代码
9. usbd_conf.c  USBD_LL_Init中新增  }/ S$ p2 P2 ~5 y
  1.   HAL_PCDEx_SetRxFiFo(&hpcd_USB_OTG_FS, 0x80);# t  Q& I3 c* x- F5 S) H
  2.   HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 0, 0x40);
    7 ?: n5 T% V. J
  3.   HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 1, 0x80);9 H/ q, i# R" M
  4.   3 n3 s$ w# P/ B' h& `
  5.   HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 1, 0x40);   //新增
    0 }  U" M( ]$ \$ }( E. m4 l) u
  6.   HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 3, 0x40);
复制代码
10. usb_device.c 修改MX_USB_DEVICE_Init与SER CODE BEGIN Includes中新增usbd_composite.h
/ B( D% r4 a0 Y; W& T- `& p$ G

7 }7 Y, T# h- p) B$ K
  1. # A: ^2 U3 U" C6 w
  2. /* USER CODE BEGIN Includes */" C* X! I4 s5 i9 M
  3. #include "usbd_composite.h"
    7 e! D* A" E% G+ q6 J/ h
  4. /* USER CODE END Includes */* m7 H- W5 Z4 c3 [! p  t0 v
  5. * d) O. c5 p+ Z, @$ @; G7 A' R
  6. void MX_USB_DEVICE_Init(void)
    + e6 S% V4 o+ I2 A% b
  7. {; n& O9 ^! r) v+ T& N- Y
  8.   /* USER CODE BEGIN USB_DEVICE_Init_PreTreatment */" `- P( W" H% L+ q( v( F: @( a
  9.   ! H* C- a8 d$ T
  10.   /* USER CODE END USB_DEVICE_Init_PreTreatment */8 l1 O: T+ Q, P- V. t3 ^
  11.   " ^( A# L1 q; F6 P
  12.   /* Init Device Library, add supported class and start the library. */
    " d' {* @$ h3 `% q% E7 H2 Q: }
  13.   if (USBD_Init(&hUsbDeviceFS, &FS_Desc, DEVICE_FS) != USBD_OK)4 `" p( O5 S4 Q
  14.   {
    7 q# W. o' x- q, L$ [* G
  15.     Error_Handler();
    4 c3 |( H% Z/ {& o" h) W
  16.   }- K- ^$ S1 P3 h2 t
  17.   if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_COMPOSITE) != USBD_OK)  //新增
    / r0 l6 o5 y7 x, j$ M
  18.   {
    ! W6 R3 T$ q  x% \, e  e
  19.   Error_Handler();
    8 w1 G3 Y+ s7 i2 V8 K, ]7 p  s
  20.   }/ A: j: z4 @# C
  21. //  if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_MSC) != USBD_OK)0 v# \1 m2 O3 k7 q, ~; ?5 K
  22. //  {9 e7 g- I: l: @" a" `+ L$ n
  23. //    Error_Handler();
    * p2 [: m# t. f, q
  24. //  }6 p% c2 g( q# q) ~0 T/ A1 }; e' Q" A% }9 x
  25. //  if (USBD_MSC_RegisterStorage(&hUsbDeviceFS, &USBD_Storage_Interface_fops_FS) != USBD_OK)8 z9 q$ V% k: q5 d# v5 q
  26. //  {- D, G8 b4 Z5 }8 e
  27. //    Error_Handler();
      H; \! T/ K9 t1 j, z! j
  28. //  }
    8 `7 \, `, P. E5 L1 o# f
  29.   if (USBD_Start(&hUsbDeviceFS) != USBD_OK)
    % M: i/ D0 u0 d: e  f" Z
  30.   {8 K! F# `$ x; i: X: |
  31.     Error_Handler();  e9 c0 t& r( r/ s& l
  32.   }
    7 i3 R# j9 U8 R$ s8 I5 k( m

  33. 0 V  V# q2 @3 v" A4 ^
  34.   /* USER CODE BEGIN USB_DEVICE_Init_PostTreatment */( k2 E3 U8 a' ?# p3 j6 o
  35. //  if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_COMPOSITE) != USBD_OK)  //新增
    ; x' N1 {0 x; k# ~
  36. //  {
      Y+ _7 j7 w* {2 A" @2 S$ `( X( A
  37. //  Error_Handler();7 Y; \& q5 w8 D8 Q9 \
  38. //  }
    1 S1 t4 Z: t# k  w# T
  39.   /* USER CODE END USB_DEVICE_Init_PostTreatment */- S" t2 m1 U  E$ |7 v
  40. }
复制代码
2 [+ q( E+ u) l4 O) F) m' T
6 a; a8 k. q- x1 O! p
11.在usbd_composite.h中新增代码8 ]0 a' v7 A6 R; P" B4 z9 ^# H

  1. 2 e/ A2 I  l' U0 u4 S, A6 m
  2. #ifndef __USBD_COMPOSITE_H( }- ~, G% x: J' u& c" d/ L
  3. #define __USBD_COMPOSITE_H( @9 k, Q8 C6 C3 g  i
  4. * [. {2 H0 p. M# g1 V( L$ }
  5. #include  "usbd_ioreq.h") l& L, V9 |' N" ^- _4 X
  6. #include "usbd_cdc.h"" v' b% v/ h, t! v* ]
  7. #include "usbd_msc.h"
    7 ]4 P/ P: ?: f  M
  8. 1 |* T7 h, q6 f0 D" b
  9. #define MC_MAX_FS_PACKET            0x40
    # P% c: @1 `2 N% X
  10. & D' H. g% n' j1 F1 O8 s
  11. #define USB_MC_CONFIG_DESC_SIZ      106 % z* `) F: O/ W2 ]
  12. + v& U; o+ Q6 K# J8 m9 R
  13. #define MC_MSC_EPIN_ADDR                MSC_EPIN_ADDR ; Q5 N8 j5 }3 }9 E
  14. #define MC_MSC_EPOUT_ADDR               MSC_EPOUT_ADDR , w# |: c7 W% V. f2 u% a! ~
  15. . l+ l6 B: B+ r5 O
  16. #define MC_CDC_IN_EP                   CDC_IN_EP
    9 \) \# d; d, `" O) ^6 w% O0 J
  17. #define MC_CDC_OUT_EP                  CDC_OUT_EP  
    ; ?3 Y% f. x# e, D# B
  18. #define MC_CDC_CMD_EP                  CDC_CMD_EP
    ' U7 w% K9 \) |$ u% {: \0 ?9 M4 O

  19. / G/ V' v" E3 W8 w& [
  20. extern USBD_ClassTypeDef  USBD_COMPOSITE;
    " Y" z  v+ j# r9 }
  21. 3 Z, Y! v: _3 m" |8 Z
  22. #endif  /* __USBD_MC_H */
    6 k/ f: ]( |/ c. f3 t8 o$ D+ p& q

  23. 9 L1 T; D; ^: P+ x
复制代码
1 O0 x( o( W4 a. @& L
/ e1 q) D# H' M1 `  [$ t( i  F' d' B3 p
12.在usbd_composite.c中新增代码
2 `# s0 f6 Y: T
# S6 {  n" v( `: [
  1. ( B7 H, ^- N8 U
  2. #include "usbd_composite.h"
    8 |& h# }) a  W  R0 q/ H1 q
  3. #include "usbd_def.h", N& ^" V2 I8 U4 \
  4. #include "usbd_msc.h"
    . Q7 K9 w9 I: L8 T& |
  5. #include "usbd_cdc.h"
    + [' u4 m/ o4 A" u2 p) U
  6. #include "usbd_storage_if.h"
    3 j8 _: R, f9 Q" q9 q* |' X: A
  7. #include "usbd_cdc_if.h"
    / `+ |% |/ \3 q
  8. ! {' x/ w( F# i: B
  9. /** @defgroup MC_CORE_Private_FunctionPrototypes( N5 x# u/ z: V
  10.   * @{" K0 B8 ^* }9 G
  11.   */% E& o2 e: {3 a+ g
  12.   
    ; S! H; ~: R8 j2 H  m' O5 ]( h
  13. USBD_CDC_HandleTypeDef     *pCDCData;
    4 X8 A. T- R( E
  14. USBD_MSC_BOT_HandleTypeDef *pMSCData;
    4 i, A4 U- C2 m! T1 H' o- f( C3 x
  15.   ) ?. {+ q. C( f0 e; v
  16. uint8_t  USBD_MC_Init (USBD_HandleTypeDef *pdev,
    + E6 w6 G0 {2 C0 H" D8 ^3 w- D9 i
  17.                             uint8_t cfgidx);  \9 w& y! Q/ [3 P+ U2 w3 y' n
  18. " u7 J* j; K# T$ g
  19. uint8_t  USBD_MC_DeInit (USBD_HandleTypeDef *pdev,
    ) L' `+ P0 Y; i8 m4 B7 @
  20.                               uint8_t cfgidx);
    * K8 K0 C. ?1 }8 B# l  J
  21. 4 I: U& R" t  P& @+ v; H& h5 F% F  G. L2 e
  22. uint8_t  USBD_MC_Setup (USBD_HandleTypeDef *pdev,
    9 B0 B# W- G# L+ L
  23.                              USBD_SetupReqTypedef *req);% v. v( M9 [: [( s2 S3 c5 s

  24. 9 Z- n( j3 c) I8 y/ \
  25. uint8_t  USBD_MC_DataIn (USBD_HandleTypeDef *pdev,
    3 F) @  [- _* n& m
  26.                               uint8_t epnum);
    3 z2 f8 ]" S. O" v, v% @
  27. ) u9 T  Y7 Y8 F
  28. 5 u& J$ B! b$ F. G
  29. uint8_t  USBD_MC_DataOut (USBD_HandleTypeDef *pdev,
    * p, P" F$ ], d+ k* s6 M: v
  30.                                uint8_t epnum);6 z& w( Y, T& j" S) y
  31. 8 I$ f6 b# h- t$ p
  32. uint8_t  *USBD_MC_GetHSCfgDesc (uint16_t *length);
    # J1 s  i$ R) E  f( I6 r8 `
  33. ) F( E, f4 Q! z8 U5 z4 @7 }
  34. uint8_t  *USBD_MC_GetFSCfgDesc (uint16_t *length);
    % g3 Q, S% A( j. \
  35. 5 H9 I' b5 Y9 n6 `
  36. uint8_t  *USBD_MC_GetOtherSpeedCfgDesc (uint16_t *length);; \8 X. N- H, i0 d$ G
  37. & m4 y5 Y  r2 p/ g3 G- P! Y2 y
  38. uint8_t  *USBD_MC_GetDeviceQualifierDescriptor (uint16_t *length);
    4 F$ F) h) V& p

  39. $ r2 [9 @4 g+ S0 O' {0 f
  40. static uint8_t  USBD_MC_RxReady (USBD_HandleTypeDef *pdev);+ @5 b% ^$ K6 y/ l/ H: [* K
  41. static void MC_Switch_MSC(USBD_HandleTypeDef *pdev);
    % u9 ~% w  {& p0 X5 k, w
  42. static void MC_Switch_CDC(USBD_HandleTypeDef *pdev);; y1 Z2 ~) `* J( \0 g. N
  43. 2 V5 d7 r1 @8 C5 e: `# i. C: J
  44. /**$ r: I7 O4 s6 k3 l$ Y& _
  45.   * @}4 q7 b& k' I# h, G, P% T; `
  46.   */
    ) g0 @2 a' r; w& }$ d
  47. extern USBD_HandleTypeDef hUsbDeviceFS;
    : N( r3 P* e0 @/ U  w* ~3 e

  48. 2 A* n! ?! R0 I8 ~
  49. 0 l$ D/ v. i3 v+ t! F/ O- c$ B$ }) O
  50. /** @defgroup MC_CORE_Private_Variables
    3 a! I# j0 K5 l) I+ E8 c" N
  51.   * @{
    # G* O# b6 P) r+ q& G/ w
  52.   */ " |3 [# ?3 @# B
  53. USBD_ClassTypeDef  USBD_COMPOSITE =
    ! o  l7 X! Q. p/ F, e
  54. {7 i8 `. S0 T: X. G2 ^" @  k
  55.   USBD_MC_Init,
    / ~4 j; i6 [! T7 z. u4 B
  56.   USBD_MC_DeInit,1 \" F( r* x1 T' t9 o7 Y- v5 c
  57.   USBD_MC_Setup,
    1 R& c' O6 w" ~; S7 C+ M
  58.   NULL, /*EP0_TxSent*/  : {4 }- t3 \$ q+ _4 t1 ~
  59.   USBD_MC_RxReady, /*EP0_RxReady*/
    " s9 K' T2 e- [- \# D& S
  60.   USBD_MC_DataIn,7 u4 S0 ~( e0 A/ c, L% v% ?
  61.   USBD_MC_DataOut,
    1 C1 f8 S5 d1 o- T$ d' v  F
  62.   NULL, /*SOF */ # N( B! C" V2 F6 ^* J' p) j
  63.   NULL,  
    & ^9 T/ |# Y/ z* @6 L
  64.   NULL,     4 F0 l: Y; R+ \0 I
  65.   USBD_MC_GetHSCfgDesc,) g! m# B6 c/ F- m% A4 ^
  66.   USBD_MC_GetFSCfgDesc,  
    + I8 I7 H$ c1 W+ i, K- }
  67.   USBD_MC_GetOtherSpeedCfgDesc,
    ) E' `& C, T4 Y3 L, Z$ s2 k& Y7 y1 b
  68.   USBD_MC_GetDeviceQualifierDescriptor,: m, g; j$ [! M' M
  69. };
    0 l0 d, p* _# B/ Y  ?
  70. 0 E7 L5 Z. l( }' X6 Q8 {9 A' C
  71. /* USB Mass storage device Configuration Descriptor */
    ( W1 l2 p- {9 @( R
  72. /*   All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */& A8 g3 D$ b; W7 H" F5 a% {
  73. uint8_t USBD_MC_CfgDesc[USB_MC_CONFIG_DESC_SIZ] =
    ) m/ O* T9 R/ K( t6 N9 o/ {
  74. {! p2 l+ O1 m/ e
  75.   /*Configuration Descriptor*/1 D% i8 j* P) C, b" H; x8 z
  76.   0x09,   /* bLength: Configuration Descriptor size */
    7 u- j- r- _  @# \0 w3 D4 L6 U
  77.   USB_DESC_TYPE_CONFIGURATION,      /* bDescriptorType: Configuration */
    , w1 X, L! r1 ~3 @( {
  78.   USB_MC_CONFIG_DESC_SIZ,                /* wTotalLength:no of returned bytes */
    $ V- o1 T  Y$ D/ H. I
  79.   0x00,
    & B0 s' j& g! s* T) X' m' ^
  80.   0x03,   /* bNumInterfaces: 3 interface */
    - d) a6 |3 x" l# h9 h4 E
  81.   0x01,   /* bConfigurationValue: Configuration value */
    ' g' X9 ]" H( e  @; L; ~% \
  82.   0x00,   /* iConfiguration: Index of string descriptor describing the configuration */8 ~: c2 z" D4 |" {
  83.   0xC0,   /* bmAttributes: self powered */+ ^+ A7 X" _4 ?+ ?! j- J# x  a: f
  84.   0x32,   /* MaxPower 0 mA */# ]. A/ F8 k* V' ^! F
  85.   
    1 _; c+ a* M) f/ A
  86.   /*---------------------------------------------------------------------------*/+ P/ |( d% w$ Y) ~$ o2 u
  87.   // IAD
    * n7 m( T0 K6 i% W3 o
  88.   0x08,        //描述符大小
    * Q7 N, c) T; ^! N; `
  89.   0x0B,        //IAD描述符类型8 D  m5 [( L, k
  90.   0x00,        // bFirstInterface ; w/ ]& E1 b: I( T1 `: c
  91.   0x02,        // bInterfaceCount
    2 }# P1 ?5 W* {% e+ ]/ n- e6 _
  92.   0x02,        // bFunctionClass: CDC Class/ q+ Q% V) G) ~9 k
  93.   0x02,        // bFunctionSubClass
    8 _2 K- C5 C( u: q! A6 I
  94.   0x01,        // bFunctionProtocol
    3 e0 U- M, J# m) r
  95.   0x00,        // iFunction      
    ) Z5 }2 m, \" z$ e& C; r' H2 [
  96.   
    - b( p. k6 x: M/ n
  97.   /*---------------------------------------------------------------------------*/
    : a; v8 j9 A0 F! k5 I% ^; j6 M; j# S
  98.   /*Interface Descriptor */
    ! R8 u1 G- c3 w1 `- E3 d. T. E: `
  99.   0x09,   /* bLength: Interface Descriptor size */1 o% ~: q. ^4 {; l
  100.   USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: Interface */. H% F* e' O9 H( g/ D8 ~: X" r3 j! s
  101.   /* Interface descriptor type */$ T0 b' N7 x5 J; I5 y: c
  102.   0x00,   /* bInterfaceNumber: Number of Interface */4 }5 D/ z- L5 ?
  103.   0x00,   /* bAlternateSetting: Alternate setting */
    ) ]+ r3 M% R* m# d
  104.   0x01,   /* bNumEndpoints: One endpoints used */
    : }$ E* R) N4 |. k' T! m
  105.   0x02,   /* bInterfaceClass: Communication Interface Class */; V( g/ @5 i+ e* ^, j
  106.   0x02,   /* bInterfaceSubClass: Abstract Control Model */. d, W( |- e+ i- c1 A
  107.   0x01,   /* bInterfaceProtocol: Common AT commands */, c. q/ z! f6 q1 Z
  108.   0x00,   /* iInterface: */
      m1 V( k5 L5 }
  109.   7 ^2 q6 l& @% j: i: ?
  110.   /*Header Functional Descriptor*/
    6 K0 n5 n9 f* B9 W
  111.   0x05,   /* bLength: Endpoint Descriptor size */7 ]* Z0 y3 _! q# \1 k+ @' K
  112.   0x24,   /* bDescriptorType: CS_INTERFACE */9 V" p4 Z/ m; |
  113.   0x00,   /* bDescriptorSubtype: Header Func Desc */
    6 M( r+ K1 r% T* J7 C* J( _) S
  114.   0x10,   /* bcdCDC: spec release number */' q% w1 {0 @+ j1 Z7 ^% `
  115.   0x01,
    & c+ f4 P0 w1 F# E+ B
  116.   
    ) ^5 a. C6 I5 x* ]9 V2 T% o
  117.   /*Call Management Functional Descriptor*/
    & _( ]/ {& ^' g" @
  118.   0x05,   /* bFunctionLength */; s7 X+ O" ^9 c1 O# p6 H
  119.   0x24,   /* bDescriptorType: CS_INTERFACE */
    + T/ w/ X9 G' e. K6 Y0 U5 O( u
  120.   0x01,   /* bDescriptorSubtype: Call Management Func Desc */
    / u" s' V6 _( S. Y. S) B
  121.   0x00,   /* bmCapabilities: D0+D1 */* a) _1 L; H1 ?0 E9 P$ l% `3 B) h$ R5 X
  122.   0x01,   /* bDataInterface: 1 */
    ! E' f' E/ K% B3 D! b
  123.   8 y( i. S. g9 c0 t
  124.   /*ACM Functional Descriptor*/
    $ M  S& c( X8 z0 s! z
  125.   0x04,   /* bFunctionLength */( Z- F/ s  J' ^+ v1 s
  126.   0x24,   /* bDescriptorType: CS_INTERFACE */
      ?6 Y4 c  h! t( o
  127.   0x02,   /* bDescriptorSubtype: Abstract Control Management desc */
    + s4 x# y% M) O3 y* W! G
  128.   0x02,   /* bmCapabilities */
    + A0 y8 J" A, r
  129.   : K8 Y( |; K) I# v
  130.   /*Union Functional Descriptor*/
    0 d3 a. \8 W' S" D! ~: Y5 @
  131.   0x05,   /* bFunctionLength */
    ) A  a5 m; \2 x4 l/ M3 O: a% X
  132.   0x24,   /* bDescriptorType: CS_INTERFACE */# _% g8 i- S& r
  133.   0x06,   /* bDescriptorSubtype: Union func desc */
    9 n, H$ {1 G* M7 m
  134.   0x00,   /* bMasterInterface: Communication class interface */  s8 r- Y" v3 j& M, a1 |
  135.   0x01,   /* bSlaveInterface0: Data Class Interface */
    + a+ S2 N1 O  T* `
  136.   & T: q& u8 M. I, E; b* Y
  137.   /*Endpoint 2 Descriptor*/& a# }  e3 T& \3 X' b
  138.   0x07,                           /* bLength: Endpoint Descriptor size */
    # Y9 m3 B- |) a% Y
  139.   USB_DESC_TYPE_ENDPOINT,   /* bDescriptorType: Endpoint */
    , \: A0 J5 C) P% B
  140.   MC_CDC_CMD_EP,                     /* bEndpointAddress */
    / B9 \/ e9 G: {9 T9 M1 t/ R
  141.   0x03,                           /* bmAttributes: Interrupt */
    9 @' @5 _5 U: ^# S' E; _5 I: T
  142.   LOBYTE(CDC_CMD_PACKET_SIZE),     /* wMaxPacketSize: */
    & t8 _) K: d# I4 M8 [
  143.   HIBYTE(CDC_CMD_PACKET_SIZE),
    . \+ j) C8 @! t  |- L4 R; S/ T$ w
  144.   0x10,                           /* bInterval: */ 6 @% V) b, T: F
  145.   
    ! W* t  K& p/ ~+ c7 |
  146.   /*Data class interface descriptor*/
    7 P! \5 j, u; V0 V) Z! }
  147.   0x09,   /* bLength: Endpoint Descriptor size */) v) B2 c5 e/ {7 u1 x
  148.   USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: */; _3 B0 f( O$ d9 X
  149.   0x01,   /* bInterfaceNumber: Number of Interface */% T8 X4 {/ b3 B' d" W% E
  150.   0x00,   /* bAlternateSetting: Alternate setting */- i- j( X3 N% k+ t. Q
  151.   0x02,   /* bNumEndpoints: Two endpoints used */4 T$ p% |+ z. X
  152.   0x0A,   /* bInterfaceClass: CDC */
    , t" _) L! S: t3 T% |  x
  153.   0x00,   /* bInterfaceSubClass: */( y3 V6 H7 A" N0 a
  154.   0x00,   /* bInterfaceProtocol: */
    8 l1 B9 v* B3 j0 L4 I1 ^, e
  155.   0x00,   /* iInterface: */
    2 ]$ G$ c' x6 [* q4 T" k- c
  156.   " h  @% M' c3 w/ w! g  v
  157.   /*Endpoint OUT Descriptor*/5 o6 l9 g& M: d* m+ F4 I& j
  158.   0x07,   /* bLength: Endpoint Descriptor size */1 _; h9 b+ T9 o9 k8 D+ c9 b
  159.   USB_DESC_TYPE_ENDPOINT,      /* bDescriptorType: Endpoint */1 h8 R' t- m& L7 e9 L' c, A
  160.   MC_CDC_OUT_EP,                        /* bEndpointAddress */
    8 c# K" m; r4 K  N* D4 C4 z
  161.   0x02,                              /* bmAttributes: Bulk */$ T9 T- p) J2 O6 i
  162.   LOBYTE(MC_MAX_FS_PACKET),  /* wMaxPacketSize: */9 E/ N, k2 r$ L7 k
  163.   HIBYTE(MC_MAX_FS_PACKET),
    5 U* s. w, J7 |! x0 `
  164.   0x00,                              /* bInterval: ignore for Bulk transfer */
    & M0 d- g9 Q" z9 a0 @9 z
  165.   : X% }3 D- w' k& P+ ~: c! j
  166.   /*Endpoint IN Descriptor*/5 X- D# C- c2 c- l
  167.   0x07,   /* bLength: Endpoint Descriptor size */5 N, h$ j; l! d$ _0 j
  168.   USB_DESC_TYPE_ENDPOINT,      /* bDescriptorType: Endpoint */3 b3 k) ?( U3 L  ]7 t4 }. x) J2 Q
  169.   MC_CDC_IN_EP,                         /* bEndpointAddress */- Q0 U2 N$ Z+ n# j; i1 m& ~
  170.   0x02,                              /* bmAttributes: Bulk */
    4 E9 R4 O! M0 f  |* ~" ?5 Q
  171.   LOBYTE(MC_MAX_FS_PACKET),  /* wMaxPacketSize: */2 }6 b% w1 b0 N2 [* I
  172.   HIBYTE(MC_MAX_FS_PACKET),
    , P9 ?! j2 y5 F* b- U
  173.   0x00,                               /* bInterval: ignore for Bulk transfer */5 K2 ^. O# R: _, q

  174. " X+ [9 }* `1 t
  175.   /*---------------------------------------------------------------------------*/
    ' Y. }# o) N" k; c0 G% P1 ^$ x
  176.   // IAD
    ' g& J0 k+ s2 n3 H7 G0 e
  177.   0x08,        //描述符大小7 Q- o' w0 N3 ?" ?
  178.   0x0B,        //IAD描述符类型. |/ P5 u, Z% h- \# T
  179.   0x02,        // bFirstInterface, D6 g( |* Q# k. x
  180.   0x01,        // bInterfaceCount) a3 M8 _/ V/ s( X! ]) p6 p" N
  181.   0x08,        // bFunctionClass: MASS STORAGE Class
    - P* Y# k. b2 ]% @# ?
  182.   0x06,        // bFunctionSubClass( A$ }3 {9 f8 O1 l* C( J6 R
  183.   0x50,        // bFunctionProtocol
    6 \) U8 q' ^& l6 q
  184.   0x01,        // iFunction   
    - \! X: z# X2 e6 }" n; M, x

  185. ' @! T6 y: h+ C3 W" {7 p5 J
  186.   /********************  Mass Storage interface ********************/) ^: g7 @: x' n; O1 \/ _8 e
  187.   0x09,   /* bLength: Interface Descriptor size */
    & K% V7 ^' U) r" u3 A
  188.   0x04,   /* bDescriptorType: */
    # I2 t) ?" [+ p* Z& z: X0 E
  189.   0x02,   /* bInterfaceNumber: Number of Interface */
    1 L6 b) v% r8 \
  190.   0x00,   /* bAlternateSetting: Alternate setting */
    - m# y& V8 e' z" Y2 y
  191.   0x02,   /* bNumEndpoints*/
    . W1 G. K! Q8 a5 z+ n7 x3 |
  192.   0x08,   /* bInterfaceClass: MSC Class */
    ( [9 U) e( [% G- r% p* L4 Q
  193.   0x06,   /* bInterfaceSubClass : SCSI transparent*/" y# w7 h; `! B. q
  194.   0x50,   /* nInterfaceProtocol */
    # d! k, U* o2 c! r. S0 s
  195.   0x05,          /* iInterface: */
    ) W7 D* E( v# F( \% I
  196.   /********************  Mass Storage Endpoints ********************/' \# q: N1 q7 D/ q) D- t
  197.   0x07,   /*Endpoint descriptor length = 7*/) K4 T, [, |: s. P) G
  198.   0x05,   /*Endpoint descriptor type */
    7 K/ n  Z8 ?- g5 j2 y: L5 Q
  199.   MC_MSC_EPIN_ADDR,   /*Endpoint address (IN, address 1) */
    9 j3 p0 [; E! m: Y' T6 f+ _4 S
  200.   0x02,   /*Bulk endpoint type */$ S7 g) R9 S8 V$ Q1 ?
  201.   LOBYTE(MC_MAX_FS_PACKET),$ B8 g+ a3 s9 F# J' d: |
  202.   HIBYTE(MC_MAX_FS_PACKET),  N6 t( y/ v' T1 M& Q- O
  203.   0x00,   /*Polling interval in milliseconds */2 B( L% z" S' r
  204.   1 }4 H. ^" V2 W# R
  205.   0x07,   /*Endpoint descriptor length = 7 */
    - w! c) _8 l+ @
  206.   0x05,   /*Endpoint descriptor type */% ~: B# N4 `; q; L
  207.   MC_MSC_EPOUT_ADDR,   /*Endpoint address (OUT, address 1) */
    . [$ p3 w  B% f1 f; {
  208.   0x02,   /*Bulk endpoint type */( h5 E  b# J7 E" ^: y3 g
  209.   LOBYTE(MC_MAX_FS_PACKET),0 h5 v3 c8 M. {1 w; r, }# f
  210.   HIBYTE(MC_MAX_FS_PACKET),( d( u' L' ^% ^% t4 l0 h2 ], ^
  211.   0x00     /*Polling interval in milliseconds*/
    " w( @) {8 P: B' v$ Q
  212. };" F3 \: p7 \7 y1 o
  213.   , Z: b$ b+ {( p2 t8 _
  214. uint8_t USBD_MC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] =
    7 o: s% m; _) G/ l- t
  215. {
    5 B# \0 r5 I+ a# H. s8 n
  216.   USB_LEN_DEV_QUALIFIER_DESC,3 [0 G, P1 j% Z- o  o; {
  217.   USB_DESC_TYPE_DEVICE_QUALIFIER,; ~2 Z9 _( G9 T% V9 F. ]7 Q
  218.   0x00,
    5 H: n4 K; C/ _
  219.   0x02,- d7 m, l5 R; @+ T
  220.   0x00,* ]0 U, q/ D: Y1 y* p
  221.   0x00,  m# n1 ~& B+ T5 k/ G
  222.   0x00,
    - y/ Q+ z* h8 q/ ?, j
  223.   MC_MAX_FS_PACKET,
    ; x; t1 B. G& \! @, X+ J5 |6 {. \
  224.   0x01,
    9 \# }0 a& q. i9 f9 S. S9 d
  225.   0x00,' N1 |1 `1 @( _/ f9 ^4 W
  226. };* J: D5 g5 C3 p  y

  227. + b9 b( Y9 c6 T" x) V
  228. /**0 p) i3 b7 R, d6 a
  229.   * @brief  USBD_MC_Init; X7 j7 j% P/ Q& n* k
  230.   *         Initialize  the mass storage configuration
    # z3 ?( s+ J# d# }3 T; n
  231.   * @param  pdev: device instance
    1 P3 L# b, W& H8 R/ i
  232.   * @param  cfgidx: configuration index
    8 _/ u8 g  }* l& E; Z
  233.   * @retval status" g: a6 \8 g$ e; j& z
  234.   */
    9 Z$ ]2 `" F" Y; a( K; N) u
  235. uint8_t  USBD_MC_Init (USBD_HandleTypeDef *pdev, uint8_t cfgidx)
    : j  o& Z, x! c
  236. {% C; o+ W; u7 T, w/ |
  237.   uint8_t ret = 0U;
      B& L0 D( o1 e$ r7 n* u
  238. . x8 A/ j5 J8 ^  q4 D" C$ E
  239.   
    2 Z, D6 Z# W7 i% c; ^  P
  240.   USBD_CDC_HandleTypeDef      * hcdc;) z+ F, d' T- L0 l6 J( R
  241.     ) S$ Q/ }+ j; Z# D& h  u0 o
  242.   MC_Switch_CDC(pdev);
    " j7 t6 A3 L/ m
  243.     e) }' F! e- V5 S9 y
  244.   USBD_LL_OpenEP(pdev,1 b: Q" `0 v% |* B
  245.                  MC_CDC_IN_EP,
      h4 |4 O) h1 @% K* L* I+ j% W
  246.                  USBD_EP_TYPE_BULK," d$ }, f4 U. i' n+ v5 z2 u
  247.                  MC_MAX_FS_PACKET);) [5 `# D, B$ O' t/ P" Y* I
  248.   
    & u, D' @$ G- m. l( u8 \& I
  249.   USBD_LL_OpenEP(pdev,+ F! z& q, s# J. Y
  250.                  MC_CDC_OUT_EP,7 Z; b( |8 [- a- x
  251.                  USBD_EP_TYPE_BULK,
    3 G$ d: S, g  J& y9 F6 J5 E# L
  252.                  MC_MAX_FS_PACKET);3 p4 ~; r0 d% J. E( f3 `
  253.   ' I! ~+ a+ T: U8 Y7 _
  254.   USBD_LL_OpenEP(pdev,) U; l/ z0 h" K8 i* C9 I+ H" c
  255.                  MC_CDC_CMD_EP,
    3 r) {( l) S  M! w
  256.                  USBD_EP_TYPE_INTR,* o1 ^5 D8 G$ H3 M
  257.                  CDC_CMD_PACKET_SIZE);
    : Y9 E4 ~/ [* k  X+ j; g! u
  258. ' ]- C% v! E+ a1 a, ^
  259.   hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
    2 Q) o: p. s& F  @
  260. & [3 e- [. D: n2 x& D5 \5 g6 V
  261.   ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Init();, ^3 [- C9 ?! {- Z- y" H* G' `+ s
  262.   
    - q" b3 @1 I. w# v8 d
  263.   hcdc->TxState =0;8 ^9 s5 ]2 K+ ^+ ]; t+ A
  264.   hcdc->RxState =0;/ X, {2 W: U0 W. Z# |
  265.   6 `/ f! o% I/ ^, ]# [
  266.   USBD_LL_PrepareReceive(pdev,7 k  o1 H! F) m2 H/ }
  267.                          MC_CDC_OUT_EP,
    * K* M/ n6 R2 w1 {* E2 I- k
  268.                          hcdc->RxBuffer,, Q2 A7 N# P( @9 `
  269.                          MC_MAX_FS_PACKET);
    $ t$ _4 e. k$ u# s0 h3 F: b' _

  270. - [5 [5 \6 [1 a3 f* r4 j5 ?2 u
  271.   pCDCData = pdev->pClassData;
    # A; N8 l8 j# ^" p) E) B" K

  272. : j8 u  l1 y. n# p
  273.   MC_Switch_MSC(pdev);
    # U9 \: T5 `9 \: l/ \0 y/ g
  274.   0 g) x0 m/ v7 G  q5 V
  275.   USBD_LL_OpenEP(pdev,3 M3 D- l8 l, _2 ]& y6 O& ]- B
  276.                  MC_MSC_EPOUT_ADDR,1 ?8 ]1 D' N- f3 R( T9 u. P
  277.                  USBD_EP_TYPE_BULK,2 Q0 F# \' Q  b: I) j3 M0 D# f; P
  278.                  MC_MAX_FS_PACKET);
    3 @6 T( G$ L. V
  279.   6 r1 K3 }0 h* _" X4 F
  280.   USBD_LL_OpenEP(pdev,, I: x$ K3 O; Z. L/ P% K2 b$ p# }
  281.                  MC_MSC_EPIN_ADDR,# L4 T  H, M8 ^  D4 ]
  282.                  USBD_EP_TYPE_BULK,! E9 {: D! o: e1 ^5 B
  283.                  MC_MAX_FS_PACKET);
    9 [; P+ D( W5 G) h2 S
  284.   
    % ~: Q3 z3 `; a# \7 q4 b# m
  285.   MSC_BOT_Init(pdev);+ [: H, _- Q( Y; Z8 g8 Y% G
  286.   2 B; M: q" ?7 \, L. K" E
  287.   pMSCData = pdev->pClassData;
    . v! c. \1 |+ v) e, ]" S
  288.   
    " s4 a  O! r% I& s$ Y, O3 [) V
  289.   if(pdev->pClassData == NULL)* C9 @) b2 `5 x& |
  290.   {
    ' o; b$ T0 F. r3 w
  291.     ret = USBD_FAIL;# @  G) k# O) t# ^2 N
  292.   }
    3 d+ p* z9 f( h

  293. 1 x4 f' o) l, ~$ C
  294.   return ret;0 c0 P9 J+ I: C0 z5 X$ r3 S) X4 o/ ~
  295. }
    + a5 F" `" O! O6 N8 Z1 }

  296. 9 W4 ]) i( ?0 T. M) I
  297. /**8 e$ Y+ R! m0 ]: b0 \! J8 E
  298.   * @brief  USBD_MC_DeInit9 m8 U7 v4 J/ M% V
  299.   *         DeInitilaize  the mass storage configuration; Z+ M: Z, d. Z% E# y3 {
  300.   * @param  pdev: device instance
    4 S$ J- y. h' B1 [& a$ u$ N3 d
  301.   * @param  cfgidx: configuration index9 W* U& T0 y& \' {4 R7 o, {7 l
  302.   * @retval status/ V% C1 ^: O7 S) ?$ f7 p
  303.   */8 x4 e+ |6 ~: t6 t% \* e
  304. uint8_t  USBD_MC_DeInit (USBD_HandleTypeDef *pdev,
    4 q  w' e0 K( M. R4 G( F* `$ G4 s8 h
  305.                               uint8_t cfgidx)
    0 J) [' B5 Q! A/ {6 K8 a
  306. {
    , P2 y: e" r1 z. B
  307.   return USBD_OK;
    # W6 ]) M' }  o4 }
  308. }
    $ Z: v2 K# C) f, C( M
  309. /**
    ) P) A9 ~# I2 z% ~# ?9 B
  310. * @brief  USBD_MC_Setup
    1 U" g+ G7 _8 C, V% ]( b
  311. *         Handle the MC specific requests9 k( X6 G6 l7 ]( t9 V8 F* Q) `
  312. * @param  pdev: device instance
    $ F3 f5 E6 y, K4 I: }) P
  313. * @param  req: USB request. \: r' c9 ^& E0 h6 i& W
  314. * @retval status
    & a, j' j5 q' \4 s( @4 g/ j2 }+ A
  315. */6 `6 V/ v  P6 @5 g4 `8 r+ [1 k
  316. uint8_t  USBD_MC_Setup (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
    ; E6 q% l$ y, ?: B' d0 a$ J4 k
  317. {3 ]& V0 m+ W2 `# p- v) |
  318.   if(req->wIndex == 0x0002)
    + F' ?' ^7 W" I+ R3 t
  319.   {8 k% A+ q. d' W
  320.     MC_Switch_MSC(pdev);) u5 l, n2 j  Z# ?
  321.     USBD_MSC_BOT_HandleTypeDef     *hmsc = (USBD_MSC_BOT_HandleTypeDef*) pdev->pClassData;   8 d/ h& w6 [2 C- A7 {
  322.     6 {3 x7 N! \8 l
  323.     switch (req->bmRequest & USB_REQ_TYPE_MASK)* w: |% C/ _1 A  Y+ q
  324.     {7 Q7 j: M8 Y' A6 x7 Z6 w

  325. 8 x) L& B( K- K+ @4 G
  326.     /* Class request */3 R, o8 L5 S- }! ]3 l+ Z0 n
  327.     case USB_REQ_TYPE_CLASS :9 t2 C, ~) M6 @6 i& \6 t
  328.       switch (req->bRequest)
    : V! B% z( ~  y" ^, r3 i9 Q
  329.       {4 W/ D/ r) {6 ]3 f3 c$ p
  330.       case BOT_GET_MAX_LUN :6 k" _) e7 L/ G1 q. ~

  331. ; o; k/ x. e; ^" f9 H# q
  332.         if((req->wValue  == 0) && ' T& t: B" ~0 _/ }6 ]$ d: r- u
  333.            (req->wLength == 1) &&
    * Y* ^- h  j7 s
  334.            ((req->bmRequest & 0x80) == 0x80))# M; W% |! Q8 B9 X. X, t/ G
  335.         {6 g+ `. I* ^6 M8 B6 f# a
  336.           hmsc->max_lun = ((USBD_StorageTypeDef *)pdev->pUserData)->GetMaxLun();4 _$ |/ q* p$ T) e( w5 L
  337.           USBD_CtlSendData (pdev,8 |2 }3 |: T0 J0 J) s
  338.                             (uint8_t *)&hmsc->max_lun,' j$ ^5 J4 R5 w6 N5 G
  339.                             1);2 l! M! F7 p& D* ]8 }7 r
  340.         }
    9 k/ }8 F8 v0 p2 q- f" _7 W
  341.         else# A- U7 u$ O& Z4 t: `* Q
  342.         {
    7 ]! }; i  Y7 e, U2 i, ~. Q
  343.            USBD_CtlError(pdev , req);
    ! x# ~1 I4 ?1 u+ ?( I  H, i
  344.            return USBD_FAIL;
    " E% l# H5 S0 b0 u6 t5 f
  345.         }9 z* q6 G. ~5 f. g
  346.         break;8 z6 G; g/ I3 A6 r/ P5 Z! s
  347.         1 n8 P, O- r8 ^, E/ n4 R; U& q
  348.       case BOT_RESET :
    ( T6 C8 P: s! w. u
  349.         if((req->wValue  == 0) &&
    ) Y. z& }* B2 t5 ^5 i7 D3 v. P
  350.            (req->wLength == 0) &&( d# D5 x( K( b
  351.           ((req->bmRequest & 0x80) != 0x80))# O8 o7 k  X% M3 u) F
  352.         {      
    7 K+ g* Q- M, ?; \
  353.            MSC_BOT_Reset(pdev);
    & v$ }( x: v. W- D- U% f2 x" Y
  354.         }
    / q: I9 ]  @' C
  355.         else
    . @' i9 A0 e7 @8 m, ]- D( N# L
  356.         {
    " S5 {* G9 ?* A0 ^
  357.            USBD_CtlError(pdev , req);
    2 r& A% |5 k& z$ b5 J. K
  358.            return USBD_FAIL; 9 l- q. ^/ n; ?$ o* O6 H
  359.         }
    " d) L8 r0 r* y& [) [! W# u3 y
  360.         break;
    3 c$ b2 o$ E4 t( D  o% o
  361. / m; T# T3 ^$ F. A3 U! v1 x
  362.       default:
    8 J) |* `# I6 x* k! l8 w: G
  363.          USBD_CtlError(pdev , req);: b) `! F. @/ Y8 w* w- {
  364.          return USBD_FAIL;
    # P9 N; b# @: q) s7 d! n
  365.       }! X3 u6 A5 W3 l( p
  366.       break;
    ; H% Q+ Z5 g! I
  367.     /* Interface & Endpoint request */
    - L0 B: L5 g. z# g+ K: [- X
  368.     case USB_REQ_TYPE_STANDARD:
    . \+ C; |: y8 f2 A
  369.       switch (req->bRequest)2 U) w% s' F. I% Q5 |; v& t; ^. {
  370.       {1 r) Z+ e* |1 r5 \
  371.       case USB_REQ_GET_INTERFACE :: U: A/ Q. ~8 O0 s+ z. I5 G, Y
  372.         USBD_CtlSendData (pdev,  a) Q- a1 Z- |- n2 O
  373.                           (uint8_t *)&hmsc->interface,
    & C5 o' y6 f4 ~5 F9 |: c" w
  374.                           1);- V; U7 M" l2 R$ w
  375.         break;
    . y9 c" }6 V* J! y
  376.         
    $ ^5 R* q; |. D1 v0 b, J) B
  377.       case USB_REQ_SET_INTERFACE :
    , g  c- u: b. N
  378.         hmsc->interface = (uint8_t)(req->wValue);
    1 F  V( o/ Q" L4 A) M! }3 [+ K0 A
  379.         break;$ g8 o' G9 L2 ~) z* g8 E
  380.       " R- v( q1 P) @8 l+ c$ g( c3 e
  381.       case USB_REQ_CLEAR_FEATURE:  / z& M& A8 c+ g" {  P& Q
  382.         
    8 N, O& ]+ F0 U- h3 u; h2 \1 d
  383.         /* Flush the FIFO and Clear the stall status */   
    % t7 v# v+ g$ ]/ s. z6 y6 Z
  384.         USBD_LL_FlushEP(pdev, (uint8_t)req->wIndex);
    ' Q8 V" g8 y5 o$ ^8 G
  385.         # W* G( B  O! H9 c1 t
  386.         /* Reactivate the EP */      
    % \. y5 j$ r5 l% h, U- J4 U, v
  387.         USBD_LL_CloseEP (pdev , (uint8_t)req->wIndex);
    ; _9 Y: ^/ I( y6 ~7 E& p
  388.         if((((uint8_t)req->wIndex) & 0x80) == 0x80). x. @, @  @9 Q, b
  389.         {3 o" F# Q; ^7 M, i
  390.           if(pdev->dev_speed == USBD_SPEED_HIGH  ) 4 a" u: _$ k; b" u
  391.           {
    5 v: z% z: h& \2 R: C' l% y$ Z0 R
  392.             /* Open EP IN */
    4 I0 s' @0 h6 r2 Q! s
  393.             USBD_LL_OpenEP(pdev,
    : ~5 m8 Z; l: i' |6 U3 S4 A, D
  394.                            MC_MSC_EPIN_ADDR,8 U& h7 J; @1 X* z/ u
  395.                            USBD_EP_TYPE_BULK,1 f1 Z' f. w9 k: F; }* e/ k
  396.                            MSC_MAX_HS_PACKET);  
    ) l6 }: M. [0 U) {: Y  ^+ v
  397.           }
    6 f0 z  Q  r/ U& l, v7 s* J* P* i) m
  398.           else. s1 s6 |0 n0 z7 a
  399.           {   " E4 \* O* F3 d8 @$ _1 @
  400.             /* Open EP IN */
    ; @  R6 I2 A* W3 A. M& k
  401.             USBD_LL_OpenEP(pdev,& A* l: d6 `6 n" L2 r9 R
  402.                            MC_MSC_EPIN_ADDR,) R6 ^4 b2 q  p% l
  403.                            USBD_EP_TYPE_BULK,1 A% B8 r# T* a4 s$ f) s! L
  404.                            MSC_MAX_FS_PACKET);  $ N+ E# v/ A( q5 k3 d9 [
  405.           }
    & c2 t" e. {5 Q" V; f
  406.         }
    4 j6 O5 i& A/ a
  407.         else6 i) y' T# H) N) ]
  408.         {
    7 ~% ]( h$ x& A' E" T& G
  409.           if(pdev->dev_speed == USBD_SPEED_HIGH  ) . b, k) C0 X6 |1 q% ], X8 z6 J$ E
  410.           {4 O0 D* F0 ]: i7 T7 x) m# r% g2 j
  411.             /* Open EP IN */
    ! c3 K. G. r5 o5 r, T5 j
  412.             USBD_LL_OpenEP(pdev,/ R7 Z; d. W+ S
  413.                            MC_MSC_EPOUT_ADDR," u& u' F6 {: N& }4 J; n9 ?
  414.                            USBD_EP_TYPE_BULK,
    # G4 z0 g0 I- n3 Y/ s* P. w7 U4 M
  415.                            MSC_MAX_HS_PACKET);  4 I0 ^9 j% b) a0 s+ A& U
  416.           }
    9 A  Y6 E, A  {6 e
  417.           else" B1 [, D5 S! Y1 x$ o5 O) o: ?3 G
  418.           {   * X" v- K. z+ k% h; ]1 ]
  419.             /* Open EP IN */% s" G: `! `! l0 ]6 ?
  420.             USBD_LL_OpenEP(pdev,* x! T4 f- U+ ]. \$ @9 {
  421.                            MC_MSC_EPOUT_ADDR,
    6 R, _  I3 j  c. F/ D
  422.                            USBD_EP_TYPE_BULK,
    * Z# t$ i! j5 q8 o! {- h' i: q5 L
  423.                            MSC_MAX_FS_PACKET);  $ X2 q/ L- m0 @3 m# Q' _- R' Y2 Q7 o; H
  424.           }+ [' x' J2 f% I2 S0 w
  425.         }
    2 X- \& K9 G' ]; s( c
  426.         & S% s5 o3 v) B6 q
  427.         /* Handle BOT error */  \+ m9 h6 x! p
  428.         MSC_BOT_CplClrFeature(pdev, (uint8_t)req->wIndex);
    1 E; R8 z5 @# h+ T
  429.         break;& j6 m5 w# K: @  Q
  430.         / F! y. @5 v6 V- P  n" [# o
  431.       }  9 z& N0 e( S+ Z" F) X% W7 g
  432.       break;
    4 d( O8 F. n: a6 _
  433.      % l1 @. I! U7 L) V0 b1 E& N
  434.     default:( ?1 z) r; M; C' e) z
  435.       break;
    7 b& N& ]: ^5 m2 g$ u( b
  436.     }
    7 U, b8 S3 @, h/ x: D; @- S; Q
  437.   }
    : `8 |& _6 O- K* X# u
  438.   else
    & Q7 y2 H$ i; n9 X: h( X( g: Y) {+ s* T
  439.   {" N0 r' }+ G/ ~  @0 i1 n: i' T
  440.     MC_Switch_CDC(pdev);1 i! i0 o: N) Y8 o9 @7 ^$ z8 B- R
  441.     static uint8_t ifalt = 0;
    ' q0 F1 {! }8 Q/ b" F
  442.     USBD_CDC_HandleTypeDef * hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData;   
    9 l% Y6 j, P; _/ D9 m" P3 T

  443. - c4 ^# J4 L! R- O3 R7 o) n! K2 E! A
  444.     switch (req->bmRequest & USB_REQ_TYPE_MASK)
    4 d5 t- y3 }# M; p& l
  445.     {1 B( C3 i- \- O5 q
  446.     case USB_REQ_TYPE_CLASS :
    6 t1 q/ f) n( U! D2 ~5 o" f
  447.       if (req->wLength)
      @& K9 }9 o1 S) h5 \! N
  448.       {. J) {" a5 U' f! T9 G5 P
  449.         if (req->bmRequest & 0x80)
    & v, e1 ~0 c3 B( T
  450.         {
    6 }! H3 s$ l; \
  451.           ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest,
    $ o% X$ X) J" e; L. T6 z$ q# f
  452.                                                             (uint8_t *)hcdc->data,
    " |, r* H( }; V3 ^( x
  453.                                                             req->wLength);. E1 D) n8 W3 G( b' S  N
  454.             USBD_CtlSendData (pdev,
    " E# c5 s0 q9 Q6 d% V. \
  455.                               (uint8_t *)hcdc->data,
    - u1 ~5 R; s* D& N8 X
  456.                               req->wLength);+ O! w) v8 f; P6 D1 u6 y/ x- z. ]
  457.         }( j) M$ f/ p- U8 {" `) W  v, w
  458.         else. }. r. |1 l$ `4 H: q, g5 ?& M1 X
  459.         {
    7 N+ o* E0 A' ~7 L- s" W
  460.           hcdc->CmdOpCode = req->bRequest;
    " X$ @" H( p. L; n1 W) l% L
  461.           hcdc->CmdLength = req->wLength;
    . y- n; _4 U$ v+ S' a
  462.          
    % g0 Z! b: u* G" @. \/ _0 W- u2 F
  463.           USBD_CtlPrepareRx (pdev,
    ! y3 W9 P9 M4 v6 p
  464.                              (uint8_t *)hcdc->data,- H( d( @7 j3 _+ X' K8 l3 l$ O" f
  465.                              req->wLength);  L' V" W' r" W
  466.         }2 J2 t; v; ~  @$ E. |8 X, O( W
  467.         
    9 o0 S+ x# M  E3 M7 S5 o
  468.       }5 x7 G7 d$ Z5 H7 m. ]  h* h$ {
  469.       else' ~6 ~' |2 b% I! [, d/ E- S! i) V
  470.       {" m: I8 x2 l; M6 z/ H7 d0 x
  471.         ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest,
    , d3 V# g7 c* v* m9 D3 u5 l& W
  472.                                                           (uint8_t*)req,7 Y! I% B( \$ q  g1 i! U1 f
  473.                                                           0);
    4 s* V1 B! `$ M2 k- l
  474.       }! a+ t5 E  D' B* |. t
  475.       break;
      S: K2 x, e1 z* d, Z9 G7 B0 d, R
  476.     / @# O5 d) E# g, m  c' S
  477.     case USB_REQ_TYPE_STANDARD:
    ' D! {' E/ L7 E+ |) z& ^" Q) \8 `) X
  478.       switch (req->bRequest)/ I1 M: Y2 P& g2 g$ Y# \( k
  479.       {      
    & e+ w" I9 A! D, S6 |
  480.       case USB_REQ_GET_INTERFACE :
    % R4 k7 o0 K3 r" k' e( s" u
  481.         USBD_CtlSendData (pdev,* r) W' F7 M2 C# H. W/ o
  482.                           &ifalt,7 y* X8 Z& l/ C2 O3 A4 E4 y# E, s
  483.                           1);
    ' w" l# |) s! Q4 V
  484.         break;* [6 f2 V3 k( N# l6 k
  485.         9 d6 s& T3 v6 ^/ q5 E
  486.       case USB_REQ_SET_INTERFACE :
    - ~" N5 d' n; i. l) U' k4 y
  487.         break;9 }, [7 Y( l7 S& R# t
  488.       }
    ! v" Z+ s3 n! h3 y( z
  489.    
    8 ^, t6 W% e* L& j
  490.     default: 8 d. e' e- H( p& G9 p; C
  491.       break;
    8 a9 h5 O! A; ~7 Q( Y# w2 [
  492.     }  : O5 \- \% P) S% l! z7 ^3 t
  493.   }
    6 U. T7 V* P0 r% k
  494.   ! l( L- M; E0 }1 u3 c
  495.   return USBD_OK;
    5 p4 V! }1 V0 z5 V! W
  496. }1 h' \6 p9 R) |! D6 L* E0 H) r
  497. # v  w0 _  u8 J7 Z4 g. i2 |: \0 n
  498. /**! t: ^9 J1 K( `4 T% i
  499. * @brief  USBD_MC_DataIn6 l' `# D; H6 k: k  J1 w2 e
  500. *         handle data IN Stage) b+ H; a) }! O9 y: t
  501. * @param  pdev: device instance3 L: v+ v8 d& Y+ @) j6 _$ v  F
  502. * @param  epnum: endpoint index. P& `- f' B9 q6 B! P3 m
  503. * @retval status
    7 P3 P: c9 i# V
  504. */9 ^% }8 E- q2 R( l; w- A9 f6 y: |
  505. uint8_t  USBD_MC_DataIn (USBD_HandleTypeDef *pdev,
    + s5 l% v& m0 y4 F- }
  506.                               uint8_t epnum)' ~4 @4 z1 H6 L+ U6 n
  507. {) @$ U4 ]7 `  w3 `8 H
  508.   if(epnum == (MC_MSC_EPIN_ADDR & 0x7f))1 C. f! w2 k0 v/ I3 h
  509.   {1 `7 E( f( b- n& a5 S3 Z3 h
  510.     MC_Switch_MSC(pdev);
    1 v+ D) i/ ~- |; X
  511.     MSC_BOT_DataIn(pdev , epnum);) t5 r4 |* t& Y0 [. x) X
  512.   }
    7 u6 G4 s3 t# T. Q1 S
  513.   else if(epnum == (MC_CDC_IN_EP & 0x7f)); P4 O1 [3 ?9 M' C1 j/ [3 j. f& s9 z
  514.   {
    5 N8 E1 w6 R' e
  515.     USBD_CDC_HandleTypeDef   *hcdc;
    - K2 p! w2 E9 C+ B
  516.     - z$ r0 a, r! G  n' u; [
  517.     MC_Switch_CDC(pdev);
      X. D9 P+ u; B" v* l
  518.     hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
    + B9 u0 v7 c2 b0 p2 u/ w4 q
  519.     hcdc->TxState = 0;    & h& Y$ h1 N) X( u4 R* R
  520.   }
    2 ?+ }7 H, p) T+ I4 }/ ~
  521.   
    - O" I/ e( Y% q7 r
  522.   return USBD_OK;; x$ C  |0 H. }4 W( s
  523. }4 F$ C4 h: J* d, [
  524. % W% l2 Z& E0 J1 B. ~
  525. /**/ V' L( U6 d4 M& R9 g, b
  526. * @brief  USBD_MC_DataOut! O  P, M2 ?: f6 e4 D3 f# I
  527. *         handle data OUT Stage3 a$ J0 @) c; _
  528. * @param  pdev: device instance
    & p7 i! ~' l( ~+ I5 R
  529. * @param  epnum: endpoint index
    % S: ?! R3 r7 d
  530. * @retval status
    $ o9 f  j" ?! q2 N
  531. */
    # L! ^% K6 }# m& L) ~
  532. uint8_t  USBD_MC_DataOut (USBD_HandleTypeDef *pdev, : J9 A7 _% v* T) u2 N
  533.                                uint8_t epnum)
    * I" s% i' y" s  M( K2 N
  534. {7 B3 i- G( \, ]$ E
  535.   if(epnum == MC_MSC_EPOUT_ADDR)9 R+ I6 X6 t. ^2 T" c0 z0 W9 l
  536.   {
    / G2 s  H9 x# _) k: W
  537.     MC_Switch_MSC(pdev);
    ' [( \5 ?' V- ~7 g) [
  538.     MSC_BOT_DataOut(pdev , epnum);
    : L% B: f* f' }3 U
  539.   }; l* l4 w& v; |
  540.   else if(epnum == MC_CDC_OUT_EP)" x0 d( a/ M- a3 O: V9 d3 `8 C6 i0 p
  541.   {
    9 }. n& W0 K. k% o& Q7 M4 n% d" G
  542.     USBD_CDC_HandleTypeDef   *hcdc;
    . o$ n3 W6 V( Y/ m0 E( C# y2 k
  543.     7 `) ?/ K% c4 h
  544.     MC_Switch_CDC(pdev);
    ' x4 k( d/ }% g& A/ i4 B  e
  545.     hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;- Y& z. s1 f0 B: |: U. W" y
  546.    
    2 ]; Y9 Q& m( P( B
  547.     hcdc->RxLength = USBD_LL_GetRxDataSize (pdev, epnum);* c6 J2 W$ Q$ S; R; G. }
  548.     ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Receive(hcdc->RxBuffer, &hcdc->RxLength);: M3 P& L4 L1 X
  549.   }
    2 ^0 {. }- H! z9 u. @
  550.   3 R+ C/ d, F- J7 o6 _7 V% c9 W5 X
  551.   return USBD_OK;
    " c9 |  q% d8 k: e, P  W
  552. }( G* l  U" x; t

  553. * V2 N# n: g/ Z
  554. /**
    . A3 Y  A( I. a$ \
  555. * @brief  USBD_MC_GetHSCfgDesc ) p1 f; S( @  d& D
  556. *         return configuration descriptor+ Y% Y. S  O8 m; V1 ~! h
  557. * @param  length : pointer data length. ]5 u$ E& g" C$ x, `& h+ T
  558. * @retval pointer to descriptor buffer. k; @/ U& x! C. V& b/ m
  559. */7 O; L2 h! L- {" z$ W
  560. uint8_t  *USBD_MC_GetHSCfgDesc (uint16_t *length)
    2 c7 F, o  h; l) V9 E/ @7 L. c3 M
  561. {
    : Q* q* A5 q. k+ W/ S
  562.   *length = sizeof (USBD_MC_CfgDesc);' \+ d+ i/ s3 `3 n9 b4 F1 a" g% n5 s) Z
  563.   return USBD_MC_CfgDesc;
    9 u; \8 x& I; `+ x8 M! s; d5 s
  564. }
    4 c8 a: n. K$ T+ P

  565. 6 z7 i6 l# `: f, N- t9 h' e
  566. /**
    ' t- B0 z/ c+ a) h; O; l% K0 e
  567. * @brief  USBD_MC_GetFSCfgDesc
    0 @: j3 p- F5 `" u7 l( z9 J9 Q
  568. *         return configuration descriptor! E! z/ T! q3 t9 f  X
  569. * @param  length : pointer data length1 r4 P- q: o4 U
  570. * @retval pointer to descriptor buffer9 n1 d3 L" a  Z/ V: M$ N' _
  571. */
    8 g! a* Z; Z8 D5 J9 g; [
  572. uint8_t  *USBD_MC_GetFSCfgDesc (uint16_t *length)% t+ z# J4 J8 p: s6 C% B/ T2 [
  573. {; a1 X" m$ F, g& h7 N# D
  574.   *length = sizeof (USBD_MC_CfgDesc);
    . \, j; ^1 Q4 `2 y! P. ^
  575.   return USBD_MC_CfgDesc;
    8 W: c9 u+ B, j: Q! H9 X
  576. }$ G: Q+ S$ ]& r8 x7 b+ G" b& o# Y

  577. 3 |: i+ v6 b: f" l; l) U
  578. /**
    & d3 w+ b8 Y4 A* g6 T6 Z
  579. * @brief  USBD_MC_GetOtherSpeedCfgDesc
    8 E% Z1 i% r$ G+ G
  580. *         return other speed configuration descriptor
    . f5 ~- F! {& u- n
  581. * @param  length : pointer data length
    . L) m  m6 x7 S$ E' P' n
  582. * @retval pointer to descriptor buffer$ U0 ]9 P7 p7 U, ]+ T* o
  583. */
    3 p& I# Q) S. E: P6 H# z! w+ e
  584. uint8_t  *USBD_MC_GetOtherSpeedCfgDesc (uint16_t *length)' }3 m7 u" C. Q/ \8 @6 d% B
  585. {, p- Y$ u7 |; l# D( U* y; e
  586.   *length = sizeof (USBD_MC_CfgDesc);
    2 }' u3 z* M  c
  587.   return USBD_MC_CfgDesc;9 Z2 p( C0 X; r1 O; S5 I9 i# Q- P; l  I
  588. }7 H: J7 w! V* c  t6 H
  589. /**1 t4 a( c. b  E2 C& _0 d
  590. * @brief  DeviceQualifierDescriptor
    ( x: f, y* N9 X/ u) J
  591. *         return Device Qualifier descriptor4 m7 T3 C, i; x/ v1 e
  592. * @param  length : pointer data length
    ' [& J2 n1 ^; B! w) G9 y- t, y' K
  593. * @retval pointer to descriptor buffer9 \7 w" x9 n' t' i
  594. */) M5 S" c, E0 ^# q6 P/ j' \
  595. uint8_t  *USBD_MC_GetDeviceQualifierDescriptor (uint16_t *length)* b* g4 B$ C1 H
  596. {
    * ^5 V- }, L6 z- a& I. Z% i
  597.   *length = sizeof (USBD_MC_DeviceQualifierDesc);2 W3 o; z$ r+ N1 _) n# |2 q
  598.   return USBD_MC_DeviceQualifierDesc;
    ) {) e9 e+ E* [# `9 D0 x- Y6 x3 ^
  599. }: N& X; ^) p' ], k

  600. & }5 D7 m! d* u/ }& q
  601. /**
    : u3 ]- l  D# R$ r
  602. * @brief  USBD_MC_RegisterStorage
    * S9 E$ |) V: T1 z3 p' M
  603. * @param  fops: storage callback
    $ n* T; J/ T, M- W) r8 Q
  604. * @retval status. k: k' P+ E' _9 ?4 U0 ~
  605. */! D; v' q0 J7 x, U) _  i# E
  606. ! x# f9 T1 W6 t7 W: {5 M$ A6 p
  607. static uint8_t  USBD_MC_RxReady (USBD_HandleTypeDef *pdev)) C# U$ @! H; p* t
  608. {9 j1 g! t' n( y6 x
  609.   USBD_CDC_HandleTypeDef   *hcdc;; b; |% `7 s" s" P+ i* T
  610.   
    ( b; x! K4 o1 U  I4 P
  611.   MC_Switch_CDC(pdev);! u+ q% c8 u  _/ ]) U$ K4 |
  612.   hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;2 y1 l  i5 z0 `  {$ Q. B3 p
  613.   6 u; L( {2 _  k* v
  614.   if((pdev->pUserData != NULL) && (hcdc->CmdOpCode != 0xFF))
    ( e- s+ H3 K& F6 ]3 u- Z$ C
  615.   {
    3 D1 w0 v2 ^& w: S9 M; ?+ e
  616.     ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(hcdc->CmdOpCode,& K! m; M7 y. J" z" h. J- W) k  x" r; t
  617.                                                       (uint8_t *)hcdc->data,
    2 }' s0 \/ B7 B7 u
  618.                                                       hcdc->CmdLength);5 o4 R) T8 P& m+ b  b: M
  619.       hcdc->CmdOpCode = 0xFF; % N% \5 j5 K5 E$ x8 S
  620.       ; V& n2 N( l5 r3 }, t5 `  d5 S
  621.   }) K8 d& N' o( m! e( C8 m
  622.   
    1 |& P, M( @4 ~- \$ k
  623.   return USBD_OK;1 Q" H% a5 ^( `8 o- v) ?
  624. }
    5 k( ^: G2 O8 z  [3 T4 |% f" D, U
  625. 5 k, O8 L' T& s  L  T: }
  626. static void MC_Switch_MSC(USBD_HandleTypeDef *pdev)
    , n5 G  |1 t1 X; z9 }$ A( s6 d
  627. {# S6 _0 J# r7 \
  628.   static USBD_MSC_BOT_HandleTypeDef msc_handle;
    ) O* _$ q! b, B1 s. s
  629.   
    ; q( f" ]* V' ?  T+ m7 j$ n
  630.   USBD_MSC_RegisterStorage(pdev, &USBD_Storage_Interface_fops_FS);3 A; O1 |; C0 D; E0 r7 R) u* Z4 S5 Y
  631.   pdev->pClassData = &msc_handle;( `6 Z6 a5 B7 X0 A- k- y2 O
  632. }  g; H" B7 ]# l/ u- s$ ^$ S
  633. 9 V8 R3 L) T( x( w
  634. static void MC_Switch_CDC(USBD_HandleTypeDef *pdev). K) m& v; Y% E% u- D# ~
  635. {
    / w+ W% b; |  c) `9 A# n  j
  636.   static USBD_CDC_HandleTypeDef cdc_handle;, _, x: H$ p- j
  637.   
    $ c3 |: P7 E9 a( N7 P9 R
  638.   USBD_CDC_RegisterInterface(pdev, &USBD_Interface_fops_FS);
    5 B; F2 X& y8 a. B# v/ p8 m4 G1 q3 o
  639.   pdev->pClassData = &cdc_handle;) ]/ E. }+ L: M! W- Y: d* [  ]
  640. }
      T; G0 |! p7 h% T- w1 X1 o
  641. 9 l% ^0 L8 O1 V0 Y9 K1 w
  642. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
    " w6 [2 v: O& R6 Y) g* V; @
复制代码
) K, a" K) I6 r- Q. W3 e, O( k
通过以上修改后电脑电脑端显示USB复合设备MSC+CDC
# U% ?9 m" r6 J* Q  S6 } msc cdc.png - j6 x4 e. j$ _- [1 J7 P0 l6 I
. [. w+ L4 m, t/ K0 M6 q& i
13.在usbd_cdc_if.c  CDC_Receive_FS   /* USER CODE BEGIN 6 */ 增加发送测试
3 d, L% q& b8 e' M' n2 Y& [8 O! B1 Y; D6 y& G8 r
  1. static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)
    + f4 C. Y* @5 D7 h# j/ f
  2. {/ Z( i% Y2 n0 i
  3.   /* USER CODE BEGIN 6 */5 ~* R/ V" m. b7 W- e
  4.   USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);. [8 O7 _+ k, G
  5.   USBD_CDC_ReceivePacket(&hUsbDeviceFS);# S4 m$ t  `3 G4 V$ |
  6.   2 z$ t  R3 m7 L5 a. T! O
  7.   CDC_Transmit_FS(UserRxBufferFS, *Len);      //把接收的返回; t4 [0 P0 ~$ a8 h, t
  8.   
    , V+ J: H7 U  T- f$ _
  9.   
    " V+ Q0 s% `9 K4 m7 C; w& q3 {2 |
  10.   return (USBD_OK);
    , z5 J" C( ^+ N) I2 a6 O
  11.   /* USER CODE END 6 */. Y0 z3 A# e! t: C- W2 P
  12. }
复制代码

  F, ~5 [6 X( \2 F% p测试串口收发
% _( K, V4 A* Q: ^ test.png
8 ~6 V2 J6 X( `( w; Q' U% t+ ~& d+ k# W7 u, e3 _& i8 ^

0 a2 @- d% R" u( @, ?3 F
3 t+ H/ ^+ N! K
8 q6 t( n/ ~' B/ n4 \4 D1 g  p% Y# J

评分

参与人数 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
非常好的资料,对初学者很有帮助;1 t; A, }; A& A8 q0 \" v" I
希望楼主多多分享,赠人玫瑰,手有余香,念念不忘,必有回响;
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; N4 g/ s2 z/ g% M* e4 K
完全按照楼主做法,在win10环境下U盘和串口都可以实现功能,在win7环境下,串口错误识别为mass storage ...

, d1 Y, j& _; q  P是不是驱动问题,我电脑Win10
电子ai好者 回答时间:2020-11-19 12:57:48
hds1988 发表于 2020-6-29 09:52' b/ G. D1 x0 W5 B
完全按照楼主做法,在win10环境下U盘和串口都可以实现功能,在win7环境下,串口错误识别为mass storage ...
' @+ @) q' r- I- K8 ~8 M7 X
微信图片编辑_20201119125724.jpg 我现在就是win7系统,和你一样的现象。请问你找到解决办法了吗?3 x1 ?8 `. [% ]4 m! q; O. n
js123456 回答时间:2021-8-10 15:34:43
用stm32cubemx生成的项目cdc,在文件usbd_conf.c中,USBD_static_malloc申请内存是以USBD_CDC_HandleTypeDef为准,函数如下:& T+ @. T8 G9 f  e9 a8 N# F! d
void *USBD_static_malloc(uint32_t size)
3 _) a/ ~' p) d8 ?- W, V$ l{/ v- ^) J* e/ F+ c5 E1 I! a
  static uint32_t mem[(sizeof(USBD_CDC_HandleTypeDef)/4)+1];/* On 32-bit boundary */
; F- k  h4 L# l2 e) B  return mem;+ d* q, G% d/ g: ?5 w( J2 W
}. ]" L; r/ f' v) N8 T' V& E- a& W
4 C1 D3 W4 p* R( j
那么在组合设备中,USBD_MSC_BOT_HandleTypeDef和USBD_CDC_HandleTypeDef都需要申请内存,怎么操作?8 F, Q. E. E+ n, l0 L0 H$ B

- \. k- d# M7 |) K3 E4 E& u
js123456 回答时间:2021-8-10 15:35:35
hds1988 发表于 2020-6-28 23:47" k& Y& L0 E8 q' ?5 {; J
完全按照楼主的说明操作一顿后,不能识别出CDC,但是能识别MSC。MCU是F407VE
7 S/ M1 \& C4 ?- t% i0 |
有可能是函数USBD_static_malloc的问题% B, g. [6 W& s. c' l

所属标签

相似技术帖

官网相关资源

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