Revert "Expose some structs for the IO ports"
This reverts commit 99ad3f0ab1
.
This commit is contained in:
parent
4948dd412e
commit
a831e48755
|
@ -1,5 +0,0 @@
|
|||
pub mod port;
|
||||
|
||||
pub const PORT_B: port::Port<port::B> = port::Port::new();
|
||||
pub const PORT_C: port::Port<port::C> = port::Port::new();
|
||||
pub const PORT_D: port::Port<port::D> = port::Port::new();
|
183
src/io/port.rs
183
src/io/port.rs
|
@ -1,183 +0,0 @@
|
|||
use core::prelude::v1::*;
|
||||
use core::ptr::{read_volatile, write_volatile};
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use Bit;
|
||||
|
||||
pub trait Information {
|
||||
const DDR: *mut u8;
|
||||
const IO: *mut u8;
|
||||
const PIN: *mut u8;
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct B;
|
||||
|
||||
impl Information for B {
|
||||
const DDR: *mut u8 = ::DDRB;
|
||||
const IO: *mut u8 = ::PORTB;
|
||||
const PIN: *mut u8 = ::PINB;
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct C;
|
||||
|
||||
impl Information for C {
|
||||
const DDR: *mut u8 = ::DDRC;
|
||||
const IO: *mut u8 = ::PORTC;
|
||||
const PIN: *mut u8 = ::PINC;
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct D;
|
||||
|
||||
impl Information for D {
|
||||
const DDR: *mut u8 = ::DDRD;
|
||||
const IO: *mut u8 = ::PORTD;
|
||||
const PIN: *mut u8 = ::PIND;
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
enum Direction {
|
||||
Output,
|
||||
Input,
|
||||
}
|
||||
|
||||
const BITS_IN_BYTE: usize = 8;
|
||||
|
||||
pub struct Configuration<P: Information> {
|
||||
_port: PhantomData<P>,
|
||||
direction: [Option<Direction>; BITS_IN_BYTE],
|
||||
pullup: [Option<bool>; BITS_IN_BYTE],
|
||||
}
|
||||
|
||||
impl<P> Configuration<P>
|
||||
where
|
||||
P: Information
|
||||
{
|
||||
#[inline]
|
||||
pub fn new() -> Configuration<P> {
|
||||
Configuration {
|
||||
_port: PhantomData,
|
||||
direction: Default::default(),
|
||||
pullup: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_all_as_output(&mut self) -> &mut Self {
|
||||
self.direction = [Some(Direction::Output); 8];
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_all_as_input(&mut self) -> &mut Self {
|
||||
self.direction = [Some(Direction::Input); 8];
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_as_output(&mut self, bit: Bit) -> &mut Self {
|
||||
self.direction[bit as usize] = Some(Direction::Output);
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_as_input(&mut self, bit: Bit) -> &mut Self {
|
||||
self.direction[bit as usize] = Some(Direction::Input);
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn enable_pullup(&mut self, bit: Bit) -> &mut Self {
|
||||
self.pullup[bit as usize] = Some(true);
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn disable_pullup(&mut self, bit: Bit) -> &mut Self {
|
||||
self.pullup[bit as usize] = Some(false);
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn configure(&self) {
|
||||
// FIXME: Both of these loops are wasteful if we are
|
||||
// setting all 8 bits, when we could set the entire IO
|
||||
// register at once. Is there a way we can track that?
|
||||
|
||||
// We use `zip` instead of `enumerate` to guarantee it's a constant
|
||||
|
||||
for (&p, i) in self.direction.iter().zip(0..BITS_IN_BYTE) {
|
||||
if let Some(enabled) = p {
|
||||
if let Direction::Output = enabled {
|
||||
unsafe { asm!("sbi $0 $1" : : "n"(P::DDR), "n"(i)) }
|
||||
} else {
|
||||
unsafe { asm!("cbi $0 $1; A" : : "n"(P::DDR), "n"(i)) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (&p, i) in self.pullup.iter().zip(0..BITS_IN_BYTE) {
|
||||
if let Some(enabled) = p {
|
||||
if enabled {
|
||||
unsafe { asm!("sbi $0 $1" : : "n"(P::IO), "n"(i)) }
|
||||
} else {
|
||||
unsafe { asm!("cbi $0 $1; B" : : "n"(P::IO), "n"(i)) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Data<P: Information> {
|
||||
_port: PhantomData<P>,
|
||||
}
|
||||
|
||||
impl<P> Data<P>
|
||||
where
|
||||
P: Information
|
||||
{
|
||||
#[inline]
|
||||
pub fn new() -> Data<P> { Data { _port: PhantomData } }
|
||||
|
||||
#[inline]
|
||||
pub fn get(&self) -> u8 {
|
||||
unsafe { read_volatile(P::PIN) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set(&self, value: u8) {
|
||||
unsafe { write_volatile(P::IO, value) };
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn bit_is_set(&self, bit: Bit) -> bool {
|
||||
bit.is_set(self.get())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_bit(&self, bit: Bit) {
|
||||
unsafe { asm!("sbi $0 $1" : : "n"(P::IO), "n"(bit as u8)) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn clear_bit(&self, bit: Bit) {
|
||||
unsafe { asm!("cbi $0 $1; C" : : "n"(P::IO), "n"(bit as u8)) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn toggle_bit(&self, bit: Bit) {
|
||||
unsafe { asm!("sbi $0 $1" : : "n"(P::PIN), "n"(bit as u8)) }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Port<P>(PhantomData<P>);
|
||||
|
||||
impl<P: Information> Port<P> {
|
||||
pub(crate) const fn new() -> Port<P> { Port(PhantomData) }
|
||||
pub fn configuration(&self) -> Configuration<P> { Configuration::new() }
|
||||
pub fn data(&self) -> Data<P> { Data::new() }
|
||||
}
|
33
src/lib.rs
33
src/lib.rs
|
@ -8,43 +8,10 @@
|
|||
|
||||
extern crate core;
|
||||
|
||||
// Look like we have a standard library
|
||||
#[allow(unused_imports)]
|
||||
use core::{option, iter, fmt, ops, clone, marker};
|
||||
|
||||
pub mod prelude;
|
||||
pub mod timer0;
|
||||
pub mod timer1;
|
||||
pub mod serial;
|
||||
pub mod io;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum Bit {
|
||||
Bit0 = 0,
|
||||
Bit1 = 1,
|
||||
Bit2 = 2,
|
||||
Bit3 = 3,
|
||||
Bit4 = 4,
|
||||
Bit5 = 5,
|
||||
Bit6 = 6,
|
||||
Bit7 = 7,
|
||||
}
|
||||
|
||||
impl Bit {
|
||||
fn as_mask(&self) -> u8 { 1 << *self as u8 }
|
||||
|
||||
pub fn is_set(&self, value: u8) -> bool {
|
||||
(value & self.as_mask()) != 0
|
||||
}
|
||||
|
||||
pub fn set(&self, value: u8) -> u8 {
|
||||
value | self.as_mask()
|
||||
}
|
||||
|
||||
pub fn unset(&self, value: u8) -> u8 {
|
||||
value & !self.as_mask()
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! bit {
|
||||
(-, $pos:expr) => {};
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
use core::prelude::v1::*;
|
||||
use core::marker::PhantomData;
|
||||
|
||||
pub use io::{PORT_B, PORT_C, PORT_D};
|
||||
|
||||
pub struct DisableInterrupts(PhantomData<()>);
|
||||
|
||||
impl DisableInterrupts {
|
||||
|
|
Loading…
Reference in New Issue