diff --git a/src/application/confirm_profile.rs b/src/application/confirm_profile.rs index 392b957..5b9494e 100644 --- a/src/application/confirm_profile.rs +++ b/src/application/confirm_profile.rs @@ -3,22 +3,16 @@ use embedded_graphics::{ primitives::rectangle::Rectangle, style::PrimitiveStyleBuilder, style::TextStyleBuilder, }; -use embedded_hal::digital::v2::{InputPin, OutputPin}; -use st7735_lcd::Orientation; +use embedded_hal::digital::v2::InputPin; + use stm32f1xx_hal::prelude::*; use crate::application::App; use crate::profiles; impl App { - pub fn confirm_profile(mut self) -> (bool, App) { - let mut disp = - st7735_lcd::ST7735::new(self.spi, self.disp_dc, self.disp_rst, true, false, 160, 128); - self.disp_cs.set_low().unwrap(); - - disp.init(&mut self.delay).unwrap(); - disp.set_orientation(&Orientation::LandscapeSwapped) - .unwrap(); + pub fn confirm_profile(&mut self) -> bool { + let mut disp = self.get_display(); let rect = Rectangle::new(Point::new(0, 0), Point::new(160, 128)) .into_styled(self.styles.fill_black); @@ -107,11 +101,8 @@ impl App { self.delay.delay_ms(10u16); } - let (spi, disp_dc, disp_rst) = disp.release(); - self.spi = spi; - self.disp_dc = disp_dc; - self.disp_rst = disp_rst; + self.release_display(disp); - (confirmed, self) + confirmed } } diff --git a/src/application/mod.rs b/src/application/mod.rs index 4caa117..7dcdbc7 100644 --- a/src/application/mod.rs +++ b/src/application/mod.rs @@ -1,4 +1,5 @@ -use embedded_hal::digital::v2::{InputPin, OutputPin}; +use core::mem; +use embedded_hal::digital::v2::OutputPin; use st7735_lcd::Orientation; use stm32f1xx_hal::{ delay::Delay, @@ -8,6 +9,8 @@ use stm32f1xx_hal::{ timer::Tim3PartialRemap, }; +use crate::max6675; + mod confirm_profile; mod profile_selection; mod run_profile; @@ -41,10 +44,10 @@ type AppDisp = pub struct App { delay: Delay, board_led: gpioc::PC13>, - spi: AppSPI, + spi: Option, disp_cs: gpioa::PA0>, - disp_dc: gpioa::PA4>, - disp_rst: gpioa::PA1>, + disp_dc: Option>>, + disp_rst: Option>>, max_cs: gpioa::PA9>, qei: AppQEI, button: gpiob::PB3>, @@ -52,19 +55,71 @@ pub struct App { selected_profile: usize, styles: Styles, + + temp_avg: f32, } impl App { pub fn run(mut self) -> ! { - self = self.splash_screen(); + self.read_temperature(); + + let mut disp = self.get_display(); + disp.init(&mut self.delay).unwrap(); + self.release_display(disp); + + self.splash_screen(); loop { - self = self.profile_selection(); - let (confirmed, app) = self.confirm_profile(); - self = app; + self.profile_selection(); + let confirmed = self.confirm_profile(); if !confirmed { continue; } - self = self.run_profile(); + self.run_profile(); } } + + fn get_display(&mut self) -> AppDisp { + let spi = mem::replace(&mut self.spi, None).expect("Spi already in use"); + let disp_dc = mem::replace(&mut self.disp_dc, None).expect("Dispaly DC already in use"); + let disp_rst = mem::replace(&mut self.disp_rst, None).expect("Display RST already in use"); + + let mut disp = st7735_lcd::ST7735::new(spi, disp_dc, disp_rst, true, false, 160, 128); + self.disp_cs.set_low().unwrap(); + + disp.set_orientation(&Orientation::LandscapeSwapped) + .unwrap(); + + disp + } + + fn release_display(&mut self, disp: AppDisp) { + self.disp_cs.set_high().unwrap(); + + let (spi, disp_dc, disp_rst) = disp.release(); + self.spi = Some(spi); + self.disp_dc = Some(disp_dc); + self.disp_rst = Some(disp_rst); + } + + fn read_temperature(&mut self) -> f32 { + let mut spi = mem::replace(&mut self.spi, None).expect("Spi already in use"); + + let mut res = max6675::read(&mut spi, &mut self.max_cs); + for _ in 0..4 { + if res.is_ok() { + break; + } + res = max6675::read(&mut spi, &mut self.max_cs); + } + + self.spi = Some(spi); + + self.temp_avg = if self.temp_avg > 0.0 { + self.temp_avg * 0.9 + res.unwrap() * 0.1 + } else { + res.unwrap() + }; + + self.temp_avg + } } diff --git a/src/application/profile_selection.rs b/src/application/profile_selection.rs index f00e8fc..41530cd 100644 --- a/src/application/profile_selection.rs +++ b/src/application/profile_selection.rs @@ -3,24 +3,16 @@ use embedded_graphics::{ primitives::rectangle::Rectangle, style::PrimitiveStyleBuilder, style::TextStyleBuilder, }; -use embedded_hal::digital::v2::{InputPin, OutputPin}; -use profont::ProFont12Point; +use embedded_hal::digital::v2::InputPin; -use st7735_lcd::Orientation; use stm32f1xx_hal::prelude::*; use crate::application::App; use crate::profiles; impl App { - pub fn profile_selection(mut self) -> App { - let mut disp = - st7735_lcd::ST7735::new(self.spi, self.disp_dc, self.disp_rst, true, false, 160, 128); - self.disp_cs.set_low().unwrap(); - - disp.init(&mut self.delay).unwrap(); - disp.set_orientation(&Orientation::LandscapeSwapped) - .unwrap(); + pub fn profile_selection(&mut self) { + let mut disp = self.get_display(); let rect = Rectangle::new(Point::new(0, 0), Point::new(160, 128)) .into_styled(self.styles.fill_black); @@ -83,11 +75,6 @@ impl App { self.delay.delay_ms(10u16); } - let (spi, disp_dc, disp_rst) = disp.release(); - self.spi = spi; - self.disp_dc = disp_dc; - self.disp_rst = disp_rst; - - self + self.release_display(disp); } } diff --git a/src/application/run_profile.rs b/src/application/run_profile.rs index ec82805..8024847 100644 --- a/src/application/run_profile.rs +++ b/src/application/run_profile.rs @@ -1,12 +1,10 @@ +use arrayvec::ArrayString; +use core::fmt::Write; use embedded_graphics::{ drawable::Drawable, fonts::Text, pixelcolor::Rgb565, prelude::*, primitive_style, primitives::rectangle::Rectangle, primitives::Line, style::PrimitiveStyle, style::PrimitiveStyleBuilder, style::TextStyleBuilder, }; - -use embedded_hal::digital::v2::OutputPin; - -use st7735_lcd::Orientation; use stm32f1xx_hal::{ delay::Delay, gpio::{gpioa, gpiob, gpioc, Alternate, Floating, Input, Output, PushPull}, @@ -22,14 +20,8 @@ use crate::application::App; use crate::profiles; impl App { - pub fn run_profile(mut self) -> App { - let mut disp = - st7735_lcd::ST7735::new(self.spi, self.disp_dc, self.disp_rst, true, false, 160, 128); - self.disp_cs.set_low().unwrap(); - - disp.init(&mut self.delay).unwrap(); - disp.set_orientation(&Orientation::LandscapeSwapped) - .unwrap(); + pub fn run_profile(&mut self) { + let mut disp = self.get_display(); let rect = Rectangle::new(Point::new(0, 0), Point::new(160, 128)) .into_styled(self.styles.fill_black); @@ -43,7 +35,7 @@ impl App { } for y in (0..110).step_by(10) { - Line::new(Point::new(0, 127 - y), Point::new(195, 127 - y)) + Line::new(Point::new(0, 127 - y), Point::new(159, 127 - y)) .into_styled(self.styles.grid) .draw(&mut disp) .unwrap(); @@ -58,13 +50,48 @@ impl App { .unwrap(); } - let (spi, disp_dc, disp_rst) = disp.release(); - self.spi = spi; - self.disp_dc = disp_dc; - self.disp_rst = disp_rst; + self.release_display(disp); + + let preheat_target = profiles::REFLOW_PROFILES[self.selected_profile].get_temp(0.0); + + let mut target_buf = ArrayString::<[_; 10]>::new(); + // Output `xxx.xx` + write!(&mut target_buf, "{:.2}", preheat_target).expect("Failed to write to buffer"); + + let mut preheat_ok_count = 0; + + while preheat_ok_count < 5 { + let temp = self.read_temperature(); + if temp > preheat_target { + preheat_ok_count += 1; + } else { + preheat_ok_count = 0; + } + + let mut temp_buf = ArrayString::<[_; 10]>::new(); + // Output `xxx.xx` + write!(&mut temp_buf, "{:.2}", temp).expect("Failed to write to buffer"); + + let mut disp = self.get_display(); + let rect = Rectangle::new(Point::new(0, 0), Point::new(160, 10)) + .into_styled(self.styles.fill_black); + rect.draw(&mut disp).unwrap(); + + Text::new(&temp_buf, Point::new(8, 0)) + .into_styled(self.styles.text_red) + .draw(&mut disp) + .unwrap(); + + Text::new(&target_buf, Point::new(80, 0)) + .into_styled(self.styles.text_green) + .draw(&mut disp) + .unwrap(); + + self.release_display(disp); + + self.delay.delay_ms(1000u32); + } loop {} - - self } } diff --git a/src/application/setup.rs b/src/application/setup.rs index cf13401..203e1b1 100644 --- a/src/application/setup.rs +++ b/src/application/setup.rs @@ -80,10 +80,10 @@ pub fn setup(cp: cortex_m::peripheral::Peripherals, dp: stm32::Peripherals) -> A App { delay: delay, board_led: led, - spi: spi, + spi: Some(spi), disp_cs: disp_cs, - disp_dc: dc, - disp_rst: rst, + disp_dc: Some(dc), + disp_rst: Some(rst), max_cs: max_cs, qei: qei, button: button, @@ -91,5 +91,7 @@ pub fn setup(cp: cortex_m::peripheral::Peripherals, dp: stm32::Peripherals) -> A selected_profile: 0, styles: Styles::new(), + + temp_avg: 0.0, } } diff --git a/src/application/splash.rs b/src/application/splash.rs index a7ce9a2..359ad4d 100644 --- a/src/application/splash.rs +++ b/src/application/splash.rs @@ -3,23 +3,14 @@ use embedded_graphics::{ primitives::rectangle::Rectangle, style::PrimitiveStyleBuilder, }; -use embedded_hal::digital::v2::OutputPin; - -use st7735_lcd::Orientation; use stm32f1xx_hal::prelude::*; use tinybmp::Bmp; use crate::application::App; impl App { - pub fn splash_screen(mut self) -> App { - let mut disp = - st7735_lcd::ST7735::new(self.spi, self.disp_dc, self.disp_rst, true, false, 160, 128); - self.disp_cs.set_low().unwrap(); - - disp.init(&mut self.delay).unwrap(); - disp.set_orientation(&Orientation::LandscapeSwapped) - .unwrap(); + pub fn splash_screen(&mut self) { + let mut disp = self.get_display(); let rect = Rectangle::new(Point::new(0, 0), Point::new(160, 128)) .into_styled(self.styles.fill_black); @@ -32,11 +23,6 @@ impl App { self.delay.delay_ms(2000u16); - let (spi, disp_dc, disp_rst) = disp.release(); - self.spi = spi; - self.disp_dc = disp_dc; - self.disp_rst = disp_rst; - - self + self.release_display(disp); } } diff --git a/src/application/styles.rs b/src/application/styles.rs index ed32c16..d500ea2 100644 --- a/src/application/styles.rs +++ b/src/application/styles.rs @@ -8,6 +8,8 @@ use profont::{ProFont12Point, ProFont14Point}; pub struct Styles { pub fill_black: PrimitiveStyle, pub text: TextStyle, + pub text_green: TextStyle, + pub text_red: TextStyle, pub text_big: TextStyle, pub text_big_black: TextStyle, pub normal_box: PrimitiveStyle, @@ -23,6 +25,8 @@ impl Styles { Styles { fill_black: primitive_style!(fill_color = Rgb565::BLACK), text: text_style!(font = ProFont12Point, text_color = Rgb565::WHITE), + text_green: text_style!(font = ProFont12Point, text_color = Rgb565::GREEN), + text_red: text_style!(font = ProFont12Point, text_color = Rgb565::RED), text_big: text_style!(font = ProFont14Point, text_color = Rgb565::WHITE), text_big_black: text_style!(font = ProFont14Point, text_color = Rgb565::BLACK), normal_box: primitive_style!(