]> patrickod personal git archive - tincan.git/commitdiff
import 0.12 (?) usb_echo wholesale
authorAndy Isaacson <adi@hexapodia.org>
Mon, 12 Jul 2021 03:11:31 +0000 (20:11 -0700)
committerAndy Isaacson <adi@hexapodia.org>
Mon, 12 Jul 2021 03:11:31 +0000 (20:11 -0700)
rs-lorachat/Cargo.toml
rs-lorachat/src/lib.rs [new file with mode: 0644]
rs-lorachat/src/main.rs

index cff8d1af3e723f0f79f97d448383549302afd962..b76ed9186bdb91f98b65ab17afbd7bb89809d003 100644 (file)
@@ -16,6 +16,7 @@ optional = true
 
 [dependencies.atsamd-hal]
 version = "0.12"
+default-features = false
 
 [dependencies.panic-halt]
 version = "0.2"
@@ -25,10 +26,6 @@ optional = true
 version = "0.2"
 optional = true
 
-[dependencies.rtic-monotonic]
-version = "=0.1.0-alpha.1"
-optional = true
-
 [dependencies.usbd-serial]
 version = "0.1"
 optional = true
@@ -37,9 +34,6 @@ optional = true
 cortex-m-semihosting = "0.3"
 heapless = "0.5"
 
-[dev-dependencies.cortex-m-rtic]
-version = "0.6.0-alpha.4"
-
 [features]
 default = ["rt", "atsamd-hal/samd21g", "panic_halt"]
 rt = ["cortex-m-rt", "atsamd-hal/samd21g-rt"]
