Skip to content

Instantly share code, notes, and snippets.

@a-gavin
Last active March 15, 2023 07:23
Show Gist options
  • Save a-gavin/ed1d0c492c69aad20e209ff241b5c594 to your computer and use it in GitHub Desktop.
Save a-gavin/ed1d0c492c69aad20e209ff241b5c594 to your computer and use it in GitHub Desktop.
Contrived RTIC Shared Resource Example
#![no_std]
#![no_main]
#[rtic::app(
device = rp_pico::hal::pac,
dispatchers = [TIMER_IRQ_1]
)]
mod app {
use rp_pico::XOSC_CRYSTAL_FREQ;
use rp_pico::hal::{
clocks,
gpio,
gpio::pin::bank0::{Gpio2, Gpio3, Gpio25},
gpio::pin::PushPullOutput,
I2C,
pac,
sio::Sio,
watchdog::Watchdog
};
use rp2040_monotonic::{
Rp2040Monotonic,
fugit::Duration,
};
use core::mem::MaybeUninit;
use embedded_hal::digital::v2::{OutputPin, ToggleableOutputPin};
use fugit::RateExtU32; // For .kHz() conversion funcs
use defmt::*;
use defmt_rtt as _;
use panic_probe as _;
const MONO_NUM: u32 = 1;
const MONO_DENOM: u32 = 1000000;
const ONE_SEC_TICKS: u64 = 1000000;
type I2CBus = I2C<pac::I2C1, (gpio::Pin<Gpio2, gpio::FunctionI2C>, gpio::Pin<Gpio3, gpio::FunctionI2C>)>;
#[monotonic(binds = TIMER_IRQ_0, default = true)]
type Rp2040Mono = Rp2040Monotonic;
#[shared]
struct Shared {}
#[local]
struct Local {
led: gpio::Pin<Gpio25, PushPullOutput>,
i2c: &'static mut I2CBus
}
#[init(local=[
i2c_ctx: MaybeUninit<I2CBus> = MaybeUninit::uninit()
])]
fn init(mut ctx: init::Context) -> (Shared, Local, init::Monotonics) {
debug!("Program init");
// Configure the clocks, watchdog - The default is to generate a 125 MHz system clock
let mut watchdog = Watchdog::new(ctx.device.WATCHDOG);
let clocks = clocks::init_clocks_and_plls(
XOSC_CRYSTAL_FREQ,
ctx.device.XOSC,
ctx.device.CLOCKS,
ctx.device.PLL_SYS,
ctx.device.PLL_USB,
&mut ctx.device.RESETS,
&mut watchdog,
)
.ok()
.unwrap();
// Init LED pin
let sio = Sio::new(ctx.device.SIO);
let gpioa = rp_pico::Pins::new(
ctx.device.IO_BANK0,
ctx.device.PADS_BANK0,
sio.gpio_bank0,
&mut ctx.device.RESETS,
);
let mut led = gpioa.led.into_push_pull_output();
led.set_low().unwrap();
// Init I2C pins
let sda_pin = gpioa.gpio2.into_mode::<gpio::FunctionI2C>();
let scl_pin = gpioa.gpio3.into_mode::<gpio::FunctionI2C>();
// Init I2C itself, using MaybeUninit (can someone help me explain what's going on here LOL)
let i2c_tmp: &'static mut _ = ctx.local.i2c_ctx.write(
I2C::i2c1(
ctx.device.I2C1,
sda_pin,
scl_pin,
100.kHz(),
&mut ctx.device.RESETS,
&clocks.system_clock
)
);
let mono = Rp2040Mono::new(ctx.device.TIMER);
debug!("Spawning heartbeat");
heartbeat::spawn().unwrap();
(
Shared {},
Local {
led: led,
i2c: i2c_tmp
},
init::Monotonics(mono)
)
}
#[task(local = [i2c, led])]
fn heartbeat(ctx: heartbeat::Context) {
// Flicker the built-in LED
debug!("Heartbeat");
_ = ctx.local.led.toggle();
// Congrats, you can use your i2c, now to do something with it!
// Re-spawn this task after 1 second
let one_second = Duration::<u64, MONO_NUM, MONO_DENOM>::from_ticks(ONE_SEC_TICKS);
heartbeat::spawn_after(one_second).unwrap();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment