zoologist 发表于 2015-11-9 12:52:22

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

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



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

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


void setup();
void loop();

MAX3421E Max;
USB Usb;

void setup()
{
    Serial.begin( 115200 );
    Serial.println("Start");
    Max.powerOn();
    delay( 200 );
}

void loop()
{
byte rcode;
    Max.Task();
    Usb.Task();
    if( Usb.getUsbTaskState() == USB_STATE_CONFIGURING ) {
      mouse1_init();
    }//if( Usb.getUsbTaskState() == USB_STATE_CONFIGURING...
    if( Usb.getUsbTaskState() == USB_STATE_RUNNING ) {
      rcode = mouse1_poll();
      if( rcode ) {
          Serial.print("Mouse Poll Error: ");
          Serial.println( rcode, HEX );
      }//if( rcode...
    }//if( Usb.getUsbTaskState() == USB_STATE_RUNNING...
}
/* Initialize mouse */
void mouse1_init( void )
{
byte rcode = 0;//return code
byte tmpdata;
byte* byte_ptr = &tmpdata;
/**/
ep_record[ 0 ] = *( Usb.getDevTableEntry( 0,0 ));//copy endpoint 0 parameters
ep_record[ 1 ].MaxPktSize = EP_MAXPKTSIZE;
ep_record[ 1 ].sndToggle = bmSNDTOG0;
ep_record[ 1 ].rcvToggle = bmRCVTOG0;
Usb.setDevTableEntry( 1, ep_record );            
/* Configure device */
rcode = Usb.setConf( DEVADDR, 0, CONFVALUE );
if( rcode ) {
    Serial.print("Error configuring mouse. Return code : ");
    Serial.println( rcode, HEX );
    while(1);//stop
}//if( rcode...

rcode = Usb.setIdle( DEVADDR, 0, 0, 0, tmpdata );
if( rcode ) {
    Serial.print("Set Idle error. Return code : ");
    Serial.println( rcode, HEX );
    while(1);//stop
}

rcode = Usb.getIdle( DEVADDR, 0, 0, 0, (char *)byte_ptr );
if( rcode ) {
    Serial.print("Get Idle error. Return code : ");
    Serial.println( rcode, HEX );
    while(1);//stop
}
Serial.print("Idle Rate: ");
Serial.print(( tmpdata * 4 ), DEC );      //rate is returned in multiples of 4ms
Serial.println(" ms");
tmpdata = 0;
rcode = Usb.setIdle( DEVADDR, 0, 0, 0, tmpdata );
if( rcode ) {
    Serial.print("Set Idle error. Return code : ");
    Serial.println( rcode, HEX );
    while(1);//stop
}

    /* Set boot protocol */
    rcode = Usb.setProto( DEVADDR, 0, 0, 0 );
    if( rcode ) {
         Serial.print("Error attempting to configure boot protocol. Return code :");
         Serial.println( rcode, HEX );
         while( 1 );//stop
    }
   
Usb.setUsbTaskState( USB_STATE_RUNNING );
return;
}
/* Poll mouse via interrupt endpoint and print result */
/* assumes EP1 as interrupt endpoint                  */
byte mouse1_poll( void )
{
byte rcode,i;
char buf[ 3 ] = { 0 };                        //mouse report buffer

unsigned long int libuf[ sizeof(buf) ];
unsigned long int x;
unsigned long int y;


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

    if( rcode ) {//error
      if( rcode == 0x04 ) {//NAK
      rcode = 0;
      }
      return( rcode );
    }
   
    for (int i=0;i<sizeof(buf);i++) {
       libuf=(buf) & 0xff;
       Serial.print(libuf,HEX); Serial.print("");
    }
   
    Serial.println("");

    return( rcode );
}
运行结果:


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



完整代码

参考:

1.        HID Firmware Specification 1.11 P71

eysajan 发表于 2015-11-10 14:37:23

支持!有了这个可以用普通电机也能做智能小车了吧?

msold5 发表于 2015-11-11 05:20:02

正准备研究下这个东西

164335413 发表于 2015-11-13 08:43:00

是不是可以支持其他的USB设备?USB的小键盘可以支持、鼠标也可以,其他的只要驱动不复杂,应该可以支持吧?

zoologist 发表于 2015-11-13 08:49:22

164335413 发表于 2015-11-13 08:43 static/image/common/back.gif
是不是可以支持其他的USB设备?USB的小键盘可以支持、鼠标也可以,其他的只要驱动不复杂,应该可以支持吧?

HID设备数据格式都体现在HID 描述符中,所以没问题
页: [1]
查看完整版本: Arduino 控制USB设备(8) 鼠标的 Boot Protocol