Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
d680c50
it works don't touch anything
stillinbeta Mar 11, 2025
9b6554e
blinky interrupt
stillinbeta Mar 25, 2025
b6c0818
Working embassy-interrupt implementation (for at least one board)
stillinbeta Mar 25, 2025
9d8472d
fmt and cleanup
stillinbeta Mar 25, 2025
9b8bdef
fix blinky interrupt example
stillinbeta Mar 25, 2025
60ce99a
cargo fmt (with line wrapping now)
stillinbeta Mar 25, 2025
be38cbd
Fmt and moving stuff
stillinbeta Mar 26, 2025
5dd855b
comments and lints
stillinbeta Mar 26, 2025
be28da0
Move initialising the embassy driver to a macro
stillinbeta Mar 27, 2025
f49b0cd
Comments and tidying for rtc modes
stillinbeta Mar 27, 2025
7e1a10d
Add embassy-time to crates.json
stillinbeta Mar 27, 2025
8609845
Require a token of rtc configuration
stillinbeta Mar 28, 2025
27dbdc1
lints and fmt
stillinbeta Mar 28, 2025
c03bd8c
Remove sync_wait!
stillinbeta Mar 28, 2025
244a38f
Completes rebase with `master`, using the correct version of `src/rtc…
kyp44 Jun 23, 2025
5815740
revert all pyportal changes for a clean HAL merge
stillinbeta May 21, 2026
0a359eb
maybe avoid race conditions?
stillinbeta May 21, 2026
a2b4e4b
bump time-queue-utils version
stillinbeta May 26, 2026
fa63f76
cargo fmt
stillinbeta May 26, 2026
f893b9a
try using embassy-sync's mutex?
stillinbeta May 27, 2026
3f1fd56
fix re-borrow
stillinbeta Aug 11, 2026
3fe6b82
Add pyportal examples back
stillinbeta May 21, 2026
276b635
pyportal changes for hal breaking changes
stillinbeta May 21, 2026
324a5bc
embassy-wifi wip
stillinbeta May 25, 2026
e9be002
Put defmt in a feature
stillinbeta May 25, 2026
68bc9a0
more embassy wip
stillinbeta May 25, 2026
5e969f5
don't loop forever????
stillinbeta Aug 12, 2026
e638c14
it's working....
stillinbeta Sep 5, 2026
80fcbdb
it's all working......
stillinbeta Sep 7, 2026
cc206f6
Move to embedded-io-* 0.7
stillinbeta Sep 7, 2026
c3f443d
Embassy Wifi now working!
stillinbeta Sep 7, 2026
2526574
use git nina
stillinbeta Sep 7, 2026
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
4 changes: 2 additions & 2 deletions boards/pyportal/.cargo/config.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# vim:ft=toml:
[target.thumbv7em-none-eabihf]
runner = "hf2 elf"
# runner = 'probe-rs run --chip ATSAMD51J20A'
# runner = "hf2 elf"
runner = 'probe-rs run --chip ATSAMD51J20A --speed=2000'

[build]
target = "thumbv7em-none-eabihf"
Expand Down
44 changes: 42 additions & 2 deletions boards/pyportal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ version = "0.7.5"
optional = true

[dependencies.atsamd-hal]
version = "0.21.0"
# TODO(stillinbeta): set to release version
path = "../../hal"
default-features = false

[dependencies.display-interface-parallel-gpio]
Expand All @@ -34,27 +35,58 @@ optional=true
version = "0.3.2"
optional = true

[dependencies.embassy-nina]
version = "0.1"
optional = true
features = []
git = "https://github.com/stillinbeta/embassy-nina.git"
rev = "ce3ecde85e0fdd0cfe81f40478f46322de099abf"

[dev-dependencies]
panic-halt = "0.2"
panic-semihosting = "0.5"
smart-leds = "~0.3"
usbd-serial = "0.2.2"
embedded-graphics = "0.8.1"
embassy-time = "0.5"
embassy-sync = "0.7.2"
critical-section = "1.2.0"
defmt-rtt = "1.2"
defmt = "1.1"
panic-probe = "1.0"
embedded-nal-async = "0.9.0"

[dev-dependencies.embassy-executor]
version = "0.10"
features = ["platform-cortex-m", "executor-thread"]

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

[dev-dependencies.cortex-m-semihosting]
version = "0.5"

[dev-dependencies.ws2812-timer-delay]
version = "~0.3"

[dev-dependencies.reqwless]
version = "0.14.0"
default-features = false
features = ["defmt"]

[features]
# ask the HAL to enable atsamd51j support
default = ["rt", "atsamd-hal/samd51j"]
dma = ["atsamd-hal/dma"]
default = ["rt", "atsamd-hal/samd51j", "atsamd-hal/undoc-features"]
rt = ["cortex-m-rt", "atsamd-hal/samd51j-rt"]
usb = ["atsamd-hal/usb", "usb-device"]
display = ["display-interface-parallel-gpio", "ili9341"]
use_semihosting = []
rtic = ["atsamd-hal/rtic"]
embassy-time = ["atsamd-hal/embassy-time"]
wifi = ["atsamd-hal/async", "embassy-nina"]
defmt = ["atsamd-hal/defmt", "embassy-nina/defmt"] # add defmt codegen link

# for cargo flash
[package.metadata]
Expand All @@ -73,3 +105,11 @@ name = "neopixel_rainbow"
[[example]]
name = "usb_echo"
required-features = ["usb"]

[[example]]
name = "embassy_timer"
required-features = ["embassy-time"]

[[example]]
name = "embassy_wifi"
required-features = ["wifi", "embassy-time", "defmt"]
4 changes: 4 additions & 0 deletions boards/pyportal/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,8 @@ fn main() {
println!("cargo:rerun-if-changed=memory.x");
}
println!("cargo:rerun-if-changed=build.rs");

if env::var_os("CARGO_FEATURE_DEFMT").is_some() {
println!("cargo::rustc-link-arg=-Tdefmt.x")
}
}
163 changes: 163 additions & 0 deletions boards/pyportal/examples/blinky_interrupt.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
//! Turn on and off with an LED
#![no_std]
#![no_main]

use core::{cell::RefCell, mem};

use atsamd_hal::ehal::digital::{OutputPin, StatefulOutputPin};
use bsp::{
pac::{interrupt, CorePeripherals, Interrupt, Peripherals},
pin_alias, RedLed,
};
use cortex_m::{asm, peripheral::NVIC};
use cortex_m_rt::entry;
use critical_section::Mutex;
use pyportal as bsp;
use rtt_target::rprintln;

use panic_semihosting as _;

macro_rules! sync_wait {
($mode0:expr, $register:ident) => {
while $mode0.syncbusy().read().$register().bit_is_set() {}
};
}

static BACKLIGHT_PIN: Mutex<RefCell<RedLed>> = Mutex::new(RefCell::new(unsafe { mem::zeroed() }));

#[entry]
fn main() -> ! {
rtt_target::rtt_init_print!();

let peripherals = Peripherals::take().unwrap();
let _core = CorePeripherals::take().unwrap();

let pins = bsp::Pins::new(peripherals.port);
let red_led: bsp::RedLed = pin_alias!(pins.red_led).into();

critical_section::with(|cs| {
let _ = BACKLIGHT_PIN.replace(cs, red_led);
BACKLIGHT_PIN.borrow_ref_mut(cs).set_low().unwrap();
});

rprintln!("starting up");

// enable global interrupts
unsafe {
NVIC::mask(Interrupt::RTC);
// core.NVIC.set_priority(Interrupt::RTC, 8);
cortex_m::interrupt::enable();
};

// use the 32k clock
peripherals
.osc32kctrl
.rtcctrl()
.write(|w| w.rtcsel().ulp32k());

let mode0 = peripherals.rtc.mode0();

// Run RTC when main chip is paused
mode0.dbgctrl().write(|w| w.dbgrun().set_bit());

// disable the clock
mode0.ctrla().write(|w| w.enable().clear_bit());
// write sync for RTC enable
sync_wait!(mode0, enable);

// trigger a reset
mode0.ctrla().modify(|_, w| w.swrst().set_bit());
// write sync reset
sync_wait!(mode0, swrst);

// set the mode
mode0.ctrla().modify(|_, w| w.mode().count32());

mode0.ctrla().modify(|_, w| {
// Use 32 bit counter
w.prescaler().div1();
// The COUNT register requires synchronization when reading.
// Disabling the synchronization will prevent reading valid values from the
// COUNT register.
w.countsync().set_bit();
w.matchclr().clear_bit();
w
});
// write sync for countsync
let init = mode0.count().read().count().bits();
sync_wait!(mode0, countsync);
// When CTRLA.COUNTSYNC is enabled, the first COUNT value is not correctly
// synchronized and thus it is a wrong value.

// clear flag
mode0.intflag().write(|w| w.cmp0().set_bit());

// wait for count to be ready
sync_wait!(mode0, count);
// read the current count
let count: u32 = mode0.count().read().count().bits();
// add 5 seconds
let next = count + (5 * 32_768);
rprintln!("count is {}, waking up at {}", count, next);

mode0.comp(0).write(|w| unsafe { w.comp().bits(next) });
// wait write

sync_wait!(mode0, comp0);

mode0.intflag().write(|w| w.cmp0().set_bit());
// enable interupt
mode0.intenset().write(|w| w.cmp0().set_bit());

// critical_section::with(|cs| {
// BACKLIGHT_PIN.borrow_ref_mut(cs).set_low();
// });

unsafe {
NVIC::unmask(Interrupt::RTC);
}

// Enable the RTC
mode0.ctrla().modify(|_, w| w.enable().set_bit());

// Block to wait for countsync to be correct
while mode0.count().read().count().bits() == init {}
// write sync for RTC enable
sync_wait!(mode0, enable);

loop {
asm::wfi();
}
}

#[interrupt]
fn RTC() {
// unsafe { NVIC::mask(Interrupt::RTC) };

critical_section::with(|_cs| {
let peripherals = unsafe { Peripherals::steal() };

let mode0 = peripherals.rtc.mode0();

// is this actually an RTC compare0 interrupt
if mode0.intflag().read().cmp0().bit_is_set() {
// clear the interrupt bit

critical_section::with(|cs| {
BACKLIGHT_PIN.borrow_ref_mut(cs).toggle().unwrap();
});

sync_wait!(mode0, count);
let count: u32 = mode0.count().read().count().bits();
// add 5 seconds
let next = count + (2 * 32_768);
rprintln!("count is {}, waking up at {}", count, next);

mode0.comp(0).write(|w| unsafe { w.comp().bits(next) });
// wait write
sync_wait!(mode0, comp0);
mode0.intflag().write(|w| w.cmp0().set_bit());
}
// unsafe { NVIC::unmask(Interrupt::RTC) };
})
}
52 changes: 52 additions & 0 deletions boards/pyportal/examples/embassy_timer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#![no_std]
#![no_main]

#[cfg(feature = "defmt")]
use {defmt_rtt as _, panic_probe as _};
#[cfg(feature = "use_semihosting")]
use panic_semihosting as _;

use bsp::{hal, pac, pin_alias};
use hal::{
clock::v2::{clock_system_at_reset, osculp32k::OscUlp32k, rtcosc::RtcOsc},
ehal::digital::StatefulOutputPin,
};
use pyportal as bsp;

use embassy_time::{Timer, Duration};



hal::embassy_time!(Driver);

#[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 red_led: bsp::RedLed = pin_alias!(pins.red_led).into();

// Select the 32khz source
let (_, clocks, tokens) = clock_system_at_reset(
peripherals.oscctrl,
peripherals.osc32kctrl,
peripherals.gclk,
peripherals.mclk,
&mut peripherals.nvmctrl,
);

let (osculp32k, _) = OscUlp32k::enable(tokens.osculp32k.osculp32k, clocks.osculp32k_base);

let (rtc, _) = RtcOsc::enable(tokens.rtcosc, osculp32k);

// SAFETY: not in a critical section

unsafe {
Driver::init(rtc);
}

loop {
red_led.toggle().unwrap();
Timer::after(Duration::from_millis(200)).await;
}
}
Loading
Loading