From aa999d4c4bdf4ede912f3aa833e7045ccfcca4b1 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Fri, 3 Mar 2023 15:07:57 +0100 Subject: Update eval-clock-cw-tx prerequisites --- sw/eval-clock-cw-tx/src/cw.rs | 13 +---- sw/eval-clock-cw-tx/src/main.rs | 122 ++++++++++++++++++++-------------------- sw/eval-clock-cw-tx/src/ui.rs | 18 +++--- sw/eval-clock-cw-tx/src/usb.rs | 30 +++++----- 4 files changed, 86 insertions(+), 97 deletions(-) (limited to 'sw/eval-clock-cw-tx/src') diff --git a/sw/eval-clock-cw-tx/src/cw.rs b/sw/eval-clock-cw-tx/src/cw.rs index 337a3ab..23a74a9 100644 --- a/sw/eval-clock-cw-tx/src/cw.rs +++ b/sw/eval-clock-cw-tx/src/cw.rs @@ -1,25 +1,18 @@ //! CW output using PWM on PA8, TIM1 CH1 use stm32f1xx_hal::{ - prelude::*, timer, pac::TIM1, - gpio::gpioa::*, - gpio::{Alternate, PushPull}, - afio::MAPR, - pwm, }; -const SIDETONE_FREQ : u32 = 1000; +pub const SIDETONE_FREQ : u32 = 1000; pub struct CWPWM { - channel : pwm::PwmChannel, + channel : timer::pwm::PwmChannel, } impl CWPWM { - pub fn new(pa8: PA8>, tim1: timer::Timer, mapr: &mut MAPR) -> Self { - let pwm = tim1.pwm(pa8, mapr, SIDETONE_FREQ.hz()); - let mut channel = pwm.split(); + pub fn new(mut channel: timer::pwm::PwmChannel) -> Self { channel.enable(); channel.set_duty(0); CWPWM { channel } diff --git a/sw/eval-clock-cw-tx/src/main.rs b/sw/eval-clock-cw-tx/src/main.rs index 2dce7bc..b256926 100644 --- a/sw/eval-clock-cw-tx/src/main.rs +++ b/sw/eval-clock-cw-tx/src/main.rs @@ -1,7 +1,7 @@ /* The MIT License (MIT) - Copyright (c) 2021 Matthias P. Braendli + Copyright (c) 2023 Matthias P. Braendli Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -24,7 +24,6 @@ #![no_main] #![no_std] - use core::mem::MaybeUninit; use cortex_m_rt::ExceptionFrame; use cortex_m_semihosting::hprintln; @@ -36,13 +35,11 @@ use stm32f1xx_hal::{ pac::interrupt, i2c, gpio, - delay::Delay, - timer::{CountDownTimer, Timer, Event}, + gpio::PinState, + timer::{CounterHz, Timer, Event}, qei::QeiOptions, }; -use embedded_hal::digital::v2::OutputPin; -use embedded_hal::digital::v2::InputPin; use hd44780_driver::{Cursor, CursorBlink, Display, DisplayMode, HD44780}; pub mod ui; @@ -57,12 +54,12 @@ use state::*; 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, + state: State, + last_sequence_state_change: u32, + feldhell_ptt: bool, + cw_ptt_timestamp: u32, + cw_key_out_n: gpio::gpioa::PA15>, + ui: ui::UI, cw_pwm: cw::CWPWM, cw_keyer: cw::Keyer, cw_paddle_tip: gpio::gpiob::PB8>, @@ -73,7 +70,7 @@ struct SharedWithISR { } static mut SHARED: MaybeUninit = MaybeUninit::uninit(); -static mut CLOCK_TIMER: MaybeUninit> = MaybeUninit::uninit(); +static mut CLOCK_TIMER: MaybeUninit> = MaybeUninit::uninit(); static mut TICK_COUNTER: MaybeUninit = MaybeUninit::uninit(); fn _ticks_now() -> u32 { @@ -86,27 +83,27 @@ fn main() -> ! { let dp = pac::Peripherals::take().unwrap(); let mut flash = dp.FLASH.constrain(); - let mut rcc = dp.RCC.constrain(); - let mut afio = dp.AFIO.constrain(&mut rcc.apb2); + let rcc = dp.RCC.constrain(); + let mut afio = dp.AFIO.constrain(); let clocks = rcc.cfgr - .use_hse(16.mhz()) - .sysclk(48.mhz()) - .pclk1(24.mhz()) - .adcclk(2.mhz()) + .use_hse(16.MHz()) + .sysclk(48.MHz()) + .pclk1(24.MHz()) + .adcclk(2.MHz()) .freeze(&mut flash.acr); assert!(clocks.usbclk_valid()); - let mut delay = Delay::new(cp.SYST, clocks); + let mut delay = cp.SYST.delay(&clocks); delay.delay_ms(200u16); - let mut gpioa = dp.GPIOA.split(&mut rcc.apb2); - let mut gpiob = dp.GPIOB.split(&mut rcc.apb2); - let mut gpioc = dp.GPIOC.split(&mut rcc.apb2); + let mut gpioa = dp.GPIOA.split(); + let mut gpiob = dp.GPIOB.split(); + let mut gpioc = dp.GPIOC.split(); - let mut timer4 = Timer::tim4(dp.TIM4, &clocks, &mut rcc.apb1) - .start_count_down(usb::TIMER_FREQ_HZ.hz()); + let mut timer4 = Timer::new(dp.TIM4, &clocks).counter_hz(); + timer4.start(usb::TIMER_FREQ_HZ.Hz()).unwrap(); timer4.listen(Event::Update); let usb_dm = gpioa.pa11; @@ -124,8 +121,9 @@ fn main() -> ! { 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); - cw::CWPWM::new(pa8, tim1, &mut afio.mapr) + let pwm = dp.TIM1.pwm_hz(pa8, &mut afio.mapr, cw::SIDETONE_FREQ.Hz(), &clocks); + let channel = pwm.split(); + cw::CWPWM::new(channel) }; let cw_paddle_tip = gpiob.pb8.into_pull_up_input(&mut gpiob.crh); // CW paddle tip @@ -133,16 +131,16 @@ fn main() -> ! { // Configure PB14 as output. (LED) let mut led = gpiob.pb14.into_push_pull_output(&mut gpiob.crh); - led.set_low().unwrap(); + led.set_low(); let (pa15, pb3, _pb4) = afio.mapr.disable_jtag(gpioa.pa15, gpiob.pb3, gpiob.pb4); - let cw_key_out_n = pa15.into_push_pull_output_with_state(&mut gpioa.crh, gpio::State::High); - let ptt_out = pb3.into_push_pull_output_with_state(&mut gpiob.crl, gpio::State::Low); - let seq_switch = gpiob.pb5.into_push_pull_output_with_state(&mut gpiob.crl, gpio::State::Low); + let cw_key_out_n = pa15.into_push_pull_output_with_state(&mut gpioa.crh, PinState::High); + let ptt_out = pb3.into_push_pull_output_with_state(&mut gpiob.crl, PinState::Low); + let seq_switch = gpiob.pb5.into_push_pull_output_with_state(&mut gpiob.crl, PinState::Low); let c1 = gpioa.pa6; let c2 = gpioa.pa7; - let qei = Timer::tim3(dp.TIM3, &clocks, &mut rcc.apb1) + let qei = Timer::new(dp.TIM3, &clocks) .qei((c1, c2), &mut afio.mapr, QeiOptions::default()); // Configure I2C1 to be used for Si5351 and display @@ -154,10 +152,9 @@ fn main() -> ! { (scl, sda), &mut afio.mapr, i2c::Mode::Standard { - frequency: 100_000.hz(), + frequency: 100_000.Hz(), }, clocks, - &mut rcc.apb1, /* start_timeout_us */ 1000, /* start_retries */ 10, /* addr_timeout_us */ 1000, @@ -183,20 +180,20 @@ fn main() -> ! { lcd.set_cursor_pos(0, &mut delay).unwrap(); lcd.write_str(" HB9EGM ", &mut delay).unwrap(); lcd.set_cursor_pos(40, &mut delay).unwrap(); - lcd.write_str(" 30m CW TX 2021 ", &mut delay).unwrap(); + lcd.write_str(" 30m TX 2023 ", &mut delay).unwrap(); delay.delay_ms(1_500u16); 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, + state: State::new(), + last_sequence_state_change: 0, + feldhell_ptt: false, + cw_ptt_timestamp: 0, cw_key_out_n, ui, cw_pwm, - cw_keyer : cw::Keyer::new(12, TICKS_PER_SECOND), + cw_keyer: cw::Keyer::new(12, TICKS_PER_SECOND), cw_paddle_tip, cw_paddle_ring, ptt_out, seq_switch, led, }; @@ -214,8 +211,8 @@ fn main() -> ! { { let timer = unsafe { &mut *CLOCK_TIMER.as_mut_ptr() }; - *timer = Timer::tim2(dp.TIM2, &clocks, &mut rcc.apb1) - .start_count_down(TICKS_PER_SECOND.hz()); + *timer = Timer::new(dp.TIM2, &clocks).counter_hz(); + timer.start(TICKS_PER_SECOND.Hz()).unwrap(); timer.listen(Event::Update); } @@ -248,6 +245,7 @@ fn main() -> ! { (*shared).state.clone() }); + let encoder_count : u16 = qei.count(); if encoder_count != last_encoder_count { let delta = encoder_count.wrapping_sub(last_encoder_count); @@ -296,7 +294,7 @@ fn main() -> ! { #[interrupt] fn TIM2() { let timer = unsafe { &mut *CLOCK_TIMER.as_mut_ptr() }; - timer.clear_update_interrupt_flag(); + timer.clear_interrupt(Event::Update); let ticks = unsafe { &mut *TICK_COUNTER.as_mut_ptr() }; *ticks += 1; @@ -308,8 +306,8 @@ fn TIM2() { shared.state.update_disp_counter += 1; } - let cw_paddle_tip_low = shared.cw_paddle_tip.is_low().unwrap(); - let cw_paddle_ring_low = shared.cw_paddle_ring.is_low().unwrap(); + let cw_paddle_tip_low = shared.cw_paddle_tip.is_low(); + let cw_paddle_ring_low = shared.cw_paddle_ring.is_low(); let cw_ptt_delay : u32 = TICKS_PER_SECOND * 800 / 1000; let ptt = match shared.state.mode { @@ -335,8 +333,8 @@ fn TIM2() { let next_state = match shared.state.sequence_state { SequenceState::Rx => { - shared.ptt_out.set_low().unwrap(); - shared.seq_switch.set_low().unwrap(); + shared.ptt_out.set_low(); + shared.seq_switch.set_low(); if ptt { if shared.state.mode == Mode::FeldHell { SequenceState::Switching(SequenceMode::FeldHell) @@ -350,8 +348,8 @@ fn TIM2() { } }, SequenceState::Switching(m) => { - shared.ptt_out.set_low().unwrap(); - shared.seq_switch.set_high().unwrap(); + shared.ptt_out.set_low(); + shared.seq_switch.set_high(); if ptt { SequenceState::Tx(m) } @@ -360,8 +358,8 @@ fn TIM2() { } }, SequenceState::Tx(m) => { - shared.ptt_out.set_high().unwrap(); - shared.seq_switch.set_high().unwrap(); + shared.ptt_out.set_high(); + shared.seq_switch.set_high(); if ptt { SequenceState::Tx(m) } @@ -375,22 +373,22 @@ fn TIM2() { SequenceState::Tx(SequenceMode::CW) => { if cw_beep { shared.cw_pwm.on(); - shared.cw_key_out_n.set_low().unwrap(); - shared.led.set_low().unwrap(); + shared.cw_key_out_n.set_low(); + shared.led.set_low(); } else { shared.cw_pwm.off(); - shared.cw_key_out_n.set_high().unwrap(); - shared.led.set_high().unwrap(); + shared.cw_key_out_n.set_high(); + shared.led.set_high(); } }, SequenceState::Tx(SequenceMode::FeldHell) => { - shared.led.set_low().unwrap(); + shared.led.set_low(); }, _ => { - shared.led.set_high().unwrap(); + shared.led.set_high(); shared.cw_pwm.off(); - shared.cw_key_out_n.set_high().unwrap(); + shared.cw_key_out_n.set_high(); }, } @@ -404,20 +402,20 @@ fn TIM2() { #[allow(non_snake_case)] #[cortex_m_rt::exception] -fn HardFault(ef: &ExceptionFrame) -> ! { +unsafe fn HardFault(ef: &ExceptionFrame) -> ! { let periph = unsafe { cortex_m::Peripherals::steal() }; let hfsr = periph.SCB.hfsr.read(); let cfsr = periph.SCB.cfsr.read(); - hprintln!("Hardfault {:x} {:x} at {:x}\n", hfsr, cfsr, ef.pc).unwrap(); + hprintln!("Hardfault {:x} {:x} at {:x}\n", hfsr, cfsr, ef.pc()); cortex_m::asm::bkpt(); loop { } } #[allow(non_snake_case)] #[cortex_m_rt::exception] -fn DefaultHandler(irqn: i16) { - hprintln!("Unhandled exception (IRQn = {})", irqn).unwrap(); +unsafe fn DefaultHandler(irqn: i16) { + hprintln!("Unhandled exception (IRQn = {})", irqn); cortex_m::asm::bkpt(); loop { } } diff --git a/sw/eval-clock-cw-tx/src/ui.rs b/sw/eval-clock-cw-tx/src/ui.rs index 809dd8d..9f3d985 100644 --- a/sw/eval-clock-cw-tx/src/ui.rs +++ b/sw/eval-clock-cw-tx/src/ui.rs @@ -28,13 +28,12 @@ use core::fmt; use core::fmt::Write; use stm32f1xx_hal::{ - delay::Delay, gpio::gpiob::*, gpio::gpioc::*, gpio::{Input, PullUp, Floating}, }; -use embedded_hal::digital::v2::InputPin; +use embedded_hal::blocking::delay::{DelayMs, DelayUs}; use hd44780_driver::HD44780; #[derive(PartialEq, Eq, Clone, Copy)] @@ -125,8 +124,8 @@ impl UI { fn read_buttons(&mut self) -> ButtonState { let mut buttons = ButtonState::default(); - let b0_low = self.btn0.is_low().unwrap(); - let b1_low = self.btn1.is_low().unwrap(); + let b0_low = self.btn0.is_low(); + let b1_low = self.btn1.is_low(); if b0_low && b1_low { buttons.e = true; @@ -138,15 +137,15 @@ impl UI { buttons.b = true; } - if self.btn2.is_low().unwrap() { + if self.btn2.is_low() { buttons.c = true; } - if self.btn3.is_low().unwrap() { + if self.btn3.is_low() { buttons.d = true; } - if self.btn_enc.is_low().unwrap() { + if self.btn_enc.is_low() { buttons.enc = true; } @@ -239,9 +238,10 @@ impl UI { } } -pub fn update_disp(lcd: &mut HD44780, state: &State, delay: &mut Delay) +pub fn update_disp + DelayMs>( + lcd: &mut HD44780, state: &State, delay: &mut D) { - let mut string = arrayvec::ArrayString::<[_; 16]>::new(); + let mut string = arrayvec::ArrayString::<16>::new(); let disp_freq = state.vfo_display() as i32; write!(string, "{:<05}.{:<03} ", disp_freq / 1000, disp_freq % 1000).unwrap(); diff --git a/sw/eval-clock-cw-tx/src/usb.rs b/sw/eval-clock-cw-tx/src/usb.rs index a74ac20..d75c287 100644 --- a/sw/eval-clock-cw-tx/src/usb.rs +++ b/sw/eval-clock-cw-tx/src/usb.rs @@ -4,7 +4,7 @@ use stm32f1xx_hal::{ pac, pac::{interrupt, Interrupt}, gpio, - timer::CountDownTimer, + timer::{CounterHz, Event}, }; use stm32f1xx_hal::usb::{Peripheral, UsbBus, UsbBusType}; use usb_device::{bus::UsbBusAllocator, prelude::*}; @@ -19,7 +19,7 @@ pub const TIMER_FREQ_HZ : u32 = 245; const FELDHELL_PATTERN_LEN : usize = 16; const MESSAGE_LEN : usize = 64; -static mut FELDHELL_TIMER: MaybeUninit> = MaybeUninit::uninit(); +static mut FELDHELL_TIMER: MaybeUninit> = MaybeUninit::uninit(); static mut SHARED_USB: MaybeUninit = MaybeUninit::uninit(); @@ -63,8 +63,8 @@ enum Font { // Shared between application and interrupt context struct USBSharedData { - incoming_buf: ArrayVec::<[u8; MESSAGE_LEN]>, - feldhell_pattern: ArrayVec::<[u16; FELDHELL_PATTERN_LEN]>, // FELDHELL columns to transmit + incoming_buf: ArrayVec::, + feldhell_pattern: ArrayVec::, // FELDHELL columns to transmit } pub fn enable_interrupts() { @@ -80,13 +80,13 @@ pub struct USBData { pub frequency : u32, pub transmit : bool, - current_str : ArrayVec::<[u8; 96]>, + current_str : ArrayVec::, send_ix : usize, } impl USBData { pub fn new( - timer4: CountDownTimer, + timer4: CounterHz, usb: pac::USB, pin_dm: gpio::gpioa::PA11>, pin_dp: gpio::gpioa::PA12>) -> USBData { @@ -148,7 +148,7 @@ impl USBData { let in_message = cortex_m::interrupt::free(|_cs| { let shared_usb = unsafe { &mut *SHARED_USB.as_mut_ptr() }; - let mut message = ArrayString::<[u8; MESSAGE_LEN]>::new(); + let mut message = ArrayString::::new(); let mut split_at = None; for (i, c) in shared_usb.incoming_buf.iter().enumerate() { @@ -168,7 +168,7 @@ impl USBData { write!(&mut message, "{}", core::str::from_utf8(front).unwrap()).ok(); - let mut keep = ArrayVec::<[u8; MESSAGE_LEN]>::new(); + let mut keep = ArrayVec::::new(); keep.try_extend_from_slice(back).ok(); shared_usb.incoming_buf.clear(); @@ -185,7 +185,7 @@ impl USBData { } }); - let mut outgoing = ArrayVec::<[u8; MESSAGE_LEN]>::new(); + let mut outgoing = ArrayVec::::new(); if let Some(m) = in_message { if m.as_str() == "tx\n" { outgoing.try_extend_from_slice(b"TX ok\n").ok(); @@ -212,7 +212,7 @@ impl USBData { outgoing.try_extend_from_slice(b"fontn ok\n").ok(); } else if m.chars().nth(0).unwrap() == 'f' { - let mut as_str = ArrayString::<[u8; MESSAGE_LEN]>::new(); + let mut as_str = ArrayString::::new(); for c in m.chars().skip(1) { as_str.push(c); @@ -269,7 +269,7 @@ impl USBData { if self.send_ix >= self.current_str.len() { cortex_m::interrupt::free(|_cs| { let serial = unsafe { USB_SERIAL.as_mut().unwrap() }; - let mut outgoing = ArrayString::<[u8; 16]>::new(); + let mut outgoing = ArrayString::<16>::new(); write!(&mut outgoing, "FH sent {}\n", self.send_ix).ok(); serial.write(outgoing.as_bytes()).ok(); }); @@ -322,7 +322,7 @@ fn usb_interrupt() { #[interrupt] fn TIM4() { let timer = unsafe { &mut *FELDHELL_TIMER.as_mut_ptr() }; - timer.clear_update_interrupt_flag(); + timer.clear_interrupt(Event::Update); let shared_usb = unsafe { &mut *SHARED_USB.as_mut_ptr() }; while shared_usb.feldhell_pattern.len() > 0 && shared_usb.feldhell_pattern.as_slice()[0] == 0 { @@ -335,13 +335,11 @@ fn TIM4() { let shared = unsafe { &mut *crate::SHARED.as_mut_ptr() }; - use embedded_hal::digital::v2::OutputPin; - if shared.state.allow_feldhell_keying() && (*pat & 0b1) == 0b1 { - shared.cw_key_out_n.set_low().unwrap(); + shared.cw_key_out_n.set_low(); } else { - shared.cw_key_out_n.set_high().unwrap(); + shared.cw_key_out_n.set_high(); } *pat >>= 1; -- cgit v1.2.3