#![no_std]
#![no_main]
#[cfg(not(feature = "use_semihosting"))]
use panic_halt as _;
#[cfg(feature = "use_semihosting")]
use panic_semihosting as _;
use cortex_m::asm::delay as cycle_delay;
use cortex_m::peripheral::NVIC;
use usb_device::bus::UsbBusAllocator;
use usb_device::prelude::*;
use usbd_serial::{SerialPort, USB_CLASS_CDC};
use bsp::hal;
use bsp::pac;
use circuit_playground_express as bsp;
use bsp::entry;
use hal::clock::GenericClockController;
use hal::prelude::*;
use hal::usb::UsbBus;
use pac::{interrupt, CorePeripherals, Peripherals};
#[entry]
fn main() -> ! {
let mut peripherals = Peripherals::take().unwrap();
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 bus_allocator = unsafe {
USB_ALLOCATOR = Some(bsp::usb_allocator(
peripherals.USB,
&mut clocks,
&mut peripherals.PM,
pins.usb_dm,
pins.usb_dp,
));
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);
}
loop {
cycle_delay(15 * 1024 * 1024);
red_led.set_high().ok();
cycle_delay(15 * 1024 * 1024);
red_led.set_low().ok();
}
}
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()]).ok();
}
};
});
});
};
}
#[interrupt]
fn USB() {
poll_usb();
}