diff --git a/semestralka_1_2hwuart_internal/Cargo.lock b/semestralka_1_2hwuart_internal/Cargo.lock index fdfde1a..b12cb20 100644 --- a/semestralka_1_2hwuart_internal/Cargo.lock +++ b/semestralka_1_2hwuart_internal/Cargo.lock @@ -1064,17 +1064,17 @@ dependencies = [ [[package]] name = "stm32-fmc" -version = "0.4.0" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72692594faa67f052e5e06dd34460951c21e83bc55de4feb8d2666e2f15480a2" +checksum = "c7f0639399e2307c2446c54d91d4f1596343a1e1d5cab605b9cce11d0ab3858c" dependencies = [ - "embedded-hal 1.0.0", + "embedded-hal 0.2.7", ] [[package]] name = "stm32-metapac" version = "18.0.0" -source = "git+https://github.com/embassy-rs/stm32-data-generated?tag=stm32-data-22374e3344a2c9150b9b3d4da45c03f398fdc54e#31546499ddabe97044beae13ca8b535575b52a56" +source = "git+https://github.com/embassy-rs/stm32-data-generated?tag=stm32-data-b9f6b0c542d85ee695d71c35ced195e0cef51ac0#9b8fb67703361e2237b6c1ec4f1ee5949223d412" dependencies = [ "cortex-m", "cortex-m-rt", diff --git a/semestralka_1_2hwuart_internal/src/bin/main.rs b/semestralka_1_2hwuart_internal/src/bin/main.rs index e7ecec3..f90ad75 100644 --- a/semestralka_1_2hwuart_internal/src/bin/main.rs +++ b/semestralka_1_2hwuart_internal/src/bin/main.rs @@ -111,9 +111,7 @@ async fn main(spawner: Spawner) { let mut last_state: u8 = 0; loop { - tx_pin.set_high(); - Timer::after(Duration::from_millis(10)).await; - info!("tick start"); + // info!("tick start"); // Timer::after(Duration::from_millis(100)).await; // info!("tick end"); @@ -125,24 +123,6 @@ async fn main(spawner: Spawner) { // } // yield_now().await; - let bit = rx_pin.is_high(); - // info!("Rx_pin read (high): {}", bit); - if bit as u8 != last_state { - info!( - "SW RX -> PD6 changed, new state = {}", - if bit { "HIGH" } else { "LOW" } - ); - last_state = bit as u8; - continue; - yield_now().await; - } - Timer::after(Duration::from_millis(1)).await; - - // ZNOVA TO ISTE ALE LOW - tx_pin.set_low(); - Timer::after(Duration::from_millis(1)).await; - let low_state = rx_pin.is_high(); - defmt::info!("Rx_pin (read): {}", low_state); yield_now().await; } @@ -174,7 +154,7 @@ pub async fn bridge_usart2_rx_to_usart1_tx( let n = usart2_rx.read(&mut buf).await; if n > 0 { let _ = usart1_tx.write(&buf[..n]).await; - info!("bridge: USART2 -> USART1 sent {} bytes", n); + // info!("bridge: USART2 -> USART1 sent {} bytes", n); } yield_now().await; } diff --git a/semestralka_1d_rx_bez_dma/src/bin/main.rs b/semestralka_1d_rx_bez_dma/src/bin/main.rs index bed0158..f90ad75 100644 --- a/semestralka_1d_rx_bez_dma/src/bin/main.rs +++ b/semestralka_1d_rx_bez_dma/src/bin/main.rs @@ -4,14 +4,17 @@ use defmt::*; use embassy_executor::Spawner; +use embassy_time::Instant; use embassy_stm32::dma::Request; -use embassy_stm32::gpio::{Input, Pull}; +use embassy_stm32::gpio::{Input, Output, Level, Pull, Speed}; use dma_gpio::software_uart::{ dma_timer::{init_tim6_for_uart, init_tim7_for_uart}, + gpio_dma_uart_rx::rx_dma_task, debug::dump_tim6_regs, }; use dma_gpio::config::{BAUD, RX_OVERSAMPLE, TX_OVERSAMPLE}; use dma_gpio::config::{TX_RING_BYTES, RX_RING_BYTES}; +use dma_gpio::software_uart::gpio_dma_uart_tx::tx_dma_task; use static_cell::StaticCell; use embassy_futures::yield_now; use dma_gpio::hw_uart_pc::usart1; @@ -19,22 +22,14 @@ use dma_gpio::hw_uart_pc::driver::uart_task; use embassy_stm32::usart::{BufferedUart, Config, BufferedInterruptHandler}; use embassy_stm32::peripherals; use embassy_stm32::bind_interrupts; -use dma_gpio::config::{PIPE_HW_TX, PIPE_HW_RX}; +use dma_gpio::config::{PIPE_HW_TX, PIPE_HW_RX, PIPE_SW_TX, PIPE_SW_RX}; use embassy_sync::{blocking_mutex::raw::CriticalSectionRawMutex, pipe::Pipe}; use dma_gpio::hw_uart_internal::usart2; use dma_gpio::hw_uart_internal::driver::uart_task as uart_task_internal; use dma_gpio::config::{PIPE_INT_TX, PIPE_INT_RX}; -use embassy_stm32::pac; -use embassy_stm32::interrupt; use embassy_time::{Duration, Timer}; -use embassy_sync::channel::Channel; use {defmt_rtt as _, panic_probe as _}; -use cortex_m::interrupt::Mutex; -use core::cell::RefCell; - -static RX_PIN_GLOBAL: Mutex>>> = Mutex::new(RefCell::new(None)); - bind_interrupts!(struct Irqs { USART1 => BufferedInterruptHandler; }); @@ -46,13 +41,14 @@ bind_interrupts!(struct Irqs2 { pub const TIM6_UP_REQ: Request = 4; static SW_TX_RING: StaticCell<[u32; TX_RING_BYTES]> = StaticCell::new(); static SW_RX_RING: StaticCell<[u8; RX_RING_BYTES]> = StaticCell::new(); -static RAW_BITS_CHANNEL: Channel = Channel::new(); #[embassy_executor::main] async fn main(spawner: Spawner) { info!("boot"); let p = embassy_stm32::init(Default::default()); info!("init m8"); + + // HARDWARE UART to the PC let mut cfg = Config::default(); cfg.baudrate = BAUD; @@ -67,7 +63,7 @@ async fn main(spawner: Spawner) { Irqs, cfg, ).unwrap(); - let _ = usart1::setup_and_spawn(BAUD); + let yield_period = usart1::setup_and_spawn(BAUD); spawner.spawn(uart_task(uart, &PIPE_HW_TX, &PIPE_HW_RX).unwrap()); // END OF HARDWARE UART to the PC @@ -86,77 +82,49 @@ async fn main(spawner: Spawner) { Irqs2, cfg2, ).unwrap(); + let _ = usart2::setup_and_spawn(BAUD); spawner.spawn(uart_task_internal(uart2, &PIPE_INT_TX, &PIPE_INT_RX).unwrap()); info!("USART2 ready"); // END OF INTERNAL HARDWARE UART (USART2) - + // USART1 <-> USART2 bridge spawner.spawn(bridge_usart1_rx_to_usart2_tx(&PIPE_HW_RX, &PIPE_INT_TX).unwrap()); spawner.spawn(bridge_usart2_rx_to_usart1_tx(&PIPE_INT_RX, &PIPE_HW_TX).unwrap()); info!("USART1 <-> USART2 bridge active"); - // END OF USART1 <-> USART2 bridge + // END OF USART1 <-> USART2 bridge - // SOFTWARE UART CONFIG - // We initialize the Input here to ensure GPIO is configured (PullUp, etc.) - let mut rx_pin = Input::new(p.PD6, Pull::Up); + // SOFTWARE UART + // let _rx = Input::new(p.PD6, Pull::Up); + let rx_pin = Input::new(p.PD6, Pull::Up); + // Configure TX as output (PB0) - use cortex_m::interrupt::free; - let rx_pin_ref: &'static mut Input<'static> = unsafe { core::mem::transmute(&mut rx_pin) }; - free(|cs| RX_PIN_GLOBAL.borrow(cs).replace(Some(rx_pin_ref))); - + let mut tx_pin = Output::new(p.PB0, Level::High, Speed::VeryHigh); init_tim6_for_uart(p.TIM6, BAUD, TX_OVERSAMPLE); - - // Init TIM7 with Interrupt enabled (see dma_timer.rs) init_tim7_for_uart(p.TIM7, BAUD, RX_OVERSAMPLE); dump_tim6_regs(); - - // Enable TIM7 Interrupt in NVIC - unsafe { - cortex_m::peripheral::NVIC::unmask(pac::Interrupt::TIM7); - } - info!("TIM7 Interrupt enabled"); - // END OF SOFTWARE UART - + // EDN OF SOFTWARE UART - let mut last_val = 0; - let mut count = 0u32; - + let mut last_yield = Instant::now(); + let mut buf = [0u8; 32]; + + let mut last_state: u8 = 0; loop { - // Receive next bit from ISR (yields if empty) - let val = RAW_BITS_CHANNEL.receive().await; + // info!("tick start"); + // Timer::after(Duration::from_millis(100)).await; + // info!("tick end"); - if val != last_val { - info!("PD6 bit changed: {} (after {} stable ticks)", val, count); - last_val = val; - count = 0; - } else { - count += 1; - } + // let n1 = PIPE_HW_RX.read(&mut buf).await; + // if n1 > 0 { + // info!("PC received: {:a}", &buf[..n1]); + // let _ = PIPE_SW_TX.write(&buf[..n1]).await; + // info!("SW UART TX sent echo: {:a}", &buf[..n1]); + // } + // yield_now().await; - // CRITICAL: Yield periodically. - // The ISR produces 153,600 samples/s. Processing them one-by-one - // will starve the UART Bridge tasks if we don't yield explicitly. - if count % 128 == 0 { - yield_now().await; - } - } -} -#[interrupt] -fn TIM7() { - let tim = unsafe { pac::TIM7 }; - - if tim.sr().read().uif() { - tim.sr().modify(|w| w.set_uif(false)); - - cortex_m::interrupt::free(|cs| { - if let Some(pin) = RX_PIN_GLOBAL.borrow(cs).borrow_mut().as_mut() { - let val = if pin.is_high() { 1u8 } else { 0u8 }; - let _ = RAW_BITS_CHANNEL.try_send(val); - } - }); + yield_now().await; } } @@ -170,7 +138,7 @@ pub async fn bridge_usart1_rx_to_usart2_tx( let n = usart1_rx.read(&mut buf).await; if n > 0 { let _ = usart2_tx.write(&buf[..n]).await; - info!("Buffer USART1 -> USART2 bytes: {:?}", &buf[..n]); + info!("bridge: USART1 -> USART2 sent {} bytes", n); } yield_now().await; } @@ -186,7 +154,7 @@ pub async fn bridge_usart2_rx_to_usart1_tx( let n = usart2_rx.read(&mut buf).await; if n > 0 { let _ = usart1_tx.write(&buf[..n]).await; - // info!("Buffer USART2 -> USART1 bytes: {:?}", &buf[..n]); + // info!("bridge: USART2 -> USART1 sent {} bytes", n); } yield_now().await; } diff --git a/semestralka_1d_rx_bez_dma/src/software_uart/dma_timer.rs b/semestralka_1d_rx_bez_dma/src/software_uart/dma_timer.rs index 084f8ab..6979383 100644 --- a/semestralka_1d_rx_bez_dma/src/software_uart/dma_timer.rs +++ b/semestralka_1d_rx_bez_dma/src/software_uart/dma_timer.rs @@ -1,4 +1,4 @@ -// src/software_uart/dma_timer.rs +// src/dma_timer.rs use embassy_stm32::{ peripherals::{TIM6, TIM7}, @@ -20,19 +20,11 @@ pub fn init_tim6_for_uart<'d>(tim6: Peri<'d, TIM6>, baud: u32, oversample: u16) } /// Initializes TIM7 to tick at `baud * oversample` frequency. -/// Each TIM7 update event triggers one DMA beat AND an Interrupt. +/// Each TIM7 update event triggers one DMA beat. pub fn init_tim7_for_uart<'d>(tim7: Peri<'d, TIM7>, baud: u32, oversample: u16) { rcc::enable_and_reset::(); let ll = Timer::new(tim7); - - // Reuse the common config first configure_basic_timer(&ll, baud, oversample); - - // Enable Update Interrupt (UIE) specifically for TIM7 - ll.regs_basic().dier().modify(|w| { - w.set_uie(true); - }); - mem::forget(ll); } @@ -54,9 +46,7 @@ fn configure_basic_timer(ll: &Timer<'_, T>, baud: u32, oversam ll.regs_basic().psc().write_value(0u16); ll.regs_basic().arr().write(|w| w.set_arr(arr)); - - ll.regs_basic().dier().modify(|w| w.set_ude(true)); - + ll.regs_basic().dier().modify(|w| w.set_ude(true)); ll.regs_basic().egr().write(|w| w.set_ug(true)); ll.regs_basic().cr1().write(|w| {