libxr
Embedded C++ framework for bare-metal, RTOS and Linux
Loading...
Searching...
No Matches
ch32_timebase.cpp
1// NOLINTBEGIN(cppcoreguidelines-pro-type-cstyle-cast,performance-no-int-to-ptr)
2#include "ch32_timebase.hpp"
3
4using namespace LibXR;
5
6namespace
7{
8constexpr uint32_t SYSTICK_ENABLE = 1U << 0U;
9constexpr uint32_t SYSTICK_CLOCK_HCLK = 1U << 2U;
10constexpr uint32_t SYSTICK_AUTO_RELOAD = 1U << 3U;
11constexpr uint32_t SYSTICK_COUNT_DOWN = 1U << 4U;
12constexpr uint64_t MICROSECONDS_PER_SECOND = 1000000ULL;
13constexpr uint64_t MILLISECONDS_PER_SECOND = 1000ULL;
14
15uint32_t timebase_clock_hz = 0U;
16
17uint64_t ReadSysTickCounter()
18{
19 auto* count_words = reinterpret_cast<volatile uint32_t*>(&SysTick->CNT);
20 uint32_t high_before;
21 uint32_t low;
22 uint32_t high_after;
23
24 // 低位回绕时重新读取,避免拼接出不一致的计数值。
25 // Retry across a low-word rollover to obtain a coherent counter value.
26 do
27 {
28 high_before = count_words[1];
29 low = count_words[0];
30 high_after = count_words[1];
31 } while (high_before != high_after);
32
33 return (static_cast<uint64_t>(high_after) << 32U) | low;
34}
35
36uint64_t CyclesToUnits(uint64_t cycles, uint64_t units_per_second)
37{
38 // 分开换算整秒和余数,避免直接乘法溢出。
39 // Convert whole seconds and remaining cycles separately to avoid overflow.
40 const uint64_t seconds = cycles / timebase_clock_hz;
41 const uint64_t remaining_cycles = cycles % timebase_clock_hz;
42 return seconds * units_per_second +
43 remaining_cycles * units_per_second / timebase_clock_hz;
44}
45} // namespace
46
48{
49 const uint32_t control = SysTick->CTLR;
50 ASSERT((control & (SYSTICK_ENABLE | SYSTICK_CLOCK_HCLK)) ==
51 (SYSTICK_ENABLE | SYSTICK_CLOCK_HCLK) &&
52 (control & (SYSTICK_AUTO_RELOAD | SYSTICK_COUNT_DOWN)) == 0U &&
53 SystemCoreClock >= MICROSECONDS_PER_SECOND);
54
55 timebase_clock_hz = SystemCoreClock;
56 ConfigureWrapRange(CyclesToUnits(UINT64_MAX, MICROSECONDS_PER_SECOND), UINT32_MAX);
57 SetReady();
58}
59
61{
63 CyclesToUnits(ReadSysTickCounter(), MICROSECONDS_PER_SECOND));
64}
65
67{
68 return MillisecondTimestamp(static_cast<uint32_t>(
69 CyclesToUnits(ReadSysTickCounter(), MILLISECONDS_PER_SECOND)));
70}
71
72// NOLINTEND(cppcoreguidelines-pro-type-cstyle-cast,performance-no-int-to-ptr)
CH32Timebase()
构造函数 / Constructor
微秒时间戳 / Microsecond timestamp
毫秒时间戳 / Millisecond timestamp
static void ConfigureWrapRange(uint64_t max_valid_us, uint32_t max_valid_ms) noexcept
配置时间戳回绕上界。 Configure the timestamp wraparound limits.
Definition timebase.hpp:95
static void SetReady(bool ready=true) noexcept
设置时间基就绪状态。 Set the timebase ready flag.
Definition timebase.hpp:85
static MicrosecondTimestamp GetMicroseconds()
获取当前时间的微秒级时间戳。 Gets the current timestamp in microseconds.
static MillisecondTimestamp GetMilliseconds()
获取当前时间的毫秒级时间戳。 Gets the current timestamp in milliseconds.
LibXR 命名空间 / LibXR namespace.
Definition ch32_can.hpp:14