Skip to content

Commit

Permalink
Add examples and update T1 BSPs
Browse files Browse the repository at this point in the history
  • Loading branch information
jbeaurivage committed Oct 18, 2024
1 parent bbc1f60 commit bd3538f
Show file tree
Hide file tree
Showing 30 changed files with 1,068 additions and 53 deletions.
6 changes: 6 additions & 0 deletions boards/atsame54_xpro/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,9 @@ can = ["atsamd-hal/can"]
[[example]]
name = "mcan"
required-features = ["can"]

[[example]]
name = "blinky_basic"

[[example]]
name = "blinky_rtic"
12 changes: 6 additions & 6 deletions boards/atsame54_xpro/examples/mcan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,12 +140,12 @@ mod app {

let (pclk_eic, gclk0) = clock::pclk::Pclk::enable(tokens.pclks.eic, clocks.gclk0);

let mut eic = hal::eic::init_with_ulp32k(&mut mclk, pclk_eic.into(), ctx.device.eic);
let mut button = bsp::pin_alias!(pins.button).into_pull_up_ei();
eic.button_debounce_pins(&[button.id()]);
button.sense(&mut eic, Sense::Fall);
button.enable_interrupt(&mut eic);
eic.finalize();
let mut eic =
hal::eic::init_with_ulp32k(&mut mclk, pclk_eic.into(), ctx.device.eic).finalize();
let mut button = bsp::pin_alias!(pins.button).into_pull_up_ei(&mut eic);
button.sense(Sense::Fall);
button.debounce();
button.enable_interrupt();

let can1_rx = bsp::pin_alias!(pins.ata6561_rx).into_mode();
let can1_tx = bsp::pin_alias!(pins.ata6561_tx).into_mode();
Expand Down
1 change: 1 addition & 0 deletions boards/feather_m0/.cargo/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ rustflags = [
# 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]
Expand Down
45 changes: 40 additions & 5 deletions boards/feather_m0/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,23 @@ version = "0.3"
optional = true

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

[features]
# ask the HAL to enable atsamd21g support
Expand All @@ -61,6 +67,8 @@ rfm = []
express = []
dma = ["atsamd-hal/dma"]
max-channels = ["dma", "atsamd-hal/max-channels"]
# Enable async support from atsamd-hal
async = ["atsamd-hal/async"]
# Enable pins for the adalogger SD card reader
adalogger = []
# Enable pins for Feather with WINC1500 wifi
Expand All @@ -72,6 +80,10 @@ use_semihosting = []
[[example]]
name = "blinky_basic"

[[example]]
name = "blinky_rtic"
required-features = ["rtic"]

[[example]]
name = "timers"

Expand Down Expand Up @@ -122,8 +134,7 @@ name = "adalogger"
required-features = ["adalogger", "usb", "sdmmc"]

[[example]]
name = "blinky_rtic"
required-features = ["rtic"]
name = "blinky_monotonic"

[[example]]
name = "uart"
Expand All @@ -132,3 +143,27 @@ required-features = ["dma"]
[[example]]
name = "i2c"
required-features = ["dma"]

[[example]]
name = "async_dmac"
required-features = ["dma", "async"]

[[example]]
name = "async_timer"
required-features = ["async"]

[[example]]
name = "async_eic"
required-features = ["async"]

[[example]]
name = "async_i2c"
required-features = ["dma", "async"]

[[example]]
name = "async_spi"
required-features = ["dma", "async"]

[[example]]
name = "async_uart"
required-features = ["dma", "async"]
73 changes: 73 additions & 0 deletions boards/feather_m0/examples/async_dmac.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
//! This example shows a safe API to
//! execute a memory-to-memory DMA transfer

#![no_std]
#![no_main]

use defmt_rtt as _;
use panic_probe as _;

atsamd_hal::bind_interrupts!(struct Irqs {
DMAC => atsamd_hal::dmac::InterruptHandler;
});

use bsp::hal;
use bsp::pac;
use feather_m0 as bsp;
use hal::{
clock::GenericClockController,
dmac::{DmaController, PriorityLevel, TriggerAction, TriggerSource},
};

#[embassy_executor::main]
async fn main(_s: embassy_executor::Spawner) {
let mut peripherals = pac::Peripherals::take().unwrap();
let _core = pac::CorePeripherals::take().unwrap();

let _clocks = GenericClockController::with_external_32kosc(
peripherals.GCLK,
&mut peripherals.PM,
&mut peripherals.SYSCTRL,
&mut peripherals.NVMCTRL,
);

// Initialize DMA Controller
let dmac = DmaController::init(peripherals.DMAC, &mut peripherals.PM);

// Turn dmac into an async controller
let mut dmac = dmac.into_future(crate::Irqs);
// Get individual handles to DMA channels
let channels = dmac.split();

// Initialize DMA Channel 0
let mut channel = channels.0.init(PriorityLevel::LVL0);

let mut source = [0xff; 500];
let mut dest = [0x0; 500];

defmt::info!(
"Launching a DMA transfer.\n\tSource: {}\n\tDestination: {}",
&source,
&dest
);

channel
.transfer_future(
&mut source,
&mut dest,
TriggerSource::DISABLE,
TriggerAction::BLOCK,
)
.await
.unwrap();

defmt::info!(
"Finished DMA transfer.\n\tSource: {}\n\tDestination: {}",
&source,
&dest
);

loop {
cortex_m::asm::wfi();
}
}
60 changes: 60 additions & 0 deletions boards/feather_m0/examples/async_eic.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#![no_std]
#![no_main]

use defmt_rtt as _;
use panic_probe as _;

use bsp::pac;
use bsp::{hal, pin_alias};
use feather_m0 as bsp;
use hal::{
clock::{enable_internal_32kosc, ClockGenId, ClockSource, GenericClockController},
ehal::digital::v2::ToggleableOutputPin,
eic::{
pin::{ExtInt2, Sense},
EIC,
},
gpio::{Pin, PullUpInterrupt},
};

atsamd_hal::bind_interrupts!(struct Irqs {
EIC => atsamd_hal::eic::InterruptHandler;
});

#[embassy_executor::main]
async fn main(_s: embassy_executor::Spawner) {
let mut peripherals = pac::Peripherals::take().unwrap();
let _core = pac::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::new(peripherals.PORT);
let mut red_led: bsp::RedLed = pin_alias!(pins.red_led).into();

let _internal_clock = clocks
.configure_gclk_divider_and_source(ClockGenId::GCLK2, 1, ClockSource::OSC32K, false)
.unwrap();
clocks.configure_standby(ClockGenId::GCLK2, true);

enable_internal_32kosc(&mut peripherals.SYSCTRL);

// Configure a clock for the EIC peripheral
let gclk2 = clocks.get_gclk(ClockGenId::GCLK2).unwrap();
let eic_clock = clocks.eic(&gclk2).unwrap();

let mut eic = EIC::init(&mut peripherals.PM, eic_clock, peripherals.EIC).into_future(Irqs);
let button: Pin<_, PullUpInterrupt> = pins.d10.into();
let mut extint = ExtInt2::new(button, &mut eic);
extint.enable_interrupt_wake();

loop {
// Here we show straight falling edge detection without
extint.wait(Sense::FALL).await;
defmt::info!("Falling edge detected");
red_led.toggle().unwrap();
}
}
77 changes: 77 additions & 0 deletions boards/feather_m0/examples/async_i2c.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#![no_std]
#![no_main]

use defmt_rtt as _;
use panic_probe as _;

use bsp::hal;
use bsp::pac;
use feather_m0 as bsp;
use fugit::MillisDuration;
use hal::{
clock::GenericClockController,
dmac::{DmaController, PriorityLevel},
prelude::*,
sercom::{i2c, Sercom3},
};
use rtic_monotonics::systick::Systick;

atsamd_hal::bind_interrupts!(struct Irqs {
SERCOM3 => atsamd_hal::sercom::i2c::InterruptHandler<Sercom3>;
DMAC => atsamd_hal::dmac::InterruptHandler;
});

#[embassy_executor::main]
async fn main(_s: embassy_executor::Spawner) {
let mut peripherals = pac::Peripherals::take().unwrap();
let _core = pac::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::new(peripherals.PORT);

// Take SDA and SCL
let (sda, scl) = (pins.sda, pins.scl);

// Initialize DMA Controller
let dmac = DmaController::init(peripherals.DMAC, &mut peripherals.PM);

// Turn dmac into an async controller
let mut dmac = dmac.into_future(Irqs);
// Get individual handles to DMA channels
let channels = dmac.split();

// Initialize DMA Channel 0
let channel0 = channels.0.init(PriorityLevel::LVL0);

let gclk0 = clocks.gclk0();
let sercom3_clock = &clocks.sercom3_core(&gclk0).unwrap();
let pads = i2c::Pads::new(sda, scl);
let mut i2c = i2c::Config::new(
&peripherals.PM,
peripherals.SERCOM3,
pads,
sercom3_clock.freq(),
)
.baud(100.kHz())
.enable()
.into_future(Irqs)
.with_dma_channel(channel0);

loop {
defmt::info!("Sending 0x00 to I2C device...");
// This test is based on the BMP388 barometer. Feel free to use any I2C
// peripheral you have on hand.
i2c.write(0x76, &[0x00]).await.unwrap();

let mut buffer = [0xff; 4];
i2c.read(0x76, &mut buffer).await.unwrap();
defmt::info!("Read buffer: {:#x}", buffer);
Systick::delay(MillisDuration::<u32>::from_ticks(500).convert()).await;
}
}
Loading

0 comments on commit bd3538f

Please sign in to comment.