nrf/uarte: prevent accidentally driving tx pin on rxonly uart if it was left in PSEL.
This commit is contained in:
parent
036f703a4a
commit
6a977d2ae9
1 changed files with 26 additions and 34 deletions
|
@ -159,7 +159,7 @@ impl<'d, T: Instance> Uarte<'d, T> {
|
||||||
txd: impl Peripheral<P = impl GpioPin> + 'd,
|
txd: impl Peripheral<P = impl GpioPin> + 'd,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
into_ref!(rxd, txd);
|
into_ref!(uarte, rxd, txd);
|
||||||
Self::new_inner(uarte, rxd.map_into(), txd.map_into(), None, None, config)
|
Self::new_inner(uarte, rxd.map_into(), txd.map_into(), None, None, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,7 +173,7 @@ impl<'d, T: Instance> Uarte<'d, T> {
|
||||||
rts: impl Peripheral<P = impl GpioPin> + 'd,
|
rts: impl Peripheral<P = impl GpioPin> + 'd,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
into_ref!(rxd, txd, cts, rts);
|
into_ref!(uarte, rxd, txd, cts, rts);
|
||||||
Self::new_inner(
|
Self::new_inner(
|
||||||
uarte,
|
uarte,
|
||||||
rxd.map_into(),
|
rxd.map_into(),
|
||||||
|
@ -185,17 +185,22 @@ impl<'d, T: Instance> Uarte<'d, T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_inner(
|
fn new_inner(
|
||||||
uarte: impl Peripheral<P = T> + 'd,
|
uarte: PeripheralRef<'d, T>,
|
||||||
rxd: PeripheralRef<'d, AnyPin>,
|
rxd: PeripheralRef<'d, AnyPin>,
|
||||||
txd: PeripheralRef<'d, AnyPin>,
|
txd: PeripheralRef<'d, AnyPin>,
|
||||||
cts: Option<PeripheralRef<'d, AnyPin>>,
|
cts: Option<PeripheralRef<'d, AnyPin>>,
|
||||||
rts: Option<PeripheralRef<'d, AnyPin>>,
|
rts: Option<PeripheralRef<'d, AnyPin>>,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
into_ref!(uarte);
|
|
||||||
|
|
||||||
let r = T::regs();
|
let r = T::regs();
|
||||||
|
|
||||||
|
let hardware_flow_control = match (rts.is_some(), cts.is_some()) {
|
||||||
|
(false, false) => false,
|
||||||
|
(true, true) => true,
|
||||||
|
_ => panic!("RTS and CTS pins must be either both set or none set."),
|
||||||
|
};
|
||||||
|
configure(r, config, hardware_flow_control);
|
||||||
|
|
||||||
rxd.conf().write(|w| w.input().connect().drive().h0h1());
|
rxd.conf().write(|w| w.input().connect().drive().h0h1());
|
||||||
r.psel.rxd.write(|w| unsafe { w.bits(rxd.psel_bits()) });
|
r.psel.rxd.write(|w| unsafe { w.bits(rxd.psel_bits()) });
|
||||||
|
|
||||||
|
@ -217,13 +222,6 @@ impl<'d, T: Instance> Uarte<'d, T> {
|
||||||
T::Interrupt::unpend();
|
T::Interrupt::unpend();
|
||||||
unsafe { T::Interrupt::enable() };
|
unsafe { T::Interrupt::enable() };
|
||||||
|
|
||||||
let hardware_flow_control = match (rts.is_some(), cts.is_some()) {
|
|
||||||
(false, false) => false,
|
|
||||||
(true, true) => true,
|
|
||||||
_ => panic!("RTS and CTS pins must be either both set or none set."),
|
|
||||||
};
|
|
||||||
configure(r, config, hardware_flow_control);
|
|
||||||
|
|
||||||
let s = T::state();
|
let s = T::state();
|
||||||
s.tx_rx_refcount.store(2, Ordering::Relaxed);
|
s.tx_rx_refcount.store(2, Ordering::Relaxed);
|
||||||
|
|
||||||
|
@ -315,6 +313,12 @@ pub(crate) fn configure(r: &RegisterBlock, config: Config, hardware_flow_control
|
||||||
r.events_rxstarted.reset();
|
r.events_rxstarted.reset();
|
||||||
r.events_txstarted.reset();
|
r.events_txstarted.reset();
|
||||||
|
|
||||||
|
// reset all pins
|
||||||
|
r.psel.txd.write(|w| w.connect().disconnected());
|
||||||
|
r.psel.rxd.write(|w| w.connect().disconnected());
|
||||||
|
r.psel.cts.write(|w| w.connect().disconnected());
|
||||||
|
r.psel.rts.write(|w| w.connect().disconnected());
|
||||||
|
|
||||||
// Enable
|
// Enable
|
||||||
apply_workaround_for_enable_anomaly(r);
|
apply_workaround_for_enable_anomaly(r);
|
||||||
r.enable.write(|w| w.enable().enabled());
|
r.enable.write(|w| w.enable().enabled());
|
||||||
|
@ -328,7 +332,7 @@ impl<'d, T: Instance> UarteTx<'d, T> {
|
||||||
txd: impl Peripheral<P = impl GpioPin> + 'd,
|
txd: impl Peripheral<P = impl GpioPin> + 'd,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
into_ref!(txd);
|
into_ref!(uarte, txd);
|
||||||
Self::new_inner(uarte, txd.map_into(), None, config)
|
Self::new_inner(uarte, txd.map_into(), None, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -340,20 +344,20 @@ impl<'d, T: Instance> UarteTx<'d, T> {
|
||||||
cts: impl Peripheral<P = impl GpioPin> + 'd,
|
cts: impl Peripheral<P = impl GpioPin> + 'd,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
into_ref!(txd, cts);
|
into_ref!(uarte, txd, cts);
|
||||||
Self::new_inner(uarte, txd.map_into(), Some(cts.map_into()), config)
|
Self::new_inner(uarte, txd.map_into(), Some(cts.map_into()), config)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_inner(
|
fn new_inner(
|
||||||
uarte: impl Peripheral<P = T> + 'd,
|
uarte: PeripheralRef<'d, T>,
|
||||||
txd: PeripheralRef<'d, AnyPin>,
|
txd: PeripheralRef<'d, AnyPin>,
|
||||||
cts: Option<PeripheralRef<'d, AnyPin>>,
|
cts: Option<PeripheralRef<'d, AnyPin>>,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
into_ref!(uarte);
|
|
||||||
|
|
||||||
let r = T::regs();
|
let r = T::regs();
|
||||||
|
|
||||||
|
configure(r, config, cts.is_some());
|
||||||
|
|
||||||
txd.set_high();
|
txd.set_high();
|
||||||
txd.conf().write(|w| w.dir().output().drive().s0s1());
|
txd.conf().write(|w| w.dir().output().drive().s0s1());
|
||||||
r.psel.txd.write(|w| unsafe { w.bits(txd.psel_bits()) });
|
r.psel.txd.write(|w| unsafe { w.bits(txd.psel_bits()) });
|
||||||
|
@ -363,12 +367,6 @@ impl<'d, T: Instance> UarteTx<'d, T> {
|
||||||
}
|
}
|
||||||
r.psel.cts.write(|w| unsafe { w.bits(cts.psel_bits()) });
|
r.psel.cts.write(|w| unsafe { w.bits(cts.psel_bits()) });
|
||||||
|
|
||||||
r.psel.rxd.write(|w| w.connect().disconnected());
|
|
||||||
r.psel.rts.write(|w| w.connect().disconnected());
|
|
||||||
|
|
||||||
let hardware_flow_control = cts.is_some();
|
|
||||||
configure(r, config, hardware_flow_control);
|
|
||||||
|
|
||||||
T::Interrupt::unpend();
|
T::Interrupt::unpend();
|
||||||
unsafe { T::Interrupt::enable() };
|
unsafe { T::Interrupt::enable() };
|
||||||
|
|
||||||
|
@ -524,7 +522,7 @@ impl<'d, T: Instance> UarteRx<'d, T> {
|
||||||
rxd: impl Peripheral<P = impl GpioPin> + 'd,
|
rxd: impl Peripheral<P = impl GpioPin> + 'd,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
into_ref!(rxd);
|
into_ref!(uarte, rxd);
|
||||||
Self::new_inner(uarte, rxd.map_into(), None, config)
|
Self::new_inner(uarte, rxd.map_into(), None, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -536,7 +534,7 @@ impl<'d, T: Instance> UarteRx<'d, T> {
|
||||||
rts: impl Peripheral<P = impl GpioPin> + 'd,
|
rts: impl Peripheral<P = impl GpioPin> + 'd,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
into_ref!(rxd, rts);
|
into_ref!(uarte, rxd, rts);
|
||||||
Self::new_inner(uarte, rxd.map_into(), Some(rts.map_into()), config)
|
Self::new_inner(uarte, rxd.map_into(), Some(rts.map_into()), config)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -549,15 +547,15 @@ impl<'d, T: Instance> UarteRx<'d, T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_inner(
|
fn new_inner(
|
||||||
uarte: impl Peripheral<P = T> + 'd,
|
uarte: PeripheralRef<'d, T>,
|
||||||
rxd: PeripheralRef<'d, AnyPin>,
|
rxd: PeripheralRef<'d, AnyPin>,
|
||||||
rts: Option<PeripheralRef<'d, AnyPin>>,
|
rts: Option<PeripheralRef<'d, AnyPin>>,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
into_ref!(uarte);
|
|
||||||
|
|
||||||
let r = T::regs();
|
let r = T::regs();
|
||||||
|
|
||||||
|
configure(r, config, rts.is_some());
|
||||||
|
|
||||||
rxd.conf().write(|w| w.input().connect().drive().h0h1());
|
rxd.conf().write(|w| w.input().connect().drive().h0h1());
|
||||||
r.psel.rxd.write(|w| unsafe { w.bits(rxd.psel_bits()) });
|
r.psel.rxd.write(|w| unsafe { w.bits(rxd.psel_bits()) });
|
||||||
|
|
||||||
|
@ -567,15 +565,9 @@ impl<'d, T: Instance> UarteRx<'d, T> {
|
||||||
}
|
}
|
||||||
r.psel.rts.write(|w| unsafe { w.bits(rts.psel_bits()) });
|
r.psel.rts.write(|w| unsafe { w.bits(rts.psel_bits()) });
|
||||||
|
|
||||||
r.psel.txd.write(|w| w.connect().disconnected());
|
|
||||||
r.psel.cts.write(|w| w.connect().disconnected());
|
|
||||||
|
|
||||||
T::Interrupt::unpend();
|
T::Interrupt::unpend();
|
||||||
unsafe { T::Interrupt::enable() };
|
unsafe { T::Interrupt::enable() };
|
||||||
|
|
||||||
let hardware_flow_control = rts.is_some();
|
|
||||||
configure(r, config, hardware_flow_control);
|
|
||||||
|
|
||||||
let s = T::state();
|
let s = T::state();
|
||||||
s.tx_rx_refcount.store(1, Ordering::Relaxed);
|
s.tx_rx_refcount.store(1, Ordering::Relaxed);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue