From e5529a8b9490633de5ccbc9daa2b3f03ade354d4 Mon Sep 17 00:00:00 2001 From: Astro Date: Sun, 8 Sep 2019 01:24:20 +0200 Subject: [PATCH] add systick interrupt for timekeeping --- firmware/src/board/delay.rs | 76 ------------------------------------- firmware/src/board/mod.rs | 1 - firmware/src/main.rs | 47 +++++++++++++++++------ 3 files changed, 35 insertions(+), 89 deletions(-) delete mode 100644 firmware/src/board/delay.rs diff --git a/firmware/src/board/delay.rs b/firmware/src/board/delay.rs deleted file mode 100644 index 0201681..0000000 --- a/firmware/src/board/delay.rs +++ /dev/null @@ -1,76 +0,0 @@ -use embedded_hal::blocking::delay::{DelayMs, DelayUs}; -use cortex_m::peripheral::syst::SystClkSource; -use cortex_m::peripheral::SYST; -use tm4c129x::CorePeripherals; - -/// precision internal oscillator -const PIOSC: u32 = 16_000_000; - -pub struct Delay { - syst: SYST, -} - -impl Delay { - /// unsafe: must only be used once to avoid concurrent use of systick - pub unsafe fn new() -> Self { - let mut syst = CorePeripherals::steal().SYST; - // PIOSC - syst.set_clock_source(SystClkSource::External); - syst.disable_interrupt(); - Delay { syst } - } -} - -impl DelayMs for Delay { - fn delay_ms(&mut self, ms: u32) { - self.delay_us(ms * 1_000); - } -} - -impl DelayMs for Delay { - fn delay_ms(&mut self, ms: u16) { - self.delay_ms(u32::from(ms)); - } -} - -impl DelayMs for Delay { - fn delay_ms(&mut self, ms: u8) { - self.delay_ms(u32::from(ms)); - } -} - -impl DelayUs for Delay { - fn delay_us(&mut self, us: u32) { - // The SysTick Reload Value register supports values between 1 and 0x00FFFFFF. - const MAX_RVR: u32 = 0x00FF_FFFF; - - let mut total_rvr = us * (PIOSC / 1_000_000); - - while total_rvr != 0 { - let current_rvr = total_rvr.min(MAX_RVR); - - self.syst.set_reload(current_rvr); - self.syst.clear_current(); - self.syst.enable_counter(); - - // Update the tracking variable while we are waiting... - total_rvr -= current_rvr; - - while !self.syst.has_wrapped() {} - - self.syst.disable_counter(); - } - } -} - -impl DelayUs for Delay { - fn delay_us(&mut self, us: u16) { - self.delay_us(u32::from(us)) - } -} - -impl DelayUs for Delay { - fn delay_us(&mut self, us: u8) { - self.delay_us(u32::from(us)) - } -} diff --git a/firmware/src/board/mod.rs b/firmware/src/board/mod.rs index 7fd365d..4a0f8f3 100644 --- a/firmware/src/board/mod.rs +++ b/firmware/src/board/mod.rs @@ -3,7 +3,6 @@ use tm4c129x; pub mod gpio; pub mod softspi; -pub mod delay; const UART_DIV: u32 = (((/*sysclk*/120_000_000 * 8) / /*baud*/115200) + 1) / 2; diff --git a/firmware/src/main.rs b/firmware/src/main.rs index 0faca56..16e65c4 100644 --- a/firmware/src/main.rs +++ b/firmware/src/main.rs @@ -2,9 +2,9 @@ #![no_std] #![no_main] -use cortex_m_rt::entry; +use cortex_m_rt::{entry, exception}; use core::fmt::{self, Write}; -use embedded_hal::blocking::delay::DelayUs; +use cortex_m::peripheral::{SYST, syst::SystClkSource}; use smoltcp::time::Instant; use smoltcp::wire::{IpCidr, IpAddress, EthernetAddress}; use smoltcp::iface::{NeighborCache, EthernetInterfaceBuilder}; @@ -76,6 +76,7 @@ fn main() -> ! { writeln!(stdout, "ionpak boot").unwrap(); board::init(); writeln!(stdout, "board initialized").unwrap(); + init_systick(); println!(r#" _ _ @@ -87,7 +88,6 @@ fn main() -> ! { | | |_| "#); - let mut delay = unsafe { board::delay::Delay::new() }; // CSn let pb4 = board::gpio::PB4.into_output(); // SCLK @@ -97,7 +97,6 @@ fn main() -> ! { // MISO let pe5 = board::gpio::PE5.into_input(); // max 2 MHz = 0.5 us - // let mut delay_fn = || delay.delay_us(1u32); let mut delay_fn = || for _ in 0..10 { cortex_m::asm::nop(); }; let spi = board::softspi::SyncSoftSpi::new( board::softspi::SoftSpi::new(pb5, pe4, pe5), @@ -189,7 +188,8 @@ fn main() -> ! { .and_then(|channel| channel.map(|channel| adc.read_data().map(|new_data| { - data = Some(Ok((channel, new_data))); + let now = get_time(); + data = Some((now, Ok((channel, new_data)))); for p in socket_pending.iter_mut() { *p = true; } @@ -197,7 +197,8 @@ fn main() -> ! { ).unwrap_or(Ok(())) ) .map_err(|e| { - data = Some(Err(e)); + let now = get_time(); + data = Some((now, Err(e))); for p in socket_pending.iter_mut() { *p = true; } @@ -211,14 +212,14 @@ fn main() -> ! { if socket.may_send() && *pending { match &data { - Some(Ok((channel, input))) => { - let _ = writeln!(socket, "channel={} input={}\r", channel, input); + Some((time, Ok((channel, input)))) => { + let _ = writeln!(socket, "t={} channel={} input={}\r", time, channel, input); } - Some(Err(ad7172::AdcError::ChecksumMismatch(Some(expected), Some(input)))) => { - let _ = writeln!(socket, "checksum_expected={:02X} checksum_input={:02X}\r", expected, input); + Some((time, Err(ad7172::AdcError::ChecksumMismatch(Some(expected), Some(input))))) => { + let _ = writeln!(socket, "t={} checksum_expected={:02X} checksum_input={:02X}\r", time, expected, input); } - Some(Err(e)) => { - let _ = writeln!(socket, "adc_error={:?}\r", e); + Some((time, Err(e))) => { + let _ = writeln!(socket, "t={} adc_error={:?}\r", time, e); } None => {} } @@ -232,3 +233,25 @@ fn main() -> ! { time += 1; } } + +const SYSTICK_RATE: u32 = 1000; +static mut TIME: u32 = 0; + +pub fn get_time() -> u32 { + unsafe { TIME } +} + +#[exception] +fn SysTick() { + unsafe { TIME += 1000 / SYSTICK_RATE; } +} + +fn init_systick() { + #[allow(mutable_transmutes)] + let syst: &mut SYST = unsafe { core::mem::transmute(&*SYST::ptr()) }; + syst.set_clock_source(SystClkSource::Core); + syst.set_reload(100 * SYST::get_ticks_per_10ms() / SYSTICK_RATE); + syst.clear_current(); + syst.enable_interrupt(); + syst.enable_counter(); +}