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
9 changes: 6 additions & 3 deletions boards/feather_m0/.cargo/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@ target = "thumbv6m-none-eabi"
rustflags = [
# This is needed if your flash or ram addresses are not aligned to 0x10000 in memory.x
# See https://github.com/rust-embedded/cortex-m-quickstart/pull/95
"-C", "link-arg=--nmagic",
"-C", "link-arg=-Tlink.x",
"-C", "link-arg=-Tdefmt.x" # uncomment if using defmt
"-C",
"link-arg=--nmagic",
"-C",
"link-arg=-Tlink.x",
"-C",
"link-arg=-Tdefmt.x", # uncomment if using defmt
]

[target.thumbv6m-none-eabi]
Expand Down
15 changes: 15 additions & 0 deletions boards/trrs_trinkey/.cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# samd21 is a Cortex-M0 and thus thumbv6m

[build]
target = "thumbv6m-none-eabi"
rustflags = [
# This is needed if your flash or ram addresses are not aligned to 0x10000 in memory.x
# See https://github.com/rust-embedded/cortex-m-quickstart/pull/95
"-C", "link-arg=--nmagic",
"-C", "link-arg=-Tlink.x",
"-C", "link-arg=-Tdefmt.x" # uncomment if using defmt
]

[target.thumbv6m-none-eabi]
runner = 'arm-none-eabi-gdb'
#runner = 'probe-run --chip ATSAMD21G18A'
2 changes: 2 additions & 0 deletions boards/trrs_trinkey/.gdbinit
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
target remote :3333
file target/thumbv6m-none-eabi/debug/examples/blinky_rtic
6 changes: 6 additions & 0 deletions boards/trrs_trinkey/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
112 changes: 112 additions & 0 deletions boards/trrs_trinkey/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
[package]
authors = ["Erik Fong <quantumerikfong@gmail.com>"]
categories = ["embedded", "hardware-support", "no-std"]
description = "Board Support crate for the Adafruit TRRS Trinkey"
edition = "2021"
keywords = ["no-std", "arm", "cortex-m", "embedded-hal"]
license = "MIT OR Apache-2.0"
name = "trrs_trinkey"
readme = "README.md"
repository = "https://github.com/atsamd-rs/atsamd"
resolver = "2"
version = "0.20.1"

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

[dependencies.cortex-m-rt]
optional = true
version = "0.7"

[dependencies.atsamd-hal]
default-features = false
path = "../../hal"
version = "0.23.1"

[dependencies.cortex-m]
features = ["critical-section-single-core"]
version = "0.7"

[dependencies.rtic]
features = ["thumbv6-backend"]
optional = true
version = "2.1.1"

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

[dependencies.embedded-sdmmc]
optional = true
version = "0.3"

[dependencies]
smart-leds = { version = "0.3.0", optional = true }
ws2812-timer-delay = { version = "0.3.0", features = ["slow"], optional = true }

[dev-dependencies]
cortex-m = "0.7"
cortex-m-semihosting = "0.3"
defmt = "0.3"
defmt-rtt = "0.4"
drogue-nom-utils = "0.1"
embassy-executor = { version = "0.6.2", features = [
"arch-cortex-m",
"executor-thread",
"task-arena-size-64",
] }
embedded-graphics = "0.7.1"
heapless = "0.8"
nom = { version = "5", default-features = false }
panic-halt = "0.2"
panic-probe = "0.3"
panic-semihosting = "0.6"
rtic-monotonics = { version = "1.3.0", features = [
"cortex-m-systick",
"systick-10khz",
] }
ssd1306 = "0.7"
usbd-hid = "0.9.0"
usbd-serial = "0.2"

[features]
# ask the HAL to enable atsamd21g support
default = ["rt", "atsamd-hal/samd21g"]
leds = ["ws2812-timer-delay", "smart-leds"]
rt = ["cortex-m-rt", "atsamd-hal/samd21g-rt"]
usb = ["atsamd-hal/usb", "usb-device"]
use_rtt = ["atsamd-hal/use_rtt"]
dma = ["atsamd-hal/dma"]
max-channels = ["dma", "atsamd-hal/max-channels"]
# Enable async support from atsamd-hal
async = ["atsamd-hal/async"]
rtic = ["dep:rtic", "atsamd-hal/rtic"]
sdmmc = ["embedded-sdmmc", "atsamd-hal/sdmmc"]
use_semihosting = []

[[example]]
name = "blinky_basic"
required-features = ["leds"]

[[example]]
name = "blinky_embassy"
required-features = ["rtic", "leds"]

[[example]]
name = "i2c"
required-features = ["dma", "usb"]

[[example]]
name = "pwm"

[[example]]
name = "uart"

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

[[example]]
name = "usb_hid"
required-features = ["usb"]
38 changes: 38 additions & 0 deletions boards/trrs_trinkey/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Adafruit TRRS Trinkey Board Support Crate

