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}