aboutsummaryrefslogtreecommitdiffstats
path: root/sw/eval-clock-cw-tx/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'sw/eval-clock-cw-tx/src/main.rs')
-rw-r--r--sw/eval-clock-cw-tx/src/main.rs82
1 files changed, 59 insertions, 23 deletions
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<gpio::Output<gpio::PushPull>>,
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();