本帖最后由 289466080 于 2019-6-23 15:56 编辑
9 }) A; D/ v. p1 F: A' m7 q3 z# z
$ ?- ?( ^* P6 Y) t 最近做个USB复合设备CDC+MSC,在网上找了好多基本都是F103做的复合设备,带OTG芯片USB复合设备网上很少可能是我搜索的关键字不够理想有的不够全面,官方给了一个视频教程但是没有参考代码,社区里面有分享到github我按照后也不能实现,后结合F1与github分享的+官方视频,实现了在STM32F730R8T6上面USB复合设备,分享下怎样用cube生成的代码实现USB复合设备(带OTG的芯片).
- X& Q V) o* }
" ~4 m y9 A, p参考:
! B. H7 J: J0 O) Egithub分享
0 D/ ]2 ~2 e7 O2 Y& q1 B' shttp://github.com/uwyciw/CDC_MSC
9 p! S& `5 D7 C; Y9 i' C* Z官方视频" _0 s1 i S1 I
https://www.stmcu.org.cn/video/index/detail/id-3988
0 i, ^- N' J6 W& a) T' RF1037 c+ V6 R$ \0 d; j8 Y: S
http://www.bbsmax.com/A/kjdwBXA5Np/
+ y; L. _( v1 V6 E# p$ X& N* P" j* u2 y8 i
5 G! F C- X! L5 y
cube 5.2.1, P" @- x1 }& n( K8 }% z/ S; K8 u
hal stm32cube_fw_f7_v1150.zip9 ~6 E+ K$ T, D0 h i& i5 j" d
3 G3 E* n! D2 Q! EUSB为 USB_OTG_FS
0 }" [3 q% P A- b- G5 M
& j( _: G" g2 t3 i1.先生成一个CDC工程下面配置图。1 J5 F7 {' N; w/ g) w* U
RCC如图箭头其他默认
4 `1 M$ k' \* }
/ k7 C6 o* U# o$ fUSB_OTG_FS如图箭头其他默认1 N) S" ]: f# X5 \) G
1 u2 K6 q0 z9 ?, F9 |; u) Z" UUSB_Device如图箭头其他默认3 P# o8 n7 T% C# |( h" l/ w3 m
+ S+ X+ I/ R( d6 Z$ i
Clock如图箭头其他默认我用的16M晶振比8M便宜$ d+ Q6 V/ ?7 c( W/ J6 d
9 G/ n! f0 z7 L' W
1 Y y6 f$ D* c) O6 j: bProject如图箭头其他默认+ h' }8 c& A+ _6 o
) a( z4 [( |$ P4 l5 J2 _' ^
code如图箭头其他默认: s4 G/ R( @5 M T
2 V# C1 m+ n4 G6 q; O2.同样生成一个新的MSC工程不可覆盖原本的工程只需修改下图与工程名其他一样+ A0 z& v- s' q8 i( N2 m
# R' [' P1 S+ X
! V% B" b9 y. f
6 T% A/ E: K! ^4 ?% W
, d/ s8 B7 {2 }& z5 z) |3.生成后把CDC工程下Src文件夹里的usbd_cdc_if.c与Inc下的usbd_cdc_if.h复制到MSC工程下Src与Inc文件夹里面,MSC工程下Src文件夹下新建usbd_composite.c与Inc下新建usbd_composite.h
7 n7 ?' ~5 i) ?; G+ |* \: P
# y+ l! y4 N, Y) g& T$ I
3 B8 y6 ~3 ?+ g, |' W
9 F% N) i/ l) S9 A" P7 m
4.把CDC工程\Middlewares\ST\STM32_USB_Device_Library\Class目录下的CDC文件夹复制到MSC工程下见图* Z3 P+ P# ^+ _3 l
- g5 C. T2 t9 U- L2 e1 J5.添加CDC路径, \" b) ]4 j2 N7 D; q: ^
. n0 Q1 n, [1 t# M
4 [/ N1 A% `, {1 l8 p% r0 H# J
7 C2 r! ~* k4 u1 ~# T* I2 |
6.在工程中添加usbd_cdc.c usbd_cdc_if.c usbd_composite.c见图& \) b7 g3 c n6 G+ D) X- P
( y# X m F5 y8 S
, H* a; h: X: _0 T7. usbd_conf.h 把USBD_MAX_NUM_INTERFACES值 1修改为3
/ {7 y X* a# X9 ~. O- /*---------- -----------*/
4 F1 [# R5 J& B, w. y/ E0 M% Y - #define USBD_MAX_NUM_INTERFACES 3U //1U
: ?& {- a4 \! o# I - /*---------- -----------*/
复制代码 8. usbd_cdc.h 修改CDC_IN_EP CDC_OUT_EP CDC_CMD_EP) _4 c7 S3 i# r* x3 S: u) n
- //#define CDC_IN_EP 0x81U /* EP1 for data IN */: x6 F. K0 ? F; _% ^9 E
- //#define CDC_OUT_EP 0x01U /* EP1 for data OUT */- u; Q1 U& x# u, I
- //#define CDC_CMD_EP 0x82U /* EP2 for CDC commands */9 B, X3 K$ m& D! B" G0 r
- #define CDC_IN_EP 0x83 /* EP1 for data IN */
, [% [ F( ]5 D- S: x- J% l$ _9 } - #define CDC_OUT_EP 0x03 /* EP1 for data OUT */" } x3 U& Y) F
- #define CDC_CMD_EP 0x82 /* EP2 for CDC commands */
复制代码 9. usbd_conf.c USBD_LL_Init中新增: g9 r# o- ~) _9 x
- HAL_PCDEx_SetRxFiFo(&hpcd_USB_OTG_FS, 0x80);
+ v( @' d5 x4 U* j - HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 0, 0x40);& ^; S$ [9 l% w' o1 F
- HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 1, 0x80); J- j& H3 ]+ b5 N2 r
-
1 G3 h# w8 @1 A) w0 O+ z1 N - HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 1, 0x40); //新增- W: h( x: `& ?# {$ }- V e; j
- HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 3, 0x40);
复制代码 10. usb_device.c 修改MX_USB_DEVICE_Init与SER CODE BEGIN Includes中新增usbd_composite.h2 I- m7 D9 [: {* m# @; g
' @ J8 ?6 S" B0 s$ g6 [- 5 x3 w( a* x/ M
- /* USER CODE BEGIN Includes */3 G9 |( W! f' U7 n
- #include "usbd_composite.h"
8 s+ L8 C8 E& p7 ?4 @ - /* USER CODE END Includes */
; e5 P4 Y" _/ F
L o7 |3 t: ]) T7 [3 F' ~- void MX_USB_DEVICE_Init(void)* e% s: [" G. U/ J
- {6 _! t1 Q4 x" H
- /* USER CODE BEGIN USB_DEVICE_Init_PreTreatment */
7 A4 t9 T# z6 g# C( O6 t# C -
- `4 B7 b% H5 I5 a2 d - /* USER CODE END USB_DEVICE_Init_PreTreatment */
2 o% T/ z* A8 }+ p1 U4 f" ~ -
, o9 E( I1 \, _7 [ - /* Init Device Library, add supported class and start the library. */
* h+ S* D: o( w9 C4 y* |3 V7 U - if (USBD_Init(&hUsbDeviceFS, &FS_Desc, DEVICE_FS) != USBD_OK)3 W- F3 N6 P2 V) |5 i+ D5 ^
- {
7 W$ m3 m4 M- g4 v8 X - Error_Handler();
* Q/ L# H8 j6 U9 B - }
" ]9 y; a2 Q; f - if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_COMPOSITE) != USBD_OK) //新增
) c% C7 \" H. @9 w9 z6 h - {+ ^9 _& B$ Y/ ~
- Error_Handler();
l7 j7 T' B4 H& } - }6 l4 ~- D2 t0 B S1 K& E* P+ Y
- // if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_MSC) != USBD_OK)
- x0 W1 m: ]4 J+ B" ]* q - // {7 C4 f* h: f; S6 H& p
- // Error_Handler();
+ {9 U/ W+ o( p* R1 k - // }: {* g! D! t' d- X! _+ H6 H
- // if (USBD_MSC_RegisterStorage(&hUsbDeviceFS, &USBD_Storage_Interface_fops_FS) != USBD_OK)
& n# M/ p' Z* r - // {+ t" J' N1 J1 s
- // Error_Handler();
- o; G# i# f- W, p( |/ a# W7 [ - // }
1 ?, r# |) V3 o) E0 d# p0 Y5 | - if (USBD_Start(&hUsbDeviceFS) != USBD_OK)
" m7 l6 `/ ~2 ^2 F! C. N( d* |7 z - {
H; Q( `3 ]/ B5 P, P - Error_Handler();* o* y m# k8 y+ V" K8 h, K
- }
- b9 j. w2 \. B5 ~& t" |# Q
, x, \5 D: g( I) M. F- /* USER CODE BEGIN USB_DEVICE_Init_PostTreatment */
0 ?6 {/ C* ?6 K7 t- h( f" u8 d6 _ - // if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_COMPOSITE) != USBD_OK) //新增8 W, h. @" `& `
- // {
3 a$ Q5 V, B2 w* z: ^ - // Error_Handler();: t0 t% \8 o7 Z6 v m/ ]) X5 c9 a8 V
- // }# L, }6 x" c# ?5 h% ]! i
- /* USER CODE END USB_DEVICE_Init_PostTreatment */# w# p9 M, w q+ Q2 X4 O0 y0 ~
- }
复制代码 8 B! s$ j3 [: Y' d7 o0 p- T& X
4 ~4 C, c9 |/ A- ~11.在usbd_composite.h中新增代码+ u: }8 C3 @% r! p P! w' s
- ! z) q1 |) P% l. X7 }
- #ifndef __USBD_COMPOSITE_H
( a) j: L% l5 y, Y* x S - #define __USBD_COMPOSITE_H
8 k# J0 i9 E- @' u4 h - + y) C- W/ v( J2 E4 ?3 Q9 L1 P
- #include "usbd_ioreq.h"
0 m( X1 t) W; k+ H, d5 K( I% M - #include "usbd_cdc.h"
, @" P9 @+ `7 W; J; ?+ w - #include "usbd_msc.h"! G" `# Q8 J/ ~9 d
- 1 I% T& A# N& [# P
- #define MC_MAX_FS_PACKET 0x40
9 x, M T! }3 S; e6 O8 f - & u2 U+ V. I/ x$ _" t% D9 t) _
- #define USB_MC_CONFIG_DESC_SIZ 106
8 P* A5 C1 ~5 _: J - % F! \/ ^) z2 N6 P: p
- #define MC_MSC_EPIN_ADDR MSC_EPIN_ADDR
- Q9 j6 P$ { W9 Y" ]# } - #define MC_MSC_EPOUT_ADDR MSC_EPOUT_ADDR - ~7 B" E5 `% {, }0 @. Z4 J9 l
- ' _; \# \- d1 V( v m+ x. }
- #define MC_CDC_IN_EP CDC_IN_EP
1 x& f4 X+ s: Q) ~- i+ v9 D+ }8 H - #define MC_CDC_OUT_EP CDC_OUT_EP * ` A) e; H, W1 p/ h1 A( S
- #define MC_CDC_CMD_EP CDC_CMD_EP
, t0 g6 k, ~ _
0 c/ `" W1 D- T4 I- extern USBD_ClassTypeDef USBD_COMPOSITE;3 Q) G- Q& n1 M( F" ~- x
- / V& d; f$ ^# t1 }# T& u
- #endif /* __USBD_MC_H */& `" L. z) z4 J( b4 K$ o/ f
* [! t7 A" F) y% m4 J9 |
复制代码 : j+ s% `3 s/ T3 Z. V
4 |4 P0 }( E/ ?8 R0 u9 s
12.在usbd_composite.c中新增代码
% G8 L, |. s6 Y2 w7 S
+ z. b) R/ P% u
+ i9 J5 q% T! M7 u- #include "usbd_composite.h"
/ U* A- I& D" h) K# B - #include "usbd_def.h"6 O* v$ B! o; y
- #include "usbd_msc.h"* A' E. W% S$ V5 n d- m
- #include "usbd_cdc.h"
4 E) i+ [9 A) t. q7 f, W8 F - #include "usbd_storage_if.h"
# `6 Z; {+ {. h) `3 V3 _+ n& a4 e5 D - #include "usbd_cdc_if.h"
% i. u8 C9 g$ ^( } - # x+ _2 r( h5 V: b* r( f
- /** @defgroup MC_CORE_Private_FunctionPrototypes, }$ ^. c1 [" g$ i" N* D
- * @{+ J) ]0 @' _1 H" O3 D
- */
/ w6 ~' v u# P - ( J/ U# y0 ^) Z: w- }/ @ U" m
- USBD_CDC_HandleTypeDef *pCDCData;0 k# P+ F0 K: G
- USBD_MSC_BOT_HandleTypeDef *pMSCData;) _( n) v8 t# u0 d4 Z% q
-
/ z. |0 h" I+ Q - uint8_t USBD_MC_Init (USBD_HandleTypeDef *pdev, ' Y3 A1 H. T2 `4 b
- uint8_t cfgidx);+ `" Y/ u3 r ~9 a: }8 w
) R w: c9 ^. |* p/ l% i+ D0 h- uint8_t USBD_MC_DeInit (USBD_HandleTypeDef *pdev,
) S# i1 s* c% D/ F% V; g - uint8_t cfgidx);
2 c" ?+ D. k/ R% u: ]
! C% J/ b3 V. P- uint8_t USBD_MC_Setup (USBD_HandleTypeDef *pdev,
) e+ N; F5 N) \9 I. m - USBD_SetupReqTypedef *req);
8 ]- q: O% Z0 y. B - : b+ u9 n7 ?4 V7 Q9 W
- uint8_t USBD_MC_DataIn (USBD_HandleTypeDef *pdev, ( m4 G* S4 K4 V: }. w; K7 g2 K+ ^
- uint8_t epnum);3 @9 U7 ]+ ], k1 I* W1 x, }$ @" f
- - U* J9 d3 A: T- }8 f
- $ v4 g4 V5 b, v! B$ n
- uint8_t USBD_MC_DataOut (USBD_HandleTypeDef *pdev, 5 Q- P% s3 @# `- w# c6 n) n% e* o
- uint8_t epnum);
% h& x. V W3 J4 `
7 h9 v. Q* T8 F4 P' P+ k; T# @/ v- uint8_t *USBD_MC_GetHSCfgDesc (uint16_t *length);- @7 s) a- P4 \5 f+ @7 G- r- C
- ( N2 f5 j4 S* F ^9 ~
- uint8_t *USBD_MC_GetFSCfgDesc (uint16_t *length); p, Y5 k- |- u; @- g
6 S9 ^8 Q4 A" m) g" f- uint8_t *USBD_MC_GetOtherSpeedCfgDesc (uint16_t *length);1 _8 l* }8 x3 p) y+ e H
4 l3 ^8 w# A, @$ T- uint8_t *USBD_MC_GetDeviceQualifierDescriptor (uint16_t *length);
3 N% W$ P7 Q' R2 A. c - 7 ]: J7 z1 S. Z' b% R. k0 s
- static uint8_t USBD_MC_RxReady (USBD_HandleTypeDef *pdev);) Y9 p; [) |/ P7 o& S
- static void MC_Switch_MSC(USBD_HandleTypeDef *pdev);/ @2 ]. T. ~# a
- static void MC_Switch_CDC(USBD_HandleTypeDef *pdev);
3 Z' L( T0 m6 ]* j - , s- t" @' e# t% J7 ~/ ?
- /**; N" S4 i2 |4 s* j
- * @}# G" N/ r2 _6 m- S; ?: B
- */ 7 P- O( R; n% }9 Q1 U3 p- ~. L
- extern USBD_HandleTypeDef hUsbDeviceFS;' B/ I+ D7 w+ h) @2 b/ [2 ^4 Z
- : m" S$ G, p3 ~4 \% m9 E: f7 h
* {4 B* {4 m% }+ t3 x' M8 Y- /** @defgroup MC_CORE_Private_Variables
* S2 E5 w$ F) a' c& U7 W& x+ O8 C - * @{9 b1 b) O* f; `" p& F
- */
: G5 u7 v2 b) N" E9 C/ N' Z! n - USBD_ClassTypeDef USBD_COMPOSITE = 7 ], l- r' e; K2 j/ ~: f
- {
/ L- \& a9 J) m0 b, w3 s# s - USBD_MC_Init,
1 d5 N- E5 L7 t& E7 T4 D ? - USBD_MC_DeInit,* w! d" S+ a7 G" k1 s5 y
- USBD_MC_Setup,9 q# A8 m& g$ r l
- NULL, /*EP0_TxSent*/
. o, b4 d1 J0 i: J - USBD_MC_RxReady, /*EP0_RxReady*/
; B; p6 s$ u @5 f - USBD_MC_DataIn,
0 r% t, M) b& w: O9 ~$ K4 w - USBD_MC_DataOut,& F n) \8 |0 d2 T( S4 t) M5 ^
- NULL, /*SOF */
- Q3 h, h1 F" p" d - NULL,
! _! M) @% x/ i2 ], ] - NULL, ; B" [- N. l: Y4 x3 ^/ b; K
- USBD_MC_GetHSCfgDesc,. j; y4 F6 @7 C' J8 B' z
- USBD_MC_GetFSCfgDesc, 3 b7 \) U& [$ p" }. {7 t1 e
- USBD_MC_GetOtherSpeedCfgDesc,
' S) F) W, e/ d( b& |# } - USBD_MC_GetDeviceQualifierDescriptor,
: }6 N. W6 x$ x1 \4 u, `" U - };& H$ A. x; }# t# ]/ K/ e% M) @
- 2 }1 L6 s, W8 x& F, M! M
- /* USB Mass storage device Configuration Descriptor */
1 g( Q0 {) F) u4 _0 v - /* All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */; a" B$ p( d) ]% ~2 B. z# }: s" P
- uint8_t USBD_MC_CfgDesc[USB_MC_CONFIG_DESC_SIZ] =
7 w, b. d+ p$ W: y6 s" ]; Z9 @ - {& c% \4 Q# F- l3 h2 Y' {% W/ H
- /*Configuration Descriptor*/4 a% h6 P2 F0 e' K: [: C
- 0x09, /* bLength: Configuration Descriptor size */7 ^8 J. X# `! n* N; Q- a
- USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */% H6 L) l% E( s7 I" l# C; t
- USB_MC_CONFIG_DESC_SIZ, /* wTotalLength:no of returned bytes */
! t. o% {; F2 x& J" I- F* n* O - 0x00,9 l$ f- D& n' O6 R
- 0x03, /* bNumInterfaces: 3 interface */' l i& L0 ?/ |
- 0x01, /* bConfigurationValue: Configuration value */
4 R4 h4 \: B, Y5 H# [. H - 0x00, /* iConfiguration: Index of string descriptor describing the configuration */
& e. n, i5 ]: n0 R7 A$ m - 0xC0, /* bmAttributes: self powered */0 X* C0 z `4 K7 }, K$ a$ t
- 0x32, /* MaxPower 0 mA */ j# L* y/ k9 P
- 6 x8 k+ S) R* `: n3 o
- /*---------------------------------------------------------------------------*/1 k7 E% U1 {. x3 |; `1 _
- // IAD
& ?4 f6 X% O# n9 z6 w5 ?+ J: F - 0x08, //描述符大小! {) f4 S$ a$ q) j- R1 F1 P
- 0x0B, //IAD描述符类型
. A$ q `0 X% o7 ~+ { - 0x00, // bFirstInterface
# @6 P, Y# b: l6 p+ [ - 0x02, // bInterfaceCount
% Y& I9 x5 V7 E' T6 \" e. S( I6 I - 0x02, // bFunctionClass: CDC Class
: t N6 O6 S+ V8 `$ I$ Q5 `* W3 ^ - 0x02, // bFunctionSubClass% W8 C4 W$ A# Y; R: o9 e7 Y1 X
- 0x01, // bFunctionProtocol
+ g! }( F8 C+ C* C5 P4 g - 0x00, // iFunction
& N6 z, B3 l8 { - ' T+ `; F/ U- M5 ?5 q
- /*---------------------------------------------------------------------------*/
9 a1 g* _4 y) N - /*Interface Descriptor */& G7 b! X1 H& `* Q; O4 @. f. C
- 0x09, /* bLength: Interface Descriptor size */$ r6 R X% T* `% V) E
- USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */
; X ]# u8 j$ U0 m! o6 L! Y' [9 { - /* Interface descriptor type */5 {& |& J8 `& J( \
- 0x00, /* bInterfaceNumber: Number of Interface */& o& Q' o' q5 D' q( p
- 0x00, /* bAlternateSetting: Alternate setting */
. ^/ v! c3 ]" R( S; m3 S - 0x01, /* bNumEndpoints: One endpoints used */
$ O9 g6 Z5 D, X: Z" P6 H - 0x02, /* bInterfaceClass: Communication Interface Class */0 l( ?( q5 Q8 N4 [
- 0x02, /* bInterfaceSubClass: Abstract Control Model */
4 ?* @0 Z/ o! v, L8 U. n% q% ^ - 0x01, /* bInterfaceProtocol: Common AT commands */
8 w% a# t1 ]1 B' \! s - 0x00, /* iInterface: *// ?0 [: C, Q: u/ g
-
: w Y$ S Q3 Q+ n9 p, P - /*Header Functional Descriptor*/
. L+ Z0 j# Z D+ A8 J; j+ [ - 0x05, /* bLength: Endpoint Descriptor size */# L$ J$ T- L% u7 x/ J& `' x, W
- 0x24, /* bDescriptorType: CS_INTERFACE */. x% L# W0 W( Y' [+ I0 i. K
- 0x00, /* bDescriptorSubtype: Header Func Desc */
$ y0 Z$ |/ l8 a0 y) J - 0x10, /* bcdCDC: spec release number */
! U! ^9 B% Z- d9 ?( W6 j - 0x01,$ U) f6 c3 @# B( O
-
2 a; Y5 D6 @; V! d5 n( ] - /*Call Management Functional Descriptor*/. {% y/ ~ |$ j( Y5 m
- 0x05, /* bFunctionLength */
0 ~ b* Y: ^7 B - 0x24, /* bDescriptorType: CS_INTERFACE */& y$ O' f }2 O8 j3 k+ s0 O
- 0x01, /* bDescriptorSubtype: Call Management Func Desc */
0 r4 P! c3 X) E1 A - 0x00, /* bmCapabilities: D0+D1 */4 W+ F' u, J2 i m
- 0x01, /* bDataInterface: 1 */
/ ~' z) r' f# ` t& M( A6 o - - D, e, m: W! ?; l j) ~
- /*ACM Functional Descriptor*/
3 T- D: ?, W, X i# M# F - 0x04, /* bFunctionLength */8 r+ g, k0 |$ e5 y7 i
- 0x24, /* bDescriptorType: CS_INTERFACE */
2 b3 c1 l6 u* r5 p/ k7 }' X1 J - 0x02, /* bDescriptorSubtype: Abstract Control Management desc */
4 m* n0 j4 u4 E4 W - 0x02, /* bmCapabilities */6 r7 L- {( g3 F' ]
-
. z3 @9 @3 W1 g# I; |+ N0 s - /*Union Functional Descriptor*/
& I: }* a; o+ `1 b) c - 0x05, /* bFunctionLength */
, B# c# x+ l: F) g: A) Z H8 { - 0x24, /* bDescriptorType: CS_INTERFACE */
6 {" q) a0 B: h6 J( ~ - 0x06, /* bDescriptorSubtype: Union func desc */
( w7 Y5 P) A5 g; L - 0x00, /* bMasterInterface: Communication class interface */! p+ h# k) u6 t. T& i9 ^
- 0x01, /* bSlaveInterface0: Data Class Interface */* Q5 ]* P# e7 X9 j/ E) C
- $ x, y: {$ l9 F# g9 m9 H
- /*Endpoint 2 Descriptor*/4 s2 ]3 A1 `% _* j- S0 Q+ A3 `
- 0x07, /* bLength: Endpoint Descriptor size */
# _8 N# x/ Q W. {5 S3 N$ B4 J! r - USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */7 Q* l4 n" c7 F
- MC_CDC_CMD_EP, /* bEndpointAddress *// h3 Q- D& P) p( e& G
- 0x03, /* bmAttributes: Interrupt */1 m$ s6 A* ?- D4 D* Q9 |+ T; d
- LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize: */
0 H$ t2 a8 l P - HIBYTE(CDC_CMD_PACKET_SIZE),
9 @: @2 D0 |0 u9 C - 0x10, /* bInterval: */ $ d) D, f% g. _1 V
-
: o/ C: @, u4 y - /*Data class interface descriptor*/
! w; n; ?) I. [" R0 q6 V8 ? - 0x09, /* bLength: Endpoint Descriptor size */% Z+ ~4 x: l- M+ \# p
- USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */
& q8 U s: d; m4 O" n1 e. T - 0x01, /* bInterfaceNumber: Number of Interface */. o4 |! `2 c! W1 |
- 0x00, /* bAlternateSetting: Alternate setting */
" \! \1 \- d# y1 { - 0x02, /* bNumEndpoints: Two endpoints used */
" }' f, x) N: U - 0x0A, /* bInterfaceClass: CDC */6 E8 g! N# ^) a" p0 M
- 0x00, /* bInterfaceSubClass: */ z- s1 E u" b( B
- 0x00, /* bInterfaceProtocol: */
" n/ N& m8 g9 g `$ Q2 s; a - 0x00, /* iInterface: */; J, ]: H ?4 }8 q
- 7 y, A, f% F0 N
- /*Endpoint OUT Descriptor*/0 |, s$ a3 w- n
- 0x07, /* bLength: Endpoint Descriptor size */+ m; z% r" @. h: i
- USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint *// k/ V3 v# g/ r; a8 t
- MC_CDC_OUT_EP, /* bEndpointAddress */
5 a. A' q( a' a% K - 0x02, /* bmAttributes: Bulk */
; o! H% w+ n! I+ Q; i; O - LOBYTE(MC_MAX_FS_PACKET), /* wMaxPacketSize: */* c/ u! p; I' g" }+ ~
- HIBYTE(MC_MAX_FS_PACKET),
- D$ A% W \7 i$ ~ - 0x00, /* bInterval: ignore for Bulk transfer */
" b) E0 H9 o8 j" { -
. N& n9 `1 p* H$ t3 G* {# h - /*Endpoint IN Descriptor*/
* m0 a+ S8 [( N1 Q7 i - 0x07, /* bLength: Endpoint Descriptor size */* p' H L0 C$ y
- USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */7 Y0 [0 `) a) S+ `- S( g6 |9 x
- MC_CDC_IN_EP, /* bEndpointAddress */" d, \0 ?0 p0 z y1 n( M
- 0x02, /* bmAttributes: Bulk */% b3 x' Z( d- E% z: `/ L2 t8 |) b
- LOBYTE(MC_MAX_FS_PACKET), /* wMaxPacketSize: */+ ~9 |- m. c# D
- HIBYTE(MC_MAX_FS_PACKET), @$ J" o: |8 I( w1 L
- 0x00, /* bInterval: ignore for Bulk transfer */& K! E0 p2 Z. |) |! K- a
* I$ S2 |, N8 c! l n* q- /*---------------------------------------------------------------------------*/
4 r. p6 q2 k4 ?# g4 k9 p - // IAD
/ r3 H/ q! P7 l# X7 F p - 0x08, //描述符大小
' A5 c2 l3 _5 N2 h1 U3 Z, r4 _ - 0x0B, //IAD描述符类型4 P# p7 T( L( G7 G
- 0x02, // bFirstInterface1 S1 s \# \! f; q7 h+ I3 j
- 0x01, // bInterfaceCount
! z2 N& _- q0 r - 0x08, // bFunctionClass: MASS STORAGE Class1 G4 C, h( d/ S
- 0x06, // bFunctionSubClass
7 h( E' J# U! D$ g0 Y# b - 0x50, // bFunctionProtocol
; p9 y0 E3 K9 W - 0x01, // iFunction & K' E& e. m" I1 ]5 v6 y
8 K* H! S- I4 `. l$ Y- /******************** Mass Storage interface ********************/5 L* v4 |5 r8 `3 Z) W
- 0x09, /* bLength: Interface Descriptor size */
1 q' i! d+ ^; v* ]" m* D - 0x04, /* bDescriptorType: */' z0 R4 C- P$ y) M1 ?* @& ~
- 0x02, /* bInterfaceNumber: Number of Interface */
- Y+ a( d4 Z# l9 k0 x - 0x00, /* bAlternateSetting: Alternate setting */
% s4 U! l, S8 }( R0 O2 D$ X! ] - 0x02, /* bNumEndpoints*/
* ] f: I5 h. K* m% S% `% W" d - 0x08, /* bInterfaceClass: MSC Class */' E! p& `$ H6 P4 _0 z$ E o
- 0x06, /* bInterfaceSubClass : SCSI transparent*/
! }# B. v6 j8 [# H" ^" G - 0x50, /* nInterfaceProtocol */
1 @0 Q* I% s* [# G) i& M - 0x05, /* iInterface: */1 k* O; F) ?0 P/ b. f5 }9 q3 z
- /******************** Mass Storage Endpoints ********************// O' E O- a: A* I
- 0x07, /*Endpoint descriptor length = 7*/" k( n9 S* B O$ _! k. V8 u$ H
- 0x05, /*Endpoint descriptor type */
) a( B( }# q& o, U: t - MC_MSC_EPIN_ADDR, /*Endpoint address (IN, address 1) */
& a7 C' ^2 n' b& n - 0x02, /*Bulk endpoint type */
) [- o1 b9 h! ~: d( I8 o2 p- l; O - LOBYTE(MC_MAX_FS_PACKET),( d6 U' T! ^& Z( j. }
- HIBYTE(MC_MAX_FS_PACKET),; b, q$ I9 n$ x4 e3 {
- 0x00, /*Polling interval in milliseconds */: T. q U) b4 Y
- : c- S0 G. }) m( e
- 0x07, /*Endpoint descriptor length = 7 */
% i/ q, E5 c7 J" i3 V - 0x05, /*Endpoint descriptor type */
0 E6 A) J0 N& a - MC_MSC_EPOUT_ADDR, /*Endpoint address (OUT, address 1) */6 ~; o+ o. G/ ~( n; y' f& k- g9 `# H
- 0x02, /*Bulk endpoint type */, D% a) e" ?8 E4 w' z, m
- LOBYTE(MC_MAX_FS_PACKET),
; M; H" v7 c5 } X - HIBYTE(MC_MAX_FS_PACKET),
/ `6 I5 v* X3 J; v8 E% _ - 0x00 /*Polling interval in milliseconds*/$ z: j9 T5 t7 Y" G" g n
- };; r4 O+ n+ v4 W8 I/ A }
-
5 P8 N; B! K' k$ l - uint8_t USBD_MC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] =
2 l1 J3 [1 R4 e. Z/ I) x - {
4 T5 h# x# ]/ h& j9 y3 @3 _ - USB_LEN_DEV_QUALIFIER_DESC,
$ q5 u' j* V3 |9 O1 E$ T - USB_DESC_TYPE_DEVICE_QUALIFIER,2 G/ y& }# W/ W2 n* S
- 0x00,/ h6 E( H$ V& L1 S2 h. {( t
- 0x02,/ V6 F) J1 E2 V3 C: u
- 0x00,5 q" g4 l6 x* l* T
- 0x00,
/ b) b8 _, ?! T4 M - 0x00,
& s! F6 u# A; |. j - MC_MAX_FS_PACKET,
0 U% W. `, J+ ^ - 0x01,
+ V1 l7 V* k8 q9 L - 0x00,8 J3 k" {6 o+ j; N1 u4 W* l
- };8 Q' K( c- ^+ D s' f, \
- ! |3 o, N6 P% w Y: y
- /**1 ]6 f% @4 M' ?- w! k
- * @brief USBD_MC_Init
; k1 I h$ H' f, n& J - * Initialize the mass storage configuration
! b0 T* }- \2 G7 ~# S5 B - * @param pdev: device instance
/ ^# Q. i6 c' P! } - * @param cfgidx: configuration index
& C1 B( U, F; l/ a: ?0 Q - * @retval status
/ B* D; F+ N$ o! o- Q - */' X8 p W1 u; v1 c' c. N2 x
- uint8_t USBD_MC_Init (USBD_HandleTypeDef *pdev, uint8_t cfgidx)1 H- s5 }# j8 m* Q$ Q5 z! s
- {
- D2 N3 x4 w$ d. }% n x& P$ p) D - uint8_t ret = 0U;
! i/ J3 r, h, F1 R. R+ z! B( y5 Q - + Q- n3 f& B8 G7 w6 C6 z. W
- 9 i# d P& ~! c! @9 @# M
- USBD_CDC_HandleTypeDef * hcdc;
' x& }1 E# H+ [; ^ - 3 x" S9 b6 Z, b5 I; G* F
- MC_Switch_CDC(pdev);
6 Q' v0 g! R* Q; @ -
4 s/ ]& C2 G: a. c2 c/ ] - USBD_LL_OpenEP(pdev,
$ o# \4 e0 [8 | - MC_CDC_IN_EP,
[5 u* A4 G0 |9 ?/ ^ - USBD_EP_TYPE_BULK,$ T& A1 q/ A' {/ N7 P1 J0 O7 w5 b* [
- MC_MAX_FS_PACKET);5 o& K- ]. U1 L1 J- m
-
" z& d1 U5 Z+ b7 _! Q - USBD_LL_OpenEP(pdev,+ Z0 F5 W; k' \1 d; ?. @' c' s, D0 V
- MC_CDC_OUT_EP,
$ l3 B3 J& M# v - USBD_EP_TYPE_BULK, I- q, y5 W* G4 R( T/ G
- MC_MAX_FS_PACKET);7 D2 W' x4 {/ g$ n5 B6 F
-
# Z q5 A& `$ b- d7 m% r - USBD_LL_OpenEP(pdev,
8 j! K) ^. s: @6 p: K$ z% Q - MC_CDC_CMD_EP,6 b& ` F& A* s1 D
- USBD_EP_TYPE_INTR,
+ d5 X4 _0 |2 g3 o - CDC_CMD_PACKET_SIZE);) d" A M* b. m/ r) {9 v {+ t* e
/ Y! S9 O, n6 y) w) ?5 x# b& g- hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;/ {8 z4 s8 b4 ?! h- h
$ n% u G7 Y1 w# c8 u- ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Init();6 n3 i7 g3 Z7 ]2 D
- $ F9 v: W6 v7 T- D# m: \6 H0 h
- hcdc->TxState =0;9 }# K# |. p$ E) V. e( m
- hcdc->RxState =0;* }2 |, ]% V. x# F& y& G
- - a' @. s0 a: B6 K
- USBD_LL_PrepareReceive(pdev,3 O) V. c" ?8 Z5 w- Q
- MC_CDC_OUT_EP,0 I; O K$ x8 t7 F7 o; o ?" K# J" N; C$ N
- hcdc->RxBuffer, G$ M3 C* M0 Y$ o
- MC_MAX_FS_PACKET);$ x! C: q9 |) M* B& P6 w N
1 V9 D. V' w- h+ O0 E5 ]- pCDCData = pdev->pClassData;( \0 n* X- a( x& s
- . c0 S- l) ]$ x" B6 \7 x
- MC_Switch_MSC(pdev);$ h- W) J. d: {: ^+ Y5 ~
-
2 \' {% a- R) Y- C) F - USBD_LL_OpenEP(pdev,$ J) o( D/ e6 [$ `
- MC_MSC_EPOUT_ADDR,
& u! g/ ~; S2 U: Q( `+ z - USBD_EP_TYPE_BULK,1 M( Z$ X% }* B: G
- MC_MAX_FS_PACKET);1 C9 r* i3 H: I. Q0 n4 M ?
- 1 b* |/ ]2 K- Q" j
- USBD_LL_OpenEP(pdev,
- n9 |7 w8 |$ L - MC_MSC_EPIN_ADDR,
' \; T0 H' f3 y V - USBD_EP_TYPE_BULK,
( K, I/ B# w: K% ]; a, ? - MC_MAX_FS_PACKET);6 k+ u) m W- p& s
- 9 F9 v |1 D- f4 N3 ? z1 c
- MSC_BOT_Init(pdev);) r6 n/ T; S+ K! c: N( B% L
- 5 m! G5 n0 `5 O0 a! Q1 i/ X
- pMSCData = pdev->pClassData;
4 H# @4 G$ @( `7 t1 ~7 S - 4 L J9 E% i. F/ e' K! F" j
- if(pdev->pClassData == NULL)5 @3 _3 z+ v Z
- {4 ]+ [$ Q3 \5 l o$ Z( n# q
- ret = USBD_FAIL;: G0 h2 R5 ~6 Q1 @
- }
* { ]; l5 |5 Z" ^ - & U* K/ V0 ?# R1 ^; [9 _8 L$ z+ G& a
- return ret;
6 f: z* V; T* C - }4 O2 a* d! @. B7 }! s4 R
- / U. t! H n& @: @: A' x
- /**
8 C/ W6 _9 J7 C; \( Q( a - * @brief USBD_MC_DeInit
& s/ v! E; U2 k2 \4 m3 [( h - * DeInitilaize the mass storage configuration. D9 s/ |, k) R. j; ?. {6 | r
- * @param pdev: device instance. g0 I5 \) d p8 C9 c
- * @param cfgidx: configuration index1 X9 I* M* {% N
- * @retval status
: E9 U! |$ N$ q+ v! K. _8 \ - */
8 @6 V7 b2 _, T/ ^7 I - uint8_t USBD_MC_DeInit (USBD_HandleTypeDef *pdev, + Q- i6 G2 u5 z- m. M
- uint8_t cfgidx)
1 F' n/ d9 S) v l/ Y2 D; I0 R - {8 m0 ?' {: w! |/ J9 [7 l a" B. _
- return USBD_OK;$ T" b3 R) X4 ~# q1 u! X
- }
5 }3 S4 I' E/ z$ i - /**
9 P$ W1 Q; V/ V3 o' N2 n4 j: F - * @brief USBD_MC_Setup
0 Q' L8 b8 M' E; d7 p( g - * Handle the MC specific requests
9 h( Y1 O5 m8 E6 C5 Q7 h/ f - * @param pdev: device instance
8 S: }, `" Q7 Y7 h7 O1 i - * @param req: USB request
) _3 C9 f1 r# O% [ - * @retval status
% r( `: o3 H" X. r* ~5 ] - */% V8 x/ _1 W8 h0 b# {5 f' n
- uint8_t USBD_MC_Setup (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); U0 f/ v; d; H5 a ~
- {' l" k1 A) z n& E; ~ u
- if(req->wIndex == 0x0002)$ L1 T$ u+ f2 l& [
- {
7 _, u" D2 j, U+ T4 I1 _ - MC_Switch_MSC(pdev);
3 `. l, P* n3 t7 V - USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef*) pdev->pClassData;
7 c4 u6 T- V- e5 A4 N, ~" i - 9 X+ A5 @; K- H, U
- switch (req->bmRequest & USB_REQ_TYPE_MASK)
) A3 R5 k2 \8 p, Y - {
/ ?0 W# B+ H/ G3 p/ Q - * R! D( t- E6 H5 n% p2 U! r( [
- /* Class request */
4 ?% v. ]6 l1 Q9 }3 c) U( w - case USB_REQ_TYPE_CLASS :1 e0 F2 i* ?7 Q' o J f" z
- switch (req->bRequest)
$ o3 O5 b( \2 ~; b1 v - {
7 U7 }* r8 f2 d! I6 ^; o - case BOT_GET_MAX_LUN :/ P0 m- U3 i( G
- + `- D5 x/ X# l9 s0 Q
- if((req->wValue == 0) &&
) Y9 ]$ F- I" x8 g" f+ R1 T: [' V - (req->wLength == 1) &&2 _9 [2 Y" x* O0 i9 y
- ((req->bmRequest & 0x80) == 0x80))
2 J5 F4 U2 i8 \9 {( i J0 C" j; j; I - {( ^9 A( n6 y. O0 ?# G3 X
- hmsc->max_lun = ((USBD_StorageTypeDef *)pdev->pUserData)->GetMaxLun();
3 |0 Z! T% E& w \* s! l - USBD_CtlSendData (pdev,
& o- g }% A9 `! {9 B - (uint8_t *)&hmsc->max_lun,9 l4 L1 ~0 _" R# I% l7 g5 D
- 1);. Z$ T( I' f. Q U2 _
- }
2 O$ A0 k+ @5 f& F% p* m9 X. h - else
) e3 s* I- l: @' q' W. ~; I - {. }, A; y- K8 {9 J6 d3 M
- USBD_CtlError(pdev , req);. x& C! e5 o; D) f
- return USBD_FAIL; . y4 ^7 P1 ]2 R% u0 k/ l
- } s/ a* C# |+ o; [
- break;: h, C( Q& v6 t
- 2 i" {2 s0 K+ @, _1 H# X
- case BOT_RESET :2 v% _7 K7 D/ Z2 \8 }( z
- if((req->wValue == 0) &&
5 I/ W+ q t# d - (req->wLength == 0) &&
7 _+ q5 o) ^6 L* r: o& h - ((req->bmRequest & 0x80) != 0x80))" s+ e7 V6 M: J5 U; @5 Y
- {
! q6 }' x: t, C8 C - MSC_BOT_Reset(pdev);4 @& a3 Q: F% q' ~: j! i/ b* @' f
- }* ?, r- F- @2 [$ R
- else
/ h% h, L, Z/ [ - {
2 T2 P& R ~! z' K/ G! ? - USBD_CtlError(pdev , req);$ ]& `! Y" O0 g
- return USBD_FAIL;
}2 c0 F" ?" Q+ {0 B, y7 k! l - }
# A+ o& @! F; T5 x: x4 e - break;
% ]! ~5 V! q4 B- S
& Q9 f7 m3 Y& _9 c: A7 R- default:
) V* @3 @: z' E+ j - USBD_CtlError(pdev , req);9 N, E1 v* V! H* W$ G% r) g% f8 k2 Q
- return USBD_FAIL;
- [: @( p$ U: I0 U4 g8 Q9 J& x2 }$ c, ` - }. |( d3 k8 [1 T- l
- break;6 K' A( [* b: t( [
- /* Interface & Endpoint request */) ?& C" v3 I( H; `4 o/ H4 c8 q( A
- case USB_REQ_TYPE_STANDARD:
; T; _! i/ _/ w" r4 r - switch (req->bRequest)
5 z/ \+ z! g" e( {$ r. a. B - {/ q y# w; P4 y& G
- case USB_REQ_GET_INTERFACE :
: O& a% B" Z9 R: n6 _8 Z - USBD_CtlSendData (pdev," e1 m2 F& N! v
- (uint8_t *)&hmsc->interface,
% V, A, l+ {1 v7 i' a - 1);$ j* [6 G; Z2 d9 }
- break;
' t. e+ x0 t! H* c2 h$ X$ g0 ^ -
6 m4 o6 W$ Y6 a- k - case USB_REQ_SET_INTERFACE :
, n1 h5 Y+ S9 A% S& h - hmsc->interface = (uint8_t)(req->wValue);- i% R- t/ T$ W3 R
- break;3 o, m5 S- h& j8 f' B% B5 Y6 D
- 9 P- L* N! A6 |
- case USB_REQ_CLEAR_FEATURE: 5 M( z9 Z5 q4 p$ C
- 9 G! [1 [3 a. |/ Q7 X' x- [! s
- /* Flush the FIFO and Clear the stall status */
9 r+ c- ?- I' F - USBD_LL_FlushEP(pdev, (uint8_t)req->wIndex);
9 V2 c# m5 Y/ ^9 y7 l9 F% d* W/ ~' b2 ? - 1 K4 m/ S5 g2 W- r- G5 a
- /* Reactivate the EP */
$ _* c7 ~: W$ r6 s3 l/ A, I3 e - USBD_LL_CloseEP (pdev , (uint8_t)req->wIndex);$ }1 `- _2 i9 E! O) w
- if((((uint8_t)req->wIndex) & 0x80) == 0x80), H6 r5 w: @" E* ~+ [0 b- b. D! ?
- {
9 F5 \" f$ L1 n1 E: U+ i9 Y - if(pdev->dev_speed == USBD_SPEED_HIGH )
7 e1 q) I+ [2 O- H. d - {
6 ]' M- D1 c/ ^* z- v! D' W1 C - /* Open EP IN */
/ K/ J# J# ?, V' I8 H - USBD_LL_OpenEP(pdev,. N" Y* I/ t) p& A
- MC_MSC_EPIN_ADDR,. M7 X5 p; D- `9 B' y! ?; s# a! ~9 p
- USBD_EP_TYPE_BULK,
+ A9 Q O( x+ ]9 O2 a& k - MSC_MAX_HS_PACKET); ; X5 G) T8 u# G" G, S
- }
1 [& N t5 W/ c: ]5 m6 ] - else
& x) q9 t/ {( A) d - {
3 d- Y" X% h9 d2 K* w2 y - /* Open EP IN */
+ A9 Q* a! \* w$ r) q. o - USBD_LL_OpenEP(pdev,
8 R8 S2 J/ X. U5 v/ `6 K) {" S/ ] - MC_MSC_EPIN_ADDR,
; m/ R" |+ @8 |/ M! a6 N - USBD_EP_TYPE_BULK,
- f0 J5 ?; L3 H0 M3 I - MSC_MAX_FS_PACKET); 5 G/ U8 ^& T" q5 h e
- }) y! u" W" H* e$ O8 X c
- }- P' D3 M0 ^& |" T5 n9 C( q
- else
7 ^8 ?2 R. [" F3 F - {
: U1 l" Q3 c+ i# N - if(pdev->dev_speed == USBD_SPEED_HIGH )
% k& Y, V$ S- ]$ L+ L4 `+ t9 `. S) r - {
6 G, f3 g) z. i( m4 |$ G - /* Open EP IN */: W V; [: `( Q4 q! A
- USBD_LL_OpenEP(pdev,- e6 n$ k! h: P2 y$ M1 T& R
- MC_MSC_EPOUT_ADDR,
- b5 _, D/ Q) |1 B/ s - USBD_EP_TYPE_BULK,5 h$ V% s( Y" H( S* p4 ~% m9 I
- MSC_MAX_HS_PACKET); 2 @9 K+ D% ?5 r; z0 ]5 f; Q# t& J1 |
- }
6 ]0 W& {7 c) w, L+ f i8 B - else
* N* ~' K) X; q) b! U - { 8 P0 t4 z4 x! l0 l# L! ]9 m
- /* Open EP IN */* k$ ?9 d- E/ \3 F3 Q! t: X
- USBD_LL_OpenEP(pdev,
: w' c9 Q, l" q2 \' | - MC_MSC_EPOUT_ADDR,& N7 U9 K" |- L8 `% k" x5 v* p
- USBD_EP_TYPE_BULK,
' g- |1 h: b, o9 R$ J - MSC_MAX_FS_PACKET);
" V1 t3 i2 e+ V* x - }
) x& [1 \( R# n2 S - }+ i3 k2 v* \' Z7 V
-
6 `% M; K+ C# \! a - /* Handle BOT error */
6 C* R5 T, }4 o' N' i) o4 [ - MSC_BOT_CplClrFeature(pdev, (uint8_t)req->wIndex);3 _1 j& L6 A% P1 W6 [
- break;+ H! R. W* u6 o1 c+ ^
-
2 E# o% q6 F" ]! `3 b2 @ - }
4 j" p. x8 t; C4 ~! g - break;
, _9 t6 Q6 B# y& {8 Y -
+ K' ]) V/ n) B- G2 G P$ j1 D: x l L - default:
9 \ _# U3 t" K9 q) P - break;8 ~/ ~& I2 Q) _7 J/ m
- }
& c1 D+ k* R! o% J - }' A: G* @7 ] f% E
- else
! d$ ]+ Y9 z5 R! Y2 O3 m. S - {, L; \8 X1 b, D: j
- MC_Switch_CDC(pdev);
1 I! T/ ?" D% a/ r& D5 `7 r. Q - static uint8_t ifalt = 0;
( t6 v7 c3 `# v6 k6 X$ q0 M - USBD_CDC_HandleTypeDef * hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData;
+ Z5 N4 c3 F9 \; \; P; U - # c' P3 Y9 _( k" H3 S
- switch (req->bmRequest & USB_REQ_TYPE_MASK)
" r, c1 O. G3 m2 } - {& x" \3 Q5 N2 j' f# S- d
- case USB_REQ_TYPE_CLASS :& @' d' ?3 D8 K6 k* s" x* @ M
- if (req->wLength) ~$ E3 h, F! m! k- J
- {" N& }- |% d, s
- if (req->bmRequest & 0x80)
7 j$ u( n4 C- m7 b/ S% m1 p - {
6 D4 J L4 D% d. ^- `1 {* r. T8 Z - ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest,
6 U! ?1 t8 W* q: W& V - (uint8_t *)hcdc->data,
+ f& u g" V- w6 E - req->wLength);
, c& L$ } f7 E" A4 A - USBD_CtlSendData (pdev, 0 ]3 d7 W- i, E; V5 N
- (uint8_t *)hcdc->data,
7 c$ k3 ?+ e/ i; X- Z1 ~ - req->wLength);
+ s7 `" O+ j3 X4 z* T5 H - }) p4 L3 e( R2 B2 M' ?' @4 c
- else
$ {4 S( c3 l- O1 Z: b9 [ - {- P5 Y: s" _0 Z* W8 |0 R* T" o7 k
- hcdc->CmdOpCode = req->bRequest;
1 O5 O6 y1 l0 e, k5 S - hcdc->CmdLength = req->wLength;
* Q; D5 @) v+ W& \* K: | -
# ]; p+ X8 v+ R2 Q7 v( [" N8 G$ R/ M - USBD_CtlPrepareRx (pdev,
5 n6 M- u* U) r - (uint8_t *)hcdc->data,& e" _2 `" ?4 J$ I: \4 `
- req->wLength);
% C. Y! c+ T! g) Q# m; s - }
5 i6 o3 R# A+ a7 s1 w - ( b( {: {( h" x2 O* S5 B
- }( y7 X. \ t5 Q
- else. B3 g' X: ], d6 r1 ~7 d, c
- {
. l1 X8 D! p; m: N5 o% F - ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest,5 C G* X1 }) f4 L( g
- (uint8_t*)req,
! Z3 y! u! R/ x, E3 D/ r - 0);
6 C' x9 n5 v3 y s/ T& ]" X! H - }
5 T& J( x& N$ G* ^+ V4 M - break;# `$ V* S9 x# n* }" n) G6 ?& X) c6 W
-
6 X& Q$ M x& e# Z9 i - case USB_REQ_TYPE_STANDARD:
8 g! _% Q# m$ W4 N! U+ H - switch (req->bRequest)
7 Y: j) K" h6 A" T2 }4 U$ f - { 1 `. m9 ? h5 v; x1 w/ |8 u
- case USB_REQ_GET_INTERFACE :
0 R: T6 C- y" }$ n; D$ W% t - USBD_CtlSendData (pdev,1 \1 f" r a! R; @0 R
- &ifalt,
4 p, X: O$ g" ?* h7 n - 1);
0 {1 J) L _% g( t" ^ - break;2 D1 a* M& W3 J U9 d
- 3 `+ H" }) K* z
- case USB_REQ_SET_INTERFACE :5 ?: O6 P; P' M( J
- break;, I1 H. \" c! x6 ]
- } {+ x. i! @. I" i9 A2 I( ]
-
/ [' y! r( s- a* N - default:
. R% a% V1 Q( m U" }: o - break;5 C+ X' N3 ~- m: W$ @8 q4 A
- } ' ?9 Z9 G5 J. b( w- |' u
- }7 g; W, w& _3 A8 l( _6 u# p
- 4 }- w" W* i/ H7 M) J$ j
- return USBD_OK;
; J/ K: O2 e) e- U' y - }
. @: O/ e6 P3 x6 b - 3 d9 O: s$ ?6 x3 Z
- /**; p% f5 s2 R+ O8 H y' \5 N2 x
- * @brief USBD_MC_DataIn
4 b1 m5 U2 t, Z" Q9 f0 o - * handle data IN Stage+ Z0 m/ }& H+ Z- d$ N4 a! k) E
- * @param pdev: device instance9 h: }4 w ]/ a' p& i" g D- g+ s
- * @param epnum: endpoint index- }4 u+ ^, i5 K
- * @retval status3 `1 j; z( Z3 G7 u0 ?7 Z
- */$ Y4 t9 j3 d: Y: g; Z& K+ p% y
- uint8_t USBD_MC_DataIn (USBD_HandleTypeDef *pdev,
. P& `* [1 x. ^6 Y - uint8_t epnum)9 E7 K& | e B3 y1 v$ V
- {% M$ @/ T" f; H: S4 d
- if(epnum == (MC_MSC_EPIN_ADDR & 0x7f))
4 m" N9 I: r: g Z7 M# L - {
8 C9 H3 \/ m) }" w: M8 A - MC_Switch_MSC(pdev);
/ h5 t% A+ k) F& t+ x - MSC_BOT_DataIn(pdev , epnum);& D5 z- G) o" \6 _4 b9 t1 U
- }
0 |3 M! ?1 q7 M! k; l& G - else if(epnum == (MC_CDC_IN_EP & 0x7f))) u1 Y6 @( ], U4 Y
- {
2 x. F$ U# C+ u* g" S$ C2 ^( a# N - USBD_CDC_HandleTypeDef *hcdc;8 a- @ Z0 g D9 p; |
- ! B1 c1 M" |7 g+ d; S2 l/ j. D( v# s
- MC_Switch_CDC(pdev);# z- }6 O x) Y5 t7 G
- hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;8 }8 S) y4 h" l+ W, p0 `& w8 n
- hcdc->TxState = 0;
8 I5 z3 F: U- k3 j9 Y8 V - }! k- M u$ o7 \. ?! Z# P. ?/ U
-
: f1 c1 W& J0 f6 z" W - return USBD_OK;
' f, N6 o& a- E U% m - }
" M2 z* _7 l# H' ~4 Y - ) D7 ]9 U# p1 u5 ^3 [
- /**( y+ N9 {, [8 M( o9 g
- * @brief USBD_MC_DataOut+ I7 c0 g6 W n6 ?6 t
- * handle data OUT Stage$ @: L5 R5 v& y/ |
- * @param pdev: device instance
7 J; N+ g3 f+ [* d9 I - * @param epnum: endpoint index' Z& N7 U( B1 D+ {# P+ p" f
- * @retval status
. o. r* \7 b J2 q& q4 ?& @ - */
: l$ `. f+ X7 Q/ {" z2 V: S" c% ^6 L - uint8_t USBD_MC_DataOut (USBD_HandleTypeDef *pdev, * ?% Y; U1 Y0 ?# c
- uint8_t epnum)! b$ @; d0 `/ @8 S& B, y/ K; \" M) M
- {+ o; l c1 a D7 |5 V
- if(epnum == MC_MSC_EPOUT_ADDR)
# `) V" `. m. \( c, {6 @9 s - {
4 O3 q4 b6 _$ | - MC_Switch_MSC(pdev);
# ~: q2 x3 e- V& d _$ \& L# j - MSC_BOT_DataOut(pdev , epnum);
" @$ H1 s2 i9 R7 w; R6 y - }5 Z7 q6 B3 o. \
- else if(epnum == MC_CDC_OUT_EP)
- s+ z, f% l# ]' ]) M s# y - {2 [5 d6 ^5 A; J6 o+ r/ N+ J" ^
- USBD_CDC_HandleTypeDef *hcdc;, \4 `2 A: U2 x5 c1 [' _( E
-
. n3 H% j6 M6 Q% g7 i0 P8 f7 _ - MC_Switch_CDC(pdev);& V2 P; ?( l. E- @5 O) y
- hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;7 f$ t k m" k
- 8 H8 V4 D2 S- E/ m
- hcdc->RxLength = USBD_LL_GetRxDataSize (pdev, epnum);
, y- y9 |, h1 }; A# R x0 i - ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Receive(hcdc->RxBuffer, &hcdc->RxLength);
* C! F. F/ i# X - }
& U( B: z# V" Q& d' m6 Y5 J - 4 t- Z' I+ T/ o$ I' U. r
- return USBD_OK;
3 C) F" k$ ?: @7 r - }: l7 [) p% c: b) \6 \4 K# y
3 g! D% K* \- W3 O- /**9 f3 E$ v1 ?& K' z" n
- * @brief USBD_MC_GetHSCfgDesc ; S4 u* S+ x; z
- * return configuration descriptor
5 z+ j) J# Q% J7 [6 }( v - * @param length : pointer data length
" C: H* Z9 A: M0 O! i - * @retval pointer to descriptor buffer$ H' d& N8 b) d# P2 ^& U8 [/ e/ g
- */
5 S7 V4 w1 x7 m: R% Q - uint8_t *USBD_MC_GetHSCfgDesc (uint16_t *length)
, ?$ m) }, R3 Z* O3 C6 L8 t# U0 T - {
* g7 S9 I# ^8 ~' [( t9 p - *length = sizeof (USBD_MC_CfgDesc);
" I7 A) h+ L5 t# q. Q, z - return USBD_MC_CfgDesc;
6 W1 j& H5 I0 q* l4 ^ - }
2 L# I E2 g& G2 O. T - + ^* w: v. @" x% ~
- /**' @; X D+ W. d9 {: Z( R. ~, D+ K
- * @brief USBD_MC_GetFSCfgDesc 2 h; z# E7 _' X/ j
- * return configuration descriptor! ?- D3 D% {. d P7 Z/ V0 ^ \
- * @param length : pointer data length- u. p5 f2 y0 U* c, l# q& }
- * @retval pointer to descriptor buffer
+ ~+ j3 M6 Z9 L6 d6 |+ l/ B - */% c1 [( E' F. d0 U$ R
- uint8_t *USBD_MC_GetFSCfgDesc (uint16_t *length)
, O. h" s, C: o* E, [ - {
+ k4 V* }- u3 m7 c, P% s - *length = sizeof (USBD_MC_CfgDesc);- L: { \. j9 H
- return USBD_MC_CfgDesc;- |, J1 l0 s! Z/ v8 G7 y
- }
" D, c( i, N; Y) {" z5 T" b
/ R/ S: x1 Z! \* N/ W U- /**8 u! i( V- U) U. @4 L
- * @brief USBD_MC_GetOtherSpeedCfgDesc
$ m# m7 }: F( B0 Y' F - * return other speed configuration descriptor
8 k1 H+ O3 _) @4 T9 o: q - * @param length : pointer data length
$ h4 p; _* Y+ Z. Q) C# | - * @retval pointer to descriptor buffer
/ e, ~ i- O& h - */- g+ p; }9 ^% f) j6 b! q! t
- uint8_t *USBD_MC_GetOtherSpeedCfgDesc (uint16_t *length)
( q$ h0 V2 v2 t$ G3 w - {7 q1 c. ] E) X% ~
- *length = sizeof (USBD_MC_CfgDesc);; q5 {7 R0 M, g' F% s
- return USBD_MC_CfgDesc;8 V, a+ V9 `0 e4 \+ C5 _
- }
& {" \0 _" g% W, \ - /**
' D4 ~! ^* Y7 x - * @brief DeviceQualifierDescriptor ' y8 r q7 G6 J) N. G8 x
- * return Device Qualifier descriptor
4 c1 g# B+ I7 |7 p3 r - * @param length : pointer data length
+ \6 J+ v) T( ^ - * @retval pointer to descriptor buffer8 v z7 x: d A, @9 k4 c
- */
+ D5 F% W" C0 b5 g - uint8_t *USBD_MC_GetDeviceQualifierDescriptor (uint16_t *length)
7 q/ c; s5 _, k5 A; r5 b+ B8 A - {$ J' r0 Y6 c* I7 q
- *length = sizeof (USBD_MC_DeviceQualifierDesc);
% H2 o" j" Y. H* Q - return USBD_MC_DeviceQualifierDesc;9 n. D: b5 r! [# ~4 N
- }
) E0 `) K2 t9 } X+ h
; _6 }+ B0 A. @/ D. ]: Y- /**5 N' Q* P2 s# K) Z' x- I
- * @brief USBD_MC_RegisterStorage
0 t6 a% d% U/ }% c4 h4 _ - * @param fops: storage callback' }8 [* ]3 z$ z4 S0 R) B
- * @retval status2 r3 S$ e; O* s8 C) E
- */
7 f. m9 ^' ?, m, s4 c( w. { - / |0 t) v7 V2 f3 t1 z9 g
- static uint8_t USBD_MC_RxReady (USBD_HandleTypeDef *pdev)
; k( l. A( [5 b! F/ y( \2 E - {+ @. Z1 ]8 ~! o8 D
- USBD_CDC_HandleTypeDef *hcdc;
3 T# ?5 H9 O. b0 ?2 z - ' \% R/ I2 F* G# T
- MC_Switch_CDC(pdev);
+ i$ _7 O; ]+ h: e9 c - hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;& y& W% J, I% l) f7 t
- $ q( {" v; Q# e( r0 d
- if((pdev->pUserData != NULL) && (hcdc->CmdOpCode != 0xFF))
3 J) S- v) ]" F8 t9 P2 }" I4 Y - {
a* |& {7 G) ? - ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(hcdc->CmdOpCode,: t2 Q- S t9 s+ M
- (uint8_t *)hcdc->data,
5 i5 D" J2 K9 R4 U - hcdc->CmdLength);. w6 \' J3 r- U' ~3 K
- hcdc->CmdOpCode = 0xFF;
) f4 q' a8 G( @9 c - 0 E9 T4 b+ I3 s( m
- }
0 ^6 G5 [, j% j" \7 a" A. e) R0 S - : U* P* m3 y0 c% b, J# p- E
- return USBD_OK;2 {# H+ O8 H, ^2 a& {4 \
- }
2 t# M) X# t, J0 I( l# B - 4 I* |/ o# z/ ]- E
- static void MC_Switch_MSC(USBD_HandleTypeDef *pdev)( q( G) T' R1 {; \
- {
- p* j! d& G. L: K - static USBD_MSC_BOT_HandleTypeDef msc_handle;
0 i) n) [1 D4 K8 x7 e. m -
' ]1 t( `. F1 z, O! K; u' H/ k - USBD_MSC_RegisterStorage(pdev, &USBD_Storage_Interface_fops_FS);
# ?3 r& {( ^5 O% E' y9 {$ f& @ - pdev->pClassData = &msc_handle;
K9 G) o6 C# ]3 E7 u" p8 d - }8 v; f4 m' b: O: N% s) {
- 9 W5 @# i6 Z, k/ I; S+ i. v" A
- static void MC_Switch_CDC(USBD_HandleTypeDef *pdev), A) i( I7 s% S6 f% y% ?
- {/ ?' f3 M5 q& S s$ q3 ]2 f
- static USBD_CDC_HandleTypeDef cdc_handle;
' i6 S! g3 c/ H/ l( Z6 } -
( l' J9 G; T, b: F# X3 v - USBD_CDC_RegisterInterface(pdev, &USBD_Interface_fops_FS);$ {# j [/ e% q9 [' {7 M( y
- pdev->pClassData = &cdc_handle; n8 t8 e4 X: G) w# r; j
- }7 p# U8 O# S% |( ^! F+ E+ N
- ! ~7 ?; e Z( G* v# X4 v* u9 ~
- /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/* l! K& X+ t0 n# J
复制代码 ( P: e( P# r5 m0 \* G* @6 u7 |; m
通过以上修改后电脑电脑端显示USB复合设备MSC+CDC; L% u' J5 H% V9 |- U; r6 _
5 u ^% Y$ ~- T8 `
4 j8 @, [) b$ X4 |0 W13.在usbd_cdc_if.c CDC_Receive_FS /* USER CODE BEGIN 6 */ 增加发送测试
7 y/ s# \- p1 f' E+ a# W% C: ~/ t+ M- K; S) j# v0 ?
- static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)
: z& v) R+ W# [; G - {: T, m2 \! t; \, ^" n
- /* USER CODE BEGIN 6 */( \+ O1 L6 D' R+ A$ {# G" t
- USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);! y5 {; @- i7 S# U- S0 z; \/ Q
- USBD_CDC_ReceivePacket(&hUsbDeviceFS);
% Q& }* A$ p* C$ _ T - 1 V! U( B. [+ R' v' w) N% k
- CDC_Transmit_FS(UserRxBufferFS, *Len); //把接收的返回$ i0 u; S5 t" d% f$ w( h. [
- y% q' {8 r5 T2 h3 c
-
' d X5 k* A7 _4 D; I - return (USBD_OK);* ^5 i" ^4 E" o0 r3 o
- /* USER CODE END 6 */) s2 `, W8 S6 @1 j# G% U
- }
复制代码 * m9 D2 r0 N, p/ ~4 B+ G0 N
测试串口收发
+ h X% a$ V3 |7 E
( ?2 J5 `0 f0 `0 f$ s9 o
& Z9 R9 }/ E3 Z6 I5 `
! ^% Q% ?. H- E* `! q% d" W
1 c$ d; b3 t0 A% B0 j3 m1 p; {6 j8 X8 Z; ^1 Q. q
|
希望楼主多多分享,赠人玫瑰,手有余香,念念不忘,必有回响;
是不是驱动问题,我电脑Win10
void *USBD_static_malloc(uint32_t size)) ^3 q7 q; J; L% K2 [, I$ B
{) K' @3 R0 r4 H# X4 @; A0 \ W
static uint32_t mem[(sizeof(USBD_CDC_HandleTypeDef)/4)+1];/* On 32-bit boundary */
return mem;
} a, R2 K2 }* R, V; _ ?% Z
5 U" Y2 `. q9 D G
那么在组合设备中,USBD_MSC_BOT_HandleTypeDef和USBD_CDC_HandleTypeDef都需要申请内存,怎么操作?7 |( s& Q+ `* @. P" }! D7 r% \! n0 D- d
有可能是函数USBD_static_malloc的问题' i; c0 a! [2 u2 }& H" d" }