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