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 panic!("UART 16550: interrupt without interrupt");
253 }
254
255 if iir.matches_all(IIR::Identification::TransmitterHoldingRegisterEmpty) {
257 if self.tx_buffer.is_some() {
263 self.transmit_continue();
264 }
265 }
266 else if iir.matches_all(IIR::Identification::ReceiveDataAvailable) {
268 self.receive();
269 }
270 else if iir.matches_all(IIR::Identification::ModemStatusChange) {
273 let _ = self.regs.msr.get();
274 }
275 else if iir.matches_all(IIR::Identification::LineStatusChange) {
278 let _ = self.regs.lsr.get();
279 }
280 else if iir.matches_all(IIR::Identification::CharacterTimeout) {
283 let _ = self.regs.rbr_thr.get();
284 }
285 else {
288 panic!("UART 16550: unknown interrupt");
289 }
290 }
291
292 pub fn transmit_sync(&self, bytes: &[u8]) {
300 let prev_ier = self.regs.ier.extract();
303 if prev_ier.is_set(IER::TransmitterHoldingRegisterEmpty) {
304 self.regs
305 .ier
306 .modify_no_read(prev_ier, IER::TransmitterHoldingRegisterEmpty::CLEAR);
307 }
308
309 for byte in bytes.iter() {
310 while !self.regs.lsr.is_set(LSR::THREmpty) {}
311 self.regs.rbr_thr.write(THR::Data.val(*byte));
312 }
313
314 self.regs.ier.set(prev_ier.get());
316 }
317
318 fn transmit_continue(&self) {
319 let mut index = self.tx_index.get();
324 let tx_data = self.tx_buffer.take().expect("UART 16550: no tx buffer");
325
326 if index < self.tx_len.get() {
327 while index < self.tx_len.get() && self.regs.lsr.is_set(LSR::THREmpty) {
329 self.regs.rbr_thr.write(THR::Data.val(tx_data[index]));
330 index += 1;
331 }
332
333 self.tx_index.set(index);
336 self.tx_buffer.replace(tx_data);
337 } else {
338 self.regs
340 .ier
341 .modify(IER::TransmitterHoldingRegisterEmpty::CLEAR);
342
343 self.tx_client
345 .map(move |client| client.transmitted_buffer(tx_data, self.tx_len.get(), Ok(())));
346 }
347 }
348
349 fn receive(&self) {
350 let rx_buffer = self.rx_buffer.take().expect("UART 16550: no rx buffer");
353 let len = self.rx_len.get();
354 let mut index = self.rx_index.get();
355
356 while self.regs.lsr.is_set(LSR::DataAvailable) && index < len {
358 rx_buffer[index] = self.regs.rbr_thr.get();
359 index += 1;
360 }
361
362 if index == len {
364 self.regs.ier.modify(IER::ReceivedDataAvailable::CLEAR);
366
367 self.rx_client.map(move |client| {
368 client.received_buffer(rx_buffer, len, Ok(()), hil::uart::Error::None)
369 });
370 } else {
371 self.rx_index.set(index);
373 self.rx_buffer.replace(rx_buffer);
374 }
375 }
376}
377
378impl hil::uart::Configure for Uart16550<'_> {
379 fn configure(&self, params: hil::uart::Parameters) -> Result<(), ErrorCode> {
380 use hil::uart::{Parity, StopBits, Width};
381
382 let divisor: u16 = (115_200 / params.baud_rate) as u16;
386 self.regs.divisor_latch_reg(|dlr| {
387 dlr.set(divisor);
388 });
389
390 let mut lcr = self.regs.lcr.extract();
391
392 match params.width {
393 Width::Six => lcr.modify(LCR::DataWordLength::Bits6),
394 Width::Seven => lcr.modify(LCR::DataWordLength::Bits7),
395 Width::Eight => lcr.modify(LCR::DataWordLength::Bits8),
396 }
397
398 match params.stop_bits {
399 StopBits::One => LCR::StopBits::One,
400 StopBits::Two => LCR::StopBits::OneHalfTwo,
404 };
405
406 match params.parity {
407 Parity::None => lcr.modify(LCR::Parity.val(0b000)),
408 Parity::Odd => lcr.modify(LCR::Parity.val(0b001)),
409 Parity::Even => lcr.modify(LCR::Parity.val(0b011)),
410 }
411
412 match params.hw_flow_control {
413 true => lcr.modify(LCR::BreakSignal::SET),
414 false => lcr.modify(LCR::BreakSignal::CLEAR),
415 }
416
417 self.regs.lcr.set(lcr.get());
418
419 Ok(())
420 }
421}
422
423impl<'a> hil::uart::Transmit<'a> for Uart16550<'a> {
424 fn set_transmit_client(&self, client: &'a dyn hil::uart::TransmitClient) {
425 self.tx_client.set(client);
426 }
427
428 fn transmit_buffer(
429 &self,
430 tx_data: &'static mut [u8],
431 tx_len: usize,
432 ) -> Result<(), (ErrorCode, &'static mut [u8])> {
433 if tx_len > tx_data.len() {
434 return Err((ErrorCode::INVAL, tx_data));
435 }
436
437 if self.tx_buffer.is_some() {
438 return Err((ErrorCode::BUSY, tx_data));
439 }
440
441 self.regs
444 .ier
445 .modify(IER::TransmitterHoldingRegisterEmpty::SET);
446
447 let mut index = 0;
449 while index < tx_len && self.regs.lsr.is_set(LSR::THREmpty) {
450 self.regs.rbr_thr.write(THR::Data.val(tx_data[index]));
451 index += 1;
452 }
453
454 self.tx_buffer.replace(tx_data);
457 self.tx_len.set(tx_len);
458 self.tx_index.set(index);
459
460 Ok(())
461 }
462
463 fn transmit_abort(&self) -> Result<(), ErrorCode> {
464 Err(ErrorCode::FAIL)
465 }
466
467 fn transmit_word(&self, _word: u32) -> Result<(), ErrorCode> {
468 Err(ErrorCode::FAIL)
469 }
470}
471
472impl<'a> hil::uart::Receive<'a> for Uart16550<'a> {
473 fn set_receive_client(&self, client: &'a dyn hil::uart::ReceiveClient) {
474 self.rx_client.set(client);
475 }
476
477 fn receive_buffer(
478 &self,
479 rx_buffer: &'static mut [u8],
480 rx_len: usize,
481 ) -> Result<(), (ErrorCode, &'static mut [u8])> {
482 if rx_buffer.len() < rx_len && rx_len > 0 {
486 return Err((ErrorCode::SIZE, rx_buffer));
487 }
488
489 self.rx_buffer.replace(rx_buffer);
493 self.rx_len.set(rx_len);
494 self.rx_index.set(0);
495
496 self.regs.ier.modify(IER::ReceivedDataAvailable::SET);
498
499 Ok(())
500 }
501
502 fn receive_abort(&self) -> Result<(), ErrorCode> {
503 Err(ErrorCode::FAIL)
506 }
507
508 fn receive_word(&self) -> Result<(), ErrorCode> {
509 Err(ErrorCode::FAIL)
511 }
512}