add gpio abstraction

pull/1/head
Astro 2019-07-30 18:25:35 +02:00
parent e4478c3efd
commit 5f3d674e24
5 changed files with 100 additions and 0 deletions

23
firmware/Cargo.lock generated
View File

@ -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"

View File

@ -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"

View File

@ -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<Self>;
fn into_input(self) -> GpioInput<Self>;
}
pub struct GpioInput<PIN>(PIN);
pub struct GpioOutput<PIN>(PIN);
macro_rules! def_gpio {
($PORT: tt, $PIN: tt, $idx: expr) => (
impl Gpio for $PIN {
fn into_output(self) -> GpioOutput<Self> {
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<Self> {
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<bool, Self::Error> {
let gpio = unsafe { &*tm4c129x::$PORT::ptr() };
Ok(gpio.data.read().data().bits() & (1 << $idx) == (1 << $idx))
}
fn is_low(&self) -> Result<bool, Self::Error> {
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)]
}

View File

@ -1,6 +1,8 @@
use cortex_m;
use tm4c129x;
mod gpio;
const LED1: u8 = 0x10; // PK4
const LED2: u8 = 0x40; // PK6

View File

@ -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;