stm32_rust_template/arch/cortex_m4/
systick.rs1use super::super::super::mcu::stm32f407::PeripheralAccess;
5use core::sync::atomic::{AtomicU32, Ordering};
6
7pub const SYSTICK_BASE: u32 = 0xE000E010;
9
10#[repr(C)]
12pub struct SysTick {
13 pub ctrl: u32, pub load: u32, pub val: u32, pub calib: u32, }
18
19pub struct SYSTICK;
21
22impl PeripheralAccess for SYSTICK {
23 const BASE_ADDRESS: u32 = SYSTICK_BASE;
24 type RegisterBlock = SysTick;
25}
26
27static TICK_COUNT: AtomicU32 = AtomicU32::new(0);
29
30pub fn get_ticks() -> u32 {
32 TICK_COUNT.load(Ordering::Relaxed)
33}
34
35pub fn increment_ticks() {
37 TICK_COUNT.fetch_add(1, Ordering::Relaxed);
38}
39
40pub const SYSTICK_CTRL_COUNTFLAG_POS: u32 = 16;
42pub const SYSTICK_CTRL_COUNTFLAG_MSK: u32 = 1 << SYSTICK_CTRL_COUNTFLAG_POS;
43
44pub const SYSTICK_CTRL_CLKSOURCE_POS: u32 = 2;
45pub const SYSTICK_CTRL_CLKSOURCE_MSK: u32 = 1 << SYSTICK_CTRL_CLKSOURCE_POS;
46
47pub const SYSTICK_CTRL_TICKINT_POS: u32 = 1;
48pub const SYSTICK_CTRL_TICKINT_MSK: u32 = 1 << SYSTICK_CTRL_TICKINT_POS;
49
50pub const SYSTICK_CTRL_ENABLE_POS: u32 = 0;
51pub const SYSTICK_CTRL_ENABLE_MSK: u32 = 1;
52
53pub const SYSTICK_LOAD_RELOAD_POS: u32 = 0;
55pub const SYSTICK_LOAD_RELOAD_MSK: u32 = 0xFFFFFF;
56
57pub const SYSTICK_VAL_CURRENT_POS: u32 = 0;
59pub const SYSTICK_VAL_CURRENT_MSK: u32 = 0xFFFFFF;
60
61pub const SYSTICK_CALIB_NOREF_POS: u32 = 31;
63pub const SYSTICK_CALIB_NOREF_MSK: u32 = 1 << SYSTICK_CALIB_NOREF_POS;
64
65pub const SYSTICK_CALIB_SKEW_POS: u32 = 30;
66pub const SYSTICK_CALIB_SKEW_MSK: u32 = 1 << SYSTICK_CALIB_SKEW_POS;
67
68pub const SYSTICK_CALIB_TENMS_POS: u32 = 0;
69pub const SYSTICK_CALIB_TENMS_MSK: u32 = 0xFFFFFF;
70
71impl SysTick {
73 pub fn enable(&mut self) {
75 self.ctrl |= SYSTICK_CTRL_ENABLE_MSK;
76 }
77
78 pub fn disable(&mut self) {
80 self.ctrl &= !SYSTICK_CTRL_ENABLE_MSK;
81 }
82
83 pub fn enable_interrupt(&mut self) {
85 self.ctrl |= SYSTICK_CTRL_TICKINT_MSK;
86 }
87
88 pub fn disable_interrupt(&mut self) {
90 self.ctrl &= !SYSTICK_CTRL_TICKINT_MSK;
91 }
92
93 pub fn set_clock_source_processor(&mut self) {
95 self.ctrl |= SYSTICK_CTRL_CLKSOURCE_MSK;
96 }
97
98 pub fn set_clock_source_external(&mut self) {
100 self.ctrl &= !SYSTICK_CTRL_CLKSOURCE_MSK;
101 }
102
103 pub fn set_reload(&mut self, value: u32) {
105 self.load = value & SYSTICK_LOAD_RELOAD_MSK;
106 }
107
108 pub fn get_current(&self) -> u32 {
110 self.val & SYSTICK_VAL_CURRENT_MSK
111 }
112
113 pub fn clear_current(&mut self) {
115 self.val = 0;
116 }
117
118 pub fn is_count_flag_set(&self) -> bool {
120 (self.ctrl & SYSTICK_CTRL_COUNTFLAG_MSK) != 0
121 }
122
123 pub fn get_tenms(&self) -> u32 {
125 self.calib & SYSTICK_CALIB_TENMS_MSK
126 }
127
128 pub fn has_no_reference(&self) -> bool {
130 (self.calib & SYSTICK_CALIB_NOREF_MSK) != 0
131 }
132
133 pub fn is_skewed(&self) -> bool {
135 (self.calib & SYSTICK_CALIB_SKEW_MSK) != 0
136 }
137}
138
139pub fn systick_config(ticks: u32) -> u32 {
144 if (ticks - 1) > SYSTICK_LOAD_RELOAD_MSK {
145 return 1; }
147
148 unsafe {
149 let systick = &mut *(SYSTICK_BASE as *mut SysTick);
150 systick.set_reload(ticks - 1);
151 systick.clear_current();
152 systick.set_clock_source_processor();
153 systick.enable_interrupt();
154 systick.enable();
155 }
156
157 0
158}
159
160pub fn systick_init_1ms(freq_hz: u32) -> u32 {
163 let ticks = freq_hz / 1000; systick_config(ticks)
165}