#![allow(unused_mut)]
#![allow(unused)]
pub struct LCD {
rs: PinD,
rw: PinD,
db4: PinB,
db5: PinB,
db6: PinB,
db7: PinB,
enable: PinD,
timer0: Timer0,
lcd_portb: PortB,
lcd_portd: PortD,
cursor_idx: u8,
_priv: (),
}
use crate::timers::*;
use crate::gpio::*;
static mut LCD_TAKING: bool = false;
impl LCD {
pub fn take() -> Option<Self> {
unsafe {
if LCD_TAKING {
None
} else {
LCD_TAKING = true;
let timer0 = Timer0::take().unwrap();
let lcd_portb = PortB::take().unwrap();
let lcd_portd = PortD::take().unwrap();
let rs = lcd_portd.set_output(PinD::PD5);
let rw = lcd_portd.set_output(PinD::PD6);
let db4 = lcd_portb.set_output(PinB::PB0);
let db5 = lcd_portb.set_output(PinB::PB1);
let db6 = lcd_portb.set_output(PinB::PB2);
let db7 = lcd_portb.set_output(PinB::PB3);
let enable = lcd_portd.set_output(PinD::PD7);
let mut cursor_index = 0 as u32;
Some(LCD {
lcd_portb,
lcd_portd,
rs,
rw,
db4,
db5,
db6,
db7,
enable,
timer0,
cursor_idx: cursor_index as u8,
_priv: (),
})
}
}
}
pub fn init(&self) {
self.timer0.start();
self.timer0.delay_ms(15);
self.lcd_portd.set_low(self.rs);
self.lcd_portd.set_low(self.rw);
self.lcd_portb.set_high(self.db4);
self.lcd_portb.set_high(self.db5);
self.lcd_portb.set_low(self.db6);
self.lcd_portb.set_low(self.db7);
self.lcd_portd.set_high(self.enable);
self.timer0.delay_ms(1);
self.lcd_portd.set_low(self.enable);
self.timer0.delay_ms(5);
self.lcd_portb.set_high(self.db4);
self.lcd_portb.set_high(self.db5);
self.lcd_portb.set_low(self.db6);
self.lcd_portb.set_low(self.db7);
self.lcd_portd.set_high(self.enable);
self.timer0.delay_ms(1);
self.lcd_portd.set_low(self.enable);
self.timer0.delay_ms(1);
self.lcd_portb.set_high(self.db4);
self.lcd_portb.set_high(self.db5);
self.lcd_portb.set_low(self.db6);
self.lcd_portb.set_low(self.db7);
self.lcd_portd.set_high(self.enable);
self.timer0.delay_ms(1);
self.lcd_portd.set_low(self.enable);
self.timer0.delay_ms(1);
self.lcd_portb.set_low(self.db4);
self.lcd_portb.set_high(self.db5);
self.lcd_portb.set_low(self.db6);
self.lcd_portb.set_low(self.db7);
self.lcd_portd.set_high(self.enable);
self.timer0.delay_ms(1);
self.lcd_portd.set_low(self.enable);
self.timer0.delay_ms(1);
self.lcd_portb.set_low(self.db4);
self.lcd_portb.set_high(self.db5);
self.lcd_portb.set_low(self.db6);
self.lcd_portb.set_low(self.db7);
self.lcd_portd.set_high(self.enable);
self.timer0.delay_ms(1);
self.lcd_portd.set_low(self.enable);
self.lcd_portb.set_low(self.db4);
self.lcd_portb.set_low(self.db5);
self.lcd_portb.set_low(self.db6);
self.lcd_portb.set_high(self.db7);
self.lcd_portd.set_high(self.enable);
self.timer0.delay_ms(1);
self.lcd_portd.set_low(self.enable);
self.timer0.delay_ms(1);
self.lcd_portb.set_low(self.db4);
self.lcd_portb.set_low(self.db5);
self.lcd_portb.set_low(self.db6);
self.lcd_portb.set_low(self.db7);
self.lcd_portd.set_high(self.enable);
self.timer0.delay_ms(1);
self.lcd_portd.set_low(self.enable);
self.lcd_portb.set_high(self.db4);
self.lcd_portb.set_low(self.db5);
self.lcd_portb.set_low(self.db6);
self.lcd_portb.set_low(self.db7);
self.lcd_portd.set_high(self.enable);
self.timer0.delay_ms(3);
self.lcd_portd.set_low(self.enable);
self.timer0.delay_ms(1);
self.lcd_portb.set_low(self.db4);
self.lcd_portb.set_low(self.db5);
self.lcd_portb.set_low(self.db6);
self.lcd_portb.set_low(self.db7);
self.lcd_portd.set_high(self.enable);
self.timer0.delay_ms(1);
self.lcd_portd.set_low(self.enable);
self.lcd_portb.set_low(self.db4);
self.lcd_portb.set_high(self.db5);
self.lcd_portb.set_high(self.db6);
self.lcd_portb.set_low(self.db7);
self.lcd_portd.set_high(self.enable);
self.timer0.delay_ms(1);
self.lcd_portd.set_low(self.enable);
self.timer0.delay_ms(2);
self.lcd_portb.set_low(self.db4);
self.lcd_portb.set_low(self.db5);
self.lcd_portb.set_low(self.db6);
self.lcd_portb.set_low(self.db7);
self.lcd_portd.set_high(self.enable);
self.timer0.delay_ms(1);
self.lcd_portd.set_low(self.enable);
self.timer0.delay_ms(1);
self.lcd_portb.set_high(self.db4);
self.lcd_portb.set_high(self.db5);
self.lcd_portb.set_high(self.db6);
self.lcd_portb.set_high(self.db7);
self.lcd_portd.set_high(self.enable);
self.timer0.delay_ms(1);
self.lcd_portd.set_low(self.enable);
self.timer0.delay_ms(1);
}
fn write_nibble(&self, nibble: u8) {
let high = (nibble >> 4) as u8;
let low = nibble;
self.lcd_portd.set_high(self.rs);
self.lcd_portd.set_low(self.rw);
if (high & 1) !=0 {
self.lcd_portb.set_high(self.db4);
} else {
self.lcd_portb.set_low(self.db4);
}
if (high & 2) !=0 {
self.lcd_portb.set_high(self.db5);
} else {
self.lcd_portb.set_low(self.db5);
}
if (high & 4) !=0 {
self.lcd_portb.set_high(self.db6);
} else {
self.lcd_portb.set_low(self.db6);
}
if (high & 8) !=0 {
self.lcd_portb.set_high(self.db7);
} else {
self.lcd_portb.set_low(self.db7);
}
self.lcd_portd.set_high(self.enable);
self.timer0.delay_ms(1);
self.lcd_portd.set_low(self.enable);
if (low & 1) !=0 {
self.lcd_portb.set_high(self.db4);
} else {
self.lcd_portb.set_low(self.db4);
}
if (low & 2) !=0 {
self.lcd_portb.set_high(self.db5);
} else {
self.lcd_portb.set_low(self.db5);
}
if (low & 4) !=0 {
self.lcd_portb.set_high(self.db6);
} else {
self.lcd_portb.set_low(self.db6);
}
if (low & 8) !=0 {
self.lcd_portb.set_high(self.db7);
} else {
self.lcd_portb.set_low(self.db7);
}
self.lcd_portd.set_high(self.enable);
self.timer0.delay_ms(1);
self.lcd_portd.set_low(self.enable);
self.timer0.delay_ms(1);
}
pub fn write_char(&mut self, character: char) {
self.write_nibble(character as u8);
self.cursor_idx += 1;
if self.cursor_idx == 16 {
self.lcd_portd.set_low(self.rs);
self.lcd_portd.set_low(self.rw);
self.lcd_portb.set_low(self.db6);
self.lcd_portb.set_low(self.db7);
self.lcd_portb.set_low(self.db4);
self.lcd_portb.set_low(self.db5);
self.lcd_portb.set_high(self.db6);
self.lcd_portb.set_high(self.db7);
self.lcd_portd.set_high(self.enable);
self.timer0.delay_ms(1);
self.lcd_portd.set_low(self.enable);
self.lcd_portb.set_low(self.db4);
self.lcd_portb.set_low(self.db5);
self.lcd_portb.set_low(self.db6);
self.lcd_portb.set_low(self.db7);
self.lcd_portd.set_high(self.enable);
self.timer0.delay_ms(1);
self.lcd_portd.set_low(self.enable);
self.timer0.delay_ms(2);
} else if self.cursor_idx == 32 {
self.clear_display();
self.cursor_idx = 0;
} else {
}
}
pub fn clear_display(&mut self) {
self.lcd_portd.set_low(self.rs);
self.lcd_portd.set_low(self.rw);
self.lcd_portb.set_low(self.db4);
self.lcd_portb.set_low(self.db5);
self.lcd_portb.set_low(self.db6);
self.lcd_portb.set_low(self.db7);
self.lcd_portd.set_high(self.enable);
self.timer0.delay_ms(2);
self.lcd_portd.set_low(self.enable);
self.timer0.delay_ms(1);
self.lcd_portb.set_high(self.db4);
self.lcd_portb.set_low(self.db5);
self.lcd_portb.set_low(self.db6);
self.lcd_portb.set_low(self.db7);
self.lcd_portd.set_high(self.enable);
self.timer0.delay_ms(2);
self.lcd_portd.set_low(self.enable);
self.cursor_idx = 0;
self.timer0.delay_ms(2);
}
pub fn print_number(&mut self, num: u16) {
let mut buffer = [' '; 5];
let thousands = (num / 1000) % 10;
let hundreds = (num / 100) % 10;
let tens = (num / 10) % 10;
let ones = num % 10;
buffer[0] = (thousands as u8 + b'0') as char;
buffer[1] = (hundreds as u8 + b'0') as char;
buffer[2] = (tens as u8 + b'0') as char;
buffer[3] = (ones as u8 + b'0') as char;
for c in buffer {
self.write_char(c);
}
}
pub fn print(&mut self, s: &str) {
for bytes in s.as_bytes() {
self.write_char(*bytes as char);
}
}
}
impl Drop for LCD {
fn drop(&mut self) {
unsafe { LCD_TAKING = false; }
}
}