aboutsummaryrefslogtreecommitdiffstats
path: root/sw
diff options
context:
space:
mode:
authorMatthias P. Braendli <matthias.braendli@mpb.li>2020-08-28 16:16:33 +0200
committerMatthias P. Braendli <matthias.braendli@mpb.li>2020-08-28 16:16:33 +0200
commit59b1601b5c2ce860b19d50908dc02869fc030924 (patch)
tree93502d5955ba3fd042e4f7a06ea380b57d475d13 /sw
parentc387565f0c3280d8024c301d4142230fc586d170 (diff)
downloadpicardy-59b1601b5c2ce860b19d50908dc02869fc030924.tar.gz
picardy-59b1601b5c2ce860b19d50908dc02869fc030924.tar.bz2
picardy-59b1601b5c2ce860b19d50908dc02869fc030924.zip
Continue TX assembly, update versions
Diffstat (limited to 'sw')
-rw-r--r--sw/picardy/Cargo.lock54
-rw-r--r--sw/picardy/Cargo.toml6
-rw-r--r--sw/picardy/src/main.rs144
-rw-r--r--sw/picardy/src/ui.rs101
-rw-r--r--sw/pio.txt2
5 files changed, 215 insertions, 92 deletions
diff --git a/sw/picardy/Cargo.lock b/sw/picardy/Cargo.lock
index 9089792..19f0e2d 100644
--- a/sw/picardy/Cargo.lock
+++ b/sw/picardy/Cargo.lock
@@ -2,15 +2,9 @@
# It is not intended for manual editing.
[[package]]
name = "aligned"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d39da9b88ae1a81c03c9c082b8db83f1d0e93914126041962af61034ab44c4a5"
-
-[[package]]
-name = "aligned"
-version = "0.3.2"
+version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eb1ce8b3382016136ab1d31a1b5ce807144f8b7eb2d5f16b2108f0f07edceb94"
+checksum = "c19796bd8d477f1a9d4ac2465b464a8b1359474f06a96bb3cda650b4fca309bf"
dependencies = [
"as-slice",
]
@@ -64,23 +58,11 @@ dependencies = [
[[package]]
name = "cortex-m"
-version = "0.5.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3c0b159a1e8306949579de3698c841dba58058197b65c60807194e4fa1e7a554"
-dependencies = [
- "aligned 0.2.0",
- "bare-metal",
- "cortex-m 0.6.3",
- "volatile-register",
-]
-
-[[package]]
-name = "cortex-m"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2be99930c99669a74d986f7fd2162085498b322e6daae8ef63a97cc9ac1dc73c"
dependencies = [
- "aligned 0.3.2",
+ "aligned",
"bare-metal",
"bitfield",
"volatile-register",
@@ -113,7 +95,7 @@ version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "113ef0ecffee2b62b58f9380f4469099b30e9f9cbee2804771b4203ba1762cfa"
dependencies = [
- "cortex-m 0.6.3",
+ "cortex-m",
]
[[package]]
@@ -172,7 +154,7 @@ version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c03864ac862876c16a308f5286f4aa217f1a69ac45df87ad3cd2847f818a642c"
dependencies = [
- "cortex-m 0.6.3",
+ "cortex-m",
"cortex-m-semihosting",
]
@@ -181,12 +163,12 @@ name = "picardy"
version = "0.1.0"
dependencies = [
"arrayvec",
- "cortex-m 0.6.3",
+ "cortex-m",
"cortex-m-rt",
"cortex-m-semihosting",
"embedded-hal",
"hd44780-driver",
- "nb 0.1.3",
+ "nb 1.0.0",
"panic-semihosting",
"shared-bus",
"si5351",
@@ -243,11 +225,11 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
[[package]]
name = "shared-bus"
-version = "0.1.4"
+version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ed792a53f339088822c0cc9d6ebfb950752016a288dc96ed3e302e9592f18ab0"
+checksum = "7f42e140835229dea9c0b2498d2c88afe52ed2bd42a7cc6068c95adb5134b541"
dependencies = [
- "cortex-m 0.5.10",
+ "cortex-m",
"embedded-hal",
]
@@ -267,25 +249,25 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
[[package]]
name = "stm32f1"
-version = "0.9.0"
+version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "22ce629123831891663402861bdc7140ebfd6a34a464329f9b9ec1cfde72055a"
+checksum = "849b1e8d9bcfd792c9d9178cf86165d299a661c26e35d9322ae9382d3f3fe460"
dependencies = [
"bare-metal",
- "cortex-m 0.6.3",
+ "cortex-m",
"cortex-m-rt",
"vcell",
]
[[package]]
name = "stm32f1xx-hal"
-version = "0.5.3"
+version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "455bf444813cdc2498130626c5d0ca42f91de1e8261751f3bdc6e5ad9e2aa128"
+checksum = "af9b9e5d7c2901ee39fc9527412327a1fe08f1d84e9d7f4b3497448e655e5098"
dependencies = [
"as-slice",
"cast",
- "cortex-m 0.6.3",
+ "cortex-m",
"cortex-m-rt",
"embedded-hal",
"nb 0.1.3",
@@ -295,9 +277,9 @@ dependencies = [
[[package]]
name = "syn"
-version = "1.0.35"
+version = "1.0.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fb7f4c519df8c117855e19dd8cc851e89eb746fe7a73f0157e0d95fdec5369b0"
+checksum = "891d8d6567fe7c7f8835a3a98af4208f3846fba258c1bc3c31d6e506239f11f9"
dependencies = [
"proc-macro2",
"quote",
diff --git a/sw/picardy/Cargo.toml b/sw/picardy/Cargo.toml
index 2452359..26b794d 100644
--- a/sw/picardy/Cargo.toml
+++ b/sw/picardy/Cargo.toml
@@ -13,11 +13,11 @@ cortex-m-rt = "0.6"
# consider cortex-m-rtfm
cortex-m-semihosting = "0.3"
panic-semihosting = "0.5"
-nb = "0.1"
+nb = "1.0"
#stm32h7 = { version = "0.9", features = ["stm32h743", "rt"] }
-stm32f1xx-hal = { version = "0.5", features = ["rt", "stm32f103"] }
+stm32f1xx-hal = { version = "0.6", features = ["rt", "stm32f103"] }
embedded-hal = { version = "0.2", features = [] }
-shared-bus = { version = "0.1.4", features = ["cortexm"] }
+shared-bus = { version = "0.2", features = ["cortex-m"] }
hd44780-driver = { path = "../deps/hd44780-driver"}
si5351 = { path = "../deps/si5351" }
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() };
diff --git a/sw/picardy/src/ui.rs b/sw/picardy/src/ui.rs
index 76f89b9..114fe1e 100644
--- a/sw/picardy/src/ui.rs
+++ b/sw/picardy/src/ui.rs
@@ -22,11 +22,14 @@
SOFTWARE.
*/
+use core::fmt;
+
use stm32f1xx_hal::{
prelude::*,
adc,
rcc::{APB2, Clocks},
stm32::ADC1,
+ gpio::gpioa::*,
gpio::gpiob::*,
gpio::gpioc::*,
gpio::{Analog, Input, PullUp},
@@ -35,15 +38,44 @@ use stm32f1xx_hal::{
use embedded_hal::digital::v2::InputPin;
#[derive(PartialEq, Eq, Clone, Copy)]
-pub enum ButtonPress {
- A,
+enum Btn0Buttons {
B,
C,
D,
- E,
+}
+
+#[derive(PartialEq, Eq, Clone, Copy)]
+enum Btn1Buttons {
+ A,
F,
- G,
- ENC,
+}
+
+#[derive(PartialEq, Eq, Clone, Copy)]
+pub struct ButtonState {
+ pub a : bool,
+ pub b : bool,
+ pub c : bool,
+ pub d : bool,
+ pub e : bool,
+ pub f : bool,
+ pub g : bool,
+ pub enc : bool,
+ pub ptt : bool,
+}
+
+impl fmt::Display for ButtonState {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "{}{}{}{}{}{}{}{}{}",
+ if self.a { "A" } else { "a" },
+ if self.b { "B" } else { "b" },
+ if self.c { "C" } else { "c" },
+ if self.d { "D" } else { "d" },
+ if self.e { "E" } else { "e" },
+ if self.f { "F" } else { "f" },
+ if self.g { "G" } else { "g" },
+ if self.enc { "X" } else { "x" },
+ if self.ptt { "P" } else { "p" })
+ }
}
pub struct UI {
@@ -53,6 +85,9 @@ pub struct UI {
btn0_ch : PB1<Analog>,
btn1_ch : PB0<Analog>,
+ _mic_sw1 : PA3<Analog>,
+ mic_sw2 : PA4<Analog>,
+
btn2 : PB12<Input<PullUp>>,
btn3 : PB13<Input<PullUp>>,
@@ -62,7 +97,7 @@ pub struct UI {
}
impl UI {
- pub fn new(pb0: PB0<Analog>, pb1: PB1<Analog>, adc1: ADC1, mut apb2: &mut APB2, clocks: &Clocks, pb12: PB12<Input<PullUp>>, pb13: PB13<Input<PullUp>>, pc15 : PC15<Input<PullUp>>) -> UI {
+ pub fn new(mic_sw1: PA3<Analog>, mic_sw2: PA4<Analog>, pb0: PB0<Analog>, pb1: PB1<Analog>, adc1: ADC1, mut apb2: &mut APB2, clocks: &Clocks, pb12: PB12<Input<PullUp>>, pb13: PB13<Input<PullUp>>, pc15 : PC15<Input<PullUp>>) -> UI {
let adc1 = adc::Adc::adc1(adc1, &mut apb2, *clocks);
@@ -75,10 +110,30 @@ impl UI {
btn3 : pb13,
btn_enc : pc15,
adc : adc1,
+ _mic_sw1 : mic_sw1,
+ mic_sw2,
}
}
- pub fn read_buttons(&mut self) -> Option<ButtonPress> {
+ pub fn read_ptt(&mut self) -> bool {
+ let _mic_sw1_value: u16 = self.adc.read(&mut self._mic_sw1).unwrap();
+ let mic_sw2_value: u16 = self.adc.read(&mut self.mic_sw2).unwrap();
+ mic_sw2_value < 500
+ }
+
+ pub fn read_buttons(&mut self) -> ButtonState {
+ let mut buttons = ButtonState {
+ a : false,
+ b : false,
+ c : false,
+ d : false,
+ e : false,
+ f : false,
+ g : false,
+ enc : false,
+ ptt : false,
+ };
+
// Debounce BTN0
let btn0_value: u16 = self.adc.read(&mut self.btn0_ch).unwrap();
@@ -93,18 +148,23 @@ impl UI {
None
}
else if v > 1650 {
- Some(ButtonPress::B)
+ Some(Btn0Buttons::B)
}
else if v > 675 {
- Some(ButtonPress::C)
+ Some(Btn0Buttons::C)
}
else {
- Some(ButtonPress::D)
+ Some(Btn0Buttons::D)
};
}
if btn0.iter().all(|&v| v != None && v == btn0[0]) {
- return btn0[0];
+ match btn0[0] {
+ None => {},
+ Some(Btn0Buttons::B) => buttons.b = true,
+ Some(Btn0Buttons::C) => buttons.c = true,
+ Some(Btn0Buttons::D) => buttons.d = true,
+ }
}
@@ -123,29 +183,34 @@ impl UI {
None
}
else if v > 675 {
- Some(ButtonPress::F)
+ Some(Btn1Buttons::F)
}
else {
- Some(ButtonPress::A)
+ Some(Btn1Buttons::A)
};
}
if btn1.iter().all(|&v| v != None && v == btn1[0]) {
- return btn1[0];
+ match btn1[0] {
+ None => {},
+ Some(Btn1Buttons::A) => buttons.a = true,
+ Some(Btn1Buttons::F) => buttons.f = true,
+ }
}
if self.btn2.is_low().unwrap() {
- return Some(ButtonPress::E)
+ buttons.e = true;
}
if self.btn3.is_low().unwrap() {
- return Some(ButtonPress::G)
+ buttons.g = true;
}
if self.btn_enc.is_low().unwrap() {
- return Some(ButtonPress::ENC)
+ buttons.enc = true;
}
- None
+ cortex_m_semihosting::hprintln!("btn {} {}: {}", btn0_value, btn1_value, buttons).unwrap();
+ buttons
}
}
diff --git a/sw/pio.txt b/sw/pio.txt
index ef97a1e..c932d08 100644
--- a/sw/pio.txt
+++ b/sw/pio.txt
@@ -31,6 +31,8 @@ Microphone switches
* SEQ1 PB4
* SEQ2 PB5
* CW_KEYn PA15
+ * MUTE_SPKR PA2
+ * MUTE_MICn PA1
## I2C1 for Si5351A-B-GT