mycelium_kernel/drivers/
serial_input.rs1use maitake::sync::WaitQueue;
2use mycelium_util::sync::InitOnce;
3
4pub struct SerialInput {
5 buf: thingbuf::StaticThingBuf<Option<u8>, 128>,
8 waiters: WaitQueue,
9}
10
11impl SerialInput {
12 pub fn new() -> Self {
13 Self {
14 buf: thingbuf::StaticThingBuf::new(),
15 waiters: WaitQueue::new(),
16 }
17 }
18}
19
20impl Default for SerialInput {
21 fn default() -> Self {
22 Self::new()
23 }
24}
25
26pub static SERIAL_INPUTS: InitOnce<alloc::vec::Vec<SerialInput>> = InitOnce::uninitialized();
27
28impl SerialInput {
29 pub async fn next_byte(&self) -> u8 {
30 if let Some(byte) = self.buf.pop() {
31 return byte.expect("buffer contains somes");
32 }
33
34 self.waiters
35 .wait()
36 .await
37 .expect("serial waiters should never be closed FOR NOW");
38 self.buf
39 .pop()
40 .expect("just got woken up wtf")
41 .expect("buffer contains somes")
42 }
43
44 pub fn handle_input(&self, byte: u8) {
45 if let Err(byte) = self.buf.push(Some(byte)) {
46 tracing::warn!(?byte, "serial buffer full, dropping byte!")
51 } else {
52 self.waiters.wake_all();
54 }
55 }
56}