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