@@ -40,6 +40,9 @@ void common_hal_neopixel_write(const nativeio_digitalinout_obj_t* digitalinout,
4040 // Turn off interrupts of any kind during timing-sensitive code.
4141 mp_hal_disable_all_interrupts ();
4242
43+ // Make sure the NVM cache is consistently timed.
44+ NVMCTRL -> CTRLB .bit .READMODE = NVMCTRL_CTRLB_READMODE_DETERMINISTIC_Val ;
45+
4346 uint32_t pin = digitalinout -> pin -> pin ;
4447 port = port_get_group_from_gpio_pin (pin );
4548 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,
5659 * set = pinMask ;
5760 asm("nop; nop;" );
5861 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;" );
6163 * clr = pinMask ;
6264 } else {
6365 * 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;" );
6767 }
6868 if ((bitMask >>= 1 ) != 0 ) {
69- asm("nop; nop; nop; nop; nop; nop; nop; nop; nop; " );
69+ asm("nop; nop; nop; nop; nop;" );
7070 } else {
7171 if (ptr >= end ) break ;
7272 p = * ptr ++ ;
@@ -76,12 +76,10 @@ void common_hal_neopixel_write(const nativeio_digitalinout_obj_t* digitalinout,
7676 } else { // 400 KHz bitstream
7777 for (;;) {
7878 * 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;" );
8181 if (p & bitMask ) {
82- // 27 cycles high
8382 asm("nop; nop; nop; nop; nop; nop; nop; nop;"
84- "nop; nop; nop; nop; nop; nop; nop; nop;"
8583 "nop; nop; nop; nop; nop; nop; nop; nop;"
8684 "nop; nop; nop;" );
8785 * clr = pinMask ;
@@ -106,6 +104,9 @@ void common_hal_neopixel_write(const nativeio_digitalinout_obj_t* digitalinout,
106104 }
107105 }
108106
107+ // Speed up! (But inconsistent timing.)
108+ NVMCTRL -> CTRLB .bit .READMODE = NVMCTRL_CTRLB_READMODE_NO_MISS_PENALTY_Val ;
109+
109110 // Turn on interrupts after timing-sensitive code.
110111 mp_hal_enable_all_interrupts ();
111112
0 commit comments