Support raw things

This commit is contained in:
Dylan McKay 2017-12-13 22:17:28 +13:00
parent 906b548dfa
commit 468289e05f
3 changed files with 58 additions and 34 deletions

View File

@ -26,13 +26,13 @@ pub trait Pin {
/// Sets the pin up as an input.
#[inline(always)]
fn set_input() {
Self::DDR::unset(Self::MASK);
Self::DDR::unset_raw(Self::MASK);
}
/// Sets the pin up as an output.
#[inline(always)]
fn set_output() {
Self::DDR::set(Self::MASK);
Self::DDR::set_raw(Self::MASK);
}
/// Set the pin to high.
@ -40,7 +40,7 @@ pub trait Pin {
/// The pin must be configured as an output.
#[inline(always)]
fn set_high() {
Self::PORT::set(Self::MASK);
Self::PORT::set_raw(Self::MASK);
}
/// Set the pin to low.
@ -48,7 +48,7 @@ pub trait Pin {
/// The pin must be configured as an output.
#[inline(always)]
fn set_low() {
Self::PORT::unset(Self::MASK);
Self::PORT::unset_raw(Self::MASK);
}
/// Toggles the pin.
@ -59,7 +59,7 @@ pub trait Pin {
// FIXME: We can optimise this on post-2006 AVRs.
// http://www.avrfreaks.net/forum/toggle-state-output-pin
// set(Self::PIN, Self::MASK);
Self::PORT::toggle(Self::MASK);
Self::PORT::toggle_raw(Self::MASK);
}
/// Check if the pin is currently high.
@ -67,7 +67,7 @@ pub trait Pin {
/// The pin must be configured as an input.
#[inline(always)]
fn is_high() -> bool {
Self::PIN::is_set(Self::MASK)
Self::PIN::is_set_raw(Self::MASK)
}
/// Checks if the pin is currently low.
@ -75,7 +75,7 @@ pub trait Pin {
/// The pin must be configured as an input.
#[inline(always)]
fn is_low() -> bool {
Self::PIN::is_clear(Self::MASK)
Self::PIN::is_clear_raw(Self::MASK)
}
}

View File

@ -34,51 +34,71 @@ pub trait Register<T: RegisterValue> : Sized {
unsafe { *Self::ADDR }
}
fn set(mask: Mask<T, Self>) {
Self::set_raw(mask.mask);
}
/// Sets a bitmask in a register.
///
/// This is equivalent to `r |= mask`.
#[inline(always)]
fn set(mask: T) {
fn set_raw(mask: T) {
unsafe {
*Self::ADDR |= mask;
}
}
fn unset(mask: Mask<T, Self>) {
Self::unset_raw(mask.mask);
}
/// Clears a bitmask from a register.
///
/// This is equivalent to `r &= !mask`.
#[inline(always)]
fn unset(mask: T) {
fn unset_raw(mask: T) {
unsafe {
*Self::ADDR &= !mask;
}
}
fn toggle(mask: Mask<T, Self>) {
Self::toggle_raw(mask.mask);
}
/// Toggles a mask in the register.
///
/// This is equivalent to `r ^= mask`.
#[inline(always)]
fn toggle(mask: T) {
fn toggle_raw(mask: T) {
unsafe {
*Self::ADDR ^= mask;
}
}
fn is_set(mask: Mask<T, Self>) -> bool {
Self::is_set_raw(mask.mask)
}
/// Checks if a mask is set in the register.
///
/// This is equivalent to `(r & mask) == mask`.
#[inline(always)]
fn is_set(mask: T) -> bool {
fn is_set_raw(mask: T) -> bool {
unsafe {
(*Self::ADDR & mask) == mask
}
}
fn is_clear(mask: Mask<T, Self>) -> bool {
Self::is_clear_raw(mask.mask)
}
/// Checks if a mask is clear in the register.
///
/// This is equivalent to `(r & mask) == 0`.
#[inline(always)]
fn is_clear(mask: T) -> bool {
fn is_clear_raw(mask: T) -> bool {
unsafe {
(*Self::ADDR & mask) == T::from(0)
}
@ -95,10 +115,14 @@ pub trait Register<T: RegisterValue> : Sized {
}
}
fn wait_until_set(mask: Mask<T, Self>) {
Self::wait_until_set_raw(mask.mask);
}
/// Waits until a mask is set.
#[inline(always)]
fn wait_until_set(mask: T) {
Self::wait_until(|| Self::is_set(mask))
fn wait_until_set_raw(mask: T) {
Self::wait_until(|| Self::is_set_raw(mask))
}
}
@ -127,28 +151,28 @@ impl<T,R> Bitset<T,R>
///
/// This is equivalent to `r |= mask`.
pub fn set_all(self) {
R::set(self.mask);
R::set_raw(self.mask);
}
/// Clears the mask from the register.
///
/// This is equivalent to `r &= !mask`.
pub fn unset_all(self) {
R::unset(self.mask);
R::unset_raw(self.mask);
}
/// Toggles the masked bits in the register.
///
/// This is equivalent to `r ^= mask`.
pub fn toggle_all(self) {
R::toggle(self.mask);
R::toggle_raw(self.mask);
}
/// Checks if the mask is clear.
///
/// This is equivalent to `(r & mask) == 0`.
pub fn is_clear(self) -> bool {
R::is_clear(self.mask)
R::is_clear_raw(self.mask)
}
}

View File

@ -53,87 +53,87 @@ pub trait HardwareSpi {
/// Sets the clock speed.
fn set_clock(clock: u32) {
let mask = clock::ClockMask::with_clock(clock);
Self::ControlRegister::set(mask.control_register_mask());
Self::StatusRegister::set(mask.status_register_mask());
Self::ControlRegister::set_raw(mask.control_register_mask());
Self::StatusRegister::set_raw(mask.status_register_mask());
}
/// Enables interrupts for the spi module.
#[inline(always)]
fn enable_interrupt() {
Self::ControlRegister::set(control_register::INTERRUPT_ENABLE);
Self::ControlRegister::set_raw(control_register::INTERRUPT_ENABLE);
}
/// Disables interrupts for the spi module.
#[inline(always)]
fn disable_interrupt() {
Self::ControlRegister::unset(control_register::INTERRUPT_ENABLE);
Self::ControlRegister::unset_raw(control_register::INTERRUPT_ENABLE);
}
/// Enables the SPI.
#[inline(always)]
fn enable() {
Self::ControlRegister::set(control_register::ENABLE);
Self::ControlRegister::set_raw(control_register::ENABLE);
}
/// Disables the SPI.
#[inline(always)]
fn disable() {
Self::ControlRegister::unset(control_register::ENABLE);
Self::ControlRegister::unset_raw(control_register::ENABLE);
}
/// Enables least-significant-bit first.
#[inline(always)]
fn set_lsb() {
Self::ControlRegister::set(control_register::DATA_ORDER_LSB);
Self::ControlRegister::set_raw(control_register::DATA_ORDER_LSB);
}
/// Enables most-significant-bit first.
#[inline(always)]
fn set_msb() {
Self::ControlRegister::unset(control_register::DATA_ORDER_LSB);
Self::ControlRegister::unset_raw(control_register::DATA_ORDER_LSB);
}
/// Enables master mode.
#[inline(always)]
fn set_master() {
Self::ControlRegister::set(control_register::MASTER);
Self::ControlRegister::set_raw(control_register::MASTER);
}
/// Enables slave mode.
#[inline(always)]
fn set_slave() {
Self::ControlRegister::unset(control_register::MASTER);
Self::ControlRegister::unset_raw(control_register::MASTER);
}
/// Enables double speed mode.
#[inline(always)]
fn enable_double_speed() {
Self::StatusRegister::set(status_register::SPI2X);
Self::StatusRegister::set_raw(status_register::SPI2X);
}
/// Disables double speed mode.
#[inline(always)]
fn disable_double_speed() {
Self::StatusRegister::unset(status_register::SPI2X);
Self::StatusRegister::unset_raw(status_register::SPI2X);
}
/// Checks if there is a write collision.
#[inline(always)]
fn is_write_collision() -> bool {
Self::StatusRegister::is_set(status_register::WCOL)
Self::StatusRegister::is_set_raw(status_register::WCOL)
}
/// Sends a byte through the serial.
#[inline(always)]
fn send_byte(byte: u8) {
Self::DataRegister::write(byte);
Self::StatusRegister::wait_until_set(status_register::SPIF);
Self::StatusRegister::wait_until_set_raw(status_register::SPIF);
}
/// Reads a byte from the serial.
#[inline(always)]
fn receive_byte() -> u8 {
Self::StatusRegister::wait_until_set(status_register::SPIF);
Self::StatusRegister::wait_until_set_raw(status_register::SPIF);
Self::DataRegister::read()
}
@ -141,7 +141,7 @@ pub trait HardwareSpi {
#[inline(always)]
fn send_receive(byte: u8) -> u8 {
Self::DataRegister::write(byte);
Self::StatusRegister::wait_until_set(status_register::SPIF);
Self::StatusRegister::wait_until_set_raw(status_register::SPIF);
Self::DataRegister::read()
}
}