rmicrobit/display/doc_example.rs
1//! a complete working example of the display system.
2//!
3//! This requires `cortex-m-rtfm` v0.5.
4//!
5//! It uses `TIMER1` to drive the display, and `RTC0` to update a simple
6//! animated image.
7//!
8//! This code is also available as `examples/heartbeat.rs`.
9//!
10//! ```
11//! #![no_main]
12//! #![no_std]
13//!
14//! extern crate panic_semihosting;
15//!
16//! use rtfm::app;
17//! use rmicrobit::nrf51;
18//! use rmicrobit::nrf51_hal::lo_res_timer::{LoResTimer, FREQ_16HZ};
19//! use rmicrobit::prelude::*;
20//! use rmicrobit::display::{DisplayPort, MicrobitDisplay, MicrobitFrame};
21//! use rmicrobit::gpio::PinsByKind;
22//! use rmicrobit::graphics::image::GreyscaleImage;
23//!
24//! fn heart_image(inner_brightness: u8) -> GreyscaleImage {
25//! let b = inner_brightness;
26//! GreyscaleImage::new(&[
27//! [0, 7, 0, 7, 0],
28//! [7, b, 7, b, 7],
29//! [7, b, b, b, 7],
30//! [0, 7, b, 7, 0],
31//! [0, 0, 7, 0, 0],
32//! ])
33//! }
34//!
35//! #[app(device = rmicrobit::nrf51, peripherals = true)]
36//! const APP: () = {
37//!
38//! struct Resources {
39//! display: MicrobitDisplay<nrf51::TIMER1>,
40//! anim_timer: LoResTimer<nrf51::RTC0>,
41//! }
42//!
43//! #[init]
44//! fn init(cx: init::Context) -> init::LateResources {
45//! let p: nrf51::Peripherals = cx.device;
46//!
47//! // Starting the low-frequency clock (needed for RTC to work)
48//! p.CLOCK.tasks_lfclkstart.write(|w| unsafe { w.bits(1) });
49//! while p.CLOCK.events_lfclkstarted.read().bits() == 0 {}
50//! p.CLOCK.events_lfclkstarted.reset();
51//!
52//! let mut rtc0 = LoResTimer::new(p.RTC0);
53//! // 16Hz; 62.5ms period
54//! rtc0.set_frequency(FREQ_16HZ);
55//! rtc0.enable_tick_event();
56//! rtc0.enable_tick_interrupt();
57//! rtc0.start();
58//!
59//! let PinsByKind {display_pins, ..} = p.GPIO.split_by_kind();
60//! let display_port = DisplayPort::new(display_pins);
61//! let display = MicrobitDisplay::new(display_port, p.TIMER1);
62//!
63//! init::LateResources {
64//! display : display,
65//! anim_timer : rtc0,
66//! }
67//! }
68//!
69//! #[task(binds = TIMER1, priority = 2,
70//! resources = [display])]
71//! fn timer1(cx: timer1::Context) {
72//! cx.resources.display.handle_event();
73//! }
74//!
75//! #[task(binds = RTC0, priority = 1,
76//! resources = [anim_timer, display])]
77//! fn rtc0(mut cx: rtc0::Context) {
78//! static mut FRAME: MicrobitFrame = MicrobitFrame::const_default();
79//! static mut STEP: u8 = 0;
80//!
81//! &cx.resources.anim_timer.clear_tick_event();
82//!
83//! let inner_brightness = match *STEP {
84//! 0..=8 => 9-*STEP,
85//! 9..=12 => 0,
86//! _ => unreachable!()
87//! };
88//!
89//! FRAME.set(&mut heart_image(inner_brightness));
90//! cx.resources.display.lock(|display| {
91//! display.set_frame(FRAME);
92//! });
93//!
94//! *STEP += 1;
95//! if *STEP == 13 {*STEP = 0};
96//! }
97//!
98//! };
99//!
100//! ```