You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
142 lines
4.1 KiB
Rust
142 lines
4.1 KiB
Rust
2 years ago
|
//! Driver for LiquidCrystal Displays plugs to the GPIO of the board.
|
||
|
//! The LCD need to be an Hitachi HD44780 chipset compatible.
|
||
|
//!
|
||
|
//! This driver inspired from the one from the arduino libriaries
|
||
|
//! (https://github.com/arduino-libraries/LiquidCrystal) and the
|
||
|
//! documentation from wikipedia (https://en.wikipedia.org/wiki/Hitachi_HD44780_LCD_controller)
|
||
|
|
||
|
use crate::gpio;
|
||
|
|
||
|
// TODO: change USIZE to a Pin struct (and implement the Pin struct :'( )
|
||
|
/// The structure handling the LCD periferic
|
||
|
pub struct Lcd {
|
||
|
/// The Register Select pinout.
|
||
|
rs_pin: usize,
|
||
|
/// The Read/Write pinout.
|
||
|
///
|
||
|
/// If set to None, assumes the rw pin of the lcd is connected to the ground (write state)
|
||
|
rw_pin: Option<usize>,
|
||
|
/// The Enable pinout.
|
||
|
///
|
||
|
/// TODO: wiki says falling-edge triggered, arduino comment says activated by a HIGH pulse.
|
||
|
e_pin: usize,
|
||
|
/// First 4 data bits pins.
|
||
|
///
|
||
|
/// Set to None if the lcd is in 4-bit mode.
|
||
|
first_data_bits_pins: Option<[usize; 4]>,
|
||
|
/// Last 4 data bits pins.
|
||
|
last_data_bits_pins: [usize; 4],
|
||
|
/// The number of line of the LCD.
|
||
|
nb_lines: usize,
|
||
|
/// The number of row of the LCD.
|
||
|
nb_rows: usize,
|
||
|
/// Weither or not the LCD has been initialized in the rigth state.
|
||
|
initialized: bool,
|
||
|
}
|
||
|
|
||
|
impl Lcd {
|
||
|
/// Instanciate a [`Lcd`] object in 4 bits mode.
|
||
|
pub const fn new_4bits_mode(
|
||
|
rs_pin: usize,
|
||
|
rw_pin: Option<usize>,
|
||
|
e_pin: usize,
|
||
|
db4: usize,
|
||
|
db5: usize,
|
||
|
db6: usize,
|
||
|
db7: usize,
|
||
|
nb_lines: usize,
|
||
|
nb_rows: usize,
|
||
|
) -> Self {
|
||
|
Self {
|
||
|
rs_pin,
|
||
|
rw_pin,
|
||
|
e_pin,
|
||
|
first_data_bits_pins: None,
|
||
|
last_data_bits_pins: [db4, db5, db6, db7],
|
||
|
nb_lines,
|
||
|
nb_rows,
|
||
|
initialized: false,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// Instanciate a [`Lcd`] object in 8 bits mode.
|
||
|
pub const fn new_8bits_mode(
|
||
|
rs_pin: usize,
|
||
|
rw_pin: Option<usize>,
|
||
|
e_pin: usize,
|
||
|
db0: usize,
|
||
|
db1: usize,
|
||
|
db2: usize,
|
||
|
db3: usize,
|
||
|
db4: usize,
|
||
|
db5: usize,
|
||
|
db6: usize,
|
||
|
db7: usize,
|
||
|
nb_lines: usize,
|
||
|
nb_rows: usize,
|
||
|
) -> Self {
|
||
|
Self {
|
||
|
rs_pin,
|
||
|
rw_pin,
|
||
|
e_pin,
|
||
|
first_data_bits_pins: Some([db0, db1, db2, db3]),
|
||
|
last_data_bits_pins: [db4, db5, db6, db7],
|
||
|
nb_lines,
|
||
|
nb_rows,
|
||
|
initialized: false,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// Initialize the LCD.
|
||
|
pub fn init(&mut self) -> Result::<(), &str> {
|
||
|
gpio::set_pin_fonction(self.rs_pin, gpio::PinFunction::Output)?;
|
||
|
gpio::set_pin_output_state(self.rs_pin, gpio::PinOutputState::Low)?;
|
||
|
if let Some(rw_pin) = self.rw_pin {
|
||
|
gpio::set_pin_fonction(rw_pin, gpio::PinFunction::Output)?;
|
||
|
gpio::set_pin_output_state(rw_pin, gpio::PinOutputState::Low)?;
|
||
|
}
|
||
|
gpio::set_pin_fonction(self.e_pin, gpio::PinFunction::Output)?;
|
||
|
gpio::set_pin_output_state(self.e_pin, gpio::PinOutputState::Low)?;
|
||
|
if let Some(first_data_bits_pins) = self.first_data_bits_pins {
|
||
|
for pin in first_data_bits_pins.into_iter() {
|
||
|
gpio::set_pin_fonction(pin, gpio::PinFunction::Output)?;
|
||
|
}
|
||
|
}
|
||
|
for pin in self.last_data_bits_pins.into_iter() {
|
||
|
gpio::set_pin_fonction(pin, gpio::PinFunction::Output)?;
|
||
|
}
|
||
|
|
||
|
// TODO: send 0b0011 3 times to make sure to be in 8bits mode 5x8 characters
|
||
|
// TODO: set the new mode with Function set (2 times if 4 bits modes, 1 to set DL=0,
|
||
|
// then the actual one)
|
||
|
self.initialized = true;
|
||
|
todo!();
|
||
|
}
|
||
|
|
||
|
/// Send an 'enable' signal.
|
||
|
fn enable(&self) {
|
||
|
todo!()
|
||
|
}
|
||
|
|
||
|
/// Send a Function Set instruction.
|
||
|
fn function_set(&self) {
|
||
|
todo!()
|
||
|
}
|
||
|
|
||
|
/// Send data to the lcd.
|
||
|
fn send_data(&self) {
|
||
|
todo!()
|
||
|
}
|
||
|
|
||
|
/// Send 8 bits of data.
|
||
|
fn send_8bit(&self) {
|
||
|
todo!()
|
||
|
}
|
||
|
|
||
|
/// Send 4 bits of data.
|
||
|
fn send_4bits(&self) {
|
||
|
// TODO: type?
|
||
|
todo!()
|
||
|
}
|
||
|
}
|