1use core::cell::Cell;
14use core::cmp::min;
15use kernel::hil::uart;
16use kernel::utilities::cells::OptionalCell;
17use kernel::utilities::registers::interfaces::{Readable, Writeable};
18use kernel::utilities::registers::{register_bitfields, ReadOnly, ReadWrite, WriteOnly};
19use kernel::utilities::StaticRef;
20use kernel::ErrorCode;
21use nrf5x::pinmux;
22
23const UARTE_MAX_BUFFER_SIZE: u32 = 0xff;
24
25static mut BYTE: u8 = 0;
26
27pub const UARTE0_BASE: StaticRef<UarteRegisters> =
28 unsafe { StaticRef::new(0x40002000 as *const UarteRegisters) };
29
30#[repr(C)]
31pub struct UarteRegisters {
32 task_startrx: WriteOnly<u32, Task::Register>,
33 task_stoprx: WriteOnly<u32, Task::Register>,
34 task_starttx: WriteOnly<u32, Task::Register>,
35 task_stoptx: WriteOnly<u32, Task::Register>,
36 _reserved1: [u32; 7],
37 task_flush_rx: WriteOnly<u32, Task::Register>,
38 _reserved2: [u32; 52],
39 event_cts: ReadWrite<u32, Event::Register>,
40 event_ncts: ReadWrite<u32, Event::Register>,
41 _reserved3: [u32; 2],
42 event_endrx: ReadWrite<u32, Event::Register>,
43 _reserved4: [u32; 3],
44 event_endtx: ReadWrite<u32, Event::Register>,
45 event_error: ReadWrite<u32, Event::Register>,
46 _reserved6: [u32; 7],
47 event_rxto: ReadWrite<u32, Event::Register>,
48 _reserved7: [u32; 1],
49 event_rxstarted: ReadWrite<u32, Event::Register>,
50 event_txstarted: ReadWrite<u32, Event::Register>,
51 _reserved8: [u32; 1],
52 event_txstopped: ReadWrite<u32, Event::Register>,
53 _reserved9: [u32; 41],
54 shorts: ReadWrite<u32, Shorts::Register>,
55 _reserved10: [u32; 64],
56 intenset: ReadWrite<u32, Interrupt::Register>,
57 intenclr: ReadWrite<u32, Interrupt::Register>,
58 _reserved11: [u32; 93],
59 errorsrc: ReadWrite<u32, ErrorSrc::Register>,
60 _reserved12: [u32; 31],
61 enable: ReadWrite<u32, Uart::Register>,
62 _reserved13: [u32; 1],
63 pselrts: ReadWrite<u32, Psel::Register>,
64 pseltxd: ReadWrite<u32, Psel::Register>,
65 pselcts: ReadWrite<u32, Psel::Register>,
66 pselrxd: ReadWrite<u32, Psel::Register>,
67 _reserved14: [u32; 3],
68 baudrate: ReadWrite<u32, Baudrate::Register>,
69 _reserved15: [u32; 3],
70 rxd_ptr: ReadWrite<u32, Pointer::Register>,
71 rxd_maxcnt: ReadWrite<u32, Counter::Register>,
72 rxd_amount: ReadOnly<u32, Counter::Register>,
73 _reserved16: [u32; 1],
74 txd_ptr: ReadWrite<u32, Pointer::Register>,
75 txd_maxcnt: ReadWrite<u32, Counter::Register>,
76 txd_amount: ReadOnly<u32, Counter::Register>,
77 _reserved17: [u32; 7],
78 config: ReadWrite<u32, Config::Register>,
79}
80
81register_bitfields! [u32,
82 Task [
84 ENABLE OFFSET(0) NUMBITS(1)
85 ],
86
87 Event [
89 READY OFFSET(0) NUMBITS(1)
90 ],
91
92 Shorts [
94 ENDRX_STARTRX OFFSET(5) NUMBITS(1),
96 ENDRX_STOPRX OFFSET(6) NUMBITS(1)
98 ],
99
100 Interrupt [
102 CTS OFFSET(0) NUMBITS(1),
103 NCTS OFFSET(1) NUMBITS(1),
104 ENDRX OFFSET(4) NUMBITS(1),
105 ENDTX OFFSET(8) NUMBITS(1),
106 ERROR OFFSET(9) NUMBITS(1),
107 RXTO OFFSET(17) NUMBITS(1),
108 RXSTARTED OFFSET(19) NUMBITS(1),
109 TXSTARTED OFFSET(20) NUMBITS(1),
110 TXSTOPPED OFFSET(22) NUMBITS(1)
111 ],
112
113 ErrorSrc [
115 OVERRUN OFFSET(0) NUMBITS(1),
116 PARITY OFFSET(1) NUMBITS(1),
117 FRAMING OFFSET(2) NUMBITS(1),
118 BREAK OFFSET(3) NUMBITS(1)
119 ],
120
121 Uart [
123 ENABLE OFFSET(0) NUMBITS(4) [
124 ON = 8,
125 OFF = 0
126 ]
127 ],
128
129 Psel [
131 PIN OFFSET(0) NUMBITS(6),
136 CONNECT OFFSET(31) NUMBITS(1)
138 ],
139
140 Baudrate [
142 BAUDRAUTE OFFSET(0) NUMBITS(32)
143 ],
144
145 Pointer [
147 POINTER OFFSET(0) NUMBITS(32)
148 ],
149
150 Counter [
152 COUNTER OFFSET(0) NUMBITS(8)
153 ],
154
155 Config [
157 HWFC OFFSET(0) NUMBITS(1),
158 PARITY OFFSET(1) NUMBITS(3)
159 ]
160];
161
162pub struct Uarte<'a> {
166 registers: StaticRef<UarteRegisters>,
167 tx_client: OptionalCell<&'a dyn uart::TransmitClient>,
168 tx_buffer: kernel::utilities::cells::TakeCell<'static, [u8]>,
169 tx_len: Cell<usize>,
170 tx_remaining_bytes: Cell<usize>,
171 rx_client: OptionalCell<&'a dyn uart::ReceiveClient>,
172 rx_buffer: kernel::utilities::cells::TakeCell<'static, [u8]>,
173 rx_remaining_bytes: Cell<usize>,
174 rx_abort_in_progress: Cell<bool>,
175 offset: Cell<usize>,
176}
177
178#[derive(Copy, Clone)]
179pub struct UARTParams {
180 pub baud_rate: u32,
181}
182
183impl<'a> Uarte<'a> {
184 pub const fn new(regs: StaticRef<UarteRegisters>) -> Uarte<'a> {
187 Uarte {
188 registers: regs,
189 tx_client: OptionalCell::empty(),
190 tx_buffer: kernel::utilities::cells::TakeCell::empty(),
191 tx_len: Cell::new(0),
192 tx_remaining_bytes: Cell::new(0),
193 rx_client: OptionalCell::empty(),
194 rx_buffer: kernel::utilities::cells::TakeCell::empty(),
195 rx_remaining_bytes: Cell::new(0),
196 rx_abort_in_progress: Cell::new(false),
197 offset: Cell::new(0),
198 }
199 }
200
201 pub fn initialize(
203 &self,
204 txd: pinmux::Pinmux,
205 rxd: pinmux::Pinmux,
206 cts: Option<pinmux::Pinmux>,
207 rts: Option<pinmux::Pinmux>,
208 ) {
209 self.registers.pseltxd.write(Psel::PIN.val(txd.into()));
210 self.registers.pselrxd.write(Psel::PIN.val(rxd.into()));
211 cts.map_or_else(
212 || {
213 self.registers.pselcts.write(Psel::CONNECT::SET);
216 },
217 |c| {
218 self.registers.pselcts.write(Psel::PIN.val(c.into()));
219 },
220 );
221 rts.map_or_else(
222 || {
223 self.registers.pselrts.write(Psel::CONNECT::SET);
226 },
227 |r| {
228 self.registers.pselrts.write(Psel::PIN.val(r.into()));
229 },
230 );
231
232 self.registers.event_endtx.write(Event::READY::CLEAR);
238
239 self.enable_uart();
240 }
241
242 fn get_divider_for_baud(&self, baud_rate: u32) -> Result<u32, ErrorCode> {
250 if baud_rate > 1_000_000 || baud_rate < 1200 {
251 return Err(ErrorCode::INVAL);
252 }
253
254 let system_clock = 16000000u64; let scalar = 32u64;
257 let target_baud: u64 = baud_rate.into();
258
259 let divider64 = (((target_baud << scalar) + (system_clock >> 1)) / system_clock) + 0x800;
261 let divider = (divider64 & 0xffff_f000) as u32;
262
263 Ok(divider)
264 }
265
266 fn set_baud_rate(&self, baud_rate: u32) -> Result<(), ErrorCode> {
267 let divider = self.get_divider_for_baud(baud_rate)?;
268 self.registers.baudrate.set(divider);
269
270 Ok(())
271 }
272
273 fn enable_uart(&self) {
275 self.registers.enable.write(Uart::ENABLE::ON);
276 }
277
278 #[allow(dead_code)]
279 fn disable_uart(&self) {
280 self.registers.enable.write(Uart::ENABLE::OFF);
281 }
282
283 fn enable_rx_interrupts(&self) {
284 self.registers.intenset.write(Interrupt::ENDRX::SET);
285 }
286
287 fn enable_tx_interrupts(&self) {
288 self.registers.intenset.write(Interrupt::ENDTX::SET);
289 }
290
291 fn disable_rx_interrupts(&self) {
292 self.registers.intenclr.write(Interrupt::ENDRX::SET);
293 }
294
295 fn disable_tx_interrupts(&self) {
296 self.registers.intenclr.write(Interrupt::ENDTX::SET);
297 }
298
299 #[inline(never)]
301 pub fn handle_interrupt(&self) {
302 if self.tx_ready() {
303 self.disable_tx_interrupts();
304 self.registers.event_endtx.write(Event::READY::CLEAR);
305 let tx_bytes = self.registers.txd_amount.get() as usize;
306
307 let rem = match self.tx_remaining_bytes.get().checked_sub(tx_bytes) {
308 None => return,
309 Some(r) => r,
310 };
311
312 if rem == 0 {
314 self.tx_client.map(|client| {
316 self.tx_buffer.take().map(|tx_buffer| {
317 client.transmitted_buffer(tx_buffer, self.tx_len.get(), Ok(()));
318 });
319 });
320 } else {
321 self.offset.set(self.offset.get() + tx_bytes);
323 self.tx_remaining_bytes.set(rem);
324 self.set_tx_dma_pointer_to_buffer();
325 self.registers
326 .txd_maxcnt
327 .write(Counter::COUNTER.val(min(rem as u32, UARTE_MAX_BUFFER_SIZE)));
328 self.registers.task_starttx.write(Task::ENABLE::SET);
329 self.enable_tx_interrupts();
330 }
331 }
332
333 if self.rx_ready() {
334 self.disable_rx_interrupts();
335
336 self.registers.event_endrx.write(Event::READY::CLEAR);
338
339 let rx_bytes = self.registers.rxd_amount.get() as usize;
341
342 if self.rx_abort_in_progress.get() {
345 self.rx_abort_in_progress.set(false);
346 self.rx_client.map(|client| {
347 self.rx_buffer.take().map(|rx_buffer| {
348 client.received_buffer(
349 rx_buffer,
350 self.offset.get() + rx_bytes,
351 Err(ErrorCode::CANCEL),
352 uart::Error::None,
353 );
354 });
355 });
356 } else {
357 self.rx_remaining_bytes
363 .set(self.rx_remaining_bytes.get().saturating_sub(rx_bytes));
364 self.offset.set(self.offset.get() + rx_bytes);
365
366 let rem = self.rx_remaining_bytes.get();
367 if rem == 0 {
368 self.rx_client.map(|client| {
370 self.rx_buffer.take().map(|rx_buffer| {
371 client.received_buffer(
372 rx_buffer,
373 self.offset.get(),
374 Ok(()),
375 uart::Error::None,
376 );
377 });
378 });
379 } else {
380 let to_read = core::cmp::min(rem, 255);
383 self.registers
384 .rxd_maxcnt
385 .write(Counter::COUNTER.val(to_read as u32));
386
387 self.set_rx_dma_pointer_to_buffer();
389 self.registers.task_startrx.write(Task::ENABLE::SET);
390 self.enable_rx_interrupts();
391 }
392 }
393 }
394 }
395
396 pub unsafe fn send_byte(&self, byte: u8) {
399 self.tx_remaining_bytes.set(1);
400 self.registers.event_endtx.write(Event::READY::CLEAR);
401 BYTE = byte;
403 self.registers.txd_ptr.set(core::ptr::addr_of!(BYTE) as u32);
404 self.registers.txd_maxcnt.write(Counter::COUNTER.val(1));
405 self.registers.task_starttx.write(Task::ENABLE::SET);
406 }
407
408 pub fn tx_ready(&self) -> bool {
410 self.registers.event_endtx.is_set(Event::READY)
411 }
412
413 pub fn rx_ready(&self) -> bool {
415 self.registers.event_endrx.is_set(Event::READY)
416 }
417
418 fn set_tx_dma_pointer_to_buffer(&self) {
419 self.tx_buffer.map(|tx_buffer| {
420 self.registers
421 .txd_ptr
422 .set(tx_buffer[self.offset.get()..].as_ptr() as u32);
423 });
424 }
425
426 fn set_rx_dma_pointer_to_buffer(&self) {
427 self.rx_buffer.map(|rx_buffer| {
428 self.registers
429 .rxd_ptr
430 .set(rx_buffer[self.offset.get()..].as_ptr() as u32);
431 });
432 }
433
434 fn setup_buffer_transmit(&self, buf: &'static mut [u8], tx_len: usize) {
436 self.tx_remaining_bytes.set(tx_len);
437 self.tx_len.set(tx_len);
438 self.offset.set(0);
439 self.tx_buffer.replace(buf);
440 self.set_tx_dma_pointer_to_buffer();
441
442 self.registers
443 .txd_maxcnt
444 .write(Counter::COUNTER.val(min(tx_len as u32, UARTE_MAX_BUFFER_SIZE)));
445 self.registers.task_starttx.write(Task::ENABLE::SET);
446
447 self.enable_tx_interrupts();
448 }
449}
450
451impl<'a> uart::Transmit<'a> for Uarte<'a> {
452 fn set_transmit_client(&self, client: &'a dyn uart::TransmitClient) {
453 self.tx_client.set(client);
454 }
455
456 fn transmit_buffer(
457 &self,
458 tx_data: &'static mut [u8],
459 tx_len: usize,
460 ) -> Result<(), (ErrorCode, &'static mut [u8])> {
461 if tx_len == 0 || tx_len > tx_data.len() {
462 Err((ErrorCode::SIZE, tx_data))
463 } else if self.tx_buffer.is_some() {
464 Err((ErrorCode::BUSY, tx_data))
465 } else {
466 self.setup_buffer_transmit(tx_data, tx_len);
467 Ok(())
468 }
469 }
470
471 fn transmit_word(&self, _data: u32) -> Result<(), ErrorCode> {
472 Err(ErrorCode::FAIL)
473 }
474
475 fn transmit_abort(&self) -> Result<(), ErrorCode> {
476 Err(ErrorCode::FAIL)
477 }
478}
479
480impl uart::Configure for Uarte<'_> {
481 fn configure(&self, params: uart::Parameters) -> Result<(), ErrorCode> {
482 if params.stop_bits != uart::StopBits::One {
485 return Err(ErrorCode::NOSUPPORT);
486 }
487 if params.parity != uart::Parity::None {
488 return Err(ErrorCode::NOSUPPORT);
489 }
490 if params.hw_flow_control {
491 return Err(ErrorCode::NOSUPPORT);
492 }
493
494 self.set_baud_rate(params.baud_rate)?;
495
496 Ok(())
497 }
498}
499
500impl<'a> uart::Receive<'a> for Uarte<'a> {
501 fn set_receive_client(&self, client: &'a dyn uart::ReceiveClient) {
502 self.rx_client.set(client);
503 }
504
505 fn receive_buffer(
506 &self,
507 rx_buf: &'static mut [u8],
508 rx_len: usize,
509 ) -> Result<(), (ErrorCode, &'static mut [u8])> {
510 if self.rx_buffer.is_some() {
511 return Err((ErrorCode::BUSY, rx_buf));
512 }
513 let truncated_length = core::cmp::min(rx_len, rx_buf.len());
515
516 self.rx_remaining_bytes.set(truncated_length);
517 self.offset.set(0);
518 self.rx_buffer.replace(rx_buf);
519 self.set_rx_dma_pointer_to_buffer();
520
521 let truncated_uart_max_length = core::cmp::min(truncated_length, 255);
522
523 self.registers
524 .rxd_maxcnt
525 .write(Counter::COUNTER.val(truncated_uart_max_length as u32));
526 self.registers.task_stoprx.write(Task::ENABLE::SET);
527 self.registers.task_startrx.write(Task::ENABLE::SET);
528
529 self.enable_rx_interrupts();
530 Ok(())
531 }
532
533 fn receive_word(&self) -> Result<(), ErrorCode> {
534 Err(ErrorCode::FAIL)
535 }
536
537 fn receive_abort(&self) -> Result<(), ErrorCode> {
538 if self.rx_buffer.is_none() {
540 Ok(())
541 } else {
542 self.rx_abort_in_progress.set(true);
543 self.registers.task_stoprx.write(Task::ENABLE::SET);
544 Err(ErrorCode::BUSY)
545 }
546 }
547}
548
549#[cfg(test)]
550mod tests {
551 use kernel::ErrorCode;
552
553 #[test]
554 fn baud_rate_divider_calculation() {
555 let u = super::Uarte::new(super::UARTE0_BASE);
556 assert_eq!(u.get_divider_for_baud(0), Err(ErrorCode::INVAL));
557 assert_eq!(u.get_divider_for_baud(4_000_000), Err(ErrorCode::INVAL));
558
559 assert_eq!(u.get_divider_for_baud(1200), Ok(0x0004F000));
571 assert_eq!(u.get_divider_for_baud(2400), Ok(0x0009D000));
572 assert_eq!(u.get_divider_for_baud(4800), Ok(0x0013B000));
573 assert_eq!(u.get_divider_for_baud(9600), Ok(0x00275000));
574 assert_eq!(u.get_divider_for_baud(19200), Ok(0x004EA000));
576 assert_eq!(u.get_divider_for_baud(76800), Ok(0x013A9000));
580 assert_eq!(u.get_divider_for_baud(250000), Ok(0x04000000));
583 assert_eq!(u.get_divider_for_baud(1000000), Ok(0x10000000));
586 assert_eq!(u.get_divider_for_baud(14400), Ok(0x003B0000));
592 assert_eq!(u.get_divider_for_baud(28800), Ok(0x0075F000));
593 assert_eq!(u.get_divider_for_baud(38400), Ok(0x009D5000));
594 assert_eq!(u.get_divider_for_baud(57600), Ok(0x00EBF000));
595 assert_eq!(u.get_divider_for_baud(115200), Ok(0x01D7E000));
596 assert_eq!(u.get_divider_for_baud(230400), Ok(0x03AFB000));
597 assert_eq!(u.get_divider_for_baud(460800), Ok(0x075F7000));
598 assert_eq!(u.get_divider_for_baud(921600), Ok(0x0EBEE000));
599 }
600}