Skip to content
This repository was archived by the owner on May 23, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"editor.formatOnSave": true,
"rust-analyzer.cargo.features": [
"esp32c3",
"jtag_serial"
],
"rust-analyzer.cargo.target": "riscv32imc-unknown-none-elf",
}
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ critical-section = { version = "1.1.1", optional = true }
[features]
default = ["uart", "critical-section"]

crlf = []

# You must enable exactly 1 of the below features to support the correct chip:
esp32 = []
esp32c2 = []
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
# esp-println

Provides `print!` and `println!` implementations various Espressif devices.
Provides `print!` and `println!` implementations for various Espressif devices.

- Supports ESP32, ESP32-C2/C3/C6, ESP32-H2, ESP32-S2/S3, and ESP8266
- Dependency free (not even depending on `esp-hal`, one optional dependency is `log`, another is `critical-section`)
- Supports JTAG-Serial output where available
- Supports RTT (lacking working RTT hosts besides _probe-rs_ for ESP32-C3)
- `no-op` features turns printing into a no-op

## RTT on ESP32-C3

Expand Down
40 changes: 38 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,52 @@ pub mod logger;
#[cfg(feature = "rtt")]
mod rtt;

#[cfg(all(not(feature = "no-op"), not(feature = "crlf")))]
#[macro_export]
macro_rules! println {
($($arg:tt)*) => {{
#[cfg(not(feature = "no-op"))]
{
use core::fmt::Write;
writeln!($crate::Printer, $($arg)*).ok();
}
}};
}

#[cfg(all(not(feature = "no-op"), feature = "crlf"))]
#[macro_export]
macro_rules! println {
($($arg:tt)*) => {{
{
use core::fmt::Write;
write!($crate::Printer, $($arg)*).ok();
write!($crate::Printer, "\r\n").ok();
}
}};
}

#[cfg(not(feature = "no-op"))]
#[macro_export]
macro_rules! print {
($($arg:tt)*) => {{
#[cfg(not(feature = "no-op"))]
{
use core::fmt::Write;
write!($crate::Printer, $($arg)*).ok();
}
}};
}

#[cfg(feature = "no-op")]
#[macro_export]
macro_rules! println {
($($arg:tt)*) => {{}};
}

#[cfg(feature = "no-op")]
#[macro_export]
macro_rules! print {
($($arg:tt)*) => {{}};
}

pub struct Printer;

impl core::fmt::Write for Printer {
Expand Down Expand Up @@ -76,9 +100,16 @@ mod serial_jtag_printer {
impl super::Printer {
pub fn write_bytes(&mut self, bytes: &[u8]) {
super::with(|| {
const TIMEOUT_ITERATIONS: usize = 5_000;

let fifo = SERIAL_JTAG_FIFO_REG as *mut u32;
let conf = SERIAL_JTAG_CONF_REG as *mut u32;

if unsafe { conf.read_volatile() } & 0b011 == 0b000 {
// still wasn't able to drain the FIFO - early return
return;
}

// todo 64 byte chunks max
for chunk in bytes.chunks(32) {
unsafe {
Expand All @@ -87,8 +118,13 @@ mod serial_jtag_printer {
}
conf.write_volatile(0b001);

let mut timeout = TIMEOUT_ITERATIONS;
while conf.read_volatile() & 0b011 == 0b000 {
// wait
timeout -= 1;
if timeout == 0 {
return;
}
}
}
}
Expand Down