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