From 1c20412933f273f9fa955b56a0d9ac65c13fcc66 Mon Sep 17 00:00:00 2001 From: Ivan Li Date: Tue, 3 May 2022 10:35:41 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20SSD1036=20128*64=20I2C=20=E5=B1=8F?= =?UTF-8?q?=E5=B9=95=E6=98=BE=E7=A4=BA=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.toml | 19 +++++---- src/main.rs | 19 ++++++++- src/screen.rs | 108 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 136 insertions(+), 10 deletions(-) create mode 100644 src/screen.rs diff --git a/Cargo.toml b/Cargo.toml index b985235..0588737 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,26 +1,29 @@ [package] -name = "ups-esp32c3-rust" -version = "0.1.0" authors = ["Ivan Li "] edition = "2018" +name = "ups-esp32c3-rust" resolver = "2" +version = "0.1.0" [profile.release] opt-level = "s" [profile.dev] debug = true # Symbols are nice and they don't increase the size on Flash -opt-level = "z" +opt-level = "z" [features] pio = ["esp-idf-sys/pio"] [dependencies] -esp-idf-sys = { version = "0.31", features = ["binstart"] } -esp-idf-hal = "0.36.0" +anyhow = {version = "1.0.57", features = ["backtrace"]} +embedded-graphics = "0.7.1" embedded-hal = "1.0.0-alpha.8" - +esp-idf-hal = "0.37.3" +esp-idf-sys = {version = "0.31.5", features = ["binstart"]} +log = "0.4.16" +ssd1306 = "0.7.0" [build-dependencies] -embuild = "0.28" -anyhow = "1" +anyhow = "1.0.57" +embuild = "0.29.1" diff --git a/src/main.rs b/src/main.rs index 77f381f..9cead4b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,9 +1,11 @@ use esp_idf_sys as _; +use log::*; use std::{thread, time::Duration}; mod beep; mod blink; mod dc_out_controller; +mod screen; fn main() { // Temporary. Will disappear once ESP-IDF 4.4 is released, but for now it is necessary to call this function once, // or else some patches to the runtime implemented by esp-idf-sys might not link properly. @@ -16,12 +18,23 @@ fn main() { let ledc_timer0 = peripherals.ledc.timer0; let ledc_channel0 = peripherals.ledc.channel0; let dc_out_ctl_pin = peripherals.pins.gpio2; + let i2c0 = peripherals.i2c0; + let gpio9 = peripherals.pins.gpio9; + let gpio10 = peripherals.pins.gpio10; + + println!("Starting screen"); + let mut screen = screen::Screen::new(i2c0, gpio9, gpio10).expect("Failed to create screen"); + thread::spawn(move || { let mut blink = blink::Blink::new(gpio5.into_output().expect("Failed to set GPIO5 as output")); blink.play(); }); + thread::spawn(move || { + thread::sleep(Duration::from_millis(5000)); + }); + thread::spawn(move || { let mut beep = beep::Beep::new( gpio6.into_output().expect("Failed to set GPIO6 as output"), @@ -47,6 +60,8 @@ fn main() { thread::sleep(Duration::from_millis(500)); } }); - - println!("Hello, world!"); + loop { + println!("Hello, world!"); + thread::sleep(Duration::from_millis(2000)); + } } diff --git a/src/screen.rs b/src/screen.rs new file mode 100644 index 0000000..37186a9 --- /dev/null +++ b/src/screen.rs @@ -0,0 +1,108 @@ +use anyhow::{Result, Error}; +use embedded_graphics::{ + mono_font::{ascii::FONT_10X20, MonoTextStyle}, + pixelcolor::Rgb565, + prelude::{Dimensions, Drawable, Point, Primitive, RgbColor}, + primitives::{PrimitiveStyleBuilder, Rectangle}, + text::Text, +}; +use embedded_hal::delay::blocking::DelayUs; +use esp_idf_hal::{ + delay, + gpio::{self}, + i2c::{self, Master, I2C0}, + prelude::*, +}; +use log::info; +use ssd1306::{ + mode::{BufferedGraphicsMode, DisplayConfig}, + prelude::I2CInterface, + size::DisplaySize128x64, + Ssd1306, +}; + +type Display = Ssd1306< + I2CInterface, gpio::Gpio10>>, + DisplaySize128x64, + BufferedGraphicsMode, +>; + +pub struct Screen { + pub display: Display, +} + +impl Screen { + pub fn new( + i2c: i2c::I2C0, + sda: gpio::Gpio9, + scl: gpio::Gpio10, + ) -> Result { + let config = ::default().baudrate(400.kHz().into()); + let i2c = i2c::Master::::new( + i2c, + i2c::MasterPins { sda, scl }, + config, + )?; + let di = ssd1306::I2CDisplayInterface::new(i2c); + + let mut delay = delay::Ets; + delay.delay_ms(10_u32); + + let mut display = ssd1306::Ssd1306::new( + di, + ssd1306::size::DisplaySize128x64, + ssd1306::rotation::DisplayRotation::Rotate0, + ) + .into_buffered_graphics_mode(); + + display + .init() + .unwrap(); + + + println!("LED rendering done"); + + let mut instance = Screen { display }; + + instance.drawBoot()?; + + Ok(instance) + } + + pub fn drawBoot(&mut self) -> Result<()> + { + println!("LED rendering done"); + self.display.clear(); + + Rectangle::new( + self.display.bounding_box().top_left, + self.display.bounding_box().size, + ) + .into_styled( + PrimitiveStyleBuilder::new() + .fill_color(Rgb565::BLUE.into()) + .stroke_color(Rgb565::YELLOW.into()) + .stroke_width(1) + .build(), + ) + .draw(&mut self.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, + ), + MonoTextStyle::new(&FONT_10X20, Rgb565::WHITE.into()), + ) + .draw(&mut self.display).expect("Failed to draw text"); + + println!("LED rendering done"); + + self.display + .flush() + .map_err(|e| anyhow::anyhow!("Display error: {:?}", e))?; + + Ok(()) + } +}