Skip to content

Commit 7cda07e

Browse files
committed
Implement clock change for the other peripherals
1 parent 28dd812 commit 7cda07e

File tree

4 files changed

+98
-19
lines changed

4 files changed

+98
-19
lines changed

cores/esp32/esp32-hal-ledc.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,33 @@ xSemaphoreHandle _ledc_sys_lock;
5353
#define LEDC_CHAN(g,c) LEDC.channel_group[(g)].channel[(c)]
5454
#define LEDC_TIMER(g,t) LEDC.timer_group[(g)].timer[(t)]
5555

56+
static void _on_apb_change(void * arg, apb_change_ev_t ev_type, uint32_t old_apb, uint32_t new_apb){
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);
61+
old_apb /= 1000000;
62+
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
72+
}
73+
LEDC_TIMER(group, timer).conf.tick_sel = 0;
74+
} else if(div_num < 256) {
75+
div_num = 256;//highest clock possible
76+
}
77+
LEDC_TIMER(group, timer).conf.clock_divider = div_num;
78+
LEDC_MUTEX_UNLOCK();
79+
}
80+
}
81+
}
82+
5683
//uint32_t frequency = (80MHz or 1MHz)/((div_num / 256.0)*(1 << bit_num));
5784
static void _ledcSetupTimer(uint8_t chan, uint32_t div_num, uint8_t bit_num, bool apb_clk)
5885
{
@@ -78,6 +105,8 @@ static void _ledcSetupTimer(uint8_t chan, uint32_t div_num, uint8_t bit_num, boo
78105
LEDC_TIMER(group, timer).conf.rst = 1;//This bit is used to reset timer the counter will be 0 after reset.
79106
LEDC_TIMER(group, timer).conf.rst = 0;
80107
LEDC_MUTEX_UNLOCK();
108+
uint32_t iarg = chan;
109+
addApbChangeCallback((void*)iarg, _on_apb_change);
81110
}
82111

83112
//max div_num 0x3FFFF (262143)

cores/esp32/esp32-hal-sigmadelta.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,26 @@
3131
xSemaphoreHandle _sd_sys_lock;
3232
#endif
3333

34+
static void _on_apb_change(void * arg, apb_change_ev_t ev_type, uint32_t old_apb, uint32_t new_apb){
35+
if(old_apb == new_apb){
36+
return;
37+
}
38+
uint32_t iarg = (uint32_t)arg;
39+
uint8_t channel = iarg;
40+
if(ev_type == APB_BEFORE_CHANGE){
41+
SIGMADELTA.cg.clk_en = 0;
42+
} else {
43+
old_apb /= 1000000;
44+
new_apb /= 1000000;
45+
SD_MUTEX_LOCK();
46+
uint32_t old_prescale = SIGMADELTA.channel[channel].prescale + 1;
47+
SIGMADELTA.channel[channel].prescale = ((new_apb * old_prescale) / old_apb) - 1;
48+
SIGMADELTA.cg.clk_en = 0;
49+
SIGMADELTA.cg.clk_en = 1;
50+
SD_MUTEX_UNLOCK();
51+
}
52+
}
53+
3454
uint32_t sigmaDeltaSetup(uint8_t channel, uint32_t freq) //chan 0-7 freq 1220-312500
3555
{
3656
if(channel > 7) {
@@ -53,6 +73,8 @@ uint32_t sigmaDeltaSetup(uint8_t channel, uint32_t freq) //chan 0-7 freq 1220-31
5373
SIGMADELTA.cg.clk_en = 0;
5474
SIGMADELTA.cg.clk_en = 1;
5575
SD_MUTEX_UNLOCK();
76+
uint32_t iarg = channel;
77+
addApbChangeCallback((void*)iarg, _on_apb_change);
5678
return apb_freq/((prescale + 1) * 256);
5779
}
5880

cores/esp32/esp32-hal-spi.c

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,18 @@ void spiSetBitOrder(spi_t * spi, uint8_t bitOrder)
372372
SPI_MUTEX_UNLOCK();
373373
}
374374

375+
static void _on_apb_change(void * arg, apb_change_ev_t ev_type, uint32_t old_apb, uint32_t new_apb)
376+
{
377+
spi_t * spi = (spi_t *)arg;
378+
if(ev_type == APB_BEFORE_CHANGE){
379+
SPI_MUTEX_LOCK();
380+
while(spi->dev->cmd.usr);
381+
} else {
382+
spi->dev->clock.val = spiFrequencyToClockDiv(old_apb / ((spi->dev->clock.clkdiv_pre + 1) * (spi->dev->clock.clkcnt_n + 1)));
383+
SPI_MUTEX_UNLOCK();
384+
}
385+
}
386+
375387
void spiStopBus(spi_t * spi)
376388
{
377389
if(!spi) {
@@ -388,6 +400,7 @@ void spiStopBus(spi_t * spi)
388400
spi->dev->ctrl2.val = 0;
389401
spi->dev->clock.val = 0;
390402
SPI_MUTEX_UNLOCK();
403+
removeApbChangeCallback(spi, _on_apb_change);
391404
}
392405

393406
spi_t * spiStartBus(uint8_t spi_num, uint32_t clockDiv, uint8_t dataMode, uint8_t bitOrder)
@@ -434,6 +447,7 @@ spi_t * spiStartBus(uint8_t spi_num, uint32_t clockDiv, uint8_t dataMode, uint8_
434447
}
435448
SPI_MUTEX_UNLOCK();
436449

450+
addApbChangeCallback(spi, _on_apb_change);
437451
return spi;
438452
}
439453

@@ -1008,17 +1022,17 @@ void IRAM_ATTR spiWritePixelsNL(spi_t * spi, const void * data_in, size_t len){
10081022
* */
10091023

10101024
typedef union {
1011-
uint32_t regValue;
1025+
uint32_t value;
10121026
struct {
1013-
unsigned regL :6;
1014-
unsigned regH :6;
1015-
unsigned regN :6;
1016-
unsigned regPre :13;
1017-
unsigned regEQU :1;
1027+
uint32_t clkcnt_l: 6; /*it must be equal to spi_clkcnt_N.*/
1028+
uint32_t clkcnt_h: 6; /*it must be floor((spi_clkcnt_N+1)/2-1).*/
1029+
uint32_t clkcnt_n: 6; /*it is the divider of spi_clk. So spi_clk frequency is system/(spi_clkdiv_pre+1)/(spi_clkcnt_N+1)*/
1030+
uint32_t clkdiv_pre: 13; /*it is pre-divider of spi_clk.*/
1031+
uint32_t clk_equ_sysclk: 1; /*1: spi_clk is eqaul to system 0: spi_clk is divided from system clock.*/
10181032
};
10191033
} spiClk_t;
10201034

1021-
#define ClkRegToFreq(reg) (apb_freq / (((reg)->regPre + 1) * ((reg)->regN + 1)))
1035+
#define ClkRegToFreq(reg) (apb_freq / (((reg)->clkdiv_pre + 1) * ((reg)->clkcnt_n + 1)))
10221036

10231037
uint32_t spiClockDivToFrequency(uint32_t clockDiv)
10241038
{
@@ -1038,7 +1052,7 @@ uint32_t spiFrequencyToClockDiv(uint32_t freq)
10381052
const spiClk_t minFreqReg = { 0x7FFFF000 };
10391053
uint32_t minFreq = ClkRegToFreq((spiClk_t*) &minFreqReg);
10401054
if(freq < minFreq) {
1041-
return minFreqReg.regValue;
1055+
return minFreqReg.value;
10421056
}
10431057

10441058
uint8_t calN = 1;
@@ -1051,18 +1065,18 @@ uint32_t spiFrequencyToClockDiv(uint32_t freq)
10511065
int32_t calPre;
10521066
int8_t calPreVari = -2;
10531067

1054-
reg.regN = calN;
1068+
reg.clkcnt_n = calN;
10551069

10561070
while(calPreVari++ <= 1) {
1057-
calPre = (((apb_freq / (reg.regN + 1)) / freq) - 1) + calPreVari;
1071+
calPre = (((apb_freq / (reg.clkcnt_n + 1)) / freq) - 1) + calPreVari;
10581072
if(calPre > 0x1FFF) {
1059-
reg.regPre = 0x1FFF;
1073+
reg.clkdiv_pre = 0x1FFF;
10601074
} else if(calPre <= 0) {
1061-
reg.regPre = 0;
1075+
reg.clkdiv_pre = 0;
10621076
} else {
1063-
reg.regPre = calPre;
1077+
reg.clkdiv_pre = calPre;
10641078
}
1065-
reg.regL = ((reg.regN + 1) / 2);
1079+
reg.clkcnt_l = ((reg.clkcnt_n + 1) / 2);
10661080
calFreq = ClkRegToFreq(&reg);
10671081
if(calFreq == (int32_t) freq) {
10681082
memcpy(&bestReg, &reg, sizeof(bestReg));
@@ -1079,6 +1093,6 @@ uint32_t spiFrequencyToClockDiv(uint32_t freq)
10791093
}
10801094
calN++;
10811095
}
1082-
return bestReg.regValue;
1096+
return bestReg.value;
10831097
}
10841098

cores/esp32/esp32-hal-timer.c

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,18 @@ bool timerAlarmEnabled(hw_timer_t *timer){
184184
return timer->dev->config.alarm_en;
185185
}
186186

187+
static void _on_apb_change(void * arg, apb_change_ev_t ev_type, uint32_t old_apb, uint32_t new_apb){
188+
hw_timer_t * timer = (hw_timer_t *)arg;
189+
if(ev_type == APB_BEFORE_CHANGE){
190+
timer->dev->config.enable = 0;
191+
} else {
192+
old_apb /= 1000000;
193+
new_apb /= 1000000;
194+
timer->dev->config.divider = (new_apb * timer->dev->config.divider) / old_apb;
195+
timer->dev->config.enable = 1;
196+
}
197+
}
198+
187199
hw_timer_t * timerBegin(uint8_t num, uint16_t divider, bool countUp){
188200
if(num > 3){
189201
return NULL;
@@ -205,12 +217,14 @@ hw_timer_t * timerBegin(uint8_t num, uint16_t divider, bool countUp){
205217
timerAttachInterrupt(timer, NULL, false);
206218
timerWrite(timer, 0);
207219
timer->dev->config.enable = 1;
220+
addApbChangeCallback(timer, _on_apb_change);
208221
return timer;
209222
}
210223

211224
void timerEnd(hw_timer_t *timer){
212225
timer->dev->config.enable = 0;
213226
timerAttachInterrupt(timer, NULL, false);
227+
removeApbChangeCallback(timer, _on_apb_change);
214228
}
215229

216230
void timerAttachInterrupt(hw_timer_t *timer, void (*fn)(void), bool edge){
@@ -271,23 +285,23 @@ void timerDetachInterrupt(hw_timer_t *timer){
271285
uint64_t timerReadMicros(hw_timer_t *timer){
272286
uint64_t timer_val = timerRead(timer);
273287
uint16_t div = timerGetDivider(timer);
274-
return timer_val * div / 80;
288+
return timer_val * div / (getApbFrequency() / 1000000);
275289
}
276290

277291
double timerReadSeconds(hw_timer_t *timer){
278292
uint64_t timer_val = timerRead(timer);
279293
uint16_t div = timerGetDivider(timer);
280-
return (double)timer_val * div / 80000000;
294+
return (double)timer_val * div / getApbFrequency();
281295
}
282296

283297
uint64_t timerAlarmReadMicros(hw_timer_t *timer){
284298
uint64_t timer_val = timerAlarmRead(timer);
285299
uint16_t div = timerGetDivider(timer);
286-
return timer_val * div / 80;
300+
return timer_val * div / (getApbFrequency() / 1000000);
287301
}
288302

289303
double timerAlarmReadSeconds(hw_timer_t *timer){
290304
uint64_t timer_val = timerAlarmRead(timer);
291305
uint16_t div = timerGetDivider(timer);
292-
return (double)timer_val * div / 80000000;
306+
return (double)timer_val * div / getApbFrequency();
293307
}

0 commit comments

Comments
 (0)