Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
john-terrell committed Sep 7, 2020
1 parent a82908b commit 1cd21cf
Show file tree
Hide file tree
Showing 7 changed files with 483 additions and 66 deletions.
4 changes: 3 additions & 1 deletion boards/sam4e_xplained_pro/blink/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ readme = "README.md"
cortex-m = "~0.6"
embedded-hal = "~0.2.3"
nb = "~0.1"
cortex-m-semihosting = "~0.3"

[dependencies.cortex-m-rt]
version = "~0.6.12"
Expand All @@ -32,7 +33,8 @@ optional = true
path = "../../.."

[features]
default = ["atsam4-hal/atsam4e16e", "panic_halt"]
default = ["rt", "atsam4-hal/atsam4e16e", "panic_halt"]
rt = ["cortex-m-rt"]
panic_halt = ["panic-halt"]
panic_abort = ["panic-abort"]
panic_semihosting = ["panic-semihosting"]
Expand Down
33 changes: 17 additions & 16 deletions boards/sam4e_xplained_pro/blink/src/main.rs
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);
}
}
88 changes: 88 additions & 0 deletions src/common/delay.rs
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)
}
}
4 changes: 3 additions & 1 deletion src/common/mod.rs
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;
205 changes: 205 additions & 0 deletions src/common/time.rs
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);
}
}
7 changes: 5 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,14 @@
//! [cortex-m-quickstart]: https://docs.rs/cortex-m-quickstart/~0.3
//!
#![deny(missing_docs)]
#![deny(warnings)]
//#![deny(missing_docs)]
//#![deny(warnings)]
#![no_std]

pub mod common;
pub use common::*;

pub extern crate embedded_hal as hal;

#[cfg(feature = "atsam4e16e")]
pub use atsam4e16e_pac as pac;
Expand Down
Loading

0 comments on commit 1cd21cf

Please sign in to comment.