Module teensy4_bsp::usb[][src]

This is supported on crate feature usb-logging only.
Expand description

Teensy 4 USB, taken from the original Teensy 4 C libraries

The USB stack provides a log implementation for logging over USB. It also provides a simpler Reader and Writer for performing I/O over the CDC interface. Use the macros of the log crate to write data over USB. Or, acquire a raw Reader and Writer to perform your own USB I/O.

You’re responsible for driving the USB driver with repeated calls to poll. See the poll documentation for considerations on where to call poll.

Most initialization functions require the imxrt_ral’s USB1 instance. You can acquire the instance through the HAL, which is exported by the BSP:

use teensy4_bsp as bsp;
use bsp::hal::ral::usb::USB1;

let instance = USB1::take().unwrap();

Logging Example

This example drives the USB logging system through the USB ISR.

use teensy4_bsp as bsp;
use bsp::hal::ral::usb::USB1;
use bsp::interrupt;

use cortex_m::interrupt::Mutex;
use core::cell::RefCell;

static POLLER: Mutex<RefCell<Option<bsp::usb::Poller>>> = Mutex::new(RefCell::new(None));

// Enable this macro for your real system!
// #[cortex_m_rt::interrupt]
fn USB_OTG1() {
    cortex_m::interrupt::free(|cs| {
        POLLER
            .borrow(cs)
            .borrow_mut()
            .as_mut()
            .map(|poller| poller.poll());
    });
}

let (poller, _) = bsp::usb::init(
    USB1::take().unwrap(),
    bsp::usb::LoggingConfig {
        filters: &[("motor", None)],
        ..Default::default()
    },
)
.unwrap();

cortex_m::interrupt::free(|cs| {
    *POLLER.borrow(cs).borrow_mut() = Some(poller);
    // Safety: invoked in a critical section that also prepares the ISR
    // shared memory. ISR memory is ready by the time the ISR runs.
    unsafe { cortex_m::peripheral::NVIC::unmask(bsp::interrupt::USB_OTG1) };
});

// You can now begin logging.
log::info!("Hello world! 3 + 2 = {}", 5);

Reader / Writer Example

This example will manually call poll in an idle loop to drive USB I/O.

use teensy4_bsp as bsp;
use bsp::hal::ral::usb::USB1;
use core::fmt::Write;

let (mut poller, mut reader, mut writer) = bsp::usb::split(USB1::take().unwrap()).unwrap();

write!(writer, "Hello world! 3 + 2 = {}", 5).unwrap();

'idle: loop {
    // Other work...

    let status = poller.poll();
    if status.cdc_rx_complete() {
        // Read the data
        let mut buffer: [u8; 256] = [0; 256];
        reader.read(&mut buffer).unwrap();
    }
}

Structs

Logging configuration

The status of a poll call

An object that can poll the USB device and driver USB device I/O

A type that can read USB serial messages from a host

A type that can send data to a USB serial host

Enums

Indicate an error when preparing or using the USB stack

Functions

Initializes the USB stack. This prepares the logging back-end. Returns a Reader that can read USB serial messages.

Drive the USB device event loop

Splits the USB stack into reading and writing halves, and returns both halves

Type Definitions

Filter log messages by module name (&'static str) to a log level