Skip to content
Snippets Groups Projects
Select Git revision
  • cb53bd6270ef2ffa0c92f64da71e8cc133d50618
  • deploy default
  • main protected
  • v2.3.0
  • v2.2.0
  • v2.1.0
  • v2.0.5
  • v2.0.4
  • v2.0.3
  • v2.0.2
  • v2.0.1
  • v2.0.0
  • v1.98a
  • v1.98
  • v1.97
  • v1.96
  • v1.94
  • v1.95
  • v1.93
  • v1.91
  • v1.9
  • v1.83
  • v1.82
23 results

blink1-lib.h

Blame
  • user avatar
    Tod Kurt authored
    ee8c819b
    History
    blink1-lib.h 15.42 KiB
    /**
     * blink(1) C library -- aka "blink1-lib"
     *
     * Part of the blink(1) open source hardware project
     * See https://github.com/todbot/blink1 for details
     *
     * 2012-2022, Tod E. Kurt, http://todbot.com/blog/ , http://thingm.com/
     *
     */
    
    
    #ifndef __BLINK1_LIB_H__
    #define __BLINK1_LIB_H__
    
    #include <stdint.h>
    #include <stdio.h>
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    #define blink1_max_devices 32
    
    #define cache_max blink1_max_devices
    //#define cache_max 16
    #define serialstrmax (8 + 1)
    #define pathstrmax 1024
    
    #define blink1mk2_serialstart 0x20000000
    #define blink1mk3_serialstart 0x30000000
    
    #define  BLINK1_VENDOR_ID       0x27B8 /* = 0x27B8 = 10168 = thingm */
    #define  BLINK1_DEVICE_ID       0x01ED /* = 0x01ED */
    
    #define blink1_report_id  1
    #define blink1_report_size 8
    #define blink1_report2_id  2
    #define blink1_report2_size 60
    #define blink1_buf_size  (blink1_report_size+1)
    #define blink1_buf2_size (blink1_report2_size+1)
    
    #define blink1_note_size 50
    
    typedef enum  {
        BLINK1_UNKNOWN = 0,
        BLINK1_MK1,   // the original one from the kickstarter
        BLINK1_MK2,   // the updated one with 2 LEDs
        BLINK1_MK3    // 2018 one based on EFM32HG
    } blink1Type_t;
    
    struct blink1_device_;
    
    #if USE_HIDAPI
    typedef struct hid_device_ blink1_device; /**< opaque blink1 structure */
    #elif USE_HIDDATA
    typedef struct usbDevice   blink1_device; /**< opaque blink1 structure */
    #else
    #warning "USE_HIDAPI or USE_HIDDATA wasn't defined, defaulting to USE_HIDAPI"
    typedef struct hid_device_ blink1_device; /**< opaque blink1 structure */
    #endif
    
    
    //
    // -------- BEGIN PUBLIC API ----------
    //
    
    // Set blink1_lib_verbose to "1" to enable low-level debugging
    extern int blink1_lib_verbose;
    
    typedef struct {
        uint8_t r; uint8_t g; uint8_t b;
    } rgb_t;
    
    typedef struct {
        rgb_t color;
        uint16_t millis;
        uint8_t ledn;     // number of led, or 0 for all
    } patternline_t;
    
    /**
     * Scan USB for blink(1) devices.
     * @return number of devices found
     */
    int          blink1_enumerate();
    
    /**
     * Scan USB for devices by given VID,PID.
     * @param vid vendor ID
     * @param pid product ID
     * @return number of devices found
     */
    int          blink1_enumerateByVidPid(int vid, int pid);
    
    /**
     * Open first found blink(1) device.
     * @return pointer to opened blink1_device or NULL if no blink1 found
     */
    blink1_device* blink1_open(void);
    
    /**
     * Open blink(1) by USB path.
     * note: this is platform-specific, and port-specific.
     * @param path string of platform-specific path to blink1
     * @return blink1_device or NULL if no blink1 found
     */
    blink1_device* blink1_openByPath(const char* path);
    
    /**
     * Open blink(1) by 8-digit serial number.
     * @param serial 8-hex digit serial number
     * @return blink1_device or NULL if no blink1 found
     */
    blink1_device* blink1_openBySerial(const char* serial);
    
    /**
     * Open by "id", which if from 0-blink1_max_devices is index
     *  or if >blink1_max_devices, is numerical representation of serial number
     * @param id ordinal 0-15 id of blink1 or numerical rep of 8-hex digit serial
     * @return blink1_device or NULL if no blink1 found
     */
    blink1_device* blink1_openById( uint32_t id );
    
    /**
     * Close opened blink1 device
     * Safe to call blink1_close on already closed device.
     * This is macro so dev can get set to NULL
     * FIXME: is there a better way
     */
    #define blink1_close(dev) { blink1_close_internal(dev); dev=NULL; }
    
    /**
     * Close opened blink1 device.  (internal)
     * Safe to call blink1_close on already closed device.
     * @param dev blink1_device
     */
    void blink1_close_internal( blink1_device* dev );
    
    /**
     * Low-level write to blink1 device.
     * Used internally by blink1-lib
     */
    int blink1_write( blink1_device* dev, void* buf, int len);
    /**
     * Low-level read from blink1 device.
     * Used internally by blink1-lib
     */
    int blink1_read( blink1_device* dev, void* buf, int len);
    
    int blink1_read_nosend( blink1_device* dev, void* buf, int len);
    
    /**
     * Get blink1 firmware version.
     * @param dev opened blink1 device
     * @return version as scaled int number (e.g. "v1.1" = 101)
     */
    int blink1_getVersion(blink1_device *dev);
    
    /**
     * Fade blink1 to given RGB color over specified time.
     * @param dev blink1 device to command
     * @param fadeMillis time to fade in milliseconds
     * @param r red part of RGB color
     * @param g green part of RGB color
     * @param b blue part of RGB color
     * @return -1 on error, 0 on success
     */
    int blink1_fadeToRGB(blink1_device *dev, uint16_t fadeMillis,
                         uint8_t r, uint8_t g, uint8_t b );
    
    /**
     * Fade specific LED on blink1mk2 to given RGB color over specified time.
     * @note For mk2 devices.
     * @param dev blink1 device to command
     * @param fadeMillis time to fade in milliseconds
     * @param r red part of RGB color
     * @param g green part of RGB color
     * @param b blue part of RGB color
     * @param n which LED to address (0=all, 1=1st LED, 2=2nd LED)
     * @return -1 on error, 0 on success
     */
    int blink1_fadeToRGBN(blink1_device *dev, uint16_t fadeMillis,
                          uint8_t r, uint8_t g, uint8_t b, uint8_t n );
    /**
     * Set blink1 immediately to a specific RGB color.
     * @note If mk2, sets all LEDs immediately
     * @param dev blink1 device to command
     * @param r red part of RGB color
     * @param g green part of RGB color
     * @param b blue part of RGB color
     * @return -1 on error, 0 on success
     */
    int blink1_setRGB(blink1_device *dev, uint8_t r, uint8_t g, uint8_t b );
    
    /**
     * Read current RGB value on specified LED.
     * @note For mk2 devices only.
     * @param dev blink1 device to command
     * @param r pointer to red part of RGB color
     * @param g pointer to green part of RGB color
     * @param b pointer to blue part of RGB color
     * @param n which LED to get (0=1st, 1=1st LED, 2=2nd LED)
     * @return -1 on error, 0 on success
     */
    int blink1_readRGB(blink1_device *dev, uint16_t* fadeMillis,
                       uint8_t* r, uint8_t* g, uint8_t* b,
                       uint8_t ledn);
    /**
     * Attempt to read current RGB value for mk1 devices.
     * @note Called by blink1_setRGB() if device is mk1.
     * @note Does not always work.
     * @param dev blink1 device to command
     * @param r pointer to red part of RGB color
     * @param g pointer to green part of RGB color
     * @param b pointer to blue part of RGB color
     * @return -1 on error, 0 on success
     */
    int blink1_readRGB_mk1(blink1_device *dev, uint16_t* fadeMillis,
                           uint8_t* r, uint8_t* g, uint8_t* b);
    
    /**
     * Read eeprom on mk1 devices
     * @note For mk1 devices only
     */
    int blink1_eeread(blink1_device *dev, uint16_t addr, uint8_t* val);
    /**
     * Write eeprom on mk1 devices
     * @note For mk1 devices only
     */
    int blink1_eewrite(blink1_device *dev, uint16_t addr, uint8_t val);
    
    /**
     * Read serial number from mk1 device. Does not work.
     * @note Use USB descriptor serial number instead.
     * @note for mk1 devices only.
     * @note does not work.
     */
    int blink1_serialnumread(blink1_device *dev, uint8_t** serialnumstr);
    /**
     * Write serial number to mk1 device. Does not work.
     * @note for mk1 devices only.
     * @note does not work.
     */
    int blink1_serialnumwrite(blink1_device *dev, uint8_t* serialnumstr);
    
    /**
     * Tickle blink1 serverdown functionality.
     * @note 'st' param for mk2 firmware only
     * @param on  enable or disable: enable=1, disable=0
     * @param millis milliseconds to wait until triggering (up to 65,355 millis)
     * @param stay lit (st=1) or set off() (st=0)
     * @param startpos pattern start position (fw 205+)
     * @param endpos pattern end pos (fw 205+)
     */
    int blink1_serverdown(blink1_device *dev, uint8_t on, uint32_t millis,
                          uint8_t st, uint8_t startpos, uint8_t endpos);
    
    /**
     * Play color pattern stored in blink1.
     * @param dev blink1 device to command
     * @param play boolean: 1=play, 0=stop
     * @param pos position to start playing from
     * @return -1 on error, 0 on success
     */
    int blink1_play(blink1_device *dev, uint8_t play, uint8_t pos);
    
    /**
     * Play color pattern stored in blink1mk2.
     * @note For mk2 devices only.
     * @param dev blink1 device to command
     * @param play boolean: 1=play, 0=stop
     * @param startpos position to start playing from
     * @param endpos position to end playing
     * @param count number of times to play (0=forever)
     * @return -1 on error, 0 on success
     */
    int blink1_playloop(blink1_device *dev, uint8_t play, uint8_t startpos, uint8_t endpos, uint8_t count);
    
    /**
     * Read the current state of a playing pattern.
     * @note For mk2 devices only.
     * @param dev blink1 device to command
     * @param playing pointer to play/stop boolean
     * @param playstart pointer to start position
     * @param playend pointer to end position
     * @param playcount pointer to count left
     * @param playpos pointer to play position
     * @return -1 on error, 0 on success
     */
    int blink1_readPlayState(blink1_device *dev, uint8_t* playing,
                             uint8_t* playstart, uint8_t* playend,
                             uint8_t* playcount, uint8_t* playpos);
    
    /**
     * Write a color pattern line to blink1.
     * @note on mk1 devices, this saves the pattern line to nonvolatile storage.
     * @note on mk2 devices, this only saves to RAM (see savePattern() for nonvol)
     * @param dev blink1 device to command
     * @param r red part of RGB color
     * @param g green part of RGB color
     * @param b blue part of RGB color
     * @param pos pattern line number 0-max_patt (FIXME: put note about this)
     * @return -1 on error, 0 on success
     */
    int blink1_writePatternLine(blink1_device *dev, uint16_t fadeMillis,
                                uint8_t r, uint8_t g, uint8_t b,
                                uint8_t pos);
    /**
     * Read a color pattern line to blink1.
     * @param dev blink1 device to command
     * @param fadeMillis pointer to milliseconds to fade to RGB color
     * @param r pointer to store red color component
     * @param g pointer to store green color component
     * @param b pointer to store blue color component
     * @return -1 on error, 0 on success
     */
    int blink1_readPatternLine(blink1_device *dev, uint16_t* fadeMillis,
                               uint8_t* r, uint8_t* g, uint8_t* b,
                               uint8_t pos);
    /**
     * Read a color pattern line to blink1.
     * @note ledn param only works on fw204+ devices
     * @param dev blink1 device to command
     * @param fadeMillis pointer to milliseconds to fade to RGB color
     * @return -1 on error, 0 on success
     */
    int blink1_readPatternLineN(blink1_device *dev, uint16_t* fadeMillis,
                                uint8_t* r, uint8_t* g, uint8_t* b, uint8_t* ledn,
                                uint8_t pos);
    /**
     * Save color pattern in RAM to nonvolatile storage.
     * @note For mk2 devices only.
     * @note this doesn't actually return a proper return value, as the
     *       time it takes to write to flash actually exceeds USB timeout
     * @param dev blink1 device to command
     * @return -1 on error, 0 on success
     */
    int blink1_savePattern(blink1_device *dev);
    
    /**
     * Sets 'ledn' parameter for blink1_savePatternLine()
     * @note only works on fw 204+ devices
     */
    int blink1_setLEDN( blink1_device* dev, uint8_t ledn);
    
    /**
     * @note only for devices with fw val 206+ or mk3
     */
    int blink1_getStartupParams( blink1_device* dev, uint8_t* bootmode,
                                 uint8_t* playstart, uint8_t* playend, uint8_t* playcount);
    
    /**
     * @note only for devices with fw val 206+ or mk3
     * FIXME: make 'params' a struct
     */
    int blink1_setStartupParams( blink1_device* dev, uint8_t bootmode,
                                 uint8_t playstart, uint8_t playend, uint8_t playcount);
    
    /**
     * Tell blink(1) to reset into bootloader.
     * mk3 devices only
     */
    int blink1_bootloaderGo( blink1_device* dev );
    
    int blink1_bootloaderLock( blink1_device* dev );
    
    /**
     * Internal testing
     */
    int blink1_getId( blink1_device *dev, uint8_t** idbuf );
    
    int blink1_testtest(blink1_device *dev, uint8_t reportid);
    
    
    // reads from notebuf
    int blink1_writeNote( blink1_device* dev, uint8_t noteid, const uint8_t* notebuf);
    
    // writes into notebuf
    int blink1_readNote( blink1_device* dev, uint8_t noteid, uint8_t** notebuf);
    
    
    char *blink1_error_msg(int errCode);
    
    /**
     * Enable blink1-lib gamma curve.
     */
    void blink1_enableDegamma();
    
    /**
     * Disable blink1-lib gamma curve.
     * @note should probably always have it disabled
     */
    void blink1_disableDegamma();
    int blink1_degamma(int n);
    
    /**
     * Using a brightness value, update an r,g,b triplet
     * Modifies r,g,b in place
     */
    void blink1_adjustBrightness( uint8_t brightness, uint8_t* r, uint8_t* g, uint8_t* b);
    
    /**
     * Simple wrapper for cross-platform millisecond delay.
     * @param delayMillis number of milliseconds to wait
     */
    void blink1_sleep(uint32_t delayMillis);
    
    /**
     * Vendor ID for blink1 devices.
     * @return blink1 VID
     */
    int blink1_vid(void);  // return VID for blink(1)
    /**
     * Product ID for blink1 devices.
     * @return blink1 PID
     */
    int blink1_pid(void);  // return PID for blink(1)
    
    
    /**
     * Return platform-specific USB path for given cache index.
     * @param i cache index
     * @return path string
     */
    const char*  blink1_getCachedPath(int i);
    /**
     * Return bilnk1 serial number for given cache index.
     * @param i cache index
     * @return 8-hexdigit serial number as string
     */
    const char*  blink1_getCachedSerial(int i);
    /**
     * Return cache index for a given platform-specific USB path.
     * @param path platform-specific path string
     * @return cache index or -1 if not found
     */
    int          blink1_getCacheIndexByPath( const char* path );
    /**
     * Return cache index for a given blink1 id (0-max or serial number as uint32)
     * @param i blink1 id (0-blink1_max_devices or serial as uint32)
     * @return cache index or -1 if not found
     */
    int          blink1_getCacheIndexById( uint32_t i );
    /**
     * Return cache index for a given blink1 serial number.
     * @param path platform-specific path string
     * @return cache index or -1 if not found
     */
    int          blink1_getCacheIndexBySerial( const char* serial );
    /**
     * Return cache index for a given blink1_device object.
     * @param dev blink1 device to lookup
     * @return cache index or -1 if not found
     */
    int          blink1_getCacheIndexByDev( blink1_device* dev );
    /**
     * Clear the blink1 device cache for a given device.
     * @param dev blink1 device
     * @return cache index that was cleared, or -1 if not found
     */
    int          blink1_clearCacheDev( blink1_device* dev );
    
    /**
     * Return serial number string for give blink1 device.
     * @param dev blink device to lookup
     * @return 8-hexdigit serial number string
     */
    const char*  blink1_getSerialForDev(blink1_device* dev);
    
    /**
     * Return number of entries in blink1 device cache.
     * @note This is the number of devices found with blink1_enumerate()
     * @return number of cache entries
     */
    int          blink1_getCachedCount(void);
    
    /**
     * Returns version of device at cache index i is a mk2
     *
     * @return mk2=1, mk1=0
     */
    int          blink1_isMk2ById(int i);
    
    /**
     * Returns if given blink1_device is a mk2 or not
     * @param dev blink1 device to check
     * @return mk2=1, mk1=0
     */
    int          blink1_isMk2(blink1_device* dev);
    
    /**
     * Returns device "mk" type at cache index i
     * @return blink1Type_t (BLINK1_MK2, BLINK1_MK2, BLINK1_MK1)
     */
    blink1Type_t blink1_deviceTypeById( int i );
    
    /**
     *
     * @return blink1Type_t (BLINK1_MK2, BLINK1_MK2, BLINK1_MK1)
     */
    blink1Type_t blink1_deviceType( blink1_device* dev );
    
    /**
     * Return a string representation of the blink(1) device type
     * (e.g. "mk2" or "mk3")
     * @return const string
     */
    const char* blink1_deviceTypeToStr(blink1Type_t t);
    
    /**
     *
     */
    void hexdump(FILE* fp, uint8_t *buffer, int len);
    
    /**
     *
     */
    int hexread(uint8_t *buffer, char *string, int buflen);
    
    /**
     *
     */
    void hsbtorgb( rgb_t* rgb, uint8_t* hsb );
    
    /**
     *
     */
    void parsecolor(rgb_t* color, char* colorstr);
    
    /**
     *
     */
    int parsePattern( char* str, int* repeats, patternline_t* pattern );
    
    /**
     * printf that can be shut up
     *
     */
    void msg(char* fmt, ...);
    
    void msg_setquiet(int q);
    
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif