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(b) = self.rcv_fifo.pop() {
265 return Ok(b);
266 }
267 if let Some(e) = self.err.take() {
268 return Err(e);
269 }
270 Ok(self.read_reg_u8(UART_RBR))
272 }
273
274 fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> {
275 if let Some(baudrate) = config.baudrate {
277 self.set_baudrate_internal(baudrate)?;
278 }
279
280 if let Some(data_bits) = config.data_bits {
282 self.set_data_bits_internal(data_bits)?;
283 }
284
285 if let Some(stop_bits) = config.stop_bits {
287 self.set_stop_bits_internal(stop_bits)?;
288 }
289
290 if let Some(parity) = config.parity {
292 self.set_parity_internal(parity)?;
293 }
294
295 Ok(())
296 }
297
298 fn baudrate(&self) -> u32 {
299 let dll = self.read_reg_u8(UART_DLL) as u16;
302 let dlh = self.read_reg_u8(UART_DLH) as u16;
303 let divisor = dll | (dlh << 8);
304
305 if divisor == 0 {
306 return 0;
307 }
308
309 self.clock_freq / (16 * divisor as u32)
310 }
311
312 fn data_bits(&self) -> DataBits {
313 let lcr: LineControlFlags = self.read_flags(UART_LCR);
314 let wlen = lcr & LineControlFlags::WORD_LENGTH_MASK;
315 if wlen == LineControlFlags::WORD_LENGTH_5 {
316 DataBits::Five
317 } else if wlen == LineControlFlags::WORD_LENGTH_6 {
318 DataBits::Six
319 } else if wlen == LineControlFlags::WORD_LENGTH_7 {
320 DataBits::Seven
321 } else {
322 DataBits::Eight }
324 }
325
326 fn stop_bits(&self) -> StopBits {
327 let lcr: LineControlFlags = self.read_flags(UART_LCR);
328 if lcr.contains(LineControlFlags::STOP_BITS) {
329 StopBits::Two
330 } else {
331 StopBits::One
332 }
333 }
334
335 fn parity(&self) -> Parity {
336 let lcr: LineControlFlags = self.read_flags(UART_LCR);
337
338 if !lcr.contains(LineControlFlags::PARITY_ENABLE) {
339 Parity::None
340 } else if lcr.contains(LineControlFlags::STICK_PARITY) {
341 if lcr.contains(LineControlFlags::EVEN_PARITY) {
343 Parity::Space
344 } else {
345 Parity::Mark
346 }
347 } else {
348 if lcr.contains(LineControlFlags::EVEN_PARITY) {
350 Parity::Even
351 } else {
352 Parity::Odd
353 }
354 }
355 }
356
357 fn open(&mut self) {
358 self.init();
359 }
360
361 fn close(&mut self) {
362 self.write_flags(UART_IER, InterruptEnableFlags::empty());
364
365 let mut mcr: ModemControlFlags = self.read_flags(UART_MCR);
367 mcr.remove(ModemControlFlags::DATA_TERMINAL_READY | ModemControlFlags::REQUEST_TO_SEND);
368 self.write_flags(UART_MCR, mcr);
369 }
370
371 fn clean_interrupt_status(&mut self) -> InterruptMask {
372 let iir: InterruptIdentificationFlags = self.read_flags(UART_IIR);
373 let mut mask = InterruptMask::empty();
374
375 if iir.contains(InterruptIdentificationFlags::NO_INTERRUPT_PENDING) {
377 return mask;
378 }
379
380 let interrupt_id = iir & InterruptIdentificationFlags::INTERRUPT_ID_MASK;
382
383 if interrupt_id == InterruptIdentificationFlags::RECEIVER_LINE_STATUS {
384 let lsr: LineStatusFlags = self.read_flags(UART_LSR);
385
386 let d = self.read_reg_u8(UART_RBR);
388
389 if lsr.contains(LineStatusFlags::OVERRUN_ERROR) {
391 self.err = Some(TransferError::Overrun(d));
392 mask |= InterruptMask::RX_AVAILABLE;
393 } else if lsr.contains(LineStatusFlags::PARITY_ERROR) {
394 self.err = Some(TransferError::Parity);
395 mask |= InterruptMask::RX_AVAILABLE;
396 } else if lsr.contains(LineStatusFlags::FRAMING_ERROR) {
397 self.err = Some(TransferError::Framing);
398 mask |= InterruptMask::RX_AVAILABLE;
399 } else if lsr.contains(LineStatusFlags::BREAK_INTERRUPT) {
400 self.err = Some(TransferError::Break);
401 mask |= InterruptMask::RX_AVAILABLE;
402 }
403 } else if interrupt_id == InterruptIdentificationFlags::RECEIVED_DATA_AVAILABLE
404 || interrupt_id == InterruptIdentificationFlags::CHARACTER_TIMEOUT
405 {
406 let d = self.read_reg_u8(UART_RBR);
408 mask |= InterruptMask::RX_AVAILABLE;
409 if self.rcv_fifo.push(d).is_err() {
410 self.err = Some(TransferError::Overrun(d));
411 }
412 } else if interrupt_id == InterruptIdentificationFlags::TRANSMITTER_HOLDING_EMPTY {
413 let mut ier: InterruptEnableFlags = self.read_flags(UART_IER);
417 ier.remove(InterruptEnableFlags::TRANSMITTER_HOLDING_EMPTY);
418 self.write_flags(UART_IER, ier);
419
420 mask |= InterruptMask::TX_EMPTY;
421 } else if interrupt_id == InterruptIdentificationFlags::MODEM_STATUS {
422 let _ = self.read_flags::<ModemStatusFlags>(UART_MSR);
424 }
425
426 mask
427 }
428
429 fn line_status(&mut self) -> LineStatus {
430 let lsr: LineStatusFlags = self.read_flags(UART_LSR);
431 let mut status = LineStatus::empty();
432
433 if lsr.contains(LineStatusFlags::DATA_READY) {
434 status |= LineStatus::DATA_READY;
435 }
436 if lsr.contains(LineStatusFlags::TRANSMITTER_HOLDING_EMPTY) {
437 status |= LineStatus::TX_HOLDING_EMPTY;
438 }
439
440 status
441 }
442
443 fn read_reg(&self, offset: usize) -> u32 {
444 self.read_reg_u8(offset as u8) as u32
445 }
446
447 fn write_reg(&mut self, offset: usize, value: u32) {
448 self.write_reg_u8(offset as u8, value as u8);
449 }
450
451 fn get_base(&self) -> usize {
452 self.base.get_base()
453 }
454
455 fn set_base(&mut self, base: usize) {
456 self.base.set_base(base);
457 }
458
459 fn clock_freq(&self) -> u32 {
460 self.clock_freq
461 }
462
463 fn enable_loopback(&mut self) {
464 let mut mcr: ModemControlFlags = self.read_flags(UART_MCR);
465 mcr.insert(ModemControlFlags::LOOPBACK_ENABLE);
466 self.write_flags(UART_MCR, mcr);
467 }
468
469 fn disable_loopback(&mut self) {
470 let mut mcr: ModemControlFlags = self.read_flags(UART_MCR);
471 mcr.remove(ModemControlFlags::LOOPBACK_ENABLE);
472 self.write_flags(UART_MCR, mcr);
473 }
474
475 fn is_loopback_enabled(&self) -> bool {
476 let mcr: ModemControlFlags = self.read_flags(UART_MCR);
477 mcr.contains(ModemControlFlags::LOOPBACK_ENABLE)
478 }
479
480 fn set_irq_mask(&mut self, mask: InterruptMask) {
481 let mut ier = InterruptEnableFlags::empty();
482 self.is_tx_empty_int_enabled = false;
483
484 if mask.contains(InterruptMask::RX_AVAILABLE) {
485 ier.insert(InterruptEnableFlags::RECEIVED_DATA_AVAILABLE);
486 ier.insert(InterruptEnableFlags::RECEIVER_LINE_STATUS);
487 }
488 if mask.contains(InterruptMask::TX_EMPTY) {
489 ier.insert(InterruptEnableFlags::TRANSMITTER_HOLDING_EMPTY);
490 self.is_tx_empty_int_enabled = true;
491 }
492
493 self.write_flags(UART_IER, ier);
494 }
495
496 fn get_irq_mask(&self) -> InterruptMask {
497 let ier: InterruptEnableFlags = self.read_flags(UART_IER);
498 let mut mask = InterruptMask::empty();
499
500 if ier.contains(InterruptEnableFlags::RECEIVED_DATA_AVAILABLE) {
501 mask |= InterruptMask::RX_AVAILABLE;
502 }
503 if self.is_tx_empty_int_enabled {
504 mask |= InterruptMask::TX_EMPTY;
505 }
506 mask
510 }
511}