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