Skip to content

Commit fb40e9f

Browse files
authored
Merge pull request #155 from braun-embedded/serial-echo-rtic
Add example that does serial RX/TX using an interrupt
2 parents 815cb05 + 43c613c commit fb40e9f

File tree

2 files changed

+113
-0
lines changed

2 files changed

+113
-0
lines changed

Cargo.toml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,14 @@ usbd-serial = "0.1.0"
7070
heapless = "0.5"
7171
cortex-m-rtic = "0.5.5"
7272

73+
[dev-dependencies.panic-rtt-target]
74+
version = "0.1.1"
75+
features = ["cortex-m"]
76+
77+
[dev-dependencies.rtt-target]
78+
version = "0.2.2"
79+
features = ["cortex-m"]
80+
7381
[profile.dev]
7482
incremental = false
7583
codegen-units = 1
@@ -100,6 +108,10 @@ required-features = ["rt"]
100108
name = "rtic_frame_serial_dma"
101109
required-features = ["rt", "stm32l4x2"]
102110

111+
[[example]]
112+
name = "serial_echo_rtic"
113+
required-features = ["rt", "stm32l4x3"]
114+
103115
[[example]]
104116
name = "timer"
105117
required-features = ["rt"]

examples/serial_echo_rtic.rs

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
#![no_main]
2+
#![no_std]
3+
4+
extern crate panic_rtt_target;
5+
6+
use heapless::{consts::U8, spsc};
7+
use nb::block;
8+
use rtt_target::{rprint, rprintln};
9+
use stm32l4xx_hal::{
10+
pac::{self, USART2},
11+
prelude::*,
12+
serial::{self, Config, Serial},
13+
};
14+
15+
#[rtic::app(device = stm32l4xx_hal::pac)]
16+
const APP: () = {
17+
struct Resources {
18+
rx: serial::Rx<USART2>,
19+
tx: serial::Tx<USART2>,
20+
21+
rx_prod: spsc::Producer<'static, u8, U8>,
22+
rx_cons: spsc::Consumer<'static, u8, U8>,
23+
}
24+
25+
#[init]
26+
fn init(_: init::Context) -> init::LateResources {
27+
static mut RX_QUEUE: spsc::Queue<u8, U8> = spsc::Queue(heapless::i::Queue::new());
28+
29+
rtt_target::rtt_init_print!();
30+
rprint!("Initializing... ");
31+
32+
let p = pac::Peripherals::take().unwrap();
33+
34+
let mut rcc = p.RCC.constrain();
35+
let mut flash = p.FLASH.constrain();
36+
let mut pwr = p.PWR.constrain(&mut rcc.apb1r1);
37+
38+
let clocks = rcc.cfgr.freeze(&mut flash.acr, &mut pwr);
39+
40+
let mut gpioa = p.GPIOA.split(&mut rcc.ahb2);
41+
42+
let tx_pin = gpioa.pa2.into_af7(&mut gpioa.moder, &mut gpioa.afrl);
43+
let rx_pin = gpioa.pa3.into_af7(&mut gpioa.moder, &mut gpioa.afrl);
44+
45+
let mut serial = Serial::usart2(
46+
p.USART2,
47+
(tx_pin, rx_pin),
48+
Config::default().baudrate(115_200.bps()),
49+
clocks,
50+
&mut rcc.apb1r1,
51+
);
52+
serial.listen(serial::Event::Rxne);
53+
54+
let (tx, rx) = serial.split();
55+
let (rx_prod, rx_cons) = RX_QUEUE.split();
56+
57+
rprintln!("done.");
58+
59+
init::LateResources {
60+
rx,
61+
tx,
62+
63+
rx_prod,
64+
rx_cons,
65+
}
66+
}
67+
68+
#[idle(resources = [rx_cons, tx])]
69+
fn idle(cx: idle::Context) -> ! {
70+
let rx = cx.resources.rx_cons;
71+
let tx = cx.resources.tx;
72+
73+
loop {
74+
if let Some(b) = rx.dequeue() {
75+
rprintln!("Echoing '{}'", b as char);
76+
block!(tx.write(b)).unwrap();
77+
}
78+
}
79+
}
80+
81+
#[task(binds = USART2, resources = [rx, rx_prod])]
82+
fn usart2(cx: usart2::Context) {
83+
let rx = cx.resources.rx;
84+
let queue = cx.resources.rx_prod;
85+
86+
let b = match rx.read() {
87+
Ok(b) => b,
88+
Err(err) => {
89+
rprintln!("Error reading from USART: {:?}", err);
90+
return;
91+
}
92+
};
93+
match queue.enqueue(b) {
94+
Ok(()) => (),
95+
Err(err) => {
96+
rprintln!("Error adding received byte to queue: {:?}", err);
97+
return;
98+
}
99+
}
100+
}
101+
};

0 commit comments

Comments
 (0)