use core::slice::IterMut; use hal::gpio::{OutputPin}; use hal::peripheral::Peripheral; use hal::pulse_control::{OutputChannel, ConfiguredChannel, PulseCode, RepeatMode, TransmissionError, ClockSource}; use smart_leds::{RGB8, SmartLedsWrite}; use fugit::{Duration, NanosDuration}; pub struct Strip { channel: CHANNEL, timing: StripTiming } pub struct StripTiming { one_high_duration: Duration::, one_low_duration: Duration::, zero_high_duration: Duration::, zero_low_duration: Duration::, } impl StripTiming { pub fn new(one_high_duration: Duration::, one_low_duration: Duration::, zero_high_duration: Duration::, zero_low_duration: Duration::) -> Self { StripTiming { one_high_duration, one_low_duration, zero_high_duration, zero_low_duration, } } } impl<'d, CHANNEL, const COUNT: usize> Strip where CHANNEL: ConfiguredChannel { pub fn new(mut channel: UnconfiguredChannel, pin: impl Peripheral + 'd, timing: StripTiming) -> Self where UnconfiguredChannel: OutputChannel = CHANNEL> { channel .set_channel_divider(4) // 1 tick = 50 ns = 0.05 us .set_carrier_modulation(false) .set_idle_output(true) .set_idle_output_level(false) .set_clock_source(ClockSource::APB); let channel = channel.assign_pin(pin); Strip:: { channel, timing } } fn byte_to_pulse_code(&self, byte: u8, data: &mut IterMut) -> () { for i in 0..8u8 { let bit = if (byte & (1 << (7 - i))) > 0 { true } else { false }; *data.next().unwrap() = self.bit_to_pulse_code(bit); } } fn bit_to_pulse_code(&self, bit: bool) -> u32 { let length1 = if bit { self.timing.one_high_duration } else { self.timing.zero_high_duration }; let length2 = if bit { self.timing.one_low_duration } else { self.timing.zero_low_duration }; let length1 = NanosDuration::::from_ticks(length1.ticks() / 50); let length2 = NanosDuration::::from_ticks(length2.ticks() / 50); PulseCode { level1: true, length1, level2: false, length2, }.into() } } impl SmartLedsWrite for Strip where CHANNEL: ConfiguredChannel { type Error = TransmissionError; type Color = RGB8; fn write(&mut self, iterator: T) -> Result<(), Self::Error> where T: Iterator, I: Into { let mut buffer: [u32; COUNT] = [0; COUNT]; let mut iter_mut = buffer.iter_mut(); for item in iterator { let rgb = item.into(); self.byte_to_pulse_code(rgb.g, &mut iter_mut); self.byte_to_pulse_code(rgb.r, &mut iter_mut); self.byte_to_pulse_code(rgb.b, &mut iter_mut); } *iter_mut.next().unwrap() = 0; self.channel.send_pulse_sequence_raw(RepeatMode::SingleShot, &buffer) } }