1use core::{fmt, mem};
29use nb::{block, Error::Other};
30use core::fmt::Write;
31
32#[derive(Debug)]
34pub enum Error {
35 Peripheral,
37 NoUplink,
39 NoDownlink,
41 BufferOverrun,
43}
44
45static mut SERIAL: Serial = Serial {
46 write: None,
47 read: None,
48};
49
50#[doc(hidden)]
51pub struct Serial {
52 write: Option<&'static mut dyn FnMut(u8) -> nb::Result<(), Error>>,
53 read: Option<&'static mut dyn FnMut() -> nb::Result<u8, Error>>,
54}
55
56impl Serial {
58 pub fn set_write<F>(write: F)
66 where F: FnMut(u8) -> nb::Result<(), Error> + 'static
67 {
68 static mut TX: [u8; 4] = [0; 4];
69 unsafe {
70 TX = mem::transmute(&write);
71 let write_ptr = &mut *(TX.as_mut_ptr() as *mut F);
72 SERIAL.write = Some(write_ptr);
73 }
74 }
75
76 pub fn set_read<F>(read: F)
81 where F: FnMut() -> nb::Result<u8, Error> + 'static
82 {
83 static mut RX: [u8; 4] = [0; 4];
84 unsafe {
85 RX = mem::transmute(&read);
86 let read_ptr = &mut *(RX.as_mut_ptr() as *mut F);
87 SERIAL.read = Some(read_ptr);
88 }
89 }
90
91 pub unsafe fn steal() -> &'static mut Self {
92 &mut SERIAL
93 }
94
95 #[doc(hidden)]
96 pub fn write(&mut self, byte: u8) -> nb::Result<(), Error> {
97 match &mut self.write {
98 Some(w) => (w)(byte),
99 _ => Err(nb::Error::Other(Error::NoUplink)),
100 }
101 }
102
103 #[doc(hidden)]
104 pub fn write_str(s: &str) {
105 let ser = unsafe { Serial::steal() };
106 ser.write_str(s).ok();
107 }
108
109 #[doc(hidden)]
110 pub fn write_fmt(arg: fmt::Arguments) {
111 let ser = unsafe { Serial::steal() };
112 ser.write_fmt(arg).ok();
113 }
114
115 #[doc(hidden)]
116 pub fn read(&mut self) -> nb::Result<u8, Error> {
117 match &mut self.read {
118 Some(r) => (r)(),
119 _ => Err(Other(Error::NoDownlink)),
120 }
121 }
122
123 #[doc(hidden)]
124 pub fn readln(&mut self, buffer: &mut [u8]) -> nb::Result<usize, Error> {
125 if self.read.is_none() {
126 return Err(Other(Error::NoDownlink));
127 }
128
129 for (i, item) in buffer.iter_mut().enumerate() {
130 let c = block!(self.read());
131 match c {
132 Ok(c) => match c {
133 b'\n' | b'\r' => return Ok(i),
134 b => {
135 *item = b;
136 },
137 },
138 Err(e) => return Err(Other(e)),
139 }
140 }
141 return Err(Other(Error::BufferOverrun));
142 }
143}
144
145impl fmt::Write for Serial
146{
147 fn write_str(&mut self, s: &str) -> fmt::Result {
148 s.as_bytes()
149 .iter()
150 .try_for_each(|c| block!(self.write(*c)))
151 .map_err(|_| fmt::Error)
152 }
153}
154
155#[macro_export]
157#[doc(hidden)]
158macro_rules! sprintln {
159 ($fmt:expr) => {
160 $crate::serial::Serial::write_str(concat!($fmt, "\r\n"));
161 };
162 ($fmt:expr, $($arg:tt)*) => {
163 $crate::serial::Serial::write_fmt(format_args!(concat!($fmt, "\r\n"), $($arg)*));
164 };
165}
166
167#[macro_export]
168#[doc(hidden)]
169macro_rules! sprint {
170 ($fmt:expr) => {
171 $crate::serial::Serial::write_str($fmt);
172 };
173 ($fmt:expr, $($arg:tt)*) => {
174 $crate::serial::Serial::write_fmt(format_args!($fmt, $($arg)*));
175 };
176}
177