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

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

[复制链接]
乡村布拉德 发布时间:2008-12-23 12:12
USB设备能否工作,枚举步骤,用“乡村爱情”里的话说,“必须的!”,网上也有很多资料,圈圈就提供了一份详细的枚举过程,但对STM32是怎么响应的没有说明,一会详细道来,先上圈圈的提供的那个枚举图示,希望圈圈支持,如果不妥,请与我联系,谢谢。
8 w. z- |* E2 F- n我将此转换成了PDF文件,方便查看。) Y6 t! R* i  g( u( s7 o# c
首先说明一个变量,定义在usb_core.c中:
% ~& ^6 v6 Z0 n6 B* j4 R1 k# zvolatile DEVICE_INFO vsDeviceInfo;
9 m, B  ^7 j; C- c1 y3 n看意思就知道他的作用了,DEVICE_INFO是个结构,定义在usb_type.h中: . j: R7 _* I8 r4 A4 F
// ***************************************************************************** ! c8 w0 J. Q; z
// DEVICE_INFO 7 h7 O+ U6 z* V; Q2 c$ q4 o! a. F5 i" u
// *****************************************************************************
" f- S# m' o3 {typedef struct _DEVICE_INFO " E7 R( L5 x  V/ w4 m, x% s
{ 3 r. r9 T/ C- B6 r: l1 n
  unsigned char bDeviceAddress;
7 I3 t$ J/ v1 I+ b. s) |: \/ Y1 |3 Q/ \6 ^) z0 {+ G
  unsigned char bCurrentFeature;
3 j6 f9 F1 ?( D  unsigned char bCurrentConfiguration;
/ v1 S( G0 w0 R; Z  unsigned char bCurrentInterface; 4 R7 U$ t5 t- N! Y  \5 @
  unsigned char bCurrentAlternateSetting;
6 x) Y. l, E/ w+ s; ?; F% O$ X' E
6 H, s# g1 V' f# A6 r4 I  WORD_2BYTE    uStatusInfo;
& t& z0 ]2 d- s8 x
2 Z% H; M7 ]2 _4 }  DEVICE_STATE  eDeviceState;
3 D9 R- t. m" I9 m4 L  RESUME_STATE  eResumeState; 9 s1 n4 [" X& W' C3 s2 e
  CONTROL_STATE eControlState; # G* E3 U. n0 d* c0 r8 }3 ~
! O" z) R  i8 M5 k: o& R
  SETUP_DATA    SetupData;
, o- T) P0 H$ @5 o
3 k- E1 g1 ~, T2 d' `  TRANSFER_INFO TransInfo;
1 b+ `" q5 o1 T8 D}
8 y- d: J/ ^: m6 d" f. WDEVICE_INFO,
1 \0 _; D% \4 q3 j  i) c- ^1 s*PDEVICE_INFO; ; D& R' ]# c: x. C7 m' c0 N9 y
; e3 K( A* |: m: Q8 p
在枚举过程中,就是如何处理好SETUP事件,如果STM32 USB接收到正确的SETUP事件,将响应函数CTR_SETUP0(),SETUP事件是特殊的OUT事件,数据方向 Host->Device,SETUP事件数据长度固定为8,数据定义在DEVICE_INFO.SetupData,其数据结构是(定义在 usb_type.h中): ; ~0 z; D5 o- v3 `# m: ]5 ^; @7 C# V
typedef struct _SETUP_DATA 7 ~  W* @1 W* l5 T  ?0 h9 n
{ 5 W5 w8 n, l. _! L( O+ y
  unsigned char bmRequestType;            // request type
' j" L6 T5 o# @+ a7 t5 s) n  unsigned char bRequest;                 // request code
0 z7 T, z* ~$ n7 V) C% v; J; p3 s7 ~) W) ]# T
  WORD_2BYTE wValue; 8 b" F3 i! V( M/ ^: a8 s  X$ ?3 @
  WORD_2BYTE wIndex; ' b! W6 O  l: J4 p
  WORD_2BYTE wLength; 4 g# b1 G9 L- b1 @4 N
} " Q( }6 _6 A. c+ S. i3 [* |: D- l
SETUP_DATA, $ h2 t4 g0 u+ D( z& y
*PSETUP_DATA; $ y5 w3 Z' t& A+ l6 M* e- p
0 V" `; F" T9 I! D: G( L2 ~
WORD_2BYTE是定义的一个共用体:
4 m; L4 j! a) S$ U0 I6 ptypedef union _WORD_2BYTE
/ ]) T; W1 d) m- T; s7 ]( n{ 4 Z+ P7 [% y& N# X. e" \
  unsigned short w;
+ z9 h2 _! L* b: t% f  struct ( G3 \( i' C) l* x+ Q7 ^, I
  {
" @9 Y3 A8 B5 [0 Y  C    unsigned char LSB; 2 F: q) n+ \, {7 P" x( B0 F, m0 c6 V
    unsigned char MSB;
0 o0 v) |1 n+ b  R, B  }b;
) q$ v5 b1 H% ]) g' C- d& b; d} 4 F1 x/ E# i, T1 i
WORD_2BYTE;
# z# i1 E; W& K1 G" E! a! @3 |3 O& n3 l- M1 d3 H% q3 O
为什么将SETUP数据结构中的wValue,wIndex,wLength如此定义? 9 R: H; F- ~& _* _% p
1:USB协议中所有数据传输都是依照低位在先的原则
# z# W. j  X0 T" [- A2:高地位字节可能功能复用
0 }- L# h7 o. k这样在后续的程序编写中就变得十分方便,ST提供的USB固件方法同样如此,但这方面的处理让人有些摸不着头脑,详情可参阅。至于具体的SETUP数据结构含义如何,还是要具备基本知识:了解USB协议
" I( g( }+ c, M6 b6 q
/ q# F4 M/ \2 uCTR_SETUP0() 函数将SETUP数据提取出来,SETUP数据结构有0长度和非0长度的数据结构,详细参阅USB2.0官方协议第9章。在这将两种区别开来分别执行 SETUP0_NoData()和SETUP0_Data()函数,并返回结果,根据返回结果再响应USB主机
) v* P7 Q# o. z8 T- Z  P// *****************************************************************************
- ?& d! R0 O6 {1 G, M2 y// Function Name  : CTR_SETUP0 ) r5 C( k5 @7 d6 b5 J
// Description    :
& a, ?2 a4 M5 W# U// Input          : + w6 B: l/ u* A- `7 P! @
// Output         :
  N) ^0 A' R' E5 m# G// Return         : & a( ?5 A. l# X7 D9 U# I
