2026-02-27 21:25:59 +01:00
|
|
|
use alloc::{alloc::Global, boxed::Box};
|
2026-02-14 20:03:32 +01:00
|
|
|
use esp_hal::{
|
2026-02-27 21:25:59 +01:00
|
|
|
Blocking, dma::BurstConfig, lcd_cam::lcd::dpi::Dpi, peripherals::DMA_CH0, spi::master::AnySpi,
|
2026-02-14 20:03:32 +01:00
|
|
|
};
|
2026-02-26 02:02:25 +01:00
|
|
|
use esp_hal_bounce_buffers::{DmaBounce, Swapchain, SwapchainWriter, allocate_dma_buffer_in};
|
2026-02-14 20:03:32 +01:00
|
|
|
|
2026-02-24 23:07:51 +01:00
|
|
|
use crate::PSRAM_ALLOCATOR;
|
2026-02-14 20:03:32 +01:00
|
|
|
|
2026-02-23 23:08:27 +01:00
|
|
|
// TODO: Rename or get rid of.
|
2026-02-22 00:59:01 +01:00
|
|
|
pub struct Framebuffer {
|
|
|
|
|
pub width: u32,
|
|
|
|
|
pub height: u32,
|
2026-02-23 23:08:27 +01:00
|
|
|
pub swapchain: Option<SwapchainWriter>,
|
|
|
|
|
pub bounce_buffers: Option<DmaBounce>,
|
2026-02-22 00:59:01 +01:00
|
|
|
}
|
|
|
|
|
|
2026-02-14 20:03:32 +01:00
|
|
|
impl Framebuffer {
|
2026-02-22 00:59:01 +01:00
|
|
|
pub fn new(
|
|
|
|
|
channel: DMA_CH0<'static>,
|
|
|
|
|
peripheral_src: AnySpi<'static>,
|
|
|
|
|
peripheral_dst: Dpi<'static, Blocking>,
|
2026-02-22 17:19:02 +01:00
|
|
|
burst_config: BurstConfig,
|
2026-02-22 16:09:20 +01:00
|
|
|
front_porch_pixels: u32,
|
|
|
|
|
width_pixels: u32,
|
|
|
|
|
height_pixels: u32,
|
2026-02-22 00:59:01 +01:00
|
|
|
rows_per_window: usize,
|
|
|
|
|
cyclic: bool,
|
|
|
|
|
) -> Self {
|
2026-02-22 16:09:20 +01:00
|
|
|
const BYTES_PER_PIXEL: usize = core::mem::size_of::<u16>();
|
|
|
|
|
let buffer_size = width_pixels as usize * height_pixels as usize * BYTES_PER_PIXEL;
|
2026-02-23 23:08:27 +01:00
|
|
|
let framebuffers = [
|
|
|
|
|
Box::leak(allocate_dma_buffer_in(
|
|
|
|
|
buffer_size,
|
|
|
|
|
burst_config,
|
|
|
|
|
&PSRAM_ALLOCATOR,
|
|
|
|
|
)),
|
|
|
|
|
Box::leak(allocate_dma_buffer_in(
|
|
|
|
|
buffer_size,
|
|
|
|
|
burst_config,
|
|
|
|
|
&PSRAM_ALLOCATOR,
|
|
|
|
|
)),
|
|
|
|
|
];
|
|
|
|
|
let (swapchain_reader, swapchain_writer) = Swapchain { framebuffers }.into_reader_writer();
|
2026-02-22 00:59:01 +01:00
|
|
|
let bounce_buffers = DmaBounce::new(
|
|
|
|
|
Global,
|
|
|
|
|
channel,
|
|
|
|
|
peripheral_src,
|
|
|
|
|
peripheral_dst,
|
2026-02-23 23:08:27 +01:00
|
|
|
swapchain_reader,
|
2026-02-22 16:09:20 +01:00
|
|
|
front_porch_pixels as usize * BYTES_PER_PIXEL,
|
|
|
|
|
width_pixels as usize * BYTES_PER_PIXEL,
|
|
|
|
|
rows_per_window,
|
2026-02-22 00:59:01 +01:00
|
|
|
burst_config,
|
|
|
|
|
cyclic,
|
2026-02-14 20:03:32 +01:00
|
|
|
);
|
|
|
|
|
|
|
|
|
|
Self {
|
2026-02-22 16:09:20 +01:00
|
|
|
width: width_pixels,
|
|
|
|
|
height: height_pixels,
|
2026-02-23 23:08:27 +01:00
|
|
|
swapchain: Some(swapchain_writer),
|
|
|
|
|
bounce_buffers: Some(bounce_buffers),
|
2026-02-14 20:03:32 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|