You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
131 lines
3.3 KiB
Rust
131 lines
3.3 KiB
Rust
#![no_std]
|
|
#![no_main]
|
|
|
|
use panic_halt as _;
|
|
|
|
use fugit::RateExtU32;
|
|
|
|
use hal::i2c;
|
|
pub use sparkfun_pro_micro_rp2040::hal;
|
|
use ssd1306::{prelude::*, I2CDisplayInterface, Ssd1306};
|
|
|
|
use embedded_graphics::text::Text;
|
|
use embedded_graphics::{
|
|
mono_font::{ascii::FONT_10X20, MonoTextStyle},
|
|
pixelcolor::BinaryColor,
|
|
prelude::*,
|
|
text::Alignment,
|
|
};
|
|
|
|
use fugit::MicrosDurationU32;
|
|
use hal::gpio::bank0::{Gpio14, Gpio15};
|
|
use hal::gpio::Pin;
|
|
use hal::pac::I2C1;
|
|
use hal::timer::Alarm;
|
|
use hal::timer::Alarm0;
|
|
|
|
#[rtic::app(device = sparkfun_pro_micro_rp2040::hal::pac, peripherals = true)]
|
|
mod app {
|
|
|
|
const CHANGE_FREQUENCY_TICKS: u32 = 1000;
|
|
|
|
use super::*;
|
|
type Display = Ssd1306<
|
|
I2CInterface<
|
|
hal::I2C<
|
|
I2C1,
|
|
(
|
|
Pin<Gpio14, hal::gpio::Function<hal::gpio::I2C>>,
|
|
Pin<Gpio15, hal::gpio::Function<hal::gpio::I2C>>,
|
|
),
|
|
>,
|
|
>,
|
|
DisplaySize128x64,
|
|
ssd1306::mode::BufferedGraphicsMode<DisplaySize128x64>,
|
|
>;
|
|
|
|
#[shared]
|
|
struct Shared {
|
|
alarm: Alarm0,
|
|
}
|
|
|
|
#[local]
|
|
struct Local {
|
|
display: Display,
|
|
state: u8,
|
|
}
|
|
|
|
#[init()]
|
|
fn init(c: init::Context) -> (Shared, Local, init::Monotonics) {
|
|
let mut resets = c.device.RESETS;
|
|
|
|
let sio = hal::Sio::new(c.device.SIO);
|
|
let pins = rp2040_hal::gpio::Pins::new(
|
|
c.device.IO_BANK0,
|
|
c.device.PADS_BANK0,
|
|
sio.gpio_bank0,
|
|
&mut resets,
|
|
);
|
|
let mut timer = hal::Timer::new(c.device.TIMER, &mut resets);
|
|
let mut alarm = timer.alarm_0().unwrap();
|
|
let _ = alarm.schedule(MicrosDurationU32::from_ticks(CHANGE_FREQUENCY_TICKS));
|
|
alarm.enable_interrupt();
|
|
|
|
let scl = pins.gpio15.into_mode();
|
|
let sda = pins.gpio14.into_mode();
|
|
let i2c = i2c::I2C::i2c1(
|
|
c.device.I2C1,
|
|
sda,
|
|
scl,
|
|
100.kHz(),
|
|
&mut resets,
|
|
125_000_000.Hz(),
|
|
);
|
|
let interface = I2CDisplayInterface::new(i2c);
|
|
let mut display = Ssd1306::new(interface, DisplaySize128x64, DisplayRotation::Rotate0)
|
|
.into_buffered_graphics_mode();
|
|
display.init().unwrap();
|
|
|
|
display.flush().unwrap();
|
|
|
|
(
|
|
Shared { alarm },
|
|
Local { display, state: 0 },
|
|
init::Monotonics(),
|
|
)
|
|
}
|
|
|
|
#[task(binds = TIMER_IRQ_0, priority = 1, shared = [alarm], local = [display, state])]
|
|
fn tick(mut c: tick::Context) {
|
|
use numtoa::NumToA;
|
|
let display = c.local.display;
|
|
display.clear();
|
|
|
|
let mut buf = [0u8; 20];
|
|
let text = c.local.state.numtoa_str(10, &mut buf);
|
|
*c.local.state += 1;
|
|
|
|
Text::with_alignment(
|
|
text,
|
|
display.bounding_box().center(),
|
|
MonoTextStyle::new(&FONT_10X20, BinaryColor::On),
|
|
Alignment::Center,
|
|
)
|
|
.draw(display)
|
|
.unwrap();
|
|
display.flush().unwrap();
|
|
|
|
c.shared.alarm.lock(|a| {
|
|
a.clear_interrupt();
|
|
let _ = a.schedule(MicrosDurationU32::from_ticks(CHANGE_FREQUENCY_TICKS));
|
|
});
|
|
}
|
|
|
|
#[idle]
|
|
fn idle(_cx: idle::Context) -> ! {
|
|
loop {
|
|
cortex_m::asm::nop();
|
|
}
|
|
}
|
|
}
|