#![no_std]
use embedded_hal::{blocking::delay::DelayMs, digital::v2::OutputPin};
#[derive(Debug, Clone, Copy)]
struct MorseChar {
length: u8,
pattern: u8,
}
const CHARS: [MorseChar; 26] = [
MorseChar {
length: 2,
pattern: 0b10,
},
MorseChar {
length: 4,
pattern: 0b0001,
},
MorseChar {
length: 4,
pattern: 0b0101,
},
MorseChar {
length: 3,
pattern: 0b001,
},
MorseChar {
length: 1,
pattern: 0b0,
},
MorseChar {
length: 4,
pattern: 0b0100,
},
MorseChar {
length: 3,
pattern: 0b011,
},
MorseChar {
length: 4,
pattern: 0b0000,
},
MorseChar {
length: 2,
pattern: 0b00,
},
MorseChar {
length: 4,
pattern: 0b1110,
},
MorseChar {
length: 3,
pattern: 0b101,
},
MorseChar {
length: 4,
pattern: 0b0010,
},
MorseChar {
length: 2,
pattern: 0b11,
},
MorseChar {
length: 2,
pattern: 0b01,
},
MorseChar {
length: 3,
pattern: 0b111,
},
MorseChar {
length: 4,
pattern: 0b0110,
},
MorseChar {
length: 4,
pattern: 0b1011,
},
MorseChar {
length: 3,
pattern: 0b010,
},
MorseChar {
length: 3,
pattern: 0b111,
},
MorseChar {
length: 1,
pattern: 0b1,
},
MorseChar {
length: 3,
pattern: 0b100,
},
MorseChar {
length: 4,
pattern: 0b1000,
},
MorseChar {
length: 3,
pattern: 0b110,
},
MorseChar {
length: 4,
pattern: 0b1001,
},
MorseChar {
length: 4,
pattern: 0b1101,
},
MorseChar {
length: 4,
pattern: 0b0011,
},
];
pub struct Morse<DELAY, PIN> {
dot_length: u16,
dash_length: u16,
space_length: u16,
delay: DELAY,
pin: PIN,
invert: bool,
}
impl<ERR, DELAY: DelayMs<u16>, PIN: OutputPin<Error = ERR>> Morse<DELAY, PIN> {
pub fn new(delay: DELAY, pin: PIN, invert: bool, dot_length: u16) -> Self {
Self {
dot_length,
dash_length: dot_length * 3,
space_length: dot_length * 3,
delay,
pin,
invert,
}
}
pub fn new_default(delay: DELAY, pin: PIN, invert: bool) -> Self {
Self::new(delay, pin, invert, 300)
}
pub fn output_str(&mut self, output: &str) -> Result<(), ERR> {
for c in output.chars() {
let c = c.to_ascii_uppercase();
if c.is_ascii_uppercase() {
let morse_char = CHARS[c as usize - 0x41];
let mut pattern = morse_char.pattern;
for _ in 0..morse_char.length {
if self.invert {
self.pin.set_low()?;
} else {
self.pin.set_high()?;
}
self.delay.delay_ms(if pattern & 0b1 == 1 {
self.dash_length
} else {
self.dot_length
});
if self.invert {
self.pin.set_high()?;
} else {
self.pin.set_low()?;
}
pattern = pattern >> 1;
self.delay.delay_ms(self.dot_length);
}
self.delay.delay_ms(self.space_length);
} else if c == ' ' {
self.delay.delay_ms(self.dot_length * 7);
}
}
Ok(())
}
}