diff --git a/Cargo.lock b/Cargo.lock index 688f411..da2c30c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -217,6 +217,19 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" +[[package]] +name = "bike" +version = "0.1.0" +dependencies = [ + "cortex-m", + "cortex-m-rt", + "embedded-hal", + "fugit", + "lights-core", + "panic-halt", + "rp-pico", +] + [[package]] name = "bit-set" version = "0.5.3" diff --git a/Cargo.toml b/Cargo.toml index 0c18479..d32a1dd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,6 +2,7 @@ resolver = "2" members = [ "authdb", + "bike-lights/bike", "bike-lights/core", "bike-lights/simulator", "changeset", diff --git a/bike-lights/bike/.cargo/config b/bike-lights/bike/.cargo/config new file mode 100644 index 0000000..ef4d7f1 --- /dev/null +++ b/bike-lights/bike/.cargo/config @@ -0,0 +1,12 @@ +[build] +target = "thumbv6m-none-eabi" + +[target.thumbv6m-none-eabi] +rustflags = [ + "-C", "link-arg=--nmagic", + "-C", "link-arg=-Tlink.x", + "-C", "inline-threshold=5", + "-C", "no-vectorize-loops", +] + +runner = "elf2uf2-rs -d" diff --git a/bike-lights/bike/Cargo.toml b/bike-lights/bike/Cargo.toml new file mode 100644 index 0000000..80fc201 --- /dev/null +++ b/bike-lights/bike/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "bike" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +cortex-m = "0.7.7" +cortex-m-rt = "0.7.3" +embedded-hal = "0.2.7" +fugit = "0.3.7" +panic-halt = "0.2.0" +rp-pico = "0.8.0" +lights-core = { path = "../core" } diff --git a/bike-lights/bike/src/main.rs b/bike-lights/bike/src/main.rs new file mode 100644 index 0000000..824e3b4 --- /dev/null +++ b/bike-lights/bike/src/main.rs @@ -0,0 +1,10 @@ +#![no_main] +#![no_std] + +use panic_halt as _; +use rp_pico::entry; + +#[entry] +fn main() -> ! { + loop {} +} diff --git a/bike-lights/core/src/lib.rs b/bike-lights/core/src/lib.rs index 3573275..ab87421 100644 --- a/bike-lights/core/src/lib.rs +++ b/bike-lights/core/src/lib.rs @@ -1,9 +1,26 @@ +#![no_std] + +extern crate alloc; +use alloc::boxed::Box; +use core::{clone::Clone, cmp::PartialEq, ops::Sub, option::Option}; + mod patterns; pub use patterns::*; mod types; pub use types::{DashboardPattern, Pattern, RGB}; +#[derive(Clone, Copy)] +pub struct Instant(pub u128); + +impl Sub for Instant { + type Output = Self; + + fn sub(self, r: Self) -> Self::Output { + Self(self.0 - r.0) + } +} + pub const FPS: u8 = 30; pub trait UI { @@ -12,13 +29,13 @@ pub trait UI { } pub trait Animation { - fn tick(&mut self, time: std::time::Instant) -> (DashboardPattern, Pattern); + fn tick(&mut self, time: Instant) -> (DashboardPattern, Pattern); } pub struct DefaultAnimation {} impl Animation for DefaultAnimation { - fn tick(&mut self, _: std::time::Instant) -> (DashboardPattern, Pattern) { + fn tick(&mut self, _: Instant) -> (DashboardPattern, Pattern) { (PRIDE_DASHBOARD, PRIDE) } } @@ -27,9 +44,9 @@ pub struct Fade { starting_dashboard: DashboardPattern, starting_lights: Pattern, - start_time: std::time::Instant, - dashboard_slope: Vec>, - body_slope: Vec>, + start_time: Instant, + dashboard_slope: [RGB; 3], + body_slope: [RGB; 60], frames: u8, } @@ -40,17 +57,17 @@ impl Fade { ending_dashboard: DashboardPattern, ending_lights: Pattern, frames: u8, - time: std::time::Instant, + time: Instant, ) -> Self { - let mut dashboard_slope = Vec::new(); - let mut body_slope = Vec::new(); + let mut dashboard_slope = [Default::default(); 3]; + let mut body_slope = [Default::default(); 60]; for i in 0..3 { let slope = RGB { r: (ending_dashboard[i].r as f64 - dashboard[i].r as f64) / frames as f64, g: (ending_dashboard[i].g as f64 - dashboard[i].g as f64) / frames as f64, b: (ending_dashboard[i].b as f64 - dashboard[i].b as f64) / frames as f64, }; - dashboard_slope.push(slope); + dashboard_slope[i] = slope; } for i in 0..60 { @@ -59,11 +76,9 @@ impl Fade { g: (ending_lights[i].g as f64 - lights[i].g as f64) / frames as f64, b: (ending_lights[i].b as f64 - lights[i].b as f64) / frames as f64, }; - body_slope.push(slope); + body_slope[i] = slope; } - println!("dashboard slope: {:?}", dashboard_slope); - Self { starting_dashboard: dashboard, starting_lights: lights, @@ -76,8 +91,8 @@ impl Fade { } impl Animation for Fade { - fn tick(&mut self, time: std::time::Instant) -> (DashboardPattern, Pattern) { - let mut frames: u8 = ((time - self.start_time).as_millis() as f64 / FPS as f64) as u8; + fn tick(&mut self, time: Instant) -> (DashboardPattern, Pattern) { + let mut frames: u8 = ((time - self.start_time).0 as f64 / FPS as f64) as u8; if frames > self.frames { frames = self.frames } @@ -142,7 +157,7 @@ pub struct Blinker { fade_out: Fade, direction: FadeDirection, - start_time: std::time::Instant, + start_time: Instant, frames: u8, } @@ -151,7 +166,7 @@ impl Blinker { starting_dashboard: DashboardPattern, starting_body: Pattern, direction: BlinkerDirection, - time: std::time::Instant, + time: Instant, ) -> Self { let mut ending_dashboard = starting_dashboard.clone(); @@ -211,8 +226,8 @@ impl Blinker { } impl Animation for Blinker { - fn tick(&mut self, time: std::time::Instant) -> (DashboardPattern, Pattern) { - let frames: u8 = ((time - self.start_time).as_millis() as f64 / FPS as f64) as u8; + fn tick(&mut self, time: Instant) -> (DashboardPattern, Pattern) { + let frames: u8 = ((time - self.start_time).0 as f64 / FPS as f64) as u8; if frames > self.frames { match self.direction { FadeDirection::FadeIn => { @@ -226,7 +241,6 @@ impl Animation for Blinker { } self.start_time = time; } - println!("anim: {:?} {}", self.direction, frames); match self.direction { FadeDirection::FadeIn => self.fade_in.tick(time), @@ -276,7 +290,7 @@ impl App { } } - fn update_animation(&mut self, time: std::time::Instant) { + fn update_animation(&mut self, time: Instant) { match self.state { State::Pattern(0) => { self.current_animation = Box::new(Fade::new( @@ -374,7 +388,7 @@ impl App { } } - pub fn tick(&mut self, time: std::time::Instant) { + pub fn tick(&mut self, time: Instant) { match self.ui.check_event() { Some(event) => { self.update_state(event); diff --git a/bike-lights/core/src/types.rs b/bike-lights/core/src/types.rs index b3a8f4b..145b515 100644 --- a/bike-lights/core/src/types.rs +++ b/bike-lights/core/src/types.rs @@ -1,4 +1,6 @@ -#[derive(Clone, Default, Debug)] +use core::default::Default; + +#[derive(Clone, Copy, Default, Debug)] pub struct RGB { pub r: T, pub g: T, @@ -6,4 +8,34 @@ pub struct RGB { } pub type DashboardPattern = [RGB; 3]; +/* +#[derive(Clone)] +pub struct DashboardPattern(pub [RGB; 3]); +*/ + +/* +impl Clone for DashboardPattern { + fn clone(&self) -> Self { + let mut v: [RGB; 3] = Default::default(); + for i in 0..3 { + v[i] = self.0[i] + } + Self(v) + } +} +*/ + pub type Pattern = [RGB; 60]; +/* +pub struct Pattern(pub [RGB; 60]); + +impl Pattern { + pub fn clone(&self) -> Self { + let mut v: [RGB; 60] = [Default::default(); 60]; + for i in 0..60 { + v[i] = self.0[i] + } + Self(v) + } +} +*/ diff --git a/bike-lights/simulator/src/main.rs b/bike-lights/simulator/src/main.rs index 11a547c..64d5222 100644 --- a/bike-lights/simulator/src/main.rs +++ b/bike-lights/simulator/src/main.rs @@ -1,7 +1,7 @@ use adw::prelude::*; use glib::{Object, Sender}; use gtk::subclass::prelude::*; -use lights_core::{App, DashboardPattern, Event, Pattern, FPS, RGB, UI}; +use lights_core::{App, DashboardPattern, Event, Instant, Pattern, FPS, RGB, UI}; use std::{ cell::RefCell, env, @@ -248,7 +248,12 @@ fn main() { rx: event_rx, })); loop { - bike_app.tick(std::time::Instant::now()); + bike_app.tick(Instant( + (std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .unwrap()) + .as_millis(), + )); std::thread::sleep(std::time::Duration::from_millis(1000 / (FPS as u64))); } });