Skip to content
This repository was archived by the owner on Aug 9, 2022. It is now read-only.

Commit 0ec9e00

Browse files
committed
Added pin initialization & refactor rx/tx
1 parent 727fc78 commit 0ec9e00

File tree

1 file changed

+80
-77
lines changed

1 file changed

+80
-77
lines changed

src/serial.rs

Lines changed: 80 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use core::convert::Infallible;
1414
use core::marker::PhantomData;
1515
use core::ops::Deref;
1616

17+
use crate::gpio::{InputSignal, OutputSignal};
1718
use crate::target;
1819
use crate::target::{uart, UART0, UART1, UART2};
1920

@@ -163,24 +164,26 @@ pub struct Serial<
163164
uart: UART,
164165
pins: Pins<TX, RX, CTS, RTS>,
165166
clock_control: crate::clock_control::ClockControlConfig,
166-
apb_lock: Option<crate::clock_control::dfs::LockAPB>,
167+
rx: Rx<UART>,
168+
tx: Tx<UART>,
167169
}
168170

169171
/// Serial receiver
170172
pub struct Rx<UART: Instance> {
171173
_uart: PhantomData<UART>,
172-
_apb_lock: Option<crate::clock_control::dfs::LockAPB>,
174+
apb_lock: Option<crate::clock_control::dfs::LockAPB>,
173175
}
174176

175177
/// Serial transmitter
176178
pub struct Tx<UART: Instance> {
177179
_uart: PhantomData<UART>,
178-
_apb_lock: Option<crate::clock_control::dfs::LockAPB>,
180+
apb_lock: Option<crate::clock_control::dfs::LockAPB>,
179181
}
180182

181183
impl<UART: Instance, TX: OutputPin, RX: InputPin, CTS: InputPin, RTS: OutputPin>
182184
Serial<UART, TX, RX, CTS, RTS>
183185
{
186+
/// Create a new serial driver
184187
pub fn new(
185188
uart: UART,
186189
pins: Pins<TX, RX, CTS, RTS>,
@@ -192,8 +195,17 @@ impl<UART: Instance, TX: OutputPin, RX: InputPin, CTS: InputPin, RTS: OutputPin>
192195
uart,
193196
pins,
194197
clock_control,
195-
apb_lock: None,
198+
rx: Rx {
199+
_uart: PhantomData,
200+
apb_lock: None,
201+
},
202+
tx: Tx {
203+
_uart: PhantomData,
204+
apb_lock: None,
205+
},
196206
};
207+
208+
serial.uart.init_pins(&mut serial.pins);
197209
serial.uart.reset(dport).enable(dport);
198210
serial
199211
.change_stop_bits(config.stop_bits)
@@ -203,6 +215,7 @@ impl<UART: Instance, TX: OutputPin, RX: InputPin, CTS: InputPin, RTS: OutputPin>
203215
Ok(serial)
204216
}
205217

218+
/// Change the number of stop bits
206219
pub fn change_stop_bits(&mut self, stop_bits: config::StopBits) -> &mut Self {
207220
//workaround for hardware issue, when UART stop bit set as 2-bit mode.
208221
self.uart
@@ -219,6 +232,7 @@ impl<UART: Instance, TX: OutputPin, RX: InputPin, CTS: InputPin, RTS: OutputPin>
219232
self
220233
}
221234

