rusEFI
The most advanced open source ECU
Loading...
Searching...
No Matches
Functions | Variables
microsecond_timer_stm32.cpp File Reference

Detailed Description

A single upcounting timer (currently TIM5) is used as a single timebase both for time measurement and event scheduling. This helps reduce jitter by not making another time measurement at the time of scheduling.

This implementation only works on stm32 because it sets hardware registers directly. ChibiOS doesn't support using timers in output compare mode, only PMW, so we have to manually configure the timer in outupt compare mode.

Date
Dec 1, 2020
Author
Matthew Kennedy, (c) 2012-2020

Definition in file microsecond_timer_stm32.cpp.

Functions

void portSetHardwareSchedulerTimer (efitick_t nowNt, efitick_t setTimeNt)
 
static void hwTimerCallback (PWMDriver *)
 
void portInitMicrosecondTimer ()
 
uint32_t getTimeNowLowerNt ()
 

Variables

static constexpr PWMConfig timerConfig
 

Function Documentation

◆ getTimeNowLowerNt()

uint32_t getTimeNowLowerNt ( )

Get a monotonically increasing (but wrapping) 32-bit timer value Implemented at port level, based on timer or CPU tick counter Main source of EFI clock, SW-extended to 64bits

2147483648 / ~168MHz = ~12 seconds to overflow

Definition at line 73 of file microsecond_timer_stm32.cpp.

73 {
74 // Using the same timer for measurement and scheduling improves
75 // precision and reduces jitter.
76 return SCHEDULER_TIMER_DEVICE->CNT;
77}

◆ hwTimerCallback()

static void hwTimerCallback ( PWMDriver )
static

Definition at line 30 of file microsecond_timer_stm32.cpp.

30 {
31 pwmDisableChannelNotificationI(&SCHEDULER_PWM_DEVICE, 0);
33}
void portMicrosecondTimerCallback()
Here is the call graph for this function:

◆ portInitMicrosecondTimer()

void portInitMicrosecondTimer ( )

This file defines the API for the microsecond timer that a port needs to implement

Do not call these functions directly, they should only be called by microsecond_timer.cpp

Definition at line 54 of file microsecond_timer_stm32.cpp.

54 {
55 pwmStart(&SCHEDULER_PWM_DEVICE, &timerConfig);
56
57 // ChibiOS doesn't let you configure timers in output compare mode, only PWM mode.
58 // We want to be able to set the compare register without waiting for an update event
59 // (which would take 358 seconds at 12mhz timer speed), so we have to use normal upcounting
60 // output compare mode instead.
61 SCHEDULER_TIMER_DEVICE->CCMR1 = STM32_TIM_CCMR1_OC1M(1);
62
63 /* TODO: implement for all possible TIMs */
64 if (SCHEDULER_TIMER_DEVICE == TIM5) {
65 /* stop timers clock when core is halted */
66 #if defined(STM32F4XX) || defined (STM32F7XX)
67 DBGMCU->APB1FZ |= DBGMCU_APB1_FZ_DBG_TIM5_STOP;
68 #endif
69 /* TODO: stm32h7? */
70 }
71}
static constexpr PWMConfig timerConfig

◆ portSetHardwareSchedulerTimer()

void portSetHardwareSchedulerTimer ( efitick_t  nowNt,
efitick_t  setTimeNt 
)

Definition at line 22 of file microsecond_timer_stm32.cpp.

22 {
23 // This implementation doesn't need the current time, only the target time
24 UNUSED(nowNt);
25
26 pwm_lld_enable_channel(&SCHEDULER_PWM_DEVICE, 0, setTimeNt);
27 pwmEnableChannelNotificationI(&SCHEDULER_PWM_DEVICE, 0);
28}
void pwm_lld_enable_channel(PWMDriver *pwmp, pwmchannel_t channel, pwmcnt_t width)
Enables a PWM channel.
UNUSED(samplingTimeSeconds)
Here is the call graph for this function:

Variable Documentation

◆ timerConfig

constexpr PWMConfig timerConfig
staticconstexpr
Initial value:
= {
.frequency = SCHEDULER_TIMER_FREQ,
.period = 0,
.callback = nullptr,
.channels = {
{PWM_OUTPUT_DISABLED, hwTimerCallback},
{PWM_OUTPUT_DISABLED, nullptr},
{PWM_OUTPUT_DISABLED, nullptr},
{PWM_OUTPUT_DISABLED, nullptr}
},
.cr2 = 0,
.bdtr = 0,
.dier = 0
}
static void hwTimerCallback(PWMDriver *)

Definition at line 35 of file microsecond_timer_stm32.cpp.

35 {
36 .frequency = SCHEDULER_TIMER_FREQ,
37 /* wanted timer period = 2^32 counts,
38 * but driver set (period - 1) value to register
39 * also period is uint32_t
40 * So set it to zero so it will overlap to 0xffffffff when writen to register */
41 .period = 0,
42 .callback = nullptr, // No update callback
43 .channels = {
44 {PWM_OUTPUT_DISABLED, hwTimerCallback}, // Channel 0 = timer callback, others unused
45 {PWM_OUTPUT_DISABLED, nullptr},
46 {PWM_OUTPUT_DISABLED, nullptr},
47 {PWM_OUTPUT_DISABLED, nullptr}
48 },
49 .cr2 = 0,
50 .bdtr = 0,
51 .dier = 0
52};

Referenced by portInitMicrosecondTimer().

Go to the source code of this file.