Skip to content

Commit 0be5397

Browse files
authored
Merge pull request #7570 from RetiredWizard/broadcomNeopix
Broadcom pi zero2w neopixel misbehaving/crash fix
2 parents 7d236f2 + 6ebb911 commit 0be5397

File tree

1 file changed

+33
-8
lines changed
  • ports/broadcom/common-hal/neopixel_write

1 file changed

+33
-8
lines changed

ports/broadcom/common-hal/neopixel_write/__init__.c

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,10 @@ void common_hal_neopixel_write(const digitalio_digitalinout_obj_t *digitalinout,
4545
uint8_t *pixels, uint32_t num_bytes) {
4646
// Wait to make sure we don't append onto the last transmission. This should only be a tick or
4747
// two.
48-
while (port_get_raw_ticks(NULL) < next_start_raw_ticks) {
48+
int icnt;
49+
while ((port_get_raw_ticks(NULL) < next_start_raw_ticks) &&
50+
(next_start_raw_ticks - port_get_raw_ticks(NULL) < 100)) {
51+
RUN_BACKGROUND_TASKS;
4952
}
5053

5154
BP_Function_Enum alt_function = GPIO_FUNCTION_OUTPUT;
@@ -92,7 +95,8 @@ void common_hal_neopixel_write(const digitalio_digitalinout_obj_t *digitalinout,
9295

9396
// Wait for the clock to start up.
9497
COMPLETE_MEMORY_READS;
95-
while (CM_PWM->CS_b.BUSY == 0) {
98+
icnt = 0;
99+
while ((CM_PWM->CS_b.BUSY == 0) && (icnt++ < 1000)) {
96100
}
97101
}
98102

@@ -134,24 +138,45 @@ void common_hal_neopixel_write(const digitalio_digitalinout_obj_t *digitalinout,
134138
expanded |= 0x80000000;
135139
}
136140
}
137-
while (pwm->STA_b.FULL1 == 1) {
138-
RUN_BACKGROUND_TASKS;
139-
}
140141
if (channel == 1) {
142+
icnt = 0;
143+
while ((pwm->STA_b.FULL1 == 1) && (icnt++ < 150)) {
144+
RUN_BACKGROUND_TASKS;
145+
}
141146
// Dummy value for the first channel.
142147
pwm->FIF1 = 0x000000;
143148
}
149+
icnt = 0;
150+
while ((pwm->STA_b.FULL1 == 1) && (icnt++ < 150)) {
151+
RUN_BACKGROUND_TASKS;
152+
}
144153
pwm->FIF1 = expanded;
145154
if (channel == 0) {
155+
icnt = 0;
156+
while ((pwm->STA_b.FULL1 == 1) && (icnt++ < 150)) {
157+
RUN_BACKGROUND_TASKS;
158+
}
146159
// Dummy value for the second channel.
147160
pwm->FIF1 = 0x000000;
148161
}
149162
}
150-
// Wait just a little bit so that transmission can start.
151-
common_hal_mcu_delay_us(2);
152-
while (pwm->STA_b.STA1 == 1) {
163+
164+
icnt = 0;
165+
while ((pwm->STA_b.EMPT1 == 0) && (icnt++ < 2500)) {
166+
RUN_BACKGROUND_TASKS;
167+
}
168+
// Wait for transmission to start.
169+
icnt = 0;
170+
while (((pwm->STA_b.STA1 == 0) && (pwm->STA_b.STA2 == 0)) && (icnt++ < 150)) {
153171
RUN_BACKGROUND_TASKS;
154172
}
173+
// Wait for transmission to complete.
174+
icnt = 0;
175+
while (((pwm->STA_b.STA1 == 1) || (pwm->STA_b.STA2 == 1)) && (icnt++ < 150)) {
176+
RUN_BACKGROUND_TASKS;
177+
}
178+
// Shouldn't be anything left in queue but clear it so the clock doesn't crash if there is
179+
pwm->CTL = PWM0_CTL_CLRF1_Msk;
155180

156181
gpio_set_function(digitalinout->pin->number, GPIO_FUNCTION_OUTPUT);
157182

0 commit comments

Comments
 (0)