#![no_std]
use embedded_hal::i2c::I2c;
const FONT_5X8: [[u8; 5]; 37] = [
[0x00, 0x00, 0x00, 0x00, 0x00], [0x7E, 0x11, 0x11, 0x11, 0x7E], [0x7F, 0x49, 0x49, 0x49, 0x36], [0x3E, 0x41, 0x41, 0x41, 0x22], [0x7F, 0x41, 0x41, 0x22, 0x1C], [0x7F, 0x49, 0x49, 0x49, 0x41], [0x7F, 0x09, 0x09, 0x09, 0x01], [0x3E, 0x41, 0x49, 0x49, 0x7A], [0x7F, 0x08, 0x08, 0x08, 0x7F], [0x00, 0x41, 0x7F, 0x41, 0x00], [0x20, 0x40, 0x41, 0x3F, 0x01], [0x7F, 0x08, 0x14, 0x22, 0x41], [0x7F, 0x40, 0x40, 0x40, 0x40], [0x7F, 0x02, 0x0C, 0x02, 0x7F], [0x7F, 0x04, 0x08, 0x10, 0x7F], [0x3E, 0x41, 0x41, 0x41, 0x3E], [0x7F, 0x09, 0x09, 0x09, 0x06], [0x3E, 0x41, 0x51, 0x21, 0x5E], [0x7F, 0x09, 0x19, 0x29, 0x46], [0x46, 0x49, 0x49, 0x49, 0x31], [0x01, 0x01, 0x7F, 0x01, 0x01], [0x3F, 0x40, 0x40, 0x40, 0x3F], [0x0F, 0x30, 0x40, 0x30, 0x0F], [0x7F, 0x20, 0x18, 0x20, 0x7F], [0x63, 0x14, 0x08, 0x14, 0x63], [0x03, 0x04, 0x78, 0x04, 0x03], [0x61, 0x51, 0x49, 0x45, 0x43], [0x3E, 0x51, 0x49, 0x45, 0x3E], [0x00, 0x42, 0x7F, 0x40, 0x00], [0x62, 0x51, 0x49, 0x49, 0x46], [0x22, 0x41, 0x49, 0x49, 0x36], [0x18, 0x14, 0x12, 0x7F, 0x10], [0x27, 0x45, 0x45, 0x45, 0x39], [0x3E, 0x49, 0x49, 0x49, 0x32], [0x01, 0x71, 0x09, 0x05, 0x03], [0x36, 0x49, 0x49, 0x49, 0x36], [0x26, 0x49, 0x49, 0x49, 0x3E], ];
pub struct SSD1306<I2C> {
i2c: I2C,
address: u8,
}
impl<I2C, E> SSD1306<I2C>
where
I2C: I2c<Error = E>,
{
pub fn new(i2c: I2C, address: u8) -> Self {
Self { i2c, address }
}
fn send_command(&mut self, command: u8) -> Result<(), E> {
self.i2c.write(self.address, &[0x00, command])?;
Ok(())
}
fn send_data(&mut self, data: u8) -> Result<(), E> {
self.i2c.write(self.address, &[0x40, data])?;
Ok(())
}
pub fn init_display(&mut self) -> Result<(), E> {
self.send_command(0xAE)?;
self.send_command(0xA8)?;
self.send_command(0x3F)?;
self.send_command(0xD3)?;
self.send_command(0x00)?;
self.send_command(0x40)?;
self.send_command(0xA1)?;
self.send_command(0xC8)?;
self.send_command(0xDA)?;
self.send_command(0x12)?;
self.send_command(0x81)?;
self.send_command(0x7F)?;
self.send_command(0xA4)?;
self.send_command(0xA6)?;
self.send_command(0xD5)?;
self.send_command(0x80)?;
self.send_command(0x8D)?;
self.send_command(0x14)?;
self.send_command(0x20)?;
self.send_command(0x01)?;
self.send_command(0xAF)?;
self.clear()?;
Ok(())
}
fn fill_screen_with_value(&mut self, value: u8) -> Result<(), E> {
self.send_command(0x21)?;
self.send_command(0x00)?;
self.send_command(0x7F)?;
self.send_command(0x22)?;
self.send_command(0x00)?;
self.send_command(0x07)?;
for _ in 0..8 {
for _ in 0..128 {
self.send_data(value)?;
}
}
Ok(())
}
pub fn fill(&mut self) -> Result<(), E> {
self.fill_screen_with_value(0xFF)?;
Ok(())
}
pub fn clear(&mut self) -> Result<(), E> {
self.fill_screen_with_value(0x00)?;
Ok(())
}
fn set_cursor(&mut self, col: u8, page: u8, len: u8) -> Result<(), E> {
self.send_command(0x21)?;
self.send_command(col)?;
self.send_command(col + len)?;
self.send_command(0x22)?;
self.send_command(page)?;
self.send_command(page)?;
Ok(())
}
fn write_char(&mut self, c: char) -> Result<(), E> {
let index = match c {
'A'..'Z' => (c as u8 - b'A' + 1) as usize,
'a'..'z' => (c.to_ascii_uppercase() as u8 - b'A' + 1) as usize,
'0'..'9' => (c as u8 - b'0' + 27) as usize,
' ' => 0,
_ => return Ok(()),
};
for &byte in &FONT_5X8[index] {
self.send_data(byte)?;
}
Ok(())
}
pub fn draw_text(&mut self, text: &str, mut col: u8, mut page: u8) -> Result<(), E> {
for c in text.chars() {
if col + 5 > 128 {
col = 0;
page += 1;
}
self.set_cursor(col, page, 5)?;
self.write_char(c)?;
col += 5;
}
Ok(())
}
}