working with the EFM32 port trying to use some PWM pins, I found that of
the four TIMER peripherals (each of which is tied to particular sets of
PWM pins it can drive), two adjacent ones are in use
for a combined RIOT timer peripheral that them forms also the
XTIMER_DEV. This means that two timers (1 and 2 of 0, 1, 2 and 3) are
practically unusable for any PWM.
Before I go head-first into hacking something together with a timer
implementation based on the RTC or the systick peripheral, was there a
particular rationale behind making this the default timer on EFM32?
AFAICS, the design does make sense when it comes to creating arbitrary
timers (where the lower timer gets its fine-grained top value output a
precise frequency), but that isn't really required when it comes to
providing a timer for XTIMER which has its own XTIMER_HZ value which
"just" needs to set to an adaequate value. How is the trade-off between
having PWM devices vs. having a fine-grained-fixed-frequency capable
timer usually handled?
: That's a limitation of the chips, where TIMEROUF only works
between adjacent timers.
The two timers are needed, because they run in cascade mode. Only that way, I can generate values for XTIMER_HZ that have sufficient resolution. I don’t recall the details, but I haven’t found another way. The recommended MCU oscillators are typically 38.4 or 40 MHz, and the prescaler is always a power of two, so I cannot get 1us precision with only one timer.
The newer chips have an additional 32-bit timer with the same problem, but this frees up timers for PWM. I have a PR that I still need to fix though
The newer chips have an additional 32-bit timer with the same problem, but
this frees up timers for PWM.
That unfortunately won't help with the hardware I have here right now :-/
The two timers are needed, because they run in cascade mode. Only that way,
I can generate values for XTIMER_HZ that have sufficient resolution.
As I understand, the timer that serves XTIMER needs to be precise 1MHz,
and may be up to 6 shifts away from it -- but there is also the option
of running it from a 32768Hz clock available as internal and often
external clock. That seems to be sufficient xtimer resolution for some
applications (it certainly is for mine).
Options are a bit limited as to how to implement such a clock without
moving the whole device on the low frequency clock (HFPERCLK TIMERn can
only be clocked from LFxO if all HF stuff actually uses that in
HFCLKSEL), but the LETIMER0 (or RTC, but LETIMER is unused) would be an
option here (provided LFACLK comes from an LFxO).
If LETIMER support were to be added, it could probably look similar to
the changes in  -- but would need to branch out in timer_init, and
(when it's a LETIMER) err out if the desired frequency is not 32768.
If you want some inspiration for a timer driver you could take a look
at the Kinetis periph/timer driver which wraps two different timer
hardware modules underneath, one for high frequency and precise
control (PIT, always clocked by the CPU bus clock), and the other for
low power consumption and lower frequency (LPTMR, usually clocked by
the RTC oscillator, but there are other options as well).
Additionally, PR#7897 adds pm_layered management inside the timer
driver for the PIT to prevent low power modes from disrupting a timer
when there is a target set.