Add feature to display console logs from the wifi firmware.
This commit is contained in:
parent
42cc0c6d73
commit
076ada4c02
@ -7,6 +7,9 @@ edition = "2021"
|
|||||||
defmt = ["dep:defmt"]
|
defmt = ["dep:defmt"]
|
||||||
log = ["dep:log"]
|
log = ["dep:log"]
|
||||||
|
|
||||||
|
# Fetch console logs from the WiFi firmware and forward them to `log` or `defmt`.
|
||||||
|
firmware-logs = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
embassy-time = { version = "0.1.0" }
|
embassy-time = { version = "0.1.0" }
|
||||||
embassy-sync = { version = "0.1.0" }
|
embassy-sync = { version = "0.1.0" }
|
||||||
|
@ -5,7 +5,7 @@ edition = "2021"
|
|||||||
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
cyw43 = { path = "../../", features = ["defmt"]}
|
cyw43 = { path = "../../", features = ["defmt", "firmware-logs"]}
|
||||||
embassy-executor = { version = "0.1.0", features = ["defmt", "integrated-timers"] }
|
embassy-executor = { version = "0.1.0", features = ["defmt", "integrated-timers"] }
|
||||||
embassy-time = { version = "0.1.0", features = ["defmt", "defmt-timestamp-uptime"] }
|
embassy-time = { version = "0.1.0", features = ["defmt", "defmt-timestamp-uptime"] }
|
||||||
embassy-rp = { version = "0.1.0", features = ["defmt", "unstable-traits", "nightly", "unstable-pac", "time-driver"] }
|
embassy-rp = { version = "0.1.0", features = ["defmt", "unstable-traits", "nightly", "unstable-pac", "time-driver"] }
|
||||||
|
81
src/lib.rs
81
src/lib.rs
@ -575,6 +575,17 @@ pub struct Runner<'a, PWR, SPI> {
|
|||||||
backplane_window: u32,
|
backplane_window: u32,
|
||||||
|
|
||||||
sdpcm_seq_max: u8,
|
sdpcm_seq_max: u8,
|
||||||
|
|
||||||
|
#[cfg(feature = "firmware-logs")]
|
||||||
|
log: LogState,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "firmware-logs")]
|
||||||
|
struct LogState {
|
||||||
|
addr: u32,
|
||||||
|
last_idx: usize,
|
||||||
|
buf: [u8; 256],
|
||||||
|
buf_count: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn new<'a, PWR, SPI>(
|
pub async fn new<'a, PWR, SPI>(
|
||||||
@ -598,6 +609,14 @@ where
|
|||||||
backplane_window: 0xAAAA_AAAA,
|
backplane_window: 0xAAAA_AAAA,
|
||||||
|
|
||||||
sdpcm_seq_max: 1,
|
sdpcm_seq_max: 1,
|
||||||
|
|
||||||
|
#[cfg(feature = "firmware-logs")]
|
||||||
|
log: LogState {
|
||||||
|
addr: 0,
|
||||||
|
last_idx: 0,
|
||||||
|
buf: [0; 256],
|
||||||
|
buf_count: 0,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
runner.init(firmware).await;
|
runner.init(firmware).await;
|
||||||
@ -715,12 +734,74 @@ where
|
|||||||
//while self.read8(FUNC_BACKPLANE, REG_BACKPLANE_CHIP_CLOCK_CSR).await & 0x80 == 0 {}
|
//while self.read8(FUNC_BACKPLANE, REG_BACKPLANE_CHIP_CLOCK_CSR).await & 0x80 == 0 {}
|
||||||
//info!("clock ok");
|
//info!("clock ok");
|
||||||
|
|
||||||
|
#[cfg(feature = "firmware-logs")]
|
||||||
|
self.log_init().await;
|
||||||
|
|
||||||
info!("init done ");
|
info!("init done ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "firmware-logs")]
|
||||||
|
async fn log_init(&mut self) {
|
||||||
|
// Initialize shared memory for logging.
|
||||||
|
|
||||||
|
let shared_addr = self
|
||||||
|
.bp_read32(CHIP.atcm_ram_base_address + CHIP.chip_ram_size - 4 - CHIP.socram_srmem_size)
|
||||||
|
.await;
|
||||||
|
info!("shared_addr {:08x}", shared_addr);
|
||||||
|
|
||||||
|
let mut shared = [0; SharedMemData::SIZE];
|
||||||
|
self.bp_read(shared_addr, &mut shared).await;
|
||||||
|
let shared = SharedMemData::from_bytes(&shared);
|
||||||
|
info!("shared: {:08x}", shared);
|
||||||
|
|
||||||
|
self.log.addr = shared.console_addr + 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "firmware-logs")]
|
||||||
|
async fn log_read(&mut self) {
|
||||||
|
// Read log struct
|
||||||
|
let mut log = [0; SharedMemLog::SIZE];
|
||||||
|
self.bp_read(self.log.addr, &mut log).await;
|
||||||
|
let log = SharedMemLog::from_bytes(&log);
|
||||||
|
|
||||||
|
let idx = log.idx as usize;
|
||||||
|
|
||||||
|
// If pointer hasn't moved, no need to do anything.
|
||||||
|
if idx == self.log.last_idx {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read entire buf for now. We could read only what we need, but then we
|
||||||
|
// run into annoying alignment issues in `bp_read`.
|
||||||
|
let mut buf = [0; 0x400];
|
||||||
|
self.bp_read(log.buf, &mut buf).await;
|
||||||
|
|
||||||
|
while self.log.last_idx != idx as usize {
|
||||||
|
let b = buf[self.log.last_idx];
|
||||||
|
if b == b'\r' || b == b'\n' {
|
||||||
|
if self.log.buf_count != 0 {
|
||||||
|
let s = unsafe { core::str::from_utf8_unchecked(&self.log.buf[..self.log.buf_count]) };
|
||||||
|
debug!("LOGS: {}", s);
|
||||||
|
self.log.buf_count = 0;
|
||||||
|
}
|
||||||
|
} else if self.log.buf_count < self.log.buf.len() {
|
||||||
|
self.log.buf[self.log.buf_count] = b;
|
||||||
|
self.log.buf_count += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.log.last_idx += 1;
|
||||||
|
if self.log.last_idx == 0x400 {
|
||||||
|
self.log.last_idx = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn run(mut self) -> ! {
|
pub async fn run(mut self) -> ! {
|
||||||
let mut buf = [0; 512];
|
let mut buf = [0; 512];
|
||||||
loop {
|
loop {
|
||||||
|
#[cfg(feature = "firmware-logs")]
|
||||||
|
self.log_read().await;
|
||||||
|
|
||||||
// Send stuff
|
// Send stuff
|
||||||
// TODO flow control not yet complete
|
// TODO flow control not yet complete
|
||||||
if !self.has_credit() {
|
if !self.has_credit() {
|
||||||
|
@ -18,6 +18,32 @@ macro_rules! impl_bytes {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct SharedMemData {
|
||||||
|
pub flags: u32,
|
||||||
|
pub trap_addr: u32,
|
||||||
|
pub assert_exp_addr: u32,
|
||||||
|
pub assert_file_addr: u32,
|
||||||
|
pub assert_line: u32,
|
||||||
|
pub console_addr: u32,
|
||||||
|
pub msgtrace_addr: u32,
|
||||||
|
pub fwid: u32,
|
||||||
|
}
|
||||||
|
impl_bytes!(SharedMemData);
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct SharedMemLog {
|
||||||
|
pub buf: u32,
|
||||||
|
pub buf_size: u32,
|
||||||
|
pub idx: u32,
|
||||||
|
pub out_idx: u32,
|
||||||
|
}
|
||||||
|
impl_bytes!(SharedMemLog);
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
Loading…
Reference in New Issue
Block a user