From c2e244378acb5c49e91f447287888c729f5d7f79 Mon Sep 17 00:00:00 2001 From: Alexander Entinger Date: Wed, 8 Feb 2023 10:24:39 +0100 Subject: [PATCH] Fix: Clean-up previous state when alternating between GPIO and PWM functionality. This fixes #613. --- cores/arduino/wiring_analog.cpp | 11 +++++++++++ cores/arduino/wiring_digital.cpp | 11 +++++++++++ 2 files changed, 22 insertions(+) diff --git a/cores/arduino/wiring_analog.cpp b/cores/arduino/wiring_analog.cpp index aec8a47d0..d11783d68 100644 --- a/cores/arduino/wiring_analog.cpp +++ b/cores/arduino/wiring_analog.cpp @@ -68,6 +68,17 @@ void analogWrite(pin_size_t pin, int val) #endif float percent = (float)val/(float)((1 << write_resolution)-1); mbed::PwmOut* pwm = digitalPinToPwm(pin); + + /* Check if this pin has been previously configured as a GPIO pin. + * If it has, delete the GPIO allocation as well as the PWM allocation + * to enforce a full re-initialisation of the PWM module. + */ + mbed::DigitalInOut * gpio = digitalPinToGpio(pin); + if ((gpio != NULL) && (pwm != NULL)) { + delete gpio; gpio = NULL; digitalPinToGpio(pin) = NULL; + delete pwm; pwm = NULL; digitalPinToPwm(pin) = NULL; + } + if (pwm == NULL) { pwm = new mbed::PwmOut(digitalPinToPinName(pin)); digitalPinToPwm(pin) = pwm; diff --git a/cores/arduino/wiring_digital.cpp b/cores/arduino/wiring_digital.cpp index c4fa74b0c..f20c0da0c 100644 --- a/cores/arduino/wiring_digital.cpp +++ b/cores/arduino/wiring_digital.cpp @@ -94,6 +94,17 @@ void digitalWrite(pin_size_t pin, PinStatus val) return; } mbed::DigitalInOut* gpio = digitalPinToGpio(pin); + + /* Check if this pin has been previously configured as a PWM pin. + * If it has, delete the GPIO allocation as well as the PWM allocation + * to enforce a full re-initialisation of the GPIO module. + */ + mbed::PwmOut * pwm = digitalPinToPwm(pin); + if ((gpio != NULL) && (pwm != NULL)) { + delete gpio; gpio = NULL; digitalPinToGpio(pin) = NULL; + delete pwm; pwm = NULL; digitalPinToPwm(pin) = NULL; + } + if (gpio == NULL) { gpio = new mbed::DigitalInOut(digitalPinToPinName(pin), PIN_OUTPUT, PullNone, val); digitalPinToGpio(pin) = gpio;