@@ -40,10 +40,13 @@ void microbit_display_print(microbit_display_obj_t *display, microbit_image_obj_
40
40
mp_int_t w = min (image->width (), 5 );
41
41
mp_int_t h = min (image->height (), 5 );
42
42
mp_int_t x = 0 ;
43
+ mp_int_t brightnesses = 0 ;
43
44
for (; x < w; ++x) {
44
45
mp_int_t y = 0 ;
45
46
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);
47
50
}
48
51
for (; y < 5 ; ++y) {
49
52
display->image_buffer [x][y] = 0 ;
@@ -54,6 +57,7 @@ void microbit_display_print(microbit_display_obj_t *display, microbit_image_obj_
54
57
display->image_buffer [x][y] = 0 ;
55
58
}
56
59
}
60
+ display->brightnesses = brightnesses;
57
61
}
58
62
59
63
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;
110
114
static int async_tick = 0 ;
111
115
static int strobe_row = 0 ;
112
116
static int strobe_mask = 0x20 ;
113
- static int minimum_brightness = 0 ;
117
+ static int previous_brightness = 0 ;
114
118
static Ticker renderTimer;
115
119
116
120
@@ -143,7 +147,7 @@ struct DisplayPoint {
143
147
144
148
#define NO_CONN 0
145
149
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] = {
147
151
{{0 ,0 }, {4 ,2 }, {2 ,4 }},
148
152
{{2 ,0 }, {0 ,2 }, {4 ,4 }},
149
153
{{4 ,0 }, {2 ,2 }, {0 ,4 }},
@@ -208,26 +212,35 @@ static void microbit_display_advance_row(void) {
208
212
}
209
213
210
214
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 */
221
225
};
222
226
227
+ #define GREYSCALE_MASK ((1 <<MAX_BRIGHTNESS)-2 )
228
+
223
229
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
+ }
225
237
// 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);
228
241
}
229
- set_pins_for_pixels (minimum_brightness );
230
- ++minimum_brightness ;
242
+ set_pins_for_pixels (next_brightness );
243
+ previous_brightness = next_brightness ;
231
244
232
245
}
233
246
@@ -286,10 +299,9 @@ void microbit_display_tick(void) {
286
299
microbit_display_advance_row ();
287
300
288
301
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 ();
293
305
}
294
306
295
307
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_
426
438
if (bright < 0 || bright > MAX_BRIGHTNESS)
427
439
nlr_raise (mp_obj_new_exception_msg (&mp_type_ValueError, " brightness out of bounds." ));
428
440
display->image_buffer [x][y] = bright;
441
+ display->brightnesses |= (1 << bright);
429
442
}
430
443
431
444
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 = {
480
493
481
494
microbit_display_obj_t microbit_display_obj = {
482
495
{µbit_display_type},
496
+ 0 ,
483
497
{ 0 }
484
498
};
485
499
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
+
486
507
void microbit_display_init (void ) {
487
508
// set pins as output
488
509
nrf_gpio_range_cfg_output (MICROBIT_DISPLAY_COLUMN_START,MICROBIT_DISPLAY_COLUMN_START + MICROBIT_DISPLAY_COLUMN_COUNT + MICROBIT_DISPLAY_ROW_COUNT);
489
510
490
511
uBit.display .disable ();
512
+
513
+ /* Hijack the DAL system ticker */
514
+ uBit.systemTicker .attach (ticker, MICROBIT_DISPLAY_REFRESH_PERIOD);
491
515
}
492
516
493
517
}
0 commit comments