use cortex_m::{asm::wfi, prelude::*}; use embedded_hal::digital::v2::{OutputPin, ToggleableOutputPin}; use nb::{self, block}; use nmea0183::{ParseResult, Parser}; use stm32f1xx_hal::{ delay::Delay, gpio::{gpiob, gpioc, Alternate, Floating, Input, OpenDrain, Output, PushPull}, i2c::BlockingI2c, pac::I2C1, prelude::*, serial::Serial, stm32, }; mod gps; mod setup; //use crate::exit; pub use setup::setup; use crate::si5153; use crate::time; use crate::wspr; pub struct App { delay: Delay, board_led: gpioc::PC13>, serial: Serial< stm32::USART3, ( gpiob::PB10>, gpiob::PB11>, ), >, i2c: BlockingI2c< I2C1, ( gpiob::PB6>, gpiob::PB7>, ), >, gps_parser: Parser, locator: arrayvec::ArrayString<6>, } // For PLL with 800MHz const WSPR_SYMBOLS: [si5153::PllParams; 4] = [ // 7040100.000000: 113 + 44687 / 70401 // actual: 7040100.000000 si5153::PllParams { p1: 14033, p2: 17455, p3: 70401, }, // 7040101.464844: 113 + 447801 / 705503 // actual: 7040101.464844 si5153::PllParams { p1: 14033, p2: 172785, p3: 705503, }, // 7040102.929688: 113 + 38515 / 60682 // actual: 7040102.929688 si5153::PllParams { p1: 14033, p2: 14678, p3: 60682, }, // 7040104.394531: 113 + 123233 / 194166 // actual: 7040104.394531 si5153::PllParams { p1: 14033, p2: 46378, p3: 194166, }, ]; impl App { pub fn run(mut self) -> ! { let callsign = arrayvec::ArrayString::<6>::from("DL1SSK").unwrap(); defmt::info!("Application Startup!"); let mut si_pll = si5153::Si5153::new(&self.i2c); si_pll.init(&mut self.i2c, 25000000, 800000000, 800000000); si_pll.set_ms_source(&mut self.i2c, si5153::Multisynth::MS0, si5153::PLL::A); defmt::info!("PLL setup complete."); let mut transmitting = false; let mut symbol_start = time::get(); let mut symbol_idx: usize = 0; let mut message: [u8; 162] = [0; 162]; loop { self.poll_gps(); if !transmitting { let ts = time::get(); if self.locator.len() > 0 && ts.minutes % 2 == 0 && ts.seconds > 1.0 && ts.seconds < 2.0 { defmt::info!("Starting tranmission"); message = wspr::encode_message(&callsign, &self.locator, 27); symbol_start = ts; symbol_idx = 0; si_pll.write_synth_params( &mut self.i2c, si5153::Multisynth::MS0, &WSPR_SYMBOLS[message[symbol_idx] as usize], ); si_pll.enable_ms_output(&mut self.i2c, si5153::Multisynth::MS0); } } else { let ts = time::get(); if (ts.seconds - symbol_start.seconds) >= 0.683 { symbol_start = ts; symbol_idx += 1; if symbol_idx < 162 { si_pll.write_synth_params( &mut self.i2c, si5153::Multisynth::MS0, &WSPR_SYMBOLS[message[symbol_idx] as usize], ); } else { si_pll.disable_ms_output(&mut self.i2c, si5153::Multisynth::MS0); transmitting = false; } } } wfi(); } //exit(); } }