Added first draft wspr transmission routine
This commit is contained in:
parent
37cc576678
commit
75992bfe79
|
@ -1,10 +1,12 @@
|
||||||
use cortex_m::prelude::*;
|
use cortex_m::{asm::wfi, prelude::*};
|
||||||
use embedded_hal::digital::v2::{OutputPin, ToggleableOutputPin};
|
use embedded_hal::digital::v2::{OutputPin, ToggleableOutputPin};
|
||||||
use nb::{self, block};
|
use nb::{self, block};
|
||||||
use nmea0183::{ParseResult, Parser};
|
use nmea0183::{ParseResult, Parser};
|
||||||
use stm32f1xx_hal::{
|
use stm32f1xx_hal::{
|
||||||
delay::Delay,
|
delay::Delay,
|
||||||
gpio::{gpiob, gpioc, Alternate, Floating, Input, Output, PushPull},
|
gpio::{gpiob, gpioc, Alternate, Floating, Input, OpenDrain, Output, PushPull},
|
||||||
|
i2c::BlockingI2c,
|
||||||
|
pac::I2C1,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
serial::Serial,
|
serial::Serial,
|
||||||
stm32,
|
stm32,
|
||||||
|
@ -18,6 +20,28 @@ pub use setup::setup;
|
||||||
|
|
||||||
use crate::si5153;
|
use crate::si5153;
|
||||||
use crate::time;
|
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
|
// For PLL with 800MHz
|
||||||
const WSPR_SYMBOLS: [si5153::PllParams; 4] = [
|
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 {
|
impl App {
|
||||||
pub fn run(mut self) -> ! {
|
pub fn run(mut self) -> ! {
|
||||||
|
let callsign = arrayvec::ArrayString::<6>::from("DL1SSK").unwrap();
|
||||||
|
|
||||||
defmt::info!("Application Startup!");
|
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 {
|
loop {
|
||||||
self.poll_gps();
|
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();
|
//exit();
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use stm32f1xx_hal::{
|
use stm32f1xx_hal::{
|
||||||
delay::Delay,
|
delay::Delay,
|
||||||
|
i2c,
|
||||||
pac::Interrupt,
|
pac::Interrupt,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
serial::{Config, Serial},
|
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 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);
|
time::setup(dp.TIM2, &clocks, &mut rcc.apb1);
|
||||||
|
|
||||||
App {
|
App {
|
||||||
delay,
|
delay,
|
||||||
board_led,
|
board_led,
|
||||||
serial,
|
serial,
|
||||||
|
i2c,
|
||||||
gps_parser,
|
gps_parser,
|
||||||
locator: arrayvec::ArrayString::new(),
|
locator: arrayvec::ArrayString::new(),
|
||||||
}
|
}
|
||||||
|
|
|
@ -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] = [
|
let data: [u8; 9] = [
|
||||||
base,
|
base,
|
||||||
((params.p3 & 0x00FF00) >> 8) as u8,
|
((params.p3 & 0x00FF00) >> 8) as u8,
|
||||||
|
@ -168,4 +168,8 @@ where
|
||||||
panic!("i2c write failed. regAdder: {}", base)
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>,
|
call_sign: &arrayvec::ArrayString<6>,
|
||||||
locator: &arrayvec::ArrayString<6>,
|
locator: &arrayvec::ArrayString<6>,
|
||||||
power: u8,
|
power: u8,
|
||||||
|
|
|
@ -15,7 +15,7 @@ mod tests {
|
||||||
fn test_encoding() {
|
fn test_encoding() {
|
||||||
let call_sign = ArrayString::<6>::from(" K1ABC").unwrap();
|
let call_sign = ArrayString::<6>::from(" K1ABC").unwrap();
|
||||||
let loc = ArrayString::<6>::from("FN42").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] = [
|
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,
|
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…
Reference in New Issue