aboutsummaryrefslogtreecommitdiffstats
path: root/sw/demo1/src/ui.rs
diff options
context:
space:
mode:
Diffstat (limited to 'sw/demo1/src/ui.rs')
-rw-r--r--sw/demo1/src/ui.rs151
1 files changed, 151 insertions, 0 deletions
diff --git a/sw/demo1/src/ui.rs b/sw/demo1/src/ui.rs
new file mode 100644
index 0000000..76f89b9
--- /dev/null
+++ b/sw/demo1/src/ui.rs
@@ -0,0 +1,151 @@
+/*
+ The MIT License (MIT)
+
+ Copyright (c) 2020 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
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all
+ copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+*/
+
+use stm32f1xx_hal::{
+ prelude::*,
+ adc,
+ rcc::{APB2, Clocks},
+ stm32::ADC1,
+ gpio::gpiob::*,
+ gpio::gpioc::*,
+ gpio::{Analog, Input, PullUp},
+};
+
+use embedded_hal::digital::v2::InputPin;
+
+#[derive(PartialEq, Eq, Clone, Copy)]
+pub enum ButtonPress {
+ A,
+ B,
+ C,
+ D,
+ E,
+ F,
+ G,
+ ENC,
+}
+
+pub struct UI {
+ btn0_hist : [u16; 3],
+ btn1_hist : [u16; 3],
+
+ btn0_ch : PB1<Analog>,
+ btn1_ch : PB0<Analog>,
+
+ btn2 : PB12<Input<PullUp>>,
+ btn3 : PB13<Input<PullUp>>,
+
+ btn_enc : PC15<Input<PullUp>>,
+
+ adc : adc::Adc<ADC1>,
+}
+
+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 {
+
+ let adc1 = adc::Adc::adc1(adc1, &mut apb2, *clocks);
+
+ UI {
+ btn0_hist : [4095; 3],
+ btn1_hist : [4095; 3],
+ btn0_ch : pb1,
+ btn1_ch : pb0,
+ btn2 : pb12,
+ btn3 : pb13,
+ btn_enc : pc15,
+ adc : adc1,
+ }
+ }
+
+ pub fn read_buttons(&mut self) -> Option<ButtonPress> {
+ // Debounce BTN0
+ let btn0_value: u16 = self.adc.read(&mut self.btn0_ch).unwrap();
+
+ self.btn0_hist[2] = self.btn0_hist[1];
+ self.btn0_hist[1] = self.btn0_hist[0];
+ self.btn0_hist[0] = btn0_value;
+
+ let mut btn0 = [None; 3];
+ for (i, &v) in self.btn0_hist.iter().enumerate() {
+ btn0[i] =
+ if v > 3050 {
+ None
+ }
+ else if v > 1650 {
+ Some(ButtonPress::B)
+ }
+ else if v > 675 {
+ Some(ButtonPress::C)
+ }
+ else {
+ Some(ButtonPress::D)
+ };
+ }
+
+ if btn0.iter().all(|&v| v != None && v == btn0[0]) {
+ return btn0[0];
+ }
+
+
+ // Debounce BTN1
+ let btn1_value: u16 = self.adc.read(&mut self.btn1_ch).unwrap();
+
+ self.btn1_hist[2] = self.btn1_hist[1];
+ self.btn1_hist[1] = self.btn1_hist[0];
+ self.btn1_hist[0] = btn1_value;
+
+
+ let mut btn1 = [None; 3];
+ for (i, &v) in self.btn1_hist.iter().enumerate() {
+ btn1[i] =
+ if v > 3050 {
+ None
+ }
+ else if v > 675 {
+ Some(ButtonPress::F)
+ }
+ else {
+ Some(ButtonPress::A)
+ };
+ }
+
+ if btn1.iter().all(|&v| v != None && v == btn1[0]) {
+ return btn1[0];
+ }
+
+ if self.btn2.is_low().unwrap() {
+ return Some(ButtonPress::E)
+ }
+
+ if self.btn3.is_low().unwrap() {
+ return Some(ButtonPress::G)
+ }
+
+ if self.btn_enc.is_low().unwrap() {
+ return Some(ButtonPress::ENC)
+ }
+
+ None
+ }
+}