Menu Toggle
v2.3.1 (RP2350)
Toggle main menu visibility
Loading...
Searching...
No Matches
riscv_platform_timer.h
Go to the documentation of this file.
1
#ifndef _HARDWARE_RISCV_PLATFORM_TIMER_
2
#define _HARDWARE_RISCV_PLATFORM_TIMER_
3
4
#ifdef __cplusplus
5
extern
"C"
{
6
#endif
7
8
#include "
pico.h
"
9
#include "hardware/structs/sio.h"
10
22
33
static
inline
void
riscv_timer_set_enabled
(
bool
enabled) {
34
if
(enabled) {
35
// Note atomic rwtype is not supported on SIO
36
sio_hw->mtime_ctrl |= SIO_MTIME_CTRL_EN_BITS;
37
}
else
{
38
sio_hw->mtime_ctrl &= ~SIO_MTIME_CTRL_EN_BITS;
39
}
40
}
41
49
static
inline
void
riscv_timer_set_fullspeed
(
bool
fullspeed) {
50
if
(fullspeed) {
51
sio_hw->mtime_ctrl |= SIO_MTIME_CTRL_FULLSPEED_BITS;
52
}
else
{
53
sio_hw->mtime_ctrl &= ~SIO_MTIME_CTRL_FULLSPEED_BITS;
54
}
55
}
56
62
static
inline
uint64_t
riscv_timer_get_mtime
(
void
) {
63
// Read procedure from RISC-V ISA manual to avoid being off by 2**32 on
64
// low half rollover -- note this loop generally executes only once, and
65
// should never execute more than twice:
66
uint32_t h0, l, h1;
67
do
{
68
h0 = sio_hw->mtimeh;
69
l = sio_hw->mtime;
70
h1 = sio_hw->mtimeh;
71
}
while
(h0 != h1);
72
return
l | (uint64_t)h1 << 32;
73
}
74
85
static
inline
void
riscv_timer_set_mtime
(uint64_t mtime) {
86
// This ought really only be done when the timer is stopped, but we can
87
// make things a bit safer by clearing the low half of the counter, then
88
// writing high half, then low half. This protects against the low half
89
// rolling over, and largely avoids getting an intermediate value that is
90
// higher than either the original or new value, if the timer is running.
91
//
92
// Note that on RP2350, mtime is shared between the two cores!(mtimcemp is
93
// core-local however.)
94
sio_hw->mtime = 0;
95
sio_hw->mtimeh = mtime >> 32;
96
sio_hw->mtime = mtime & 0xffffffffu;
97
}
98
108
static
inline
uint64_t
riscv_timer_get_mtimecmp
(
void
) {
109
// Use the same procedure as reading mtime, which should be safe assuming
110
// mtimecmp increases monotonically with successive interrupts.
111
uint32_t h0, l, h1;
112
do
{
113
h0 = sio_hw->mtimecmph;
114
l = sio_hw->mtimecmp;
115
h1 = sio_hw->mtimecmph;
116
}
while
(h0 != h1);
117
return
l | (uint64_t)h1 << 32;
118
}
119
130
static
inline
void
riscv_timer_set_mtimecmp
(uint64_t mtimecmp) {
131
// Use write procedure from RISC-V ISA manual to avoid causing a spurious
132
// interrupt when updating the two halves of mtimecmp.
133
// No lower than original:
134
sio_hw->mtimecmp = -1u;
135
// No lower than original, no lower than new (assuming new >= original):
136
sio_hw->mtimecmph = mtimecmp >> 32;
137
// Equal to new:
138
sio_hw->mtimecmp = mtimecmp & 0xffffffffu;
139
}
140
141
#ifdef __cplusplus
142
}
143
#endif
144
145
#endif
riscv_timer_get_mtimecmp
static uint64_t riscv_timer_get_mtimecmp(void)
Get the current RISC-V platform timer mtimecmp value for this core.
Definition
riscv_platform_timer.h:108
riscv_timer_set_enabled
static void riscv_timer_set_enabled(bool enabled)
Enable or disable the RISC-V platform timer.
Definition
riscv_platform_timer.h:33
riscv_timer_set_mtimecmp
static void riscv_timer_set_mtimecmp(uint64_t mtimecmp)
Set a new RISC-V platform timer interrupt comparison value (mtimecmp) for this core.
Definition
riscv_platform_timer.h:130
riscv_timer_set_mtime
static void riscv_timer_set_mtime(uint64_t mtime)
Update the RISC-V platform timer.
Definition
riscv_platform_timer.h:85
riscv_timer_get_mtime
static uint64_t riscv_timer_get_mtime(void)
Read the RISC-V platform timer.
Definition
riscv_platform_timer.h:62
riscv_timer_set_fullspeed
static void riscv_timer_set_fullspeed(bool fullspeed)
Configure the RISC-V platform timer to run at full system clock speed.
Definition
riscv_platform_timer.h:49
pico.h