mirror of
https://github.com/italicsjenga/rp-hal-boards.git
synced 2024-12-24 21:21: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 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();
|
//! 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.
|
//! // Need to perform clock init before using UART or it will freeze.
|
||||||
//! let uart = UartPeripheral::<_, _>::enable(
|
//! let uart = UartPeripheral::enable(
|
||||||
//! peripherals.UART0,
|
//! peripherals.UART0,
|
||||||
|
//! pins,
|
||||||
//! &mut peripherals.RESETS,
|
//! &mut peripherals.RESETS,
|
||||||
//! uart::common_configs::_9600_8_N_1,
|
//! uart::common_configs::_9600_8_N_1,
|
||||||
//! clocks.peripheral_clock.into(),
|
//! clocks.peripheral_clock.into(),
|
||||||
//! ).unwrap();
|
//! ).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");
|
//! 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.
|
/// 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,
|
device: D,
|
||||||
_state: S,
|
_state: S,
|
||||||
|
pins: P,
|
||||||
config: UartConfig,
|
config: UartConfig,
|
||||||
effective_baudrate: Baud,
|
effective_baudrate: Baud,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: State, D: UartDevice> UartPeripheral<S, D> {
|
impl<S: State, D: UartDevice, P: ValidUartPinout<D>> UartPeripheral<S, D, P> {
|
||||||
fn transition<To: State>(self, state: To) -> UartPeripheral<To, D> {
|
fn transition<To: State>(self, state: To) -> UartPeripheral<To, D, P> {
|
||||||
UartPeripheral {
|
UartPeripheral {
|
||||||
device: self.device,
|
device: self.device,
|
||||||
|
pins: self.pins,
|
||||||
config: self.config,
|
config: self.config,
|
||||||
effective_baudrate: self.effective_baudrate,
|
effective_baudrate: self.effective_baudrate,
|
||||||
_state: state,
|
_state: state,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Releases the underlying device.
|
/// Releases the underlying device and pins.
|
||||||
pub fn free(self) -> D {
|
pub fn free(self) -> (D, P) {
|
||||||
self.device
|
(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.
|
/// 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_down(resets);
|
||||||
device.reset_bring_up(resets);
|
device.reset_bring_up(resets);
|
||||||
|
|
||||||
UartPeripheral {
|
UartPeripheral {
|
||||||
device,
|
device,
|
||||||
|
_state: Disabled,
|
||||||
|
pins,
|
||||||
config: common_configs::_9600_8_N_1, // placeholder
|
config: common_configs::_9600_8_N_1, // placeholder
|
||||||
effective_baudrate: Baud(0),
|
effective_baudrate: Baud(0),
|
||||||
_state: Disabled,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,8 +98,8 @@ impl<D: UartDevice> UartPeripheral<Disabled, D> {
|
||||||
self,
|
self,
|
||||||
config: UartConfig,
|
config: UartConfig,
|
||||||
frequency: Hertz,
|
frequency: Hertz,
|
||||||
) -> Result<UartPeripheral<Enabled, D>, Error> {
|
) -> Result<UartPeripheral<Enabled, D, P>, Error> {
|
||||||
let mut device = self.free();
|
let (mut device, pins) = self.free();
|
||||||
let effective_baudrate = configure_baudrate(&mut device, &config.baudrate, &frequency)?;
|
let effective_baudrate = configure_baudrate(&mut device, &config.baudrate, &frequency)?;
|
||||||
|
|
||||||
device.uartlcr_h.write(|w| {
|
device.uartlcr_h.write(|w| {
|
||||||
|
@ -105,11 +108,14 @@ impl<D: UartDevice> UartPeripheral<Disabled, D> {
|
||||||
w
|
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| {
|
device.uartcr.write(|w| {
|
||||||
w.uarten().set_bit();
|
w.uarten().set_bit();
|
||||||
w.txe().set_bit();
|
w.txe().bit(P::TX_ENABLED);
|
||||||
w.rxe().set_bit();
|
w.rxe().bit(P::RX_ENABLED);
|
||||||
|
w.ctsen().bit(P::CTS_ENABLED);
|
||||||
|
w.rtsen().bit(P::RTS_ENABLED);
|
||||||
|
|
||||||
w
|
w
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -122,20 +128,23 @@ impl<D: UartDevice> UartPeripheral<Disabled, D> {
|
||||||
Ok(UartPeripheral {
|
Ok(UartPeripheral {
|
||||||
device,
|
device,
|
||||||
config,
|
config,
|
||||||
|
pins,
|
||||||
effective_baudrate,
|
effective_baudrate,
|
||||||
_state: Enabled,
|
_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.
|
/// 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
|
// Disable the UART, both TX and RX
|
||||||
self.device.uartcr.write(|w| {
|
self.device.uartcr.write(|w| {
|
||||||
w.uarten().clear_bit();
|
w.uarten().clear_bit();
|
||||||
w.txe().clear_bit();
|
w.txe().clear_bit();
|
||||||
w.rxe().clear_bit();
|
w.rxe().clear_bit();
|
||||||
|
w.ctsen().clear_bit();
|
||||||
|
w.rtsen().clear_bit();
|
||||||
w
|
w
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -361,7 +370,7 @@ fn set_format<'w>(
|
||||||
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;
|
type Error = ReadErrorType;
|
||||||
|
|
||||||
fn read(&mut self) -> nb::Result<u8, Self::Error> {
|
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")]
|
#[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;
|
type Error = ReadErrorType;
|
||||||
|
|
||||||
fn read(&mut self) -> nb::Result<u8, Self::Error> {
|
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;
|
type Error = Infallible;
|
||||||
|
|
||||||
fn write(&mut self, word: u8) -> nb::Result<(), Self::Error> {
|
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")]
|
#[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;
|
type Error = SerialInfallible;
|
||||||
|
|
||||||
fn write(&mut self, word: u8) -> nb::Result<(), Self::Error> {
|
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 {
|
fn write_str(&mut self, s: &str) -> fmt::Result {
|
||||||
s.bytes()
|
s.bytes()
|
||||||
.try_for_each(|c| nb::block!(self.write(c)))
|
.try_for_each(|c| nb::block!(self.write(c)))
|
||||||
|
|
|
@ -2,7 +2,16 @@ use crate::gpio::{bank0, FunctionUart, Pin};
|
||||||
use crate::pac::{UART0, UART1};
|
use crate::pac::{UART0, UART1};
|
||||||
|
|
||||||
/// Declares a valid UART pinout.
|
/// 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>
|
impl<UART, TX, RX, CTS, RTS> ValidUartPinout<UART> for Pins<TX, RX, CTS, RTS>
|
||||||
where
|
where
|
||||||
|
@ -11,6 +20,10 @@ where
|
||||||
CTS: Cts<UART>,
|
CTS: Cts<UART>,
|
||||||
RTS: Rts<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)
|
impl<UART, TX, RX> ValidUartPinout<UART> for (TX, RX)
|
||||||
|
@ -18,6 +31,10 @@ where
|
||||||
TX: Tx<UART>,
|
TX: Tx<UART>,
|
||||||
RX: Rx<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)
|
impl<UART, TX, RX, CTS, RTS> ValidUartPinout<UART> for (TX, RX, CTS, RTS)
|
||||||
|
@ -27,6 +44,10 @@ where
|
||||||
CTS: Cts<UART>,
|
CTS: Cts<UART>,
|
||||||
RTS: Rts<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.
|
/// 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.
|
/// 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.
|
/// 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)]
|
#[allow(missing_docs)]
|
||||||
pub struct Pins<TX, RX, CTS, RTS> {
|
pub struct Pins<TX, RX, CTS, RTS> {
|
||||||
pub tx: TX,
|
pub tx: TX,
|
||||||
|
@ -49,22 +85,8 @@ pub struct Pins<TX, RX, CTS, RTS> {
|
||||||
pub cts: CTS,
|
pub cts: CTS,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Pins<(), (), (), ()> {
|
impl Default for Pins<(), (), (), ()> {
|
||||||
/// Create a new pinout. This can be used as a builder pattern
|
fn default() -> Self {
|
||||||
///
|
|
||||||
/// ```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 {
|
|
||||||
Self {
|
Self {
|
||||||
tx: (),
|
tx: (),
|
||||||
rx: (),
|
rx: (),
|
||||||
|
@ -116,35 +138,35 @@ impl<TX, RX, CTS, RTS> Pins<TX, RX, CTS, RTS> {
|
||||||
/// Indicates a valid TX pin for UART0 or UART1
|
/// Indicates a valid TX pin for UART0 or UART1
|
||||||
pub trait Tx<UART> {
|
pub trait Tx<UART> {
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
const IS_SET: bool;
|
const ENABLED: bool;
|
||||||
}
|
}
|
||||||
/// Indicates a valid RX pin for UART0 or UART1
|
/// Indicates a valid RX pin for UART0 or UART1
|
||||||
pub trait Rx<UART> {
|
pub trait Rx<UART> {
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
const IS_SET: bool;
|
const ENABLED: bool;
|
||||||
}
|
}
|
||||||
/// Indicates a valid CTS pin for UART0 or UART1
|
/// Indicates a valid CTS pin for UART0 or UART1
|
||||||
pub trait Cts<UART> {
|
pub trait Cts<UART> {
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
const IS_SET: bool;
|
const ENABLED: bool;
|
||||||
}
|
}
|
||||||
/// Indicates a valid RTS pin for UART0 or UART1
|
/// Indicates a valid RTS pin for UART0 or UART1
|
||||||
pub trait Rts<UART> {
|
pub trait Rts<UART> {
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
const IS_SET: bool;
|
const ENABLED: bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<UART> Tx<UART> for () {
|
impl<UART> Tx<UART> for () {
|
||||||
const IS_SET: bool = false;
|
const ENABLED: bool = false;
|
||||||
}
|
}
|
||||||
impl<UART> Rx<UART> for () {
|
impl<UART> Rx<UART> for () {
|
||||||
const IS_SET: bool = false;
|
const ENABLED: bool = false;
|
||||||
}
|
}
|
||||||
impl<UART> Cts<UART> for () {
|
impl<UART> Cts<UART> for () {
|
||||||
const IS_SET: bool = false;
|
const ENABLED: bool = false;
|
||||||
}
|
}
|
||||||
impl<UART> Rts<UART> for () {
|
impl<UART> Rts<UART> for () {
|
||||||
const IS_SET: bool = false;
|
const ENABLED: bool = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! impl_valid_uart {
|
macro_rules! impl_valid_uart {
|
||||||
|
@ -157,22 +179,22 @@ macro_rules! impl_valid_uart {
|
||||||
$(
|
$(
|
||||||
$(
|
$(
|
||||||
impl Tx<$uart> for Pin<bank0::$tx, FunctionUart> {
|
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> {
|
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> {
|
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> {
|
impl Rts<$uart> for Pin<bank0::$rts, FunctionUart> {
|
||||||
const IS_SET: bool = true;
|
const ENABLED: bool = true;
|
||||||
}
|
}
|
||||||
)*
|
)*
|
||||||
)*
|
)*
|
||||||
|
|
Loading…
Reference in a new issue