aboutsummaryrefslogtreecommitdiffstats
path: root/Demos/Device/ClassDriver/GenericHID/HostTestApp/test_generic_hid_libusb.js
blob: 363786429ad5da398cbe7b65a2ade886c451f905 (plain) (blame)
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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#!/usr/bin/env node

//             LUFA Library
//     Copyright (C) Dean Camera, 2017.
//
//  dean [at] fourwalledcubicle [dot] com
//           www.lufa-lib.org

// LUFA Generic HID device demo host test script. This script will send a
// continuous stream of generic reports to the device, to show a variable LED
// pattern on the target board. Send and received report data is printed to
// the terminal.
//
// You have to install the usb and async modules prior to executing this script:
// apt-get install libusb-1.0-0-dev
// npm install usb async sprintf

var usb = require('usb');
var async = require('async');
var sprintf = require('sprintf');

var deviceVid = 0x03EB;
var devicePid = 0x204F;
var reportLength = 8;

function getAndInitHidDeviceAndInterface()
{
    device = usb.findByIds(deviceVid, devicePid);
    if (!device) {
        console.log('No device found');
        process.exit(1);
    }
    device.open();

    var hidInterface = device.interface(0);
    if (hidInterface.isKernelDriverActive()) {
        hidInterface.detachKernelDriver();
    }
    hidInterface.claim();

    async.series([
        function(callback) {
            setConfiguration(0, function(error, data) {
                callback();
            });
        }
    ]);

    return {hidDevice:device, hidInterface:hidInterface};
}

function read(hidInterface, callback)
{
    endpoint = hidInterface.endpoints[0];
    endpoint.transfer(reportLength, function(error, data) {
        if (error) {
            console.log(error)
        } else {
            console.log("Received LED Pattern:", data.slice(0, 4));
        }
        callback();
    });
}

function write(hidDevice, message, callback)
{
    hidDevice.controlTransfer(    // Send a Set Report control request
        parseInt('00100001', 2),  // bmRequestType (constant for this control request)
        0x09,                     // bmRequest (constant for this control request)
        0x0809,                   // wValue (MSB is report type, LSB is report number)
        0,                        // wIndex (interface number)
        message,                  // message to be sent
        function(error, data) {   // callback to be executed upon finishing the transfer
            console.log("Sent LED Pattern:", message.slice(1, 5))
            callback();
        }
    );
}

function setConfiguration(configurationNumber, callback)
{
    device.controlTransfer(                 // Send a Set Configuration control request
        parseInt('00000000', 2),            // bmRequestType
        0x09,                               // bmRequest
        0,                                  // wValue (Configuration value)
        0,                                  // wIndex
        new Buffer(0),                      // message to be sent
        callback                            // callback to be executed upon finishing the transfer
    );
}

// @TODO: Fix this function because apparently it doesn't work for some reason.
function getStringDescriptor(stringId, languageId, callback)
{
    var STRING_DESCRIPTOR_TYPE = 0x03;
    var wValue = (STRING_DESCRIPTOR_TYPE << 8) | stringId;

    device.controlTransfer(       // Send a Get Descriptor control request
        parseInt('10000000', 2),  // bmRequestType
        0x06,                     // bmRequest
        wValue,                   // wValue
        languageId,               // wIndex
        64,                       // response length
        callback                  // callback to be executed upon finishing the transfer
    );
}

function setNextPattern()
{
    var pattern = [
        hidInterface.interface,
        (p >> 3) & 1,
        (p >> 2) & 1,
        (p >> 1) & 1,
        (p >> 0) & 1
    ];

    async.series([
        function(callback) {
            write(hidDevice, new Buffer(pattern), callback);
        },
        function(callback) {
            read(hidInterface, callback);
        },
        function(callback) {
            p = (p + 1) % 16
            setTimeout(setNextPattern, 200);
            callback();
        }]);
}

var hidDeviceAndInterface = getAndInitHidDeviceAndInterface();
var hidDevice = hidDeviceAndInterface.hidDevice
var hidInterface = hidDeviceAndInterface.hidInterface;

console.log(sprintf("Connected to device 0x%04X/0x%04X - %s [%s]",
            hidDevice.deviceDescriptor.idVendor,
            hidDevice.deviceDescriptor.idProduct,
            hidDevice.deviceDescriptor.iProduct,
            hidDevice.deviceDescriptor.iManufacturer));

p = 0
setNextPattern();