diff options
Diffstat (limited to 'examples/rp2040_local_i2c_init/src/main.rs')
| -rw-r--r-- | examples/rp2040_local_i2c_init/src/main.rs | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/examples/rp2040_local_i2c_init/src/main.rs b/examples/rp2040_local_i2c_init/src/main.rs new file mode 100644 index 0000000..6776892 --- /dev/null +++ b/examples/rp2040_local_i2c_init/src/main.rs @@ -0,0 +1,115 @@ +#![no_std] +#![no_main] +#![feature(type_alias_impl_trait)] + +#[rtic::app( + device = rp_pico::hal::pac, + dispatchers = [TIMER_IRQ_1] +)] +mod app { + use rp_pico::hal::{ + clocks, gpio, + gpio::pin::bank0::{Gpio2, Gpio25, Gpio3}, + gpio::pin::PushPullOutput, + pac, + sio::Sio, + watchdog::Watchdog, + I2C, + }; + use rp_pico::XOSC_CRYSTAL_FREQ; + + use core::mem::MaybeUninit; + use embedded_hal::digital::v2::{OutputPin, ToggleableOutputPin}; + use fugit::RateExtU32; + use rtic_monotonics::rp2040::*; + + use panic_probe as _; + + type I2CBus = I2C< + pac::I2C1, + ( + gpio::Pin<Gpio2, gpio::FunctionI2C>, + gpio::Pin<Gpio3, gpio::FunctionI2C>, + ), + >; + + #[shared] + struct Shared {} + + #[local] + struct Local { + led: gpio::Pin<Gpio25, PushPullOutput>, + i2c: &'static mut I2CBus, + } + + #[init(local=[ + // Task local initialized resources are static + // Here we use MaybeUninit to allow for initialization in init() + // This enables its usage in driver initialization + i2c_ctx: MaybeUninit<I2CBus> = MaybeUninit::uninit() + ])] + fn init(mut ctx: init::Context) -> (Shared, Local) { + // Initialize the interrupt for the RP2040 timer and obtain the token + // proving that we have. + let rp2040_timer_token = rtic_monotonics::create_rp2040_monotonic_token!(); + // Configure the clocks, watchdog - The default is to generate a 125 MHz system clock + Timer::start(ctx.device.TIMER, &mut ctx.device.RESETS, rp2040_timer_token); // default rp2040 clock-rate is 125MHz + 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 to overwrite the previously + // uninitialized i2c_ctx variable without dropping its value + // (i2c_ctx definined in init local resources above) + 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, + )); + + // Spawn heartbeat task + heartbeat::spawn().ok(); + + // Return resources and timer + (Shared {}, Local { led, i2c: i2c_tmp }) + } + + #[task(local = [i2c, led])] + async fn heartbeat(ctx: heartbeat::Context) { + // Flicker the built-in LED + _ = ctx.local.led.toggle(); + + // Congrats, you can use your i2c and have access to it here, + // now to do something with it! + + // Re-spawn this task after 1 second + Timer::delay(1000.millis()).await; + } +} |
