rb-blink1 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +0 -0
- data/README.rdoc +1 -0
- data/Rakefile +5 -0
- data/ext/blink1/blink1-lib.c +552 -0
- data/ext/blink1/blink1-lib.h +83 -0
- data/ext/blink1/blink1.c +296 -0
- data/ext/blink1/extconf.rb +56 -0
- data/ext/blink1/hid.c.libusb +1424 -0
- data/ext/blink1/hid.c.mac +1156 -0
- data/ext/blink1/hid.c.windows +920 -0
- data/ext/blink1/include/blink1-lib.h +83 -0
- data/ext/blink1/include/color_funcs.h +101 -0
- data/ext/blink1/include/hidapi.h +383 -0
- data/ext/blink1/include/osccal.h +85 -0
- data/ext/blink1/include/usbconfig.h +388 -0
- data/lib/blink1/version.rb +3 -0
- data/lib/blink1.rb +2 -0
- data/rb-blink1.gemspec +24 -0
- metadata +81 -0
data/LICENSE
ADDED
File without changes
|
data/README.rdoc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
= blink1.rb
|
data/Rakefile
ADDED
@@ -0,0 +1,552 @@
|
|
1
|
+
/*
|
2
|
+
* blink(1) C library --
|
3
|
+
*
|
4
|
+
*
|
5
|
+
* 2012, Tod E. Kurt, http://todbot.com/blog/ , http://thingm.com/
|
6
|
+
*
|
7
|
+
*/
|
8
|
+
|
9
|
+
#include <stdio.h>
|
10
|
+
#include <stdlib.h>
|
11
|
+
#include <string.h>
|
12
|
+
#include <ctype.h> // for toupper()
|
13
|
+
|
14
|
+
#ifdef _WIN32
|
15
|
+
#include <windows.h>
|
16
|
+
#else
|
17
|
+
#include <unistd.h> // for usleep()
|
18
|
+
#endif
|
19
|
+
|
20
|
+
#include "blink1-lib.h"
|
21
|
+
|
22
|
+
|
23
|
+
#ifdef DEBUG_PRINTF
|
24
|
+
#define LOG(...) fprintf(stderr, __VA_ARGS__)
|
25
|
+
#else
|
26
|
+
#define LOG(...) do {} while (0)
|
27
|
+
#endif
|
28
|
+
|
29
|
+
#define blink1_report_id 1
|
30
|
+
|
31
|
+
// addresses in EEPROM
|
32
|
+
#define blink1_eeaddr_osccal 0
|
33
|
+
#define blink1_eeaddr_bootmode 1
|
34
|
+
#define blink1_eeaddr_serialnum 2
|
35
|
+
#define blink1_serialnum_len 4
|
36
|
+
#define blink1_eeaddr_patternstart (blink1_eeaddr_serialnum + blink1_serialnum_len)
|
37
|
+
|
38
|
+
#define pathmax 16
|
39
|
+
#define pathstrmax 128
|
40
|
+
#define serialmax (8 + 1)
|
41
|
+
|
42
|
+
|
43
|
+
// FIXME: use hid_device_info instead with custom sorter on serial or path
|
44
|
+
static char blink1_cached_paths[pathmax][pathstrmax];
|
45
|
+
static int blink1_cached_count = 0;
|
46
|
+
static wchar_t blink1_cached_serials[pathmax][serialmax];
|
47
|
+
|
48
|
+
static int blink1_enable_degamma = 1;
|
49
|
+
|
50
|
+
//----------------------------------------------------------------------------
|
51
|
+
|
52
|
+
//
|
53
|
+
int blink1_enumerate(void)
|
54
|
+
{
|
55
|
+
return blink1_enumerateByVidPid( blink1_vid(), blink1_pid() );
|
56
|
+
}
|
57
|
+
|
58
|
+
// get all matching devices by VID/PID pair
|
59
|
+
int blink1_enumerateByVidPid(int vid, int pid)
|
60
|
+
{
|
61
|
+
struct hid_device_info *devs, *cur_dev;
|
62
|
+
|
63
|
+
int p = 0;
|
64
|
+
devs = hid_enumerate(vid, pid);
|
65
|
+
cur_dev = devs;
|
66
|
+
while (cur_dev) {
|
67
|
+
if( (cur_dev->vendor_id != 0 && cur_dev->product_id != 0) &&
|
68
|
+
(cur_dev->vendor_id == vid && cur_dev->product_id == pid) ) {
|
69
|
+
if( cur_dev->serial_number != NULL ) { // can happen if not root
|
70
|
+
strcpy( blink1_cached_paths[p], cur_dev->path );
|
71
|
+
wcscpy( blink1_cached_serials[p], cur_dev->serial_number );
|
72
|
+
p++;
|
73
|
+
}
|
74
|
+
}
|
75
|
+
cur_dev = cur_dev->next;
|
76
|
+
}
|
77
|
+
hid_free_enumeration(devs);
|
78
|
+
|
79
|
+
blink1_cached_count = p;
|
80
|
+
|
81
|
+
blink1_sortSerials();
|
82
|
+
|
83
|
+
return p;
|
84
|
+
}
|
85
|
+
|
86
|
+
//
|
87
|
+
int blink1_getCachedCount(void)
|
88
|
+
{
|
89
|
+
return blink1_cached_count;
|
90
|
+
}
|
91
|
+
|
92
|
+
//
|
93
|
+
const char* blink1_getCachedPath(int i)
|
94
|
+
{
|
95
|
+
return blink1_cached_paths[i];
|
96
|
+
}
|
97
|
+
//
|
98
|
+
const wchar_t* blink1_getCachedSerial(int i)
|
99
|
+
{
|
100
|
+
return blink1_cached_serials[i];
|
101
|
+
}
|
102
|
+
|
103
|
+
//
|
104
|
+
hid_device* blink1_openByPath(const char* path)
|
105
|
+
{
|
106
|
+
if( path == NULL || strlen(path) == 0 ) return NULL;
|
107
|
+
hid_device* handle = hid_open_path( path );
|
108
|
+
return handle;
|
109
|
+
}
|
110
|
+
|
111
|
+
//
|
112
|
+
hid_device* blink1_openBySerial(const wchar_t* serial)
|
113
|
+
{
|
114
|
+
if( serial == NULL || wcslen(serial) == 0 ) return NULL;
|
115
|
+
int vid = blink1_vid();
|
116
|
+
int pid = blink1_pid();
|
117
|
+
|
118
|
+
LOG("opening %ls at vid/pid %x/%x\n", serial, vid,pid);
|
119
|
+
hid_device* handle = hid_open(vid,pid, serial );
|
120
|
+
return handle;
|
121
|
+
}
|
122
|
+
|
123
|
+
//
|
124
|
+
hid_device* blink1_openById( int i )
|
125
|
+
{
|
126
|
+
//return blink1_openByPath( blink1_getCachedPath(i) );
|
127
|
+
return blink1_openBySerial( blink1_getCachedSerial(i) );
|
128
|
+
}
|
129
|
+
|
130
|
+
//
|
131
|
+
hid_device* blink1_open(void)
|
132
|
+
{
|
133
|
+
int vid = blink1_vid();
|
134
|
+
int pid = blink1_pid();
|
135
|
+
|
136
|
+
hid_device* handle = hid_open(vid,pid, NULL); // FIXME?
|
137
|
+
|
138
|
+
return handle;
|
139
|
+
}
|
140
|
+
|
141
|
+
//
|
142
|
+
// FIXME: search through blink1s list to zot it too?
|
143
|
+
void blink1_close( hid_device* dev )
|
144
|
+
{
|
145
|
+
if( dev != NULL )
|
146
|
+
hid_close(dev);
|
147
|
+
dev = NULL;
|
148
|
+
hid_exit(); // FIXME: this cleans up libusb in a way that hid_close doesn't
|
149
|
+
}
|
150
|
+
|
151
|
+
//
|
152
|
+
int blink1_write( hid_device* dev, void* buf, int len)
|
153
|
+
{
|
154
|
+
if( dev==NULL ) {
|
155
|
+
return -1; // BLINK1_ERR_NOTOPEN;
|
156
|
+
}
|
157
|
+
int rc = hid_send_feature_report( dev, buf, len );
|
158
|
+
return rc;
|
159
|
+
}
|
160
|
+
|
161
|
+
// len should contain length of buf
|
162
|
+
// after call, len will contain actual len of buf read
|
163
|
+
int blink1_read( hid_device* dev, void* buf, int len)
|
164
|
+
{
|
165
|
+
if( dev==NULL ) {
|
166
|
+
return -1; // BLINK1_ERR_NOTOPEN;
|
167
|
+
}
|
168
|
+
int rc = hid_send_feature_report(dev, buf, len); // FIXME: check rc
|
169
|
+
|
170
|
+
if( (rc = hid_get_feature_report(dev, buf, len) == -1) ) {
|
171
|
+
LOG("error reading data: %s\n",blink1_error_msg(rc));
|
172
|
+
}
|
173
|
+
return rc;
|
174
|
+
}
|
175
|
+
|
176
|
+
|
177
|
+
// -------------------------------------------------------------------------
|
178
|
+
// everything below here doesn't need to know about USB details
|
179
|
+
// except for a "hid_device*"
|
180
|
+
// -------------------------------------------------------------------------
|
181
|
+
|
182
|
+
#include <unistd.h>
|
183
|
+
|
184
|
+
//
|
185
|
+
int blink1_getSerialNumber(hid_device *dev, char* buf)
|
186
|
+
{
|
187
|
+
if( dev == NULL ) return -1;
|
188
|
+
/*
|
189
|
+
wchar_t* wbuf = dev->serial_number;
|
190
|
+
int i=0;
|
191
|
+
while( wbuf ) {
|
192
|
+
buf[i++] = *wbuf;
|
193
|
+
}
|
194
|
+
return i;
|
195
|
+
*/
|
196
|
+
return -1;
|
197
|
+
}
|
198
|
+
|
199
|
+
//
|
200
|
+
int blink1_getVersion(hid_device *dev)
|
201
|
+
{
|
202
|
+
char buf[9] = {blink1_report_id, 'v' };
|
203
|
+
int len = sizeof(buf);
|
204
|
+
|
205
|
+
//hid_set_nonblocking(dev, 0);
|
206
|
+
int rc = blink1_write(dev, buf, sizeof(buf));
|
207
|
+
blink1_sleep( 50 ); //FIXME:
|
208
|
+
if( rc != -1 ) // no error
|
209
|
+
rc = blink1_read(dev, buf, len);
|
210
|
+
if( rc != -1 ) // also no error
|
211
|
+
rc = ((buf[3]-'0') * 100) + (buf[4]-'0');
|
212
|
+
// rc is now version number or error
|
213
|
+
// FIXME: we don't know vals of errcodes
|
214
|
+
return rc;
|
215
|
+
}
|
216
|
+
|
217
|
+
//
|
218
|
+
int blink1_eeread(hid_device *dev, uint16_t addr, uint8_t* val)
|
219
|
+
{
|
220
|
+
char buf[9] = {blink1_report_id, 'e', addr };
|
221
|
+
int len = sizeof(buf);
|
222
|
+
|
223
|
+
int rc = blink1_write(dev, buf, len );
|
224
|
+
blink1_sleep( 50 ); // FIXME:
|
225
|
+
if( rc != -1 ) // no error
|
226
|
+
rc = blink1_read(dev, buf, len );
|
227
|
+
if( rc != -1 )
|
228
|
+
*val = buf[3];
|
229
|
+
return rc;
|
230
|
+
}
|
231
|
+
|
232
|
+
//
|
233
|
+
int blink1_eewrite(hid_device *dev, uint16_t addr, uint8_t val)
|
234
|
+
{
|
235
|
+
char buf[9] = {blink1_report_id, 'E', addr, val };
|
236
|
+
|
237
|
+
int rc = blink1_write(dev, buf, sizeof(buf) );
|
238
|
+
|
239
|
+
return rc;
|
240
|
+
}
|
241
|
+
|
242
|
+
// FIXME: this doesn't work
|
243
|
+
int blink1_serialnumread(hid_device *dev, uint8_t** serialnum)
|
244
|
+
{
|
245
|
+
int rc = 0;
|
246
|
+
for( int i=0; i<blink1_serialnum_len; i++ ) { // serial num is 8 chars long
|
247
|
+
//blink1_eeread( dev, blink1_eeaddr_serialnum+i, (serialnum+i) );
|
248
|
+
}
|
249
|
+
return rc;
|
250
|
+
}
|
251
|
+
|
252
|
+
//
|
253
|
+
static uint8_t parseHex(char c)
|
254
|
+
{
|
255
|
+
c = toupper(c);
|
256
|
+
if (c >= '0' && c <= '9') return (c - '0');
|
257
|
+
if (c >= 'A' && c <= 'F') return (c - 'A')+10;
|
258
|
+
return 0;
|
259
|
+
}
|
260
|
+
|
261
|
+
// serialnum comes in as an ascii set of 8 characters representing
|
262
|
+
// 4-bytes
|
263
|
+
int blink1_serialnumwrite(hid_device *dev, uint8_t* serialnumstr)
|
264
|
+
{
|
265
|
+
uint8_t serialnum[4];
|
266
|
+
serialnum[0] = parseHex( serialnumstr[0] )*16 + parseHex( serialnumstr[1] );
|
267
|
+
serialnum[1] = parseHex( serialnumstr[2] )*16 + parseHex( serialnumstr[3] );
|
268
|
+
serialnum[2] = parseHex( serialnumstr[4] )*16 + parseHex( serialnumstr[5] );
|
269
|
+
serialnum[3] = parseHex( serialnumstr[6] )*16 + parseHex( serialnumstr[7] );
|
270
|
+
|
271
|
+
int rc = 0;
|
272
|
+
for( int i=0; i<blink1_serialnum_len; i++ ) { // serialnum is 4 chars long
|
273
|
+
blink1_sleep(50); //FIXME:
|
274
|
+
uint8_t v = serialnum[i];
|
275
|
+
int rc = blink1_eewrite( dev, blink1_eeaddr_serialnum+i, v);
|
276
|
+
if( rc == -1 ) { // try again
|
277
|
+
LOG("blink1_serialwrite: oops, trying again on char %d\n",i);
|
278
|
+
rc = blink1_eewrite(dev,blink1_eeaddr_serialnum+i, v);
|
279
|
+
if( rc == -1 ) {
|
280
|
+
LOG("blink1_serialwrite: error on try again\n");
|
281
|
+
break;
|
282
|
+
}
|
283
|
+
}
|
284
|
+
|
285
|
+
}
|
286
|
+
return rc;
|
287
|
+
}
|
288
|
+
|
289
|
+
|
290
|
+
//
|
291
|
+
int blink1_fadeToRGB(hid_device *dev, uint16_t fadeMillis,
|
292
|
+
uint8_t r, uint8_t g, uint8_t b)
|
293
|
+
{
|
294
|
+
int dms = fadeMillis/10; // millis_divided_by_10
|
295
|
+
|
296
|
+
char buf[9];
|
297
|
+
|
298
|
+
buf[0] = blink1_report_id; // report id
|
299
|
+
buf[1] = 'c'; // command code for 'fade to rgb'
|
300
|
+
buf[2] = ((blink1_enable_degamma) ? blink1_degamma(r) : r );
|
301
|
+
buf[3] = ((blink1_enable_degamma) ? blink1_degamma(g) : g );
|
302
|
+
buf[4] = ((blink1_enable_degamma) ? blink1_degamma(b) : b );
|
303
|
+
buf[5] = (dms >> 8);
|
304
|
+
buf[6] = dms % 0xff;
|
305
|
+
|
306
|
+
int rc = blink1_write(dev, buf, sizeof(buf) );
|
307
|
+
|
308
|
+
return rc;
|
309
|
+
}
|
310
|
+
|
311
|
+
//
|
312
|
+
int blink1_setRGB(hid_device *dev, uint8_t r, uint8_t g, uint8_t b )
|
313
|
+
{
|
314
|
+
char buf[9];
|
315
|
+
|
316
|
+
buf[0] = blink1_report_id; // report id
|
317
|
+
buf[1] = 'n'; // command code for "set rgb now"
|
318
|
+
buf[2] = ((blink1_enable_degamma) ? blink1_degamma(r) : r ); // red
|
319
|
+
buf[3] = ((blink1_enable_degamma) ? blink1_degamma(g) : g ); // grn
|
320
|
+
buf[4] = ((blink1_enable_degamma) ? blink1_degamma(b) : b ); // blu
|
321
|
+
|
322
|
+
int rc = blink1_write(dev, buf, sizeof(buf) );
|
323
|
+
|
324
|
+
return rc;
|
325
|
+
}
|
326
|
+
|
327
|
+
|
328
|
+
//
|
329
|
+
int blink1_serverdown(hid_device *dev, uint8_t on, uint16_t millis)
|
330
|
+
{
|
331
|
+
int dms = millis/10; // millis_divided_by_10
|
332
|
+
|
333
|
+
char buf[9] = {blink1_report_id, 'D', on, (dms>>8), (dms % 0xff) };
|
334
|
+
|
335
|
+
int rc = blink1_write(dev, buf, sizeof(buf) );
|
336
|
+
return rc;
|
337
|
+
}
|
338
|
+
|
339
|
+
//
|
340
|
+
int blink1_play(hid_device *dev, uint8_t play, uint8_t pos)
|
341
|
+
{
|
342
|
+
char buf[9] = {blink1_report_id, 'p', play, pos };
|
343
|
+
int rc = blink1_write(dev, buf, sizeof(buf) );
|
344
|
+
return rc;
|
345
|
+
}
|
346
|
+
|
347
|
+
//
|
348
|
+
int blink1_writePatternLine(hid_device *dev, uint16_t fadeMillis,
|
349
|
+
uint8_t r, uint8_t g, uint8_t b,
|
350
|
+
uint8_t pos)
|
351
|
+
{
|
352
|
+
int dms = fadeMillis/10; // millis_divided_by_10
|
353
|
+
r = (blink1_enable_degamma) ? blink1_degamma(r) : r ;
|
354
|
+
g = (blink1_enable_degamma) ? blink1_degamma(g) : g ;
|
355
|
+
b = (blink1_enable_degamma) ? blink1_degamma(b) : b ;
|
356
|
+
char buf[9] = {blink1_report_id, 'P', r,g,b, (dms>>8), (dms % 0xff), pos };
|
357
|
+
int rc = blink1_write(dev, buf, sizeof(buf) );
|
358
|
+
return rc;
|
359
|
+
}
|
360
|
+
|
361
|
+
//
|
362
|
+
int blink1_readPatternLine(hid_device *dev, uint16_t* fadeMillis,
|
363
|
+
uint8_t* r, uint8_t* g, uint8_t* b,
|
364
|
+
uint8_t pos)
|
365
|
+
{
|
366
|
+
char buf[9] = {blink1_report_id, 'R', 0,0,0, 0,0, pos };
|
367
|
+
int rc = blink1_write(dev, buf, sizeof(buf) );
|
368
|
+
blink1_sleep( 50 ); // FIXME:
|
369
|
+
if( rc != -1 ) // no error
|
370
|
+
rc = blink1_read(dev, buf, sizeof(buf) );
|
371
|
+
if( rc != -1 ) {
|
372
|
+
*r = buf[2];
|
373
|
+
*g = buf[3];
|
374
|
+
*b = buf[4];
|
375
|
+
*fadeMillis = ((buf[5]<<8) + (buf[6] &0xff)) * 10;
|
376
|
+
}
|
377
|
+
return rc;
|
378
|
+
}
|
379
|
+
|
380
|
+
|
381
|
+
// FIXME:
|
382
|
+
int readUUID( hid_device* dev, uint8_t** uuid )
|
383
|
+
{
|
384
|
+
return -1;
|
385
|
+
}
|
386
|
+
// FIXME:
|
387
|
+
int setUUID( hid_device* dev, uint8_t* uuid )
|
388
|
+
{
|
389
|
+
return -1;
|
390
|
+
}
|
391
|
+
|
392
|
+
|
393
|
+
/* ------------------------------------------------------------------------- */
|
394
|
+
|
395
|
+
// FIXME: this is wrong
|
396
|
+
// FIXME: provide function that generated this
|
397
|
+
uint8_t degamma_lookup[256] = {
|
398
|
+
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
|
399
|
+
1,1,1,1,1,1,2,2,2,2,2,3,3,3,3,4,
|
400
|
+
4,4,4,5,5,5,5,6,6,6,7,7,7,8,8,9,
|
401
|
+
9,9,10,10,11,11,11,12,12,13,13,14,14,15,15,16,
|
402
|
+
16,17,17,18,18,19,19,20,20,21,22,22,23,23,24,25,
|
403
|
+
25,26,27,27,28,29,29,30,31,31,32,33,33,34,35,36,
|
404
|
+
36,37,38,39,40,40,41,42,43,44,44,45,46,47,48,49,
|
405
|
+
50,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,
|
406
|
+
65,66,67,68,69,70,71,72,73,74,75,76,77,79,80,81,
|
407
|
+
82,83,84,85,87,88,89,90,91,93,94,95,96,97,99,100,
|
408
|
+
101,102,104,105,106,108,109,110,112,113,114,116,117,118,120,121,
|
409
|
+
122,124,125,127,128,129,131,132,134,135,137,138,140,141,143,144,
|
410
|
+
146,147,149,150,152,153,155,156,158,160,161,163,164,166,168,169,
|
411
|
+
171,172,174,176,177,179,181,182,184,186,188,189,191,193,195,196,
|
412
|
+
198,200,202,203,205,207,209,211,212,214,216,218,220,222,224,225,
|
413
|
+
227,229,231,233,235,237,239,241,243,245,247,249,251,253,255,255,
|
414
|
+
};
|
415
|
+
|
416
|
+
void blink1_enableDegamma()
|
417
|
+
{
|
418
|
+
blink1_enable_degamma = 1;
|
419
|
+
}
|
420
|
+
void blink1_disableDegamma()
|
421
|
+
{
|
422
|
+
blink1_enable_degamma = 0;
|
423
|
+
}
|
424
|
+
|
425
|
+
// a simple logarithmic -> linear mapping as a sort of gamma correction
|
426
|
+
// maps from 0-255 to 0-255
|
427
|
+
static int blink1_degamma_log2lin( int n )
|
428
|
+
{
|
429
|
+
//return (int)(1.0* (n * 0.707 )); // 1/sqrt(2)
|
430
|
+
return (((1<<(n/32))-1) + ((1<<(n/32))*((n%32)+1)+15)/32);
|
431
|
+
}
|
432
|
+
|
433
|
+
//
|
434
|
+
int blink1_degamma( int n )
|
435
|
+
{
|
436
|
+
//return degamma_lookup[n];
|
437
|
+
return blink1_degamma_log2lin(n);
|
438
|
+
}
|
439
|
+
|
440
|
+
|
441
|
+
// qsort C-string comparison function
|
442
|
+
int cmp_path(const void *a, const void *b)
|
443
|
+
{
|
444
|
+
return strncmp( (const char *)a, (const char *)b, pathstrmax);
|
445
|
+
}
|
446
|
+
// qsort wchar_t string comparison function
|
447
|
+
int cmp_serial(const void *a, const void *b)
|
448
|
+
{
|
449
|
+
return wcsncmp( (const wchar_t *)a, (const wchar_t *)b, serialmax);
|
450
|
+
}
|
451
|
+
|
452
|
+
//
|
453
|
+
void blink1_sortPaths(void)
|
454
|
+
{
|
455
|
+
size_t elemsize = sizeof( blink1_cached_paths[0] ); // 128
|
456
|
+
//size_t count = sizeof(blink1_cached_paths) / elemsize; // 16
|
457
|
+
|
458
|
+
return qsort( blink1_cached_paths, blink1_cached_count,elemsize,cmp_path);
|
459
|
+
}
|
460
|
+
|
461
|
+
//
|
462
|
+
void blink1_sortSerials(void)
|
463
|
+
{
|
464
|
+
size_t elemsize = sizeof( blink1_cached_serials[0] ); //
|
465
|
+
//size_t count = sizeof(blink1_cached_serials) / elemsize; //
|
466
|
+
|
467
|
+
qsort( blink1_cached_serials,
|
468
|
+
blink1_cached_count,
|
469
|
+
elemsize,
|
470
|
+
cmp_serial);
|
471
|
+
}
|
472
|
+
|
473
|
+
//
|
474
|
+
int blink1_vid(void)
|
475
|
+
{
|
476
|
+
uint8_t rawVid[2] = {USB_CFG_VENDOR_ID};
|
477
|
+
int vid = rawVid[0] + 256 * rawVid[1];
|
478
|
+
return vid;
|
479
|
+
}
|
480
|
+
//
|
481
|
+
int blink1_pid(void)
|
482
|
+
{
|
483
|
+
uint8_t rawPid[2] = {USB_CFG_DEVICE_ID};
|
484
|
+
int pid = rawPid[0] + 256 * rawPid[1];
|
485
|
+
return pid;
|
486
|
+
}
|
487
|
+
|
488
|
+
// simple cross-platform millis sleep func
|
489
|
+
void blink1_sleep(uint16_t millis)
|
490
|
+
{
|
491
|
+
#ifdef WIN32
|
492
|
+
Sleep(millis);
|
493
|
+
#else
|
494
|
+
usleep( millis * 1000);
|
495
|
+
#endif
|
496
|
+
}
|
497
|
+
|
498
|
+
//
|
499
|
+
char *blink1_error_msg(int errCode)
|
500
|
+
{
|
501
|
+
/*
|
502
|
+
static char buf[80];
|
503
|
+
|
504
|
+
switch(errCode){
|
505
|
+
case USBOPEN_ERR_ACCESS: return "Access to device denied";
|
506
|
+
case USBOPEN_ERR_NOTFOUND: return "The specified device was not found";
|
507
|
+
case USBOPEN_ERR_IO: return "Communication error with device";
|
508
|
+
default:
|
509
|
+
sprintf(buf, "Unknown USB error %d", errCode);
|
510
|
+
return buf;
|
511
|
+
}
|
512
|
+
*/
|
513
|
+
return NULL; /* not reached */
|
514
|
+
}
|
515
|
+
|
516
|
+
|
517
|
+
/*
|
518
|
+
|
519
|
+
//
|
520
|
+
int blink1_nightlight(hid_device *dev, uint8_t on)
|
521
|
+
{
|
522
|
+
char buf[9] = { blink1_report_id, 'N', on };
|
523
|
+
|
524
|
+
int rc = blink1_write(dev, buf, sizeof(buf) );
|
525
|
+
|
526
|
+
return rc;
|
527
|
+
}
|
528
|
+
|
529
|
+
|
530
|
+
//
|
531
|
+
int blink1_command(hid_device* dev, int num_send, int num_recv,
|
532
|
+
uint8_t* buf_send, uint8_t* buf_recv )
|
533
|
+
{
|
534
|
+
if( dev==NULL ) {
|
535
|
+
return -1; // BLINK1_ERR_NOTOPEN;
|
536
|
+
}
|
537
|
+
int err = 0;
|
538
|
+
if( (err = usbhidSetReport(dev, (char*)buf_send, num_send)) != 0) {
|
539
|
+
fprintf(stderr,"error writing data: %s\n",blink1_error_msg(err));
|
540
|
+
return err;
|
541
|
+
}
|
542
|
+
|
543
|
+
if( num_recv > 0 ) {
|
544
|
+
int len = num_recv;
|
545
|
+
if((err = usbhidGetReport(dev, 0, (char*)buf_recv, &len)) != 0) {
|
546
|
+
fprintf(stderr,"error reading data: %s\n",blink1_error_msg(err));
|
547
|
+
} else { // it was good
|
548
|
+
}
|
549
|
+
}
|
550
|
+
return err;
|
551
|
+
}
|
552
|
+
*/
|
@@ -0,0 +1,83 @@
|
|
1
|
+
/*
|
2
|
+
* blink(1) C library --
|
3
|
+
*
|
4
|
+
* 2012, Tod E. Kurt, http://todbot.com/blog/ , http://thingm.com/
|
5
|
+
*
|
6
|
+
*/
|
7
|
+
|
8
|
+
|
9
|
+
#ifndef __BLINK1_LIB_H__
|
10
|
+
#define __BLINK1_LIB_H__
|
11
|
+
|
12
|
+
#include <stdint.h>
|
13
|
+
|
14
|
+
#include "hidapi.h"
|
15
|
+
#include "usbconfig.h" // from firmware, for VID,PID,vendor name & product name
|
16
|
+
|
17
|
+
#ifdef __cplusplus
|
18
|
+
extern "C" {
|
19
|
+
#endif
|
20
|
+
|
21
|
+
#define blink1_max_devices 16
|
22
|
+
|
23
|
+
|
24
|
+
int blink1_vid(void);
|
25
|
+
int blink1_pid(void);
|
26
|
+
void blink1_sortPaths(void);
|
27
|
+
void blink1_sortSerials(void);
|
28
|
+
|
29
|
+
int blink1_enumerate();
|
30
|
+
int blink1_enumerateByVidPid(int vid, int pid);
|
31
|
+
const char* blink1_getCachedPath(int i);
|
32
|
+
const wchar_t* blink1_getCachedSerial(int i);
|
33
|
+
int blink1_getCachedCount(void);
|
34
|
+
|
35
|
+
hid_device* blink1_open(void);
|
36
|
+
hid_device* blink1_openByPath(const char* path);
|
37
|
+
hid_device* blink1_openBySerial(const wchar_t* serial);
|
38
|
+
hid_device* blink1_openById( int i );
|
39
|
+
|
40
|
+
void blink1_close( hid_device* dev );
|
41
|
+
|
42
|
+
int blink1_write( hid_device* dev, void* buf, int len);
|
43
|
+
int blink1_read( hid_device* dev, void* buf, int len);
|
44
|
+
|
45
|
+
int blink1_getSerialNumber(hid_device *dev, char* buf);
|
46
|
+
int blink1_getVersion(hid_device *dev);
|
47
|
+
|
48
|
+
int blink1_fadeToRGB(hid_device *dev, uint16_t fadeMillis,
|
49
|
+
uint8_t r, uint8_t g, uint8_t b );
|
50
|
+
|
51
|
+
int blink1_setRGB(hid_device *dev, uint8_t r, uint8_t g, uint8_t b );
|
52
|
+
|
53
|
+
int blink1_eeread(hid_device *dev, uint16_t addr, uint8_t* val);
|
54
|
+
int blink1_eewrite(hid_device *dev, uint16_t addr, uint8_t val);
|
55
|
+
|
56
|
+
int blink1_serialnumread(hid_device *dev, uint8_t** serialnumstr);
|
57
|
+
int blink1_serialnumwrite(hid_device *dev, uint8_t* serialnumstr);
|
58
|
+
|
59
|
+
//int blink1_nightlight(hid_device *dev, uint8_t on);
|
60
|
+
int blink1_serverdown(hid_device *dev, uint8_t on, uint16_t millis);
|
61
|
+
|
62
|
+
int blink1_play(hid_device *dev, uint8_t play, uint8_t pos);
|
63
|
+
int blink1_writePatternLine(hid_device *dev, uint16_t fadeMillis,
|
64
|
+
uint8_t r, uint8_t g, uint8_t b,
|
65
|
+
uint8_t pos);
|
66
|
+
int blink1_readPatternLine(hid_device *dev, uint16_t* fadeMillis,
|
67
|
+
uint8_t* r, uint8_t* g, uint8_t* b,
|
68
|
+
uint8_t pos);
|
69
|
+
//int blink1_playPattern(hid_device *dev,,);
|
70
|
+
|
71
|
+
char *blink1_error_msg(int errCode);
|
72
|
+
|
73
|
+
void blink1_enableDegamma();
|
74
|
+
void blink1_disableDegamma();
|
75
|
+
int blink1_degamma(int n);
|
76
|
+
|
77
|
+
void blink1_sleep(uint16_t delayMillis);
|
78
|
+
|
79
|
+
#ifdef __cplusplus
|
80
|
+
}
|
81
|
+
#endif
|
82
|
+
|
83
|
+
#endif
|