diff --git a/ports/broadcom/common-hal/neopixel_write/__init__.c b/ports/broadcom/common-hal/neopixel_write/__init__.c index 0cd76ebca9..245244614f 100644 --- a/ports/broadcom/common-hal/neopixel_write/__init__.c +++ b/ports/broadcom/common-hal/neopixel_write/__init__.c @@ -45,7 +45,10 @@ void common_hal_neopixel_write(const digitalio_digitalinout_obj_t *digitalinout, 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 // 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; @@ -92,7 +95,8 @@ void common_hal_neopixel_write(const digitalio_digitalinout_obj_t *digitalinout, // Wait for the clock to start up. 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; } } - while (pwm->STA_b.FULL1 == 1) { - RUN_BACKGROUND_TASKS; - } if (channel == 1) { + icnt = 0; + while ((pwm->STA_b.FULL1 == 1) && (icnt++ < 150)) { + RUN_BACKGROUND_TASKS; + } // Dummy value for the first channel. pwm->FIF1 = 0x000000; } + icnt = 0; + while ((pwm->STA_b.FULL1 == 1) && (icnt++ < 150)) { + RUN_BACKGROUND_TASKS; + } pwm->FIF1 = expanded; if (channel == 0) { + icnt = 0; + while ((pwm->STA_b.FULL1 == 1) && (icnt++ < 150)) { + RUN_BACKGROUND_TASKS; + } // Dummy value for the second channel. pwm->FIF1 = 0x000000; } } - // Wait just a little bit so that transmission can start. - common_hal_mcu_delay_us(2); - while (pwm->STA_b.STA1 == 1) { + + icnt = 0; + while ((pwm->STA_b.EMPT1 == 0) && (icnt++ < 2500)) { 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);