| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411 |
- #![no_main]
- #![no_std]
-
- mod board;
- mod assets {
- include!(concat!(env!("OUT_DIR"), "/assets.rs"));
- }
-
-
- use cortex_m_semihosting::{debug, hprintln};
- use mkl25z4_hal as hal;
- use panic_semihosting as _;
- use mkl25z4_hal::gpio::GpioExt;
- use mkl25z4_hal::spi::{Phase, Polarity, Spi};
- use mkl25z4_hal::time::{NonCopyableMonoTimer, U32Ext};
- use mkl25z4_hal::timer::{Timer, TimerInterrupt};
- use embedded_hal::digital::v2::OutputPin;
- use embedded_epd::{gui, Display};
- use embedded_epd as epd;
- use nb::block;
- use embedded_hal::timer::CountDown;
-
- use board::led;
-
- struct EPDTimer<Timer> {
- timer: Timer,
- }
-
- impl<Timer> CountDown for EPDTimer<Timer>
- where
- Timer: CountDown<Time = hal::time::Hertz>,
- {
- type Time = epd::Hertz;
-
- fn start<T>(&mut self, timeout: T)
- where
- T: Into<epd::Hertz>,
- {
- self.timer.start(hal::time::Hertz(timeout.into().0))
- }
-
- fn wait(&mut self) -> nb::Result<(), void::Void> {
- self.timer.wait()
- }
- }
-
- #[rtfm::app(device = mkl25z4_hal::mkl25z4, peripherals = true)]
- const APP: () = {
- struct Resources {
- }
-
- #[init]
- fn init(ctx: init::Context) {
- let mut sim = ctx.device.SIM;
- mkl25z4_hal::watchdog::disable(&mut sim);
- let clocks = mkl25z4_hal::clocks::init();
-
- let mut gpiob = ctx.device.GPIOB.split(&mut sim);
- let mut gpioc = ctx.device.GPIOC.split(&mut sim);
- let mut gpiod = ctx.device.GPIOD.split(&mut sim);
-
- let mut led = led::Led {
- red: gpiob.pb18.into_push_pull_output(&mut gpiob.pddr),
- green: gpiob.pb19.into_push_pull_output(&mut gpiob.pddr),
- blue: gpiod.pd1.into_push_pull_output(&mut gpiod.pddr),
- };
- //led::init(&p.device.PORTB, &p.device.GPIOB, &p.device.PORTD, &p.device.GPIOD, &p.device.SIM);
- led.set_color(true, true, true);
-
- /*for _ in 0..2 {
- time.delay_ms(1000);
- led.set_color(false, false, true);
- time.delay_ms(1000);
- led.set_color(false, true, false);
- }*/
-
- let mosi = gpioc.pc6.into_alternate(&mut gpioc.pddr);
- let miso = gpioc.pc7.into_alternate(&mut gpioc.pddr);
- let sck = gpioc.pc5.into_alternate(&mut gpioc.pddr);
- let mode = hal::spi::Mode {
- polarity: Polarity::IdleLow,
- phase: Phase::CaptureOnFirstTransition,
- };
- let spi0 = Spi::spi0(ctx.device.SPI0, mosi, miso, sck, mode, &mut sim);
-
- // Initialize the display.
- let busy = gpioc.pc3.into_floating_input(&mut gpioc.pddr);
- let mut reset = gpioc.pc2.into_push_pull_output(&mut gpioc.pddr);
- reset.set_high().unwrap();
- let mut data_cmd = gpioc.pc1.into_push_pull_output(&mut gpioc.pddr);
- data_cmd.set_high().unwrap();
- let mut cs = gpioc.pc0.into_push_pull_output(&mut gpioc.pddr);
- cs.set_high().unwrap();
-
- let t = EPDTimer {
- timer: Timer::pit(ctx.device.PIT, hal::time::Hertz(1), clocks, &mut sim),
- };
-
- let mut display = epd::gdew042z15::GDEW042Z15::new(spi0, busy, reset, data_cmd, cs, t);
- block!(display.init()).ok();
- block!(display.start_frame()).ok();
- led.set_color(false, false, false);
- let layout = gui::Layout::new(
- 400,
- 300,
- gui::VerticalSplit::expand_bottom(
- 24,
- gui::Fill::new(epd::Color::White),
- gui::VerticalSplit::expand_bottom(
- 1,
- gui::Fill::new(epd::Color::Black),
- gui::HorizontalSplit::expand_right(
- 48,
- gui::Fill::new(epd::Color::White),
- //gui::Image::new(&assets::ALARM_CLOCK_36),
- gui::HorizontalSplit::expand_right(
- 1,
- gui::Fill::new(epd::Color::Black),
- gui::HorizontalSplit::expand_left(
- 49,
- gui::VerticalSplit::expand_bottom(
- 132,
- gui::Align::new(
- gui::HorizontalAlign::Center,
- gui::VerticalAlign::Top,
- gui::Text::new("12:34", &assets::ROBOTO_100),
- ),
- gui::Align::new(
- gui::HorizontalAlign::Center,
- gui::VerticalAlign::Top,
- gui::HorizontalSplit::expand_right(
- 36,
- gui::Image::new(&assets::ALARM_CLOCK_36),
- gui::Text::new("Do. 8:00", &assets::ROBOTO_30),
- ),
- ),
- ),
- gui::Fill::new(epd::Color::White),
- ),
- ),
- ),
- ),
- ),
- );
- let mut row_buffer = [0u8; 400 / 8];
- layout.render(&mut display, &mut row_buffer);
- display.end_frame();
- led.set_color(true, true, false);
-
- let (_, _, _, _, _, mut t) = display.destroy();
-
- /*let pit_ = display.time.deactivate(&mut p.device.SIM);*/
- t.start(epd::Hertz(1));
- t.timer.enable_interrupt();
- let mut nvic = ctx.core.NVIC;
- nvic.enable(mkl25z4::Interrupt::PIT);
-
- led.set_color(true, true, true);
- }
-
- #[idle]
- fn idle(_cx: idle::Context) -> ! {
- // Sleep
- loop {
- // wfi needs to be disabled for GDB
- /*// add some side effect to prevent this from turning into a UDF instruction
- // see rust-lang/rust#28728 for details
- atomic::compiler_fence(Ordering::SeqCst);*/
- cortex_m::asm::wfi();
- }
- }
- };
-
- /*#![no_main]
- #![no_std]
-
- extern crate cortex_m;
- extern crate cortex_m_rt as rt;
- //extern crate cortex_m_rtfm as rtfm;
- extern crate embedded_epd as epd;
- extern crate embedded_hal;
- extern crate mkl25z4;
- extern crate mkl25z4_hal as hal;
- //extern crate panic_halt;
- extern crate panic_semihosting;
- extern crate void;
- #[macro_use(block)]
- extern crate nb;
- extern crate bme280;
-
- mod board;
- mod assets {
- include!(concat!(env!("OUT_DIR"), "/assets.rs"));
- }
-
- use bme280::BME280;
- use board::led;
- use embedded_hal::prelude::*;
- use embedded_hal::timer::CountDown;
- use epd::{gui, Display};
- use hal::gpio::GpioExt;
- use hal::i2c::BlockingI2c;
- use hal::spi::{Phase, Polarity, Spi};
- use hal::time::{NonCopyableMonoTimer, U32Ext};
- use hal::timer::{Timer, TimerInterrupt};
- use rt::pre_init;
- use rtfm::{app, Threshold};
-
- /*use core::sync::atomic;
- use core::sync::atomic::Ordering;*/
-
- struct EPDTimer<Timer> {
- timer: Timer,
- }
-
- impl<Timer> CountDown for EPDTimer<Timer>
- where
- Timer: CountDown<Time = hal::time::Hertz>,
- {
- type Time = epd::Hertz;
-
- fn start<T>(&mut self, timeout: T)
- where
- T: Into<epd::Hertz>,
- {
- self.timer.start(hal::time::Hertz(timeout.into().0))
- }
-
- fn wait(&mut self) -> nb::Result<(), void::Void> {
- self.timer.wait()
- }
- }
-
- #[pre_init]
- unsafe fn disable_watchdog() {
- use mkl25z4::SIM;
- (*SIM::ptr()).copc.write(|w| w.bits(0));
- }
-
- app! {
- device: mkl25z4,
-
- resources: {
- static ON: bool = false;
- static pit: hal::timer::Timer<mkl25z4::PIT>;
- static rgb_led: led::Led;
- },
-
- tasks: {
- PIT: {
- path: pit_handler,
- resources: [pit, rgb_led, ON],
- },
- },
- }
-
- fn init(mut p: init::Peripherals, _r: init::Resources) -> init::LateResources {
- mkl25z4_hal::watchdog::disable(&mut p.device.SIM);
- let clocks = mkl25z4_hal::clocks::init();
- //let time = hal::time::MonoTimer::new(p.device.PIT, clocks, &mut p.device.SIM);
-
- let mut gpiob = p.device.GPIOB.split(&mut p.device.SIM);
- let mut gpioc = p.device.GPIOC.split(&mut p.device.SIM);
- let mut gpiod = p.device.GPIOD.split(&mut p.device.SIM);
-
- let mut led = led::Led {
- red: gpiob.pb18.into_push_pull_output(&mut gpiob.pddr),
- green: gpiob.pb19.into_push_pull_output(&mut gpiob.pddr),
- blue: gpiod.pd1.into_push_pull_output(&mut gpiod.pddr),
- };
- //led::init(&p.device.PORTB, &p.device.GPIOB, &p.device.PORTD, &p.device.GPIOD, &p.device.SIM);
- led.set_color(true, true, true);
-
- let timer = NonCopyableMonoTimer::new(p.device.PIT, clocks, &mut p.device.SIM);
- let scl = gpiob.pb2.into_alternate(&mut gpiob.pddr);
- let sda = gpiob.pb3.into_alternate(&mut gpiob.pddr);
- let i2c0 = BlockingI2c::i2c0(
- p.device.I2C0,
- sda,
- scl,
- 100000u32.hz(),
- timer,
- clocks,
- &mut p.device.SIM,
- 1000000,
- 10,
- 1000000,
- 1000000,
- );
- let mut bme280 = BME280::new_primary(i2c0);
- let (_, _, _, timer) = i2c0.free(&mut p.device.SIM);
- let pit_ = timer.free(&mut p.device.SIM);
-
- /*for _ in 0..2 {
- time.delay_ms(1000);
- led.set_color(false, false, true);
- time.delay_ms(1000);
- led.set_color(false, true, false);
- }*/
-
- let mosi = gpioc.pc6.into_alternate(&mut gpioc.pddr);
- let miso = gpioc.pc7.into_alternate(&mut gpioc.pddr);
- let sck = gpioc.pc5.into_alternate(&mut gpioc.pddr);
- let mode = hal::spi::Mode {
- polarity: Polarity::IdleLow,
- phase: Phase::CaptureOnFirstTransition,
- };
- let spi0 = Spi::spi0(p.device.SPI0, mosi, miso, sck, mode, &mut p.device.SIM);
-
- // Initialize the display.
- let busy = gpioc.pc3.into_floating_input(&mut gpioc.pddr);
- let mut reset = gpioc.pc2.into_push_pull_output(&mut gpioc.pddr);
- reset.set_high();
- let mut data_cmd = gpioc.pc1.into_push_pull_output(&mut gpioc.pddr);
- data_cmd.set_high();
- let mut cs = gpioc.pc0.into_push_pull_output(&mut gpioc.pddr);
- cs.set_high();
-
- let t = EPDTimer {
- timer: Timer::pit(pit_, hal::time::Hertz(1), clocks, &mut p.device.SIM),
- };
-
- let mut display = epd::gdew042z15::GDEW042Z15::new(spi0, busy, reset, data_cmd, cs, t);
- block!(display.init()).ok();
- block!(display.start_frame()).ok();
- led.set_color(false, false, false);
- let layout = gui::Layout::new(
- 400,
- 300,
- gui::VerticalSplit::expand_bottom(
- 24,
- gui::Fill::new(epd::Color::White),
- gui::VerticalSplit::expand_bottom(
- 1,
- gui::Fill::new(epd::Color::Black),
- gui::HorizontalSplit::expand_right(
- 48,
- gui::Fill::new(epd::Color::White),
- //gui::Image::new(&assets::ALARM_CLOCK_36),
- gui::HorizontalSplit::expand_right(
- 1,
- gui::Fill::new(epd::Color::Black),
- gui::HorizontalSplit::expand_left(
- 49,
- gui::VerticalSplit::expand_bottom(
- 132,
- gui::Align::new(
- gui::HorizontalAlign::Center,
- gui::VerticalAlign::Top,
- gui::Text::new("12:34", &assets::ROBOTO_100),
- ),
- gui::Align::new(
- gui::HorizontalAlign::Center,
- gui::VerticalAlign::Top,
- gui::HorizontalSplit::expand_right(
- 36,
- gui::Image::new(&assets::ALARM_CLOCK_36),
- gui::Text::new("Do. 8:00", &assets::ROBOTO_30),
- ),
- ),
- ),
- gui::Fill::new(epd::Color::White),
- ),
- ),
- ),
- ),
- ),
- );
- let mut row_buffer = [0u8; 400 / 8];
- layout.render(&mut display, &mut row_buffer);
- display.end_frame();
- led.set_color(true, true, false);
-
- let (_, _, _, _, _, mut t) = display.destroy();
-
- /*let pit_ = display.time.deactivate(&mut p.device.SIM);*/
- t.start(epd::Hertz(1));
- t.timer.enable_interrupt();
- p.core.NVIC.enable(mkl25z4::Interrupt::PIT);
-
- led.set_color(true, true, true);
-
- init::LateResources {
- pit: t.timer,
- rgb_led: led,
- }
- }
-
- fn idle() -> ! {
- // Sleep
- loop {
- // wfi needs to be disabled for GDB
- /*// add some side effect to prevent this from turning into a UDF instruction
- // see rust-lang/rust#28728 for details
- atomic::compiler_fence(Ordering::SeqCst);*/
- rtfm::wfi();
- }
- }
-
- // TASKS
-
- // Toggle the state of the LED
- fn pit_handler(_t: &mut Threshold, mut r: PIT::Resources) {
- if *r.ON {
- r.rgb_led.set_color(false, false, true);
- } else {
- r.rgb_led.set_color(true, false, false);
- }
- r.pit.wait().ok();
- *r.ON = !*r.ON;
- }*/
|