你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

基于STM32的USB程序开发笔记(四)——USB设备的枚举(上)

[复制链接]
乡村布拉德 发布时间:2008-12-23 12:12
USB设备能否工作,枚举步骤,用“乡村爱情”里的话说,“必须的!”,网上也有很多资料,圈圈就提供了一份详细的枚举过程,但对STM32是怎么响应的没有说明,一会详细道来,先上圈圈的提供的那个枚举图示,希望圈圈支持,如果不妥,请与我联系,谢谢。
1 G' r! ]" e' ]/ h我将此转换成了PDF文件,方便查看。8 l: ~2 }9 j2 P" I: D0 C
首先说明一个变量,定义在usb_core.c中:
: p0 a$ u4 Y0 P% u# C  W& |) fvolatile DEVICE_INFO vsDeviceInfo; ' J  ]& s; |) L) J& M7 A5 M
看意思就知道他的作用了,DEVICE_INFO是个结构,定义在usb_type.h中:
; p1 C8 z: R, M3 m! L// ***************************************************************************** ( D3 }% y: F+ |  t4 X( h% O
// DEVICE_INFO
& q( k- \1 D1 i( f6 n" G/ S2 h// ***************************************************************************** 2 I. Q3 z$ v+ D& z1 ^/ \, ^
typedef struct _DEVICE_INFO
" a7 t' N# g# q{
0 R8 ^  h9 l: ^. O! H+ u* I8 r  unsigned char bDeviceAddress;
1 l/ \5 y7 z/ p$ ]  |" H9 b1 K
  unsigned char bCurrentFeature; $ u3 J! q. i, h) ?0 u8 V
  unsigned char bCurrentConfiguration; % m$ p7 t! H) T0 y
  unsigned char bCurrentInterface; ; ]! ?& a1 N5 A, ^
  unsigned char bCurrentAlternateSetting;
