- Rust 100%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| .cargo | ||
| examples | ||
| src | ||
| .gitignore | ||
| Cargo.lock | ||
| Cargo.toml | ||
| LICENSE | ||
| README.md | ||
stm32f723e-disc
Board support crate for the STMicroelectronics STM32F723E-DISCO discovery kit, written in Rust on top of stm32f7xx-hal.
Covers the parts of the board a graphical application needs that are not provided by the HAL:
- the 240x240 ST7789H2 LCD, attached to the Flexible Memory Controller (FMC) as a 16-bit parallel device,
- the external PSRAM on the same FMC, used as a heap for framebuffers,
- DMA2 memory-to-memory transfers that push a whole frame from PSRAM into the LCD while the CPU draws the next one,
- an
embedded-graphicsDrawTargetwith double buffering, - the FT6x06 capacitive touch controller on I2C3, with multi touch events,
- the user button, EXTI-capable, and the two user LEDs.
Design
The crate does not take ownership of peripherals. An application must split the GPIO ports itself and hand the pins and peripherals to the init functions. This makes the crate compatible with bare metal and different RTOS (RTIC, Embassy, Bern RTOS), making it flexible at little extra development effort.
Initialisation is ordered by tokens: fmc::init returns a PSRAM and an LCD token, psram::init_heap consumes the first, lcd::init consumes the second. It is not possible to allocate framebuffers before the FMC is configured, or to configure it twice.
The HAL, cortex-m, cortex-m-rt, heapless and embedded-graphics are re-exported. Applications should use these re-exports instead of adding the crates themselves, which guarantees a single version of each and avoids trait-mismatch errors between crate and application.
Usage
use stm32f723e_disc as bsp;
use bsp::embedded_graphics::{pixelcolor::Rgb565, prelude::*, primitives::{Circle, PrimitiveStyle}};
use bsp::stm32f7xx_hal::{pac, prelude::*};
let p = pac::Peripherals::take().unwrap();
p.RCC.ahb1enr.modify(|_, w| w.dma2en().enabled());
p.RCC.apb1enr.modify(|_, w| w.i2c3en().enabled());
let mut rcc = p.RCC.constrain();
let clocks = rcc.cfgr.sysclk(216.MHz()).freeze();
let gpioa = p.GPIOA.split();
let gpioh = p.GPIOH.split();
// ... split ports B, D, E, F, G and build `bsp::fmc::Pins` (see the examples) ...
let (psram, lcd) = bsp::fmc::init(p.FMC, fmc_pins, &clocks);
let heap = bsp::psram::init_heap(psram);
let mut delay = p.TIM2.delay_us(&clocks);
let mut display = bsp::lcd::init(
lcd,
p.DMA2,
gpioh.ph11.into(), // backlight
gpioh.ph9.into(), // touch panel reset
|ms| delay.delay_ms(ms), // the crate does not own SysTick
heap,
);
display.set_backlight(true);
let mut touch = bsp::touch::Touch::new(p.I2C3, gpioa.pa8.into(), gpioh.ph8.into(), &clocks, &mut rcc.apb1);
loop {
display.clear(Rgb565::BLACK).ok();
if let Ok(bsp::touch::Event::Single(pt)) = touch.read() {
Circle::new(Point::new(pt.x as i32 - 10, pt.y as i32 - 10), 20)
.into_styled(PrimitiveStyle::with_fill(Rgb565::RED))
.draw(&mut display)
.ok();
}
display.flush();
}
Examples
| Example | What it shows |
|---|---|
bsp_leds |
blink pattern on the two user LEDs |
bsp_button |
count button presses, show the count on the LEDs |
bsp_button_leds |
LEDs follow the button |
bsp_button_interrupt |
button on the EXTI0 interrupt, count shown on the display |
bsp_display |
bouncing balls spawned by touch, with a FPS counter |
bsp_multitouch |
two-finger tracking |
bare_fmc_lcd_psram_dma |
the whole display path with HAL and PAC only, no crate code |
rustup target add thumbv7em-none-eabihf
cargo install probe-rs-tools --locked
# build, flash using ST-LINK and run
cargo run --release --example bsp_display
Using this crate as a dependency
Depend on it by git URL and pin a tag:
[dependencies]
stm32f723e-disc = { git = "https://git.domi.work/domi/stm32f723e-disc.git", tag = "v0.1.0" }
Note: the embedded-graphics feature is a default feature, use default-features = false to drop the DrawTarget implementation and dependency.