-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
a82908b
commit 1cd21cf
Showing
7 changed files
with
483 additions
and
66 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,37 +1,38 @@ | ||
#![no_std] | ||
#![no_main] | ||
|
||
extern crate cortex_m; | ||
extern crate cortex_m_rt; | ||
extern crate cortex_m_semihosting; | ||
extern crate atsam4_hal as hal; | ||
extern crate embedded_hal; | ||
|
||
#[cfg(not(feature = "use_semihosting"))] | ||
extern crate panic_halt; | ||
#[cfg(feature = "use_semihosting")] | ||
extern crate panic_semihosting; | ||
|
||
use cortex_m_rt::entry; | ||
use hal::clock::ClockController; | ||
use hal::pac::{CorePeripherals, Peripherals}; | ||
use hal::prelude::*; | ||
use hal::delay::Delay; | ||
use embedded_hal::prelude::*; | ||
use cortex_m_semihosting::hprintln; | ||
|
||
#[entry] | ||
fn main() -> ! { | ||
let mut peripherals = Peripherals::take().unwrap(); | ||
let core = CorePeripherals::take().unwrap(); | ||
|
||
let mut clocks = ClockController::with_internal_32kosc( | ||
peripherals.GCLK, | ||
&mut peripherals.PM, | ||
&mut peripherals.SYSCTRL, | ||
&mut peripherals.NVMCTRL, | ||
let mut peripherals = Peripherals::take().unwrap(); | ||
let clocks = ClockController::with_internal_32kosc( | ||
peripherals.PMC, | ||
&mut peripherals.EFC | ||
); | ||
|
||
// let mut pins = hal::Pins::new(peripherals.PORT); | ||
// let mut red_led = pins.d2.into_open_drain_output(&mut pins.port); | ||
// let mut delay = Delay::new(core.SYST, &mut clocks); | ||
let mut delay = Delay::new(core.SYST, clocks.into()); | ||
|
||
// loop { | ||
// delay.delay_ms(200u8); | ||
// red_led.set_high().unwrap(); | ||
// delay.delay_ms(200u8); | ||
// red_led.set_low().unwrap(); | ||
// } | ||
loop { | ||
hprintln!("This message will repeat every second.").ok(); | ||
delay.delay_ms(1000u32); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
//! Delays | ||
use cortex_m::peripheral::syst::SystClkSource; | ||
use cortex_m::peripheral::SYST; | ||
|
||
use crate::time::Hertz; | ||
use hal::blocking::delay::{DelayMs, DelayUs}; | ||
|
||
/// System timer (SysTick) as a delay provider | ||
pub struct Delay { | ||
sysclock: Hertz, | ||
syst: SYST, | ||
} | ||
|
||
impl Delay { | ||
/// Configures the system timer (SysTick) as a delay provider | ||
pub fn new(mut syst: SYST, sysclock: Hertz) -> Self { | ||
syst.set_clock_source(SystClkSource::Core); | ||
|
||
Delay { | ||
syst, | ||
sysclock: sysclock, | ||
} | ||
} | ||
|
||
/// Releases the system timer (SysTick) resource | ||
pub fn free(self) -> SYST { | ||
self.syst | ||
} | ||
} | ||
|
||
impl DelayMs<u32> for Delay { | ||
fn delay_ms(&mut self, ms: u32) { | ||
self.delay_us(ms * 1_000); | ||
} | ||
} | ||
|
||
impl DelayMs<u16> for Delay { | ||
fn delay_ms(&mut self, ms: u16) { | ||
self.delay_ms(ms as u32); | ||
} | ||
} | ||
|
||
impl DelayMs<u8> for Delay { | ||
fn delay_ms(&mut self, ms: u8) { | ||
self.delay_ms(ms as u32); | ||
} | ||
} | ||
|
||
impl DelayUs<u32> 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 * (self.sysclock.0 / 1_000_000); | ||
|
||
while total_rvr != 0 { | ||
let current_rvr = if total_rvr <= MAX_RVR { | ||
total_rvr | ||
} else { | ||
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<u16> for Delay { | ||
fn delay_us(&mut self, us: u16) { | ||
self.delay_us(us as u32) | ||
} | ||
} | ||
|
||
impl DelayUs<u8> for Delay { | ||
fn delay_us(&mut self, us: u8) { | ||
self.delay_us(us as u32) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,3 @@ | ||
//! Module containing common code for all SAM4 microcontrollers | ||
//! Module containing common code for all SAM4 microcontrollers | ||
pub mod delay; | ||
pub mod time; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,205 @@ | ||
//! Time units | ||
// Frequency based | ||
|
||
/// Bits per second | ||
#[derive(Clone, Copy, PartialEq, Eq, Debug)] | ||
pub struct Bps(pub u32); | ||
|
||
/// Hertz | ||
#[derive(Clone, Copy, PartialEq, Eq, Debug)] | ||
pub struct Hertz(pub u32); | ||
|
||
/// KiloHertz | ||
#[derive(Clone, Copy, PartialEq, Eq, Debug)] | ||
pub struct KiloHertz(pub u32); | ||
|
||
/// MegaHertz | ||
#[derive(Clone, Copy, PartialEq, Eq, Debug)] | ||
pub struct MegaHertz(pub u32); | ||
|
||
// Period based | ||
|
||
/// Seconds | ||
#[derive(Clone, Copy, PartialEq, Eq, Debug)] | ||
pub struct Seconds(pub u32); | ||
|
||
/// Miliseconds | ||
#[derive(Clone, Copy, PartialEq, Eq, Debug)] | ||
pub struct Miliseconds(pub u32); | ||
|
||
/// Microseconds | ||
#[derive(Clone, Copy, PartialEq, Eq, Debug)] | ||
pub struct Microseconds(pub u32); | ||
|
||
/// Extension trait that adds convenience methods to the `u32` type | ||
pub trait U32Ext { | ||
/// Wrap in `Bps` | ||
fn bps(self) -> Bps; | ||
|
||
/// Wrap in `Hertz` | ||
fn hz(self) -> Hertz; | ||
|
||
/// Wrap in `KiloHertz` | ||
fn khz(self) -> KiloHertz; | ||
|
||
/// Wrap in `MegaHertz` | ||
fn mhz(self) -> MegaHertz; | ||
|
||
/// Wrap in `Seconds` | ||
fn s(self) -> Seconds; | ||
|
||
/// Wrap in `Miliseconds` | ||
fn ms(self) -> Miliseconds; | ||
|
||
/// Wrap in `Microseconds` | ||
fn us(self) -> Microseconds; | ||
} | ||
|
||
impl U32Ext for u32 { | ||
|
||
// Frequency based | ||
|
||
fn bps(self) -> Bps { | ||
Bps(self) | ||
} | ||
|
||
fn hz(self) -> Hertz { | ||
Hertz(self) | ||
} | ||
|
||
fn khz(self) -> KiloHertz { | ||
KiloHertz(self) | ||
} | ||
|
||
fn mhz(self) -> MegaHertz { | ||
MegaHertz(self) | ||
} | ||
|
||
// Period based | ||
|
||
fn s(self) -> Seconds { | ||
Seconds(self) | ||
} | ||
|
||
fn ms(self) -> Miliseconds { | ||
Miliseconds(self) | ||
} | ||
|
||
fn us(self) -> Microseconds { | ||
Microseconds(self) | ||
} | ||
} | ||
|
||
// Frequency based | ||
|
||
impl Into<Hertz> for KiloHertz { | ||
fn into(self) -> Hertz { | ||
Hertz(self.0 * 1_000) | ||
} | ||
} | ||
|
||
impl Into<Hertz> for MegaHertz { | ||
fn into(self) -> Hertz { | ||
Hertz(self.0 * 1_000_000) | ||
} | ||
} | ||
|
||
impl Into<KiloHertz> for MegaHertz { | ||
fn into(self) -> KiloHertz { | ||
KiloHertz(self.0 * 1_000) | ||
} | ||
} | ||
|
||
impl Into<KiloHertz> for Hertz { | ||
fn into(self) -> KiloHertz { | ||
KiloHertz(self.0 / 1_000) | ||
} | ||
} | ||
|
||
impl Into<MegaHertz> for Hertz { | ||
fn into(self) -> MegaHertz { | ||
MegaHertz(self.0 / 1_000_000) | ||
} | ||
} | ||
|
||
impl Into<MegaHertz> for KiloHertz { | ||
fn into(self) -> MegaHertz { | ||
MegaHertz(self.0 / 1_000) | ||
} | ||
} | ||
|
||
// Period based | ||
|
||
impl Into<Miliseconds> for Seconds { | ||
fn into(self) -> Miliseconds { | ||
Miliseconds(self.0 * 1_000) | ||
} | ||
} | ||
|
||
impl Into<Microseconds> for Seconds { | ||
fn into(self) -> Microseconds { | ||
Microseconds(self.0 * 1_000_000) | ||
} | ||
} | ||
|
||
impl Into<Microseconds> for Miliseconds { | ||
fn into(self) -> Microseconds { | ||
Microseconds(self.0 * 1_000) | ||
} | ||
} | ||
|
||
impl Into<Seconds> for Miliseconds { | ||
fn into(self) -> Seconds { | ||
Seconds(self.0 / 1_000) | ||
} | ||
} | ||
|
||
impl Into<Seconds> for Microseconds { | ||
fn into(self) -> Seconds { | ||
Seconds(self.0 / 1_000_000) | ||
} | ||
} | ||
|
||
impl Into<Miliseconds> for Microseconds { | ||
fn into(self) -> Miliseconds { | ||
Miliseconds(self.0 / 1_000) | ||
} | ||
} | ||
|
||
// Frequency <-> Period | ||
|
||
impl Into<Hertz> for Microseconds { | ||
fn into(self) -> Hertz { | ||
Hertz(1_000_000_u32 / self.0) | ||
} | ||
} | ||
|
||
impl Into<Microseconds> for Hertz { | ||
fn into(self) -> Microseconds { | ||
Microseconds(1_000_000_u32 / self.0) | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use crate::time::*; | ||
|
||
#[test] | ||
fn convert_us_to_hz() { | ||
let as_us: Microseconds = 3.hz().into(); | ||
assert_eq!(as_us.0, 333_333_u32); | ||
} | ||
|
||
#[test] | ||
fn convert_ms_to_us() { | ||
let as_us: Microseconds = 3.ms().into(); | ||
assert_eq!(as_us.0, 3_000_u32); | ||
} | ||
|
||
#[test] | ||
fn convert_mhz_to_hz() { | ||
let as_hz: Hertz = 48.mhz().into(); | ||
assert_eq!(as_hz.0, 48_000_000_u32); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.