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