// ***************************************************************************** " r/ e8 D8 k( Z" C
void CTR_SETUP0(void)
; P7 P% I4 _3 |/ z{ # F6 m' Z# D  f$ A
  RESULT eResult;
3 z8 c+ G. T7 [6 W: R+ `- Z) @, o/ ?, P/ ~
  BufferCopy_PMAToUser( (unsigned char *)&vsDeviceInfo.SetupData,
& J/ l: i- c* k1 z! w' G6 J! C                        GetBuffDescTable_RXAddr(ENDP0), 3 `/ A% M, G2 T* D4 G2 B
                        GetBuffDescTable_RXCount(ENDP0));
2 G; k8 S5 O: d3 Q0 J' U" j
! v6 U/ T5 L* G4 ^; c  if(vsDeviceInfo.SetupData.wLength.w == 0) * z6 u$ A: ?# a( e! F+ H
  {
+ x# F6 t; _* {! k) R& {: u    eResult = SETUP0_NoData();
) u* T9 u" P  n* m' a/ U  }
0 t% P8 B1 g6 l% t  else + `# a" f7 O1 G: Q3 ~
  {
- r$ d. t! N" \& Z8 c  e4 }    eResult = SETUP0_Data();
  ~$ A$ i0 K. g9 J  } ; {5 ~2 }3 Y, u4 j

- c; D# E2 e$ {3 z) D: T1 o  switch(eResult) , V, n; E0 Z, w# k8 R$ f
  {
; c* ?; j; C$ N" I8 n5 `  case RESULT_SUCCESS:
  u+ t, j3 X" O, G* x6 M5 D* }! u2 e
    break;
# O0 V4 _( G; r1 K! f5 J
5 B* w: d  B: E# b) e9 i# {9 F  case RESULT_LASTDATA: 7 q6 V0 n; }9 r5 ?6 g$ B

9 |- Z, _) j; D2 J2 {    break;
5 A# R% |  o3 d" n! H3 ]4 e+ z6 u2 \3 i2 C% K
  case RESULT_ERROR:   h/ E# ~5 j" ?8 s: ]
  case RESULT_UNSUPPORT: 5 _7 j5 l+ u$ l! z
    SetEPR_RXStatus(ENDP0, EP_RX_VALID); * q1 E6 s& b2 ]3 P, U6 V
    SetEPR_TXStatus(ENDP0, EP_TX_STALL); . R& O; h* W5 q0 N! ]* r& `
    break;
  T2 E5 D. r4 O1 F  }
/ f) E1 ^+ N+ p0 y, F  |* g! c} . `; C* J, Q) }0 X

