use alloc::{alloc::Global, boxed::Box}; use esp_hal::{ Blocking, dma::BurstConfig, lcd_cam::lcd::dpi::Dpi, peripherals::DMA_CH0, spi::master::AnySpi, }; use esp_hal_bounce_buffers::{DmaBounce, Swapchain, SwapchainWriter, allocate_dma_buffer_in}; use crate::PSRAM_ALLOCATOR; // TODO: Rename or get rid of. pub struct Framebuffer { pub width: u32, pub height: u32, pub swapchain: Option, pub bounce_buffers: Option, } impl Framebuffer { pub fn new( channel: DMA_CH0<'static>, peripheral_src: AnySpi<'static>, peripheral_dst: Dpi<'static, Blocking>, burst_config: BurstConfig, front_porch_pixels: u32, width_pixels: u32, height_pixels: u32, rows_per_window: usize, cyclic: bool, ) -> Self { const BYTES_PER_PIXEL: usize = core::mem::size_of::(); let buffer_size = width_pixels as usize * height_pixels as usize * BYTES_PER_PIXEL; 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(); let bounce_buffers = DmaBounce::new( Global, channel, peripheral_src, peripheral_dst, swapchain_reader, front_porch_pixels as usize * BYTES_PER_PIXEL, width_pixels as usize * BYTES_PER_PIXEL, rows_per_window, burst_config, cyclic, ); Self { width: width_pixels, height: height_pixels, swapchain: Some(swapchain_writer), bounce_buffers: Some(bounce_buffers), } } }