极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 12364|回复: 4

Arduino 控制USB设备(8) 鼠标的 Boot Protocol

[复制链接]
发表于 2015-11-9 12:52:22 | 显示全部楼层 |阅读模式
前面介绍了USB 鼠标数据的读取,个人感觉最困难的部分就是解析HID Descriptor,不同的鼠标的Descriptor不同,发出来的格式也不同。相比之下,键盘切换到 Boot Protocol 之后问题就简单多了。本文介绍如何将鼠标切换到这个模式下。
我们在之前中断方式获得鼠标改变代码的基础上,这样会使得整体效率比较高。
当 Mouse 工作在 Boot Protocol下面的时候,默认使用下面的 HID  Protocol【参考1】



根据资料,编写程序如下:
  1. /* Mouse communication via interrupt endpoint  */
  2. /* Assumes EP1 as interrupt IN ep              */
  3. #include "max3421e.h"
  4. #include "usb.h"

  5. #define DEVADDR 1
  6. #define CONFVALUE 1
  7. #define EP_MAXPKTSIZE 5
  8. EP_RECORD ep_record[ 2 ];  //endpoint record structure for the mouse


  9. void setup();
  10. void loop();

  11. MAX3421E Max;
  12. USB Usb;

  13. void setup()
  14. {
  15.     Serial.begin( 115200 );
  16.     Serial.println("Start");
  17.     Max.powerOn();
  18.     delay( 200 );
  19. }

  20. void loop()
  21. {
  22. byte rcode;
  23.     Max.Task();
  24.     Usb.Task();
  25.     if( Usb.getUsbTaskState() == USB_STATE_CONFIGURING ) {
  26.         mouse1_init();
  27.     }//if( Usb.getUsbTaskState() == USB_STATE_CONFIGURING...
  28.     if( Usb.getUsbTaskState() == USB_STATE_RUNNING ) {
  29.         rcode = mouse1_poll();
  30.         if( rcode ) {
  31.           Serial.print("Mouse Poll Error: ");
  32.           Serial.println( rcode, HEX );
  33.         }//if( rcode...
  34.     }//if( Usb.getUsbTaskState() == USB_STATE_RUNNING...
  35. }
  36. /* Initialize mouse */
  37. void mouse1_init( void )
  38. {
  39. byte rcode = 0;  //return code
  40. byte tmpdata;
  41. byte* byte_ptr = &tmpdata;
  42.   /**/
  43.   ep_record[ 0 ] = *( Usb.getDevTableEntry( 0,0 ));  //copy endpoint 0 parameters
  44.   ep_record[ 1 ].MaxPktSize = EP_MAXPKTSIZE;
  45.   ep_record[ 1 ].sndToggle = bmSNDTOG0;
  46.   ep_record[ 1 ].rcvToggle = bmRCVTOG0;
  47.   Usb.setDevTableEntry( 1, ep_record );            
  48.   /* Configure device */
  49.   rcode = Usb.setConf( DEVADDR, 0, CONFVALUE );
  50.   if( rcode ) {
  51.     Serial.print("Error configuring mouse. Return code : ");
  52.     Serial.println( rcode, HEX );
  53.     while(1);  //stop
  54.   }//if( rcode...
  55.   
  56.   rcode = Usb.setIdle( DEVADDR, 0, 0, 0, tmpdata );
  57.   if( rcode ) {
  58.     Serial.print("Set Idle error. Return code : ");
  59.     Serial.println( rcode, HEX );
  60.     while(1);  //stop
  61.   }
  62.   
  63.   rcode = Usb.getIdle( DEVADDR, 0, 0, 0, (char *)byte_ptr );
  64.   if( rcode ) {
  65.     Serial.print("Get Idle error. Return code : ");
  66.     Serial.println( rcode, HEX );
  67.     while(1);  //stop
  68.   }
  69.   Serial.print("Idle Rate: ");
  70.   Serial.print(( tmpdata * 4 ), DEC );        //rate is returned in multiples of 4ms
  71.   Serial.println(" ms");
  72.   tmpdata = 0;
  73.   rcode = Usb.setIdle( DEVADDR, 0, 0, 0, tmpdata );
  74.   if( rcode ) {
  75.     Serial.print("Set Idle error. Return code : ");
  76.     Serial.println( rcode, HEX );
  77.     while(1);  //stop
  78.   }
  79.   
  80.     /* Set boot protocol */
  81.     rcode = Usb.setProto( DEVADDR, 0, 0, 0 );
  82.     if( rcode ) {
  83.          Serial.print("Error attempting to configure boot protocol. Return code :");
  84.          Serial.println( rcode, HEX );
  85.          while( 1 );  //stop
  86.     }  
  87.    
  88.   Usb.setUsbTaskState( USB_STATE_RUNNING );
  89.   return;
  90. }
  91. /* Poll mouse via interrupt endpoint and print result */
  92. /* assumes EP1 as interrupt endpoint                  */
  93. byte mouse1_poll( void )
  94. {
  95.   byte rcode,i;
  96.   char buf[ 3 ] = { 0 };                          //mouse report buffer

  97.   unsigned long int libuf[ sizeof(buf) ];
  98.   unsigned long int x;
  99.   unsigned long int y;

  100.   
  101.   /* poll mouse */
  102.   rcode = Usb.inTransfer( DEVADDR, 1, sizeof(buf), buf, 1 );  //

  103.     if( rcode ) {  //error
  104.       if( rcode == 0x04 ) {  //NAK
  105.         rcode = 0;
  106.       }
  107.       return( rcode );
  108.     }
  109.    
  110.     for (int i=0;i<sizeof(buf);i++) {
  111.        libuf[i]=(buf[i]) & 0xff;
  112.        Serial.print(libuf[i],HEX); Serial.print("  ");
  113.     }
  114.    
  115.     Serial.println("");
  116.   
  117.     return( rcode );
  118. }
复制代码

运行结果:


特别注意:经过我的实验,不是所有的鼠标都支持 Boot Protocol ,前面实验中用到的Dell 和HP鼠标都无法正常工作,可能是这两种鼠标不支持Boot Protocol 。换一个角度说,如果客户使用 USB 键盘,那么一定要有进入 BIOS  Setup的需求,但是客户通常不会有在Setup中使用鼠标的需求,所以鼠标对于Boot Protocol的支持不好也在情理之中。
我发现好用的反倒是一个杂牌鼠标



完整代码

参考:

1.        HID Firmware Specification 1.11 P71

本帖子中包含更多资源

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

x
回复

使用道具 举报

发表于 2015-11-10 14:37:23 | 显示全部楼层
支持!有了这个可以用普通电机也能做智能小车了吧?
回复 支持 反对

使用道具 举报

发表于 2015-11-11 05:20:02 来自手机 | 显示全部楼层
正准备研究下这个东西
回复 支持 反对

使用道具 举报

发表于 2015-11-13 08:43:00 | 显示全部楼层
是不是可以支持其他的USB设备?USB的小键盘可以支持、鼠标也可以,其他的只要驱动不复杂,应该可以支持吧?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-11-13 08:49:22 | 显示全部楼层
164335413 发表于 2015-11-13 08:43
是不是可以支持其他的USB设备?USB的小键盘可以支持、鼠标也可以,其他的只要驱动不复杂,应该可以支持吧?

HID  设备数据格式都体现在HID 描述符中,所以没问题
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-4-19 21:05 , Processed in 0.043612 second(s), 21 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表