From aef8d42d42bb5bf4a4c47138a6699fcd3c0e270e Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Tue, 20 Nov 2018 21:05:41 +0100 Subject: [PATCH] ws2812: add support for the Arduino --- ws2812/ws2812_avr_16m.go | 41 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 ws2812/ws2812_avr_16m.go diff --git a/ws2812/ws2812_avr_16m.go b/ws2812/ws2812_avr_16m.go new file mode 100644 index 0000000..6db1205 --- /dev/null +++ b/ws2812/ws2812_avr_16m.go @@ -0,0 +1,41 @@ +// +build arduino + +package ws2812 + +// This file implements the WS2812 protocol for 16MHz AVR microcontrollers. + +import ( + "device/avr" +) + +// Send a single byte using the WS2812 protocol. +func (d Device) WriteByte(c byte) { + // For the AVR at 16MHz + portSet, maskSet := d.Pin.PortMaskSet() + portClear, maskClear := d.Pin.PortMaskClear() + + avr.AsmFull(` + send_bit: + st {portSet}, {maskSet} ; [2] set output high + lsl {value} ; [1] shift off the next bit, store it in C + brcs skip_store ; [1/2] branch if this bit is high (long pulse) + st {portClear}, {maskClear} ; [2] set output low (short pulse) + skip_store: + nop ; [6] wait before changing the output again + nop + nop + nop + nop + nop + st {portClear}, {maskClear} ; [2] set output low (end of pulse) + subi {i}, 1 ; [1] subtract one (for the loop) + brne send_bit ; [1/2] send the next bit, if not at the end of the loop + `, map[string]interface{}{ + "value": c, + "i": 8, + "maskSet": maskSet, + "portSet": portSet, + "maskClear": maskClear, + "portClear": portClear, + }) +}