diff --git a/kuboble-pygamer/.gitignore b/kuboble-pygamer/.gitignore new file mode 100644 index 0000000..61ead86 --- /dev/null +++ b/kuboble-pygamer/.gitignore @@ -0,0 +1 @@ +/vendor diff --git a/kuboble-pygamer/src/main.rs b/kuboble-pygamer/src/main.rs index dc652dd..d2af899 100644 --- a/kuboble-pygamer/src/main.rs +++ b/kuboble-pygamer/src/main.rs @@ -24,44 +24,52 @@ systick_monotonic!(Mono, 1000); #[rtic::app(device = pygamer::pac, dispatchers = [TC0])] mod app { - use crate::{output, Mono}; + use pygamer::{delay::Delay, timer::SpinTimer, Pins}; + use rtic_monotonics::Monotonic; + + use crate::{ + output::{self, neopixels_test, DisplayDriver, NeoPixels}, + Mono, + }; #[shared] struct Shared {} #[local] - struct Local {} + struct Local { + neopixels: NeoPixels, + np_color: bool, + display: DisplayDriver, + } #[init] - fn init(cx: init::Context) -> (Shared, Local) { + fn init(mut cx: init::Context) -> (Shared, Local) { // Get the peripherals and pins and setup clocks let mut clocks = pygamer::clock::GenericClockController::with_internal_32kosc( - peripherals.GCLK, - &mut peripherals.MCLK, - &mut peripherals.OSC32KCTRL, - &mut peripherals.OSCCTRL, - &mut peripherals.NVMCTRL, + cx.device.GCLK, + &mut cx.device.MCLK, + &mut cx.device.OSC32KCTRL, + &mut cx.device.OSCCTRL, + &mut cx.device.NVMCTRL, ); - let mut pins = Pins::new(peripherals.PORT).split(); - // TODO: use sleeping delay here for battery life? Evidently worth it even for delays of like 50ms - //let x = SleepingDelay::new(); - let mut delay = Delay::new(core.SYST, &mut clocks); + let mut pins = Pins::new(cx.device.PORT).split(); + let mut delay = Delay::new(cx.core.SYST, &mut clocks); // Initialize the display let (display, _backlight) = pins .display .init( &mut clocks, - peripherals.SERCOM4, - &mut peripherals.MCLK, - peripherals.TC2, + cx.device.SERCOM4, + &mut cx.device.MCLK, + cx.device.TC2, &mut delay, &mut pins.port, ) .unwrap(); - // Need to share the delay - let delay = RefCell::new(delay); + // Start the monotonic + Mono::start(delay.free(), 120_000_000); // Set up the neo-pixels driver // Note: This is the non-deprecated way but is jittery as commented in the example @@ -73,38 +81,36 @@ mod app { let neopixels_timer = SpinTimer::new(4); let neopixels = pins.neopixel.init(neopixels_timer, &mut pins.port); - neopixels_test::spawn(0).unwrap(); - display_test::spawn().unwrap(); - - Mono::start(cx.core.SYST, 12_000_000); + display_test::spawn().unwrap_or_else(|_| panic!()); - (Shared {}, Local {}) - } - - #[task(priority = 1)] - async fn neopixels_test( - _: neopixels_test::Context, - mut neopixels: crate::output::NeoPixels, - ) { - output::neopixels_test(neopixels).await + ( + Shared {}, + Local { + neopixels, + display, + np_color: false, + }, + ) } - #[task(priority = 1)] - async fn display_test(_: display_test::Context, mut display: output::DisplayDriver) { - output::display_test(display).await + #[task(priority = 1, local = [display])] + async fn display_test(cx: display_test::Context) { + output::display_test(cx.local.display).await } - // TODO: Do a test about idle if there are suspended higher priority software tasks - #[idle] + #[idle(local = [np_color, neopixels])] fn idle(cx: idle::Context) -> ! { // error: no `local_to_foo` field in `idle::LocalResources` // _cx.local.local_to_foo += 1; // error: no `local_to_bar` field in `idle::LocalResources` // _cx.local.local_to_bar += 1; + let color = *cx.local.np_color; + neopixels_test(cx.local.neopixels, color); loop { - cortex_m::asm::nop(); + *cx.local.np_color = !color; + rtic::export::wfi(); } } } @@ -122,7 +128,7 @@ fn main() -> ! { &mut peripherals.NVMCTRL, ); let mut pins = Pins::new(peripherals.PORT).split(); - // TODO: use sleeping delay here for battery life? Evidently worth it even for delays of like 50ms + //let x = SleepingDelay::new(); let mut delay = Delay::new(core.SYST, &mut clocks); diff --git a/kuboble-pygamer/src/output.rs b/kuboble-pygamer/src/output.rs index 1cd9b3f..085f336 100644 --- a/kuboble-pygamer/src/output.rs +++ b/kuboble-pygamer/src/output.rs @@ -51,38 +51,32 @@ impl PieceExt for Piece { const STAR_COLOR: RGB = RGB::new(4, 4, 0); -pub async fn neopixels_test(mut neopixels: NeoPixels) -> ! { +pub fn neopixels_test(neopixels: &mut NeoPixels, color: bool) { loop { - let colors = [Piece::Green.neopixel_color(), RGB::default()]; + let colors = if color { + [Piece::Green.neopixel_color(), RGB::default()] + } else { + [Piece::Orange.neopixel_color(), RGB::default()] + }; neopixels.write(colors.into_iter().cycle().take(5)).unwrap(); - Mono::delay(500.millis()).await; - - let colors = [Piece::Orange.neopixel_color(), RGB::default()]; - - neopixels.write(colors.into_iter().cycle().take(5)).unwrap(); - Mono::delay(500.millis()).await; - - let colors = [Piece::Blue.neopixel_color(), RGB::default()]; - - neopixels.write(colors.into_iter().cycle().take(5)).unwrap(); - Mono::delay(500.millis()).await; } } -pub async fn display_test(mut display: DisplayDriver) -> ! { +pub async fn display_test(display: &mut DisplayDriver) -> ! { + display.clear(Rgb565::WHITE).unwrap(); loop { embedded_graphics::primitives::Rectangle::new(Point::zero(), Size::new(100, 100)) .into_styled(PrimitiveStyle::with_fill(Rgb565::CSS_DARK_BLUE)) - .draw(&mut display) + .draw(display) .unwrap(); - Mono::delay(750.millis()).await; + Mono::delay(2000.millis()).await; embedded_graphics::primitives::Rectangle::new(Point::zero(), Size::new(100, 100)) .into_styled(PrimitiveStyle::with_fill(Rgb565::CSS_DARK_RED)) - .draw(&mut display) + .draw(display) .unwrap(); - Mono::delay(750.millis()).await; + Mono::delay(2000.millis()).await; } }