1#![cfg_attr(not(test), no_std)]
2
3extern crate alloc;
4
5use alloc::sync::Arc;
6use core::{
7 sync::atomic::{AtomicBool, Ordering},
8 task::Poll,
9};
10use futures::task::AtomicWaker;
11
12#[derive(Debug, Clone, Copy, Default)]
13pub struct IrqEvent {
14 pub can_get: bool,
15 pub can_put: bool,
16}
17
18#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
24#[non_exhaustive]
25pub enum ErrorKind {
26 Overrun,
28 FrameFormat,
31 Parity,
33 Noise,
35 Closed,
37 Other,
39}
40
41impl core::error::Error for ErrorKind {}
42
43impl core::fmt::Display for ErrorKind {
44 #[inline]
45 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
46 match self {
47 Self::Overrun => write!(f, "The peripheral receive buffer was overrun"),
48 Self::Parity => write!(f, "Parity check failed"),
49 Self::Noise => write!(f, "Serial line is too noisy to read valid data"),
50 Self::FrameFormat => write!(
51 f,
52 "Received data does not conform to the peripheral configuration"
53 ),
54 Self::Closed => write!(f, "Device was closed"),
55 Self::Other => write!(
56 f,
57 "A different error occurred. The original error may contain more information"
58 ),
59 }
60 }
61}
62
63pub trait Registers: Clone + 'static {
64 fn can_put(&self) -> bool;
65 fn put(&self, c: u8) -> Result<(), ErrorKind>;
66 fn can_get(&self) -> bool;
67 fn get(&self) -> Result<u8, ErrorKind>;
68 fn get_irq_event(&self) -> IrqEvent;
69 fn clean_irq_event(&self, event: IrqEvent);
70}
71
72pub struct Serial<R: Registers> {
73 registers: R,
74 tx: ChData,
75 rx: ChData,
76 pub irq_handler: Option<IrqHandler<R>>,
77}
78
79impl<R: Registers> Serial<R> {
80 pub fn new(registers: R) -> Self {
81 let tx = ChData::new();
82 let rx = ChData::new();
83
84 Self {
85 registers: registers.clone(),
86 tx: tx.clone(),
87 rx: rx.clone(),
88 irq_handler: Some(IrqHandler { registers, tx, rx }),
89 }
90 }
91
92 pub fn try_take_tx(&mut self) -> Option<Sender<R>> {
93 self.tx.try_take()?;
94
95 Some(Sender {
96 registers: self.registers.clone(),
97 data: self.tx.clone(),
98 })
99 }
100
101 pub fn try_take_rx(&mut self) -> Option<Receiver<R>> {
102 self.rx.try_take()?;
103
104 Some(Receiver {
105 registers: self.registers.clone(),
106 data: self.rx.clone(),
107 })
108 }
109
110 pub unsafe fn get_irq_event(&self) -> IrqEvent {
116 self.registers.get_irq_event()
117 }
118
119 pub unsafe fn clean_irq_event(&self, state: IrqEvent) {
125 self.registers.clean_irq_event(state);
126 }
127}
128
129pub struct IrqHandler<R: Registers> {
130 registers: R,
131 tx: ChData,
132 rx: ChData,
133}
134
135unsafe impl<R: Registers> Sync for IrqHandler<R> {}
136
137impl<R: Registers> IrqHandler<R> {
138 pub unsafe fn handle_irq(&self) {
143 let state = self.registers.get_irq_event();
144
145 if state.can_get {
146 self.rx.waker.wake();
147 }
148 if state.can_put {
149 self.tx.waker.wake();
150 }
151
152 self.registers.clean_irq_event(state);
153 }
154}
155
156unsafe impl<R: Registers> Send for Serial<R> {}
157unsafe impl<R: Registers> Send for Sender<R> {}
158unsafe impl<R: Registers> Send for Receiver<R> {}
159
160#[derive(Clone)]
161struct ChData {
162 taken: Arc<AtomicBool>,
163 waker: Arc<AtomicWaker>,
164}
165
166impl ChData {
167 fn new() -> Self {
168 Self {
169 taken: Arc::new(AtomicBool::new(false)),
170 waker: Arc::new(AtomicWaker::new()),
171 }
172 }
173
174 fn try_take(&self) -> Option<()> {
175 match self
176 .taken
177 .compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed)
178 {
179 Ok(taken) => {
180 if taken {
181 None
182 } else {
183 Some(())
184 }
185 }
186 Err(_) => None,
187 }
188 }
189}
190
191pub struct Sender<R: Registers> {
192 registers: R,
193 data: ChData,
194}
195
196impl<R: Registers> Sender<R> {
197 pub fn write(&mut self, buf: &[u8]) -> Result<usize, ErrorKind> {
198 let mut written = 0;
199 for &byte in buf {
200 if !self.registers.can_put() {
201 break;
202 }
203 self.registers.put(byte)?;
204 written += 1;
205 }
206 Ok(written)
207 }
208
209 pub fn can_put(&self) -> bool {
210 self.registers.can_put()
211 }
212
213 pub fn write_all(&mut self, buf: &[u8]) -> impl Future<Output = Result<(), ErrorKind>> {
214 WaitForWriteAll {
215 waiter: self.data.waker.clone(),
216 sender: self,
217 buf,
218 }
219 }
220}
221
222impl<R: Registers> Drop for Sender<R> {
223 fn drop(&mut self) {
224 self.data.taken.store(false, Ordering::Release);
225 }
226}
227
228pub struct Receiver<R: Registers> {
229 registers: R,
230 data: ChData,
231}
232
233impl<R: Registers> Receiver<R> {
234 pub fn read(&mut self, buf: &mut [u8]) -> Result<usize, ErrorKind> {
235 let mut read = 0;
236 for byte in buf {
237 if !self.registers.can_get() {
238 break;
239 }
240 *byte = self.registers.get()?;
241 read += 1;
242 }
243 Ok(read)
244 }
245
246 pub fn read_all(&mut self, buf: &mut [u8]) -> impl Future<Output = Result<(), ErrorKind>> {
247 WaitForReadAll {
248 waiter: self.data.waker.clone(),
249 rx: self,
250 buf,
251 i: 0,
252 }
253 }
254}
255
256impl<R: Registers> Drop for Receiver<R> {
257 fn drop(&mut self) {
258 self.data.taken.store(false, Ordering::Release);
259 }
260}
261
262struct WaitForWriteAll<'a, 'b, R: Registers> {
263 waiter: Arc<AtomicWaker>,
264 sender: &'a mut Sender<R>,
265 buf: &'b [u8],
266}
267
268impl<'a, 'b, R: Registers> Future for WaitForWriteAll<'a, 'b, R> {
269 type Output = Result<(), ErrorKind>;
270
271 fn poll(
272 mut self: core::pin::Pin<&mut Self>,
273 cx: &mut core::task::Context<'_>,
274 ) -> core::task::Poll<Self::Output> {
275 self.waiter.register(cx.waker());
276
277 let buf = self.buf;
278 match self.sender.write(buf) {
279 Ok(n) => {
280 self.buf = &buf[n..];
281 if n < buf.len() {
282 Poll::Pending
283 } else {
284 Poll::Ready(Ok(()))
285 }
286 }
287 Err(e) => Poll::Ready(Err(e)),
288 }
289 }
290}
291
292struct WaitForReadAll<'a, 'b, R: Registers> {
293 waiter: Arc<AtomicWaker>,
294 rx: &'a mut Receiver<R>,
295 buf: &'b mut [u8],
296 i: usize,
297}
298
299impl<'a, 'b, R: Registers> Future for WaitForReadAll<'a, 'b, R> {
300 type Output = Result<(), ErrorKind>;
301
302 fn poll(
303 mut self: core::pin::Pin<&mut Self>,
304 cx: &mut core::task::Context<'_>,
305 ) -> core::task::Poll<Self::Output> {
306 self.waiter.register(cx.waker());
307 let begin = self.i;
308 for i in begin..self.buf.len() {
309 if self.rx.registers.can_get() {
310 match self.rx.registers.get() {
311 Ok(b) => {
312 self.buf[i] = b;
313 self.i += 1;
314 }
315 Err(e) => {
316 return Poll::Ready(Err(e));
317 }
318 }
319 } else {
320 return Poll::Pending;
321 }
322 }
323 Poll::Ready(Ok(()))
324 }
325}