Initial commit

master
Levi Pearson 2019-03-14 18:24:48 -06:00
commit 72a645e8ba
8 changed files with 327 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
/target
**/*.rs.bk
Cargo.lock

19
Cargo.toml Normal file
View File

@ -0,0 +1,19 @@
[package]
name = "msp432-hal"
version = "0.1.0"
authors = ["Levi Pearson <levipearson@gmail.com>"]
categories = ["embedded", "hardware-support", "no-std"]
description = "HAL for the TI MSP432 family of microcontrollers"
keywords = ["arm", "cortex-m", "msp432", "hal"]
edition = "2018"
[dependencies]
cortex-m = "0.5"
embedded-hal = "0.2"
nb = "0.1"
msp432p401r = { path = "../msp432p401r" }
void = { version = "1.0", default-features = false }
cast = { version = "0.2", default-features = false }
[features]
rt = ["msp432p401r/rt"]

63
src/cs.rs Normal file
View File

@ -0,0 +1,63 @@
//! Clock System
use core::cmp;
use pac::{cs, CS};
use crate::time::Hertz;
/// Extension trait that constrains the `CS` peripheral
pub trait CsExt {
/// Constrains the `CS` peripheral so that it plays nicely with other abstractions
fn constrain(self) -> Cs;
}
impl CsExt for CS {
fn constrain(self) -> Cs {
Cs {
}
}
}
/*
+--------+-----------------------+---------------+-------------------------------------+
| Clock | Default Clock Source | Default Clock | Description |
| | | Frequency | |
+========+=======================+===============+=====================================+
| MCLK | DCO | 3 MHz | Master Clock - Sources CPU and |
| | | | peripherals |
+--------+-----------------------+---------------+-------------------------------------+
| HSMCLK | DCO | 3 MHz | Subsystem Master Clock - Sources |
| | | | peripherals |
+--------+-----------------------+---------------+-------------------------------------+
| SMCLK | DCO | 3 MHz | Low-speed subsystem master clock - |
| | | | Sources peripherals |
+--------+-----------------------+---------------+-------------------------------------+
| ACLK | LFXT (or REFO if no | 32.768 kHz | Auxiliary clock - Sources |
| | crystal present) | | peripherals |
+--------+-----------------------+---------------+-------------------------------------+
| BCLK | LFXT (or REFO if no | 32.768 kHz | Low-speed backup domain clock - |
| | crystal present) | | Sources LPM peripherals |
+--------+-----------------------+---------------+-------------------------------------+
*/
pub struct Cs {
}
/// Frozen clock frequencies
///
/// This value holds the current clocks frequencies and indicates that they can
/// no longer be changed
#[derive(Clone, Copy)]
pub struct Clocks {
sysclk: Hertz,
}
impl Clocks {
/// Returns the system (core) frequency
pub fn sysclk(&self) -> Hertz {
self.sysclk
}
}

74
src/delay.rs Normal file
View File

@ -0,0 +1,74 @@
//! Delays
use cast::u32;
use cortex_m::peripheral::syst::SystClkSource;
use cortex_m::peripheral::SYST;
use hal::blocking::delay::{DelayMs, DelayUs};
use crate::cs::Clocks;
/// System timer (SysTick) as a delay provider
pub struct Delay {
clocks: Clocks,
syst: SYST,
}
impl Delay {
/// Configure the system timer (SysTick) as a delay provider
pub fn new(mut syst: SYST, clocks: Clocks) -> Self {
syst.set_clock_source(SystClkSource::Core);
Delay { syst, clocks }
}
/// Release 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(u32(ms));
}
}
impl DelayMs<u8> for Delay {
fn delay_ms(&mut self, ms: u8) {
self.delay_ms(u32(ms));
}
}
impl DelayUs<u32> for Delay {
fn delay_us(&mut self, us: u32) {
let rvr = us * (self.clocks.sysclk().0 / 1_000_000);
assert!(rvr < (1 << 24));
self.syst.set_reload(rvr);
self.syst.clear_current();
self.syst.enable_counter();
while !self.syst.has_wrapped() {}
self.syst.disable_counter();
}
}
impl DelayUs<u16> for Delay {
fn delay_us(&mut self, us: u16) {
self.delay_us(u32(us));
}
}
impl DelayUs<u8> for Delay {
fn delay_us(&mut self, us: u8) {
self.delay_us(u32(us));
}
}

