Skip to content

Commit a2bbca1

Browse files
committed
Broadcom Raspberry Pi Zero2W neopixel timing fix
These changes result in working neopixel functionality. I've tested on both the zero2w and the pi4b (The 4b didn't exhibit the original issue) and the boards now behave properly with 1 to 30 pixels and the board hanging no longer occurs. Remove mod that didn't help during testing Restoring back to original structure Replace 2 microsecond delay w/deterministic loop Remove unneded check for empty queue Put transmit delay outside loop so Queue is used Make sure last transmission is complete
1 parent 795e46c commit a2bbca1

File tree

1 file changed

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

1 file changed

+32
-8
lines changed

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

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,11 @@ 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+
52+
RUN_BACKGROUND_TASKS;
4953
}
5054

5155
BP_Function_Enum alt_function = GPIO_FUNCTION_OUTPUT;
@@ -92,7 +96,8 @@ void common_hal_neopixel_write(const digitalio_digitalinout_obj_t *digitalinout,
9296

9397
// Wait for the clock to start up.
9498
COMPLETE_MEMORY_READS;
95-
while (CM_PWM->CS_b.BUSY == 0) {
99+
icnt = 0;
100+
while ((CM_PWM->CS_b.BUSY == 0) & (icnt++ < 1000)) {
96101
}
97102
}
98103

@@ -134,22 +139,41 @@ void common_hal_neopixel_write(const digitalio_digitalinout_obj_t *digitalinout,
134139
expanded |= 0x80000000;
135140
}
136141
}
137-
while (pwm->STA_b.FULL1 == 1) {
138-
RUN_BACKGROUND_TASKS;
139-
}
140142
if (channel == 1) {
143+
icnt=0;
144+
while ((pwm->STA_b.FULL1 == 1) & (icnt++ < 150)) {
145+
RUN_BACKGROUND_TASKS;
146+
}
141147
// Dummy value for the first channel.
142148
pwm->FIF1 = 0x000000;
143149
}
150+
icnt=0;
151+
while ((pwm->STA_b.FULL1 == 1) & (icnt++ < 150)) {
152+
RUN_BACKGROUND_TASKS;
153+
}
144154
pwm->FIF1 = expanded;
145155
if (channel == 0) {
156+
icnt=0;
157+
while ((pwm->STA_b.FULL1 == 1) & (icnt++ < 150)) {
158+
RUN_BACKGROUND_TASKS;
159+
}
146160
// Dummy value for the second channel.
147161
pwm->FIF1 = 0x000000;
148162
}
149163
}
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) {
164+
165+
icnt = 0;
166+
while ((pwm->STA_b.EMPT1 == 0) & (icnt++ < 2500)) {
167+
RUN_BACKGROUND_TASKS;
168+
}
169+
// Wait for transmission to start.
170+
icnt = 0;
171+
while (((pwm->STA_b.STA1 ==0) & (pwm->STA_b.STA2 == 0)) & (icnt++ < 150)) {
172+
RUN_BACKGROUND_TASKS;
173+
}
174+
// Wait for transmission to complete.
175+
icnt = 0;
176+
while (((pwm->STA_b.STA1 == 1) | (pwm->STA_b.STA2 == 1)) & (icnt++ < 150)) {
153177
RUN_BACKGROUND_TASKS;
154178
}
155179

0 commit comments

Comments
 (0)