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

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

[复制链接]
289466080 发布时间:2019-6-23 13:44
本帖最后由 289466080 于 2019-6-23 15:56 编辑 0 t; C' F( r- G- M% \) n, J

. Y* N' }2 E+ [    最近做个USB复合设备CDC+MSC,在网上找了好多基本都是F103做的复合设备,带OTG芯片USB复合设备网上很少可能是我搜索的关键字不够理想有的不够全面,官方给了一个视频教程但是没有参考代码,社区里面有分享到github我按照后也不能实现,后结合F1与github分享的+官方视频,实现了在STM32F730R8T6上面USB复合设备,分享下怎样用cube生成的代码实现USB复合设备(带OTG的芯片).1 u5 p5 y! _2 I

8 t2 I4 ~$ U8 I9 D参考:9 F. P8 ]6 B1 O+ \
github分享0 x, h8 J+ ~4 r9 f" ]/ W0 g
http://github.com/uwyciw/CDC_MSC* Z. C* a/ a0 {- L( w' }# }
官方视频; w# g: x5 o( k6 D0 z7 D
https://www.stmcu.org.cn/video/index/detail/id-3988
$ f  Z3 S' v# H% oF103
4 B9 B2 D- n  ^3 o/ Q" f) h! Uhttp://www.bbsmax.com/A/kjdwBXA5Np/
% D$ C2 S$ Z8 C6 Q, z7 u
3 p# @6 d! w, y$ [4 J3 h
: J" {, z# v# ?cube 5.2.1( X$ f1 l5 X/ {/ s) @( \3 p
hal  stm32cube_fw_f7_v1150.zip% j3 x: I0 x' ~4 T2 d- u7 ?, b
5 H; U: Z# x# ?: @- L
USB为 USB_OTG_FS
" b! }" `- Z8 y% H* \
) |* r3 |5 e* H1 e$ x# W0 t! @; C1.先生成一个CDC工程下面配置图。! u# ^/ ]9 G+ L! t9 k
RCC如图箭头其他默认, B4 f5 ?2 n/ Q8 H0 X
RCC.png
  y2 N% |6 ~# ?3 o" qUSB_OTG_FS如图箭头其他默认
1 {! O2 a- x# M. |8 y, B USB_OTG_FS.png % Q/ p: q7 U1 B) c. W
USB_Device
如图箭头其他默认. D5 ^1 i3 E9 U1 ^& k8 B! K7 y# {
USB_Device.png 3 O& o, S  u, C# f+ H0 c3 P1 |
Clock如图箭头其他默认我用的16M晶振比8M便宜
9 x# @4 R3 F+ ?, p1 n# C Clock.PNG + t3 V+ k* X0 k. j) t3 [

0 O$ ]0 |% u# r% W- Z: B; kProject如图箭头其他默认6 G4 e- m' a! r
Project.png
6 v4 w* S  x% A8 G& Y1 Q# Pcode如图箭头其他默认
" X( @; U  h8 L/ n0 W code.png - B. F5 h" K! a8 @
2.同样生成一个新的MSC工程不可覆盖原本的工程只需修改下图与工程名其他一样- N; R# m# d3 t- H) s" g

3 \% @, h% }, y& n1 A/ j7 ? USB_Device-MSC.png
' p* `4 Q( E1 }" i* J
+ W, o+ L; G8 v& x$ }" D9 @9 Y# }& Z" N
3.生成后把CDC工程下Src文件夹里的usbd_cdc_if.c与Inc下的usbd_cdc_if.h复制到MSC工程下Src与Inc文件夹里面,MSC工程下Src文件夹下新建usbd_composite.c与Inc下新建usbd_composite.h
5 T9 j3 y4 m; X; s4 ?
/ r; x4 c+ i: ~! g( ^ h.png 3 n/ V  Q; q3 x( k3 `  `6 x5 {8 B

3 \. Y; e5 s& l4 R- X4 J' h" }4.把CDC工程\Middlewares\ST\STM32_USB_Device_Library\Class目录下的CDC文件夹复制到MSC工程下见图
7 O" K7 e% n2 ^! ^) L; m/ ] cdc.png % |$ h* D- @! J5 d+ C5 W
5.添加CDC路径8 q$ w' `; ^) X: i! ?

0 K1 B7 [8 x. q7 `* s! A CDC-PATHS.png
: X/ b0 R5 x( S2 H4 ^
; `* l+ k/ E) N, b3 S( r7 m6.在工程中添加usbd_cdc.c usbd_cdc_if.c usbd_composite.c见图! \; }( h: U1 Q. b; Q
keil-add.png
( V) }2 w$ |: P3 n, T( r( A/ K7 E+ b$ S" F! N. S
7. usbd_conf.h 把USBD_MAX_NUM_INTERFACES值 1修改为3
" G5 d% z& l# ?  h8 Q$ U3 g% k$ V
  1. /*---------- -----------*/
    3 q) k. ]$ n# @% u, p
  2. #define USBD_MAX_NUM_INTERFACES     3U    //1U3 `5 w; t7 L; u4 m
  3. /*---------- -----------*/
复制代码
8. usbd_cdc.h 修改CDC_IN_EP CDC_OUT_EP CDC_CMD_EP6 i+ X' @- m* f- K7 u/ Z1 O2 ~
  1. //#define CDC_IN_EP                                   0x81U  /* EP1 for data IN */9 N, J; F+ k8 x6 e8 U+ y
  2. //#define CDC_OUT_EP                                  0x01U  /* EP1 for data OUT */
    ! v3 t; ~. Y  k7 d+ T
  3. //#define CDC_CMD_EP                                  0x82U  /* EP2 for CDC commands */
    $ e* ?3 I5 ]/ y
  4. #define CDC_IN_EP                                   0x83  /* EP1 for data IN */# ^6 _2 a; q! J% N; a, I
  5. #define CDC_OUT_EP                                  0x03  /* EP1 for data OUT */3 h3 u( V6 D+ B% t
  6. #define CDC_CMD_EP                                  0x82  /* EP2 for CDC commands */
复制代码
9. usbd_conf.c  USBD_LL_Init中新增- E% B$ T3 ]) U& y: c' J, g
  1.   HAL_PCDEx_SetRxFiFo(&hpcd_USB_OTG_FS, 0x80);
    : F5 t$ ?! z5 K7 `7 C; w+ K
  2.   HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 0, 0x40);
    ! K6 A$ l& @6 O% Y( D
  3.   HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 1, 0x80);
    ( v" U$ R; Q+ y
  4.   
    ! t" ?8 S: Q2 C
  5.   HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 1, 0x40);   //新增
    : i- t" Y. J4 s5 m, H0 i2 \
  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: A5 e( H/ q% W
+ [( D# B. ^9 L  z

  1. ' k0 r# i6 v3 F7 \& _6 W# z
  2. /* USER CODE BEGIN Includes */
    6 c) L3 P: Q2 \! u8 U
  3. #include "usbd_composite.h"  ?; j( [; c" m6 V! ?  q/ [* A& V4 k6 l+ o
  4. /* USER CODE END Includes */$ z4 O3 b& b' D: A# O2 O/ i
  5. - z. H: M" w- Q( X) A- @; I- ]
  6. void MX_USB_DEVICE_Init(void)
    ; f2 U& ~6 r8 w6 {5 z( a
  7. {, ^  P' w6 s' |2 Z  R
  8.   /* USER CODE BEGIN USB_DEVICE_Init_PreTreatment */
    ' t2 i, E0 n  J. i) j. z$ U1 V
  9.   
    % Z; @& H) e7 ~" }7 B% I
  10.   /* USER CODE END USB_DEVICE_Init_PreTreatment */
    ! }7 j9 ^, `- t# X5 s6 |9 b; l
  11.   % V/ @2 S4 w, l8 J! m4 N7 M& Y# a
  12.   /* Init Device Library, add supported class and start the library. */2 {) P" i0 y* a6 |
  13.   if (USBD_Init(&hUsbDeviceFS, &FS_Desc, DEVICE_FS) != USBD_OK)
    8 N3 B1 ^, A4 I# j8 G
  14.   {/ C1 y0 S  G1 u' y* f
  15.     Error_Handler();1 u2 {( c5 R; E  f
  16.   }' a; z- I7 a8 T# p
  17.   if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_COMPOSITE) != USBD_OK)  //新增6 x2 ^. q# A# X
  18.   {
    6 _6 |, }5 L. t/ D( ]! I1 z7 k
  19.   Error_Handler();3 |& g# ]" U/ N4 N5 t$ S! N
  20.   }+ E% @& S* t' e! i" D- P  w" g8 n
  21. //  if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_MSC) != USBD_OK). P" P+ }: w+ i* M
  22. //  {
    8 |5 N$ f1 j0 q3 G! {* h* D& O
  23. //    Error_Handler();& V" }1 M- |5 v8 X+ C3 i0 N) Z" ^
  24. //  }
    9 d+ I) c3 I1 }" @; h5 J9 K2 w
  25. //  if (USBD_MSC_RegisterStorage(&hUsbDeviceFS, &USBD_Storage_Interface_fops_FS) != USBD_OK)
    2 j" ^8 X2 v6 |# @+ j; @: B
  26. //  {
    5 m4 s8 T# `( l& b
  27. //    Error_Handler();, E3 w/ l' b6 \4 Y/ ]
  28. //  }2 j5 K1 {8 w+ ]$ a3 T( q8 A
  29.   if (USBD_Start(&hUsbDeviceFS) != USBD_OK)
    " \0 R" B) G8 T2 ]  ~/ u; u7 F, Q
  30.   {- w2 f* W8 g$ C, y
  31.     Error_Handler();
    " u) \2 y- S" |
  32.   }
    ( Z$ e1 b: B2 ?  s2 @+ T. }

  33. / z8 E5 H" ?' W% O' _/ z
  34.   /* USER CODE BEGIN USB_DEVICE_Init_PostTreatment */
    ( |9 N9 g0 h/ M" H0 ~
  35. //  if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_COMPOSITE) != USBD_OK)  //新增
    # Y8 I. j/ G- Q$ C; t
  36. //  {
    3 P% @3 |9 ~. Y4 p
  37. //  Error_Handler();
    1 O5 l! g% y4 f% y. J4 O8 h# K
  38. //  }
    / p9 W9 m2 \8 c6 t6 Y
  39.   /* USER CODE END USB_DEVICE_Init_PostTreatment */4 w7 v/ m$ O0 R
  40. }
