RealUnicorn2.go (1386B)
1 // +build linux,arm linux,arm64 2 3 package unicorn 4 5 import ( 6 "image" 7 "log" 8 "os" 9 "os/signal" 10 "syscall" 11 12 "github.com/ecc1/spi" 13 ) 14 15 type RealUnicorn2 struct { 16 *BaseUnicorn2 17 device *spi.Device 18 } 19 20 func (u *RealUnicorn2) renderImage(im image.Image) { 21 b := im.Bounds() 22 width, height := b.Dx(), b.Dy() 23 sz := (width * height * 3) + 1 24 write := make([]byte, sz) 25 26 // Write leading bit 27 write[0] = 0x72 28 29 // Write color values 30 ix := 1 31 for x := 0; x < width; x++ { 32 for y := 0; y < height; y++ { 33 col := im.At(x, y) 34 r, g, b, _ := col.RGBA() 35 write[ix] = byte(r) 36 ix++ 37 write[ix] = byte(g) 38 ix++ 39 write[ix] = byte(b) 40 ix++ 41 } 42 } 43 // Write to the device 44 err := u.device.Transfer(write) 45 if err != nil { 46 log.Printf("Error writing to SPI device %v", err) 47 } 48 } 49 50 // NewUnicorn2 ... 51 // Constructs a new and improved unicorn from stuff and things 52 func NewUnicorn2() (*RealUnicorn2, error) { 53 dev, err := spi.Open("/dev/spidev0.0", 9000000, 0) 54 if err != nil { 55 return nil, err 56 } 57 return &RealUnicorn2{ 58 NewBaseUnicorn2(), 59 dev, 60 }, nil 61 } 62 63 // StartRender ... 64 // Passes through to base to actually do the render 65 func (u *RealUnicorn2) StartRender() chan bool { 66 return u.StartRenderBase(u.renderImage) 67 } 68 69 // MainLoop ... 70 // Just blocks until sigterm 71 func (u *RealUnicorn2) MainLoop() { 72 c := make(chan os.Signal, 2) 73 signal.Notify(c, os.Interrupt, syscall.SIGTERM) 74 <-c 75 }