Build some of the framework for the bike application

This now sends a set of lights to the dashboard from a pico. I had to
adjust some of the colors as they do not look nearly as good in lights
as they do in the screen. There is no real application loop yet, no the
ability to get feedback from external controls.
This commit is contained in:
Savanni D'Gerinel 2023-12-14 12:41:13 -05:00
parent afd10cff66
commit 2a2f1048d3
5 changed files with 163 additions and 17 deletions

19
Cargo.lock generated
View File

@ -221,9 +221,12 @@ checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b"
name = "bike" name = "bike"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"az",
"cortex-m", "cortex-m",
"cortex-m-rt", "cortex-m-rt",
"embedded-alloc",
"embedded-hal", "embedded-hal",
"fixed",
"fugit", "fugit",
"lights-core", "lights-core",
"panic-halt", "panic-halt",
@ -801,6 +804,16 @@ dependencies = [
"serde 1.0.188", "serde 1.0.188",
] ]
[[package]]
name = "embedded-alloc"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ddae17915accbac2cfbc64ea0ae6e3b330e6ea124ba108dada63646fd3c6f815"
dependencies = [
"critical-section",
"linked_list_allocator",
]
[[package]] [[package]]
name = "embedded-dma" name = "embedded-dma"
version = "0.2.0" version = "0.2.0"
@ -2194,6 +2207,12 @@ dependencies = [
"fixed", "fixed",
] ]
[[package]]
name = "linked_list_allocator"
version = "0.10.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9afa463f5405ee81cdb9cc2baf37e08ec7e4c8209442b5d72c04cfb2cd6e6286"
[[package]] [[package]]
name = "linux-raw-sys" name = "linux-raw-sys"
version = "0.4.8" version = "0.4.8"

View File

@ -6,10 +6,13 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
cortex-m = "0.7.7" az = { version = "1" }
cortex-m-rt = "0.7.3" cortex-m-rt = { version = "0.7.3" }
embedded-hal = "0.2.7" cortex-m = { version = "0.7.7" }
fugit = "0.3.7" embedded-alloc = { version = "0.5.1" }
panic-halt = "0.2.0" embedded-hal = { version = "0.2.7" }
rp-pico = "0.8.0" fixed = { version = "1" }
fugit = { version = "0.3.7" }
lights-core = { path = "../core" } lights-core = { path = "../core" }
panic-halt = { version = "0.2.0" }
rp-pico = { version = "0.8.0" }

View File

@ -1,10 +1,134 @@
#![no_main] #![no_main]
#![no_std] #![no_std]
extern crate alloc;
use az::*;
use core::cell::RefCell;
use cortex_m::delay::Delay;
use embedded_alloc::Heap;
use embedded_hal::{blocking::spi::Write, digital::v2::OutputPin};
use fixed::types::I16F16;
use fugit::RateExtU32;
use lights_core::{
BodyPattern, DashboardPattern, Event, TRANS_PRIDE_BODY, TRANS_PRIDE_DASHBOARD, UI,
};
use panic_halt as _; use panic_halt as _;
use rp_pico::entry; use rp_pico::{
entry,
hal::{
clocks::init_clocks_and_plls,
pac::{CorePeripherals, Peripherals},
spi::{Enabled, Spi, SpiDevice, ValidSpiPinout},
watchdog::Watchdog,
Clock, Sio,
},
Pins,
};
#[global_allocator]
static HEAP: Heap = Heap::empty();
const LIGHT_SCALE: I16F16 = I16F16::lit("256.0");
const GLOBAL_BRIGHTESS: u8 = 1;
struct BikeUI<D: SpiDevice, P: ValidSpiPinout<D>> {
spi: RefCell<Spi<Enabled, D, P, 8>>,
}
impl<D: SpiDevice, P: ValidSpiPinout<D>> BikeUI<D, P> {
fn new(spi: Spi<Enabled, D, P, 8>) -> Self {
Self {
spi: RefCell::new(spi),
}
}
}
impl<D: SpiDevice, P: ValidSpiPinout<D>> UI for BikeUI<D, P> {
fn check_event(&self) -> Option<Event> {
None
}
fn update_lights(&self, dashboard_lights: DashboardPattern, body_lights: BodyPattern) {
let mut lights: [u8; 20] = [0; 20];
lights[16] = 0xff;
lights[17] = 0xff;
lights[18] = 0xff;
lights[19] = 0xff;
for (idx, rgb) in dashboard_lights.iter().enumerate() {
lights[(idx + 1) * 4 + 0] = 0xe0 + GLOBAL_BRIGHTESS;
lights[(idx + 1) * 4 + 1] = (I16F16::from(rgb.r) * LIGHT_SCALE).saturating_as();
lights[(idx + 1) * 4 + 2] = (I16F16::from(rgb.b) * LIGHT_SCALE).saturating_as();
lights[(idx + 1) * 4 + 3] = (I16F16::from(rgb.g) * LIGHT_SCALE).saturating_as();
}
let mut spi = self.spi.borrow_mut();
spi.write(lights.as_slice());
}
}
#[entry] #[entry]
fn main() -> ! { fn main() -> ! {
loop {} {
use core::mem::MaybeUninit;
const HEAP_SIZE: usize = 8096;
static mut HEAP_MEM: [MaybeUninit<u8>; HEAP_SIZE] = [MaybeUninit::uninit(); HEAP_SIZE];
unsafe { HEAP.init(HEAP_MEM.as_ptr() as usize, HEAP_SIZE) }
}
let mut pac = Peripherals::take().unwrap();
let core = CorePeripherals::take().unwrap();
let sio = Sio::new(pac.SIO);
let mut watchdog = Watchdog::new(pac.WATCHDOG);
let pins = Pins::new(
pac.IO_BANK0,
pac.PADS_BANK0,
sio.gpio_bank0,
&mut pac.RESETS,
);
let clocks = init_clocks_and_plls(
12_000_000u32,
pac.XOSC,
pac.CLOCKS,
pac.PLL_SYS,
pac.PLL_USB,
&mut pac.RESETS,
&mut watchdog,
)
.ok()
.unwrap();
let mut delay = Delay::new(core.SYST, clocks.system_clock.freq().to_Hz());
let mut spi_clk = pins.gpio10.into_function();
let mut spi_sdo = pins.gpio11.into_function();
let spi = Spi::<_, _, _, 8>::new(pac.SPI1, (spi_sdo, spi_clk));
let mut spi = spi.init(
&mut pac.RESETS,
clocks.peripheral_clock.freq(),
1_u32.MHz(),
embedded_hal::spi::MODE_1,
);
let ui = BikeUI::new(spi);
// let app = App::new(Box::new(ui));
// app.tick(TRANS_PRIDE_DASHBOARD, TRANS_PRIDE_BODY);
ui.update_lights(TRANS_PRIDE_DASHBOARD, TRANS_PRIDE_BODY);
/*
spi.write(&[
0, 0, 0, 0, 0xe1, 0x80, 0x00, 0x00, 0xe1, 0x00, 0x80, 0x00, 0xe1, 0x00, 0x00, 0x80, 0xff,
0xff, 0xff, 0xff,
]);
*/
let mut led_pin = pins.led.into_push_pull_output();
loop {
led_pin.set_high().unwrap();
delay.delay_ms(500);
led_pin.set_low().unwrap();
delay.delay_ms(500);
}
} }

