From 74471a58f1c62c8ceaaaa8624b25a8caaeb801ad Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Tue, 1 Mar 2022 13:14:17 +0100 Subject: [PATCH] ws2812: support high-MHz ARMv6M chips like the RP2040 The possible branch distance is a lot shorter on ARMv6M (Cortex-M and Cortex-M0+) for conditional branches. Therefore, convert this long conditional branch into an unconditional branch. This probably makes the code a little bit slower but because it is in the low period of the WS2812 signal it shouldn't matter for the protocol. And it avoids difficult workarounds specifically for the RP2040. --- ws2812/gen-ws2812.go | 6 ++++-- ws2812/ws2812-asm_cortexm.go | 25 +++++++++++++++---------- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/ws2812/gen-ws2812.go b/ws2812/gen-ws2812.go index 2b2bc765a..b00f72e8a 100644 --- a/ws2812/gen-ws2812.go +++ b/ws2812/gen-ws2812.go @@ -59,7 +59,7 @@ var architectures = map[string]architectureImpl{ maxBaseCyclesT0H: 1 + 3 + 2, // shift + branch (not taken) + store minBaseCyclesT1H: 1 + 1 + 2, // shift + branch (taken) + store maxBaseCyclesT1H: 1 + 3 + 2, // shift + branch (taken) + store - minBaseCyclesTLD: 1 + 1 + 2, // subtraction + branch + store (in next cycle) + minBaseCyclesTLD: 1 + 2 + 2, // subtraction + branch x2 + store (in next cycle) valueTemplate: "uint32(c) << 24", template: ` 1: @ send_bit @@ -73,7 +73,9 @@ var architectures = map[string]architectureImpl{ str {maskClear}, {portClear} @ [2] T1H -> T1L transition @DELAY3 subs {i}, #1 @ [1] - bne.n 1b @ [1/3] send_bit + beq.n 3f @ [1/3] end + b 1b @ [1/3] send_bit +3: @ end `, }, "tinygoriscv": { diff --git a/ws2812/ws2812-asm_cortexm.go b/ws2812/ws2812-asm_cortexm.go index 9fb12fd6b..8bef27ecc 100644 --- a/ws2812/ws2812-asm_cortexm.go +++ b/ws2812/ws2812-asm_cortexm.go @@ -56,9 +56,10 @@ func (d Device) writeByte16(c byte) { nop nop nop - nop subs {i}, #1 @ [1] - bne.n 1b @ [1/3] send_bit + beq.n 3f @ [1/3] end + b 1b @ [1/3] send_bit + 3: @ end `, map[string]interface{}{ "value": value, "i": 8, @@ -186,9 +187,10 @@ func (d Device) writeByte48(c byte) { nop nop nop - nop subs {i}, #1 @ [1] - bne.n 1b @ [1/3] send_bit + beq.n 3f @ [1/3] end + b 1b @ [1/3] send_bit + 3: @ end `, map[string]interface{}{ "value": value, "i": 8, @@ -351,9 +353,10 @@ func (d Device) writeByte64(c byte) { nop nop nop - nop subs {i}, #1 @ [1] - bne.n 1b @ [1/3] send_bit + beq.n 3f @ [1/3] end + b 1b @ [1/3] send_bit + 3: @ end `, map[string]interface{}{ "value": value, "i": 8, @@ -638,9 +641,10 @@ func (d Device) writeByte120(c byte) { nop nop nop - nop subs {i}, #1 @ [1] - bne.n 1b @ [1/3] send_bit + beq.n 3f @ [1/3] end + b 1b @ [1/3] send_bit + 3: @ end `, map[string]interface{}{ "value": value, "i": 8, @@ -1032,9 +1036,10 @@ func (d Device) writeByte168(c byte) { nop nop nop - nop subs {i}, #1 @ [1] - bne.n 1b @ [1/3] send_bit + beq.n 3f @ [1/3] end + b 1b @ [1/3] send_bit + 3: @ end `, map[string]interface{}{ "value": value, "i": 8,