diff --git a/lib/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.cpp b/lib/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.cpp index 563095a36..d3927fc2f 100644 --- a/lib/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.cpp +++ b/lib/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.cpp @@ -11,7 +11,6 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . - */ #ifdef ESP32 @@ -68,12 +67,19 @@ int32_t _analog_pin2chan(uint32_t pin) { // returns -1 if uallocated return -1; } -void _analogWriteFreqRange(void) { +void _analogWriteFreqRange(uint8_t pin) { _analogInit(); // make sure the mapping array is initialized - for (uint32_t channel = 0; channel < MAX_PWMS; channel++) { - if (pwm_channel[channel] < 255) { - ledcSetup(channel, pwm_frequency, pwm_bit_num); - } + if (pin == 255) { + for (uint32_t channel = 0; channel < MAX_PWMS; channel++) { + if (pwm_channel[channel] < 255) { + ledcSetup(channel, pwm_frequency, pwm_bit_num); + } + } + } else { + int32_t channel = _analog_pin2chan(pin); + if (channel >= 0) { + ledcSetup(channel, pwm_frequency, pwm_bit_num); + } } } @@ -89,12 +95,22 @@ uint32_t _analogGetResolution(uint32_t x) { void analogWriteRange(uint32_t range) { pwm_bit_num = _analogGetResolution(range); - _analogWriteFreqRange(); + _analogWriteFreqRange(255); +} + +void analogWriteRange(uint32_t range, uint8_t pin) { + pwm_bit_num = _analogGetResolution(range); + _analogWriteFreqRange(pin); } void analogWriteFreq(uint32_t freq) { pwm_frequency = freq; - _analogWriteFreqRange(); + _analogWriteFreqRange(255); +} + +void analogWriteFreq(uint32_t freq, uint8_t pin) { + pwm_frequency = freq; + _analogWriteFreqRange(pin); } int32_t analogAttach(uint32_t pin, bool output_invert) { // returns ledc channel used, or -1 if failed @@ -109,7 +125,7 @@ int32_t analogAttach(uint32_t pin, bool output_invert) { // returns ledc chan // ledcAttachPin(pin, channel); -- replicating here because we want the default duty uint8_t group=(chan/8), channel=(chan%8), timer=((chan/2)%4); - + // AddLog(LOG_LEVEL_INFO, "PWM: ledc_channel pin=%i out_invert=%i", pin, output_invert); ledc_channel_config_t ledc_channel = { (int)pin, // gpio @@ -123,7 +139,6 @@ int32_t analogAttach(uint32_t pin, bool output_invert) { // returns ledc chan }; ledc_channel_config(&ledc_channel); - ledcSetup(channel, pwm_frequency, pwm_bit_num); // Serial.printf("PWM: New attach pin %d to channel %d\n", pin, channel); return channel; @@ -143,19 +158,18 @@ extern "C" void __wrap__Z11analogWritehi(uint8_t pin, int val) { /* The primary goal of this function is to add phase control to PWM ledc functions. - + Phase control allows to stress less the power supply of LED lights. By default all phases are starting at the same moment. This means the the power supply always takes a power hit at the start of each new cycle, even if the average power is low. - - Phase control is also of major importance for H-bridge where + Phase control is also of major importance for H-bridge where both PWM lines should NEVER be active at the same time. - + Unfortunately Arduino Core does not allow any customization nor extendibility for the ledc/analogWrite functions. We have therefore no other choice than duplicating part of Arduino code. - + WARNING: this means it can easily break if ever Arduino internal implementation changes. */ diff --git a/lib/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.h b/lib/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.h index a4c6a602e..a8a014abf 100644 --- a/lib/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.h +++ b/lib/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.h @@ -26,7 +26,9 @@ // input range is in full range, ledc needs bits void analogWriteRange(uint32_t range); +void analogWriteRange(uint32_t range, uint8_t pin); void analogWriteFreq(uint32_t freq); +void analogWriteFreq(uint32_t freq, uint8_t pin); int32_t analogAttach(uint32_t pin, bool output_invert = false); // returns the ledc channel, or -1 if failed. This is implicitly called by analogWrite if the channel was not already allocated void analogWrite(uint8_t pin, int val); diff --git a/tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino b/tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino index 8cdea103a..39e9c8d68 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino @@ -182,8 +182,9 @@ void ShutterRtc50mS(void) startWaveformClockCycles(Pin(GPIO_PWM1, i), cc/2, cc/2, 0, -1, 0, false); #endif // ESP8266 #ifdef ESP32 - analogWriteFreq(Shutter[i].pwm_velocity); - analogWrite(Pin(GPIO_PWM1, i), 50); + analogWriteFreq(Shutter[i].pwm_velocity,Pin(GPIO_PWM1, i)); + TasmotaGlobal.pwm_value[i] = 512; + PwmApplyGPIO(false); #endif // ESP32 } break; @@ -467,7 +468,6 @@ void ShutterDecellerateForStop(uint8_t i) delay(50); AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Velocity %ld, Delta %d"), Shutter[i].pwm_velocity, Shutter[i].accelerator ); // Control will be done in RTC Ticker. - } if (ShutterGlobal.position_mode == SHT_COUNTER){ missing_steps = ((Shutter[i].target_position-Shutter[i].start_position)*Shutter[i].direction*ShutterGlobal.open_velocity_max/RESOLUTION/STEPS_PER_SECOND) - RtcSettings.pulse_counter[i]; @@ -477,7 +477,13 @@ void ShutterDecellerateForStop(uint8_t i) //AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Remain %d count %d -> target %d, dir %d"), missing_steps, RtcSettings.pulse_counter[i], (uint32_t)(Shutter[i].target_position-Shutter[i].start_position)*Shutter[i].direction*ShutterGlobal.open_velocity_max/RESOLUTION/STEPS_PER_SECOND, Shutter[i].direction); while (RtcSettings.pulse_counter[i] < (uint32_t)(Shutter[i].target_position-Shutter[i].start_position)*Shutter[i].direction*ShutterGlobal.open_velocity_max/RESOLUTION/STEPS_PER_SECOND && missing_steps > 0) { } +#ifdef ESP8266 analogWrite(Pin(GPIO_PWM1, i), 0); // removed with 8.3 because of reset caused by watchog +#endif +#ifdef ESP32 + TasmotaGlobal.pwm_value[i] = 0; + PwmApplyGPIO(false); +#endif // ESP32 Shutter[i].real_position = ShutterCalculatePosition(i); //AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Remain steps %d"), missing_steps); AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Real %d, Pulsecount %d, tobe %d, Start %d"), Shutter[i].real_position,RtcSettings.pulse_counter[i], (uint32_t)(Shutter[i].target_position-Shutter[i].start_position)*Shutter[i].direction*ShutterGlobal.open_velocity_max/RESOLUTION/STEPS_PER_SECOND, Shutter[i].start_position); @@ -635,8 +641,15 @@ void ShutterStartInit(uint32_t i, int32_t direction, int32_t target_pos) switch (ShutterGlobal.position_mode) { #ifdef SHUTTER_STEPPER case SHT_COUNTER: +#ifdef ESP8266 analogWriteFreq(Shutter[i].pwm_velocity); analogWrite(Pin(GPIO_PWM1, i), 0); +#endif +#ifdef ESP32 + analogWriteFreq(PWM_MIN,Pin(GPIO_PWM1, i)); + TasmotaGlobal.pwm_value[i] = 0; + PwmApplyGPIO(false); +#endif RtcSettings.pulse_counter[i] = 0; break; #endif