Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 31 additions & 4 deletions boards/arduino_mkr1000/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
[package]
name = "arduino_mkr1000"
version = "0.5.1"
authors = ["Eric Rushing <[email protected]>"]
version = "0.6.0"
authors = [
"Eric Rushing <[email protected]>",
"Joël Bourgault <[email protected]>",
]
description = "Board Support crate for the Arduino MKR 1000 WiFi"
keywords = ["no-std", "arm", "cortex-m", "embedded-hal"]
categories = ["embedded", "hardware-support", "no-std"]
Expand All @@ -15,25 +18,49 @@ version = "0.7"
optional = true

[dependencies.atsamd-hal]
version = "0.14"
version = "0.16"
default-features = false

[dependencies.usb-device]
version = "0.2"
optional = true

[dev-dependencies]
cortex-m = "0.7"
usbd-serial = "0.1"
panic-halt = "0.2"
panic-semihosting = "0.5"
cortex-m-rtic = "1.0"

[features]
# ask the HAL to enable atsamd21g support
default = ["rt", "atsamd-hal/samd21g"]
default = ["rt", "atsamd-hal/samd21g", "usb"]
rt = ["cortex-m-rt", "atsamd-hal/samd21g-rt"]
usb = ["atsamd-hal/usb", "usb-device"]
unproven = ["atsamd-hal/unproven"]
use_semihosting = []
rtic = ["atsamd-hal/rtic"]

# for cargo flash
[package.metadata]
chip = "ATSAMD21G18A"

[dependencies]
embedded-hal = "0.2.7"

[[example]]
name = "blinky_basic"

[[example]]
name = "blinky_rtic"
required-features = ["rtic", "unproven"]
# This example also requires `cortex-m-rtic`.
# Don't import `rtic`; see `blinky_rtic` comments in code for explanation.

[[example]]
name = "usb_logging"
required-features = ["usb"]

[[example]]
name = "pwm"
required-features = ["unproven"]
13 changes: 7 additions & 6 deletions boards/arduino_mkr1000/examples/blinky_basic.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
#![no_std]
#![no_main]

use arduino_mkr1000 as bsp;
use bsp::hal;

#[cfg(not(feature = "use_semihosting"))]
use panic_halt as _;
#[cfg(feature = "use_semihosting")]
use panic_semihosting as _;

use bsp::entry;
use arduino_mkr1000 as bsp;
use bsp::hal;

use bsp::{entry, pin_alias};
use hal::clock::GenericClockController;
use hal::delay::Delay;
use hal::pac::{CorePeripherals, Peripherals};
Expand All @@ -25,9 +25,10 @@ fn main() -> ! {
&mut peripherals.SYSCTRL,
&mut peripherals.NVMCTRL,
);
let mut pins = bsp::Pins::new(peripherals.PORT);
let mut led = pins.d6.into_open_drain_output(&mut pins.port);
let pins = bsp::pins::Pins::new(peripherals.PORT);
let mut led = pin_alias!(pins.led).into_push_pull_output();
let mut delay = Delay::new(core.SYST, &mut clocks);

