@@ -66,10 +66,20 @@ void common_hal_neopixel_write(const digitalio_digitalinout_obj_t *digitalinout,
6666 .clk_src = RMT_CLK_SRC_DEFAULT ,
6767 .resolution_hz = 40000000 ,
6868 .trans_queue_depth = 1 ,
69- .mem_block_symbols = SOC_RMT_MEM_WORDS_PER_CHANNEL ,
7069 };
70+
71+ // Greedily try and grab as much RMT memory as we can. The more we get, the
72+ // smoother the output will be because we'll trigger fewer interrupts. We'll
73+ // give it all back once we're done.
7174 rmt_channel_handle_t channel ;
72- CHECK_ESP_RESULT (rmt_new_tx_channel (& config , & channel ));
75+ esp_err_t result = ESP_ERR_NOT_FOUND ;
76+ // If no other channels are in use, we can use all of the RMT RAM including the RX channels.
77+ config .mem_block_symbols = SOC_RMT_MEM_WORDS_PER_CHANNEL * SOC_RMT_CHANNELS_PER_GROUP ;
78+ while (result == ESP_ERR_NOT_FOUND && config .mem_block_symbols > 0 ) {
79+ result = rmt_new_tx_channel (& config , & channel );
80+ config .mem_block_symbols -= SOC_RMT_MEM_WORDS_PER_CHANNEL ;
81+ }
82+ CHECK_ESP_RESULT (result );
7383
7484 size_t ns_per_tick = 1e9 / 40000000 ;
7585 uint16_t ws2812_t0h_ticks = WS2812_T0H_NS / ns_per_tick ;
@@ -97,7 +107,11 @@ void common_hal_neopixel_write(const digitalio_digitalinout_obj_t *digitalinout,
97107 }
98108 };
99109 rmt_encoder_handle_t encoder ;
100- CHECK_ESP_RESULT (rmt_new_bytes_encoder (& encoder_config , & encoder ));
110+ result = rmt_new_bytes_encoder (& encoder_config , & encoder );
111+ if (result != ESP_OK ) {
112+ rmt_del_channel (channel );
113+ return ;
114+ }
101115
102116 // Wait to make sure we don't append onto the last transmission. This should only be a tick or
103117 // two.
@@ -111,7 +125,7 @@ void common_hal_neopixel_write(const digitalio_digitalinout_obj_t *digitalinout,
111125 .loop_count = 0 ,
112126 .flags .eot_level = 0
113127 };
114- esp_err_t result = rmt_transmit (channel , encoder , pixels , (size_t )numBytes , & transmit_config );
128+ result = rmt_transmit (channel , encoder , pixels , (size_t )numBytes , & transmit_config );
115129 if (result != ESP_OK ) {
116130 rmt_del_encoder (encoder );
117131 rmt_disable (channel );
0 commit comments