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