L4Re Operating System Framework
Interface and Usage Documentation
•All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
uart_16550.h
1/*
2 * Copyright (C) 2008-2021 Technische Universität Dresden.
3 * Copyright (C) 2023-2024 Kernkonzept GmbH.
4 * Author(s): Adam Lackorzynski <adam@os.inf.tu-dresden.de>
5 * Alexander Warg <alexander.warg@os.inf.tu-dresden.de>
6 *
7 * License: see LICENSE.spdx (in this directory or the directories above)
8 */
9#pragma once
10
11#include "uart_base.h"
12
13namespace L4
14{
15 class Uart_16550 : public Uart
16 {
17 protected:
18 enum Registers
19 {
20 TRB = 0x00, // Transmit/Receive Buffer (read/write)
21 BRD_LOW = 0x00, // Baud Rate Divisor LSB if bit 7 of LCR is set (read/write)
22 IER = 0x01, // Interrupt Enable Register (read/write)
23 BRD_HIGH = 0x01, // Baud Rate Divisor MSB if bit 7 of LCR is set (read/write)
24 IIR = 0x02, // Interrupt Identification Register (read only)
25 FCR = 0x02, // 16550 FIFO Control Register (write only)
26 LCR = 0x03, // Line Control Register (read/write)
27 MCR = 0x04, // Modem Control Register (read/write)
28 LSR = 0x05, // Line Status Register (read only)
29 MSR = 0x06, // Modem Status Register (read only)
30 SPR = 0x07, // Scratch Pad Register (read/write)
31 };
32
33 enum Register_value_iir
34 {
35 IIR_BUSY = 7,
36 };
37
38 enum Register_value_lsr
39 {
40 LSR_DR = 0x01, // Receiver data ready
41 LSR_THRE = 0x20, // Transmit hold register empty
42 LSR_TSRE = 0x40, // Transmitter empty
43 };
44
45 enum Init_values
46 {
47#ifdef UART_16550_INIT_MCR
48 Init_mcr = UART_16550_INIT_MCR,
49#else
50 Init_mcr = 0,
51#endif
52#ifdef UART_16550_INIT_IER
53 Init_ier = UART_16550_INIT_IER,
54#else
55 Init_ier = 0,
56#endif
57#ifdef UART_16550_INIT_FCR
58 Init_fcr = UART_16550_INIT_FCR,
59#else
60 Init_fcr = 0,
61#endif
62 };
63
64 public:
65 enum
66 {
67 PAR_NONE = 0x00,
68 PAR_EVEN = 0x18,
69 PAR_ODD = 0x08,
70 DAT_5 = 0x00,
71 DAT_6 = 0x01,
72 DAT_7 = 0x02,
73 DAT_8 = 0x03,
74 STOP_1 = 0x00,
75 STOP_2 = 0x04,
76
77 MODE_8N1 = PAR_NONE | DAT_8 | STOP_1,
78 MODE_7E1 = PAR_EVEN | DAT_7 | STOP_1,
79
80 // these two values are to leave either mode
81 // or baud rate unchanged on a call to change_mode
82 MODE_NC = 0x1000000,
83 BAUD_NC = 0x1000000,
84
85 Base_rate_x86 = 115200,
86 Base_rate_pxa = 921600,
87 };
88
89 explicit Uart_16550(unsigned long base_rate, unsigned char init_flags = 0,
90 unsigned char ier_bits = Init_ier,
91 unsigned char mcr_bits = Init_mcr,
92 unsigned char fcr_bits = Init_fcr)
93 : _base_rate(base_rate), _init_flags(init_flags), _mcr_bits(mcr_bits),
94 _ier_bits(ier_bits), _fcr_bits(fcr_bits)
95 {}
96
97 bool startup(Io_register_block const *regs) override;
98 void shutdown() override;
99 bool change_mode(Transfer_mode m, Baud_rate r) override;
100 int get_char(bool blocking = true) const override;
101 int char_avail() const override;
102 int tx_avail() const;
103 void wait_tx_done() const;
104 inline void out_char(char c) const;
105 int write(char const *s, unsigned long count,
106 bool blocking = true) const override;
107 bool enable_rx_irq(bool enable = true) override;
108
109 private:
110 unsigned long _base_rate;
111 unsigned char _init_flags;
112 unsigned char _mcr_bits;
113 unsigned char _ier_bits;
114 unsigned char _fcr_bits;
115 };
116}
L4 low-level kernel interface.