working, but data are in pipe, but we read ringbuffer, critical bug, fix now
This commit is contained in:
@@ -21,32 +21,37 @@ const BAUD: u32 = 115_200;
|
|||||||
const TX_PIN_BIT: u8 = 2; // PA2
|
const TX_PIN_BIT: u8 = 2; // PA2
|
||||||
const TX_OVERSAMPLE: u16 = 1;
|
const TX_OVERSAMPLE: u16 = 1;
|
||||||
const RX_OVERSAMPLE: u16 = 16;
|
const RX_OVERSAMPLE: u16 = 16;
|
||||||
|
const RX_RING_BYTES: usize = 4096;
|
||||||
|
const TX_RING_BYTES: usize = 4096;
|
||||||
|
// Nemoze by generic, v taskoch treba manualne zmenit
|
||||||
|
// Compiler upozorni, takze ostava takto
|
||||||
const PIPE_TX_SIZE: usize = 256;
|
const PIPE_TX_SIZE: usize = 256;
|
||||||
const PIPE_RX_SIZE: usize = 256;
|
const PIPE_RX_SIZE: usize = 256;
|
||||||
const RX_RING_BYTES: usize = 4096;
|
|
||||||
|
|
||||||
static PIPE_TX: Pipe<CriticalSectionRawMutex, PIPE_TX_SIZE> = Pipe::new();
|
static PIPE_TX: Pipe<CriticalSectionRawMutex, PIPE_TX_SIZE> = Pipe::new();
|
||||||
static PIPE_RX: Pipe<CriticalSectionRawMutex, PIPE_RX_SIZE> = Pipe::new();
|
static PIPE_RX: Pipe<CriticalSectionRawMutex, PIPE_RX_SIZE> = Pipe::new();
|
||||||
static RX_RING: StaticCell<[u8; RX_RING_BYTES]> = StaticCell::new();
|
static RX_RING: StaticCell<[u8; RX_RING_BYTES]> = StaticCell::new();
|
||||||
|
static TX_RING: StaticCell<[u32; TX_RING_BYTES]> = StaticCell::new();
|
||||||
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
async fn main(spawner: Spawner) {
|
async fn main(spawner: Spawner) {
|
||||||
let p = embassy_stm32::init(Default::default());
|
let p = embassy_stm32::init(Default::default());
|
||||||
info!("Hehe");
|
info!("Hehe");
|
||||||
|
|
||||||
let _rx = Input::new(p.PA3, Pull::Up);
|
let rx = Input::new(p.PA3, Pull::Up);
|
||||||
let _tx = Output::new(p.PA2, Level::High, Speed::VeryHigh);
|
let tx = Output::new(p.PA2, Level::High, Speed::VeryHigh);
|
||||||
|
|
||||||
init_tim6_for_uart(p.TIM6, BAUD, TX_OVERSAMPLE);
|
init_tim6_for_uart(p.TIM6, BAUD, TX_OVERSAMPLE);
|
||||||
init_tim7_for_uart(p.TIM7, BAUD, RX_OVERSAMPLE);
|
init_tim7_for_uart(p.TIM7, BAUD, RX_OVERSAMPLE);
|
||||||
dump_tim6_regs();
|
dump_tim6_regs();
|
||||||
|
|
||||||
// Safe one-time init from StaticCell
|
// Safe one-time init from StaticCell
|
||||||
let ring: &mut [u8; RX_RING_BYTES] = RX_RING.init([0; RX_RING_BYTES]);
|
let rx_ring: &mut [u8; RX_RING_BYTES] = RX_RING.init([0; RX_RING_BYTES]);
|
||||||
|
let tx_ring: &mut [u32; TX_RING_BYTES] = TX_RING.init([0; TX_RING_BYTES]);
|
||||||
|
|
||||||
// Spawn tasks
|
// Spawn tasks
|
||||||
spawner.spawn(tx_dma_task(p.GPDMA1_CH0, &PIPE_TX).unwrap());
|
spawner.spawn(tx_dma_task(p.GPDMA1_CH0, tx_ring).unwrap());
|
||||||
spawner.spawn(rx_dma_task(p.GPDMA1_CH1, &PIPE_RX, ring).unwrap());
|
spawner.spawn(rx_dma_task(p.GPDMA1_CH1, &PIPE_RX, rx_ring).unwrap());
|
||||||
|
|
||||||
let uart_cfg = UartConfig {
|
let uart_cfg = UartConfig {
|
||||||
data_bits: 8,
|
data_bits: 8,
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
// src/software_uart/runtime.rs
|
// src/software_uart/runtime.rs
|
||||||
use defmt::{info, warn};
|
|
||||||
use embassy_executor::task;
|
use embassy_executor::task;
|
||||||
|
use embassy_stm32::pac::GPIOA;
|
||||||
use embassy_stm32::{
|
use embassy_stm32::{
|
||||||
dma::{ReadableRingBuffer as DmaRingRx, TransferOptions},
|
|
||||||
peripherals::{GPDMA1_CH0, GPDMA1_CH1},
|
peripherals::{GPDMA1_CH0, GPDMA1_CH1},
|
||||||
Peri,
|
Peri,
|
||||||
};
|
};
|
||||||
use embassy_sync::{blocking_mutex::raw::CriticalSectionRawMutex, pipe::Pipe};
|
use embassy_stm32::dma::{
|
||||||
use embassy_time::Duration;
|
ReadableRingBuffer as DmaRingRx,
|
||||||
use crate::software_uart::{
|
WritableRingBuffer as DmaRingTx,
|
||||||
gpio_dma_uart_rx::TIM7_UP_REQ,
|
TransferOptions,
|
||||||
gpio_dma_uart_tx::GpioDmaBsrrTx,
|
|
||||||
debug::{dump_dma_ch0_regs, dump_tim6_regs},
|
|
||||||
};
|
};
|
||||||
|
use crate::software_uart::gpio_dma_uart_tx::TIM6_UP_REQ;
|
||||||
|
use embassy_sync::{blocking_mutex::raw::CriticalSectionRawMutex, pipe::Pipe};
|
||||||
|
use crate::software_uart::gpio_dma_uart_rx::TIM7_UP_REQ;
|
||||||
|
|
||||||
/// RX DMA task: reads GPIO samples paced by TIM7 and fills PIPE_RX
|
/// RX DMA task: reads GPIO samples paced by TIM7 and fills PIPE_RX
|
||||||
#[task]
|
#[task]
|
||||||
@@ -38,32 +38,28 @@ pub async fn rx_dma_task(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// TX DMA task: dequeues prebuilt frames from PIPE_TX and writes to GPIOA.BSRR
|
/// TX DMA ring task: streams u32 BSRR words paced by TIM6.
|
||||||
#[task]
|
#[task]
|
||||||
pub async fn tx_dma_task(
|
pub async fn tx_dma_task(
|
||||||
ch: Peri<'static, GPDMA1_CH0>,
|
ch: Peri<'static, GPDMA1_CH0>,
|
||||||
pipe_tx: &'static Pipe<CriticalSectionRawMutex, 256>,
|
ring_mem: &'static mut [u32],
|
||||||
) {
|
) {
|
||||||
let mut tx = GpioDmaBsrrTx::new(ch);
|
let bsrr_ptr = GPIOA.bsrr().as_ptr() as *mut u32;
|
||||||
info!("DMA TX task started");
|
|
||||||
|
|
||||||
|
let mut opts = TransferOptions::default();
|
||||||
|
opts.half_transfer_ir = true;
|
||||||
|
opts.complete_transfer_ir = true;
|
||||||
|
|
||||||
|
// SAFETY: ring_mem is exclusive here, bsrr_ptr valid, paced by TIM6
|
||||||
|
let mut tx = unsafe {
|
||||||
|
DmaRingTx::<u32>::new(ch, TIM6_UP_REQ, bsrr_ptr, ring_mem, opts)
|
||||||
|
};
|
||||||
|
|
||||||
|
tx.start();
|
||||||
|
defmt::info!("TX DMA ring started");
|
||||||
|
|
||||||
|
// The DMA now streams ring_mem.
|
||||||
loop {
|
loop {
|
||||||
let mut b = [0u8; 4];
|
// embassy_futures::yield_now().await;
|
||||||
let n = pipe_tx.read(&mut b).await;
|
|
||||||
if n != 4 {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let w = u32::from_le_bytes(b);
|
|
||||||
info!("DMA write 0x{:08X} -> GPIOA.BSRR", w);
|
|
||||||
|
|
||||||
match embassy_time::with_timeout(Duration::from_millis(20), tx.write_word(w)).await {
|
|
||||||
Ok(()) => {}
|
|
||||||
Err(_) => {
|
|
||||||
warn!("DMA timeout: no TIM6 request");
|
|
||||||
dump_tim6_regs();
|
|
||||||
dump_dma_ch0_regs();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user