Merge pull request #7570 from RetiredWizard/broadcomNeopix

Broadcom pi zero2w neopixel misbehaving/crash fix
This commit is contained in:
Scott Shawcroft 2023-02-14 09:56:18 -08:00 committed by GitHub
commit 0be53977f9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 33 additions and 8 deletions

View File

@ -45,7 +45,10 @@ void common_hal_neopixel_write(const digitalio_digitalinout_obj_t *digitalinout,
uint8_t *pixels, uint32_t num_bytes) { uint8_t *pixels, uint32_t num_bytes) {
// Wait to make sure we don't append onto the last transmission. This should only be a tick or // Wait to make sure we don't append onto the last transmission. This should only be a tick or
// two. // two.
while (port_get_raw_ticks(NULL) < next_start_raw_ticks) { int icnt;
while ((port_get_raw_ticks(NULL) < next_start_raw_ticks) &&
(next_start_raw_ticks - port_get_raw_ticks(NULL) < 100)) {
RUN_BACKGROUND_TASKS;
} }
BP_Function_Enum alt_function = GPIO_FUNCTION_OUTPUT; BP_Function_Enum alt_function = GPIO_FUNCTION_OUTPUT;
@ -92,7 +95,8 @@ void common_hal_neopixel_write(const digitalio_digitalinout_obj_t *digitalinout,
// Wait for the clock to start up. // Wait for the clock to start up.
COMPLETE_MEMORY_READS; COMPLETE_MEMORY_READS;
while (CM_PWM->CS_b.BUSY == 0) { icnt = 0;
while ((CM_PWM->CS_b.BUSY == 0) && (icnt++ < 1000)) {
} }
} }
@ -134,24 +138,45 @@ void common_hal_neopixel_write(const digitalio_digitalinout_obj_t *digitalinout,
expanded |= 0x80000000; expanded |= 0x80000000;
} }
} }
while (pwm->STA_b.FULL1 == 1) {
RUN_BACKGROUND_TASKS;
}
if (channel == 1) { if (channel == 1) {
icnt = 0;
while ((pwm->STA_b.FULL1 == 1) && (icnt++ < 150)) {
RUN_BACKGROUND_TASKS;
}
// Dummy value for the first channel. // Dummy value for the first channel.
pwm->FIF1 = 0x000000; pwm->FIF1 = 0x000000;
} }
icnt = 0;
while ((pwm->STA_b.FULL1 == 1) && (icnt++ < 150)) {
RUN_BACKGROUND_TASKS;
}
pwm->FIF1 = expanded; pwm->FIF1 = expanded;
if (channel == 0) { if (channel == 0) {
icnt = 0;
while ((pwm->STA_b.FULL1 == 1) && (icnt++ < 150)) {
RUN_BACKGROUND_TASKS;
}
// Dummy value for the second channel. // Dummy value for the second channel.
pwm->FIF1 = 0x000000; pwm->FIF1 = 0x000000;
} }
} }
// Wait just a little bit so that transmission can start.
common_hal_mcu_delay_us(2); icnt = 0;
while (pwm->STA_b.STA1 == 1) { while ((pwm->STA_b.EMPT1 == 0) && (icnt++ < 2500)) {
RUN_BACKGROUND_TASKS; RUN_BACKGROUND_TASKS;
} }
// Wait for transmission to start.
icnt = 0;
while (((pwm->STA_b.STA1 == 0) && (pwm->STA_b.STA2 == 0)) && (icnt++ < 150)) {
RUN_BACKGROUND_TASKS;
}
// Wait for transmission to complete.
icnt = 0;
while (((pwm->STA_b.STA1 == 1) || (pwm->STA_b.STA2 == 1)) && (icnt++ < 150)) {
RUN_BACKGROUND_TASKS;
}
// Shouldn't be anything left in queue but clear it so the clock doesn't crash if there is
pwm->CTL = PWM0_CTL_CLRF1_Msk;
gpio_set_function(digitalinout->pin->number, GPIO_FUNCTION_OUTPUT); gpio_set_function(digitalinout->pin->number, GPIO_FUNCTION_OUTPUT);