#![allow(clippy::empty_loop)]
#![no_std]
#![no_main]
use stm32f4xx_hal as hal;
#[cfg(not(debug_assertions))]
use panic_halt as _;
#[cfg(debug_assertions)]
use panic_semihosting as _;
use cortex_m_rt::ExceptionFrame;
use cortex_m_rt::{entry, exception};
use embedded_graphics::{
mono_font::{ascii::FONT_5X8, MonoTextStyleBuilder},
pixelcolor::BinaryColor,
prelude::*,
text::Text,
};
use ssd1306::{prelude::*, I2CDisplayInterface, Ssd1306};
use hal::{i2c::I2c, pac, prelude::*};
use rand_core::RngCore;
use core::fmt;
use heapless::String;
pub const SCREEN_WIDTH: i32 = 128;
pub const SCREEN_HEIGHT: i32 = 64;
pub const FONT_HEIGHT: i32 = 8;
pub const VCENTER_PIX: i32 = (SCREEN_HEIGHT - FONT_HEIGHT) / 2;
pub const HINSET_PIX: i32 = 20;
#[entry]
fn main() -> ! {
if let (Some(dp), Some(cp)) = (
pac::Peripherals::take(),
cortex_m::peripheral::Peripherals::take(),
) {
let rcc = dp.RCC.constrain();
let clocks = rcc
.cfgr
.use_hse(8.MHz()) .sysclk(128.MHz())
.freeze();
let mut delay_source = cp.SYST.delay(&clocks);
let gpiob = dp.GPIOB.split();
let scl = gpiob.pb8.into_alternate().set_open_drain();
let sda = gpiob.pb9.into_alternate().set_open_drain();
let i2c = I2c::new(dp.I2C1, (scl, sda), 400.kHz(), &clocks);
let interface = I2CDisplayInterface::new(i2c);
let mut disp = Ssd1306::new(interface, DisplaySize128x64, DisplayRotation::Rotate0)
.into_buffered_graphics_mode();
disp.init().unwrap();
let mut rand_source = dp.RNG.constrain(&clocks);
let mut format_buf = String::<20>::new();
loop {
disp.clear();
let rand_val = rand_source.next_u32();
format_buf.clear();
if fmt::write(&mut format_buf, format_args!("{}", rand_val)).is_ok() {
let text_style = MonoTextStyleBuilder::new()
.font(&FONT_5X8)
.text_color(BinaryColor::On)
.build();
Text::new(&format_buf, Point::new(HINSET_PIX, VCENTER_PIX), text_style)
.draw(&mut disp)
.unwrap();
}
disp.flush().unwrap();
delay_source.delay_ms(100u8);
}
}
loop {}
}
#[exception]
unsafe fn HardFault(ef: &ExceptionFrame) -> ! {
panic!("{:#?}", ef);
}