1#![no_std]
2#![doc = include_str!("../README.md")]
3
4use core::{
5 future::Future,
6 ptr::NonNull,
7 sync::atomic::{fence, Ordering},
8};
9
10use bitflags::bitflags;
11use embedded_io::ErrorType;
12use spin_on::spin_on;
13use tock_registers::{
14 fields::FieldValue, interfaces::*, register_bitfields, register_structs, registers::*,
15};
16
17#[derive(Debug)]
18pub enum ErrorKind {
19 Framing,
20 Parity,
21 Break,
22 Overrun,
23}
24
25register_bitfields! [
26 u32,
28
29 Data [
30 DATA OFFSET(0) NUMBITS(8) [],
31 FRAMING_ERROR OFFSET(8) NUMBITS(1) [],
32 PARITY_ERROR OFFSET(9) NUMBITS(1) [],
33 BREAK_ERROR OFFSET(10) NUMBITS(1) [],
34 OVERRUN_ERROR OFFSET(11) NUMBITS(1) [],
35 ],
36
37 Fr [
38 CLEAR_TO_SEND OFFSET(0) NUMBITS(1) [],
39 DATA_SET_READY OFFSET(1) NUMBITS(1) [],
40 DATA_CARRIER_DETECT OFFSET(2) NUMBITS(1) [],
41 BUSY OFFSET(3) NUMBITS(1) [],
42 RX_FIFO_EMPTY OFFSET(4) NUMBITS(1) [],
43 TX_FIFO_FULL OFFSET(5) NUMBITS(1) [],
44 RX_FIFO_FULL OFFSET(6) NUMBITS(1) [],
45 TX_FIFO_EMPTY OFFSET(7) NUMBITS(1) [],
46 ],
47
48 LineControlRegister [
49 SEND_BREAK OFFSET(0) NUMBITS(1) [],
50 PARITY_ENABLE OFFSET(1) NUMBITS(1) [],
51 EVEN_PARITY_SELECT OFFSET(2) NUMBITS(1) [
52 Odd = 0,
53 Even = 1,
54 ],
55 TWO_STOP_BITS_SELECT OFFSET(3) NUMBITS(1) [],
56 ENABLE_FIFO OFFSET(4) NUMBITS(1) [],
57 WORD_LEN OFFSET(5) NUMBITS(2) [
58 B5 = 0b00,
59 B6 = 0b01,
60 B7 = 0b10,
61 B8 = 0b11,
62 ],
63 STICK_PARITY_SELECT OFFSET(7) NUMBITS(1)[],
64 ],
65
66 ControlRegister [
67 ENABLE OFFSET(0) NUMBITS(1) [],
68 SIR_ENABLE OFFSET(1) NUMBITS(1) [],
69 SIR_LP OFFSET(2) NUMBITS(1) [],
70 LOOPBACK_ENABLE OFFSET(7) NUMBITS(1) [],
71 TX_ENABLE OFFSET(8) NUMBITS(1) [],
72 RX_ENABLE OFFSET(9) NUMBITS(1) [],
73 DATA_TRANSMIT_READY OFFSET(10) NUMBITS(1) [],
74 REQUEST_TO_SEND OFFSET(11) NUMBITS(1) [],
75 OUT1 OFFSET(12) NUMBITS(1) [],
76 OUT2 OFFSET(13) NUMBITS(1) [],
77 RTS_ENABLE OFFSET(14) NUMBITS(1) [],
78 CTS_ENABLE OFFSET(15) NUMBITS(1) [],
79 ],
80 IFLS [
81 TXIFLSEL OFFSET(0) NUMBITS(2) [],
82 RXIFLSEL OFFSET(3) NUMBITS(2) [],
83 ],
84];
85
86register_structs! {
87 Registers {
88 (0x00 => dr: ReadWrite<u32, Data::Register>),
89 (0x04 => _reserved0),
90 (0x18 => fr: ReadOnly<u32, Fr::Register>),
92 (0x1c => _reserved1),
93 (0x24 => ibrd: ReadWrite<u32>),
94 (0x28 => fbrd: ReadWrite<u32>),
95 (0x2c => lcr_h: ReadWrite<u32, LineControlRegister::Register>),
96 (0x30 => cr: ReadWrite<u32, ControlRegister::Register>),
98 (0x34 => ifls: ReadWrite<u32, IFLS::Register>),
100 (0x38 => imsc: ReadWrite<u32>),
102 (0x3c => ris: ReadOnly<u32>),
104 (0x40 => mis: ReadOnly<u32>),
106 (0x44 => icr: WriteOnly<u32>),
108 (0x48 => @END),
109 }
110}
111
112#[derive(Clone, Copy, PartialEq, Eq, Debug)]
114pub enum DataBits {
115 Bits5,
116 Bits6,
117 Bits7,
118 Bits8,
119}
120
121impl From<DataBits> for FieldValue<u32, LineControlRegister::Register> {
122 fn from(val: DataBits) -> Self {
123 match val {
124 DataBits::Bits5 => LineControlRegister::WORD_LEN::B5,
125 DataBits::Bits6 => LineControlRegister::WORD_LEN::B6,
126 DataBits::Bits7 => LineControlRegister::WORD_LEN::B7,
127 DataBits::Bits8 => LineControlRegister::WORD_LEN::B8,
128 }
129 }
130}
131
132#[derive(Clone, Copy, PartialEq, Eq, Debug)]
134pub enum Parity {
135 None,
136 Even,
137 Odd,
138}
139
140#[derive(Clone, Copy, PartialEq, Eq, Debug)]
142pub enum StopBits {
143 #[doc = "1 stop bit"]
144 STOP1,
145 #[doc = "2 stop bits"]
146 STOP2,
147}
148
149pub struct Config {
150 pub baud_rate: u32,
151 pub clock_freq: u64,
152 pub data_bits: DataBits,
153 pub stop_bits: StopBits,
154 pub parity: Parity,
155}
156
157pub struct Pl011 {
158 base: usize,
159}
160
161impl Pl011 {
162 pub async fn new(base: NonNull<u8>, config: Option<Config>) -> Self {
163 let mut s = Self {
164 base: base.as_ptr() as usize,
165 };
166 s.set_config(config).await;
167 s
168 }
169
170 pub fn new_sync(base: NonNull<u8>, config: Option<Config>) -> Self {
171 spin_on(Self::new(base, config))
172 }
173
174 async fn flush_all(&mut self) {
175 self.wait_expect(|reg| reg.fr.matches_all(Fr::TX_FIFO_EMPTY::SET + Fr::BUSY::CLEAR))
176 .await;
177 }
178
179 pub async fn set_config(&mut self, config: Option<Config>) {
180 self.flush_all().await;
181
182 self.reg().cr.modify(ControlRegister::ENABLE::CLEAR);
184
185 self.reg()
189 .lcr_h
190 .modify(LineControlRegister::ENABLE_FIFO::CLEAR);
191
192 fence(Ordering::Release);
193
194 if let Some(config) = config {
195 let pen;
196 let eps;
197 let sps;
198
199 match config.parity {
200 Parity::None => {
201 pen = LineControlRegister::PARITY_ENABLE::CLEAR;
202 eps = LineControlRegister::EVEN_PARITY_SELECT::CLEAR;
203 sps = LineControlRegister::STICK_PARITY_SELECT::CLEAR;
204 }
205 Parity::Even => {
206 pen = LineControlRegister::PARITY_ENABLE::SET;
207 eps = LineControlRegister::EVEN_PARITY_SELECT::SET;
208 sps = LineControlRegister::STICK_PARITY_SELECT::CLEAR;
209 }
210 Parity::Odd => {
211 pen = LineControlRegister::PARITY_ENABLE::SET;
212 eps = LineControlRegister::EVEN_PARITY_SELECT::CLEAR;
213 sps = LineControlRegister::STICK_PARITY_SELECT::CLEAR;
214 }
215 }
216 let word_len = config.data_bits.into();
217 let stp2 = match config.stop_bits {
218 StopBits::STOP1 => LineControlRegister::TWO_STOP_BITS_SELECT::CLEAR,
219 StopBits::STOP2 => LineControlRegister::TWO_STOP_BITS_SELECT::SET,
220 };
221
222 let baud_rate_div = (8 * config.clock_freq) / config.baud_rate as u64;
223 let mut baud_ibrd = baud_rate_div >> 7;
224 let mut baud_fbrd = ((baud_rate_div & 0x7f) + 1) / 2;
225
226 if baud_ibrd == 0 {
227 baud_ibrd = 1;
228 baud_fbrd = 0;
229 } else if baud_ibrd >= 65535 {
230 baud_ibrd = 65535;
231 baud_fbrd = 0;
232 }
233
234 self.reg().ibrd.set(baud_ibrd as u32);
235 self.reg().fbrd.set(baud_fbrd as u32);
236
237 self.reg()
238 .lcr_h
239 .write(LineControlRegister::ENABLE_FIFO::SET + word_len + pen + eps + sps + stp2);
240 } else {
241 self.reg()
242 .lcr_h
243 .modify(LineControlRegister::ENABLE_FIFO::SET);
244 }
245
246 self.reg().cr.write(
247 ControlRegister::ENABLE::SET
248 + ControlRegister::TX_ENABLE::SET
249 + ControlRegister::RX_ENABLE::SET,
250 );
251 }
252 pub fn set_config_sync(&mut self, config: Option<Config>) {
253 spin_on(self.set_config(config));
254 }
255
256 async fn read(&self) -> Result<u8, ErrorKind> {
257 self.wait_expect(|reg| reg.fr.read(Fr::RX_FIFO_EMPTY) == 0)
258 .await;
259
260 let val = self.reg().dr.get();
261 let b = Data::DATA.read(val) as u8;
262
263 if Data::FRAMING_ERROR.is_set(val) {
264 return Err(ErrorKind::Framing);
265 }
266 if Data::PARITY_ERROR.is_set(val) {
267 return Err(ErrorKind::Parity);
268 }
269 if Data::OVERRUN_ERROR.is_set(val) {
270 return Err(ErrorKind::Overrun);
271 }
272 if Data::BREAK_ERROR.is_set(val) {
273 return Err(ErrorKind::Break);
274 }
275
276 Ok(b)
277 }
278
279 async fn write(&self, data: u8) {
280 self.wait_expect(|reg| reg.fr.read(Fr::TX_FIFO_FULL) == 0)
281 .await;
282
283 self.reg().dr.write(Data::DATA.val(data as u32));
284 }
285
286 fn reg(&self) -> &Registers {
287 unsafe { &*(self.base as *const Registers) }
288 }
289
290 async fn wait_expect<F>(&self, expect: F)
291 where
292 F: Fn(&Registers) -> bool,
293 {
294 WaitExpectFuture {
295 base: self.base,
296 expect,
297 }
298 .await;
299 }
300
301 pub fn set_tx_fifo_threadhold(&mut self, threshold: Threshold) {
302 self.reg().ifls.modify(IFLS::TXIFLSEL.val(threshold as _));
303 }
304
305 pub fn set_rx_fifo_threadhold(&mut self, threshold: Threshold) {
306 self.reg().ifls.modify(IFLS::RXIFLSEL.val(threshold as _));
307 }
308
309 pub fn write_imsc(&mut self, mask: IMSC) {
310 self.reg().imsc.set(mask.bits());
311 }
312
313 pub fn read_ris(&self) -> RIS {
314 RIS::from_bits_truncate(self.reg().ris.get())
315 }
316 pub fn read_mis(&self) -> MIS {
317 MIS::from_bits_truncate(self.reg().mis.get())
318 }
319
320 pub fn write_icr(&mut self, mask: RIS) {
321 self.reg().icr.set(mask.bits());
322 }
323}
324
325bitflags! {
326 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
327 pub struct IMSC: u32 {
328 const RIMIM = 1 << 0;
330 const CTSMIM = 1 << 1;
332 const CDCDMIM = 1 << 2;
334 const DSRMIM = 1 << 3;
335 const RXIM = 1 << 4;
337 const TXIM = 1 << 5;
339 const RTIM = 1 << 6;
341 const FEIM = 1 << 7;
342 const PEIM = 1 << 8;
343 const BEIM = 1 << 9;
344 const OEIM = 1 << 10;
345 }
346
347 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
348 pub struct RIS: u32 {
349 const RIRMIS = 1 << 0;
350 const CTSRMIS = 1 << 1;
351 const DCDRMIS = 1 << 2;
352 const DSRRMIS = 1 << 3;
353 const RXRIS = 1 << 4;
354 const TXRIS = 1 << 5;
355 const RTRIS = 1 << 6;
356 const FERIS = 1 << 7;
357 const PERIS = 1 << 8;
358 const BERIS = 1 << 9;
359 const OERIS = 1 << 10;
360 }
361 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
362 pub struct MIS: u32 {
363 const RIMMIS = 1 << 0;
364 const CTSMMIS = 1 << 1;
365 const DCDMMIS = 1 << 2;
366 const DSRMMIS = 1 << 3;
367 const RXMIS = 1 << 4;
368 const TXMIS = 1 << 5;
369 const RTMIS = 1 << 6;
370 const FEMIS = 1 << 7;
371 const PEMIS = 1 << 8;
372 const BEMIS = 1 << 9;
373 const OEMIS = 1 << 10;
374 }
375
376 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
377 pub struct ICR: u32 {
378 const RIMIC = 1 << 0;
379 const CTSMIC = 1 << 1;
380 const DCDMIC = 1 << 2;
381 const DSRMIC = 1 << 3;
382 const RXIC = 1 << 4;
383 const TXIC = 1 << 5;
384 const RTIC = 1 << 6;
385 const FEIC = 1 << 7;
386 const PEIC = 1 << 8;
387 const BEIC = 1 << 9;
388 const OEIC = 1 << 10;
389 }
390}
391
392#[repr(C)]
393#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
394pub enum Threshold {
395 Level1 = 000,
397 Level2 = 0b001,
399 Level3 = 0b010,
401 Level4 = 0b011,
403 Level5 = 0b100,
405}
406
407struct WaitExpectFuture<F>
408where
409 F: Fn(&Registers) -> bool,
410{
411 base: usize,
412 expect: F,
413}
414
415impl<F> Future for WaitExpectFuture<F>
416where
417 F: Fn(&Registers) -> bool,
418{
419 type Output = ();
420
421 fn poll(
422 self: core::pin::Pin<&mut Self>,
423 cx: &mut core::task::Context<'_>,
424 ) -> core::task::Poll<Self::Output> {
425 let reg = unsafe { &*(self.base as *const Registers) };
426 let expect = (self.expect)(reg);
427 if expect {
428 core::task::Poll::Ready(())
429 } else {
430 cx.waker().wake_by_ref();
431 core::task::Poll::Pending
432 }
433 }
434}
435
436impl embedded_io::Error for ErrorKind {
437 fn kind(&self) -> embedded_io::ErrorKind {
438 match self {
439 ErrorKind::Framing => embedded_io::ErrorKind::InvalidData,
440 ErrorKind::Parity => embedded_io::ErrorKind::InvalidData,
441 ErrorKind::Break => embedded_io::ErrorKind::InvalidData,
442 ErrorKind::Overrun => embedded_io::ErrorKind::Other,
443 }
444 }
445}
446
447impl ErrorType for Pl011 {
448 type Error = ErrorKind;
449}
450
451impl embedded_io::Write for Pl011 {
452 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
453 spin_on(Pl011::write(self, buf[0]));
454 Ok(1)
455 }
456
457 fn flush(&mut self) -> Result<(), Self::Error> {
458 Ok(())
459 }
460}
461impl embedded_io::Read for Pl011 {
462 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
463 let b = spin_on(Pl011::read(self))?;
464 buf[0] = b;
465 Ok(1)
466 }
467}
468
469impl embedded_io_async::Write for Pl011 {
470 async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
471 Pl011::write(self, buf[0]).await;
472 Ok(1)
473 }
474}
475impl embedded_io_async::Read for Pl011 {
476 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
477 let b = Pl011::read(self).await?;
478 buf[0] = b;
479 Ok(1)
480 }
481}