USB枚举问题

[复制链接]
 楼主| ranxiaokang 发表于 2013-4-10 14:12 | 显示全部楼层 |阅读模式
请问大家一个问题,做USB键盘时,返回报告描述符时始终有几个字节数据没有返回(小于最大数据包大小)
 楼主| ranxiaokang 发表于 2013-4-10 14:27 | 显示全部楼层
比如最后剩下12个字节数据,我发送到了端点0的缓冲区,主机并没有发起IN传输将这几个字节数据读走,就没有谁帮帮我吗。
john_lee 发表于 2013-4-10 17:05 | 显示全部楼层
HID descriptor 中的 wDescriptorLength 是不是写小了?
jornny520 发表于 2013-4-10 23:28 | 显示全部楼层
我也是刚学,,说一下,也不清楚是不是你想要的答案。主机在一开始的时候 并不是读取description里面的全部数据,而是先读部分,第一次的数据里面告诉了主机description的长度,后面他会再发一次指令要求输入全部的数据。
 楼主| ranxiaokang 发表于 2013-4-11 10:01 | 显示全部楼层
john_lee 发表于 2013-4-10 17:05
HID descriptor 中的 wDescriptorLength 是不是写小了?

HID描述符的length没有写少
 楼主| ranxiaokang 发表于 2013-4-11 10:02 | 显示全部楼层
jornny520 发表于 2013-4-10 23:28
我也是刚学,,说一下,也不清楚是不是你想要的答案。主机在一开始的时候 并不是读取description里 ...

报告描述符的长度从配置描述符中已知了,只需要获取完全就是了。
john_lee 发表于 2013-4-11 11:57 | 显示全部楼层
ranxiaokang 发表于 2013-4-11 10:01
HID描述符的length没有写少

不是hid descriptor的length,而是hid descriptor中的每个report 的 length:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
 楼主| ranxiaokang 发表于 2013-4-11 14:59 | 显示全部楼层
john_lee 发表于 2013-4-11 11:57
不是hid descriptor的length,而是hid descriptor中的每个report 的 length:

谢谢版主的回答,这个是没有写少的。
 楼主| ranxiaokang 发表于 2013-4-12 10:06 | 显示全部楼层
