diff --git a/src/screen.rs b/src/screen.rs index e924580..99f8f14 100644 --- a/src/screen.rs +++ b/src/screen.rs @@ -1,18 +1,19 @@ -use anyhow::{anyhow, Result}; +use anyhow::{anyhow, Result, Ok}; use embedded_graphics::{ - mono_font::{ascii::FONT_10X20, MonoTextStyle, iso_8859_10::FONT_6X10}, + mono_font::{ascii::FONT_10X20, iso_8859_10::FONT_6X10, MonoTextStyle}, pixelcolor::Rgb565, prelude::{Dimensions, Drawable, Point, Primitive, RgbColor}, primitives::{PrimitiveStyleBuilder, Rectangle}, text::Text, }; -use embedded_hal::delay::blocking::DelayUs; +use embedded_hal::{delay::blocking::DelayUs, i2c::blocking::{I2c, Operation}}; use esp_idf_hal::{ delay, gpio::{self}, i2c::{self, Master, I2C0}, prelude::*, }; +use log::warn; use ssd1306::{ mode::{BufferedGraphicsMode, DisplayConfig}, prelude::I2CInterface, @@ -27,7 +28,7 @@ type Display = Ssd1306< >; pub struct Screen { - pub display: Display, + pub display: Option, } impl Screen { @@ -37,13 +38,21 @@ impl Screen { scl: gpio::Gpio10, ) -> Result { let config = ::default().baudrate(400.kHz().into()); - let i2c = i2c::Master::::new( - i2c, - i2c::MasterPins { sda, scl }, - config, - )?; + let mut i2c = i2c::Master::::new(i2c, i2c::MasterPins { sda, scl }, config)?; + + let mut buff = [0u8; 10]; + if let Err(err) = i2c.transaction(0x3C, &mut [Operation::Read(&mut buff)]) { + warn!("Failed to initialize display: {}", err); + warn!("Failed to initialize display: {}", err); + warn!("Failed to initialize display: {}", err); + warn!("Failed to initialize display: {}", err); + warn!("Failed to initialize display: {}", err); + return Ok(Self { display: None }); + } + let di = ssd1306::I2CDisplayInterface::new(i2c); + let mut delay = delay::Ets; delay.delay_ms(10_u32)?; @@ -55,22 +64,27 @@ impl Screen { .into_buffered_graphics_mode(); display - .init().map_err(|err| anyhow!("Can not init display: {:?}", err))?; + .init() + .map_err(|err| anyhow!("Can not init display: {:?}", err))?; - let mut instance = Screen { display }; + let mut instance = Screen { display: Some(display) }; instance.draw_boot()?; Ok(instance) } - pub fn draw_boot(&mut self) -> Result<()> - { - self.display.clear(); + pub fn draw_boot(&mut self) -> Result<()> { + if self.display.is_none() { + return Ok(()); + } + let display = self.display.as_mut().unwrap(); + + display.clear(); Rectangle::new( - self.display.bounding_box().top_left, - self.display.bounding_box().size, + display.bounding_box().top_left, + display.bounding_box().size, ) .into_styled( PrimitiveStyleBuilder::new() @@ -79,19 +93,21 @@ impl Screen { .stroke_width(1) .build(), ) - .draw(&mut self.display).expect("Failed to draw rectangle"); + .draw(display) + .expect("Failed to draw rectangle"); Text::new( "Ivan's UPS", Point::new( 12, - (self.display.bounding_box().size.height - 10) as i32 / 2 + 1, + (display.bounding_box().size.height - 10) as i32 / 2 + 1, ), MonoTextStyle::new(&FONT_10X20, Rgb565::WHITE.into()), ) - .draw(&mut self.display).expect("Failed to draw text"); + .draw(display) + .expect("Failed to draw text"); - self.display + display .flush() .map_err(|e| anyhow::anyhow!("Display error: {:?}", e))?; @@ -99,30 +115,27 @@ impl Screen { } pub fn draw_voltage(&mut self, adapter: f32, battery: f32) -> Result<()> { - self.display.clear(); + if let Some(display) = self.display.as_mut() { + display.clear(); - Text::new( - format!("Adp. {:.2} mV", adapter).as_str(), - Point::new( - 12, - 24, - ), - MonoTextStyle::new(&FONT_6X10, Rgb565::WHITE.into()), - ) - .draw(&mut self.display).expect("Failed to draw text"); - Text::new( - format!("Bat. {:.2} mV", battery).as_str(), - Point::new( - 12, - 36, - ), - MonoTextStyle::new(&FONT_6X10, Rgb565::WHITE.into()), - ) - .draw(&mut self.display).expect("Failed to draw text"); - - self.display - .flush() - .map_err(|e| anyhow::anyhow!("Display error: {:?}", e))?; + Text::new( + format!("Adp. {:.2} mV", adapter).as_str(), + Point::new(12, 24), + MonoTextStyle::new(&FONT_6X10, Rgb565::WHITE.into()), + ) + .draw(display) + .expect("Failed to draw text"); + Text::new( + format!("Bat. {:.2} mV", battery).as_str(), + Point::new(12, 36), + MonoTextStyle::new(&FONT_6X10, Rgb565::WHITE.into()), + ) + .draw(display) + .expect("Failed to draw text"); + display + .flush() + .map_err(|e| anyhow::anyhow!("Display error: {:?}", e))?; + } Ok(()) }