aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitri Sokolyuk <demon@dim13.org>2018-04-25 08:53:24 +0200
committerDimitri Sokolyuk <demon@dim13.org>2018-04-25 08:53:24 +0200
commit05a943a9334c1bd116125a3f078e6af38cfe952c (patch)
tree895986d3f6705026dc8b0f1dafc4687915fe25d6
initial import
-rw-r--r--blinkstick.go53
-rw-r--r--cmd/blinkstick/main.go55
-rw-r--r--cmd/color/main.go25
-rw-r--r--hid.go38
4 files changed, 171 insertions, 0 deletions
diff --git a/blinkstick.go b/blinkstick.go
new file mode 100644
index 0000000..d3aade3
--- /dev/null
+++ b/blinkstick.go
@@ -0,0 +1,53 @@
+package blinkstick
+
+import (
+ "bytes"
+ "image/color"
+ "io"
+)
+
+/* Reports:
+ 1: LED Data [R, G, B]
+ 2: Name [Binary Data 0..32]
+ 3: Data [Binary Data 0..32]
+ 4: Mode set [MODE]: 0 - RGB LED Strip, 1 - Inverse RGB LED Strip, 2 - WS2812
+ 5: LED Data [CHANNEL, INDEX, R, G, B]
+ 6: LED Frame [Channel, [G, R, B][0..7]]
+ 7: LED Frame [Channel, [G, R, B][0..15]]
+ 8: LED Frame [Channel, [G, R, B][0..31]]
+ 9: LED Frame [Channel, [G, R, B][0..63]]
+*/
+
+type Scene [8]color.Color
+
+func rgb(c color.Color) (uint8, uint8, uint8) {
+ if c == nil {
+ return 0, 0, 0
+ }
+ r, g, b, _ := c.RGBA()
+ return uint8(r >> 8), uint8(g >> 8), uint8(b >> 8)
+}
+
+func SetIndex(w io.Writer, i int, c color.Color) {
+ buf := bytes.NewBuffer([]byte{5, 0, byte(i)})
+ r, g, b := rgb(c)
+ buf.Write([]byte{r, g, b})
+ io.Copy(w, buf)
+}
+
+func Set(w io.Writer, s Scene) {
+ buf := bytes.NewBuffer([]byte{6, 0})
+ for _, c := range s {
+ r, g, b := rgb(c)
+ buf.Write([]byte{g, r, b})
+ }
+ io.Copy(w, buf)
+}
+
+func SetAll(w io.Writer, c color.Color) {
+ Set(w, Scene{c, c, c, c, c, c, c, c})
+}
+
+func Off(w io.Writer) {
+ Set(w, Scene{})
+}
diff --git a/cmd/blinkstick/main.go b/cmd/blinkstick/main.go
new file mode 100644
index 0000000..e39e774
--- /dev/null
+++ b/cmd/blinkstick/main.go
@@ -0,0 +1,55 @@
+package main
+
+import (
+ "image/color"
+ "log"
+ "time"
+
+ "dim13.org/blinkstick"
+)
+
+func newBinary(n int, c color.Color) blinkstick.Scene {
+ var s blinkstick.Scene
+ for i := 0; i < 8; i++ {
+ if n&(1<<uint(i)) != 0 {
+ s[i] = c
+ }
+ }
+ return s
+}
+
+func newTwiddle(n int, c color.Color) blinkstick.Scene {
+ var s blinkstick.Scene
+ n %= 14
+ if n < 8 {
+ s[n] = c
+ } else {
+ s[14-n] = c
+ }
+ return s
+}
+
+func main() {
+ dev, err := blinkstick.Open()
+ if err != nil {
+ log.Fatal(err)
+ }
+ defer dev.Close()
+
+ defer blinkstick.Off(dev)
+
+ pal := []color.Color{
+ color.YCbCr{0x1f, 0x00, 0xff}, // red
+ color.YCbCr{0x3f, 0x00, 0xbf}, // yellow
+ color.YCbCr{0x1f, 0x00, 0x00}, // green
+ color.YCbCr{0x1f, 0xff, 0x1f}, // blue
+ color.Black, // off
+ }
+
+ for _, c := range pal {
+ for i := 0; i < 8; i++ {
+ blinkstick.SetIndex(dev, i, c)
+ time.Sleep(time.Second / 2)
+ }
+ }
+}
diff --git a/cmd/color/main.go b/cmd/color/main.go
new file mode 100644
index 0000000..3e97749
--- /dev/null
+++ b/cmd/color/main.go
@@ -0,0 +1,25 @@
+package main
+
+import (
+ "flag"
+ "log"
+
+ "dim13.org/blinkstick"
+ "golang.org/x/image/colornames"
+)
+
+func main() {
+ flag.Parse()
+ c, ok := colornames.Map[flag.Arg(0)]
+ if !ok {
+ return
+ }
+
+ dev, err := blinkstick.Open()
+ if err != nil {
+ log.Fatal(err)
+ }
+ defer dev.Close()
+
+ blinkstick.SetAll(dev, c)
+}
diff --git a/hid.go b/hid.go
new file mode 100644
index 0000000..5c598e8
--- /dev/null
+++ b/hid.go
@@ -0,0 +1,38 @@
+package blinkstick
+
+import (
+ "errors"
+
+ "github.com/karalabe/hid"
+)
+
+const (
+ vendorID = 0x20a0
+ productID = 0x41e5
+)
+
+var (
+ ErrUnsupported = errors.New("unsupproted platform")
+ ErrNotFound = errors.New("device not found")
+)
+
+/* Found device:
+ Manufacturer: Agile Innovative Ltd
+ Description: BlinkStick
+ Serial: BS019296-3.0
+ Current Color: #000000
+ Mode: 2
+ LEDs: unsupported
+ Info Block 1:
+ Info Block 2:
+*/
+
+func Open() (*hid.Device, error) {
+ if !hid.Supported() {
+ return nil, ErrUnsupported
+ }
+ for _, dev := range hid.Enumerate(vendorID, productID) {
+ return dev.Open()
+ }
+ return nil, ErrNotFound
+}