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 }*/