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