From d45189798c160cee329b7c59636b0caf538244f6 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Wed, 31 Jan 2024 23:18:07 +0100 Subject: DART-70: get VOX and CW working --- sw/dart-70/src/cw.rs | 2 ++ sw/dart-70/src/main.rs | 92 ++++++++++++++++++++++++++++++++++++++++++------- sw/dart-70/src/state.rs | 33 +++++++----------- sw/dart-70/src/ui.rs | 26 ++++++++++---- 4 files changed, 113 insertions(+), 40 deletions(-) (limited to 'sw') diff --git a/sw/dart-70/src/cw.rs b/sw/dart-70/src/cw.rs index 4656f81..7ff8c05 100644 --- a/sw/dart-70/src/cw.rs +++ b/sw/dart-70/src/cw.rs @@ -5,6 +5,7 @@ use stm32f1xx_hal::{ pac::TIM1, }; +/* const CW_MAPPING : [u8; 50] = [ //{{{ // Read bits from right to left @@ -69,6 +70,7 @@ const CW_MAPPING : [u8; 50] = [ //{{{ ]; //}}} const CW_MACRO : &[u8; 28] = b"CQ DE HB9EGM HB9EGM HB9EGM K"; +*/ pub const SIDETONE_FREQ : u32 = 800; diff --git a/sw/dart-70/src/main.rs b/sw/dart-70/src/main.rs index 77f6044..7967b23 100644 --- a/sw/dart-70/src/main.rs +++ b/sw/dart-70/src/main.rs @@ -58,7 +58,7 @@ struct SharedWithISR { state: State, last_sequence_state_change: u32, cw_ptt_timestamp: u32, - cw_key_n: gpio::gpioa::PA15>, + cw_key_n: gpio::gpioa::PA15>, ui: ui::UI, cw_pwm: cw::CWPWM, cw_keyer: cw::Keyer, @@ -70,6 +70,7 @@ struct SharedWithISR { mute_spkr: gpio::gpioa::PA2>, mute_micn: gpio::gpioa::PA1>, led: gpio::gpiob::PB14>, + vox_ptt_n : gpio::gpioa::PA0>, } static mut SHARED: MaybeUninit = MaybeUninit::uninit(); @@ -116,7 +117,7 @@ fn main() -> ! { let btn2 = gpiob.pb12.into_floating_input(&mut gpiob.crh); // BTN2 Button C let btn3 = gpiob.pb13.into_floating_input(&mut gpiob.crh); // BTN3 Button D let pc15 = gpioc.pc15.into_floating_input(&mut gpioc.crh); // ENC BTN - let ui = ui::UI::new(mic_ptt, vox_ptt_n, btn0, btn1, btn2, btn3, pc15); + let ui = ui::UI::new(mic_ptt, btn0, btn1, btn2, btn3, pc15); let cw_pwm = { let pa8 = gpioa.pa8.into_alternate_push_pull(&mut gpioa.crh); // CW PWM output using TIM1 Ch1 @@ -137,7 +138,7 @@ fn main() -> ! { led.set_low(); let (pa15, pb3, pb4) = afio.mapr.disable_jtag(gpioa.pa15, gpiob.pb3, gpiob.pb4); - let cw_key_n = pa15.into_open_drain_output_with_state(&mut gpioa.crh, PinState::High); + let cw_key_n = pa15.into_push_pull_output_with_state(&mut gpioa.crh, PinState::High); let en_pa = pb3.into_push_pull_output_with_state(&mut gpiob.crl, PinState::Low); let en_rx = pb4.into_push_pull_output_with_state(&mut gpiob.crl, PinState::Low); @@ -223,7 +224,7 @@ fn main() -> ! { ui, cw_pwm, cw_keyer : cw::Keyer::new(12, TICKS_PER_SECOND), - cw_paddle_tip, cw_paddle_ring, en_pa, en_rx, en_tx, mute_spkr, mute_micn, led + cw_paddle_tip, cw_paddle_ring, en_pa, en_rx, en_tx, mute_spkr, mute_micn, led, vox_ptt_n }; si_clock::SiClock::new(i2c_busmanager.acquire_i2c(), shared.state.bfo(), shared.state.vfo()) @@ -322,6 +323,7 @@ fn s_meter_from_adc(adc : u16) -> u8 { // ADC is 12-bit, convert to dB full-scale let adc_db = 10f32 * log10f::log10f(adc / 4092f32); + /* /* Hand-calibrated lookup table */ if adc_db <= -35f32 { 1 @@ -340,6 +342,17 @@ fn s_meter_from_adc(adc : u16) -> u8 { } else { 9 + } */ + + let fake_s = -adc_db; + if fake_s < 0.0 { + 0 + } + else if fake_s > 255.0 { + 255 + } + else { + fake_s as u8 } } @@ -351,7 +364,7 @@ fn TIM2() { let ticks = unsafe { &mut *TICK_COUNTER.as_mut_ptr() }; *ticks += 1; - let mut shared = unsafe { &mut *SHARED.as_mut_ptr() }; + let shared = unsafe { &mut *SHARED.as_mut_ptr() }; let button_result = shared.ui.handle_buttons(&mut shared.state); if button_result.display_update { @@ -380,12 +393,21 @@ fn TIM2() { _ => false, }; - let cw_beep = shared.state.send_tone || + let cw_beep = if shared.state.send_tone { + shared.cw_keyer.tick(*ticks, false, true) + } + else { match shared.state.mode { Mode::CW(CWMode::StraightKey) => cw_paddle_tip_low, Mode::CW(CWMode::Iambic) => shared.cw_keyer.tick(*ticks, cw_paddle_tip_low, cw_paddle_ring_low), _ => false, - }; + } + }; + + let dig_ptt = match shared.state.mode { + Mode::DIG => shared.vox_ptt_n.is_low(), + _ => false, + }; let next_state = match shared.state.sequence_state { SequenceState::Rx => { @@ -394,7 +416,15 @@ fn TIM2() { shared.en_rx.set_high(); shared.en_tx.set_low(); shared.en_pa.set_low(); - if button_result.ptt || cw_ptt { + shared.led.set_high(); + + let mode_relevant_ptt = match shared.state.mode { + Mode::CW(_) => cw_ptt, + Mode::DIG => dig_ptt, + _ => button_result.ptt, + }; + + if mode_relevant_ptt { SequenceState::MutingSpkr } else { @@ -413,6 +443,9 @@ fn TIM2() { else if cw_ptt { SequenceState::SwitchingCW } + else if dig_ptt { + SequenceState::SwitchingDIG + } else { SequenceState::Rx } @@ -444,10 +477,25 @@ fn TIM2() { SequenceState::Rx } }, + SequenceState::SwitchingDIG => { + shared.mute_spkr.set_high(); + shared.en_rx.set_low(); + shared.en_tx.set_high(); + shared.en_pa.set_low(); + shared.mute_micn.set_high(); + + if dig_ptt { + SequenceState::TxDIG + } + else { + SequenceState::Rx + } + }, SequenceState::TxSSB => { shared.en_rx.set_low(); shared.en_tx.set_high(); shared.en_pa.set_high(); + shared.led.set_low(); if button_result.ptt { SequenceState::TxSSB @@ -457,10 +505,19 @@ fn TIM2() { } }, SequenceState::TxCW => { + shared.mute_spkr.set_low(); shared.en_rx.set_low(); shared.en_tx.set_high(); shared.en_pa.set_high(); + if cw_beep { + shared.led.set_low(); + } + else { + shared.led.set_high(); + } + + if cw_ptt { SequenceState::TxCW } @@ -468,29 +525,40 @@ fn TIM2() { SequenceState::SwitchingCW } }, + SequenceState::TxDIG => { + shared.mute_spkr.set_high(); + shared.en_rx.set_low(); + shared.en_tx.set_high(); + shared.en_pa.set_high(); + shared.led.set_low(); + + if dig_ptt { + SequenceState::TxDIG + } + else { + SequenceState::SwitchingDIG + } + }, }; match shared.state.sequence_state { SequenceState::TxCW => { if cw_beep { - shared.led.set_low(); shared.cw_pwm.on(); shared.cw_key_n.set_low(); } else { - shared.led.set_high(); shared.cw_pwm.off(); shared.cw_key_n.set_high(); } }, _ => { - shared.led.set_high(); shared.cw_pwm.off(); shared.cw_key_n.set_high(); }, } - const SWITCHING_DELAY : u32 = TICKS_PER_SECOND * 80 / 1000; + const SWITCHING_DELAY : u32 = TICKS_PER_SECOND * 20 / 1000; if shared.state.sequence_state != next_state && shared.last_sequence_state_change + SWITCHING_DELAY <= *ticks { shared.state.sequence_state = next_state; diff --git a/sw/dart-70/src/state.rs b/sw/dart-70/src/state.rs index d5d4bf3..ffde88a 100644 --- a/sw/dart-70/src/state.rs +++ b/sw/dart-70/src/state.rs @@ -1,5 +1,6 @@ pub const VHF_BAND_EDGE : u32 = 70_000_000; pub const VHF_INITIAL_VFO : u32 = 70_200_000; +pub const VFO_FREQ_ERROR : i32 = 2_000; // measured at 70.2 MHz // Values below are measured with the assembled XTAL filter pub const XTAL_FILT_FREQ : u32 = 11_057_500; pub const BFO_LSB : u32 = XTAL_FILT_FREQ + 1_400; @@ -38,6 +39,7 @@ pub enum Mode { USB, CustomShift(u32), CW(CWMode), + DIG, } #[derive(Clone, PartialEq, Eq)] @@ -48,6 +50,8 @@ pub enum SequenceState { TxSSB, SwitchingCW, TxCW, + SwitchingDIG, + TxDIG, } impl SequenceState { @@ -89,19 +93,12 @@ impl State { } pub fn bfo(&self) -> u32 { - if self.send_tone { - 0 - } - else { - match self.mode { - Mode::LSB => BFO_LSB, - Mode::USB => BFO_USB, - Mode::CustomShift(fs) => fs, - Mode::CW(_) => match self.sequence_state { - SequenceState::SwitchingCW | SequenceState::TxCW => 0, - _ => BFO_CW, - }, - } + match self.mode { + Mode::LSB => BFO_LSB, + Mode::USB => BFO_USB, + Mode::CustomShift(fs) => fs, + Mode::CW(_) => BFO_CW, + Mode::DIG => BFO_USB, } } @@ -113,14 +110,8 @@ impl State { } pub fn vfo(&self) -> u32 { - let cw_offset = match self.sequence_state { - SequenceState::SwitchingCW | SequenceState::TxCW => 500, - _ => 0, - }; - - let vfo = (self.vhf_qrg() - self.bfo()) as i32 + - if self.sequence_state.apply_rit() { self.rit } else { 0 } + - cw_offset; + let vfo = (self.vhf_qrg() - self.bfo()) as i32 + VFO_FREQ_ERROR + + if self.sequence_state.apply_rit() { self.rit } else { 0 }; vfo as u32 } } diff --git a/sw/dart-70/src/ui.rs b/sw/dart-70/src/ui.rs index f607b2b..9db2988 100644 --- a/sw/dart-70/src/ui.rs +++ b/sw/dart-70/src/ui.rs @@ -31,7 +31,7 @@ use stm32f1xx_hal::{ gpio::gpioa::*, gpio::gpiob::*, gpio::gpioc::*, - gpio::{Input, PullUp, Floating}, + gpio::{Input, Floating}, }; use embedded_hal::blocking::delay::{DelayMs, DelayUs}; @@ -104,7 +104,6 @@ pub struct UI { btn_enc : PC15>, mic_ptt : PA3>, - _vox_ptt_n : PA0>, previous_button_state : ButtonState, } @@ -112,7 +111,6 @@ pub struct UI { impl UI { pub fn new( mic_ptt: PA3>, - vox_ptt_n: PA0>, btn0: PB1>, btn1: PB0>, btn2: PB12>, @@ -126,7 +124,6 @@ impl UI { btn3, btn_enc, mic_ptt, - _vox_ptt_n: vox_ptt_n, previous_button_state: ButtonState::default(), } } @@ -189,8 +186,9 @@ impl UI { (UISelection::Mode, Mode::USB) => (UISelection::Mode, Mode::LSB), (UISelection::Mode, Mode::LSB) => (UISelection::Mode, Mode::CW(CWMode::StraightKey)), (UISelection::Mode, Mode::CW(CWMode::StraightKey)) => (UISelection::Mode, Mode::CW(CWMode::Iambic)), - (UISelection::Mode, Mode::CW(CWMode::Iambic)) => (UISelection::Mode, Mode::USB), - (UISelection::Mode, Mode::CustomShift(_)) => (UISelection::Mode, Mode::USB), + (UISelection::Mode, Mode::CW(CWMode::Iambic)) => (UISelection::Mode, Mode::DIG), + (UISelection::Mode, Mode::CustomShift(_)) => (UISelection::Mode, Mode::DIG), + (UISelection::Mode, Mode::DIG) => (UISelection::Mode, Mode::USB), (_, f) => (UISelection::Mode, f), }; @@ -322,7 +320,20 @@ pub fn update_disp + DelayMs "Rx", + SequenceState::MutingSpkr => "Ms", + SequenceState::SwitchingSSB => "Ss", + SequenceState::TxSSB => "Ts", + SequenceState::SwitchingCW => "Sc", + SequenceState::TxCW => "Tc", + SequenceState::SwitchingDIG => "Sd", + SequenceState::TxDIG => "Td", + }).unwrap(); + */ } lcd.set_cursor_pos(0, delay).unwrap(); @@ -348,6 +359,7 @@ pub fn update_disp + DelayMs "IFs", Mode::CW(CWMode::StraightKey) => "CWs", Mode::CW(CWMode::Iambic) => "CWp", + Mode::DIG => "DIG", }; write!(string, "{} 1/2", mode).unwrap(); -- cgit v1.2.3