some_serial/pl011/
runtime.rs1use super::*;
2
3#[derive(Clone, Copy)]
4struct Pl011ConfigSnapshot {
5 ilpr: u32,
6 ibrd: u32,
7 fbrd: u32,
8 lcr_h: u32,
9 cr: u32,
10 ifls: u32,
11 imsc: u32,
12 dmacr: u32,
13}
14
15impl Pl011ConfigSnapshot {
16 fn capture(registers: &Pl011Registers) -> Self {
17 Self {
18 ilpr: registers.uartilpr.get(),
19 ibrd: registers.uartibrd.get(),
20 fbrd: registers.uartfbrd.get(),
21 lcr_h: registers.uartlcr_h.get(),
22 cr: registers.uartcr.get(),
23 ifls: registers.uartifls.get(),
24 imsc: registers.uartimsc.get(),
25 dmacr: registers.uartdmacr.get(),
26 }
27 }
28
29 fn restore(self, registers: &Pl011Registers) {
30 registers.uartilpr.set(self.ilpr);
31 registers.uartibrd.set(self.ibrd);
32 registers.uartfbrd.set(self.fbrd);
33 registers.uartlcr_h.set(self.lcr_h);
34 registers.uartifls.set(self.ifls);
35 registers.uartimsc.set(self.imsc);
36 registers.uartdmacr.set(self.dmacr);
37 registers.uartcr.set(self.cr);
40 }
41}
42
43impl UartPort for Pl011 {
44 fn startup(&mut self, config: &Config) -> Result<(), ConfigError> {
45 let snapshot = Pl011ConfigSnapshot::capture(self.registers());
46 if let Err(error) = self.open().and_then(|()| self.set_config(config)) {
47 snapshot.restore(self.registers());
48 return Err(error);
49 }
50 self.mask_all();
51 Ok(())
52 }
53
54 fn shutdown(&mut self) {
55 self.registers().uartimsc.set(0);
56 self.registers().uartcr.modify(UARTCR::UARTEN::CLEAR);
57 }
58
59 fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> {
60 let snapshot = Pl011ConfigSnapshot::capture(self.registers());
61 let result = (|| {
62 self.registers().uartcr.modify(UARTCR::UARTEN::CLEAR);
63 self.wait_until_not_busy()?;
64
65 self.registers().uartlcr_h.modify(UARTLCR_H::FEN::CLEAR);
66 if let Some(baudrate) = config.baudrate {
67 self.set_baudrate_internal(baudrate)?;
68 }
69 if let Some(data_bits) = config.data_bits {
70 self.set_data_bits_internal(data_bits)?;
71 }
72 if let Some(stop_bits) = config.stop_bits {
73 self.set_stop_bits_internal(stop_bits)?;
74 }
75 if let Some(parity) = config.parity {
76 self.set_parity_internal(parity)?;
77 }
78 self.registers().uartlcr_h.modify(UARTLCR_H::FEN::SET);
79 self.registers().uartcr.set(snapshot.cr);
80 Ok(())
81 })();
82
83 if result.is_err() {
84 snapshot.restore(self.registers());
85 }
86 result
87 }
88
89 fn read_rx(&mut self) -> Option<RxSample> {
90 Pl011::read_rx(self)
91 }
92
93 fn discard_rx(&mut self) {
94 for _ in 0..32 {
98 if self.registers().uartfr.is_set(UARTFR::RXFE) {
99 break;
100 }
101 let _ = self.registers().uartdr.get();
102 }
103 self.registers().uartrsr_ecr.set(0);
104 self.saved_rx_status = Pl011RxStatus::empty();
105 self.registers()
106 .uarticr
107 .set(imsc_for_events(SerialEventSet::RX));
108 }
109
110 fn discard_tx(&mut self) -> bool {
111 false
115 }
116
117 fn write_tx(&mut self, bytes: &[u8]) -> usize {
118 let mut written = 0;
119 for &byte in bytes {
120 if self.registers().uartfr.is_set(UARTFR::TXFF) {
121 break;
122 }
123 self.registers().uartdr.set(byte as u32);
124 written += 1;
125 }
126 written
127 }
128
129 fn tx_idle(&mut self) -> bool {
130 let fr = self.registers().uartfr.extract();
131 !fr.is_set(UARTFR::BUSY) && !fr.is_set(UARTFR::TXFF)
132 }
133
134 fn mask(&mut self, sources: SerialEventSet) {
135 let enabled = self.registers().uartimsc.get();
136 self.registers()
137 .uartimsc
138 .set(enabled & !imsc_for_events(sources));
139 }
140
141 fn mask_all(&mut self) {
142 self.registers().uartimsc.set(0);
143 }
144
145 fn rearm(&mut self, sources: SerialEventSet) -> SerialEventSet {
146 let enabled = self.registers().uartimsc.get() | imsc_for_events(sources);
147 self.registers().uartimsc.set(enabled);
148
149 let fr = self.registers().uartfr.extract();
150 let rsr = self.registers().uartrsr_ecr.extract();
151 let mut ready = SerialEventSet::empty();
152 if sources.intersects(SerialEventSet::RX) && !fr.is_set(UARTFR::RXFE) {
153 ready |= SerialEventSet::RX_DATA;
154 }
155 if sources.contains(SerialEventSet::RX_STATUS) && !Pl011RxStatus::from_rsr(rsr).is_empty() {
156 ready |= SerialEventSet::RX_STATUS;
157 }
158 if sources.contains(SerialEventSet::TX_SPACE) && !fr.is_set(UARTFR::TXFF) {
159 ready |= SerialEventSet::TX_SPACE;
160 }
161 if !ready.is_empty() {
162 self.registers()
163 .uartimsc
164 .set(enabled & !imsc_for_events(ready));
165 }
166 ready
167 }
168}
169
170impl SplitUart for Pl011 {
171 type Control = Self;
172 type Irq = Pl011Irq;
173 type EmergencyTx = Pl011EmergencyTx;
174
175 fn runtime_info(&self) -> UartInfo {
176 UartInfo {
177 name: "PL011 UART",
178 register_base: self.base.0.as_ptr() as usize,
179 initial_baudrate: self.current_baudrate(),
180 }
181 }
182
183 fn split(self) -> SerialParts<Self::Control, Self::Irq, Self::EmergencyTx> {
184 let irq = Pl011Irq {
185 base: self.base,
186 saved_rx_status: Pl011RxStatus::empty(),
187 };
188 let emergency_tx = Pl011EmergencyTx { base: self.base };
189 SerialParts::new(self, irq, emergency_tx)
190 }
191}
192
193impl PollingUart for Pl011 {
194 fn poll_status(&mut self) -> SerialEvent {
195 Pl011::poll_status(self)
196 }
197
198 fn write_byte(&mut self, byte: u8) {
199 Pl011::write_byte(self, byte);
200 }
201
202 fn read_byte(&mut self, status: SerialEvent) -> Option<Result<u8, TransferError>> {
203 Pl011::read_byte(self, status)
204 }
205}