235+
/// Change the number of data bits
222236
pub fn change_data_bits(&mut self, data_bits: config::DataBits) -> &mut Self {
223237
self.uart.conf0.modify(|_, w| match data_bits {
224238
config::DataBits::DataBits5 => w.bit_num().data_bits_5(),
@@ -230,6 +244,7 @@ impl<UART: Instance, TX: OutputPin, RX: InputPin, CTS: InputPin, RTS: OutputPin>
230244
self
231245
}
232246

247+
/// Change the type of parity checking
233248
pub fn change_parity(&mut self, parity: config::Parity) -> &mut Self {
234249
self.uart.conf0.modify(|_, w| match parity {
235250
config::Parity::ParityNone => w.parity_en().clear_bit(),
@@ -242,10 +257,10 @@ impl<UART: Instance, TX: OutputPin, RX: InputPin, CTS: InputPin, RTS: OutputPin>
242257

243258
/// Change the baudrate.
244259
///
245-
/// Will automatically select the clock source. WHen possible the reference clock (1MHz) will be used,
246-
/// because this is constant when the clock source/frequency changes.
247-
/// However if one of the clock frequencies is below 10MHz
248-
/// or if the baudrate is above the reference clock or if the baudrate cannot be set within 1.5%
260+
/// Will automatically select the clock source. When possible the reference clock (1MHz) will
261+
/// be used, because this is constant when the clock source/frequency changes.
262+
/// However if one of the clock frequencies is below 10MHz or if the baudrate is above
263+
/// the reference clock or if the baudrate cannot be set within 1.5%
249264
/// then use the APB clock.
250265
pub fn change_baudrate<T: Into<Hertz> + Copy>(
251266
&mut self,
@@ -287,13 +302,15 @@ impl<UART: Instance, TX: OutputPin, RX: InputPin, CTS: InputPin, RTS: OutputPin>
287302
baudrate: T,
288303
use_apb_frequency: bool,
289304
) -> Result<&mut Self, Error> {
290-
if let None = self.apb_lock {
305+
if let None = self.rx.apb_lock {
291306
if use_apb_frequency {
292-
self.apb_lock = Some(self.clock_control.lock_apb_frequency());
307+
self.rx.apb_lock = Some(self.clock_control.lock_apb_frequency());
308+
self.tx.apb_lock = Some(self.clock_control.lock_apb_frequency());
293309
}
294310
} else {
295311
if !use_apb_frequency {
296-
self.apb_lock = None;
312+
self.rx.apb_lock = None;
313+
self.tx.apb_lock = None;
297314
}
298315
}
299316

@@ -330,10 +347,12 @@ impl<UART: Instance, TX: OutputPin, RX: InputPin, CTS: InputPin, RTS: OutputPin>
330347
Ok(self)
331348
}
332349

350+
/// Returns if the reference or APB clock is used
333351
pub fn is_clock_apb(&self) -> bool {
334352
self.uart.conf0.read().tick_ref_always_on().bit_is_set()
335353
}
336354

355+
/// Returns the current baudrate
337356
pub fn baudrate(&self) -> Hertz {
338357
let use_apb_frequency = self.uart.conf0.read().tick_ref_always_on().bit_is_set();
339358
let sclk_freq = if use_apb_frequency {
@@ -368,71 +387,15 @@ impl<UART: Instance, TX: OutputPin, RX: InputPin, CTS: InputPin, RTS: OutputPin>
368387
self.uart.status.read().st_utx_out().is_tx_idle()
369388
}
370389

390+
/// Split the serial driver in separate TX and RX drivers
371391
pub fn split(self) -> (Tx<UART>, Rx<UART>) {
372-
(
373-
Tx {
374-
_uart: PhantomData,
375-
_apb_lock: if let None = self.apb_lock {
376-
None
377-
} else {
378-
Some(self.clock_control.lock_apb_frequency())
379-
},
380-
},
381-
Rx {
382-
_uart: PhantomData,
383-
_apb_lock: if let None = self.apb_lock {
384-
None
385-
} else {
386-
Some(self.clock_control.lock_apb_frequency())
387-
},
388-
},
389-
)
392+
(self.tx, self.rx)
390393
}
391394

395+
/// Release the UART and GPIO resources
392396
pub fn release(self) -> (UART, Pins<TX, RX, CTS, RTS>) {
393397
(self.uart, self.pins)
394398
}
395-
396-
fn rx_count(&self) -> u8 {
397-
unsafe { self.uart.status.read().rxfifo_cnt().bits() }
398-
}
399-
400-
fn rx_is_idle(&self) -> bool {
401-
unsafe { self.uart.status.read().st_urx_out().is_rx_idle() }
402-
}
403-
404-
fn read(&mut self) -> nb::Result<u8, Infallible> {
405-
if self.rx_count() == 0 {
406-
Err(nb::Error::WouldBlock)
407-
} else {
408-
Ok(unsafe { self.uart.rx_fifo.read().bits() })
409-
}
410-
}
411-
412-
fn tx_count(&self) -> u8 {
413-
unsafe { self.uart.status.read().txfifo_cnt().bits() }
414-
}
415-
416-
fn tx_is_idle(&self) -> bool {
417-
unsafe { self.uart.status.read().st_utx_out().is_tx_idle() }
418-
}
419-
420-
fn flush(&mut self) -> nb::Result<(), Infallible> {
421-
if self.tx_is_idle() {
422-
Ok(())
423-
} else {
424-
Err(nb::Error::WouldBlock)
425-
}
426-
}
427-
428-
fn write(&mut self, byte: u8) -> nb::Result<(), Infallible> {
429-
if self.tx_count() < UART_FIFO_SIZE {
430-
unsafe { self.uart.tx_fifo.write_with_zero(|w| w.bits(byte)) }
431-
Ok(())
432-
} else {
433-
Err(nb::Error::WouldBlock)
434-
}
435-
}
436399
}
437400

438401
impl<UART: Instance, TX: OutputPin, RX: InputPin, CTS: InputPin, RTS: OutputPin> serial::Read<u8>
@@ -441,7 +404,7 @@ impl<UART: Instance, TX: OutputPin, RX: InputPin, CTS: InputPin, RTS: OutputPin>
441404
type Error = Infallible;
442405

443406
fn read(&mut self) -> nb::Result<u8, Self::Error> {
444-
self.read()
407+
self.rx.read()
445408
}
446409
}
447410

@@ -451,11 +414,11 @@ impl<UART: Instance, TX: OutputPin, RX: InputPin, CTS: InputPin, RTS: OutputPin>
451414
type Error = Infallible;
452415

453416
fn flush(&mut self) -> nb::Result<(), Self::Error> {
454-
self.flush()
417+
self.tx.flush()
455418
}
456419

457420
fn write(&mut self, byte: u8) -> nb::Result<(), Self::Error> {
458-
self.write(byte)
421+
self.tx.write(byte)
459422
}
460423
}
461424

@@ -472,10 +435,12 @@ impl<UART: Instance, TX: OutputPin, RX: InputPin, CTS: InputPin, RTS: OutputPin>
472435
}
473436

474437
impl<UART: Instance> Rx<UART> {
438+
/// Get count of bytes in the receive FIFO
475439
pub fn count(&self) -> u8 {
476440
unsafe { (*UART::ptr()).status.read().rxfifo_cnt().bits() }
477441
}
478442

443+
/// Check if the receivers is idle
479444
pub fn is_idle(&self) -> bool {
480445
unsafe { (*UART::ptr()).status.read().st_urx_out().is_rx_idle() }
481446
}
@@ -494,10 +459,12 @@ impl<UART: Instance> serial::Read<u8> for Rx<UART> {
494459
}
495460

496461
impl<UART: Instance> Tx<UART> {
462+
/// Get count of bytes in the transmitter FIFO
497463
pub fn count(&self) -> u8 {
498464
unsafe { (*UART::ptr()).status.read().txfifo_cnt().bits() }
499465
}
500466

467+
/// Check if the transmitter is idle
501468
pub fn is_idle(&self) -> bool {
502469
unsafe { (*UART::ptr()).status.read().st_utx_out().is_tx_idle() }
503470
}
@@ -539,16 +506,25 @@ where
539506

540507
pub trait Instance: Deref<Target = uart::RegisterBlock> {
541508
fn ptr() -> *const uart::RegisterBlock;
509+
/// Enable peripheral
542510
fn enable(&mut self, dport: &mut target::DPORT) -> &mut Self;
511+
/// Disable peripheral
543512
fn disable(&mut self, dport: &mut target::DPORT) -> &mut Self;
513+
/// Reset peripheral
544514
fn reset(&mut self, dport: &mut target::DPORT) -> &mut Self;
515+
516+
/// Initialize pins
517+
fn init_pins<TX: OutputPin, RX: InputPin, CTS: InputPin, RTS: OutputPin>(
518+
&mut self,
519+
pins: &mut Pins<TX, RX, CTS, RTS>,
520+
) -> &mut Self;
545521
}
546522

547523
static UART_MEM_LOCK: CriticalSectionSpinLockMutex<()> = CriticalSectionSpinLockMutex::new(());
548524

549525
macro_rules! halUart {
550526
($(
551-
$UARTX:ident: ($uartX:ident),
527+
$UARTX:ident: ($uartX:ident, $txd:ident, $rxd:ident, $cts:ident, $rts:ident),
552528
)+) => {
553529
$(
554530
impl Instance for $UARTX {
@@ -584,13 +560,40 @@ macro_rules! halUart {
584560
self
585561

586562
}
563+
564+
fn init_pins<TX: OutputPin, RX: InputPin, CTS: InputPin, RTS: OutputPin>(
565+
&mut self, pins: &mut Pins<TX,RX,CTS,RTS>
566+
) -> &mut Self {
567+
pins
568+
.tx
569+
.set_to_push_pull_output()
570+
.connect_peripheral_to_output(OutputSignal::$txd);
571+
572+
pins
573+
.rx
574+
.set_to_input()
575+
.connect_input_to_peripheral(InputSignal::$rxd);
576+
577+
if let Some(cts) = pins.cts.as_mut() {
578+
cts
579+
.set_to_input()
580+
.connect_input_to_peripheral(InputSignal::$cts);
581+
}
582+
583+
if let Some(rts) = pins.rts.as_mut() {
584+
rts
585+
.set_to_push_pull_output()
586+
.connect_peripheral_to_output(OutputSignal::$rts);
587+
}
588+
self
589+
}
587590
}
588591
)+
589592
}
590593
}
591594

592595
halUart! {
593-
UART0: (uart0),
594-
UART1: (uart1),
595-
UART2: (uart2),
596+
UART0: (uart0, U0TXD, U0RXD, U0CTS, U0RTS),
597+
UART1: (uart1, U1TXD, U1RXD, U1CTS, U1RTS),
598+
UART2: (uart2, U2TXD, U2RXD, U2CTS, U2RTS),
596599
}

0 commit comments

Comments
 (0)