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