描述符如下
  1. unsigned char code device_descriptor[] = {
  2.         0x12,                /* bLength */
  3.         0x01,                /* bDescriptor */
  4.         0x10, 0x01,        /* bcdUSB */
  5.         0x00,                /* bDeviceClass */
  6.         0x00,                /* bDeviceSubClass */
  7.         0x00,                /* bDevcieProtocol */
  8.         //0x40,                /* bMaxPacketSize */
  9.         0x10,                /* bMaxPacketSize */
  10.         0x00, 0x80,        /* idVendor */
  11.         0x01, 0x00,        /* idProduct */
  12.         0x00, 0x01,        /* bcdDevice */
  13.         0x00,//0x01,                /* iManufacturer */
  14.         0x00,//0x02,                /* iProduct */
  15.         0x00,                /* iSerialNumber */
  16.         0x01                /* bNumConfigurations */
  17. };

  18. unsigned char code config_descriptor[] = {
  19.         /* usb configuration descriptor */
  20.         0x09,                /* bLength */
  21.         0x02,                /* bDescriptorType */
  22.         0x22, 0x00,        /* wTotalLength */
  23.         0x01,                /* bNumInterfaces */
  24.         0x01,                /* bConfigurationValue */
  25.         0x00,                /* iConfiguration */
  26.         0x80,                /* bmAttributes */
  27.         0x32,                /* bMaxPower */

  28.         /* usb interface descriptor */
  29.         0x09,                /* bLength */
  30.         0x04,                /* bDescriptorType */
  31.         0x00,                /* bInterfaceNumber */
  32.         0x00,                /* bAlternateSetting */
  33.         0x01,                /* bNumEndpoints */
  34.         0x03,                /* bInterfaceClass */
  35.         0x01,                /* bInterfaceSubClass */
  36.         0x01,                /* bInterfaceProtocol */
  37.         0x00,                /* iInterface */

  38.         /* usb hid descriptor */
  39.         0x09,                /* bLength */
  40.         0x21,                /* bDescriptorType */
  41.         0x01, 0x01,        /* bcdHID */
  42.         0x00,                /* bCountryCode */
  43.         0x01,                /* bNumDescriptor */
  44.         0x22,                /* wDescriptorType */
  45.         0x2d, 0x00,        /* wDescriptorLength */

  46.         /* usb endpoint descriptor */
  47.         0x07,                /* bLength */
  48.         0x05,                /* bDescriptorType */
  49.         0x81,                /* bEndpointAddress */
  50.         0x03,                /* bmAttributes */
  51.         0x08, 0x00,        /* wMaxPacketSize */
  52.         0x0a                /* bInterval */
  53. };

  54. //#define USB_KEYBOARD_USE_LED                1
  55. #define REPORT_DESCRIPTOR_SIZE                0x3f
  56. #define REPORT_DESCRIPTOR_NOLED_SIZE        0x2d

  57. /*
  58. * 键盘有输入报告和输出报告,其中输入报告8个字节,输出报告1个字节
  59. * 输入报告格式如下:
  60. * [Key6][Key5][Key4][Key3][Key2][Key1][Reserved][Function Key]
  61. * 输出报告格式如下:
  62. * 7~5                4        3        2                1                0
  63. * Reserved        Kana        Compose        Scroll Lock        Caps Lock        Num Lock
  64. */
  65. unsigned char code report_descriptor[] = {
  66.         0x05, 0x01,        /* Usage Page(Generic Desktop) */
  67.         0x09, 0x06,        /* Usage(Keyboard) */
  68.         0xa1, 0x01,        /* Collection(Application) */

  69.         /* function key, such as Ctrl, Shift... */
  70.         0x05, 0x07,        /* Usage Page(Keyboard) */
  71.         0x19, 0xe0,        /* Usage Minimum(Keyboard LeftControl) */
  72.         0x29, 0xe7,        /* Usage Maximum(Keyboard Right GUI) */
  73.         0x15, 0x00,        /* Logical Minimum(0) */
  74.         0x25, 0x01,        /* Logical Maximum(1) */
  75.         0x75, 0x01,        /* Report Size(1) */
  76.         0x95, 0x08,        /* Report Count(8) */
  77.         0x81, 0x02,        /* Input(Data, Variable, Absolute) */

  78.         /* byte for reserved */
  79.         0x95, 0x01,        /* Report Count(1) */
  80.         0x75, 0x08,        /* Report Size(8) */
  81.         0x81, 0x01,        /* Input(Constant) */

  82. #ifdef USB_KEYBOARD_USE_LED
  83.         /* for LED */
  84.         0x95, 0x05,        /* Report Count(5) */
  85.         0x75, 0x01,        /* Report Size(1) */
  86.         0x05, 0x08,        /* Usage Page(for LEDs) */
  87.         0x19, 0x01,        /* Usage Minimum(Num Lock) */
  88.         0x29, 0x05,        /* Usage Maximum(Kana) */
  89.         0x91, 0x02,        /* Output(Data, Variable, Absolute) */
  90.         0x95, 0x01,        /* Report Count(1) */
  91.         0x75, 0x03,        /* Report Size(3) */
  92.         0x91, 0x01,        /* Output(Constant) */
  93. #endif
  94.         /* generic key */
  95.         0x95, 0x06,        /* Report Count(6) */
  96.         0x75, 0x08,        /* Report Size(8) */
  97.         0x15, 0x00,        /* Logical Minimum(0) */
  98.         0x25, 0x65,        /* Logical Maximum(101) */
  99.         0x05, 0x07,        /* Usage Page(Key Codes) */
  100.         0x19, 0x00,        /* Usage Minimum(0) */
  101.         0x29, 0x65,        /* Usage Maximum(101) */
  102.         0x81, 0x00,        /* Input(Data, Array) */

  103.         0xc0                /* End Collection */
  104. };
 楼主| ranxiaokang 发表于 2013-4-12 10:08 | 显示全部楼层
报告描述符长度为0x2d时,有0x0d字节未获取,如果是0x3f,则有0x0f字节未获取,感觉是丢掉了少于端点0最大数据包长度的数据。
 楼主| ranxiaokang 发表于 2013-4-12 10:11 | 显示全部楼层
