From 03ad81d7afaea119df607b6e65f19bd5362fab39 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Thu, 15 Apr 2021 13:07:56 +0200 Subject: Get FELDHELL to work --- sw/eval-clock-cw-tx/src/main.rs | 82 +++++++++++++++++++++++++++++------------ 1 file changed, 59 insertions(+), 23 deletions(-) (limited to 'sw/eval-clock-cw-tx/src/main.rs') diff --git a/sw/eval-clock-cw-tx/src/main.rs b/sw/eval-clock-cw-tx/src/main.rs index a548f81..0d70630 100644 --- a/sw/eval-clock-cw-tx/src/main.rs +++ b/sw/eval-clock-cw-tx/src/main.rs @@ -47,10 +47,10 @@ use hd44780_driver::{Cursor, CursorBlink, Display, DisplayMode, HD44780}; pub mod ui; pub mod usb; +pub mod feldhell_font; pub mod cw; pub mod state; pub mod si_clock; -pub mod log10f; use state::*; @@ -59,6 +59,7 @@ const TICKS_PER_SECOND : u32 = 100; struct SharedWithISR { state : State, last_sequence_state_change : u32, + feldhell_ptt : bool, cw_ptt_timestamp : u32, cw_key_out_n : gpio::gpioa::PA15>, ui : ui::UI, @@ -78,12 +79,6 @@ fn _ticks_now() -> u32 { cortex_m::interrupt::free(|_cs| unsafe { *TICK_COUNTER.as_ptr() }) } -fn get_state_copy() -> State { - cortex_m::interrupt::free(|_cs| unsafe { - (*SHARED.as_ptr()).state.clone() - }) -} - #[cortex_m_rt::entry] fn main() -> ! { let cp = cortex_m::Peripherals::take().unwrap(); @@ -109,9 +104,14 @@ fn main() -> ! { let mut gpiob = dp.GPIOB.split(&mut rcc.apb2); let mut gpioc = dp.GPIOC.split(&mut rcc.apb2); + let mut timer4 = Timer::tim4(dp.TIM4, &clocks, &mut rcc.apb1) + .start_count_down(usb::TIMER_FREQ_HZ.hz()); + timer4.listen(Event::Update); + let usb_dm = gpioa.pa11; let usb_dp = gpioa.pa12.into_floating_input(&mut gpioa.crh); - let usb = usb::USB::new(dp.USB, usb_dm, usb_dp); + let mut usb = usb::USBData::new(timer4, dp.USB, usb_dm, usb_dp); + usb::enable_interrupts(); // Buttons as analog inputs (multi-level) let pb0 = gpiob.pb0.into_floating_input(&mut gpiob.crl); // BTN1 Button B, has external pullup @@ -184,13 +184,12 @@ fn main() -> ! { lcd.write_str(" 30m CW TX 2021 ", &mut delay).unwrap(); delay.delay_ms(1_500u16); - usb.enable_interrupts(); - let mut siclock = { let shared = unsafe { &mut *SHARED.as_mut_ptr() }; *shared = SharedWithISR { state : State::new(), last_sequence_state_change : 0, + feldhell_ptt : false, cw_ptt_timestamp : 0, cw_key_out_n, ui, @@ -202,7 +201,7 @@ fn main() -> ! { si_clock::SiClock::new(i2c_busmanager.acquire_i2c(), 0, shared.state.vfo_display()) }; - ui::update_disp(&mut lcd, &get_state_copy(), &mut delay); + ui::update_disp(&mut lcd, unsafe { &(*SHARED.as_ptr()).state }, &mut delay); let mut last_encoder_count = qei.count(); @@ -221,13 +220,31 @@ fn main() -> ! { unsafe { pac::NVIC::unmask(pac::Interrupt::TIM2); } let mut last_disp_update_counter = 1; + let mut previous_usb_freq = usb.frequency; let mut previous_vfo = 0; let mut previous_state = SequenceState::Rx; loop { let mut update_disp_required = false; - let state = get_state_copy(); + usb.handle(); + + if previous_usb_freq != usb.frequency { + previous_usb_freq = usb.frequency; + + cortex_m::interrupt::free(|_cs| { + let shared = unsafe { &mut *SHARED.as_mut_ptr() }; + shared.state.set_vfo(usb.frequency); + }); + + update_disp_required = true; + } + + let state = cortex_m::interrupt::free(|_cs| unsafe { + let shared = SHARED.as_mut_ptr(); + (*shared).feldhell_ptt = usb.is_transmit(); + (*shared).state.clone() + }); let encoder_count : u16 = qei.count(); if encoder_count != last_encoder_count { @@ -267,6 +284,7 @@ fn main() -> ! { } } +#[allow(non_snake_case)] #[interrupt] fn TIM2() { let timer = unsafe { &mut *CLOCK_TIMER.as_mut_ptr() }; @@ -286,7 +304,7 @@ fn TIM2() { 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 { + let ptt = match shared.state.mode { Mode::CW(_) => { if cw_paddle_tip_low || cw_paddle_ring_low { shared.cw_ptt_timestamp = *ticks; @@ -295,49 +313,58 @@ fn TIM2() { else { shared.cw_ptt_timestamp + cw_ptt_delay > *ticks } + }, + Mode::FeldHell => { + shared.feldhell_ptt } }; 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), + Mode::FeldHell => false, // Done in usb.c }; let next_state = match shared.state.sequence_state { SequenceState::Rx => { shared.ptt_out.set_low().unwrap(); shared.led.set_high().unwrap(); - if cw_ptt { - SequenceState::SwitchingCW + if ptt { + if shared.state.mode == Mode::FeldHell { + SequenceState::Switching(SequenceMode::FeldHell) + } + else { + SequenceState::Switching(SequenceMode::CW) + } } else { SequenceState::Rx } }, - SequenceState::SwitchingCW => { + SequenceState::Switching(m) => { shared.ptt_out.set_high().unwrap(); shared.led.set_low().unwrap(); - if cw_ptt { - SequenceState::TxCW + if ptt { + SequenceState::Tx(m) } else { SequenceState::Rx } }, - SequenceState::TxCW => { + SequenceState::Tx(m) => { shared.ptt_out.set_high().unwrap(); shared.led.set_low().unwrap(); - if cw_ptt { - SequenceState::TxCW + if ptt { + SequenceState::Tx(m) } else { - SequenceState::SwitchingCW + SequenceState::Switching(m) } }, }; match shared.state.sequence_state { - SequenceState::TxCW => { + SequenceState::Tx(SequenceMode::CW) => { if cw_beep { shared.cw_pwm.on(); shared.cw_key_out_n.set_low().unwrap(); @@ -347,6 +374,15 @@ fn TIM2() { shared.cw_key_out_n.set_high().unwrap(); } }, + SequenceState::Tx(SequenceMode::FeldHell) => { + // cw_key_out_n is handled by TIM4 ISR in usb.rs + if cw_beep { + shared.cw_pwm.on(); + } + else { + shared.cw_pwm.off(); + } + }, _ => { shared.cw_pwm.off(); shared.cw_key_out_n.set_high().unwrap(); -- cgit v1.2.3