rp2350/
uart.rs

1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright OxidOS Automotive 2025.
4
5use core::cell::Cell;
6use kernel::deferred_call::{DeferredCall, DeferredCallClient};
7use kernel::hil;
8use kernel::hil::uart::ReceiveClient;
9use kernel::hil::uart::{
10    Configure, Parameters, Parity, Receive, StopBits, Transmit, TransmitClient, Width,
11};
12use kernel::utilities::cells::{OptionalCell, TakeCell};
13use kernel::utilities::registers::interfaces::{ReadWriteable, Readable, Writeable};
14use kernel::utilities::registers::{register_bitfields, register_structs, ReadWrite};
15use kernel::utilities::StaticRef;
16use kernel::ErrorCode;
17
18use crate::clocks;
19
20register_structs! {
21
22    UartRegisters {
23        /// Data Register, UARTDR
24        (0x000 => uartdr: ReadWrite<u32, UARTDR::Register>),
25        /// Receive Status Register/Error Clear Register, UARTRSR/UARTECR
26        (0x004 => uartrsr: ReadWrite<u32, UARTRSR::Register>),
27        (0x008 => _reserved0),
28        /// Flag Register, UARTFR
29        (0x018 => uartfr: ReadWrite<u32, UARTFR::Register>),
30        (0x01C => _reserved1),
31        /// IrDA Low-Power Counter Register, UARTILPR
32        (0x020 => uartilpr: ReadWrite<u32, UARTILPR::Register>),
33        /// Integer Baud Rate Register, UARTIBRD
34        (0x024 => uartibrd: ReadWrite<u32, UARTIBRD::Register>),
35        /// Fractional Baud Rate Register, UARTFBRD
36        (0x028 => uartfbrd: ReadWrite<u32, UARTFBRD::Register>),
37        /// Line Control Register, UARTLCR_H
38        (0x02C => uartlcr_h: ReadWrite<u32, UARTLCR_H::Register>),
39        /// Control Register, UARTCR
40        (0x030 => uartcr: ReadWrite<u32, UARTCR::Register>),
41        /// Interrupt FIFO Level Select Register, UARTIFLS
42        (0x034 => uartifls: ReadWrite<u32, UARTIFLS::Register>),
43        /// Interrupt Mask Set/Clear Register, UARTIMSC
44        (0x038 => uartimsc: ReadWrite<u32, UARTIMSC::Register>),
45        /// Raw Interrupt Status Register, UARTRIS
46        (0x03C => uartris: ReadWrite<u32, UARTRIS::Register>),
47        /// Masked Interrupt Status Register, UARTMIS
48        (0x040 => uartmis: ReadWrite<u32, UARTMIS::Register>),
49        /// Interrupt Clear Register, UARTICR
50        (0x044 => uarticr: ReadWrite<u32, UARTICR::Register>),
51        /// DMA Control Register, UARTDMACR
52        (0x048 => uartdmacr: ReadWrite<u32, UARTDMACR::Register>),
53        (0x04C => _reserved2),
54        /// UARTPeriphID0 Register
55        (0xFE0 => uartperiphid0: ReadWrite<u32, UARTPERIPHID0::Register>),
56        /// UARTPeriphID1 Register
57        (0xFE4 => uartperiphid1: ReadWrite<u32, UARTPERIPHID1::Register>),
58        /// UARTPeriphID2 Register
59        (0xFE8 => uartperiphid2: ReadWrite<u32, UARTPERIPHID2::Register>),
60        /// UARTPeriphID3 Register
61        (0xFEC => uartperiphid3: ReadWrite<u32, UARTPERIPHID3::Register>),
62        /// UARTPCellID0 Register
63        (0xFF0 => uartpcellid0: ReadWrite<u32, UARTPCELLID0::Register>),
64        /// UARTPCellID1 Register
65        (0xFF4 => uartpcellid1: ReadWrite<u32, UARTPCELLID1::Register>),
66        /// UARTPCellID2 Register
67        (0xFF8 => uartpcellid2: ReadWrite<u32, UARTPCELLID2::Register>),
68        /// UARTPCellID3 Register
69        (0xFFC => uartpcellid3: ReadWrite<u32, UARTPCELLID3::Register>),
70        (0x1000 => @END),
71    }
72}
73register_bitfields![u32,
74UARTDR [
75    /// Overrun error. This bit is set to 1 if data is received and the receive FIFO is already full. This is cleared to 0 once there is an empty space in the FIFO and a new character can be written to it.
76    OE OFFSET(11) NUMBITS(1) [],
77    /// Break error. This bit is set to 1 if a break condition was detected, indicating that the received data input was held LOW for longer than a full-word transmission time (defined as start, data, parity and stop bits). In FIFO mode, this error is associated with the character at the top of the FIFO. When a break occurs, only one 0 character is loaded into the FIFO. The next character is only enabled after the receive data input goes to a 1 (marking state), and the next valid start bit is received.
78    BE OFFSET(10) NUMBITS(1) [],
79    /// Parity error. When set to 1, it indicates that the parity of the received data character does not match the parity that the EPS and SPS bits in the Line Control Register, UARTLCR_H. In FIFO mode, this error is associated with the character at the top of the FIFO.
80    PE OFFSET(9) NUMBITS(1) [],
81    /// Framing error. When set to 1, it indicates that the received character did not have a valid stop bit (a valid stop bit is 1). In FIFO mode, this error is associated with the character at the top of the FIFO.
82    FE OFFSET(8) NUMBITS(1) [],
83    /// Receive (read) data character. Transmit (write) data character.
84    DATA OFFSET(0) NUMBITS(8) []
85],
86UARTRSR [
87    /// Overrun error. This bit is set to 1 if data is received and the FIFO is already full. This bit is cleared to 0 by a write to UARTECR. The FIFO contents remain valid because no more data is written when the FIFO is full, only the contents of the shift register are overwritten. The CPU must now read the data, to empty the FIFO.
88    OE OFFSET(3) NUMBITS(1) [],
89    /// Break error. This bit is set to 1 if a break condition was detected, indicating that the received data input was held LOW for longer than a full-word transmission time (defined as start, data, parity, and stop bits). This bit is cleared to 0 after a write to UARTECR. In FIFO mode, this error is associated with the character at the top of the FIFO. When a break occurs, only one 0 character is loaded into the FIFO. The next character is only enabled after the receive data input goes to a 1 (marking state) and the next valid start bit is received.
90    BE OFFSET(2) NUMBITS(1) [],
91    /// Parity error. When set to 1, it indicates that the parity of the received data character does not match the parity that the EPS and SPS bits in the Line Control Register, UARTLCR_H. This bit is cleared to 0 by a write to UARTECR. In FIFO mode, this error is associated with the character at the top of the FIFO.
92    PE OFFSET(1) NUMBITS(1) [],
93    /// Framing error. When set to 1, it indicates that the received character did not have a valid stop bit (a valid stop bit is 1). This bit is cleared to 0 by a write to UARTECR. In FIFO mode, this error is associated with the character at the top of the FIFO.
94    FE OFFSET(0) NUMBITS(1) []
95],
96UARTFR [
97    /// Ring indicator. This bit is the complement of the UART ring indicator, nUARTRI, modem status input. That is, the bit is 1 when nUARTRI is LOW.
98    RI OFFSET(8) NUMBITS(1) [],
99    /// Transmit FIFO empty. The meaning of this bit depends on the state of the FEN bit in the Line Control Register, UARTLCR_H. If the FIFO is disabled, this bit is set when the transmit holding register is empty. If the FIFO is enabled, the TXFE bit is set when the transmit FIFO is empty. This bit does not indicate if there is data in the transmit shift register.
100    TXFE OFFSET(7) NUMBITS(1) [],
101    /// Receive FIFO full. The meaning of this bit depends on the state of the FEN bit in the UARTLCR_H Register. If the FIFO is disabled, this bit is set when the receive holding register is full. If the FIFO is enabled, the RXFF bit is set when the receive FIFO is full.
102    RXFF OFFSET(6) NUMBITS(1) [],
103    /// Transmit FIFO full. The meaning of this bit depends on the state of the FEN bit in the UARTLCR_H Register. If the FIFO is disabled, this bit is set when the transmit holding register is full. If the FIFO is enabled, the TXFF bit is set when the transmit FIFO is full.
104    TXFF OFFSET(5) NUMBITS(1) [],
105    /// Receive FIFO empty. The meaning of this bit depends on the state of the FEN bit in the UARTLCR_H Register. If the FIFO is disabled, this bit is set when the receive holding register is empty. If the FIFO is enabled, the RXFE bit is set when the receive FIFO is empty.
106    RXFE OFFSET(4) NUMBITS(1) [],
107    /// UART busy. If this bit is set to 1, the UART is busy transmitting data. This bit remains set until the complete byte, including all the stop bits, has been sent from the shift register. This bit is set as soon as the transmit FIFO becomes non-empty, regardless of whether the UART is enabled or not.
108    BUSY OFFSET(3) NUMBITS(1) [],
109    /// Data carrier detect. This bit is the complement of the UART data carrier detect, nUARTDCD, modem status input. That is, the bit is 1 when nUARTDCD is LOW.
110    DCD OFFSET(2) NUMBITS(1) [],
111    /// Data set ready. This bit is the complement of the UART data set ready, nUARTDSR, modem status input. That is, the bit is 1 when nUARTDSR is LOW.
112    DSR OFFSET(1) NUMBITS(1) [],
113    /// Clear to send. This bit is the complement of the UART clear to send, nUARTCTS, modem status input. That is, the bit is 1 when nUARTCTS is LOW.
114    CTS OFFSET(0) NUMBITS(1) []
115],
116UARTILPR [
117    /// 8-bit low-power divisor value. These bits are cleared to 0 at reset.
118    ILPDVSR OFFSET(0) NUMBITS(8) []
119],
120UARTIBRD [
121    /// The integer baud rate divisor. These bits are cleared to 0 on reset.
122    BAUD_DIVINT OFFSET(0) NUMBITS(16) []
123],
124UARTFBRD [
125    /// The fractional baud rate divisor. These bits are cleared to 0 on reset.
126    BAUD_DIVFRAC OFFSET(0) NUMBITS(6) []
127],
128UARTLCR_H [
129    /// Stick parity select. 0 = stick parity is disabled 1 = either: * if the EPS bit is 0 then the parity bit is transmitted and checked as a 1 * if the EPS bit is 1 then the parity bit is transmitted and checked as a 0. This bit has no effect when the PEN bit disables parity checking and generation.
130    SPS OFFSET(7) NUMBITS(1) [],
131    /// Word length. These bits indicate the number of data bits transmitted or received in a frame as follows: b11 = 8 bits b10 = 7 bits b01 = 6 bits b00 = 5 bits.
132    WLEN OFFSET(5) NUMBITS(2) [
133        BITS_5 = 0b00,
134        BITS_6 = 0b01,
135        BITS_7 = 0b10,
136        BITS_8 = 0b11,
137    ],
138    /// Enable FIFOs: 0 = FIFOs are disabled (character mode) that is, the FIFOs become 1-byte-deep holding registers 1 = transmit and receive FIFO buffers are enabled (FIFO mode).
139    FEN OFFSET(4) NUMBITS(1) [],
140    /// Two stop bits select. If this bit is set to 1, two stop bits are transmitted at the end of the frame. The receive logic does not check for two stop bits being received.
141    STP2 OFFSET(3) NUMBITS(1) [],
142    /// Even parity select. Controls the type of parity the UART uses during transmission and reception: 0 = odd parity. The UART generates or checks for an odd number of 1s in the data and parity bits. 1 = even parity. The UART generates or checks for an even number of 1s in the data and parity bits. This bit has no effect when the PEN bit disables parity checking and generation.
143    EPS OFFSET(2) NUMBITS(1) [],
144    /// Parity enable: 0 = parity is disabled and no parity bit added to the data frame 1 = parity checking and generation is enabled.
145    PEN OFFSET(1) NUMBITS(1) [],
146    /// Send break. If this bit is set to 1, a low-level is continually output on the UARTTXD output, after completing transmission of the current character. For the proper execution of the break command, the software must set this bit for at least two complete frames. For normal use, this bit must be cleared to 0.
147    BRK OFFSET(0) NUMBITS(1) []
148],
149UARTCR [
150    /// CTS hardware flow control enable. If this bit is set to 1, CTS hardware flow control is enabled. Data is only transmitted when the nUARTCTS signal is asserted.
151    CTSEN OFFSET(15) NUMBITS(1) [],
152    /// RTS hardware flow control enable. If this bit is set to 1, RTS hardware flow control is enabled. Data is only requested when there is space in the receive FIFO for it to be received.
153    RTSEN OFFSET(14) NUMBITS(1) [],
154    /// This bit is the complement of the UART Out2 (nUARTOut2) modem status output. That is, when the bit is programmed to a 1, the output is 0. For DTE this can be used as Ring Indicator (RI).
155    OUT2 OFFSET(13) NUMBITS(1) [],
156    /// This bit is the complement of the UART Out1 (nUARTOut1) modem status output. That is, when the bit is programmed to a 1 the output is 0. For DTE this can be used as Data Carrier Detect (DCD).
157    OUT1 OFFSET(12) NUMBITS(1) [],
158    /// Request to send. This bit is the complement of the UART request to send, nUARTRTS, modem status output. That is, when the bit is programmed to a 1 then nUARTRTS is LOW.
159    RTS OFFSET(11) NUMBITS(1) [],
160    /// Data transmit ready. This bit is the complement of the UART data transmit ready, nUARTDTR, modem status output. That is, when the bit is programmed to a 1 then nUARTDTR is LOW.
161    DTR OFFSET(10) NUMBITS(1) [],
162    /// Receive enable. If this bit is set to 1, the receive section of the UART is enabled. Data reception occurs for either UART signals or SIR signals depending on the setting of the SIREN bit. When the UART is disabled in the middle of reception, it completes the current character before stopping.
163    RXE OFFSET(9) NUMBITS(1) [],
164    /// Transmit enable. If this bit is set to 1, the transmit section of the UART is enabled. Data transmission occurs for either UART signals, or SIR signals depending on the setting of the SIREN bit. When the UART is disabled in the middle of transmission, it completes the current character before stopping.
165    TXE OFFSET(8) NUMBITS(1) [],
166    /// Loopback enable. If this bit is set to 1 and the SIREN bit is set to 1 and the SIRTEST bit in the Test Control Register, UARTTCR is set to 1, then the nSIROUT path is inverted, and fed through to the SIRIN path. The SIRTEST bit in the test register must be set to 1 to override the normal half-duplex SIR operation. This must be the requirement for accessing the test registers during normal operation, and SIRTEST must be cleared to 0 when loopback testing is finished. This feature reduces the amount of external coupling required during system test. If this bit is set to 1, and the SIRTEST bit is set to 0, the UARTTXD path is fed through to the UARTRXD path. In either SIR mode or UART mode, when this bit is set, the modem outputs are also fed through to the modem inputs. This bit is cleared to 0 on reset, to disable loopback.
167    LBE OFFSET(7) NUMBITS(1) [],
168    /// SIR low-power IrDA mode. This bit selects the IrDA encoding mode. If this bit is cleared to 0, low-level bits are transmitted as an active high pulse with a width of 3 / 16th of the bit period. If this bit is set to 1, low-level bits are transmitted with a pulse width that is 3 times the period of the IrLPBaud16 input signal, regardless of the selected bit rate. Setting this bit uses less power, but might reduce transmission distances.
169    SIRLP OFFSET(2) NUMBITS(1) [],
170    /// SIR enable: 0 = IrDA SIR ENDEC is disabled. nSIROUT remains LOW (no light pulse generated), and signal transitions on SIRIN have no effect. 1 = IrDA SIR ENDEC is enabled. Data is transmitted and received on nSIROUT and SIRIN. UARTTXD remains HIGH, in the marking state. Signal transitions on UARTRXD or modem status inputs have no effect. This bit has no effect if the UARTEN bit disables the UART.
171    SIREN OFFSET(1) NUMBITS(1) [],
172    /// UART enable: 0 = UART is disabled. If the UART is disabled in the middle of transmission or reception, it completes the current character before stopping. 1 = the UART is enabled. Data transmission and reception occurs for either UART signals or SIR signals depending on the setting of the SIREN bit.
173    UARTEN OFFSET(0) NUMBITS(1) []
174],
175UARTIFLS [
176    /// Receive interrupt FIFO level select. The trigger points for the receive interrupt are as follows: b000 = Receive FIFO becomes >= 1 / 8 full b001 = Receive FIFO becomes >= 1 / 4 full b010 = Receive FIFO becomes >= 1 / 2 full b011 = Receive FIFO becomes >= 3 / 4 full b100 = Receive FIFO becomes >= 7 / 8 full b101-b111 = reserved.
177    RXIFLSEL OFFSET(3) NUMBITS(3) [
178        FIFO_1_8 = 0b000,
179        FIFO_1_4 = 0b001,
180        FIFO_1_2 = 0b010,
181        FIFO_3_4 = 0b011,
182        FIFO_7_8 = 0b100,
183    ],
184    /// Transmit interrupt FIFO level select. The trigger points for the transmit interrupt are as follows: b000 = Transmit FIFO becomes <= 1 / 8 full b001 = Transmit FIFO becomes <= 1 / 4 full b010 = Transmit FIFO becomes <= 1 / 2 full b011 = Transmit FIFO becomes <= 3 / 4 full b100 = Transmit FIFO becomes <= 7 / 8 full b101-b111 = reserved.
185    TXIFLSEL OFFSET(0) NUMBITS(3) []
186],
187UARTIMSC [
188    /// Overrun error interrupt mask. A read returns the current mask for the UARTOEINTR interrupt. On a write of 1, the mask of the UARTOEINTR interrupt is set. A write of 0 clears the mask.
189    OEIM OFFSET(10) NUMBITS(1) [],
190    /// Break error interrupt mask. A read returns the current mask for the UARTBEINTR interrupt. On a write of 1, the mask of the UARTBEINTR interrupt is set. A write of 0 clears the mask.
191    BEIM OFFSET(9) NUMBITS(1) [],
192    /// Parity error interrupt mask. A read returns the current mask for the UARTPEINTR interrupt. On a write of 1, the mask of the UARTPEINTR interrupt is set. A write of 0 clears the mask.
193    PEIM OFFSET(8) NUMBITS(1) [],
194    /// Framing error interrupt mask. A read returns the current mask for the UARTFEINTR interrupt. On a write of 1, the mask of the UARTFEINTR interrupt is set. A write of 0 clears the mask.
195    FEIM OFFSET(7) NUMBITS(1) [],
196    /// Receive timeout interrupt mask. A read returns the current mask for the UARTRTINTR interrupt. On a write of 1, the mask of the UARTRTINTR interrupt is set. A write of 0 clears the mask.
197    RTIM OFFSET(6) NUMBITS(1) [],
198    /// Transmit interrupt mask. A read returns the current mask for the UARTTXINTR interrupt. On a write of 1, the mask of the UARTTXINTR interrupt is set. A write of 0 clears the mask.
199    TXIM OFFSET(5) NUMBITS(1) [],
200    /// Receive interrupt mask. A read returns the current mask for the UARTRXINTR interrupt. On a write of 1, the mask of the UARTRXINTR interrupt is set. A write of 0 clears the mask.
201    RXIM OFFSET(4) NUMBITS(1) [],
202    /// nUARTDSR modem interrupt mask. A read returns the current mask for the UARTDSRINTR interrupt. On a write of 1, the mask of the UARTDSRINTR interrupt is set. A write of 0 clears the mask.
203    DSRMIM OFFSET(3) NUMBITS(1) [],
204    /// nUARTDCD modem interrupt mask. A read returns the current mask for the UARTDCDINTR interrupt. On a write of 1, the mask of the UARTDCDINTR interrupt is set. A write of 0 clears the mask.
205    DCDMIM OFFSET(2) NUMBITS(1) [],
206    /// nUARTCTS modem interrupt mask. A read returns the current mask for the UARTCTSINTR interrupt. On a write of 1, the mask of the UARTCTSINTR interrupt is set. A write of 0 clears the mask.
207    CTSMIM OFFSET(1) NUMBITS(1) [],
208    /// nUARTRI modem interrupt mask. A read returns the current mask for the UARTRIINTR interrupt. On a write of 1, the mask of the UARTRIINTR interrupt is set. A write of 0 clears the mask.
209    RIMIM OFFSET(0) NUMBITS(1) []
210],
211UARTRIS [
212    /// Overrun error interrupt status. Returns the raw interrupt state of the UARTOEINTR interrupt.
213    OERIS OFFSET(10) NUMBITS(1) [],
214    /// Break error interrupt status. Returns the raw interrupt state of the UARTBEINTR interrupt.
215    BERIS OFFSET(9) NUMBITS(1) [],
216    /// Parity error interrupt status. Returns the raw interrupt state of the UARTPEINTR interrupt.
217    PERIS OFFSET(8) NUMBITS(1) [],
218    /// Framing error interrupt status. Returns the raw interrupt state of the UARTFEINTR interrupt.
219    FERIS OFFSET(7) NUMBITS(1) [],
220    /// Receive timeout interrupt status. Returns the raw interrupt state of the UARTRTINTR interrupt. a
221    RTRIS OFFSET(6) NUMBITS(1) [],
222    /// Transmit interrupt status. Returns the raw interrupt state of the UARTTXINTR interrupt.
223    TXRIS OFFSET(5) NUMBITS(1) [],
224    /// Receive interrupt status. Returns the raw interrupt state of the UARTRXINTR interrupt.
225    RXRIS OFFSET(4) NUMBITS(1) [],
226    /// nUARTDSR modem interrupt status. Returns the raw interrupt state of the UARTDSRINTR interrupt.
227    DSRRMIS OFFSET(3) NUMBITS(1) [],
228    /// nUARTDCD modem interrupt status. Returns the raw interrupt state of the UARTDCDINTR interrupt.
229    DCDRMIS OFFSET(2) NUMBITS(1) [],
230    /// nUARTCTS modem interrupt status. Returns the raw interrupt state of the UARTCTSINTR interrupt.
231    CTSRMIS OFFSET(1) NUMBITS(1) [],
232    /// nUARTRI modem interrupt status. Returns the raw interrupt state of the UARTRIINTR interrupt.
233    RIRMIS OFFSET(0) NUMBITS(1) []
234],
235UARTMIS [
236    /// Overrun error masked interrupt status. Returns the masked interrupt state of the UARTOEINTR interrupt.
237    OEMIS OFFSET(10) NUMBITS(1) [],
238    /// Break error masked interrupt status. Returns the masked interrupt state of the UARTBEINTR interrupt.
239    BEMIS OFFSET(9) NUMBITS(1) [],
240    /// Parity error masked interrupt status. Returns the masked interrupt state of the UARTPEINTR interrupt.
241    PEMIS OFFSET(8) NUMBITS(1) [],
242    /// Framing error masked interrupt status. Returns the masked interrupt state of the UARTFEINTR interrupt.
243    FEMIS OFFSET(7) NUMBITS(1) [],
244    /// Receive timeout masked interrupt status. Returns the masked interrupt state of the UARTRTINTR interrupt.
245    RTMIS OFFSET(6) NUMBITS(1) [],
246    /// Transmit masked interrupt status. Returns the masked interrupt state of the UARTTXINTR interrupt.
247    TXMIS OFFSET(5) NUMBITS(1) [],
248    /// Receive masked interrupt status. Returns the masked interrupt state of the UARTRXINTR interrupt.
249    RXMIS OFFSET(4) NUMBITS(1) [],
250    /// nUARTDSR modem masked interrupt status. Returns the masked interrupt state of the UARTDSRINTR interrupt.
251    DSRMMIS OFFSET(3) NUMBITS(1) [],
252    /// nUARTDCD modem masked interrupt status. Returns the masked interrupt state of the UARTDCDINTR interrupt.
253    DCDMMIS OFFSET(2) NUMBITS(1) [],
254    /// nUARTCTS modem masked interrupt status. Returns the masked interrupt state of the UARTCTSINTR interrupt.
255    CTSMMIS OFFSET(1) NUMBITS(1) [],
256    /// nUARTRI modem masked interrupt status. Returns the masked interrupt state of the UARTRIINTR interrupt.
257    RIMMIS OFFSET(0) NUMBITS(1) []
258],
259UARTICR [
260    /// Overrun error interrupt clear. Clears the UARTOEINTR interrupt.
261    OEIC OFFSET(10) NUMBITS(1) [],
262    /// Break error interrupt clear. Clears the UARTBEINTR interrupt.
263    BEIC OFFSET(9) NUMBITS(1) [],
264    /// Parity error interrupt clear. Clears the UARTPEINTR interrupt.
265    PEIC OFFSET(8) NUMBITS(1) [],
266    /// Framing error interrupt clear. Clears the UARTFEINTR interrupt.
267    FEIC OFFSET(7) NUMBITS(1) [],
268    /// Receive timeout interrupt clear. Clears the UARTRTINTR interrupt.
269    RTIC OFFSET(6) NUMBITS(1) [],
270    /// Transmit interrupt clear. Clears the UARTTXINTR interrupt.
271    TXIC OFFSET(5) NUMBITS(1) [],
272    /// Receive interrupt clear. Clears the UARTRXINTR interrupt.
273    RXIC OFFSET(4) NUMBITS(1) [],
274    /// nUARTDSR modem interrupt clear. Clears the UARTDSRINTR interrupt.
275    DSRMIC OFFSET(3) NUMBITS(1) [],
276    /// nUARTDCD modem interrupt clear. Clears the UARTDCDINTR interrupt.
277    DCDMIC OFFSET(2) NUMBITS(1) [],
278    /// nUARTCTS modem interrupt clear. Clears the UARTCTSINTR interrupt.
279    CTSMIC OFFSET(1) NUMBITS(1) [],
280    /// nUARTRI modem interrupt clear. Clears the UARTRIINTR interrupt.
281    RIMIC OFFSET(0) NUMBITS(1) []
282],
283UARTDMACR [
284    /// DMA on error. If this bit is set to 1, the DMA receive request outputs, UARTRXDMASREQ or UARTRXDMABREQ, are disabled when the UART error interrupt is asserted.
285    DMAONERR OFFSET(2) NUMBITS(1) [],
286    /// Transmit DMA enable. If this bit is set to 1, DMA for the transmit FIFO is enabled.
287    TXDMAE OFFSET(1) NUMBITS(1) [],
288    /// Receive DMA enable. If this bit is set to 1, DMA for the receive FIFO is enabled.
289    RXDMAE OFFSET(0) NUMBITS(1) []
290],
291UARTPERIPHID0 [
292    /// These bits read back as 0x11
293    PARTNUMBER0 OFFSET(0) NUMBITS(8) []
294],
295UARTPERIPHID1 [
296    /// These bits read back as 0x1
297    DESIGNER0 OFFSET(4) NUMBITS(4) [],
298    /// These bits read back as 0x0
299    PARTNUMBER1 OFFSET(0) NUMBITS(4) []
300],
301UARTPERIPHID2 [
302    /// This field depends on the revision of the UART: r1p0 0x0 r1p1 0x1 r1p3 0x2 r1p4 0x2 r1p5 0x3
303    REVISION OFFSET(4) NUMBITS(4) [],
304    /// These bits read back as 0x4
305    DESIGNER1 OFFSET(0) NUMBITS(4) []
306],
307UARTPERIPHID3 [
308    /// These bits read back as 0x00
309    CONFIGURATION OFFSET(0) NUMBITS(8) []
310],
311UARTPCELLID0 [
312    /// These bits read back as 0x0D
313    UARTPCELLID0 OFFSET(0) NUMBITS(8) []
314],
315UARTPCELLID1 [
316    /// These bits read back as 0xF0
317    UARTPCELLID1 OFFSET(0) NUMBITS(8) []
318],
319UARTPCELLID2 [
320    /// These bits read back as 0x05
321    UARTPCELLID2 OFFSET(0) NUMBITS(8) []
322],
323UARTPCELLID3 [
324    /// These bits read back as 0xB1
325    UARTPCELLID3 OFFSET(0) NUMBITS(8) []
326]
327];
328
329#[derive(Copy, Clone, PartialEq)]
330enum UARTStateTX {
331    Idle,
332    Transmitting,
333    AbortRequested,
334}
335
336#[derive(Copy, Clone, PartialEq)]
337enum UARTStateRX {
338    Idle,
339    Receiving,
340    AbortRequested,
341}
342
343const UART0_BASE: StaticRef<UartRegisters> =
344    unsafe { StaticRef::new(0x40070000 as *const UartRegisters) };
345
346const UART1_BASE: StaticRef<UartRegisters> =
347    unsafe { StaticRef::new(0x40078000 as *const UartRegisters) };
348
349pub struct Uart<'a> {
350    registers: StaticRef<UartRegisters>,
351    clocks: OptionalCell<&'a clocks::Clocks>,
352
353    tx_client: OptionalCell<&'a dyn TransmitClient>,
354    rx_client: OptionalCell<&'a dyn ReceiveClient>,
355
356    tx_buffer: TakeCell<'static, [u8]>,
357    tx_position: Cell<usize>,
358    tx_len: Cell<usize>,
359    tx_status: Cell<UARTStateTX>,
360
361    rx_buffer: TakeCell<'static, [u8]>,
362    rx_position: Cell<usize>,
363    rx_len: Cell<usize>,
364    rx_status: Cell<UARTStateRX>,
365
366    deferred_call: DeferredCall,
367}
368
369impl<'a> Uart<'a> {
370    pub fn new_uart0() -> Self {
371        Self {
372            registers: UART0_BASE,
373            clocks: OptionalCell::empty(),
374
375            tx_client: OptionalCell::empty(),
376            rx_client: OptionalCell::empty(),
377
378            tx_buffer: TakeCell::empty(),
379            tx_position: Cell::new(0),
380            tx_len: Cell::new(0),
381            tx_status: Cell::new(UARTStateTX::Idle),
382
383            rx_buffer: TakeCell::empty(),
384            rx_position: Cell::new(0),
385            rx_len: Cell::new(0),
386            rx_status: Cell::new(UARTStateRX::Idle),
387
388            deferred_call: DeferredCall::new(),
389        }
390    }
391    pub fn new_uart1() -> Self {
392        Self {
393            registers: UART1_BASE,
394            clocks: OptionalCell::empty(),
395
396            tx_client: OptionalCell::empty(),
397            rx_client: OptionalCell::empty(),
398
399            tx_buffer: TakeCell::empty(),
400            tx_position: Cell::new(0),
401            tx_len: Cell::new(0),
402            tx_status: Cell::new(UARTStateTX::Idle),
403            rx_buffer: TakeCell::empty(),
404            rx_position: Cell::new(0),
405            rx_len: Cell::new(0),
406            rx_status: Cell::new(UARTStateRX::Idle),
407
408            deferred_call: DeferredCall::new(),
409        }
410    }
411
412    pub(crate) fn set_clocks(&self, clocks: &'a clocks::Clocks) {
413        self.clocks.set(clocks);
414    }
415
416    pub fn enable(&self) {
417        self.registers.uartcr.modify(UARTCR::UARTEN::SET);
418    }
419
420    pub fn disable(&self) {
421        self.registers.uartcr.modify(UARTCR::UARTEN::CLEAR);
422    }
423
424    pub fn enable_transmit_interrupt(&self) {
425        self.registers.uartimsc.modify(UARTIMSC::TXIM::SET);
426    }
427
428    pub fn disable_transmit_interrupt(&self) {
429        self.registers.uartimsc.modify(UARTIMSC::TXIM::CLEAR);
430    }
431
432    pub fn enable_receive_interrupt(&self) {
433        self.registers.uartifls.modify(UARTIFLS::RXIFLSEL::FIFO_1_8);
434
435        self.registers.uartimsc.modify(UARTIMSC::RXIM::SET);
436    }
437
438    pub fn disable_receive_interrupt(&self) {
439        self.registers.uartimsc.modify(UARTIMSC::RXIM::CLEAR);
440    }
441
442    fn uart_is_writable(&self) -> bool {
443        !self.registers.uartfr.is_set(UARTFR::TXFF)
444    }
445
446    pub fn send_byte(&self, data: u8) {
447        while !self.uart_is_writable() {}
448        self.registers.uartdr.write(UARTDR::DATA.val(data as u32));
449    }
450
451    pub fn handle_interrupt(&self) {
452        if self.registers.uartimsc.is_set(UARTIMSC::TXIM) {
453            if self.registers.uartfr.is_set(UARTFR::TXFE) {
454                if self.tx_status.get() == UARTStateTX::Idle {
455                    kernel::debug!("No data to transmit");
456                } else if self.tx_status.get() == UARTStateTX::Transmitting {
457                    self.disable_transmit_interrupt();
458                    if self.tx_position.get() < self.tx_len.get() {
459                        self.fill_fifo();
460                        self.enable_transmit_interrupt();
461                    }
462                    // Transmission is done
463                    else {
464                        self.tx_status.set(UARTStateTX::Idle);
465                        self.tx_client.map(|client| {
466                            self.tx_buffer.take().map(|buf| {
467                                client.transmitted_buffer(buf, self.tx_position.get(), Ok(()));
468                            });
469                        });
470                    }
471                }
472            }
473        }
474
475        if self.registers.uartimsc.is_set(UARTIMSC::RXIM) {
476            if self.registers.uartfr.is_set(UARTFR::RXFF) {
477                let byte = self.registers.uartdr.get() as u8;
478
479                self.disable_receive_interrupt();
480                if self.rx_status.get() == UARTStateRX::Receiving {
481                    if self.rx_position.get() < self.rx_len.get() {
482                        self.rx_buffer.map(|buf| {
483                            buf[self.rx_position.get()] = byte;
484                            self.rx_position.replace(self.rx_position.get() + 1);
485                        });
486                    }
487                    if self.rx_position.get() == self.rx_len.get() {
488                        // reception done
489                        self.rx_status.replace(UARTStateRX::Idle);
490                    } else {
491                        self.enable_receive_interrupt();
492                    }
493                    // notify client if transfer is done
494                    if self.rx_status.get() == UARTStateRX::Idle {
495                        self.rx_client.map(|client| {
496                            if let Some(buf) = self.rx_buffer.take() {
497                                client.received_buffer(
498                                    buf,
499                                    self.rx_len.get(),
500                                    Ok(()),
501                                    hil::uart::Error::None,
502                                );
503                            }
504                        });
505                    }
506                }
507            }
508        }
509    }
510
511    fn fill_fifo(&self) {
512        while self.uart_is_writable() && self.tx_position.get() < self.tx_len.get() {
513            self.tx_buffer.map(|buf| {
514                self.registers
515                    .uartdr
516                    .set(buf[self.tx_position.get()].into());
517                self.tx_position.replace(self.tx_position.get() + 1);
518            });
519        }
520    }
521
522    pub fn is_configured(&self) -> bool {
523        self.registers.uartcr.is_set(UARTCR::UARTEN)
524            && (self.registers.uartcr.is_set(UARTCR::RXE)
525                || self.registers.uartcr.is_set(UARTCR::TXE))
526    }
527
528    pub fn debug_configure(&self, params: Parameters) -> Result<(), ErrorCode> {
529        self.disable();
530        self.registers.uartlcr_h.modify(UARTLCR_H::FEN::CLEAR);
531
532        let clk = self.clocks.map_or(125_000_000, |clocks| {
533            clocks.get_frequency(clocks::Clock::Peripheral)
534        });
535
536        // Calculate baud rate
537        let baud_rate_div = 8 * clk / params.baud_rate;
538        let mut baud_ibrd = baud_rate_div >> 7;
539        let mut baud_fbrd = (baud_rate_div & 0x7f).div_ceil(2);
540
541        if baud_ibrd == 0 {
542            baud_ibrd = 1;
543            baud_fbrd = 0;
544        } else if baud_ibrd >= 65535 {
545            baud_ibrd = 65535;
546            baud_fbrd = 0;
547        }
548
549        self.registers
550            .uartibrd
551            .write(UARTIBRD::BAUD_DIVINT.val(baud_ibrd));
552        self.registers
553            .uartfbrd
554            .write(UARTFBRD::BAUD_DIVFRAC.val(baud_fbrd));
555
556        self.registers.uartlcr_h.modify(UARTLCR_H::BRK::SET);
557        // Configure the word length
558        match params.width {
559            Width::Six => self.registers.uartlcr_h.modify(UARTLCR_H::WLEN::BITS_6),
560            Width::Seven => self.registers.uartlcr_h.modify(UARTLCR_H::WLEN::BITS_7),
561            Width::Eight => self.registers.uartlcr_h.modify(UARTLCR_H::WLEN::BITS_8),
562        }
563
564        // Configure parity
565        match params.parity {
566            Parity::None => {
567                self.registers.uartlcr_h.modify(UARTLCR_H::PEN::CLEAR);
568                self.registers.uartlcr_h.modify(UARTLCR_H::EPS::CLEAR);
569            }
570
571            Parity::Odd => {
572                self.registers.uartlcr_h.modify(UARTLCR_H::PEN::SET);
573                self.registers.uartlcr_h.modify(UARTLCR_H::EPS::CLEAR);
574            }
575            Parity::Even => {
576                self.registers.uartlcr_h.modify(UARTLCR_H::PEN::SET);
577                self.registers.uartlcr_h.modify(UARTLCR_H::EPS::SET);
578            }
579        }
580
581        // Set the stop bit length - 2 stop bits
582        match params.stop_bits {
583            StopBits::One => self.registers.uartlcr_h.modify(UARTLCR_H::STP2::CLEAR),
584            StopBits::Two => self.registers.uartlcr_h.modify(UARTLCR_H::STP2::SET),
585        }
586
587        // Set flow control
588        if params.hw_flow_control {
589            self.registers.uartcr.modify(UARTCR::RTSEN::SET);
590            self.registers.uartcr.modify(UARTCR::CTSEN::SET);
591        } else {
592            self.registers.uartcr.modify(UARTCR::RTSEN::CLEAR);
593            self.registers.uartcr.modify(UARTCR::CTSEN::CLEAR);
594        }
595        self.registers.uartlcr_h.modify(UARTLCR_H::BRK::CLEAR);
596
597        // FIFO is not precise enough for receive
598        self.registers.uartlcr_h.modify(UARTLCR_H::FEN::CLEAR);
599
600        // Enable uart and transmit
601        self.registers
602            .uartcr
603            .modify(UARTCR::UARTEN::SET + UARTCR::TXE::SET + UARTCR::RXE::SET);
604
605        self.registers
606            .uartdmacr
607            .write(UARTDMACR::TXDMAE::SET + UARTDMACR::RXDMAE::SET);
608
609        Ok(())
610    }
611}
612
613impl DeferredCallClient for Uart<'_> {
614    fn register(&'static self) {
615        self.deferred_call.register(self)
616    }
617
618    fn handle_deferred_call(&self) {
619        if self.tx_status.get() == UARTStateTX::AbortRequested {
620            // alert client
621            self.tx_client.map(|client| {
622                self.tx_buffer.take().map(|buf| {
623                    client.transmitted_buffer(buf, self.tx_position.get(), Err(ErrorCode::CANCEL));
624                });
625            });
626            self.tx_status.set(UARTStateTX::Idle);
627        }
628
629        if self.rx_status.get() == UARTStateRX::AbortRequested {
630            // alert client
631            self.rx_client.map(|client| {
632                self.rx_buffer.take().map(|buf| {
633                    client.received_buffer(
634                        buf,
635                        self.rx_position.get(),
636                        Err(ErrorCode::CANCEL),
637                        hil::uart::Error::Aborted,
638                    );
639                });
640            });
641            self.rx_status.set(UARTStateRX::Idle);
642        }
643    }
644}
645
646impl Configure for Uart<'_> {
647    fn configure(&self, params: Parameters) -> Result<(), ErrorCode> {
648        self.disable();
649        self.registers.uartlcr_h.modify(UARTLCR_H::FEN::CLEAR);
650
651        let clk = self.clocks.map_or(125_000_000, |clocks| {
652            clocks.get_frequency(clocks::Clock::Peripheral)
653        });
654
655        // Calculate baud rate
656        let baud_rate_div = 8 * clk / params.baud_rate;
657        let mut baud_ibrd = baud_rate_div >> 7;
658        let mut baud_fbrd = (baud_rate_div & 0x7f).div_ceil(2);
659
660        if baud_ibrd == 0 {
661            baud_ibrd = 1;
662            baud_fbrd = 0;
663        } else if baud_ibrd >= 65535 {
664            baud_ibrd = 65535;
665            baud_fbrd = 0;
666        }
667
668        self.registers
669            .uartibrd
670            .write(UARTIBRD::BAUD_DIVINT.val(baud_ibrd));
671        self.registers
672            .uartfbrd
673            .write(UARTFBRD::BAUD_DIVFRAC.val(baud_fbrd));
674
675        self.registers.uartlcr_h.modify(UARTLCR_H::BRK::SET);
676        // Configure the word length
677        match params.width {
678            Width::Six => self.registers.uartlcr_h.modify(UARTLCR_H::WLEN::BITS_6),
679            Width::Seven => self.registers.uartlcr_h.modify(UARTLCR_H::WLEN::BITS_7),
680            Width::Eight => self.registers.uartlcr_h.modify(UARTLCR_H::WLEN::BITS_8),
681        }
682
683        // Configure parity
684        match params.parity {
685            Parity::None => {
686                self.registers.uartlcr_h.modify(UARTLCR_H::PEN::CLEAR);
687                self.registers.uartlcr_h.modify(UARTLCR_H::EPS::CLEAR);
688            }
689
690            Parity::Odd => {
691                self.registers.uartlcr_h.modify(UARTLCR_H::PEN::SET);
692                self.registers.uartlcr_h.modify(UARTLCR_H::EPS::CLEAR);
693            }
694            Parity::Even => {
695                self.registers.uartlcr_h.modify(UARTLCR_H::PEN::SET);
696                self.registers.uartlcr_h.modify(UARTLCR_H::EPS::SET);
697            }
698        }
699
700        // Set the stop bit length - 2 stop bits
701        match params.stop_bits {
702            StopBits::One => self.registers.uartlcr_h.modify(UARTLCR_H::STP2::CLEAR),
703            StopBits::Two => self.registers.uartlcr_h.modify(UARTLCR_H::STP2::SET),
704        }
705
706        // Set flow control
707        if params.hw_flow_control {
708            self.registers.uartcr.modify(UARTCR::RTSEN::SET);
709            self.registers.uartcr.modify(UARTCR::CTSEN::SET);
710        } else {
711            self.registers.uartcr.modify(UARTCR::RTSEN::CLEAR);
712            self.registers.uartcr.modify(UARTCR::CTSEN::CLEAR);
713        }
714        self.registers.uartlcr_h.modify(UARTLCR_H::BRK::CLEAR);
715
716        // FIFO is not precise enough for receive
717        self.registers.uartlcr_h.modify(UARTLCR_H::FEN::CLEAR);
718
719        // Enable uart and transmit
720        self.registers
721            .uartcr
722            .modify(UARTCR::UARTEN::SET + UARTCR::TXE::SET + UARTCR::RXE::SET);
723
724        self.registers
725            .uartdmacr
726            .write(UARTDMACR::TXDMAE::SET + UARTDMACR::RXDMAE::SET);
727
728        Ok(())
729    }
730}
731
732impl<'a> Transmit<'a> for Uart<'a> {
733    fn set_transmit_client(&self, client: &'a dyn TransmitClient) {
734        self.tx_client.set(client);
735    }
736
737    fn transmit_buffer(
738        &self,
739        tx_buffer: &'static mut [u8],
740        tx_len: usize,
741    ) -> Result<(), (ErrorCode, &'static mut [u8])> {
742        if self.tx_status.get() == UARTStateTX::Idle {
743            if tx_len <= tx_buffer.len() {
744                self.tx_buffer.put(Some(tx_buffer));
745                self.tx_position.set(0);
746                self.tx_len.set(tx_len);
747                self.tx_status.set(UARTStateTX::Transmitting);
748                self.enable_transmit_interrupt();
749                self.fill_fifo();
750                Ok(())
751            } else {
752                Err((ErrorCode::SIZE, tx_buffer))
753            }
754        } else {
755            Err((ErrorCode::BUSY, tx_buffer))
756        }
757    }
758
759    fn transmit_word(&self, _word: u32) -> Result<(), ErrorCode> {
760        Err(ErrorCode::FAIL)
761    }
762
763    fn transmit_abort(&self) -> Result<(), ErrorCode> {
764        if self.tx_status.get() != UARTStateTX::Idle {
765            self.disable_transmit_interrupt();
766            self.tx_status.set(UARTStateTX::AbortRequested);
767
768            self.deferred_call.set();
769
770            Err(ErrorCode::BUSY)
771        } else {
772            Ok(())
773        }
774    }
775}
776
777impl<'a> Receive<'a> for Uart<'a> {
778    fn set_receive_client(&self, client: &'a dyn ReceiveClient) {
779        self.rx_client.set(client);
780    }
781
782    fn receive_buffer(
783        &self,
784        rx_buffer: &'static mut [u8],
785        rx_len: usize,
786    ) -> Result<(), (ErrorCode, &'static mut [u8])> {
787        if self.rx_status.get() == UARTStateRX::Idle {
788            if rx_len <= rx_buffer.len() {
789                self.rx_buffer.put(Some(rx_buffer));
790                self.rx_position.set(0);
791                self.rx_len.set(rx_len);
792                self.rx_status.set(UARTStateRX::Receiving);
793                self.enable_receive_interrupt();
794                Ok(())
795            } else {
796                Err((ErrorCode::SIZE, rx_buffer))
797            }
798        } else {
799            Err((ErrorCode::BUSY, rx_buffer))
800        }
801    }
802
803    fn receive_word(&self) -> Result<(), ErrorCode> {
804        Err(ErrorCode::FAIL)
805    }
806
807    fn receive_abort(&self) -> Result<(), ErrorCode> {
808        if self.rx_status.get() != UARTStateRX::Idle {
809            self.disable_receive_interrupt();
810            self.rx_status.set(UARTStateRX::AbortRequested);
811
812            self.deferred_call.set();
813
814            Err(ErrorCode::BUSY)
815        } else {
816            Ok(())
817        }
818    }
819}