Expand description
§Universal Asynchronous Receiver/Transmitter (UART)
§Overview
The UART is a hardware peripheral which handles communication using serial communication interfaces, such as RS232 and RS485. This peripheral provides a cheap and ubiquitous method for full- and half-duplex communication between devices.
Depending on your device, two or more UART controllers are available for use, all of which can be configured and used in the same way. All UART controllers are compatible with UART-enabled devices from various manufacturers, and can also support Infrared Data Association (IrDA) protocols.
§Configuration
Each UART controller is individually configurable, and the usual setting such as baud rate, data bits, parity, and stop bits can easily be configured. Additionally, the receive (RX) and transmit (TX) pins need to be specified.
let mut uart1 = Uart::new(
peripherals.UART1,
Config::default())
.unwrap()
.with_rx(peripherals.GPIO1)
.with_tx(peripherals.GPIO2);
The UART controller can be configured to invert the polarity of the pins. This is achieved by inverting the desired pins, and then constructing the UART instance using the inverted pins.
§Usage
The UART driver implements a number of third-party traits, with the intention of making the HAL inter-compatible with various device drivers from the community. This includes, but is not limited to, the embedded-hal and embedded-io blocking traits, and the embedded-hal-async and embedded-io-async asynchronous traits.
In addition to the interfaces provided by these traits, native APIs are also available. See the examples below for more information on how to interact with this driver.
§Examples
§Sending and Receiving Data
// Write bytes out over the UART:
uart1.write_bytes(b"Hello, world!").expect("write error!");
§Splitting the UART into RX and TX Components
// The UART can be split into separate Transmit and Receive components:
let (mut rx, mut tx) = uart1.split();
// Each component can be used individually to interact with the UART:
tx.write_bytes(&[42u8]).expect("write error!");
let mut byte = [0u8; 1];
rx.read_bytes(&mut byte);
§Inverting RX and TX Pins
let (rx, _) = peripherals.GPIO2.split();
let (_, tx) = peripherals.GPIO1.split();
let mut uart1 = Uart::new(
peripherals.UART1,
Config::default())
.unwrap()
.with_rx(rx.inverted())
.with_tx(tx.inverted());
§Constructing RX and TX Components
let tx = UartTx::new(
peripherals.UART0,
Config::default())
.unwrap()
.with_tx(peripherals.GPIO1);
let rx = UartRx::new(
peripherals.UART1,
Config::default())
.unwrap()
.with_rx(peripherals.GPIO2);
§Operation with interrupts that by UART/Serial
Notice, that in practice a proper serial terminal should be used to connect to the board (espmonitor and espflash won’t work)
let delay = Delay::new();
// Default pins for UART/Serial communication
let (tx_pin, rx_pin) = (peripherals.GPIO1, peripherals.GPIO3);
let config = Config::default().with_rx_fifo_full_threshold(30);
let mut uart0 = Uart::new(
peripherals.UART0,
config)
.unwrap()
.with_rx(rx_pin)
.with_tx(tx_pin);
uart0.set_interrupt_handler(interrupt_handler);
critical_section::with(|cs| {
uart0.set_at_cmd(AtCmdConfig::default().with_cmd_char(b'#'));
uart0.listen(UartInterrupt::AtCmd | UartInterrupt::RxFifoFull);
SERIAL.borrow_ref_mut(cs).replace(uart0);
});
loop {
critical_section::with(|cs| {
let mut serial = SERIAL.borrow_ref_mut(cs);
let serial = serial.as_mut().unwrap();
writeln!(serial,
"Hello World! Send a single `#` character or send
at least 30 characters to trigger interrupts.")
.ok();
});
delay.delay(1.secs());
}
static SERIAL: Mutex<RefCell<Option<Uart<esp_hal::Blocking>>>> =
Mutex::new(RefCell::new(None));
#[handler]
fn interrupt_handler() {
critical_section::with(|cs| {
let mut serial = SERIAL.borrow_ref_mut(cs);
let serial = serial.as_mut().unwrap();
let mut buf = [0u8; 64];
if let Ok(cnt) = serial.read_buffered_bytes(&mut buf) {
writeln!(serial, "Read {} bytes", cnt).ok();
}
let pending_interrupts = serial.interrupts();
writeln!(
serial,
"Interrupt AT-CMD: {} RX-FIFO-FULL: {}",
pending_interrupts.contains(UartInterrupt::AtCmd),
pending_interrupts.contains(UartInterrupt::RxFifoFull),
).ok();
serial.clear_interrupts(
UartInterrupt::AtCmd | UartInterrupt::RxFifoFull
);
});
}
Structs§
- Any UART peripheral.
- AtCmd
Config unstable
Configuration for the AT-CMD detection functionality - UART Configuration
- UART (Full-duplex)
- UART (Receive)
- UART (Transmit)
Enums§
- UART clock source
- A configuration error.
- Number of data bits
- UART Error
- Parity check
- Number of stop bits
- Uart
Interrupt unstable
List of exposed UART events.