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.
This commit is contained in:
bunnie 2024-11-08 00:14:21 +08:00
parent f0e573638d
commit dc0fd47ff4
2 changed files with 29 additions and 9 deletions

View file

@ -24,4 +24,5 @@ locales = { path = "../../locales" }
[features]
cramium-soc = ["utralib/cramium-soc"]
default = []
decongest-udma = []
default = ["decongest-udma"]

View file

@ -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::<Point>::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();