Skip to content
This repository was archived by the owner on Jul 6, 2019. It is now read-only.

Commit 39b76aa

Browse files
committed
systick: Refactoring.
1 parent 046d76a commit 39b76aa

File tree

3 files changed

+67
-31
lines changed

3 files changed

+67
-31
lines changed

apps/app_blink_k20.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ pub unsafe fn main() {
3737
// Pins for MC HCK (http://www.mchck.org/)
3838
let led1 = pin::Pin::new(pin::PortB, 16, pin::GPIO, Some(zinc::hal::pin::Out));
3939

40-
systick::setup(480000, false);
40+
systick::setup(systick::ten_ms().unwrap_or(480000));
4141
systick::enable();
4242
loop {
4343
led1.set_high();

apps/old_app_systick.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,15 @@ unsafe fn systick_handler() {
4040
#[no_split_stack]
4141
pub fn main() {
4242
platform.configuration.setup();
43-
systick::setup(systick::CALIBRATED, true);
43+
systick::setup(systick::ten_ms().unwrap_or(480000));
4444

4545
let led1 = platform.led1.setup();
4646

4747
led1.set_high();
4848

4949
let mut ison: bool = true;
5050

51+
systick::enable_irq();
5152
systick::enable();
5253

5354
unsafe { loop {

src/hal/cortex_common/systick.rs

Lines changed: 64 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -15,68 +15,103 @@
1515

1616
//! Interface to SYSTICK timer.
1717
18-
#[path="../../lib/ioreg.rs"] mod ioreg;
18+
use core::option::{Option,None,Some};
1919

20-
/// A constant that requests to use hardware calibration value.
21-
/// Note that not all core implementations support this.
22-
pub static CALIBRATED: u32 = 0xffffffff;
20+
#[path="../../lib/ioreg.rs"] mod ioreg;
2321

24-
/// Initializes systick timer.
22+
/// Initialize systick timer.
23+
///
24+
/// After this call system timer will be disabled, and needs to be enabled manual. SysTick irq will
25+
/// be disabled and needs to be enabled manually, too.
2526
///
2627
/// Arguments:
2728
///
28-
/// * calibration: Timer reload value, or `CALIBRATED` to use the device 10ms
29-
/// calibrated value.
30-
/// * enable_irq: true, if IRQ should be initially enabled.
31-
pub fn setup(calibration: u32, enable_irq: bool) {
32-
reg::SYSTICK.set_CONTROL(0b100); // disabled, no interrupt
33-
let reload_val: u32 = match calibration {
34-
CALIBRATED => reg::SYSTICK.CALIBRATION() & 0xffffff,
35-
val => val,
36-
};
37-
reg::SYSTICK.set_RELOAD(reload_val);
38-
reg::SYSTICK.set_CURRENT(0);
39-
if enable_irq {
40-
reg::SYSTICK.set_CONTROL(0b110);
29+
/// * reload: Reload value for the timer
30+
pub fn setup(reload: u32) {
31+
reg::SYSTICK.csr.set_enable(false).set_tickint(false).set_clksource(reg::CPU);
32+
33+
reg::SYSTICK.rvr.set_reload(reload);
34+
reg::SYSTICK.cvr.set_current(0);
35+
}
36+
37+
/// Read ten millisecond calibration value from hardware
38+
pub fn ten_ms() -> Option<u32> {
39+
let calib = reg::SYSTICK.calib.tenms();
40+
match calib {
41+
0 => None,
42+
val => Some(val)
4143
}
4244
}
4345

4446
/// Enables the timer.
4547
pub fn enable() {
46-
reg::SYSTICK.set_CONTROL(reg::SYSTICK.CONTROL() | 1);
48+
reg::SYSTICK.csr.set_enable(true);
49+
}
50+
51+
/// Disable the timer.
52+
pub fn disable() {
53+
reg::SYSTICK.csr.set_enable(false);
4754
}
4855

4956
/// Enables interrupts generation for timer.
5057
pub fn enable_irq() {
51-
reg::SYSTICK.set_CONTROL(reg::SYSTICK.CONTROL() | 0b010);
58+
reg::SYSTICK.csr.set_tickint(true);
5259
}
5360

5461
/// Disables interrupts generation for timer, which is still ticking.
5562
pub fn disable_irq() {
56-
reg::SYSTICK.set_CONTROL(reg::SYSTICK.CONTROL() & !0b010);
63+
reg::SYSTICK.csr.set_tickint(false);
5764
}
5865

5966
/// Gets the current 24bit systick value.
6067
pub fn get_current() -> u32 {
61-
reg::SYSTICK.CURRENT() & 0xFFFFFF
68+
reg::SYSTICK.cvr.current()
6269
}
6370

6471
/// Checks if the timer has been triggered since last call.
6572
/// The flag is cleared when this is called.
6673
pub fn tick() -> bool {
67-
((reg::SYSTICK.CONTROL() >> 16) & 0x1) == 1
74+
reg::SYSTICK.csr.countflag()
6875
}
6976

77+
#[allow(dead_code)]
7078
mod reg {
7179
use lib::volatile_cell::VolatileCell;
80+
use core::ops::Drop;
81+
82+
ioregs!(SYSTICK = {
83+
/// SysTick Control and Status Register
84+
0x0 => reg32 csr
85+
{
86+
16 => countflag : ro, //= Returns 1 if timer counted to 0
87+
//= since last time this was read.
88+
2 => clksource : rw {
89+
0 => External, //= External clock
90+
1 => CPU, //= CPU clock
91+
},
92+
1 => tickint : rw, //= Enable SysTick exception
93+
0 => enable : rw
94+
},
95+
96+
/// Reload Value Register
97+
0x4 => reg32 rvr {
98+
23..0 => reload : rw //= Reload value
99+
}
100+
101+
/// Current Value Register
102+
0x8 => reg32 cvr {
103+
31..0 => current : rw //= Current timer value
104+
},
72105

73-
ioreg_old!(SYSTICKReg: u32, CONTROL, RELOAD, CURRENT, CALIBRATION)
74-
reg_rw!(SYSTICKReg, u32, CONTROL, set_CONTROL, CONTROL)
75-
reg_rw!(SYSTICKReg, u32, RELOAD, set_RELOAD, RELOAD)
76-
reg_rw!(SYSTICKReg, u32, CURRENT, set_CURRENT, CURRENT)
77-
reg_r!( SYSTICKReg, u32, CALIBRATION, CALIBRATION)
106+
0xc => reg32 calib {
107+
31 => noref : ro, //= If 1, the reference clock is not provided
108+
30 => skew : ro, //= If 1, the calibration value is inexact
109+
23..0 => tenms : ro, //= An optional Reload value for 10ms (100Hz) timing
110+
//= If zero calibration value not known
111+
},
112+
})
78113

79114
extern {
80-
#[link_name="armmem_SYSTICK"] pub static SYSTICK: SYSTICKReg;
115+
#[link_name="armmem_SYSTICK"] pub static SYSTICK: SYSTICK;
81116
}
82117
}

0 commit comments

Comments
 (0)