1use core::cell::Cell;
8use kernel::ErrorCode;
9
10use kernel::hil;
11use kernel::hil::uart;
12use kernel::utilities::cells::OptionalCell;
13use kernel::utilities::cells::TakeCell;
14use kernel::utilities::registers::interfaces::{ReadWriteable, Readable, Writeable};
15use kernel::utilities::registers::{register_bitfields, register_structs, ReadWrite};
16use kernel::utilities::StaticRef;
17
18const UART0_BASE: StaticRef<UartRegisters> =
19 unsafe { StaticRef::new(0x4001_C000 as *const UartRegisters) };
20
21pub const UART1_BASE: StaticRef<UartRegisters> =
22 unsafe { StaticRef::new(0x4001_D000 as *const UartRegisters) };
23
24register_structs! {
25 pub UartRegisters {
26 (0x000 => dr: ReadWrite<u32, DR::Register>),
27 (0x004 => rsr: ReadWrite<u32, RSR::Register>),
28 (0x008 => _reserved0),
29 (0x018 => fr: ReadWrite<u32, FR::Register>),
30 (0x01c => _reserved1),
31 (0x020 => ilpr: ReadWrite<u32, ILPR::Register>),
32 (0x024 => ibrd: ReadWrite<u32, IBRD::Register>),
33 (0x028 => fbrd: ReadWrite<u32, FBRD::Register>),
34 (0x02c => lcrh: ReadWrite<u32, LCRH::Register>),
35 (0x030 => cr: ReadWrite<u32, CR::Register>),
36 (0x034 => ifls: ReadWrite<u32, IFLS::Register>),
37 (0x038 => ier: ReadWrite<u32, IER::Register>),
38 (0x03c => ies: ReadWrite<u32, IES::Register>),
39 (0x040 => mis: ReadWrite<u32, MIS::Register>),
40 (0x044 => iec: ReadWrite<u32, IEC::Register>),
41 (0x048 => @END),
42 }
43}
44
45register_bitfields![u32,
46 DR [
47 DATA OFFSET(0) NUMBITS(8) [],
48 FEDATA OFFSET(8) NUMBITS(1) [],
49 PEDATA OFFSET(9) NUMBITS(1) [],
50 BEDATA OFFSET(10) NUMBITS(1) [],
51 OEDATA OFFSET(11) NUMBITS(1) []
52 ],
53 RSR [
54 FESTAT OFFSET(0) NUMBITS(1) [],
55 PESTAT OFFSET(1) NUMBITS(1) [],
56 BESTAT OFFSET(2) NUMBITS(1) [],
57 OESTAT OFFSET(4) NUMBITS(1) []
58 ],
59 FR [
60 CTS OFFSET(0) NUMBITS(1) [],
61 DSR OFFSET(1) NUMBITS(1) [],
62 DCD OFFSET(2) NUMBITS(1) [],
63 BUSY OFFSET(3) NUMBITS(1) [],
64 RXFE OFFSET(4) NUMBITS(1) [],
65 TXFF OFFSET(5) NUMBITS(1) [],
66 RXFF OFFSET(6) NUMBITS(1) [],
67 TXFE OFFSET(7) NUMBITS(1) [],
68 TXBUSY OFFSET(8) NUMBITS(1) []
69 ],
70 ILPR [
71 ILPDVSR OFFSET(0) NUMBITS(8) []
72 ],
73 IBRD [
74 DIVINT OFFSET(0) NUMBITS(16) []
75 ],
76 FBRD [
77 DIVFRAC OFFSET(0) NUMBITS(6) []
78 ],
79 LCRH [
80 BRK OFFSET(0) NUMBITS(1) [],
81 PEN OFFSET(1) NUMBITS(1) [],
82 EPS OFFSET(2) NUMBITS(1) [],
83 STP2 OFFSET(3) NUMBITS(1) [],
84 FEN OFFSET(4) NUMBITS(1) [],
85 WLEN OFFSET(5) NUMBITS(2) [],
86 SPS OFFSET(7) NUMBITS(1) []
87 ],
88 CR [
89 UARTEN OFFSET(0) NUMBITS(1) [],
90 SIREN OFFSET(1) NUMBITS(1) [],
91 SIRLP OFFSET(2) NUMBITS(1) [],
92 CLKEN OFFSET(3) NUMBITS(1) [],
93 CLKSEL OFFSET(4) NUMBITS(2) [
94 CLK_24MHZ = 0x1,
95 CLK_12MHZ = 0x2,
96 CLK_6MHZ = 0x3,
97 CLK_3MHZ = 0x4
98 ],
99 LBE OFFSET(7) NUMBITS(1) [],
100 TXE OFFSET(8) NUMBITS(1) [],
101 RXE OFFSET(9) NUMBITS(1) [],
102 DTR OFFSET(10) NUMBITS(1) [],
103 RTS OFFSET(11) NUMBITS(1) [],
104 OUT1 OFFSET(12) NUMBITS(1) [],
105 OUT2 OFFSET(13) NUMBITS(1) [],
106 RTSEN OFFSET(14) NUMBITS(1) [],
107 CTSEN OFFSET(15) NUMBITS(1) []
108 ],
109 IFLS [
110 TXIFLSEL OFFSET(0) NUMBITS(3) [],
111 RXIFLSEL OFFSET(3) NUMBITS(3) []
112 ],
113 IER [
114 TXCMPMIM OFFSET(0) NUMBITS(1) [],
115 CTSMIM OFFSET(1) NUMBITS(1) [],
116 DCDMIM OFFSET(2) NUMBITS(1) [],
117 DSRMIM OFFSET(3) NUMBITS(1) [],
118 RXIM OFFSET(4) NUMBITS(1) [],
119 TXIM OFFSET(5) NUMBITS(1) [],
120 RTIM OFFSET(6) NUMBITS(1) [],
121 FEIM OFFSET(7) NUMBITS(1) [],
122 PEIM OFFSET(8) NUMBITS(1) [],
123 BEIM OFFSET(9) NUMBITS(1) [],
124 OEIM OFFSET(10) NUMBITS(1) []
125 ],
126 IES [
127 TXCMPMIS OFFSET(0) NUMBITS(1) [],
128 CTSMIS OFFSET(1) NUMBITS(1) [],
129 DCDMIS OFFSET(2) NUMBITS(1) [],
130 DSRMIS OFFSET(3) NUMBITS(1) [],
131 RXIS OFFSET(4) NUMBITS(1) [],
132 TXIS OFFSET(5) NUMBITS(1) [],
133 RTIS OFFSET(6) NUMBITS(1) [],
134 FEIS OFFSET(7) NUMBITS(1) [],
135 PEIS OFFSET(8) NUMBITS(1) [],
136 BEIS OFFSET(9) NUMBITS(1) [],
137 OEIS OFFSET(10) NUMBITS(1) []
138 ],
139 MIS [
140 TXCMPMMIS OFFSET(0) NUMBITS(1) [],
141 CTSMMIS OFFSET(1) NUMBITS(1) [],
142 DCDMMIS OFFSET(2) NUMBITS(1) [],
143 DSRMMIS OFFSET(3) NUMBITS(1) [],
144 RXMIS OFFSET(4) NUMBITS(1) [],
145 TXMIS OFFSET(5) NUMBITS(1) [],
146 RTMIS OFFSET(6) NUMBITS(1) [],
147 FEMIS OFFSET(7) NUMBITS(1) [],
148 PEMIS OFFSET(8) NUMBITS(1) [],
149 BEMIS OFFSET(9) NUMBITS(1) [],
150 OEMIS OFFSET(10) NUMBITS(1) []
151 ],
152 IEC [
153 TXCMPMMIC OFFSET(0) NUMBITS(1) [],
154 CTSMMIC OFFSET(1) NUMBITS(1) [],
155 DCDMMIC OFFSET(2) NUMBITS(1) [],
156 DSRMMIC OFFSET(3) NUMBITS(1) [],
157 RXIC OFFSET(4) NUMBITS(1) [],
158 TXIC OFFSET(5) NUMBITS(1) [],
159 RTIC OFFSET(6) NUMBITS(1) [],
160 FEIC OFFSET(7) NUMBITS(1) [],
161 PEIC OFFSET(8) NUMBITS(1) [],
162 BEIC OFFSET(9) NUMBITS(1) [],
163 OEMC OFFSET(10) NUMBITS(1) []
164 ]
165];
166
167pub struct Uart<'a> {
168 registers: StaticRef<UartRegisters>,
169 clock_frequency: u32,
170 tx_client: OptionalCell<&'a dyn hil::uart::TransmitClient>,
171 rx_client: OptionalCell<&'a dyn hil::uart::ReceiveClient>,
172
173 tx_buffer: TakeCell<'static, [u8]>,
174 tx_len: Cell<usize>,
175 tx_index: Cell<usize>,
176
177 rx_buffer: TakeCell<'static, [u8]>,
178 rx_len: Cell<usize>,
179 rx_index: Cell<usize>,
180}
181
182#[derive(Copy, Clone)]
183pub struct UartParams {
184 pub baud_rate: u32,
185}
186
187impl Uart<'_> {
188 pub fn new_uart_0() -> Self {
190 Self {
191 registers: UART0_BASE,
192 clock_frequency: 24_000_000,
193 tx_client: OptionalCell::empty(),
194 rx_client: OptionalCell::empty(),
195 tx_buffer: TakeCell::empty(),
196 tx_len: Cell::new(0),
197 tx_index: Cell::new(0),
198 rx_buffer: TakeCell::empty(),
199 rx_len: Cell::new(0),
200 rx_index: Cell::new(0),
201 }
202 }
203
204 pub fn new_uart_1() -> Self {
206 Self {
207 registers: UART1_BASE,
208 clock_frequency: 24_000_000,
209 tx_client: OptionalCell::empty(),
210 rx_client: OptionalCell::empty(),
211 tx_buffer: TakeCell::empty(),
212 tx_len: Cell::new(0),
213 tx_index: Cell::new(0),
214 rx_buffer: TakeCell::empty(),
215 rx_len: Cell::new(0),
216 rx_index: Cell::new(0),
217 }
218 }
219
220 fn set_baud_rate(&self, baud_rate: u32) {
221 let regs = self.registers;
222
223 let baud_clk = 16 * baud_rate;
224 let integer_divisor = self.clock_frequency / baud_clk;
225 let intermediate_long = (self.clock_frequency * 64) / baud_clk;
226 let fraction_divisor_long = intermediate_long - (integer_divisor * 64);
227
228 regs.ibrd.write(IBRD::DIVINT.val(integer_divisor));
229 regs.fbrd.write(FBRD::DIVFRAC.val(fraction_divisor_long));
230 }
231
232 fn enable_tx_interrupt(&self) {
233 let regs = self.registers;
234
235 regs.ifls.modify(IFLS::TXIFLSEL.val(0));
237
238 regs.ier.modify(IER::TXIM::SET + IER::TXCMPMIM::SET);
239 }
240
241 fn disable_tx_interrupt(&self) {
242 let regs = self.registers;
243
244 regs.ier.modify(IER::TXIM::CLEAR + IER::TXCMPMIM::CLEAR);
245 regs.iec.modify(IEC::TXIC::SET + IEC::TXCMPMMIC::SET);
246 }
247
248 fn enable_rx_interrupt(&self) {
249 let regs = self.registers;
250
251 regs.ifls.modify(IFLS::RXIFLSEL.val(1));
253
254 regs.ier.modify(IER::RXIM::SET + IER::RTIM::SET);
255 }
256
257 fn disable_rx_interrupt(&self) {
258 let regs = self.registers;
259
260 regs.ier.modify(IER::RXIM::CLEAR + IER::RTIM::CLEAR);
261 regs.iec.modify(IEC::RXIC::SET + IEC::RTIC::SET);
262 }
263
264 fn tx_progress(&self) {
265 let regs = self.registers;
266 let idx = self.tx_index.get();
267 let len = self.tx_len.get();
268
269 if idx < len {
270 self.enable_tx_interrupt();
275
276 self.tx_buffer.map(|tx_buf| {
279 let tx_len = len - idx;
280
281 for i in 0..tx_len {
282 if regs.fr.is_set(FR::TXFF) {
283 break;
284 }
285 let tx_idx = idx + i;
286 regs.dr.write(DR::DATA.val(tx_buf[tx_idx] as u32));
287 self.tx_index.set(tx_idx + 1)
288 }
289 });
290 }
291 }
292
293 fn rx_progress(&self) {
294 let regs = self.registers;
295 let idx = self.rx_index.get();
296 let len = self.rx_len.get();
297
298 if idx < len {
299 self.rx_buffer.map(|rx_buf| {
302 let rx_len = len - idx;
303
304 for i in 0..rx_len {
305 if regs.fr.is_set(FR::RXFE) {
306 break;
307 }
308
309 let rx_idx = idx + i;
310 let charecter = regs.dr.read(DR::DATA);
311
312 rx_buf[rx_idx] = charecter as u8;
313
314 self.rx_index.set(rx_idx + 1)
315 }
316 });
317 }
318
319 if self.rx_index.get() < self.rx_len.get() {
320 self.enable_rx_interrupt();
322 }
323 }
324
325 pub fn handle_interrupt(&self) {
326 let regs = self.registers;
327 let irq = regs.ies.extract();
328
329 if irq.is_set(IES::TXCMPMIS) {
330 self.disable_tx_interrupt();
332
333 if self.tx_index.get() >= self.tx_len.get() {
334 if self.rx_buffer.is_none() {
339 regs.cr.modify(CR::UARTEN::CLEAR);
340 }
341 regs.cr.modify(CR::TXE::CLEAR);
342
343 self.tx_client.map(|client| {
344 self.tx_buffer.take().map(|tx_buf| {
345 client.transmitted_buffer(tx_buf, self.tx_len.get(), Ok(()));
346 });
347 });
348 } else {
349 self.tx_progress();
351 }
352 }
353
354 if irq.is_set(IES::RTIS) {
355 self.disable_rx_interrupt();
356
357 self.rx_progress();
358
359 if self.rx_index.get() >= self.rx_len.get() {
360 if self.tx_buffer.is_none() {
362 regs.cr.modify(CR::UARTEN::CLEAR);
363 }
364 regs.cr.modify(CR::RXE::CLEAR);
365
366 self.rx_client.map(|client| {
367 self.rx_buffer.take().map(|rx_buf| {
368 client.received_buffer(
369 rx_buf,
370 self.rx_len.get(),
371 Ok(()),
372 uart::Error::None,
373 );
374 });
375 });
376 }
377 }
378 }
379
380 pub fn transmit_sync(&self, bytes: &[u8]) {
381 let regs = self.registers;
382 for b in bytes.iter() {
383 while regs.fr.is_set(FR::TXFF) {}
384 regs.dr.write(DR::DATA.val(*b as u32));
385 }
386 }
387}
388
389impl hil::uart::Configure for Uart<'_> {
390 fn configure(&self, params: hil::uart::Parameters) -> Result<(), ErrorCode> {
391 let regs = self.registers;
392
393 regs.cr
395 .write(CR::UARTEN::CLEAR + CR::RXE::CLEAR + CR::TXE::CLEAR);
396
397 regs.cr.modify(CR::CLKEN::SET + CR::CLKSEL::CLK_24MHZ);
399
400 self.set_baud_rate(params.baud_rate);
402
403 regs.cr.modify(CR::RTSEN::CLEAR + CR::CTSEN::CLEAR);
405 regs.lcrh.write(LCRH::FEN::SET);
407 regs.lcrh.modify(LCRH::WLEN.val(3) + LCRH::FEN::SET);
409
410 regs.ier.set(0x00);
412 regs.iec.set(0xFF);
413
414 Ok(())
415 }
416}
417
418impl<'a> hil::uart::Transmit<'a> for Uart<'a> {
419 fn set_transmit_client(&self, client: &'a dyn hil::uart::TransmitClient) {
420 self.tx_client.set(client);
421 }
422
423 fn transmit_buffer(
424 &self,
425 tx_data: &'static mut [u8],
426 tx_len: usize,
427 ) -> Result<(), (ErrorCode, &'static mut [u8])> {
428 if tx_len == 0 || tx_len > tx_data.len() {
429 Err((ErrorCode::SIZE, tx_data))
430 } else if self.tx_buffer.is_some() {
431 Err((ErrorCode::BUSY, tx_data))
432 } else {
433 self.tx_buffer.replace(tx_data);
435 self.tx_len.set(tx_len);
436 self.tx_index.set(0);
437
438 self.registers.cr.modify(CR::UARTEN::SET + CR::TXE::SET);
440
441 self.tx_progress();
442 Ok(())
443 }
444 }
445
446 fn transmit_abort(&self) -> Result<(), ErrorCode> {
447 Err(ErrorCode::FAIL)
448 }
449
450 fn transmit_word(&self, _word: u32) -> Result<(), ErrorCode> {
451 Err(ErrorCode::FAIL)
452 }
453}
454
455impl<'a> hil::uart::Receive<'a> for Uart<'a> {
456 fn set_receive_client(&self, client: &'a dyn hil::uart::ReceiveClient) {
457 self.rx_client.set(client);
458 }
459
460 fn receive_buffer(
461 &self,
462 rx_buffer: &'static mut [u8],
463 rx_len: usize,
464 ) -> Result<(), (ErrorCode, &'static mut [u8])> {
465 if rx_len == 0 || rx_len > rx_buffer.len() {
466 Err((ErrorCode::SIZE, rx_buffer))
467 } else {
468 self.rx_buffer.replace(rx_buffer);
470 self.rx_len.set(rx_len);
471 self.rx_index.set(0);
472
473 self.registers.cr.modify(CR::UARTEN::SET + CR::RXE::SET);
475
476 self.rx_progress();
477 Ok(())
478 }
479 }
480
481 fn receive_abort(&self) -> Result<(), ErrorCode> {
482 Err(ErrorCode::FAIL)
483 }
484
485 fn receive_word(&self) -> Result<(), ErrorCode> {
486 Err(ErrorCode::FAIL)
487 }
488}