Fix multi-byte button logic on trinket

This commit is contained in:
Aode (Lion) 2022-03-12 14:06:53 -06:00
parent b466d0fb0c
commit bed76daf1f
7 changed files with 75 additions and 56 deletions

View file

@ -85,14 +85,14 @@ where
.current_states .current_states
.iter() .iter()
.enumerate() .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; let mut index = 1;
for key in iter { for key in iter {
*output.get_mut(index)? = key; *output.get_mut(index)? = key;
index += 1; index += 1;
} }
*output.get_mut(0)? = index as u8; *output.get_mut(0)? = (index - 1) as u8;
Some(index) Some(index)
} }
} }

View file

@ -40,12 +40,12 @@ fn matches(input: &[u8], count: usize, bytes: &'static [u8]) -> bool {
} }
fn write_length_delim(bytes: &[u8], output: &mut [u8]) -> Option<usize> { fn write_length_delim(bytes: &[u8], output: &mut [u8]) -> Option<usize> {
let len = bytes.len() + 1; let out_len = bytes.len() + 1;
if output.len() < len { if output.len() < out_len {
return None; return None;
} }
output[0] = bytes.len() as u8; 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)
} }

View file

@ -202,9 +202,9 @@ fn poll_usb() -> Option<()> {
serial.write(bytes).ok()?; serial.write(bytes).ok()?;
serial.flush().ok() serial.flush().ok()
})?; })?;
return None;
} }
return None;
} }
Some(()) Some(())
@ -214,15 +214,17 @@ fn poll_usb() -> Option<()> {
let n = handle_input(&mut Device, &input, &mut output_buffer, count)?; let n = handle_input(&mut Device, &input, &mut output_buffer, count)?;
if n > 0 { if n == 0 {
cortex_m::interrupt::free(|cs| { return None;
let mut serial = USB_SERIAL.borrow(cs).borrow_mut();
let serial = serial.as_mut()?;
serial.write(&output_buffer[0..n]).ok()?;
serial.flush().ok()
})?;
} }
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(()) Some(())
} }

View file

