Update deps, implement own BSP
This commit is contained in:
parent
90c91e74c3
commit
0f6b49950a
18
Cargo.toml
18
Cargo.toml
|
@ -7,15 +7,17 @@ version = "0.1.0"
|
|||
build = "src/build.rs"
|
||||
|
||||
[dependencies]
|
||||
atsamd-hal = "0.12"
|
||||
cortex-m = "0.6.0"
|
||||
cortex-m-rt = "0.6.10"
|
||||
apa102-spi = "0.3.2"
|
||||
atsamd-hal = "0.14"
|
||||
bitbang-hal = "0.3.2"
|
||||
cortex-m = "0.7.4"
|
||||
cortex-m-rt = "0.7.1"
|
||||
cortex-m-semihosting = "0.3.3"
|
||||
embedded-hal = "0.2"
|
||||
once_cell = { version = "1.7.2", default-features = false }
|
||||
panic-halt = "0.2.0"
|
||||
smart-leds = "0.3"
|
||||
trinket_m0 = { version = "0.9.0", features = ["unproven", "usb"] }
|
||||
trinket_m0 = { version = "0.11.0", features = ["unproven", "usb"] }
|
||||
usb-device = "0.2"
|
||||
usbd-serial = "0.1"
|
||||
streamdeck-common = { version = "0.1.0", path = "./streamdeck-common" }
|
||||
|
@ -32,10 +34,8 @@ bench = false
|
|||
|
||||
[profile.release]
|
||||
codegen-units = 1 # better optimizations
|
||||
debug = true # symbols are nice and they don't increase the size on Flash
|
||||
lto = true # better optimizations
|
||||
debug = true # symbols are nice and they don't increase the size on Flash
|
||||
lto = true # better optimizations
|
||||
|
||||
[workspace]
|
||||
members = [
|
||||
"./streamdeck-common",
|
||||
]
|
||||
members = ["./streamdeck-common"]
|
||||
|
|
110
src/bsp.rs
Normal file
110
src/bsp.rs
Normal file
|
@ -0,0 +1,110 @@
|
|||
use atsamd_hal::gpio::v2::{
|
||||
Disabled, Floating, Input, Output, Pin, PullUp, PushPull, PA00, PA01, PA14,
|
||||
};
|
||||
use atsamd_hal::prelude::_embedded_hal_timer_CountDown as CountDown;
|
||||
use embedded_hal::timer::Periodic;
|
||||
|
||||
pub struct Dotstar {
|
||||
pub ci: Pin<PA01, Disabled<Floating>>,
|
||||
pub di: Pin<PA00, Disabled<Floating>>,
|
||||
pub nc: Pin<PA14, Disabled<Floating>>,
|
||||
}
|
||||
|
||||
pub type Spi<C> = bitbang_hal::spi::SPI<
|
||||
Pin<PA14, Input<PullUp>>,
|
||||
Pin<PA00, Output<PushPull>>,
|
||||
Pin<PA01, Output<PushPull>>,
|
||||
C,
|
||||
>;
|
||||
|
||||
impl Dotstar {
|
||||
pub fn init<C: CountDown + Periodic>(self, timer: C) -> apa102_spi::Apa102<Spi<C>> {
|
||||
let spi = bitbang_hal::spi::SPI::new(
|
||||
apa102_spi::MODE,
|
||||
self.nc.into(),
|
||||
self.di.into(),
|
||||
self.ci.into(),
|
||||
timer,
|
||||
);
|
||||
|
||||
apa102_spi::Apa102::new(spi)
|
||||
}
|
||||
}
|
||||
|
||||
atsamd_hal::bsp_pins! (
|
||||
PA08 {
|
||||
name: d0
|
||||
aliases: {
|
||||
AlternateC: Sda
|
||||
}
|
||||
}
|
||||
PA02 {
|
||||
name: d1
|
||||
aliases: {
|
||||
AlternateC: Scl
|
||||
}
|
||||
}
|
||||
PA09 {
|
||||
name: d2
|
||||
}
|
||||
PA07 {
|
||||
name: d3
|
||||
aliases: {
|
||||
AlternateC: UartTx
|
||||
}
|
||||
}
|
||||
PA06 {
|
||||
name: d4
|
||||
aliases: {
|
||||
AlternateC: UartRx
|
||||
}
|
||||
}
|
||||
PA10 {
|
||||
name: d13
|
||||
aliases: {
|
||||
PushPullOutput: RedLed
|
||||
}
|
||||
}
|
||||
PA01 {
|
||||
name: dotstar_ci
|
||||
aliases: {
|
||||
AlternateD: Sclk
|
||||
}
|
||||
}
|
||||
PA00 {
|
||||
name: dotstar_di
|
||||
aliases: {
|
||||
AlternateD: Mosi
|
||||
}
|
||||
}
|
||||
PA14 {
|
||||
name: dotstar_nc
|
||||
aliases: {
|
||||
AlternateD: Miso
|
||||
}
|
||||
}
|
||||
PA31 {
|
||||
name: swdio
|
||||
}
|
||||
PA30 {
|
||||
name: swdclk
|
||||
}
|
||||
PA28 {
|
||||
name: usb_host_enable
|
||||
}
|
||||
PA23 {
|
||||
name: usb_sof
|
||||
}
|
||||
PA24 {
|
||||
name: usb_dm
|
||||
aliases: {
|
||||
AlternateG: UsbDm
|
||||
}
|
||||
}
|
||||
PA25 {
|
||||
name: usb_dp
|
||||
aliases: {
|
||||
AlternateG: UsbDp
|
||||
}
|
||||
}
|
||||
);
|
43
src/main.rs
43
src/main.rs
|
@ -1,6 +1,7 @@
|
|||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use atsamd_hal::clock::{ClockGenId, ClockSource};
|
||||
use panic_halt as _; // you can put a breakpoint on `rust_begin_unwind` to catch panics
|
||||
use trinket_m0 as hal;
|
||||
|
||||
|
@ -15,9 +16,7 @@ use hal::{
|
|||
entry,
|
||||
pac::{interrupt, CorePeripherals, Peripherals},
|
||||
prelude::_atsamd_hal_embedded_hal_digital_v2_OutputPin,
|
||||
timer::SpinTimer,
|
||||
usb::UsbBus,
|
||||
Dotstar,
|
||||
};
|
||||
use once_cell::unsync::OnceCell;
|
||||
use smart_leds::{SmartLedsWrite, RGB8};
|
||||
|
@ -25,8 +24,10 @@ use streamdeck_common::{handle_input, Handshake, UnsafeSync};
|
|||
use usb_device::{bus::UsbBusAllocator, prelude::*};
|
||||
use usbd_serial::{SerialPort, USB_CLASS_CDC};
|
||||
|
||||
mod bsp;
|
||||
mod trinket_buttons;
|
||||
|
||||
use bsp::{Dotstar, Pins};
|
||||
use trinket_buttons::Buttons;
|
||||
|
||||
static USB_ALLOCATOR: UnsafeSync<OnceCell<UsbBusAllocator<UsbBus>>> =
|
||||
|
@ -46,9 +47,9 @@ fn main() -> ! {
|
|||
&mut peripherals.SYSCTRL,
|
||||
&mut peripherals.NVMCTRL,
|
||||
);
|
||||
let mut pins = hal::Pins::new(peripherals.PORT);
|
||||
let pins = Pins::new(peripherals.PORT);
|
||||
|
||||
let mut red_led = pins.d13.into_open_drain_output(&mut pins.port);
|
||||
let mut red_led = pins.d13.into_push_pull_output();
|
||||
red_led.set_low().unwrap();
|
||||
|
||||
let usb_allocator = hal::usb_allocator(
|
||||
|
@ -57,9 +58,15 @@ fn main() -> ! {
|
|||
&mut peripherals.PM,
|
||||
pins.usb_dm,
|
||||
pins.usb_dp,
|
||||
&mut pins.port,
|
||||
);
|
||||
|
||||
let timer_clock = clocks
|
||||
.configure_gclk_divider_and_source(ClockGenId::GCLK1, 1, ClockSource::OSC32K, false)
|
||||
.unwrap();
|
||||
clocks.configure_standby(ClockGenId::GCLK1, true);
|
||||
let tc45 = &clocks.tc4_tc5(&timer_clock).unwrap();
|
||||
let timer = atsamd_hal::timer::TimerCounter::tc4_(tc45, peripherals.TC4, &mut peripherals.PM);
|
||||
|
||||
// SAFETY: No interrupt will access USB_ALLOCATOR before this point, since it is only
|
||||
// referenced from inside the USB_SERIAL mutex and the USB_BUS mutex, which have not been set
|
||||
// yet.
|
||||
|
@ -101,14 +108,14 @@ fn main() -> ! {
|
|||
d3: pins.d3,
|
||||
d4: pins.d4,
|
||||
}
|
||||
.init(&mut pins.port);
|
||||
.init();
|
||||
|
||||
let mut rgb = Dotstar {
|
||||
ci: pins.dotstar_ci,
|
||||
di: pins.dotstar_di,
|
||||
nc: pins.dotstar_nc,
|
||||
}
|
||||
.init(SpinTimer::new(12), &mut pins.port);
|
||||
.init(timer);
|
||||
let off = RGB8 { r: 0, g: 0, b: 0 };
|
||||
rgb.write([off].iter().cloned()).unwrap();
|
||||
|
||||
|
@ -168,10 +175,8 @@ fn poll_usb(handshake: &mut Handshake) -> Option<()> {
|
|||
|
||||
let current_time = SYST::get_current();
|
||||
|
||||
if count == 32 {
|
||||
if handshake.perform(&input, current_time, &mut Device)? {
|
||||
return Some(());
|
||||
}
|
||||
if count == 32 && handshake.perform(&input, current_time, &mut Device)? {
|
||||
return Some(());
|
||||
}
|
||||
|
||||
let is_complete = handshake.is_complete();
|
||||
|
@ -182,13 +187,15 @@ fn poll_usb(handshake: &mut Handshake) -> Option<()> {
|
|||
handle_input(&mut Device, &input, count)
|
||||
}
|
||||
|
||||
fn with_op_lock_spin(cs: &cortex_m::interrupt::CriticalSection) -> bool {
|
||||
let mut operation_lock = OPERATION_LOCK.borrow(cs).borrow_mut();
|
||||
let prev = *operation_lock;
|
||||
*operation_lock = true;
|
||||
prev
|
||||
}
|
||||
|
||||
fn with_op_lock(mut f: impl FnMut()) {
|
||||
while cortex_m::interrupt::free(|cs| {
|
||||
let mut operation_lock = OPERATION_LOCK.borrow(cs).borrow_mut();
|
||||
let prev = *operation_lock;
|
||||
*operation_lock = true;
|
||||
prev
|
||||
}) {
|
||||
while cortex_m::interrupt::free(with_op_lock_spin) {
|
||||
cycle_delay(1024);
|
||||
}
|
||||
|
||||
|
@ -214,7 +221,7 @@ impl streamdeck_common::Device<16, 1> for Device {
|
|||
let mut id = [0u8; 16];
|
||||
|
||||
for i in 0..4 {
|
||||
id[i * 4 + 0] = unsafe { (*generator[i])[3] };
|
||||
id[i * 4] = unsafe { (*generator[i])[3] };
|
||||
id[i * 4 + 1] = unsafe { (*generator[i])[2] };
|
||||
id[i * 4 + 2] = unsafe { (*generator[i])[1] };
|
||||
id[i * 4 + 3] = unsafe { (*generator[i])[0] };
|
||||
|
|
|
@ -1,19 +1,16 @@
|
|||
use atsamd_hal::common::gpio::{
|
||||
v2::{
|
||||
pin::{PA02, PA06, PA07, PA08, PA09},
|
||||
Floating, Input, PullUp,
|
||||
},
|
||||
Pin, Port,
|
||||
use atsamd_hal::common::gpio::v2::{
|
||||
Disabled, Floating, Input, Pin, PullUp, PA02, PA06, PA07, PA08, PA09,
|
||||
};
|
||||
use core::convert::Infallible;
|
||||
use embedded_hal::digital::v2::InputPin;
|
||||
use streamdeck_common::{ButtonPins, ButtonState};
|
||||
|
||||
pub(crate) struct Buttons {
|
||||
pub(crate) d0: Pin<PA08, Input<Floating>>,
|
||||
pub(crate) d1: Pin<PA02, Input<Floating>>,
|
||||
pub(crate) d2: Pin<PA09, Input<Floating>>,
|
||||
pub(crate) d3: Pin<PA07, Input<Floating>>,
|
||||
pub(crate) d4: Pin<PA06, Input<Floating>>,
|
||||
pub(crate) d0: Pin<PA08, Disabled<Floating>>,
|
||||
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) struct Pins {
|
||||
|
@ -25,19 +22,19 @@ pub(crate) struct Pins {
|
|||
}
|
||||
|
||||
impl<'a> ButtonPins<'a, 5> for Pins {
|
||||
fn to_array(&'a self) -> [&'a dyn InputPin<Error = ()>; 5] {
|
||||
fn to_array(&'a self) -> [&'a dyn InputPin<Error = Infallible>; 5] {
|
||||
[&self.d0, &self.d1, &self.d2, &self.d3, &self.d4]
|
||||
}
|
||||
}
|
||||
|
||||
impl Buttons {
|
||||
pub(crate) fn init(self, port: &mut Port) -> ButtonState<Pins, 5> {
|
||||
pub(crate) fn init(self) -> ButtonState<Pins, 5> {
|
||||
ButtonState::from_pins(Pins {
|
||||
d0: self.d0.into_pull_up_input(port),
|
||||
d1: self.d1.into_pull_up_input(port),
|
||||
d2: self.d2.into_pull_up_input(port),
|
||||
d3: self.d3.into_pull_up_input(port),
|
||||
d4: self.d4.into_pull_up_input(port),
|
||||
d0: self.d0.into(),
|
||||
d1: self.d1.into(),
|
||||
d2: self.d2.into(),
|
||||
d3: self.d3.into(),
|
||||
d4: self.d4.into(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
use core::convert::Infallible;
|
||||
use embedded_hal::digital::v2::InputPin;
|
||||
|
||||
const DEBOUNCE_TIMEOUT: u32 = 100;
|
||||
|
||||
pub trait ButtonPins<'a, const N: usize> {
|
||||
fn to_array(&'a self) -> [&'a dyn InputPin<Error = ()>; N];
|
||||
fn to_array(&'a self) -> [&'a dyn InputPin<Error = Infallible>; N];
|
||||
}
|
||||
|
||||
pub struct ButtonState<T, const N: usize> {
|
||||
|
@ -56,13 +57,11 @@ where
|
|||
*debounce_time = current_time;
|
||||
}
|
||||
|
||||
if *debounce_time + DEBOUNCE_TIMEOUT < current_time {
|
||||
if *current_state != *last_state {
|
||||
*current_state = *last_state;
|
||||
if *debounce_time + DEBOUNCE_TIMEOUT < current_time && *current_state != *last_state {
|
||||
*current_state = *last_state;
|
||||
|
||||
if *current_state {
|
||||
needs_update |= true;
|
||||
}
|
||||
if *current_state {
|
||||
needs_update |= true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,9 @@ impl<T> UnsafeSync<T> {
|
|||
UnsafeSync(item)
|
||||
}
|
||||
|
||||
/// # Safety
|
||||
///
|
||||
/// uhh...
|
||||
pub unsafe fn get(&self) -> &T {
|
||||
&self.0
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use crate::device::Device;
|
||||
|
||||
static NAME: &'static [u8] = b"Streamdeck";
|
||||
static AUTHOR: &'static [u8] = b"asonix";
|
||||
static REPO: &'static [u8] = b"https://git.asonix.dog/asonix/trinket-streamdeck";
|
||||
static NAME: &[u8] = b"Streamdeck";
|
||||
static AUTHOR: &[u8] = b"asonix";
|
||||
static REPO: &[u8] = b"https://git.asonix.dog/asonix/trinket-streamdeck";
|
||||
|
||||
pub fn handle_input<D, const SN_LEN: usize, const EXTRAS_LEN: usize>(
|
||||
device: &mut D,
|
||||
|
|
Loading…
Reference in a new issue