mirror of
https://github.com/slint-ui/slint.git
synced 2025-10-23 00:32:46 +00:00
[autofix.ci] apply automated fixes
This commit is contained in:
parent
3c64a19127
commit
26f217d12c
4 changed files with 64 additions and 89 deletions
|
@ -91,7 +91,7 @@ esp32-s3-box-3 = [
|
||||||
esp32-s3-lcd-ev-board = [
|
esp32-s3-lcd-ev-board = [
|
||||||
"slint/unsafe-single-threaded",
|
"slint/unsafe-single-threaded",
|
||||||
"esp-hal/esp32s3",
|
"esp-hal/esp32s3",
|
||||||
"esp-hal/unstable", # required for PSRAM support
|
"esp-hal/unstable", # required for PSRAM support
|
||||||
"esp-hal/psram",
|
"esp-hal/psram",
|
||||||
"embedded-hal",
|
"embedded-hal",
|
||||||
"embedded-hal-bus",
|
"embedded-hal-bus",
|
||||||
|
@ -106,7 +106,7 @@ esp32-s3-lcd-ev-board = [
|
||||||
esope-sld-c-w-s3 = [
|
esope-sld-c-w-s3 = [
|
||||||
"slint/unsafe-single-threaded",
|
"slint/unsafe-single-threaded",
|
||||||
"esp-hal/esp32s3",
|
"esp-hal/esp32s3",
|
||||||
"esp-hal/unstable", # required for PSRAM support
|
"esp-hal/unstable", # required for PSRAM support
|
||||||
"esp-hal/psram",
|
"esp-hal/psram",
|
||||||
"embedded-hal",
|
"embedded-hal",
|
||||||
"embedded-hal-bus",
|
"embedded-hal-bus",
|
||||||
|
|
|
@ -15,12 +15,13 @@ use embedded_graphics_framebuf::FrameBuf;
|
||||||
use slint::platform::software_renderer::Rgb565Pixel;
|
use slint::platform::software_renderer::Rgb565Pixel;
|
||||||
use slint::PhysicalSize;
|
use slint::PhysicalSize;
|
||||||
|
|
||||||
|
use alloc::alloc::{alloc, handle_alloc_error};
|
||||||
use alloc::boxed::Box;
|
use alloc::boxed::Box;
|
||||||
use alloc::rc::Rc;
|
use alloc::rc::Rc;
|
||||||
use core::cell::RefCell;
|
|
||||||
use core::alloc::Layout;
|
use core::alloc::Layout;
|
||||||
use alloc::alloc::{alloc, handle_alloc_error};
|
use core::cell::RefCell;
|
||||||
|
|
||||||
|
use eeprom24x::{Eeprom24x, SlaveAddr};
|
||||||
use esp_hal::clock::CpuClock;
|
use esp_hal::clock::CpuClock;
|
||||||
use esp_hal::dma::{DmaDescriptor, DmaTxBuf, ExternalBurstConfig, CHUNK_SIZE};
|
use esp_hal::dma::{DmaDescriptor, DmaTxBuf, ExternalBurstConfig, CHUNK_SIZE};
|
||||||
use esp_hal::gpio::{Level, Output, OutputConfig};
|
use esp_hal::gpio::{Level, Output, OutputConfig};
|
||||||
|
@ -39,7 +40,6 @@ use esp_hal::timer::{timg::TimerGroup, AnyTimer};
|
||||||
use esp_hal::Config as HalConfig;
|
use esp_hal::Config as HalConfig;
|
||||||
use esp_println::logger::init_logger_from_env;
|
use esp_println::logger::init_logger_from_env;
|
||||||
use log::{error, info};
|
use log::{error, info};
|
||||||
use eeprom24x::{Eeprom24x, SlaveAddr};
|
|
||||||
|
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
||||||
|
@ -108,7 +108,6 @@ pub fn init() {
|
||||||
.expect("Slint platform already initialized");
|
.expect("Slint platform already initialized");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// FrameBufferBackend wrapper for a PSRAM-backed [Rgb565; N] slice.
|
/// FrameBufferBackend wrapper for a PSRAM-backed [Rgb565; N] slice.
|
||||||
pub struct PSRAMFrameBuffer<'a> {
|
pub struct PSRAMFrameBuffer<'a> {
|
||||||
buf: &'a mut [Rgb565; LCD_BUFFER_SIZE],
|
buf: &'a mut [Rgb565; LCD_BUFFER_SIZE],
|
||||||
|
@ -176,7 +175,7 @@ impl slint::platform::Platform for EspBackend {
|
||||||
|
|
||||||
// Allocate framebuffer in PSRAM and reuse as DMA buffer with proper 64-byte alignment
|
// Allocate framebuffer in PSRAM and reuse as DMA buffer with proper 64-byte alignment
|
||||||
const FRAME_BYTES: usize = LCD_BUFFER_SIZE * 2;
|
const FRAME_BYTES: usize = LCD_BUFFER_SIZE * 2;
|
||||||
|
|
||||||
// Use manual allocation with alignment like Conway's implementation
|
// Use manual allocation with alignment like Conway's implementation
|
||||||
let layout = Layout::from_size_align(FRAME_BYTES, 64).unwrap();
|
let layout = Layout::from_size_align(FRAME_BYTES, 64).unwrap();
|
||||||
let fb_ptr = unsafe {
|
let fb_ptr = unsafe {
|
||||||
|
@ -187,37 +186,38 @@ impl slint::platform::Platform for EspBackend {
|
||||||
}
|
}
|
||||||
ptr
|
ptr
|
||||||
};
|
};
|
||||||
|
|
||||||
// Initialize the buffer with zeros
|
// Initialize the buffer with zeros
|
||||||
unsafe {
|
unsafe {
|
||||||
core::ptr::write_bytes(fb_ptr, 0, FRAME_BYTES);
|
core::ptr::write_bytes(fb_ptr, 0, FRAME_BYTES);
|
||||||
}
|
}
|
||||||
|
|
||||||
let psram_buf: &'static mut [u8] = unsafe { core::slice::from_raw_parts_mut(fb_ptr, FRAME_BYTES) };
|
let psram_buf: &'static mut [u8] =
|
||||||
|
unsafe { core::slice::from_raw_parts_mut(fb_ptr, FRAME_BYTES) };
|
||||||
|
|
||||||
// Verify PSRAM buffer allocation and alignment
|
// Verify PSRAM buffer allocation and alignment
|
||||||
let buf_ptr = psram_buf.as_ptr() as usize;
|
let buf_ptr = psram_buf.as_ptr() as usize;
|
||||||
info!("PSRAM buffer allocated at address: 0x{:08X}", buf_ptr);
|
info!("PSRAM buffer allocated at address: 0x{:08X}", buf_ptr);
|
||||||
info!("PSRAM buffer length: {}", psram_buf.len());
|
info!("PSRAM buffer length: {}", psram_buf.len());
|
||||||
info!("PSRAM buffer alignment modulo 64: {}", buf_ptr % 64);
|
info!("PSRAM buffer alignment modulo 64: {}", buf_ptr % 64);
|
||||||
|
|
||||||
// Assert that we have proper 64-byte alignment for DMA
|
// Assert that we have proper 64-byte alignment for DMA
|
||||||
assert_eq!(buf_ptr % 64, 0, "PSRAM buffer must be 64-byte aligned for DMA");
|
assert_eq!(buf_ptr % 64, 0, "PSRAM buffer must be 64-byte aligned for DMA");
|
||||||
info!("PSRAM buffer is properly 64-byte aligned for DMA");
|
info!("PSRAM buffer is properly 64-byte aligned for DMA");
|
||||||
|
|
||||||
// Publish PSRAM buffer pointer and len for app core
|
// Publish PSRAM buffer pointer and len for app core
|
||||||
unsafe {
|
unsafe {
|
||||||
PSRAM_BUF_PTR = psram_buf.as_mut_ptr();
|
PSRAM_BUF_PTR = psram_buf.as_mut_ptr();
|
||||||
PSRAM_BUF_LEN = FRAME_BYTES;
|
PSRAM_BUF_LEN = FRAME_BYTES;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configure DMA buffer with proper burst configuration
|
// Configure DMA buffer with proper burst configuration
|
||||||
let mut dma_tx: DmaTxBuf = unsafe {
|
let mut dma_tx: DmaTxBuf = unsafe {
|
||||||
let descriptors = &mut *core::ptr::addr_of_mut!(TX_DESCRIPTORS);
|
let descriptors = &mut *core::ptr::addr_of_mut!(TX_DESCRIPTORS);
|
||||||
DmaTxBuf::new_with_config(descriptors, psram_buf, ExternalBurstConfig::Size64).unwrap()
|
DmaTxBuf::new_with_config(descriptors, psram_buf, ExternalBurstConfig::Size64).unwrap()
|
||||||
};
|
};
|
||||||
|
|
||||||
// Allocate pixel buffer for Slint rendering
|
// Allocate pixel buffer for Slint rendering
|
||||||
const FRAME_PIXELS: usize = LCD_BUFFER_SIZE;
|
const FRAME_PIXELS: usize = LCD_BUFFER_SIZE;
|
||||||
let mut pixel_box: Box<[Rgb565Pixel; FRAME_PIXELS]> =
|
let mut pixel_box: Box<[Rgb565Pixel; FRAME_PIXELS]> =
|
||||||
Box::new([Rgb565Pixel(0); FRAME_PIXELS]);
|
Box::new([Rgb565Pixel(0); FRAME_PIXELS]);
|
||||||
|
@ -225,7 +225,7 @@ impl slint::platform::Platform for EspBackend {
|
||||||
|
|
||||||
// Initialize LCD DPI interface
|
// Initialize LCD DPI interface
|
||||||
let lcd_cam = LcdCam::new(peripherals.LCD_CAM);
|
let lcd_cam = LcdCam::new(peripherals.LCD_CAM);
|
||||||
|
|
||||||
// Read configuration from EEPROM
|
// Read configuration from EEPROM
|
||||||
let pclk_hz = ((eeid[12] as u32) * 1_000_000 + (eeid[13] as u32) * 100_000).min(13_600_000);
|
let pclk_hz = ((eeid[12] as u32) * 1_000_000 + (eeid[13] as u32) * 100_000).min(13_600_000);
|
||||||
let flags = eeid[25];
|
let flags = eeid[25];
|
||||||
|
@ -233,7 +233,7 @@ impl slint::platform::Platform for EspBackend {
|
||||||
let vsync_idle_low = (flags & 0x02) != 0;
|
let vsync_idle_low = (flags & 0x02) != 0;
|
||||||
let de_idle_high = (flags & 0x04) != 0;
|
let de_idle_high = (flags & 0x04) != 0;
|
||||||
let pclk_active_neg = (flags & 0x20) != 0;
|
let pclk_active_neg = (flags & 0x20) != 0;
|
||||||
|
|
||||||
// Log display configuration to match Conway's working values
|
// Log display configuration to match Conway's working values
|
||||||
info!("Display configuration:");
|
info!("Display configuration:");
|
||||||
info!(" Resolution: {}x{}", display_width, display_height);
|
info!(" Resolution: {}x{}", display_width, display_height);
|
||||||
|
@ -243,25 +243,14 @@ impl slint::platform::Platform for EspBackend {
|
||||||
info!(" VSYNC idle low: {}", vsync_idle_low);
|
info!(" VSYNC idle low: {}", vsync_idle_low);
|
||||||
info!(" DE idle high: {}", de_idle_high);
|
info!(" DE idle high: {}", de_idle_high);
|
||||||
info!(" PCLK active neg: {}", pclk_active_neg);
|
info!(" PCLK active neg: {}", pclk_active_neg);
|
||||||
|
|
||||||
let dpi_config = DpiConfig::default()
|
let dpi_config = DpiConfig::default()
|
||||||
.with_clock_mode(ClockMode {
|
.with_clock_mode(ClockMode {
|
||||||
polarity: if pclk_active_neg {
|
polarity: if pclk_active_neg { Polarity::IdleHigh } else { Polarity::IdleLow },
|
||||||
Polarity::IdleHigh
|
phase: if pclk_active_neg { Phase::ShiftHigh } else { Phase::ShiftLow },
|
||||||
} else {
|
|
||||||
Polarity::IdleLow
|
|
||||||
},
|
|
||||||
phase: if pclk_active_neg {
|
|
||||||
Phase::ShiftHigh
|
|
||||||
} else {
|
|
||||||
Phase::ShiftLow
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
.with_frequency(Rate::from_hz(pclk_hz))
|
.with_frequency(Rate::from_hz(pclk_hz))
|
||||||
.with_format(Format {
|
.with_format(Format { enable_2byte_mode: true, ..Default::default() })
|
||||||
enable_2byte_mode: true,
|
|
||||||
..Default::default()
|
|
||||||
})
|
|
||||||
// Use exact timing values that work with Conway's implementation
|
// Use exact timing values that work with Conway's implementation
|
||||||
.with_timing(FrameTiming {
|
.with_timing(FrameTiming {
|
||||||
horizontal_active_width: 320,
|
horizontal_active_width: 320,
|
||||||
|
@ -274,21 +263,9 @@ impl slint::platform::Platform for EspBackend {
|
||||||
vsync_width: 4,
|
vsync_width: 4,
|
||||||
hsync_position: 43 + 4, // (= back_porch + pulse = 47) Conway's working value
|
hsync_position: 43 + 4, // (= back_porch + pulse = 47) Conway's working value
|
||||||
})
|
})
|
||||||
.with_vsync_idle_level(if vsync_idle_low {
|
.with_vsync_idle_level(if vsync_idle_low { Level::Low } else { Level::High })
|
||||||
Level::Low
|
.with_hsync_idle_level(if hsync_idle_low { Level::Low } else { Level::High })
|
||||||
} else {
|
.with_de_idle_level(if de_idle_high { Level::High } else { Level::Low })
|
||||||
Level::High
|
|
||||||
})
|
|
||||||
.with_hsync_idle_level(if hsync_idle_low {
|
|
||||||
Level::Low
|
|
||||||
} else {
|
|
||||||
Level::High
|
|
||||||
})
|
|
||||||
.with_de_idle_level(if de_idle_high {
|
|
||||||
Level::High
|
|
||||||
} else {
|
|
||||||
Level::Low
|
|
||||||
})
|
|
||||||
.with_disable_black_region(false);
|
.with_disable_black_region(false);
|
||||||
|
|
||||||
let mut dpi = Dpi::new(lcd_cam.lcd, peripherals.DMA_CH2, dpi_config)
|
let mut dpi = Dpi::new(lcd_cam.lcd, peripherals.DMA_CH2, dpi_config)
|
||||||
|
@ -329,7 +306,7 @@ impl slint::platform::Platform for EspBackend {
|
||||||
Rgb565Pixel(0x001F) // Blue
|
Rgb565Pixel(0x001F) // Blue
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pack initial test pattern into DMA buffer
|
// Pack initial test pattern into DMA buffer
|
||||||
let dst = dma_tx.as_mut_slice();
|
let dst = dma_tx.as_mut_slice();
|
||||||
for (i, px) in pixel_buf.iter().enumerate() {
|
for (i, px) in pixel_buf.iter().enumerate() {
|
||||||
|
@ -337,7 +314,7 @@ impl slint::platform::Platform for EspBackend {
|
||||||
dst[2 * i] = lo;
|
dst[2 * i] = lo;
|
||||||
dst[2 * i + 1] = hi;
|
dst[2 * i + 1] = hi;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initial flush of the screen buffer
|
// Initial flush of the screen buffer
|
||||||
info!("Sending initial test pattern to display...");
|
info!("Sending initial test pattern to display...");
|
||||||
match dpi.send(false, dma_tx) {
|
match dpi.send(false, dma_tx) {
|
||||||
|
@ -368,32 +345,33 @@ impl slint::platform::Platform for EspBackend {
|
||||||
|
|
||||||
// Spawn Conway update task on app core (core 1)
|
// Spawn Conway update task on app core (core 1)
|
||||||
let mut cpu_control = CpuControl::new(peripherals.CPU_CTRL);
|
let mut cpu_control = CpuControl::new(peripherals.CPU_CTRL);
|
||||||
let _app_core = cpu_control.start_app_core(unsafe { &mut *core::ptr::addr_of_mut!(APP_CORE_STACK) }, move || {
|
let _app_core = cpu_control.start_app_core(
|
||||||
// Initialize TimerGroup and timer1 for app core Embassy time driver
|
unsafe { &mut *core::ptr::addr_of_mut!(APP_CORE_STACK) },
|
||||||
let timg1 = TimerGroup::new(unsafe { esp_hal::peripherals::TIMG1::steal() });
|
move || {
|
||||||
let timer1: AnyTimer = timg1.timer0.into();
|
// Initialize TimerGroup and timer1 for app core Embassy time driver
|
||||||
// Initialize Embassy time driver on app core
|
let timg1 = TimerGroup::new(unsafe { esp_hal::peripherals::TIMG1::steal() });
|
||||||
esp_hal_embassy::init([timer0, timer1]);
|
let timer1: AnyTimer = timg1.timer0.into();
|
||||||
// SAFETY: PSRAM_BUF_PTR and PSRAM_BUF_LEN are published before
|
// Initialize Embassy time driver on app core
|
||||||
let psram_ptr = unsafe { PSRAM_BUF_PTR };
|
esp_hal_embassy::init([timer0, timer1]);
|
||||||
let psram_len = unsafe { PSRAM_BUF_LEN };
|
// SAFETY: PSRAM_BUF_PTR and PSRAM_BUF_LEN are published before
|
||||||
// Wait until PSRAM is ready
|
let psram_ptr = unsafe { PSRAM_BUF_PTR };
|
||||||
loop {
|
let psram_len = unsafe { PSRAM_BUF_LEN };
|
||||||
if PSRAM_READY.try_take().is_some() {
|
// Wait until PSRAM is ready
|
||||||
break;
|
loop {
|
||||||
|
if PSRAM_READY.try_take().is_some() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Simple spin wait
|
||||||
|
core::hint::spin_loop();
|
||||||
}
|
}
|
||||||
// Simple spin wait
|
// Initialize and run Embassy executor on app core
|
||||||
core::hint::spin_loop();
|
static EXECUTOR: StaticCell<Executor> = StaticCell::new();
|
||||||
}
|
let executor = EXECUTOR.init(Executor::new());
|
||||||
// Initialize and run Embassy executor on app core
|
executor.run(|spawner| {
|
||||||
static EXECUTOR: StaticCell<Executor> = StaticCell::new();
|
spawner.spawn(slint_task(psram_ptr, psram_len)).ok();
|
||||||
let executor = EXECUTOR.init(Executor::new());
|
});
|
||||||
executor.run(|spawner| {
|
},
|
||||||
spawner
|
);
|
||||||
.spawn(slint_task(psram_ptr, psram_len))
|
|
||||||
.ok();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Core 0: Only send DMA frames in a loop
|
// Core 0: Only send DMA frames in a loop
|
||||||
loop {
|
loop {
|
||||||
|
@ -418,33 +396,27 @@ impl slint::platform::Platform for EspBackend {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
async fn slint_task(psram_ptr: *mut u8, _psram_len: usize) {
|
async fn slint_task(psram_ptr: *mut u8, _psram_len: usize) {
|
||||||
// Reconstruct the framebuffer
|
// Reconstruct the framebuffer
|
||||||
let fb: &mut [Rgb565; LCD_BUFFER_SIZE] =
|
let fb: &mut [Rgb565; LCD_BUFFER_SIZE] =
|
||||||
unsafe { &mut *(psram_ptr as *mut [Rgb565; LCD_BUFFER_SIZE]) };
|
unsafe { &mut *(psram_ptr as *mut [Rgb565; LCD_BUFFER_SIZE]) };
|
||||||
|
|
||||||
let mut frame_buf = FrameBuf::new(
|
let mut frame_buf =
|
||||||
PSRAMFrameBuffer::new(fb),
|
FrameBuf::new(PSRAMFrameBuffer::new(fb), LCD_H_RES_USIZE.into(), LCD_V_RES_USIZE.into());
|
||||||
LCD_H_RES_USIZE.into(),
|
|
||||||
LCD_V_RES_USIZE.into(),
|
|
||||||
);
|
|
||||||
let mut ticker = Ticker::every(embassy_time::Duration::from_millis(100));
|
let mut ticker = Ticker::every(embassy_time::Duration::from_millis(100));
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
// Update Slint timers and animations
|
// Update Slint timers and animations
|
||||||
slint::platform::update_timers_and_animations();
|
slint::platform::update_timers_and_animations();
|
||||||
|
|
||||||
// For now, just fill the framebuffer with a simple pattern
|
// For now, just fill the framebuffer with a simple pattern
|
||||||
// In a real implementation, this would render the Slint UI
|
// In a real implementation, this would render the Slint UI
|
||||||
frame_buf.clear(Rgb565::BLUE).ok();
|
frame_buf.clear(Rgb565::BLUE).ok();
|
||||||
|
|
||||||
ticker.next().await;
|
ticker.next().await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,4 +13,3 @@ target = "xtensa-esp32s3-none-elf"
|
||||||
|
|
||||||
[unstable]
|
[unstable]
|
||||||
build-std = ["core", "alloc"]
|
build-std = ["core", "alloc"]
|
||||||
|
|
||||||
|
|
|
@ -76,6 +76,10 @@ pub fn init() {}
|
||||||
mod embassy;
|
mod embassy;
|
||||||
|
|
||||||
pub mod prelude {
|
pub mod prelude {
|
||||||
#[cfg(any(feature = "esp32-s3-box-3", feature = "esp32-s3-lcd-ev-board", feature = "esope-sld-c-w-s3"))]
|
#[cfg(any(
|
||||||
|
feature = "esp32-s3-box-3",
|
||||||
|
feature = "esp32-s3-lcd-ev-board",
|
||||||
|
feature = "esope-sld-c-w-s3"
|
||||||
|
))]
|
||||||
pub use esp_hal;
|
pub use esp_hal;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue