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 ADDED
File without changes
data/README.rdoc ADDED
@@ -0,0 +1 @@
1
+ = blink1.rb
data/Rakefile ADDED
@@ -0,0 +1,5 @@
1
+ require 'rake/testtask'
2
+ require 'rake/clean'
3
+
4
+ NAME = 'blink1'
5
+
@@ -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