Created
August 7, 2020 01:12
-
-
Save sajattack/8deca7c0a96b4390250f6d31fb18508f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #![no_std] | |
| #![no_main] | |
| extern crate metro_m4 as hal; | |
| extern crate cortex_m; | |
| extern crate panic_halt; | |
| extern crate usb_device; | |
| extern crate usbd_serial; | |
| use hal::clock::GenericClockController; | |
| use hal::entry; | |
| use hal::pac::{interrupt, CorePeripherals, Peripherals}; | |
| use hal::prelude::*; | |
| 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 mut core = CorePeripherals::take().unwrap(); | |
| let mut clocks = GenericClockController::with_external_32kosc( | |
| peripherals.GCLK, | |
| &mut peripherals.MCLK, | |
| &mut peripherals.OSC32KCTRL, | |
| &mut peripherals.OSCCTRL, | |
| &mut peripherals.NVMCTRL, | |
| ); | |
| 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( | |
| pins.usb_dm, | |
| pins.usb_dp, | |
| peripherals.USB, | |
| &mut clocks, | |
| &mut peripherals.MCLK, | |
| &mut pins.port, | |
| )); | |
| USB_ALLOCATOR.as_ref().unwrap() | |
| }; | |
| unsafe { | |
| USB_SERIAL = Some(SerialPort::new(&bus_allocator)); | |
| USB_BUS = Some( | |
| UsbDeviceBuilder::new(&bus_allocator, UsbVidPid(0x2222, 0x3333)) | |
| .manufacturer("Fake company") | |
| .product("Serial port") | |
| .serial_number("TEST") | |
| .device_class(USB_CLASS_CDC) | |
| .build(), | |
| ); | |
| } | |
| unsafe { | |
| core.NVIC.set_priority(interrupt::USB_TRCPT0, 1); | |
| NVIC::unmask(interrupt::USB_TRCPT0); | |
| core.NVIC.set_priority(interrupt::USB_TRCPT1, 1); | |
| NVIC::unmask(interrupt::USB_TRCPT1); | |
| core.NVIC.set_priority(interrupt::USB_SOF_HSOF, 1); | |
| NVIC::unmask(interrupt::USB_SOF_HSOF); | |
| core.NVIC.set_priority(interrupt::USB_OTHER, 1); | |
| NVIC::unmask(interrupt::USB_OTHER); | |
| } | |
| let tc0 = peripherals.TC0; | |
| // Flash the LED in a spin loop to demonstrate that USB is | |
| // entirely interrupt driven. | |
| loop { | |
| cycle_delay(5 * 1024 * 1024); | |
| red_led.toggle(); | |
| // Turn off interrupts so we don't fight with the interrupt | |
| cortex_m::interrupt::free(|_| unsafe { | |
| USB_BUS.as_mut().map(|_| { | |
| USB_SERIAL.as_mut().map(|serial| { | |
| let _ = serial.write("log: ".as_bytes()); | |
| tc0.count16().ctrla.write(|w| w.dmaos().set_bit()); | |
| if tc0.count16().ctrla.read().dmaos().bit_is_set() { | |
| let _ = serial.write("bit is set\r\n".as_bytes()); | |
| } else { | |
| let _ = serial.write("bit is not set\r\n".as_bytes()); | |
| } | |
| }); | |
| }) | |
| }); | |
| } | |
| } | |
| 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]); | |
| // Make the other side happy | |
| let mut buf = [0u8; 16]; | |
| let _ = serial.read(&mut buf); | |
| }); | |
| }); | |
| }; | |
| } | |
| #[interrupt] | |
| fn USB_TRCPT0() { | |
| poll_usb(); | |
| } | |
| #[interrupt] | |
| fn USB_TRCPT1() { | |
| poll_usb(); | |
| } | |
| #[interrupt] | |
| fn USB_SOF_HSOF() { | |
| poll_usb(); | |
| } | |
| #[interrupt] | |
| fn USB_OTHER() { | |
| poll_usb(); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment