请教各位大佬,我最近使用F405芯片,用stm32CubeMX默认创建了一个USBHID的例程,这个例程默认就是一个HID模拟鼠标移动的程序,我创建之后也是可以正常枚举并且鼠标正常移动的,说明生成的工程是没有问题的,然后我把报告描述符修改成了一个多点触摸的描述符,这个描述符是以前项目使用的,是没有问题的。变量也没有改变,只是把报告描述符的内容替换了,如下图:
这个报告描述符字节比较大,又474个字节,然后我又把相应的配置描述符修改了,如下图所示: 把配置描述符集合里HID描述符中描述报告描述符大小的字节改成我们修改后的大小,如下图
按道理,将这些修改之后,就相当于重新约定了HID上报数据的协议,随后,我又按照新规定的报告描述符的协议模拟上报触控点的数据。+ O( K9 V A: h* i1 n- F' X. a 通过Bus hound显示枚举是成功的,也一直在按照报告描述符规定的协议向主机发送数据,但是没有模拟触控的现象,我使用以前的工程是有明显 的触控屏幕的现象的。通过设备管理器查看设备是正常运行的,然后用Bus hound观察枚举过程,发现一直在上报数据,但是在枚举过程中在主机 发送GET_REPORT之后出现了USTS c0000004 stall pid 错误,出现之后枚举也没有停止,而是正常运行的,数据也是正常上报的, 但就是没有现象,我感觉是主机没有接收到报告描述符,或者接收错误了,导致虽然数据是正常上报的,但是系统不知道上报的数据的含义, 有没有大佬懂得这方面的错误,还请指导一下,工程其他地方都没有动,就是修改了配置、报告描述符等信息。
. k2 p( p8 `) t |
最全USB HID开发资料,悉心整理一个月,亲自测试
【源码】STLINK-V3MINI 高速USB仿真器,成功改刷【高速CMSIS-DAP】
STM32 USB CDC 虚拟多串口
实战经验 | 选择USBX模块生成USB CDC ACM无PD的项目
STM32 USB HID键盘例程
刘氓兔的杂谈【001】-片上USB 高速PHY
【经验分享】在进行 USB CDC 类开发时,无法发送 64整数倍的数据
在线直播|无需编写任何代码即可在STM32上实现USB-C Power Delivery
圈圈发布USB图书第二版有感,以及分享一些我学习USB过程...
USB Audio设计与实现
微信公众号
手机版
{
//Below is the report descriptor for an example multi-touch device, which can support
//up to 5 simultaneous contacts. This report descriptor also supports multiple device modes.6 e4 U8 o$ ]8 v3 i- m7 H- I8 p
//The OS may select the device mode (ex: mouse, single-touch digitizer, multi-touch digitizer). [9 W' W: w% } k. \" x
//by sending a SET_REPORT (feature) control transfer. In each mode, the device firmware0 R! x) J' Q+ m5 T
//should behave differently and send input packets on the HID IN endpoint, formatted# I, X& C2 ]2 k, o
//based on the report descriptor collections associated with that mode.
//Each IN packet (HID report) sent to the host (in multi-touch digitizer mode) is ?? bytes long (Bytes 0-13). ! F+ c, S3 i& E: W2 M
//The data is sent in little endian format. To send the report to the host, verify
//that the HID IN endpoint buffer is not already busy, then place the data in the HID : M o& f* r5 w
//IN endpoint buffer SRAM, and then call the UsbSendEP5Report() function. The data will
//then get sent to the host, at the next opportunity when the host polls that endpoint ( S9 L6 a, ?' j: t
//(by sending an IN token packet to the endpoint).
. f1 A" K' _ R0 F4 X0 y1 D) v
//NOTE (Contact identifier number): For a multi-touch device, the firmware needs to
//keep track of each contact point separately and independantly. For example, suppose # w' q+ C4 V3 g* l: Y c
//a human first presses one finger to the screen. The firmware would detect this, and 6 q( m2 n: H+ x+ E2 w r. E
//it should arbitrarily assign a contact identifier number for this contact. Typically
//it would be assigned something like contact ID = "1". As the human moves their finger
//around on the contact surface the firmware will report new X and Y coordinate
//information for this contact, but the contact ID byte should always be = "1" for
//this contact.
//6 b3 [* x+ f2 e( S9 K+ p( }2 q3 w0 k& @
//Now suppose the human places a second finger onto the touch surface, so there are
//two simultanous contacts. The firmware should assign this second contact a new 5 V F8 z, G! M8 P8 N
//contact ID, for instance, contact ID = "2". So long as the first contact is still: Z$ F" m- M* n1 {* B+ k
//valid, the firmware needs to continue reporting ID = "1" for the first contact.
//The firmware will continue to report information using these contact ID numbers
//until such time as a contact becomes invalid (human removes their finger from the 5 R* \, S/ P$ }- Z4 S$ w
//screen).
+ M: Z' p0 Q' p7 N ?" O, E
' N' ?8 ]3 v( x& B+ Y; |: _, q; M
//Top level collection for use in Multi-Touch Digitizer device mode.
//-------------------------------------------------------------------) X/ }: i Q9 k3 y
//Format for multi-touch digitizer input reports Using this report descriptor:) r( B+ d3 l: e0 i1 Y
//Byte[0] = Report ID == MULTI_TOUCH_DATA_REPORT_ID
//1st contact point info in bytes 1-6.5 x) A8 a+ H+ `$ I7 d
//Byte[1] = Bits7-3: pad bits (unused), Bit1:In Range, Bit0:Tip Switch% r" H1 H: i `+ ?
//Byte[2] = Contact identifier number (see note above)
//Byte[3] = X-coordinate LSB
//Byte[4] = X-coordinate MSB
//Byte[5] = Y-coordinate LSB; e' d) R& g+ P* E L( ~3 F
//Byte[6] = Y-coordinate MSB
//2nd contact point info in bytes 7-12
//Byte[7] = Bits7-3: pad bits (unused), Bit1:In Range, Bit0:Tip Switch, A3 y# l) q+ Y2 K% {7 i _3 A
//Byte[8] = Contact identifier number (see note above)2 U1 R _. I# ^% m, }; i
//Byte[9] = X-coordinate LSB) @9 m- L0 \$ h1 a( O- A2 H
//Byte[10]= X-coordinate MSB
//Byte[11]= Y-coordinate LSB
//Byte[12]= Y-coordinate MSB' x( b; R' c6 ~
//3rd contact point info in bytes 13-18
//Byte[13] = Bits7-3: pad bits (unused), Bit1:In Range, Bit0:Tip Switch. k' Q9 B7 S% Y) `: C9 E- b' D
//Byte[14] = Contact identifier number (see note above)
//Byte[15] = X-coordinate LSB& c1 r* G; e! X; S+ e
//Byte[16] = X-coordinate MSB
//Byte[17] = Y-coordinate LSB0 B$ q0 U$ x2 x- a
//Byte[18] = Y-coordinate MSB
//4th contact point info in bytes 19-24. [$ y4 w+ Y# Y. H$ }* h% B; f
//Byte[19] = Bits7-3: pad bits (unused), Bit1:In Range, Bit0:Tip Switch0 H7 {5 O; s3 K5 z! R/ H. w
//Byte[20] = Contact identifier number (see note above)
//Byte[21] = X-coordinate LSB
//Byte[22] = X-coordinate MSB
//Byte[23] = Y-coordinate LSB
//Byte[24] = Y-coordinate MSB
% m. ?; Z* j7 l1 P+ Z- g
//5th contact point info in bytes 25-30
//Byte[25] = Bits7-3: pad bits (unused), Bit1:In Range, Bit0:Tip Switch
//Byte[26] = Contact identifier number (see note above)& H0 R! [1 x+ b% o8 ~2 O2 X
//Byte[27] = X-coordinate LSB
//Byte[28]= X-coordinate MSB% J6 ^: T( i% Y5 l
//Byte[29]= Y-coordinate LSB }, z; y/ V. a# g: O# k* E) h8 Z
//Byte[30]= Y-coordinate MSB
//Byte[31]= 8-bit number indicating how many of the above contact points are valid. - H s! C) c% n* N
// If only the first contact is valid, send "1" here. If both are valid, send "2".......etc.# U- S+ m- m1 Y. i4 s6 |
//HID Report descriptor for an example Multi-Touch (5 simultaneous contacts), multi-modes device., a" S1 j$ W0 Q. {2 N. N* |
//------------------------------------------------------------------------------------------------
//Note: In a real application, at a minimum, certain terms in the report descriptor $ p# N$ t( X9 T( F! Z4 E
//(ex: UNIT, UNIT_EXPONENT, PHYSICAL_MAXIMUM and LOGICAL_MAXIMUM) will need to be modified to j$ Z8 b( L* I7 C6 u7 U! \- Q8 ?
//match the characteristics (ex: size) of the actual application being developed. See the HID1_11.pdf6 w$ _* s: c! {' N2 a! e
//specifications regarding these terms.2 w( N8 J6 _% \: p) q
# R' [$ o$ A( k/ g% X9 z
$ x7 p0 J+ z9 D- F+ Z+ g7 A+ p {
//contact point* h5 A1 y0 ~1 G# t! }/ Q w
0x05, 0x0D, // USAGE_PAGE (Digitizers) + E0 A# z7 g0 s5 I: b, D0 r" N6 a
0x09, 0x04, // USAGE (Touch Screen)
0xA1, 0x01, // COLLECTION (Application)
0x85, MULTI_TOUCH_DATA_REPORT_ID, // REPORT_ID (Touch)
0x09, 0x22, // USAGE (Finger)
//Finger 0 , C- l) _( p [
FINGER_USAGE,
//Finger 1 $ b1 N; u! _* p$ [
FINGER_USAGE,5 T5 r) F: {7 e* `- b
//Finger 2
FINGER_USAGE,( [4 b! g, g; q
//Finger 3 ! G; K6 s6 k* P6 p8 f; i- m
FINGER_USAGE,
//Finger 4 # I( K# X" s; z9 m$ }" `3 j
FINGER_USAGE,
//Finger 5 y; Q: a" \; O4 r P% m" r
FINGER_USAGE,+ T" W& }! F2 A" e
//Finger 6
FINGER_USAGE,. b) U, R7 e( r# ~9 Q
//Finger 7 ' }5 k3 G; i6 p/ R
FINGER_USAGE,
//Finger 8
FINGER_USAGE,7 \5 |6 b$ Q# E& k$ O
//Finger 9
FINGER_USAGE,5 L( Z1 C1 s: m( E- z# l
//Timestamp in relative time - Scan Time
9 _# B1 p' I0 @
0x05, 0x0D, // Usage Page (Digitizer) + w9 I$ t( X* G
0x55, 0x0C, // Unit Exponent (-4)
0x66, 0x01, 0x10, // Unit (Seconds)
0x47, 0xFF, 0xFF, 0x00, 0x00, // Physical Maximum (65535)
0x27, 0xFF, 0xFF, 0x00, 0x00, // Logical Maximum (65535)
0x75, 0x10, // Report Size (16) 2 W% f& B( H+ T/ W* k
0x95, 0x01, // Report Count (1)
0x09, 0x56, // Usage (0x56, Relative Scan Time)
0x81, 0x02, // Input (Data,Var,Abs)
5 E% `7 k- j: B4 L' F
//indicating how many of the above contact points
0x05, 0x0D, // USAGE_PAGE (Digitizers)
0x09, 0x54, // USAGE (Actual (contact) count)9 D8 R/ h5 }9 [, m- R
0x95, 0x01, // REPORT_COUNT (1) h5 R1 |7 @" i4 O( N# V* Q
0x75, 0x08, // REPORT_SIZE (8) & b9 Z& C6 g! A% v
0x25, 0x0A, // LOGICAL_MAXIMUM (10) % O/ q/ b- D1 p( I C. o
0x81, 0x02, // INPUT (Data,Var,Abs)
" `% }1 W& y1 O
//In addition to standard HID reports (containing contact X/Y/tip-switch/in-range 0 e. V2 M2 h# ~- O6 X& a- q
//information), the firmware can send feature report information to the host. 1 N6 z$ @9 f3 [
//Feature reports lets the host know information about the firmware/hardware {5 v8 G, h, U& I |
//application design. The host will typically request a feature report by sending
//a GET_REPORT control transfer, with the bRequest = REPORT, but with wIndex (MSB) = 0x03* [/ ?& D# p# I9 Z+ T+ q- r
//(get feature report request as indicated in the HID1_11.pdf specifications). If a
//feature report is sent to the host, it should be sent as a 2-byte packet (for 4 c6 j+ T ^! N
//this example project), formatted like follows:
//Byte[0]= Report ID == VALID_CONTACTS_FEATURE_REPORT_ID == Feature report ID
//Byte[1]= Maximum number of contacts simultaneously supported by this application. Always == 2 in this demo, since this report descriptor only has input fields for 2 contact points
//See the UserGetReportHandler() function that sends this type of packet in the MultiTouch.c file.
//GET_REPORT CTL : A1 01 52 03 04 00 02 00
// IN : 52 05
0x85, VALID_CONTACTS_FEATURE_REPORT_ID, // REPORT_ID (Feature)
0x09, 0x55, // USAGE(Maximum Count)' V) B, m, P/ w4 Q1 _ G
0xB1, 0x02, // FEATURE (Data,Var,Abs)
0x06, 0x00, 0xff, // USAGE_PAGE (Vendor Defined) 1 n; M& [/ f5 \- j2 b4 t
0x09, 0xC5, // USAGE (Vendor Usage 0xC5)
0x85, VALID_CONTACTS_FEATURE_REPORT_ID, // REPORT_ID (VALID_CONTACTS_FEATURE_REPORT_ID) : w; A# L3 J6 e$ v2 S4 z2 G
0x15, 0x00, // LOGICAL_MINIMUM (0) 7 @4 J' \) k8 D) a. |8 K
0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (0xff)
0x75, 0x08, // REPORT_SIZE (8) 3 H1 C2 X- Z9 s7 Y; L+ w9 s" H+ @
0x96, 0x00, 0x01, // REPORT_COUNT (0x100) (256)
0xB1, 0x02, // FEATURE (Data,Var,Abs)/ C; I$ }. ^6 E8 R
0x05, 0x0d, // USAGE_PAGE (Digitizer). I/ ?" L- f. [, J& u: {
0x85, Latency_Mode_Feature_Report_ID, // REPORT_ID (Latency)
0x09, 0x60, // USAGE(Latency Mode)
0x75, 0x01, // REPORT_SIZE (1)
0x95, 0x01, // REPORT_COUNT (1)6 D* K( F+ n# q& z5 K" d* l
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0xb1, 0x02, // FEATURE (Data,Var,Abs)9 f; f( w, j& B) X9 G# O
0x95, 0x07, // REPORT_COUNT (7)
0xb1, 0x03, // FEATURE (Cnst,Var,Abs)
0xC0, // END_COLLECTION3 d. w/ r: }5 K. i/ a& M
4 h. F& y7 c" O M, E
//Top level collection describing the feature report that the host will use (SET_REPORT (feature) control transfer) to set the device mode (ex: mouse, single-touch digitizer, multi-touch digitizer)0 e4 P3 U1 P5 R9 m! v
//-------------------------------------------------------------------
//Format of the feature report output data that the host will send to the device (when it wants to change the device mode):% l9 e2 y8 k* _* N1 J+ h. z Z
//byte[0] = Report ID = DEVICE_MODE_FEATURE_REPORT_ID
//byte[1] = Device Mode (that the device should switch into)
//byte[2] = Device Identifier! _: ~5 n* I1 t' R: n; R( }
4 u0 |' X& [( o) a* k$ U' u
//SET_REPORT CTL : 21 09 53 03 04 00 03 009 \' n( W* T6 L6 }! ], u4 l: V: D, E
// IN : 53 02 00
0 I* _" N, @# z, w D
0x09, 0x0E, // USAGE (Device Configuration): N7 o2 B1 i/ z( C
0xa1, 0x01, // COLLECTION (Application)
0x85, DEVICE_MODE_FEATURE_REPORT_ID, // REPORT_ID (Configuration)
0x09, 0x23, // USAGE (Device Settings)
0xa1, 0x02, // COLLECTION (logical) 4 A: t" m8 ]' A: p! U9 v
0x09, 0x52, // USAGE (Device Mode) 7 t) v. m% e& `4 V) {
0x09, 0x53, // USAGE (Device Identifier)$ `0 m, w* }+ ]6 {
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x0a, // LOGICAL_MAXIMUM (10)
0x75, 0x08, // REPORT_SIZE (8)
0x95, 0x02, // REPORT_COUNT (2)
0xb1, 0x02, // FEATURE (Data,Var,Abs) ) D3 J y4 S: G6 s8 N! w5 [; c
0xc0, // END_COLLECTION (logical)$ D |6 B6 j& b- K4 g
0xc0, // END_COLLECTION (application)# n V% G( N; l
! p) D9 Q8 x* \' ]
0 G0 u- m. Y0 M% I9 S
//Top level collection for use in Mouse device mode. ; N j$ i" i2 Y# v/ r o9 `; `
//-------------------------------------------------------------------
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x02, // Usage (Mouse) 2 x6 z+ k1 E. k3 {7 |
0xA1, 0x01, // Collection (Application) * }8 _+ C4 ], U. E
0x85, MOUSE_DATA_REPORT_ID, // REPORT_ID (mouse)0 f4 C: Q) E6 Z6 d/ e& p7 ^% C- d
0x09, 0x01, // Usage (Pointer)
0xA1, 0x00, // Collection (Physical)
0x05, 0x09, // Usage Page (Buttons) 7 }! U( i5 F% x, A( e+ w- _' T
0x19, 0x01, // Usage Minimum (01) : j: Y0 c3 i/ n
0x29, 0x03, // Usage Maximum (03) 6 a% z1 O, r7 u
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1) ; Q$ `; \$ T. O3 v
0x45, 0x00, // Physical Maximum (0)# X* l2 N9 j" ?4 Z/ O
0x65, 0x00, // Unit (none) - Q5 I+ a- c6 u$ o& h9 A( P H2 R
0x95, 0x03, // Report Count (3)
0x75, 0x01, // Report Size (1) 8 H' a* ]3 V7 c5 N2 s
0x81, 0x02, // Input (Data, Variable, Absolute) , H) m4 q6 n4 }+ p6 A, {# Q
0x95, 0x01, // Report Count (1) 6 h% l1 k. }( \ [
0x75, 0x05, // Report Size (5) 7 E3 ^; U9 q9 ?0 U# G1 c
0x81, 0x01, // Input (Constant) ;5 bit padding
0x05, 0x01, // Usage Page (Generic Desktop) h* D/ v- {/ J! ~' |# \
0x09, 0x30, // Usage (X) 5 o5 Q9 A6 [+ v/ U" W0 @
0x09, 0x31, // Usage (Y) 8 j) I. L2 ?$ x4 f6 L! d4 ~
0x15, 0x81, // Logical Minimum (-127)
0x25, 0x7F, // Logical Maximum (127)
0x75, 0x08, // Report Size (8)
0x95, 0x02, // Report Count (2) 3 L1 M( l, _+ b/ d2 q# C
0x81, 0x06, // Input (Data, Variable, Relative)
0xC0, // End Collection
0xC0, // End Collection $ t& L! J6 q, I4 e; i0 e
};
#define FINGER_USAGE \
0xA1, 0x02, /* COLLECTION (Logical) */ \; M7 p" j% {* S! f k3 N" }
0x05, 0x0D, /* USAGE_PAGE (Digitizers) */ \
0x09, 0x42, /* USAGE (Tip Switch) */ \
0x15, 0x00, /* LOGICAL_MINIMUM (0) */ \
0x25, 0x01, /* LOGICAL_MAXIMUM (1) */ \
0x75, 0x01, /* REPORT_SIZE (1) */ \
0x95, 0x01, /* REPORT_COUNT (1) */ \
0x81, 0x02, /* INPUT (Data,Var,Abs) */ \
0x09, 0x32, /* USAGE (In Range) */ \
0x81, 0x02, /* INPUT (Data,Var,Abs) */ \' c$ Y) f) A: ?, \6 V
0x09, 0x51, /* Usage(Contact ID) */ \& N$ S- j5 f# l1 d, p
0x75, 0x06, /* REPORT_SIZE (6) */ \
0x95, 0x01, /* REPORT_COUNT (1) */ \. \3 o5 G2 I k% Q9 D y
0x15, 0x00, /* LOGICAL_MINIMUM (0) */ \* f# f) f+ [) C1 b2 k5 i& o
0x25, 0x3F, /* LOGICAL_MAXIMUM (63) */ \5 X) v4 H* ~) [* m0 K
0x81, 0x02, /* INPUT (Data,Var,Abs) */ \
0x05, 0x01, /* USAGE_PAGE (Generic Desk.. */ \8 X! y6 _& c! b- j5 k
0x26, 0x20, 0x35, /* LOGICAL_MAXIMUM (13600) */ \
0x75, 0x10, /* REPORT_SIZE (16) */ \
0x95, 0x01, /* REPORT_COUNT (1) */ \
0x55, 0x0E, /* UNIT_EXPONENT (-2) */ \
0x65, 0x33, /* UNIT (Inches, English Linear) */ \
0x09, 0x30, /* USAGE (X) */ \. _3 i K8 H4 F2 c i1 g$ j! w
0x35, 0x00, /* PHYSICAL_MINIMUM (0) */ \4 ~" D' i# H* I0 W
0x46, 0x50, 0x05, /* PHYSICAL_MAXIMUM (0x550 = 1360) */ \8 s4 ^" a6 `- e' d
0x81, 0x02, /* INPUT (Data,Var,Abs) */ \+ h3 E& x4 a' g$ G' C M
0x26, 0xE2, 0x1D, /* LOGICAL_MAXIMUM (7650) */ \8 i: Y: X2 F; J3 ?
0x46, 0xFD, 0x02, /* PHYSICAL_MAXIMUM (0x2FD = 765) */ \4 [0 m* Q; R- @% I/ f" N
0x09, 0x31, /* USAGE (Y) */ \7 S* O- Q/ }* b
0x81, 0x02, /* INPUT (Data,Var,Abs) */ \
0xC0 /* END_COLLECTION */ / L. t' w" K) c% A' [
#endif: l9 r1 J2 m/ q8 g! z% K: Y
2 q6 b2 `6 e) x+ H% v
你可以試試看這是我寫的觸控描述