" j& k, y2 c' a2 E/ r6 vSETUP0_Data() 和SETUP0_NoData()函数支持的所有USB请求类型只有罗列的这些,有多少种组合都定义在USB协议中,程序根据请求代码,再去执行对应函数,这样做的目的就是让程序结构明了。其中注释为"// done"的部分表明此部分功能已完成。对于未完成部分,希望大家在交流中完善。
* m, x9 b9 s1 l) V; u6 t* [0 z
3 [& x9 N& ~9 h! _// ***************************************************************************** $ \% `$ U+ ~2 U9 \2 o, D
// Routine Groups: SETUP_Data . X+ X7 J. c/ J" v9 I* {
// *****************************************************************************
9 |0 @& n( }4 l  B5 f, |, DRESULT SETUP0_Data(void)
% N0 U; [$ g7 \) F9 N{
+ U" S' m. d, l4 V" ?  g  // SetupData.bRequest: request code
0 I" ]- K6 g( R, T8 T- s  switch(vsDeviceInfo.SetupData.bRequest)
- M5 ]% X3 `: q  ^9 E  {
" k" m: i; r4 O$ j- K, Q  case SR_GET_STATUS:         return SR_GetStatus();                  // done
( {1 `& i% k5 g7 v( F  case SR_GET_DESCRIPTOR:     return SR_GetDescriptor();              // done * V% k, X: u# m$ {
  case SR_SET_DESCRIPTOR:     return SR_SetDescriptor();              // unsupport
6 I$ u; H; \6 b2 a7 @  case SR_GET_CONFIGURATION:  return SR_GetConfiguration();           // done
- l. ?; B& |, y9 s! `  case SR_GET_INTERFACE:      return SR_GetInterface();               // unsupport # w* d# m: x$ ^8 _2 S) v5 M
  case SR_SYNCH_FRAME:        return SR_SynchFrame();                 // unsupport
: y$ l# ]4 [+ ]0 x2 w
+ S: Z% h5 |5 E/ D7 }0 l/ C  default: return RESULT_UNSUPPORT;
6 Q1 ]: e& J2 \4 w9 _5 `) `  } . t4 p/ v: U$ m6 i9 q
} ; z1 r# v3 }- s- R  Q6 u8 z% Z! U( H
1 e) z& t( I0 q# ~
// ***************************************************************************** # L0 V0 b& A( T2 ~
// Routine Groups: SETUP_NoData
$ o& x( a# a0 H- L/ I, P0 U0 [// *****************************************************************************
3 v9 u0 }  j  Y# t7 a2 fRESULT SETUP0_NoData(void) 0 s( T  o0 p- {7 m! B! P/ R7 d
{ 8 ^/ Z3 B7 G6 [0 b
  // SetupData.bRequest: request code
; [# i) f0 {! E4 O: q+ ~  switch(vsDeviceInfo.SetupData.bRequest) $ [/ r+ |4 C* p" G( j
  { $ S0 T! p! ^& D
  case SR_CLEAR_FEATURE:      return SR_ClearFeature();        // unsupport
9 x( C) u: L4 C* |/ [5 D' L; H  case SR_SET_FEATURE:        return SR_SetFeature();          // unsupport
/ _+ I" D8 |# O0 H* |+ G  Z  case SR_SET_ADDRESS:        return SR_SetAddress();          // done ; ~( V. y( w" X4 j  X
  case SR_SET_CONFIGURATION:  return SR_SetConfiguration();    // done
9 ?8 u4 o- t1 j* F- Q; P  case SR_SET_INTERFACE:      return SR_SetInterface();        // unsupport
( n8 O: Z' x+ e' A  Q( y
! f! k. R' m$ A, t* g$ d  default: return RESULT_UNSUPPORT;
6 u+ C. P- m1 s0 Q  }
  j0 o' y! K" Y, J' ?5 _! `% W5 X}
9 }3 I* F4 i+ w& y7 j( Z" x& E
' _, v  B3 [; Z( z5 }+ O下篇将介绍上述的各个请求函数如何响应主机。3 a2 a" O1 L; P8 @# T

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 手机版