@ -12,12 +12,10 @@ function bossac() {
set -e set -e
cp memory.x ../ cargo build --release -p $PROJECT
cargo build --release
arm-none-eabi-objcopy -O binary \ arm-none-eabi-objcopy -O binary \
../target/thumbv6m-none-eabi/release/$PROJECT \ target/thumbv6m-none-eabi/release/$PROJECT \
../target/thumbv6m-none-eabi/release/$PROJECT.bin target/thumbv6m-none-eabi/release/$PROJECT.bin
ports="$(ls /dev/ | grep 'ttyACM')" ports="$(ls /dev/ | grep 'ttyACM')"
@ -38,7 +36,5 @@ for port in $ports; do
bossac -i -d \ bossac -i -d \
--port "$port" -U -e -w -v -o 0x2000 \ --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 done
rm ../memory.x

View file

@ -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<String> { fn git_info() -> Option<String> {
let mut git_string: Option<String> = None; let mut git_string: Option<String> = None;
@ -47,6 +69,8 @@ fn version_info() -> Result<String, anyhow::Error> {
} }
fn main() -> Result<(), anyhow::Error> { fn main() -> Result<(), anyhow::Error> {
memory_x();
let version = version_info()?; let version = version_info()?;
let version = if let Some(git) = git_info() { let version = if let Some(git) = git_info() {
format!("{}-{}", version, git) format!("{}-{}", version, git)

View file

@ -1,5 +1,5 @@
use atsamd_hal::common::gpio::v2::{ 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 common::{ButtonPins, ButtonState};
use core::convert::Infallible; use core::convert::Infallible;
@ -10,7 +10,7 @@ pub(crate) struct Buttons {
pub(crate) d1: Pin<PA02, Disabled<Floating>>, pub(crate) d1: Pin<PA02, Disabled<Floating>>,
pub(crate) d2: Pin<PA09, Disabled<Floating>>, pub(crate) d2: Pin<PA09, Disabled<Floating>>,
pub(crate) d3: Pin<PA07, Disabled<Floating>>, pub(crate) d3: Pin<PA07, Disabled<Floating>>,
pub(crate) d4: Pin<PA06, Disabled<Floating>>, // pub(crate) d4: Pin<PA06, Disabled<Floating>>,
} }
pub(crate) struct Pins { pub(crate) struct Pins {
@ -18,23 +18,23 @@ pub(crate) struct Pins {
d1: Pin<PA02, Input<PullUp>>, d1: Pin<PA02, Input<PullUp>>,
d2: Pin<PA09, Input<PullUp>>, d2: Pin<PA09, Input<PullUp>>,
d3: Pin<PA07, Input<PullUp>>, d3: Pin<PA07, Input<PullUp>>,
d4: Pin<PA06, Input<PullUp>>, // d4: Pin<PA06, Input<PullUp>>,
} }
impl<'a> ButtonPins<'a, 5> for Pins { impl<'a> ButtonPins<'a, 4> for Pins {
fn to_array(&'a self) -> [&'a dyn InputPin<Error = Infallible>; 5] { fn to_array(&'a self) -> [&'a dyn InputPin<Error = Infallible>; 4] {
[&self.d0, &self.d1, &self.d2, &self.d3, &self.d4] [&self.d0, &self.d1, &self.d2, &self.d3]
} }
} }
impl Buttons { impl Buttons {
pub(crate) fn init(self) -> ButtonState<Pins, 5> { pub(crate) fn init(self) -> ButtonState<Pins, 4> {
ButtonState::from_pins(Pins { ButtonState::from_pins(Pins {
d0: self.d0.into(), d0: self.d0.into(),
d1: self.d1.into(), d1: self.d1.into(),
d2: self.d2.into(), d2: self.d2.into(),
d3: self.d3.into(), d3: self.d3.into(),
d4: self.d4.into(), // d4: self.d4.into(),
}) })
} }
} }

View file

@ -117,7 +117,7 @@ fn main() -> ! {
d1: pins.d1, d1: pins.d1,
d2: pins.d2, d2: pins.d2,
d3: pins.d3, d3: pins.d3,
d4: pins.d4, // d4: pins.d4,
} }
.init(); .init();
@ -171,12 +171,7 @@ fn main() -> ! {
if let Some(len) = buttons.tick(current_time, &mut output) { if let Some(len) = buttons.tick(current_time, &mut output) {
updated_at = current_time; updated_at = current_time;
let _ = cortex_m::interrupt::free(|cs| { let _ = write_serial(&output[0..len]);
let mut serial = USB_SERIAL.borrow(cs).borrow_mut();
let serial = serial.as_mut().unwrap();
let _ = serial.write(&output[0..len])?;
serial.flush()
});
let byte = output[1..len] let byte = output[1..len]
.iter() .iter()
@ -231,14 +226,10 @@ fn poll_usb() -> Option<()> {
if let common::HandshakeResponse::Write { bytes } = if let common::HandshakeResponse::Write { bytes } =
handshake.perform(&input, current_time)? handshake.perform(&input, current_time)?
{ {
cortex_m::interrupt::free(|cs| { write_serial(bytes)?;
let mut serial = USB_SERIAL.borrow(cs).borrow_mut();
let serial = serial.as_mut()?;
serial.write(bytes).ok()?;
serial.flush().ok()
})?;
return None;
} }
return None;
} }
Some(()) Some(())
@ -246,18 +237,24 @@ fn poll_usb() -> Option<()> {
let mut output_buffer = [0; 256]; let mut output_buffer = [0; 256];
if let Some(n) = handle_input(&mut Device, &input, &mut output_buffer, count) { let len = handle_input(&mut Device, &input, &mut output_buffer, count)?;
if n > 0 {
cortex_m::interrupt::free(|cs| { if len == 0 {
let mut serial = USB_SERIAL.borrow(cs).borrow_mut(); return None;
let serial = serial.as_mut()?;
serial.write(&output_buffer[..n]).ok()?;
serial.flush().ok()
})?;
}
} }
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; struct Device;