extern "C" {
fn lcd1602Init(iChannel: i32, iAddr: i32) -> i32;
fn lcd1602SetCursor(x: i32, y: i32) -> i32;
fn lcd1602Control(bBacklight: i32, bCursor: i32, bBlink: i32) -> i32;
fn lcd1602WriteString(szText: *const std::ffi::c_char) -> i32;
fn lcd1602Clear() -> i32;
fn lcd1602Shutdown();
fn lcd2004Init(iChannel: i32, iAddr: i32) -> i32;
fn lcd2004SetCursor(x: i32, y: i32) -> i32;
fn lcd2004Control(bBacklight: i32, bCursor: i32, bBlink: i32) -> i32;
fn lcd2004WriteString(szText: *const std::ffi::c_char) -> i32;
fn lcd2004Clear() -> i32;
fn lcd2004Shutdown();
}
pub trait Lcd {
fn new(channel: i32, addr: i32) -> Option<Self>
where Self: Sized;
fn set_cursor(&self, x: i32, y: i32);
fn control(&self, backlight: bool, cursor: bool, blink: bool);
fn write(&self, text: &str);
fn clear(&self);
fn lines() -> i32;
fn columns() -> i32;
}
pub struct Lcd1602 {}
impl Lcd for Lcd1602 {
fn new(channel: i32, addr: i32) -> Option<Lcd1602> {
let result = unsafe {
lcd1602Init(channel, addr)
};
match result {
0 => Some(Lcd1602 {}),
_ => None
}
}
fn set_cursor(&self, x: i32, y: i32) {
unsafe {
lcd1602SetCursor(x, y);
}
}
fn control(&self, backlight: bool, cursor: bool, blink: bool) {
unsafe {
lcd1602Control(if backlight {1} else {0}, if cursor {1} else {0}, if blink {1} else {0});
}
}
fn write(&self, text: &str) {
let cstr = std::ffi::CString::new(text.chars().map(|c| {
if c >= ' ' && c < '~' && c != '\\' {
return c as u8
}
match c {
'¥' => 0x5C,
'→' => 0x7E,
'←' => 0x7F,
'°' => 0xDF,
'α' => 0xE0,
'ä' | 'Ä' => 0xE1,
'β' | 'ß' | 'ẞ' => 0xE2,
'ε' => 0xE3,
'μ' => 0xE4,
'σ' => 0xE5,
'ρ' => 0xE6,
'√' => 0xE8,
'ö' | 'Ö' => 0xEF,
'θ' => 0xF2,
'Ω' => 0xF3,
'∞' => 0xF4,
'ü' | 'Ü' => 0xF5,
'Σ' | '∑' => 0xF6,
'π' => 0xF7,
'÷' => 0xFD,
_ => 0xDB }
}).collect::<Vec<u8>>()).expect("CString::new failed");
let ptr = cstr.into_raw();
unsafe {
lcd1602WriteString(ptr);
let _ = std::ffi::CString::from_raw(ptr);
}
}
fn clear(&self) {
unsafe {
lcd1602Clear();
}
}
fn lines() -> i32 {2}
fn columns() -> i32 {16}
}
impl Drop for Lcd1602 {
fn drop(&mut self) {
unsafe {
lcd1602Shutdown();
}
}
}
pub struct Lcd2004 {}
impl Lcd for Lcd2004 {
fn new(channel: i32, addr: i32) -> Option<Lcd2004> {
let result = unsafe {
lcd2004Init(channel, addr)
};
match result {
0 => Some(Lcd2004 {}),
_ => None
}
}
fn set_cursor(&self, x: i32, y: i32) {
unsafe {
lcd2004SetCursor(x, y);
}
}
fn control(&self, backlight: bool, cursor: bool, blink: bool) {
unsafe {
lcd2004Control(if backlight {1} else {0}, if cursor {1} else {0}, if blink {1} else {0});
}
}
fn write(&self, text: &str) {
let cstr = std::ffi::CString::new(text.chars().map(|c| {
if c >= ' ' && c < '~' && c != '\\' {
return c as u8
}
match c {
'¥' => 0x5C,
'→' => 0x7E,
'←' => 0x7F,
'°' => 0xDF,
'α' => 0xE0,
'ä' | 'Ä' => 0xE1,
'β' | 'ß' | 'ẞ' => 0xE2,
'ε' => 0xE3,
'μ' => 0xE4,
'σ' => 0xE5,
'ρ' => 0xE6,
'√' => 0xE8,
'ö' | 'Ö' => 0xEF,
'θ' => 0xF2,
'Ω' => 0xF3,
'∞' => 0xF4,
'ü' | 'Ü' => 0xF5,
'Σ' | '∑' => 0xF6,
'π' => 0xF7,
'÷' => 0xFD,
_ => 0xDB }
}).collect::<Vec<u8>>()).expect("CString::new failed");
let ptr = cstr.into_raw();
unsafe {
lcd2004WriteString(ptr);
let _ = std::ffi::CString::from_raw(ptr);
}
}
fn clear(&self) {
unsafe {
lcd2004Clear();
}
}
fn lines() -> i32 {4}
fn columns() -> i32 {20}
}
impl Drop for Lcd2004 {
fn drop(&mut self) {
unsafe {
lcd2004Shutdown();
}
}
}