1mod registers;
9
10use bitflags::Flags;
11use heapless::Deque;
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: Deque<u8, 64>,
38 base: T,
39 clock_freq: u32,
40 is_tx_empty_int_enabled: bool,
41 err: Option<TransferError>,
42}
43
44impl<T: Kind> Ns16550<T> {
45 fn new(base: T, clock_freq: u32) -> Serial<Self> {
46 Serial::new(Self {
47 rcv_fifo: Deque::new(),
48 base,
49 clock_freq,
50 is_tx_empty_int_enabled: false,
51 err: None,
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
268 .rcv_fifo
269 .pop_front()
270 .expect("should check line status first"))
271 }
272
273 fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> {
274 if let Some(baudrate) = config.baudrate {
276 self.set_baudrate_internal(baudrate)?;
277 }
278
279 if let Some(data_bits) = config.data_bits {
281 self.set_data_bits_internal(data_bits)?;
282 }
283
284 if let Some(stop_bits) = config.stop_bits {
286 self.set_stop_bits_internal(stop_bits)?;
287 }
288
289 if let Some(parity) = config.parity {
291 self.set_parity_internal(parity)?;
292 }
293
294 Ok(())
295 }
296
297 fn baudrate(&self) -> u32 {
298 let dll = self.read_reg_u8(UART_DLL) as u16;
301 let dlh = self.read_reg_u8(UART_DLH) as u16;
302 let divisor = dll | (dlh << 8);
303
304 if divisor == 0 {
305 return 0;
306 }
307
308 self.clock_freq / (16 * divisor as u32)
309 }
310
311 fn data_bits(&self) -> DataBits {
312 let lcr: LineControlFlags = self.read_flags(UART_LCR);
313 let wlen = lcr & LineControlFlags::WORD_LENGTH_MASK;
314 if wlen == LineControlFlags::WORD_LENGTH_5 {
315 DataBits::Five
316 } else if wlen == LineControlFlags::WORD_LENGTH_6 {
317 DataBits::Six
318 } else if wlen == LineControlFlags::WORD_LENGTH_7 {
319 DataBits::Seven
320 } else {
321 DataBits::Eight }
323 }
324
325 fn stop_bits(&self) -> StopBits {
326 let lcr: LineControlFlags = self.read_flags(UART_LCR);
327 if lcr.contains(LineControlFlags::STOP_BITS) {
328 StopBits::Two
329 } else {
330 StopBits::One
331 }
332 }
333
334 fn parity(&self) -> Parity {
335 let lcr: LineControlFlags = self.read_flags(UART_LCR);
336
337 if !lcr.contains(LineControlFlags::PARITY_ENABLE) {
338 Parity::None
339 } else if lcr.contains(LineControlFlags::STICK_PARITY) {
340 if lcr.contains(LineControlFlags::EVEN_PARITY) {
342 Parity::Space
343 } else {
344 Parity::Mark
345 }
346 } else {
347 if lcr.contains(LineControlFlags::EVEN_PARITY) {
349 Parity::Even
350 } else {
351 Parity::Odd
352 }
353 }
354 }
355
356 fn open(&mut self) {
357 self.init();
358 }
359
360 fn close(&mut self) {
361 self.write_flags(UART_IER, InterruptEnableFlags::empty());
363
364 let mut mcr: ModemControlFlags = self.read_flags(UART_MCR);
366 mcr.remove(ModemControlFlags::DATA_TERMINAL_READY | ModemControlFlags::REQUEST_TO_SEND);
367 self.write_flags(UART_MCR, mcr);
368 }
369
370 fn clean_interrupt_status(&mut self) -> InterruptMask {
371 let iir: InterruptIdentificationFlags = self.read_flags(UART_IIR);
372 let mut mask = InterruptMask::empty();
373
374 if iir.contains(InterruptIdentificationFlags::NO_INTERRUPT_PENDING) {
376 return mask;
377 }
378
379 let interrupt_id = iir & InterruptIdentificationFlags::INTERRUPT_ID_MASK;
381
382 if interrupt_id == InterruptIdentificationFlags::RECEIVER_LINE_STATUS {
384 let lsr: LineStatusFlags = self.read_flags(UART_LSR);
386
387 let d = self.read_reg_u8(UART_RBR);
389
390 if lsr.contains(LineStatusFlags::OVERRUN_ERROR) {
392 self.err = Some(TransferError::Overrun(d));
393 mask |= InterruptMask::RX_AVAILABLE;
394 } else if lsr.contains(LineStatusFlags::PARITY_ERROR) {
395 self.err = Some(TransferError::Parity);
396 mask |= InterruptMask::RX_AVAILABLE;
397 } else if lsr.contains(LineStatusFlags::FRAMING_ERROR) {
398 self.err = Some(TransferError::Framing);
399 mask |= InterruptMask::RX_AVAILABLE;
400 } else if lsr.contains(LineStatusFlags::BREAK_INTERRUPT) {
401 self.err = Some(TransferError::Break);
402 mask |= InterruptMask::RX_AVAILABLE;
403 } else if lsr.contains(LineStatusFlags::DATA_READY) {
404 if self.rcv_fifo.push_back(d).is_err() {
406 self.err = Some(TransferError::Overrun(d));
407 }
408 mask |= InterruptMask::RX_AVAILABLE;
409 }
410 } else if interrupt_id == InterruptIdentificationFlags::RECEIVED_DATA_AVAILABLE
411 || interrupt_id == InterruptIdentificationFlags::CHARACTER_TIMEOUT
412 {
413 mask |= InterruptMask::RX_AVAILABLE;
415
416 while self
418 .read_flags::<LineStatusFlags>(UART_LSR)
419 .contains(LineStatusFlags::DATA_READY)
420 {
421 let d = self.read_reg_u8(UART_RBR);
422 if self.rcv_fifo.push_back(d).is_err() {
423 self.err = Some(TransferError::Overrun(d));
424 break;
425 }
426 }
427 } else if interrupt_id == InterruptIdentificationFlags::TRANSMITTER_HOLDING_EMPTY {
428 let mut ier: InterruptEnableFlags = self.read_flags(UART_IER);
432 ier.remove(InterruptEnableFlags::TRANSMITTER_HOLDING_EMPTY);
433 self.write_flags(UART_IER, ier);
434 if self.is_tx_empty_int_enabled {
435 mask |= InterruptMask::TX_EMPTY;
436 }
437 } else if interrupt_id == InterruptIdentificationFlags::MODEM_STATUS {
438 let _ = self.read_flags::<ModemStatusFlags>(UART_MSR);
440 }
441
442 mask
443 }
444
445 fn line_status(&mut self) -> LineStatus {
446 let lsr: LineStatusFlags = self.read_flags(UART_LSR);
447 let mut status = LineStatus::empty();
448 if self.err.is_some() {
449 status |= LineStatus::DATA_READY;
450 }
451
452 if lsr.contains(LineStatusFlags::TRANSMITTER_HOLDING_EMPTY) {
453 status |= LineStatus::TX_HOLDING_EMPTY;
454 }
455
456 if self
457 .read_flags::<InterruptEnableFlags>(UART_IER)
458 .contains(InterruptEnableFlags::RECEIVED_DATA_AVAILABLE)
459 {
460 if !self.rcv_fifo.is_empty() {
462 status |= LineStatus::DATA_READY;
463 }
464 } else {
465 if lsr.contains(LineStatusFlags::DATA_READY) {
467 let b = self.read_reg_u8(UART_RBR);
468 if self.rcv_fifo.push_back(b).is_err() {
469 self.err = Some(TransferError::Overrun(b));
470 }
471 status |= LineStatus::DATA_READY;
472 }
473 }
474
475 status
476 }
477
478 fn read_reg(&self, offset: usize) -> u32 {
479 self.read_reg_u8(offset as u8) as u32
480 }
481
482 fn write_reg(&mut self, offset: usize, value: u32) {
483 self.write_reg_u8(offset as u8, value as u8);
484 }
485
486 fn get_base(&self) -> usize {
487 self.base.get_base()
488 }
489
490 fn set_base(&mut self, base: usize) {
491 self.base.set_base(base);
492 }
493
494 fn clock_freq(&self) -> u32 {
495 self.clock_freq
496 }
497
498 fn enable_loopback(&mut self) {
499 let mut mcr: ModemControlFlags = self.read_flags(UART_MCR);
500 mcr.insert(ModemControlFlags::LOOPBACK_ENABLE);
501 self.write_flags(UART_MCR, mcr);
502 }
503
504 fn disable_loopback(&mut self) {
505 let mut mcr: ModemControlFlags = self.read_flags(UART_MCR);
506 mcr.remove(ModemControlFlags::LOOPBACK_ENABLE);
507 self.write_flags(UART_MCR, mcr);
508 }
509
510 fn is_loopback_enabled(&self) -> bool {
511 let mcr: ModemControlFlags = self.read_flags(UART_MCR);
512 mcr.contains(ModemControlFlags::LOOPBACK_ENABLE)
513 }
514
515 fn set_irq_mask(&mut self, mask: InterruptMask) {
516 let mut ier = InterruptEnableFlags::empty();
517 self.is_tx_empty_int_enabled = false;
518
519 if mask.contains(InterruptMask::RX_AVAILABLE) {
520 ier.insert(InterruptEnableFlags::RECEIVED_DATA_AVAILABLE);
521 ier.insert(InterruptEnableFlags::RECEIVER_LINE_STATUS);
522 }
523 if mask.contains(InterruptMask::TX_EMPTY) {
524 ier.insert(InterruptEnableFlags::TRANSMITTER_HOLDING_EMPTY);
525 self.is_tx_empty_int_enabled = true;
526 }
527
528 self.write_flags(UART_IER, ier);
529 }
530
531 fn get_irq_mask(&self) -> InterruptMask {
532 let ier: InterruptEnableFlags = self.read_flags(UART_IER);
533 let mut mask = InterruptMask::empty();
534
535 if ier.contains(InterruptEnableFlags::RECEIVED_DATA_AVAILABLE) {
536 mask |= InterruptMask::RX_AVAILABLE;
537 }
538 if self.is_tx_empty_int_enabled {
539 mask |= InterruptMask::TX_EMPTY;
540 }
541 mask
545 }
546}