1use super::{
4 Capability, Config, DataReg, EightBit, Error, Error as UartError, Flags, Receive, Transmit,
5 Uart, ValidConfig, ValidPads,
6};
7use crate::{
8 ehal_02::{
9 blocking,
10 serial::{Read, Write},
11 },
12 typelevel::NoneT,
13};
14use nb::Error::WouldBlock;
15use num_traits::AsPrimitive;
16
17impl<C, D> Read<C::Word> for Uart<C, D>
18where
19 C: ValidConfig,
20 D: Receive,
21 DataReg: AsPrimitive<C::Word>,
22{
23 type Error = Error;
24
25 #[inline]
27 fn read(&mut self) -> nb::Result<C::Word, Error> {
28 <Self as embedded_hal_nb::serial::Read<C::Word>>::read(self)
29 }
30}
31
32impl<C, D> Write<C::Word> for Uart<C, D>
33where
34 C: ValidConfig,
35 D: Transmit,
36{
37 type Error = UartError;
38
39 #[inline]
41 fn write(&mut self, word: C::Word) -> nb::Result<(), Self::Error> {
42 <Self as embedded_hal_nb::serial::Write<C::Word>>::write(self, word)
43 }
44
45 #[inline]
47 fn flush(&mut self) -> nb::Result<(), Self::Error> {
48 <Self as embedded_hal_nb::serial::Write<C::Word>>::flush(self)
49 }
50}
51
52impl<C, D> blocking::serial::write::Default<C::Word> for Uart<C, D>
53where
54 C: ValidConfig,
55 D: Transmit,
56 Uart<C, D>: Write<C::Word>,
57{
58}
59
60impl embedded_io::Error for UartError {
61 #[inline]
62 fn kind(&self) -> embedded_io::ErrorKind {
63 embedded_io::ErrorKind::Other
64 }
65}
66
67impl<C, D, R, T> embedded_io::ErrorType for Uart<C, D, R, T>
68where
69 C: ValidConfig,
70 D: Capability,
71{
72 type Error = UartError;
73}
74
75impl<P, D, R> embedded_io::Write for Uart<Config<P, EightBit>, D, R, NoneT>
76where
77 P: ValidPads,
78 D: Transmit,
79{
80 #[inline]
81 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
82 for word in buf {
83 nb::block!(<Self as embedded_hal_nb::serial::Write<u8>>::write(
84 self, *word
85 ))?;
86 }
87
88 Ok(buf.len())
89 }
90
91 #[inline]
93 fn flush(&mut self) -> Result<(), Self::Error> {
94 nb::block!(<Self as embedded_hal_nb::serial::Write<u8>>::flush(self))?;
95 Ok(())
96 }
97}
98
99impl<P, D, T> embedded_io::Read for Uart<Config<P, EightBit>, D, NoneT, T>
100where
101 P: ValidPads,
102 D: Receive,
103{
104 #[inline]
105 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
106 if buf.is_empty() {
107 return Ok(0);
108 }
109
110 while !self.read_flags_errors()?.contains(Flags::RXC) {
111 core::hint::spin_loop();
112 }
113
114 let mut bytes_read = 0;
115
116 while self.read_flags_errors()?.contains(Flags::RXC) {
117 let w = nb::block!(<Self as embedded_hal_nb::serial::Read<u8>>::read(self))?;
118 buf[bytes_read] = w;
119 bytes_read += 1;
120 }
121
122 Ok(bytes_read)
123 }
124
125 #[inline]
126 fn read_exact(
127 &mut self,
128 buf: &mut [u8],
129 ) -> Result<(), embedded_io::ReadExactError<Self::Error>> {
130 if buf.is_empty() {
131 return Ok(());
132 }
133
134 for byte in buf.iter_mut() {
135 let w = nb::block!(<Self as embedded_hal_nb::serial::Read<u8>>::read(self))?;
136 *byte = w;
137 }
138
139 Ok(())
140 }
141}
142
143impl embedded_hal_nb::serial::Error for UartError {
144 #[inline]
145 fn kind(&self) -> embedded_hal_nb::serial::ErrorKind {
146 use embedded_hal_nb::serial::ErrorKind;
147
148 match self {
149 Self::ParityError => ErrorKind::Parity,
150 Self::FrameError => ErrorKind::FrameFormat,
151 Self::Overflow => ErrorKind::Overrun,
152 _ => ErrorKind::Other,
153 }
154 }
155}
156
157impl<C, D, R, T, W> embedded_hal_nb::serial::ErrorType for Uart<C, D, R, T>
158where
159 C: ValidConfig<Word = W>,
160 W: Copy,
161 D: Capability,
162{
163 type Error = UartError;
164}
165
166impl<C, D, R, T> embedded_hal_nb::serial::Read<C::Word> for Uart<C, D, R, T>
167where
168 C: ValidConfig,
169 D: Receive,
170 DataReg: AsPrimitive<C::Word>,
171{
172 #[inline]
173 fn read(&mut self) -> nb::Result<C::Word, Self::Error> {
174 let flags = self.read_flags_errors()?;
176 if flags.contains(Flags::RXC) {
177 unsafe { Ok(self.read_data().as_()) }
178 } else {
179 Err(WouldBlock)
180 }
181 }
182}
183
184impl<C, D, R, T> embedded_hal_nb::serial::Write<C::Word> for Uart<C, D, R, T>
185where
186 C: ValidConfig,
187 D: Transmit,
188{
189 #[inline]
191 fn write(&mut self, word: C::Word) -> nb::Result<(), Self::Error> {
192 if self.read_flags().contains(Flags::DRE) {
193 unsafe { self.write_data(word.as_()) };
194 Ok(())
195 } else {
196 Err(WouldBlock)
197 }
198 }
199
200 #[inline]
202 fn flush(&mut self) -> nb::Result<(), Self::Error> {
203 if self.read_flags().contains(Flags::TXC) {
204 self.clear_flags(Flags::TXC);
205 Ok(())
206 } else {
207 Err(WouldBlock)
208 }
209 }
210}
211
212#[cfg(feature = "dma")]
213mod dma {
214 use super::*;
215 use crate::{
216 dmac::{AnyChannel, Beat, Ready},
217 sercom::{
218 Sercom,
219 dma::{SercomPtr, SharedSliceBuffer, read_dma, write_dma},
220 },
221 };
222
223 impl<C, D, R, T, W> Uart<C, D, R, T>
224 where
225 C: ValidConfig<Word = W>,
226 D: Capability,
227 W: Beat,
228 {
229 pub(in super::super) fn sercom_ptr(&self) -> SercomPtr<W> {
230 SercomPtr(self.data_ptr())
231 }
232 }
233
234 impl<P, D, R, T, S> embedded_io::Write for Uart<Config<P, EightBit>, D, R, T>
235 where
236 P: ValidPads<Sercom = S>,
237 D: Transmit,
238 T: AnyChannel<Status = Ready>,
239 S: Sercom,
240 {
241 #[inline]
242 fn write(&mut self, bytes: &[u8]) -> Result<usize, Self::Error> {
243 let sercom_ptr = self.sercom_ptr();
244 let channel = self.tx_channel.as_mut();
245 let mut buffer = SharedSliceBuffer::from_slice(bytes);
246
247 unsafe {
248 write_dma::<_, _, S>(channel, sercom_ptr, &mut buffer);
249 }
250
251 while !channel.xfer_complete() {
252 core::hint::spin_loop();
253 }
254
255 while !self.read_flags().contains(Flags::TXC) {
256 core::hint::spin_loop();
257 }
258
259 Ok(bytes.len())
260 }
261
262 #[inline]
264 fn flush(&mut self) -> Result<(), Self::Error> {
265 nb::block!(<Self as embedded_hal_nb::serial::Write<u8>>::flush(self))?;
266 Ok(())
267 }
268 }
269
270 impl<P, D, R, T, S> embedded_io::Read for Uart<Config<P, EightBit>, D, R, T>
271 where
272 P: ValidPads<Sercom = S>,
273 D: Receive,
274 R: AnyChannel<Status = Ready>,
275 S: Sercom,
276 {
277 #[inline]
278 fn read(&mut self, mut buffer: &mut [u8]) -> Result<usize, Self::Error> {
279 if buffer.is_empty() {
280 return Ok(0);
281 }
282
283 let sercom_ptr = self.sercom_ptr();
284 let channel = self.rx_channel.as_mut();
285
286 unsafe {
287 read_dma::<_, _, S>(channel, sercom_ptr, &mut buffer);
288 }
289
290 while !channel.xfer_complete() {
291 core::hint::spin_loop();
292 }
293
294 while !self.read_flags().contains(Flags::RXC) {
295 core::hint::spin_loop();
296 }
297
298 self.read_flags_errors()?;
299
300 Ok(buffer.len())
301 }
302 }
303}