#![no_std] extern crate cortex_m; extern crate embedded_hal; extern crate gemma_m0 as hal; extern crate panic_halt; pub use cortex_m::asm::delay; pub use hal::entry; use core::u8; use embedded_hal::digital::OutputPin; use hal::{ clock::GenericClockController, Peripherals }; use lights::{ HardwareRgb, Lights }; pub fn boot() -> impl Lights { let mut peripherals = Peripherals::take().unwrap(); let _clock = GenericClockController::with_internal_32kosc( peripherals.GCLK, &mut peripherals.PM, &mut peripherals.SYSCTRL, &mut peripherals.NVMCTRL ); let mut pins = hal::Pins::new(peripherals.PORT); NeopixelLights { out: pins.d1.into_push_pull_output(&mut pins.port) } } // approx. 20ns per clock cycle; const ZERO_HIGH_CYCLES: u32 = 11; // smidge above 200ns const ONE_HIGH_CYCLES: u32 = 35; // about 700ns const DATA_LOW_CYCLES: u32 = 25; // about 500ns const LATCH_CYCLES: u32 = 300; // about 6000ns //const FRAME_DELAY_CYCLES: u32 = 1_000_000; // about 20ms, but doesn't count the time for the other operations pub struct NeopixelLights { out: T } impl NeopixelLights { #[inline] fn write(&mut self, bit: bool) { self.out.set_high(); delay(if bit { ONE_HIGH_CYCLES } else { ZERO_HIGH_CYCLES }); self.out.set_low(); delay(DATA_LOW_CYCLES); } #[inline] fn byte(&mut self, byte: u8) { self.write(byte & 0x80 != 0); self.write(byte & 0x40 != 0); self.write(byte & 0x20 != 0); self.write(byte & 0x10 != 0); self.write(byte & 0x08 != 0); self.write(byte & 0x04 != 0); self.write(byte & 0x02 != 0); self.write(byte & 0x01 != 0); } } impl Lights for NeopixelLights { type Pixel = HardwareRgb; #[inline] fn render(&mut self, rgb: &HardwareRgb) { // GRB pixel order self.byte(rgb.1); self.byte(rgb.0); self.byte(rgb.2); } fn latch(&mut self) { delay(LATCH_CYCLES); } }