复制代码

4 p: \; a  q( _/ [% i% p

: H: a: f: i+ F/ Y# E11.在usbd_composite.h中新增代码
7 j- J6 X! T! w, Y5 A, i& [) I, e
  1. : P/ z& S$ T+ W5 D! o3 V4 }6 p# f
  2. #ifndef __USBD_COMPOSITE_H+ P: @! S& s. z3 L1 S, [
  3. #define __USBD_COMPOSITE_H
    / H3 g/ H! _. }  K! o  Y$ ~0 g

  4. ; N+ J/ w* |1 g5 Y7 D6 q
  5. #include  "usbd_ioreq.h"  V: R" W8 e8 X+ K0 R
  6. #include "usbd_cdc.h"  q9 {7 a3 H4 i& j# o, ]: o/ B
  7. #include "usbd_msc.h". e/ d) h* L- f- v
  8. 8 |0 `! o' I  i, ^/ h7 f6 {
  9. #define MC_MAX_FS_PACKET            0x40
    7 y! _& n! p; |1 w" P

  10. - {( f- A5 g4 K( [- ]/ m9 P
  11. #define USB_MC_CONFIG_DESC_SIZ      106
    - Y5 r) W1 Y1 W6 o5 D" E1 e

  12. . w- n* ?; B( s
  13. #define MC_MSC_EPIN_ADDR                MSC_EPIN_ADDR
    0 A3 \0 n. ]& |9 c% `
  14. #define MC_MSC_EPOUT_ADDR               MSC_EPOUT_ADDR 0 @* C& `' T9 E# E1 _* Y# e& o
  15. 8 z5 @* A/ |8 C) |
  16. #define MC_CDC_IN_EP                   CDC_IN_EP 2 J4 v5 [! U' U" L$ l0 ^) }
  17. #define MC_CDC_OUT_EP                  CDC_OUT_EP  
    0 T# ~8 j- t; z1 f% U! g
  18. #define MC_CDC_CMD_EP                  CDC_CMD_EP
    ! _9 y  i4 C/ W3 b1 r7 E$ T) }
  19. ) J! {/ {* {" t0 c
  20. extern USBD_ClassTypeDef  USBD_COMPOSITE;
    % {& t9 {/ a) G8 b
  21. 9 n1 S0 I" X. Q  Y. M& u4 ?
  22. #endif  /* __USBD_MC_H */
    7 d$ v" b+ p6 L! t
  23. ' |% h/ ^5 J3 N0 C; B; z' V$ a
复制代码

4 [% T7 ]2 n% S; J
4 x% X+ ^3 e/ g- A! J12.在usbd_composite.c中新增代码6 S- \) A" n' O4 f0 n% W0 l8 X
) {  k& {) T4 z/ y' d/ I
  1. / m3 [9 W: w2 J7 u
  2. #include "usbd_composite.h". H) d& x2 e3 s1 y  ]9 O1 s: p8 [
  3. #include "usbd_def.h"
    5 m. l% A3 e! n9 @
  4. #include "usbd_msc.h"
    ( T5 a& U* M3 y6 b# k( |
  5. #include "usbd_cdc.h"
    2 R9 H' O* e1 v4 y. H% b4 U( U
  6. #include "usbd_storage_if.h"2 P! y9 w# J% H
  7. #include "usbd_cdc_if.h"
    / @* A- N/ ]6 i4 `7 z- s( c* H& N
  8. 4 {+ u! X5 E" U& r0 Y2 y: G( r
  9. /** @defgroup MC_CORE_Private_FunctionPrototypes
    - m, F) G* t) N
  10.   * @{" F3 P) R8 T" y* _3 H0 u
  11.   */
    ! M) A: u; T( Z" L2 s- X
  12.   
    " |# u% i; p/ L+ s4 E% b! S3 q
  13. USBD_CDC_HandleTypeDef     *pCDCData;; U( @0 z7 n; n
  14. USBD_MSC_BOT_HandleTypeDef *pMSCData;) a0 k) V& [" [; P$ {
  15.   : {4 S8 U) P, s$ _& M7 z
  16. uint8_t  USBD_MC_Init (USBD_HandleTypeDef *pdev,
    : e4 S% v6 f5 ]2 N
  17.                             uint8_t cfgidx);
    - i, X0 U. P% }) J9 J
  18. ! M" g% k1 X' L5 K6 s& p
  19. uint8_t  USBD_MC_DeInit (USBD_HandleTypeDef *pdev, % y/ U) |# [3 q; {1 ?, w4 M: d/ a' E
  20.                               uint8_t cfgidx);
    . S3 A4 q% J6 H4 J0 a6 O
  21. 5 J  d$ y0 e. }1 Y
  22. uint8_t  USBD_MC_Setup (USBD_HandleTypeDef *pdev, 7 [' L  L" B4 R# f, T: u
  23.                              USBD_SetupReqTypedef *req);
    * _$ y4 F) ]5 @# o8 S1 V

  24. : H$ p' |0 ?- G8 S2 M
  25. uint8_t  USBD_MC_DataIn (USBD_HandleTypeDef *pdev,
    1 @8 U' A, H8 Y& X! ]. u
  26.                               uint8_t epnum);
    " N- c* K0 O* @! C+ U( B) V9 z! C# `

  27. 0 l! Q3 \# _, ^
  28. ( j% Q7 p7 `$ J( x. U
  29. uint8_t  USBD_MC_DataOut (USBD_HandleTypeDef *pdev,
    4 M  l/ S* e0 @4 W, j
  30.                                uint8_t epnum);( b. ^0 L/ U! ]/ ?# z4 r
  31. 4 G. ^. i1 v3 k9 l. d# }
  32. uint8_t  *USBD_MC_GetHSCfgDesc (uint16_t *length);- A8 `! L. O8 ]0 `

  33. $ a" K; ~! q) L9 H
  34. uint8_t  *USBD_MC_GetFSCfgDesc (uint16_t *length);
    : z: C3 e  Z* }% A
  35. + c1 K3 c) q6 x  k, C9 E' Y
  36. uint8_t  *USBD_MC_GetOtherSpeedCfgDesc (uint16_t *length);) s% M4 Q6 s% X3 I; t% _0 o4 y/ x1 @
  37. ; @6 d, y9 P) \% C
  38. uint8_t  *USBD_MC_GetDeviceQualifierDescriptor (uint16_t *length);
    ) T) _9 O2 M1 Q+ J- m
  39. , r5 f6 R7 P/ Y+ X$ Q+ B
  40. static uint8_t  USBD_MC_RxReady (USBD_HandleTypeDef *pdev);# ]2 X& f" M4 R
  41. static void MC_Switch_MSC(USBD_HandleTypeDef *pdev);' o9 u6 \. w, l0 q3 \5 n& Q. D
  42. static void MC_Switch_CDC(USBD_HandleTypeDef *pdev);
    1 {$ Q! n& p# x. ~: k6 @+ y) N
  43. " O% p$ u8 P7 y
  44. /**
    ' m. n3 ]6 {6 r# w
  45.   * @}
    $ v- g# X* U  X0 b; R
  46.   */ # N( ~9 r' i) D  `& J, a( u: c) H
  47. extern USBD_HandleTypeDef hUsbDeviceFS;, V- I6 l2 }- V; y" Q8 F
  48. , D1 f, b/ d& P& o8 k) H
  49. , v% i0 p! J& A) d3 m7 U
  50. /** @defgroup MC_CORE_Private_Variables( k; s7 b, b; S3 b; h
  51.   * @{7 v, Y% V, c/ |# n
  52.   */ 3 t- A  h0 r. v- s& X6 }/ p, M) Q
  53. USBD_ClassTypeDef  USBD_COMPOSITE =   t, S7 l" u5 ]. P; s+ R# u, c4 W* Y
  54. {
      f- ?+ ?" t: i
  55.   USBD_MC_Init,4 g3 U. @: @2 u7 s& e5 F5 ~  E, {
  56.   USBD_MC_DeInit,, Z/ V' a. g1 C' O. f( R5 i
  57.   USBD_MC_Setup,3 Y3 g: _. J: c! S
  58.   NULL, /*EP0_TxSent*/  
    % [7 S$ U4 m' |& m! [
  59.   USBD_MC_RxReady, /*EP0_RxReady*/
    2 E' |* R( C% i5 T7 I4 o7 I
  60.   USBD_MC_DataIn,) H9 e7 F) Q: L( K, O
  61.   USBD_MC_DataOut,
      g( X; ]1 h2 y
  62.   NULL, /*SOF */ . @# ~) C: f3 n4 K
  63.   NULL,  
    - P8 T/ ^+ p3 `7 o/ W9 U* J
  64.   NULL,     
    ( P. P9 q: w+ i9 k
  65.   USBD_MC_GetHSCfgDesc,6 J; |+ K4 N  Q  B
  66.   USBD_MC_GetFSCfgDesc,  
    # M% Z' v. E  W# W' z( I
  67.   USBD_MC_GetOtherSpeedCfgDesc,
    6 \2 V1 `$ V, V5 I, V5 t' [
  68.   USBD_MC_GetDeviceQualifierDescriptor,
    ' @8 `5 j$ X: D) j+ z
  69. };1 j2 `* J9 y0 b& `9 h! r

  70. + {9 o" v3 V+ S! o0 l! L
  71. /* USB Mass storage device Configuration Descriptor */2 Q7 }0 B& T! A: s0 \; t; \. X! z
  72. /*   All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */
    1 Q+ G1 X; z  `0 L# {9 R1 y
  73. uint8_t USBD_MC_CfgDesc[USB_MC_CONFIG_DESC_SIZ] =
    ' d$ c! v7 r3 v0 b3 l/ m
  74. {4 w3 e6 Q% R- J2 g# c
  75.   /*Configuration Descriptor*/+ _' c# V4 d* I4 m7 w; e
  76.   0x09,   /* bLength: Configuration Descriptor size */
    ' l, N& V4 w! m
  77.   USB_DESC_TYPE_CONFIGURATION,      /* bDescriptorType: Configuration */. P# R% @- g) ]: y
  78.   USB_MC_CONFIG_DESC_SIZ,                /* wTotalLength:no of returned bytes */9 q" a5 t3 S1 s6 t, R6 m
  79.   0x00,
    : c3 \" [1 H6 w  w( u  {" c
  80.   0x03,   /* bNumInterfaces: 3 interface */' |- y; A2 {' a' G$ P
  81.   0x01,   /* bConfigurationValue: Configuration value *// x9 q; j$ {& _. b, `% l
  82.   0x00,   /* iConfiguration: Index of string descriptor describing the configuration */4 u0 a& n" {2 X7 d- S6 _- X
  83.   0xC0,   /* bmAttributes: self powered */8 j5 X. F; g) X6 M9 [
  84.   0x32,   /* MaxPower 0 mA */
    1 L0 i9 a8 F$ U, b
  85.   1 g9 p1 |+ g$ j& v+ j9 D" B* W
  86.   /*---------------------------------------------------------------------------*/7 e* |2 Z4 p5 E. K  i$ i( Q. k/ t9 Y  f
  87.   // IAD
    # R9 J* ~: X/ F/ `
  88.   0x08,        //描述符大小
    + f" e2 j0 z2 r# z: {
  89.   0x0B,        //IAD描述符类型
    ' v/ b  e% F: n8 d6 C+ q
  90.   0x00,        // bFirstInterface : G2 ^8 e) ?$ V/ ?, U8 Q7 _
  91.   0x02,        // bInterfaceCount
    & V2 D' C+ _; q, _6 F. a) b
  92.   0x02,        // bFunctionClass: CDC Class
    6 Q& [2 K  B3 t5 M
  93.   0x02,        // bFunctionSubClass& e3 p+ ?. [4 L2 @2 l: p
  94.   0x01,        // bFunctionProtocol2 J! L8 ?# t  b6 y9 C, Z
  95.   0x00,        // iFunction       % m0 ?1 m/ d; W" e1 ]0 B$ Y- r, J( e
  96.   
    3 g% f: e6 ~7 w+ g; s
  97.   /*---------------------------------------------------------------------------*/
    + J0 F, ^5 P/ M0 t5 k* n# U) ]+ S- i
  98.   /*Interface Descriptor */
    ( M9 b/ E  ?# y* V, t7 y" ~9 a
  99.   0x09,   /* bLength: Interface Descriptor size */4 ~1 D  s# E- N1 v' Q; R7 Q0 m
  100.   USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: Interface */, T6 T; q6 j, r& ~  t
  101.   /* Interface descriptor type */9 z" L, ^5 C  i6 ]+ ?, J
  102.   0x00,   /* bInterfaceNumber: Number of Interface */
    % S8 p' x) I. [: t
  103.   0x00,   /* bAlternateSetting: Alternate setting */
    ( P: q+ }7 w/ [' r, h0 a
  104.   0x01,   /* bNumEndpoints: One endpoints used */
    8 G* P( R- g6 Y
  105.   0x02,   /* bInterfaceClass: Communication Interface Class */
    6 S; b6 v/ v1 S. k/ E8 c! \) r9 q: f
  106.   0x02,   /* bInterfaceSubClass: Abstract Control Model */* R5 m  ^6 E5 {0 d6 \5 O- O
  107.   0x01,   /* bInterfaceProtocol: Common AT commands */$ u; G# [8 I1 p5 O  l1 C
  108.   0x00,   /* iInterface: */
    " O0 r  Z5 i4 b* ~+ u# l6 P/ z
  109.   
    1 H0 f2 f1 V- d% V6 K# j) H
  110.   /*Header Functional Descriptor*/
    2 N# G2 k% ]- Z8 o2 |
  111.   0x05,   /* bLength: Endpoint Descriptor size */
    2 m) X& A; s- x$ X; f4 ?/ C- A0 D
  112.   0x24,   /* bDescriptorType: CS_INTERFACE */
    : o) G/ I: F/ d$ s
  113.   0x00,   /* bDescriptorSubtype: Header Func Desc *// z- f( k" j5 O- y8 V+ ]7 w2 F
  114.   0x10,   /* bcdCDC: spec release number */1 H/ J3 ?' U/ t/ B" E0 _
  115.   0x01,
    . }) E  ~$ i/ V! Q( Y
  116.   " F1 m2 b2 e- T- A/ g
  117.   /*Call Management Functional Descriptor*/
    ; I) N6 L/ f9 F
  118.   0x05,   /* bFunctionLength */. E: D8 K/ }+ u4 p" A( r3 m
  119.   0x24,   /* bDescriptorType: CS_INTERFACE */( |% f' u+ b3 c
  120.   0x01,   /* bDescriptorSubtype: Call Management Func Desc */
    % H& _, Q& U6 p$ v
  121.   0x00,   /* bmCapabilities: D0+D1 */
    9 y* r( G. K) a& T
  122.   0x01,   /* bDataInterface: 1 */
    ' B( f$ a9 Q3 V0 n' Q. M
  123.   ' C- w/ p0 B, u" Q/ r% P
  124.   /*ACM Functional Descriptor*/
    - g5 ]" c. C( E0 S" m( C6 j2 q
  125.   0x04,   /* bFunctionLength */
    3 P0 U" B, l6 c, x# |7 u# R
  126.   0x24,   /* bDescriptorType: CS_INTERFACE */
    : ^  F$ N5 _$ z  x/ O7 C
  127.   0x02,   /* bDescriptorSubtype: Abstract Control Management desc */; S; F9 p) c6 A5 f: u! g1 j* j
  128.   0x02,   /* bmCapabilities */9 _/ e6 P- `" G' W% {" i' A
  129.   
    7 }% A8 h' a. z# }- P7 ~
  130.   /*Union Functional Descriptor*/
    4 _( a' K1 a! t7 u' j/ u
  131.   0x05,   /* bFunctionLength */
    1 q. y. f* I( k2 y, U1 ?
  132.   0x24,   /* bDescriptorType: CS_INTERFACE */
    & ~9 B" p6 o1 [" ]8 R
  133.   0x06,   /* bDescriptorSubtype: Union func desc */6 _) ~  c$ @' i5 x# o3 l+ R
  134.   0x00,   /* bMasterInterface: Communication class interface */
    1 N, T, W0 ^. F# H) o8 H7 X& t
  135.   0x01,   /* bSlaveInterface0: Data Class Interface */
      F4 p& Y& K+ C. H# f, b5 g
  136.   
    ; D" _+ y5 ?0 ]4 w! W2 u
  137.   /*Endpoint 2 Descriptor*/- V- ?* v+ L; y* o# c% ?$ I
  138.   0x07,                           /* bLength: Endpoint Descriptor size */
    ( d4 R" L- ?7 B7 p% @" \
  139.   USB_DESC_TYPE_ENDPOINT,   /* bDescriptorType: Endpoint */2 L3 L: a1 @/ q( P5 T& n
  140.   MC_CDC_CMD_EP,                     /* bEndpointAddress */" p0 S9 q; t4 j! f
  141.   0x03,                           /* bmAttributes: Interrupt */1 k0 \( b6 m4 J- H
  142.   LOBYTE(CDC_CMD_PACKET_SIZE),     /* wMaxPacketSize: */
    ( X6 q2 Z$ n; U1 R, X
  143.   HIBYTE(CDC_CMD_PACKET_SIZE),
    $ B$ O5 G6 g/ j5 C7 B: b0 o
  144.   0x10,                           /* bInterval: */ 7 e* B2 I6 D5 a) Q8 W. f
  145.   ( l% Z7 ?! M, Q5 b0 G# ?
  146.   /*Data class interface descriptor*/
      X" D1 Y! Q( m+ G% y- d1 r" o  b
  147.   0x09,   /* bLength: Endpoint Descriptor size */
    $ S$ y3 R7 L" F( R( k4 @+ {
  148.   USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: */; O; q$ M8 ~" V" j( Y% J3 h
  149.   0x01,   /* bInterfaceNumber: Number of Interface */
    ! D; Z; T# r0 e$ B8 F- e4 o
  150.   0x00,   /* bAlternateSetting: Alternate setting */+ g$ @5 `: S& l( v& a* H, |- Z
  151.   0x02,   /* bNumEndpoints: Two endpoints used */
    # t- `( k3 J" h) ]
  152.   0x0A,   /* bInterfaceClass: CDC */
    5 u$ d- X9 D7 ?& O" ^+ D/ I
  153.   0x00,   /* bInterfaceSubClass: */. ]! `; D4 ]- ]
  154.   0x00,   /* bInterfaceProtocol: */
    ( `2 b/ h" s( h0 b+ l" d0 v
  155.   0x00,   /* iInterface: */
    ) e4 {" f' ^- T) |
  156.   " H3 t: g6 L5 j/ j$ k5 C, D! ]
  157.   /*Endpoint OUT Descriptor*/
    6 a' d) W7 k3 W( V4 S4 J$ N
  158.   0x07,   /* bLength: Endpoint Descriptor size */3 K0 A5 b2 j% A3 K2 a5 a1 t* d, h
  159.   USB_DESC_TYPE_ENDPOINT,      /* bDescriptorType: Endpoint */: {7 @/ C8 a# Q* c' G
  160.   MC_CDC_OUT_EP,                        /* bEndpointAddress */
    0 I3 N9 g3 B8 Y
  161.   0x02,                              /* bmAttributes: Bulk */
    / p4 m4 c, \5 [& D
  162.   LOBYTE(MC_MAX_FS_PACKET),  /* wMaxPacketSize: */4 v- \' O2 Y1 A9 _5 i* R
  163.   HIBYTE(MC_MAX_FS_PACKET),2 M: `6 E8 ^8 M. l" @& y2 C' _
  164.   0x00,                              /* bInterval: ignore for Bulk transfer */, g  r4 E; \+ C! y
  165.   
    9 l. C0 x# a4 b
  166.   /*Endpoint IN Descriptor*/
    . z0 }9 W) H* ~, _6 S# k% Q) v
  167.   0x07,   /* bLength: Endpoint Descriptor size */
    1 L- v0 X7 j8 m3 ?# k3 `" X& O. L
  168.   USB_DESC_TYPE_ENDPOINT,      /* bDescriptorType: Endpoint */
    $ l8 m5 y. L+ u7 ]
  169.   MC_CDC_IN_EP,                         /* bEndpointAddress */- ?9 o9 v1 z) C  f
  170.   0x02,                              /* bmAttributes: Bulk */
    $ h) R: G5 D" K( _
  171.   LOBYTE(MC_MAX_FS_PACKET),  /* wMaxPacketSize: */- J, L5 b! F7 f" s* ]
  172.   HIBYTE(MC_MAX_FS_PACKET),
    ' L; `" _! L* C3 }9 z0 D0 ^1 S9 P/ Z
  173.   0x00,                               /* bInterval: ignore for Bulk transfer */6 t5 K! f- j2 c) |0 l  c  i
  174. + |! P  M- m- x' `
  175.   /*---------------------------------------------------------------------------*/
    : j: y. b* v% P6 E+ K
  176.   // IAD# F; M) p: I7 b+ }" n3 m( C: g
  177.   0x08,        //描述符大小
    3 J0 X! D5 d. L, U
  178.   0x0B,        //IAD描述符类型) A" L  X0 u) f9 g# v9 v7 s& _
  179.   0x02,        // bFirstInterface
    # K6 B  L. d  a, U) ]1 ~
  180.   0x01,        // bInterfaceCount
    ( D* r4 Q9 e% }6 ]: }
  181.   0x08,        // bFunctionClass: MASS STORAGE Class. E  a' ~1 j% f# E5 l# F' A* h
  182.   0x06,        // bFunctionSubClass
    & t; p/ j$ X% a6 K  \# Z- h
  183.   0x50,        // bFunctionProtocol5 t& M7 x( h: o8 X" g$ p2 M
  184.   0x01,        // iFunction    ( I) H2 s  d9 j5 i, D/ ^9 t

  185. 2 |, K; ^; ?7 g
  186.   /********************  Mass Storage interface ********************/5 a& G2 Y. F' H" L
  187.   0x09,   /* bLength: Interface Descriptor size */
    4 G0 y% f; p% d0 p5 h+ @
  188.   0x04,   /* bDescriptorType: */, V& h, l+ Q) K5 g
  189.   0x02,   /* bInterfaceNumber: Number of Interface */* s' L; z  y. h
  190.   0x00,   /* bAlternateSetting: Alternate setting */
    5 v! s0 t- n9 `- X4 X! E7 O& f0 S! m
  191.   0x02,   /* bNumEndpoints*/& C4 o! N0 ?) k. O
  192.   0x08,   /* bInterfaceClass: MSC Class *// k6 ]2 [2 p; |
  193.   0x06,   /* bInterfaceSubClass : SCSI transparent*/4 [9 Q$ F; O) v2 p0 ^! I% d
  194.   0x50,   /* nInterfaceProtocol */
    - w) S% F3 j" X3 A
  195.   0x05,          /* iInterface: */. v3 F& q) V* `& Y: b* p+ \
  196.   /********************  Mass Storage Endpoints ********************/- l( W" Y( [; a" o$ h& t$ |* x
  197.   0x07,   /*Endpoint descriptor length = 7*/& q6 x8 o9 u# M8 B7 \( g
  198.   0x05,   /*Endpoint descriptor type */
    & `9 n+ `" i9 ]! F. K; Z
  199.   MC_MSC_EPIN_ADDR,   /*Endpoint address (IN, address 1) */
    % s/ c$ N2 i( m6 z3 m5 a- C
  200.   0x02,   /*Bulk endpoint type */
    $ U; ~3 @2 k) m; w2 q
  201.   LOBYTE(MC_MAX_FS_PACKET),9 u+ s* m9 ?$ [$ Q% L
  202.   HIBYTE(MC_MAX_FS_PACKET),
    9 n, _/ p' O6 s4 Z
  203.   0x00,   /*Polling interval in milliseconds */
    * U6 G' S/ ]5 p; b  k6 K4 z
  204.   2 p7 i( x. c+ I) j( J
  205.   0x07,   /*Endpoint descriptor length = 7 */8 O3 k9 U. H* Z, Q6 Q5 ?, \
  206.   0x05,   /*Endpoint descriptor type */
    ; g% X  P) Z. m
  207.   MC_MSC_EPOUT_ADDR,   /*Endpoint address (OUT, address 1) */
    # I7 G; b$ i% B4 y
  208.   0x02,   /*Bulk endpoint type */
    2 o. e4 Z5 o8 ]" ?5 Z* b) k
  209.   LOBYTE(MC_MAX_FS_PACKET),! n* X7 M! f% J# C  c$ q% x5 ~3 I
  210.   HIBYTE(MC_MAX_FS_PACKET),7 s- r6 B; n$ P$ x/ ~
  211.   0x00     /*Polling interval in milliseconds*/
    - x- ]4 p! Q& R7 ]' |! n3 S
  212. };. o( W8 i1 v" L% i
  213.   
    0 s7 r$ a- M7 f2 l) J5 H
  214. uint8_t USBD_MC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] =
    6 ^6 b. Z4 m+ d2 U+ L. N$ L1 M# |
  215. {
    % U* d2 H6 ~2 Q9 z$ f, c
  216.   USB_LEN_DEV_QUALIFIER_DESC,; L! k7 A  Z0 f& W5 d
  217.   USB_DESC_TYPE_DEVICE_QUALIFIER,
    9 b1 Q7 x9 ~6 x- N4 q! d
  218.   0x00,
    6 Y" m' J, A8 e1 ?: ~
  219.   0x02,0 y$ w' J4 E2 f, X6 L' [7 q
  220.   0x00,
    * e. j- {* m( w% k$ X
  221.   0x00,$ |* ]+ K) B5 k! i  F9 o) K- H! p
  222.   0x00,
    . q( j* ]$ n( F( w) z
  223.   MC_MAX_FS_PACKET,2 Z. e. N  @$ Z8 m6 \. t6 N# C! _
  224.   0x01,: r3 C5 ^. a' A* D
  225.   0x00,- ~- v, |7 j1 U$ }/ x, M
  226. };' X" U  N9 f( H' Z5 |. G
  227. ' }* Z/ Z) N, [0 v- w6 X
  228. /**9 |# V) R7 x6 Q1 b5 i( r
  229.   * @brief  USBD_MC_Init! ~/ Z" \$ ?  ]
  230.   *         Initialize  the mass storage configuration
    / |3 s8 N  g( P+ S" \/ V- v0 z; e
  231.   * @param  pdev: device instance
    & ]6 X/ [  z% s0 C# H- L+ \
  232.   * @param  cfgidx: configuration index
    . q  }7 C  R6 [$ m. G/ s
  233.   * @retval status
    0 d- t3 }8 S3 {: Y* T% W6 Y
  234.   */# t( j, Y! L, g
  235. uint8_t  USBD_MC_Init (USBD_HandleTypeDef *pdev, uint8_t cfgidx)
    : n$ g- ]- H: T- V) M2 T
  236. {/ X. b5 s+ L  l6 Y' \" b
  237.   uint8_t ret = 0U;2 v8 R2 J3 u/ P( S1 ^: `
  238. 1 P* G" c# w9 S
  239.   
    - p- A) y6 d/ s: J" t% c$ P( {/ X/ ?( }
  240.   USBD_CDC_HandleTypeDef      * hcdc;8 q7 w3 i8 _  m+ v; N7 {$ v* ~# ^
  241.     . c7 \! J" J+ a  g; K
  242.   MC_Switch_CDC(pdev);+ }) v# u, E# v
  243.   % h$ r  }2 q. C7 d0 t6 J4 w/ b
  244.   USBD_LL_OpenEP(pdev,* d$ h8 I/ m0 E! O7 R4 i2 v
  245.                  MC_CDC_IN_EP,
    * u' R$ j% Z2 b/ c- s! l! o
  246.                  USBD_EP_TYPE_BULK," M" C) `5 X9 E" F2 j# J, x; O
  247.                  MC_MAX_FS_PACKET);" l  E7 z! W$ j( \# M
  248.   
    - j3 |9 u; p* `1 d( p
  249.   USBD_LL_OpenEP(pdev," p0 v2 r5 T, E  P! E( D
  250.                  MC_CDC_OUT_EP,8 Z5 K8 m" t" b8 e- @$ J
  251.                  USBD_EP_TYPE_BULK,
    5 i5 @! t) Z; ]/ Z6 s* y8 ~: s
  252.                  MC_MAX_FS_PACKET);& r7 i8 p5 L7 {2 a# |
  253.   
    - i* [* k+ ^2 P: {/ |7 ~8 R
  254.   USBD_LL_OpenEP(pdev,8 H! j3 k9 W: o  ^% {( H) a. X
  255.                  MC_CDC_CMD_EP,! D+ A, ]6 V' o) `3 E! j& A5 z3 E
  256.                  USBD_EP_TYPE_INTR,
    8 e: Y( x; |  k0 y3 `  k* n. `* K# y
  257.                  CDC_CMD_PACKET_SIZE);
    6 N8 O7 O, Z* M% D3 ^2 K* ]! K" B

  258. 7 K* E+ Q" N6 P4 r0 ~" j
  259.   hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;4 ~; S: N' n1 P

  260. $ m- X* X6 }1 g' K4 W' J
  261.   ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Init();
    . X+ E, S; |- t% m
  262.   
    : K0 |* d! g8 j0 t# A/ W# M
  263.   hcdc->TxState =0;
      W8 U8 Y: z2 F$ f
  264.   hcdc->RxState =0;
    1 d4 Q% M9 N  Q" |9 s- Q
  265.   ( G; z% b' X) a6 n, S5 X
  266.   USBD_LL_PrepareReceive(pdev,
    8 u. P6 q; D# t# n  F9 I
  267.                          MC_CDC_OUT_EP,( G# e. C0 m) j( O9 x) S
  268.                          hcdc->RxBuffer,
    3 o0 U! Y! Z9 K7 i- j
  269.                          MC_MAX_FS_PACKET);
    - K7 F6 o# A; G

  270. + t2 c$ E6 m6 ~7 c* l3 b" J: R
  271.   pCDCData = pdev->pClassData;
    2 G" e# l% t! o, \7 X9 }! Z

  272. 7 P2 ~% i; \0 A  M5 y: ]7 z
  273.   MC_Switch_MSC(pdev);
    1 b+ g+ `8 C$ R1 W# [2 X! b4 R$ M
  274.   - [3 c( q: Z# z/ `; g7 a3 \# w
  275.   USBD_LL_OpenEP(pdev,
    " k- k, b' j. G1 T5 l: V
  276.                  MC_MSC_EPOUT_ADDR,
    * _' O4 L' v5 j1 P, C. I
  277.                  USBD_EP_TYPE_BULK,
    . `* R& s" u4 L. O8 e
  278.                  MC_MAX_FS_PACKET);  R/ ?: P; d, o4 y  n0 U
  279.   
    , p5 Y1 Q8 Y& \. J; ?
  280.   USBD_LL_OpenEP(pdev,5 f  H. K' f2 ?4 `& I* ~4 L2 f4 o
  281.                  MC_MSC_EPIN_ADDR,
      Z& B' I1 Y7 A/ L; j# ^/ v
  282.                  USBD_EP_TYPE_BULK,
    1 j! J* Y. k. s/ E
  283.                  MC_MAX_FS_PACKET);
    5 W  V9 `9 j# p: n* b, n% x
  284.   6 U4 y5 B/ A& ?/ W* e% A9 e7 G( s
  285.   MSC_BOT_Init(pdev);* ~5 G1 q; {" G3 {' `
  286.   0 E' ]4 A: m0 P' u
  287.   pMSCData = pdev->pClassData;) t2 j8 X, a) ^, Z1 ]2 Z& o! a
  288.   ' l' O6 V5 J8 a- s
  289.   if(pdev->pClassData == NULL)
    1 C: h7 Q& {% V+ @6 {. q
  290.   {, e6 c4 D9 r3 f- \3 b1 S
  291.     ret = USBD_FAIL;
    7 s! k; R" A! q* K& I# w* u8 G* _% n
  292.   }
    # Y: W' [; s3 m7 U: {0 j1 {
  293. ( X& F* g/ r% `
  294.   return ret;# J7 l5 `3 V* b3 ^' l
  295. }1 r  `9 S0 C4 n" y" [) G

  296. ' P$ Q9 Y+ N! @: U
  297. /**
    ( x4 o  O( x% O) n$ l/ ~
  298.   * @brief  USBD_MC_DeInit5 B* R$ d4 h1 [0 R
  299.   *         DeInitilaize  the mass storage configuration7 b/ v4 t& e4 X) T, q1 q4 B0 r/ b
  300.   * @param  pdev: device instance' @: b* q. {# D) [* w
  301.   * @param  cfgidx: configuration index
    ' [+ F7 S3 X, X, y
  302.   * @retval status
    9 h6 I9 |; A; G
  303.   */
    9 ~$ Y4 ]* `& [- @5 x
  304. uint8_t  USBD_MC_DeInit (USBD_HandleTypeDef *pdev, & s# I# d2 a! e- u8 U# z
  305.                               uint8_t cfgidx)
    3 o: U9 q" {' e" x$ f, ~% J
  306. {
    5 a0 z: y. g6 }" B
  307.   return USBD_OK;
    0 m: i% q2 K4 L% d' ~5 D
  308. }
    8 l+ r5 r4 Q+ B( m5 B% r& e; Z
  309. /**+ \" o2 C) A2 l: X/ X! Q
  310. * @brief  USBD_MC_Setup* f4 b: Y5 _1 K; A1 n. B
  311. *         Handle the MC specific requests
    , m" S+ Y: c% e" }/ m4 ?
  312. * @param  pdev: device instance
    3 U& {) o7 Q! Q4 [& ~0 }% p
  313. * @param  req: USB request
    ' J3 L" k" {3 l3 l( x+ V0 T# v
  314. * @retval status
    0 c9 t6 ~$ V. Y6 m3 u, X
  315. */
    : f. j+ [( S+ w. f
  316. uint8_t  USBD_MC_Setup (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
    - Y. f  z# F  W" C0 j4 x
  317. {7 g4 I& X' y7 r# @
  318.   if(req->wIndex == 0x0002)
    / {$ H0 l0 J4 U, v: K
  319.   {
    ; E0 h" D7 p1 @3 |3 J/ s
  320.     MC_Switch_MSC(pdev);
    , m/ A* Z7 e, F, w8 r
  321.     USBD_MSC_BOT_HandleTypeDef     *hmsc = (USBD_MSC_BOT_HandleTypeDef*) pdev->pClassData;   ' H! L; z2 u  o
  322.     . L3 {: f) Z! A# A2 v) S
  323.     switch (req->bmRequest & USB_REQ_TYPE_MASK)
    & y) _$ G7 w$ u7 ?! }& D( }, ~* Q6 N5 @  T
  324.     {
    . ~7 |: F1 q( E% V" Y8 m2 i, k% \
  325. 4 x2 h% H. K  k) ?
  326.     /* Class request */; v+ H4 D9 D& m7 K% Y" q
  327.     case USB_REQ_TYPE_CLASS :
    4 a& v2 ~6 ~0 j1 `1 j
  328.       switch (req->bRequest)
    4 _9 v( e5 C1 B7 X9 b$ g
  329.       {
    7 D5 f2 b% ~- L3 U. v$ U( M+ m& z0 |
  330.       case BOT_GET_MAX_LUN :
    / ~; ?% c/ |$ Q! L# n% M

  331. ! T6 Z+ c3 q0 I3 s
  332.         if((req->wValue  == 0) && # Q; C' n5 U8 ?- G( r
  333.            (req->wLength == 1) &&7 y& z# c% O  u1 I. s
  334.            ((req->bmRequest & 0x80) == 0x80))7 s- s& X* W6 h
  335.         {5 n. q. i$ e  I* T) ]0 T) K
  336.           hmsc->max_lun = ((USBD_StorageTypeDef *)pdev->pUserData)->GetMaxLun();
    ' q3 x* @0 G7 r
  337.           USBD_CtlSendData (pdev,1 ~1 c8 @3 p# [, C3 t; i' c
  338.                             (uint8_t *)&hmsc->max_lun,6 \1 ~8 K3 f" E* O
  339.                             1);7 B' z7 E8 k8 I  m; ?$ I
  340.         }, E. x% r" ~) B
  341.         else0 G' D3 @: w# L9 ~: s: l& t  R# _% q+ |
  342.         {/ q% ?% j% w' z# S0 E1 j
  343.            USBD_CtlError(pdev , req);
    - D) }$ m- ^% q* M% j
  344.            return USBD_FAIL; 3 D, I$ F$ q" V. A" C6 i- [3 Q
  345.         }
    ( ]: i5 G( F8 Z# h1 i
  346.         break;
    5 z; u( k; Y! ~/ O: \4 j& X
  347.         
    # c) S6 k" ^% X/ N, ~. N& Q
  348.       case BOT_RESET :. F- \0 F2 z3 I3 s
  349.         if((req->wValue  == 0) &&
    ; w/ l: S; M  _) I  o  L
  350.            (req->wLength == 0) &&
    9 F% [% l6 O' j7 |+ q6 b' X
  351.           ((req->bmRequest & 0x80) != 0x80))3 c" D. _9 Z  }0 m' T* W; f" n9 |
  352.         {      . `8 _. V# e6 G% B: }
  353.            MSC_BOT_Reset(pdev);
    , C2 }  G1 Q' K: t7 V
  354.         }1 e0 d2 n* E5 J) f) G
  355.         else
    . K. |+ J2 ~' Q! X' ]% A
  356.         {
    . ^* B3 K- s' r% Y! E' B+ |- n  P( _  E
  357.            USBD_CtlError(pdev , req);1 i6 q* w2 P: D' D, S
  358.            return USBD_FAIL;
    ( H1 U* Z! ?- u9 Y, a
  359.         }
    " G  Y; ^, e3 a" J; N' L, g4 y0 f
  360.         break;5 j8 q: Z, @. w. |3 J% o9 f2 @
  361. 1 l/ Y) P3 @3 t, E. J  L. x9 _7 J
  362.       default:% Q. k7 S) ?0 J2 ?0 d
  363.          USBD_CtlError(pdev , req);# ?$ W! M: \1 k' V8 y8 ?
  364.          return USBD_FAIL; 6 A/ j/ Z/ p$ f9 T
  365.       }
    * y) p( s" \, q7 d: W: W% B
  366.       break;/ M% {& q3 p7 N, N! |$ u
  367.     /* Interface & Endpoint request */3 G9 J  [7 e$ T
  368.     case USB_REQ_TYPE_STANDARD:3 E. B5 W3 U  a
  369.       switch (req->bRequest)+ {7 r/ n- O& K7 S+ B/ f1 U
  370.       {0 ?: ~% j# A1 |/ S0 X
  371.       case USB_REQ_GET_INTERFACE :
    ' V6 U, j" y$ s2 t
  372.         USBD_CtlSendData (pdev,. j& V' Z4 s# h$ l
  373.                           (uint8_t *)&hmsc->interface,
    0 p% c% m, I  O" g5 G9 o  q0 w
  374.                           1);
    + s2 `! Z& `1 i
  375.         break;
      j9 k0 t$ a, O& v
  376.         * u: B. W+ b# K. @7 M" i2 p
  377.       case USB_REQ_SET_INTERFACE :
    4 D! c; x. L1 s, |8 e% {
  378.         hmsc->interface = (uint8_t)(req->wValue);0 ]+ P" P$ E. |( I0 s8 z/ I6 \1 |
  379.         break;, U- I/ a8 ^) w) G2 |( B9 o) G# @9 e
  380.       
    - z1 E) s( P! `+ F- p: V/ s
  381.       case USB_REQ_CLEAR_FEATURE:  , d0 D5 n0 ^4 Y) N
  382.         
    * Y1 F( @2 u( v1 P
  383.         /* Flush the FIFO and Clear the stall status */   
    ) d1 C: k' |/ G$ L4 G. a
  384.         USBD_LL_FlushEP(pdev, (uint8_t)req->wIndex);
    2 k' Y7 [7 t2 K: C2 U9 f1 u
  385.         ! T1 f, x. j& J9 O0 T5 F
  386.         /* Reactivate the EP */      ; ~. E7 T3 m+ x
  387.         USBD_LL_CloseEP (pdev , (uint8_t)req->wIndex);% B5 x5 t4 P, T9 W. B( j
  388.         if((((uint8_t)req->wIndex) & 0x80) == 0x80)7 B/ F* K* x2 E
  389.         {2 T3 U  f4 r& D- z
  390.           if(pdev->dev_speed == USBD_SPEED_HIGH  )
      M8 D; T; K; m0 i
  391.           {
    : p. \' v# o" L$ g- G- H) p
  392.             /* Open EP IN */
    / K5 K) H# I" W; [( b2 L5 ^
  393.             USBD_LL_OpenEP(pdev,3 C2 o8 b) m) U, A* R" q, @' X
  394.                            MC_MSC_EPIN_ADDR,4 _( Q7 H# h8 {6 e0 e8 s, M
  395.                            USBD_EP_TYPE_BULK,
    7 D; q& v5 }$ z. E' _: p6 k" l
  396.                            MSC_MAX_HS_PACKET);  
    ( T1 S8 z( L2 O
  397.           }$ R' [5 \) Z% [5 a0 W
  398.           else
    + t+ ^5 q8 K7 a; s/ c6 m
  399.           {   2 B( _' n. |' _1 Y! v4 G. w* L& K/ P
  400.             /* Open EP IN */0 i; d7 @3 {: {, c" S" A& B
  401.             USBD_LL_OpenEP(pdev,
    4 l5 q3 D! c0 h7 B- Q6 E$ T, e
  402.                            MC_MSC_EPIN_ADDR,4 ?, o0 W- r2 U$ ~, E8 G6 c
  403.                            USBD_EP_TYPE_BULK,
    * R7 H0 n9 ?! F$ |" q3 W
  404.                            MSC_MAX_FS_PACKET);  
    4 I$ [1 E3 l- e# t
  405.           }
    9 _; q4 f! `% l7 n2 |
  406.         }, {  ~" u: q6 B9 V% Q
  407.         else
    " ^) k  t. u# w
  408.         {8 Z' T; ~! O7 B- R5 z/ _9 B  Y
  409.           if(pdev->dev_speed == USBD_SPEED_HIGH  ) 9 b2 I4 j# k8 E. w. ?6 i) K1 D8 `
  410.           {
    : K( P# S& v+ H! o
  411.             /* Open EP IN */; {  P$ y5 r% i2 |& |$ D+ P
  412.             USBD_LL_OpenEP(pdev,: P, T8 a0 i9 N( i1 v0 d; M
  413.                            MC_MSC_EPOUT_ADDR,
    4 e5 ]$ S/ V# R5 c2 F1 ?% V
  414.                            USBD_EP_TYPE_BULK,
    - y6 N: l/ P9 O/ D, T
  415.                            MSC_MAX_HS_PACKET);  * O0 S( O% a7 l; Y) V' H# C
  416.           }- q' Q: N0 ^# [, L. Q/ \4 z! ~
  417.           else8 g- m6 Y# H9 K. @4 w
  418.           {   ! Q2 p& }0 t2 Z2 K6 M
  419.             /* Open EP IN */& m0 A3 {! X; V: j% I
  420.             USBD_LL_OpenEP(pdev,3 Y; V" b' J) a( |" c
  421.                            MC_MSC_EPOUT_ADDR,
    . Z5 L. [) i" g* L# Z: T
  422.                            USBD_EP_TYPE_BULK,
      @+ d6 ^/ q5 w# _( P
  423.                            MSC_MAX_FS_PACKET);  + [3 k& ^4 f# g  t$ m0 |' j
  424.           }# `2 p) e, Z. J! L$ x+ {
  425.         }$ b) a7 `0 a8 V
  426.         ' {+ N4 d8 X/ |* z: c2 V
  427.         /* Handle BOT error */
    ! t" x/ w6 N1 Z8 a/ s8 h4 m& R- o6 {9 d
  428.         MSC_BOT_CplClrFeature(pdev, (uint8_t)req->wIndex);# q5 ]3 Y' ~- g; c
  429.         break;
      D9 _6 K7 b. d1 Y- D8 w0 u
  430.         
    ' ?0 ~8 o( \& ~' z5 B
  431.       }  
    # w% |9 u6 g3 `* n4 |0 C
  432.       break;
    * M: U; x$ ^5 ^  r6 F# W
  433.      3 S' c; Y  X& H+ @0 U
  434.     default:
    0 E  e( ]2 l# x/ a+ T2 p4 d8 _
  435.       break;' R3 d! x) o" v- O0 D7 h2 [
  436.     }7 Z* ^) M+ e: ?% X5 G$ `
  437.   }% }8 o& Z2 E5 |& A- x% e& b
  438.   else0 I- ^) J) l2 u  A7 T
  439.   {  D, ^6 m. T* n/ e$ l. C
  440.     MC_Switch_CDC(pdev);2 _0 F6 f- q/ r. W$ q" \2 i
  441.     static uint8_t ifalt = 0;
    ( J& y2 x- C6 N" Y7 P- v& q
  442.     USBD_CDC_HandleTypeDef * hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData;   
    4 H  J% R; C. t7 x. _- P% C9 [( g

  443. , s" E8 @+ |5 p5 ?  [& T
  444.     switch (req->bmRequest & USB_REQ_TYPE_MASK)$ |$ o7 `/ _5 P. c1 G9 @
  445.     {9 V+ e3 O5 r' U, g" x" c
  446.     case USB_REQ_TYPE_CLASS :
    - D; a0 g0 X& u3 J0 L: Z% y
  447.       if (req->wLength)  o. }* f5 I* L& p- R
  448.       {6 p/ ^( K' ]7 m- K
  449.         if (req->bmRequest & 0x80)( u+ @1 Q4 R# a/ W0 @' f
  450.         {
    * k# ]* S% z8 c- j/ }4 n( m& B
  451.           ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest,
      {- E: ]( j3 L7 j; x1 h
  452.                                                             (uint8_t *)hcdc->data,, a. S" [% ?: o  l' a5 n
  453.                                                             req->wLength);
    ) S9 H8 N% c$ b, T4 s% n8 c' X7 A7 E
  454.             USBD_CtlSendData (pdev, ' A  z8 u* ]# _) `" Z. `( n5 A
  455.                               (uint8_t *)hcdc->data,+ D% b* w- M% E. r6 e. |8 `
  456.                               req->wLength);: s2 `: ]- A& [: R
  457.         }7 V8 f7 l9 S  v2 ^: y
  458.         else( D3 i& k7 q% X+ |# Y# U2 |& v0 K& l
  459.         {
    5 Y2 `# Y9 P$ e, Z, ~; m) ^8 Y3 o
  460.           hcdc->CmdOpCode = req->bRequest;$ g, m' L1 b1 g) d7 T/ ^# O/ I
  461.           hcdc->CmdLength = req->wLength;$ G4 z! v1 l' i
  462.          
    2 ^) d" C/ a2 v% c- i, L) H* A! g6 Z' S
  463.           USBD_CtlPrepareRx (pdev,
    " I! C. R' |8 u  w, N, m
  464.                              (uint8_t *)hcdc->data,1 P  T; ~7 {) Q+ @( N% |( }
  465.                              req->wLength);# p1 ~5 x8 H/ }6 H4 k8 i
  466.         }6 _8 j8 Y' e+ L* f! @8 `; g7 r
  467.         9 ]% `- L2 M: K+ G- N+ E& c3 q
  468.       }
    - d# Q' o4 I' k1 N
  469.       else& E  ]; X, [, B' o) _, e* s
  470.       {+ E! s0 z' g, `( _+ a, \+ M% X7 [
  471.         ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest,
    $ J% |7 b1 N- |2 p
  472.                                                           (uint8_t*)req,+ }! ^1 z. r: z8 ]$ m9 D
  473.                                                           0);
    7 s9 I& Q/ t- k3 C; q
  474.       }: Q4 G) C2 q7 Q! c
  475.       break;0 B0 W8 C- m0 o& q: M6 f8 U: N2 o6 Z& l
  476.    
    . O  H% W- f/ R# X7 A5 F" T" ?5 \
  477.     case USB_REQ_TYPE_STANDARD:6 [1 W. p% `3 w% Z
  478.       switch (req->bRequest)
    ; n2 n4 O% z. _6 a! W% }
  479.       {      $ O) y) Y% {$ ?( @
  480.       case USB_REQ_GET_INTERFACE :
    7 m: ~1 J$ _) E/ D1 Z/ @9 E2 E
  481.         USBD_CtlSendData (pdev," ^. P  F3 [9 w4 E" ~& x/ @3 ]( W
  482.                           &ifalt,
    2 {, c5 v/ S/ D& z* \3 Z0 ^8 g+ y
  483.                           1);+ \1 x0 _4 K0 T6 i: t8 W0 R3 }
  484.         break;# U# @! P) W9 i& t
  485.         
    ; k, T" k  ^$ P6 d- V
  486.       case USB_REQ_SET_INTERFACE :$ Y: _1 r5 X! Y8 t1 K/ [
  487.         break;, X" Q8 r$ k, T$ ?# o; g& n; J- d
  488.       }" j; H! Z/ m: f* Q2 ?+ W! \3 U
  489.    
    8 M8 b6 ?& @$ E+ ?
  490.     default: & g! @7 Y, d0 S7 |+ L1 r! `
  491.       break;
    2 T9 ~2 i1 Y7 A! h4 X( w- q
  492.     }  
      n% u  F1 q. A( H% ]8 f
  493.   }- C7 E* p, t2 f! r4 `/ p  r: v: j
  494.   
    % p3 H# N  F9 q- ~! c0 W, v
  495.   return USBD_OK;7 O5 ]0 J1 Y5 B7 `8 c& k: \* t
  496. }! R, Y$ Q+ {9 _7 E7 D0 u

  497. + N$ z& R$ t- K8 l
  498. /**" V$ i: o5 W9 j" [5 k2 S
  499. * @brief  USBD_MC_DataIn
    - n+ Z) M3 A! f" b
  500. *         handle data IN Stage
    / {# ]/ [7 h8 W
  501. * @param  pdev: device instance
    ' @& q; m% Q& r3 I
  502. * @param  epnum: endpoint index
    0 c- x1 B0 A+ v% D! J
  503. * @retval status
    , F  a. i3 U5 P6 m  [
  504. */9 s5 v& K* T. c- ~
  505. uint8_t  USBD_MC_DataIn (USBD_HandleTypeDef *pdev, 7 p( m' x% Y; C' D2 G$ w
  506.                               uint8_t epnum)7 J& H$ b+ w) z
  507. {
    & k9 }) s7 t3 ~% \6 X9 A
  508.   if(epnum == (MC_MSC_EPIN_ADDR & 0x7f))
    9 n9 V& [( {2 E8 Z3 C5 m. r
  509.   {# p! O" \( j0 y& h
  510.     MC_Switch_MSC(pdev);  I4 n" Q7 A9 z: M- D
  511.     MSC_BOT_DataIn(pdev , epnum);
    5 h9 |7 i4 @0 o" z  ~
  512.   }
    ; c7 z; f0 K" n) I& C5 j$ Y5 B1 S0 p
  513.   else if(epnum == (MC_CDC_IN_EP & 0x7f))" _; x% `1 u2 B6 T8 D6 U( [
  514.   {
    ) s, u% o9 S$ [2 q8 ~1 }
  515.     USBD_CDC_HandleTypeDef   *hcdc;6 V8 \8 f. Q4 R+ i: [3 U! C% i0 |9 ?
  516.    
    * A; l& k6 y( O  G* A6 T0 D
  517.     MC_Switch_CDC(pdev);
    % }# k9 o0 @; {! v7 N, I0 I
  518.     hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
    - K$ h' w1 A/ `. w6 G
  519.     hcdc->TxState = 0;    3 F. |. P0 F, s* s( A
  520.   }+ c) C6 u( S) F% }2 ?% H( q
  521.   * \( C, V  T3 t
  522.   return USBD_OK;
    : L& p, B, |9 d
  523. }8 S" `8 m0 |) V
  524. & ]' U4 ?' y5 q; l
  525. /**
    / V& t0 q8 h8 u; U* |$ \
  526. * @brief  USBD_MC_DataOut7 f2 u7 ^: @- B/ b3 X% T. g
  527. *         handle data OUT Stage9 t$ a8 y7 M$ G1 h& U+ V
  528. * @param  pdev: device instance
    ' d: K# w% U2 m- U; ^& B9 I3 _0 [/ H+ s
  529. * @param  epnum: endpoint index
    0 ?4 Z# t2 T* v0 Z; K- W
  530. * @retval status
    " Z% ?$ P) ]5 V# ?  R+ e
  531. */8 T2 W4 X: ~& ^/ A( R. t
  532. uint8_t  USBD_MC_DataOut (USBD_HandleTypeDef *pdev, # }! f# T4 E. E
  533.                                uint8_t epnum), V2 _7 Y8 @6 i; U4 v
  534. {
    9 V: h+ }, X; d( {4 M
  535.   if(epnum == MC_MSC_EPOUT_ADDR)
      H; P* `3 |7 n
  536.   {2 `5 ?+ Q$ P2 H: I$ r
  537.     MC_Switch_MSC(pdev);
    $ ]" l; L! b+ d9 t7 P) k
  538.     MSC_BOT_DataOut(pdev , epnum);
    - n# ^. R/ \2 W# J5 u3 N! f
  539.   }
    * w+ t: j- g. `5 s& z2 A1 T
  540.   else if(epnum == MC_CDC_OUT_EP)4 H2 i# X" B6 u# t) j* o
  541.   {
    2 E! a( c" G8 a" }
  542.     USBD_CDC_HandleTypeDef   *hcdc;3 R! g# M1 K' r, u7 v8 e
  543.     * e9 z4 M% |1 d5 B$ t8 h! Y! X: K
  544.     MC_Switch_CDC(pdev);
    0 s7 U: I3 g; ?% E3 U# Z
  545.     hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;' r) }/ ?5 D7 C* _; @2 s  t
  546.    
    ! b  k6 L, u' P! ?+ e; E+ X
  547.     hcdc->RxLength = USBD_LL_GetRxDataSize (pdev, epnum);: x  B# i4 y! j: Q
  548.     ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Receive(hcdc->RxBuffer, &hcdc->RxLength);
    & O1 c* F( ], g# h
  549.   }, K# U& y* t3 y" M% y: N
  550.   8 E9 o2 P4 k% p6 t5 j+ X) p
  551.   return USBD_OK;
    6 |% f5 G( D7 a- E' O- {5 P
  552. }
    ' z( k/ d4 T6 `! V$ }0 l
  553. ; g/ U3 z4 E$ v" X4 O
  554. /**
    ! E3 n. N9 ^9 E: S- b8 b
  555. * @brief  USBD_MC_GetHSCfgDesc
    9 a% t& F! h' w- j7 c3 t
  556. *         return configuration descriptor- N! I9 ^( `7 d8 M1 }5 x9 M
  557. * @param  length : pointer data length
    + }2 I7 u) `4 o& {- {
  558. * @retval pointer to descriptor buffer! r# O+ {% N( J  G: c
  559. */
    9 c8 z$ T! f" `3 ^' I' G
  560. uint8_t  *USBD_MC_GetHSCfgDesc (uint16_t *length)' P% P0 d  I1 Z" E5 Q) F
  561. {
    ! z9 }' y8 h9 g$ _% v8 K& c( Q
  562.   *length = sizeof (USBD_MC_CfgDesc);' F: t( v# k% n! O) O, i0 b* v/ O
  563.   return USBD_MC_CfgDesc;
    2 {1 Y7 ^9 l( u
  564. }
    1 g( e. Z& [! _; X. b% C
  565. 4 y+ T- }0 J: _% |+ T7 w/ b
  566. /**3 ^& B" M  V: \" _6 D/ \
  567. * @brief  USBD_MC_GetFSCfgDesc % x( Y5 [2 r! R0 G& a
  568. *         return configuration descriptor
    4 ]/ ^# l; q9 C/ C* G* p
  569. * @param  length : pointer data length& A* n: ~- L# y2 D% ]% L( l
  570. * @retval pointer to descriptor buffer
    ! d7 U* i! {3 n1 h
  571. */( ~5 P+ i( o  e' |8 K4 Q
  572. uint8_t  *USBD_MC_GetFSCfgDesc (uint16_t *length)# E  L/ W" U- Y5 B: z7 y# q8 L
  573. {' a( W& {8 ~  U: q3 [4 L- j
  574.   *length = sizeof (USBD_MC_CfgDesc);) h, c0 e! \9 u( I
  575.   return USBD_MC_CfgDesc;, c( `5 n  C/ M# J' S4 p
  576. }* r; s7 V* J  a5 S. D; _% _* z3 q
  577. 7 y7 v3 q3 W$ R/ k5 S! W
  578. /**
    . U7 O- u) D2 M  Z, x9 e$ w) ?
  579. * @brief  USBD_MC_GetOtherSpeedCfgDesc
    % ~# f1 a( \3 y0 F" D8 R/ x
  580. *         return other speed configuration descriptor5 J4 G$ Z' K2 d6 T
  581. * @param  length : pointer data length; ]2 E3 g; q* x0 B+ K/ k
  582. * @retval pointer to descriptor buffer
    ' h8 f- z# H) K" ]% ^4 b  p; I
  583. */
    ; g7 r7 e1 p# K6 k. n
  584. uint8_t  *USBD_MC_GetOtherSpeedCfgDesc (uint16_t *length)2 ?5 f6 [% ?: Q- V1 P9 z
  585. {+ Y0 P- h% m1 |( B9 z$ p
  586.   *length = sizeof (USBD_MC_CfgDesc);
    ! W* S; p" A* H# k8 q5 z
  587.   return USBD_MC_CfgDesc;
    4 ^+ m( J$ k3 B! f
  588. }
    / G) ~8 \  a4 ^
  589. /**
    0 S+ |; }0 c' ?" ^
  590. * @brief  DeviceQualifierDescriptor / p) }2 j+ P6 L( S5 W: U% k
  591. *         return Device Qualifier descriptor
    3 v4 w1 W! ~! `! D0 Z7 O( x
  592. * @param  length : pointer data length
    ! h, C! _' w3 B/ ~
  593. * @retval pointer to descriptor buffer% V7 D! ^+ z  y, s+ w8 H  Z: [" `
  594. */
    ) o7 A9 h0 B0 Z  b4 M5 D
  595. uint8_t  *USBD_MC_GetDeviceQualifierDescriptor (uint16_t *length)
    9 M( w0 Z& F/ \: \
  596. {+ l6 N! F9 Q! W% m* r8 ^. ~
  597.   *length = sizeof (USBD_MC_DeviceQualifierDesc);
    " \/ i% E6 z+ A( f$ H% ^
  598.   return USBD_MC_DeviceQualifierDesc;+ |7 W1 j, o/ M: [$ ~
  599. }
    + O. r. w! W0 w# `8 ?, J
  600. + k, h0 S/ M2 W- Y
  601. /**' }% {* H; b) [- [
  602. * @brief  USBD_MC_RegisterStorage+ V: K& y2 O: {, u* P7 Y  ^
  603. * @param  fops: storage callback
    . U/ ]# A  N1 P" W1 I& d
  604. * @retval status
    8 |' C+ m" t/ D; L# ~
  605. */3 L  Q2 }9 z! U: @! a9 l: m) T

  606. / Q4 |1 s) p8 K+ V
  607. static uint8_t  USBD_MC_RxReady (USBD_HandleTypeDef *pdev)& K2 v7 g, l/ f, O2 ^
  608. {8 f5 l+ \3 G; @5 F0 d! }
  609.   USBD_CDC_HandleTypeDef   *hcdc;
    2 K# b5 f$ X; X1 V, }
  610.   
      [3 s' Z, h: ~  K9 N
  611.   MC_Switch_CDC(pdev);
    # {$ W( G2 k. S" ^3 U
  612.   hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;) z: U; V5 F8 V
  613.   
    6 ?! @; L0 c! S# Y$ V4 p' A2 ^
  614.   if((pdev->pUserData != NULL) && (hcdc->CmdOpCode != 0xFF))$ s; ?: X8 z( u+ B3 H
  615.   {  ?3 s! ~9 B0 A3 n( F" s6 a
  616.     ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(hcdc->CmdOpCode,
    7 T0 U' R$ m. ]9 U. G2 t
  617.                                                       (uint8_t *)hcdc->data,' o' J& x' I/ j' [
  618.                                                       hcdc->CmdLength);2 j* z  m9 y% x' F
  619.       hcdc->CmdOpCode = 0xFF;   z$ h$ J3 B' t
  620.       
    % y  g  F2 ^5 X" t2 p6 _5 y3 @4 s
  621.   }# _  E, P& R( F
  622.   7 M; F( k/ x+ D! y
  623.   return USBD_OK;2 d! C9 h1 K- G6 X, Z: \
  624. }* j+ J3 |$ y( [) R& ~: r  x
  625. 1 X( q, a, z9 ^% X' E
  626. static void MC_Switch_MSC(USBD_HandleTypeDef *pdev)
    + A) _9 k& N* b: q1 P0 K$ h
  627. {! P, B& ?' ~' k  v) G
  628.   static USBD_MSC_BOT_HandleTypeDef msc_handle;
    9 {9 z$ a8 ^* S3 V* a8 e) O+ w
  629.   9 `9 k7 B2 ]2 m
  630.   USBD_MSC_RegisterStorage(pdev, &USBD_Storage_Interface_fops_FS);
    0 t6 L8 j5 \: h: v- X9 T
  631.   pdev->pClassData = &msc_handle;% @2 }  y# U- K; h! j* P+ V
  632. }8 V$ B$ W% g6 k

  633. / }0 B  o( W5 E
  634. static void MC_Switch_CDC(USBD_HandleTypeDef *pdev)
    ! \! x8 e9 E7 T0 {# o1 K- g9 E
  635. {+ F  O9 _2 D  _2 D0 H' L0 t
  636.   static USBD_CDC_HandleTypeDef cdc_handle;
    - m9 n) Q0 L3 a- y! }9 d
  637.   
    3 N6 A4 G! {( A/ \4 {7 Y
  638.   USBD_CDC_RegisterInterface(pdev, &USBD_Interface_fops_FS);
    $ k- t5 t" Q0 B9 \& U
  639.   pdev->pClassData = &cdc_handle;+ Z/ b0 H1 u; ]) D5 ^7 i0 Q
  640. }4 O. A. F; [7 x+ q5 w* {& o4 {
  641. $ f7 o# [* C( R' H+ k4 V
  642. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/2 G# M6 S: }& h4 f& ^
复制代码
* k* S* a% ^) o  c+ K  \
通过以上修改后电脑电脑端显示USB复合设备MSC+CDC# S: `+ e5 t  |$ U' t( R
msc cdc.png + B! k( D. z! P+ Z. V

7 [" r* ~5 a+ N+ k; J- w! ^13.在usbd_cdc_if.c  CDC_Receive_FS   /* USER CODE BEGIN 6 */ 增加发送测试
* i# X3 a9 w) w; Q5 E. F: ?, \4 z- }. h  ~5 P2 U* h: F
  1. static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)( a( `9 x6 n6 v) r& V
  2. {8 L/ D* S; n1 ]# p) w" ^$ P) w
  3.   /* USER CODE BEGIN 6 */
    7 q3 z# V5 {. o, k4 T
  4.   USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);
    . N# T, @$ L! n
  5.   USBD_CDC_ReceivePacket(&hUsbDeviceFS);+ U8 u' H# h$ Y" W
  6.   + z! Z2 @5 W7 P* K+ P" [) q% y
  7.   CDC_Transmit_FS(UserRxBufferFS, *Len);      //把接收的返回8 Y9 e$ r) ]* P
  8.   
    + Y- S3 \+ s1 ~
  9.   & h3 E0 w% t( L
  10.   return (USBD_OK);
    * N, q! B6 j9 }
  11.   /* USER CODE END 6 */
    , j2 B9 E# k0 e  B7 C( h# \- w+ `) i9 b
  12. }
复制代码

( r* D; T3 S  ]测试串口收发- W0 S( x2 y* Q* x# g. l/ z& C
test.png
! w4 g/ D* k* A3 t
: h; ?, I/ i5 ?: c, A6 o& O5 C+ B0 P* e7 G6 B3 W
. {* }5 H8 Y9 q: c9 ], [

/ V- c: O/ u! q* B5 K( }  K

评分

参与人数 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
非常好的资料,对初学者很有帮助;6 O' ?8 N3 O% d0 ], g" p4 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" C2 u; C! t) E3 r! I* i0 c
完全按照楼主做法,在win10环境下U盘和串口都可以实现功能,在win7环境下,串口错误识别为mass storage ...
6 s+ b0 T* y- A& f; U1 B/ J5 F6 e, |! c
是不是驱动问题,我电脑Win10
电子ai好者 回答时间:2020-11-19 12:57:48
hds1988 发表于 2020-6-29 09:521 j* v7 g& ?% J  l$ T
完全按照楼主做法,在win10环境下U盘和串口都可以实现功能,在win7环境下,串口错误识别为mass storage ...
8 Q! c" x$ P+ Q- L( s/ D/ |
微信图片编辑_20201119125724.jpg 我现在就是win7系统,和你一样的现象。请问你找到解决办法了吗?7 \- N7 C" P8 u# Q& L  |( H
js123456 回答时间:2021-8-10 15:34:43
用stm32cubemx生成的项目cdc,在文件usbd_conf.c中,USBD_static_malloc申请内存是以USBD_CDC_HandleTypeDef为准,函数如下:8 P$ q  q6 Y: w4 U. u$ Q
void *USBD_static_malloc(uint32_t size)
) B) @* j& ]' q" X- u{' I$ m* |2 A- V  ]. h
  static uint32_t mem[(sizeof(USBD_CDC_HandleTypeDef)/4)+1];/* On 32-bit boundary */( g3 U8 F* f5 Y* r0 C
  return mem;, \1 P; |& M7 T
}
7 K8 ^* k7 n7 m$ A0 e" ]. R# q2 D0 b7 y. w5 a  i
那么在组合设备中,USBD_MSC_BOT_HandleTypeDef和USBD_CDC_HandleTypeDef都需要申请内存,怎么操作?. k/ Y. r* I, ^& L+ @

% a) n  w$ u, g8 L7 t' F$ t
js123456 回答时间:2021-8-10 15:35:35
hds1988 发表于 2020-6-28 23:47
& K9 S. _1 {  m8 D完全按照楼主的说明操作一顿后,不能识别出CDC,但是能识别MSC。MCU是F407VE

; \- Z# h! g% e有可能是函数USBD_static_malloc的问题
. s7 g$ }. J4 f: D

所属标签

相似技术帖

官网相关资源

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