mirror of
https://github.com/italicsjenga/rp-hal-boards.git
synced 2024-12-24 05:01:31 +11:00
Added pins to the uart constructor functions
This commit is contained in:
parent
bdfb4d82c9
commit
a4a0bcf987
|
@ -16,17 +16,20 @@
|
|||
//! let mut watchdog = Watchdog::new(peripherals.WATCHDOG);
|
||||
//! let mut clocks = init_clocks_and_plls(XOSC_CRYSTAL_FREQ, peripherals.XOSC, peripherals.CLOCKS, peripherals.PLL_SYS, peripherals.PLL_USB, &mut peripherals.RESETS, &mut watchdog).ok().unwrap();
|
||||
//!
|
||||
//! // Set up UART on GP0 and GP1 (Pico pins 1 and 2)
|
||||
//! let pins = (
|
||||
//! pins.gpio0.into_mode::<FunctionUart>(),
|
||||
//! pins.gpio1.into_mode::<FunctionUart>(),
|
||||
//! );
|
||||
//! // Need to perform clock init before using UART or it will freeze.
|
||||
//! let uart = UartPeripheral::<_, _>::enable(
|
||||
//! let uart = UartPeripheral::enable(
|
||||
//! peripherals.UART0,
|
||||
//! pins,
|
||||
//! &mut peripherals.RESETS,
|
||||
//! uart::common_configs::_9600_8_N_1,
|
||||
//! clocks.peripheral_clock.into(),
|
||||
//! ).unwrap();
|
||||
//!
|
||||
//! // Set up UART on GP0 and GP1 (Pico pins 1 and 2)
|
||||
//! let _tx_pin = pins.gpio0.into_mode::<FunctionUart>();
|
||||
//! let _rx_pin = pins.gpio1.into_mode::<FunctionUart>();
|
||||
//! uart.write_full_blocking(b"Hello World!\r\n");
|
||||
//! ```
|
||||
|
||||
|
|
|
@ -53,40 +53,43 @@ impl eh1_0_alpha::serial::Error for ReadErrorType {
|
|||
}
|
||||
|
||||
/// An UART Peripheral based on an underlying UART device.
|
||||
pub struct UartPeripheral<S: State, D: UartDevice> {
|
||||
pub struct UartPeripheral<S: State, D: UartDevice, P: ValidUartPinout<D>> {
|
||||
device: D,
|
||||
_state: S,
|
||||
pins: P,
|
||||
config: UartConfig,
|
||||
effective_baudrate: Baud,
|
||||
}
|
||||
|
||||
impl<S: State, D: UartDevice> UartPeripheral<S, D> {
|
||||
fn transition<To: State>(self, state: To) -> UartPeripheral<To, D> {
|
||||
impl<S: State, D: UartDevice, P: ValidUartPinout<D>> UartPeripheral<S, D, P> {
|
||||
fn transition<To: State>(self, state: To) -> UartPeripheral<To, D, P> {
|
||||
UartPeripheral {
|
||||
device: self.device,
|
||||
pins: self.pins,
|
||||
config: self.config,
|
||||
effective_baudrate: self.effective_baudrate,
|
||||
_state: state,
|
||||
}
|
||||
}
|
||||
|
||||
/// Releases the underlying device.
|
||||
pub fn free(self) -> D {
|
||||
self.device
|
||||
/// Releases the underlying device and pins.
|
||||
pub fn free(self) -> (D, P) {
|
||||
(self.device, self.pins)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: UartDevice> UartPeripheral<Disabled, D> {
|
||||
impl<D: UartDevice, P: ValidUartPinout<D>> UartPeripheral<Disabled, D, P> {
|
||||
/// Creates an UartPeripheral in Disabled state.
|
||||
pub fn new(device: D, resets: &mut pac::RESETS) -> UartPeripheral<Disabled, D> {
|
||||
pub fn new(device: D, pins: P, resets: &mut pac::RESETS) -> UartPeripheral<Disabled, D, P> {
|
||||
device.reset_bring_down(resets);
|
||||
device.reset_bring_up(resets);
|
||||
|
||||
UartPeripheral {
|
||||
device,
|
||||
_state: Disabled,
|
||||
pins,
|
||||
config: common_configs::_9600_8_N_1, // placeholder
|
||||
effective_baudrate: Baud(0),
|
||||
_state: Disabled,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -95,8 +98,8 @@ impl<D: UartDevice> UartPeripheral<Disabled, D> {
|
|||
self,
|
||||
config: UartConfig,
|
||||
frequency: Hertz,
|
||||
) -> Result<UartPeripheral<Enabled, D>, Error> {
|
||||
let mut device = self.free();
|
||||
) -> Result<UartPeripheral<Enabled, D, P>, Error> {
|
||||
let (mut device, pins) = self.free();
|
||||
let effective_baudrate = configure_baudrate(&mut device, &config.baudrate, &frequency)?;
|
||||
|
||||
device.uartlcr_h.write(|w| {
|
||||
|
@ -105,11 +108,14 @@ impl<D: UartDevice> UartPeripheral<Disabled, D> {
|
|||
w
|
||||
});
|
||||
|
||||
// Enable the UART, both TX and RX
|
||||
// Enable the UART, and the TX,RC,CTS and RTS based on the pins
|
||||
device.uartcr.write(|w| {
|
||||
w.uarten().set_bit();
|
||||
w.txe().set_bit();
|
||||
w.rxe().set_bit();
|
||||
w.txe().bit(P::TX_ENABLED);
|
||||
w.rxe().bit(P::RX_ENABLED);
|
||||
w.ctsen().bit(P::CTS_ENABLED);
|
||||
w.rtsen().bit(P::RTS_ENABLED);
|
||||
|
||||
w
|
||||
});
|
||||
|
||||
|
@ -122,20 +128,23 @@ impl<D: UartDevice> UartPeripheral<Disabled, D> {
|
|||
Ok(UartPeripheral {
|
||||
device,
|
||||
config,
|
||||
pins,
|
||||
effective_baudrate,
|
||||
_state: Enabled,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: UartDevice> UartPeripheral<Enabled, D> {
|
||||
impl<D: UartDevice, P: ValidUartPinout<D>> UartPeripheral<Enabled, D, P> {
|
||||
/// Disable this UART Peripheral, falling back to the Disabled state.
|
||||
pub fn disable(self) -> UartPeripheral<Disabled, D> {
|
||||
pub fn disable(self) -> UartPeripheral<Disabled, D, P> {
|
||||
// Disable the UART, both TX and RX
|
||||
self.device.uartcr.write(|w| {
|
||||
w.uarten().clear_bit();
|
||||
w.txe().clear_bit();
|
||||
w.rxe().clear_bit();
|
||||
w.ctsen().clear_bit();
|
||||
w.rtsen().clear_bit();
|
||||
w
|
||||
});
|
||||
|
||||
|
@ -361,7 +370,7 @@ fn set_format<'w>(
|
|||
w
|
||||
}
|
||||
|
||||
impl<D: UartDevice> Read<u8> for UartPeripheral<Enabled, D> {
|
||||
impl<D: UartDevice, P: ValidUartPinout<D>> Read<u8> for UartPeripheral<Enabled, D, P> {
|
||||
type Error = ReadErrorType;
|
||||
|
||||
fn read(&mut self) -> nb::Result<u8, Self::Error> {
|
||||
|
@ -378,7 +387,7 @@ impl<D: UartDevice> Read<u8> for UartPeripheral<Enabled, D> {
|
|||
}
|
||||
|
||||
#[cfg(feature = "eh1_0_alpha")]
|
||||
impl<D: UartDevice> eh1::Read<u8> for UartPeripheral<Enabled, D> {
|
||||
impl<D: UartDevice, P: ValidUartPinout<D>> eh1::Read<u8> for UartPeripheral<Enabled, D, P> {
|
||||
type Error = ReadErrorType;
|
||||
|
||||
fn read(&mut self) -> nb::Result<u8, Self::Error> {
|
||||
|
@ -417,7 +426,7 @@ impl eh1_0_alpha::serial::Error for SerialInfallible {
|
|||
}
|
||||
}
|
||||
|
||||
impl<D: UartDevice> Write<u8> for UartPeripheral<Enabled, D> {
|
||||
impl<D: UartDevice, P: ValidUartPinout<D>> Write<u8> for UartPeripheral<Enabled, D, P> {
|
||||
type Error = Infallible;
|
||||
|
||||
fn write(&mut self, word: u8) -> nb::Result<(), Self::Error> {
|
||||
|
@ -434,7 +443,7 @@ impl<D: UartDevice> Write<u8> for UartPeripheral<Enabled, D> {
|
|||
}
|
||||
|
||||
#[cfg(feature = "eh1_0_alpha")]
|
||||
impl<D: UartDevice> eh1::Write<u8> for UartPeripheral<Enabled, D> {
|
||||
impl<D: UartDevice, P: ValidUartPinout<D>> eh1::Write<u8> for UartPeripheral<Enabled, D, P> {
|
||||
type Error = SerialInfallible;
|
||||
|
||||
fn write(&mut self, word: u8) -> nb::Result<(), Self::Error> {
|
||||
|
@ -453,7 +462,7 @@ impl<D: UartDevice> eh1::Write<u8> for UartPeripheral<Enabled, D> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<D: UartDevice> fmt::Write for UartPeripheral<Enabled, D> {
|
||||
impl<D: UartDevice, P: ValidUartPinout<D>> fmt::Write for UartPeripheral<Enabled, D, P> {
|
||||
fn write_str(&mut self, s: &str) -> fmt::Result {
|
||||
s.bytes()
|
||||
.try_for_each(|c| nb::block!(self.write(c)))
|
||||
|
|
|
@ -2,7 +2,16 @@ use crate::gpio::{bank0, FunctionUart, Pin};
|
|||
use crate::pac::{UART0, UART1};
|
||||
|
||||
/// Declares a valid UART pinout.
|
||||
pub trait ValidUartPinout<UART> {}
|
||||
pub trait ValidUartPinout<UART> {
|
||||
/// Indicates TX should be enabled for this pinout
|
||||
const TX_ENABLED: bool;
|
||||
/// Indicates RX should be enabled for this pinout
|
||||
const RX_ENABLED: bool;
|
||||
/// Indicates CTS should be enabled for this pinout
|
||||
const CTS_ENABLED: bool;
|
||||
/// Indicates RTS should be enabled for this pinout
|
||||
const RTS_ENABLED: bool;
|
||||
}
|
||||
|
||||
impl<UART, TX, RX, CTS, RTS> ValidUartPinout<UART> for Pins<TX, RX, CTS, RTS>
|
||||
where
|
||||
|
@ -11,6 +20,10 @@ where
|
|||
CTS: Cts<UART>,
|
||||
RTS: Rts<UART>,
|
||||
{
|
||||
const TX_ENABLED: bool = TX::ENABLED;
|
||||
const RX_ENABLED: bool = RX::ENABLED;
|
||||
const CTS_ENABLED: bool = CTS::ENABLED;
|
||||
const RTS_ENABLED: bool = RTS::ENABLED;
|
||||
}
|
||||
|
||||
impl<UART, TX, RX> ValidUartPinout<UART> for (TX, RX)
|
||||
|
@ -18,6 +31,10 @@ where
|
|||
TX: Tx<UART>,
|
||||
RX: Rx<UART>,
|
||||
{
|
||||
const TX_ENABLED: bool = TX::ENABLED;
|
||||
const RX_ENABLED: bool = RX::ENABLED;
|
||||
const CTS_ENABLED: bool = false;
|
||||
const RTS_ENABLED: bool = false;
|
||||
}
|
||||
|
||||
impl<UART, TX, RX, CTS, RTS> ValidUartPinout<UART> for (TX, RX, CTS, RTS)
|
||||
|
@ -27,6 +44,10 @@ where
|
|||
CTS: Cts<UART>,
|
||||
RTS: Rts<UART>,
|
||||
{
|
||||
const TX_ENABLED: bool = TX::ENABLED;
|
||||
const RX_ENABLED: bool = RX::ENABLED;
|
||||
const CTS_ENABLED: bool = CTS::ENABLED;
|
||||
const RTS_ENABLED: bool = RTS::ENABLED;
|
||||
}
|
||||
|
||||
/// Customizable Uart pinout, allowing you to set the pins individually.
|
||||
|
@ -41,6 +62,21 @@ where
|
|||
/// Every field can be set to `()` to not configure them.
|
||||
///
|
||||
/// Note that you can also use tuples `(RX, TX)` or `(RX, TX, CTS, RTS)` instead of this type.
|
||||
///
|
||||
/// This struct can either be filled manually or with a builder pattern:
|
||||
///
|
||||
/// ```no_run
|
||||
/// # use rp2040_hal::uart::{Pins, ValidUartPinout};
|
||||
/// # use rp2040_hal::pac::UART0;
|
||||
/// # let gpio_pins: rp2040_hal::gpio::Pins = unsafe { core::mem::zeroed() };
|
||||
/// let pins = Pins::default()
|
||||
/// .tx(gpio_pins.gpio0.into_mode())
|
||||
/// .rx(gpio_pins.gpio1.into_mode());
|
||||
///
|
||||
/// fn assert_is_valid_uart0<T: ValidUartPinout<UART0>>(_: T) {}
|
||||
///
|
||||
/// assert_is_valid_uart0(pins);
|
||||
/// ```
|
||||
#[allow(missing_docs)]
|
||||
pub struct Pins<TX, RX, CTS, RTS> {
|
||||
pub tx: TX,
|
||||
|
@ -49,22 +85,8 @@ pub struct Pins<TX, RX, CTS, RTS> {
|
|||
pub cts: CTS,
|
||||
}
|
||||
|
||||
impl Pins<(), (), (), ()> {
|
||||
/// Create a new pinout. This can be used as a builder pattern
|
||||
///
|
||||
/// ```no_run
|
||||
/// # use rp2040_hal::uart::{Pins, ValidUartPinout};
|
||||
/// # use rp2040_hal::pac::UART0;
|
||||
/// # let gpio_pins: rp2040_hal::gpio::Pins = unsafe { core::mem::zeroed() };
|
||||
/// let pins = Pins::new()
|
||||
/// .tx(gpio_pins.gpio0.into_mode())
|
||||
/// .rx(gpio_pins.gpio1.into_mode());
|
||||
///
|
||||
/// fn assert_is_valid_uart0<T: ValidUartPinout<UART0>>(_: T) {}
|
||||
///
|
||||
/// assert_is_valid_uart0(pins);
|
||||
/// ```
|
||||
pub fn new() -> Self {
|
||||
impl Default for Pins<(), (), (), ()> {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
tx: (),
|
||||
rx: (),
|
||||
|
@ -116,35 +138,35 @@ impl<TX, RX, CTS, RTS> Pins<TX, RX, CTS, RTS> {
|
|||
/// Indicates a valid TX pin for UART0 or UART1
|
||||
pub trait Tx<UART> {
|
||||
#[allow(missing_docs)]
|
||||
const IS_SET: bool;
|
||||
const ENABLED: bool;
|
||||
}
|
||||
/// Indicates a valid RX pin for UART0 or UART1
|
||||
pub trait Rx<UART> {
|
||||
#[allow(missing_docs)]
|
||||
const IS_SET: bool;
|
||||
const ENABLED: bool;
|
||||
}
|
||||
/// Indicates a valid CTS pin for UART0 or UART1
|
||||
pub trait Cts<UART> {
|
||||
#[allow(missing_docs)]
|
||||
const IS_SET: bool;
|
||||
const ENABLED: bool;
|
||||
}
|
||||
/// Indicates a valid RTS pin for UART0 or UART1
|
||||
pub trait Rts<UART> {
|
||||
#[allow(missing_docs)]
|
||||
const IS_SET: bool;
|
||||
const ENABLED: bool;
|
||||
}
|
||||
|
||||
impl<UART> Tx<UART> for () {
|
||||
const IS_SET: bool = false;
|
||||
const ENABLED: bool = false;
|
||||
}
|
||||
impl<UART> Rx<UART> for () {
|
||||
const IS_SET: bool = false;
|
||||
const ENABLED: bool = false;
|
||||
}
|
||||
impl<UART> Cts<UART> for () {
|
||||
const IS_SET: bool = false;
|
||||
const ENABLED: bool = false;
|
||||
}
|
||||
impl<UART> Rts<UART> for () {
|
||||
const IS_SET: bool = false;
|
||||
const ENABLED: bool = false;
|
||||
}
|
||||
|
||||
macro_rules! impl_valid_uart {
|
||||
|
@ -157,22 +179,22 @@ macro_rules! impl_valid_uart {
|
|||
$(
|
||||
$(
|
||||
impl Tx<$uart> for Pin<bank0::$tx, FunctionUart> {
|
||||
const IS_SET: bool = true;
|
||||
const ENABLED: bool = true;
|
||||
}
|
||||
)*
|
||||
$(
|
||||
impl Rx<$uart> for Pin<bank0::$rx, FunctionUart> {
|
||||
const IS_SET: bool = true;
|
||||
const ENABLED: bool = true;
|
||||
}
|
||||
)*
|
||||
$(
|
||||
impl Cts<$uart> for Pin<bank0::$cts, FunctionUart> {
|
||||
const IS_SET: bool = true;
|
||||
const ENABLED: bool = true;
|
||||
}
|
||||
)*
|
||||
$(
|
||||
impl Rts<$uart> for Pin<bank0::$rts, FunctionUart> {
|
||||
const IS_SET: bool = true;
|
||||
const ENABLED: bool = true;
|
||||
}
|
||||
)*
|
||||
)*
|
||||
|
|
Loading…
Reference in a new issue