From bed76daf1ff67c274b358d66aeba71562b70c096 Mon Sep 17 00:00:00 2001 From: "Aode (Lion)" Date: Sat, 12 Mar 2022 14:06:53 -0600 Subject: [PATCH] Fix multi-byte button logic on trinket --- common/src/buttons.rs | 4 ++-- common/src/usb.rs | 8 ++++---- pico/src/main.rs | 20 ++++++++++--------- trinket/deploy.sh | 12 ++++------- trinket/src/build.rs | 26 +++++++++++++++++++++++- trinket/src/buttons.rs | 16 +++++++-------- trinket/src/main.rs | 45 ++++++++++++++++++++---------------------- 7 files changed, 75 insertions(+), 56 deletions(-) diff --git a/common/src/buttons.rs b/common/src/buttons.rs index a190c75..68cbeab 100644 --- a/common/src/buttons.rs +++ b/common/src/buttons.rs @@ -85,14 +85,14 @@ where .current_states .iter() .enumerate() - .filter_map(|(i, state)| if *state { None } else { Some(i as u8) }); + .filter_map(|(i, state)| if *state { Some(i as u8) } else { None }); let mut index = 1; for key in iter { *output.get_mut(index)? = key; index += 1; } - *output.get_mut(0)? = index as u8; + *output.get_mut(0)? = (index - 1) as u8; Some(index) } } diff --git a/common/src/usb.rs b/common/src/usb.rs index 940bd75..e636160 100644 --- a/common/src/usb.rs +++ b/common/src/usb.rs @@ -40,12 +40,12 @@ fn matches(input: &[u8], count: usize, bytes: &'static [u8]) -> bool { } fn write_length_delim(bytes: &[u8], output: &mut [u8]) -> Option { - let len = bytes.len() + 1; - if output.len() < len { + let out_len = bytes.len() + 1; + if output.len() < out_len { return None; } output[0] = bytes.len() as u8; - output[1..].copy_from_slice(bytes); + output[1..out_len].copy_from_slice(bytes); - Some(len) + Some(out_len) } diff --git a/pico/src/main.rs b/pico/src/main.rs index 2e40a1a..f12c865 100644 --- a/pico/src/main.rs +++ b/pico/src/main.rs @@ -202,9 +202,9 @@ fn poll_usb() -> Option<()> { serial.write(bytes).ok()?; serial.flush().ok() })?; - - return None; } + + return None; } Some(()) @@ -214,15 +214,17 @@ fn poll_usb() -> Option<()> { let n = handle_input(&mut Device, &input, &mut output_buffer, count)?; - if n > 0 { - cortex_m::interrupt::free(|cs| { - let mut serial = USB_SERIAL.borrow(cs).borrow_mut(); - let serial = serial.as_mut()?; - serial.write(&output_buffer[0..n]).ok()?; - serial.flush().ok() - })?; + if n == 0 { + return None; } + cortex_m::interrupt::free(|cs| { + let mut serial = USB_SERIAL.borrow(cs).borrow_mut(); + let serial = serial.as_mut()?; + serial.write(&output_buffer[0..n]).ok()?; + serial.flush().ok() + })?; + Some(()) } diff --git a/trinket/deploy.sh b/trinket/deploy.sh index 9d5b24a..13477b5 100755 --- a/trinket/deploy.sh +++ b/trinket/deploy.sh @@ -12,12 +12,10 @@ function bossac() { set -e -cp memory.x ../ - -cargo build --release +cargo build --release -p $PROJECT arm-none-eabi-objcopy -O binary \ - ../target/thumbv6m-none-eabi/release/$PROJECT \ - ../target/thumbv6m-none-eabi/release/$PROJECT.bin + target/thumbv6m-none-eabi/release/$PROJECT \ + target/thumbv6m-none-eabi/release/$PROJECT.bin ports="$(ls /dev/ | grep 'ttyACM')" @@ -38,7 +36,5 @@ for port in $ports; do bossac -i -d \ --port "$port" -U -e -w -v -o 0x2000 \ - ../target/thumbv6m-none-eabi/release/$PROJECT.bin -R + target/thumbv6m-none-eabi/release/$PROJECT.bin -R done - -rm ../memory.x diff --git a/trinket/src/build.rs b/trinket/src/build.rs index 67f3742..2536641 100644 --- a/trinket/src/build.rs +++ b/trinket/src/build.rs @@ -1,4 +1,26 @@ -use std::{fs::File, io::Read, path::Path, process::Command}; +use std::{ + fs::File, + io::{Read, Write}, + path::{Path, PathBuf}, + process::Command, +}; + +fn memory_x() { + // Put `memory.x` in our output directory and ensure it's + // on the linker search path. + let out = &PathBuf::from(std::env::var_os("OUT_DIR").unwrap()); + File::create(out.join("memory.x")) + .unwrap() + .write_all(include_bytes!("../memory.x")) + .unwrap(); + println!("cargo:rustc-link-search={}", out.display()); + + // By default, Cargo will re-run a build script whenever + // any file in the project changes. By specifying `memory.x` + // here, we ensure the build script is only re-run when + // `memory.x` is changed. + println!("cargo:rerun-if-changed=memory.x"); +} fn git_info() -> Option { let mut git_string: Option = None; @@ -47,6 +69,8 @@ fn version_info() -> Result { } fn main() -> Result<(), anyhow::Error> { + memory_x(); + let version = version_info()?; let version = if let Some(git) = git_info() { format!("{}-{}", version, git) diff --git a/trinket/src/buttons.rs b/trinket/src/buttons.rs index fdfa638..ce93fca 100644 --- a/trinket/src/buttons.rs +++ b/trinket/src/buttons.rs @@ -1,5 +1,5 @@ use atsamd_hal::common::gpio::v2::{ - Disabled, Floating, Input, Pin, PullUp, PA02, PA06, PA07, PA08, PA09, + Disabled, Floating, Input, Pin, PullUp, PA02, PA07, PA08, PA09, }; use common::{ButtonPins, ButtonState}; use core::convert::Infallible; @@ -10,7 +10,7 @@ pub(crate) struct Buttons { pub(crate) d1: Pin>, pub(crate) d2: Pin>, pub(crate) d3: Pin>, - pub(crate) d4: Pin>, + // pub(crate) d4: Pin>, } pub(crate) struct Pins { @@ -18,23 +18,23 @@ pub(crate) struct Pins { d1: Pin>, d2: Pin>, d3: Pin>, - d4: Pin>, + // d4: Pin>, } -impl<'a> ButtonPins<'a, 5> for Pins { - fn to_array(&'a self) -> [&'a dyn InputPin; 5] { - [&self.d0, &self.d1, &self.d2, &self.d3, &self.d4] +impl<'a> ButtonPins<'a, 4> for Pins { + fn to_array(&'a self) -> [&'a dyn InputPin; 4] { + [&self.d0, &self.d1, &self.d2, &self.d3] } } impl Buttons { - pub(crate) fn init(self) -> ButtonState { + pub(crate) fn init(self) -> ButtonState { ButtonState::from_pins(Pins { d0: self.d0.into(), d1: self.d1.into(), d2: self.d2.into(), d3: self.d3.into(), - d4: self.d4.into(), + // d4: self.d4.into(), }) } } diff --git a/trinket/src/main.rs b/trinket/src/main.rs index 0391989..8d4f634 100644 --- a/trinket/src/main.rs +++ b/trinket/src/main.rs @@ -117,7 +117,7 @@ fn main() -> ! { d1: pins.d1, d2: pins.d2, d3: pins.d3, - d4: pins.d4, + // d4: pins.d4, } .init(); @@ -171,12 +171,7 @@ fn main() -> ! { if let Some(len) = buttons.tick(current_time, &mut output) { updated_at = current_time; - let _ = cortex_m::interrupt::free(|cs| { - let mut serial = USB_SERIAL.borrow(cs).borrow_mut(); - let serial = serial.as_mut().unwrap(); - let _ = serial.write(&output[0..len])?; - serial.flush() - }); + let _ = write_serial(&output[0..len]); let byte = output[1..len] .iter() @@ -231,14 +226,10 @@ fn poll_usb() -> Option<()> { if let common::HandshakeResponse::Write { bytes } = handshake.perform(&input, current_time)? { - cortex_m::interrupt::free(|cs| { - let mut serial = USB_SERIAL.borrow(cs).borrow_mut(); - let serial = serial.as_mut()?; - serial.write(bytes).ok()?; - serial.flush().ok() - })?; - return None; + write_serial(bytes)?; } + + return None; } Some(()) @@ -246,18 +237,24 @@ fn poll_usb() -> Option<()> { let mut output_buffer = [0; 256]; - if let Some(n) = handle_input(&mut Device, &input, &mut output_buffer, count) { - if n > 0 { - cortex_m::interrupt::free(|cs| { - let mut serial = USB_SERIAL.borrow(cs).borrow_mut(); - let serial = serial.as_mut()?; - serial.write(&output_buffer[..n]).ok()?; - serial.flush().ok() - })?; - } + let len = handle_input(&mut Device, &input, &mut output_buffer, count)?; + + if len == 0 { + return None; } - None + write_serial(&output_buffer[..len])?; + + Some(()) +} + +fn write_serial(bytes: &[u8]) -> Option<()> { + cortex_m::interrupt::free(|cs| { + let mut serial = USB_SERIAL.borrow(cs).borrow_mut(); + let serial = serial.as_mut()?; + serial.write(bytes).ok()?; + serial.flush().ok() + }) } struct Device;