diff options
| author | Dario Nieuwenhuis <[email protected]> | 2022-12-25 22:50:27 +0100 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2022-12-25 22:50:59 +0100 |
| commit | 076ada4c0233d2f89c89cda4c01910a86add90ac (patch) | |
| tree | 0f1aaed0e8291c889359b68831ed5469e0cba127 /src | |
| parent | 42cc0c6d736f6d296ef2a6a636ddf8733cdcd7c6 (diff) | |
Add feature to display console logs from the wifi firmware.
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib.rs | 81 | ||||
| -rw-r--r-- | src/structs.rs | 26 |
2 files changed, 107 insertions, 0 deletions
diff --git a/src/lib.rs b/src/lib.rs index 430821752..883e669de 100644 --- a/src/lib.rs +++ b/src/lib.rs | |||
| @@ -575,6 +575,17 @@ pub struct Runner<'a, PWR, SPI> { | |||
| 575 | backplane_window: u32, | 575 | backplane_window: u32, |
| 576 | 576 | ||
| 577 | sdpcm_seq_max: u8, | 577 | sdpcm_seq_max: u8, |
| 578 | |||
| 579 | #[cfg(feature = "firmware-logs")] | ||
| 580 | log: LogState, | ||
| 581 | } | ||
| 582 | |||
| 583 | #[cfg(feature = "firmware-logs")] | ||
| 584 | struct LogState { | ||
| 585 | addr: u32, | ||
| 586 | last_idx: usize, | ||
| 587 | buf: [u8; 256], | ||
| 588 | buf_count: usize, | ||
| 578 | } | 589 | } |
| 579 | 590 | ||
| 580 | pub async fn new<'a, PWR, SPI>( | 591 | pub async fn new<'a, PWR, SPI>( |
| @@ -598,6 +609,14 @@ where | |||
| 598 | backplane_window: 0xAAAA_AAAA, | 609 | backplane_window: 0xAAAA_AAAA, |
| 599 | 610 | ||
| 600 | sdpcm_seq_max: 1, | 611 | sdpcm_seq_max: 1, |
| 612 | |||
| 613 | #[cfg(feature = "firmware-logs")] | ||
| 614 | log: LogState { | ||
| 615 | addr: 0, | ||
| 616 | last_idx: 0, | ||
| 617 | buf: [0; 256], | ||
| 618 | buf_count: 0, | ||
| 619 | }, | ||
| 601 | }; | 620 | }; |
| 602 | 621 | ||
| 603 | runner.init(firmware).await; | 622 | runner.init(firmware).await; |
| @@ -715,12 +734,74 @@ where | |||
| 715 | //while self.read8(FUNC_BACKPLANE, REG_BACKPLANE_CHIP_CLOCK_CSR).await & 0x80 == 0 {} | 734 | //while self.read8(FUNC_BACKPLANE, REG_BACKPLANE_CHIP_CLOCK_CSR).await & 0x80 == 0 {} |
| 716 | //info!("clock ok"); | 735 | //info!("clock ok"); |
| 717 | 736 | ||
| 737 | #[cfg(feature = "firmware-logs")] | ||
| 738 | self.log_init().await; | ||
| 739 | |||
| 718 | info!("init done "); | 740 | info!("init done "); |
| 719 | } | 741 | } |
| 720 | 742 | ||
| 743 | #[cfg(feature = "firmware-logs")] | ||
| 744 | async fn log_init(&mut self) { | ||
| 745 | // Initialize shared memory for logging. | ||
| 746 | |||
| 747 | let shared_addr = self | ||
| 748 | .bp_read32(CHIP.atcm_ram_base_address + CHIP.chip_ram_size - 4 - CHIP.socram_srmem_size) | ||
| 749 | .await; | ||
| 750 | info!("shared_addr {:08x}", shared_addr); | ||
| 751 | |||
| 752 | let mut shared = [0; SharedMemData::SIZE]; | ||
| 753 | self.bp_read(shared_addr, &mut shared).await; | ||
| 754 | let shared = SharedMemData::from_bytes(&shared); | ||
| 755 | info!("shared: {:08x}", shared); | ||
| 756 | |||
| 757 | self.log.addr = shared.console_addr + 8; | ||
| 758 | } | ||
| 759 | |||
| 760 | #[cfg(feature = "firmware-logs")] | ||
| 761 | async fn log_read(&mut self) { | ||
| 762 | // Read log struct | ||
| 763 | let mut log = [0; SharedMemLog::SIZE]; | ||
| 764 | self.bp_read(self.log.addr, &mut log).await; | ||
| 765 | let log = SharedMemLog::from_bytes(&log); | ||
| 766 | |||
| 767 | let idx = log.idx as usize; | ||
| 768 | |||
| 769 | // If pointer hasn't moved, no need to do anything. | ||
| 770 | if idx == self.log.last_idx { | ||
| 771 | return; | ||
| 772 | } | ||
| 773 | |||
| 774 | // Read entire buf for now. We could read only what we need, but then we | ||
| 775 | // run into annoying alignment issues in `bp_read`. | ||
| 776 | let mut buf = [0; 0x400]; | ||
| 777 | self.bp_read(log.buf, &mut buf).await; | ||
| 778 | |||
| 779 | while self.log.last_idx != idx as usize { | ||
| 780 | let b = buf[self.log.last_idx]; | ||
| 781 | if b == b'\r' || b == b'\n' { | ||
| 782 | if self.log.buf_count != 0 { | ||
| 783 | let s = unsafe { core::str::from_utf8_unchecked(&self.log.buf[..self.log.buf_count]) }; | ||
| 784 | debug!("LOGS: {}", s); | ||
| 785 | self.log.buf_count = 0; | ||
| 786 | } | ||
| 787 | } else if self.log.buf_count < self.log.buf.len() { | ||
| 788 | self.log.buf[self.log.buf_count] = b; | ||
| 789 | self.log.buf_count += 1; | ||
| 790 | } | ||
| 791 | |||
| 792 | self.log.last_idx += 1; | ||
| 793 | if self.log.last_idx == 0x400 { | ||
| 794 | self.log.last_idx = 0; | ||
| 795 | } | ||
| 796 | } | ||
| 797 | } | ||
| 798 | |||
| 721 | pub async fn run(mut self) -> ! { | 799 | pub async fn run(mut self) -> ! { |
| 722 | let mut buf = [0; 512]; | 800 | let mut buf = [0; 512]; |
| 723 | loop { | 801 | loop { |
| 802 | #[cfg(feature = "firmware-logs")] | ||
| 803 | self.log_read().await; | ||
| 804 | |||
| 724 | // Send stuff | 805 | // Send stuff |
| 725 | // TODO flow control not yet complete | 806 | // TODO flow control not yet complete |
| 726 | if !self.has_credit() { | 807 | if !self.has_credit() { |
diff --git a/src/structs.rs b/src/structs.rs index 6d4525a46..41a340661 100644 --- a/src/structs.rs +++ b/src/structs.rs | |||
| @@ -21,6 +21,32 @@ macro_rules! impl_bytes { | |||
| 21 | #[derive(Clone, Copy)] | 21 | #[derive(Clone, Copy)] |
| 22 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 22 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 23 | #[repr(C)] | 23 | #[repr(C)] |
| 24 | pub struct SharedMemData { | ||
| 25 | pub flags: u32, | ||
| 26 | pub trap_addr: u32, | ||
| 27 | pub assert_exp_addr: u32, | ||
| 28 | pub assert_file_addr: u32, | ||
| 29 | pub assert_line: u32, | ||
| 30 | pub console_addr: u32, | ||
| 31 | pub msgtrace_addr: u32, | ||
| 32 | pub fwid: u32, | ||
| 33 | } | ||
| 34 | impl_bytes!(SharedMemData); | ||
| 35 | |||
| 36 | #[derive(Clone, Copy)] | ||
| 37 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 38 | #[repr(C)] | ||
| 39 | pub struct SharedMemLog { | ||
| 40 | pub buf: u32, | ||
| 41 | pub buf_size: u32, | ||
| 42 | pub idx: u32, | ||
| 43 | pub out_idx: u32, | ||
| 44 | } | ||
| 45 | impl_bytes!(SharedMemLog); | ||
| 46 | |||
| 47 | #[derive(Clone, Copy)] | ||
| 48 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 49 | #[repr(C)] | ||
| 24 | pub struct SdpcmHeader { | 50 | pub struct SdpcmHeader { |
| 25 | pub len: u16, | 51 | pub len: u16, |
| 26 | pub len_inv: u16, | 52 | pub len_inv: u16, |
