updated UART echo RTIC example
This commit is contained in:
parent
60305ef393
commit
f7ff74940a
@ -1,12 +1,7 @@
|
||||
//! More complex UART application
|
||||
//!
|
||||
//! Uses the IRQ capabilities of the VA10820 peripheral and the RTIC framework to poll the UART in
|
||||
//! a non-blocking way. You can send variably sized strings to the VA10820 which will be echoed
|
||||
//! back to the sender.
|
||||
//!
|
||||
//! This script was tested with an Arduino Due. You can find the test script in the
|
||||
//! [`/test/DueSerialTest`](https://egit.irs.uni-stuttgart.de/rust/va108xx-hal/src/branch/main/test/DueSerialTest)
|
||||
//! folder.
|
||||
//! a non-blocking way. All received data will be sent back to the sender.
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
@ -26,37 +21,29 @@ mod app {
|
||||
use embedded_io::Write;
|
||||
use panic_rtt_target as _;
|
||||
use ringbuf::{
|
||||
traits::{Observer, Producer},
|
||||
traits::{Consumer, Observer, Producer, SplitRef},
|
||||
CachingCons, StaticProd,
|
||||
};
|
||||
use rtic_example::SYSCLK_FREQ;
|
||||
use rtic_sync::make_channel;
|
||||
use rtic_monotonics::Monotonic;
|
||||
use rtt_target::{rprintln, rtt_init_print};
|
||||
use va108xx_hal::{
|
||||
gpio::PinsB,
|
||||
pac,
|
||||
prelude::*,
|
||||
uart::{self, IrqCfg, IrqContextTimeoutOrMaxSize, IrqResult, RxWithIrq},
|
||||
uart::{self, RxWithIrq, Tx},
|
||||
};
|
||||
|
||||
#[local]
|
||||
struct Local {
|
||||
data_producer: StaticProd<'static, u8, RX_RING_BUF_SIZE>,
|
||||
data_consumer: CachingCons<&'static StaticRb<u8, RX_RING_BUF_SIZE>>,
|
||||
uart_rx: RxWithIrq<pac::Uartb>,
|
||||
rx: RxWithIrq<pac::Uartb>,
|
||||
tx: Tx<pac::Uartb>,
|
||||
}
|
||||
|
||||
#[shared]
|
||||
struct Shared {
|
||||
rx_buf: [u8; 64],
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
struct RxInfo {
|
||||
pub bytes_read: usize,
|
||||
pub end_idx: usize,
|
||||
pub timeout: bool,
|
||||
}
|
||||
struct Shared {}
|
||||
|
||||
rtic_monotonics::systick_monotonic!(Mono, 1_000);
|
||||
|
||||
@ -72,23 +59,21 @@ mod app {
|
||||
let tx = gpiob.pb21.into_funsel_1();
|
||||
let rx = gpiob.pb20.into_funsel_1();
|
||||
|
||||
let irq_cfg = IrqCfg::new(pac::interrupt::OC3, true, true);
|
||||
let irq_uart =
|
||||
uart::Uart::new(&mut dp.sysconfig, 50.MHz(), dp.uartb, (tx, rx), 115200.Hz());
|
||||
let (tx, rx) = irq_uart.split();
|
||||
let rx = rx.into_rx_with_irq(&dp.irqsel, pac::interrupt::OC3);
|
||||
let mut rx = rx.into_rx_with_irq(&dp.irqsel, pac::interrupt::OC3);
|
||||
|
||||
let context = IrqContextTimeoutOrMaxSize::new(64);
|
||||
rx.read_fixed_len_or_timeout_based_using_irq(&mut context)
|
||||
.expect("UART RX init failed");
|
||||
rx.start();
|
||||
|
||||
let (rx_info_tx, rx_info_rx) = make_channel!(RxInfo, 3);
|
||||
let rx_buf: [u8; 64] = [0; 64];
|
||||
let (data_producer, data_consumer) = unsafe { RINGBUF.split_ref() };
|
||||
(
|
||||
Shared { uart_rx, rx_buf },
|
||||
Shared {},
|
||||
Local {
|
||||
rx_info_tx,
|
||||
rx_info_rx,
|
||||
data_producer,
|
||||
data_consumer,
|
||||
rx,
|
||||
tx,
|
||||
},
|
||||
)
|
||||
}
|
||||
@ -103,16 +88,16 @@ mod app {
|
||||
|
||||
#[task(
|
||||
binds = OC3,
|
||||
shared = [rx_buf],
|
||||
shared = [],
|
||||
local = [
|
||||
uart_rx,
|
||||
rx,
|
||||
data_producer
|
||||
],
|
||||
)]
|
||||
fn reception_task(cx: reception_task::Context) {
|
||||
let mut buf: [u8; 16] = [0; 16];
|
||||
let mut ringbuf_full = false;
|
||||
let result = cx.local.uart_rx.irq_handler(&mut buf);
|
||||
let result = cx.local.rx.irq_handler(&mut buf);
|
||||
if result.bytes_read > 0 && result.errors.is_none() {
|
||||
if cx.local.data_producer.vacant_len() < result.bytes_read {
|
||||
ringbuf_full = true;
|
||||
@ -128,32 +113,23 @@ mod app {
|
||||
}
|
||||
}
|
||||
|
||||
#[task(shared = [rx_buf], local = [data_consumer], priority=1)]
|
||||
#[task(shared = [], local = [
|
||||
buf: [u8; RX_RING_BUF_SIZE] = [0; RX_RING_BUF_SIZE],
|
||||
data_consumer,
|
||||
tx
|
||||
], priority=1)]
|
||||
async fn echo_handler(cx: echo_handler::Context) {
|
||||
/*
|
||||
let mut irq_uart = cx.shared.irq_uart;
|
||||
let mut rx_buf = cx.shared.rx_buf;
|
||||
loop {
|
||||
match cx.local.rx_info_rx.recv().await {
|
||||
Ok(rx_info) => {
|
||||
rprintln!("reception success, {} bytes read", rx_info.bytes_read);
|
||||
if rx_info.timeout {
|
||||
rprintln!("timeout occurred");
|
||||
}
|
||||
rx_buf.lock(|rx_buf| {
|
||||
let string = core::str::from_utf8(&rx_buf[0..rx_info.end_idx])
|
||||
.expect("Invalid string format");
|
||||
rprintln!("read string: {}", string);
|
||||
irq_uart.lock(|uart| {
|
||||
writeln!(uart.uart, "{}", string).expect("Sending reply failed");
|
||||
});
|
||||
});
|
||||
}
|
||||
Err(e) => {
|
||||
rprintln!("error receiving RX info: {:?}", e);
|
||||
}
|
||||
}
|
||||
let bytes_to_read = cx.local.data_consumer.occupied_len();
|
||||
let actual_read_bytes = cx
|
||||
.local
|
||||
.data_consumer
|
||||
.pop_slice(&mut cx.local.buf[0..bytes_to_read]);
|
||||
cx.local
|
||||
.tx
|
||||
.write_all(&cx.local.buf[0..actual_read_bytes])
|
||||
.expect("Failed to write to TX");
|
||||
Mono::delay(50.millis()).await;
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
@ -222,6 +222,30 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "cortex-debug",
|
||||
"request": "launch",
|
||||
"name": "UART Echo with RTIC",
|
||||
"servertype": "jlink",
|
||||
"cwd": "${workspaceRoot}",
|
||||
"device": "Cortex-M0",
|
||||
"svdFile": "./va108xx/svd/va108xx-base.svd.patched",
|
||||
"preLaunchTask": "uart-echo-rtic-example",
|
||||
"executable": "${workspaceFolder}/target/thumbv6m-none-eabi/debug/uart-echo-rtic",
|
||||
"interface": "jtag",
|
||||
"runToEntryPoint": "main",
|
||||
"rttConfig": {
|
||||
"enabled": true,
|
||||
"address": "auto",
|
||||
"decoders": [
|
||||
{
|
||||
"port": 0,
|
||||
"timestamp": true,
|
||||
"type": "console"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "cortex-debug",
|
||||
"request": "launch",
|
||||
@ -428,4 +452,4 @@
|
||||
}
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -122,13 +122,13 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "rust: cargo build uart irq",
|
||||
"label": "uart-echo-rtic-example",
|
||||
"type": "shell",
|
||||
"command": "~/.cargo/bin/cargo", // note: full path to the cargo
|
||||
"args": [
|
||||
"build",
|
||||
"--bin",
|
||||
"uart-rtic",
|
||||
"uart-echo-rtic",
|
||||
],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
|
Loading…
Reference in New Issue
Block a user