Gamepad & WSN

Category Archives: 手柄

LibUSB通过SetReport()请求与USBHID设备通信

Author:Gamepader    IN:手柄    Tags: , , ,     评论: 0    超过198人围观

自从基于libUSB的USB设备固件更新程序(下载数据)之后,好久没时间继续我的USB折腾了。今天继续。
本文开发环境:Win7
上位机编译环境:VC++ Express 2010
libusb-win32-devel-filter-1.2.6
首先,安装所需要控制的设备的LibUSB-Win32 Filter,注意:不是LibUSB-Win32本身啊,否则LibUSB驱动程序或替代M$的默认USBHID类设备驱动程序,结果是USBHID设备没有反应。
然后,开始编写上位机程序:
按照LibUSB文档说明的操作顺序,先打开设备:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
//此处VID、PID为测试用,工业生产请勿使用,如有冒犯贵公司,请及时指出以便我们修改
#define MY_VID 0x0666
#define MY_PID 0x0001
#define MY_CONFIG 0x01
usb_init(); /* initialize the library */
usb_find_busses(); /* find all busses */
usb_find_devices(); /* find all connected devices */
if(!(dev = open_dev())) {
printf("error opening device: \n%s\n", usb_strerror());
printf("Is your USB-Device successfully pluged in?\n\n");
}
else {
printf("success: device %04X:%04X opened\n", MY_VID, MY_PID);
}
if(usb_set_configuration(dev, MY_CONFIG) < 0) {
printf("error setting config #%d: %s\n", MY_CONFIG, usb_strerror());
printf("Is your USB-Device running?\n\n");
usb_close(dev);
}
else
{
printf("success: set configuration #%d\n", MY_CONFIG);
}

if(usb_claim_interface(dev, 0) < 0) {
printf("error claiming interface #%d:\n%s\n", MY_INTF, usb_strerror());
printf("Please check your USB-Device's firmware!\n\n");
usb_close(dev);
}
else {
printf("success: claim interface #%d\n", MY_INTF);
}

此时已经成功打开设备的接口1。接下来,可以发送SetReport()请求。
根据USB HID协议规范,Set Report()请求总长8个字节,分为bmRequestType、bRequest、wValue(2 bytes)、wIndex(2 bytes)、wLength(2 bytes)。需要注意的是,USB请求都是低位在前,也就是说,一个WORD的低8位先传输,高8位后传输。这8个字节的请求之后,通过Control transfer 的 Output端点下发数据。

  • bmRequestType=0x21;表示USBHID类请求;
  • bRequest=0x09;表示SetReport()请求;
  • wValue=0x0003;Report ID = 0,Report Type = 0x03(01:Input,02:Output,03:Feature,04-ff:Reserved)表示通过Feature Report发送数据(USB键盘的LED是通过Output Report发送的数据)。
  • wIndex=0x0000;表示选择端点0。
  • wLength=0x0300;表示数据长度是3 bytes

接下来通过控制传输的输出端点发送3 bytes的数据:char ShiftMouseScrollDown1[] = {0x02,0xf3,0xff};

具体在LibUSB中,是使用usb_control_msg()函数实现的,该函数的原型为:

1
2
3
4
int usb_control_msg(usb_dev_handle *dev,
        int requesttype, int request,
        int value, int index, char *bytes, int size,
        int timeout);

usb_control_msg 函数在默认控制管道发送控制请求,该函数的参数符合标准USB的数据规范。
对照上方的数解释,构建出这些函数参数

1
2
3
4
5
6
7
8
9
10
    ret = usb_control_msg(dev, 0x21, 0x09,
                0x0300, 0x0000, ShiftMouseScrollDown1, 3,
                1000);//1000 ms timeout
    if(ret < 0) {
        printf("error writing:\n%s\n", usb_strerror());
    }
    else
    {
        printf("success! COMMAND sent in %d bytes\n", ret);
    }

至此,数据发送完成。通过Bus Hound软件应该可以捕捉到传输的数据。
需要多次发送的话,多次调用usb_control_msg()即可。
发送完成之后的关闭USB接口操作,

1
2
    usb_release_interface(dev, MY_INTF);
    usb_close(dev);

一些基础细节,请参考我之前的博文
基于libUSB的USB设备固件更新程序

可能出现的问题:

  1. 不小心安装了LibUSB-Win32驱动程序,此时不要惊慌,直接使用USBDeview这个小软件,找到对应的设备,卸载(其驱动程序),重新拔插一次设备即可恢复系统驱动。
12-24
2012

计算CC2500信道的一段小程序(FCC 兼容)

Author:Gamepader    IN:手柄    Tags: , , ,     评论: 2    超过201人围观

最近在做一个RF模块测试架,其中一个功能是根据输入的频率来检测当前频率的丢包率(PER)和误码率(BER). 本来想直接做成输入信道号,但是后来一想,还是考虑一下做UI的童鞋的感受吧,于是写了一个小函数进行频率到信道的转换。 为了在MCU上测试不出问题,先来验证一下我的简单算法,就有了下面这段c语言程序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include "Stdio.h"
#include "Conio.h"

int main(void)
{
    unsigned long a;
    unsigned char channel;
    printf("This is a demo to calculat CC2500's data.\r\n");
    printf("Input Frequency, Output Channel Number.\r\n");
    printf("Base=2.402GHz,Space=333.2519kHz,DataRate:249.939kHz\r\n");
    printf("So,Let's start!\r\n\r\n");
    while(1)
    {
        printf("Press 'q' to exit,Other key to continue\r\n\r\n");
        if(getch()!='q')
        {
             /* 此处添加代码 */
            printf("Input (RF_FREQ-2,400,000)(kHz)= ");
            scanf("%ld",&a);
            channel=(a-2000)/333;/*[email protected]*/
            printf("Channel= %u\r\n",channel);

        }
        else
        {
            for(channel=20;channel;--channel)
            {
                printf("%d ",channel);

            }
            getch();
            return 0;
        }
    }
}

代码在TC2.0环境下测试通过,下载地址在这里(freq2channel.c,685Bytes),Windows平台下编译好的exe文件在这里(freq2channel.exe,12.5KB)

原创文章,转载请注明来自//www.gamepader.com/archives/2012/07/a-fcc-compatible-code-to-calculat-channel-of-cc2500.html

07-26
2012

2.4G无线通信跳频思考

Author:Gamepader    IN:创意, 手柄    Tags: , ,     评论: 0    超过488人围观

这几天在思考2.4G抗干扰问题,业界通用的办法是通信双方采用相同的随机数发生算法,通过(传输)一个公用的密码种子进行计算。这样带来的好处就不说了,肯定是很多的:-),但是弊端也较为明显:没有针对性,无法根据干扰快速绕开混杂信道、算法复杂,消耗系统资源,影响通信实时性。
经过思考,得出一个不成熟的偏门解决方案:两边设置一个channel数组,进行伪跳频。数组的设置方式参考wifi信道之间的频率,查找频带间隙(但是只能找到干扰较小的频段),设置2.4G的跳频数组,同时应该参考WIFI路由器的跳频规则,进行规避,因为2.4G频段的主要干扰源就是WIFI,其频带宽、功率大,蓝牙带来的干扰规范由于其协议规范问题,则没有可以利用来跳频的规律。
以上想法纯属想象,没有经过实际工程检测,读者应该根据自己的经验与工程实际加以判断。

07-21
2012
loading...