Module nonblocking

Source
Expand description

Non-blocking support for the 5×5 LED display.

Together with tiny-led-matrix, this module provides:

  • support for driving the LED display from a timer interrupt
  • ten levels of brightness for each LED
  • simple 5×5 greyscale and black-and-white image types.

The module doesn’t define interrupt handlers directly; instead it provides a function to be called from a timer interrupt. It knows how to program one of the micro:bit’s timers to provide that interrupt.

§Example

This shows general usage but is not a working example. For a working exaple see display_nonblocking.

use microbit::{
    Board,
    hal,
    display::nonblocking::{Display, GreyscaleImage},
};
use embedded_hal::delay::DelayNs;

let board = Board::take().unwrap();

let mut display = Display::new(board.TIMER1, board.display_pins);

// in your main function
{
    let mut timer2 = hal::Timer::new(board.TIMER0);
    loop {
        display.show(&GreyscaleImage::new(&[
            [0, 7, 0, 7, 0],
            [7, 0, 7, 0, 7],
            [7, 0, 0, 0, 7],
            [0, 7, 0, 7, 0],
            [0, 0, 7, 0, 0],
        ]));
        timer2.delay_ms(1000);

        display.clear();
        timer2.delay_ms(1000);
    }
}

// in a timer interrupt
{
    display.handle_display_event();
}

§Coordinate system

The LEDs are identified using (x,y) coordinates as follows:

(0,0) ... (4,0)
 ...  ...  ...
(0,4) ... (4,4)

where the ‘bottom’ (x,4) of the board is the edge connector.

§Greyscale model

LED brightness levels are described using a scale from 0 (off) to 9 (brightest) inclusive.

These are converted to time slices using the same timings as used by the micro:bit MicroPython port (this is different to the 0 to 255 scale used by the micro:bit runtime).

The time slice for each level above 1 is approximately 1.9× the slice for the previous level.

An LED with brightness 9 is lit for one fifth of the time.

§Images

An image is a type that implements the tiny_led_matrix::Render trait. Two image types are provided:

  • GreyscaleImage, allowing all 9 levels (using one byte for each LED)
  • BitImage, allowing only ‘on’ and ‘off’ (using five bytes)

§Display

A Display instance controls the LEDs and programs a timer. There should normally be a single Display instance in the program. It is a wrapper around tiny_led_matrix::Display to expose an API similar to the blocking API.

§Frames

Internally types implementing Render aren’t used directly with the Display; instead they’re used to update a MicrobitFrame instance which is in turn passed to the tiny_led_matrix::Display.

A MicrobitFrame instance is a ‘compiled’ representation of a 5×5 greyscale image, in a form that’s more directly usable by the display code.

This is exposed in the public API so that you can construct the MicrobitFrame representation in code running at a low priority. Then only Display::show_frame() has to be called in code that can’t be interrupted by the display timer.

§Timer integration

The Display expects to control a single timer. It can use the micro:bit’s TIMER0, TIMER1, or TIMER2.

For the micro:bit v1 this uses a 6ms period to light each of the three internal LED rows, so that the entire display is updated every 18ms.

For the micro:bit v2 this uses a 3ms period to light each of the five internal LED rows, so that the entire display is updated every 15ms.

When rendering greyscale images, the Display requests extra interrupts within each 6ms or 3ms period. It only requests interrupts for the greyscale levels which are actually required for what’s currently being displayed.

§Technical details

The timer is set to 16-bit mode, using a 62.5kHz or 135Khz clock (16 µs or 8µs ticks). It resets every 375 ticks.

§Usage

Choose a timer to drive the display from (TIMER0, TIMER1, or TIMER2).

When your program starts:

In an interrupt handler for the timer call .handle_display_event()

To change what’s displayed; pass an image (GreyscaleImage or BitImage) to Display::show.

You can call show() at any time, so long as you’re not interrupting, or interruptable by, Display::handle_display_event().

See display_rtic or display_nonblocking example for a complete working example.

Structs§

BitImage
A 5×5 image supporting only two levels of brightness (on and off).
Display
Non-blocking interface to the on board 5x5 LED display
GreyscaleImage
A 5×5 image supporting the full range of brightnesses for each LED.
MicrobitFrame
A ‘Compiled’ representation of a 5×5 image to be displayed.

Constants§

MAX_BRIGHTNESS
The maximum brightness level for greyscale images (ie, 9; the minimum is 0).

Traits§

Frame
A ‘Compiled’ representation of an image to be displayed.