mirror of
https://github.com/google/pebble.git
synced 2026-02-16 10:16:50 -05:00
Import of the watch repository from Pebble
This commit is contained in:
74
src/fw/kernel/util/interval_timer.h
Normal file
74
src/fw/kernel/util/interval_timer.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2024 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
//! @file interval_timer.h
|
||||
//!
|
||||
//! Times the average number of milliseconds between samples. Taking a sample is ISR-safe. Uses
|
||||
//! the RTC time domain which should be fairly accurate for real clock time. Note that because
|
||||
//! we use the RTC we may occasionally have to discard intervals because the wall clock time was
|
||||
//! changed. This is not ideal, but it's still a better source of time than our SysTick time source
|
||||
//! as that is not necessarily synced to real time.
|
||||
//!
|
||||
//! The resolution of the recorded timer will be same as the configured resolution of our RTC
|
||||
//! peripheral, which at the time of writing is 1/256 of a second.
|
||||
//!
|
||||
//! The average is calculated as an exponential moving average.
|
||||
//! https://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average
|
||||
//! The weighting factor (how responsive to recent changes) is configurable.
|
||||
|
||||
typedef struct {
|
||||
uint64_t last_sample_timestamp_ms;
|
||||
|
||||
// The minimum and maximum values for an interval for it to be included into the average.
|
||||
uint32_t min_expected_ms;
|
||||
uint32_t max_expected_ms;
|
||||
|
||||
uint32_t weighting_factor_inverted;
|
||||
|
||||
//! The moving average we've calculated based on the samples we have so far.
|
||||
uint32_t average_ms;
|
||||
//! The number of samples we've taken.
|
||||
uint32_t num_samples;
|
||||
} IntervalTimer;
|
||||
|
||||
//! Initialize an interval timer.
|
||||
//!
|
||||
//! Allows the specification of an acceptable range of intervals. This is used to discard invalid
|
||||
//! intervals.
|
||||
//!
|
||||
//! Intervals are averaged together in a moving average that includes the last n intervals. The
|
||||
//! number of intervals to average over is configurable.
|
||||
//!
|
||||
//! @param min_expected_ms The minimum number of milliseconds between samples
|
||||
//! @param min_expected_ms The maximum number of milliseconds between samples
|
||||
//! @param weighting_factor_inverted
|
||||
//! 1 / alpha. Specified as a inverted number to avoid dealing with floats. The higher the
|
||||
//! number the less responsive to recent changes our average is.
|
||||
void interval_timer_init(IntervalTimer *timer, uint32_t min_expected_ms, uint32_t max_expected_ms,
|
||||
uint32_t weighting_factory_inverted);
|
||||
|
||||
//! Record a sample that marks the start/end of an interval.
|
||||
//! Safe to call from an ISR.
|
||||
void interval_timer_take_sample(IntervalTimer *timer);
|
||||
|
||||
//! @param[out] average_ms_out The average ms for the interval.
|
||||
//! @return The number of valid intervals that are in our moving average. Note that this value
|
||||
//! will never be larger than num_intervals_in_average.
|
||||
uint32_t interval_timer_get(IntervalTimer *timer, uint32_t *average_ms_out);
|
||||
Reference in New Issue
Block a user