以下是枚举过程的代码:
  1. #include "types.h"
  2. #include "printf.h"
  3. #include "time.h"
  4. #include "d12.h"
  5. #include "ch9.h"
  6. #include "usb.h"
  7. #include "hid.h"


  8. struct usb_device idata                device;

  9. void usb_interrupt_handler(void) interrupt 0
  10. //void usb_interrupt_handler(void)
  11. {
  12.         struct usb_device *idata dev = &device;
  13.         u16 idata status;

  14.         status = d12_read_interrupt_status();
  15.         //printf("status %x\r\n", (int)status);
  16.         switch (status) {
  17.         case D12_INT_BUS_RESET:
  18.                 //printf("usb bus reset.\r\n");
  19.                 break;
  20.         case D12_INT_SUSPEND_CHANGE:
  21.                 //printf("usb bus suspend.\r\n");
  22.                 break;
  23.         case D12_INT_EPT0_OUT:
  24.                 ept0out_event_handler(dev);
  25.                 break;
  26.         case D12_INT_EPT0_IN:
  27.                 ept0in_event_handler(dev);
  28.                 break;
  29.         case D12_INT_EPT1_OUT:
  30.                 break;
  31.         case D12_INT_EPT1_IN:
  32.                 d12_read_trans_status(D12_EPT1_IN);
  33.                 break;
  34.         default:
  35.                 break;
  36.         }
  37. }

  38. void ept0out_event_handler(struct usb_device *dev)
  39. {
  40.         struct usb_setup_packet *idata pkt;
  41.         u8 idata buf[8];
  42.         u8 idata status;

  43.         status = d12_read_trans_status(D12_EPT0_OUT);
  44.         pkt = (struct usb_setup_packet *)buf;

  45.         //buf[0] = 0x80;
  46.         //puts("ept0out_event_handler\r\n");
  47.         if (status & D12_TRANS_STATUS_SETUP_PACKET) {
  48.                 d12_read_buffer(D12_EPT0_OUT, buf, 8);
  49.                 //printf("bmRequestType 0x%x bRequest 0x%x wValue 0x%x wIndex 0x%x wLength 0x%x\r\n",
  50.                 //        (int)pkt->bmRequestType, (int)pkt->bRequest, (int)pkt->wValue, (int)pkt->wIndex, (int)pkt->wLength);
  51.                 //printf("bRequest 0x%x\r\n", (int)pkt->bRequest);
  52.                 //printf("bmRequestType %x\r\n", (int)buf[0]);
  53.                 //printf("bRequest %x\r\n", buf[1]);
  54.                 //puts("usb setup request\r\n");
  55.                 //printf("读端点0缓冲区8个字节\r\n");
  56.                 //printf("0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\r\n",
  57.                 //        (int)buf[0], (int)buf[1], (int)buf[2], (int)buf[3], (int)buf[4], (int)buf[5], (int)buf[6], (int)buf[7], (int)buf[8]);
  58.                 d12_ack_setup();
  59.                 d12_clear_buffer();
  60.                 usb_setup_request(dev, pkt);
  61.         } else {
  62.                 d12_read_buffer(D12_EPT0_OUT, buf, 8);
  63.                 //d12_ack_setup();
  64.                 d12_clear_buffer();
  65.         }
  66. }

  67. void usb_setup_request(struct usb_device *dev, struct usb_setup_packet *pkt)
  68. {
  69.         switch (pkt->bmRequestType & USB_TYPE_MASK) {
  70.         case USB_TYPE_STANDARD:
  71.                 //puts("usb standard request\r\n");
  72.                 usb_standard_request(dev, pkt);
  73.                 break;
  74.         case USB_TYPE_CLASS:
  75.                 usb_class_request(dev, pkt);
  76.                 break;
  77.         default:
  78.                 break;
  79.         }

  80.         if (pkt->bmRequestType & 0x80) {
  81.                 dev->dir = USB_DIR_IN;
  82.                 usb_control_transfer(dev);
  83.         } else {
  84.                 dev->dir = USB_DIR_OUT;
  85.                 //d12_write_buffer(D12_EPT0_IN, (u8 *)0, 0);
  86.                 usb_control_transfer(dev);
  87.         }
  88.        
  89. }

  90. void usb_standard_request(struct usb_device *dev, struct usb_setup_packet *pkt)
  91. {
  92.         //struct usb_request
  93.         u16 idata value = le16_to_cpu(pkt->wValue);
  94.         u16 idata index = le16_to_cpu(pkt->wIndex);
  95.         u16 idata length = le16_to_cpu(pkt->wLength);

  96.         //printf("length = %x\r\n", (int)length);
  97.         switch (pkt->bRequest) {
  98.         case USB_REQ_GET_STATUS:
  99.                 //puts("get status\r\n");
  100.                 break;
  101.         case USB_REQ_CLEAR_FEATURE:
  102.                 //puts("clear feature\r\n");
  103.                 break;
  104.         //case USB_REQ_SET_FEATURE:
  105.         //        break;
  106.         case USB_REQ_SET_FEATURE:
  107.                 //puts("set feature\r\n");
  108.                 break;
  109.         case USB_REQ_SET_ADDRESS:
  110.                 d12_set_address((u8)value);
  111.                 //d12_write_buffer(D12_EPT0_IN, (u8 *)0, 0); /* return zero-length data packet */
  112.                 usb_set_device_state(dev, USB_STATE_ADDRESS);
  113.                 //puts("set address\r\n");
  114.                 break;
  115.         case USB_REQ_GET_DESCRIPTOR:
  116.                 //printf("length = %x\r\n", length);
  117.                 switch (value >> 8) {
  118.                 case USB_DT_DEVICE:
  119.                         dev->buf = device_descriptor;
  120.                         dev->size = MIN(0x12, length);
  121.                         //puts("get device descriptor\r\n");
  122.                         break;
  123.                 case USB_DT_CONFIG:
  124.                         dev->buf = config_descriptor;
  125.                         //dev->size = MIN(0x43, length);
  126.                         dev->size = MIN(0x22, length);
  127.                         //puts("get config descriptor\r\n");
  128.                         break;
  129.                 case USB_DT_STRING:
  130.                         break;
  131.                 case USB_DT_REPORT:
  132.                         dev->buf = report_descriptor;
  133.                         dev->size = MIN(0x2d, length);
  134.                         //printf("get report descriptor\r\n");
  135.                         //dev->size = 0x2d;
  136.                         break;
  137.                 }
  138.                 //puts("get device descriptor\r\n");
  139.                 //usb_control_transfer(dev);
  140.                 break;
  141.         case USB_REQ_SET_DESCRIPTOR:
  142.                 //puts("set descriptor\r\n");
  143.                 break;
  144.         case USB_REQ_GET_CONFIGURATION:
  145.                 dev->buf = &dev->config;
  146.                 dev->size = 1;
  147.                 //puts("get config\r\n");
  148.                 //usb_control_transfer(dev);
  149.                 break;
  150.         case USB_REQ_SET_CONFIGURATION:
  151.                 dev->config = (u8)value;
  152.                 //d12_endpoint_enable(ENABLE);
  153.                 d12_endpoint_enable(1);
  154.                 //d12_write_buffer(D12_EPT0_IN, (u8 *)0, 0);
  155.                 usb_set_device_state(dev, USB_STATE_CONFIGURED);
  156.                 //puts("set config\r\n");
  157.                 break;
  158.         case USB_REQ_GET_INTERFACE:
  159.                 //d12_write_buffer(D12_EPT0_IN, (u8 *)0, 0);
  160.                 //puts("get interface\r\n");
  161.                 break;
  162.         case USB_REQ_SET_INTERFACE:
  163.                 //puts("set interface\r\n");
  164.                 break;
  165.         default:
  166.                 break;
  167.         }
  168. }

  169. void usb_class_request(struct usb_device *dev, struct usb_setup_packet *pkt)
  170. {
  171.         hid_class_request(dev, pkt);
  172. }

  173. void ept0in_event_handler(struct usb_device *dev)
  174. {
  175.         //puts("ept0in_event_handler\r\n");
  176.         d12_read_trans_status(D12_EPT0_IN);
  177.        
  178.         usb_control_transfer(dev);
  179. }

  180. void usb_control_transfer(struct usb_device *dev)
  181. {
  182.         u8 code buf_size = 16;
  183.         u8 idata len;

  184.         //printf("size %x\r\n", (int)dev->size);
  185.         //puts("control transfer\r\n");
  186.         if (dev->dir == USB_DIR_IN) {
  187.                 //puts("control transfer\r\n");
  188.                 //printf("size %x\r\n", (int)dev->size);
  189.                 if (dev->size != 0) {
  190.                         if (dev->size >= buf_size) {
  191.                                 len = buf_size;
  192.                                 dev->size -= len;
  193.                         } else {
  194.                                 len = dev->size;
  195.                                 dev->size = 0;
  196.                         }
  197.                         //dev->size -= len;

  198.                         d12_write_buffer(D12_EPT0_IN, dev->buf, len);
  199.                         dev->buf += len;
  200.                 }
  201.         } else {
  202.                 d12_write_buffer(D12_EPT0_IN, (u8 *)0, 0);
  203.         }
  204. }

  205. void usb_set_device_state(struct usb_device *dev, enum usb_device_state new_state)
  206. {
  207.         dev->state = new_state;
  208. }

  209. enum usb_device_state usb_get_device_state(void)
  210. {
  211.         struct usb_device *dev = &device;

  212.         return &dev->state;
  213. }

  214. u8 usb_init(void)
  215. {
  216.         u16 chip_id;

  217.         chip_id = d12_read_id();
  218.         if (chip_id != D12_CHIP_ID) {
  219.                 printf("d12 is not working.\r\n");
  220.                 return -1;
  221.         }

  222.         d12_disconnect();
  223.         delayms(100);
  224.         d12_init();

  225.         return 0;
  226. }
 楼主| ranxiaokang 发表于 2013-4-12 10:13 | 显示全部楼层
