Initial commit
commit
72a645e8ba
|
@ -0,0 +1,3 @@
|
||||||
|
/target
|
||||||
|
**/*.rs.bk
|
||||||
|
Cargo.lock
|
|
@ -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"]
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
|
@ -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>,
|
||||||
|
}
|
|
@ -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;
|
|
@ -0,0 +1,3 @@
|
||||||
|
//! Prelude
|
||||||
|
|
||||||
|
pub use hal::prelude::*;
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue