|
25 | 25 | */
|
26 | 26 |
|
27 | 27 | #include "py/mphal.h"
|
| 28 | +#include "py/mpstate.h" |
28 | 29 | #include "shared-bindings/neopixel_write/__init__.h"
|
29 | 30 | #include "nrf_pwm.h"
|
30 | 31 |
|
@@ -97,14 +98,11 @@ static NRF_PWM_Type* find_free_pwm (void) {
|
97 | 98 | return NULL;
|
98 | 99 | }
|
99 | 100 |
|
100 |
| -static uint16_t* pixels_pattern_heap = NULL; |
101 | 101 | static size_t pixels_pattern_heap_size = 0;
|
102 |
| -static bool pattern_on_heap = false; |
103 | 102 | // Called during reset_port() to free the pattern buffer
|
104 | 103 | void neopixel_write_reset(void) {
|
105 |
| - pixels_pattern_heap = NULL; |
| 104 | + MP_STATE_VM(pixels_pattern_heap) = NULL; |
106 | 105 | pixels_pattern_heap_size = 0;
|
107 |
| - pattern_on_heap = false; |
108 | 106 | }
|
109 | 107 |
|
110 | 108 | uint64_t next_start_tick_ms = 0;
|
@@ -148,35 +146,37 @@ void common_hal_neopixel_write (const digitalio_digitalinout_obj_t* digitalinout
|
148 | 146 | (void) sd_softdevice_is_enabled(&sd_en);
|
149 | 147 |
|
150 | 148 | if (pixels_pattern_heap_size < pattern_size) {
|
151 |
| - if (pattern_on_heap) { |
152 |
| - m_free(pixels_pattern_heap); |
| 149 | + // Current heap buffer is too small. |
| 150 | + if (MP_STATE_VM(pixels_pattern_heap)) { |
| 151 | + // Old pixels_pattern_heap will be gc'd; don't free it. |
153 | 152 | pixels_pattern = NULL;
|
154 |
| - pixels_pattern_heap = NULL; |
| 153 | + MP_STATE_VM(pixels_pattern_heap) = NULL; |
155 | 154 | pixels_pattern_heap_size = 0;
|
156 | 155 | }
|
157 | 156 |
|
158 | 157 | if (sd_en) {
|
159 | 158 | // If the soft device is enabled then we must use PWM to
|
160 | 159 | // transmit. This takes a bunch of memory to do so raise an
|
161 | 160 | // exception if we can't.
|
162 |
| - pixels_pattern_heap = (uint16_t *) m_malloc(pattern_size, false); |
| 161 | + MP_STATE_VM(pixels_pattern_heap) = (uint16_t *) m_malloc(pattern_size, false); |
163 | 162 | } else {
|
164 |
| - pixels_pattern_heap = (uint16_t *) m_malloc_maybe(pattern_size, false); |
| 163 | + // Might return NULL. |
| 164 | + MP_STATE_VM(pixels_pattern_heap) = (uint16_t *) m_malloc_maybe(pattern_size, false); |
165 | 165 | }
|
166 |
| - if (pixels_pattern_heap) { |
167 |
| - pattern_on_heap = true; |
| 166 | + if (MP_STATE_VM(pixels_pattern_heap)) { |
168 | 167 | pixels_pattern_heap_size = pattern_size;
|
169 | 168 | }
|
170 | 169 | }
|
171 |
| - pixels_pattern = pixels_pattern_heap; |
| 170 | + // Might be NULL, which means we failed to allocate. |
| 171 | + pixels_pattern = MP_STATE_VM(pixels_pattern_heap); |
172 | 172 | }
|
173 | 173 | }
|
174 | 174 |
|
175 | 175 | // Wait to make sure we don't append onto the last transmission.
|
176 | 176 | wait_until(next_start_tick_ms, next_start_tick_us);
|
177 | 177 |
|
178 | 178 | // Use the identified device to choose the implementation
|
179 |
| - // If a PWM device is available use DMA |
| 179 | + // If a PWM device is available and we have a buffer, use DMA. |
180 | 180 | if ( (pixels_pattern != NULL) && (pwm != NULL) ) {
|
181 | 181 | uint16_t pos = 0; // bit position
|
182 | 182 |
|
|
0 commit comments