获取设备描述符、配置描述符都是对的,希望大虾们帮我看看是哪里出了问题。
 楼主| ranxiaokang 发表于 2013-4-16 16:47 | 显示全部楼层
liyihong028 发表于 2013-4-16 23:40 | 显示全部楼层
device_descriptor[]中的bMaxPacketSize应该为0x40,而不是0x10.
 楼主| ranxiaokang 发表于 2013-4-20 10:52 | 显示全部楼层
本帖最后由 ranxiaokang 于 2013-4-20 11:02 编辑
liyihong028 发表于 2013-4-16 23:40
device_descriptor[]中的bMaxPacketSize应该为0x40,而不是0x10.

device_descriptor[]中的bMaxPacketSize表示端点0的最大传输能力,d12就是16个字节,而不是64个字节。
jiege0129 发表于 2013-4-22 11:35 | 显示全部楼层
报告描述符的长度为63,而你在hid描述符中写0x2d,改为63应该就可以了,还有,你报告描述符中有输出功能,但是你没有定义输出端点,应该增加一个端点作为输出。
 楼主| ranxiaokang 发表于 2013-4-22 14:11 | 显示全部楼层
jiege0129 发表于 2013-4-22 11:35
报告描述符的长度为63,而你在hid描述符中写0x2d,改为63应该就可以了,还有,你报告描述符中有输出功能, ...

不是这个问题啊,报告描述符中如果使用LED,那么描述符长度为63,如果不使用LED的话,长度就是0x2d,也就不需要输出端点了。
jiege0129 发表于 2013-4-22 16:44 | 显示全部楼层
ranxiaokang 发表于 2013-4-22 14:11
不是这个问题啊,报告描述符中如果使用LED,那么描述符长度为63,如果不使用LED的话,长度就是0x2d,也就 ...

对啊,那你描述符里有写啊,这样后面的数据就忽略了,oxc0不就也会被忽略吗
 楼主| ranxiaokang 发表于 2013-4-22 16:55 | 显示全部楼层
jiege0129 发表于 2013-4-22 16:44
对啊,那你描述符里有写啊,这样后面的数据就忽略了,oxc0不就也会被忽略吗 ...

我有宏定义会忽略这部分的定义。
jiege0129 发表于 2013-4-22 19:10 | 显示全部楼层
ranxiaokang 发表于 2013-4-22 16:55
我有宏定义会忽略这部分的定义。

哦,看到了,那描述符应该是没问题,那你枚举成功了吗,用bus hound抓的数据确实是不完全的,至少报告描述符不能全部抓到。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

14

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部