pub unsafe trait Peripherals {
    // Required methods
    fn usb(&self) -> *const ();
    fn usbphy(&self) -> *const ();
}
Expand description

A type that owns all USB register blocks

An implementation of Peripherals is expected to own the USB1 or USB2 registers. This includes

  • USB core registers
  • USB PHY registers

When an instance of Peripherals exists, you must make sure that nothing else, other than the owner of the Peripherals object, accesses those registers.

Safety

Peripherals should only be implemented on a type that owns the various register blocks required for all USB operation. Incorrect usage, or failure to ensure exclusive ownership, could lead to data races and incorrect USB functionality.

All pointers are expected to point at the starting register block for the specified peripheral. Calls to the functions must return the the same value every time they’re called.

Example

A safe implementation of Peripherals that works with the imxrt-ral register access layer.

use imxrt_ral as ral;
use ral::usb;

struct Peripherals {
    usb: ral::usb::Instance,
    phy: ral::usbphy::Instance,
    _nc: ral::usbnc::Instance,
    _analog: ral::usb_analog::Instance,
}

impl Peripherals {
    /// Panics if the instances are already taken
    fn usb1() -> Peripherals {
        Self {
            usb: ral::usb::USB1::take().unwrap(),
            phy: ral::usbphy::USBPHY1::take().unwrap(),
            _nc: ral::usbnc::USBNC1::take().unwrap(),
            _analog: ral::usb_analog::USB_ANALOG::take().unwrap(),
        }
    }
}

// This implementation is safe, because a `Peripherals` object
// owns the four imxrt-ral instances, which are
// guaranteed to be singletons. Given this approach, no one else
// can safely access the USB registers.
unsafe impl imxrt_usbd::Peripherals for Peripherals {
    fn usb(&self) -> *const () {
        let rb: &ral::usb::RegisterBlock = &self.usb;
        (rb as *const ral::usb::RegisterBlock).cast()
    }
    fn usbphy(&self) -> *const () {
        let rb: &ral::usbphy::RegisterBlock = &self.phy;
        (rb as *const ral::usbphy::RegisterBlock).cast()
    }
}

let peripherals = Peripherals::usb1();
let bus = imxrt_usbd::BusAdapter::new(
    peripherals,
    // Rest of setup...
);

Required Methods§

source

fn usb(&self) -> *const ()

Returns the pointer to the USB register block.

source

fn usbphy(&self) -> *const ()

Returns the pointer to the USBPHY register block.

Implementors§

source§

impl<const N: u8> Peripherals for Instances<N>