From 9d9cabaab621e784e57c96562e22b5e36b623985 Mon Sep 17 00:00:00 2001 From: Alistair Francis Date: Sat, 21 Dec 2024 21:56:10 +1000 Subject: [PATCH] chips: apollo3: Disable UART when not in use The UART uses a relativly large amount of power just being enabled. So instead of enabling it at startup let's instead only enable UART when required and then disable it afterwards. As part of this we want to ensure that interupts are only handled for the TX/RX FIFO events. Signed-off-by: Alistair Francis --- chips/apollo3/src/uart.rs | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/chips/apollo3/src/uart.rs b/chips/apollo3/src/uart.rs index 08d411cfa4..9d53942c50 100644 --- a/chips/apollo3/src/uart.rs +++ b/chips/apollo3/src/uart.rs @@ -326,13 +326,20 @@ impl Uart<'_> { let regs = self.registers; let irq = regs.ies.extract(); - if irq.is_set(IES::TXIS) || irq.is_set(IES::TXCMPMIS) { + if irq.is_set(IES::TXCMPMIS) { // TXRIS Interrupt self.disable_tx_interrupt(); if self.tx_index.get() >= self.tx_len.get() { // We sent everything to the UART hardware, now from an // interrupt callback we can issue the callback. + + // Disable the UART + if self.rx_buffer.is_none() { + regs.cr.modify(CR::UARTEN::CLEAR); + } + regs.cr.modify(CR::TXE::CLEAR); + self.tx_client.map(|client| { self.tx_buffer.take().map(|tx_buf| { client.transmitted_buffer(tx_buf, self.tx_len.get(), Ok(())); @@ -344,12 +351,18 @@ impl Uart<'_> { } } - if irq.is_set(IES::RXIS) || irq.is_set(IES::RTIS) { + if irq.is_set(IES::RTIS) { self.disable_rx_interrupt(); self.rx_progress(); if self.rx_index.get() >= self.rx_len.get() { + // Disable the UART + if self.tx_buffer.is_none() { + regs.cr.modify(CR::UARTEN::CLEAR); + } + regs.cr.modify(CR::RXE::CLEAR); + self.rx_client.map(|client| { self.rx_buffer.take().map(|rx_buf| { client.received_buffer( @@ -394,10 +407,6 @@ impl hil::uart::Configure for Uart<'_> { // Set 8 data bits, no parity, 1 stop bit and no flow control regs.lcrh.modify(LCRH::WLEN.val(3) + LCRH::FEN::SET); - // Enable the UART - regs.cr - .modify(CR::UARTEN::SET + CR::RXE::SET + CR::TXE::SET); - // Disable interrupts regs.ier.set(0x00); regs.iec.set(0xFF); @@ -426,6 +435,9 @@ impl<'a> hil::uart::Transmit<'a> for Uart<'a> { self.tx_len.set(tx_len); self.tx_index.set(0); + // Enable the UART + self.registers.cr.modify(CR::UARTEN::SET + CR::TXE::SET); + self.tx_progress(); Ok(()) } @@ -458,6 +470,9 @@ impl<'a> hil::uart::Receive<'a> for Uart<'a> { self.rx_len.set(rx_len); self.rx_index.set(0); + // Enable the UART + self.registers.cr.modify(CR::UARTEN::SET + CR::RXE::SET); + self.rx_progress(); Ok(()) }