#![no_std]
mod command;
pub mod config;
pub mod interface;
use command::{oled_init, oled_set_cursor};
use config::Ssd1315DisplayConfig;
use display_interface::{DataFormat, WriteOnlyDataCommand};
use embedded_graphics::draw_target::DrawTarget;
use embedded_graphics::geometry::{OriginDimensions, Size};
use embedded_graphics::pixelcolor::raw::ToBytes;
use embedded_graphics::pixelcolor::BinaryColor;
use embedded_graphics::Pixel;
pub struct Ssd1315<DI> {
interface: DI,
buffer: [[u8; 128]; 8],
config: Ssd1315DisplayConfig,
}
impl<DI: WriteOnlyDataCommand> Ssd1315<DI> {
pub fn new(interface: DI) -> Self {
Self {
interface,
buffer: [[0; 128]; 8],
config: Default::default(),
}
}
pub fn set_custom_config(&mut self, config: Ssd1315DisplayConfig) {
self.config = config;
}
pub fn init_screen(&mut self) {
oled_init(&mut self.interface, self.config);
}
pub fn flush_screen(&mut self) {
for (page, data) in self.buffer.iter().enumerate() {
oled_set_cursor(&mut self.interface, page as u8);
self.interface.send_data(DataFormat::U8(data)).unwrap();
}
self.buffer = [[0; 128]; 8];
}
}
impl<DI> OriginDimensions for Ssd1315<DI> {
fn size(&self) -> Size {
Size::new(128, 64)
}
}
impl<DI> DrawTarget for Ssd1315<DI> {
type Color = BinaryColor;
type Error = core::convert::Infallible;
fn draw_iter<I>(&mut self, pixels: I) -> Result<(), Self::Error>
where
I: IntoIterator<Item = Pixel<Self::Color>>,
{
for Pixel(coord, color) in pixels.into_iter() {
match coord.into() {
(x @ 1..=128, y @ 1..=8) => {
self.buffer[0][x as usize - 1] |= color.to_ne_bytes()[0] << (y - 1)
}
(x @ 1..=128, y @ 9..=16) => {
self.buffer[1][x as usize - 1] |= color.to_ne_bytes()[0] << (y - 8 - 1)
}
(x @ 1..=128, y @ 17..=24) => {
self.buffer[2][x as usize - 1] |= color.to_ne_bytes()[0] << (y - 16 - 1)
}
(x @ 1..=128, y @ 25..=32) => {
self.buffer[3][x as usize - 1] |= color.to_ne_bytes()[0] << (y - 24 - 1)
}
(x @ 1..=128, y @ 33..=40) => {
self.buffer[4][x as usize - 1] |= color.to_ne_bytes()[0] << (y - 32 - 1)
}
(x @ 1..=128, y @ 41..=48) => {
self.buffer[5][x as usize - 1] |= color.to_ne_bytes()[0] << (y - 40 - 1)
}
(x @ 1..=128, y @ 49..=56) => {
self.buffer[6][x as usize - 1] |= color.to_ne_bytes()[0] << (y - 48 - 1)
}
(x @ 1..=128, y @ 57..=64) => {
self.buffer[7][x as usize - 1] |= color.to_ne_bytes()[0] << (y - 56 - 1)
}
_ => unreachable!(
"`x` coordinate or `page` coordinate indexed out of bound of its corresponding size of OLED screen!"
),
}
}
Ok(())
}
}
pub trait DrawFromRaw {
fn draw_from_raw<DI>(&self, instance: &mut Ssd1315<DI>);
}
impl DrawFromRaw for [[u8; 128]; 8] {
fn draw_from_raw<DI>(&self, instance: &mut Ssd1315<DI>) {
instance.buffer.clone_from(self)
}
}