From 93ee54a2fb52bf20c49e9dfc846e03f400322ec5 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Tue, 15 Nov 2022 16:14:31 -0800 Subject: [PATCH 1/2] Fix PWM status LED never_reset It doesn't need never reset because the status LED is only active when user code isn't. This also fixes PWM never reset on espressif so that deinit will undo it. Fixes #6223 --- ports/espressif/common-hal/pwmio/PWMOut.c | 18 +++++++++++++++++- supervisor/shared/status_leds.c | 18 +++--------------- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/ports/espressif/common-hal/pwmio/PWMOut.c b/ports/espressif/common-hal/pwmio/PWMOut.c index d83ce6590a..161f547480 100644 --- a/ports/espressif/common-hal/pwmio/PWMOut.c +++ b/ports/espressif/common-hal/pwmio/PWMOut.c @@ -166,7 +166,20 @@ void common_hal_pwmio_pwmout_never_reset(pwmio_pwmout_obj_t *self) { void common_hal_pwmio_pwmout_reset_ok(pwmio_pwmout_obj_t *self) { never_reset_tim[self->tim_handle.timer_num] = false; - never_reset_chan[self->chan_handle.channel] = false; + // Search if any other channel is using the timer and is never reset. + // Otherwise, we clear never_reset for the timer as well. + bool other_never_reset = false; + for (size_t i = 0; i < LEDC_CHANNEL_MAX; i++) { + if (i != self->tim_handle.timer_num && + reserved_channels[i] == self->tim_handle.timer_num && + never_reset_chan[i]) { + other_never_reset = true; + break; + } + } + if (!other_never_reset) { + never_reset_chan[self->chan_handle.channel] = false; + } } bool common_hal_pwmio_pwmout_deinited(pwmio_pwmout_obj_t *self) { @@ -182,11 +195,13 @@ void common_hal_pwmio_pwmout_deinit(pwmio_pwmout_obj_t *self) { ledc_stop(LEDC_LOW_SPEED_MODE, self->chan_handle.channel, 0); } reserved_channels[self->chan_handle.channel] = INDEX_EMPTY; + never_reset_chan[self->chan_handle.channel] = false; // Search if any other channel is using the timer bool taken = false; for (size_t i = 0; i < LEDC_CHANNEL_MAX; i++) { if (reserved_channels[i] == self->tim_handle.timer_num) { taken = true; + break; } } // Variable frequency means there's only one channel on the timer @@ -195,6 +210,7 @@ void common_hal_pwmio_pwmout_deinit(pwmio_pwmout_obj_t *self) { reserved_timer_freq[self->tim_handle.timer_num] = 0; // if timer isn't varfreq this will be off aleady varfreq_timers[self->tim_handle.timer_num] = false; + never_reset_tim[self->tim_handle.timer_num] = false; } common_hal_reset_pin(self->pin); self->deinited = true; diff --git a/supervisor/shared/status_leds.c b/supervisor/shared/status_leds.c index 315e64a9a0..7e6c7983b1 100644 --- a/supervisor/shared/status_leds.c +++ b/supervisor/shared/status_leds.c @@ -179,27 +179,15 @@ void status_led_init() { #elif CIRCUITPY_PWM_RGB_LED if (common_hal_mcu_pin_is_free(CIRCUITPY_RGB_STATUS_R)) { - pwmout_result_t red_result = common_hal_pwmio_pwmout_construct(&rgb_status_r, CIRCUITPY_RGB_STATUS_R, 0, 50000, false); - - if (PWMOUT_OK == red_result) { - common_hal_pwmio_pwmout_never_reset(&rgb_status_r); - } + common_hal_pwmio_pwmout_construct(&rgb_status_r, CIRCUITPY_RGB_STATUS_R, 0, 50000, false); } if (common_hal_mcu_pin_is_free(CIRCUITPY_RGB_STATUS_G)) { - pwmout_result_t green_result = common_hal_pwmio_pwmout_construct(&rgb_status_g, CIRCUITPY_RGB_STATUS_G, 0, 50000, false); - - if (PWMOUT_OK == green_result) { - common_hal_pwmio_pwmout_never_reset(&rgb_status_g); - } + common_hal_pwmio_pwmout_construct(&rgb_status_g, CIRCUITPY_RGB_STATUS_G, 0, 50000, false); } if (common_hal_mcu_pin_is_free(CIRCUITPY_RGB_STATUS_B)) { - pwmout_result_t blue_result = common_hal_pwmio_pwmout_construct(&rgb_status_b, CIRCUITPY_RGB_STATUS_B, 0, 50000, false); - - if (PWMOUT_OK == blue_result) { - common_hal_pwmio_pwmout_never_reset(&rgb_status_b); - } + common_hal_pwmio_pwmout_construct(&rgb_status_b, CIRCUITPY_RGB_STATUS_B, 0, 50000, false); } #elif defined(MICROPY_HW_LED_STATUS) From 8e4e84c58b337eadfa1cd764011786d7c540e187 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Tue, 15 Nov 2022 16:51:47 -0800 Subject: [PATCH 2/2] Match channel number, not timer number --- ports/espressif/common-hal/pwmio/PWMOut.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/espressif/common-hal/pwmio/PWMOut.c b/ports/espressif/common-hal/pwmio/PWMOut.c index 161f547480..68518fbd25 100644 --- a/ports/espressif/common-hal/pwmio/PWMOut.c +++ b/ports/espressif/common-hal/pwmio/PWMOut.c @@ -170,7 +170,7 @@ void common_hal_pwmio_pwmout_reset_ok(pwmio_pwmout_obj_t *self) { // Otherwise, we clear never_reset for the timer as well. bool other_never_reset = false; for (size_t i = 0; i < LEDC_CHANNEL_MAX; i++) { - if (i != self->tim_handle.timer_num && + if (i != self->chan_handle.channel && reserved_channels[i] == self->tim_handle.timer_num && never_reset_chan[i]) { other_never_reset = true;