Skip to content

Commit 59cbcac

Browse files
authored
Merge pull request #862 from mrwatts88/serial-irq-example
Serial IRQ example
2 parents 7f96050 + 0943a2d commit 59cbcac

File tree

2 files changed

+92
-0
lines changed

2 files changed

+92
-0
lines changed

Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -724,6 +724,10 @@ required-features = ["gpiod", "sdio", "sdio-host"] # stm32f405
724724
name = "serial"
725725
required-features = []
726726

727+
[[example]]
728+
name = "serial-echo-irq"
729+
required-features = []
730+
727731
[[example]]
728732
name = "serial-9bit"
729733
required-features = ["gpiod"] # stm32f411

examples/serial-echo-irq.rs

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
//! Serial echo using USART RX interrupt
2+
//!
3+
//! This example demonstrates interrupt-driven serial reception with echo.
4+
//! Characters received on USART2 are echoed back.
5+
//!
6+
//! Tested on STM32F446 Nucleo board where USART2 is connected to the
7+
//! ST-LINK virtual COM port (PA2=TX, PA3=RX).
8+
//!
9+
//! ```bash
10+
//! cargo run --features stm32f446 --release --example serial-echo-irq
11+
//! ```
12+
//!
13+
//! Example connection with picocom:
14+
//!
15+
//! ```bash
16+
//! picocom -b 115200 /dev/ttyACM0
17+
//! ```
18+
//!
19+
//! Type into the picocom terminal to see characters echoed.
20+
//! You will also see the characters logged in the terminal connected to the board.
21+
//!
22+
23+
#![no_std]
24+
#![no_main]
25+
26+
use core::cell::RefCell;
27+
use cortex_m::interrupt::Mutex;
28+
use cortex_m_rt::entry;
29+
use panic_halt as _;
30+
use rtt_target::{rprintln, rtt_init_print};
31+
32+
use stm32f4xx_hal::{
33+
interrupt, pac,
34+
prelude::*,
35+
rcc::Config,
36+
serial::{self, Serial},
37+
};
38+
39+
type SerialType = Serial<pac::USART2>;
40+
static SERIAL: Mutex<RefCell<Option<SerialType>>> = Mutex::new(RefCell::new(None));
41+
42+
#[entry]
43+
fn main() -> ! {
44+
rtt_init_print!();
45+
46+
let dp = pac::Peripherals::take().unwrap();
47+
let mut rcc = dp.RCC.freeze(Config::hsi().sysclk(48.MHz()));
48+
let gpioa = dp.GPIOA.split(&mut rcc);
49+
50+
let tx = gpioa.pa2;
51+
let rx = gpioa.pa3;
52+
53+
let mut serial: SerialType = Serial::new(
54+
dp.USART2,
55+
(tx, rx),
56+
serial::Config::default().baudrate(115200.bps()),
57+
&mut rcc,
58+
)
59+
.unwrap();
60+
61+
serial.listen(serial::Event::RxNotEmpty);
62+
63+
cortex_m::interrupt::free(|cs| {
64+
SERIAL.borrow(cs).replace(Some(serial));
65+
});
66+
67+
// Enable USART2 interrupt
68+
unsafe {
69+
pac::NVIC::unmask(pac::Interrupt::USART2);
70+
}
71+
72+
#[allow(clippy::empty_loop)]
73+
loop {}
74+
}
75+
76+
#[interrupt]
77+
fn USART2() {
78+
cortex_m::interrupt::free(|cs| {
79+
if let Some(serial) = SERIAL.borrow(cs).borrow_mut().as_mut() {
80+
if let Ok(byte) = serial.read() {
81+
rprintln!("Received: {} ('{}')", byte, byte as char);
82+
83+
// Echo received byte
84+
let _ = serial.write(byte);
85+
}
86+
}
87+
});
88+
}

0 commit comments

Comments
 (0)