From 07452b215ec73eb939a180fc1b4459d15a0cad54 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Wed, 21 Aug 2024 11:56:30 -0700 Subject: [PATCH 1/2] Fix FreeRTOS weirdness on Funhouse Funhouse has DotStars attached to SPI that exercises this bug. Most boards are NeoPixel and avoid this. Fixes #9486 --- ports/espressif/common-hal/busio/SPI.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ports/espressif/common-hal/busio/SPI.c b/ports/espressif/common-hal/busio/SPI.c index 19446bb3d054..6439ca411299 100644 --- a/ports/espressif/common-hal/busio/SPI.c +++ b/ports/espressif/common-hal/busio/SPI.c @@ -129,6 +129,7 @@ void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { // Wait for any other users of this to finish. while (!common_hal_busio_spi_try_lock(self)) { + RUN_BACKGROUND_TASKS; } // Mark us as deinit early in case we are used in an interrupt. @@ -139,7 +140,10 @@ void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { spi_bus_remove_device(spi_handle[self->host_id]); spi_bus_free(self->host_id); + // Release the mutex before we delete it. Otherwise FreeRTOS gets unhappy. + xSemaphoreGive(self->mutex); vSemaphoreDelete(self->mutex); + self->mutex = NULL; common_hal_reset_pin(self->MOSI); common_hal_reset_pin(self->MISO); @@ -166,7 +170,7 @@ bool common_hal_busio_spi_try_lock(busio_spi_obj_t *self) { } bool common_hal_busio_spi_has_lock(busio_spi_obj_t *self) { - return xSemaphoreGetMutexHolder(self->mutex) == xTaskGetCurrentTaskHandle(); + return self->mutex != NULL && xSemaphoreGetMutexHolder(self->mutex) == xTaskGetCurrentTaskHandle(); } void common_hal_busio_spi_unlock(busio_spi_obj_t *self) { From 28f3d91752028b02387790b866aa387b5cd8aa8d Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Wed, 21 Aug 2024 12:44:40 -0700 Subject: [PATCH 2/2] Unlock DotStar SPI before deinit --- supervisor/shared/status_leds.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/supervisor/shared/status_leds.c b/supervisor/shared/status_leds.c index 73b1f4ef15a6..e7b3d4b6e46d 100644 --- a/supervisor/shared/status_leds.c +++ b/supervisor/shared/status_leds.c @@ -196,8 +196,10 @@ void status_led_deinit() { #elif defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK) #if CIRCUITPY_BITBANG_APA102 + shared_module_bitbangio_spi_unlock(&status_apa102); shared_module_bitbangio_spi_deinit(&status_apa102); #else + common_hal_busio_spi_unlock(&status_apa102); common_hal_busio_spi_deinit(&status_apa102); #endif