Code cleanup
This commit is contained in:
parent
95464568c7
commit
2ea4e57857
|
|
@ -10,6 +10,7 @@ use ekv::{
|
||||||
};
|
};
|
||||||
use embassy_embedded_hal::{adapter::BlockingAsync, flash::partition::Partition};
|
use embassy_embedded_hal::{adapter::BlockingAsync, flash::partition::Partition};
|
||||||
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
||||||
|
use embassy_sync_old::blocking_mutex::raw::CriticalSectionRawMutex as CriticalSectionRawMutexOld;
|
||||||
use embedded_storage_async::nor_flash::{NorFlash, ReadNorFlash};
|
use embedded_storage_async::nor_flash::{NorFlash, ReadNorFlash};
|
||||||
use esp_hal::rng::Trng;
|
use esp_hal::rng::Trng;
|
||||||
use esp_storage::FlashStorage;
|
use esp_storage::FlashStorage;
|
||||||
|
|
@ -102,11 +103,11 @@ impl<T: NorFlash + ReadNorFlash> ekv::flash::Flash for EkvFlash<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct AcidDatabase {
|
pub struct AcidDatabase {
|
||||||
db: Database<EkvFlash<PartitionAcid>, esp_sync::RawMutex>,
|
db: Database<EkvFlash<PartitionAcid>, CriticalSectionRawMutexOld>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Deref for AcidDatabase {
|
impl Deref for AcidDatabase {
|
||||||
type Target = Database<EkvFlash<PartitionAcid>, esp_sync::RawMutex>;
|
type Target = Database<EkvFlash<PartitionAcid>, CriticalSectionRawMutexOld>;
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
&self.db
|
&self.db
|
||||||
|
|
@ -125,7 +126,7 @@ impl AcidDatabase {
|
||||||
db_config.random_seed = Trng::try_new()
|
db_config.random_seed = Trng::try_new()
|
||||||
.expect("A `TrngSource` was not initialized before constructing this `Trng`.")
|
.expect("A `TrngSource` was not initialized before constructing this `Trng`.")
|
||||||
.random();
|
.random();
|
||||||
let db = Database::<_, esp_sync::RawMutex>::new(EkvFlash::new(flash), db_config);
|
let db = Database::<_, CriticalSectionRawMutexOld>::new(EkvFlash::new(flash), db_config);
|
||||||
|
|
||||||
#[cfg(feature = "format-db")]
|
#[cfg(feature = "format-db")]
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -447,6 +447,8 @@ struct MainPeripherals {
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
async fn main_task(peripherals: MainPeripherals) {
|
async fn main_task(peripherals: MainPeripherals) {
|
||||||
|
// let _spawner = unsafe { Spawner::for_current_executor() }.await;
|
||||||
|
|
||||||
// Enable the TRNG source, so `Trng` can be constructed.
|
// Enable the TRNG source, so `Trng` can be constructed.
|
||||||
let _trng_source = TrngSource::new(peripherals.RNG, peripherals.ADC1);
|
let _trng_source = TrngSource::new(peripherals.RNG, peripherals.ADC1);
|
||||||
|
|
||||||
|
|
@ -769,12 +771,6 @@ async fn main_task(peripherals: MainPeripherals) {
|
||||||
|
|
||||||
info!("Awaiting on all tasks...");
|
info!("Awaiting on all tasks...");
|
||||||
|
|
||||||
// let spawner = unsafe { Spawner::for_current_executor() }.await;
|
|
||||||
|
|
||||||
// peripherals
|
|
||||||
// .high_priority_task_spawner
|
|
||||||
// .must_spawn(run_bounce_buffers(framebuffer));
|
|
||||||
|
|
||||||
framebuffer
|
framebuffer
|
||||||
.bounce_buffers
|
.bounce_buffers
|
||||||
.take()
|
.take()
|
||||||
|
|
@ -816,11 +812,6 @@ async fn main_task(peripherals: MainPeripherals) {
|
||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::task]
|
|
||||||
async fn run_bounce_buffers(framebuffer: &'static mut Framebuffer) {
|
|
||||||
framebuffer.bounce_buffers.as_mut().unwrap().send().await;
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn run_alloc_stats_reporter() {
|
async fn run_alloc_stats_reporter() {
|
||||||
let mut psram_used_prev = 0;
|
let mut psram_used_prev = 0;
|
||||||
let mut heap_used_prev = 0;
|
let mut heap_used_prev = 0;
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,8 @@
|
||||||
use core::{
|
use core::{
|
||||||
alloc::Layout,
|
alloc::Layout,
|
||||||
cell::UnsafeCell,
|
cell::UnsafeCell,
|
||||||
marker::PhantomData,
|
|
||||||
ops::{Deref, DerefMut},
|
ops::{Deref, DerefMut},
|
||||||
pin::Pin,
|
sync::atomic::{self, AtomicBool},
|
||||||
sync::atomic::{self, AtomicBool, AtomicU32, AtomicUsize},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use alloc::{
|
use alloc::{
|
||||||
|
|
@ -14,37 +12,23 @@ use alloc::{
|
||||||
vec,
|
vec,
|
||||||
};
|
};
|
||||||
use bytemuck::{AnyBitPattern, NoUninit};
|
use bytemuck::{AnyBitPattern, NoUninit};
|
||||||
use embassy_sync::{
|
|
||||||
channel::{Channel, TrySendError},
|
|
||||||
signal::Signal,
|
|
||||||
};
|
|
||||||
use embassy_time::{Duration, Instant, Timer, WithTimeout};
|
|
||||||
use esp_alloc::MemoryCapability;
|
|
||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
Blocking,
|
Blocking,
|
||||||
dma::{
|
dma::{
|
||||||
self, AnyGdmaChannel, BufView, BurstConfig, DmaChannel, DmaChannelConvert, DmaDescriptor,
|
self, BurstConfig, DmaDescriptor, DmaTxBuffer, Mem2Mem, SimpleMem2Mem,
|
||||||
DmaDescriptorFlags, DmaEligible, DmaRxStreamBuf, DmaTxBuf, DmaTxBuffer, DmaTxInterrupt,
|
SimpleMem2MemTransfer,
|
||||||
ExternalBurstConfig, InternalBurstConfig, Mem2Mem, SimpleMem2Mem, SimpleMem2MemTransfer,
|
|
||||||
},
|
},
|
||||||
dma_descriptors, handler,
|
handler,
|
||||||
interrupt::{self, Priority},
|
interrupt::{self, Priority},
|
||||||
lcd_cam::lcd::dpi::{Dpi, DpiTransfer},
|
lcd_cam::lcd::dpi::{Dpi, DpiTransfer},
|
||||||
peripherals::{DMA, DMA_CH0, Interrupt, Peripherals, SPI2},
|
peripherals::{DMA, DMA_CH0, Interrupt},
|
||||||
ram,
|
ram,
|
||||||
spi::master::AnySpi,
|
spi::master::AnySpi,
|
||||||
};
|
};
|
||||||
use esp_sync::RawMutex;
|
use log::error;
|
||||||
use i_slint_core::software_renderer::{Rgb565Pixel, TargetPixel};
|
|
||||||
use indoc::{formatdoc, indoc};
|
|
||||||
use log::{error, info, warn};
|
|
||||||
use ouroboros::self_referencing;
|
use ouroboros::self_referencing;
|
||||||
use rmk::{
|
|
||||||
futures::{self, FutureExt, pin_mut},
|
|
||||||
join_all,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::{PSRAM_ALLOCATOR, peripherals::st7701s::St7701s, util::DurationExt};
|
use crate::PSRAM_ALLOCATOR;
|
||||||
|
|
||||||
/// THIS IS TAKEN FROM https://github.com/esp-rs/esp-hal/blob/main/esp-hal/src/soc/esp32s3/mod.rs
|
/// THIS IS TAKEN FROM https://github.com/esp-rs/esp-hal/blob/main/esp-hal/src/soc/esp32s3/mod.rs
|
||||||
/// Write back a specific range of data in the cache.
|
/// Write back a specific range of data in the cache.
|
||||||
|
|
@ -523,7 +507,6 @@ impl DmaBounce {
|
||||||
let descriptors_per_frame = descriptors_per_window * windows_len;
|
let descriptors_per_frame = descriptors_per_window * windows_len;
|
||||||
let descriptors_frame =
|
let descriptors_frame =
|
||||||
Box::leak(vec![DmaDescriptor::EMPTY; descriptors_per_frame].into_boxed_slice());
|
Box::leak(vec![DmaDescriptor::EMPTY; descriptors_per_frame].into_boxed_slice());
|
||||||
let descriptors_frame_ptr = descriptors_frame.as_ptr();
|
|
||||||
|
|
||||||
// Link up the descriptors.
|
// Link up the descriptors.
|
||||||
let mut next = if cyclic {
|
let mut next = if cyclic {
|
||||||
|
|
@ -570,7 +553,10 @@ impl DmaBounce {
|
||||||
(descriptors_frame, descriptors_per_window)
|
(descriptors_frame, descriptors_per_window)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn linear_descriptors_prepare(
|
/// Safety:
|
||||||
|
/// TX descriptors require read access to the buffer.
|
||||||
|
/// RX descriptors require write access to the buffer.
|
||||||
|
unsafe fn linear_descriptors_prepare(
|
||||||
descriptors: &mut [DmaDescriptor],
|
descriptors: &mut [DmaDescriptor],
|
||||||
mut buffer: Option<&[u8]>,
|
mut buffer: Option<&[u8]>,
|
||||||
mut setup_desc: impl FnMut(&mut DmaDescriptor),
|
mut setup_desc: impl FnMut(&mut DmaDescriptor),
|
||||||
|
|
@ -591,48 +577,20 @@ impl DmaBounce {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn linear_descriptors_prepare_mut(
|
|
||||||
descriptors: &mut [DmaDescriptor],
|
|
||||||
mut buffer: Option<&mut [u8]>,
|
|
||||||
mut setup_desc: impl FnMut(&mut DmaDescriptor),
|
|
||||||
) {
|
|
||||||
for descriptor in descriptors.iter_mut() {
|
|
||||||
if let Some(inner_buffer) = buffer {
|
|
||||||
descriptor.buffer = inner_buffer.as_mut_ptr();
|
|
||||||
buffer = Some(&mut inner_buffer[descriptor.size()..]);
|
|
||||||
}
|
|
||||||
(setup_desc)(descriptor);
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(buffer) = buffer {
|
|
||||||
assert!(
|
|
||||||
buffer.is_empty(),
|
|
||||||
"a buffer of an incompatible length was assigned to a descriptor set"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn enable_interrupts() {
|
fn enable_interrupts() {
|
||||||
// Enable interrupts for the peripheral
|
// Enable interrupts for the peripheral, pt. 1.
|
||||||
// interrupt::enable(INTERRUPT_INBOUND, dma_inbound_interrupt_handler.priority()).unwrap();
|
|
||||||
interrupt::enable(
|
interrupt::enable(
|
||||||
INTERRUPT_OUTBOUND,
|
INTERRUPT_OUTBOUND,
|
||||||
dma_outbound_interrupt_handler.priority(),
|
dma_outbound_interrupt_handler.priority(),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// Bind the handler
|
// Bind the interrupt handler.
|
||||||
unsafe {
|
unsafe {
|
||||||
// interrupt::bind_interrupt(INTERRUPT_INBOUND, dma_inbound_interrupt_handler.handler());
|
|
||||||
interrupt::bind_interrupt(INTERRUPT_OUTBOUND, dma_outbound_interrupt_handler.handler());
|
interrupt::bind_interrupt(INTERRUPT_OUTBOUND, dma_outbound_interrupt_handler.handler());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable interrupts in the peripheral.
|
// Enable interrupts for the peripheral, pt. 2.
|
||||||
// DMA::regs()
|
|
||||||
// .ch(DMA_CHANNEL_INBOUND)
|
|
||||||
// .in_int()
|
|
||||||
// .ena()
|
|
||||||
// .modify(|_, w| w.in_done().bit(true));
|
|
||||||
DMA::regs()
|
DMA::regs()
|
||||||
.ch(DMA_CHANNEL_OUTBOUND)
|
.ch(DMA_CHANNEL_OUTBOUND)
|
||||||
.out_int()
|
.out_int()
|
||||||
|
|
@ -650,19 +608,21 @@ impl DmaBounce {
|
||||||
let buffer_src_window = &self.swapchain_src.get_latest_framebuffer()
|
let buffer_src_window = &self.swapchain_src.get_latest_framebuffer()
|
||||||
[self.window_index_next * self.window_size..][..self.window_size];
|
[self.window_index_next * self.window_size..][..self.window_size];
|
||||||
|
|
||||||
|
unsafe {
|
||||||
Self::linear_descriptors_prepare(self.src_descs, Some(buffer_src_window), |_desc| {
|
Self::linear_descriptors_prepare(self.src_descs, Some(buffer_src_window), |_desc| {
|
||||||
// No need to call `DmaDescriptor::reset_for_tx`, because
|
// No need to call `DmaDescriptor::reset_for_tx`, because
|
||||||
// 1. we don't rely on the ownership flag;
|
// 1. we don't rely on the ownership flag;
|
||||||
// 2. the EOF flag is already set during the construction of this buffer.
|
// 2. the EOF flag is already set during the construction of this buffer.
|
||||||
});
|
});
|
||||||
// TODO: Precompute a descriptor list for each buffer, then use `None` instead of `Some(&mut *self.bounce_buffer_dst)`.
|
// TODO: Precompute a descriptor list for each buffer, then use `None` instead of `Some(&mut *self.bounce_buffer_dst)`.
|
||||||
Self::linear_descriptors_prepare_mut(
|
Self::linear_descriptors_prepare(
|
||||||
self.bounce_dst_descs,
|
self.bounce_dst_descs,
|
||||||
Some(&mut *self.bounce_buffer_dst),
|
Some(self.bounce_buffer_dst),
|
||||||
|desc| {
|
|desc| {
|
||||||
desc.reset_for_rx();
|
desc.reset_for_rx();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// Extend the lifetime to 'static because it is required by Mem2Mem.
|
// Extend the lifetime to 'static because it is required by Mem2Mem.
|
||||||
//
|
//
|
||||||
|
|
@ -702,19 +662,21 @@ impl DmaBounce {
|
||||||
let buffer_src_window = &self.swapchain_src.get_latest_framebuffer()
|
let buffer_src_window = &self.swapchain_src.get_latest_framebuffer()
|
||||||
[self.window_index_next * self.window_size..][..self.window_size];
|
[self.window_index_next * self.window_size..][..self.window_size];
|
||||||
|
|
||||||
|
unsafe {
|
||||||
Self::linear_descriptors_prepare(self.src_descs, Some(buffer_src_window), |_desc| {
|
Self::linear_descriptors_prepare(self.src_descs, Some(buffer_src_window), |_desc| {
|
||||||
// No need to call `DmaDescriptor::reset_for_tx`, because
|
// No need to call `DmaDescriptor::reset_for_tx`, because
|
||||||
// 1. we don't rely on the ownership flag;
|
// 1. we don't rely on the ownership flag;
|
||||||
// 2. the EOF flag is already set during the construction of this buffer.
|
// 2. the EOF flag is already set during the construction of this buffer.
|
||||||
});
|
});
|
||||||
// TODO: Precompute a descriptor list for each buffer, then use `None` instead of `Some(&mut *self.bounce_buffer_dst)`.
|
// TODO: Precompute a descriptor list for each buffer, then use `None` instead of `Some(&mut *self.bounce_buffer_dst)`.
|
||||||
Self::linear_descriptors_prepare_mut(
|
Self::linear_descriptors_prepare(
|
||||||
self.bounce_dst_descs,
|
self.bounce_dst_descs,
|
||||||
Some(&mut *self.bounce_buffer_dst),
|
Some(self.bounce_buffer_dst),
|
||||||
|desc| {
|
|desc| {
|
||||||
desc.reset_for_rx();
|
desc.reset_for_rx();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
// Extend the lifetime to 'static because it is required by Mem2Mem.
|
// Extend the lifetime to 'static because it is required by Mem2Mem.
|
||||||
|
|
@ -776,108 +738,6 @@ impl DmaBounce {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn send(&mut self) {
|
|
||||||
Self::enable_interrupts();
|
|
||||||
|
|
||||||
// Receive the first window, so that the outbound transfer can read valid data.
|
|
||||||
self.receive_window().await;
|
|
||||||
|
|
||||||
let mut dma_tx_buffer = self.get_dma_tx_buffer();
|
|
||||||
let mut transfer = self
|
|
||||||
.peripheral_dst
|
|
||||||
.take()
|
|
||||||
.unwrap()
|
|
||||||
.send(self.cyclic /* Send perpetually */, dma_tx_buffer)
|
|
||||||
.unwrap_or_else(|(error, _, _)| {
|
|
||||||
panic!("failed to begin the transmission of the first frame: {error:?}");
|
|
||||||
});
|
|
||||||
|
|
||||||
let mut windows_skipped_total = 0;
|
|
||||||
|
|
||||||
loop {
|
|
||||||
// warn!(
|
|
||||||
// "Receiving window: {} {}",
|
|
||||||
// self.window_index_next, self.frame_index_next
|
|
||||||
// );
|
|
||||||
self.receive_window().await;
|
|
||||||
// warn!(
|
|
||||||
// "Window received: {} {}",
|
|
||||||
// self.window_index_next, self.frame_index_next
|
|
||||||
// );
|
|
||||||
let windows_sent = WINDOWS_SENT
|
|
||||||
.wait()
|
|
||||||
.with_timeout(Duration::from_millis(100))
|
|
||||||
.await
|
|
||||||
.unwrap_or_else(|_| {
|
|
||||||
error!("Timed out when waiting for skipped windows.");
|
|
||||||
0
|
|
||||||
});
|
|
||||||
let windows_skipped = windows_sent as isize - 1;
|
|
||||||
|
|
||||||
if windows_skipped != 0 {
|
|
||||||
self.increase_window_counter(windows_skipped);
|
|
||||||
windows_skipped_total += windows_skipped;
|
|
||||||
// error!(
|
|
||||||
// "Skipped {windows_skipped} windows. Windows skipped per frame: {:.2}%",
|
|
||||||
// 100.0 * windows_skipped_total as f32
|
|
||||||
// / (self.windows_len * (self.frame_index_next + 1)) as f32
|
|
||||||
// );
|
|
||||||
}
|
|
||||||
|
|
||||||
// warn!(
|
|
||||||
// "X: {} {} {}",
|
|
||||||
// windows_skipped, self.window_index_next, self.frame_index_next
|
|
||||||
// );
|
|
||||||
|
|
||||||
if !self.cyclic && (self.window_index_next == 1 || transfer.is_done()) {
|
|
||||||
if self.window_index_next > 1 {
|
|
||||||
self.increase_window_counter(
|
|
||||||
self.windows_len as isize - self.window_index_next as isize + 1,
|
|
||||||
);
|
|
||||||
} else if self.window_index_next == 0 {
|
|
||||||
self.increase_window_counter(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Investigate why the DPI transfer isn't done at this point.
|
|
||||||
// The `DpiTransfer::wait()` below takes 0.001039 s.
|
|
||||||
// Perhaps it's the minimum screen refresh period?
|
|
||||||
//
|
|
||||||
// assert!(transfer.is_done());
|
|
||||||
// if !transfer.is_done() {
|
|
||||||
// error!(
|
|
||||||
// "transfer is not done yet. {} {}",
|
|
||||||
// self.frame_index_next, self.window_index_next
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
|
|
||||||
let result;
|
|
||||||
let peripheral_dst;
|
|
||||||
// let start = Instant::now();
|
|
||||||
(result, peripheral_dst, dma_tx_buffer) = transfer.wait();
|
|
||||||
// let duration = Instant::now().duration_since(start);
|
|
||||||
// warn!("Waited for {} seconds", duration.display_as_secs());
|
|
||||||
|
|
||||||
if let Err(error) = result {
|
|
||||||
error!("DPI error during sending: {error:?}");
|
|
||||||
}
|
|
||||||
|
|
||||||
transfer =
|
|
||||||
peripheral_dst
|
|
||||||
.send(false, dma_tx_buffer)
|
|
||||||
.unwrap_or_else(|(error, _, _)| {
|
|
||||||
panic!("failed to begin the transmission of a frame: {error:?}");
|
|
||||||
});
|
|
||||||
|
|
||||||
FRAMES_SKIPPED.signal(
|
|
||||||
FRAMES_SKIPPED
|
|
||||||
.try_take()
|
|
||||||
.map(|frames_skipped| frames_skipped + 1)
|
|
||||||
.unwrap_or_default(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_dma_tx_buffer(&mut self) -> DmaTxBounceBuf {
|
fn get_dma_tx_buffer(&mut self) -> DmaTxBounceBuf {
|
||||||
DmaTxBounceBuf {
|
DmaTxBounceBuf {
|
||||||
preparation: dma::Preparation {
|
preparation: dma::Preparation {
|
||||||
|
|
@ -885,8 +745,10 @@ impl DmaBounce {
|
||||||
direction: dma::TransferDirection::Out,
|
direction: dma::TransferDirection::Out,
|
||||||
accesses_psram: false,
|
accesses_psram: false,
|
||||||
burst_transfer: self.burst_config,
|
burst_transfer: self.burst_config,
|
||||||
check_owner: Some(false), // Possibly want to set this to false
|
// We don't care about ownership.
|
||||||
auto_write_back: false, // Possibly true
|
// Just yeet whatever the descriptors point to to the destination peripheral.
|
||||||
|
check_owner: Some(false),
|
||||||
|
auto_write_back: false,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -920,9 +782,6 @@ unsafe impl DmaTxBuffer for DmaTxBounceBuf {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Intended to be listened on by the renderer, to synchronize the refresh frequency with.
|
|
||||||
pub static FRAMES_SKIPPED: Signal<RawMutex, usize> = Signal::new();
|
|
||||||
static WINDOWS_SENT: Signal<RawMutex, usize> = Signal::new();
|
|
||||||
static DMA_STATE: SyncUnsafeCell<Option<DmaBounce>> = SyncUnsafeCell(UnsafeCell::new(None));
|
static DMA_STATE: SyncUnsafeCell<Option<DmaBounce>> = SyncUnsafeCell(UnsafeCell::new(None));
|
||||||
|
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
|
|
@ -930,16 +789,6 @@ pub struct SyncUnsafeCell<T>(UnsafeCell<T>);
|
||||||
|
|
||||||
unsafe impl<T> Sync for SyncUnsafeCell<T> {}
|
unsafe impl<T> Sync for SyncUnsafeCell<T> {}
|
||||||
|
|
||||||
// #[derive(Clone, Copy)]
|
|
||||||
// struct DmaState {
|
|
||||||
// descriptors_ptr: *const DmaDescriptor,
|
|
||||||
// descriptors_per_window: usize,
|
|
||||||
// windows_per_frame: usize,
|
|
||||||
// last_window_index: usize,
|
|
||||||
// }
|
|
||||||
|
|
||||||
// unsafe impl Sync for DmaState {}
|
|
||||||
|
|
||||||
#[handler(priority = Priority::Priority3)]
|
#[handler(priority = Priority::Priority3)]
|
||||||
#[ram] // Improves performance.
|
#[ram] // Improves performance.
|
||||||
fn dma_outbound_interrupt_handler() {
|
fn dma_outbound_interrupt_handler() {
|
||||||
|
|
@ -971,7 +820,6 @@ fn dma_outbound_interrupt_handler() {
|
||||||
let window_sent_index =
|
let window_sent_index =
|
||||||
unsafe { descriptor_ptr.offset_from_unsigned(dma_state.bounce_src_descs.as_ptr()) }
|
unsafe { descriptor_ptr.offset_from_unsigned(dma_state.bounce_src_descs.as_ptr()) }
|
||||||
/ dma_state.descriptors_per_window;
|
/ dma_state.descriptors_per_window;
|
||||||
// warn!("{window_sent_index}");
|
|
||||||
// The next window to be sent is `(window_sent_index + 1) % dma_state.windows_len`.
|
// The next window to be sent is `(window_sent_index + 1) % dma_state.windows_len`.
|
||||||
// That is not the window we want to buffer, because the transmissions would race.
|
// That is not the window we want to buffer, because the transmissions would race.
|
||||||
// We instead want to buffer the next window:
|
// We instead want to buffer the next window:
|
||||||
|
|
@ -987,8 +835,6 @@ fn dma_outbound_interrupt_handler() {
|
||||||
|
|
||||||
dma_state.window_index_next = window_index_next;
|
dma_state.window_index_next = window_index_next;
|
||||||
|
|
||||||
// warn!("{window_sent_index} {window_index_next}");
|
|
||||||
|
|
||||||
let mut receiving_transfer = dma_state
|
let mut receiving_transfer = dma_state
|
||||||
.receiving_transfer
|
.receiving_transfer
|
||||||
.take()
|
.take()
|
||||||
|
|
@ -997,14 +843,10 @@ fn dma_outbound_interrupt_handler() {
|
||||||
.with_mut(|x| x.transfer.take())
|
.with_mut(|x| x.transfer.take())
|
||||||
.expect("no ongoing inner transfer to a bounce buffer present");
|
.expect("no ongoing inner transfer to a bounce buffer present");
|
||||||
|
|
||||||
// if !receiving_transfer.is_done() {
|
|
||||||
// error!("{window_sent_index}");
|
|
||||||
// error!("the transfer to a bounce buffer has not finished yet, aborting");
|
|
||||||
// }
|
|
||||||
|
|
||||||
if receiving_transfer.is_done() {
|
if receiving_transfer.is_done() {
|
||||||
drop(receiving_transfer);
|
drop(receiving_transfer);
|
||||||
} else {
|
} else {
|
||||||
|
// error!("the transfer to a bounce buffer has not finished yet, waiting");
|
||||||
receiving_transfer.wait().unwrap();
|
receiving_transfer.wait().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,6 @@ use crate::{
|
||||||
proxy::OUTPUT_STRING_CHANNEL,
|
proxy::OUTPUT_STRING_CHANNEL,
|
||||||
ui::{
|
ui::{
|
||||||
backend::SlintBackend,
|
backend::SlintBackend,
|
||||||
dpi::FRAMES_SKIPPED,
|
|
||||||
messages::{
|
messages::{
|
||||||
CallbackMessage, CallbackMessageLogin, CallbackMessageUserEdit,
|
CallbackMessage, CallbackMessageLogin, CallbackMessageUserEdit,
|
||||||
CallbackMessageUserSites, CallbackMessageUsers, LoginResult,
|
CallbackMessageUserSites, CallbackMessageUsers, LoginResult,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue