@@ -461,9 +461,58 @@ static int esp8266_pwm_pin_index[ESP8266_PWM_MAX_CH];
461461static uint32_t esp8266_pwm_gpio [ESP8266_PWM_MAX_CH ];
462462static uint32_t esp8266_pwm_duty [ESP8266_PWM_MAX_CH ];
463463static float esp8266_pwm_value [ESP8266_PWM_MAX_CH ];
464+ static bool esp8266_pwm_initial_value_set [ESP8266_PWM_MAX_CH ];
464465static int esp8266_pwm_count = 0 ;
465466static bool esp8266_pwm_started = false;
466- static bool esp8266_pwm_finalized = false;
467+
468+ static bool ESP8266_IsPWMRole (int role )
469+ {
470+ return role == IOR_PWM
471+ || role == IOR_PWM_n
472+ || role == IOR_PWM_ScriptOnly
473+ || role == IOR_PWM_ScriptOnly_n ;
474+ }
475+
476+ static int ESP8266_CountConfiguredPWMPins (void )
477+ {
478+ int count = 0 ;
479+
480+ for (int i = 0 ; i < g_numPins ; i ++ )
481+ {
482+ if (!ESP8266_IsPWMRole (g_cfg .pins .roles [i ]))
483+ {
484+ continue ;
485+ }
486+
487+ espPinMapping_t * pin = g_pins + i ;
488+ if (pin -> pin == GPIO_NUM_NC || pin -> pin == GPIO_NUM_0 )
489+ {
490+ continue ;
491+ }
492+
493+ bool duplicate = false;
494+ for (int j = 0 ; j < i ; j ++ )
495+ {
496+ if (ESP8266_IsPWMRole (g_cfg .pins .roles [j ]) && g_pins [j ].pin == pin -> pin )
497+ {
498+ duplicate = true;
499+ break ;
500+ }
501+ }
502+ if (duplicate )
503+ {
504+ continue ;
505+ }
506+
507+ count ++ ;
508+ if (count >= ESP8266_PWM_MAX_CH )
509+ {
510+ return ESP8266_PWM_MAX_CH ;
511+ }
512+ }
513+
514+ return count ;
515+ }
467516
468517static int ESP8266_GetPWMChannelForPinIndex (int index )
469518{
@@ -522,6 +571,18 @@ static bool ESP8266_PWM_Rebuild(void)
522571 return false;
523572 }
524573
574+ float phase [ESP8266_PWM_MAX_CH ];
575+ for (int i = 0 ; i < esp8266_pwm_count ; i ++ )
576+ {
577+ phase [i ] = 0.0f ;
578+ }
579+ err = pwm_set_phases (phase );
580+ if (err != ESP_OK )
581+ {
582+ ADDLOG_ERROR (LOG_FEATURE_PINS , "ESP8266 PWM phase init failed: %i" , err );
583+ return false;
584+ }
585+
525586 err = pwm_start ();
526587 if (err != ESP_OK )
527588 {
@@ -534,14 +595,38 @@ static bool ESP8266_PWM_Rebuild(void)
534595 return true;
535596}
536597
537- void HAL_PIN_PWM_Finalize (void )
598+ static bool ESP8266_PWM_HasInitialValues (void )
538599{
539- esp8266_pwm_finalized = true;
600+ for (int i = 0 ; i < esp8266_pwm_count ; i ++ )
601+ {
602+ if (!esp8266_pwm_initial_value_set [i ])
603+ {
604+ return false;
605+ }
606+ }
540607
541- if (!esp8266_pwm_started )
608+ return true;
609+ }
610+
611+ static void ESP8266_PWM_TryStartQueuedGroup (void )
612+ {
613+ if (esp8266_pwm_started )
542614 {
543- ESP8266_PWM_Rebuild ();
615+ return ;
616+ }
617+
618+ int expected_count = ESP8266_CountConfiguredPWMPins ();
619+ if (expected_count <= 0 || esp8266_pwm_count < expected_count )
620+ {
621+ return ;
544622 }
623+
624+ if (!ESP8266_PWM_HasInitialValues ())
625+ {
626+ return ;
627+ }
628+
629+ ESP8266_PWM_Rebuild ();
545630}
546631
547632int PIN_GetPWMIndexForPinIndex (int index )
@@ -593,16 +678,21 @@ void HAL_PIN_PWM_Stop(int index)
593678 esp8266_pwm_gpio [i ] = esp8266_pwm_gpio [i + 1 ];
594679 esp8266_pwm_duty [i ] = esp8266_pwm_duty [i + 1 ];
595680 esp8266_pwm_value [i ] = esp8266_pwm_value [i + 1 ];
681+ esp8266_pwm_initial_value_set [i ] = esp8266_pwm_initial_value_set [i + 1 ];
596682 }
597683 esp8266_pwm_count -- ;
598684
599685 gpio_set_level (pin -> pin , 0 );
600686 pin -> isConfigured = false;
601687
602- if (esp8266_pwm_finalized )
688+ if (esp8266_pwm_started )
603689 {
604690 ESP8266_PWM_Rebuild ();
605691 }
692+ else
693+ {
694+ ESP8266_PWM_TryStartQueuedGroup ();
695+ }
606696}
607697
608698void HAL_PIN_PWM_Start (int index , int freq )
@@ -640,18 +730,21 @@ void HAL_PIN_PWM_Start(int index, int freq)
640730 esp8266_pwm_gpio [ch ] = (uint32_t )pin -> pin ;
641731 esp8266_pwm_duty [ch ] = 0 ;
642732 esp8266_pwm_value [ch ] = -1.0f ;
733+ esp8266_pwm_initial_value_set [ch ] = false;
643734 esp8266_pwm_count ++ ;
644735
645736 pin -> isConfigured = true;
646737 ESP_ConfigurePin (pin -> pin , GPIO_MODE_OUTPUT , false, false, GPIO_INTR_DISABLE );
647738 ADDLOG_INFO (LOG_FEATURE_PINS , "ESP8266 PWM queued ch %i pin %i" , ch , pin -> pin );
648739
649- // PIN_SetupPins finalises the ESP8266 PWM group after all configured PWM pins are queued.
650- // If a user changes pin roles after initial setup, rebuild immediately so the new channel exists.
651- if (esp8266_pwm_finalized )
740+ if (esp8266_pwm_started )
652741 {
653742 ESP8266_PWM_Rebuild ();
654743 }
744+ else
745+ {
746+ ESP8266_PWM_TryStartQueuedGroup ();
747+ }
655748}
656749
657750void HAL_PIN_PWM_Update (int index , float value )
@@ -678,14 +771,12 @@ void HAL_PIN_PWM_Update(int index, float value)
678771
679772 uint32_t duty = ESP8266_PWMValueToDuty (value );
680773 esp8266_pwm_duty [ch ] = duty ;
774+ esp8266_pwm_initial_value_set [ch ] = true;
681775
682776 if (!esp8266_pwm_started )
683777 {
684- if (!esp8266_pwm_finalized )
685- {
686- return ;
687- }
688- if (!ESP8266_PWM_Rebuild ())
778+ ESP8266_PWM_TryStartQueuedGroup ();
779+ if (!esp8266_pwm_started )
689780 {
690781 return ;
691782 }
0 commit comments