8 q/ k* X3 a( \/ W1 S* a( s7 o# P' M$ N0 X) e9 Y2 l7 w0 s+ S$ ]9 S1 g
  WORD_2BYTE    uStatusInfo;
1 T7 ^9 F9 b( m# ?/ @2 K/ K# A/ j  H' ?0 A2 V
  DEVICE_STATE  eDeviceState; ( g0 w, E9 _4 L6 W
  RESUME_STATE  eResumeState;
- C' ?4 C4 N5 @- [$ L  CONTROL_STATE eControlState;
" B5 k: |4 @9 U9 D# `; ~- K0 f
9 f% M+ d- A- b/ ]  SETUP_DATA    SetupData;
6 K6 B9 U' e  A
" R8 e, q9 h3 [6 Z  TRANSFER_INFO TransInfo;
9 D! p9 \! q) _}   i$ z4 d) B+ j3 ^- P
DEVICE_INFO, 3 t( Y0 g6 F0 V- L# h
*PDEVICE_INFO;
3 z. G. _6 {- F" P2 Y7 ]
& e+ a! V( P: q/ u. t在枚举过程中,就是如何处理好SETUP事件,如果STM32 USB接收到正确的SETUP事件,将响应函数CTR_SETUP0(),SETUP事件是特殊的OUT事件,数据方向 Host->Device,SETUP事件数据长度固定为8,数据定义在DEVICE_INFO.SetupData,其数据结构是(定义在 usb_type.h中): & m4 Y0 ^4 q. D, m: |7 C, v$ u
typedef struct _SETUP_DATA
( |& C$ h* c2 i) O{
: U) h$ V; X/ ^" h/ t. N9 f  unsigned char bmRequestType;            // request type " m3 k. V/ T8 D- k' o( A% q, F4 c  I( F
  unsigned char bRequest;                 // request code
' w4 V0 H4 P' j& ^' {* v1 ^4 f2 d# M% k' F
  WORD_2BYTE wValue; : J8 y! v0 o" U' V
  WORD_2BYTE wIndex;
; @* M- g. M- K2 M( q& R  WORD_2BYTE wLength;
+ y6 v) P: G' {( [}
) B7 e9 \, U! e* U+ z7 J) tSETUP_DATA,
6 R9 w  d' ?1 F7 d*PSETUP_DATA;
6 G5 [8 q3 a8 u! c
& J) j' U* |! yWORD_2BYTE是定义的一个共用体:
" [& ~0 E" k$ D. Z$ c( |; k( ^typedef union _WORD_2BYTE 2 p. u8 w7 J' B! o  G3 `8 `( O
{
1 I( p" `6 b9 M" [  unsigned short w;
' c4 K. z/ A- I9 Q/ e% ^  struct
( ]2 ?+ ]7 _1 F* k. v  { 9 b* I1 O1 ]$ l$ L2 x' M0 b
    unsigned char LSB; / H. q! p& V) e
    unsigned char MSB;
; B: M; ~  O5 C; A% X  }b;
7 [- h% B$ L5 L, b5 u7 N2 B# q}   Y" Q! \" v0 ?3 E0 p% G
WORD_2BYTE;
6 j4 U/ X  i; \$ n  g: d! l0 }6 n- N$ ~6 O1 O
为什么将SETUP数据结构中的wValue,wIndex,wLength如此定义? % i$ j8 T% `: @! ]2 C4 [% L5 c" [3 L
1:USB协议中所有数据传输都是依照低位在先的原则 0 C7 X8 r0 f+ i5 S) o) S
2:高地位字节可能功能复用
+ G8 S" z  l. P- t/ a* _& Y这样在后续的程序编写中就变得十分方便,ST提供的USB固件方法同样如此,但这方面的处理让人有些摸不着头脑,详情可参阅。至于具体的SETUP数据结构含义如何,还是要具备基本知识:了解USB协议
* D) n1 M2 o$ m) t3 a6 K. E; Y
# u1 o- e9 f" RCTR_SETUP0() 函数将SETUP数据提取出来,SETUP数据结构有0长度和非0长度的数据结构,详细参阅USB2.0官方协议第9章。在这将两种区别开来分别执行 SETUP0_NoData()和SETUP0_Data()函数,并返回结果,根据返回结果再响应USB主机
5 B* t" H: ?- G  e// ***************************************************************************** 2 y6 l2 U. ~/ E6 Q9 g: z
// Function Name  : CTR_SETUP0 ; P6 o7 _# G. m2 K
// Description    :
' h% y9 l' Y- R3 z# j1 _// Input          : 9 O- P, K! ^, {+ ^* [
// Output         :
$ N* W9 X! z8 A. r/ ]" ?// Return         : / h5 e  r8 V' ~- r% h
// ***************************************************************************** 1 y0 m/ Y+ l1 K: r/ x! x
void CTR_SETUP0(void)
1 N+ s% r: b1 D, V+ \1 P{ ; o3 x5 M; n3 r5 ?% Z' P: }- r( \4 O
  RESULT eResult;
4 }. g5 m5 ]7 F- C
" ?6 O8 q* C5 l6 M  BufferCopy_PMAToUser( (unsigned char *)&vsDeviceInfo.SetupData,
6 N+ [) z, i7 I                        GetBuffDescTable_RXAddr(ENDP0), 4 _" E: C6 _) M; G
                        GetBuffDescTable_RXCount(ENDP0));
- {) }" Q$ R4 Y- }% V2 q+ R, x3 T0 v* [/ I! _
  if(vsDeviceInfo.SetupData.wLength.w == 0) 7 }2 w5 |3 F+ K
  {
8 o" U2 _+ H; R4 y) `/ ^6 I6 ?    eResult = SETUP0_NoData(); + l: x# ^1 v) j& d# j2 m: e% ~
  } 8 Z1 v& I9 G! D) \8 k+ p
  else
5 L' K  i: r7 J2 b1 ]' s8 [# f4 u" N  {
4 `5 p, v3 W0 i    eResult = SETUP0_Data();
3 J$ \9 W: ~. r, _7 l2 r  } - i) N! U0 S1 h: L) ^! c$ J

* F. g- @) d3 V  S) U  switch(eResult) 0 N; i  r7 m9 t. P8 f$ z0 g
  { * E: W. }7 a" h' k6 R* s1 W( G
  case RESULT_SUCCESS:   X( L9 w8 N9 k% V) E
' _2 {! s6 M) y- ]; w9 ~. K- p* O
    break;
7 M6 X/ }% i( H# B
: t1 k# ~" P( p1 @, L& I  case RESULT_LASTDATA: 8 }6 n/ x% u1 P+ l# A7 h
* R+ s) Q0 L! C
    break;
% N" E, @* V, t( u' r- A7 D/ H; ^5 a  \) N
  case RESULT_ERROR:
; A# f0 S1 }* g. u1 p2 k/ h, i  case RESULT_UNSUPPORT:
) ?/ c( v) k' R3 j5 A$ `) z- U    SetEPR_RXStatus(ENDP0, EP_RX_VALID);
& C- y0 \/ x% n    SetEPR_TXStatus(ENDP0, EP_TX_STALL);
) o) [- ]) u$ o: l' v    break;
: Y( m! r% f1 V  X4 ]& e  }
' |4 F: C% m* M}
6 o8 M* }" ^- ?) A
% j2 a/ z7 m7 m/ x; cSETUP0_Data() 和SETUP0_NoData()函数支持的所有USB请求类型只有罗列的这些,有多少种组合都定义在USB协议中,程序根据请求代码,再去执行对应函数,这样做的目的就是让程序结构明了。其中注释为"// done"的部分表明此部分功能已完成。对于未完成部分,希望大家在交流中完善。 ! {/ ^7 T2 G/ H  R. v, z
; }' n2 P6 _; _0 n  L
// *****************************************************************************
/ P8 D1 J6 X7 P- h// Routine Groups: SETUP_Data
* \% y9 t" _7 G) l// ***************************************************************************** . w# m* M2 C8 B% c
RESULT SETUP0_Data(void) 4 c: L, ?" ?* I$ i# p) Q9 n
{
) g" }: P$ w5 P& P9 }6 B: s0 T3 u$ Y  // SetupData.bRequest: request code # s) w# A2 f) Q7 T. H+ g6 ?& A
  switch(vsDeviceInfo.SetupData.bRequest) + r* Q5 i8 ^; \
  {
! Z  e$ P( {8 D2 P  case SR_GET_STATUS:         return SR_GetStatus();                  // done
  H9 I( \3 C* d  case SR_GET_DESCRIPTOR:     return SR_GetDescriptor();              // done & l8 v9 ?7 y; s, r
  case SR_SET_DESCRIPTOR:     return SR_SetDescriptor();              // unsupport
  l: A' W' c( g  case SR_GET_CONFIGURATION:  return SR_GetConfiguration();           // done 9 O: }3 o# D7 M9 W+ \/ q! [
  case SR_GET_INTERFACE:      return SR_GetInterface();               // unsupport
7 ~/ Q) x& n: G! `1 N( I; l  case SR_SYNCH_FRAME:        return SR_SynchFrame();                 // unsupport 5 U: U7 @) H8 @$ i( v9 J5 s% U- y

) {& }0 @$ T3 Z, }3 t* h  default: return RESULT_UNSUPPORT;
' A3 X+ l& I8 p( S# x# @  }
' F, }& Z1 ~! }8 A5 R, r} 4 ^0 Q7 g% a+ T5 D
0 N+ w0 ~* r0 L$ j) ^$ {& J" B
// ***************************************************************************** 5 R  H# n4 k/ V( K% T2 K
// Routine Groups: SETUP_NoData * R) ~9 H, k; E6 d6 {3 E" Q
// *****************************************************************************
& e2 W( m9 H6 [4 E8 aRESULT SETUP0_NoData(void)
  J, E. q# |' o% ~1 G- L{ ) O' i5 W- \0 |& d( w
  // SetupData.bRequest: request code ( [% y2 x8 t; i/ H4 k! r( R( Z
  switch(vsDeviceInfo.SetupData.bRequest)
# y- t) [4 d+ e  {
" J: Q& ~, y9 j& W) ^  case SR_CLEAR_FEATURE:      return SR_ClearFeature();        // unsupport ! a0 N9 g! W: \8 `4 E
  case SR_SET_FEATURE:        return SR_SetFeature();          // unsupport
% f7 T" q! K: X8 z  case SR_SET_ADDRESS:        return SR_SetAddress();          // done / r$ {# o; L1 t- B/ H
  case SR_SET_CONFIGURATION:  return SR_SetConfiguration();    // done
$ V$ B8 O8 N) S6 V  case SR_SET_INTERFACE:      return SR_SetInterface();        // unsupport 6 r& d+ L/ \% U- f( G0 v

6 v& q6 A1 O4 G/ T: t: H2 W! m  default: return RESULT_UNSUPPORT;
, |) J0 m% Y% {: e- {8 h  } / ?  h* y+ c$ e# B
}
- C' C3 `) v: A. m* I0 j; z, M* B+ p3 Z, i8 F) f: \
下篇将介绍上述的各个请求函数如何响应主机。
: m) j( j+ E/ b- e" O* ]

USB枚举过程图解.pdf

下载

273.09 KB, 下载次数: 202

收藏 评论9 发布时间:2008-12-23 12:12

举报

9个回答
luoqizhu-173640 回答时间:2010-3-5 17:11:29

回复:基于STM32的USB程序开发笔记(四)——USB设备的枚举(上)

谢谢谢谢谢谢谢谢谢谢
baobaoaileilei 回答时间:2010-3-18 09:04:51

RE:基于STM32的USB程序开发笔记(四)——USB设备的枚举(上)

谢谢
lihongying-1191 回答时间:2010-4-24 10:48:49

回复:基于STM32的USB程序开发笔记(四)——USB设备的枚举(上)

good!!
fancatls 回答时间:2010-4-25 22:36:26

RE:基于STM32的USB程序开发笔记(四)——USB设备的枚举(上)

非常感谢
viking_xie 回答时间:2011-4-19 14:44:10

RE:基于STM32的USB程序开发笔记(四)——USB设备的枚举(上)

很好,谢谢分享.
aganmelody 回答时间:2011-10-6 20:33:12

回复:基于STM32的USB程序开发笔记(四)——USB设备的枚举(上)

好,正在学习中
fengye5340 回答时间:2013-3-14 14:44:57

回复:基于STM32的USB程序开发笔记(四)——USB设备的枚举(上)

感谢楼主分享资料
sunsword 回答时间:2013-6-11 09:35:31

回复:基于STM32的USB程序开发笔记(四)——USB设备的枚举(上)

谢谢你 分享资料
sange-2008502 回答时间:2013-7-8 08:55:36

RE:基于STM32的USB程序开发笔记(四)——USB设备的枚举(上)

正要学习枚举过程

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版