Skip to content

Commit 623164e

Browse files
Mark Shannondpgeorge
authored andcommitted
Minimise work in display rendering by only rendering used brightness's.
1 parent 917582c commit 623164e

File tree

4 files changed

+54
-34
lines changed

4 files changed

+54
-34
lines changed

inc/microbit/microbitdisplay.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
typedef struct _microbit_display_obj_t {
44
mp_obj_base_t base;
5+
/* boolean histogram of brightness in buffer */
6+
mp_int_t brightnesses;
57
mp_int_t image_buffer[5][5];
68
} microbit_display_obj_t;
79

source/microbit/main.cpp

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,13 @@ extern "C" {
44
void mp_run(void);
55

66
void microbit_display_tick(void);
7-
}
8-
9-
static void ticker(void) {
10-
/* Make sure we call the DAL ticker function */
11-
uBit.systemTick();
12-
/* Then update Python display */
13-
microbit_display_tick();
7+
148
}
159

1610
void app_main() {
17-
/*
11+
1812
// debugging: print memory layout
13+
/*
1914
extern uint32_t __data_start__, __data_end__;
2015
extern uint32_t __bss_start__, __bss_end__;
2116
extern uint32_t __HeapLimit, __StackLimit, __StackTop;
@@ -29,9 +24,6 @@ void app_main() {
2924
*/
3025

3126
currentFiber->flags |= MICROBIT_FIBER_FLAG_DO_NOT_PAGE;
32-
33-
/* Hijack the DAL system ticker */
34-
uBit.systemTicker.attach(ticker, MICROBIT_DISPLAY_REFRESH_PERIOD);
3527

3628

3729
while (1) {

source/microbit/microbitdisplay.cpp

Lines changed: 46 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,13 @@ void microbit_display_print(microbit_display_obj_t *display, microbit_image_obj_
4040
mp_int_t w = min(image->width(), 5);
4141
mp_int_t h = min(image->height(), 5);
4242
mp_int_t x = 0;
43+
mp_int_t brightnesses = 0;
4344
for (; x < w; ++x) {
4445
mp_int_t y = 0;
4546
for (; y < h; ++y) {
46-
display->image_buffer[x][y] = image->getPixelValue(x, y);
47+
mp_int_t pix = image->getPixelValue(x, y);
48+
display->image_buffer[x][y] = pix;
49+
brightnesses |= (1 << pix);
4750
}
4851
for (; y < 5; ++y) {
4952
display->image_buffer[x][y] = 0;
@@ -54,6 +57,7 @@ void microbit_display_print(microbit_display_obj_t *display, microbit_image_obj_
5457
display->image_buffer[x][y] = 0;
5558
}
5659
}
60+
display->brightnesses = brightnesses;
5761
}
5862

5963
STATIC void do_synchronous_animation(microbit_display_obj_t *display, mp_obj_t iterable, mp_int_t delay, bool repeat);
@@ -110,7 +114,7 @@ static int async_delay = 1000;
110114
static int async_tick = 0;
111115
static int strobe_row = 0;
112116
static int strobe_mask = 0x20;
113-
static int minimum_brightness = 0;
117+
static int previous_brightness = 0;
114118
static Ticker renderTimer;
115119

116120

@@ -143,7 +147,7 @@ struct DisplayPoint {
143147

144148
#define NO_CONN 0
145149

146-
DisplayPoint display_map[MICROBIT_DISPLAY_COLUMN_COUNT][MICROBIT_DISPLAY_ROW_COUNT] = {
150+
static const DisplayPoint display_map[MICROBIT_DISPLAY_COLUMN_COUNT][MICROBIT_DISPLAY_ROW_COUNT] = {
147151
{{0,0}, {4,2}, {2,4}},
148152
{{2,0}, {0,2}, {4,4}},
149153
{{4,0}, {2,2}, {0,4}},
@@ -208,26 +212,35 @@ static void microbit_display_advance_row(void) {
208212
}
209213

210214
static const int render_timings[] =
211-
{ 0, /* Brightness, Duration */
212-
32, /* 1, 32 */
213-
32, /* 2, 64 */
214-
64, /* 3, 128 */
215-
128, /* 4, 256 */
216-
256, /* 5, 512 */
217-
480, /* 6, 992 */
218-
924, /* 7, 1916 */
219-
1784, /* 8, 3700 */
220-
/* Always on 9, 6000 */
215+
{ 0, /* Brightness*/
216+
32, /* 1 */
217+
64, /* 2 */
218+
128, /* 3 */
219+
256, /* 4 */
220+
512, /* 5 */
221+
992, /* 6 */
222+
1916, /* 7 */
223+
3700, /* 8 */
224+
/* Always on 9 */
221225
};
222226

227+
#define GREYSCALE_MASK ((1<<MAX_BRIGHTNESS)-2)
228+
223229
static void render_row() {
224-
230+
mp_int_t next_brightness = previous_brightness+1;
231+
mp_int_t brightnesses = microbit_display_obj.brightnesses;
232+
for (; next_brightness < MAX_BRIGHTNESS; ++next_brightness) {
233+
if ((1<< next_brightness) & brightnesses) {
234+
break;
235+
}
236+
}
225237
// Attach to timer
226-
if (minimum_brightness < MAX_BRIGHTNESS) {
227-
renderTimer.attach_us(render_row, render_timings[minimum_brightness]);
238+
if (next_brightness < MAX_BRIGHTNESS) {
239+
mp_int_t interval = render_timings[next_brightness] - render_timings[previous_brightness];
240+
renderTimer.attach_us(render_row, interval);
228241
}
229-
set_pins_for_pixels(minimum_brightness);
230-
++minimum_brightness;
242+
set_pins_for_pixels(next_brightness);
243+
previous_brightness = next_brightness;
231244

232245
}
233246

@@ -286,10 +299,9 @@ void microbit_display_tick(void) {
286299
microbit_display_advance_row();
287300

288301
microbit_display_update();
289-
290-
minimum_brightness = 1;
291-
render_row();
292-
302+
previous_brightness = 0;
303+
if (microbit_display_obj.brightnesses & GREYSCALE_MASK)
304+
render_row();
293305
}
294306

295307
STATIC void do_synchronous_animation_once(microbit_display_obj_t *display, mp_obj_t iterator, mp_int_t delay) {
@@ -426,6 +438,7 @@ void microbit_display_set_pixel(microbit_display_obj_t *display, mp_int_t x, mp_
426438
if (bright < 0 || bright > MAX_BRIGHTNESS)
427439
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "brightness out of bounds."));
428440
display->image_buffer[x][y] = bright;
441+
display->brightnesses |= (1 << bright);
429442
}
430443

431444
STATIC mp_obj_t microbit_display_set_pixel_func(mp_uint_t n_args, const mp_obj_t *args) {
@@ -480,14 +493,25 @@ STATIC const mp_obj_type_t microbit_display_type = {
480493

481494
microbit_display_obj_t microbit_display_obj = {
482495
{&microbit_display_type},
496+
0,
483497
{ 0 }
484498
};
485499

500+
static void ticker(void) {
501+
/* Make sure we call the DAL ticker function */
502+
uBit.systemTick();
503+
/* Update display */
504+
microbit_display_tick();
505+
}
506+
486507
void microbit_display_init(void) {
487508
//set pins as output
488509
nrf_gpio_range_cfg_output(MICROBIT_DISPLAY_COLUMN_START,MICROBIT_DISPLAY_COLUMN_START + MICROBIT_DISPLAY_COLUMN_COUNT + MICROBIT_DISPLAY_ROW_COUNT);
489510

490511
uBit.display.disable();
512+
513+
/* Hijack the DAL system ticker */
514+
uBit.systemTicker.attach(ticker, MICROBIT_DISPLAY_REFRESH_PERIOD);
491515
}
492516

493517
}

source/microbit/mprun.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
#include "pyexec.h"
1212
#include MICROPY_HAL_H
1313

14+
extern void microbit_display_init(void);
15+
1416
void microbit_display_exception(mp_obj_t exc_in) {
1517
mp_uint_t n, *values;
1618
mp_obj_exception_get_traceback(exc_in, &n, &values);
@@ -73,7 +75,7 @@ void mp_run(void) {
7375
mp_stack_set_limit(1800); // stack is 2k
7476

7577
// allocate the heap statically in the bss
76-
static uint32_t heap[9856 / 4];
78+
static uint32_t heap[9820 / 4];
7779
gc_init(heap, (uint8_t*)heap + sizeof(heap));
7880

7981
/*

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy