faster and smarter DMA
This commit is contained in:
@@ -150,7 +150,7 @@ pub async fn bridge_usart1_rx_to_usart2_tx(
|
|||||||
let n = usart1_rx.read(&mut buf).await;
|
let n = usart1_rx.read(&mut buf).await;
|
||||||
if n > 0 {
|
if n > 0 {
|
||||||
let _ = usart2_tx.write(&buf[..n]).await;
|
let _ = usart2_tx.write(&buf[..n]).await;
|
||||||
info!("bridge USART1 - USART2 sent:{} bytes: {}", n, &buf[..n]);
|
// info!("bridge USART1 - USART2 sent:{} bytes: {}", n, &buf[..n]);
|
||||||
}
|
}
|
||||||
yield_now().await;
|
yield_now().await;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,23 +35,56 @@ pub async fn rx_dma_task(
|
|||||||
let mut rx = unsafe { ReadableRingBuffer::new(ch, TIM7_UP_REQ, register, ring, opts) };
|
let mut rx = unsafe { ReadableRingBuffer::new(ch, TIM7_UP_REQ, register, ring, opts) };
|
||||||
rx.start();
|
rx.start();
|
||||||
|
|
||||||
let mut raw_chunk = [0u8; 256];
|
// We read into the second half of a buffer, keeping "leftovers" in the first half.
|
||||||
let mut levels = [0u8; 256];
|
const CHUNK_SIZE: usize = 256;
|
||||||
let mut last_bytes: [u8; 16] = [0; 16]; // remember previous 16 samples
|
const HISTORY_SIZE: usize = 256; // Enough to hold a potential split frame
|
||||||
let mut last_value: u8 = 0; // remember previous single IDR sample (optional)
|
const TOTAL_BUF_SIZE: usize = HISTORY_SIZE + CHUNK_SIZE;
|
||||||
|
|
||||||
|
// Logic level buffer
|
||||||
|
let mut level_buf = [0u8; TOTAL_BUF_SIZE];
|
||||||
|
let mut valid_len = 0usize;
|
||||||
|
|
||||||
|
let mut raw_chunk = [0u8; CHUNK_SIZE];
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let _ = rx.read_exact(&mut raw_chunk).await;
|
let _ = rx.read_exact(&mut raw_chunk).await;
|
||||||
|
|
||||||
// convert IDR bits to logic levels
|
|
||||||
for (i, b) in raw_chunk.iter().enumerate() {
|
for (i, b) in raw_chunk.iter().enumerate() {
|
||||||
levels[i] = ((*b >> RX_PIN_BIT) & 1) as u8;
|
level_buf[valid_len + i] = ((*b >> RX_PIN_BIT) & 1) as u8;
|
||||||
|
}
|
||||||
|
let current_end = valid_len + CHUNK_SIZE;
|
||||||
|
|
||||||
|
// 3. Decode everything we have
|
||||||
|
let (decoded, consumed) = decode_uart_samples(
|
||||||
|
&level_buf[..current_end],
|
||||||
|
RX_OVERSAMPLE,
|
||||||
|
&UART_CFG
|
||||||
|
);
|
||||||
|
|
||||||
|
if !decoded.is_empty() {
|
||||||
|
pipe_rx.write(decoded.as_slice()).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
let (decoded, _consumed) = decode_uart_samples(&levels, RX_OVERSAMPLE, &UART_CFG);
|
// 4. Shift remaining data to front
|
||||||
if !decoded.is_empty() {
|
// We processed 'consumed' samples.
|
||||||
// info!("SW RX decoded {:a}", decoded.as_slice());
|
// We keep everything from 'consumed' up to 'current_end'.
|
||||||
pipe_rx.write(decoded.as_slice()).await;
|
let remaining = current_end - consumed;
|
||||||
|
|
||||||
|
// Safety check: if remaining > HISTORY_SIZE, we are in trouble (buffer too small / decoder stuck).
|
||||||
|
// But for now, just shift.
|
||||||
|
if remaining > 0 {
|
||||||
|
level_buf.copy_within(consumed..current_end, 0);
|
||||||
|
}
|
||||||
|
valid_len = remaining;
|
||||||
|
|
||||||
|
// If valid_len grows too large (decoder not consuming), we must discard to avoid panic on next write
|
||||||
|
if valid_len >= HISTORY_SIZE {
|
||||||
|
// Discard oldest to make space
|
||||||
|
// logic: we move the last (HISTORY_SIZE/2) to 0.
|
||||||
|
// This effectively "skips" garbage data.
|
||||||
|
let keep = HISTORY_SIZE / 2;
|
||||||
|
level_buf.copy_within(valid_len - keep..valid_len, 0);
|
||||||
|
valid_len = keep;
|
||||||
}
|
}
|
||||||
|
|
||||||
yield_now().await;
|
yield_now().await;
|
||||||
|
|||||||
Reference in New Issue
Block a user