This crate provides a type-safe API for working with the [Adafruit TRRS Trinkey
board](https://www.adafruit.com/product/5954) ([Adafruit tutorial page](https://learn.adafruit.com/adafruit-trrs-trinkey/)).

<figure>
<img src="https://raw.githubusercontent.com/adafruit/Adafruit-TRRS-Trinkey-PCB/refs/heads/main/Adafruit%20TRRS%20Trinkey%20PrettyPins.svg" alt="Adafruit TRRS Trinkey Pinout">
<figcaption>Adafruit TRRS Trinkey Pinout</figcaption>
</figure>

## Prerequisites

- Install the cross compile toolchain `rustup target add thumbv6m-none-eabi`
- Install [cargo-hf2 the hf2 bootloader flasher tool](https://crates.io/crates/cargo-hf2) however your platform requires

## Uploading an example

NOTE: `cargo-hf2` does not seem to work. It will require the following PR: https://github.com/jacobrosenthal/hf2-rs/pull/49

Check out the repository for examples:

https://github.com/atsamd-rs/atsamd/tree/master/boards/trrs_trinkey/examples

- Be in this directory `cd boards/trrs_trinkey`
- Put your device in bootloader mode usually by hitting the reset button twice.
- Build and upload in one step

```
$ cargo hf2 --features leds --release --example blinky_basic
Finished `release` profile [optimized + debuginfo] target(s) in 0.06s
Searching for a connected device with known vid/pid pair.
Trying Ok(Some("Adafruit Industries")) Ok(Some("TRRS Trinkey M0"))
Flashing "/home/quantum_p/LocalDocs/atsamd/target/thumbv6m-none-eabi/release/examples/blinky_basic"
Finished in 0.123s
$
```

The `usb_hid` example is the most useful given what the intended use of the device is. If you need details about other peripherials, the examples from other boards like the `feather_m0` should be sufficient, but have not yet been explicitly tested on this board.
16 changes: 16 additions & 0 deletions boards/trrs_trinkey/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
use std::env;
use std::fs::File;
use std::io::Write;
use std::path::PathBuf;
fn main() {
if env::var_os("CARGO_FEATURE_RT").is_some() {
let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
File::create(out.join("memory.x"))
.unwrap()
.write_all(include_bytes!("memory.x"))
.unwrap();
println!("cargo:rustc-link-search={}", out.display());
println!("cargo:rerun-if-changed=memory.x");
}
println!("cargo:rerun-if-changed=build.rs");
}
54 changes: 54 additions & 0 deletions boards/trrs_trinkey/examples/blinky_basic.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#![no_std]
#![no_main]

use panic_halt as _;

use trrs_trinkey as bsp;

use bsp::entry;
use bsp::hal;

use hal::clock::GenericClockController;
use hal::delay::Delay;
use hal::ehal::delay::DelayNs;
use hal::pac::{CorePeripherals, Peripherals};
use hal::time::Hertz;
use hal::timer::TimerCounter;
use hal::timer_traits::InterruptDrivenTimer;

use smart_leds::{hsv::RGB8, SmartLedsWrite};
use ws2812_timer_delay::Ws2812;

#[entry]
fn main() -> ! {
let mut peripherals = Peripherals::take().unwrap();
let 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 gclk0 = clocks.gclk0();
let timer_clock = clocks.tcc2_tc3(&gclk0).unwrap();
let mut timer = TimerCounter::tc3_(&timer_clock, peripherals.tc3, &mut peripherals.pm);
timer.start(Hertz::MHz(3).into_duration());
let neo_pixel = pins.neo_pixel.into_push_pull_output();
let mut ws2812 = Ws2812::new(timer, neo_pixel);

let mut delay = Delay::new(core.SYST, &mut clocks);

const NUM_LEDS: usize = 1;
let off = [RGB8::default(); NUM_LEDS];
let on = [RGB8::new(0, 0, 5)];

loop {
ws2812.write(off.iter().cloned()).unwrap();
delay.delay_ms(500);
ws2812.write(on.iter().cloned()).unwrap();
delay.delay_ms(500);
}
}
55 changes: 55 additions & 0 deletions boards/trrs_trinkey/examples/blinky_embassy.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
//! Uses RTIC with systick to blink a led in an asynchronous fashion.
#![no_std]
#![no_main]

use feather_m0 as bsp;

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

use bsp::{hal, pac, pin_alias};
use hal::clock::{ClockGenId, ClockSource, GenericClockController};
use hal::prelude::*;
use hal::rtc::rtic::rtc_clock;

// We can use the RTIC monotonic with embassy
hal::rtc_monotonic!(Mono, rtc_clock::ClockCustom<8_192>);

// However, to do so, we need to define this, which is normally defined within
// RTIC. This sets the RTC monotonic interrupt priority to be the most
// important.
#[no_mangle]
static RTIC_ASYNC_MAX_LOGICAL_PRIO: u8 = 1;

#[embassy_executor::main]
async fn main(_s: embassy_executor::Spawner) {
let mut peripherals = pac::Peripherals::take().unwrap();
let _core = pac::CorePeripherals::take().unwrap();
let pins = bsp::Pins::new(peripherals.port);
let mut clocks = GenericClockController::with_external_32kosc(
peripherals.gclk,
&mut peripherals.pm,
&mut peripherals.sysctrl,
&mut peripherals.nvmctrl,
);

// Set the RTC clock to use a 8.192 kHz clock derived from the external 32 kHz
// oscillator.
let rtc_clock_src = clocks
.configure_gclk_divider_and_source(ClockGenId::Gclk2, 4, ClockSource::Xosc32k, false)
.unwrap();
clocks.configure_standby(ClockGenId::Gclk2, true);
let _ = clocks.rtc(&rtc_clock_src).unwrap();

let mut red_led: bsp::RedLed = pin_alias!(pins.red_led).into();

// Start the monotonic
Mono::start(peripherals.rtc);

loop {
let _ = red_led.toggle();
Mono::delay(1u64.secs()).await;
}
}
Loading
Loading