nixie-clock-firmware/src/application/mod.rs

132 lines
3.8 KiB
Rust

use cortex_m::{asm::wfi, prelude::*};
use embedded_hal::digital::v2::{InputPin, OutputPin, ToggleableOutputPin};
use nb::{self, block};
use nmea0183::Parser;
use stm32f1xx_hal::{
delay::Delay,
gpio::{gpioa, gpiob, gpioc, Alternate, Floating, Input, OpenDrain, Output, PushPull},
i2c::BlockingI2c,
pac::I2C1,
pac::SPI1,
prelude::*,
serial::Serial,
spi::{Spi, Spi1NoRemap},
stm32,
};
mod gps;
mod setup;
//use crate::exit;
pub use setup::setup;
use crate::time;
type AppSPI = Spi<
SPI1,
Spi1NoRemap,
(
gpioa::PA5<Alternate<PushPull>>,
gpioa::PA6<Input<Floating>>,
gpioa::PA7<Alternate<PushPull>>,
),
>;
pub struct App {
delay: Delay,
board_led: gpioc::PC13<Output<PushPull>>,
serial: Serial<
stm32::USART1,
(
gpioa::PA9<Alternate<PushPull>>,
gpioa::PA10<Input<Floating>>,
),
>,
gps_parser: Parser,
button1: gpiob::PB0<Input<Floating>>,
button2: gpiob::PB1<Input<Floating>>,
spi: AppSPI,
disp_strobe: gpioa::PA0<Output<PushPull>>,
}
fn fendangle_digit(num: u8) -> u8 {
if num <= 9 {
(9 - num).reverse_bits() >> 4
} else {
15
}
}
impl App {
pub fn run(mut self) -> ! {
defmt::info!("Application Startup!");
let mut cnt = 0;
let mut utc_offset = 2;
let mut prev_button1_state = self.button1.is_high().unwrap();
let mut prev_button2_state = self.button2.is_high().unwrap();
loop {
self.poll_gps();
if prev_button1_state && !self.button1.is_high().unwrap() {
utc_offset = if utc_offset == 0 { 23 } else { utc_offset - 1 };
defmt::info!("Button 1 pressed, new offset: {}", utc_offset);
}
if prev_button2_state && !self.button2.is_high().unwrap() {
utc_offset = if utc_offset == 23 { 0 } else { utc_offset + 1 };
defmt::info!("Button 2 pressed, new offset: {}", utc_offset);
}
prev_button1_state = self.button1.is_high().unwrap();
prev_button2_state = self.button2.is_high().unwrap();
if cnt >= 250 {
let mut time = time::get();
time.hours = (time.hours + utc_offset) % 24;
let hours_high = (time.hours as u8) / 10;
let hours_low = (time.hours as u8) % 10;
let minutes_high = (time.minutes as u8) / 10;
let minutes_low = (time.minutes as u8) % 10;
let seconds_high = (time.seconds as u8) / 10;
let seconds_low = (time.seconds as u8) % 10;
defmt::info!(
"Display Time: {} {} : {} {} : {} {}",
hours_high,
hours_low,
minutes_high,
minutes_low,
seconds_high,
seconds_low
);
let hours_byte = fendangle_digit(hours_high) << 4 | fendangle_digit(hours_low);
let minutes_byte =
fendangle_digit(minutes_high) << 4 | fendangle_digit(minutes_low);
let seconds_byte =
fendangle_digit(seconds_high) << 4 | fendangle_digit(seconds_low);
self.spi
.write(&[seconds_byte, minutes_byte, hours_byte])
.unwrap();
defmt::debug!("Bytes: {=[u8]:x}", [hours_byte, minutes_byte, hours_byte]);
self.disp_strobe.set_high().unwrap();
self.delay.delay_ms(1u16);
self.disp_strobe.set_low().unwrap();
//self.board_led.toggle().unwrap();
cnt = 10;
}
cnt += 1;
self.delay.delay_ms(1u16);
}
}
}