现在的位置: 首页 > 综合 > 正文

usb2-鼠标里的hid

2013年09月13日 ⁄ 综合 ⁄ 共 2194字 ⁄ 字号 评论关闭

hid spec 下载:
http://www.usb.org/developers/hidpage#Class_Definitions
hid usage table 下载

http://www.usb.org/developers/hidpage#HID_Usage

mouse设备和主机的hid规范,每次中断传输,mouse发给pc 4个字节的数据data,含义如下

      data[0] --
      |--bit7: 1 表示 Y 坐标的变化量超出-256 ~ 255的范围,0表示没有溢出
      |--bit6: 1 表示 X 坐标的变化量超出-256 ~ 255的范围,0表示没有溢出
      |--bit5: Y 坐标变化的符号位,1表示负数,即鼠标向下移动
      |--bit4: X 坐标变化的符号位,1表示负数,即鼠标向左移动
      |--bit3: 恒为1
      |--bit2: 1表示中键按下
      |--bit1: 1表示右键按下
      |--bit0: 1表示左键按下
      data[1] -- X坐标变化量,与data的bit4组成9位符号数,负数表示向左移,正数表右移。用补码表示变化量
      data[2] -- Y坐标变化量,与data的bit5组成9位符号数,负数表示向下移,正数表上移。用补码表示变化量
      data[3] -- 滚轮变化。
//refer to http://group.ednchina.com/93/54358.aspx

所以在

①host side
主机侧usb鼠标驱动linux/drivers/hid/usbhid/usbmouse.c的urb中断函数usb_mouse_irq中,有如下代码

        input_report_key(dev, BTN_LEFT,   data[0] & 0x01);  
        input_report_key(dev, BTN_RIGHT,  data[0] & 0x02);  
        input_report_key(dev, BTN_MIDDLE, data[0] & 0x04);  
  
        input_report_rel(dev, REL_X,     data[1]);
        input_report_rel(dev, REL_Y,     data[2]);
        input_report_rel(dev, REL_WHEEL, data[3]); 

以此第2行为例:data[0] 是单片机发来的数据,
假如data[0]=2,则data[0] & 0x02=1。所以驱动会将BTN_RIGHT的按下状态发送到usbcore,usbcore给driver event ,driver event再将数据按照一定格式写入设备文件。
假如data[0]<>2,则data[0] & 0x02<>1。所以驱动将BTN_RIGHT的释放状态发送出去。

device side
比如一个装备5个按键的单片机,用来模拟鼠标的一些按键和滚轮

k1--BTN_LEFT
k2--REL_WHEEL (+2)
k3--BTN_RIGHT
k4--BTN_MIDDLE
k5--REL_WHEEL (-2)

根据hid规范,定义大小为4个字符的数组

static INT8S MouseData[4] = {0,0,0,0};//typedef signed   char  INT8S;
/*Byte0:keys, Byte1:up-down moving, Byte2:l-r moving, byte3:wheel*/

当单片机
检测到k1键,左键,按下时,令MouseData[0]=1
检测到k3键,右键,按下时,令MouseData[0]=2
检测到k4键,中键,按下时,令MouseData[0]=4
检测到k2键,滚轮上滚,按下时,令MouseData[3]=2
检测到k5键,滚轮下滚,按下时,令MouseData[3]=-2
程序如下

	    switch( KeyScan( ) )
	    {
	        case K1_PRESS://left button
	            MouseData[0] = 1;
	            break;
	        case K2_PRESS://wheel front
	            MouseData[3] = 2;
	            break;
	        case K3_PRESS://Right press
	            MouseData[0] = 2;
	            break;
	        case K4_PRESS://middle press
	            MouseData[0] = 4;
	            break;
	        case K5_PRESS://wheel back
	            MouseData[3] = -2;
	            break;
	        case K1_RELEASE:
	        case K3_RELEASE:
	        case K4_RELEASE:
	            break;
	        default:
	            btmp = 0;
	            break;        
	    }

在主机每次中断传输请求时,单片机将MouseData发送给主机,每次中断传输4个字节,如下

 HID_SendData( (INT8U *)MouseData, 4 );//typedef unsigned char  INT8U;

在mini2440,插入usb鼠标后会自动生成设备文件/dev/input/event1(event0是触摸屏设备)。假如这个鼠标传输的不是按键的状态,也不是在每次按键按下的时候去传输,而是定时上报adc的数值,那么在主机每次请求中断传输的时候就会得到adc的值而将其写入设备文件。这样可以将此单片机做成一个usb数据采集模块。在host侧,编写应用程序读取/dev/input/event1,就可得到adc数据。当然,没必要非得像鼠标一样按照input模型写驱动和从/dev/input/eventx读数据,可以按照混杂设备写等均可,只要符合hid规范。

抱歉!评论已关闭.