From 685067a75f1756a2b24333fe5378576405dc4317 Mon Sep 17 00:00:00 2001 From: Priec Date: Thu, 20 Nov 2025 13:28:09 +0100 Subject: [PATCH] jsut minor changes, UNTESTED DMA TIMER CHANGE --- semestralka_1_connected/src/bin/main.rs | 11 ++++------- .../src/software_uart/dma_timer.rs | 3 ++- .../src/software_uart/gpio_dma_uart_rx.rs | 8 +++----- .../src/software_uart/gpio_dma_uart_tx.rs | 7 +++---- .../src/software_uart/uart_emulation.rs | 18 +++++++++--------- 5 files changed, 21 insertions(+), 26 deletions(-) diff --git a/semestralka_1_connected/src/bin/main.rs b/semestralka_1_connected/src/bin/main.rs index c520cb8..948cb78 100644 --- a/semestralka_1_connected/src/bin/main.rs +++ b/semestralka_1_connected/src/bin/main.rs @@ -68,11 +68,11 @@ async fn main(spawner: Spawner) { config.rcc.pll1 = Some(Pll { source: PllSource::HSI, // 16 MHz / 1 × 20 / 2 = 160 MHz - prediv: PllPreDiv::DIV1, // or 1.into() - mul: PllMul::MUL20, // or 20.into() + prediv: PllPreDiv::DIV1, + mul: PllMul::MUL20, divp: None, divq: None, - divr: Some(PllDiv::DIV2), // or Some(2.into()) + divr: Some(PllDiv::DIV2), }); config.enable_independent_io_supply = true; config.enable_independent_analog_supply = true; @@ -131,14 +131,12 @@ async fn main(spawner: Spawner) { let rx_pin = Input::new(p.PD6, Pull::Up); unsafe { RX_PIN = Some(rx_pin) }; - // Configure TX as output (PB0) let mut tx_pin = Output::new(p.PB0, Level::High, Speed::VeryHigh); init_tim6_for_uart(p.TIM6, BAUD, TX_OVERSAMPLE); init_tim7_for_uart(p.TIM7, BAUD, RX_OVERSAMPLE); - dump_tim6_regs(); - let bsrr_ptr = embassy_stm32::pac::GPIOB.bsrr().as_ptr() as *mut u32; // POZOR B REGISTER + let bsrr_ptr = embassy_stm32::pac::GPIOB.bsrr().as_ptr() as *mut u32; // POZOR B REGISTER spawner.spawn(tx_dma_task(p.GPDMA1_CH0, bsrr_ptr, SW_TX_RING.init([0; TX_RING_BYTES]), &PIPE_SW_TX).unwrap()); // EDN OF SOFTWARE UART @@ -148,7 +146,6 @@ async fn main(spawner: Spawner) { spawner.spawn(rx_dma_task(p.GPDMA1_CH1, gpio_idr, rx_ring, &PIPE_SW_RX).unwrap()); info!("SW UART RX DMA started"); - // Process decoded bytes coming from PIPE_SW_RX let mut buf = [0u8; 64]; loop { let n = PIPE_SW_RX.read(&mut buf).await; diff --git a/semestralka_1_connected/src/software_uart/dma_timer.rs b/semestralka_1_connected/src/software_uart/dma_timer.rs index cb4c7b9..e38be3f 100644 --- a/semestralka_1_connected/src/software_uart/dma_timer.rs +++ b/semestralka_1_connected/src/software_uart/dma_timer.rs @@ -39,7 +39,8 @@ fn configure_basic_timer(ll: &Timer<'_, T>, baud: u32, oversam let target = baud.saturating_mul(oversample.max(1) as u32).max(1); // Compute ARR (prescaler = 0) - let mut arr = (f_timer / target).saturating_sub(1) as u16; + // let mut arr = (f_timer / target).saturating_sub(1) as u16; + let mut arr = ((f_timer + target / 2) / target).saturating_sub(1) as u16; if arr == 0 { arr = 1; } ll.regs_basic().cr1().write(|w| { diff --git a/semestralka_1_connected/src/software_uart/gpio_dma_uart_rx.rs b/semestralka_1_connected/src/software_uart/gpio_dma_uart_rx.rs index ec7fec5..581eaa0 100644 --- a/semestralka_1_connected/src/software_uart/gpio_dma_uart_rx.rs +++ b/semestralka_1_connected/src/software_uart/gpio_dma_uart_rx.rs @@ -37,7 +37,7 @@ pub async fn rx_dma_task( // We read into the second half of a buffer, keeping "leftovers" in the first half. const CHUNK_SIZE: usize = 4096; - const HISTORY_SIZE: usize = 512; // Enough to hold a potential split frame + const HISTORY_SIZE: usize = 512; const TOTAL_BUF_SIZE: usize = HISTORY_SIZE + CHUNK_SIZE; // Logic level buffer @@ -54,7 +54,6 @@ pub async fn rx_dma_task( } let current_end = valid_len + CHUNK_SIZE; - // 3. Decode everything we have let (decoded, consumed) = decode_uart_samples( &level_buf[..current_end], RX_OVERSAMPLE, @@ -69,13 +68,12 @@ pub async fn rx_dma_task( } } - // 4. Shift remaining data to front + // Shift remaining data to front // We processed 'consumed' samples. // We keep everything from 'consumed' up to 'current_end'. 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. + // SAFETY if remaining > HISTORY_SIZE, we are in trouble (buffer too small / decoder stuck). if remaining > 0 { level_buf.copy_within(consumed..current_end, 0); } diff --git a/semestralka_1_connected/src/software_uart/gpio_dma_uart_tx.rs b/semestralka_1_connected/src/software_uart/gpio_dma_uart_tx.rs index c98dbbe..8afaec6 100644 --- a/semestralka_1_connected/src/software_uart/gpio_dma_uart_tx.rs +++ b/semestralka_1_connected/src/software_uart/gpio_dma_uart_tx.rs @@ -59,14 +59,13 @@ pub async fn tx_dma_task( let used = encode_uart_frames(TX_PIN_BIT, &rx_buf[..n], &mut frame_buf).await; if used > 0 { - // Align arming to a clean TIM6 update boundary: - // 1) clear any pending UIF + // Clear pending UIF tim6.sr().write(|w| w.set_uif(false)); - // 2) wait for the next UIF (next bit tick) + // Wait for the next UIF (next bit tick) while !tim6.sr().read().uif() { yield_now().await; } - // 3) clear UIF so first DMA beat happens on the FOLLOWING tick + // Clear UIF so first DMA beat happens on the FOLLOWING tick tim6.sr().write(|w| w.set_uif(false)); let mut tx_opts = TransferOptions::default(); diff --git a/semestralka_1_connected/src/software_uart/uart_emulation.rs b/semestralka_1_connected/src/software_uart/uart_emulation.rs index 51ca7d9..45e6d35 100644 --- a/semestralka_1_connected/src/software_uart/uart_emulation.rs +++ b/semestralka_1_connected/src/software_uart/uart_emulation.rs @@ -115,7 +115,7 @@ pub fn decode_uart_samples( let frame_bits = 1 + nbits + parity_bits + stop_bits_count; let frame_len = frame_bits * ovs; - // Helper: Majority vote over 3 samples centered at `i` + // Majority vote over 3 samples centered at `i` let get_bit = |i: usize| -> u8 { let mut votes = 0; // Check i-1, i, i+1. Saturating sub/add handles boundaries roughly. @@ -136,7 +136,7 @@ pub fn decode_uart_samples( } }; - // We loop while we have enough remaining samples for a full frame + // Loop while we have enough remaining samples for a full frame while idx + frame_len <= samples.len() { // Wait for falling edge (High -> Low) // samples[idx] == 1 (Idle/Stop) && samples[idx+1] == 0 (Start) @@ -146,7 +146,7 @@ pub fn decode_uart_samples( let center_offset = 1 + (ovs / 2); let mut scan_idx = idx + center_offset; - // 1. Validate Start Bit (Must be 0) + // Validate Start Bit if get_bit(scan_idx) != 0 { idx += 1; // False start (noise), move on continue; @@ -155,7 +155,7 @@ pub fn decode_uart_samples( // Move to center of first data bit scan_idx += ovs; - // 2. Read Data Bits + // Read Data Bits let mut data: u8 = 0; for bit in 0..nbits { if get_bit(scan_idx) == 1 { @@ -164,22 +164,22 @@ pub fn decode_uart_samples( scan_idx += ovs; } - // 3. Skip Parity (if any) + // Skip Parity if cfg.parity != Parity::None { scan_idx += ovs; } - // 4. Validate Stop Bit (Must be 1) + // Validate Stop Bit (Must be 1) // If stop bit is 0, it's a framing error. We reject the whole byte. if get_bit(scan_idx) == 0 { - idx += 1; // Try to find a real start bit on the next sample + idx += 1; // Next sample continue; } - // 5. Byte is valid + // Byte is valid let _ = out.push(data); - // 6. Active Resync: Fast-forward through the stop bit(s) and idle time + // Active Resync: Fast-forward through the stop bit(s) and idle time // scan_idx is currently at the center of the Stop bit. idx = scan_idx; // Advance while we are reading High (1).