2023-04-14 21:53:56 +02:00
|
|
|
#![no_std]
|
|
|
|
#![no_main]
|
|
|
|
|
2024-04-11 00:00:38 +02:00
|
|
|
use rtic_monotonics::rp2040::prelude::*;
|
|
|
|
|
|
|
|
rp2040_timer_monotonic!(Mono);
|
|
|
|
|
|
|
|
#[rtic::app(device = rp_pico::hal::pac)]
|
2023-04-14 21:53:56 +02:00
|
|
|
mod app {
|
2024-04-11 00:00:38 +02:00
|
|
|
use super::*;
|
|
|
|
|
2023-04-14 21:53:56 +02:00
|
|
|
use rp_pico::hal::{
|
2024-04-11 00:00:38 +02:00
|
|
|
clocks,
|
|
|
|
gpio::{
|
|
|
|
self,
|
|
|
|
bank0::{Gpio2, Gpio25, Gpio3},
|
2024-04-21 12:46:29 +02:00
|
|
|
FunctionSio, PullNone, PullUp, SioOutput,
|
2024-04-11 00:00:38 +02:00
|
|
|
},
|
2023-04-14 21:53:56 +02:00
|
|
|
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 panic_probe as _;
|
|
|
|
|
|
|
|
type I2CBus = I2C<
|
|
|
|
pac::I2C1,
|
|
|
|
(
|
2024-04-11 00:00:38 +02:00
|
|
|
gpio::Pin<Gpio2, gpio::FunctionI2C, PullUp>,
|
|
|
|
gpio::Pin<Gpio3, gpio::FunctionI2C, PullUp>,
|
2023-04-14 21:53:56 +02:00
|
|
|
),
|
|
|
|
>;
|
|
|
|
|
|
|
|
#[shared]
|
|
|
|
struct Shared {}
|
|
|
|
|
|
|
|
#[local]
|
|
|
|
struct Local {
|
2024-04-21 12:46:29 +02:00
|
|
|
led: gpio::Pin<Gpio25, FunctionSio<SioOutput>, PullNone>,
|
2023-04-14 21:53:56 +02:00
|
|
|
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) {
|
|
|
|
// Configure the clocks, watchdog - The default is to generate a 125 MHz system clock
|
2024-04-11 00:00:38 +02:00
|
|
|
Mono::start(ctx.device.TIMER, &mut ctx.device.RESETS); // default rp2040 clock-rate is 125MHz
|
2023-04-14 21:53:56 +02:00
|
|
|
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,
|
|
|
|
);
|
2024-04-11 00:00:38 +02:00
|
|
|
let mut led = gpioa
|
|
|
|
.led
|
|
|
|
.into_pull_type::<PullNone>()
|
|
|
|
.into_push_pull_output();
|
2023-04-14 21:53:56 +02:00
|
|
|
led.set_low().unwrap();
|
|
|
|
|
|
|
|
// Init I2C pins
|
2024-04-21 12:46:29 +02:00
|
|
|
let sda_pin: gpio::Pin<_, gpio::FunctionI2C, _> = gpioa
|
2024-04-11 00:00:38 +02:00
|
|
|
.gpio2
|
|
|
|
.into_pull_up_disabled()
|
2024-04-21 12:46:29 +02:00
|
|
|
.reconfigure();
|
|
|
|
let scl_pin: gpio::Pin<_, gpio::FunctionI2C, _> = gpioa
|
2024-04-11 00:00:38 +02:00
|
|
|
.gpio3
|
|
|
|
.into_pull_up_disabled()
|
2024-04-21 12:46:29 +02:00
|
|
|
.reconfigure();
|
2023-04-14 21:53:56 +02:00
|
|
|
|
|
|
|
// 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) {
|
2023-04-17 07:43:37 +02:00
|
|
|
// Loop forever.
|
|
|
|
//
|
|
|
|
// It is important to remember that tasks that loop
|
|
|
|
// forever should have an `await` somewhere in that loop.
|
|
|
|
//
|
|
|
|
// Without the await, the task will never yield back to
|
|
|
|
// the async executor, which means that no other lower or
|
|
|
|
// equal priority task will be able to run.
|
|
|
|
loop {
|
|
|
|
// Flicker the built-in LED
|
|
|
|
_ = ctx.local.led.toggle();
|
2023-04-14 21:53:56 +02:00
|
|
|
|
2023-04-17 07:43:37 +02:00
|
|
|
// Congrats, you can use your i2c and have access to it here,
|
|
|
|
// now to do something with it!
|
2023-04-14 21:53:56 +02:00
|
|
|
|
2023-04-17 07:43:37 +02:00
|
|
|
// Delay for 1 second
|
2024-04-11 00:00:38 +02:00
|
|
|
Mono::delay(1000.millis()).await;
|
2023-04-17 07:43:37 +02:00
|
|
|
}
|
2023-04-14 21:53:56 +02:00
|
|
|
}
|
|
|
|
}
|