@@ -55,27 +55,32 @@ xSemaphoreHandle _ledc_sys_lock = NULL;
55
55
56
56
static void _on_apb_change (void * arg , apb_change_ev_t ev_type , uint32_t old_apb , uint32_t new_apb ){
57
57
if (ev_type == APB_AFTER_CHANGE && old_apb != new_apb ){
58
- uint32_t iarg = (uint32_t )arg ;
59
- uint8_t chan = iarg ;
60
- uint8_t group = (chan /8 ), timer = ((chan /2 )%4 );
58
+ uint16_t iarg = (uint16_t * )arg ;
59
+ uint8_t chan = 0 ;
61
60
old_apb /= 1000000 ;
62
61
new_apb /= 1000000 ;
63
- if (LEDC_TIMER (group , timer ).conf .tick_sel ){
64
- LEDC_MUTEX_LOCK ();
65
- uint32_t old_div = LEDC_TIMER (group , timer ).conf .clock_divider ;
66
- uint32_t div_num = (new_apb * old_div ) / old_apb ;
67
- if (div_num > LEDC_DIV_NUM_HSTIMER0_V ){
68
- new_apb = REF_CLK_FREQ / 1000000 ;
69
- div_num = (new_apb * old_div ) / old_apb ;
70
- if (div_num > LEDC_DIV_NUM_HSTIMER0_V ) {
71
- div_num = LEDC_DIV_NUM_HSTIMER0_V ;//lowest clock possible
62
+ while (iarg ){ // run though all active channels, adjusting timing configurations
63
+ if (iarg & 1 ) {// this channel is active
64
+ uint8_t group = (chan /8 ), timer = ((chan /2 )%4 );
65
+ if (LEDC_TIMER (group , timer ).conf .tick_sel ){
66
+ LEDC_MUTEX_LOCK ();
67
+ uint32_t old_div = LEDC_TIMER (group , timer ).conf .clock_divider ;
68
+ uint32_t div_num = (new_apb * old_div ) / old_apb ;
69
+ if (div_num > LEDC_DIV_NUM_HSTIMER0_V ){
70
+ div_num = ((REF_CLK_FREQ /1000000 ) * old_div ) / old_apb ;
71
+ if (div_num > LEDC_DIV_NUM_HSTIMER0_V ) {
72
+ div_num = LEDC_DIV_NUM_HSTIMER0_V ;//lowest clock possible
73
+ }
74
+ LEDC_TIMER (group , timer ).conf .tick_sel = 0 ;
75
+ } else if (div_num < 256 ) {
76
+ div_num = 256 ;//highest clock possible
77
+ }
78
+ LEDC_TIMER (group , timer ).conf .clock_divider = div_num ;
79
+ LEDC_MUTEX_UNLOCK ();
72
80
}
73
- LEDC_TIMER (group , timer ).conf .tick_sel = 0 ;
74
- } else if (div_num < 256 ) {
75
- div_num = 256 ;//highest clock possible
76
81
}
77
- LEDC_TIMER ( group , timer ). conf . clock_divider = div_num ;
78
- LEDC_MUTEX_UNLOCK () ;
82
+ iarg = iarg >> 1 ;
83
+ chan ++ ;
79
84
}
80
85
}
81
86
}
@@ -85,13 +90,16 @@ static void _ledcSetupTimer(uint8_t chan, uint32_t div_num, uint8_t bit_num, boo
85
90
{
86
91
uint8_t group = (chan /8 ), timer = ((chan /2 )%4 );
87
92
static bool tHasStarted = false;
93
+ static uint16_t _activeChannels = 0 ;
88
94
if (!tHasStarted ) {
89
95
tHasStarted = true;
90
96
DPORT_SET_PERI_REG_MASK (DPORT_PERIP_CLK_EN_REG , DPORT_LEDC_CLK_EN );
91
97
DPORT_CLEAR_PERI_REG_MASK (DPORT_PERIP_RST_EN_REG , DPORT_LEDC_RST );
92
98
LEDC .conf .apb_clk_sel = 1 ;//LS use apb clock
99
+ addApbChangeCallback ((void * )& _activeChannels , _on_apb_change );
100
+
93
101
#if !CONFIG_DISABLE_HAL_LOCKS
94
- if ( _ledc_sys_lock == NULL ) _ledc_sys_lock = xSemaphoreCreateMutex ();
102
+ _ledc_sys_lock = xSemaphoreCreateMutex ();
95
103
#endif
96
104
}
97
105
LEDC_MUTEX_LOCK ();
@@ -105,8 +113,7 @@ static void _ledcSetupTimer(uint8_t chan, uint32_t div_num, uint8_t bit_num, boo
105
113
LEDC_TIMER (group , timer ).conf .rst = 1 ;//This bit is used to reset timer the counter will be 0 after reset.
106
114
LEDC_TIMER (group , timer ).conf .rst = 0 ;
107
115
LEDC_MUTEX_UNLOCK ();
108
- uint32_t iarg = chan ;
109
- addApbChangeCallback ((void * )iarg , _on_apb_change );
116
+ _activeChannels |= (1 << chan ); // mark as active for APB callback
110
117
}
111
118
112
119
//max div_num 0x3FFFF (262143)
0 commit comments