From dc0fd47ff42231733f78ca2f7ece98990faeb60c Mon Sep 17 00:00:00 2001 From: bunnie Date: Fri, 8 Nov 2024 00:14:21 +0800 Subject: [PATCH] add an option to decongest udma There is a hardware bug that causes SPIM RX packets to fail when the UDMA bus is busy (like when streaming video). This causes swap memory to fail because it relies on the SPIM bus. This patch causes the video to sample *after* any computation happens, so that any swap memory that might be hit taken care of. This reduces the efficiency of the loop somewhat, because without the decongesting, we could kick off the camera read and do useful computation while the camera streamed data. Now we have to keep them separate to work around this bug. --- services/bao-video/Cargo.toml | 3 ++- services/bao-video/src/main.rs | 35 ++++++++++++++++++++++++++-------- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/services/bao-video/Cargo.toml b/services/bao-video/Cargo.toml index 6add7c00f..bbaf9e8e6 100644 --- a/services/bao-video/Cargo.toml +++ b/services/bao-video/Cargo.toml @@ -24,4 +24,5 @@ locales = { path = "../../locales" } [features] cramium-soc = ["utralib/cramium-soc"] -default = [] +decongest-udma = [] +default = ["decongest-udma"] diff --git a/services/bao-video/src/main.rs b/services/bao-video/src/main.rs index 45bb6a50b..dda5d2d91 100644 --- a/services/bao-video/src/main.rs +++ b/services/bao-video/src/main.rs @@ -94,10 +94,14 @@ fn wrapped_main() -> ! { cam.set_slicing((border, 0), (cols - border, QR_HEIGHT)); log::info!("320x240 resolution setup with 256x240 slicing"); + #[cfg(feature = "decongest-udma")] + log::info!("Decongest udma option enabled."); + let mut frames = 0; let mut frame = [0u8; QR_WIDTH * QR_HEIGHT]; // while iox.get_gpio_pin_value(IoxPort::PB, 9) == IoxValue::High {} loop { + #[cfg(not(feature = "decongest-udma"))] cam.capture_async(); let mut candidates = Vec::::new(); @@ -189,16 +193,23 @@ fn wrapped_main() -> ! { }); let grids = search_img.detect_grids(); log::info!("grids len {}", grids.len()); - let rawdata = grids[0].get_raw_data(); - match rawdata { - Ok((md, rd)) => { - log::info!("{:?}, {}:{:x?}", md, rd.len, &rd.data[..(rd.len / 8) + 1]); - } - Err(e) => { - log::info!("Error: {:?}", e); + if grids.len() > 0 { + let rawdata = grids[0].get_raw_data(); + match rawdata { + Ok((md, rd)) => { + log::info!( + "{:?}, {}:{:x?}", + md, + rd.len, + &rd.data[..(rd.len / 8) + 1] + ); + } + Err(e) => { + log::info!("Error: {:?}", e); + } } + log::info!("{:?}", grids[0].decode()); } - log::info!("{:?}", grids[0].decode()); } } } @@ -216,6 +227,14 @@ fn wrapped_main() -> ! { // clear the front buffer sh1107.clear(); + #[cfg(feature = "decongest-udma")] + { + // don't parallelize the camera capture to avoid triggering a hardware bug + // in the SPIM block. + while iox.get_gpio_pin_value(IoxPort::PB, 9) == IoxValue::High {} + cam.capture_async(); + } + // wait for the transfer to finish cam.capture_await(true); let fb: &[u32] = cam.rx_buf();