View File

@ -4,7 +4,7 @@ extern crate alloc;
use alloc::boxed::Box; use alloc::boxed::Box;
use az::*; use az::*;
use core::{clone::Clone, cmp::PartialEq, ops::Sub, option::Option}; use core::{clone::Clone, cmp::PartialEq, ops::Sub, option::Option};
use fixed::types::{I16F0, I16F16, I48F16, I8F8, U128F0, U16F0}; use fixed::types::{I48F16, I8F8, U128F0, U16F0};
mod patterns; mod patterns;
pub use patterns::*; pub use patterns::*;

View File

@ -46,12 +46,12 @@ pub const PRIDE_YELLOW: RGB<I8F8> = RGB {
pub const PRIDE_GREEN: RGB<I8F8> = RGB { pub const PRIDE_GREEN: RGB<I8F8> = RGB {
r: I8F8::lit("0"), r: I8F8::lit("0"),
g: I8F8::lit("0.5"), g: I8F8::lit("0.5"),
b: I8F8::lit("0.14"), b: I8F8::lit("0.05"),
}; };
pub const PRIDE_INDIGO: RGB<I8F8> = RGB { pub const PRIDE_INDIGO: RGB<I8F8> = RGB {
r: I8F8::lit("0.14"), r: I8F8::lit("0.04"),
g: I8F8::lit("0.25"), g: I8F8::lit("0.15"),
b: I8F8::lit("0.55"), b: I8F8::lit("0.55"),
}; };
@ -62,15 +62,15 @@ pub const PRIDE_VIOLET: RGB<I8F8> = RGB {
}; };
pub const TRANS_BLUE: RGB<I8F8> = RGB { pub const TRANS_BLUE: RGB<I8F8> = RGB {
r: I8F8::lit("0.36"), r: I8F8::lit("0.06"),
g: I8F8::lit("0.81"), g: I8F8::lit("0.41"),
b: I8F8::lit("0.98"), b: I8F8::lit("0.98"),
}; };
pub const TRANS_PINK: RGB<I8F8> = RGB { pub const TRANS_PINK: RGB<I8F8> = RGB {
r: I8F8::lit("0.96"), r: I8F8::lit("0.96"),
g: I8F8::lit("0.66"), g: I8F8::lit("0.16"),
b: I8F8::lit("0.72"), b: I8F8::lit("0.32"),
}; };
pub const OFF_DASHBOARD: DashboardPattern = [RGB_OFF; 3]; pub const OFF_DASHBOARD: DashboardPattern = [RGB_OFF; 3];