diff --git a/Cargo.lock b/Cargo.lock index f1ccda7..6f1409f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1160,9 +1160,9 @@ dependencies = [ "cortex-m-rt", "defmt", "defmt-rtt", - "embassy-embedded-hal", - "embassy-executor", - "embassy-rp", + "embassy-embedded-hal 0.1.0", + "embassy-executor 0.5.0", + "embassy-rp 0.1.0", "embassy-sync 0.6.0", "embassy-time", "embedded-hal 1.0.0", @@ -1196,6 +1196,23 @@ dependencies = [ "nb 1.1.0", ] +[[package]] +name = "embassy-embedded-hal" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5794414bc20e0d750f145bc0e82366b19dd078e9e075e8331fb8dd069a1cb6a2" +dependencies = [ + "embassy-futures", + "embassy-sync 0.6.0", + "embassy-time", + "embedded-hal 0.2.7", + "embedded-hal 1.0.0", + "embedded-hal-async", + "embedded-storage", + "embedded-storage-async", + "nb 1.1.0", +] + [[package]] name = "embassy-executor" version = "0.5.0" @@ -1206,7 +1223,21 @@ dependencies = [ "critical-section", "defmt", "document-features", - "embassy-executor-macros", + "embassy-executor-macros 0.4.1", + "embassy-time-driver", + "embassy-time-queue-driver", +] + +[[package]] +name = "embassy-executor" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ed0e24bdd4a5f4ff1b72ee4f264b1d23e179ea71a77d984b5fd24877a2bbe1" +dependencies = [ + "cortex-m", + "critical-section", + "document-features", + "embassy-executor-macros 0.5.0", "embassy-time-driver", "embassy-time-queue-driver", ] @@ -1223,6 +1254,18 @@ dependencies = [ "syn 2.0.48", ] +[[package]] +name = "embassy-executor-macros" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4d4c0c34b32c2c653c9eecce1cefaf8539dd9a54e61deb5499254f01e2fcac2" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.48", +] + [[package]] name = "embassy-futures" version = "0.1.1" @@ -1241,6 +1284,17 @@ dependencies = [ "num-traits", ] +[[package]] +name = "embassy-hal-internal" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ef3bac31ec146321248a169e9c7b5799f1e0b3829c7a9b324cb4600a7438f59" +dependencies = [ + "cortex-m", + "critical-section", + "num-traits", +] + [[package]] name = "embassy-net-driver" version = "0.2.0" @@ -1271,9 +1325,9 @@ dependencies = [ "critical-section", "defmt", "document-features", - "embassy-embedded-hal", + "embassy-embedded-hal 0.1.0", "embassy-futures", - "embassy-hal-internal", + "embassy-hal-internal 0.1.0", "embassy-sync 0.5.0", "embassy-time", "embassy-time-driver", @@ -1296,6 +1350,42 @@ dependencies = [ "rp2040-boot2", ] +[[package]] +name = "embassy-rp" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c5d0300b0ed5229bf1c25488c64c1ce55024c5153c246f378b1f2e353d5ec9a" +dependencies = [ + "atomic-polyfill", + "cfg-if", + "cortex-m", + "cortex-m-rt", + "critical-section", + "document-features", + "embassy-embedded-hal 0.2.0", + "embassy-futures", + "embassy-hal-internal 0.2.0", + "embassy-sync 0.6.0", + "embassy-time", + "embassy-time-driver", + "embassy-usb-driver", + "embedded-hal 0.2.7", + "embedded-hal 1.0.0", + "embedded-hal-async", + "embedded-hal-nb", + "embedded-io", + "embedded-io-async", + "embedded-storage", + "embedded-storage-async", + "fixed", + "nb 1.1.0", + "pio", + "pio-proc", + "rand_core 0.6.4", + "rp-pac", + "rp2040-boot2", +] + [[package]] name = "embassy-sync" version = "0.5.0" @@ -1325,9 +1415,9 @@ dependencies = [ [[package]] name = "embassy-time" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "274c019608a9004aed3cafc871e2a3c87ce9351d537dcaab4cc5db184d4a04b1" +checksum = "158080d48f824fad101d7b2fae2d83ac39e3f7a6fa01811034f7ab8ffc6e7309" dependencies = [ "cfg-if", "critical-section", @@ -3797,6 +3887,18 @@ dependencies = [ "siphasher 0.3.11", ] +[[package]] +name = "pi-led-pwm" +version = "0.1.0" +dependencies = [ + "cortex-m-rt", + "embassy-embedded-hal 0.2.0", + "embassy-executor 0.6.0", + "embassy-rp 0.2.0", + "embassy-time", + "panic-probe", +] + [[package]] name = "pi-usb-serial" version = "0.1.0" @@ -3804,9 +3906,9 @@ dependencies = [ "cortex-m-rt", "defmt", "defmt-rtt", - "embassy-embedded-hal", - "embassy-executor", - "embassy-rp", + "embassy-embedded-hal 0.1.0", + "embassy-executor 0.5.0", + "embassy-rp 0.1.0", "embassy-sync 0.6.0", "embassy-time", "embassy-usb", diff --git a/Cargo.toml b/Cargo.toml index 17ab5b4..6aca137 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,4 +31,4 @@ members = [ "timezone-testing", "tree", "visions/server", "pi-usb-serial", "tft" -, "serial-comm"] +, "serial-comm", "pi-led-pwm"] diff --git a/bike-lights/core/src/lib.rs b/bike-lights/core/src/lib.rs index 3bc79be..06fe01b 100644 --- a/bike-lights/core/src/lib.rs +++ b/bike-lights/core/src/lib.rs @@ -292,6 +292,35 @@ impl Animation for Blinker { } } +pub enum FlowDirection { + Forward, + Backward, +} + +pub struct Water { + transition: Fade, + flow_direction: FlowDirection, + transition_size: u8, + splash: u8, + splash_zone: u8, +} + +impl Water { + fn new( + starting_dashboard: DashboardPattern, + starting_body: BodyPattern, + time: Instant, + ) { + Self { + transition: Fade::new(starting_dashboard, starting_body, WATER_DASHBOARD, WATER_BODY, DEFAULT_FRAMES), + flow_direction: FlowDirection::Forward, + transition_size: 4, + splash: 2, + splash_zone: 5, + } + } +} + #[derive(Clone, Debug)] pub enum Event { Brake, @@ -336,7 +365,7 @@ impl Pattern { fn body(&self) -> BodyPattern { match self { - Pattern::Water => OFF_BODY, + Pattern::Water => WATER_BODY, Pattern::GayPride => PRIDE_BODY, Pattern::TransPride => TRANS_PRIDE_BODY, } @@ -384,6 +413,13 @@ impl App { fn update_animation(&mut self, time: Instant) { match self.state { + State::Pattern(Pattern::Water) => { + self.current_animation = Box::new(Water::new( + self.dashboard_lights.clone(), + self.lights.clone(), + time, + )); + } State::Pattern(ref pattern) => { self.current_animation = Box::new(Fade::new( self.dashboard_lights.clone(), diff --git a/bike-lights/core/src/patterns.rs b/bike-lights/core/src/patterns.rs index 12fb7ed..a81a589 100644 --- a/bike-lights/core/src/patterns.rs +++ b/bike-lights/core/src/patterns.rs @@ -97,8 +97,83 @@ pub const OFF_BODY: BodyPattern = [RGB_OFF; 60]; pub const DEFAULT_FRAMES: U16F0 = U16F0::lit("30"); pub const WATER_DASHBOARD: DashboardPattern = [WATER_1, WATER_2, WATER_3]; +pub const WATER_BODY: BodyPattern = [ + WATER_1, + WATER_1, + WATER_1, + WATER_1, + WATER_1, + WATER_1, + WATER_1, + WATER_1, + WATER_1, + WATER_1, -pub const WATER_BODY: BodyPattern = [RGB_OFF; 60]; + WATER_2, + WATER_2, + WATER_2, + WATER_2, + WATER_2, + WATER_2, + WATER_2, + WATER_2, + WATER_2, + WATER_2, + + WATER_3, + WATER_3, + WATER_3, + WATER_3, + WATER_3, + WATER_3, + WATER_3, + WATER_3, + WATER_3, + WATER_3, + + + WATER_3, + WATER_3, + WATER_3, + WATER_3, + WATER_3, + WATER_3, + WATER_3, + WATER_3, + WATER_3, + WATER_3, + + WATER_2, + WATER_2, + WATER_2, + WATER_2, + WATER_2, + WATER_2, + WATER_2, + WATER_2, + WATER_2, + WATER_2, + + WATER_1, + WATER_1, + WATER_1, + WATER_1, + WATER_1, + WATER_1, + WATER_1, + WATER_1, + WATER_1, + WATER_1, +]; + +pub const FIRE_DASHBOARD: DashboardPattern = [RGB_OFF; 3]; +pub const FIRE_BODY: BodyPattern = [RGB_OFF; 60]; + +pub const EARTH_DASHBOARD: DashboardPattern = [RGB_OFF; 3]; +pub const EARTH_BODY: BodyPattern = [RGB_OFF; 60]; + +pub const AIR_DASHBOARD: DashboardPattern = [RGB_OFF; 3]; +pub const AIR_BODY: BodyPattern = [RGB_OFF; 60]; pub const PRIDE_DASHBOARD: DashboardPattern = [PRIDE_RED, PRIDE_GREEN, PRIDE_INDIGO]; diff --git a/pi-led-pwm/.cargo/config.toml b/pi-led-pwm/.cargo/config.toml new file mode 100644 index 0000000..f4e2179 --- /dev/null +++ b/pi-led-pwm/.cargo/config.toml @@ -0,0 +1,6 @@ +[build] +target = "thumbv6m-none-eabi" + +[target.'cfg(all(target_arch = "arm", target_os = "none"))'] +runner = "elf2uf2-rs -d" + diff --git a/pi-led-pwm/Cargo.toml b/pi-led-pwm/Cargo.toml new file mode 100644 index 0000000..65ece09 --- /dev/null +++ b/pi-led-pwm/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "pi-led-pwm" +version = "0.1.0" +edition = "2021" + +[dependencies] +cortex-m-rt = "0.7.3" +embassy-embedded-hal = "0.2.0" +embassy-executor = { version = "0.6.0", features = ["arch-cortex-m", "executor-interrupt", "executor-thread", "integrated-timers"] } +embassy-rp = { version = "0.2.0", features = ["time-driver", "critical-section-impl"] } +embassy-time = "0.3.2" +panic-probe = "0.3.2" diff --git a/pi-led-pwm/build.rs b/pi-led-pwm/build.rs new file mode 100644 index 0000000..fa64500 --- /dev/null +++ b/pi-led-pwm/build.rs @@ -0,0 +1,26 @@ +use std::env; +use std::fs::File; +use std::io::Write; +use std::path::PathBuf; + +fn main() { + // Put `memory.x` in our output directory and ensure it's + // on the linker search path. + let out = &PathBuf::from(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"); + + println!("cargo:rustc-link-arg-bins=--nmagic"); + println!("cargo:rustc-link-arg-bins=-Tlink.x"); + println!("cargo:rustc-link-arg-bins=-Tlink-rp.x"); + // println!("cargo:rustc-link-arg-bins=-Tdefmt.x"); +} diff --git a/pi-led-pwm/memory.x b/pi-led-pwm/memory.x new file mode 100644 index 0000000..e6b80c4 --- /dev/null +++ b/pi-led-pwm/memory.x @@ -0,0 +1,36 @@ +MEMORY { + BOOT2 : ORIGIN = 0x10000000, LENGTH = 0x100 + FLASH : ORIGIN = 0x10000100, LENGTH = 2048K - 0x100 + /* + * RAM consists of 4 banks, SRAM0-SRAM3, with a striped mapping. + * This is usually good for performance, as it distributes load on + * those banks evenly. + */ + RAM : ORIGIN = 0x20000000, LENGTH = 256K + /* + * RAM banks 4 and 5 use a direct mapping. They can be used to have + * memory areas dedicated for some specific job, improving predictability + * of access times. + * Example: Separate stacks for core0 and core1. + */ + SRAM4 : ORIGIN = 0x20040000, LENGTH = 4k + SRAM5 : ORIGIN = 0x20041000, LENGTH = 4k + + /* SRAM banks 0-3 can also be accessed directly. However, those ranges + alias with the RAM mapping, above. So don't use them at the same time! + SRAM0 : ORIGIN = 0x21000000, LENGTH = 64k + SRAM1 : ORIGIN = 0x21010000, LENGTH = 64k + SRAM2 : ORIGIN = 0x21020000, LENGTH = 64k + SRAM3 : ORIGIN = 0x21030000, LENGTH = 64k + */ +} + +EXTERN(BOOT2_FIRMWARE) + +SECTIONS { + /* ### Boot loader */ + .boot2 ORIGIN(BOOT2) : + { + KEEP(*(.boot2)); + } > BOOT2 +} INSERT BEFORE .text; diff --git a/pi-led-pwm/src/main.rs b/pi-led-pwm/src/main.rs new file mode 100644 index 0000000..5083a22 --- /dev/null +++ b/pi-led-pwm/src/main.rs @@ -0,0 +1,50 @@ + +#![no_std] +#![no_main] + +use embassy_executor::Spawner; +use embassy_rp::pwm::Pwm; +use embassy_time::Timer; +use panic_probe as _; + +struct RgBreathing { + val: u16, + change: i8, +} + +impl RgBreathing { + +} + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + let p = embassy_rp::init(Default::default()); + + let mut config_gb = embassy_rp::pwm::Config::default(); + config_gb.top = 256; + config_gb.compare_a = 256; + config_gb.compare_b = 256; + let mut pwm_gb = Pwm::new_output_ab(p.PWM_SLICE1, + p.PIN_2, + p.PIN_3, + config_gb.clone()); + + let mut config_r = embassy_rp::pwm::Config::default(); + config_r.top = 256; + config_r.compare_a = 256; + let mut pwm_r = Pwm::new_output_a(p.PWM_SLICE2, + p.PIN_4, + config_r.clone()); + + loop { + Timer::after_secs(1).await; + /* + config_gb.compare_a = config_gb.compare_a.rotate_left(1); + config_gb.compare_b = config_gb.compare_b.rotate_left(2); + pwm_gb.set_config(&config_gb); + + config_r.compare_a = config_r.compare_a.rotate_left(3); + pwm_r.set_config(&config_r); + */ + }; +}