aboutsummaryrefslogtreecommitdiffstats
path: root/sw/picardy/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'sw/picardy/src/main.rs')
-rw-r--r--sw/picardy/src/main.rs144
1 files changed, 109 insertions, 35 deletions
diff --git a/sw/picardy/src/main.rs b/sw/picardy/src/main.rs
index b1bcf0f..071f4e9 100644
--- a/sw/picardy/src/main.rs
+++ b/sw/picardy/src/main.rs
@@ -35,10 +35,13 @@ use stm32f1xx_hal::{
i2c,
gpio,
delay::Delay,
- timer::{Timer},
+ timer::{Timer, Event},
+ qei::QeiOptions,
};
-use embedded_hal::digital::v2::{OutputPin, ToggleableOutputPin};
+use stm32f1xx_hal::stm32::{/*NVIC, Interrupt,*/ interrupt};
+
+use embedded_hal::digital::v2::{OutputPin};
use hd44780_driver::{Cursor, CursorBlink, Display, DisplayMode, HD44780};
pub mod ui;
@@ -50,15 +53,45 @@ enum Mode {
VFO,
BFO,
}
+
+enum TuneSpeed {
+ Slow,
+ Mid,
+ Fast
+}
+
struct State {
mode : Mode,
bfo : u32,
bfo_tune_fail : bool,
- vfo : u32,
+ qrg : u32,
+ tune_speed : TuneSpeed,
transmit : bool,
}
+impl State {
+ fn vfo(&self) -> u32 {
+ self.qrg - self.bfo
+ }
+
+ fn vfo_incr(&self) -> i32 {
+ match self.tune_speed {
+ TuneSpeed::Slow => 10,
+ TuneSpeed::Mid => 200,
+ TuneSpeed::Fast => 1000,
+ }
+ }
+
+ fn bfo_incr(&self) -> i32 {
+ match self.tune_speed {
+ TuneSpeed::Slow => 10,
+ TuneSpeed::Mid => 50,
+ TuneSpeed::Fast => 100,
+ }
+ }
+}
+
fn update_disp<T: hd44780_driver::bus::DataBus>(lcd: &mut HD44780<T>, state: &State, delay: &mut Delay)
{
let mut string = arrayvec::ArrayString::<[_; 16]>::new();
@@ -82,9 +115,16 @@ fn update_disp<T: hd44780_driver::bus::DataBus>(lcd: &mut HD44780<T>, state: &St
string.clear();
match state.mode {
- Mode::BFO => write!(string, " {:<10}", state.vfo).unwrap(),
- Mode::VFO => write!(string, ">{:<10}", state.vfo).unwrap(),
+ Mode::BFO => write!(string, " {:<10}", state.qrg).unwrap(),
+ Mode::VFO => write!(string, ">{:<10}", state.qrg).unwrap(),
+ }
+
+ match state.tune_speed {
+ TuneSpeed::Slow => write!(string, "S").unwrap(),
+ TuneSpeed::Mid => write!(string, "M").unwrap(),
+ TuneSpeed::Fast => write!(string, "F").unwrap(),
}
+
lcd.set_cursor_pos(40, delay).unwrap();
lcd.write_str(&string, delay).unwrap();
}
@@ -93,9 +133,10 @@ fn update_disp<T: hd44780_driver::bus::DataBus>(lcd: &mut HD44780<T>, state: &St
fn main() -> ! {
let mut state = State {
mode : Mode::VFO,
- bfo : 4_195_210,
+ bfo : 4_916_550,
bfo_tune_fail : false,
- vfo : 23_000_000,
+ qrg : 28_000_000,
+ tune_speed : TuneSpeed::Mid,
transmit : false,
};
@@ -115,13 +156,15 @@ fn main() -> ! {
let mut gpioc = dp.GPIOC.split(&mut rcc.apb2);
// Buttons as analog inputs (multi-level)
+ let mic_sw1 = gpioa.pa3.into_analog(&mut gpioa.crl);
+ let mic_sw2 = gpioa.pa4.into_analog(&mut gpioa.crl);
let pb0 = gpiob.pb0.into_analog(&mut gpiob.crl);
let pb1 = gpiob.pb1.into_analog(&mut gpiob.crl);
let pb12 = gpiob.pb12.into_pull_up_input(&mut gpiob.crh);
let pb13 = gpiob.pb13.into_pull_up_input(&mut gpiob.crh);
let pc15 = gpioc.pc15.into_pull_up_input(&mut gpioc.crh);
let adc1 = dp.ADC1;
- let mut ui = ui::UI::new(pb0, pb1, adc1, &mut rcc.apb2, &clocks, pb12, pb13, pc15);
+ let mut ui = ui::UI::new(mic_sw1, mic_sw2, pb0, pb1, adc1, &mut rcc.apb2, &clocks, pb12, pb13, pc15);
// Configure PB14 as output. (LED)
@@ -134,11 +177,14 @@ fn main() -> ! {
let mut _seq1 = pb4.into_push_pull_output_with_state(&mut gpiob.crl, gpio::State::Low);
let mut _seq2 = gpiob.pb5.into_push_pull_output_with_state(&mut gpiob.crl, gpio::State::Low);
+ let mut mute_spkr = gpioa.pa2.into_push_pull_output_with_state(&mut gpioa.crl, gpio::State::Low);
+ let mut mute_micn = gpioa.pa1.into_push_pull_output_with_state(&mut gpioa.crl, gpio::State::Low);
+
let c1 = gpioa.pa6;
let c2 = gpioa.pa7;
let qei = Timer::tim3(dp.TIM3, &clocks, &mut rcc.apb1)
- .qei((c1, c2), &mut afio.mapr);
+ .qei((c1, c2), &mut afio.mapr, QeiOptions::default());
// Configure I2C2 for display
let scl2 = gpiob.pb10.into_alternate_open_drain(&mut gpiob.crh);
@@ -159,10 +205,10 @@ fn main() -> ! {
/* data_timeout_us */ 1000,
);
- let i2c2_busmanager = shared_bus::CortexMBusManager::new(i2c2);
+ let i2c2_busmanager = shared_bus::BusManagerSimple::new(i2c2);
const I2C_ADDRESS: u8 = 0b010_0000; // MCP23008, depending on solder bridges
- let mut lcd = match HD44780::new_i2c_mcp23008(i2c2_busmanager.acquire(), I2C_ADDRESS, &mut delay) {
+ let mut lcd = match HD44780::new_i2c_mcp23008(i2c2_busmanager.acquire_i2c(), I2C_ADDRESS, &mut delay) {
Ok(lcd) => lcd,
Err(_) => panic!("HD44780 init fail"),
};
@@ -198,16 +244,21 @@ fn main() -> ! {
/* addr_timeout_us */ 1000,
/* data_timeout_us */ 1000,
);
- let i2c_busmanager = shared_bus::CortexMBusManager::new(i2c);
+ let i2c_busmanager = shared_bus::BusManagerSimple::new(i2c);
- let mut siclock = si_clock::SiClock::new(i2c_busmanager.acquire(), state.bfo, state.vfo);
+ let mut siclock = si_clock::SiClock::new(i2c_busmanager.acquire_i2c(), state.bfo, state.vfo());
update_disp(&mut lcd, &state, &mut delay);
let mut last_encoder_count = qei.count();
- loop {
- led.toggle().unwrap();
+ let mut timer1 = Timer::tim1(dp.TIM1, &clocks, &mut rcc.apb2)
+ .start_count_down(40.hz());
+ timer1.listen(Event::Update);
+
+ //unsafe { NVIC::unmask(Interrupt::TIM1_UP); }
+
+ loop {
let mut update_disp_required = false;
let encoder_count = qei.count();
@@ -217,49 +268,72 @@ fn main() -> ! {
match state.mode {
Mode::VFO => {
- state.vfo = (state.vfo as i32 + delta * 500) as u32;
- siclock.set_vfo(state.vfo);
+ state.qrg = (state.qrg as i32 + delta * state.vfo_incr()) as u32;
},
Mode::BFO => {
- state.bfo = (state.bfo as i32 + delta * 50) as u32;
+ state.bfo = (state.bfo as i32 + delta * state.bfo_incr()) as u32;
state.bfo_tune_fail = !siclock.set_bfo(state.bfo).is_ok();
},
}
+ siclock.set_vfo(state.vfo());
+
update_disp_required = true;
}
- if let Some(b) = ui.read_buttons() {
- match b {
- ui::ButtonPress::A => { state.mode = Mode::BFO; },
- ui::ButtonPress::B => { state.mode = Mode::VFO; },
- ui::ButtonPress::C => {},
- ui::ButtonPress::D => {},
- ui::ButtonPress::E => {
- state.transmit = false;
+ let button_state = ui.read_buttons();
- seq0n.set_high().unwrap();
- },
- ui::ButtonPress::F => {
- state.transmit = true;
+ if button_state.a {
+ state.mode = Mode::BFO;
+ update_disp_required = true;
+ }
+ else if button_state.b {
+ state.mode = Mode::VFO;
+ update_disp_required = true;
+ }
- seq0n.set_low().unwrap();
- },
- ui::ButtonPress::G => {},
- ui::ButtonPress::ENC => {},
+ if button_state.g {
+ state.tune_speed = match state.tune_speed {
+ TuneSpeed::Slow => TuneSpeed::Mid,
+ TuneSpeed::Mid => TuneSpeed::Fast,
+ TuneSpeed::Fast => TuneSpeed::Slow,
};
-
update_disp_required = true;
}
+ let ptt = false; //ui.read_ptt();
+ update_disp_required |= state.transmit != ptt;
+ state.transmit = ptt;
+
+ if state.transmit {
+ mute_spkr.set_high().unwrap();
+ mute_micn.set_high().unwrap();
+ seq0n.set_low().unwrap();
+ led.set_high().unwrap();
+ }
+ else {
+ mute_spkr.set_low().unwrap();
+ mute_micn.set_low().unwrap();
+ seq0n.set_high().unwrap();
+ led.set_low().unwrap();
+ }
+
if update_disp_required {
update_disp(&mut lcd, &state, &mut delay)
};
last_encoder_count = encoder_count;
+
+ delay.delay_ms(20u8);
+
+ //cortex_m::asm::wfi();
}
}
+#[interrupt]
+fn TIM1_UP() {
+}
+
#[cortex_m_rt::exception]
fn HardFault(ef: &ExceptionFrame) -> ! {
let periph = unsafe { cortex_m::Peripherals::steal() };