Skip to content

Commit

Permalink
deps(pygamer)!: Upgrade pygamer BSP display driver and graphics dep…
Browse files Browse the repository at this point in the history
…endencies (#777)

* Upgrades the display and graphics dependencies: st7735-lcd, embedded-graphics, tinybmp
* Corrects the README.md to list `pygamer` as a `samd51j` BSP instead of the erroneous `same53j`.
* Adds an empty `DisplayError` and a `DisplayDriver` type alias, both to address clippy lints.

* Changes the `DisplayError` to an enum with variants to provide more detail about why the display driver initialization failed.
* Exposes the `dma` and `max-channels` HAL features in the BSP for convenience.
* Adds a `cortex_m::asm::wfi()` call inside the terminal infinite loop in the examples to address the `empty_loop` clippy lint.

---------

Co-authored-by: Dan Whitman <dwhitman44@mgail.com>
  • Loading branch information
kyp44 and Dan Whitman authored Nov 11, 2024
1 parent f91c7aa commit 4b701a4
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 17 deletions.
15 changes: 9 additions & 6 deletions boards/pygamer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ version = "0.11.0"

[dependencies]
cortex-m = {version = "0.7", features = ["critical-section-single-core"]}
st7735-lcd = "0.8.1"
embedded-hal-bus = "0.2.0"
# This version is pinned as recommended by: https://docs.rs/embedded-hal-bus/0.2.0/embedded_hal_bus/spi/struct.ExclusiveDevice.html#method.new_no_delay
st7735-lcd = "=0.10.0"

[dependencies.cortex-m-rt]
optional = true
Expand All @@ -29,23 +31,24 @@ version = "0.18.2"

[dependencies.usb-device]
optional = true
version = "0.3.1"
version = "0.3.2"

[dev-dependencies]
embedded-graphics = "0.7.1"
embedded-hal-bus = "0.2.0"
embedded-graphics = "0.8.1"
embedded-sdmmc = "0.8.0"
lis3dh = "0.4.3"
micromath = "2.1"
panic-halt = "0.2"
panic-halt = "1"
rtic = {version = "2.1.1", features = ["thumbv7-backend"]}
smart-leds = "0.4"
tinybmp = "0.3.1"
tinybmp = "0.6"
usbd-serial = "0.2"

[features]
# ask the HAL to enable atsamd51j support
default = ["rt", "atsamd-hal/samd51j"]
dma = ["atsamd-hal/dma"]
max-channels = ["dma", "atsamd-hal/max-channels"]
panic_led = []
rt = ["cortex-m-rt", "atsamd-hal/samd51j-rt"]
usb = ["atsamd-hal/usb", "usb-device"]
Expand Down
4 changes: 3 additions & 1 deletion boards/pygamer/examples/clock_out.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,7 @@ fn main() -> ! {
.configure_gclk_divider_and_source(Gclk2, 40, Dpll0, false)
.unwrap();
let _clock_out_pin: GclkOut = pins.d5.into();
loop {}
loop {
cortex_m::asm::wfi();
}
}
4 changes: 3 additions & 1 deletion boards/pygamer/examples/ferris_img.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,7 @@ fn main() -> ! {
let ferris = Image::new(&raw_image, Point::new(32, 32));

ferris.draw(&mut display).unwrap();
loop {}
loop {
cortex_m::asm::wfi();
}
}
4 changes: 3 additions & 1 deletion boards/pygamer/examples/qspi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,9 @@ fn main() -> ! {
flash.read_memory(0, &mut read_buf);
assert_eq!(read_buf, write_buf);

loop {}
loop {
cortex_m::asm::wfi();
}
}

/// Wait for the write-in-progress and suspended write/erase.
Expand Down
52 changes: 44 additions & 8 deletions boards/pygamer/src/pins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use super::{hal, pac};

use hal::prelude::*;

use embedded_hal_bus::spi as bspi;
use hal::clock::GenericClockController;
use hal::gpio::PA01;
use hal::pwm;
Expand Down Expand Up @@ -581,30 +582,65 @@ pub struct Display {
pub tft_backlight: TftBacklightReset,
}

/// Error that can occur when initializing the display.
#[derive(Debug)]
pub enum DisplayError {
/// Could not configure the SERCOM4 clock.
SercomClock,
/// Could not configure the SPI port to drive the display.
Spi,
/// Could not setup the ST7735 display driver.
Driver,
/// Could not configure the TC2/TC3 clock for PWM control of the backlight.
Tc2Tc3Clock,
}
impl From<()> for DisplayError {
#[inline]
fn from(_value: ()) -> Self {
Self::Driver
}
}

pub type TftPads = spi::Pads<Sercom4, IoSet1, NoneT, TftMosi, TftSclk>;
pub type TftSpi = spi::Spi<spi::Config<TftPads>, spi::Tx>;
pub type TftSpi = bspi::ExclusiveDevice<
spi::PanicOnRead<spi::Spi<spi::Config<TftPads>, spi::Tx>>,
TftCs,
bspi::NoDelay,
>;

/// The on-board display driver that is a
/// [`DrawTarget`](https://docs.rs/embedded-graphics/latest/embedded_graphics/draw_target/trait.DrawTarget.html)
/// for embedded graphics.
pub type DisplayDriver = ST7735<TftSpi, TftDc, TftReset>;

impl Display {
/// Convenience for setting up the on board display.
/// Convenience for setting up the on-board display.
pub fn init(
self,
clocks: &mut GenericClockController,
sercom4: pac::Sercom4,
mclk: &mut pac::Mclk,
timer2: pac::Tc2,
delay: &mut hal::delay::Delay,
) -> Result<(ST7735<TftSpi, TftDc, TftReset>, Pwm2<PA01>), ()> {
) -> Result<(DisplayDriver, Pwm2<PA01>), DisplayError> {
let gclk0 = clocks.gclk0();
let clock = &clocks.sercom4_core(&gclk0).ok_or(())?;
let clock = &clocks
.sercom4_core(&gclk0)
.ok_or(DisplayError::SercomClock)?;
let pads = spi::Pads::default()
.sclk(self.tft_sclk)
.data_out(self.tft_mosi);
let tft_spi = spi::Config::new(mclk, sercom4, pads, clock.freq())
.spi_mode(spi::MODE_0)
.baud(16.MHz())
.enable();
let mut tft_cs: TftCs = self.tft_cs.into();
tft_cs.set_low().ok();
let tft_spi = bspi::ExclusiveDevice::new_no_delay(
spi::Config::new(mclk, sercom4, pads, clock.freq())
.spi_mode(spi::MODE_0)
.baud(16.MHz())
.enable()
.into_panic_on_read(),
tft_cs,
)
.map_err(|_| DisplayError::Spi)?;
let mut display = st7735_lcd::ST7735::new(
tft_spi,
self.tft_dc.into(),
Expand Down

0 comments on commit 4b701a4

Please sign in to comment.