diff options
Diffstat (limited to 'sw/picardy/src/main.rs')
-rw-r--r-- | sw/picardy/src/main.rs | 160 |
1 files changed, 98 insertions, 62 deletions
diff --git a/sw/picardy/src/main.rs b/sw/picardy/src/main.rs index ffe5a47..a6a3e4a 100644 --- a/sw/picardy/src/main.rs +++ b/sw/picardy/src/main.rs @@ -60,14 +60,18 @@ struct SharedWithISR { state : State, last_sequence_state_change : u32, cw_ptt_timestamp : u32, + cw_key_n : gpio::gpioa::PA15<gpio::Output<gpio::OpenDrain>>, ui : ui::UI, cw_pwm: cw::CWPWM, + cw_keyer: cw::Keyer, cw_paddle_tip: gpio::gpiob::PB8<gpio::Input<gpio::PullUp>>, + cw_paddle_ring: gpio::gpiob::PB9<gpio::Input<gpio::PullUp>>, seq0n: gpio::gpiob::PB3<gpio::Output<gpio::PushPull>>, seq1_pa: gpio::gpiob::PB4<gpio::Output<gpio::PushPull>>, seq2_switch: gpio::gpiob::PB5<gpio::Output<gpio::PushPull>>, mute_spkr : gpio::gpioa::PA2<gpio::Output<gpio::PushPull>>, mute_micn : gpio::gpioa::PA1<gpio::Output<gpio::PushPull>>, + led : gpio::gpiob::PB14<gpio::Output<gpio::PushPull>>, } static mut SHARED: MaybeUninit<SharedWithISR> = MaybeUninit::uninit(); @@ -114,14 +118,15 @@ fn main() -> ! { let adc1 = dp.ADC1; let ui = ui::UI::new(mic_sw1, mic_sw2, pb0, pb1, adc1, &mut rcc.apb2, &clocks, pb12, pb13, pc15); - let (cw_pwm, cw_paddle_tip) = { + let cw_pwm = { let pa8 = gpioa.pa8.into_alternate_push_pull(&mut gpioa.crh); // CW PWM output using TIM1 Ch1 let tim1 = Timer::tim1(dp.TIM1, &clocks, &mut rcc.apb2); - let cw_pwm = cw::CWPWM::new(pa8, tim1, &mut afio.mapr); - let cw_paddle_tip = gpiob.pb8.into_pull_up_input(&mut gpiob.crh); // CW paddle tip - (cw_pwm, cw_paddle_tip) + cw::CWPWM::new(pa8, tim1, &mut afio.mapr) }; + let cw_paddle_tip = gpiob.pb8.into_pull_up_input(&mut gpiob.crh); // CW paddle tip + let cw_paddle_ring = gpiob.pb9.into_pull_up_input(&mut gpiob.crh); // CW paddle ring + let mut s_meter = gpioa.pa5.into_analog(&mut gpioa.crl); let mut adc2 = adc::Adc::adc2(dp.ADC2, &mut rcc.apb2, clocks); let mut last_s_meter_update_time = 0; @@ -131,7 +136,7 @@ fn main() -> ! { led.set_low().unwrap(); let (pa15, pb3, pb4) = afio.mapr.disable_jtag(gpioa.pa15, gpiob.pb3, gpiob.pb4); - let _cw_key_n = pa15.into_push_pull_output_with_state(&mut gpioa.crh, gpio::State::High); // TODO output + let cw_key_n = pa15.into_open_drain_output_with_state(&mut gpioa.crh, gpio::State::High); let seq0n = pb3.into_push_pull_output_with_state(&mut gpiob.crl, gpio::State::High); let seq1_pa = pb4.into_push_pull_output_with_state(&mut gpiob.crl, gpio::State::Low); @@ -215,9 +220,11 @@ fn main() -> ! { state : State::new(), last_sequence_state_change : 0, cw_ptt_timestamp : 0, + cw_key_n, ui, cw_pwm, - cw_paddle_tip, seq0n, seq1_pa, seq2_switch, mute_spkr, mute_micn + cw_keyer : cw::Keyer::new(12, TICKS_PER_SECOND), + cw_paddle_tip, cw_paddle_ring, seq0n, seq1_pa, seq2_switch, mute_spkr, mute_micn, led }; si_clock::SiClock::new(i2c_busmanager.acquire_i2c(), shared.state.bfo(), shared.state.vfo()) @@ -243,15 +250,15 @@ fn main() -> ! { unsafe { pac::NVIC::unmask(pac::Interrupt::TIM2); } let mut last_disp_update_counter = 1; + let mut previous_vfo = 0; + let mut previous_bfo = 0; + loop { let mut update_disp_required = false; let mut bfo_tune_fail = false; let state = get_state_copy(); - let previous_vfo = state.vfo(); - let previous_bfo = state.bfo(); - let encoder_count : u16 = qei.count(); if encoder_count != last_encoder_count { let delta = encoder_count.wrapping_sub(last_encoder_count); @@ -259,7 +266,11 @@ fn main() -> ! { let require_bfo_update = cortex_m::interrupt::free(|_cs| { let shared = unsafe { &mut *SHARED.as_mut_ptr() }; - shared.ui.update_encoder(&mut shared.state, delta) + let r = shared.ui.update_encoder(&mut shared.state, delta); + if let Mode::CW(CWMode::Iambic) = shared.state.mode { + shared.cw_keyer.set_speed(shared.state.cw_wpm, TICKS_PER_SECOND) + } + r }); if require_bfo_update { @@ -269,23 +280,17 @@ fn main() -> ! { update_disp_required = true; } - if previous_bfo != state.bfo() { - bfo_tune_fail = !siclock.set_bfo(state.bfo()).is_ok(); + let bfo = state.bfo(); + if previous_bfo != bfo { + bfo_tune_fail = !siclock.set_bfo(bfo).is_ok(); } + previous_bfo = bfo; - if previous_vfo != state.vfo() { - siclock.set_vfo(state.vfo()); - } - - match state.sequence_state { - SequenceState::Rx => { - led.set_high().unwrap(); - }, - SequenceState::Switching => {} - SequenceState::Tx => { - led.set_low().unwrap(); - } + let vfo = state.vfo(); + if previous_vfo != vfo { + siclock.set_vfo(vfo); } + previous_vfo = vfo; let s_meter_value: u16 = adc2.read(&mut s_meter).unwrap(); @@ -333,22 +338,27 @@ fn TIM2() { } let cw_paddle_tip_low = shared.cw_paddle_tip.is_low().unwrap(); - - const CW_PTT_DELAY : u32 = TICKS_PER_SECOND * 800 / 1000; - let cw_ptt = if shared.state.mode == Mode::CW { - if cw_paddle_tip_low { - shared.cw_ptt_timestamp = *ticks; - true - } - else { - shared.cw_ptt_timestamp + CW_PTT_DELAY > *ticks - } - } - else { - false + let cw_paddle_ring_low = shared.cw_paddle_ring.is_low().unwrap(); + + let cw_ptt_delay : u32 = TICKS_PER_SECOND * 800 / 1000; + let cw_ptt = match shared.state.mode { + Mode::CW(_) => { + if cw_paddle_tip_low || cw_paddle_ring_low { + shared.cw_ptt_timestamp = *ticks; + true + } + else { + shared.cw_ptt_timestamp + cw_ptt_delay > *ticks + } + }, + _ => false, }; - let cw_beep = shared.state.mode == Mode::CW && cw_paddle_tip_low; + let cw_beep = 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 next_state = match shared.state.sequence_state { SequenceState::Rx => { @@ -356,60 +366,86 @@ fn TIM2() { shared.mute_micn.set_low().unwrap(); shared.seq2_switch.set_low().unwrap(); shared.seq0n.set_high().unwrap(); - shared.cw_pwm.off(); - - if button_result.ptt || cw_ptt { - SequenceState::Switching + if button_result.ptt { + SequenceState::SwitchingSSB + } + else if cw_ptt { + SequenceState::SwitchingCW } else { SequenceState::Rx } }, - SequenceState::Switching => { + SequenceState::SwitchingSSB => { shared.mute_spkr.set_high().unwrap(); shared.seq2_switch.set_high().unwrap(); shared.seq0n.set_low().unwrap(); shared.seq1_pa.set_low().unwrap(); + shared.mute_micn.set_high().unwrap(); - if cw_beep { - shared.cw_pwm.on(); + if button_result.ptt { + SequenceState::TxSSB } else { - shared.cw_pwm.off(); - } - - if button_result.ptt { - shared.mute_micn.set_high().unwrap(); - SequenceState::Tx + SequenceState::Rx } - else if cw_ptt { - shared.mute_micn.set_low().unwrap(); - SequenceState::Tx + }, + SequenceState::SwitchingCW => { + shared.mute_spkr.set_high().unwrap(); + shared.seq2_switch.set_high().unwrap(); + shared.seq0n.set_low().unwrap(); + shared.seq1_pa.set_low().unwrap(); + shared.mute_micn.set_low().unwrap(); + if cw_ptt { + SequenceState::TxCW } else { SequenceState::Rx } }, - SequenceState::Tx => { + SequenceState::TxSSB => { shared.seq1_pa.set_high().unwrap(); - if cw_beep { - shared.cw_pwm.on(); + if button_result.ptt { + SequenceState::TxSSB } else { - shared.cw_pwm.off(); + SequenceState::SwitchingSSB } + }, + SequenceState::TxCW => { + shared.seq1_pa.set_high().unwrap(); - if button_result.ptt || cw_ptt { - SequenceState::Tx + if cw_ptt { + SequenceState::TxCW } else { - SequenceState::Switching + SequenceState::SwitchingCW } }, }; - const SWITCHING_DELAY : u32 = TICKS_PER_SECOND * 20 / 1000; + match shared.state.sequence_state { + SequenceState::TxCW => { + if cw_beep { + shared.led.set_low().unwrap(); + shared.cw_pwm.on(); + shared.cw_key_n.set_low().unwrap(); + } + else { + shared.led.set_high().unwrap(); + shared.cw_pwm.off(); + shared.cw_key_n.set_high().unwrap(); + } + }, + _ => { + shared.led.set_high().unwrap(); + shared.cw_pwm.off(); + shared.cw_key_n.set_high().unwrap(); + }, + } + + const SWITCHING_DELAY : u32 = TICKS_PER_SECOND * 40 / 1000; if shared.state.sequence_state != next_state && shared.last_sequence_state_change + SWITCHING_DELAY <= *ticks { shared.state.sequence_state = next_state; |