diff --git a/itsybitsy_m0_lights/src/lib.rs b/itsybitsy_m0_lights/src/lib.rs index 5fcc919..2888d1f 100644 --- a/itsybitsy_m0_lights/src/lib.rs +++ b/itsybitsy_m0_lights/src/lib.rs @@ -63,43 +63,85 @@ where { #[inline] pub fn write(&mut self, bit: bool) { - // go high - self.high_out.set_high().unwrap(); - - // experimentally, there is some unknown overhead - // but these timings appear to work for me - unsafe { - compiler_fence(Ordering::SeqCst); - asm!( - // 8 nops - "nop;", "nop;", "nop;", "nop;", "nop;", "nop;", "nop;", "nop;", - ); - compiler_fence(Ordering::SeqCst); - } - if bit { unsafe { + compiler_fence(Ordering::SeqCst); + self.high_out.set_high().unwrap(); compiler_fence(Ordering::SeqCst); asm!( - // 14 nops + // 15 nops "nop;", "nop;", "nop;", "nop;", "nop;", "nop;", "nop;", "nop;", "nop;", "nop;", - "nop;", "nop;", "nop;", "nop;", + "nop;", "nop;", "nop;", "nop;", "nop;", + ); + compiler_fence(Ordering::SeqCst); + self.high_out.set_low().unwrap(); + compiler_fence(Ordering::SeqCst); + asm!( + // 8 nops + "nop;", "nop;", "nop;", "nop;", "nop;", "nop;", "nop;", "nop;", + ); + compiler_fence(Ordering::SeqCst); + } + } else { + unsafe { + compiler_fence(Ordering::SeqCst); + self.high_out.set_high().unwrap(); + compiler_fence(Ordering::SeqCst); + asm!( + // 8 nops + "nop;", "nop;", "nop;", "nop;", "nop;", "nop;", "nop;", "nop;", + ); + compiler_fence(Ordering::SeqCst); + self.high_out.set_low().unwrap(); + compiler_fence(Ordering::SeqCst); + asm!( + // 15 nops + "nop;", "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(); + if false { + // go high + self.high_out.set_high().unwrap(); - unsafe { - compiler_fence(Ordering::SeqCst); - asm!( - // 15 nops - "nop;", "nop;", "nop;", "nop;", "nop;", "nop;", "nop;", "nop;", "nop;", "nop;", - "nop;", "nop;", "nop;", "nop;", "nop;", - ); - compiler_fence(Ordering::SeqCst); + // experimentally, there is some unknown overhead + // but these timings appear to work for me + unsafe { + compiler_fence(Ordering::SeqCst); + asm!( + // 8 nops + "nop;", "nop;", "nop;", "nop;", "nop;", "nop;", "nop;", "nop;", + ); + compiler_fence(Ordering::SeqCst); + } + + if bit { + unsafe { + compiler_fence(Ordering::SeqCst); + asm!( + // 14 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(); + + unsafe { + compiler_fence(Ordering::SeqCst); + asm!( + // 15 nops + "nop;", "nop;", "nop;", "nop;", "nop;", "nop;", "nop;", "nop;", "nop;", "nop;", + "nop;", "nop;", "nop;", "nop;", "nop;", + ); + compiler_fence(Ordering::SeqCst); + } } }