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