From 78d4b92d4e3d889f1ab1ea709c356a31a5500f80 Mon Sep 17 00:00:00 2001 From: BCG Date: Mon, 14 Feb 2022 00:47:45 -0500 Subject: [PATCH] Added support for 125MHz to WS2812 for RP2040 --- ws2812/ws2812-asm_cortexm.go | 299 +++++++++++++++++++++++++++++++++++ ws2812/ws2812.go | 2 +- ws2812/ws2812_cortexm.go | 3 + 3 files changed, 303 insertions(+), 1 deletion(-) diff --git a/ws2812/ws2812-asm_cortexm.go b/ws2812/ws2812-asm_cortexm.go index 9fb12fd6b..2f4e9a523 100644 --- a/ws2812/ws2812-asm_cortexm.go +++ b/ws2812/ws2812-asm_cortexm.go @@ -652,6 +652,305 @@ func (d Device) writeByte120(c byte) { interrupt.Restore(mask) } +func (d Device) writeByte125(c byte) { + portSet, maskSet := d.Pin.PortMaskSet() + portClear, maskClear := d.Pin.PortMaskClear() + + // Timings: + // T0H: 44 - 46 cycles or 352.0ns - 368.0ns + // T1H: 132 - 134 cycles or 1056.0ns - 1072.0ns + // TLD: 144 - cycles or 1152.0ns - + mask := interrupt.Disable() + value := uint32(c) << 24 + device.AsmFull(` + 1: @ send_bit + str {maskSet}, {portSet} @ [2] T0H and T0L start here + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + lsls {value}, #1 @ [1] + bcs.n 2f @ [1/3] skip_store + str {maskClear}, {portClear} @ [2] T0H -> T0L transition + 2: @ skip_store + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + str {maskClear}, {portClear} @ [2] T1H -> T1L transition + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + subs {i}, #1 @ [1] + bne.n 1b @ [1/3] send_bit + `, map[string]interface{}{ + "value": value, + "i": 8, + "maskSet": maskSet, + "portSet": portSet, + "maskClear": maskClear, + "portClear": portClear, + }) + interrupt.Restore(mask) +} + func (d Device) writeByte168(c byte) { portSet, maskSet := d.Pin.PortMaskSet() portClear, maskClear := d.Pin.PortMaskClear() diff --git a/ws2812/ws2812.go b/ws2812/ws2812.go index a93c9f043..a371c6191 100644 --- a/ws2812/ws2812.go +++ b/ws2812/ws2812.go @@ -1,7 +1,7 @@ // Package ws2812 implements a driver for WS2812 and SK6812 RGB LED strips. package ws2812 // import "tinygo.org/x/drivers/ws2812" -//go:generate go run gen-ws2812.go -arch=cortexm 16 48 64 120 168 +//go:generate go run gen-ws2812.go -arch=cortexm 16 48 64 120 125 168 //go:generate go run gen-ws2812.go -arch=tinygoriscv 160 320 import ( diff --git a/ws2812/ws2812_cortexm.go b/ws2812/ws2812_cortexm.go index fb153b957..18588377a 100644 --- a/ws2812/ws2812_cortexm.go +++ b/ws2812/ws2812_cortexm.go @@ -29,6 +29,9 @@ func (d Device) WriteByte(c byte) error { case 120_000_000: // 120MHz d.writeByte120(c) return nil + case 125_000_000: // 125MHz + d.writeByte125(c) + return nil case 168_000_000: // 168MHz, e.g. stm32f405 d.writeByte168(c) return nil