22
src/gpio.rs Normal file
View File

@ -0,0 +1,22 @@
//! General Purpose Input / Output
use pac::DIO;
use core::marker::PhantomData;
use hal::digital::OutputPin;
pub trait GpioExt {
type Parts;
/// Consume and split the device into its constituent parts
fn split(self) -> Self::Parts;
}
/// Represents a pin configured for input.
pub struct Input<MODE> {
_mode: PhantomData<MODE>,
}
/// Represents a pin configured for output.
pub struct Output<MODE> {
_mode: PhantomData<MODE>,
}

26
src/lib.rs Normal file
View File

@ -0,0 +1,26 @@
//! HAL for the MSP432 family of microcontrollers
//!
//! This is an implementation of the [`embedded-hal`] traits for the MSP432 family of
//! microcontrollers.
//!
//! [`embedded-hal`]: https://github.com/japaric/embedded-hal
//!
//! # Usage
//!
//! To build applications (binary crates) using this crate follow the [cortex-m-quickstart]
//! instructions and add this crate as a dependency in step number 5 and make sure you enable the
//! "rt" Cargo feature of this crate.
//!
//! [cortex-m-quickstart]: https://docs.rs/cortex-m-quickstart/~0.3
#![warn(missing_docs)]
#![no_std]
extern crate embedded_hal as hal;
extern crate msp432p401r as pac;
pub mod prelude;
pub mod gpio;
pub mod delay;
pub mod cs;
pub mod time;

3
src/prelude.rs Normal file
View File

@ -0,0 +1,3 @@
//! Prelude
pub use hal::prelude::*;

117
src/time.rs Normal file
View File

@ -0,0 +1,117 @@
//! Time units
use cortex_m::peripheral::DWT;
use crate::cs::Clocks;
/// Bits per seconds
#[derive(Clone, Copy)]
pub struct Bps(pub u32);
/// Hertz
#[derive(Clone, Copy)]
pub struct Hertz(pub u32);
/// KiloHertz
#[derive(Clone, Copy)]
pub struct KiloHertz(pub u32);
/// MegaHertz
#[derive(Clone, Copy)]
pub struct MegaHertz(pub u32);
/// Extension trait to add convenience methods to `u32`
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;
}
impl U32Ext for u32 {
fn bps(self) -> Bps {
Bps(self)
}
fn hz(self) -> Hertz {
Hertz(self)
}
fn khz(self) -> KiloHertz {
KiloHertz(self)
}
fn mhz(self) -> MegaHertz {
MegaHertz(self)
}
}
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)
}
}
/// A monotonic nondecreasing timer
#[derive(Clone, Copy)]
pub struct MonoTimer {
frequency: Hertz,
}
impl MonoTimer {
/// Create a new monotonic timer
pub fn new(mut dwt: DWT, clocks: Clocks) -> Self {
dwt.enable_cycle_counter();
// can't stop or reset CYCCNT
drop(dwt);
MonoTimer {
frequency: clocks.sysclk(),
}
}
/// Return the frequency at which the timer is operating
pub fn frequency(&self) -> Hertz {
self.frequency
}
/// Returns an `Instant` corresponding to "now"
pub fn now(&self) -> Instant {
Instant {
now: DWT::get_cycle_count(),
}
}
}
/// A measurement from a monotonically nondecreasing clock
#[derive(Clone, Copy)]
pub struct Instant {
now: u32,
}
impl Instant {
/// Ticks elapsed since the `Instant` was created
pub fn elapsed(&self) -> u32 {
DWT::get_cycle_count().wrapping_sub(self.now)
}
}