Skip to content

Commit

Permalink
Attempts to update to the async fork (atsamd-rs/atsamd#635) of the la…
Browse files Browse the repository at this point in the history
…test `pygamer` and `atsamd-hal` to test using async timers for async delays.

However, now the display no longer works, which may be related to a SPI issue in the updated HAL: atsamd-rs/atsamd#751
  • Loading branch information
Dan Whitman committed Oct 7, 2024
1 parent 8d9551f commit e984ac3
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 74 deletions.
10 changes: 7 additions & 3 deletions kuboble-pygamer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,22 @@ edition = "2021"
name = "kuboble-pygamer"
version = "0.1.0"

[patch.crates-io]
# Needed currently due to unpublished updated
pygamer = {path = "../../atsamd/boards/pygamer"}

[dependencies]
cortex-m = {version = "0.7.7", features = ["critical-section-single-core"]}
derive-new = "0.7.0"
embedded-graphics = "0.7.1"
kuboble-core = {path = "../kuboble-core"}
pygamer = {version = "0.9.0", features = ["panic_led", "rt"]}
pygamer = {version = "0.10.0", features = ["panic_led"]}
pygamer-engine = {path = "../pygamer-engine"}
rtic = {version = "2.1.1", features = ["thumbv7-backend"]}
rtic-monotonics = {version = "2.0.2", features = ["cortex-m-systick"]}
smart-leds = "0.3.0"
smart-leds = "0.4.0"
st7735-lcd = "0.8.1"
ws2812-timer-delay = "0.3.0"
ws2812-spi = "0.5.0"

[features]
unlocked = ["kuboble-core/unlocked"]
Expand Down
5 changes: 2 additions & 3 deletions kuboble-pygamer/src/controls.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
use core::cell::RefCell;

use kuboble_core::level_run::Direction;
use pygamer::adc::Adc;
use pygamer::delay::Delay;
use pygamer::hal::adc::Adc;
use pygamer::hal::delay::Delay;
use pygamer::pac::ADC1;
use pygamer::pins::{ButtonReader, JoystickReader, Keys};
use pygamer::prelude::*;
use pygamer_engine::{ControlAction, Controller, GameResult};

const JOYSTICK_THRESH: i16 = 1024;
Expand Down
78 changes: 45 additions & 33 deletions kuboble-pygamer/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,28 @@
#![no_main]
#![feature(let_chains)]

use controls::PyGamerController;
use core::cell::RefCell;
use kuboble_core::level_select::LevelProgress;
use output::PyGamerOutput;
use pac::{CorePeripherals, Peripherals};
use pygamer::adc::Adc;
use pygamer::clock::GenericClockController;
use pygamer::delay::Delay;
use pygamer::pac::gclk::pchctrl::GEN_A;
use pygamer::sleeping_delay::SleepingDelay;
use pygamer::timer::SpinTimer;
use pygamer::{entry, pac, Pins};
use pygamer_engine::run_game;
use rtic_monotonics::systick::prelude::*;

mod controls;
//mod controls;
mod output;

systick_monotonic!(Mono, 1000);

#[rtic::app(device = pygamer::pac, dispatchers = [TC0])]
mod app {
use pygamer::{delay::Delay, timer::SpinTimer, Pins};
use rtic_monotonics::Monotonic;
use embedded_graphics::{pixelcolor::Rgb565, prelude::RgbColor};
use pygamer::{
hal::{
clock::GenericClockController,
delay::Delay,
sercom::{spi, IoSet1, Sercom2},
time::Hertz,
},
Pins,
};

use crate::{
output::{self, neopixels_test, DisplayDriver, NeoPixels},
output::{self, DisplayDriver, NeoPixels},
Mono,
};

Expand All @@ -37,15 +32,15 @@ mod app {

#[local]
struct Local {
neopixels: NeoPixels<SpinTimer>,
//neopixels: NeoPixels,
np_color: bool,
display: DisplayDriver,
}

#[init]
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(
let mut clocks = GenericClockController::with_internal_32kosc(
cx.device.GCLK,
&mut cx.device.MCLK,
&mut cx.device.OSC32KCTRL,
Expand All @@ -56,37 +51,54 @@ mod app {
let mut delay = Delay::new(cx.core.SYST, &mut clocks);

// Initialize the display
let (display, _backlight) = pins
let (mut display, _backlight) = pins
.display
.init(
&mut clocks,
cx.device.SERCOM4,
&mut cx.device.MCLK,
cx.device.TC2,
&mut delay,
&mut pins.port,
)
.unwrap();

output::wtf(&mut display);
panic!();

// 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
// here: https://github.com/atsamd-rs/atsamd/blob/master/boards/pygamer/examples/neopixel_rainbow_spi.rs
// Maybe look back into this later so we don't have to use the deprecated SpinTimer.
/* let tc4_clock = clocks.tc4_tc5(&clocks.gclk0()).unwrap();
let mut neopixels_timer = TimerCounter::tc4_(&tc4_clock, peripherals.TC4, &mut peripherals.MCLK);
neopixels_timer.start(3.mhz()); */
let neopixels_timer = SpinTimer::new(4);
// Currently in the `pygamer` examples there are no neopixel examples, because the timers are too jittery
// and are not reliable.
// `SpinTimer` seemed to work well but this has been fully deprecated and removed.
// `TimeCounter` was jittery and did not work well.
// Using a luckily placed SPI pin TODO.
// TODO: Once this is resolved, switch to the best method, check here for new examples: https://github.com/atsamd-rs/atsamd/tree/master/boards/pygamer/examples
/*let mut neopixels_timer =
TimerCounter::tc4_(&tc4_clock, cx.device.TC4, &mut cx.device.MCLK);
neopixels_timer.start(3.mhz());
let neopixels = pins.neopixel.init(neopixels_timer, &mut pins.port);
let neopixels = pins.neopixel.init(); */
/* let config = spi::Config::new(
&cx.device.MCLK,
cx.device.SERCOM2,
spi::Pads::<Sercom2, IoSet1>::default()
.data_in(pins.i2c.sda)
.data_out(pins.neopixel.neopixel)
.sclk(pins.i2c.scl),
Hertz::MHz(3),
);
let mut neopixels = ws2812_spi::Ws2812::new(config.enable());
output::neopixels_test(&mut neopixels, true);
panic!(); */

display_test::spawn().unwrap_or_else(|_| panic!());
display_test::spawn().unwrap();

(
Shared {},
Local {
neopixels,
//neopixels,
display,
np_color: false,
},
Expand All @@ -98,7 +110,7 @@ mod app {
output::display_test(cx.local.display).await
}

#[idle(local = [np_color, neopixels])]
/* #[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;
Expand All @@ -107,12 +119,12 @@ mod app {
// _cx.local.local_to_bar += 1;
let color = *cx.local.np_color;
neopixels_test(cx.local.neopixels, color);
//neopixels_test(cx.local.neopixels, color);
loop {
*cx.local.np_color = !color;
rtic::export::wfi();
}
}
} */
}

/* #[entry]
Expand Down
78 changes: 43 additions & 35 deletions kuboble-pygamer/src/output.rs
Original file line number Diff line number Diff line change
@@ -1,40 +1,40 @@
use core::iter::{repeat, repeat_n};

use crate::Mono;
use embedded_graphics::pixelcolor::Rgb565;
use embedded_graphics::prelude::*;
use embedded_graphics::primitives::PrimitiveStyle;
use kuboble_core::{LevelRating, Piece};
use pygamer::gpio::v2::PA15;
use pygamer::gpio::Pin;
use pygamer::hal::hal::digital::v1_compat::OldOutputPin;
use pygamer::hal::hal::timer::{CountDown, Periodic};
use pygamer::{
gpio::v2::{Alternate, Output, PushPull, C, PA00, PB05, PB13, PB14, PB15},
pac::SERCOM4,
sercom::{
v2::{Pad1, Pad2, Pad3},
Pad, SPIMaster4,
},
use kuboble_core::Piece;
use pygamer::hal::gpio::{
Alternate, Output, Pin, PushPull, C, PA00, PA12, PA13, PA15, PB05, PB13, PB15,
};
use pygamer_engine::{BufferedDisplay, GameDisplay, GameIndicator, GameOutput};
use rtic_monotonics::rtic_time::embedded_hal::delay::DelayNs;
use pygamer::hal::sercom::spi::{Config, Duplex, Pads, Spi, Tx};
use pygamer::hal::sercom::IoSet1;
use pygamer::hal::typelevel::NoneT;
use pygamer::pac::{SERCOM2, SERCOM4};
use pygamer::{TftDc, TftReset, TftSpi};
use rtic_monotonics::systick::prelude::*;
use rtic_monotonics::Monotonic;
use smart_leds::{SmartLedsWrite, RGB};
use ws2812_timer_delay::Ws2812;

pub type DisplayDriver = st7735_lcd::ST7735<
SPIMaster4<
Pad<SERCOM4, Pad2, Pin<PB14, Alternate<C>>>,
Pad<SERCOM4, Pad3, Pin<PB15, Alternate<C>>>,
Pad<SERCOM4, Pad1, Pin<PB13, Alternate<C>>>,
>,
Spi<Config<Pads<SERCOM4, IoSet1, NoneT, Pin<PB15, Alternate<C>>, Pin<PB13, Alternate<C>>>>, Tx>,
Pin<PB05, Output<PushPull>>,
Pin<PA00, Output<PushPull>>,
>;

pub type NeoPixels<T> = Ws2812<T, OldOutputPin<Pin<PA15, Output<PushPull>>>>;
pub type NeoPixels = ws2812_spi::Ws2812<
Spi<
Config<
Pads<
SERCOM2,
IoSet1,
Pin<PA12, Alternate<C>>,
Pin<PA15, Alternate<C>>,
Pin<PA13, Alternate<C>>,
>,
>,
Duplex,
>,
>;

trait PieceExt {
fn neopixel_color(&self) -> RGB<u8>;
Expand All @@ -51,16 +51,23 @@ impl PieceExt for Piece {

const STAR_COLOR: RGB<u8> = RGB::new(4, 4, 0);

pub fn neopixels_test(neopixels: &mut NeoPixels<pygamer::timer::SpinTimer>, color: bool) {
loop {
let colors = if color {
[Piece::Green.neopixel_color(), RGB::default()]
} else {
[Piece::Orange.neopixel_color(), RGB::default()]
};
pub fn neopixels_test(neopixels: &mut NeoPixels, color: bool) {
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();
}
neopixels.write(colors.into_iter().cycle().take(5)).unwrap();
}

// TODO
pub fn wtf(display: &mut DisplayDriver) {
display.clear(Rgb565::WHITE).unwrap();
embedded_graphics::primitives::Rectangle::new(Point::zero(), Size::new(100, 100))
.into_styled(PrimitiveStyle::with_fill(Rgb565::CSS_DARK_BLUE))
.draw(display)
.unwrap();
}

pub async fn display_test(display: &mut DisplayDriver) -> ! {
Expand All @@ -70,16 +77,16 @@ pub async fn display_test(display: &mut DisplayDriver) -> ! {
.into_styled(PrimitiveStyle::with_fill(Rgb565::CSS_DARK_BLUE))
.draw(display)
.unwrap();
Mono::delay(2000.millis()).await;
Mono::delay(2.secs()).await;

embedded_graphics::primitives::Rectangle::new(Point::zero(), Size::new(100, 100))
.into_styled(PrimitiveStyle::with_fill(Rgb565::CSS_DARK_RED))
.draw(display)
.unwrap();
Mono::delay(2000.millis()).await;
Mono::delay(2.secs()).await;
}
}

/*
pub struct PyGamerOutput<T> {
display: DisplayDriver,
buffer: BufferedDisplay,
Expand Down Expand Up @@ -146,3 +153,4 @@ impl<T> GameDisplay for PyGamerOutput<T> {
impl<T: CountDown + Periodic> GameOutput for PyGamerOutput<T> {
const SLIDE_SPEED: i32 = 14;
}
*/

0 comments on commit e984ac3

Please sign in to comment.