From 5f3d674e244874b8d29eb4d521ac0e03183d0569 Mon Sep 17 00:00:00 2001 From: Astro Date: Tue, 30 Jul 2019 18:25:35 +0200 Subject: [PATCH] add gpio abstraction --- firmware/Cargo.lock | 23 ++++++++ firmware/Cargo.toml | 1 + firmware/src/board/gpio.rs | 73 +++++++++++++++++++++++++ firmware/src/{board.rs => board/mod.rs} | 2 + firmware/src/main.rs | 1 + 5 files changed, 100 insertions(+) create mode 100644 firmware/src/board/gpio.rs rename firmware/src/{board.rs => board/mod.rs} (99%) diff --git a/firmware/Cargo.lock b/firmware/Cargo.lock index 6c66a63..343e2c7 100644 --- a/firmware/Cargo.lock +++ b/firmware/Cargo.lock @@ -94,6 +94,15 @@ dependencies = [ "build_const 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "embedded-hal" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "nb 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "generic-array" version = "0.12.3" @@ -109,6 +118,7 @@ dependencies = [ "cortex-m 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", "cortex-m-rt 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "embedded-hal 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "libm 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "smoltcp 0.4.0 (git+https://github.com/m-labs/smoltcp?rev=cd893e6)", "tm4c129x 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -134,6 +144,11 @@ name = "managed" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "nb" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "proc-macro2" version = "0.4.30" @@ -257,6 +272,11 @@ name = "vcell" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "volatile-register" version = "0.2.0" @@ -298,10 +318,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum cortex-m-rt 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "17805910e3ecf029bdbfcc42b7384d9e3d9e5626153fa810002c1ef9839338ac" "checksum cortex-m-rt-macros 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d7ae692573e0acccb1579fef1abf5a5bf1d2f3f0149a22b16870ec9309aee25f" "checksum crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d663548de7f5cca343f1e0a48d14dcfb0e9eb4e079ec58883b7251539fa10aeb" +"checksum embedded-hal 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ee4908a155094da7723c2d60d617b820061e3b4efcc3d9e293d206a5a76c170b" "checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum libm 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7fc7aa29613bd6a620df431842069224d8bc9011086b1db4c0e0cd47fa03ec9a" "checksum managed 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "43e2737ecabe4ae36a68061398bf27d2bfd0763f4c3c837a398478459494c4b7" +"checksum nb 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b1411551beb3c11dedfb0a90a0fa256b47d28b9ec2cdff34c25a2fa59e45dbdc" "checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" "checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" "checksum r0 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2a38df5b15c8d5c7e8654189744d8e396bddc18ad48041a500ce52d6948941f" @@ -319,6 +341,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" "checksum vcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "45c297f0afb6928cd08ab1ff9d95e99392595ea25ae1b5ecf822ff8764e57a0d" +"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" "checksum volatile-register 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0d67cb4616d99b940db1d6bd28844ff97108b498a6ca850e5b6191a532063286" "checksum walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "bb08f9e670fab86099470b97cd2b252d6527f0b3cc1401acdb595ffc9dd288ff" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" diff --git a/firmware/Cargo.toml b/firmware/Cargo.toml index 876be98..c10efea 100644 --- a/firmware/Cargo.toml +++ b/firmware/Cargo.toml @@ -12,6 +12,7 @@ cortex-m = { version = "0.5", features = ["const-fn"] } cortex-m-rt = "0.6" crc = { version = "1.7", default-features = false } tm4c129x = { version = "0.8", features = ["rt"] } +embedded-hal = { version = "0.2", features = ["unproven"] } [dependencies.smoltcp] git = "https://github.com/m-labs/smoltcp" diff --git a/firmware/src/board/gpio.rs b/firmware/src/board/gpio.rs new file mode 100644 index 0000000..6f8349f --- /dev/null +++ b/firmware/src/board/gpio.rs @@ -0,0 +1,73 @@ +use core::mem::transmute; +use core::slice::from_raw_parts_mut; +use embedded_hal::digital::v2::{InputPin, OutputPin}; + +pub trait Gpio where Self: Sized { + fn into_output(self) -> GpioOutput; + fn into_input(self) -> GpioInput; +} + +pub struct GpioInput(PIN); +pub struct GpioOutput(PIN); + +macro_rules! def_gpio { + ($PORT: tt, $PIN: tt, $idx: expr) => ( + impl Gpio for $PIN { + fn into_output(self) -> GpioOutput { + let gpio = unsafe { &*tm4c129x::$PORT::ptr() }; + gpio.dir.modify(|_, w| w.dir().bits(1 << $idx)); + gpio.den.modify(|_, w| w.den().bits(1 << $idx)); + GpioOutput(self) + } + fn into_input(self) -> GpioInput { + let gpio = unsafe { &*tm4c129x::$PORT::ptr() }; + gpio.dir.modify(|_, w| w.dir().bits(1 << $idx)); + gpio.den.modify(|_, w| w.den().bits(1 << $idx)); + GpioInput(self) + } + } + + impl InputPin for GpioInput<$PIN> { + type Error = (); + fn is_high(&self) -> Result { + let gpio = unsafe { &*tm4c129x::$PORT::ptr() }; + Ok(gpio.data.read().data().bits() & (1 << $idx) == (1 << $idx)) + } + fn is_low(&self) -> Result { + let gpio = unsafe { &*tm4c129x::$PORT::ptr() }; + Ok(gpio.data.read().data().bits() & (1 << $idx) != (1 << $idx)) + } + } + + impl OutputPin for GpioOutput<$PIN> { + type Error = (); + fn set_low(&mut self) -> Result<(), Self::Error> { + let gpio = unsafe { &*tm4c129x::$PORT::ptr() }; + let data = masked_data(unsafe { transmute(&gpio.data) }, $idx); + *data = 0; + Ok(()) + } + fn set_high(&mut self) -> Result<(), Self::Error> { + let gpio = unsafe { &*tm4c129x::$PORT::ptr() }; + let data = masked_data(unsafe { transmute(&gpio.data) }, $idx); + *data = 1 << $idx; + Ok(()) + } + } + ) +} + +pub struct PB4; +def_gpio!(GPIO_PORTB_AHB, PB4, 4); +pub struct PB5; +def_gpio!(GPIO_PORTB_AHB, PB5, 5); +pub struct PE4; +def_gpio!(GPIO_PORTE_AHB, PE4, 5); +pub struct PE5; +def_gpio!(GPIO_PORTE_AHB, PE5, 5); + +/// Setting of GPIO pins is optimized by address masking +fn masked_data<'a>(data: *mut u32, bits: u8) -> &'a mut u32 { + let data = unsafe { from_raw_parts_mut(data, 0x100) }; + &mut data[usize::from(bits)] +} diff --git a/firmware/src/board.rs b/firmware/src/board/mod.rs similarity index 99% rename from firmware/src/board.rs rename to firmware/src/board/mod.rs index d09c751..8fb7303 100644 --- a/firmware/src/board.rs +++ b/firmware/src/board/mod.rs @@ -1,6 +1,8 @@ use cortex_m; use tm4c129x; +mod gpio; + const LED1: u8 = 0x10; // PK4 const LED2: u8 = 0x40; // PK6 diff --git a/firmware/src/main.rs b/firmware/src/main.rs index d0350a1..39c5b02 100644 --- a/firmware/src/main.rs +++ b/firmware/src/main.rs @@ -10,6 +10,7 @@ extern crate cortex_m_rt; extern crate tm4c129x; extern crate smoltcp; extern crate crc; +extern crate embedded_hal; use core::cell::{Cell, RefCell}; use core::fmt;