diff --git a/tasmota/tasmota_xdrv_driver/xdrv_27_esp32_shutter.ino b/tasmota/tasmota_xdrv_driver/xdrv_27_esp32_shutter.ino index 67e9ae81e..a0b447e39 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_27_esp32_shutter.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_27_esp32_shutter.ino @@ -23,6 +23,7 @@ * Shutter or Blind support using two consecutive relays * Shutters for ESP32 with max eight shutters using more RAM and Settings from filesystem \*********************************************************************************************/ +#include "soc/soc_caps.h" #define XDRV_27 27 #ifndef SHUTTER_STEPPER @@ -178,6 +179,7 @@ struct SHUTTER { uint16_t last_reported_time = 0; // get information on skipped 50ms loop() slots uint32_t last_stop_time = 0; // record the last time the relay was switched off uint8_t button_simu_pressed = 0; // record if both button where pressed simultanously + uint8_t ledc_channel = 0; // current used channel for PWM } Shutter[MAX_SHUTTERS_ESP32]; struct SHUTTERGLOBAL { @@ -469,9 +471,6 @@ int32_t ShutterCalculatePosition(uint32_t i) void ShutterDecellerateForStop(uint8_t i) { -#ifdef ESP32 - bool pwm_apply = false; // ESP32 only, do we need to apply PWM changes -#endif switch (ShutterGlobal.position_mode) { case SHT_PWM_VALUE: case SHT_COUNTER: @@ -491,13 +490,10 @@ 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; - pwm_apply = true; -#endif // ESP32 + ledcWrite(Shutter[i].ledc_channel, 0); + ledcAttachPin(Pin(GPIO_PWM1, i), SOC_LEDC_CHANNEL_NUM); + Shutter[i].ledc_channel = 0; 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); @@ -506,9 +502,6 @@ void ShutterDecellerateForStop(uint8_t i) Shutter[i].pwm_velocity = 0; break; } -#ifdef ESP32 - if (pwm_apply) { PwmApplyGPIO(false); } -#endif } uint16_t ShutterGetCycleTime(uint8_t i, uint8_t max_runtime) { @@ -539,6 +532,20 @@ uint16_t ShutterGetCycleTime(uint8_t i, uint8_t max_runtime) { return cycle_time; } +uint8_t ShutterGetFreeChannel() { + uint8_t nextFreeChannel = 0; + for (uint8_t i = 0; i < MAX_SHUTTERS_ESP32; i++) { + //SOC_LEDC_CHANNEL_NUM + nextFreeChannel = tmax(nextFreeChannel, Shutter[i].ledc_channel); + } + if (nextFreeChannel >= SOC_LEDC_CHANNEL_NUM) { + AddLog(LOG_LEVEL_ERROR, PSTR("SHT: All PWM channel busy. Open issue-ticket.")); + } else { + AddLog(LOG_LEVEL_DEBUG, PSTR("SHT: Use channel %d"), nextFreeChannel+1); + } + return nextFreeChannel++; +} + uint8_t ShutterGetOptions(uint8_t index) { return ShutterSettings.shutter_options[index]; } @@ -964,9 +971,6 @@ void ShutterReportPosition(bool always, uint32_t index) void ShutterRtc50mS(void) { -#ifdef ESP32 - bool pwm_apply = false; // ESP32 only, do we need to apply PWM changes -#endif // No Logging allowed. RTC Timer for (uint8_t i = 0; i < TasmotaGlobal.shutters_present; i++) { if (Shutter[i].direction) { @@ -987,25 +991,15 @@ void ShutterRtc50mS(void) //AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Accelerator i=%d -> %d"),i, Shutter[i].accelerator); ShutterUpdateVelocity(i); digitalWrite(Pin(GPIO_PWM1, i), LOW); - #ifdef ESP8266 - // Convert frequency into clock cycles - uint32_t cc = microsecondsToClockCycles(1000000UL) / Shutter[i].pwm_velocity; - startWaveformClockCycles(Pin(GPIO_PWM1, i), cc/2, cc/2, 0, -1, 0, false); - #endif // ESP8266 - #ifdef ESP32 - ledcWriteTone(i, Shutter[i].pwm_velocity); // - ledcWrite(i, 512); // Setzt den PWM-Wert auf 0 + + ledcWriteTone(Shutter[i].ledc_channel, Shutter[i].pwm_velocity); // + //ledcWrite(i, 512); // Setzt den PWM-Wert auf 0 TasmotaGlobal.pwm_value[i] = 512; - pwm_apply = true; - #endif // ESP32 } break; } } // if (Shutter[i].direction) } -#ifdef ESP32 - if (pwm_apply) { PwmApplyGPIO(false); } -#endif } void ShutterSetPosition(uint32_t device, uint32_t position) @@ -1172,16 +1166,11 @@ 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 - ledcSetup(i, Shutter[i].pwm_velocity, 8); - ledcAttachPin(Pin(GPIO_PWM1, i), i); // Nehmen Sie an, dass GPIO_PWM1 der gewünschte GPIO-Pin ist. - ledcWriteTone(i, Shutter[i].pwm_velocity); // - ledcWrite(i, 0); // Setzt den PWM-Wert auf 0 -#endif + Shutter[i].ledc_channel = ShutterGetFreeChannel(); + ledcSetup(Shutter[i].ledc_channel, Shutter[i].pwm_velocity, 8); + ledcAttachPin(Pin(GPIO_PWM1, i), Shutter[i].ledc_channel); + ledcWriteTone(Shutter[i].ledc_channel, Shutter[i].pwm_velocity); + ledcWrite(Shutter[i].ledc_channel, 0); // Setzt den PWM-Wert auf 0 RtcSettings.pulse_counter[i] = 0; break; #endif