1use core::cell::Cell;
11use kernel::deferred_call::{DeferredCall, DeferredCallClient};
12use kernel::hil::uart;
13use kernel::utilities::cells::{OptionalCell, TakeCell};
14use kernel::utilities::StaticRef;
15use kernel::ErrorCode;
16
17use crate::event_manager::LiteXEventManager;
18use crate::litex_registers::{
19 register_bitfields, LiteXSoCRegisterConfiguration, Read, ReadRegWrapper, Write, WriteRegWrapper,
20};
21
22const EVENT_MANAGER_INDEX_TX: usize = 0;
23const EVENT_MANAGER_INDEX_RX: usize = 1;
24
25type LiteXUartEV<'a, R> = LiteXEventManager<
26 'a,
27 u8,
28 <R as LiteXSoCRegisterConfiguration>::ReadOnly8,
29 <R as LiteXSoCRegisterConfiguration>::ReadWrite8,
30 <R as LiteXSoCRegisterConfiguration>::ReadWrite8,
31>;
32
33#[repr(C)]
38pub struct LiteXUartPhyRegisters<R: LiteXSoCRegisterConfiguration> {
39 tuning_word: R::ReadWrite32,
41}
42
43#[repr(C)]
45pub struct LiteXUartRegisters<R: LiteXSoCRegisterConfiguration> {
46 rxtx: R::ReadWrite8,
48 txfull: R::ReadOnly8,
50 rxempty: R::ReadOnly8,
52 ev_status: R::ReadOnly8,
54 ev_pending: R::ReadWrite8,
56 ev_enable: R::ReadWrite8,
58 txempty: R::ReadOnly8,
60 rxfull: R::ReadOnly8,
62}
63
64impl<R: LiteXSoCRegisterConfiguration> LiteXUartRegisters<R> {
65 fn ev(&self) -> LiteXUartEV<'_, R> {
67 LiteXUartEV::<R>::new(&self.ev_status, &self.ev_pending, &self.ev_enable)
68 }
69}
70
71register_bitfields![u8,
72 rxtx [
73 data OFFSET(0) NUMBITS(8) []
74 ],
75 txfull [
76 full OFFSET(0) NUMBITS(1) []
77 ],
78 rxempty [
79 empty OFFSET(0) NUMBITS(1) []
80 ],
81 txempty [
82 empty OFFSET(0) NUMBITS(1) []
83 ],
84 rxfull [
85 full OFFSET(0) NUMBITS(1) []
86 ]
87];
88
89pub struct LiteXUart<'a, R: LiteXSoCRegisterConfiguration> {
90 uart_regs: StaticRef<LiteXUartRegisters<R>>,
91 phy: Option<(StaticRef<LiteXUartPhyRegisters<R>>, u32)>,
92 tx_client: OptionalCell<&'a dyn uart::TransmitClient>,
93 rx_client: OptionalCell<&'a dyn uart::ReceiveClient>,
94 tx_buffer: TakeCell<'static, [u8]>,
95 tx_len: Cell<usize>,
96 tx_progress: Cell<usize>,
97 tx_aborted: Cell<bool>,
98 tx_deferred_call: Cell<bool>,
99 rx_buffer: TakeCell<'static, [u8]>,
100 rx_len: Cell<usize>,
101 rx_progress: Cell<usize>,
102 rx_aborted: Cell<bool>,
103 rx_deferred_call: Cell<bool>,
104 deferred_call: DeferredCall,
105 initialized: Cell<bool>,
106}
107
108impl<'a, R: LiteXSoCRegisterConfiguration> LiteXUart<'a, R> {
109 pub fn new(
110 uart_base: StaticRef<LiteXUartRegisters<R>>,
111 phy_args: Option<(StaticRef<LiteXUartPhyRegisters<R>>, u32)>,
112 ) -> LiteXUart<'a, R> {
113 LiteXUart {
114 uart_regs: uart_base,
115 phy: phy_args,
116 tx_client: OptionalCell::empty(),
117 rx_client: OptionalCell::empty(),
118 tx_buffer: TakeCell::empty(),
119 tx_len: Cell::new(0),
120 tx_progress: Cell::new(0),
121 tx_aborted: Cell::new(false),
122 tx_deferred_call: Cell::new(false),
123 rx_buffer: TakeCell::empty(),
124 rx_len: Cell::new(0),
125 rx_progress: Cell::new(0),
126 rx_aborted: Cell::new(false),
127 rx_deferred_call: Cell::new(false),
128 deferred_call: DeferredCall::new(),
129 initialized: Cell::new(false),
130 }
131 }
132
133 pub fn initialize(&self) {
134 self.uart_regs.ev().disable_all();
135 self.initialized.set(true);
136 }
137
138 pub fn transmit_sync(&self, bytes: &[u8]) {
139 let regs = self.uart_regs;
142 let ev = regs.ev();
143
144 let interrupt_pending = ev.event_pending(EVENT_MANAGER_INDEX_TX);
148 let interrupt_enabled = ev.event_enabled(EVENT_MANAGER_INDEX_TX);
149 ev.disable_event(EVENT_MANAGER_INDEX_TX);
150
151 for b in bytes.iter() {
152 while ReadRegWrapper::wrap(®s.txfull).is_set(txfull::full) {}
153 WriteRegWrapper::wrap(®s.rxtx).write(rxtx::data.val(*b));
154 }
155
156 while ReadRegWrapper::wrap(®s.txfull).is_set(txfull::full) {}
158
159 if !interrupt_pending && ev.event_pending(EVENT_MANAGER_INDEX_TX) {
161 ev.clear_event(EVENT_MANAGER_INDEX_TX);
162 }
163
164 if interrupt_enabled {
166 ev.enable_event(EVENT_MANAGER_INDEX_TX);
167 }
168 }
169
170 pub fn service_interrupt(&self) {
171 let ev = self.uart_regs.ev();
172
173 if ev.event_asserted(EVENT_MANAGER_INDEX_RX) {
174 self.rx_data();
178 }
179
180 if ev.event_asserted(EVENT_MANAGER_INDEX_TX) {
181 ev.clear_event(EVENT_MANAGER_INDEX_TX);
182 self.resume_tx();
183 }
184 }
185
186 fn deferred_rx_abort(&self) {
187 let buffer = self.rx_buffer.take().unwrap(); let progress = self.rx_progress.get();
191
192 self.rx_client.map(move |client| {
193 client.received_buffer(buffer, progress, Err(ErrorCode::CANCEL), uart::Error::None)
194 });
195 }
196
197 fn rx_data(&self) {
198 let ev = self.uart_regs.ev();
200 let buffer = self.rx_buffer.take().unwrap(); let len = self.rx_len.get();
202 let mut progress = self.rx_progress.get();
203
204 while {
206 !ReadRegWrapper::wrap(&self.uart_regs.rxempty).is_set(rxempty::empty) && progress < len
207 } {
208 buffer[progress] = ReadRegWrapper::wrap(&self.uart_regs.rxtx).read(rxtx::data);
209 progress += 1;
210
211 ev.clear_event(EVENT_MANAGER_INDEX_RX);
213 }
214
215 if progress == len {
218 self.uart_regs.ev().disable_event(EVENT_MANAGER_INDEX_RX);
220 self.rx_client
221 .map(move |client| client.received_buffer(buffer, len, Ok(()), uart::Error::None));
222 } else {
223 self.rx_buffer.replace(buffer);
224 self.rx_progress.set(progress);
225 }
226 }
227
228 fn deferred_tx_abort(&self) {
229 let buffer = self.tx_buffer.take().unwrap(); let progress = self.tx_progress.get();
233
234 self.tx_client
235 .map(move |client| client.transmitted_buffer(buffer, progress, Err(ErrorCode::CANCEL)));
236 }
237
238 fn resume_tx(&self) {
242 let len = self.tx_len.get();
246 let mut progress = self.tx_progress.get();
247 let buffer = self.tx_buffer.take().unwrap(); let mut fifo_full: bool;
260 while {
261 fifo_full = ReadRegWrapper::wrap(&self.uart_regs.txfull).is_set(txfull::full);
262 !fifo_full && progress < len
263 } {
264 WriteRegWrapper::wrap(&self.uart_regs.rxtx).write(rxtx::data.val(buffer[progress]));
265 progress += 1;
266 }
267
268 if progress < len {
269 assert!(fifo_full);
272
273 self.tx_progress.set(progress);
276 self.tx_buffer.replace(buffer);
277 } else if fifo_full || self.uart_regs.ev().event_pending(EVENT_MANAGER_INDEX_TX) {
278 self.tx_progress.set(progress);
284 self.tx_buffer.replace(buffer);
285 } else {
286 self.uart_regs.ev().disable_event(EVENT_MANAGER_INDEX_TX);
291 self.tx_client
292 .map(move |client| client.transmitted_buffer(buffer, len, Ok(())));
293 }
294 }
295}
296
297impl<R: LiteXSoCRegisterConfiguration> uart::Configure for LiteXUart<'_, R> {
298 fn configure(&self, params: uart::Parameters) -> Result<(), ErrorCode> {
299 if let Some((ref phy_regs, system_clock)) = self.phy {
305 if params.width != uart::Width::Eight
306 || params.parity != uart::Parity::None
307 || params.stop_bits != uart::StopBits::One
308 || params.hw_flow_control
309 {
310 Err(ErrorCode::NOSUPPORT)
311 } else if params.baud_rate == 0 || params.baud_rate > system_clock {
312 Err(ErrorCode::INVAL)
313 } else {
314 let tuning_word = if params.baud_rate == system_clock {
315 u32::MAX
316 } else {
317 (((params.baud_rate as u64) * (1 << 32)) / (system_clock as u64)) as u32
318 };
319 phy_regs.tuning_word.set(tuning_word);
320
321 Ok(())
322 }
323 } else {
324 Err(ErrorCode::NOSUPPORT)
325 }
326 }
327}
328
329impl<'a, R: LiteXSoCRegisterConfiguration> uart::Transmit<'a> for LiteXUart<'a, R> {
330 fn set_transmit_client(&self, client: &'a dyn uart::TransmitClient) {
331 self.tx_client.set(client);
332 }
333
334 fn transmit_buffer(
335 &self,
336 tx_buffer: &'static mut [u8],
337 tx_len: usize,
338 ) -> Result<(), (ErrorCode, &'static mut [u8])> {
339 assert!(self.initialized.get());
341
342 if tx_buffer.len() < tx_len {
343 return Err((ErrorCode::SIZE, tx_buffer));
344 }
345
346 if self.tx_buffer.is_some() {
347 return Err((ErrorCode::BUSY, tx_buffer));
348 }
349
350 self.uart_regs.ev().clear_event(EVENT_MANAGER_INDEX_TX);
352 self.uart_regs.ev().enable_event(EVENT_MANAGER_INDEX_TX);
353
354 let mut fifo_full: bool;
372 let mut progress: usize = 0;
373 while {
374 fifo_full = ReadRegWrapper::wrap(&self.uart_regs.txfull).is_set(txfull::full);
375 (progress < tx_len) && !fifo_full
376 } {
377 WriteRegWrapper::wrap(&self.uart_regs.rxtx).write(rxtx::data.val(tx_buffer[progress]));
378 progress += 1;
379 }
380
381 self.tx_progress.set(progress);
383 self.tx_len.set(tx_len);
384 self.tx_buffer.replace(tx_buffer);
385 self.tx_aborted.set(false);
386
387 if !(fifo_full || self.uart_regs.ev().event_pending(EVENT_MANAGER_INDEX_TX)) {
398 assert!(progress == tx_len);
399
400 self.tx_deferred_call.set(true);
401 self.deferred_call.set();
402 }
403
404 Ok(())
407 }
408
409 fn transmit_word(&self, _word: u32) -> Result<(), ErrorCode> {
410 assert!(self.initialized.get());
412
413 Err(ErrorCode::FAIL)
414 }
415
416 fn transmit_abort(&self) -> Result<(), ErrorCode> {
417 assert!(self.initialized.get());
425
426 self.uart_regs.ev().disable_event(EVENT_MANAGER_INDEX_TX);
427
428 if self.tx_buffer.is_some() {
429 self.tx_aborted.set(true);
430 self.tx_deferred_call.set(true);
431 self.deferred_call.set();
432
433 Err(ErrorCode::BUSY)
434 } else {
435 Ok(())
436 }
437 }
438}
439
440impl<'a, R: LiteXSoCRegisterConfiguration> uart::Receive<'a> for LiteXUart<'a, R> {
441 fn set_receive_client(&self, client: &'a dyn uart::ReceiveClient) {
442 self.rx_client.set(client);
443 }
444
445 fn receive_buffer(
446 &self,
447 rx_buffer: &'static mut [u8],
448 rx_len: usize,
449 ) -> Result<(), (ErrorCode, &'static mut [u8])> {
450 assert!(self.initialized.get());
452
453 if rx_len > rx_buffer.len() {
454 return Err((ErrorCode::SIZE, rx_buffer));
455 }
456
457 if self.rx_buffer.is_some() {
458 return Err((ErrorCode::BUSY, rx_buffer));
459 }
460
461 self.rx_buffer.replace(rx_buffer);
464 self.rx_len.set(rx_len);
465 self.rx_progress.set(0);
466 self.rx_aborted.set(false);
467
468 if !ReadRegWrapper::wrap(&self.uart_regs.rxempty).is_set(rxempty::empty)
476 && !self.uart_regs.ev().event_pending(EVENT_MANAGER_INDEX_RX)
477 {
478 self.rx_deferred_call.set(true);
486 self.deferred_call.set();
487 } else {
488 self.uart_regs.ev().enable_event(EVENT_MANAGER_INDEX_RX);
491 }
492
493 Ok(())
494 }
495
496 fn receive_word(&self) -> Result<(), ErrorCode> {
497 assert!(self.initialized.get());
499 Err(ErrorCode::FAIL)
500 }
501
502 fn receive_abort(&self) -> Result<(), ErrorCode> {
503 assert!(self.initialized.get());
505
506 self.uart_regs.ev().disable_event(EVENT_MANAGER_INDEX_RX);
508
509 if self.rx_buffer.is_some() {
510 self.rx_aborted.set(true);
513 self.rx_deferred_call.set(true);
514 self.deferred_call.set();
515
516 Err(ErrorCode::BUSY)
517 } else {
518 Ok(())
519 }
520 }
521}
522
523impl<R: LiteXSoCRegisterConfiguration> DeferredCallClient for LiteXUart<'_, R> {
524 fn register(&'static self) {
525 self.deferred_call.register(self)
526 }
527
528 fn handle_deferred_call(&self) {
529 if self.tx_deferred_call.get() {
531 self.tx_deferred_call.set(false);
532 if self.tx_aborted.get() {
534 self.deferred_tx_abort();
535 } else {
536 self.resume_tx();
539 }
540 }
541
542 if self.rx_deferred_call.get() {
543 self.rx_deferred_call.set(false);
544 if self.rx_aborted.get() {
546 self.deferred_rx_abort();
547 } else {
548 self.uart_regs.ev().enable_event(EVENT_MANAGER_INDEX_RX);
558 self.rx_data();
559 }
560 }
561 }
562}