1mod registers;
9
10use bitflags::Flags;
11use heapless::Vec;
12use rdif_serial::{
13 Config, ConfigError, DataBits, InterruptMask, LineStatus, Parity, Register, Serial, StopBits,
14 TransferError,
15};
16use registers::*;
17
18#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
19mod pio;
20mod mmio;
22
23pub use mmio::*;
24#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
25pub use pio::*;
26
27pub trait Kind: Send + Sync + 'static {
28 fn read_reg(&self, reg: u8) -> u8;
29 fn write_reg(&mut self, reg: u8, val: u8);
30 fn get_base(&self) -> usize;
31 fn set_base(&mut self, base: usize);
32}
33
34#[derive(Clone, Debug)]
35#[repr(align(64))]
36pub struct Ns16550<T: Kind> {
37 rcv_fifo: Vec<u8, 64>,
38 base: T,
39 clock_freq: u32,
40 err: Option<TransferError>,
41 is_tx_empty_int_enabled: bool,
42}
43
44impl<T: Kind> Ns16550<T> {
45 fn new(base: T, clock_freq: u32) -> Serial<Self> {
46 Serial::new(Self {
47 rcv_fifo: Vec::new(),
48 base,
49 clock_freq,
50 err: None,
51 is_tx_empty_int_enabled: false,
52 })
53 }
54
55 fn read_reg_u8(&self, reg: u8) -> u8 {
57 self.base.read_reg(reg)
58 }
59
60 fn write_reg_u8(&mut self, reg: u8, val: u8) {
61 self.base.write_reg(reg, val);
62 }
63
64 fn read_flags<F: Flags<Bits = u8>>(&self, reg: u8) -> F {
66 F::from_bits_retain(self.base.read_reg(reg))
67 }
68
69 fn write_flags<F: Flags<Bits = u8>>(&mut self, reg: u8, val: F) {
70 self.base.write_reg(reg, val.bits());
71 }
72
73 pub fn is_16550_plus(&self) -> bool {
75 let fifo: InterruptIdentificationFlags = self.read_flags(UART_IIR);
78 fifo.contains(InterruptIdentificationFlags::FIFO_ENABLE_MASK)
79 }
80
81 fn set_baudrate_internal(&mut self, baudrate: u32) -> Result<(), ConfigError> {
83 if baudrate == 0 || self.clock_freq == 0 {
84 return Err(ConfigError::InvalidBaudrate);
85 }
86
87 let divisor = self.clock_freq / (16 * baudrate);
88 if divisor == 0 || divisor > 0xFFFF {
89 return Err(ConfigError::InvalidBaudrate);
90 }
91
92 let mut lcr: LineControlFlags = self.read_flags(UART_LCR);
94
95 lcr.insert(LineControlFlags::DIVISOR_LATCH_ACCESS);
97 self.write_flags(UART_LCR, lcr);
98
99 self.write_reg_u8(UART_DLL, (divisor & 0xFF) as u8);
101 self.write_reg_u8(UART_DLH, ((divisor >> 8) & 0xFF) as u8);
102
103 lcr.remove(LineControlFlags::DIVISOR_LATCH_ACCESS);
105 self.write_flags(UART_LCR, lcr);
106
107 Ok(())
108 }
109
110 fn set_data_bits_internal(&mut self, bits: DataBits) -> Result<(), ConfigError> {
112 let wlen = match bits {
113 DataBits::Five => LineControlFlags::WORD_LENGTH_5,
114 DataBits::Six => LineControlFlags::WORD_LENGTH_6,
115 DataBits::Seven => LineControlFlags::WORD_LENGTH_7,
116 DataBits::Eight => LineControlFlags::WORD_LENGTH_8,
117 };
118
119 let mut lcr: LineControlFlags = self.read_flags(UART_LCR);
120 lcr.remove(LineControlFlags::WORD_LENGTH_MASK);
122 lcr.insert(wlen);
123 self.write_flags(UART_LCR, lcr);
124
125 Ok(())
126 }
127
128 fn set_stop_bits_internal(&mut self, bits: StopBits) -> Result<(), ConfigError> {
130 let mut lcr: LineControlFlags = self.read_flags(UART_LCR);
131 match bits {
132 StopBits::One => lcr.remove(LineControlFlags::STOP_BITS),
133 StopBits::Two => lcr.insert(LineControlFlags::STOP_BITS),
134 }
135 self.write_flags(UART_LCR, lcr);
136 Ok(())
137 }
138
139 fn set_parity_internal(&mut self, parity: Parity) -> Result<(), ConfigError> {
141 let mut lcr: LineControlFlags = self.read_flags(UART_LCR);
142
143 lcr.remove(
145 LineControlFlags::PARITY_ENABLE
146 | LineControlFlags::EVEN_PARITY
147 | LineControlFlags::STICK_PARITY,
148 );
149
150 match parity {
152 Parity::None => {
153 }
155 Parity::Odd => {
156 lcr.insert(LineControlFlags::PARITY_ENABLE);
157 }
158 Parity::Even => {
159 lcr.insert(LineControlFlags::PARITY_ENABLE | LineControlFlags::EVEN_PARITY);
160 }
161 Parity::Mark => {
162 lcr.insert(LineControlFlags::PARITY_ENABLE | LineControlFlags::STICK_PARITY);
163 }
164 Parity::Space => {
165 lcr.insert(
166 LineControlFlags::PARITY_ENABLE
167 | LineControlFlags::EVEN_PARITY
168 | LineControlFlags::STICK_PARITY,
169 );
170 }
171 }
172
173 self.write_flags(UART_LCR, lcr);
174 Ok(())
175 }
176
177 pub fn enable_fifo(&mut self, enable: bool) {
179 if enable && self.is_16550_plus() {
180 let mut fcr = FifoControlFlags::ENABLE_FIFO;
181 fcr.insert(FifoControlFlags::CLEAR_RECEIVER_FIFO);
182 fcr.insert(FifoControlFlags::CLEAR_TRANSMITTER_FIFO);
183 fcr.insert(FifoControlFlags::TRIGGER_1_BYTE);
184 self.write_flags(UART_FCR, fcr);
185 } else {
186 self.write_flags(UART_FCR, FifoControlFlags::empty());
187 }
188 }
189
190 pub fn set_fifo_trigger_level(&mut self, level: u8) {
192 if !self.is_16550_plus() {
193 return;
194 }
195
196 let trigger_value = match level {
197 0..=3 => FifoControlFlags::TRIGGER_1_BYTE,
198 4..=7 => FifoControlFlags::TRIGGER_4_BYTES,
199 8..=11 => FifoControlFlags::TRIGGER_8_BYTES,
200 _ => FifoControlFlags::TRIGGER_14_BYTES,
201 };
202
203 let mut fcr: FifoControlFlags = self.read_flags(UART_FCR);
205 fcr.remove(FifoControlFlags::TRIGGER_LEVEL_MASK);
206 fcr.insert(trigger_value);
207 self.write_flags(UART_FCR, fcr);
208 }
209
210 fn init(&mut self) {
212 self.write_flags(UART_IER, InterruptEnableFlags::empty());
214
215 let mut mcr: ModemControlFlags = self.read_flags(UART_MCR);
217 mcr.insert(ModemControlFlags::DATA_TERMINAL_READY | ModemControlFlags::REQUEST_TO_SEND);
218 self.write_flags(UART_MCR, mcr);
219 }
220
221 pub fn clear_receive_fifo(&mut self) {
223 if self.is_16550_plus() {
224 let mut fcr = FifoControlFlags::ENABLE_FIFO;
225 fcr.insert(FifoControlFlags::CLEAR_RECEIVER_FIFO);
226 self.write_flags(UART_FCR, fcr);
227 }
228 self.rcv_fifo.clear();
229 }
230
231 pub fn clear_transmit_fifo(&mut self) {
233 if self.is_16550_plus() {
234 let mut fcr = FifoControlFlags::ENABLE_FIFO;
235 fcr.insert(FifoControlFlags::CLEAR_TRANSMITTER_FIFO);
236 self.write_flags(UART_FCR, fcr);
237 }
238 }
239
240 pub fn is_fifo_enabled(&self) -> bool {
242 if !self.is_16550_plus() {
243 return false;
244 }
245 let iir: InterruptIdentificationFlags = self.read_flags(UART_IIR);
247 iir.contains(InterruptIdentificationFlags::FIFO_ENABLE_MASK)
248 }
249}
250
251impl<T: Kind> Register for Ns16550<T> {
252 fn write_byte(&mut self, byte: u8) {
253 self.write_reg_u8(UART_THR, byte);
254 if self.is_tx_empty_int_enabled {
257 let mut ier: InterruptEnableFlags = self.read_flags(UART_IER);
258 ier.insert(InterruptEnableFlags::TRANSMITTER_HOLDING_EMPTY);
259 self.write_flags(UART_IER, ier);
260 }
261 }
262
263 fn read_byte(&mut self) -> Result<u8, TransferError> {
264 if let Some(e) = self.err.take() {
265 return Err(e);
266 }
267 Ok(self.rcv_fifo.pop().unwrap())
268 }
269
270 fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> {
271 if let Some(baudrate) = config.baudrate {
273 self.set_baudrate_internal(baudrate)?;
274 }
275
276 if let Some(data_bits) = config.data_bits {
278 self.set_data_bits_internal(data_bits)?;
279 }
280
281 if let Some(stop_bits) = config.stop_bits {
283 self.set_stop_bits_internal(stop_bits)?;
284 }
285
286 if let Some(parity) = config.parity {
288 self.set_parity_internal(parity)?;
289 }
290
291 Ok(())
292 }
293
294 fn baudrate(&self) -> u32 {
295 let dll = self.read_reg_u8(UART_DLL) as u16;
298 let dlh = self.read_reg_u8(UART_DLH) as u16;
299 let divisor = dll | (dlh << 8);
300
301 if divisor == 0 {
302 return 0;
303 }
304
305 self.clock_freq / (16 * divisor as u32)
306 }
307
308 fn data_bits(&self) -> DataBits {
309 let lcr: LineControlFlags = self.read_flags(UART_LCR);
310 let wlen = lcr & LineControlFlags::WORD_LENGTH_MASK;
311 if wlen == LineControlFlags::WORD_LENGTH_5 {
312 DataBits::Five
313 } else if wlen == LineControlFlags::WORD_LENGTH_6 {
314 DataBits::Six
315 } else if wlen == LineControlFlags::WORD_LENGTH_7 {
316 DataBits::Seven
317 } else {
318 DataBits::Eight }
320 }
321
322 fn stop_bits(&self) -> StopBits {
323 let lcr: LineControlFlags = self.read_flags(UART_LCR);
324 if lcr.contains(LineControlFlags::STOP_BITS) {
325 StopBits::Two
326 } else {
327 StopBits::One
328 }
329 }
330
331 fn parity(&self) -> Parity {
332 let lcr: LineControlFlags = self.read_flags(UART_LCR);
333
334 if !lcr.contains(LineControlFlags::PARITY_ENABLE) {
335 Parity::None
336 } else if lcr.contains(LineControlFlags::STICK_PARITY) {
337 if lcr.contains(LineControlFlags::EVEN_PARITY) {
339 Parity::Space
340 } else {
341 Parity::Mark
342 }
343 } else {
344 if lcr.contains(LineControlFlags::EVEN_PARITY) {
346 Parity::Even
347 } else {
348 Parity::Odd
349 }
350 }
351 }
352
353 fn open(&mut self) {
354 self.init();
355 }
356
357 fn close(&mut self) {
358 self.write_flags(UART_IER, InterruptEnableFlags::empty());
360
361 let mut mcr: ModemControlFlags = self.read_flags(UART_MCR);
363 mcr.remove(ModemControlFlags::DATA_TERMINAL_READY | ModemControlFlags::REQUEST_TO_SEND);
364 self.write_flags(UART_MCR, mcr);
365 }
366
367 fn clean_interrupt_status(&mut self) -> InterruptMask {
368 let iir: InterruptIdentificationFlags = self.read_flags(UART_IIR);
369 let mut mask = InterruptMask::empty();
370
371 if iir.contains(InterruptIdentificationFlags::NO_INTERRUPT_PENDING) {
373 return mask;
374 }
375
376 let interrupt_id = iir & InterruptIdentificationFlags::INTERRUPT_ID_MASK;
378
379 if interrupt_id == InterruptIdentificationFlags::RECEIVER_LINE_STATUS {
380 let lsr: LineStatusFlags = self.read_flags(UART_LSR);
381
382 let d = self.read_reg_u8(UART_RBR);
384
385 if lsr.contains(LineStatusFlags::OVERRUN_ERROR) {
387 self.err = Some(TransferError::Overrun(d));
388 mask |= InterruptMask::RX_AVAILABLE;
389 } else if lsr.contains(LineStatusFlags::PARITY_ERROR) {
390 self.err = Some(TransferError::Parity);
391 mask |= InterruptMask::RX_AVAILABLE;
392 } else if lsr.contains(LineStatusFlags::FRAMING_ERROR) {
393 self.err = Some(TransferError::Framing);
394 mask |= InterruptMask::RX_AVAILABLE;
395 } else if lsr.contains(LineStatusFlags::BREAK_INTERRUPT) {
396 self.err = Some(TransferError::Break);
397 mask |= InterruptMask::RX_AVAILABLE;
398 }
399 } else if interrupt_id == InterruptIdentificationFlags::RECEIVED_DATA_AVAILABLE
400 || interrupt_id == InterruptIdentificationFlags::CHARACTER_TIMEOUT
401 {
402 let d = self.read_reg_u8(UART_RBR);
404 mask |= InterruptMask::RX_AVAILABLE;
405 if self.rcv_fifo.push(d).is_err() {
406 self.err = Some(TransferError::Overrun(d));
407 }
408 } else if interrupt_id == InterruptIdentificationFlags::TRANSMITTER_HOLDING_EMPTY {
409 let mut ier: InterruptEnableFlags = self.read_flags(UART_IER);
413 ier.remove(InterruptEnableFlags::TRANSMITTER_HOLDING_EMPTY);
414 self.write_flags(UART_IER, ier);
415
416 mask |= InterruptMask::TX_EMPTY;
417 } else if interrupt_id == InterruptIdentificationFlags::MODEM_STATUS {
418 let _ = self.read_flags::<ModemStatusFlags>(UART_MSR);
420 }
421
422 mask
423 }
424
425 fn line_status(&mut self) -> LineStatus {
426 let lsr: LineStatusFlags = self.read_flags(UART_LSR);
427 let mut status = LineStatus::empty();
428
429 if lsr.contains(LineStatusFlags::DATA_READY) {
430 self.rcv_fifo.push(self.read_reg_u8(UART_RBR)).ok();
431 }
432 if lsr.contains(LineStatusFlags::TRANSMITTER_HOLDING_EMPTY) {
433 status |= LineStatus::TX_HOLDING_EMPTY;
434 }
435 if !self.rcv_fifo.is_empty() {
436 status |= LineStatus::DATA_READY;
437 }
438 status
439 }
440
441 fn read_reg(&self, offset: usize) -> u32 {
442 self.read_reg_u8(offset as u8) as u32
443 }
444
445 fn write_reg(&mut self, offset: usize, value: u32) {
446 self.write_reg_u8(offset as u8, value as u8);
447 }
448
449 fn get_base(&self) -> usize {
450 self.base.get_base()
451 }
452
453 fn set_base(&mut self, base: usize) {
454 self.base.set_base(base);
455 }
456
457 fn clock_freq(&self) -> u32 {
458 self.clock_freq
459 }
460
461 fn enable_loopback(&mut self) {
462 let mut mcr: ModemControlFlags = self.read_flags(UART_MCR);
463 mcr.insert(ModemControlFlags::LOOPBACK_ENABLE);
464 self.write_flags(UART_MCR, mcr);
465 }
466
467 fn disable_loopback(&mut self) {
468 let mut mcr: ModemControlFlags = self.read_flags(UART_MCR);
469 mcr.remove(ModemControlFlags::LOOPBACK_ENABLE);
470 self.write_flags(UART_MCR, mcr);
471 }
472
473 fn is_loopback_enabled(&self) -> bool {
474 let mcr: ModemControlFlags = self.read_flags(UART_MCR);
475 mcr.contains(ModemControlFlags::LOOPBACK_ENABLE)
476 }
477
478 fn set_irq_mask(&mut self, mask: InterruptMask) {
479 let mut ier = InterruptEnableFlags::empty();
480 self.is_tx_empty_int_enabled = false;
481
482 if mask.contains(InterruptMask::RX_AVAILABLE) {
483 ier.insert(InterruptEnableFlags::RECEIVED_DATA_AVAILABLE);
484 ier.insert(InterruptEnableFlags::RECEIVER_LINE_STATUS);
485 }
486 if mask.contains(InterruptMask::TX_EMPTY) {
487 ier.insert(InterruptEnableFlags::TRANSMITTER_HOLDING_EMPTY);
488 self.is_tx_empty_int_enabled = true;
489 }
490
491 self.write_flags(UART_IER, ier);
492 }
493
494 fn get_irq_mask(&self) -> InterruptMask {
495 let ier: InterruptEnableFlags = self.read_flags(UART_IER);
496 let mut mask = InterruptMask::empty();
497
498 if ier.contains(InterruptEnableFlags::RECEIVED_DATA_AVAILABLE) {
499 mask |= InterruptMask::RX_AVAILABLE;
500 }
501 if self.is_tx_empty_int_enabled {
502 mask |= InterruptMask::TX_EMPTY;
503 }
504 mask
508 }
509}