#![no_main]
use panic_halt as _;
+use feather_m0 as hal;
+use hal::entry;
-use bsp::hal;
-use bsp::pac;
-use feather_m0 as bsp;
-
-use bsp::entry;
use hal::clock::GenericClockController;
-use hal::delay::Delay;
-use hal::prelude::*;
-use pac::{CorePeripherals, Peripherals};
+use hal::pac::{interrupt, CorePeripherals, Peripherals};
+
+use hal::usb::UsbBus;
+use usb_device::bus::UsbBusAllocator;
+
+use usb_device::prelude::*;
+use usbd_serial::{SerialPort, USB_CLASS_CDC};
+
+use cortex_m::asm::delay as cycle_delay;
+use cortex_m::peripheral::NVIC;
#[entry]
fn main() -> ! {
let mut peripherals = Peripherals::take().unwrap();
- let core = CorePeripherals::take().unwrap();
- let mut clocks = GenericClockController::with_external_32kosc(
+ let mut core = CorePeripherals::take().unwrap();
+ let mut clocks = GenericClockController::with_internal_32kosc(
peripherals.GCLK,
&mut peripherals.PM,
&mut peripherals.SYSCTRL,
&mut peripherals.NVMCTRL,
);
- let pins = bsp::Pins::new(peripherals.PORT);
- let mut red_led: bsp::RedLed = pins.d13.into();
- let mut delay = Delay::new(core.SYST, &mut clocks);
+ let mut pins = hal::Pins::new(peripherals.PORT);
+ let mut red_led = pins.d13.into_open_drain_output(&mut pins.port);
+
+ let bus_allocator = unsafe {
+ USB_ALLOCATOR = Some(hal::usb_allocator(
+ peripherals.USB,
+ &mut clocks,
+ &mut peripherals.PM,
+ pins.usb_dm,
+ pins.usb_dp,
+ &mut pins.port,
+ ));
+ USB_ALLOCATOR.as_ref().unwrap()
+ };
+
+ unsafe {
+ USB_SERIAL = Some(SerialPort::new(&bus_allocator));
+ USB_BUS = Some(
+ UsbDeviceBuilder::new(&bus_allocator, UsbVidPid(0x16c0, 0x27dd))
+ .manufacturer("Fake company")
+ .product("Serial port")
+ .serial_number("TEST")
+ .device_class(USB_CLASS_CDC)
+ .build(),
+ );
+ }
+
+ unsafe {
+ core.NVIC.set_priority(interrupt::USB, 1);
+ NVIC::unmask(interrupt::USB);
+ }
+
+ // Flash the LED in a spin loop to demonstrate that USB is
+ // entirely interrupt driven.
loop {
- delay.delay_ms(250u8);
- delay.delay_ms(250u8);
- delay.delay_ms(250u8);
- delay.delay_ms(250u8);
- red_led.set_high().unwrap();
- delay.delay_ms(100u8);
- red_led.set_low().unwrap();
- delay.delay_ms(100u8);
- red_led.set_high().unwrap();
- delay.delay_ms(100u8);
- red_led.set_low().unwrap();
+ cycle_delay(15 * 1024 * 1024);
+ red_led.toggle();
}
}
+
+static mut USB_ALLOCATOR: Option<UsbBusAllocator<UsbBus>> = None;
+static mut USB_BUS: Option<UsbDevice<UsbBus>> = None;
+static mut USB_SERIAL: Option<SerialPort<UsbBus>> = None;
+
+fn poll_usb() {
+ unsafe {
+ USB_BUS.as_mut().map(|usb_dev| {
+ USB_SERIAL.as_mut().map(|serial| {
+ usb_dev.poll(&mut [serial]);
+ let mut buf = [0u8; 64];
+
+ if let Ok(count) = serial.read(&mut buf) {
+ for (i, c) in buf.iter().enumerate() {
+ if i >= count {
+ break;
+ }
+ serial.write(&[c.clone()]);
+ }
+ };
+ });
+ });
+ };
+}
+
+#[interrupt]
+fn USB() {
+ poll_usb();
+}
\ No newline at end of file