-
Notifications
You must be signed in to change notification settings - Fork 264
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: uart break detection interrupt #2858
Open
zpg6
wants to merge
36
commits into
esp-rs:main
Choose a base branch
from
zpg6:feat/uart/break-detection-interrupt
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
36 commits
Select commit
Hold shift + click to select a range
3d14724
feat: uart break detection interrupt
zpg6 be1a908
format: run `cargo xtask fmt-packages`
zpg6 b7c3f70
docs: CHANGELOG entry
zpg6 3e52d6a
fix: no Result needed for `wait_for_break_async`
zpg6 44be3e6
fix: clarify added interrupt in changelog
zpg6 d1531ac
test: adding `uart_interrupts` example
zpg6 a38ed91
test: adds examples for blocking and async break detection w/o handlers
zpg6 118dce8
chore: format on register write statement
zpg6 735f527
chore: comment format
zpg6 fecb91c
chore: more formatting
zpg6 473780c
fix: for blocking impl be sure to enable the interrupt and clear it
zpg6 9d0c122
fix: flipped rx and tx in `Uart::new()`
zpg6 06cc4fd
fix: note only tested on `esp32`
zpg6 a19f915
fix: better handler debug output to demonstrate
zpg6 7c830df
fix: again more useful debug output
zpg6 af8a228
chore: formatting
zpg6 149c6b9
chore: format and debug output
zpg6 d344c91
docs: clarify interrupt every time a byte is received
zpg6 a2153e7
fmt: debug message too long
zpg6 f2c9d35
test: adds uart_brk_det HIL test
zpg6 ed719da
chore: embassy features not needed for blocking example
zpg6 fd52ecf
chore: revert to latest main
zpg6 1deff46
Merge branch 'main' into feat/uart/break-detection-interrupt
zpg6 cdb7bdc
feat: migrate to v0.23
zpg6 049ee95
chore: add back into changelog
zpg6 9f908e9
chore: fmt hil test
zpg6 772a297
fix: unused import
zpg6 ef343f3
fix: managing merge conflicts
zpg6 ed711b8
fix: fmt
zpg6 a05264e
fix: revert uart.rs
zpg6 aa29c3a
fix: fmt
zpg6 4962299
Merge branch 'main' into feat/uart/break-detection-interrupt
zpg6 351ea0e
fix: repush to match with main
zpg6 8d01053
fix: `.rx`
zpg6 bd3d1aa
fix: fmt
zpg6 a710fcc
chore: cleanup examples
zpg6 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
//! Blocking UART break detection example. | ||
//! | ||
//! The following wiring is assumed: | ||
//! - RX => GPIO16 | ||
|
||
//% CHIPS: esp32 | ||
//% FEATURES: esp-hal/unstable | ||
|
||
#![no_std] | ||
#![no_main] | ||
|
||
use esp_backtrace as _; | ||
use esp_hal::{ | ||
main, | ||
uart::{Config as UartConfig, DataBits, Parity, StopBits, Uart}, | ||
}; | ||
|
||
#[main] | ||
fn main() -> ! { | ||
let peripherals = esp_hal::init(esp_hal::Config::default()); | ||
let uart_config = UartConfig::default() | ||
.with_baudrate(19200) | ||
.with_data_bits(DataBits::_8) | ||
.with_parity(Parity::None) | ||
.with_stop_bits(StopBits::_1); | ||
let mut uart = Uart::new(peripherals.UART1, uart_config) | ||
.expect("Failed to initialize UART") | ||
.with_rx(peripherals.GPIO16); | ||
|
||
loop { | ||
uart.wait_for_break(); | ||
esp_println::print!("\nBREAK"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
//! Async UART break detection example. | ||
//! | ||
//! The following wiring is assumed: | ||
//! - RX => GPIO16 | ||
|
||
//% CHIPS: esp32 | ||
//% FEATURES: embassy esp-hal/unstable | ||
|
||
#![no_std] | ||
#![no_main] | ||
|
||
use embassy_executor::Spawner; | ||
use esp_backtrace as _; | ||
use esp_hal::uart::{Config as UartConfig, DataBits, Parity, StopBits, Uart}; | ||
|
||
#[esp_hal_embassy::main] | ||
async fn main(_spawner: Spawner) { | ||
let peripherals = esp_hal::init(esp_hal::Config::default()); | ||
let uart_config = UartConfig::default() | ||
.with_baudrate(19200) | ||
.with_data_bits(DataBits::_8) | ||
.with_parity(Parity::None) | ||
.with_stop_bits(StopBits::_1); | ||
let mut uart = Uart::new(peripherals.UART1, uart_config) | ||
.expect("Failed to initialize UART") | ||
.with_rx(peripherals.GPIO16) | ||
.into_async(); | ||
|
||
loop { | ||
uart.wait_for_break_async().await; | ||
esp_println::print!("\nBREAK"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
//! Example of responding to UART interrupts. | ||
//! | ||
//! The following wiring is assumed: | ||
//! - RX => GPIO16 | ||
|
||
//% CHIPS: esp32 | ||
//% FEATURES: esp-hal/unstable | ||
|
||
#![no_std] | ||
#![no_main] | ||
|
||
use core::cell::RefCell; | ||
|
||
use critical_section::Mutex; | ||
use esp_backtrace as _; | ||
use esp_hal::{ | ||
handler, | ||
main, | ||
ram, | ||
uart::{Config as UartConfig, DataBits, Parity, RxConfig, StopBits, Uart, UartInterrupt}, | ||
Blocking, | ||
}; | ||
|
||
static SERIAL: Mutex<RefCell<Option<Uart<Blocking>>>> = Mutex::new(RefCell::new(None)); | ||
|
||
#[main] | ||
fn main() -> ! { | ||
let peripherals = esp_hal::init(esp_hal::Config::default()); | ||
let uart_config = UartConfig::default() | ||
.with_baudrate(19200) | ||
.with_data_bits(DataBits::_8) | ||
.with_parity(Parity::None) | ||
.with_stop_bits(StopBits::_1) | ||
.with_rx(RxConfig::default().with_fifo_full_threshold(1)); | ||
let mut uart = Uart::new(peripherals.UART1, uart_config) | ||
.expect("Failed to initialize UART") | ||
.with_rx(peripherals.GPIO16); | ||
|
||
uart.set_interrupt_handler(handler); | ||
|
||
critical_section::with(|cs| { | ||
uart.clear_interrupts(UartInterrupt::RxBreakDetected | UartInterrupt::RxFifoFull); | ||
uart.listen(UartInterrupt::RxBreakDetected | UartInterrupt::RxFifoFull); | ||
SERIAL.borrow_ref_mut(cs).replace(uart); | ||
}); | ||
|
||
loop {} | ||
} | ||
|
||
#[handler] | ||
#[ram] | ||
fn handler() { | ||
critical_section::with(|cs| { | ||
let mut serial = SERIAL.borrow_ref_mut(cs); | ||
let serial = serial.as_mut().unwrap(); | ||
|
||
if serial.interrupts().contains(UartInterrupt::RxBreakDetected) { | ||
esp_println::print!("\nBREAK"); | ||
} | ||
if serial.interrupts().contains(UartInterrupt::RxFifoFull) { | ||
let mut byte = [0u8; 1]; | ||
serial.read(&mut byte).unwrap(); | ||
esp_println::print!(" {:02X}", byte[0]); | ||
} | ||
|
||
serial.clear_interrupts(UartInterrupt::RxBreakDetected | UartInterrupt::RxFifoFull); | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
//! UART Break Detection test | ||
|
||
//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3 | ||
//% FEATURES: embassy | ||
|
||
#![no_std] | ||
#![no_main] | ||
|
||
use esp_hal::{ | ||
uart::{Config as UartConfig, Uart}, | ||
Blocking, | ||
}; | ||
use hil_test as _; | ||
|
||
struct Context { | ||
uart: Uart<'static, Blocking>, | ||
} | ||
|
||
#[cfg(test)] | ||
#[embedded_test::tests(default_timeout = 3, executor = esp_hal_embassy::Executor::new())] | ||
mod tests { | ||
use super::*; | ||
|
||
#[init] | ||
fn init() -> Context { | ||
let peripherals = esp_hal::init(esp_hal::Config::default()); | ||
|
||
let (_, pin) = hil_test::common_test_pins!(peripherals); | ||
let (rx, tx) = pin.split(); | ||
let uart = Uart::new(peripherals.UART1, UartConfig::default()) | ||
.expect("Failed to initialize UART") | ||
.with_rx(rx) | ||
.with_tx(tx); | ||
|
||
Context { uart } | ||
} | ||
|
||
#[test] | ||
fn test_wait_for_break_blocking(mut ctx: Context) { | ||
// TODO: Send (or simulate) a break signal, otherwise this will fail via timeout | ||
ctx.uart.wait_for_break(); | ||
} | ||
|
||
#[test] | ||
async fn test_wait_for_break_async(ctx: Context) { | ||
// TODO: Send (or simulate) a break signal, otherwise this will fail via timeout | ||
ctx.uart.into_async().wait_for_break_async().await; | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
int_ena
bit to be set?int_ena
at the end of the function without actually checking if it was cleared beforeThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
int_raw
only functions ifint_ena
is set. Is this incorrect?int_clr
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, as far as I know only
int_st
and the actual interrupt handling is affected, whereint_st = int_raw & int_ena
. Usually.Hmm yeah disregard that point, I saw something else, not what you wrote. But in that case you should disable listening for the interrupt :)