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

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

[复制链接]
289466080 发布时间:2019-6-23 13:44
本帖最后由 289466080 于 2019-6-23 15:56 编辑
0 O& u: j7 [5 n8 `8 g4 f
9 N  n8 U- G/ C- p4 r) R3 t    最近做个USB复合设备CDC+MSC,在网上找了好多基本都是F103做的复合设备,带OTG芯片USB复合设备网上很少可能是我搜索的关键字不够理想有的不够全面,官方给了一个视频教程但是没有参考代码,社区里面有分享到github我按照后也不能实现,后结合F1与github分享的+官方视频,实现了在STM32F730R8T6上面USB复合设备,分享下怎样用cube生成的代码实现USB复合设备(带OTG的芯片).
# ?% Z3 [5 d& `: x* u6 g4 h0 t3 A5 U/ J* H" J
参考:
1 I5 v# b  W. V; v, q* Z% U1 ygithub分享
9 [2 v, e* x" P" X: Z2 R* f) Ohttp://github.com/uwyciw/CDC_MSC: ]+ \+ e5 B& l9 t! Q% D) f$ U
官方视频
2 f/ B5 y# L) Q# f1 ?https://www.stmcu.org.cn/video/index/detail/id-3988; B; S0 P* c: I  t
F1035 L( a& \* P9 c8 N
http://www.bbsmax.com/A/kjdwBXA5Np/
: `, X1 F, A, b6 X
& K( H. |* B3 ~- b# j. e) N0 P% k0 v# J1 A
cube 5.2.1
4 Z: l% S+ }" i+ Vhal  stm32cube_fw_f7_v1150.zip
5 t1 L$ _5 Y" u$ b, Q1 L/ V$ W2 [. c  i
USB为 USB_OTG_FS
! F6 T$ N8 H- D6 ~& A7 O6 R: C. [# h5 u# J1 Q9 ]! J
1.先生成一个CDC工程下面配置图。5 n# {9 F* y! C, v, @8 `( r
RCC如图箭头其他默认' z' G; H( [2 j6 S" o. ?/ R& r
RCC.png
+ H. Y( O* v3 z! p0 C3 \+ `) ~& gUSB_OTG_FS如图箭头其他默认, c; H' Z' A. A5 u1 H3 {
USB_OTG_FS.png , ~% |8 t5 L& ~4 I: {
USB_Device
如图箭头其他默认
4 P" m/ G- F* y* J& R USB_Device.png : K5 }9 l- a# M- [, I) c
Clock如图箭头其他默认我用的16M晶振比8M便宜: Z& @: y* D1 z2 R
Clock.PNG
" ?4 r! S; u' w8 M
( L6 W7 t3 a3 W: o& aProject如图箭头其他默认- v% b! p# R3 N4 `' t' y  |5 z
Project.png
$ P3 T5 D' W5 j1 [0 Tcode如图箭头其他默认( w# u  Y3 c2 o
code.png ' [7 u2 N' i! l6 @
2.同样生成一个新的MSC工程不可覆盖原本的工程只需修改下图与工程名其他一样$ V0 E: m7 V' Q5 Y3 h
8 D1 P! X7 b! f! {" O/ z
USB_Device-MSC.png * @4 o# Q9 N4 }
" q* `. h6 u, F* S, `* H3 u
6 b2 r1 }, l% |0 u+ W* @
3.生成后把CDC工程下Src文件夹里的usbd_cdc_if.c与Inc下的usbd_cdc_if.h复制到MSC工程下Src与Inc文件夹里面,MSC工程下Src文件夹下新建usbd_composite.c与Inc下新建usbd_composite.h: {7 K$ Y  c! n

: Z) o& w2 Z3 v! Y9 P2 {) J h.png
& R$ n+ ]" T/ z4 Y* @) E" d, A: |! R/ B1 F. `- z( W
4.把CDC工程\Middlewares\ST\STM32_USB_Device_Library\Class目录下的CDC文件夹复制到MSC工程下见图4 t& `, I0 G! i* p  n: k
cdc.png
/ y/ I5 M% }8 i' j( ?  B1 Q0 k( l) {5 W5.添加CDC路径; Y. R; g- c8 n$ `

- [6 K; f! G! c4 r CDC-PATHS.png
1 y  H1 o# l  _- x% O, I' P; z+ S0 v3 N3 S4 f$ c" o
6.在工程中添加usbd_cdc.c usbd_cdc_if.c usbd_composite.c见图
$ x' Q3 p+ V0 S- I: F keil-add.png
; Y( G4 c, ?- g8 H, o8 n+ [* J
5 {: r6 d2 r8 a* n! G) Q7. usbd_conf.h 把USBD_MAX_NUM_INTERFACES值 1修改为3, A7 J0 j3 I( L8 k4 A- N
  1. /*---------- -----------*/
    : r% p6 _3 G. h7 Q' T4 V* I
  2. #define USBD_MAX_NUM_INTERFACES     3U    //1U1 v: J. o. p4 U/ O7 L% l" p
  3. /*---------- -----------*/
复制代码
8. usbd_cdc.h 修改CDC_IN_EP CDC_OUT_EP CDC_CMD_EP! y4 k- d4 z% R) [: e0 s
  1. //#define CDC_IN_EP                                   0x81U  /* EP1 for data IN */* O  b) n! o9 n0 l8 Z) i! o9 h6 f
  2. //#define CDC_OUT_EP                                  0x01U  /* EP1 for data OUT */
    ( G8 z7 D- ?: U2 B
  3. //#define CDC_CMD_EP                                  0x82U  /* EP2 for CDC commands */
    " k3 ^* u# o  r# ~" I/ ]' |1 i( C) v
  4. #define CDC_IN_EP                                   0x83  /* EP1 for data IN */
    5 s7 ^) j1 b5 G5 o$ Y5 V% A$ `
  5. #define CDC_OUT_EP                                  0x03  /* EP1 for data OUT */
    + _0 e- y) D9 u
  6. #define CDC_CMD_EP                                  0x82  /* EP2 for CDC commands */
复制代码
9. usbd_conf.c  USBD_LL_Init中新增
5 c5 k. o4 \6 ~& n/ d
  1.   HAL_PCDEx_SetRxFiFo(&hpcd_USB_OTG_FS, 0x80);0 f. H" Z' q5 Y8 u
  2.   HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 0, 0x40);9 g4 O# v, Y9 B( B$ [
  3.   HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 1, 0x80);
    % N  W8 j, k9 s) t+ n
  4.   ' K( p/ f; j5 n% p9 @
  5.   HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 1, 0x40);   //新增
    0 R4 E7 l+ s) h) a. y  Z! h  N6 w
  6.   HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 3, 0x40);
复制代码
10. usb_device.c 修改MX_USB_DEVICE_Init与SER CODE BEGIN Includes中新增usbd_composite.h
6 S& @. s/ u- d
. [" Y8 m0 q; Q# q- [

  1. 6 G0 U8 L* U) c/ Z0 u
  2. /* USER CODE BEGIN Includes */% F4 e# J" v+ a1 o5 v2 x9 G' L
  3. #include "usbd_composite.h"6 L3 S. U$ l) T2 u, F
  4. /* USER CODE END Includes */
    ' O) O8 _, n& u+ L3 A
  5. & \7 ~- X7 s" e- n7 b& x
  6. void MX_USB_DEVICE_Init(void)
    & @( Z0 o! Q: ], \0 X: k2 ]8 a
  7. {
    8 n& i) _% A1 s* t
  8.   /* USER CODE BEGIN USB_DEVICE_Init_PreTreatment */
    $ p/ c" N3 V8 v/ g" h  l
  9.   
    4 S& M# v2 d9 J  K
  10.   /* USER CODE END USB_DEVICE_Init_PreTreatment */
    7 F- B0 n3 L6 [. G
  11.   & _3 {& j" n5 j$ T0 ]6 G4 A
  12.   /* Init Device Library, add supported class and start the library. */
    % I! m' M, E' s
  13.   if (USBD_Init(&hUsbDeviceFS, &FS_Desc, DEVICE_FS) != USBD_OK)* m8 i' H* a2 N* M
  14.   {
    9 }; l0 m  l0 d$ {1 q4 C, N
  15.     Error_Handler();8 J# m! N4 R3 }3 x+ l
  16.   }
    " l" S/ I! U' t1 R  J) q5 R
  17.   if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_COMPOSITE) != USBD_OK)  //新增
    # V& ^( K9 `. B: [5 D  `8 K' V
  18.   {
    2 o% J4 t& h0 d) n, f
  19.   Error_Handler();
    ) P6 L. e! k6 B0 r- r
  20.   }
    0 w( D: s1 y: Z/ X( x7 T
  21. //  if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_MSC) != USBD_OK)' g: q7 h* z# s
  22. //  {" x/ F" r; e* Q: f
  23. //    Error_Handler();/ c% P4 O. y5 r2 X9 G2 {
  24. //  }$ L3 x9 h* ]' {$ Z+ _! S
  25. //  if (USBD_MSC_RegisterStorage(&hUsbDeviceFS, &USBD_Storage_Interface_fops_FS) != USBD_OK)
    % w* b3 t1 A9 z8 E1 W
  26. //  {
    ! h$ U: V4 |) T7 C3 e  I( H4 J
  27. //    Error_Handler();/ T: c/ p/ {: g+ r; _( h3 ]% V; Q
  28. //  }' {" G) q! {. z" \" K- m/ c& ~) ~- C
  29.   if (USBD_Start(&hUsbDeviceFS) != USBD_OK)& b' J8 i- H) ~1 _! s# D
  30.   {: U+ ~7 y1 c5 C; [9 \5 J2 v, F
  31.     Error_Handler();) m) h; _0 ?+ Z& J& ^7 M
  32.   }
    7 G, i% n8 u6 B% D: n8 ~" ^
  33. ' A1 W6 y9 m1 n1 f3 k* N: l$ n
  34.   /* USER CODE BEGIN USB_DEVICE_Init_PostTreatment */" ?4 y3 ?5 @* H8 l( n" q' k
  35. //  if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_COMPOSITE) != USBD_OK)  //新增
    ) J5 X. a/ \9 U  t
  36. //  {. c/ t: ?4 O/ }
  37. //  Error_Handler();% T3 K+ {) s2 R* T
  38. //  }
    6 Q9 B" C$ N2 F; q- ^$ a$ {
  39.   /* USER CODE END USB_DEVICE_Init_PostTreatment */
    $ B/ L3 p2 J' p! @
  40. }
复制代码

  c) }) s4 t* s* y$ C/ ~# Z: w  i5 ^4 }6 ]

5 Q$ o8 N5 I+ N; b, P5 y/ \11.在usbd_composite.h中新增代码
7 p% p! |6 r  s2 _

  1. 0 u% @+ N7 u* E+ u% \0 L
  2. #ifndef __USBD_COMPOSITE_H
    / u: _# f0 s7 u# H
  3. #define __USBD_COMPOSITE_H
    " u" {. |0 x, P' j9 ~

  4. * r8 z% _% R8 \6 K7 e) ~* d  H
  5. #include  "usbd_ioreq.h"
    % _4 }* b" ]9 Q9 Q2 J" N
  6. #include "usbd_cdc.h"
    * R& }' ?. {2 p6 Z
  7. #include "usbd_msc.h"
    , [1 `( J' V6 T6 |+ x

  8. % y, G  L  N5 I
  9. #define MC_MAX_FS_PACKET            0x40
    , z4 E! B8 {: l5 J. s$ ]5 E
  10. 3 p0 s, E& o4 i% E8 H, W
  11. #define USB_MC_CONFIG_DESC_SIZ      106
    $ ^. }! _$ D1 l

  12. ! G2 r, N# D2 I3 G% j
  13. #define MC_MSC_EPIN_ADDR                MSC_EPIN_ADDR , ?1 A/ g3 T# C  D; n9 d9 i
  14. #define MC_MSC_EPOUT_ADDR               MSC_EPOUT_ADDR
      K* n& H* p" }
  15. : F2 |% |% _  h: H# P  l& J
  16. #define MC_CDC_IN_EP                   CDC_IN_EP
    & \# u( R- ?2 L
  17. #define MC_CDC_OUT_EP                  CDC_OUT_EP  ' Z' @' ?+ l5 |' Q
  18. #define MC_CDC_CMD_EP                  CDC_CMD_EP , E6 {" D1 a) e

  19. 1 U2 ?, }( u3 U7 L( d. ]& X+ _
  20. extern USBD_ClassTypeDef  USBD_COMPOSITE;
    6 s2 Z- y' b1 I) [. F/ `3 o
  21. ) m. h' n1 v7 u
  22. #endif  /* __USBD_MC_H */
    ) A+ b% v# B9 q  F7 b( Y

  23. * D+ s4 t& e$ U* m  u# F
复制代码

7 d9 C& N5 T9 O, d  G! \! h
" z0 u3 T8 ~: Q3 y12.在usbd_composite.c中新增代码$ {6 t1 T. |0 m8 Q  a, x. @1 ^. j
$ N3 F( r' h) H% a+ |% `# Z3 e* E

  1. " \$ v- i3 d/ T1 v& e- _
  2. #include "usbd_composite.h"# j" c/ H# D* u2 A3 o* k8 I
  3. #include "usbd_def.h"
    7 i3 g+ s5 `8 K! I- l* ?
  4. #include "usbd_msc.h"
    , ^5 V1 J  O$ F" ?: w; L
  5. #include "usbd_cdc.h"
    $ B& K: i8 R9 `' l0 d( B! R$ t
  6. #include "usbd_storage_if.h"
    2 ], q/ b$ x4 w, _8 ]
  7. #include "usbd_cdc_if.h"
    & W7 [7 v# p( o% E' n: [& Q* E

  8. / b# n2 |4 g. L& O% U# B& I1 ^
  9. /** @defgroup MC_CORE_Private_FunctionPrototypes6 v0 C" K) g0 C8 E: A& W5 C! @( q
  10.   * @{: {* e; j9 d" X3 a6 S5 m% r, l
  11.   */. M4 V9 m. Y$ U2 f% u% j
  12.   
      H# f0 f# M4 _; B- A
  13. USBD_CDC_HandleTypeDef     *pCDCData;
    7 l- Q8 l) A9 N
  14. USBD_MSC_BOT_HandleTypeDef *pMSCData;9 D+ B2 v9 d% T( W5 s3 c( ^
  15.   ! J! e% m  z* i7 K( V3 k0 c
  16. uint8_t  USBD_MC_Init (USBD_HandleTypeDef *pdev, 4 k/ Q0 z7 l3 l
  17.                             uint8_t cfgidx);* b4 k3 [, K9 f- p! ?5 r9 N" }
  18. 9 V: i. p0 `% X* R5 F& C3 ^( N, R
  19. uint8_t  USBD_MC_DeInit (USBD_HandleTypeDef *pdev,
    & r% n, R* G0 {5 v1 H& }% F7 R# G
  20.                               uint8_t cfgidx);
    7 {3 t8 E" K9 p
  21. , ^" j5 C, z& ^; w
  22. uint8_t  USBD_MC_Setup (USBD_HandleTypeDef *pdev,
    4 y, @4 L/ `- E# d
  23.                              USBD_SetupReqTypedef *req);
    2 S# e% v  i0 b& T2 _

  24. 7 Z2 y9 }& b7 B* z) a6 Q
  25. uint8_t  USBD_MC_DataIn (USBD_HandleTypeDef *pdev, 6 o" N1 e$ }6 A+ m: R3 [" F
  26.                               uint8_t epnum);
    1 L4 p- P- y! E' Q
  27. 9 _0 `9 S) L0 L$ ~* P$ Q+ d
  28. " X2 L4 u7 ~+ R7 d% O7 ?
  29. uint8_t  USBD_MC_DataOut (USBD_HandleTypeDef *pdev, 5 B' h- B! m% w" Z2 T
  30.                                uint8_t epnum);
    * K  p4 V0 n! a9 N8 f9 j
  31. . E6 E& q' {+ W# n9 B8 b5 }2 }
  32. uint8_t  *USBD_MC_GetHSCfgDesc (uint16_t *length);' T3 b  o2 n7 f! ^) P
  33. / A) g9 ?1 ?+ U5 z7 Z2 A# ]2 ]. W
  34. uint8_t  *USBD_MC_GetFSCfgDesc (uint16_t *length);- Y2 b. ~: K" {% m" Q2 R: ]

  35. ; Y# n9 @0 K( f. B& n4 d
  36. uint8_t  *USBD_MC_GetOtherSpeedCfgDesc (uint16_t *length);5 H' N- j* k, i: I

  37. 2 g' c9 |' j4 A- S; k  K
  38. uint8_t  *USBD_MC_GetDeviceQualifierDescriptor (uint16_t *length);+ z; S3 M4 u+ s+ ?8 ^
  39. 8 H2 l; {! o! p! P3 d" ]
  40. static uint8_t  USBD_MC_RxReady (USBD_HandleTypeDef *pdev);
    . @# i  |# U! {; D( T3 g9 A
  41. static void MC_Switch_MSC(USBD_HandleTypeDef *pdev);& g7 b; o5 Y0 c
  42. static void MC_Switch_CDC(USBD_HandleTypeDef *pdev);
    8 w% g  b1 @* L. k: ]
  43. , o4 G4 [4 K! \( ^/ [1 `
  44. /**# h% C, @9 I+ S0 s. g
  45.   * @}' B( k# C, ^5 j4 L6 [
  46.   */
    # q. m' i8 N7 p+ \: ^! g
  47. extern USBD_HandleTypeDef hUsbDeviceFS;9 A4 \5 u6 x) L9 y' m# J8 G$ d
  48. ! o3 l  h  J; K
  49. / h6 a1 B( K% f4 V8 O
  50. /** @defgroup MC_CORE_Private_Variables& r7 V( L8 r7 i6 u% ]
  51.   * @{1 b; ^: w% T9 H7 i
  52.   */
    $ r8 {+ L+ p2 d2 J; _
  53. USBD_ClassTypeDef  USBD_COMPOSITE =   ~, R1 {+ Q" \
  54. {" w* d' q+ Y  \4 D+ B8 [
  55.   USBD_MC_Init,$ _' Y+ P; v6 h/ x
  56.   USBD_MC_DeInit," H$ _* t3 _5 J: z1 i' q" Z
  57.   USBD_MC_Setup,7 `8 Z. w5 T4 {3 F; m( k
  58.   NULL, /*EP0_TxSent*/  . {1 n  F9 I. M5 x
  59.   USBD_MC_RxReady, /*EP0_RxReady*/8 }5 ^5 u: b, e6 s& U+ E
  60.   USBD_MC_DataIn,8 A* \8 e0 V2 I/ `
  61.   USBD_MC_DataOut,- X2 G& }" X, ~: m# N0 I
  62.   NULL, /*SOF */ # A8 L$ m* M4 d4 w
  63.   NULL,  5 W  T' J% c* z
  64.   NULL,     
    / i0 f8 o7 _% i2 f' g! W0 p; j  v
  65.   USBD_MC_GetHSCfgDesc,
    2 V' \6 b5 @3 T  ~# q' P
  66.   USBD_MC_GetFSCfgDesc,  
    * b' E' Q  H$ y& d! N9 {
  67.   USBD_MC_GetOtherSpeedCfgDesc,
    5 T( M7 R" P' Z2 N( s1 m) |
  68.   USBD_MC_GetDeviceQualifierDescriptor,0 s( r0 C$ N7 g; P
  69. };
    * f  A% u8 b2 d$ E2 _% a: ~

  70. ' i/ L, e- y3 R, L3 m+ m
  71. /* USB Mass storage device Configuration Descriptor */
    : Q3 L. Z2 q, {' O6 _1 _
  72. /*   All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */
    + X, u0 k5 F' O+ U' b" x7 ?4 x
  73. uint8_t USBD_MC_CfgDesc[USB_MC_CONFIG_DESC_SIZ] =
    . X' }4 }) P. L; g; H
  74. {5 z- M" P7 d% n* v) J
  75.   /*Configuration Descriptor*/
    ; P! U, U9 E2 l* t* ?4 e
  76.   0x09,   /* bLength: Configuration Descriptor size */
    ; Y2 \1 c  H& ]1 G# j! n
  77.   USB_DESC_TYPE_CONFIGURATION,      /* bDescriptorType: Configuration */
    1 _/ T5 m1 h% Q2 D* |4 d
  78.   USB_MC_CONFIG_DESC_SIZ,                /* wTotalLength:no of returned bytes */' N+ m* d( I0 R$ R+ Z1 k1 n) i( U6 c8 ?
  79.   0x00,
    & p# s1 o) k/ P$ X$ \; ?" M
  80.   0x03,   /* bNumInterfaces: 3 interface */+ J6 V, y$ s9 p' ^0 G# o
  81.   0x01,   /* bConfigurationValue: Configuration value */" l3 @& ^) x+ @. n4 j3 H. V
  82.   0x00,   /* iConfiguration: Index of string descriptor describing the configuration */2 |6 y& k1 @$ l2 M; f! `
  83.   0xC0,   /* bmAttributes: self powered */
    8 p: Q2 ^9 V/ @8 @) m$ A% }
  84.   0x32,   /* MaxPower 0 mA */  A$ D- o1 a7 E3 M
  85.   5 ~9 S+ v: W6 g9 H
  86.   /*---------------------------------------------------------------------------*/
      Z. a6 y5 y7 q. ^+ B* Y
  87.   // IAD9 M# B8 W: J  N: n/ Q
  88.   0x08,        //描述符大小
    ( \; [9 P- k  W2 e
  89.   0x0B,        //IAD描述符类型
    # c$ N! T  g. V& Q, a! U' e/ V
  90.   0x00,        // bFirstInterface ' E7 f; [5 Z: z& V- {5 q
  91.   0x02,        // bInterfaceCount
    0 W1 A  h% o- U
  92.   0x02,        // bFunctionClass: CDC Class1 Y) e: k( m: ]6 }9 \* c
  93.   0x02,        // bFunctionSubClass
    3 k; r( X; c% @/ X# p/ a- _
  94.   0x01,        // bFunctionProtocol
    ! h/ Q1 }3 V5 ^) Y5 x% N) b5 u
  95.   0x00,        // iFunction      
    ) J( [5 s: y2 D6 p# u/ }- G  ]
  96.   ) \- s9 Z$ P1 J8 A/ k  m4 @& v
  97.   /*---------------------------------------------------------------------------*/
    4 m8 p$ Q: h2 d. [  U( e- K, [3 I
  98.   /*Interface Descriptor */
    ' z# ?/ Q* I2 G- {
  99.   0x09,   /* bLength: Interface Descriptor size */
    % A+ a0 `- a" q9 A1 N* e
  100.   USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: Interface */
    . K/ }% F$ k% X) f- ~
  101.   /* Interface descriptor type */
    : `: R3 L; s4 J: W9 Q; |" p" N
  102.   0x00,   /* bInterfaceNumber: Number of Interface */6 B. y) z  O0 Q
  103.   0x00,   /* bAlternateSetting: Alternate setting */, k% M: Q% V, H) a8 F3 J
  104.   0x01,   /* bNumEndpoints: One endpoints used */
    " L8 F  @6 v! d$ I* X/ Y; I
  105.   0x02,   /* bInterfaceClass: Communication Interface Class */
    ( P3 h8 k4 M; V2 D% [$ T! R9 i
  106.   0x02,   /* bInterfaceSubClass: Abstract Control Model */# {; `9 P# f2 W, M% a
  107.   0x01,   /* bInterfaceProtocol: Common AT commands */
    1 M4 `1 D1 L/ m. N2 i
  108.   0x00,   /* iInterface: */, p/ _- |& N; O# d, u6 U( ]
  109.   
    , ?7 v+ r3 v' `
  110.   /*Header Functional Descriptor*/
    $ k7 R& A; u% _4 y7 l! \' p0 e6 T
  111.   0x05,   /* bLength: Endpoint Descriptor size */
    6 s8 S, q1 b0 w( v( s3 X* k$ I
  112.   0x24,   /* bDescriptorType: CS_INTERFACE */# B* f! E) @) o
  113.   0x00,   /* bDescriptorSubtype: Header Func Desc */% W& ~7 R6 o# _
  114.   0x10,   /* bcdCDC: spec release number */- k2 Q$ s8 t( l6 V8 B% ]9 A
  115.   0x01,
    ) T( ]) G- h6 n2 |
  116.   
    . V8 M2 C$ e6 k2 @% _- i
  117.   /*Call Management Functional Descriptor*/8 y3 V, o5 A. X, C$ R
  118.   0x05,   /* bFunctionLength */9 t2 k" D; E6 z5 k0 |0 I
  119.   0x24,   /* bDescriptorType: CS_INTERFACE */% N% v9 I" E! J
  120.   0x01,   /* bDescriptorSubtype: Call Management Func Desc */
    : t0 I" r; N# m" F7 h+ i
  121.   0x00,   /* bmCapabilities: D0+D1 */! b, A( u; P) r3 @- X
  122.   0x01,   /* bDataInterface: 1 */1 ~/ Q) l8 a3 M" j
  123.   - j/ D2 P0 P3 f* ^+ K2 ~. }# k
  124.   /*ACM Functional Descriptor*/
    ' u  B+ I% K# P6 U; B( i( b
  125.   0x04,   /* bFunctionLength */  |) P2 C& k" ~  P$ D
  126.   0x24,   /* bDescriptorType: CS_INTERFACE */( V. [/ I% K- v, t  Q! q" j# Z6 m
  127.   0x02,   /* bDescriptorSubtype: Abstract Control Management desc */
    4 K$ O) G( g( d
  128.   0x02,   /* bmCapabilities */( j  y$ S( R4 |% v- @- d6 Y
  129.   
    4 i" [  P/ E. n1 T, G/ x! H
  130.   /*Union Functional Descriptor*/
    & A$ l: `0 P2 W+ v, [/ c: V7 J5 u% }! v1 |
  131.   0x05,   /* bFunctionLength */* w) W4 m$ X7 \3 w. g
  132.   0x24,   /* bDescriptorType: CS_INTERFACE */
    ' o) V/ ~8 {" c; h$ P! f
  133.   0x06,   /* bDescriptorSubtype: Union func desc */
    - q9 _( _8 ?2 S+ t  `
  134.   0x00,   /* bMasterInterface: Communication class interface */) V2 y( y1 @: r. V
  135.   0x01,   /* bSlaveInterface0: Data Class Interface */7 C  Q0 r. o6 r2 h
  136.   + n  N7 _* {9 i
  137.   /*Endpoint 2 Descriptor*/2 S' J! ~! y) a9 Y1 a! E
  138.   0x07,                           /* bLength: Endpoint Descriptor size */
    5 G* ^9 K: P, h3 W4 z, E
  139.   USB_DESC_TYPE_ENDPOINT,   /* bDescriptorType: Endpoint */2 w1 r% D# ]8 p. o0 C
  140.   MC_CDC_CMD_EP,                     /* bEndpointAddress */4 T8 f" w% G) U: o1 o) Z
  141.   0x03,                           /* bmAttributes: Interrupt */6 o( |  w+ k) X8 V' M% r
  142.   LOBYTE(CDC_CMD_PACKET_SIZE),     /* wMaxPacketSize: */
    " W( g' `. l/ c
  143.   HIBYTE(CDC_CMD_PACKET_SIZE),: d- P; |- a* A8 @$ U1 l
  144.   0x10,                           /* bInterval: */
    1 l4 K3 U% `  h8 A) \" B# I; ?
  145.   ) R0 Q& h8 J) L% h8 @
  146.   /*Data class interface descriptor*/
    " y7 f! b  I" G% e  `
  147.   0x09,   /* bLength: Endpoint Descriptor size */
    + J1 Q2 s+ U- A# v8 `
  148.   USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: */
    ! n& u, Q* W# x0 Y& Q
  149.   0x01,   /* bInterfaceNumber: Number of Interface */
    % V" n0 V# t& |# Z- s4 Q, l
  150.   0x00,   /* bAlternateSetting: Alternate setting */
    / R) S0 G  V3 h4 L" F1 O) ~
  151.   0x02,   /* bNumEndpoints: Two endpoints used */
    + [/ o$ n, h8 D0 p
  152.   0x0A,   /* bInterfaceClass: CDC */! T3 E% c  E7 D& d1 i) L
  153.   0x00,   /* bInterfaceSubClass: */
    * t: R6 Q0 U. H6 ~
  154.   0x00,   /* bInterfaceProtocol: */% g7 F" l. h3 S7 F" a3 V  }6 x
  155.   0x00,   /* iInterface: */
    1 `- j4 J! j" G
  156.   4 V4 V' I  z  K2 N9 {
  157.   /*Endpoint OUT Descriptor*/
    4 b$ q# d# K8 ^+ ]$ v4 k
  158.   0x07,   /* bLength: Endpoint Descriptor size */
    - \2 r* C7 x; j: u4 L; o& d* G( _! l
  159.   USB_DESC_TYPE_ENDPOINT,      /* bDescriptorType: Endpoint */
    0 l! r$ f7 z: i/ y0 E
  160.   MC_CDC_OUT_EP,                        /* bEndpointAddress */  `7 A: z( ?+ h6 o0 u) x! z. l8 U
  161.   0x02,                              /* bmAttributes: Bulk */
    * A7 x0 n& R% K/ \7 O
  162.   LOBYTE(MC_MAX_FS_PACKET),  /* wMaxPacketSize: */
    " L) U! O# @" s5 ^% c  @
  163.   HIBYTE(MC_MAX_FS_PACKET),
    0 A( @5 i3 X8 s" d% E
  164.   0x00,                              /* bInterval: ignore for Bulk transfer *// Y# M6 y4 N+ B. Z9 F
  165.   
    9 r  ]* S4 P+ V2 G
  166.   /*Endpoint IN Descriptor*/
    & p/ \" `# _* w% @9 O$ R+ E; t( E
  167.   0x07,   /* bLength: Endpoint Descriptor size */4 q$ H$ T' |9 n: K8 J" `
  168.   USB_DESC_TYPE_ENDPOINT,      /* bDescriptorType: Endpoint */  `) h9 v# g- a5 {; {: ~$ ^
  169.   MC_CDC_IN_EP,                         /* bEndpointAddress */! K- T' @8 r8 ]3 p7 \7 s
  170.   0x02,                              /* bmAttributes: Bulk */
    4 e$ a/ Q3 s. G
  171.   LOBYTE(MC_MAX_FS_PACKET),  /* wMaxPacketSize: *// o2 g$ ^* k, {7 m7 R0 j6 e
  172.   HIBYTE(MC_MAX_FS_PACKET),
    + A1 S$ J! N: ~8 ^* [& K$ I
  173.   0x00,                               /* bInterval: ignore for Bulk transfer */
    . {2 t8 ]2 ~+ O- U; M$ [$ b
  174. 1 U/ p* }2 `5 D: R7 z* G. t
  175.   /*---------------------------------------------------------------------------*/+ ~, f% @5 P1 _) l( n8 [( ~
  176.   // IAD& w# L: N& i: e6 I/ F3 }* W
  177.   0x08,        //描述符大小
    5 B" b3 W# d/ B$ r
  178.   0x0B,        //IAD描述符类型# n/ P  ^' F4 g7 ~8 U% g
  179.   0x02,        // bFirstInterface
    2 ?1 g0 w, y! t) ?: e. U
  180.   0x01,        // bInterfaceCount
    3 F1 g3 D9 a& E9 `0 u  Z5 S9 f
  181.   0x08,        // bFunctionClass: MASS STORAGE Class  B, n& ^4 q  ^  F$ a2 ^' V4 [
  182.   0x06,        // bFunctionSubClass6 x- g4 F) z+ D
  183.   0x50,        // bFunctionProtocol
    # r  E/ X" e( s2 ^1 h9 ~
  184.   0x01,        // iFunction   
    5 \$ B! \$ E+ L; l4 T! H

  185. # P. ~/ Y/ E+ ^8 M: K  D: |- `
  186.   /********************  Mass Storage interface ********************/
    ' N* d& I3 \8 p6 F
  187.   0x09,   /* bLength: Interface Descriptor size */
    * L- V/ S* h; r* ^: o; w8 [
  188.   0x04,   /* bDescriptorType: */, V$ \; o6 O" e0 S. I
  189.   0x02,   /* bInterfaceNumber: Number of Interface */1 L, }* N5 \5 N  j* C4 U2 t
  190.   0x00,   /* bAlternateSetting: Alternate setting */( A2 J2 g+ p! d, r
  191.   0x02,   /* bNumEndpoints*/6 U% U6 R) w3 o, H4 V: p
  192.   0x08,   /* bInterfaceClass: MSC Class */
    ( m, l. W1 a* m! o, r& Y
  193.   0x06,   /* bInterfaceSubClass : SCSI transparent*/) k$ [0 f! V) r3 l; E6 D
  194.   0x50,   /* nInterfaceProtocol */. o, `7 x: P6 X4 G4 U
  195.   0x05,          /* iInterface: */. ~; x% ~+ N' T/ K, U1 [) s
  196.   /********************  Mass Storage Endpoints ********************/9 v( B6 l. A' D: T# L
  197.   0x07,   /*Endpoint descriptor length = 7*/7 z: _' Y4 ]8 M! X* y" |$ m& [; T
  198.   0x05,   /*Endpoint descriptor type */
    # C6 c0 c% M! h7 [7 K3 ^7 W
  199.   MC_MSC_EPIN_ADDR,   /*Endpoint address (IN, address 1) */
      h2 i3 U; _: u2 d. H. l. g! H
  200.   0x02,   /*Bulk endpoint type */4 }1 }" J0 e  K1 L- Q/ s
  201.   LOBYTE(MC_MAX_FS_PACKET),
    ( N- s/ T2 o: a4 ^1 \9 Y" n
  202.   HIBYTE(MC_MAX_FS_PACKET),0 M- S2 `0 G+ |  M# K9 f
  203.   0x00,   /*Polling interval in milliseconds */
    ) p0 Z' d6 z$ s3 e% G
  204.   . u$ x" m( b: L. h- ^' F
  205.   0x07,   /*Endpoint descriptor length = 7 */
    - Y6 F; c6 p& C8 d# p! j' X
  206.   0x05,   /*Endpoint descriptor type */
    9 e' c! D: b  z; P* b' Z9 k- r
  207.   MC_MSC_EPOUT_ADDR,   /*Endpoint address (OUT, address 1) */
    * F4 a6 n( W0 f/ ?3 g) o' }
  208.   0x02,   /*Bulk endpoint type */- ?8 B7 H  x' m, r5 n, U$ D
  209.   LOBYTE(MC_MAX_FS_PACKET),, Z* T) I) h) V, P, g' A# ?
  210.   HIBYTE(MC_MAX_FS_PACKET),+ _+ o6 A1 d- x9 N' p  x
  211.   0x00     /*Polling interval in milliseconds*/' A, r" Q2 `1 p! S9 I: M  S
  212. };! C- `; |, \, A1 t
  213.   
    : R, e* F3 I: \  j
  214. uint8_t USBD_MC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] =5 b! m3 B. @2 i' @
  215. {& h2 k3 F! p( d) U: t. H
  216.   USB_LEN_DEV_QUALIFIER_DESC,
    7 {6 y7 \9 b; ]/ a
  217.   USB_DESC_TYPE_DEVICE_QUALIFIER,
    ' o! w* t; K. V% [$ P- X8 [1 z. a, E
  218.   0x00,( G/ v1 ?9 ~1 q" c
  219.   0x02,2 d. Y5 v+ i1 a( p+ h# |0 j7 \5 i
  220.   0x00,
    ' I3 A. b& O! I! o& N% |
  221.   0x00,
    5 z3 \  I8 l# [6 M% l5 y
  222.   0x00,
    * ]  x; b: ]! F
  223.   MC_MAX_FS_PACKET,
    + d9 T' m7 W4 j) t2 U8 f7 K
  224.   0x01,; C. t" Z  r# M9 W' V
  225.   0x00,. j, [6 C  t. {, u2 S4 R
  226. };
    $ @, j& W$ ^/ [, k7 b  ^* K1 f& S

  227. . a7 l* c& X' S3 [$ I5 h; O; a
  228. /**
    6 U* H4 U; l3 A& F4 G% s+ w
  229.   * @brief  USBD_MC_Init
    0 _! i* ^; V! z
  230.   *         Initialize  the mass storage configuration
    , M& Z' ?( H0 b* z, \% j& c, F
  231.   * @param  pdev: device instance8 E! z6 O1 W: z2 T
  232.   * @param  cfgidx: configuration index
    # r' z! S  a: F# @) O+ U
  233.   * @retval status
    & {: F+ i  S& R7 u
  234.   *// d2 q; g$ ?4 x% r8 A
  235. uint8_t  USBD_MC_Init (USBD_HandleTypeDef *pdev, uint8_t cfgidx)
    6 N% U; i' i, L
  236. {' f7 d) u2 [6 L/ |! @
  237.   uint8_t ret = 0U;# B1 d3 C$ j) s5 q3 i. K+ d
  238. % V! J+ X) d0 p9 Q5 Q  j, Q
  239.   # ]! J. \/ @+ q+ D# i2 k
  240.   USBD_CDC_HandleTypeDef      * hcdc;+ i/ `  r7 Y# x% r
  241.     / l& g5 b: Q: ~1 n5 g  h& p; t
  242.   MC_Switch_CDC(pdev);
    , |1 R5 `( f+ }) w
  243.   ! b- Q5 e6 E& G
  244.   USBD_LL_OpenEP(pdev,
    . e# X4 D) h- i# f$ w5 g
  245.                  MC_CDC_IN_EP,
    2 Q1 R) O+ l. m2 b
  246.                  USBD_EP_TYPE_BULK,6 |& C" D$ S: h# B
  247.                  MC_MAX_FS_PACKET);4 l: W* K/ H$ d/ A4 F: T( r
  248.   
    1 |! a- o- X: k% g/ q5 U0 k+ {0 n
  249.   USBD_LL_OpenEP(pdev,5 ]' ^1 k7 @0 x& o' Q5 A
  250.                  MC_CDC_OUT_EP,' I! H: M! G7 y- B2 g
  251.                  USBD_EP_TYPE_BULK,* A+ B1 T3 K; ^/ z/ W
  252.                  MC_MAX_FS_PACKET);5 Q! V# u: ~7 \8 |# e% t! p
  253.   
    ( L" h2 k8 D2 Y; l
  254.   USBD_LL_OpenEP(pdev,
    7 k7 P* L2 n, y! A
  255.                  MC_CDC_CMD_EP,
    0 W' J# h. T: ~8 x8 Q4 J
  256.                  USBD_EP_TYPE_INTR,
    $ |6 i6 c, K4 s
  257.                  CDC_CMD_PACKET_SIZE);: v( f8 t& B% N; K) w$ Y1 v5 _7 v

  258. . b) ^2 C3 A4 c; R
  259.   hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
    6 G; O: q' X! j7 `6 A
  260. * g8 N8 H0 u1 v% v1 R# H, _; N" \% f
  261.   ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Init();
    ! u* b" N# j5 c7 {  U- L$ J. E
  262.   6 p" t4 e2 P+ x1 q1 \" I
  263.   hcdc->TxState =0;; I( k* v( m  [
  264.   hcdc->RxState =0;' V# D: j9 ~3 h9 M
  265.   
    2 F, I3 @. E; x  F  S4 t
  266.   USBD_LL_PrepareReceive(pdev,5 S4 e' g4 r3 G3 r: X. n
  267.                          MC_CDC_OUT_EP,
    2 ~- T5 u9 y- F' |
  268.                          hcdc->RxBuffer,
    $ U9 x2 l; Z+ V% r0 F6 C
  269.                          MC_MAX_FS_PACKET);
    1 L2 M; q7 r' r  e

  270. ! ~# L3 z4 E' R
  271.   pCDCData = pdev->pClassData;# G* }/ E. c, G( X. B: T. p- D: o4 J

  272. ) |, }# l  L& V
  273.   MC_Switch_MSC(pdev);& s& v$ z- p- F5 K) M7 A
  274.   
    ; I- p/ d  t; v9 r; e8 s
  275.   USBD_LL_OpenEP(pdev,
    % W  w" \5 H% r) G" ^
  276.                  MC_MSC_EPOUT_ADDR,- X8 e2 m  h; H
  277.                  USBD_EP_TYPE_BULK,% V% `# y0 ^8 k/ Q9 S$ l# `
  278.                  MC_MAX_FS_PACKET);4 r" A+ K  j" |+ O2 I
  279.   
    ( ~. ~- a6 d! C! q5 Z5 e7 R
  280.   USBD_LL_OpenEP(pdev,: Y. U  H' j5 G8 l$ V
  281.                  MC_MSC_EPIN_ADDR,
      g, ?0 [$ E! o. R5 C: B
  282.                  USBD_EP_TYPE_BULK,' n% s3 A7 t1 L0 B6 r: h7 O
  283.                  MC_MAX_FS_PACKET);
    0 g- Q* R: p, p$ i8 `
  284.   : h! D; Z# l$ \( W! u8 H) e: i
  285.   MSC_BOT_Init(pdev);9 s! {$ P+ E+ i3 V* P9 e1 {. `
  286.   
    ' s' i% o8 Z6 d/ h: u
  287.   pMSCData = pdev->pClassData;
    $ w( y, B' \& G; v, Y- V  W
  288.   
    ; {& R4 u: l  ~# r
  289.   if(pdev->pClassData == NULL)
    ! \( |4 i1 d/ p$ R, o7 k, g
  290.   {" ~! _  c: N1 A1 r3 U9 m9 }
  291.     ret = USBD_FAIL;2 j0 g  g+ a5 G8 b4 f; j1 t$ h
  292.   }
    0 d# a& B" g0 P( J

  293. 4 N5 @4 ~' I$ H6 G" m/ p7 N
  294.   return ret;
    : X( X  O4 ]# @- B' g" p) d
  295. }
    - c* M1 `4 H/ W

  296. * `  A  Y2 p% S3 N* @# p' [
  297. /**4 [9 n* t' @" }
  298.   * @brief  USBD_MC_DeInit
    0 q, _9 t4 l# v8 l. q
  299.   *         DeInitilaize  the mass storage configuration
    8 \$ e6 g# S4 h4 H0 ^0 z
  300.   * @param  pdev: device instance# L8 v3 C4 p( I5 Y1 k
  301.   * @param  cfgidx: configuration index6 F& ^3 i( W5 x+ c. h3 u9 e
  302.   * @retval status
    5 J/ s9 E7 p" B, f2 I
  303.   */
    6 W/ ]0 x1 O. ^+ O4 X( Z/ ?
  304. uint8_t  USBD_MC_DeInit (USBD_HandleTypeDef *pdev,
    6 r2 M% L2 n  S1 ~0 t# l' L* C. i, T( e
  305.                               uint8_t cfgidx)
    ; X+ |: y9 C3 o& L4 _5 e6 ]
  306. {+ M, m, i4 T8 e$ _7 k2 Y
  307.   return USBD_OK;
    # I: a; x! T, g' H6 P
  308. }+ p/ q# G1 \7 s5 d; L3 x
  309. /**
    2 Q7 g6 r" T4 U6 @
  310. * @brief  USBD_MC_Setup
    4 w; F9 h$ W1 w. `
  311. *         Handle the MC specific requests9 a( f  a1 B) M) `; W0 Y
  312. * @param  pdev: device instance
    # B4 D, n- g& V
  313. * @param  req: USB request
    , h# p/ G& u' Y4 ^3 _/ L7 ?
  314. * @retval status
    9 w( _8 b. u1 U. f% I5 R. q0 k0 ^
  315. */
    ' F/ {; ?7 K- p, u& V
  316. uint8_t  USBD_MC_Setup (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
    ! w# ?2 F: Y6 T8 b* K  ^& O# Y! m
  317. {$ P, r  m8 T; U8 ?' ?) ?/ P* T
  318.   if(req->wIndex == 0x0002)
    " ?9 x0 D0 k( s# p, z6 K: ]4 F9 w
  319.   {
    1 G( I( f) M; Z1 c
  320.     MC_Switch_MSC(pdev);
    & l5 n# R5 B0 B0 R$ y+ J
  321.     USBD_MSC_BOT_HandleTypeDef     *hmsc = (USBD_MSC_BOT_HandleTypeDef*) pdev->pClassData;   
    1 Q  J6 [- I7 S1 S1 \8 D# q6 G% [( \9 @
  322.     5 u8 o" z3 b7 d9 M
  323.     switch (req->bmRequest & USB_REQ_TYPE_MASK): b* Z, n4 y- @+ y+ B: E9 n7 o, q. Q
  324.     {- s9 J1 O' @* M( l" z2 [5 B
  325. 5 \* q( ~& U% a! ?2 {
  326.     /* Class request */
    1 e. {! p5 h" Z0 m* e* n' g
  327.     case USB_REQ_TYPE_CLASS :
    . M: K! j" P5 z/ t/ s" L: J8 W3 Q& v( x
  328.       switch (req->bRequest)0 u/ _, V" F8 h
  329.       {
    2 Q4 ~3 K8 y9 q+ x$ ^2 z
  330.       case BOT_GET_MAX_LUN :
    ! X0 Z: x: X( z9 _! s; B% U
  331. ) h+ }' V/ g% K! r# y
  332.         if((req->wValue  == 0) && 0 o3 w" v* y; [
  333.            (req->wLength == 1) &&+ O& `5 }6 E5 Y9 t# o
  334.            ((req->bmRequest & 0x80) == 0x80))) w$ m, m" r9 x
  335.         {- g  ]& l! W; Z6 }" U: F
  336.           hmsc->max_lun = ((USBD_StorageTypeDef *)pdev->pUserData)->GetMaxLun();
    9 j  j7 q, T& Z4 Z
  337.           USBD_CtlSendData (pdev,
    # }3 s. @/ P7 O5 m3 d, [
  338.                             (uint8_t *)&hmsc->max_lun,7 s! m! A# o& Y. Y9 S
  339.                             1);
    # i4 p& ^8 [' K6 d
  340.         }
    4 |7 t) E: O2 i. f% q8 z  h
  341.         else
    0 N+ D# d, H( v' I. E
  342.         {
    7 I% e& H' p/ z/ P" o$ i8 e" D
  343.            USBD_CtlError(pdev , req);
    5 _9 b( X1 s$ q3 s) t. b) x0 `" _6 M
  344.            return USBD_FAIL; $ G7 E% Z: ?# B& P; R6 g
  345.         }
    & d3 z9 }9 C. s7 W. k* k* S) V
  346.         break;
    ! O& c3 F! ?% J& V3 P% f6 R
  347.         ) S5 F9 o' V  o9 }# q7 \
  348.       case BOT_RESET :3 j5 z  E8 Q, t9 A
  349.         if((req->wValue  == 0) &&
    3 v1 t/ e) ]" P% w" {) U
  350.            (req->wLength == 0) &&
    4 x, F1 V- M& w4 }
  351.           ((req->bmRequest & 0x80) != 0x80))
    1 G% N1 Q, f/ e3 A' V. e
  352.         {      
    & ~$ K# Z7 f% m
  353.            MSC_BOT_Reset(pdev);  U2 j3 Q# Q2 d# Y& j
  354.         }
    ( q, c, y/ ^/ f" k
  355.         else$ h" V- E8 C  m) U$ L+ K1 H
  356.         {
    / b* K% ^% R& e5 @
  357.            USBD_CtlError(pdev , req);
    5 d0 _, ^' `! I$ k
  358.            return USBD_FAIL; 3 n, `/ N# G1 a3 D8 L
  359.         }
    8 a- e0 q( e$ K( l
  360.         break;
    ) p, L+ F; A! E3 K. y, Q% ?
  361. , A( t5 {) l+ F8 P
  362.       default:
    ( n4 ?9 N- y* ^
  363.          USBD_CtlError(pdev , req);0 L0 |7 K; A, O$ Y+ {0 i! M6 a
  364.          return USBD_FAIL;
    2 _: R" F5 H% O6 ~7 p
  365.       }2 ^) v; y4 g9 J6 i, u
  366.       break;: v; B( S9 d; Z& x% q# D3 V* M
  367.     /* Interface & Endpoint request */+ ?0 J4 ^2 u- v* Q" G! P
  368.     case USB_REQ_TYPE_STANDARD:
    $ P2 N) s3 S1 I. a8 K
  369.       switch (req->bRequest)
    - Q! I. Q2 |- F" J1 ~# `6 p9 D7 M% A1 h
  370.       {' {/ m2 }# [* E  z* _5 p) K
  371.       case USB_REQ_GET_INTERFACE :* D2 K. g5 a8 i+ p4 L
  372.         USBD_CtlSendData (pdev,, x! c0 e$ i( Y8 |- M+ X; V
  373.                           (uint8_t *)&hmsc->interface,- e4 v: ]* [6 e9 H3 G
  374.                           1);
    0 g* }2 T7 l& m1 B* C/ a+ ?
  375.         break;& r* C8 ^7 F+ h1 i
  376.         ( @# n8 J) f% V' |# M! D- _
  377.       case USB_REQ_SET_INTERFACE :6 D" v. @/ H" \
  378.         hmsc->interface = (uint8_t)(req->wValue);7 u$ I1 B) O, G3 {1 H' o
  379.         break;
    0 h& B# Y2 M9 b+ [
  380.       , {+ N- K& {: V0 z  G& N& c* r+ i  @
  381.       case USB_REQ_CLEAR_FEATURE:  
      L+ `3 M0 |3 z  F+ S1 F3 C
  382.         7 Y% G. a! G, u; u: _8 Z2 k- A
  383.         /* Flush the FIFO and Clear the stall status */   
    1 p5 E( R" B% g
  384.         USBD_LL_FlushEP(pdev, (uint8_t)req->wIndex);% A" |' [  h* e) D6 `) X2 d
  385.         ; |% b% G3 E# V" S, N
  386.         /* Reactivate the EP */      2 R& ]$ ?) l, O, \5 J
  387.         USBD_LL_CloseEP (pdev , (uint8_t)req->wIndex);# V, k3 O6 B% X  ~
  388.         if((((uint8_t)req->wIndex) & 0x80) == 0x80)
    / p0 h7 O" S2 B4 X5 |: j
  389.         {4 r1 ?& |# r) m9 R* E6 n+ V
  390.           if(pdev->dev_speed == USBD_SPEED_HIGH  )
    2 b$ M% V2 T7 B$ Y
  391.           {
    ( a$ F  ^9 I& _2 R
  392.             /* Open EP IN */; j9 h5 ]+ z" k- M$ q! i3 G( P2 L6 a& ^+ w
  393.             USBD_LL_OpenEP(pdev,6 l6 h" u' i7 Z$ Z
  394.                            MC_MSC_EPIN_ADDR,( q/ G/ C! e# d5 F: O! M
  395.                            USBD_EP_TYPE_BULK,& g* V1 q# \8 ?% ~$ O
  396.                            MSC_MAX_HS_PACKET);  
    % y  [6 n; P" Y* ~+ Y- v% A
  397.           }) F( r( A/ q7 r9 l, q
  398.           else+ ]- d% |3 ^" L2 ^. k
  399.           {   $ p& |$ M+ n! J8 R, g: H, H
  400.             /* Open EP IN */& T$ G0 B: U1 y4 R0 t" M
  401.             USBD_LL_OpenEP(pdev,
    8 ?* S# r1 u- ~" ?
  402.                            MC_MSC_EPIN_ADDR,
    . ~  P: L' Z4 l$ @8 {2 N+ o
  403.                            USBD_EP_TYPE_BULK,! D9 U% d% P" k7 w2 s. L2 q( g
  404.                            MSC_MAX_FS_PACKET);  ! Z5 A. H6 E% k
  405.           }( Z" D) k- h2 o# i
  406.         }3 M9 b8 h. g& j+ K2 l
  407.         else3 n9 i+ W$ n0 A& G) Y
  408.         {& S7 \$ E. f  y" m5 q
  409.           if(pdev->dev_speed == USBD_SPEED_HIGH  )
    $ ?/ f$ Q5 }/ o" e1 K% ?5 Y" b
  410.           {2 L% q  n2 ]+ {! `2 B: A; K
  411.             /* Open EP IN */2 y- J* h( n% p/ {# ?
  412.             USBD_LL_OpenEP(pdev,
    + @" C  [3 L- M  X: j3 K! `
  413.                            MC_MSC_EPOUT_ADDR,
    * x4 B3 c, @4 }. ~& O2 ^) Y
  414.                            USBD_EP_TYPE_BULK,& e8 R6 \' [  J, [
  415.                            MSC_MAX_HS_PACKET);  9 R8 ~4 v$ }# L
  416.           }! {+ Z7 d0 r: _  D0 A
  417.           else. W+ ^  \1 I8 j  @1 M
  418.           {   $ M& ^+ |9 L( `# ~8 g+ K
  419.             /* Open EP IN */; [( t$ W  x8 u
  420.             USBD_LL_OpenEP(pdev,
    5 J. h! X5 W. p! I" W  @
  421.                            MC_MSC_EPOUT_ADDR," X2 J- S  F4 h3 {+ {0 V
  422.                            USBD_EP_TYPE_BULK,9 f' c& x; P0 k8 E; q0 x
  423.                            MSC_MAX_FS_PACKET);  
    / u  @: O1 `9 N8 `4 k
  424.           }4 J9 F/ e4 [# u" p0 M6 ^
  425.         }
    % D  H6 l+ i2 c! _
  426.         
    0 s* J7 v- d( F8 y- ]& O
  427.         /* Handle BOT error */
    + Y5 b. C6 a4 u8 s/ B2 s! ~, L) f7 z
  428.         MSC_BOT_CplClrFeature(pdev, (uint8_t)req->wIndex);. `, u* H7 h6 k- s
  429.         break;
    / U/ U+ i( X3 Y; U" B: J) q- B
  430.         
    ' V9 W$ r# N: f7 M1 q$ f2 F0 {. T
  431.       }  
    & q% V/ R6 `1 q  G4 g$ d
  432.       break;
    6 q7 i: C1 r' ~' I3 j
  433.      9 D, m# }: O; a; ^
  434.     default:- G( K" I4 B3 O: \% J
  435.       break;4 @4 W1 k; I# F( i) f
  436.     }
    , {, R+ e# H" X9 D9 G7 I
  437.   }
    7 v% {9 T- f. w: P( n- z+ L
  438.   else. r7 @5 f6 M; I' s6 f
  439.   {
    % \4 ^$ C8 G3 o9 a7 Z2 }
  440.     MC_Switch_CDC(pdev);
    ; ]8 `  e* m; h# D' h. ~
  441.     static uint8_t ifalt = 0;
    / r$ m7 l$ O9 d
  442.     USBD_CDC_HandleTypeDef * hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData;   
    / ^9 Z4 K0 S0 q6 i# b- y

  443. : I4 q: F( j4 e  k! W* u- y
  444.     switch (req->bmRequest & USB_REQ_TYPE_MASK)
    . B0 b7 i5 @8 _$ |. X9 g1 u+ b
  445.     {
    ; \1 B% r* T4 {! [
  446.     case USB_REQ_TYPE_CLASS :
    8 ~& q' p) N. f. V. }/ K8 o9 d$ R
  447.       if (req->wLength)
    . p  J/ d' l  _! u4 J
  448.       {
    9 M1 N4 U4 |! V% b3 }2 p+ o. H
  449.         if (req->bmRequest & 0x80)  E2 u9 ^& w6 [9 L) I& [
  450.         {
    4 f" a! k, [2 v9 L
  451.           ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest,
    ' L' _3 F# g% j. K% f
  452.                                                             (uint8_t *)hcdc->data,
    ; y2 E" z1 F7 r6 z9 o
  453.                                                             req->wLength);. D' H! s0 G& H1 z) x2 L, s
  454.             USBD_CtlSendData (pdev,
    9 g1 {* M& r* p% n1 Y
  455.                               (uint8_t *)hcdc->data,
    ( {2 k9 Z: q# s5 c! G+ a
  456.                               req->wLength);
    + P2 a, \' J0 S* {' n
  457.         }& \/ p- K, G; N( C8 W1 i! z- _/ }
  458.         else
    + ^9 n4 V) t- r
  459.         {
    , b- C" u$ t, S$ A
  460.           hcdc->CmdOpCode = req->bRequest;
    6 B# L/ Q( [. B# J
  461.           hcdc->CmdLength = req->wLength;
    1 K$ q- m: V, |8 w9 Y
  462.           ( B) v! b" ~6 }) ]9 U
  463.           USBD_CtlPrepareRx (pdev, 6 F0 |) X; d1 D) w6 g0 b
  464.                              (uint8_t *)hcdc->data," w& ?* E* g- ~0 e/ p
  465.                              req->wLength);, Q$ H+ `' o% `" h0 v
  466.         }
    2 ]) L  S$ Y8 r+ V3 |, M) f0 h
  467.         8 l9 i9 C7 y  O( e
  468.       }
    6 r" n  w* c; r7 E' m
  469.       else- M7 B, x0 C  X0 D6 H8 K. H
  470.       {
    8 S3 M9 Z7 k6 e: W# N' Q9 j
  471.         ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest,6 o- e; z% j. U2 V* V
  472.                                                           (uint8_t*)req,: |+ M  ~; c$ `3 ~
  473.                                                           0);
    $ s1 E0 X1 {) d" q6 l
  474.       }
    / b: j8 T1 R, b  `; B+ s
  475.       break;; S% @: N8 _* r* c, l0 i6 G/ d+ s+ |! }
  476.     0 S' ]) R+ k7 h& A' f
  477.     case USB_REQ_TYPE_STANDARD:3 d) u9 d# x2 M0 o% }" Y  J) I- w! I
  478.       switch (req->bRequest)
    " M4 {/ F0 _$ [& q: v# t4 @3 [) ^
  479.       {      
    4 F' U% E; r6 e5 r: f# u- o! @
  480.       case USB_REQ_GET_INTERFACE :+ u( Q. ~6 I  _% X  @7 {, J& p# R
  481.         USBD_CtlSendData (pdev,
    ) S+ I  U' l  o) v) s& w: a
  482.                           &ifalt,2 W! _% e- {7 l+ j" p
  483.                           1);
    ) p: \$ Q6 v0 l3 d9 y; J
  484.         break;. O3 P5 n3 g, ?3 E
  485.         * ~5 _$ S+ v7 g# N* H* S
  486.       case USB_REQ_SET_INTERFACE :( N4 t" l: @  H) _  K
  487.         break;& M  i5 X) e6 p3 e
  488.       }% l7 y6 N* q+ H# J1 \
  489.     / k: A* ]: @1 {6 M: c; c0 [
  490.     default:
    - u. S/ [( B* ^8 {8 s3 m
  491.       break;
    ; k- O  V% [6 }, {
  492.     }  
    % {, O, E' m: s0 V1 J9 D
  493.   }% {) A* v$ C0 r* Q6 d) A- S
  494.   $ m2 d) s5 I8 ]0 g. A
  495.   return USBD_OK;
    % Q( r( F; i7 A1 m
  496. }
      z/ b8 u  k' E2 Q2 y+ @4 M

  497. 7 R9 j6 M- l5 E$ F
  498. /**6 A, w) l* A2 r1 Q5 l- }, p/ k( V: B
  499. * @brief  USBD_MC_DataIn- c9 }( Q# A, N$ |7 a  t
  500. *         handle data IN Stage
    + j0 G7 J3 y5 H; g) |
  501. * @param  pdev: device instance
    + \) G3 F" z7 c
  502. * @param  epnum: endpoint index$ D& V# Y- k# S& c- D8 B, ~
  503. * @retval status
    + p0 g) V! |7 B# U+ b7 }2 j
  504. */; ?6 d  S! j: c
  505. uint8_t  USBD_MC_DataIn (USBD_HandleTypeDef *pdev,
    6 @* j3 |% C/ O
  506.                               uint8_t epnum)
    : S8 O& B5 D% f
  507. {4 P6 P0 I# F* u6 R
  508.   if(epnum == (MC_MSC_EPIN_ADDR & 0x7f))
    - Q7 c2 _  B! m/ z) \4 T0 m( i
  509.   {
    + q! N* |5 }+ d. w1 |
  510.     MC_Switch_MSC(pdev);
    $ r% b4 }, w( [7 b, z# d
  511.     MSC_BOT_DataIn(pdev , epnum);
    / Q. b* z# A4 ~
  512.   }5 H( A0 ]6 j) A2 O* X( v% o6 `
  513.   else if(epnum == (MC_CDC_IN_EP & 0x7f))
    7 T1 ~( @% z. f8 l& I+ a+ }
  514.   {+ g/ ]- n- h0 ]6 q' A
  515.     USBD_CDC_HandleTypeDef   *hcdc;
    3 \3 f, E* N# v/ M% t/ c
  516.    
    * r6 j' z/ r& T4 n% H: O
  517.     MC_Switch_CDC(pdev);6 x' A8 A# W1 Q: u9 t
  518.     hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;: x8 Y# Q. f, d4 N" y  ]0 k
  519.     hcdc->TxState = 0;   
    . t# P- u8 b8 H& [+ u5 V( @
  520.   }
    7 K( D# W6 Q0 A4 I/ O4 S4 i$ C# F
  521.   
    # y3 ^% O: x5 V! Q( Y
  522.   return USBD_OK;8 q# j* ^9 c) j2 ?3 _
  523. }" w& G4 w5 R' Z3 Z6 t& Z

  524. & H9 p. x4 S  G: E' a5 `/ I
  525. /**
    ! t, B, x- O0 `  M# T" L
  526. * @brief  USBD_MC_DataOut
    : G: `2 j$ h. {% ^
  527. *         handle data OUT Stage  F7 `$ g8 j1 t7 j( `
  528. * @param  pdev: device instance
    % i* ]/ F* b: o4 @
  529. * @param  epnum: endpoint index
    3 {) b3 M: E" f7 Q
  530. * @retval status
    $ o* U& G! K3 Z4 r4 h$ F# w, ]+ V
  531. */4 t' ?6 n% N+ [$ n" U/ f8 B
  532. uint8_t  USBD_MC_DataOut (USBD_HandleTypeDef *pdev,
    + v5 e5 O% N* A: A8 M& h8 K' f
  533.                                uint8_t epnum)" K$ s% E2 G0 ]$ k7 B% ^9 r
  534. {/ R( X! U/ z' A! S( ?
  535.   if(epnum == MC_MSC_EPOUT_ADDR)
    : C; D' a/ j) V* ~. m
  536.   {
    3 R5 }1 Q7 {; U: Y8 {
  537.     MC_Switch_MSC(pdev);1 h8 X0 ?3 X+ v2 I4 P
  538.     MSC_BOT_DataOut(pdev , epnum);
    7 v0 w* V$ y1 D
  539.   }; K; J" Z. N! X3 J% j  `2 j( }
  540.   else if(epnum == MC_CDC_OUT_EP)) K+ y' l" v  z8 z* Y
  541.   {
    " }# P; A: c6 N* W8 K& a$ k. L, W
  542.     USBD_CDC_HandleTypeDef   *hcdc;, L$ _9 n) h( W5 |1 k
  543.    
    5 d1 X! |# d4 S. \7 q) ?) [
  544.     MC_Switch_CDC(pdev);
    . j: _% Q- |* m4 K, ]
  545.     hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;# K! e: W/ p7 n
  546.    
    $ P/ A+ @+ R# P& Y# E2 J7 M1 F
  547.     hcdc->RxLength = USBD_LL_GetRxDataSize (pdev, epnum);  r$ m/ r4 T; x: E9 y: E- ^9 b% m1 a
  548.     ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Receive(hcdc->RxBuffer, &hcdc->RxLength);* `( ]5 P9 H9 `7 T! i
  549.   }
    0 ?* j9 a+ \7 P8 `
  550.   " x) `$ F8 C% M+ d
  551.   return USBD_OK;
    7 C5 h3 x: X- f2 N
  552. }0 X, e: b1 U# a$ R( @  m

  553. 1 G3 c% c6 ?, {( X9 b5 m$ y9 c; c& a. x
  554. /**
    . b9 W; \: }' S: G2 P' a' q6 @
  555. * @brief  USBD_MC_GetHSCfgDesc ) s% [8 a  g  W. |8 |& n2 K; E; f9 s
  556. *         return configuration descriptor
    ! g1 F9 W1 Y! P
  557. * @param  length : pointer data length
    , i* q* i. p; Q. m5 a! Z
  558. * @retval pointer to descriptor buffer9 U' f0 c4 H- U5 b
  559. */% u" P* D1 y/ b) T2 {% K
  560. uint8_t  *USBD_MC_GetHSCfgDesc (uint16_t *length)
    . a9 f+ v" [) K- k9 _
  561. {
    * d" L" n8 m: m3 b0 L3 L
  562.   *length = sizeof (USBD_MC_CfgDesc);
    0 f. l) J$ |: ^0 s4 p2 `
  563.   return USBD_MC_CfgDesc;) |( y( E, D$ I
  564. }
    4 J  C+ ~1 X$ c
  565. 8 U4 p/ H3 N/ z; R
  566. /**
    - }8 k2 V: }8 W, ^4 E$ j& o4 H6 N& k
  567. * @brief  USBD_MC_GetFSCfgDesc 4 n6 F: c: K, \0 u
  568. *         return configuration descriptor
    8 y% D  i, i- ]. B
  569. * @param  length : pointer data length' W$ c/ {- f, u" x' p% z8 ?9 B) A4 R
  570. * @retval pointer to descriptor buffer
    3 h( L2 T7 q( k- P
  571. */* @" Q$ s- D' H* r, Z
  572. uint8_t  *USBD_MC_GetFSCfgDesc (uint16_t *length)
    : D# A- W5 Y7 ~" e: D
  573. {
    ' R; u7 z& M, f; q3 i; ^9 N
  574.   *length = sizeof (USBD_MC_CfgDesc);9 o  Y( i% d" p6 U
  575.   return USBD_MC_CfgDesc;
    , o! B; d9 j1 x' J9 `% _
  576. }
    + S# z) {8 t( l& F. D
  577. 3 f8 x' b# f! u& {* U2 U
  578. /**, z; i( a+ \" b
  579. * @brief  USBD_MC_GetOtherSpeedCfgDesc
    7 L7 Z2 S, [  [6 c5 r  |
  580. *         return other speed configuration descriptor
    ( Y1 C# k2 C; i' T0 s
  581. * @param  length : pointer data length
    , U/ |% d; [+ o2 r
  582. * @retval pointer to descriptor buffer* O7 F# P( v: c" Z/ I
  583. */" V+ c: L. W, H" a
  584. uint8_t  *USBD_MC_GetOtherSpeedCfgDesc (uint16_t *length)
    + q4 [+ N" D* W- e! n& @
  585. {! f7 N6 `9 n, I6 I
  586.   *length = sizeof (USBD_MC_CfgDesc);3 i8 j2 p/ \  l% t! y
  587.   return USBD_MC_CfgDesc;" i% \' H) t7 p2 _3 Q0 R, {  |
  588. }5 D9 k" [% Q6 M; A0 f
  589. /**" m( `% `6 j" Y. u% G4 d8 A. Z
  590. * @brief  DeviceQualifierDescriptor
    2 Y- g3 ^. ?1 [; g" s
  591. *         return Device Qualifier descriptor  C6 l0 K& Y5 E* ~
  592. * @param  length : pointer data length
    . z3 l4 Z5 |2 _. {
  593. * @retval pointer to descriptor buffer- P. y* H2 c8 L" g4 V
  594. */- k3 A9 c, Q; U" }
  595. uint8_t  *USBD_MC_GetDeviceQualifierDescriptor (uint16_t *length)
    2 O& h; a* {8 |
  596. {
    3 X4 [# B$ ~* P: _, e) X
  597.   *length = sizeof (USBD_MC_DeviceQualifierDesc);* U# ^1 [+ n4 v/ r' A4 ~
  598.   return USBD_MC_DeviceQualifierDesc;
    " `( F% `) @+ |
  599. }2 E; r. y5 `9 L2 ^/ R

  600. 1 T9 K! T+ n$ a) \. F. N2 L5 l: l
  601. /**' ]0 b' k: \9 @: }
  602. * @brief  USBD_MC_RegisterStorage% ~9 `' _& `, h3 O# b
  603. * @param  fops: storage callback6 Z3 ]% l8 Z9 z( b5 J
  604. * @retval status
    9 i3 B. `5 Q1 Q7 J& q" N/ R
  605. */
    1 Z. O8 j: ^2 X5 h
  606. 5 u% b7 x( J+ @6 f- A, k
  607. static uint8_t  USBD_MC_RxReady (USBD_HandleTypeDef *pdev)5 G9 h4 C9 K( e" N) v
  608. {% H+ M& M1 a2 N' s$ [# l8 I
  609.   USBD_CDC_HandleTypeDef   *hcdc;
    % X4 Z, Y. W2 [2 B: _; W
  610.   
    7 k# j9 |. [7 B
  611.   MC_Switch_CDC(pdev);4 T) @/ A* J# ]' N/ F3 u8 a
  612.   hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;% p! Z/ y$ x, w( v3 U
  613.   
    ; X/ j( Z# C) a$ i+ J) M
  614.   if((pdev->pUserData != NULL) && (hcdc->CmdOpCode != 0xFF))- e- s9 V. o) H  Y( g: w
  615.   {! l+ o& S, {# `& k* I% z( T. \
  616.     ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(hcdc->CmdOpCode,, w- }, Y! a7 w/ N' U) `
  617.                                                       (uint8_t *)hcdc->data,$ Q6 `1 T1 K7 ]
  618.                                                       hcdc->CmdLength);: H( t6 m9 A4 p7 k% Q) q, {1 t+ ?  H
  619.       hcdc->CmdOpCode = 0xFF; 6 H2 a# e  Z0 J  ^9 b
  620.       6 V  B3 Q- L! |  F
  621.   }
    6 C* O+ O( J8 Y( Q2 n
  622.   ( }- k5 W( x: r( l7 ]+ k
  623.   return USBD_OK;9 I7 k: L& @$ L+ A9 o6 o
  624. }
    ) T) A& O5 T$ w. f: ~' P3 W

  625. + d* g9 r- s0 B6 K
  626. static void MC_Switch_MSC(USBD_HandleTypeDef *pdev)
    1 c; ]( `* F) N, ?/ a
  627. {% T  e  L: j1 ^' U% P- p2 L) e7 c
  628.   static USBD_MSC_BOT_HandleTypeDef msc_handle;5 |& h2 a0 D4 V1 _, m
  629.   & r8 l8 Y. {! Z( S% `
  630.   USBD_MSC_RegisterStorage(pdev, &USBD_Storage_Interface_fops_FS);
    * @$ S* K6 w. r2 N6 a; S
  631.   pdev->pClassData = &msc_handle;* d  @) \( B7 v9 H& x
  632. }
    0 R# ~; A- ^. s. P5 t% `6 v: p
  633. 5 u' b9 L2 v( L4 T0 k5 J) |
  634. static void MC_Switch_CDC(USBD_HandleTypeDef *pdev): E( d$ g6 `7 p* h
  635. {" z. C+ q% S0 z# a& a+ N
  636.   static USBD_CDC_HandleTypeDef cdc_handle;' U8 Y3 W8 H  X; g  s% K) I# R9 l
  637.   
    ( b3 [" k( C$ d
  638.   USBD_CDC_RegisterInterface(pdev, &USBD_Interface_fops_FS);
    ( N( N& ?) Y  \. d$ z& [0 o
  639.   pdev->pClassData = &cdc_handle;: v& `* ~' y% O+ i- o: A. v/ `
  640. }/ j+ v5 {. F  a4 y9 o  ]0 A

  641. : ^) M0 \7 G' h# M5 S
  642. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/; M( U/ ^% Y8 ~/ s; a1 Y
复制代码

- b4 p3 ^2 C4 ?2 M% f通过以上修改后电脑电脑端显示USB复合设备MSC+CDC) V- |3 j$ d6 A6 C& t9 o
msc cdc.png
' |9 k4 K7 o2 i( W/ s$ V0 G
  i* u7 n$ t; \# p, }( i2 L( r4 t. M13.在usbd_cdc_if.c  CDC_Receive_FS   /* USER CODE BEGIN 6 */ 增加发送测试
; {/ s  S; c0 X# ]3 m) Z7 u0 ~* `1 T) Y( k6 w' ~
  1. static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)  \/ X  |2 ~! t/ U+ g1 U! e
  2. {
    * k# ^) Z+ h8 g, o2 k5 S1 \; S2 c  C
  3.   /* USER CODE BEGIN 6 */# s# c: c& M* e
  4.   USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);. D8 W% F3 |7 G2 A2 N1 |
  5.   USBD_CDC_ReceivePacket(&hUsbDeviceFS);
    8 }; i" s. E. W; L5 t- t
  6.   
    3 h- R$ e& f( D0 H& O7 F% z
  7.   CDC_Transmit_FS(UserRxBufferFS, *Len);      //把接收的返回
    * t+ F. }, X: \9 a, c% C& M6 C
  8.   9 ]7 v+ w3 G7 y& O0 l5 @
  9.   
    ( g! `& e. G. ^' |1 h. j8 c
  10.   return (USBD_OK);! X* X1 ]$ e9 k4 K" U( ?5 m7 |/ _
  11.   /* USER CODE END 6 */5 Z2 S9 K! B; J, u% k5 \( L1 _
  12. }
复制代码
8 w( q% W4 f( Z- G& S
测试串口收发
1 V% T+ K7 P& _ test.png & D% ^) ]% Q/ _3 G8 v
) `$ t* H& {9 M
; V( s/ g5 M# R( c  Z  {5 t2 ?
5 R' @$ s8 G6 W! s% P0 t

2 o# S8 s: x: N7 A

评分

参与人数 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
非常好的资料,对初学者很有帮助;  u# s4 W4 s% ^9 R  S
希望楼主多多分享,赠人玫瑰,手有余香,念念不忘,必有回响;
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  c8 o2 u3 w4 M5 l5 c8 ^* `: A
完全按照楼主做法,在win10环境下U盘和串口都可以实现功能,在win7环境下,串口错误识别为mass storage ...
; i$ Y- g2 v6 l0 p, K4 @# ~
是不是驱动问题,我电脑Win10
电子ai好者 回答时间:2020-11-19 12:57:48
hds1988 发表于 2020-6-29 09:52
+ J2 f* y  n0 S& ]2 F/ {& G完全按照楼主做法,在win10环境下U盘和串口都可以实现功能,在win7环境下,串口错误识别为mass storage ...

& n: N" g4 A9 p% x* a' f 微信图片编辑_20201119125724.jpg 我现在就是win7系统,和你一样的现象。请问你找到解决办法了吗?* t( h8 \4 }6 @; \; {
js123456 回答时间:2021-8-10 15:34:43
用stm32cubemx生成的项目cdc,在文件usbd_conf.c中,USBD_static_malloc申请内存是以USBD_CDC_HandleTypeDef为准,函数如下:' \' @  D% C( d
void *USBD_static_malloc(uint32_t size)- u3 Z8 G  T1 }( }: ]* S& _: c
{) f7 ^& z! I4 v% o  n/ o  Y' S; j: @
  static uint32_t mem[(sizeof(USBD_CDC_HandleTypeDef)/4)+1];/* On 32-bit boundary */
. l4 o, N6 P0 |) q  return mem;- U3 d( V* o1 |" b& D( f7 b
}
! f5 h$ ^: N+ T$ `
4 t" W/ }0 H, }  ]% Z4 E那么在组合设备中,USBD_MSC_BOT_HandleTypeDef和USBD_CDC_HandleTypeDef都需要申请内存,怎么操作?
  K5 h8 C5 g0 U) k
& G7 X9 a, @1 j
js123456 回答时间:2021-8-10 15:35:35
hds1988 发表于 2020-6-28 23:47. T: w& V7 {- X8 z% q
完全按照楼主的说明操作一顿后,不能识别出CDC,但是能识别MSC。MCU是F407VE
& I. v/ f# v4 V& `
有可能是函数USBD_static_malloc的问题
. |' W" P2 m" c3 I

所属标签

相似分享

官网相关资源

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