#![no_std]
extern crate embedded_hal;
use embedded_hal::blocking::delay::DelayMs;
use embedded_hal::blocking::delay::DelayUs;
use embedded_hal::digital::OutputPin;
pub trait DataBus {
fn write<D: DelayUs<u16> + DelayMs<u8>>(&mut self, byte: u8, data: bool, delay: &mut D);
}
pub struct EightBitBus<
RS: OutputPin,
EN: OutputPin,
D0: OutputPin,
D1: OutputPin,
D2: OutputPin,
D3: OutputPin,
D4: OutputPin,
D5: OutputPin,
D6: OutputPin,
D7: OutputPin,
> {
rs: RS,
en: EN,
d0: D0,
d1: D1,
d2: D2,
d3: D3,
d4: D4,
d5: D5,
d6: D6,
d7: D7,
}
impl<
RS: OutputPin,
EN: OutputPin,
D0: OutputPin,
D1: OutputPin,
D2: OutputPin,
D3: OutputPin,
D4: OutputPin,
D5: OutputPin,
D6: OutputPin,
D7: OutputPin,
> EightBitBus<RS, EN, D0, D1, D2, D3, D4, D5, D6, D7>
{
fn set_bus_bits(&mut self, data: u8) {
let db0: bool = (0b0000_0001 & data) != 0;
let db1: bool = (0b0000_0010 & data) != 0;
let db2: bool = (0b0000_0100 & data) != 0;
let db3: bool = (0b0000_1000 & data) != 0;
let db4: bool = (0b0001_0000 & data) != 0;
let db5: bool = (0b0010_0000 & data) != 0;
let db6: bool = (0b0100_0000 & data) != 0;
let db7: bool = (0b1000_0000 & data) != 0;
if db0 {
self.d0.set_high();
} else {
self.d0.set_low();
}
if db1 {
self.d1.set_high();
} else {
self.d1.set_low();
}
if db2 {
self.d2.set_high();
} else {
self.d2.set_low();
}
if db3 {
self.d3.set_high();
} else {
self.d3.set_low();
}
if db4 {
self.d4.set_high();
} else {
self.d4.set_low();
}
if db5 {
self.d5.set_high();
} else {
self.d5.set_low();
}
if db6 {
self.d6.set_high();
} else {
self.d6.set_low();
}
if db7 {
self.d7.set_high();
} else {
self.d7.set_low();
}
}
}
impl<
RS: OutputPin,
EN: OutputPin,
D0: OutputPin,
D1: OutputPin,
D2: OutputPin,
D3: OutputPin,
D4: OutputPin,
D5: OutputPin,
D6: OutputPin,
D7: OutputPin,
> DataBus for EightBitBus<RS, EN, D0, D1, D2, D3, D4, D5, D6, D7>
{
fn write<D: DelayUs<u16> + DelayMs<u8>>(&mut self, byte: u8, data: bool, delay: &mut D) {
if data {
self.rs.set_high();
} else {
self.rs.set_low();
}
self.set_bus_bits(byte);
self.en.set_high();
delay.delay_ms(2u8);
self.en.set_low();
if data {
self.rs.set_low();
}
}
}
pub struct FourBitBus<
RS: OutputPin,
EN: OutputPin,
D4: OutputPin,
D5: OutputPin,
D6: OutputPin,
D7: OutputPin,
> {
rs: RS,
en: EN,
d4: D4,
d5: D5,
d6: D6,
d7: D7,
}
impl<RS: OutputPin, EN: OutputPin, D4: OutputPin, D5: OutputPin, D6: OutputPin, D7: OutputPin>
FourBitBus<RS, EN, D4, D5, D6, D7>
{
fn write_lower_nibble(&mut self, data: u8) {
let db0: bool = (0b0000_0001 & data) != 0;
let db1: bool = (0b0000_0010 & data) != 0;
let db2: bool = (0b0000_0100 & data) != 0;
let db3: bool = (0b0000_1000 & data) != 0;
if db0 {
self.d4.set_high();
} else {
self.d4.set_low();
}
if db1 {
self.d5.set_high();
} else {
self.d5.set_low();
}
if db2 {
self.d6.set_high();
} else {
self.d6.set_low();
}
if db3 {
self.d7.set_high();
} else {
self.d7.set_low();
}
}
fn write_upper_nibble(&mut self, data: u8) {
let db4: bool = (0b0001_0000 & data) != 0;
let db5: bool = (0b0010_0000 & data) != 0;
let db6: bool = (0b0100_0000 & data) != 0;
let db7: bool = (0b1000_0000 & data) != 0;
if db4 {
self.d4.set_high();
} else {
self.d4.set_low();
}
if db5 {
self.d5.set_high();
} else {
self.d5.set_low();
}
if db6 {
self.d6.set_high();
} else {
self.d6.set_low();
}
if db7 {
self.d7.set_high();
} else {
self.d7.set_low();
}
}
}
impl<RS: OutputPin, EN: OutputPin, D4: OutputPin, D5: OutputPin, D6: OutputPin, D7: OutputPin>
DataBus for FourBitBus<RS, EN, D4, D5, D6, D7>
{
fn write<D: DelayUs<u16> + DelayMs<u8>>(&mut self, byte: u8, data: bool, delay: &mut D) {
if data {
self.rs.set_high();
} else {
self.rs.set_low();
}
self.write_upper_nibble(byte);
self.en.set_high();
delay.delay_ms(2u8);
self.en.set_low();
self.write_lower_nibble(byte);
self.en.set_high();
delay.delay_ms(2u8);
self.en.set_low();
if data {
self.rs.set_low();
}
}
}
pub struct HD44780<D: DelayUs<u16> + DelayMs<u8>, B: DataBus> {
bus: B,
delay: D,
}
pub enum Direction {
Left,
Right,
}
impl<
D: DelayUs<u16> + DelayMs<u8>,
RS: OutputPin,
EN: OutputPin,
D0: OutputPin,
D1: OutputPin,
D2: OutputPin,
D3: OutputPin,
D4: OutputPin,
D5: OutputPin,
D6: OutputPin,
D7: OutputPin,
> HD44780<D, EightBitBus<RS, EN, D0, D1, D2, D3, D4, D5, D6, D7>>
{
pub fn new_8bit(
rs: RS,
en: EN,
d0: D0,
d1: D1,
d2: D2,
d3: D3,
d4: D4,
d5: D5,
d6: D6,
d7: D7,
delay: D,
) -> HD44780<D, EightBitBus<RS, EN, D0, D1, D2, D3, D4, D5, D6, D7>> {
let mut hd = HD44780 {
bus: EightBitBus {
rs,
en,
d0,
d1,
d2,
d3,
d4,
d5,
d6,
d7,
},
delay,
};
hd.init_8bit();
return hd;
}
}
impl<
D: DelayUs<u16> + DelayMs<u8>,
RS: OutputPin,
EN: OutputPin,
D4: OutputPin,
D5: OutputPin,
D6: OutputPin,
D7: OutputPin,
> HD44780<D, FourBitBus<RS, EN, D4, D5, D6, D7>>
{
pub fn new_4bit(
rs: RS,
en: EN,
d4: D4,
d5: D5,
d6: D6,
d7: D7,
delay: D,
) -> HD44780<D, FourBitBus<RS, EN, D4, D5, D6, D7>> {
let mut hd = HD44780 {
bus: FourBitBus {
rs,
en,
d4,
d5,
d6,
d7,
},
delay,
};
hd.init_4bit();
return hd;
}
}
impl<D, B> HD44780<D, B>
where
D: DelayUs<u16> + DelayMs<u8>,
B: DataBus,
{
pub fn reset(&mut self) {
self.bus.write(0b0000_0010, false, &mut self.delay);
self.delay.delay_us(150);
}
pub fn set_display_mode(&mut self, display_on: bool, cursor_visible: bool, cursor_blink: bool) {
let display_bit = {
if display_on {
0b0000_0100
} else {
0b0000_0000
}
};
let cursor_visible_bit = {
if cursor_visible {
0b0000_0010
} else {
0b0000_0000
}
};
let cursor_blink_bit = {
if cursor_blink {
0b0000_0001
} else {
0b0000_0000
}
};
let cmd_byte = 0b0000_1000 | display_bit | cursor_visible_bit | cursor_blink_bit;
self.bus.write(cmd_byte, false, &mut self.delay);
self.delay.delay_us(150);
}
pub fn clear(&mut self) {
self.bus.write(0b0000_0001, false, &mut self.delay);
self.delay.delay_ms(15u8);
}
pub fn set_cursor_pos(&mut self, position: u8) {
let lower_7_bits = 0b0111_1111 & position;
self.bus
.write(0b1000_0000 | lower_7_bits, false, &mut self.delay);
self.delay.delay_us(150);
}
pub fn shift_cursor(&mut self, dir: Direction) {
let bits = match dir {
Direction::Left => 0b0000_0000,
Direction::Right => 0b0000_0100,
};
self.bus.write(0b0001_0000 | bits, false, &mut self.delay);
self.delay.delay_us(150);
}
pub fn shift_display(&mut self, dir: Direction) {
let bits = match dir {
Direction::Left => 0b0000_0000,
Direction::Right => 0b0000_0100,
};
self.bus.write(0b0001_1000 | bits, false, &mut self.delay);
self.delay.delay_us(150);
}
fn init_4bit(&mut self) {
self.delay.delay_ms(15u8);
self.bus.write(0x33, false, &mut self.delay);
self.delay.delay_ms(5u8);
self.bus.write(0x32, false, &mut self.delay);
self.delay.delay_us(100);
self.bus.write(0x28, false, &mut self.delay);
self.delay.delay_us(100);
self.bus.write(0x0E, false, &mut self.delay);
self.delay.delay_us(100);
self.bus.write(0x01, false, &mut self.delay);
self.delay.delay_us(100);
self.bus.write(0x06, false, &mut self.delay);
self.delay.delay_us(100);
self.bus.write(0x80, false, &mut self.delay);
self.delay.delay_us(100);
}
fn init_8bit(&mut self) {
self.delay.delay_ms(15u8);
self.bus.write(0b0011_0000, false, &mut self.delay);
self.delay.delay_ms(5u8);
self.bus.write(0b0011_1000, false, &mut self.delay);
self.delay.delay_us(100);
self.bus.write(0b0000_1110, false, &mut self.delay);
self.delay.delay_us(100);
self.bus.write(0b0000_0001, false, &mut self.delay);
self.delay.delay_us(100);
self.bus.write(0b000_0111, false, &mut self.delay);
self.delay.delay_us(100);
self.bus.write(0b000_0110, false, &mut self.delay);
self.delay.delay_us(100);
}
pub fn write_str(&mut self, string: &str) {
for c in string.chars() {
self.write_char(c);
}
}
pub fn write_char(&mut self, data: char) {
self.bus.write(data as u8, true, &mut self.delay);
self.delay.delay_us(100);
}
}