diff --git a/cores/arduino/wiring_analog.c b/cores/arduino/wiring_analog.c index 2a8421a..cdf1226 100644 --- a/cores/arduino/wiring_analog.c +++ b/cores/arduino/wiring_analog.c @@ -148,7 +148,7 @@ It is recommended to turn off the timer in the following order: */ void analogWriteStop(uint32_t PinNumber) { - if (pwmIsInited > 0) + if ((pwmIsInited > 0) && (digitalPinPwmIsOn(PinNumber))) { // load the timer address and channel number corresponding to the specified pin htimer32.Instance = pwmPinToTimer(PinNumber); @@ -164,6 +164,10 @@ void analogWriteStop(uint32_t PinNumber) HAL_Timer32_Stop(&htimer32); HAL_Timer32_Deinit(&htimer32); } + + // config pin as input when timer channel off + HAL_GPIO_PinConfig(digitalPinToPort(PinNumber), digitalPinToBitMask(PinNumber), + HAL_GPIO_MODE_GPIO_INPUT, HAL_GPIO_PULL_NONE, HAL_GPIO_DS_2MA); } } diff --git a/variants/standart/pins_arduino.h b/variants/standart/pins_arduino.h index 5f59b36..16dc84b 100644 --- a/variants/standart/pins_arduino.h +++ b/variants/standart/pins_arduino.h @@ -76,6 +76,7 @@ uint32_t analogInputToChannelNumber(uint32_t PinNumber); // PWM bool digitalPinHasPWM(uint8_t p); +bool digitalPinPwmIsOn(uint8_t digitalPin); // use only if digitalPinHasPWM() == true // determines which timer the pin belongs to TIMER32_TypeDef* pwmPinToTimer(uint32_t digPinNumber); // determines which timer channel the pin belongs to diff --git a/variants/standart/variant.c b/variants/standart/variant.c index 1cec497..62b59fb 100644 --- a/variants/standart/variant.c +++ b/variants/standart/variant.c @@ -107,6 +107,10 @@ volatile uint32_t* portInputRegister(GPIO_TypeDef* GPIO_x) return &GPIO_x->STATE; } +// return config of pin with pinShift(0...16) in portReg (config, pupd, ds for ports 0...2) +#define PIN_PAD_CONFIG(portReg, pinShift) ((PAD_CONFIG->portReg >> (pinShift<<1)) & 0b11) + + // ---------------------- ADC ---------------------- // // determines the ADC channel number by the board pin number uint32_t analogInputToChannelNumber(uint32_t PinNumber) @@ -142,6 +146,38 @@ uint32_t analogInputToChannelNumber(uint32_t PinNumber) } // ---------------------- PWM ---------------------- // +// use only if digitalPinHasPWM() == true +#define PWM_PIN_TO_PORT_NUMBER(pin) (((pin==10)||(pin==11)) ? 1:0) +// use only if digitalPinHasPWM() == true +static inline uint8_t pwmPinToGpioPinShift(uint8_t digitalPin) +{ + if (digitalPin == 3) + return 0; + else if ((digitalPin == 5) || (digitalPin == 11)) + return 1; + else if (digitalPin == 6) + return 2; + else // pins 9 10 + return 3; +} +// use only if digitalPinHasPWM() == true +// return true if digitalPin configured as pwm +bool digitalPinPwmIsOn(uint8_t digitalPin) +{ + uint8_t config = 0; + uint8_t pinShift = pwmPinToGpioPinShift(digitalPin); + + if (PWM_PIN_TO_PORT_NUMBER(digitalPin) == 0) + config = PIN_PAD_CONFIG(PORT_0_CFG, pinShift); + else + config = PIN_PAD_CONFIG(PORT_1_CFG, pinShift); + + if (config == 2) + return true; + else + return false; +} + bool digitalPinHasPWM(uint8_t p) { bool ret = false; @@ -232,7 +268,6 @@ int8_t digitalPinToInterrupt(uint32_t digPinNumber) // pins shift in registers #define PIN_3_SHIFT 3 #define PIN_4_SHIFT 4 -#define PORT1_GET_PAD_CONFIG(pinShift) ((PAD_CONFIG->PORT_1_CFG >> (pinShift<<1)) & 0b11) #define PORT1_GET_PAD_PUPD(pinShift) ((PAD_CONFIG->PORT_1_PUPD >> (pinShift<<1)) & 0b11) #define PORT1_GET_GPIO_STATE(pinShift) ((GPIO_1->OUTPUT_ >> pinShift) & 0b1) @@ -242,7 +277,7 @@ void spi_onBegin(void) // because spi needs pin 1.3 for correct work // replace config from 1.3 to 1.4 - uint8_t config = PORT1_GET_PAD_CONFIG(PIN_3_SHIFT); + uint8_t config = PIN_PAD_CONFIG(PORT_1_CFG, PIN_3_SHIFT); if (config == 0) // common gpio { // get info from pin gpio1.3 and set config to gpio1.4