diff --git a/rs-lorachat/src/lib.rs b/rs-lorachat/src/lib.rs
new file mode 100644 (file)
index 0000000..ad9b80c
--- /dev/null
@@ -0,0 +1,226 @@
+#![no_std]
+
+extern crate atsamd_hal as hal;
+
+#[cfg(feature = "rt")]
+extern crate cortex_m_rt;
+#[cfg(feature = "rt")]
+pub use cortex_m_rt::entry;
+
+use hal::prelude::*;
+use hal::*;
+
+pub use hal::common::*;
+pub use hal::samd21::*;
+pub use hal::target_device as pac;
+
+use gpio::{Floating, Input, PfC, Port};
+use hal::clock::GenericClockController;
+use hal::sercom::{I2CMaster3, PadPin, SPIMaster4, UART0};
+use hal::time::Hertz;
+
+#[cfg(feature = "usb")]
+use hal::usb::usb_device::bus::UsbBusAllocator;
+#[cfg(feature = "usb")]
+pub use hal::usb::UsbBus;
+
+define_pins!(
+    /// Maps the pins to their arduino names and
+    /// the numbers printed on the board.
+    struct Pins,
+    target_device: target_device,
+
+    /// AREF pin - has 1uF capacitor to ground
+    pin aref = a3,
+
+    /// Analog pin 0.  Can act as a true analog output
+    /// as it has a DAC (which is not currently supported
+    /// by this hal) as well as input.
+    pin a0 = a2,
+
+    /// Analog Pin 1
+    pin a1 = b8,
+    /// Analog Pin 2
+    pin a2 = b9,
+    /// Analog Pin 3
+    pin a3 = a4,
+    /// Analog Pin 4
+    pin a4 = a5,
+    /// Analog Pin 5
+    pin a5 = b2,
+
+    /// Pin 0, rx
+    pin d0 = a11,
+    /// Pin 1, tx
+    pin d1 = a10,
+    /// Pin 5, PWM capable
+    pin d5 = a15,
+    /// Pin 6, PWM capable
+    pin d6 = a20,
+    /// Pin 9, PWM capable.  Also analog input (A7)
+    pin d9 = a7,
+    /// Pin 10, PWM capable
+    pin d10 = a18,
+    /// Pin 11, PWM capable
+    pin d11 = a16,
+    /// Pin 12, PWM capable
+    pin d12 = a19,
+    /// Pin 13, which is also attached to
+    /// the red LED.  PWM capable.
+    pin d13 = a17,
+
+    /// The I2C data line
+    pin sda = a22,
+    /// The I2C clock line
+    pin scl = a23,
+
+    /// The SPI SCK
+    pin sck = b11,
+    /// The SPI MOSI
+    pin mosi = b10,
+    /// The SPI MISO
+    pin miso = a12,
+
+    /// The USB D- pad
+    pin usb_dm = a24,
+    /// The USB D+ pad
+    pin usb_dp = a25,
+
+    /// SPI chip select for the RFM module
+    #[cfg(feature = "rfm")]
+    pin rfm_cs = a6,
+
+    /// Reset for the RFM module
+    #[cfg(feature = "rfm")]
+    pin rfm_reset = a8,
+
+    /// Interrupt from the RFM module
+    #[cfg(feature = "rfm")]
+    pin rfm_irq = a9,
+
+    /// Neopixel data
+    #[cfg(feature = "express")]
+    pin neopixel = a6,
+
+    /// SPI clock for the external flash
+    #[cfg(feature = "express")]
+    pin flash_sck = a9,
+
+    /// SPI MOSI for the external flash
+    #[cfg(feature = "express")]
+    pin flash_mosi = a8,
+
+    /// SPI MISO for the external flash
+    #[cfg(feature = "express")]
+    pin flash_miso = a14,
+
+    /// SPI chip select for the external flash
+    #[cfg(feature = "express")]
+    pin flash_cs = a13,
+);
+
+/// Convenience for setting up the labelled SPI peripheral.
+/// This powers up SERCOM4 and configures it for use as an
+/// SPI Master in SPI Mode 0.
+pub fn spi_master<F: Into<Hertz>>(
+    clocks: &mut GenericClockController,
+    bus_speed: F,
+    sercom4: pac::SERCOM4,
+    pm: &mut pac::PM,
+    sck: gpio::Pb11<Input<Floating>>,
+    mosi: gpio::Pb10<Input<Floating>>,
+    miso: gpio::Pa12<Input<Floating>>,
+    port: &mut Port,
+) -> SPIMaster4<
+    hal::sercom::Sercom4Pad0<gpio::Pa12<gpio::PfD>>,
+    hal::sercom::Sercom4Pad2<gpio::Pb10<gpio::PfD>>,
+    hal::sercom::Sercom4Pad3<gpio::Pb11<gpio::PfD>>,
+> {
+    let gclk0 = clocks.gclk0();
+    SPIMaster4::new(
+        &clocks.sercom4_core(&gclk0).unwrap(),
+        bus_speed.into(),
+        hal::hal::spi::Mode {
+            phase: hal::hal::spi::Phase::CaptureOnFirstTransition,
+            polarity: hal::hal::spi::Polarity::IdleLow,
+        },
+        sercom4,
+        pm,
+        (miso.into_pad(port), mosi.into_pad(port), sck.into_pad(port)),
+    )
+}
+
+/// Convenience for setting up the labelled SDA, SCL pins to
+/// operate as an I2C master running at the specified frequency.
+pub fn i2c_master<F: Into<Hertz>>(
+    clocks: &mut GenericClockController,
+    bus_speed: F,
+    sercom3: pac::SERCOM3,
+    pm: &mut pac::PM,
+    sda: gpio::Pa22<Input<Floating>>,
+    scl: gpio::Pa23<Input<Floating>>,
+    port: &mut Port,
+) -> I2CMaster3<
+    hal::sercom::Sercom3Pad0<hal::gpio::Pa22<hal::gpio::PfC>>,
+    hal::sercom::Sercom3Pad1<hal::gpio::Pa23<hal::gpio::PfC>>,
+> {
+    let gclk0 = clocks.gclk0();
+    I2CMaster3::new(
+        &clocks.sercom3_core(&gclk0).unwrap(),
+        bus_speed.into(),
+        sercom3,
+        pm,
+        sda.into_pad(port),
+        scl.into_pad(port),
+    )
+}
+
+/// Convenience for setting up the labelled RX, TX pins to
+/// operate as a UART device running at the specified baud.
+pub fn uart<F: Into<Hertz>>(
+    clocks: &mut GenericClockController,
+    baud: F,
+    sercom0: pac::SERCOM0,
+    pm: &mut pac::PM,
+    d0: gpio::Pa11<Input<Floating>>,
+    d1: gpio::Pa10<Input<Floating>>,
+    port: &mut Port,
+) -> UART0<
+    hal::sercom::Sercom0Pad3<gpio::Pa11<PfC>>,
+    hal::sercom::Sercom0Pad2<gpio::Pa10<PfC>>,
+    (),
+    (),
+> {
+    let gclk0 = clocks.gclk0();
+
+    UART0::new(
+        &clocks.sercom0_core(&gclk0).unwrap(),
+        baud.into(),
+        sercom0,
+        pm,
+        (d0.into_pad(port), d1.into_pad(port)),
+    )
+}
+
+#[cfg(feature = "usb")]
+pub fn usb_allocator(
+    usb: pac::USB,
+    clocks: &mut GenericClockController,
+    pm: &mut pac::PM,
+    dm: gpio::Pa24<Input<Floating>>,
+    dp: gpio::Pa25<Input<Floating>>,
+    port: &mut Port,
+) -> UsbBusAllocator<UsbBus> {
+    use gpio::IntoFunction;
+
+    let gclk0 = clocks.gclk0();
+    let usb_clock = &clocks.usb(&gclk0).unwrap();
+
+    UsbBusAllocator::new(UsbBus::new(
+        usb_clock,
+        pm,
+        dm.into_function(port),
+        dp.into_function(port),
+        usb,
+    ))
+}
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();
+}