From 36dae0e6de9dc81da7f289a3392abc208685baac Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Fri, 28 Aug 2020 18:57:50 +0200 Subject: Fix buttons and filter frequencies for LSB and USB --- frontpanel.svg | 1681 +++++++++++++++++++++++++----------------------- sw/picardy/src/main.rs | 54 +- sw/picardy/src/ui.rs | 88 ++- sw/pio.txt | 8 +- 4 files changed, 969 insertions(+), 862 deletions(-) diff --git a/frontpanel.svg b/frontpanel.svg index 961e331..454d34d 100644 --- a/frontpanel.svg +++ b/frontpanel.svg @@ -1,6 +1,4 @@ - - + version="1.1" + viewBox="0 0 297 210" + height="210mm" + width="297mm"> + inkscape:window-y="0" + inkscape:window-x="1919" + inkscape:window-height="1044" + inkscape:window-width="1876" + showgrid="true" + inkscape:current-layer="layer3" + inkscape:document-units="mm" + inkscape:cy="421.67161" + inkscape:cx="312.86424" + inkscape:zoom="3.823541" + inkscape:pageshadow="2" + inkscape:pageopacity="0.0" + borderopacity="1.0" + bordercolor="#666666" + pagecolor="#ffffff" + id="base"> + empopacity="0.25098039" + empcolor="#4242ff" + opacity="0.1254902" + color="#2a2aff" + spacingy="1" + spacingx="1" + units="mm" + id="grid3713" + type="xygrid" /> + originx="0.762" + empopacity="0.59215686" + empcolor="#00950b" + opacity="0.21176471" + color="#3d9d00" + spacingy="0.508" + spacingx="0.508" + units="in" + id="grid4530" + type="xygrid" /> @@ -72,122 +71,76 @@ image/svg+xml - + + id="layer1" + inkscape:groupmode="layer" + inkscape:label="Outline"> + id="rect3715" + d="m 165.26435,166.444 v 64.7741 H 44.735638 V 131.78191 H 135.382" + style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.5;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.9476988" /> Outline 120x100 mm + x="44.332863" + sodipodi:role="line">Outline 120x100 mm + id="layer2" + inkscape:groupmode="layer"> + height="5.2948303" + width="90.382004" + id="rect4590" + style="opacity:1;fill:#a4a4a4;fill-opacity:1;stroke:none;stroke-width:0.5;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.9476988" /> + width="5.4545593" + height="64.555992" + x="159.54544" + y="79.444008" /> + width="120" + height="1.9999951" + x="45" + y="142" /> + style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.5;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.9476988" + id="path4598" /> + id="layer3" + inkscape:groupmode="layer"> - - - - - - - - + transform="translate(15.239997,-7.0088705e-6)" + id="g4640"> + id="g4654" + transform="translate(30.479997,-7.0088705e-6)"> + transform="translate(-7.6200029,-12.700007)" + id="g4668"> + id="g4682" + transform="translate(7.6199941,-12.700014)"> + transform="translate(22.859994,-12.700014)" + id="g4696"> - - - - LCD 2x16 - I2C backpack + id="g4710" + transform="translate(38.099997,-12.700007)"> + + + + + + + + + + + LCD 2x16 + I2C backpack + - - - - + id="use4869" /> - - - - + transform="translate(2.5396019)" + id="use4871" /> - - - + + + x="0" + y="0" + inkscape:tiled-clone-of="#ellipse4704-3" + xlink:href="#ellipse4704-3" + transform="translate(10.158408)" + id="use4877" /> + + + + + x="0" + y="0" + inkscape:tiled-clone-of="#ellipse4704-3" + xlink:href="#ellipse4704-3" + transform="translate(22.856417)" + id="use4887" /> + + + + + x="0" + y="0" + inkscape:tiled-clone-of="#ellipse4704-3" + xlink:href="#ellipse4704-3" + transform="translate(35.554426)" + id="use4897" /> + transform="translate(38.094028)" + id="use4899" /> + transform="translate(-5.0799934,-15.24)" /> + id="use4953" /> + transform="translate(3.0480066,-15.24)" /> + id="use4957" /> + GND 5V CLK DAT LAT + x="183.58234" + y="49.836163" + style="font-size:2.11667px;stroke:none;stroke-width:0.5">GND 5V CLK DAT LAT - + transform="translate(27.94,-35.560001)" + id="g5038"> + ry="1.0160071" /> + + height="12.192002" + width="12.191998" + id="rect5006" + style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.5;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.9874477" /> - + + cx="109.982" + cy="160.724" + rx="1.0160029" + ry="1.0160071" /> + d="m 444.48047,565.2207 a 3.8400109,3.8400267 0 0 0 -3.83985,3.83985 v 15.35937 h 7.67969 v -15.35937 a 3.8400109,3.8400267 0 0 0 -3.83984,-3.83985 z" + transform="scale(0.26458333)" + id="ellipse5020" /> + style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.5;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.9874477" + inkscape:connector-curvature="0" /> - + d="m 145.542,125.164 v -30.479995 0" + style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.5;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.9874477" /> + - + d="m 110.84071,55.206114 a 3.0480031,3.0479997 0 0 0 -1.36684,2.539897 3.0480031,3.0479997 0 0 0 3.04787,3.047875 3.0480031,3.0479997 0 0 0 3.04839,-3.047875 3.0480031,3.0479997 0 0 0 -1.36684,-2.539897 z" + style="opacity:1;fill:#37ae35;fill-opacity:1;stroke:#000000;stroke-width:0.30000001;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> - + ry="0.66426831" /> + + - - - - - - - - + transform="rotate(90,179.8318,52.774208)" /> + x="0" + y="0" + inkscape:tiled-clone-of="#ellipse4704-3" + xlink:href="#ellipse4704-3" + transform="rotate(90,178.562,54.044008)" + id="use4871-5" + style="opacity:0.98999999" /> + + + + + x="0" + y="0" + inkscape:tiled-clone-of="#ellipse4704-3" + xlink:href="#ellipse4704-3" + transform="rotate(90,172.21299,60.393013)" + id="use4881-9" + style="opacity:0.98999999" /> + + + + + x="0" + y="0" + inkscape:tiled-clone-of="#ellipse4704-3" + xlink:href="#ellipse4704-3" + transform="rotate(90,165.86399,66.742018)" + id="use4891-9" + style="opacity:0.98999999" /> Base board UI connectorBase board UI connector + x="161.27582" + y="66.474731" /> 3V33V3BT0BT0BT1BT1BT2BT2BT3BT35V5VSDASDASCLSCLENaENaENbENbBTNBTNGND + x="173.09532" + sodipodi:role="line">GND + id="path5192" + inkscape:connector-curvature="0" /> + id="path5194" + inkscape:connector-curvature="0" /> + transform="translate(20.65,2.5400048)" + id="g5204"> + id="path5200" + d="m 133.35,125.164 h 2.032 v 1.524" + style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.30000001;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + d="m 134.366,126.688 h 2.032" + style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.40000001;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> - + id="path5206" + d="m 170.942,92.144005 -7.942,5.08" + style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.40000001;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + id="path5208" + d="M 170.942,89.604005 C 155.2777,99.382483 153.48312,110.71284 153.162,122.624" + style="opacity:1;fill:none;fill-opacity:1;stroke:#991900;stroke-width:0.40000001;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + id="path5218" + d="M 170.942,84.524005 C 154.05199,94.93562 124.22934,123.07191 138,127.704" + style="opacity:1;fill:none;fill-opacity:1;stroke:#996d00;stroke-width:0.40000001;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + - - - - + id="path5224" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cc" /> + id="g5230" + transform="translate(-84.382,-73.659995)"> + sodipodi:nodetypes="cccc" /> + transform="translate(-27.432,7.6200048)" + id="g5242"> + id="path5238" + d="m 133.35,125.164 h 2.032 v 1.524" + style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.30000001;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + inkscape:connector-curvature="0" + id="path5240" + d="m 134.366,126.688 h 2.032" + style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.40000001;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + transform="translate(-19.812,-5.1639952)" + id="g5248"> + id="path5244" + d="m 133.35,125.164 h 2.032 v 1.524" + style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.30000001;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.40000001;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + transform="translate(-35.052,-5.1639952)" + id="g5254"> + id="path5250" + d="m 133.35,125.164 h 2.032 v 1.524" + style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.30000001;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.40000001;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + transform="translate(-42.672,7.6200048)" + id="g5260"> + id="path5256" + d="m 133.35,125.164 h 2.032 v 1.524" + style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.30000001;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.40000001;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + transform="translate(-50.292,-5.0799952)" + id="g5266"> + id="path5262" + d="m 133.35,125.164 h 2.032 v 1.524" + style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.30000001;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.40000001;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + transform="translate(-57.912,7.6200048)" + id="g5272"> + + + + + - + 2.2k + + id="path5308" + d="m 107.442,112.464 c -1.016,0 -1.442,0 -2.54,0" + style="opacity:1;fill:none;fill-opacity:1;stroke:#005d99;stroke-width:0.40000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + + + + + + + 2.2k + id="tspan5312" + x="85.448608" + y="115.86897" + style="fill:#053254;fill-opacity:1;stroke:none;stroke-width:0.21">2.2k + id="g5324" + transform="translate(-27.939996,-38.100006)"> + 2.2k + sodipodi:nodetypes="cc" /> + id="path5348" + d="m 74.422,115.004 c -0.785686,5.91661 0.97246,10.29074 10.16,10.16" + style="opacity:1;fill:none;fill-opacity:1;stroke:#001499;stroke-width:0.40000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + transform="translate(-43.061996,-35.560006)" + id="g5340"> - + A 2.2k - - - - - - - - + id="tspan218" + x="75.349663" + y="117.24467" + style="stroke-width:0.2">B + C + D + E + F + G diff --git a/sw/picardy/src/main.rs b/sw/picardy/src/main.rs index 071f4e9..d6f2bf9 100644 --- a/sw/picardy/src/main.rs +++ b/sw/picardy/src/main.rs @@ -60,9 +60,18 @@ enum TuneSpeed { Fast } +enum FilterShift { + LSB, + USB, + Custom(u32), +} + +const BFO_LSB : u32 = 4_915_940; +const BFO_USB : u32 = 4_914_910; + struct State { mode : Mode, - bfo : u32, + filter_shift : FilterShift, bfo_tune_fail : bool, qrg : u32, tune_speed : TuneSpeed, @@ -71,8 +80,16 @@ struct State { } impl State { + fn bfo(&self) -> u32 { + match self.filter_shift { + FilterShift::LSB => BFO_LSB, + FilterShift::USB => BFO_USB, + FilterShift::Custom(fs) => fs, + } + } + fn vfo(&self) -> u32 { - self.qrg - self.bfo + self.qrg - self.bfo() } fn vfo_incr(&self) -> i32 { @@ -101,7 +118,13 @@ fn update_disp(lcd: &mut HD44780, state: &St (false, Mode::BFO) => write!(string, ">").unwrap(), (false, Mode::VFO) => write!(string, " ").unwrap(), } - write!(string, "{:<10}", state.bfo).unwrap(); + write!(string, "{:<10}", state.bfo()).unwrap(); + + match state.filter_shift { + FilterShift::USB => write!(string, "U").unwrap(), + FilterShift::LSB => write!(string, "L").unwrap(), + FilterShift::Custom(_) => write!(string, " ").unwrap(), + } if state.transmit { write!(string, " T").unwrap(); @@ -133,7 +156,7 @@ fn update_disp(lcd: &mut HD44780, state: &St fn main() -> ! { let mut state = State { mode : Mode::VFO, - bfo : 4_916_550, + filter_shift : FilterShift::USB, bfo_tune_fail : false, qrg : 28_000_000, tune_speed : TuneSpeed::Mid, @@ -246,7 +269,7 @@ fn main() -> ! { ); let i2c_busmanager = shared_bus::BusManagerSimple::new(i2c); - let mut siclock = si_clock::SiClock::new(i2c_busmanager.acquire_i2c(), 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); @@ -271,8 +294,9 @@ fn main() -> ! { state.qrg = (state.qrg as i32 + delta * state.vfo_incr()) as u32; }, Mode::BFO => { - state.bfo = (state.bfo as i32 + delta * state.bfo_incr()) as u32; - state.bfo_tune_fail = !siclock.set_bfo(state.bfo).is_ok(); + let new_bfo = (state.bfo() as i32 + delta * state.bfo_incr()) as u32; + state.filter_shift = FilterShift::Custom(new_bfo); + state.bfo_tune_fail = !siclock.set_bfo(state.bfo()).is_ok(); }, } @@ -292,6 +316,17 @@ fn main() -> ! { update_disp_required = true; } + if button_state.f { + state.filter_shift = match state.filter_shift { + FilterShift::USB => FilterShift::LSB, + FilterShift::LSB => FilterShift::USB, + FilterShift::Custom(_) => FilterShift::USB, + }; + state.bfo_tune_fail = !siclock.set_bfo(state.bfo()).is_ok(); + update_disp_required = true; + } + + if button_state.g { state.tune_speed = match state.tune_speed { TuneSpeed::Slow => TuneSpeed::Mid, @@ -301,9 +336,8 @@ fn main() -> ! { update_disp_required = true; } - let ptt = false; //ui.read_ptt(); - update_disp_required |= state.transmit != ptt; - state.transmit = ptt; + update_disp_required |= state.transmit != button_state.ptt; + state.transmit = button_state.ptt; if state.transmit { mute_spkr.set_high().unwrap(); diff --git a/sw/picardy/src/ui.rs b/sw/picardy/src/ui.rs index 114fe1e..2e93459 100644 --- a/sw/picardy/src/ui.rs +++ b/sw/picardy/src/ui.rs @@ -63,6 +63,22 @@ pub struct ButtonState { pub ptt : bool, } +impl Default for ButtonState { + fn default() -> Self { + ButtonState { + a : false, + b : false, + c : false, + d : false, + e : false, + f : false, + g : false, + enc : false, + ptt : false, + } + } +} + impl fmt::Display for ButtonState { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}{}{}{}{}{}{}{}{}", @@ -85,8 +101,8 @@ pub struct UI { btn0_ch : PB1, btn1_ch : PB0, - _mic_sw1 : PA3, - mic_sw2 : PA4, + mic_sw1 : PA3, + _mic_sw2 : PA4, btn2 : PB12>, btn3 : PB13>, @@ -110,91 +126,74 @@ impl UI { btn3 : pb13, btn_enc : pc15, adc : adc1, - _mic_sw1 : mic_sw1, - mic_sw2, + mic_sw1, + _mic_sw2 : mic_sw2, } } - 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, - }; + let mut buttons = ButtonState::default(); - // Debounce BTN0 + // Debounce BTN0 and BTN1 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 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 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(); + buttons.ptt = mic_sw1_value < 500; + 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(Btn0Buttons::B) - } else if v > 675 { - Some(Btn0Buttons::C) + Some(Btn1Buttons::F) } else { - Some(Btn0Buttons::D) + Some(Btn1Buttons::A) }; } if btn0.iter().all(|&v| v != None && v == btn0[0]) { match btn0[0] { None => {}, - Some(Btn0Buttons::B) => buttons.b = true, - Some(Btn0Buttons::C) => buttons.c = true, - Some(Btn0Buttons::D) => buttons.d = true, + Some(Btn1Buttons::A) => buttons.a = true, + Some(Btn1Buttons::F) => buttons.f = true, } } - - // 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 > 1650 { + Some(Btn0Buttons::B) + } else if v > 675 { - Some(Btn1Buttons::F) + Some(Btn0Buttons::C) } else { - Some(Btn1Buttons::A) + Some(Btn0Buttons::D) }; } if btn1.iter().all(|&v| v != None && v == btn1[0]) { match btn1[0] { None => {}, - Some(Btn1Buttons::A) => buttons.a = true, - Some(Btn1Buttons::F) => buttons.f = true, + Some(Btn0Buttons::B) => buttons.b = true, + Some(Btn0Buttons::C) => buttons.c = true, + Some(Btn0Buttons::D) => buttons.d = true, } } @@ -210,7 +209,6 @@ impl UI { buttons.enc = true; } - cortex_m_semihosting::hprintln!("btn {} {}: {}", btn0_value, btn1_value, buttons).unwrap(); buttons } } diff --git a/sw/pio.txt b/sw/pio.txt index c932d08..917ed7a 100644 --- a/sw/pio.txt +++ b/sw/pio.txt @@ -5,8 +5,8 @@ Pin mapping: see datasheet Table 5 ## GPIO inputs Analog multi-level button inputs - * BTN0 PB1 - * BTN1 PB0 + * BTN0 PB1 ADC12_IN9 + * BTN1 PB0 ADC12_IN8 Digital buttons * BTN2 PB12 @@ -22,8 +22,8 @@ CW paddle * CW_RING PB9 Microphone switches - * SW1 PA3 - * SW2 PA4 + * SW1 PA3 ADC12_IN3 + * SW2 PA4 ADC12_IN4 ## GPIO outputs -- cgit v1.2.3