diff options
Diffstat (limited to 'src/main.rs')
| -rw-r--r-- | src/main.rs | 104 |
1 files changed, 102 insertions, 2 deletions
diff --git a/src/main.rs b/src/main.rs index 9bea689..cc1623e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,6 +10,70 @@ const SHORT: u16 = 75; const LONG: u16 = SHORT * 3; const SPACE: u16 = SHORT * 7; +struct RingBuf<T: Copy, const N: usize> { + data: [T; N], + read_idx: usize, + write_idx: usize, +} + +impl<T: Copy, const N: usize> RingBuf<T, N> { + pub fn new(initial: T) -> Self { + Self { + data: [initial; N], + read_idx: 0, + write_idx: 0, + } + } + + pub fn peek(&self) -> Option<T> { + if self.write_idx != self.read_idx { + Some(self.data[self.read_idx]) + } else { + None + } + } + + pub fn push(&mut self, value: T) { + if self.write_idx + 1 != self.read_idx { + self.data[self.write_idx] = value; + self.write_idx += 1; + if self.write_idx == N { + self.write_idx = 0; + } + } + } + + pub fn pop(&mut self) -> Option<T> { + if self.write_idx != self.read_idx { + let res = Some(self.data[self.read_idx]); + self.read_idx += 1; + if self.read_idx == N { + self.read_idx = 0; + } + res + } else { + None + } + } +} + +#[derive(Clone, Copy)] +struct LedInstruction { + state: bool, + time: u16, + left: u16, +} + +impl LedInstruction { + pub fn new(state: bool, time: u16) -> Self { + Self { + state, + time, + left: time, + } + } +} + macro_rules! morse { ( $led:expr, $( $delay:expr ),* ) => { { @@ -24,6 +88,36 @@ macro_rules! morse { }; } +macro_rules! push_morse { + ( $buf:expr, $( $delay:expr ),* ) => { + { + $( + $buf.push(LedInstruction::new(true, $delay)); + $buf.push(LedInstruction::new(false, SHORT)); + )* + $buf.push(LedInstruction::new(false, LONG - SHORT)); + } + } +} + +fn push_morse<const N: usize>(buf: &mut RingBuf<LedInstruction, N>, c: u8) { + let c = char::from_u32(c as u32); + if let Some(c) = c { + match c { + 'a' => { + buf.push(LedInstruction::new(true, SHORT)); + buf.push(LedInstruction::new(false, SHORT)); + buf.push(LedInstruction::new(true, LONG)); + buf.push(LedInstruction::new(false, SHORT)); + buf.push(LedInstruction::new(false, LONG - SHORT)); + }, + 'b' => push_morse!(buf, LONG, SHORT, SHORT, SHORT), + + _ => {}, + } + } +} + fn blink_morse(led: &mut PB5<Output>, c: u8) { let c = char::from_u32(c as u32); if let Some(c) = c { @@ -86,9 +180,15 @@ fn main() -> ! { 57600.into_baudrate(), ); + let mut buf: RingBuf<_, 100> = RingBuf::new(LedInstruction::new(false, 0)); + loop { - let b = nb::block!(serial.read()).void_unwrap(); + // let b = nb::block!(serial.read()).void_unwrap(); + match serial.read() { + Ok(b) => push_morse(&mut buf, b), + Err(_) => {}, + } - blink_morse(&mut led, b); + buf.update(millis()); } } |
