More cleanup
This commit is contained in:
parent
bf5957a8bf
commit
3e52243efe
|
|
@ -8,7 +8,7 @@ use enumset::EnumSet;
|
|||
use crate::ffi::string::__xkbc_memcpy;
|
||||
|
||||
// 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.
|
||||
|
||||
|
|
|
|||
|
|
@ -30,12 +30,10 @@ use embassy_sync::blocking_mutex;
|
|||
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
||||
use embassy_sync::channel::Channel;
|
||||
use embassy_time::{Duration, Timer};
|
||||
use esp_alloc::{HeapRegion, MemoryCapability};
|
||||
use esp_alloc::MemoryCapability;
|
||||
use esp_hal::clock::CpuClock;
|
||||
use esp_hal::dma::{BurstConfig, ExternalBurstConfig, InternalBurstConfig};
|
||||
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::i2c::master::{I2c, I2cAddress};
|
||||
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::peripherals::{DMA_CH0, SPI2};
|
||||
use esp_hal::psram::{FlashFreq, PsramConfig, PsramSize, SpiRamFreq, SpiTimingConfigCoreClock};
|
||||
use esp_hal::ram;
|
||||
use esp_hal::rng::TrngSource;
|
||||
use esp_hal::sha::ShaBackend;
|
||||
use esp_hal::spi::master::AnySpi;
|
||||
|
|
@ -78,6 +75,7 @@ use {esp_alloc as _, esp_backtrace as _};
|
|||
use crate::matrix::IoeMatrix;
|
||||
use crate::peripherals::st7701s::{St7701s, St7701sController};
|
||||
use crate::proxy::create_hid_report_interceptor;
|
||||
use crate::ram::{PSRAM_ALLOCATOR, STACK_SIZE_CORE_APP};
|
||||
use crate::ui::backend::SlintBackend;
|
||||
use crate::ui::dpi::Framebuffer;
|
||||
use crate::vial::{
|
||||
|
|
@ -96,6 +94,7 @@ mod logging;
|
|||
mod matrix;
|
||||
mod peripherals;
|
||||
mod proxy;
|
||||
mod ram;
|
||||
mod ui;
|
||||
mod util;
|
||||
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>
|
||||
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(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 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.
|
||||
// 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]
|
||||
async fn main(_spawner: Spawner) {
|
||||
let config = esp_hal::Config::default()
|
||||
|
|
@ -255,7 +135,7 @@ async fn main(_spawner: Spawner) {
|
|||
#[cfg(feature = "alt-log")]
|
||||
let (tx, rx) = (peripherals.GPIO12, peripherals.GPIO5);
|
||||
#[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())
|
||||
.unwrap()
|
||||
|
|
@ -271,32 +151,8 @@ async fn main(_spawner: Spawner) {
|
|||
#[cfg(feature = "rtt-log")]
|
||||
logging::rtt::setup_logging();
|
||||
|
||||
// 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!("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
|
||||
);
|
||||
}
|
||||
// Set up allocators.
|
||||
ram::initialize(peripherals.PSRAM);
|
||||
|
||||
// let mut io = Io::new(peripherals.IO_MUX);
|
||||
// io.set_interrupt_handler(interrupt_handler);
|
||||
|
|
@ -657,7 +513,7 @@ async fn main_task(peripherals: MainPeripherals) {
|
|||
let window_size = [framebuffer.height, framebuffer.width];
|
||||
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());
|
||||
esp_rtos::start_second_core(
|
||||
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::{
|
||||
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 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.
|
||||
pub struct Framebuffer {
|
||||
|
|
@ -16,7 +22,7 @@ pub struct Framebuffer {
|
|||
|
||||
impl Framebuffer {
|
||||
pub fn new(
|
||||
channel: DMA_CH0<'static>,
|
||||
channel: esp_hal::peripherals::DMA_CH0<'static>,
|
||||
peripheral_src: AnySpi<'static>,
|
||||
peripheral_dst: Dpi<'static, Blocking>,
|
||||
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