548 lines
15 KiB
C
548 lines
15 KiB
C
/**
|
|
* 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
|