1use kernel::utilities::registers::interfaces::{ReadWriteable, Readable};
6use kernel::utilities::registers::{register_bitfields, register_structs, ReadOnly, ReadWrite};
7use kernel::utilities::StaticRef;
8
9register_structs! {
10
11    TicksRegisters {
12        (0x000 => proc0_ctrl: ReadWrite<u32, PROC0_CTRL::Register>),
14
15        (0x004 => proc0_cycles: ReadWrite<u32>),
16
17        (0x008 => proc0_count: ReadWrite<u32>),
18        (0x00C => proc1_ctrl: ReadWrite<u32, PROC1_CTRL::Register>),
20
21        (0x010 => proc1_cycles: ReadWrite<u32>),
22
23        (0x014 => proc1_count: ReadWrite<u32>),
24        (0x018 => timer0_ctrl: ReadWrite<u32, TIMER0_CTRL::Register>),
26
27        (0x01C => timer0_cycles: ReadWrite<u32, TIMER0_CYCLES::Register>),
28
29        (0x020 => timer0_count: ReadOnly<u32, TIMER0_COUNT::Register>),
30        (0x024 => timer1_ctrl: ReadWrite<u32, TIMER1_CTRL::Register>),
32
33        (0x028 => timer1_cycles: ReadWrite<u32, TIMER1_CYCLES::Register>),
34
35        (0x02C => timer1_count: ReadOnly<u32, TIMER1_COUNT::Register>),
36        (0x030 => watchdog_ctrl: ReadWrite<u32, WATCHDOG_CTRL::Register>),
38
39        (0x034 => watchdog_cycles: ReadWrite<u32>),
40
41        (0x038 => watchdog_count: ReadWrite<u32>),
42        (0x03C => riscv_ctrl: ReadWrite<u32, RISCV_CTRL::Register>),
44
45        (0x040 => riscv_cycles: ReadWrite<u32>),
46
47        (0x044 => riscv_count: ReadWrite<u32>),
48        (0x048 => @END),
49    }
50}
51register_bitfields![u32,
52PROC0_CTRL [
53    RUNNING OFFSET(1) NUMBITS(1) [],
55    ENABLE OFFSET(0) NUMBITS(1) []
57],
58PROC0_CYCLES [
59    PROC0_CYCLES OFFSET(0) NUMBITS(9) []
61],
62PROC0_COUNT [
63    PROC0_COUNT OFFSET(0) NUMBITS(9) []
65],
66PROC1_CTRL [
67    RUNNING OFFSET(1) NUMBITS(1) [],
69    ENABLE OFFSET(0) NUMBITS(1) []
71],
72PROC1_CYCLES [
73    PROC1_CYCLES OFFSET(0) NUMBITS(9) []
75],
76PROC1_COUNT [
77    PROC1_COUNT OFFSET(0) NUMBITS(9) []
79],
80TIMER0_CTRL [
81    RUNNING OFFSET(1) NUMBITS(1) [],
83    ENABLE OFFSET(0) NUMBITS(1) []
85],
86TIMER0_CYCLES [
87    TIMER0_CYCLES OFFSET(0) NUMBITS(9) []
89],
90TIMER0_COUNT [
91    TIMER0_COUNT OFFSET(0) NUMBITS(9) []
93],
94TIMER1_CTRL [
95    RUNNING OFFSET(1) NUMBITS(1) [],
97    ENABLE OFFSET(0) NUMBITS(1) []
99],
100TIMER1_CYCLES [
101    TIMER1_CYCLES OFFSET(0) NUMBITS(9) []
103],
104TIMER1_COUNT [
105    TIMER1_COUNT OFFSET(0) NUMBITS(9) []
107],
108WATCHDOG_CTRL [
109    RUNNING OFFSET(1) NUMBITS(1) [],
111    ENABLE OFFSET(0) NUMBITS(1) []
113],
114WATCHDOG_CYCLES [
115    WATCHDOG_CYCLES OFFSET(0) NUMBITS(9) []
117],
118WATCHDOG_COUNT [
119    WATCHDOG_COUNT OFFSET(0) NUMBITS(9) []
121],
122RISCV_CTRL [
123    RUNNING OFFSET(1) NUMBITS(1) [],
125    ENABLE OFFSET(0) NUMBITS(1) []
127],
128RISCV_CYCLES [
129    RISCV_CYCLES OFFSET(0) NUMBITS(9) []
131],
132RISCV_COUNT [
133    RISCV_COUNT OFFSET(0) NUMBITS(9) []
135]
136];
137const TICKS_BASE: StaticRef<TicksRegisters> =
138    unsafe { StaticRef::new(0x40108000 as *const TicksRegisters) };
139
140pub struct Ticks {
141    registers: StaticRef<TicksRegisters>,
142}
143
144impl Ticks {
145    pub fn new() -> Self {
146        Self {
147            registers: TICKS_BASE,
148        }
149    }
150
151    pub fn set_timer0_generator(&self) {
152        self.registers
153            .timer0_ctrl
154            .modify(TIMER0_CTRL::ENABLE::CLEAR);
155        self.registers
156            .timer0_cycles
157            .modify(TIMER0_CYCLES::TIMER0_CYCLES.val(12));
158        self.registers.timer0_ctrl.modify(TIMER0_CTRL::ENABLE::SET);
159    }
160
161    pub fn set_timer1_generator(&self) {
162        self.registers
163            .timer1_ctrl
164            .modify(TIMER1_CTRL::ENABLE::CLEAR);
165        self.registers
166            .timer1_cycles
167            .modify(TIMER1_CYCLES::TIMER1_CYCLES.val(12));
168        self.registers.timer1_ctrl.modify(TIMER1_CTRL::ENABLE::SET);
169    }
170
171    pub fn is_timer0_on(&self) -> bool {
172        self.registers.timer0_ctrl.is_set(TIMER0_CTRL::RUNNING)
173    }
174}