]> patrickod personal git archive - tincan.git/blobdiff - rs-lorachat/src/main.rs
import 0.12 (?) usb_echo wholesale
[tincan.git] / rs-lorachat / src / main.rs
index 92e4f458b9cc0de51cf81de13ee84dae9f7d6927..89ad86887f19693e0dee1ae09d39d68f844fa337 100644 (file)
 #![no_std]
 #![no_main]
 
-use panic_halt as _;
+extern crate cortex_m;
+extern crate feather_m0 as hal;
+extern crate panic_halt;
+extern crate usb_device;
+extern crate usbd_serial;
 
-use bsp::hal;
-use feather_m0 as bsp;
-
-use bsp::entry;
-use hal::clock::{GenericClockController};
-use hal::delay::Delay;
-use hal::pac::{CorePeripherals, Peripherals};
+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 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 delay = Delay::new(core.SYST, &mut clocks);
-    let mut red_led = pins.d13.into_push_pull_output();
+    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()
+    };
 
-    red_led.set_high().unwrap();
-    delay.delay_ms(500_u32);
-    red_led.set_low().unwrap();
-    delay.delay_ms(500_u32);
-    red_led.set_high().unwrap();
-
-    red_led.set_low().unwrap();
-    delay.delay_ms(500_u32);
+    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(1_000_u32);
-        red_led.set_high().unwrap();
-        delay.delay_ms(1_000_u32);
-        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();
+}