SimpleKernel 1.17.0
Loading...
Searching...
No Matches
ns16550a.hpp
Go to the documentation of this file.
1
5#pragma once
6
7#include <cstdint>
8#include <optional>
9
10#include "expected.hpp"
11#include "mmio_accessor.hpp"
12
13namespace ns16550a {
14
23class Ns16550a {
24 public:
30 [[nodiscard]] static auto Create(uint64_t dev_addr) -> Expected<Ns16550a> {
31 if (dev_addr == 0) {
32 return std::unexpected(Error{ErrorCode::kInvalidArgument});
33 }
34
35 Ns16550a uart(dev_addr);
36
37 // UART 初始化序列
38 uart.mmio_.Write<uint8_t>(kRegIER, 0x00); // 禁用所有中断
39 uart.mmio_.Write<uint8_t>(kRegLCR, 0x80); // 启用 DLAB(设置波特率)
40 uart.mmio_.Write<uint8_t>(kUartDLL, 0x03); // 波特率低字节(38400)
41 uart.mmio_.Write<uint8_t>(kUartDLM, 0x00); // 波特率高字节
42 uart.mmio_.Write<uint8_t>(kRegLCR, 0x03); // 8 位,无校验,1 停止位
43 uart.mmio_.Write<uint8_t>(kRegFCR, 0x07); // 启用并清除 FIFO
44 uart.mmio_.Write<uint8_t>(kRegIER, 0x01); // 启用接收中断
45
46 return uart;
47 }
48
53 auto PutChar(uint8_t c) const -> void {
54 while ((mmio_.Read<uint8_t>(kRegLSR) & (1 << 5)) == 0) {
55 }
56 mmio_.Write<uint8_t>(kRegTHR, c);
57 }
58
63 [[nodiscard]] auto GetChar() const -> uint8_t {
64 while ((mmio_.Read<uint8_t>(kRegLSR) & (1 << 0)) == 0) {
65 }
66 return mmio_.Read<uint8_t>(kRegRHR);
67 }
68
73 [[nodiscard]] auto TryGetChar() const -> std::optional<uint8_t> {
74 if ((mmio_.Read<uint8_t>(kRegLSR) & (1 << 0)) != 0) {
75 return mmio_.Read<uint8_t>(kRegRHR);
76 }
77 return std::nullopt;
78 }
79
84 [[nodiscard]] auto HasData() const -> bool {
85 return (mmio_.Read<uint8_t>(kRegLSR) & (1 << 0)) != 0;
86 }
87
101 [[nodiscard]] auto GetInterruptId() const -> uint8_t {
102 return mmio_.Read<uint8_t>(kRegISR);
103 }
104
109 [[nodiscard]] auto IsInterruptPending() const -> bool {
110 return (mmio_.Read<uint8_t>(kRegISR) & 0x01) == 0;
111 }
112
115 Ns16550a() = default;
116 Ns16550a(const Ns16550a&) = delete;
117 Ns16550a(Ns16550a&&) = default;
118 auto operator=(const Ns16550a&) -> Ns16550a& = delete;
119 auto operator=(Ns16550a&&) -> Ns16550a& = default;
120 ~Ns16550a() = default;
122
123 private:
125 static constexpr uint8_t kRegRHR = 0;
127 static constexpr uint8_t kRegTHR = 0;
129 static constexpr uint8_t kRegIER = 1;
131 static constexpr uint8_t kRegFCR = 2;
133 static constexpr uint8_t kRegISR = 2;
135 static constexpr uint8_t kRegLCR = 3;
137 static constexpr uint8_t kRegMCR = 4;
139 static constexpr uint8_t kRegLSR = 5;
141 static constexpr uint8_t kRegMSR = 6;
142
144 static constexpr uint8_t kUartDLL = 0;
146 static constexpr uint8_t kUartDLM = 1;
147
149
150 explicit Ns16550a(uint64_t dev_addr) : mmio_(dev_addr) {}
151};
152
153} // namespace ns16550a
NS16550A 串口驱动
Definition ns16550a.hpp:23
auto TryGetChar() const -> std::optional< uint8_t >
非阻塞式尝试读取一个字符
Definition ns16550a.hpp:73
static constexpr uint8_t kRegTHR
write mode: Transmit Holding Reg
Definition ns16550a.hpp:127
auto PutChar(uint8_t c) const -> void
写入一个字符
Definition ns16550a.hpp:53
static constexpr uint8_t kRegIER
write mode: interrupt enable reg
Definition ns16550a.hpp:129
Ns16550a(const Ns16550a &)=delete
static constexpr uint8_t kUartDLM
MSB of divisor Latch when enabled.
Definition ns16550a.hpp:146
auto operator=(const Ns16550a &) -> Ns16550a &=delete
static constexpr uint8_t kRegLSR
read mode: Line Status Reg
Definition ns16550a.hpp:139
Ns16550a(Ns16550a &&)=default
static constexpr uint8_t kRegISR
read mode: Interrupt Status Reg
Definition ns16550a.hpp:133
static constexpr uint8_t kRegMCR
write mode: Modem Control Reg
Definition ns16550a.hpp:137
static constexpr uint8_t kRegFCR
write mode: FIFO control Reg
Definition ns16550a.hpp:131
static auto Create(uint64_t dev_addr) -> Expected< Ns16550a >
工厂方法:创建并初始化 NS16550A 驱动
Definition ns16550a.hpp:30
MmioAccessor mmio_
Definition ns16550a.hpp:148
Ns16550a(uint64_t dev_addr)
Definition ns16550a.hpp:150
auto HasData() const -> bool
检查接收缓冲区是否有数据可读(不消耗数据)
Definition ns16550a.hpp:84
static constexpr uint8_t kRegMSR
read mode: Modem Status Reg
Definition ns16550a.hpp:141
auto GetChar() const -> uint8_t
阻塞式读取一个字符
Definition ns16550a.hpp:63
static constexpr uint8_t kRegLCR
write mode: Line Control Reg
Definition ns16550a.hpp:135
auto operator=(Ns16550a &&) -> Ns16550a &=default
auto IsInterruptPending() const -> bool
检查是否有中断挂起
Definition ns16550a.hpp:109
static constexpr uint8_t kRegRHR
read mode: Receive holding reg
Definition ns16550a.hpp:125
auto GetInterruptId() const -> uint8_t
读取中断标识寄存器(ISR / IIR)
Definition ns16550a.hpp:101
static constexpr uint8_t kUartDLL
LSB of divisor Latch when enabled.
Definition ns16550a.hpp:144
@ kInvalidArgument
std::expected< T, Error > Expected
std::expected 别名模板
Definition expected.hpp:365
错误类型,用于 std::expected
Definition expected.hpp:343
通用 MMIO 寄存器访问器
auto Write(size_t offset, T val) const -> void
Write to MMIO register.
auto Read(size_t offset) const -> T
Read from MMIO register.
volatile uint8_t * uart
TODO: Add description.
Definition main.cpp:10