RealUnicorn.go (1358B)
1 // +build linux,arm linux,arm64 2 3 package unicorn 4 5 import ( 6 "log" 7 "os" 8 "os/signal" 9 "syscall" 10 11 "github.com/ecc1/spi" 12 ) 13 14 type RealUnicorn struct { 15 BaseUnicorn 16 device *spi.Device 17 } 18 19 // NewUnicorn ... 20 // Constructs a new real unicorn from fairy dust and sprinkles 21 func NewUnicorn() (*RealUnicorn, error) { 22 dev, err := spi.Open("/dev/spidev0.0", 9000000, 0) 23 if err != nil { 24 return nil, err 25 } 26 27 return &RealUnicorn{ 28 BaseUnicorn{ 29 pixels: makePixels(16, 16), 30 }, 31 dev, 32 }, nil 33 } 34 35 func (u *RealUnicorn) Show() { 36 // Width * height * colours + leading bit 37 width := int(u.GetWidth()) 38 height := int(u.GetHeight()) 39 sz := (width * height * 3) + 1 40 write := make([]byte, sz) 41 42 // Add the leading bit 43 write[0] = 0x72 44 // Add all the pixel values 45 ix := 1 46 for x := 0; x < width; x++ { 47 for y := 0; y < height; y++ { 48 for j := 0; j < 3; j++ { 49 write[ix] = byte(u.pixels[x][y][j]) 50 ix++ 51 } 52 } 53 } 54 // Write to the device 55 err := u.device.Transfer(write) 56 if err != nil { 57 log.Printf("Error writing to SPI device %v", err) 58 } 59 } 60 61 func (u *RealUnicorn) Off() { 62 u.Close() 63 } 64 65 func (u *RealUnicorn) Close() error { 66 return u.device.Close() 67 } 68 69 // MainLoop ... 70 // Do nothing until SIGTERM, then close the SPI library 71 func (u *RealUnicorn) MainLoop() { 72 c := make(chan os.Signal, 2) 73 signal.Notify(c, os.Interrupt, syscall.SIGTERM) 74 <-c 75 u.Close() 76 }