@@ -46,6 +46,9 @@ __attribute__((naked,noinline,aligned(16)))
46
46
static void neopixel_send_buffer_core (volatile uint32_t * clraddr , uint32_t pinMask ,
47
47
const uint8_t * ptr , int numBytes );
48
48
49
+ // The SAMD21 timing loop durations below are approximate,
50
+ // because the other instructions take significant time.
51
+
49
52
static void neopixel_send_buffer_core (volatile uint32_t * clraddr , uint32_t pinMask ,
50
53
const uint8_t * ptr , int numBytes ) {
51
54
asm volatile (" push {r4, r5, r6, lr};"
@@ -54,25 +57,28 @@ static void neopixel_send_buffer_core(volatile uint32_t *clraddr, uint32_t pinMa
54
57
" ldrb r5, [r2, #0];" // r5 := *ptr
55
58
" add r2, #1;" // ptr++
56
59
" movs r4, #128;" // r4-mask, 0x80
60
+
57
61
"loopBit:"
58
62
" str r1, [r0, #4];" // set
59
63
#ifdef SAMD21
60
- " movs r6, #3 ; d2: sub r6, #1; bne d2;" // delay 3
64
+ " movs r6, #2 ; d2: sub r6, #1; bne d2;" // 248 ns high (entire T0H or start T1H)
61
65
#endif
62
66
#ifdef SAM_D5X_E5X
63
- " movs r6, #16 ; d2: subs r6, #1; bne d2;" // delay 3
67
+ " movs r6, #11 ; d2: subs r6, #1; bne d2;" // 300 ns high (entire T0H or start T1H)
64
68
#endif
65
69
" tst r4, r5;" // mask&r5
66
70
" bne skipclr;"
67
71
" str r1, [r0, #0];" // clr
72
+
68
73
"skipclr:"
69
74
#ifdef SAMD21
70
- " movs r6, #6 ; d0: sub r6, #1; bne d0;" // delay 6
75
+ " movs r6, #7 ; d0: sub r6, #1; bne d0;" // 772 ns low or high (start T0L or end T1H)
71
76
#endif
72
77
#ifdef SAM_D5X_E5X
73
- " movs r6, #16 ; d0: subs r6, #1; bne d0;" // delay 6
78
+ " movs r6, #15 ; d0: subs r6, #1; bne d0;" // 388 ns low or high (start T0L or end T1H)
74
79
#endif
75
80
" str r1, [r0, #0];" // clr (possibly again, doesn't matter)
81
+
76
82
#ifdef SAMD21
77
83
" asr r4, r4, #1;" // mask >>= 1
78
84
#endif
@@ -82,15 +88,20 @@ static void neopixel_send_buffer_core(volatile uint32_t *clraddr, uint32_t pinMa
82
88
" beq nextbyte;"
83
89
" uxtb r4, r4;"
84
90
#ifdef SAMD21
85
- " movs r6, #2 ; d1: sub r6, #1; bne d1;" // delay 2
91
+ " movs r6, #5 ; d1: sub r6, #1; bne d1;" // 496 ns (end TOL or entire T1L)
86
92
#endif
87
93
#ifdef SAM_D5X_E5X
88
- " movs r6, #15 ; d1: subs r6, #1; bne d1;" // delay 2
94
+ " movs r6, #20 ; d1: subs r6, #1; bne d1;" // 548 ns (end TOL or entire T1L)
89
95
#endif
90
96
" b loopBit;"
97
+
91
98
"nextbyte:"
92
- #ifdef SAM_D5X_E5X
93
- " movs r6, #12; d3: subs r6, #1; bne d3;" // delay 2
99
+ #ifdef SAMD21
100
+ " movs r6, #1; d3: sub r6, #1; bne d3;" // 60 ns (end TOL or entire T1L)
101
+ // other instructions add more delay
102
+ #endif
103
+ #ifdef SAM_D5X_E5X
104
+ " movs r6, #18; d3: subs r6, #1; bne d3;" // extra for 936 ns total (byte end T0L or entire T1L)
94
105
#endif
95
106
" cmp r2, r3;"
96
107
" bcs neopixel_stop;"
0 commit comments