make lcd a lib
This commit is contained in:
parent
de278aaa52
commit
ceaeb97787
81
lcd-writer/src/lcd.rs
Normal file
81
lcd-writer/src/lcd.rs
Normal file
@ -0,0 +1,81 @@
|
||||
use rppal::{i2c, i2c::I2c};
|
||||
use std::io;
|
||||
|
||||
const C0: u8 = 7;
|
||||
const A0: u8 = 6;
|
||||
|
||||
#[allow(unused)]
|
||||
#[repr(u8)]
|
||||
enum LcdCommand {
|
||||
Clear = 1,
|
||||
ReturnHome = 2,
|
||||
DisplayOn = 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0,
|
||||
FunctionSet = 1 << 5 | 1 << 4 | 1 << 3,
|
||||
EntryModeSet = 1 << 2 | 1 << 1,
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
#[repr(u8)]
|
||||
enum ControlByte {
|
||||
Normal = 1 << C0,
|
||||
Last = 0 << C0,
|
||||
Data = 0 << C0 | 1 << A0,
|
||||
}
|
||||
|
||||
fn i2c_err_to_io_err(err: i2c::Error) -> io::Error {
|
||||
match err {
|
||||
i2c::Error::Io(v) => v,
|
||||
i2c::Error::InvalidSlaveAddress(addr) => io::Error::new(
|
||||
io::ErrorKind::ConnectionRefused,
|
||||
format!("invalid slave address {}", addr),
|
||||
),
|
||||
i2c::Error::FeatureNotSupported => io::Error::new(
|
||||
io::ErrorKind::ConnectionRefused,
|
||||
"invalid slave address {}".to_owned(),
|
||||
),
|
||||
i2c::Error::UnknownModel => io::Error::new(
|
||||
io::ErrorKind::ConnectionRefused,
|
||||
"invalid slave address {}".to_owned(),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Lcd {
|
||||
bus: I2c,
|
||||
}
|
||||
|
||||
impl Lcd {
|
||||
pub fn new() -> io::Result<Self> {
|
||||
let mut bus = I2c::with_bus(1).map_err(i2c_err_to_io_err)?;
|
||||
bus.set_slave_address(60).map_err(i2c_err_to_io_err)?;
|
||||
let setup = [
|
||||
ControlByte::Last as u8,
|
||||
LcdCommand::FunctionSet as u8,
|
||||
LcdCommand::DisplayOn as u8,
|
||||
LcdCommand::EntryModeSet as u8,
|
||||
LcdCommand::Clear as u8,
|
||||
];
|
||||
bus.write(&setup).map_err(i2c_err_to_io_err)?;
|
||||
Ok(Self { bus })
|
||||
}
|
||||
|
||||
pub fn write(&mut self, value: &str) -> io::Result<()> {
|
||||
let mut data = vec![ControlByte::Data as u8];
|
||||
data.extend(value.bytes());
|
||||
let _ = self.bus.write(&data).map_err(i2c_err_to_io_err)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn set_cursor(&mut self, col: u8, row: u8) -> io::Result<()> {
|
||||
let pos = col | (row * 0x40) | 1 << 7;
|
||||
let data = vec![ControlByte::Last as u8, pos];
|
||||
let _ = self.bus.write(&data).map_err(i2c_err_to_io_err)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn clear(&mut self) -> io::Result<()> {
|
||||
let data = vec![ControlByte::Last as u8, LcdCommand::Clear as u8];
|
||||
let _ = self.bus.write(&data).map_err(i2c_err_to_io_err)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
1
lcd-writer/src/lib.rs
Normal file
1
lcd-writer/src/lib.rs
Normal file
@ -0,0 +1 @@
|
||||
pub mod lcd;
|
@ -1,79 +1,21 @@
|
||||
use rppal::{i2c, i2c::I2c};
|
||||
use std::io::{self, stdin, stdout, BufRead, Write};
|
||||
|
||||
const C0: u8 = 7;
|
||||
const A0: u8 = 6;
|
||||
use lcd::Lcd;
|
||||
|
||||
#[allow(unused)]
|
||||
#[repr(u8)]
|
||||
enum LcdCommand {
|
||||
Clear = 1,
|
||||
ReturnHome = 2,
|
||||
DisplayOn = 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0,
|
||||
FunctionSet = 1 << 5 | 1 << 4 | 1 << 3,
|
||||
EntryModeSet = 1 << 2 | 1 << 1,
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
#[repr(u8)]
|
||||
enum ControlByte {
|
||||
Normal = 1 << C0,
|
||||
Last = 0 << C0,
|
||||
Data = 0 << C0 | 1 << A0,
|
||||
}
|
||||
|
||||
struct Lcd {
|
||||
bus: I2c,
|
||||
}
|
||||
|
||||
impl Lcd {
|
||||
pub fn new() -> Result<Self, i2c::Error> {
|
||||
let mut bus = I2c::with_bus(1)?;
|
||||
bus.set_slave_address(60)?;
|
||||
let setup = [
|
||||
ControlByte::Last as u8,
|
||||
LcdCommand::FunctionSet as u8,
|
||||
LcdCommand::DisplayOn as u8,
|
||||
LcdCommand::EntryModeSet as u8,
|
||||
LcdCommand::Clear as u8,
|
||||
];
|
||||
bus.write(&setup)?;
|
||||
Ok(Self { bus })
|
||||
}
|
||||
|
||||
pub fn write(&mut self, value: &str) -> Result<(), i2c::Error> {
|
||||
let mut data = vec![ControlByte::Data as u8];
|
||||
data.extend(value.bytes());
|
||||
let _ = self.bus.write(&data)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn set_cursor(&mut self, col: u8, row: u8) -> Result<(), i2c::Error> {
|
||||
let pos = col | (row * 0x40) | 1 << 7;
|
||||
let data = vec![ControlByte::Last as u8, pos];
|
||||
let _ = self.bus.write(&data)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn clear(&mut self) -> Result<(), i2c::Error> {
|
||||
let data = vec![ControlByte::Last as u8, LcdCommand::Clear as u8];
|
||||
let _ = self.bus.write(&data)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
mod lcd;
|
||||
|
||||
fn main() -> io::Result<()> {
|
||||
let mut lcd = Lcd::new().unwrap();
|
||||
let mut lcd = Lcd::new()?;
|
||||
loop {
|
||||
print!("> ");
|
||||
stdout().lock().flush()?;
|
||||
let mut line = String::new();
|
||||
stdin().lock().read_line(&mut line)?;
|
||||
if line.starts_with("clear") {
|
||||
lcd.clear().unwrap();
|
||||
lcd.set_cursor(0, 0).unwrap();
|
||||
lcd.clear()?;
|
||||
lcd.set_cursor(0, 0)?;
|
||||
} else if line.starts_with("print") {
|
||||
lcd.write(&line[6..]).unwrap();
|
||||
lcd.write(&line[6..])?;
|
||||
} else {
|
||||
println!("unrecognized command \"{line}\"");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user