diff --git a/Cargo.toml b/Cargo.toml index 24be7a8..e831977 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,7 @@ stm32l4xx-hal = { version = "0.7.1", features = ["stm32l442", "stm32-usbd"] } rtic-monotonics = { version = "1.0.0", features = ["cortex-m-systick", "systick-100hz"]} thiserror = { version = "1.0.50", package = "thiserror-core", default-features = false } embedded-graphics = "0.8.1" -tinyvec = "1.6.0" +tinyvec = { version = "1.6.0", features = ["rustc_1_55"] } ublox = { version = "0.4.5", default-features = false } nb = "1.1.0" bytemuck = { version = "1.14.3", features = ["derive"] } @@ -23,6 +23,8 @@ usb-device = { version = "0.2.9", features = ["defmt"] } usbd-serial = "0.1.0" # spin = "0.9.8" rtic-sync = "1.3.0" +embedded-text = "0.7.0" +u8g2-fonts = "0.4.0" # cargo build/run [profile.dev] diff --git a/src/bin/minimal.rs b/src/bin/minimal.rs index 2f3f2a0..0f8f7a7 100644 --- a/src/bin/minimal.rs +++ b/src/bin/minimal.rs @@ -25,7 +25,7 @@ use stm32l4xx_hal::serial; use stm32l4xx_hal::serial::Config; use gps_watch::gps::Gps; use embedded_graphics::mono_font::{ascii::FONT_10X20, MonoTextStyle}; -use gps_watch::FmtBuf; +use gps_watch::{FmtBuf, fabs}; use core::num::Wrapping; use embedded_graphics::mono_font::iso_8859_2::FONT_4X6; use hal::pac::{Interrupt, USB}; @@ -54,7 +54,10 @@ type GpsUart = Serial>, PA10 (Shared, Local) { + fn init(mut cx: init::Context) -> (Shared, Local) { trace!("init enter"); // #[cfg(debug_assertions)] @@ -99,8 +102,8 @@ mod app { let mut flash = cx.device.FLASH.constrain(); let mut rcc = cx.device.RCC.constrain(); let mut pwr = cx.device.PWR.constrain(&mut rcc.apb1r1); - // let clocks = rcc.cfgr.lse(CrystalBypass::Disable, ClockSecuritySystem::Disable).freeze(&mut flash.acr, &mut pwr); - let clocks = rcc.cfgr.freeze(&mut flash.acr, &mut pwr); + let clocks = rcc.cfgr.lse(CrystalBypass::Disable, ClockSecuritySystem::Disable).freeze(&mut flash.acr, &mut pwr); + // let clocks = rcc.cfgr.freeze(&mut flash.acr, &mut pwr); // Create SysTick monotonic for task scheduling Systick::start( @@ -135,15 +138,15 @@ mod app { // let display = SharpMemDisplay::new(spi1, cs); // Initialize RTC and interrupts - // let mut rtc = hal::rtc::Rtc::rtc( - // cx.device.RTC, - // &mut rcc.apb1r1, - // &mut rcc.bdcr, - // &mut pwr.cr1, - // RtcConfig::default().clock_config(RtcClockSource::LSE) - // ); - // rtc.wakeup_timer().start(10000u16); - // rtc.listen(&mut cx.device.EXTI, Event::WakeupTimer); + let mut rtc = hal::rtc::Rtc::rtc( + cx.device.RTC, + &mut rcc.apb1r1, + &mut rcc.bdcr, + &mut pwr.cr1, + RtcConfig::default().clock_config(RtcClockSource::LSE) + ); + rtc.wakeup_timer().start(10000u16); + rtc.listen(&mut cx.device.EXTI, Event::WakeupTimer); // rtic::pend(Interrupt::RTC_WKUP); // Initialize UART for GPS @@ -298,11 +301,15 @@ mod app { trace!("display_task enter"); cx.shared.display.lock(|display| display.clear_flush()); + let clock_font = FontRenderer::new::(); + let mut i = Wrapping(0u8); loop { debug!("display_task loop"); // let pos = cx.shared.gps.lock(|gps| gps.position); - let mut txt = FmtBuf(Default::default()); + let mut dbg_txt = FmtBuf::<512>(Default::default()); + let mut time = FmtBuf::<8>(Default::default()); + let mut coords = FmtBuf::<64>(Default::default()); // write!(txt, "Lat: {}\nLon: {}", pos.latitude, pos.longitude).unwrap(); // cx.shared.recv_buf.lock(|(x, started)| { // let _ = write!(txt, "{:x} {x:x?}", x.len()); @@ -310,16 +317,54 @@ mod app { // *started = false; // }); cx.shared.gps.lock(|gps| { - let _ = write!(txt, "{} {:x?}", gps.count, gps.last_packet); + let _ = write!(dbg_txt, "Debug Info:\nReceived {} bytes\nLast Message: {:x?}", gps.count, gps.last_packet); + + let pos = gps.pos(); + let _ = write!(coords, + "{:.4}°{}\n{:.4}°{}", + fabs(pos.0), + if pos.0 >= 0.0 { 'N' } else { 'S' }, + fabs(pos.1), + if pos.1 >= 0.0 { 'E' } else { 'W' } + ); + + let _ = write!(time, "{}:{:02}", gps.time.0-5, gps.time.1); }); // info!("formatted: {}", txt.as_str()); cx.shared.display.lock(|display| { display.clear(); + // Debug infos + TextBox::new( + dbg_txt.as_str().unwrap(), + Rectangle {top_left: Point {x: 5, y: 135}, size: Size {width: 350, height: 100}}, + MonoTextStyle::new(&FONT_6X12, BinaryColor::On) + ).draw(display).unwrap(); + + // Watch UI + Rectangle {top_left: Point {x: 0, y: 0}, size: Size {width: 128, height: 128}} + .into_styled( + PrimitiveStyleBuilder::new() + .stroke_alignment(embedded_graphics::primitives::StrokeAlignment::Inside) + .stroke_color(BinaryColor::On) + .stroke_width(4) + .build() + ).draw(display).unwrap(); + + clock_font.render_aligned( + time.as_str().unwrap(), + Point {x: 64, y: 20}, + u8g2_fonts::types::VerticalPosition::Top, + u8g2_fonts::types::HorizontalAlignment::Center, + u8g2_fonts::types::FontColor::Transparent(BinaryColor::On), + display + ).unwrap(); + Text::new( - txt.as_str().unwrap(), - Point::new(30, 30), - MonoTextStyle::new(&FONT_4X6, BinaryColor::On) + coords.as_str().unwrap(), + Point {x: 20, y: 80}, + MonoTextStyle::new(&FONT_6X12, BinaryColor::On) ).draw(display).unwrap(); + display.flush(); }); @@ -330,7 +375,7 @@ mod app { // rect_styled.draw(display).unwrap(); // display.flush(); // }); - Systick::delay(1000.millis()).await; + Systick::delay(200.millis()).await; i += 1; } } diff --git a/src/gps.rs b/src/gps.rs index 0db7d75..2a58cb2 100644 --- a/src/gps.rs +++ b/src/gps.rs @@ -18,6 +18,7 @@ pub struct Gps { pub parser: UbxParser, pub position: Position, + pub time: (u8, u8, u8), pub last_packet: Result, pub count: usize } @@ -35,6 +36,7 @@ impl Gps let mut s = Self { serial, parser: UbxParser::new(), + time: (10, 10, 0), position: Position { latitude: 0, longitude: 0 }, last_packet: Ok(UbxPacket::OtherPacket), count: 0 @@ -81,9 +83,14 @@ impl Gps if let Ok(UbxPacket::NavPvt(ref navpvt)) = r { self.position.latitude = navpvt.lat; self.position.longitude = navpvt.lon; + self.time = (navpvt.hour, navpvt.min, navpvt.sec); } self.last_packet = r; } } } + + pub fn pos(&self) -> (f32, f32) { + ((self.position.latitude as f32) * 10e-7, (self.position.longitude as f32) * 10e-7) + } } \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 24850e8..5af188d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -36,9 +36,9 @@ pub fn exit() -> ! { } } -pub struct FmtBuf(pub ArrayVec<[u8; 256]>); +pub struct FmtBuf(pub ArrayVec<[u8; N]>); -impl Write for FmtBuf { +impl Write for FmtBuf { fn write_str(&mut self, s: &str) -> fmt::Result { for b in s.bytes() { self.0.try_push(b); @@ -47,8 +47,12 @@ impl Write for FmtBuf { } } -impl FmtBuf { +impl FmtBuf { pub fn as_str(&self) -> Option<&str> { core::str::from_utf8(self.0.as_slice()).ok() } +} + +pub fn fabs(x: f32) -> f32 { + f32::from_bits(x.to_bits() & !(1 << 31)) } \ No newline at end of file diff --git a/src/ubx.rs b/src/ubx.rs index a6b076c..1804df6 100644 --- a/src/ubx.rs +++ b/src/ubx.rs @@ -68,7 +68,8 @@ impl UbxParser { None } else { self.state = Start; - Some(Err(BadStart {expect: 0xb5, saw: b})) + // Some(Err(BadStart {expect: 0xb5, saw: b})) + None }, Sync1 => if b == 0x62 { @@ -94,10 +95,11 @@ impl UbxParser { }, Len1 {class, id, len1, checksum} => { let len = (b as u16) << 8 | (len1 as u16); - self.state = Len2 {class, id, len, checksum: checksum.next(b)}; if len as usize > UBX_BUF_SIZE { + self.state = Start; Some(Err(TooLarge(len))) } else { + self.state = Len2 {class, id, len, checksum: checksum.next(b)}; None } }, diff --git a/stm32l4xx-hal/src/rtc.rs b/stm32l4xx-hal/src/rtc.rs index 8f9e6b1..a3e0d23 100644 --- a/stm32l4xx-hal/src/rtc.rs +++ b/stm32l4xx-hal/src/rtc.rs @@ -610,7 +610,7 @@ impl timer::CountDown for WakeupTimer<'_> { // Let's wait for WUTWF to clear. Otherwise we might run into a race // condition, if the user calls this method again really quickly. - while rtc_registers::is_wakeup_timer_write_flag_set(&self.rtc.rtc) {} + // while rtc_registers::is_wakeup_timer_write_flag_set(&self.rtc.rtc) {} } fn wait(&mut self) -> nb::Result<(), Void> {