More cleanup
This commit is contained in:
parent
bf5957a8bf
commit
3e52243efe
|
|
@ -8,7 +8,7 @@ use enumset::EnumSet;
|
||||||
use crate::ffi::string::__xkbc_memcpy;
|
use crate::ffi::string::__xkbc_memcpy;
|
||||||
|
|
||||||
// Here we select the allocator to use for libxkbcommon.
|
// Here we select the allocator to use for libxkbcommon.
|
||||||
pub use crate::PSRAM_ALLOCATOR as XKBC_ALLOCATOR;
|
pub use crate::ram::PSRAM_ALLOCATOR as XKBC_ALLOCATOR;
|
||||||
|
|
||||||
// Implementation based on esp-alloc's `compat` feature.
|
// Implementation based on esp-alloc's `compat` feature.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,12 +30,10 @@ use embassy_sync::blocking_mutex;
|
||||||
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
||||||
use embassy_sync::channel::Channel;
|
use embassy_sync::channel::Channel;
|
||||||
use embassy_time::{Duration, Timer};
|
use embassy_time::{Duration, Timer};
|
||||||
use esp_alloc::{HeapRegion, MemoryCapability};
|
use esp_alloc::MemoryCapability;
|
||||||
use esp_hal::clock::CpuClock;
|
use esp_hal::clock::CpuClock;
|
||||||
use esp_hal::dma::{BurstConfig, ExternalBurstConfig, InternalBurstConfig};
|
use esp_hal::dma::{BurstConfig, ExternalBurstConfig, InternalBurstConfig};
|
||||||
use esp_hal::efuse::Efuse;
|
use esp_hal::efuse::Efuse;
|
||||||
#[cfg(not(feature = "alt-log"))]
|
|
||||||
use esp_hal::gpio::NoPin;
|
|
||||||
use esp_hal::gpio::{Flex, Input, InputConfig, Level, Output, OutputConfig, Pull};
|
use esp_hal::gpio::{Flex, Input, InputConfig, Level, Output, OutputConfig, Pull};
|
||||||
use esp_hal::i2c::master::{I2c, I2cAddress};
|
use esp_hal::i2c::master::{I2c, I2cAddress};
|
||||||
use esp_hal::interrupt::software::{SoftwareInterrupt, SoftwareInterruptControl};
|
use esp_hal::interrupt::software::{SoftwareInterrupt, SoftwareInterruptControl};
|
||||||
|
|
@ -44,7 +42,6 @@ use esp_hal::lcd_cam::lcd::dpi::Dpi;
|
||||||
use esp_hal::ledc::{self, LSGlobalClkSource, Ledc, LowSpeed};
|
use esp_hal::ledc::{self, LSGlobalClkSource, Ledc, LowSpeed};
|
||||||
use esp_hal::peripherals::{DMA_CH0, SPI2};
|
use esp_hal::peripherals::{DMA_CH0, SPI2};
|
||||||
use esp_hal::psram::{FlashFreq, PsramConfig, PsramSize, SpiRamFreq, SpiTimingConfigCoreClock};
|
use esp_hal::psram::{FlashFreq, PsramConfig, PsramSize, SpiRamFreq, SpiTimingConfigCoreClock};
|
||||||
use esp_hal::ram;
|
|
||||||
use esp_hal::rng::TrngSource;
|
use esp_hal::rng::TrngSource;
|
||||||
use esp_hal::sha::ShaBackend;
|
use esp_hal::sha::ShaBackend;
|
||||||
use esp_hal::spi::master::AnySpi;
|
use esp_hal::spi::master::AnySpi;
|
||||||
|
|
@ -78,6 +75,7 @@ use {esp_alloc as _, esp_backtrace as _};
|
||||||
use crate::matrix::IoeMatrix;
|
use crate::matrix::IoeMatrix;
|
||||||
use crate::peripherals::st7701s::{St7701s, St7701sController};
|
use crate::peripherals::st7701s::{St7701s, St7701sController};
|
||||||
use crate::proxy::create_hid_report_interceptor;
|
use crate::proxy::create_hid_report_interceptor;
|
||||||
|
use crate::ram::{PSRAM_ALLOCATOR, STACK_SIZE_CORE_APP};
|
||||||
use crate::ui::backend::SlintBackend;
|
use crate::ui::backend::SlintBackend;
|
||||||
use crate::ui::dpi::Framebuffer;
|
use crate::ui::dpi::Framebuffer;
|
||||||
use crate::vial::{
|
use crate::vial::{
|
||||||
|
|
@ -96,6 +94,7 @@ mod logging;
|
||||||
mod matrix;
|
mod matrix;
|
||||||
mod peripherals;
|
mod peripherals;
|
||||||
mod proxy;
|
mod proxy;
|
||||||
|
mod ram;
|
||||||
mod ui;
|
mod ui;
|
||||||
mod util;
|
mod util;
|
||||||
mod vial;
|
mod vial;
|
||||||
|
|
@ -107,20 +106,9 @@ mod console;
|
||||||
// For more information see: <https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/system/app_image_format.html#application-description>
|
// For more information see: <https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/system/app_image_format.html#application-description>
|
||||||
esp_bootloader_esp_idf::esp_app_desc!();
|
esp_bootloader_esp_idf::esp_app_desc!();
|
||||||
|
|
||||||
// Memory allocation regions.
|
|
||||||
// These can be debugged using `xtensa-esp32s3-elf-size -A <path-to-binary>`.
|
|
||||||
// A panic such as `memory allocation of 3740121773 bytes failed` is caused by a heap overflow. The size is `DEEDBAAD` in hex.
|
|
||||||
|
|
||||||
/// Total heap size
|
|
||||||
const HEAP_SIZE: usize = 112 * 1024;
|
|
||||||
/// Size of the app core's stack
|
|
||||||
const STACK_SIZE_CORE_APP: usize = 80 * 1024;
|
|
||||||
|
|
||||||
// const FRAME_DURATION_MIN: Duration = Duration::from_millis(40); // 25 FPS
|
// const FRAME_DURATION_MIN: Duration = Duration::from_millis(40); // 25 FPS
|
||||||
const FRAME_DURATION_MIN: Duration = Duration::from_millis(100); // 10 FPS
|
const FRAME_DURATION_MIN: Duration = Duration::from_millis(100); // 10 FPS
|
||||||
|
|
||||||
pub static PSRAM_ALLOCATOR: esp_alloc::EspHeap = esp_alloc::EspHeap::empty();
|
|
||||||
|
|
||||||
static KEYBOARD_REPORT_PROXY: Channel<CriticalSectionRawMutex, Report, 16> = Channel::new();
|
static KEYBOARD_REPORT_PROXY: Channel<CriticalSectionRawMutex, Report, 16> = Channel::new();
|
||||||
static LCD_ENABLED: AtomicBool = AtomicBool::new(false);
|
static LCD_ENABLED: AtomicBool = AtomicBool::new(false);
|
||||||
|
|
||||||
|
|
@ -130,114 +118,6 @@ static LCD_ENABLED: AtomicBool = AtomicBool::new(false);
|
||||||
// /// Used to signal that the MCU is ready to render the GUI.
|
// /// Used to signal that the MCU is ready to render the GUI.
|
||||||
// static SIGNAL_UI_RENDER: Signal<CriticalSectionRawMutex, ()> = Signal::new();
|
// static SIGNAL_UI_RENDER: Signal<CriticalSectionRawMutex, ()> = Signal::new();
|
||||||
|
|
||||||
#[embassy_executor::task]
|
|
||||||
async fn test_bounce_buffers_task(
|
|
||||||
channel: DMA_CH0<'static>,
|
|
||||||
peripheral: SPI2<'static>,
|
|
||||||
st7701s: St7701s<'static, Blocking>,
|
|
||||||
) {
|
|
||||||
test_bounce_buffers(channel, peripheral, st7701s).await;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(unused)]
|
|
||||||
async fn test_bounce_buffers(
|
|
||||||
channel: DMA_CH0<'static>,
|
|
||||||
peripheral: SPI2<'static>,
|
|
||||||
mut st7701s: St7701s<'static, Blocking>,
|
|
||||||
) {
|
|
||||||
error!("TEST BOUNCE BUFFERS SECTION ENTERED");
|
|
||||||
|
|
||||||
const BYTES_PER_PIXEL: usize = core::mem::size_of::<u16>();
|
|
||||||
// Assume highest burst config setting.
|
|
||||||
const EXTERNAL_BURST_CONFIG: ExternalBurstConfig = ExternalBurstConfig::Size32;
|
|
||||||
const ALIGNMENT_PIXELS: usize = EXTERNAL_BURST_CONFIG as usize / BYTES_PER_PIXEL;
|
|
||||||
// The total number of pixels demanded by the DPI, per row.
|
|
||||||
const WIDTH_TOTAL_PIXELS: usize = 368;
|
|
||||||
// The total number of rows demanded by the DPI, per frame.
|
|
||||||
const HEIGHT_PIXELS: usize = 960;
|
|
||||||
// The number of unused pixels at the start of the row.
|
|
||||||
const FRONT_PORCH_ACTUAL_PIXELS: usize = 120;
|
|
||||||
// The number of actually visible pixels, per row.
|
|
||||||
const WIDTH_VISIBLE_PIXELS: usize = 240;
|
|
||||||
// The number of pixels not stored in a bounce buffer, per row.
|
|
||||||
// This many arbitrary pixels are sent to the DPI.
|
|
||||||
const FRONT_PORCH_SKIPPED_PIXELS: usize =
|
|
||||||
(FRONT_PORCH_ACTUAL_PIXELS / ALIGNMENT_PIXELS) * ALIGNMENT_PIXELS;
|
|
||||||
const WIDTH_STORED_PIXELS: usize = WIDTH_TOTAL_PIXELS - FRONT_PORCH_SKIPPED_PIXELS;
|
|
||||||
const VISIBLE_OFFSET_IN_BUFFER_PIXELS: usize =
|
|
||||||
FRONT_PORCH_ACTUAL_PIXELS - FRONT_PORCH_SKIPPED_PIXELS;
|
|
||||||
const ROWS_PER_WINDOW: usize = 16;
|
|
||||||
let burst_config = BurstConfig {
|
|
||||||
internal_memory: InternalBurstConfig::Enabled,
|
|
||||||
external_memory: EXTERNAL_BURST_CONFIG,
|
|
||||||
};
|
|
||||||
let (swapchain_reader, mut swapchain_writer) = Swapchain {
|
|
||||||
framebuffers: [
|
|
||||||
Box::leak(allocate_dma_buffer_in(
|
|
||||||
HEIGHT_PIXELS * WIDTH_STORED_PIXELS * BYTES_PER_PIXEL,
|
|
||||||
burst_config,
|
|
||||||
&PSRAM_ALLOCATOR,
|
|
||||||
)),
|
|
||||||
Box::leak(allocate_dma_buffer_in(
|
|
||||||
HEIGHT_PIXELS * WIDTH_STORED_PIXELS * BYTES_PER_PIXEL,
|
|
||||||
burst_config,
|
|
||||||
&PSRAM_ALLOCATOR,
|
|
||||||
)),
|
|
||||||
],
|
|
||||||
}
|
|
||||||
.into_reader_writer();
|
|
||||||
|
|
||||||
{
|
|
||||||
let write_guard = &mut swapchain_writer.write();
|
|
||||||
let buffer_src = bytemuck::cast_slice_mut::<u8, Rgb565Pixel>(write_guard);
|
|
||||||
let colors = (0..WIDTH_VISIBLE_PIXELS as u8 / 2)
|
|
||||||
.rev()
|
|
||||||
.map(|val| Rgb565Pixel::from_rgb(0xFF, val * 2, 0))
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
for (index, pixel) in buffer_src.iter_mut().enumerate() {
|
|
||||||
let mut x =
|
|
||||||
(index % WIDTH_STORED_PIXELS) as i16 - VISIBLE_OFFSET_IN_BUFFER_PIXELS as i16;
|
|
||||||
let mut y = (index / WIDTH_STORED_PIXELS) as i16;
|
|
||||||
|
|
||||||
if x < WIDTH_VISIBLE_PIXELS as i16 {
|
|
||||||
x = core::cmp::min(x, WIDTH_VISIBLE_PIXELS as i16 - 1 - x);
|
|
||||||
y = core::cmp::min(y, HEIGHT_PIXELS as i16 - 1 - y);
|
|
||||||
let min = core::cmp::min(x, y);
|
|
||||||
|
|
||||||
*pixel = colors[min as usize % colors.len()];
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
*pixel = Rgb565Pixel::default();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut dma_bounce = DmaBounce::new(
|
|
||||||
Global,
|
|
||||||
channel,
|
|
||||||
AnySpi::from(peripheral),
|
|
||||||
st7701s.dpi,
|
|
||||||
swapchain_reader,
|
|
||||||
FRONT_PORCH_SKIPPED_PIXELS * BYTES_PER_PIXEL,
|
|
||||||
WIDTH_STORED_PIXELS * BYTES_PER_PIXEL,
|
|
||||||
ROWS_PER_WINDOW,
|
|
||||||
burst_config,
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
let mut bb_controller = DmaBounceController::new(dma_bounce);
|
|
||||||
|
|
||||||
error!("TEST BOUNCE BUFFERS TASK LAUNCHED");
|
|
||||||
|
|
||||||
loop {
|
|
||||||
bb_controller.start().await.unwrap();
|
|
||||||
st7701s.controller.sleep_off().await;
|
|
||||||
Timer::after_secs(1).await;
|
|
||||||
st7701s.controller.sleep_on().await;
|
|
||||||
bb_controller.stop().await.unwrap();
|
|
||||||
Timer::after_secs(1).await;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[esp_rtos::main]
|
#[esp_rtos::main]
|
||||||
async fn main(_spawner: Spawner) {
|
async fn main(_spawner: Spawner) {
|
||||||
let config = esp_hal::Config::default()
|
let config = esp_hal::Config::default()
|
||||||
|
|
@ -255,7 +135,7 @@ async fn main(_spawner: Spawner) {
|
||||||
#[cfg(feature = "alt-log")]
|
#[cfg(feature = "alt-log")]
|
||||||
let (tx, rx) = (peripherals.GPIO12, peripherals.GPIO5);
|
let (tx, rx) = (peripherals.GPIO12, peripherals.GPIO5);
|
||||||
#[cfg(not(feature = "alt-log"))]
|
#[cfg(not(feature = "alt-log"))]
|
||||||
let (tx, rx) = (NoPin, NoPin);
|
let (tx, rx) = (esp_hal::gpio::NoPin, esp_hal::gpio::NoPin);
|
||||||
|
|
||||||
Uart::new(peripherals.UART2, Default::default())
|
Uart::new(peripherals.UART2, Default::default())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
|
@ -271,32 +151,8 @@ async fn main(_spawner: Spawner) {
|
||||||
#[cfg(feature = "rtt-log")]
|
#[cfg(feature = "rtt-log")]
|
||||||
logging::rtt::setup_logging();
|
logging::rtt::setup_logging();
|
||||||
|
|
||||||
// Use the internal DRAM as the heap.
|
// Set up allocators.
|
||||||
// Memory reclaimed from the esp-idf bootloader.
|
ram::initialize(peripherals.PSRAM);
|
||||||
const HEAP_SIZE_RECLAIMED: usize = const {
|
|
||||||
let range = esp_metadata_generated::memory_range!("DRAM2_UNINIT");
|
|
||||||
range.end - range.start
|
|
||||||
};
|
|
||||||
|
|
||||||
esp_alloc::heap_allocator!(#[ram(reclaimed)] size: HEAP_SIZE_RECLAIMED);
|
|
||||||
esp_alloc::heap_allocator!(size: HEAP_SIZE - HEAP_SIZE_RECLAIMED);
|
|
||||||
info!("Heap initialized! {:#?}", esp_alloc::HEAP.stats());
|
|
||||||
|
|
||||||
// Initialize the PSRAM allocator.
|
|
||||||
{
|
|
||||||
let (psram_offset, psram_size) = esp_hal::psram::psram_raw_parts(&peripherals.PSRAM);
|
|
||||||
unsafe {
|
|
||||||
PSRAM_ALLOCATOR.add_region(HeapRegion::new(
|
|
||||||
psram_offset,
|
|
||||||
psram_size,
|
|
||||||
MemoryCapability::External.into(),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
info!(
|
|
||||||
"PSRAM allocator initialized with capacity of {} MiB!",
|
|
||||||
psram_size / 1024 / 1024
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// let mut io = Io::new(peripherals.IO_MUX);
|
// let mut io = Io::new(peripherals.IO_MUX);
|
||||||
// io.set_interrupt_handler(interrupt_handler);
|
// io.set_interrupt_handler(interrupt_handler);
|
||||||
|
|
@ -657,7 +513,7 @@ async fn main_task(peripherals: MainPeripherals) {
|
||||||
let window_size = [framebuffer.height, framebuffer.width];
|
let window_size = [framebuffer.height, framebuffer.width];
|
||||||
let swapchain_writer = framebuffer.swapchain.take().unwrap();
|
let swapchain_writer = framebuffer.swapchain.take().unwrap();
|
||||||
|
|
||||||
static SECOND_CORE_STACK: StaticCell<Stack<STACK_SIZE_CORE_APP>> = StaticCell::new();
|
static SECOND_CORE_STACK: StaticCell<Stack<{ STACK_SIZE_CORE_APP }>> = StaticCell::new();
|
||||||
let second_core_stack = SECOND_CORE_STACK.init(Stack::new());
|
let second_core_stack = SECOND_CORE_STACK.init(Stack::new());
|
||||||
esp_rtos::start_second_core(
|
esp_rtos::start_second_core(
|
||||||
peripherals.CPU_CTRL,
|
peripherals.CPU_CTRL,
|
||||||
|
|
|
||||||
44
firmware/acid-firmware/src/ram.rs
Normal file
44
firmware/acid-firmware/src/ram.rs
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
use esp_alloc::{HeapRegion, MemoryCapability};
|
||||||
|
use esp_hal::ram;
|
||||||
|
use log::info;
|
||||||
|
|
||||||
|
// Memory allocation regions.
|
||||||
|
// These can be debugged using `xtensa-esp32s3-elf-size -A <path-to-binary>`.
|
||||||
|
// A panic such as `memory allocation of 3740121773 bytes failed` is caused by a heap overflow. The size is `DEEDBAAD` in hex.
|
||||||
|
|
||||||
|
/// Total heap size
|
||||||
|
pub const HEAP_SIZE: usize = 112 * 1024;
|
||||||
|
/// Size of the app core's stack
|
||||||
|
pub const STACK_SIZE_CORE_APP: usize = 80 * 1024;
|
||||||
|
|
||||||
|
pub static PSRAM_ALLOCATOR: esp_alloc::EspHeap = esp_alloc::EspHeap::empty();
|
||||||
|
|
||||||
|
pub fn initialize(psram_peripheral: esp_hal::peripherals::PSRAM) {
|
||||||
|
// Use the internal DRAM as the heap.
|
||||||
|
// Memory reclaimed from the esp-idf bootloader.
|
||||||
|
const HEAP_SIZE_RECLAIMED: usize = const {
|
||||||
|
let range = esp_metadata_generated::memory_range!("DRAM2_UNINIT");
|
||||||
|
range.end - range.start
|
||||||
|
};
|
||||||
|
|
||||||
|
esp_alloc::heap_allocator!(#[ram(reclaimed)] size: HEAP_SIZE_RECLAIMED);
|
||||||
|
esp_alloc::heap_allocator!(size: HEAP_SIZE - HEAP_SIZE_RECLAIMED);
|
||||||
|
info!("IRAM heap initialized!\n{}", esp_alloc::HEAP.stats());
|
||||||
|
|
||||||
|
// Initialize the PSRAM allocator.
|
||||||
|
{
|
||||||
|
let (psram_offset, psram_size) = esp_hal::psram::psram_raw_parts(&psram_peripheral);
|
||||||
|
unsafe {
|
||||||
|
PSRAM_ALLOCATOR.add_region(HeapRegion::new(
|
||||||
|
psram_offset,
|
||||||
|
psram_size,
|
||||||
|
MemoryCapability::External.into(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
info!(
|
||||||
|
"PSRAM heap initialized with capacity of {} MiB!\n{}",
|
||||||
|
psram_size / 1024 / 1024,
|
||||||
|
PSRAM_ALLOCATOR.stats(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,10 +1,16 @@
|
||||||
use alloc::{alloc::Global, boxed::Box};
|
use alloc::{alloc::Global, boxed::Box, vec::Vec};
|
||||||
|
use embassy_time::Timer;
|
||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
Blocking, dma::BurstConfig, lcd_cam::lcd::dpi::Dpi, peripherals::DMA_CH0, spi::master::AnySpi,
|
Blocking,
|
||||||
|
dma::{BurstConfig, ExternalBurstConfig, InternalBurstConfig},
|
||||||
|
lcd_cam::lcd::dpi::Dpi,
|
||||||
|
spi::master::AnySpi,
|
||||||
};
|
};
|
||||||
use esp_hal_bounce_buffers::{DmaBounce, Swapchain, SwapchainWriter, allocate_dma_buffer_in};
|
use esp_hal_bounce_buffers::{DmaBounce, Swapchain, SwapchainWriter, allocate_dma_buffer_in};
|
||||||
|
use i_slint_core::software_renderer::{Rgb565Pixel, TargetPixel};
|
||||||
|
use log::error;
|
||||||
|
|
||||||
use crate::PSRAM_ALLOCATOR;
|
use crate::{DmaBounceController, PSRAM_ALLOCATOR, peripherals::st7701s::St7701s};
|
||||||
|
|
||||||
// TODO: Rename or get rid of.
|
// TODO: Rename or get rid of.
|
||||||
pub struct Framebuffer {
|
pub struct Framebuffer {
|
||||||
|
|
@ -16,7 +22,7 @@ pub struct Framebuffer {
|
||||||
|
|
||||||
impl Framebuffer {
|
impl Framebuffer {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
channel: DMA_CH0<'static>,
|
channel: esp_hal::peripherals::DMA_CH0<'static>,
|
||||||
peripheral_src: AnySpi<'static>,
|
peripheral_src: AnySpi<'static>,
|
||||||
peripheral_dst: Dpi<'static, Blocking>,
|
peripheral_dst: Dpi<'static, Blocking>,
|
||||||
burst_config: BurstConfig,
|
burst_config: BurstConfig,
|
||||||
|
|
@ -62,3 +68,102 @@ impl Framebuffer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(unused)]
|
||||||
|
async fn test_bounce_buffers(
|
||||||
|
channel: esp_hal::peripherals::DMA_CH0<'static>,
|
||||||
|
peripheral: esp_hal::peripherals::SPI2<'static>,
|
||||||
|
mut st7701s: St7701s<'static, Blocking>,
|
||||||
|
) {
|
||||||
|
error!("TEST BOUNCE BUFFERS SECTION ENTERED");
|
||||||
|
|
||||||
|
const BYTES_PER_PIXEL: usize = core::mem::size_of::<u16>();
|
||||||
|
// Assume highest burst config setting.
|
||||||
|
const EXTERNAL_BURST_CONFIG: ExternalBurstConfig = ExternalBurstConfig::Size32;
|
||||||
|
const ALIGNMENT_PIXELS: usize = EXTERNAL_BURST_CONFIG as usize / BYTES_PER_PIXEL;
|
||||||
|
// The total number of pixels demanded by the DPI, per row.
|
||||||
|
const WIDTH_TOTAL_PIXELS: usize = 368;
|
||||||
|
// The total number of rows demanded by the DPI, per frame.
|
||||||
|
const HEIGHT_PIXELS: usize = 960;
|
||||||
|
// The number of unused pixels at the start of the row.
|
||||||
|
const FRONT_PORCH_ACTUAL_PIXELS: usize = 120;
|
||||||
|
// The number of actually visible pixels, per row.
|
||||||
|
const WIDTH_VISIBLE_PIXELS: usize = 240;
|
||||||
|
// The number of pixels not stored in a bounce buffer, per row.
|
||||||
|
// This many arbitrary pixels are sent to the DPI.
|
||||||
|
const FRONT_PORCH_SKIPPED_PIXELS: usize =
|
||||||
|
(FRONT_PORCH_ACTUAL_PIXELS / ALIGNMENT_PIXELS) * ALIGNMENT_PIXELS;
|
||||||
|
const WIDTH_STORED_PIXELS: usize = WIDTH_TOTAL_PIXELS - FRONT_PORCH_SKIPPED_PIXELS;
|
||||||
|
const VISIBLE_OFFSET_IN_BUFFER_PIXELS: usize =
|
||||||
|
FRONT_PORCH_ACTUAL_PIXELS - FRONT_PORCH_SKIPPED_PIXELS;
|
||||||
|
const ROWS_PER_WINDOW: usize = 16;
|
||||||
|
let burst_config = BurstConfig {
|
||||||
|
internal_memory: InternalBurstConfig::Enabled,
|
||||||
|
external_memory: EXTERNAL_BURST_CONFIG,
|
||||||
|
};
|
||||||
|
let (swapchain_reader, mut swapchain_writer) = Swapchain {
|
||||||
|
framebuffers: [
|
||||||
|
Box::leak(allocate_dma_buffer_in(
|
||||||
|
HEIGHT_PIXELS * WIDTH_STORED_PIXELS * BYTES_PER_PIXEL,
|
||||||
|
burst_config,
|
||||||
|
&PSRAM_ALLOCATOR,
|
||||||
|
)),
|
||||||
|
Box::leak(allocate_dma_buffer_in(
|
||||||
|
HEIGHT_PIXELS * WIDTH_STORED_PIXELS * BYTES_PER_PIXEL,
|
||||||
|
burst_config,
|
||||||
|
&PSRAM_ALLOCATOR,
|
||||||
|
)),
|
||||||
|
],
|
||||||
|
}
|
||||||
|
.into_reader_writer();
|
||||||
|
|
||||||
|
{
|
||||||
|
let write_guard = &mut swapchain_writer.write();
|
||||||
|
let buffer_src = bytemuck::cast_slice_mut::<u8, Rgb565Pixel>(write_guard);
|
||||||
|
let colors = (0..WIDTH_VISIBLE_PIXELS as u8 / 2)
|
||||||
|
.rev()
|
||||||
|
.map(|val| Rgb565Pixel::from_rgb(0xFF, val * 2, 0))
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
for (index, pixel) in buffer_src.iter_mut().enumerate() {
|
||||||
|
let mut x =
|
||||||
|
(index % WIDTH_STORED_PIXELS) as i16 - VISIBLE_OFFSET_IN_BUFFER_PIXELS as i16;
|
||||||
|
let mut y = (index / WIDTH_STORED_PIXELS) as i16;
|
||||||
|
|
||||||
|
if x < WIDTH_VISIBLE_PIXELS as i16 {
|
||||||
|
x = core::cmp::min(x, WIDTH_VISIBLE_PIXELS as i16 - 1 - x);
|
||||||
|
y = core::cmp::min(y, HEIGHT_PIXELS as i16 - 1 - y);
|
||||||
|
let min = core::cmp::min(x, y);
|
||||||
|
|
||||||
|
*pixel = colors[min as usize % colors.len()];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
*pixel = Rgb565Pixel::default();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut dma_bounce = DmaBounce::new(
|
||||||
|
Global,
|
||||||
|
channel,
|
||||||
|
AnySpi::from(peripheral),
|
||||||
|
st7701s.dpi,
|
||||||
|
swapchain_reader,
|
||||||
|
FRONT_PORCH_SKIPPED_PIXELS * BYTES_PER_PIXEL,
|
||||||
|
WIDTH_STORED_PIXELS * BYTES_PER_PIXEL,
|
||||||
|
ROWS_PER_WINDOW,
|
||||||
|
burst_config,
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
let mut bb_controller = DmaBounceController::new(dma_bounce);
|
||||||
|
|
||||||
|
error!("TEST BOUNCE BUFFERS TASK LAUNCHED");
|
||||||
|
|
||||||
|
loop {
|
||||||
|
bb_controller.start().await.unwrap();
|
||||||
|
st7701s.controller.sleep_off().await;
|
||||||
|
Timer::after_secs(1).await;
|
||||||
|
st7701s.controller.sleep_on().await;
|
||||||
|
bb_controller.stop().await.unwrap();
|
||||||
|
Timer::after_secs(1).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue