1 /**
2  * Barebones C wrapper for the blink(1) C library.
3  *
4  * blink(1) C library -- aka "blink1-lib"
5  *
6  * Part of the blink(1) open source hardware project
7  * See https://github.com/todbot/blink1 for details
8  *
9  * 2012-2014, Tod E. Kurt, http://todbot.com/blog/ , http://thingm.com/
10  *
11  */
12 
13 module blink1.clib;
14 
15 // Provides FILE pointer
16 import core.stdc.stdio : FILE;
17 
18 
19 extern (C) {
20 
21 immutable int blink1_max_devices = 32;
22 
23 immutable int cache_max = blink1_max_devices;
24 //#define cache_max 16
25 immutable int serialstrmax = 8 + 1;
26 immutable int pathstrmax = 1024;
27 
28 immutable int blink1mk2_serialstart = 0x20000000;
29 immutable int blink1mk3_serialstart = 0x30000000;
30 
31 immutable int BLINK1_VENDOR_ID = 0x27B8; /* = 0x27B8 = 10168 = thingm */
32 immutable int BLINK1_DEVICE_ID = 0x01ED; /* = 0x01ED */
33 
34 immutable int blink1_report_id = 1;
35 immutable int blink1_report_size = 8;
36 immutable int blink1_report2_id = 2;
37 immutable int blink1_report2_size = 60;
38 immutable int blink1_buf_size = blink1_report_size + 1;
39 immutable int blink1_buf2_size = blink1_report2_size + 1;
40 
41 immutable int blink1_note_size = 50;
42 
43 /**
44  * Enumeration of supported blink(1) devices.
45  */
46 enum blink1Type_t {
47 	/// Unknown type
48     BLINK1_UNKNOWN = 0,
49     /// The original one from the kickstarter
50     BLINK1_MK1,   
51     /// The updated one with 2 LEDs
52     BLINK1_MK2,   
53     /// 2018 one based on EFM32HG
54     BLINK1_MK3
55 }
56 
57 // struct blink1_device_;
58 struct hid_device_;
59 alias hid_device = hid_device_;
60 
61 version(USE_HIDAPI) {
62 	/**< opaque blink1 structure */
63 	alias blink1_device = hid_device_; 
64 } else {
65 	version(USE_HIDDATA) {
66 		/**< opaque blink1 structure */
67 		alias blink1_device = usbDevice;
68 	} else {
69 		pragma(msg, "version identifier USE_HIDAPI or USE_HIDDATA wasn't defined, defaulting to USE_HIDAPI");
70 		/**< opaque blink1 structure */
71 		alias blink1_device = hid_device_; 
72 	}
73 }
74 
75 
76 //
77 // -------- BEGIN PUBLIC API ----------
78 //
79 
80 // you can define "extern int blink1_lib_verbose"
81 // and set it to "1" to enable low-level debugging
82 
83 /**
84  * Struct representing a RGB color.
85  */
86 struct rgb_t {
87     ubyte r; ubyte g; ubyte b;
88 }
89 
90 /***
91  * Struct representing a pattern line.
92  */
93 struct patternline_t {
94 	/// The color of this pattern.
95     rgb_t color;
96 	/// Time in milliseconds to transition towards this pattern.
97     ushort millis;
98     /// number of led, or 0 for all
99     ubyte ledn;
100 }
101 
102 
103 /**
104  * Scan USB for blink(1) devices.
105  * Returns: number of devices found
106  */
107 int          blink1_enumerate();
108 
109 /**
110  * Scan USB for devices by given VID,PID.
111  *
112  * Params:
113  *     vid = vendor ID
114  *     pid = product ID
115  *
116  * Returns: number of devices found
117  */
118 int          blink1_enumerateByVidPid(int vid, int pid);
119 
120 /**
121  * Open first found blink(1) device.
122  *
123  * Returns: pointer to opened [blink1_device] or NULL if no blink1 found
124  */
125 blink1_device* blink1_open();
126 
127 /**
128  * Open blink(1) by USB path.
129  *
130  * Note: this is platform-specific, and port-specific.
131  *
132  * Params:
133  *     path = string of platform-specific path to blink1
134  *
135  * Returns: [blink1_device] or NULL if no blink1 found
136  */
137 blink1_device* blink1_openByPath(const char* path);
138 
139 /**
140  * Open blink(1) by 8-digit serial number.
141  *
142  * Params:
143  *     serial = 8-hex digit serial number
144  *
145  * Returns: [blink1_device] or NULL if no blink1 found
146  */
147 blink1_device* blink1_openBySerial(const char* serial);
148 
149 /**
150  * Open by "id", which if from 0-[blink1_max_devices] is index
151  *  or if [blink1_max_devices], is numerical representation of serial number
152  *
153  * Params: 
154  *    id = ordinal 0-15 id of blink1 or numerical rep of 8-hex digit serial
155  * Returns: blink1_device or NULL if no blink1 found
156  */
157 blink1_device* blink1_openById(uint id );
158 
159 
160 /**
161  * Close opened blink1 device.
162  *
163  * Safe to call blink1_close on already closed device.
164  *
165  * Params:
166  *     dev = blink1_device
167  */
168 void blink1_close_internal( blink1_device* dev );
169 
170 /**
171  * Low-level write to blink1 device.
172  *
173  * Used internally by blink1-lib
174  */
175 int blink1_write( blink1_device* dev, void* buf, int len);
176 /**
177  * Low-level read from blink1 device.
178  *
179  * Used internally by blink1-lib
180  */
181 int blink1_read( blink1_device* dev, void* buf, int len);
182 
183 int blink1_read_nosend( blink1_device* dev, void* buf, int len);
184 
185 /**
186  * Get blink1 firmware version.
187  *
188  * Params:
189  *     dev = opened blink1 device
190  * Returns: version as scaled int number (e.g. "v1.1" = 101)
191  */
192 int blink1_getVersion(blink1_device *dev);
193 
194 /**
195  * Fade blink1 to given RGB color over specified time.
196  *
197  * Params:
198  *     dev = blink1 device to command
199  *     fadeMillis = time to fade in milliseconds
200  *     r = red part of RGB color
201  *     g = green part of RGB color
202  *     b = blue part of RGB color
203  *
204  * Returns: -1 on error, 0 on success
205  */
206 int blink1_fadeToRGB(blink1_device *dev, ushort fadeMillis,
207                      ubyte r, ubyte g, ubyte b );
208 
209 /**
210  * Fade specific LED on blink1mk2 to given RGB color over specified time.
211  *
212  * For mk2 devices and above..
213  *
214  * Params:
215  *     dev = blink1 device to command
216  *     fadeMillis = time to fade in milliseconds
217  *     r = red part of RGB color
218  *     g = green part of RGB color
219  *     b = blue part of RGB color
220  *     n = which LED to address (0=all, 1=1st LED, 2=2nd LED)
221  *
222  * Returns: -1 on error, 0 on success
223  */
224 int blink1_fadeToRGBN(blink1_device *dev, ushort fadeMillis,
225                       ubyte r, ubyte g, ubyte b, ubyte n );
226 /**
227  * Set blink1 immediately to a specific RGB color.
228  *
229  * If mk2 or above, sets all LEDs immediately
230  *
231  * Params:
232  *     dev = blink1 device to command
233  *     r = red part of RGB color
234  *     g = green part of RGB color
235  *     b = blue part of RGB color
236  *
237  * Returns: -1 on error, 0 on success
238  */
239 int blink1_setRGB(blink1_device *dev, ubyte r, ubyte g, ubyte b );
240 
241 /**
242  * Read current RGB value on specified LED.
243  *
244  * For mk2 devices or above.
245  *
246  * Params:
247  *     dev = blink1 device to command
248  *     r = pointer to red part of RGB color
249  *     g = pointer to green part of RGB color
250  *     b = pointer to blue part of RGB color
251  *     n = which LED to get (0=1st, 1=1st LED, 2=2nd LED)
252  * Returns: -1 on error, 0 on success
253  */
254 int blink1_readRGB(blink1_device *dev, ushort* fadeMillis,
255                    ubyte* r, ubyte* g, ubyte* b,
256                    ubyte ledn);
257 /**
258  * Attempt to read current RGB value for mk1 devices.
259  *
260  * Called by blink1_setRGB() if device is mk1.
261  * Does not always work.
262  *
263  * Params:
264  *     dev = blink1 device to command
265  *     r = pointer to red part of RGB color
266  *     g = pointer to green part of RGB color
267  *     b = pointer to blue part of RGB color
268  *
269  * Returns: -1 on error, 0 on success
270  */
271 int blink1_readRGB_mk1(blink1_device *dev, ushort* fadeMillis,
272                        ubyte* r, ubyte* g, ubyte* b);
273 
274 /**
275  * Read eeprom on mk1 devices
276  *
277  * For mk1 devices only
278  */
279 int blink1_eeread(blink1_device *dev, ushort addr, ubyte* val);
280 /**
281  * Write eeprom on mk1 devices
282  *
283  * For mk1 devices only
284  */
285 int blink1_eewrite(blink1_device *dev, ushort addr, ubyte val);
286 
287 /**
288  * Read serial number from mk1 device. Does not work.
289  *
290  * Note: Use USB descriptor serial number instead.
291  * Note: for mk1 devices only.
292  * Note: does not work.
293  */
294 int blink1_serialnumread(blink1_device *dev, ubyte** serialnumstr);
295 /**
296  * Write serial number to mk1 device. Does not work.
297  *
298  * For mk1 devices only.
299  * Does not work.
300  */
301 int blink1_serialnumwrite(blink1_device *dev, ubyte* serialnumstr);
302 
303 /**
304  * Tickle blink1 serverdown functionality.
305  *
306  * 'st' param for mk2 firmware only
307  *
308  * Params:
309  *     on  = enable or disable: enable=1, disable=0
310  *     millis = milliseconds to wait until triggering (up to 65,355 millis)
311  *     stay = lit (st=1) or set off() (st=0)
312  *     startpos = pattern start position (fw 205+)
313  *     endpos = pattern end pos (fw 205+)
314  */
315 int blink1_serverdown(blink1_device *dev, ubyte on, ushort millis,
316                       ubyte st, ubyte startpos, ubyte endpos);
317 
318 /**
319  * Play color pattern stored in blink1.
320  *
321  * Params:
322  *     dev = blink1 device to command
323  *     play = boolean: 1=play, 0=stop
324  *     pos = position to start playing from
325  * Retruns: -1 on error, 0 on success
326  */
327 int blink1_play(blink1_device *dev, ubyte play, ubyte pos);
328 
329 /**
330  * Play color pattern stored in blink1mk2.
331  *
332  * For mk2 devices only.
333  *
334  * Params:
335  *     dev = blink1 device to command
336  *     play = boolean: 1=play, 0=stop
337  *     startpos = position to start playing from
338  *     endpos = position to end playing
339  *     count = number of times to play (0=forever)
340  *
341  * Returns: -1 on error, 0 on success
342  */
343 int blink1_playloop(blink1_device *dev, ubyte play, ubyte startpos, ubyte endpos, ubyte count);
344 
345 /**
346  * Read the current state of a playing pattern.
347  *
348  * For mk2 devices only.
349  *
350  * Params:
351  *     dev = blink1 device to command
352  *     playing = pointer to play/stop boolean
353  *     playstart = pointer to start position
354  *     playend = pointer to end position
355  *     playcount = pointer to count left
356  *     playpos = pointer to play position
357  *
358  * Returns: -1 on error, 0 on success
359  */
360 int blink1_readPlayState(blink1_device *dev, ubyte * playing,
361                          ubyte* playstart, ubyte* playend,
362                          ubyte* playcount, ubyte* playpos);
363 
364 /**
365  * Write a color pattern line to blink1.
366  *
367  * On mk1 devices, this saves the pattern line to nonvolatile storage.
368  * On mk2 devices and above, this only saves to RAM (see savePattern() for nonvol).
369  *
370  * Params:
371  *     dev = blink1 device to command
372  *     r = red part of RGB color
373  *     g = green part of RGB color
374  *     b = blue part of RGB color
375  *     pos = pattern line number 0-max_patt (FIXME: put note about this)
376  * Returns: -1 on error, 0 on success
377  */
378 int blink1_writePatternLine(blink1_device *dev, ushort fadeMillis,
379                             ubyte r, ubyte g, ubyte b,
380                             ubyte pos);
381 /**
382  * Read a color pattern line to blink1.
383  *
384  * Params:
385  *     dev = blink1 device to command
386  *     fadeMillis = pointer to milliseconds to fade to RGB color
387  *     r = pointer to store red color component
388  *     g = pointer to store green color component
389  *     b = pointer to store blue color component
390  * Returns: -1 on error, 0 on success
391  */
392 int blink1_readPatternLine(blink1_device *dev, ushort* fadeMillis,
393                            ubyte* r, ubyte* g, ubyte* b,
394                            ubyte pos);
395 /**
396  * Read a color pattern line to blink1.
397  * ledn param only works on fw204+ devices
398  *
399  * Params:
400  *     dev = blink1 device to command
401  *     fadeMillis = pointer to milliseconds to fade to RGB color
402  *     r = pointer to store red color component
403  *     g = pointer to store green color component
404  *     b = pointer to store blue color component
405  *     ledn = pointer to store led number
406  *     pos = pattern line number 0-max-patt
407  *
408  * Returns: -1 on error, 0 on success
409  */
410 int blink1_readPatternLineN(blink1_device *dev, ushort* fadeMillis,
411                             ubyte* r, ubyte* g, ubyte* b, ubyte* ledn,
412                             ubyte pos);
413 /**
414  * Save color pattern in RAM to nonvolatile storage.
415  *
416  * For mk2 devices and above.
417  * Note this doesn't actually return a proper return value, as the
418  *       time it takes to write to flash actually exceeds USB timeout
419  * Params:
420  *     dev = blink1 device to command
421  *
422  * Returns: -1 on error, 0 on success
423  */
424 int blink1_savePattern(blink1_device *dev);
425 
426 /**
427  * Sets 'ledn' parameter for blink1_savePatternLine()
428  *
429  * Only works on fw 204+ devices
430  */
431 int blink1_setLEDN( blink1_device* dev, ubyte ledn);
432 
433 /**
434  * @note only for devices with fw val 206+ or mk3
435  */
436 int blink1_getStartupParams( blink1_device* dev, ubyte* bootmode,
437                              ubyte* playstart, ubyte* playend, ubyte* playcount);
438 
439 /**
440  * Only for devices with fw val 206+ or mk3
441  * FIXME: make 'params' a struct
442  */
443 int blink1_setStartupParams( blink1_device* dev, ubyte bootmode,
444                              ubyte playstart, ubyte playend, ubyte playcount);
445 
446 /**
447  * Tell blink(1) to reset into bootloader.
448  *
449  * mk3 devices only
450  */
451 int blink1_bootloaderGo( blink1_device* dev );
452 
453 int blink1_bootloaderLock( blink1_device* dev );
454 
455 /**
456  * Internal testing
457  */
458 int blink1_getId( blink1_device *dev, ubyte** idbuf );
459 
460 int blink1_testtest(blink1_device *dev, ubyte reportid);
461 
462 
463 /// reads from notebuf
464 int blink1_writeNote( blink1_device* dev, ubyte noteid, const ubyte* notebuf);
465 
466 /// writes into notebuf
467 int blink1_readNote( blink1_device* dev, ubyte noteid, ubyte** notebuf);
468 
469 
470 char *blink1_error_msg(int errCode);
471 
472 /**
473  * Enable blink1-lib gamma curve.
474  */
475 void blink1_enableDegamma();
476 
477 /**
478  * Disable blink1-lib gamma curve.
479  * @note should probably always have it disabled
480  */
481 void blink1_disableDegamma();
482 int blink1_degamma(int n);
483 
484 /**
485  * Using a brightness value, update an r,g,b triplet
486  * Modifies r,g,b in place
487  */
488 void blink1_adjustBrightness( ubyte brightness, ubyte* r, ubyte* g, ubyte* b);
489 
490 /**
491  * Simple wrapper for cross-platform millisecond delay.
492  *
493  * Params:
494  *     delayMillis = number of milliseconds to wait
495  */
496 void blink1_sleep(ushort delayMillis);
497 
498 /**
499  * Vendor ID for blink1 devices.
500  *
501  * Returns: blink1 VID
502  */
503 int blink1_vid();  // return VID for blink(1)
504 /**
505  * Product ID for blink1 devices.
506  *
507  * Returns: blink1 PID
508  */
509 int blink1_pid();  // return PID for blink(1)
510 
511 
512 /**
513  * Return platform-specific USB path for given cache index.
514  *
515  * Params:
516  *     i = cache index
517  *
518  * Returns: path string
519  */
520 char*  blink1_getCachedPath(int i);
521 /**
522  * Return bilnk1 serial number for given cache index.
523  *
524  * Params:
525  *     i = cache index
526  *
527  * Returns: 8-hexdigit serial number as string
528  */
529 char*  blink1_getCachedSerial(int i);
530 /**
531  * Return cache index for a given platform-specific USB path.
532  *
533  * Params:
534  *     path = platform-specific path string
535  *
536  * Returns: cache index or -1 if not found
537  */
538 int          blink1_getCacheIndexByPath( const char* path );
539 /**
540  * Return cache index for a given blink1 id (0-max or serial number as uint32)
541  *
542  * Params:
543  *     i = blink1 id (0-blink1_max_devices or serial as uint32)
544  *
545  * Returns: cache index or -1 if not found
546  */
547 int          blink1_getCacheIndexById( ushort i );
548 /**
549  * Return cache index for a given blink1 serial number.
550  *
551  * Params:
552  *     path = platform-specific path string
553  *
554  * Returns: cache index or -1 if not found
555  */
556 int          blink1_getCacheIndexBySerial( const char* serial );
557 /**
558  * Return cache index for a given blink1_device object.
559  *
560  * Params:
561  *     dev = blink1 device to lookup
562  *
563  * Returns: cache index or -1 if not found
564  */
565 int          blink1_getCacheIndexByDev( blink1_device* dev );
566 /**
567  * Clear the blink1 device cache for a given device.
568  *
569  * Params:
570  *     dev = blink1 device
571  *
572  * Returns: cache index that was cleared, or -1 if not found
573  */
574 int          blink1_clearCacheDev( blink1_device* dev );
575 
576 /**
577  * Return serial number string for give blink1 device.
578  * 
579  * Params:
580  *     dev = blink device to lookup
581  *
582  * Returns: 8-hexdigit serial number string
583  */
584 char*  blink1_getSerialForDev(blink1_device* dev);
585 
586 /**
587  * Return number of entries in blink1 device cache.
588  *
589  * note This is the number of devices found with blink1_enumerate()
590  *
591  * Returns: number of cache entries
592  */
593 int          blink1_getCachedCount();
594 
595 /**
596  * Returns version of device at cache index i is a mk2
597  *
598  * Returns: mk2=1, mk1=0
599  */
600 int          blink1_isMk2ById(int i);
601 
602 /**
603  * Returns if given blink1_device is a mk2 or not
604  *
605  * Params:
606  *     dev = blink1 device to check
607  * Returns: mk2=1, mk1=0
608  */
609 int          blink1_isMk2(blink1_device* dev);
610 
611 /**
612  * Returns device "mk" type at cache index i
613  *
614  * Returns: blink1Type_t (BLINK1_MK2, BLINK1_MK2, BLINK1_MK1)
615  */
616 blink1Type_t blink1_deviceTypeById( int i );
617 
618 /**
619  *
620  * Returns: blink1Type_t (BLINK1_MK2, BLINK1_MK2, BLINK1_MK1)
621  */
622 blink1Type_t blink1_deviceType( blink1_device* dev );
623 
624 /**
625  * Return a string representation of the blink(1) device type
626  * (e.g. "mk2" or "mk3")
627  *
628  * Returns: const string
629  */
630 char* blink1_deviceTypeToStr(blink1Type_t t);
631 
632 /**
633  *
634  */
635 void hexdump(FILE* fp, ubyte* buffer, int len);
636 
637 /**
638  *
639  */
640 int hexread(ubyte *buffer, char* str, int buflen);
641 
642 /**
643  *
644  */
645 void hsbtorgb( rgb_t* rgb, ubyte* hsb );
646 
647 /**
648  *
649  */
650 void parsecolor(rgb_t* color, char* colorstr);
651 
652 /**
653  *
654  */
655 int parsePattern( char* str, int* repeats, patternline_t* pattern );
656 
657 /**
658  * printf that can be shut up
659  *
660  */
661 void msg(char* fmt, ...);
662 
663 void msg_setquiet(int q);
664 
665 }
666 
667 /*void blink1_close( blink1_device *dev) {
668 	blink1_close_internal(dev);
669 }*/