1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
// Copyright (c) 2026 taitep
// SPDX-License-Identifier: BSD-2-Clause
//
// This file is part of TRVE (https://gitea.taitep.se/taitep/trve)
// See LICENSE file in the project root for full license text.
use std::io::{self, Read, Write};
pub struct UartFifo<const CAP: usize> {
buf: [u8; CAP],
head: usize,
tail: usize,
len: usize,
}
impl<const CAP: usize> UartFifo<CAP> {
pub fn pop_single_byte(&mut self) -> Option<u8> {
if self.is_empty() {
return None;
}
let value = self.buf[self.tail];
self.advance_read(1);
Some(value)
}
pub fn push_single_byte(&mut self, value: u8) -> bool {
if self.is_full() {
return false;
}
self.buf[self.head] = value;
self.advance_write(1);
true
}
pub fn is_empty(&self) -> bool {
self.len == 0
}
pub fn is_full(&self) -> bool {
self.len == CAP
}
fn write_slice(&mut self) -> &mut [u8] {
if self.is_full() {
return &mut [];
}
if self.head >= self.tail {
&mut self.buf[self.head..]
} else {
&mut self.buf[self.head..self.tail]
}
}
fn advance_write(&mut self, n: usize) {
debug_assert!(n <= CAP - self.len);
self.head = (self.head + n) % CAP;
self.len += n;
}
fn read_slice(&self) -> &[u8] {
if self.is_empty() {
return &[];
}
if self.tail < self.head {
&self.buf[self.tail..self.head]
} else {
&self.buf[self.tail..]
}
}
fn advance_read(&mut self, n: usize) {
debug_assert!(n <= self.len);
self.tail = (self.tail + n) % CAP;
self.len -= n;
}
pub fn read_from<R: Read>(&mut self, reader: &mut R) -> io::Result<usize> {
let slice = self.write_slice();
if slice.is_empty() {
return Ok(0);
}
let n = reader.read(slice)?;
self.advance_write(n);
Ok(n)
}
pub fn write_to<W: Write>(&mut self, writer: &mut W) -> io::Result<usize> {
let slice = self.read_slice();
if slice.is_empty() {
return Ok(0);
}
let n = writer.write(slice)?;
self.advance_read(n);
Ok(n)
}
}
impl<const SIZE: usize> Default for UartFifo<SIZE> {
fn default() -> Self {
UartFifo {
buf: [0; SIZE],
head: 0,
tail: 0,
len: 0,
}
}
}
|