Fix: allow defmt-espflash + auto configuration @ esp-println (#1687)

* esp-println: Fix 'defmt-espflash,auto' feature combination

* formatted according to instructions

* restructure, compiles also on 'esp32'

* Added CI check for compiling with 'dfm-espflash' feature

---------

Co-authored-by: Asko Kauppi <akauppi@gmail.com>
This commit is contained in:
Demo for summer'23 2024-06-24 16:26:08 +03:00 committed by GitHub
parent 9691141fed
commit c864c8a982
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 86 additions and 50 deletions

View File

@ -208,6 +208,14 @@ jobs:
--target=${{ matrix.device.target }} \ --target=${{ matrix.device.target }} \
esp-println esp-println
# So #1678 doesn't reoccur ('defmt-espflash,auto')
- name: Build (with feature 'defmt-espflash')
run: |
cargo xtask build-package \
--features=${{ matrix.device.soc }},log,defmt-espflash \
--target=${{ matrix.device.target }} \
esp-println
extras: extras:
runs-on: ubuntu-latest runs-on: ubuntu-latest

View File

@ -10,8 +10,7 @@ fn main() {
assert_unique_used_features!("jtag-serial", "uart", "auto"); assert_unique_used_features!("jtag-serial", "uart", "auto");
// Ensure that, if the `jtag-serial` communication method feature is enabled, // Ensure that, if the `jtag-serial` communication method feature is enabled,
// either the `esp32c3`, `esp32c6`, `esp32h2`, or `esp32s3` chip feature is // a compatible chip feature is also enabled.
// enabled.
if cfg!(feature = "jtag-serial") if cfg!(feature = "jtag-serial")
&& !(cfg!(feature = "esp32c3") && !(cfg!(feature = "esp32c3")
|| cfg!(feature = "esp32c6") || cfg!(feature = "esp32c6")

View File

@ -4,7 +4,7 @@
#[cfg(feature = "critical-section")] #[cfg(feature = "critical-section")]
use critical_section::RestoreState; use critical_section::RestoreState;
use super::Printer; use super::PrinterImpl;
/// Global logger lock. /// Global logger lock.
#[cfg(feature = "critical-section")] #[cfg(feature = "critical-section")]
@ -52,7 +52,7 @@ unsafe impl defmt::Logger for Logger {
// section. // section.
ENCODER.end_frame(do_write); ENCODER.end_frame(do_write);
Printer.flush(); Self::flush();
#[cfg(feature = "critical-section")] #[cfg(feature = "critical-section")]
{ {
@ -74,7 +74,7 @@ unsafe impl defmt::Logger for Logger {
} }
unsafe fn flush() { unsafe fn flush() {
Printer.flush(); PrinterImpl::flush();
} }
unsafe fn write(bytes: &[u8]) { unsafe fn write(bytes: &[u8]) {
@ -85,5 +85,5 @@ unsafe impl defmt::Logger for Logger {
} }
fn do_write(bytes: &[u8]) { fn do_write(bytes: &[u8]) {
Printer.write_bytes_assume_cs(bytes) PrinterImpl::write_bytes_assume_cs(bytes)
} }

View File

@ -68,18 +68,6 @@ macro_rules! dbg {
}; };
} }
#[cfg(any(feature = "jtag-serial", feature = "auto"))]
pub struct PrinterSerialJtag;
#[cfg(any(feature = "uart", feature = "auto"))]
pub struct PrinterUart;
#[cfg(feature = "jtag-serial")]
pub type PrinterImpl = PrinterSerialJtag;
#[cfg(feature = "uart")]
pub type PrinterImpl = PrinterUart;
pub struct Printer; pub struct Printer;
impl core::fmt::Write for Printer { impl core::fmt::Write for Printer {
@ -90,69 +78,105 @@ impl core::fmt::Write for Printer {
} }
impl Printer { impl Printer {
#[cfg(not(feature = "auto"))] fn write_bytes(bytes: &[u8]) {
pub fn write_bytes(bytes: &[u8]) {
with(|| { with(|| {
PrinterImpl::write_bytes_assume_cs(bytes); PrinterImpl::write_bytes_assume_cs(bytes);
PrinterImpl::flush(); PrinterImpl::flush();
}) })
} }
}
#[cfg(feature = "jtag-serial")]
type PrinterImpl = serial_jtag_printer::Printer;
#[cfg(feature = "uart")]
type PrinterImpl = uart_printer::Printer;
#[cfg(feature = "auto")] #[cfg(feature = "auto")]
pub fn write_bytes(bytes: &[u8]) { type PrinterImpl = auto_printer::Printer;
#[cfg(any(
#[cfg(all(
feature = "auto",
any(
feature = "esp32c3", feature = "esp32c3",
feature = "esp32c6", feature = "esp32c6",
feature = "esp32h2", feature = "esp32h2",
feature = "esp32p4", // as mentioned in 'build.rs'
feature = "esp32s3" feature = "esp32s3"
)
))] ))]
{ mod auto_printer {
use super::with;
use crate::{
serial_jtag_printer::Printer as PrinterSerialJtag,
uart_printer::Printer as PrinterUart,
};
pub struct Printer;
impl Printer {
fn use_jtag() -> bool {
// Decide if serial-jtag is used by checking SOF interrupt flag. // Decide if serial-jtag is used by checking SOF interrupt flag.
// SOF packet is sent by the HOST every 1ms on a full speed bus. // SOF packet is sent by the HOST every 1ms on a full speed bus.
// Between two consecutive ticks, there will be at least 1ms (selectable tick // Between two consecutive ticks, there will be at least 1ms (selectable tick
// rate range is 1 - 1000Hz). // rate range is 1 - 1000Hz).
// We don't reset the flag - if it was ever connected we assume serial-jtag is // We don't reset the flag - if it was ever connected we assume serial-jtag is
// used // used
#[cfg(feature = "esp32c3")] #[cfg(feature = "esp32c3")]
const USB_DEVICE_INT_RAW: *const u32 = 0x60043008 as *const u32; const USB_DEVICE_INT_RAW: *const u32 = 0x60043008 as *const u32;
#[cfg(feature = "esp32c6")] #[cfg(feature = "esp32c6")]
const USB_DEVICE_INT_RAW: *const u32 = 0x6000f008 as *const u32; const USB_DEVICE_INT_RAW: *const u32 = 0x6000f008 as *const u32;
#[cfg(feature = "esp32h2")] #[cfg(feature = "esp32h2")]
const USB_DEVICE_INT_RAW: *const u32 = 0x6000f008 as *const u32; const USB_DEVICE_INT_RAW: *const u32 = 0x6000f008 as *const u32;
#[cfg(feature = "esp32p4")]
const USB_DEVICE_INT_RAW: *const u32 = unimplemented!();
#[cfg(feature = "esp32s3")] #[cfg(feature = "esp32s3")]
const USB_DEVICE_INT_RAW: *const u32 = 0x60038000 as *const u32; const USB_DEVICE_INT_RAW: *const u32 = 0x60038000 as *const u32;
const SOF_INT_MASK: u32 = 0b10; const SOF_INT_MASK: u32 = 0b10;
let is_serial_jtag = unsafe { (USB_DEVICE_INT_RAW.read_volatile() & SOF_INT_MASK) != 0 }
unsafe { (USB_DEVICE_INT_RAW.read_volatile() & SOF_INT_MASK) != 0 }; }
if is_serial_jtag { pub fn write_bytes_assume_cs(bytes: &[u8]) {
if Self::use_jtag() {
with(|| { with(|| {
PrinterSerialJtag::write_bytes_assume_cs(bytes); PrinterSerialJtag::write_bytes_assume_cs(bytes);
PrinterSerialJtag::flush();
}) })
} else { } else {
with(|| { with(|| {
PrinterUart::write_bytes_assume_cs(bytes); PrinterUart::write_bytes_assume_cs(bytes);
PrinterUart::flush();
}) })
} }
} }
#[cfg(not(any( pub fn flush() {
feature = "esp32c3", if Self::use_jtag() {
feature = "esp32c6", with(|| {
feature = "esp32h2", PrinterSerialJtag::flush();
feature = "esp32s3" })
)))] } else {
with(|| { with(|| {
PrinterUart::write_bytes_assume_cs(bytes);
PrinterUart::flush(); PrinterUart::flush();
}) })
} }
} }
}
}
#[cfg(all(
feature = "auto",
not(any(
feature = "esp32c3",
feature = "esp32c6",
feature = "esp32h2",
feature = "esp32p4",
feature = "esp32s3"
))
))]
mod auto_printer {
// models that only have UART
pub type Printer = crate::uart_printer::Printer;
}
#[cfg(all( #[cfg(all(
any(feature = "jtag-serial", feature = "auto"), any(feature = "jtag-serial", feature = "auto"),
@ -166,6 +190,7 @@ impl Printer {
))] ))]
mod serial_jtag_printer { mod serial_jtag_printer {
use portable_atomic::{AtomicBool, Ordering}; use portable_atomic::{AtomicBool, Ordering};
pub struct Printer;
#[cfg(feature = "esp32c3")] #[cfg(feature = "esp32c3")]
const SERIAL_JTAG_FIFO_REG: usize = 0x6004_3000; const SERIAL_JTAG_FIFO_REG: usize = 0x6004_3000;
@ -222,7 +247,7 @@ mod serial_jtag_printer {
true true
} }
impl super::PrinterSerialJtag { impl Printer {
pub fn write_bytes_assume_cs(bytes: &[u8]) { pub fn write_bytes_assume_cs(bytes: &[u8]) {
if fifo_full() { if fifo_full() {
// The FIFO is full. Let's see if we can progress. // The FIFO is full. Let's see if we can progress.
@ -265,7 +290,9 @@ mod serial_jtag_printer {
#[cfg(all(any(feature = "uart", feature = "auto"), feature = "esp32"))] #[cfg(all(any(feature = "uart", feature = "auto"), feature = "esp32"))]
mod uart_printer { mod uart_printer {
const UART_TX_ONE_CHAR: usize = 0x4000_9200; const UART_TX_ONE_CHAR: usize = 0x4000_9200;
impl super::PrinterUart {
pub struct Printer;
impl Printer {
pub fn write_bytes_assume_cs(bytes: &[u8]) { pub fn write_bytes_assume_cs(bytes: &[u8]) {
for &b in bytes { for &b in bytes {
unsafe { unsafe {
@ -282,7 +309,8 @@ mod uart_printer {
#[cfg(all(any(feature = "uart", feature = "auto"), feature = "esp32s2"))] #[cfg(all(any(feature = "uart", feature = "auto"), feature = "esp32s2"))]
mod uart_printer { mod uart_printer {
impl super::PrinterUart { pub struct Printer;
impl Printer {
pub fn write_bytes_assume_cs(bytes: &[u8]) { pub fn write_bytes_assume_cs(bytes: &[u8]) {
// On ESP32-S2 the UART_TX_ONE_CHAR ROM-function seems to have some issues. // On ESP32-S2 the UART_TX_ONE_CHAR ROM-function seems to have some issues.
for chunk in bytes.chunks(64) { for chunk in bytes.chunks(64) {
@ -421,7 +449,8 @@ mod uart_printer {
} }
} }
impl super::PrinterUart { pub struct Printer;
impl Printer {
pub fn write_bytes_assume_cs(bytes: &[u8]) { pub fn write_bytes_assume_cs(bytes: &[u8]) {
for chunk in bytes.chunks(Device::CHUNK_SIZE) { for chunk in bytes.chunks(Device::CHUNK_SIZE) {
for &b in chunk { for &b in chunk {