Skip to content

Commit d4f3bce

Browse files
author
Jiang Jiang Jian
committed
Merge branch 'fix/update_dfs_compensate_table' into 'master'
fix(esp_hw_support): update esp32 dfs table to make the timing drift always negative Closes PM-437, WIFIBUG-1248, and PM-405 See merge request espressif/esp-idf!39838
2 parents 72cc5de + 2d2aac0 commit d4f3bce

File tree

5 files changed

+40
-26
lines changed

5 files changed

+40
-26
lines changed

components/bt/controller/esp32/bt.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -965,7 +965,7 @@ static void btdm_sleep_enter_phase1_wrapper(uint32_t lpcycles)
965965
assert(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
966966
// allow a maximum time uncertainty to be about 488ppm(1/2048) at least as clock drift
967967
// and set the timer in advance
968-
uint32_t uncertainty = (us_to_sleep >> 11);
968+
uint32_t uncertainty = (us_to_sleep / 1000);
969969
if (uncertainty < BTDM_MIN_TIMER_UNCERTAINTY_US) {
970970
uncertainty = BTDM_MIN_TIMER_UNCERTAINTY_US;
971971
}

components/esp_hw_support/port/esp32/rtc_clk.c

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -403,16 +403,16 @@ static void rtc_clk_cpu_freq_to_8m(void)
403403
}
404404

405405
#ifndef BOOTLOADER_BUILD
406-
static const DRAM_ATTR int16_t dfs_lact_conpensate_table[3][3] = { \
406+
static const DRAM_ATTR int16_t dfs_lact_compensate_table[3][3] = { \
407407
/* From / To 80 160 240*/ \
408-
/* 10 */ {138, 220, 18}, \
409-
/* 20 */ {128, 205, -3579}, \
410-
/* 40 */ {34, 100, 0}, \
408+
/* 10 */ {78, 172, -1}, \
409+
/* 20 */ {2, 105, -90}, \
410+
/* 40 */ {-190, -18, -372}, \
411411
};
412412

413413
__attribute__((weak)) IRAM_ATTR int16_t rtc_clk_get_lact_compensation_delay(uint32_t cur_freq, uint32_t tar_freq)
414414
{
415-
return dfs_lact_conpensate_table[(cur_freq == 10) ? 0 : (cur_freq == 20) ? 1 : 2][(tar_freq == 80) ? 0 : (tar_freq == 160) ? 1 : 2];
415+
return dfs_lact_compensate_table[(cur_freq == 10) ? 0 : (cur_freq == 20) ? 1 : 2][(tar_freq == 80) ? 0 : (tar_freq == 160) ? 1 : 2];
416416
}
417417
#endif
418418

@@ -437,6 +437,12 @@ NOINLINE_ATTR static void rtc_clk_cpu_freq_to_pll_mhz(int cpu_freq_mhz)
437437
}
438438
#endif
439439
clk_ll_cpu_set_freq_mhz_from_pll(cpu_freq_mhz);
440+
/* adjust ref_tick */
441+
clk_ll_ref_tick_set_divider(SOC_CPU_CLK_SRC_PLL, cpu_freq_mhz);
442+
/* switch clock source */
443+
clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_PLL);
444+
rtc_clk_apb_freq_update(80 * MHZ);
445+
esp_rom_set_cpu_ticks_per_us(cpu_freq_mhz);
440446
#ifndef BOOTLOADER_BUILD
441447
if (cur_freq <= 40 && delay_cycle < 0) {
442448
for (int i = 0; i > delay_cycle; --i) {
@@ -445,12 +451,6 @@ NOINLINE_ATTR static void rtc_clk_cpu_freq_to_pll_mhz(int cpu_freq_mhz)
445451
timer_ll_set_lact_clock_prescale(TIMER_LL_GET_HW(LACT_MODULE), 80 / LACT_TICKS_PER_US);
446452
}
447453
#endif
448-
/* adjust ref_tick */
449-
clk_ll_ref_tick_set_divider(SOC_CPU_CLK_SRC_PLL, cpu_freq_mhz);
450-
/* switch clock source */
451-
clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_PLL);
452-
rtc_clk_apb_freq_update(80 * MHZ);
453-
esp_rom_set_cpu_ticks_per_us(cpu_freq_mhz);
454454
rtc_clk_wait_for_slow_cycle();
455455
esp_rom_delay_us(30);
456456
}

components/esp_pm/pm_impl.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -667,7 +667,10 @@ static void IRAM_ATTR do_switch(pm_mode_t new_mode)
667667
#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP
668668
esp_clk_utils_mspi_speed_mode_sync_before_cpu_freq_switching(new_config.source_freq_mhz, new_config.freq_mhz);
669669
#endif
670+
extern portMUX_TYPE s_time_update_lock;
671+
portENTER_CRITICAL_SAFE(&s_time_update_lock);
670672
rtc_clk_cpu_freq_set_config_fast(&new_config);
673+
portEXIT_CRITICAL_SAFE(&s_time_update_lock);
671674
#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP
672675
esp_clk_utils_mspi_speed_mode_sync_after_cpu_freq_switching(new_config.source_freq_mhz, new_config.freq_mhz);
673676
#endif

components/esp_timer/src/esp_timer_impl_lac.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,9 @@ esp_err_t esp_timer_impl_init(intr_handler_t alarm_handler)
276276
* will not cause issues in practice.
277277
*/
278278
REG_SET_BIT(INT_ENA_REG, TIMG_LACT_INT_ENA);
279+
portENTER_CRITICAL_SAFE(&s_time_update_lock);
279280
timer_ll_set_lact_clock_prescale(TIMER_LL_GET_HW(LACT_MODULE), esp_clk_apb_freq() / MHZ / LACT_TICKS_PER_US);
281+
portEXIT_CRITICAL_SAFE(&s_time_update_lock);
280282
// Set the step for the sleep mode when the timer will work
281283
// from a slow_clk frequency instead of the APB frequency.
282284
uint32_t slowclk_ticks_per_us = esp_clk_slowclk_cal_get() * LACT_TICKS_PER_US;

