]> patrickod personal git archive - tincan.git/blob - rs-lorachat/src/main.rs
89ad86887f19693e0dee1ae09d39d68f844fa337
[tincan.git] / rs-lorachat / src / main.rs
1 #![no_std]
2 #![no_main]
3
4 extern crate cortex_m;
5 extern crate feather_m0 as hal;
6 extern crate panic_halt;
7 extern crate usb_device;
8 extern crate usbd_serial;
9
10 use hal::clock::GenericClockController;
11 use hal::entry;
12 use hal::pac::{interrupt, CorePeripherals, Peripherals};
13 use hal::prelude::*;
14
15 use hal::usb::UsbBus;
16 use usb_device::bus::UsbBusAllocator;
17
18 use usb_device::prelude::*;
19 use usbd_serial::{SerialPort, USB_CLASS_CDC};
20
21 use cortex_m::asm::delay as cycle_delay;
22 use cortex_m::peripheral::NVIC;
23
24 #[entry]
25 fn main() -> ! {
26     let mut peripherals = Peripherals::take().unwrap();
27     let mut core = CorePeripherals::take().unwrap();
28     let mut clocks = GenericClockController::with_internal_32kosc(
29         peripherals.GCLK,
30         &mut peripherals.PM,
31         &mut peripherals.SYSCTRL,
32         &mut peripherals.NVMCTRL,
33     );
34     let mut pins = hal::Pins::new(peripherals.PORT);
35     let mut red_led = pins.d13.into_open_drain_output(&mut pins.port);
36
37     let bus_allocator = unsafe {
38         USB_ALLOCATOR = Some(hal::usb_allocator(
39             peripherals.USB,
40             &mut clocks,
41             &mut peripherals.PM,
42             pins.usb_dm,
43             pins.usb_dp,
44             &mut pins.port,
45         ));
46         USB_ALLOCATOR.as_ref().unwrap()
47     };
48
49     unsafe {
50         USB_SERIAL = Some(SerialPort::new(&bus_allocator));
51         USB_BUS = Some(
52             UsbDeviceBuilder::new(&bus_allocator, UsbVidPid(0x16c0, 0x27dd))
53                 .manufacturer("Fake company")
54                 .product("Serial port")
55                 .serial_number("TEST")
56                 .device_class(USB_CLASS_CDC)
57                 .build(),
58         );
59     }
60
61     unsafe {
62         core.NVIC.set_priority(interrupt::USB, 1);
63         NVIC::unmask(interrupt::USB);
64     }
65
66     // Flash the LED in a spin loop to demonstrate that USB is
67     // entirely interrupt driven.
68     loop {
69         cycle_delay(15 * 1024 * 1024);
70         red_led.toggle();
71     }
72 }
73
74 static mut USB_ALLOCATOR: Option<UsbBusAllocator<UsbBus>> = None;
75 static mut USB_BUS: Option<UsbDevice<UsbBus>> = None;
76 static mut USB_SERIAL: Option<SerialPort<UsbBus>> = None;
77
78 fn poll_usb() {
79     unsafe {
80         USB_BUS.as_mut().map(|usb_dev| {
81             USB_SERIAL.as_mut().map(|serial| {
82                 usb_dev.poll(&mut [serial]);
83                 let mut buf = [0u8; 64];
84
85                 if let Ok(count) = serial.read(&mut buf) {
86                     for (i, c) in buf.iter().enumerate() {
87                         if i >= count {
88                             break;
89                         }
90                         serial.write(&[c.clone()]);
91                     }
92                 };
93             });
94         });
95     };
96 }
97
98 #[interrupt]
99 fn USB() {
100     poll_usb();
101 }