SimpleKernel 1.17.0
Loading...
Searching...
No Matches
pl011.hpp
Go to the documentation of this file.
1
5#pragma once
6
7#include <cstdint>
8#include <optional>
9
10#include "mmio_accessor.hpp"
11
12namespace pl011 {
13
22class Pl011 {
23 public:
28 auto PutChar(uint8_t c) const -> void {
29 while (mmio_.Read<uint32_t>(kRegFR) & kFRTxFIFO) {
30 }
31 mmio_.Write<uint32_t>(kRegDR, c);
32 }
33
38 [[nodiscard]] auto GetChar() const -> uint8_t {
39 while (mmio_.Read<uint32_t>(kRegFR) & kFRRXFE) {
40 }
41 return static_cast<uint8_t>(mmio_.Read<uint32_t>(kRegDR));
42 }
43
48 [[nodiscard]] auto TryGetChar() const -> std::optional<uint8_t> {
49 if (mmio_.Read<uint32_t>(kRegFR) & kFRRXFE) {
50 return std::nullopt;
51 }
52 return static_cast<uint8_t>(mmio_.Read<uint32_t>(kRegDR));
53 }
54
59 [[nodiscard]] auto HasData() const -> bool {
60 return !(mmio_.Read<uint32_t>(kRegFR) & kFRRXFE);
61 }
62
71 [[nodiscard]] auto GetMaskedInterruptStatus() const -> uint32_t {
72 return mmio_.Read<uint32_t>(kRegMIS);
73 }
74
82 [[nodiscard]] auto GetRawInterruptStatus() const -> uint32_t {
83 return mmio_.Read<uint32_t>(kRegRIS);
84 }
85
93 auto ClearInterrupt(uint32_t mask) const -> void {
94 mmio_.Write<uint32_t>(kRegICR, mask);
95 }
96
101 [[nodiscard]] auto IsInterruptPending() const -> bool {
102 return GetMaskedInterruptStatus() != 0;
103 }
104
109 template <typename Callback>
110 auto HandleInterrupt(Callback&& callback) -> void {
111 while (HasData()) {
112 callback(GetChar());
113 }
114 }
115
118
124 explicit Pl011(uint64_t dev_addr, uint64_t clock = 0, uint64_t baud_rate = 0)
125 : mmio_(dev_addr), base_clock_(clock), baud_rate_(baud_rate) {
126 mmio_.Write<uint32_t>(kRegRSRECR, 0);
127 mmio_.Write<uint32_t>(kRegCR, 0);
128
129 if (baud_rate_ != 0) {
130 uint32_t divisor = (base_clock_ * 4) / baud_rate_;
131 mmio_.Write<uint32_t>(kRegIBRD, divisor >> 6);
132 mmio_.Write<uint32_t>(kRegFBRD, divisor & 0x3f);
133 }
134
135 mmio_.Write<uint32_t>(kRegLCRH, kLCRHWlen8);
136 mmio_.Write<uint32_t>(kRegIMSC, kIMSCRxim);
138 }
139 Pl011() = default;
140 Pl011(const Pl011&) = delete;
141 Pl011(Pl011&&) = default;
142 auto operator=(const Pl011&) -> Pl011& = delete;
143 auto operator=(Pl011&&) -> Pl011& = default;
144 ~Pl011() = default;
146
147 private:
149 static constexpr uint32_t kRegDR = 0x00;
151 static constexpr uint32_t kRegRSRECR = 0x04;
153 static constexpr uint32_t kRegFR = 0x18;
155 static constexpr uint32_t kRegIBRD = 0x24;
157 static constexpr uint32_t kRegFBRD = 0x28;
159 static constexpr uint32_t kRegLCRH = 0x2C;
161 static constexpr uint32_t kRegCR = 0x30;
163 static constexpr uint32_t kRegIMSC = 0x38;
165 static constexpr uint32_t kRegRIS = 0x3C;
167 static constexpr uint32_t kRegMIS = 0x40;
169 static constexpr uint32_t kRegICR = 0x44;
170
172 static constexpr uint32_t kFRTxFIFO = (1 << 5);
173 static constexpr uint32_t kFRRXFE = (1 << 4);
174
176 static constexpr uint32_t kLCRHWlen8 = (3 << 5);
177
179 static constexpr uint32_t kCREnable = (1 << 0);
180 static constexpr uint32_t kCRTxEnable = (1 << 8);
181 static constexpr uint32_t kCRRxEnable = (1 << 9);
182
184 static constexpr uint32_t kIMSCRxim = (1 << 4);
185
187 uint64_t base_clock_{0};
188 uint64_t baud_rate_{0};
189};
190
191} // namespace pl011
PL011 串口驱动
Definition pl011.hpp:22
static constexpr uint32_t kRegRSRECR
receive status or error clear
Definition pl011.hpp:151
auto PutChar(uint8_t c) const -> void
写入一个字符
Definition pl011.hpp:28
static constexpr uint32_t kRegIBRD
integer baud register
Definition pl011.hpp:155
Pl011(uint64_t dev_addr, uint64_t clock=0, uint64_t baud_rate=0)
构造函数
Definition pl011.hpp:124
Pl011(Pl011 &&)=default
auto HasData() const -> bool
检查接收缓冲区是否有数据可读(不消耗数据)
Definition pl011.hpp:59
Pl011()=default
static constexpr uint32_t kLCRHWlen8
line control register bits
Definition pl011.hpp:176
static constexpr uint32_t kFRRXFE
Definition pl011.hpp:173
static constexpr uint32_t kRegCR
control register
Definition pl011.hpp:161
auto operator=(const Pl011 &) -> Pl011 &=delete
auto GetChar() const -> uint8_t
阻塞式读取一个字符
Definition pl011.hpp:38
MmioAccessor mmio_
Definition pl011.hpp:186
Pl011(const Pl011 &)=delete
auto GetMaskedInterruptStatus() const -> uint32_t
读取屏蔽后的中断状态寄存器(MIS)
Definition pl011.hpp:71
static constexpr uint32_t kRegIMSC
interrupt mask set/clear
Definition pl011.hpp:163
static constexpr uint32_t kCREnable
control register bits
Definition pl011.hpp:179
static constexpr uint32_t kRegLCRH
line control register
Definition pl011.hpp:159
auto HandleInterrupt(Callback &&callback) -> void
处理串口接收中断,对每个收到的字符调用回调
Definition pl011.hpp:110
uint64_t baud_rate_
Definition pl011.hpp:188
static constexpr uint32_t kRegDR
data register
Definition pl011.hpp:149
static constexpr uint32_t kRegMIS
masked interrupt status register
Definition pl011.hpp:167
static constexpr uint32_t kRegFBRD
fractional baud register
Definition pl011.hpp:157
static constexpr uint32_t kCRTxEnable
Definition pl011.hpp:180
auto operator=(Pl011 &&) -> Pl011 &=default
auto TryGetChar() const -> std::optional< uint8_t >
非阻塞式尝试读取一个字符
Definition pl011.hpp:48
auto ClearInterrupt(uint32_t mask) const -> void
清除指定中断
Definition pl011.hpp:93
static constexpr uint32_t kRegRIS
raw interrupt status register
Definition pl011.hpp:165
static constexpr uint32_t kRegFR
flag register
Definition pl011.hpp:153
auto IsInterruptPending() const -> bool
检查是否有中断挂起
Definition pl011.hpp:101
static constexpr uint32_t kRegICR
interrupt clear register
Definition pl011.hpp:169
static constexpr uint32_t kCRRxEnable
Definition pl011.hpp:181
uint64_t base_clock_
Definition pl011.hpp:187
static constexpr uint32_t kIMSCRxim
interrupt mask bits
Definition pl011.hpp:184
static constexpr uint32_t kFRTxFIFO
flag register bits
Definition pl011.hpp:172
auto GetRawInterruptStatus() const -> uint32_t
读取原始中断状态寄存器(RIS)
Definition pl011.hpp:82
~Pl011()=default
通用 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.