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
.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)
}
}

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> {
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)
}

View file

@ -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(())
}

View file

@ -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

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

View file

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

View file

@ -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;