@@ -40,6 +40,9 @@ void common_hal_neopixel_write(const nativeio_digitalinout_obj_t* digitalinout,
40
40
// Turn off interrupts of any kind during timing-sensitive code.
41
41
mp_hal_disable_all_interrupts ();
42
42
43
+ // Make sure the NVM cache is consistently timed.
44
+ NVMCTRL -> CTRLB .bit .READMODE = NVMCTRL_CTRLB_READMODE_DETERMINISTIC_Val ;
45
+
43
46
uint32_t pin = digitalinout -> pin -> pin ;
44
47
port = port_get_group_from_gpio_pin (pin );
45
48
pinMask = (1UL << (pin % 32 )); // From port_pin_set_output_level ASF code.
@@ -56,17 +59,14 @@ void common_hal_neopixel_write(const nativeio_digitalinout_obj_t* digitalinout,
56
59
* set = pinMask ;
57
60
asm("nop; nop;" );
58
61
if (p & bitMask ) {
59
- asm("nop; nop; nop; nop; nop; nop; nop; nop;"
60
- "nop; nop; nop; nop; nop;" );
62
+ asm("nop; nop; nop; nop; nop; nop; nop;" );
61
63
* clr = pinMask ;
62
64
} else {
63
65
* clr = pinMask ;
64
- asm("nop; nop; nop; nop; nop; nop; nop; nop;"
65
- "nop; nop; nop; nop; nop; nop; nop; nop;"
66
- "nop; nop;" );
66
+ asm("nop; nop;" );
67
67
}
68
68
if ((bitMask >>= 1 ) != 0 ) {
69
- asm("nop; nop; nop; nop; nop; nop; nop; nop; nop; " );
69
+ asm("nop; nop; nop; nop; nop;" );
70
70
} else {
71
71
if (ptr >= end ) break ;
72
72
p = * ptr ++ ;
@@ -76,12 +76,10 @@ void common_hal_neopixel_write(const nativeio_digitalinout_obj_t* digitalinout,
76
76
} else { // 400 KHz bitstream
77
77
for (;;) {
78
78
* set = pinMask ;
79
- // 11 cycles high regardless
80
- asm("nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; " );
79
+
80
+ asm("nop; nop; nop; nop; nop; nop; nop;" );
81
81
if (p & bitMask ) {
82
- // 27 cycles high
83
82
asm("nop; nop; nop; nop; nop; nop; nop; nop;"
84
- "nop; nop; nop; nop; nop; nop; nop; nop;"
85
83
"nop; nop; nop; nop; nop; nop; nop; nop;"
86
84
"nop; nop; nop;" );
87
85
* clr = pinMask ;
@@ -106,6 +104,9 @@ void common_hal_neopixel_write(const nativeio_digitalinout_obj_t* digitalinout,
106
104
}
107
105
}
108
106
107
+ // Speed up! (But inconsistent timing.)
108
+ NVMCTRL -> CTRLB .bit .READMODE = NVMCTRL_CTRLB_READMODE_NO_MISS_PENALTY_Val ;
109
+
109
110
// Turn on interrupts after timing-sensitive code.
110
111
mp_hal_enable_all_interrupts ();
111
112
0 commit comments