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