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 for byte in buf.iter_mut() {
111 let w = nb::block!(<Self as embedded_hal_nb::serial::Read<u8>>::read(self))?;
112 *byte = w;
113 }
114
115 Ok(buf.len())
116 }
117}
118
119impl embedded_hal_nb::serial::Error for UartError {
120 #[inline]
121 fn kind(&self) -> embedded_hal_nb::serial::ErrorKind {
122 use embedded_hal_nb::serial::ErrorKind;
123
124 match self {
125 Self::ParityError => ErrorKind::Parity,
126 Self::FrameError => ErrorKind::FrameFormat,
127 Self::Overflow => ErrorKind::Overrun,
128 _ => ErrorKind::Other,
129 }
130 }
131}
132
133impl<C, D, R, T, W> embedded_hal_nb::serial::ErrorType for Uart<C, D, R, T>
134where
135 C: ValidConfig<Word = W>,
136 W: Copy,
137 D: Capability,
138{
139 type Error = UartError;
140}
141
142impl<C, D, R, T> embedded_hal_nb::serial::Read<C::Word> for Uart<C, D, R, T>
143where
144 C: ValidConfig,
145 D: Receive,
146 DataReg: AsPrimitive<C::Word>,
147{
148 #[inline]
149 fn read(&mut self) -> nb::Result<C::Word, Self::Error> {
150 let flags = self.read_flags_errors()?;
152 if flags.contains(Flags::RXC) {
153 unsafe { Ok(self.read_data().as_()) }
154 } else {
155 Err(WouldBlock)
156 }
157 }
158}
159
160impl<C, D, R, T> embedded_hal_nb::serial::Write<C::Word> for Uart<C, D, R, T>
161where
162 C: ValidConfig,
163 D: Transmit,
164{
165 #[inline]
167 fn write(&mut self, word: C::Word) -> nb::Result<(), Self::Error> {
168 if self.read_flags().contains(Flags::DRE) {
169 unsafe { self.write_data(word.as_()) };
170 Ok(())
171 } else {
172 Err(WouldBlock)
173 }
174 }
175
176 #[inline]
178 fn flush(&mut self) -> nb::Result<(), Self::Error> {
179 if self.read_flags().contains(Flags::TXC) {
180 self.clear_flags(Flags::TXC);
181 Ok(())
182 } else {
183 Err(WouldBlock)
184 }
185 }
186}
187
188#[cfg(feature = "dma")]
189mod dma {
190 use super::*;
191 use crate::{
192 dmac::{AnyChannel, Beat, Ready},
193 sercom::{
194 dma::{read_dma, write_dma, SercomPtr, SharedSliceBuffer},
195 Sercom,
196 },
197 };
198
199 impl<C, D, R, T, W> Uart<C, D, R, T>
200 where
201 C: ValidConfig<Word = W>,
202 D: Capability,
203 W: Beat,
204 {
205 pub(in super::super) fn sercom_ptr(&self) -> SercomPtr<W> {
206 SercomPtr(self.data_ptr())
207 }
208 }
209
210 impl<P, D, R, T, S> embedded_io::Write for Uart<Config<P, EightBit>, D, R, T>
211 where
212 P: ValidPads<Sercom = S>,
213 D: Transmit,
214 T: AnyChannel<Status = Ready>,
215 S: Sercom,
216 {
217 #[inline]
218 fn write(&mut self, bytes: &[u8]) -> Result<usize, Self::Error> {
219 let sercom_ptr = self.sercom_ptr();
220 let channel = self.tx_channel.as_mut();
221 let mut buffer = SharedSliceBuffer::from_slice(bytes);
222
223 unsafe {
224 write_dma::<_, _, S>(channel, sercom_ptr, &mut buffer);
225 }
226
227 while !channel.xfer_complete() {
228 core::hint::spin_loop();
229 }
230
231 while !self.read_flags().contains(Flags::TXC) {
232 core::hint::spin_loop();
233 }
234
235 Ok(bytes.len())
236 }
237
238 #[inline]
240 fn flush(&mut self) -> Result<(), Self::Error> {
241 nb::block!(<Self as embedded_hal_nb::serial::Write<u8>>::flush(self))?;
242 Ok(())
243 }
244 }
245
246 impl<P, D, R, T, S> embedded_io::Read for Uart<Config<P, EightBit>, D, R, T>
247 where
248 P: ValidPads<Sercom = S>,
249 D: Receive,
250 R: AnyChannel<Status = Ready>,
251 S: Sercom,
252 {
253 #[inline]
254 fn read(&mut self, mut buffer: &mut [u8]) -> Result<usize, Self::Error> {
255 if buffer.is_empty() {
256 return Ok(0);
257 }
258
259 let sercom_ptr = self.sercom_ptr();
260 let channel = self.rx_channel.as_mut();
261
262 unsafe {
263 read_dma::<_, _, S>(channel, sercom_ptr, &mut buffer);
264 }
265
266 while !channel.xfer_complete() {
267 core::hint::spin_loop();
268 }
269
270 while !self.read_flags().contains(Flags::RXC) {
271 core::hint::spin_loop();
272 }
273
274 self.read_flags_errors()?;
275
276 Ok(buffer.len())
277 }
278 }
279}