1use core::cell::Cell;
8
9use kernel::hil;
10use kernel::utilities::cells::{OptionalCell, TakeCell};
11use kernel::utilities::registers::interfaces::{ReadWriteable, Readable, Writeable};
12use kernel::utilities::registers::{
13 register_bitfields, Aliased, Field, InMemoryRegister, ReadOnly, ReadWrite,
14};
15use kernel::utilities::StaticRef;
16use kernel::ErrorCode;
17
18pub const UART0_BASE: StaticRef<Uart16550Registers> =
19 unsafe { StaticRef::new(0x1000_0000 as *const Uart16550Registers) };
20
21pub const UART_16550_BAUD_BASE: usize = 399193;
22
23type Uart16550RegshiftInt = u8;
24
25#[repr(C)]
26pub struct Uart16550Registers {
27 rbr_thr: Aliased<Uart16550RegshiftInt, RBR::Register, THR::Register>,
33
34 ier: ReadWrite<Uart16550RegshiftInt, IER::Register>,
38
39 iir_fcr: Aliased<Uart16550RegshiftInt, IIR::Register, FCR::Register>,
43
44 lcr: ReadWrite<Uart16550RegshiftInt, LCR::Register>,
46
47 mcr: ReadWrite<Uart16550RegshiftInt, MCR::Register>,
49
50 lsr: ReadOnly<Uart16550RegshiftInt, LSR::Register>,
52
53 msr: ReadOnly<Uart16550RegshiftInt, MSR::Register>,
55}
56
57impl Uart16550Registers {
58 fn divisor_latch_reg<F, R>(&self, f: F) -> R
74 where
75 F: FnOnce(&InMemoryRegister<u16, DLR::Register>) -> R,
76 {
77 let dlab_field = Field::<Uart16550RegshiftInt, LCR::Register>::new(1, 7);
78
79 self.lcr.modify(dlab_field.val(1));
81
82 let old_val = u16::from_be_bytes([self.ier.get(), self.rbr_thr.get()]);
85
86 self.lcr.modify(dlab_field.val(0));
88
89 let dlr = InMemoryRegister::<u16, DLR::Register>::new(old_val);
90 let ret = f(&dlr);
91
92 let [new_ier, new_rbr_thr] = u16::to_be_bytes(dlr.get());
94
95 self.lcr.modify(dlab_field.val(1));
97
98 self.ier.set(new_ier as Uart16550RegshiftInt);
100 self.rbr_thr.set(new_rbr_thr as Uart16550RegshiftInt);
101
102 self.lcr.modify(dlab_field.val(0));
104
105 ret
106 }
107}
108
109register_bitfields![u8,
110 RBR [
111 Data OFFSET(0) NUMBITS(8) [],
112 ],
113 THR [
114 Data OFFSET(0) NUMBITS(8) [],
115 ],
116 IER [
117 ModemStatusRegisterChange OFFSET(3) NUMBITS(1) [],
118 ReceiverLineStatusRegisterChange OFFSET(2) NUMBITS(1) [],
119 TransmitterHoldingRegisterEmpty OFFSET(1) NUMBITS(1) [],
120 ReceivedDataAvailable OFFSET(0) NUMBITS(1) [],
121 ],
122 IIR [
123 FIFO OFFSET(6) NUMBITS(2) [
124 NoFIFO = 0,
125 UnusableFIFO = 2,
126 FIFOEnabled = 3,
127 ],
128 Identification OFFSET(1) NUMBITS(3) [
129 ModemStatusChange = 0,
130 TransmitterHoldingRegisterEmpty = 1,
131 ReceiveDataAvailable = 2,
132 LineStatusChange = 3,
133 CharacterTimeout = 6,
134 ],
135 Pending OFFSET(0) NUMBITS(1) [
136 Pending = 0,
137 NotPending = 1,
138 ],
139 ],
140 FCR [
141 ReceiveFIFOInterruptTriggerLevel OFFSET(6) NUMBITS(2) [
142 Bytes1 = 0,
143 Bytes4 = 1,
144 Bytes8 = 2,
145 Bytes14 = 3,
146 ],
147 DMAMode OFFSET(3) NUMBITS(1) [
148 Mode0 = 0,
149 Mode1 = 1,
150 ],
151 ClearTransmitFIFO OFFSET(2) NUMBITS(1) [],
152 ClearReceiveFIFO OFFSET(1) NUMBITS(1) [],
153 Enable OFFSET(0) NUMBITS(1) [],
154 ],
155 LCR [
156 BreakSignal OFFSET(6) NUMBITS(1) [],
157 ParityMode OFFSET(4) NUMBITS(2) [
158 Odd = 0,
159 Even = 1,
160 High = 2,
161 Low = 3,
162 ],
163 Parity OFFSET(3) NUMBITS(1) [],
164 StopBits OFFSET(2) NUMBITS(1) [
165 One = 0,
166 OneHalfTwo = 1,
167 ],
168 DataWordLength OFFSET(0) NUMBITS(2) [
169 Bits5 = 0,
170 Bits6 = 1,
171 Bits7 = 2,
172 Bits8 = 3,
173 ],
174 ],
175 MCR [
176 LoopbackMode OFFSET(4) NUMBITS(1) [],
177 AuxiliaryOutput2 OFFSET(3) NUMBITS(1) [],
178 AuxiliaryOutput1 OFFSET(2) NUMBITS(1) [],
179 RequestToSend OFFSET(1) NUMBITS(1) [],
180 DataTerminalReady OFFSET(0) NUMBITS(1) [],
181 ],
182 LSR [
183 ErronousDataInFIFO OFFSET(7) NUMBITS(1) [],
184 THREmptyLineIdle OFFSET(6) NUMBITS(1) [],
185 THREmpty OFFSET(5) NUMBITS(1) [],
186 BreakSignalReceived OFFSET(4) NUMBITS(1) [],
187 FramingError OFFSET(3) NUMBITS(1) [],
188 ParityError OFFSET(2) NUMBITS(1) [],
189 OverrunError OFFSET(1) NUMBITS(1) [],
190 DataAvailable OFFSET(0) NUMBITS(1) [],
191 ],
192 MSR [
193 CarrierDetect OFFSET(7) NUMBITS(1) [],
194 RingIndicator OFFSET(6) NUMBITS(1) [],
195 DataSetReady OFFSET(5) NUMBITS(1) [],
196 ClearToSend OFFSET(4) NUMBITS(1) [],
197 ChangeInCarrierDetect OFFSET(3) NUMBITS(1) [],
198 TrailingEdgeRingIndicator OFFSET(2) NUMBITS(1) [],
199 ChangeInDataSetReady OFFSET(1) NUMBITS(1) [],
200 ChangeInClearToSend OFFSET(0) NUMBITS(1) [],
201 ],
202];
203
204register_bitfields![u16,
205 DLR [
206 Divisor OFFSET(0) NUMBITS(16) [],
207 ],
208];
209
210pub struct Uart16550<'a> {
211 regs: StaticRef<Uart16550Registers>,
212 tx_client: OptionalCell<&'a dyn hil::uart::TransmitClient>,
213 rx_client: OptionalCell<&'a dyn hil::uart::ReceiveClient>,
214 tx_buffer: TakeCell<'static, [u8]>,
215 tx_len: Cell<usize>,
216 tx_index: Cell<usize>,
217 rx_buffer: TakeCell<'static, [u8]>,
218 rx_len: Cell<usize>,
219 rx_index: Cell<usize>,
220}
221
222impl<'a> Uart16550<'a> {
223 pub fn new(regs: StaticRef<Uart16550Registers>) -> Uart16550<'a> {
224 regs.ier.set(0xF);
226
227 regs.iir_fcr.write(FCR::Enable::CLEAR);
228
229 Uart16550 {
230 regs,
231 tx_client: OptionalCell::empty(),
232 rx_client: OptionalCell::empty(),
233 tx_buffer: TakeCell::empty(),
234 tx_len: Cell::new(0),
235 tx_index: Cell::new(0),
236 rx_buffer: TakeCell::empty(),
237 rx_len: Cell::new(0),
238 rx_index: Cell::new(0),
239 }
240 }
241}
242
243impl Uart16550<'_> {
244 pub fn handle_interrupt(&self) {
245 let iir = self.regs.iir_fcr.extract();
249
250 if !iir.matches_all(IIR::Pending::Pending) {
252 return;
260 }
261
262 if iir.matches_all(IIR::Identification::TransmitterHoldingRegisterEmpty) {
264 if self.tx_buffer.is_some() {
270 self.transmit_continue();
271 }
272 }
273 else if iir.matches_all(IIR::Identification::ReceiveDataAvailable) {
275 self.receive();
276 }
277 else if iir.matches_all(IIR::Identification::ModemStatusChange) {
280 let _ = self.regs.msr.get();
281 }
282 else if iir.matches_all(IIR::Identification::LineStatusChange) {
285 let _ = self.regs.lsr.get();
286 }
287 else if iir.matches_all(IIR::Identification::CharacterTimeout) {
290 let _ = self.regs.rbr_thr.get();
291 }
292 else {
295 panic!("UART 16550: unknown interrupt");
296 }
297 }
298
299 pub fn transmit_sync(&self, bytes: &[u8]) {
307 let prev_ier = self.regs.ier.extract();
310 if prev_ier.is_set(IER::TransmitterHoldingRegisterEmpty) {
311 self.regs
312 .ier
313 .modify_no_read(prev_ier, IER::TransmitterHoldingRegisterEmpty::CLEAR);
314 }
315
316 for byte in bytes.iter() {
317 while !self.regs.lsr.is_set(LSR::THREmpty) {}
318 self.regs.rbr_thr.write(THR::Data.val(*byte));
319 }
320
321 self.regs.ier.set(prev_ier.get());
323 }
324
325 fn transmit_continue(&self) {
326 let mut index = self.tx_index.get();
331 let tx_data = self.tx_buffer.take().expect("UART 16550: no tx buffer");
332
333 if index < self.tx_len.get() {
334 while index < self.tx_len.get() && self.regs.lsr.is_set(LSR::THREmpty) {
336 self.regs.rbr_thr.write(THR::Data.val(tx_data[index]));
337 index += 1;
338 }
339
340 self.tx_index.set(index);
343 self.tx_buffer.replace(tx_data);
344 } else {
345 self.regs
347 .ier
348 .modify(IER::TransmitterHoldingRegisterEmpty::CLEAR);
349
350 self.tx_client
352 .map(move |client| client.transmitted_buffer(tx_data, self.tx_len.get(), Ok(())));
353 }
354 }
355
356 fn receive(&self) {
357 let rx_buffer = self.rx_buffer.take().expect("UART 16550: no rx buffer");
360 let len = self.rx_len.get();
361 let mut index = self.rx_index.get();
362
363 while self.regs.lsr.is_set(LSR::DataAvailable) && index < len {
365 rx_buffer[index] = self.regs.rbr_thr.get();
366 index += 1;
367 }
368
369 if index == len {
371 self.regs.ier.modify(IER::ReceivedDataAvailable::CLEAR);
373
374 self.rx_client.map(move |client| {
375 client.received_buffer(rx_buffer, len, Ok(()), hil::uart::Error::None)
376 });
377 } else {
378 self.rx_index.set(index);
380 self.rx_buffer.replace(rx_buffer);
381 }
382 }
383}
384
385impl hil::uart::Configure for Uart16550<'_> {
386 fn configure(&self, params: hil::uart::Parameters) -> Result<(), ErrorCode> {
387 use hil::uart::{Parity, StopBits, Width};
388
389 let divisor: u16 = (115_200 / params.baud_rate) as u16;
393 self.regs.divisor_latch_reg(|dlr| {
394 dlr.set(divisor);
395 });
396
397 let mut lcr = self.regs.lcr.extract();
398
399 match params.width {
400 Width::Six => lcr.modify(LCR::DataWordLength::Bits6),
401 Width::Seven => lcr.modify(LCR::DataWordLength::Bits7),
402 Width::Eight => lcr.modify(LCR::DataWordLength::Bits8),
403 }
404
405 match params.stop_bits {
406 StopBits::One => LCR::StopBits::One,
407 StopBits::Two => LCR::StopBits::OneHalfTwo,
411 };
412
413 match params.parity {
414 Parity::None => lcr.modify(LCR::Parity.val(0b000)),
415 Parity::Odd => lcr.modify(LCR::Parity.val(0b001)),
416 Parity::Even => lcr.modify(LCR::Parity.val(0b011)),
417 }
418
419 match params.hw_flow_control {
420 true => lcr.modify(LCR::BreakSignal::SET),
421 false => lcr.modify(LCR::BreakSignal::CLEAR),
422 }
423
424 self.regs.lcr.set(lcr.get());
425
426 Ok(())
427 }
428}
429
430impl<'a> hil::uart::Transmit<'a> for Uart16550<'a> {
431 fn set_transmit_client(&self, client: &'a dyn hil::uart::TransmitClient) {
432 self.tx_client.set(client);
433 }
434
435 fn transmit_buffer(
436 &self,
437 tx_data: &'static mut [u8],
438 tx_len: usize,
439 ) -> Result<(), (ErrorCode, &'static mut [u8])> {
440 if tx_len > tx_data.len() {
441 return Err((ErrorCode::INVAL, tx_data));
442 }
443
444 if self.tx_buffer.is_some() {
445 return Err((ErrorCode::BUSY, tx_data));
446 }
447
448 self.regs
451 .ier
452 .modify(IER::TransmitterHoldingRegisterEmpty::SET);
453
454 let mut index = 0;
456 while index < tx_len && self.regs.lsr.is_set(LSR::THREmpty) {
457 self.regs.rbr_thr.write(THR::Data.val(tx_data[index]));
458 index += 1;
459 }
460
461 self.tx_buffer.replace(tx_data);
464 self.tx_len.set(tx_len);
465 self.tx_index.set(index);
466
467 Ok(())
468 }
469
470 fn transmit_abort(&self) -> Result<(), ErrorCode> {
471 Err(ErrorCode::FAIL)
472 }
473
474 fn transmit_word(&self, _word: u32) -> Result<(), ErrorCode> {
475 Err(ErrorCode::FAIL)
476 }
477}
478
479impl<'a> hil::uart::Receive<'a> for Uart16550<'a> {
480 fn set_receive_client(&self, client: &'a dyn hil::uart::ReceiveClient) {
481 self.rx_client.set(client);
482 }
483
484 fn receive_buffer(
485 &self,
486 rx_buffer: &'static mut [u8],
487 rx_len: usize,
488 ) -> Result<(), (ErrorCode, &'static mut [u8])> {
489 if rx_buffer.len() < rx_len && rx_len > 0 {
493 return Err((ErrorCode::SIZE, rx_buffer));
494 }
495
496 self.rx_buffer.replace(rx_buffer);
500 self.rx_len.set(rx_len);
501 self.rx_index.set(0);
502
503 self.regs.ier.modify(IER::ReceivedDataAvailable::SET);
505
506 Ok(())
507 }
508
509 fn receive_abort(&self) -> Result<(), ErrorCode> {
510 Err(ErrorCode::FAIL)
513 }
514
515 fn receive_word(&self) -> Result<(), ErrorCode> {
516 Err(ErrorCode::FAIL)
518 }
519}