esp_timer, hal: add support for non-integer systimer frequency

When ESP32-C2 is paired with a 26 MHz XTAL, the systimer tick
frequency becomes equal to 26 / 2.5 = 10.4 MHz. Previously we always
assumed that systimer tick frequency is integer (and 1 MHz * power of
two, above that!).
This commit introduces a new LL macro, SYSTIMER_LL_TICKS_PER_US_DIV.
It should be set in such a way that:

1. SYSTIMER_LL_TICKS_PER_US / SYSTIMER_LL_TICKS_PER_US_DIV equals the
   actual systimer tick frequency,
2. and SYSTIMER_LL_TICKS_PER_US is integer.

For ESP32-C2 this means that SYSTIMER_LL_TICKS_PER_US = 52 and
SYSTIMER_LL_TICKS_PER_US_DIV = 5.

This introduced two possible issues:

1. Overflow when multiplying systimer counter by 5
   - Should not be an issue, since systimer counter is 52-bit, so
     counter * 5 is no more than 55-bit.
2. The code needs to perform:
   - divide by 5: when converting from microseconds to ticks
   - divide by 52: when converting from ticks to microseconds
   The latter potentially introduces a performance issue for the
   esp_timer_get_time function.
This commit is contained in:
Ivan Grokhotkov
2022-07-01 19:58:23 +02:00
committed by songruojing
parent f0f9890096
commit 5b54ae76d4
17 changed files with 102 additions and 113 deletions

View File

@@ -679,9 +679,9 @@ config SOC_SYSTIMER_BIT_WIDTH_HI
int
default 20
config SOC_SYSTIMER_FIXED_TICKS_US
int
default 16
config SOC_SYSTIMER_HAS_FIXED_TICKS_PER_US
bool
default y
config SOC_SYSTIMER_INT_LEVEL
bool

View File

@@ -277,14 +277,14 @@
#define SOC_SPIRAM_SUPPORTED 1
/*-------------------------- SYS TIMER CAPS ----------------------------------*/
#define SOC_SYSTIMER_SUPPORTED 1
#define SOC_SYSTIMER_COUNTER_NUM (2) // Number of counter units
#define SOC_SYSTIMER_ALARM_NUM (3) // Number of alarm units
#define SOC_SYSTIMER_BIT_WIDTH_LO (32) // Bit width of systimer low part
#define SOC_SYSTIMER_BIT_WIDTH_HI (20) // Bit width of systimer high part
#define SOC_SYSTIMER_FIXED_TICKS_US (16) // Number of ticks per microsecond is fixed
#define SOC_SYSTIMER_INT_LEVEL (1) // Systimer peripheral uses level
#define SOC_SYSTIMER_ALARM_MISS_COMPENSATE (1) // Systimer peripheral can generate interrupt immediately if t(target) > t(current)
#define SOC_SYSTIMER_SUPPORTED 1
#define SOC_SYSTIMER_COUNTER_NUM (2) // Number of counter units
#define SOC_SYSTIMER_ALARM_NUM (3) // Number of alarm units
#define SOC_SYSTIMER_BIT_WIDTH_LO (32) // Bit width of systimer low part
#define SOC_SYSTIMER_BIT_WIDTH_HI (20) // Bit width of systimer high part
#define SOC_SYSTIMER_HAS_FIXED_TICKS_PER_US (1) // Number of ticks per microsecond is fixed (16 ticks/us)
#define SOC_SYSTIMER_INT_LEVEL (1) // Systimer peripheral uses level
#define SOC_SYSTIMER_ALARM_MISS_COMPENSATE (1) // Systimer peripheral can generate interrupt immediately if t(target) > t(current)
/*-------------------------- TIMER GROUP CAPS --------------------------------*/
#define SOC_TIMER_GROUPS (2)