diff --git a/itsybitsy_m0_lights/src/lib.rs b/itsybitsy_m0_lights/src/lib.rs index aba4915..e8ffef8 100644 --- a/itsybitsy_m0_lights/src/lib.rs +++ b/itsybitsy_m0_lights/src/lib.rs @@ -1,4 +1,5 @@ #![no_std] +#![feature(asm)] extern crate cortex_m; extern crate embedded_hal; @@ -9,6 +10,7 @@ pub use cortex_m::asm::delay; pub use hal::entry; use core::fmt::Debug; +use core::sync::atomic::{compiler_fence, Ordering}; use core::u8; pub use embedded_hal::digital::v2::OutputPin; use hal::{clock::GenericClockController, pac::Peripherals}; @@ -67,14 +69,42 @@ where { #[inline] pub fn write(&mut self, bit: bool) { + // go high self.high_out.set_high().unwrap(); - delay(if bit { - ONE_HIGH_CYCLES - } else { - ZERO_HIGH_CYCLES - }); + + unsafe { + compiler_fence(Ordering::SeqCst); + asm!( + // ? nops + "nop;", "nop;", "nop;", "nop;", "nop;", "nop;", "nop;", "nop;", "nop;", + ); + compiler_fence(Ordering::SeqCst); + } + + if bit { + unsafe { + compiler_fence(Ordering::SeqCst); + asm!( + // 7 nops + "nop;", "nop;", "nop;", "nop;", "nop;", "nop;", "nop;", "nop;", "nop;", "nop;", + "nop;", "nop;", "nop;", "nop;", + ); + compiler_fence(Ordering::SeqCst); + } + } + + // go low self.high_out.set_low().unwrap(); - delay(if bit { ONE_LOW_CYCLES } else { ZERO_LOW_CYCLES }); + + unsafe { + compiler_fence(Ordering::SeqCst); + asm!( + // 2 nops + "nop;", "nop;", "nop;", "nop;", "nop;", "nop;", "nop;", "nop;", "nop;", "nop;", + "nop;", "nop;", "nop;", "nop;", "nop;", + ); + compiler_fence(Ordering::SeqCst); + } } #[inline] @@ -87,7 +117,14 @@ where self.write(byte & 0x04 != 0); self.write(byte & 0x02 != 0); self.write(byte & 0x01 != 0); - delay(5); + unsafe { + compiler_fence(Ordering::SeqCst); + asm!( + // 5 nops + "nop;", "nop;", "nop;", "nop;", "nop;", + ); + compiler_fence(Ordering::SeqCst); + } } /// Blink light, probably to indicate a loop is still running