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