Browse Source

Added first draft wspr transmission routine

main
Sebastian 7 months ago
parent
commit
75992bfe79
  1. 92
      src/application/mod.rs
  2. 19
      src/application/setup.rs
  3. 6
      src/si5153.rs
  4. 2
      src/wspr.rs
  5. 2
      testsuite/tests/wspr.rs

92
src/application/mod.rs

@ -1,10 +1,12 @@
use cortex_m::prelude::*;
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, Output, PushPull},
gpio::{gpiob, gpioc, Alternate, Floating, Input, OpenDrain, Output, PushPull},
i2c::BlockingI2c,
pac::I2C1,
prelude::*,
serial::Serial,
stm32,
@ -18,6 +20,28 @@ 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>,
}
// For PLL with 800MHz
const WSPR_SYMBOLS: [si5153::PllParams; 4] = [
@ -51,28 +75,62 @@ const WSPR_SYMBOLS: [si5153::PllParams; 4] = [
},
];
pub struct App {
delay: Delay,
board_led: gpioc::PC13<Output<PushPull>>,
serial: Serial<
stm32::USART3,
(
gpiob::PB10<Alternate<PushPull>>,
gpiob::PB11<Input<Floating>>,
),
>,
gps_parser: Parser,
locator: arrayvec::ArrayString<6>,
}
impl App {
pub fn run(mut self) -> ! {
let callsign = arrayvec::ArrayString::<6>::from("DL1SSK").unwrap();
defmt::info!("Application Startup!");
let mut last_ts = 0;
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();

19
src/application/setup.rs

@ -1,5 +1,6 @@
use stm32f1xx_hal::{
delay::Delay,
i2c,
pac::Interrupt,
prelude::*,
serial::{Config, Serial},
@ -59,12 +60,30 @@ pub fn setup(cp: cortex_m::peripheral::Peripherals, dp: stm32::Peripherals) -> A
let gps_parser = Parser::new();
let scl = gpiob.pb6.into_alternate_open_drain(&mut gpiob.crl);
let sda = gpiob.pb7.into_alternate_open_drain(&mut gpiob.crl);
let mut i2c = i2c::BlockingI2c::i2c1(
dp.I2C1,
(scl, sda),
&mut afio.mapr,
i2c::Mode::Standard {
frequency: 400_000.hz(),
},
clocks,
&mut rcc.apb1,
5,
1,
5,
5,
);
time::setup(dp.TIM2, &clocks, &mut rcc.apb1);
App {
delay,
board_led,
serial,
i2c,
gps_parser,
locator: arrayvec::ArrayString::new(),
}

6
src/si5153.rs

@ -150,7 +150,7 @@ where
}
}
pub fn write_params(&self, i2c: &mut I2C, base: u8, params: &PllParams) {
fn write_params(&self, i2c: &mut I2C, base: u8, params: &PllParams) {
let data: [u8; 9] = [
base,
((params.p3 & 0x00FF00) >> 8) as u8,
@ -168,4 +168,8 @@ where
panic!("i2c write failed. regAdder: {}", base)
}
}
pub fn write_synth_params(&self, i2c: &mut I2C, synth: Multisynth, params: &PllParams) {
self.write_params(i2c, synth.base_address(), params);
}
}

2
src/wspr.rs

@ -128,7 +128,7 @@ fn add_sync(symbols: &mut [u8; WSPR_LENGTH]) {
}
}
pub fn endcode_message(
pub fn encode_message(
call_sign: &arrayvec::ArrayString<6>,
locator: &arrayvec::ArrayString<6>,
power: u8,

2
testsuite/tests/wspr.rs

@ -15,7 +15,7 @@ mod tests {
fn test_encoding() {
let call_sign = ArrayString::<6>::from(" K1ABC").unwrap();
let loc = ArrayString::<6>::from("FN42").unwrap();
let symbols = wspr::endcode_message(&call_sign, &loc, 37);
let symbols = wspr::encode_message(&call_sign, &loc, 37);
let expected_symbols: [u8; 162] = [
3, 3, 0, 0, 2, 0, 0, 0, 1, 0, 2, 0, 1, 3, 1, 2, 2, 2, 1, 0, 0, 3, 2, 3, 1, 3, 3, 2, 2,

Loading…
Cancel
Save