Closed MohaBeacon closed 4 months ago
extern crate alloc; use core::ptr::addr_of_mut;
use alloc::{rc::Rc, boxed::Box}; slint::include_modules!();
fn create_slint_app() -> AppWindow { let ui = AppWindow::new().expect("Failed to load UI");
let ui_handle = ui.as_weak();
ui.on_request_increase_value(move || {
let ui = ui_handle.unwrap();
ui.set_counter(ui.get_counter() + 1);
});
ui
}
use rp_pico as bsp;
use bsp::entry; use fugit::RateExtU32;
use display_interface_spi::SPIInterface; use embedded_graphics::prelude::*; use embedded_graphics::{ pixelcolor::Rgb565, primitives::{Circle, PrimitiveStyleBuilder, Rectangle, Triangle}, };
use bsp::hal::{ clocks::{init_clocks_and_plls, Clock}, gpio, pac, pwm, sio::Sio, spi, watchdog::Watchdog, };
use bsp::hal::prelude::*; use gc9a01a; use panichalt as ; use slint::platform::{Platform, software_renderer::MinimalSoftwareWindow}; use slint::platform::software_renderer::Rgb565Pixel;
fn main() -> ! { use bsp::hal; use embedded_hal::timer; // Pull in any important traits use fugit::RateExtU32; use slint::platform::WindowEvent;
// -------- Setup Allocator --------
const HEAP_SIZE: usize = 200 * 1024;
static mut HEAP: [u8; HEAP_SIZE] = [0; HEAP_SIZE];
#[global_allocator]
static ALLOCATOR: embedded_alloc::Heap = embedded_alloc::Heap::empty();
unsafe { ALLOCATOR.init(addr_of_mut!(HEAP) as *const u8 as usize, core::mem::size_of_val(&HEAP)) };
// -------- Setup peripherials --------
let mut pac = pac::Peripherals::take().unwrap();
let core = pac::CorePeripherals::take().unwrap();
let mut watchdog = Watchdog::new(pac.WATCHDOG);
let sio = Sio::new(pac.SIO);
// External high-speed crystal on the pico board is 12Mhz
let external_xtal_freq_hz = 12_000_000u32;
let clocks = init_clocks_and_plls(
external_xtal_freq_hz,
pac.XOSC,
pac.CLOCKS,
pac.PLL_SYS,
pac.PLL_USB,
&mut pac.RESETS,
&mut watchdog,
)
.ok()
.unwrap();
let mut delay = cortex_m::delay::Delay::new(core.SYST, clocks.system_clock.freq().to_Hz());
let pins = bsp::Pins::new(
pac.IO_BANK0,
pac.PADS_BANK0,
sio.gpio_bank0,
&mut pac.RESETS,
);
let timer = hal::Timer::new(pac.TIMER, &mut pac.RESETS);
// These are implicitly used by the spi driver if they are in the correct mode
let _spi_sclk = pins.gpio10.into_mode::<gpio::FunctionSpi>();
let _spi_mosi = pins.gpio11.into_mode::<gpio::FunctionSpi>();
let spi_cs = pins.gpio9.into_push_pull_output();
// Create an SPI driver instance for the SPI1 device
let spi = spi::Spi::<_, _, 8>::new(pac.SPI1);
// Exchange the uninitialised SPI driver for an initialised one
let spi = spi.init(
&mut pac.RESETS,
clocks.peripheral_clock.freq(),
8_000_000u32.Hz(),
&embedded_hal::spi::MODE_0,
);
let dc_pin = pins.gpio8.into_push_pull_output();
let rst_pin = pins.gpio12.into_push_pull_output();
let spi_interface = SPIInterface::new(spi, dc_pin, spi_cs);
// initialize PWM for backlight
let pwm_slices = pwm::Slices::new(pac.PWM, &mut pac.RESETS);
// Configure PWM6
let mut pwm = pwm_slices.pwm4;
pwm.set_ph_correct();
pwm.enable();
// Output channel B on PWM6 to GPIO 13
let mut channel = pwm.channel_b;
channel.output_to(pins.led);
// Create display driver
let mut display = gc9a01a::GC9A01A::new(spi_interface, rst_pin, channel);
// Bring out of reset
display.reset(&mut delay).unwrap();
// Turn on backlight
display.set_backlight(55000);
// Initialize registers
display.initialize(&mut delay).unwrap();
// -------- Setup the Slint backend --------
let window = slint::platform::software_renderer::MinimalSoftwareWindow::new(Default::default());
slint::platform::set_platform(alloc::boxed::Box::new(MyPlatform {
window: window.clone(),
timer,
}))
.unwrap();
struct MyPlatform {
window: alloc::rc::Rc<slint::platform::software_renderer::MinimalSoftwareWindow>,
timer: hal::Timer,
}
impl slint::platform::Platform for MyPlatform {
fn create_window_adapter(&self) -> Result<alloc::rc::Rc<dyn slint::platform::WindowAdapter>, slint::PlatformError> {
Ok(self.window.clone())
}
fn duration_since_start(&self) -> core::time::Duration {
core::time::Duration::from_micros(self.timer.get_counter_low().into())
}
}
// -------- Configure the UI --------
// (need to be done after the call to slint::platform::set_platform)
let _ui = create_slint_app();
// -------- Event loop --------
let mut line = [slint::platform::software_renderer::Rgb565Pixel(0); 240];
loop {
slint::platform::update_timers_and_animations();
window.draw_if_needed(|renderer| {
use embedded_graphics_core::prelude::*;
struct DisplayWrapper<'a, T>(
&'a mut T,
&'a mut [slint::platform::software_renderer::Rgb565Pixel],
);
impl<T: DrawTarget<Color = embedded_graphics_core::pixelcolor::Rgb565>>
slint::platform::software_renderer::LineBufferProvider for DisplayWrapper<'_, T>
{
type TargetPixel = slint::platform::software_renderer::Rgb565Pixel;
fn process_line(
&mut self,
line: usize,
range: core::ops::Range<usize>,
render_fn: impl FnOnce(&mut [Self::TargetPixel]),
) {
let rect = embedded_graphics_core::primitives::Rectangle::new(
Point::new(range.start as _, line as _),
Size::new(range.len() as _, 1),
);
render_fn(&mut self.1[range.clone()]);
// NOTE! this is not an efficient way to send pixel to the screen, but it is kept simple on this template.
// It would be much faster to use the DMA to send pixel in parallel.
// See the example in https://github.com/slint-ui/slint/blob/master/examples/mcu-board-support/pico_st7789.rs
self.0
.fill_contiguous(
&rect,
self.1[range.clone()].iter().map(|p| {
embedded_graphics_core::pixelcolor::raw::RawU16::new(p.0).into()
}),
)
.map_err(drop)
.unwrap();
}
}
renderer.render_by_line(DisplayWrapper(&mut display, &mut line));
});
if window.has_active_animations() {
continue;
}
// TODO: we could save battery here by going to sleep up to
// slint::platform::duration_until_next_timer_update()
// or until the next touch interrupt, whatever comes first
// cortex_m::asm::wfe();
}
exit()
}
pub fn exit() -> ! { loop { cortex_m::asm::bkpt(); } }
Thank you for taking the time to report your issue with Slint!
What is the problem here?
Maybe you could put the code into a repo on Github or elsewhere and put a link to that repo here? It is way easier to just check out something than to copy/paste things into possibly multiple files. The missing Cargo.toml makes it even harder to just try this out.
A short description of what you actually observe and what you expect to happen instead would also help.
i have tried to use https://docs.rs/gc9a01a/latest/gc9a01a/ it is working fine with draw line by line - but when trying to use buffer - embedded hal - not able to know how to // ... configure the screen driver to use buffer1 or buffer2 ... in the docs of mcu
[dependencies] embedded-hal = { version = "0.2.7", features = ["unproven"]} embedded-alloc = "0.5" embedded-graphics-core ="0.4.0" display-interface ="0.4.1" display-interface-spi = "0.4.1" shared-bus = "0.2.4" gc9a01a = "0.1.1" cortex-m = "0.7" cortex-m-rt = "0.7" panic-halt = "0.2" tinybmp = "0.5" embedded-graphics = "0.8.0" rp-pico = "0.7" fugit = "0.3"
Do you have enough memory to drive a buffer on the rp-pico?
Do you have enough memory to drive a buffer on the rp-pico?
yes i have, i feel my configuration to make it work is having a trouble. let me update and let you know on this.
![no_std]
![no_main]
extern crate alloc; use alloc::{rc::Rc, boxed::Box}; slint::include_modules!();
fn create_slint_app() -> AppWindow { let ui = AppWindow::new().expect("Failed to load UI");
}
use rp_pico as bsp;
use bsp::entry; use fugit::RateExtU32;
use display_interface_spi::SPIInterface; use embedded_graphics::prelude::*; use embedded_graphics::{ pixelcolor::Rgb565, primitives::{Circle, PrimitiveStyleBuilder, Rectangle, Triangle}, };
use bsp::hal::{ clocks::{init_clocks_and_plls, Clock}, gpio, pac, pwm, sio::Sio, spi, watchdog::Watchdog, };
use bsp::hal::prelude::*; use gc9a01a; use panichalt as ; use slint::platform::{Platform, software_renderer::MinimalSoftwareWindow}; use slint::platform::software_renderer::Rgb565Pixel;
[entry]
fn main() -> ! { use bsp::hal; use embedded_hal::timer; // Pull in any important traits use fugit::RateExtU32; use slint::platform::WindowEvent;
}
pub fn exit() -> ! { loop { cortex_m::asm::bkpt(); } }
[dependencies] embedded-hal = { version = "0.2.7", features = ["unproven"]} embedded-alloc = "0.5" embedded-graphics-core ="0.4.0" display-interface ="0.4.1" display-interface-spi = "0.4.1" gc9a01a = "0.1.1" cortex-m = "0.7" cortex-m-rt = "0.7" panic-halt = "0.2" tinybmp = "0.5" embedded-graphics = "0.8.0" rp-pico = "0.7" fugit = "0.3"
[dev-dependencies] cortex-m = "0.7" cortex-m-rt = "0.7" panic-halt = "0.2" tinybmp = "0.5" embedded-graphics = "0.8.0" rp-pico = "0.7" fugit = "0.3"
[dependencies.slint] version = "1.6.0" default-features = false features = ["compat-1-2", "unsafe-single-threaded", "libm", "renderer-software"]
[build-dependencies] slint-build = "1.6.0"