145 lines
4.1 KiB
Rust
145 lines
4.1 KiB
Rust
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<Output<PushPull>>,
|
|
serial: Serial<
|
|
stm32::USART3,
|
|
(
|
|
gpiob::PB10<Alternate<PushPull>>,
|
|
gpiob::PB11<Input<Floating>>,
|
|
),
|
|
>,
|
|
i2c: BlockingI2c<
|
|
I2C1,
|
|
(
|
|
gpiob::PB6<Alternate<OpenDrain>>,
|
|
gpiob::PB7<Alternate<OpenDrain>>,
|
|
),
|
|
>,
|
|
gps_parser: Parser,
|
|
locator: arrayvec::ArrayString<6>,
|
|
transmitting: bool,
|
|
}
|
|
|
|
// 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 symbol_start = time::get();
|
|
let mut symbol_idx: usize = 0;
|
|
let mut message: [u8; 162] = [0; 162];
|
|
|
|
loop {
|
|
self.poll_gps();
|
|
|
|
if !self.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");
|
|
self.transmitting = true;
|
|
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();
|
|
let delta_sec = (ts.seconds - symbol_start.seconds)
|
|
+ (ts.minutes - symbol_start.minutes) as f32 * 60.0;
|
|
if delta_sec >= 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],
|
|
);
|
|
defmt::info!("Tranmitting Symbol {}", symbol_idx);
|
|
} else {
|
|
si_pll.disable_ms_output(&mut self.i2c, si5153::Multisynth::MS0);
|
|
self.transmitting = false;
|
|
defmt::info!("Transmission ended");
|
|
}
|
|
}
|
|
}
|
|
//wfi();
|
|
}
|
|
|
|
//exit();
|
|
}
|
|
}
|