loop {
delay.delay_ms(200u8);
led.set_high().unwrap();
Expand Down
92 changes: 92 additions & 0 deletions boards/arduino_mkr1000/examples/blinky_rtic.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
//! Uses RTIC with the RTC as time source to blink an LED.
//!
//! The idle task is sleeping the CPU, so in practice this gives similar power
//! figure as the "sleeping_timer_rtc" example.
//!
//! Note on imports: this example requires `cortex-m-rtic`, whih brings the
//! `rtic` package, but also brings/selects the appropriate RTIC backend.
//!
//! If `rtic` package is imported instead of `cortex-m-rtic`, following message
//! is displayed at compilation, containing `No backend feature selected.`:
//!
//! ```sh
//! $ cargo build
//! (...)
//! error: failed to run custom build command for `rtic v2.2.0`
//! Caused by:
//! process didn't exit successfully: `/home/.../dev/électronique/my-great-prj/target/debug/build/rtic-4840d1be515a89f0/build-script-build` (exit status: 101)
//! --- stderr
//! thread 'main' panicked at /home/.../.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rtic-2.2.0/build.rs:18:34:
//! No backend feature selected.
//! note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
//! ```

#![no_std]
#![no_main]

use arduino_mkr1000 as bsp;

#[cfg(not(feature = "use_semihosting"))]
use panic_halt as _;
#[cfg(feature = "use_semihosting")]
use panic_semihosting as _;
use rtic::app;

#[app(device = bsp::pac, peripherals = true, dispatchers = [EVSYS])]
mod app {
use super::*;
use bsp::hal;
use hal::clock::{ClockGenId, ClockSource, GenericClockController};
use hal::pac::Peripherals;
use hal::prelude::*;
use hal::rtc::{Count32Mode, Duration, Rtc};

#[local]
struct Local {}

#[shared]
struct Shared {
// The LED could be a local resource, since it is only used in one task
// But we want to showcase shared resources and locking
led: bsp::pins::Led,
}

#[monotonic(binds = RTC, default = true)]
type RtcMonotonic = Rtc<Count32Mode>;

#[init]
fn init(cx: init::Context) -> (Shared, Local, init::Monotonics) {
let mut peripherals: Peripherals = cx.device;
let pins = bsp::pins::Pins::new(peripherals.PORT);
let mut core: rtic::export::Peripherals = cx.core;
let mut clocks = GenericClockController::with_external_32kosc(
peripherals.GCLK,
&mut peripherals.PM,
&mut peripherals.SYSCTRL,
&mut peripherals.NVMCTRL,
);
let _gclk = clocks.gclk0();
let rtc_clock_src = clocks
.configure_gclk_divider_and_source(ClockGenId::GCLK2, 1, ClockSource::XOSC32K, false)
.unwrap();
clocks.configure_standby(ClockGenId::GCLK2, true);
let rtc_clock = clocks.rtc(&rtc_clock_src).unwrap();
let rtc = Rtc::count32_mode(peripherals.RTC, rtc_clock.freq(), &mut peripherals.PM);
let led = bsp::pin_alias!(pins.led).into();

// We can use the RTC in standby for maximum power savings
core.SCB.set_sleepdeep();

// Start the blink task
blink::spawn().unwrap();

(Shared { led }, Local {}, init::Monotonics(rtc))
}

#[task(shared = [led])]
fn blink(mut cx: blink::Context) {
// If the LED were a local resource, the lock would not be necessary
let _ = cx.shared.led.lock(|led| led.toggle());
blink::spawn_after(Duration::millis(750)).ok();
}
}
52 changes: 52 additions & 0 deletions boards/arduino_mkr1000/examples/pwm.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#![no_std]
#![no_main]

use arduino_mkr1000 as bsp;
use bsp::hal;

#[cfg(not(feature = "use_semihosting"))]
use panic_halt as _;
#[cfg(feature = "use_semihosting")]
use panic_semihosting as _;

use bsp::entry;
use hal::clock::GenericClockController;
use hal::delay::Delay;
use hal::pac::{CorePeripherals, Peripherals};
use hal::prelude::*;
use hal::pwm::{Channel, Pwm0};

#[entry]
fn main() -> ! {
let mut peripherals = Peripherals::take().unwrap();
let core = CorePeripherals::take().unwrap();
let mut clocks = GenericClockController::with_external_32kosc(
peripherals.GCLK,
&mut peripherals.PM,
&mut peripherals.SYSCTRL,
&mut peripherals.NVMCTRL,
);
let mut delay = Delay::new(core.SYST, &mut clocks);
let pins = bsp::pins::Pins::new(peripherals.PORT);
let gclk0 = clocks.gclk0();

// configure target pin
let _pin: bsp::pins::D6PwmF = pins.led.into();

let mut pwm0 = Pwm0::new(
&clocks.tcc0_tcc1(&gclk0).unwrap(),
1u32.kHz(),
peripherals.TCC0,
&mut peripherals.PM,
);
let channel = Channel::_2;
pwm0.enable(channel);

let max_duty = pwm0.get_max_duty();
loop {
pwm0.set_duty(channel, max_duty);
delay.delay_ms(500u16);
pwm0.set_duty(channel, max_duty / 4);
delay.delay_ms(500u16);
}
}
105 changes: 105 additions & 0 deletions boards/arduino_mkr1000/examples/usb_logging.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
#![no_std]
#![no_main]

use arduino_mkr1000 as bsp;
use bsp::hal;

#[cfg(not(feature = "use_semihosting"))]
use panic_halt as _;
#[cfg(feature = "use_semihosting")]
use panic_semihosting as _;

use bsp::entry;
use hal::clock::GenericClockController;
use hal::delay::Delay;
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::peripheral::NVIC;

static mut USB_ALLOCATOR: Option<UsbBusAllocator<UsbBus>> = None;
static mut USB_BUS: Option<UsbDevice<UsbBus>> = None;
static mut USB_SERIAL: Option<SerialPort<UsbBus>> = None;

#[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.PM,
&mut peripherals.SYSCTRL,
&mut peripherals.NVMCTRL,
);
let pins = bsp::pins::Pins::new(peripherals.PORT);
let mut led = bsp::pin_alias!(pins.led).into_push_pull_output();
let mut delay = Delay::new(core.SYST, &mut clocks);

let usb_n = bsp::pin_alias!(pins.usb_n);
let usb_p = bsp::pin_alias!(pins.usb_p);

let bus_allocator = unsafe {
USB_ALLOCATOR = Some(bsp::usb::usb_allocator(
peripherals.USB,
&mut clocks,
&mut peripherals.PM,
usb_n.into(),
usb_p.into(),
));
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, 1);
NVIC::unmask(interrupt::USB);
}

loop {
delay.delay_ms(200u8);
led.set_high().unwrap();
delay.delay_ms(200u8);
led.set_low().unwrap();

// Turn off interrupts so we don't fight with the interrupt
cortex_m::interrupt::free(|_| unsafe {
if let Some(serial) = USB_SERIAL.as_mut() {
let _ = serial.write("log line\r\n".as_bytes());
}
});
}
}

fn poll_usb() {
unsafe {
if let Some(usb_dev) = USB_BUS.as_mut() {
if let Some(serial) = USB_SERIAL.as_mut() {
usb_dev.poll(&mut [serial]);
// Make the other side happy
let mut buf = [0u8; 16];
let _ = serial.read(&mut buf);
}
}
};
}

#[interrupt]
fn USB() {
poll_usb();
}
Loading