mirror of
https://github.com/tinygo-org/drivers.git
synced 2026-07-26 10:38:41 +00:00
f459992f3c
This adds hardware timing support for driving WS2812 LEDs on Cortex-M microcontrollers running at 160MHz (such as the STM32U585). - Updated `go:generate` directive to include 160MHz. - Generated the corresponding `ws2812_writeByte160` assembly routine. - Added a switch case in `WriteByte` to handle generic 160MHz processors. Signed-off-by: deadprogram <ron@hybridgroup.com>
2595 lines
43 KiB
Go
2595 lines
43 KiB
Go
//go:build cortexm
|
|
|
|
package ws2812
|
|
|
|
// Warning: autogenerated file. Instead of modifying this file, change
|
|
// gen-ws2812.go and run "go generate".
|
|
|
|
import "runtime/interrupt"
|
|
import "unsafe"
|
|
|
|
/*
|
|
#include <stdint.h>
|
|
|
|
__attribute__((always_inline))
|
|
void ws2812_writeByte16(char c, uint32_t *portSet, uint32_t *portClear, uint32_t maskSet, uint32_t maskClear) {
|
|
// Timings:
|
|
// T0H: 6 - 8 cycles or 375.0ns - 500.0ns
|
|
// T1H: 17 - 19 cycles or 1062.5ns - 1187.5ns
|
|
// TLD: 19 - cycles or 1187.5ns -
|
|
uint32_t value = (uint32_t)c << 24;
|
|
char i = 8;
|
|
__asm__ __volatile__(
|
|
"1: @ send_bit\n"
|
|
"\t str %[maskSet], %[portSet] @ [2] T0H and T0L start here\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t lsls %[value], #1 @ [1]\n"
|
|
"\t bcs.n 2f @ [1/3] skip_store\n"
|
|
"\t str %[maskClear], %[portClear] @ [2] T0H -> T0L transition\n"
|
|
"\t2: @ skip_store\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t str %[maskClear], %[portClear] @ [2] T1H -> T1L transition\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t subs %[i], #1 @ [1]\n"
|
|
"\t beq.n 3f @ [1/3] end\n"
|
|
"\t b 1b @ [1/3] send_bit\n"
|
|
"\t3: @ end\n"
|
|
: [value]"+r"(value),
|
|
[i]"+r"(i)
|
|
: [maskSet]"r"(maskSet),
|
|
[portSet]"m"(*portSet),
|
|
[maskClear]"r"(maskClear),
|
|
[portClear]"m"(*portClear));
|
|
}
|
|
|
|
__attribute__((always_inline))
|
|
void ws2812_writeByte48(char c, uint32_t *portSet, uint32_t *portClear, uint32_t maskSet, uint32_t maskClear) {
|
|
// Timings:
|
|
// T0H: 17 - 19 cycles or 354.2ns - 395.8ns
|
|
// T1H: 51 - 53 cycles or 1062.5ns - 1104.2ns
|
|
// TLD: 56 - cycles or 1166.7ns -
|
|
uint32_t value = (uint32_t)c << 24;
|
|
char i = 8;
|
|
__asm__ __volatile__(
|
|
"1: @ send_bit\n"
|
|
"\t str %[maskSet], %[portSet] @ [2] T0H and T0L start here\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t lsls %[value], #1 @ [1]\n"
|
|
"\t bcs.n 2f @ [1/3] skip_store\n"
|
|
"\t str %[maskClear], %[portClear] @ [2] T0H -> T0L transition\n"
|
|
"\t2: @ skip_store\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t str %[maskClear], %[portClear] @ [2] T1H -> T1L transition\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t subs %[i], #1 @ [1]\n"
|
|
"\t beq.n 3f @ [1/3] end\n"
|
|
"\t b 1b @ [1/3] send_bit\n"
|
|
"\t3: @ end\n"
|
|
: [value]"+r"(value),
|
|
[i]"+r"(i)
|
|
: [maskSet]"r"(maskSet),
|
|
[portSet]"m"(*portSet),
|
|
[maskClear]"r"(maskClear),
|
|
[portClear]"m"(*portClear));
|
|
}
|
|
|
|
__attribute__((always_inline))
|
|
void ws2812_writeByte64(char c, uint32_t *portSet, uint32_t *portClear, uint32_t maskSet, uint32_t maskClear) {
|
|
// Timings:
|
|
// T0H: 23 - 25 cycles or 359.4ns - 390.6ns
|
|
// T1H: 68 - 70 cycles or 1062.5ns - 1093.8ns
|
|
// TLD: 74 - cycles or 1156.2ns -
|
|
uint32_t value = (uint32_t)c << 24;
|
|
char i = 8;
|
|
__asm__ __volatile__(
|
|
"1: @ send_bit\n"
|
|
"\t str %[maskSet], %[portSet] @ [2] T0H and T0L start here\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t lsls %[value], #1 @ [1]\n"
|
|
"\t bcs.n 2f @ [1/3] skip_store\n"
|
|
"\t str %[maskClear], %[portClear] @ [2] T0H -> T0L transition\n"
|
|
"\t2: @ skip_store\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t str %[maskClear], %[portClear] @ [2] T1H -> T1L transition\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t subs %[i], #1 @ [1]\n"
|
|
"\t beq.n 3f @ [1/3] end\n"
|
|
"\t b 1b @ [1/3] send_bit\n"
|
|
"\t3: @ end\n"
|
|
: [value]"+r"(value),
|
|
[i]"+r"(i)
|
|
: [maskSet]"r"(maskSet),
|
|
[portSet]"m"(*portSet),
|
|
[maskClear]"r"(maskClear),
|
|
[portClear]"m"(*portClear));
|
|
}
|
|
|
|
__attribute__((always_inline))
|
|
void ws2812_writeByte120(char c, uint32_t *portSet, uint32_t *portClear, uint32_t maskSet, uint32_t maskClear) {
|
|
// Timings:
|
|
// T0H: 42 - 44 cycles or 350.0ns - 366.7ns
|
|
// T1H: 126 - 128 cycles or 1050.0ns - 1066.7ns
|
|
// TLD: 138 - cycles or 1150.0ns -
|
|
uint32_t value = (uint32_t)c << 24;
|
|
char i = 8;
|
|
__asm__ __volatile__(
|
|
"1: @ send_bit\n"
|
|
"\t str %[maskSet], %[portSet] @ [2] T0H and T0L start here\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t lsls %[value], #1 @ [1]\n"
|
|
"\t bcs.n 2f @ [1/3] skip_store\n"
|
|
"\t str %[maskClear], %[portClear] @ [2] T0H -> T0L transition\n"
|
|
"\t2: @ skip_store\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t str %[maskClear], %[portClear] @ [2] T1H -> T1L transition\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t subs %[i], #1 @ [1]\n"
|
|
"\t beq.n 3f @ [1/3] end\n"
|
|
"\t b 1b @ [1/3] send_bit\n"
|
|
"\t3: @ end\n"
|
|
: [value]"+r"(value),
|
|
[i]"+r"(i)
|
|
: [maskSet]"r"(maskSet),
|
|
[portSet]"m"(*portSet),
|
|
[maskClear]"r"(maskClear),
|
|
[portClear]"m"(*portClear));
|
|
}
|
|
|
|
__attribute__((always_inline))
|
|
void ws2812_writeByte125(char c, uint32_t *portSet, uint32_t *portClear, uint32_t maskSet, uint32_t maskClear) {
|
|
// 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 -
|
|
uint32_t value = (uint32_t)c << 24;
|
|
char i = 8;
|
|
__asm__ __volatile__(
|
|
"1: @ send_bit\n"
|
|
"\t str %[maskSet], %[portSet] @ [2] T0H and T0L start here\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t lsls %[value], #1 @ [1]\n"
|
|
"\t bcs.n 2f @ [1/3] skip_store\n"
|
|
"\t str %[maskClear], %[portClear] @ [2] T0H -> T0L transition\n"
|
|
"\t2: @ skip_store\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t str %[maskClear], %[portClear] @ [2] T1H -> T1L transition\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t subs %[i], #1 @ [1]\n"
|
|
"\t beq.n 3f @ [1/3] end\n"
|
|
"\t b 1b @ [1/3] send_bit\n"
|
|
"\t3: @ end\n"
|
|
: [value]"+r"(value),
|
|
[i]"+r"(i)
|
|
: [maskSet]"r"(maskSet),
|
|
[portSet]"m"(*portSet),
|
|
[maskClear]"r"(maskClear),
|
|
[portClear]"m"(*portClear));
|
|
}
|
|
|
|
__attribute__((always_inline))
|
|
void ws2812_writeByte150(char c, uint32_t *portSet, uint32_t *portClear, uint32_t maskSet, uint32_t maskClear) {
|
|
// Timings:
|
|
// T0H: 53 - 55 cycles or 353.3ns - 366.7ns
|
|
// T1H: 158 - 160 cycles or 1053.3ns - 1066.7ns
|
|
// TLD: 173 - cycles or 1153.3ns -
|
|
uint32_t value = (uint32_t)c << 24;
|
|
char i = 8;
|
|
__asm__ __volatile__(
|
|
"1: @ send_bit\n"
|
|
"\t str %[maskSet], %[portSet] @ [2] T0H and T0L start here\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t lsls %[value], #1 @ [1]\n"
|
|
"\t bcs.n 2f @ [1/3] skip_store\n"
|
|
"\t str %[maskClear], %[portClear] @ [2] T0H -> T0L transition\n"
|
|
"\t2: @ skip_store\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t str %[maskClear], %[portClear] @ [2] T1H -> T1L transition\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t subs %[i], #1 @ [1]\n"
|
|
"\t beq.n 3f @ [1/3] end\n"
|
|
"\t b 1b @ [1/3] send_bit\n"
|
|
"\t3: @ end\n"
|
|
: [value]"+r"(value),
|
|
[i]"+r"(i)
|
|
: [maskSet]"r"(maskSet),
|
|
[portSet]"m"(*portSet),
|
|
[maskClear]"r"(maskClear),
|
|
[portClear]"m"(*portClear));
|
|
}
|
|
|
|
__attribute__((always_inline))
|
|
void ws2812_writeByte160(char c, uint32_t *portSet, uint32_t *portClear, uint32_t maskSet, uint32_t maskClear) {
|
|
// Timings:
|
|
// T0H: 56 - 58 cycles or 350.0ns - 362.5ns
|
|
// T1H: 168 - 170 cycles or 1050.0ns - 1062.5ns
|
|
// TLD: 184 - cycles or 1150.0ns -
|
|
uint32_t value = (uint32_t)c << 24;
|
|
char i = 8;
|
|
__asm__ __volatile__(
|
|
"1: @ send_bit\n"
|
|
"\t str %[maskSet], %[portSet] @ [2] T0H and T0L start here\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t lsls %[value], #1 @ [1]\n"
|
|
"\t bcs.n 2f @ [1/3] skip_store\n"
|
|
"\t str %[maskClear], %[portClear] @ [2] T0H -> T0L transition\n"
|
|
"\t2: @ skip_store\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t str %[maskClear], %[portClear] @ [2] T1H -> T1L transition\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t subs %[i], #1 @ [1]\n"
|
|
"\t beq.n 3f @ [1/3] end\n"
|
|
"\t b 1b @ [1/3] send_bit\n"
|
|
"\t3: @ end\n"
|
|
: [value]"+r"(value),
|
|
[i]"+r"(i)
|
|
: [maskSet]"r"(maskSet),
|
|
[portSet]"m"(*portSet),
|
|
[maskClear]"r"(maskClear),
|
|
[portClear]"m"(*portClear));
|
|
}
|
|
|
|
__attribute__((always_inline))
|
|
void ws2812_writeByte168(char c, uint32_t *portSet, uint32_t *portClear, uint32_t maskSet, uint32_t maskClear) {
|
|
// Timings:
|
|
// T0H: 59 - 61 cycles or 351.2ns - 363.1ns
|
|
// T1H: 177 - 179 cycles or 1053.6ns - 1065.5ns
|
|
// TLD: 194 - cycles or 1154.8ns -
|
|
uint32_t value = (uint32_t)c << 24;
|
|
char i = 8;
|
|
__asm__ __volatile__(
|
|
"1: @ send_bit\n"
|
|
"\t str %[maskSet], %[portSet] @ [2] T0H and T0L start here\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t lsls %[value], #1 @ [1]\n"
|
|
"\t bcs.n 2f @ [1/3] skip_store\n"
|
|
"\t str %[maskClear], %[portClear] @ [2] T0H -> T0L transition\n"
|
|
"\t2: @ skip_store\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t str %[maskClear], %[portClear] @ [2] T1H -> T1L transition\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t subs %[i], #1 @ [1]\n"
|
|
"\t beq.n 3f @ [1/3] end\n"
|
|
"\t b 1b @ [1/3] send_bit\n"
|
|
"\t3: @ end\n"
|
|
: [value]"+r"(value),
|
|
[i]"+r"(i)
|
|
: [maskSet]"r"(maskSet),
|
|
[portSet]"m"(*portSet),
|
|
[maskClear]"r"(maskClear),
|
|
[portClear]"m"(*portClear));
|
|
}
|
|
|
|
__attribute__((always_inline))
|
|
void ws2812_writeByte200(char c, uint32_t *portSet, uint32_t *portClear, uint32_t maskSet, uint32_t maskClear) {
|
|
// Timings:
|
|
// T0H: 70 - 72 cycles or 350.0ns - 360.0ns
|
|
// T1H: 210 - 212 cycles or 1050.0ns - 1060.0ns
|
|
// TLD: 230 - cycles or 1150.0ns -
|
|
uint32_t value = (uint32_t)c << 24;
|
|
char i = 8;
|
|
__asm__ __volatile__(
|
|
"1: @ send_bit\n"
|
|
"\t str %[maskSet], %[portSet] @ [2] T0H and T0L start here\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t lsls %[value], #1 @ [1]\n"
|
|
"\t bcs.n 2f @ [1/3] skip_store\n"
|
|
"\t str %[maskClear], %[portClear] @ [2] T0H -> T0L transition\n"
|
|
"\t2: @ skip_store\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t str %[maskClear], %[portClear] @ [2] T1H -> T1L transition\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t nop\n"
|
|
"\t subs %[i], #1 @ [1]\n"
|
|
"\t beq.n 3f @ [1/3] end\n"
|
|
"\t b 1b @ [1/3] send_bit\n"
|
|
"\t3: @ end\n"
|
|
: [value]"+r"(value),
|
|
[i]"+r"(i)
|
|
: [maskSet]"r"(maskSet),
|
|
[portSet]"m"(*portSet),
|
|
[maskClear]"r"(maskClear),
|
|
[portClear]"m"(*portClear));
|
|
}
|
|
*/
|
|
import "C"
|
|
|
|
func (d Device) writeByte16(c byte) {
|
|
portSet, maskSet := d.Pin.PortMaskSet()
|
|
portClear, maskClear := d.Pin.PortMaskClear()
|
|
|
|
mask := interrupt.Disable()
|
|
C.ws2812_writeByte16(C.char(c), (*C.uint32_t)(unsafe.Pointer(portSet)), (*C.uint32_t)(unsafe.Pointer(portClear)), C.uint32_t(maskSet), C.uint32_t(maskClear))
|
|
|
|
interrupt.Restore(mask)
|
|
}
|
|
|
|
func (d Device) writeByte48(c byte) {
|
|
portSet, maskSet := d.Pin.PortMaskSet()
|
|
portClear, maskClear := d.Pin.PortMaskClear()
|
|
|
|
mask := interrupt.Disable()
|
|
C.ws2812_writeByte48(C.char(c), (*C.uint32_t)(unsafe.Pointer(portSet)), (*C.uint32_t)(unsafe.Pointer(portClear)), C.uint32_t(maskSet), C.uint32_t(maskClear))
|
|
|
|
interrupt.Restore(mask)
|
|
}
|
|
|
|
func (d Device) writeByte64(c byte) {
|
|
portSet, maskSet := d.Pin.PortMaskSet()
|
|
portClear, maskClear := d.Pin.PortMaskClear()
|
|
|
|
mask := interrupt.Disable()
|
|
C.ws2812_writeByte64(C.char(c), (*C.uint32_t)(unsafe.Pointer(portSet)), (*C.uint32_t)(unsafe.Pointer(portClear)), C.uint32_t(maskSet), C.uint32_t(maskClear))
|
|
|
|
interrupt.Restore(mask)
|
|
}
|
|
|
|
func (d Device) writeByte120(c byte) {
|
|
portSet, maskSet := d.Pin.PortMaskSet()
|
|
portClear, maskClear := d.Pin.PortMaskClear()
|
|
|
|
mask := interrupt.Disable()
|
|
C.ws2812_writeByte120(C.char(c), (*C.uint32_t)(unsafe.Pointer(portSet)), (*C.uint32_t)(unsafe.Pointer(portClear)), C.uint32_t(maskSet), C.uint32_t(maskClear))
|
|
|
|
interrupt.Restore(mask)
|
|
}
|
|
|
|
func (d Device) writeByte125(c byte) {
|
|
portSet, maskSet := d.Pin.PortMaskSet()
|
|
portClear, maskClear := d.Pin.PortMaskClear()
|
|
|
|
mask := interrupt.Disable()
|
|
C.ws2812_writeByte125(C.char(c), (*C.uint32_t)(unsafe.Pointer(portSet)), (*C.uint32_t)(unsafe.Pointer(portClear)), C.uint32_t(maskSet), C.uint32_t(maskClear))
|
|
|
|
interrupt.Restore(mask)
|
|
}
|
|
|
|
func (d Device) writeByte150(c byte) {
|
|
portSet, maskSet := d.Pin.PortMaskSet()
|
|
portClear, maskClear := d.Pin.PortMaskClear()
|
|
|
|
mask := interrupt.Disable()
|
|
C.ws2812_writeByte150(C.char(c), (*C.uint32_t)(unsafe.Pointer(portSet)), (*C.uint32_t)(unsafe.Pointer(portClear)), C.uint32_t(maskSet), C.uint32_t(maskClear))
|
|
|
|
interrupt.Restore(mask)
|
|
}
|
|
|
|
func (d Device) writeByte160(c byte) {
|
|
portSet, maskSet := d.Pin.PortMaskSet()
|
|
portClear, maskClear := d.Pin.PortMaskClear()
|
|
|
|
mask := interrupt.Disable()
|
|
C.ws2812_writeByte160(C.char(c), (*C.uint32_t)(unsafe.Pointer(portSet)), (*C.uint32_t)(unsafe.Pointer(portClear)), C.uint32_t(maskSet), C.uint32_t(maskClear))
|
|
|
|
interrupt.Restore(mask)
|
|
}
|
|
|
|
func (d Device) writeByte168(c byte) {
|
|
portSet, maskSet := d.Pin.PortMaskSet()
|
|
portClear, maskClear := d.Pin.PortMaskClear()
|
|
|
|
mask := interrupt.Disable()
|
|
C.ws2812_writeByte168(C.char(c), (*C.uint32_t)(unsafe.Pointer(portSet)), (*C.uint32_t)(unsafe.Pointer(portClear)), C.uint32_t(maskSet), C.uint32_t(maskClear))
|
|
|
|
interrupt.Restore(mask)
|
|
}
|
|
|
|
func (d Device) writeByte200(c byte) {
|
|
portSet, maskSet := d.Pin.PortMaskSet()
|
|
portClear, maskClear := d.Pin.PortMaskClear()
|
|
|
|
mask := interrupt.Disable()
|
|
C.ws2812_writeByte200(C.char(c), (*C.uint32_t)(unsafe.Pointer(portSet)), (*C.uint32_t)(unsafe.Pointer(portClear)), C.uint32_t(maskSet), C.uint32_t(maskClear))
|
|
|
|
interrupt.Restore(mask)
|
|
}
|