1use core::cell::Cell;
7use kernel::deferred_call::{DeferredCall, DeferredCallClient};
8use kernel::hil;
9use kernel::platform::chip::ClockInterface;
10use kernel::utilities::cells::{OptionalCell, TakeCell};
11use kernel::utilities::registers::interfaces::{ReadWriteable, Readable, Writeable};
12use kernel::utilities::registers::{register_bitfields, ReadOnly, ReadWrite};
13use kernel::utilities::StaticRef;
14use kernel::ErrorCode;
15
16use crate::rcc;
17
18#[repr(C)]
20struct UsartRegisters {
21 cr1: ReadWrite<u32, CR1::Register>,
23 cr2: ReadWrite<u32, CR2::Register>,
25 cr3: ReadWrite<u32, CR3::Register>,
27 brr: ReadWrite<u32, BRR::Register>,
29 gtpr: ReadWrite<u32, GTPR::Register>,
31 rtor: ReadWrite<u32, RTOR::Register>,
33 rqr: ReadWrite<u32, RTOR::Register>,
35 isr: ReadWrite<u32, ISR::Register>,
37 icr: ReadWrite<u32, ICR::Register>,
39 rdr: ReadOnly<u32>,
41 tdr: ReadWrite<u32>,
43}
44
45register_bitfields![u32,
46 CR1 [
47 M1 OFFSET(28) NUMBITS(1) [],
49 EOBIE OFFSET(15) NUMBITS(1) [],
51 RTOIE OFFSET(26) NUMBITS(1) [],
53 DEAT OFFSET(21) NUMBITS(5) [],
55 DEDT OFFSET(16) NUMBITS(5) [],
57 OVER8 OFFSET(15) NUMBITS(1) [],
59 CMIE OFFSET(14) NUMBITS(1) [],
61 MME OFFSET(13) NUMBITS(1) [],
63 M0 OFFSET(12) NUMBITS(1) [],
65 WAKE OFFSET(11) NUMBITS(1) [],
67 PCE OFFSET(10) NUMBITS(1) [],
69 PS OFFSET(9) NUMBITS(1) [],
71 PEIE OFFSET(8) NUMBITS(1) [],
73 TXEIE OFFSET(7) NUMBITS(1) [],
75 TCIE OFFSET(6) NUMBITS(1) [],
77 RXNEIE OFFSET(5) NUMBITS(1) [],
79 IDLEIE OFFSET(4) NUMBITS(1) [],
81 TE OFFSET(3) NUMBITS(1) [],
83 RE OFFSET(2) NUMBITS(1) [],
85 UESM OFFSET(1) NUMBITS(1) [],
87 UE OFFSET(0) NUMBITS(1) []
89 ],
90 CR2 [
91 ADD1 OFFSET(28) NUMBITS(1) [],
93 ADD0 OFFSET(24) NUMBITS(4) [],
95 RTOEN OFFSET(23) NUMBITS(1) [],
97 ABRMOD OFFSET(21) NUMBITS(2) [],
99 ABREN OFFSET(20) NUMBITS(1) [],
101 MSBFIRST OFFSET(19) NUMBITS(1) [],
103 DATAINV OFFSET(18) NUMBITS(1) [],
105 TXINV OFFSET(17) NUMBITS(1) [],
107 RXINV OFFSET(16) NUMBITS(1) [],
109 SWAP OFFSET(15) NUMBITS(1) [],
111 LINEN OFFSET(14) NUMBITS(1) [],
113 STOP OFFSET(12) NUMBITS(2) [],
115 CLKEN OFFSET(11) NUMBITS(1) [],
117 CPOL OFFSET(10) NUMBITS(1) [],
119 CPHA OFFSET(9) NUMBITS(1) [],
121 LBCL OFFSET(8) NUMBITS(1) [],
123 LBDIE OFFSET(6) NUMBITS(1) [],
125 LBDL OFFSET(5) NUMBITS(1) [],
127 ADDM7 OFFSET(4) NUMBITS(1) []
129 ],
130 CR3 [
131 WUFIE OFFSET(22) NUMBITS(1) [],
133 WUS OFFSET(20) NUMBITS(2) [],
135 SCARCNT OFFSET(17) NUMBITS(2) [],
137 DEP OFFSET(15) NUMBITS(1) [],
139 DEM OFFSET(14) NUMBITS(1) [],
141 DDRE OFFSET(13) NUMBITS(1) [],
143 OVRDIS OFFSET(12) NUMBITS(1) [],
145 ONEBIT OFFSET(11) NUMBITS(1) [],
147 CTSIE OFFSET(10) NUMBITS(1) [],
149 CTSE OFFSET(9) NUMBITS(1) [],
151 RTSE OFFSET(8) NUMBITS(1) [],
153 DMAT OFFSET(7) NUMBITS(1) [],
155 DMAR OFFSET(6) NUMBITS(1) [],
157 SCEN OFFSET(5) NUMBITS(1) [],
159 NACK OFFSET(4) NUMBITS(1) [],
161 HDSEL OFFSET(3) NUMBITS(1) [],
163 IRLP OFFSET(2) NUMBITS(1) [],
165 IREN OFFSET(1) NUMBITS(1) [],
167 EIE OFFSET(0) NUMBITS(1) []
169 ],
170 BRR [
171 DIV_Mantissa OFFSET(4) NUMBITS(12) [],
173 DIV_Fraction OFFSET(0) NUMBITS(4) []
175 ],
176 GTPR [
177 GT OFFSET(8) NUMBITS(8) [],
179 PSC OFFSET(0) NUMBITS(8) []
181 ],
182 RTOR [
183 BLEN OFFSET(24) NUMBITS(8) [],
185 RTO OFFSET(0) NUMBITS(24) []
187 ],
188 RQR [
189 TXFRQ OFFSET(0) NUMBITS(1) [],
191 RXFRQ OFFSET(3) NUMBITS(1) [],
193 MMRQ OFFSET(2) NUMBITS(1) [],
195 SBKRQ OFFSET(1) NUMBITS(1) [],
197 ABRRQ OFFSET(0) NUMBITS(1) []
199 ],
200 ISR [
201 REACK OFFSET(22) NUMBITS(1) [],
203 TEACK OFFSET(21) NUMBITS(1) [],
205 WUF OFFSET(20) NUMBITS(1) [],
207 RWU OFFSET(19) NUMBITS(1) [],
209 SBKF OFFSET(18) NUMBITS(1) [],
211 CMF OFFSET(17) NUMBITS(1) [],
213 BUSY OFFSET(16) NUMBITS(1) [],
215 ABRF OFFSET(15) NUMBITS(1) [],
217 ABRE OFFSET(14) NUMBITS(1) [],
219 EOBF OFFSET(12) NUMBITS(1) [],
221 RTOF OFFSET(11) NUMBITS(1) [],
223 CTS OFFSET(10) NUMBITS(1) [],
225 CTSIF OFFSET(9) NUMBITS(1) [],
227 LBDF OFFSET(8) NUMBITS(1) [],
229 TXE OFFSET(7) NUMBITS(1) [],
231 TC OFFSET(6) NUMBITS(1) [],
233 RXNE OFFSET(5) NUMBITS(1) [],
235 IDLE OFFSET(4) NUMBITS(1) [],
237 ORE OFFSET(3) NUMBITS(1) [],
239 NF OFFSET(2) NUMBITS(1) [],
241 FE OFFSET(1) NUMBITS(1) [],
243 PE OFFSET(0) NUMBITS(1) []
245 ],
246 ICR [
247 WUCF OFFSET(20) NUMBITS(1) [],
249 CMCF OFFSET(17) NUMBITS(1) [],
251 EOBCF OFFSET(12) NUMBITS(1) [],
253 RTOCF OFFSET(11) NUMBITS(1) [],
255 CTSCF OFFSET(9) NUMBITS(1) [],
257 LBDCF OFFSET(8) NUMBITS(1) [],
259 TCCF OFFSET(6) NUMBITS(1) [],
261 IDLECF OFFSET(4) NUMBITS(1) [],
263 ORECF OFFSET(3) NUMBITS(1) [],
265 NCF OFFSET(2) NUMBITS(1) [],
267 FECF OFFSET(1) NUMBITS(1) [],
269 PECF OFFSET(0) NUMBITS(1) []
271 ]
272];
273
274const USART1_BASE: StaticRef<UsartRegisters> =
275 unsafe { StaticRef::new(0x40013800 as *const UsartRegisters) };
276const USART2_BASE: StaticRef<UsartRegisters> =
277 unsafe { StaticRef::new(0x40004400 as *const UsartRegisters) };
278const USART3_BASE: StaticRef<UsartRegisters> =
279 unsafe { StaticRef::new(0x40004800 as *const UsartRegisters) };
280
281#[allow(non_camel_case_types)]
282#[derive(Copy, Clone, PartialEq)]
283enum USARTStateTX {
284 Idle,
285 Transmitting,
286 AbortRequested,
287}
288
289#[allow(non_camel_case_types)]
290#[derive(Copy, Clone, PartialEq)]
291enum USARTStateRX {
292 Idle,
293 Receiving,
294 AbortRequested,
295}
296
297pub struct Usart<'a> {
298 registers: StaticRef<UsartRegisters>,
299 clock: UsartClock<'a>,
300
301 tx_client: OptionalCell<&'a dyn hil::uart::TransmitClient>,
302 rx_client: OptionalCell<&'a dyn hil::uart::ReceiveClient>,
303
304 tx_buffer: TakeCell<'static, [u8]>,
305 tx_position: Cell<usize>,
306 tx_len: Cell<usize>,
307 tx_status: Cell<USARTStateTX>,
308
309 rx_buffer: TakeCell<'static, [u8]>,
310 rx_position: Cell<usize>,
311 rx_len: Cell<usize>,
312 rx_status: Cell<USARTStateRX>,
313
314 deferred_call: DeferredCall,
315}
316
317impl<'a> Usart<'a> {
318 fn new(base_addr: StaticRef<UsartRegisters>, clock: UsartClock<'a>) -> Self {
319 Self {
320 registers: base_addr,
321 clock,
322
323 tx_client: OptionalCell::empty(),
324 rx_client: OptionalCell::empty(),
325
326 tx_buffer: TakeCell::empty(),
327 tx_position: Cell::new(0),
328 tx_len: Cell::new(0),
329 tx_status: Cell::new(USARTStateTX::Idle),
330
331 rx_buffer: TakeCell::empty(),
332 rx_position: Cell::new(0),
333 rx_len: Cell::new(0),
334 rx_status: Cell::new(USARTStateRX::Idle),
335
336 deferred_call: DeferredCall::new(),
337 }
338 }
339
340 pub fn new_usart1(rcc: &'a rcc::Rcc) -> Self {
341 Self::new(
342 USART1_BASE,
343 UsartClock(rcc::PeripheralClock::new(
344 rcc::PeripheralClockType::APB2(rcc::PCLK2::USART1),
345 rcc,
346 )),
347 )
348 }
349
350 pub fn new_usart2(rcc: &'a rcc::Rcc) -> Self {
351 Self::new(
352 USART2_BASE,
353 UsartClock(rcc::PeripheralClock::new(
354 rcc::PeripheralClockType::APB1(rcc::PCLK1::USART2),
355 rcc,
356 )),
357 )
358 }
359
360 pub fn new_usart3(rcc: &'a rcc::Rcc) -> Self {
361 Self::new(
362 USART3_BASE,
363 UsartClock(rcc::PeripheralClock::new(
364 rcc::PeripheralClockType::APB1(rcc::PCLK1::USART3),
365 rcc,
366 )),
367 )
368 }
369
370 pub fn is_enabled_clock(&self) -> bool {
371 self.clock.is_enabled()
372 }
373
374 pub fn enable_clock(&self) {
375 self.clock.enable();
376 }
377
378 pub fn disable_clock(&self) {
379 self.clock.disable();
380 }
381
382 pub fn send_byte(&self, byte: u8) {
384 while !self.registers.isr.is_set(ISR::TXE) {}
386 self.registers.tdr.set(byte.into());
387 }
388
389 fn enable_transmit_interrupt(&self) {
390 self.registers.cr1.modify(CR1::TXEIE::SET);
391 }
392
393 fn disable_transmit_interrupt(&self) {
394 self.registers.cr1.modify(CR1::TXEIE::CLEAR);
395 }
396
397 fn enable_receive_interrupt(&self) {
398 self.registers.cr1.modify(CR1::RXNEIE::SET);
399 }
400
401 fn disable_receive_interrupt(&self) {
402 self.registers.cr1.modify(CR1::RXNEIE::CLEAR);
403 }
404
405 fn clear_overrun(&self) {
406 self.registers.icr.modify(ICR::ORECF::SET);
407 }
408
409 pub fn handle_interrupt(&self) {
410 if self.registers.isr.is_set(ISR::TXE) {
411 self.disable_transmit_interrupt();
412
413 if self.tx_status.get() == USARTStateTX::Transmitting {
415 if self.tx_position.get() < self.tx_len.get() {
416 self.tx_buffer.map(|buf| {
417 self.registers.tdr.set(buf[self.tx_position.get()].into());
418 self.tx_position.replace(self.tx_position.get() + 1);
419 });
420 }
421 if self.tx_position.get() == self.tx_len.get() {
422 self.tx_status.replace(USARTStateTX::Idle);
424 } else {
425 self.enable_transmit_interrupt();
426 }
427 if self.tx_status.get() == USARTStateTX::Idle {
429 self.tx_client.map(|client| {
430 if let Some(buf) = self.tx_buffer.take() {
431 client.transmitted_buffer(buf, self.tx_len.get(), Ok(()));
432 }
433 });
434 }
435 }
436 }
437
438 if self.registers.isr.is_set(ISR::RXNE) {
439 let byte = self.registers.rdr.get() as u8;
440 self.disable_receive_interrupt();
441
442 if self.rx_status.get() == USARTStateRX::Receiving {
444 if self.rx_position.get() < self.rx_len.get() {
445 self.rx_buffer.map(|buf| {
446 buf[self.rx_position.get()] = byte;
447 self.rx_position.replace(self.rx_position.get() + 1);
448 });
449 }
450 if self.rx_position.get() == self.rx_len.get() {
451 self.rx_status.replace(USARTStateRX::Idle);
453 } else {
454 self.enable_receive_interrupt();
455 }
456 if self.rx_status.get() == USARTStateRX::Idle {
458 self.rx_client.map(|client| {
459 if let Some(buf) = self.rx_buffer.take() {
460 client.received_buffer(
461 buf,
462 self.rx_len.get(),
463 Ok(()),
464 hil::uart::Error::None,
465 );
466 }
467 });
468 }
469 }
470 }
471
472 if self.registers.isr.is_set(ISR::ORE) {
473 self.clear_overrun();
474 self.rx_status.replace(USARTStateRX::Idle);
475 self.rx_client.map(|client| {
476 if let Some(buf) = self.rx_buffer.take() {
477 client.received_buffer(
478 buf,
479 self.rx_position.get(),
480 Err(ErrorCode::CANCEL),
481 hil::uart::Error::OverrunError,
482 );
483 }
484 });
485 }
486 }
487}
488
489impl DeferredCallClient for Usart<'_> {
490 fn register(&'static self) {
491 self.deferred_call.register(self);
492 }
493
494 fn handle_deferred_call(&self) {
495 if self.tx_status.get() == USARTStateTX::AbortRequested {
496 self.tx_client.map(|client| {
498 self.tx_buffer.take().map(|buf| {
499 client.transmitted_buffer(buf, self.tx_position.get(), Err(ErrorCode::CANCEL));
500 });
501 });
502 self.tx_status.set(USARTStateTX::Idle);
503 }
504
505 if self.rx_status.get() == USARTStateRX::AbortRequested {
506 self.rx_client.map(|client| {
508 self.rx_buffer.take().map(|buf| {
509 client.received_buffer(
510 buf,
511 self.rx_position.get(),
512 Err(ErrorCode::CANCEL),
513 hil::uart::Error::Aborted,
514 );
515 });
516 });
517 self.rx_status.set(USARTStateRX::Idle);
518 }
519 }
520}
521
522impl<'a> hil::uart::Transmit<'a> for Usart<'a> {
523 fn set_transmit_client(&self, client: &'a dyn hil::uart::TransmitClient) {
524 self.tx_client.set(client);
525 }
526
527 fn transmit_buffer(
528 &self,
529 tx_data: &'static mut [u8],
530 tx_len: usize,
531 ) -> Result<(), (ErrorCode, &'static mut [u8])> {
532 if self.tx_status.get() == USARTStateTX::Idle {
533 if tx_len <= tx_data.len() {
534 self.tx_buffer.put(Some(tx_data));
535 self.tx_position.set(0);
536 self.tx_len.set(tx_len);
537 self.tx_status.set(USARTStateTX::Transmitting);
538 self.enable_transmit_interrupt();
539 Ok(())
540 } else {
541 Err((ErrorCode::SIZE, tx_data))
542 }
543 } else {
544 Err((ErrorCode::BUSY, tx_data))
545 }
546 }
547
548 fn transmit_word(&self, _word: u32) -> Result<(), ErrorCode> {
549 Err(ErrorCode::FAIL)
550 }
551
552 fn transmit_abort(&self) -> Result<(), ErrorCode> {
553 if self.tx_status.get() != USARTStateTX::Idle {
554 self.disable_transmit_interrupt();
555 self.tx_status.set(USARTStateTX::AbortRequested);
556
557 self.deferred_call.set();
558
559 Err(ErrorCode::BUSY)
560 } else {
561 Ok(())
562 }
563 }
564}
565
566impl hil::uart::Configure for Usart<'_> {
567 fn configure(&self, params: hil::uart::Parameters) -> Result<(), ErrorCode> {
568 if params.baud_rate != 115200
569 || params.stop_bits != hil::uart::StopBits::One
570 || params.parity != hil::uart::Parity::None
571 || params.hw_flow_control
572 || params.width != hil::uart::Width::Eight
573 {
574 panic!(
575 "Currently we only support uart setting of 115200bps 8N1, no hardware flow control"
576 );
577 }
578
579 self.registers.cr1.modify(CR1::M0::CLEAR);
581 self.registers.cr1.modify(CR1::M1::CLEAR);
582
583 self.registers.cr2.modify(CR2::STOP.val(0b00_u32));
585
586 self.registers.cr1.modify(CR1::PCE::CLEAR);
588
589 self.registers.brr.modify(BRR::DIV_Fraction.val(0x5_u32));
595 self.registers.brr.modify(BRR::DIV_Mantissa.val(0x4_u32));
596
597 self.registers.cr1.modify(CR1::TE::SET);
599
600 self.registers.cr1.modify(CR1::RE::SET);
602
603 self.registers.cr1.modify(CR1::UE::SET);
605
606 Ok(())
607 }
608}
609
610impl<'a> hil::uart::Receive<'a> for Usart<'a> {
611 fn set_receive_client(&self, client: &'a dyn hil::uart::ReceiveClient) {
612 self.rx_client.set(client);
613 }
614
615 fn receive_buffer(
616 &self,
617 rx_buffer: &'static mut [u8],
618 rx_len: usize,
619 ) -> Result<(), (ErrorCode, &'static mut [u8])> {
620 if self.rx_status.get() == USARTStateRX::Idle {
621 if rx_len <= rx_buffer.len() {
622 self.rx_buffer.put(Some(rx_buffer));
623 self.rx_position.set(0);
624 self.rx_len.set(rx_len);
625 self.rx_status.set(USARTStateRX::Receiving);
626 self.enable_receive_interrupt();
627 Ok(())
628 } else {
629 Err((ErrorCode::SIZE, rx_buffer))
630 }
631 } else {
632 Err((ErrorCode::BUSY, rx_buffer))
633 }
634 }
635
636 fn receive_word(&self) -> Result<(), ErrorCode> {
637 Err(ErrorCode::FAIL)
638 }
639
640 fn receive_abort(&self) -> Result<(), ErrorCode> {
641 if self.rx_status.get() != USARTStateRX::Idle {
642 self.disable_receive_interrupt();
643 self.rx_status.set(USARTStateRX::AbortRequested);
644
645 self.deferred_call.set();
646
647 Err(ErrorCode::BUSY)
648 } else {
649 Ok(())
650 }
651 }
652}
653
654struct UsartClock<'a>(rcc::PeripheralClock<'a>);
655
656impl ClockInterface for UsartClock<'_> {
657 fn is_enabled(&self) -> bool {
658 self.0.is_enabled()
659 }
660
661 fn enable(&self) {
662 self.0.enable();
663 }
664
665 fn disable(&self) {
666 self.0.disable();
667 }
668}