components/esp_timer/test_apps/main/test_esp_timer_dfs.c

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -63,15 +63,19 @@ static IRAM_ATTR void periodic_timer_callback(void* arg)
6363
static int64_t measuring_periodic_timer_accuracy(uint64_t alarm_records[])
6464
{
6565
int64_t sum_jitter_us = 0;
66-
int64_t max_jitter_us = 0;
66+
int64_t max_jitter_us = -(ALARM_PERIOD_MS * 1000);
67+
int64_t min_jitter_us = ALARM_PERIOD_MS * 1000;
6768
int64_t jitter_array[ALARM_TIMES] = {0};
6869

6970
for (int i = 1; i <= ALARM_TIMES; ++i) {
7071
int64_t jitter_us = (int64_t)alarm_records[i] - (int64_t)alarm_records[i - 1] - ALARM_PERIOD_MS * 1000;
7172
jitter_array[i - 1] = jitter_us;
72-
if (llabs(jitter_us) > llabs(max_jitter_us)) {
73+
if (jitter_us > max_jitter_us) {
7374
max_jitter_us = jitter_us;
7475
}
76+
if (jitter_us < min_jitter_us) {
77+
min_jitter_us = jitter_us;
78+
}
7579
sum_jitter_us += jitter_us;
7680
}
7781
int64_t avg_jitter_us = sum_jitter_us / ALARM_TIMES;
@@ -86,14 +90,19 @@ static int64_t measuring_periodic_timer_accuracy(uint64_t alarm_records[])
8690
double stddev = sqrt(variance);
8791

8892
printf("Average jitter us: %"PRIi64"\n", avg_jitter_us);
89-
printf("Max jitter us: %"PRIi64"\n", max_jitter_us);
93+
if (max_jitter_us > 0) {
94+
printf("\e[1;31mMax jitter us: %"PRIi64"\n\e[0m", max_jitter_us);
95+
} else {
96+
printf("Max jitter us: %"PRIi64"\n", max_jitter_us);
97+
}
98+
printf("Min jitter us: %"PRIi64"\n", min_jitter_us);
9099
printf("Standard Deviation: %.3f\n", stddev);
91100
printf("Drift Percentage: %.3f%%\n", (double)avg_jitter_us / (ALARM_PERIOD_MS * 10));
92101

93102
// Reset measurement
94103
s_current_alarm = 0;
95104
bzero(s_alarm_records, sizeof(s_alarm_records));
96-
return avg_jitter_us;
105+
return max_jitter_us;
97106
}
98107

99108
static int64_t test_periodic_timer_accuracy_on_dfs(esp_timer_handle_t timer)
@@ -109,9 +118,9 @@ static int64_t test_periodic_timer_accuracy_on_dfs(esp_timer_handle_t timer)
109118
// Each FreeRTOS tick will perform a min_freq_mhz->max_freq_mhz -> min_freq_mhz frequency switch
110119
xSemaphoreTake(s_alarm_finished, portMAX_DELAY);
111120
ESP_ERROR_CHECK(esp_timer_stop(timer));
112-
int64_t avg_jitter_us = measuring_periodic_timer_accuracy(s_alarm_records);
121+
int64_t max_jitter_us = measuring_periodic_timer_accuracy(s_alarm_records);
113122
vSemaphoreDelete(s_alarm_finished);
114-
return avg_jitter_us;
123+
return max_jitter_us;
115124
}
116125

117126
// The results of this test are meaningful only if `CONFIG_ESP_SYSTEM_RTC_EXT_XTAL` is enabled
@@ -183,7 +192,7 @@ TEST_CASE("Test DFS lact conpensate magic table ", "[esp_timer][manual][ignore]"
183192
esp_pm_configure(&pm_config);
184193

185194
int32_t max_delay = 300;
186-
int32_t min_delay = (pm_config.max_freq_mhz == 240) ? -4000 : 0;
195+
int32_t min_delay = (pm_config.max_freq_mhz == 240) ? -4000 : -300;
187196
int32_t test_delay = (max_delay + min_delay) / 2;
188197
int32_t last_delay = 0;
189198
int32_t best_delay = 0;
@@ -192,19 +201,19 @@ TEST_CASE("Test DFS lact conpensate magic table ", "[esp_timer][manual][ignore]"
192201
do {
193202
printf("Test delay %ld\n", test_delay);
194203
test_lact_compensation_delay = test_delay;
195-
int64_t avg = test_periodic_timer_accuracy_on_dfs(periodic_timer);
204+
int64_t max_jitter_us = test_periodic_timer_accuracy_on_dfs(periodic_timer);
196205
last_delay = test_delay;
197-
if (avg < 0) {
198-
test_delay = (test_delay + max_delay) / 2;
199-
min_delay = last_delay;
200-
} else {
206+
if (max_jitter_us > 0) {
201207
test_delay = (test_delay + min_delay) / 2;
202208
max_delay = last_delay;
209+
} else {
210+
test_delay = (test_delay + max_delay) / 2;
211+
min_delay = last_delay;
203212
}
204213

205-
if (llabs(avg) < llabs(min_avg)) {
214+
if (llabs(max_jitter_us) < llabs(min_avg)) {
206215
best_delay = last_delay;
207-
min_avg = avg;
216+
min_avg = max_jitter_us;
208217
}
209218
} while (test_delay != last_delay);
210219

0 commit comments

Comments
 (0)