@@ -135,7 +135,7 @@ STATIC void preflight_pins_or_throw(uint8_t clock_pin, uint8_t *rgb_pins, uint8_
135
135
136
136
//| :class:`~_protomatter.Protomatter` displays an in-memory framebuffer to an LED matrix.
137
137
//|
138
- //| .. class:: Protomatter(width, bit_depth, rgb_pins, addr_pins, clock_pin, latch_pin, oe_pin , *, doublebuffer=True, framebuffer=None)
138
+ //| .. class:: Protomatter(width, bit_depth, rgb_pins, addr_pins, clock_pin, latch_pin, output_enable_pin , *, doublebuffer=True, framebuffer=None)
139
139
//|
140
140
//| Create a Protomatter object with the given attributes. The height of
141
141
//| the display is determined by the number of rgb and address pins:
@@ -153,31 +153,39 @@ STATIC void preflight_pins_or_throw(uint8_t clock_pin, uint8_t *rgb_pins, uint8_
153
153
//| microcontroller board. For instance, the Feather M4 Express works
154
154
//| together with the RGB Matrix Feather.
155
155
//|
156
- //| When specified as True, double buffering can reduce some flickering of
157
- //| the matrix; however, this increases memory usage.
156
+ //| The framebuffer is in "RGB565" format.
158
157
//|
159
- //| The framebuffer is in "RGB565" format. If a framebuffer is not
160
- //| passed in, one is allocated and initialized to all black. To update
161
- //| the content, modify the framebuffer and call swapbuffers.
158
+ //| "RGB565" means that it is organized as a series of 16-bit numbers
159
+ //| where the highest 5 bits are interpreted as red, the next 6 as
160
+ //| green, and the final 5 as blue. The object can be any buffer, but
161
+ //| `array.array` and `ulab.array` objects are most often useful.
162
+ //| To update the content, modify the framebuffer and call refresh.
163
+ //|
164
+ //| If a framebuffer is not passed in, one is allocated and initialized
165
+ //| to all black. In any case, the framebuffer can be retrieved
166
+ //| by passing the protomatter object to memoryview().
162
167
//|
163
168
//| If doublebuffer is False, some memory is saved, but the display may
164
169
//| flicker during updates.
165
170
//|
166
171
//| If a framebuffer is not passed in, one is allocated internally. To
167
172
//| retrieve it, pass the protomatter object to memoryview().
168
173
//|
174
+ //| A Protomatter framebuffer is often used in conjunction with a
175
+ //| `framebufferio.FramebufferDisplay`.
176
+ //|
169
177
170
178
STATIC mp_obj_t protomatter_protomatter_make_new (const mp_obj_type_t * type , size_t n_args , const mp_obj_t * pos_args , mp_map_t * kw_args ) {
171
179
enum { ARG_width , ARG_bit_depth , ARG_rgb_list , ARG_addr_list ,
172
- ARG_clock_pin , ARG_latch_pin , ARG_oe_pin , ARG_doublebuffer , ARG_framebuffer };
180
+ ARG_clock_pin , ARG_latch_pin , ARG_output_enable_pin , ARG_doublebuffer , ARG_framebuffer };
173
181
static const mp_arg_t allowed_args [] = {
174
182
{ MP_QSTR_width , MP_ARG_INT | MP_ARG_REQUIRED },
175
183
{ MP_QSTR_bit_depth , MP_ARG_INT | MP_ARG_REQUIRED },
176
184
{ MP_QSTR_rgb_pins , MP_ARG_OBJ | MP_ARG_REQUIRED },
177
185
{ MP_QSTR_addr_pins , MP_ARG_OBJ | MP_ARG_REQUIRED },
178
186
{ MP_QSTR_clock_pin , MP_ARG_OBJ | MP_ARG_REQUIRED },
179
187
{ MP_QSTR_latch_pin , MP_ARG_OBJ | MP_ARG_REQUIRED },
180
- { MP_QSTR_oe_pin , MP_ARG_OBJ | MP_ARG_REQUIRED },
188
+ { MP_QSTR_output_enable_pin , MP_ARG_OBJ | MP_ARG_REQUIRED },
181
189
{ MP_QSTR_doublebuffer , MP_ARG_BOOL , { .u_bool = true } },
182
190
{ MP_QSTR_framebuffer , MP_ARG_OBJ , { .u_obj = mp_const_none } },
183
191
};
@@ -195,7 +203,7 @@ STATIC mp_obj_t protomatter_protomatter_make_new(const mp_obj_type_t *type, size
195
203
uint8_t addr_pins [MP_ARRAY_SIZE (self -> addr_pins )];
196
204
uint8_t clock_pin = validate_pin (args [ARG_clock_pin ].u_obj );
197
205
uint8_t latch_pin = validate_pin (args [ARG_latch_pin ].u_obj );
198
- uint8_t oe_pin = validate_pin (args [ARG_oe_pin ].u_obj );
206
+ uint8_t output_enable_pin = validate_pin (args [ARG_output_enable_pin ].u_obj );
199
207
200
208
validate_pins (MP_QSTR_rgb_pins , rgb_pins , MP_ARRAY_SIZE (self -> rgb_pins ), args [ARG_rgb_list ].u_obj , & rgb_count );
201
209
validate_pins (MP_QSTR_addr_pins , addr_pins , MP_ARRAY_SIZE (self -> addr_pins ), args [ARG_addr_list ].u_obj , & addr_count );
@@ -214,14 +222,14 @@ STATIC mp_obj_t protomatter_protomatter_make_new(const mp_obj_type_t *type, size
214
222
args [ARG_bit_depth ].u_int ,
215
223
rgb_count , rgb_pins ,
216
224
addr_count , addr_pins ,
217
- clock_pin , latch_pin , oe_pin ,
225
+ clock_pin , latch_pin , output_enable_pin ,
218
226
args [ARG_doublebuffer ].u_bool ,
219
227
framebuffer , NULL );
220
228
221
229
claim_and_never_reset_pins (args [ARG_rgb_list ].u_obj );
222
230
claim_and_never_reset_pins (args [ARG_addr_list ].u_obj );
223
231
claim_and_never_reset_pin (args [ARG_clock_pin ].u_obj );
224
- claim_and_never_reset_pin (args [ARG_oe_pin ].u_obj );
232
+ claim_and_never_reset_pin (args [ARG_output_enable_pin ].u_obj );
225
233
claim_and_never_reset_pin (args [ARG_latch_pin ].u_obj );
226
234
227
235
return MP_OBJ_FROM_PTR (self );
@@ -247,89 +255,91 @@ static void check_for_deinit(protomatter_protomatter_obj_t *self) {
247
255
}
248
256
}
249
257
250
- //| .. attribute:: paused
258
+ //| .. attribute:: brightness
251
259
//|
252
- //| When paused, the matrix is not driven and all its LEDs are unlit.
260
+ //| In the current implementation, 0.0 turns the display off entirely
261
+ //| and any other value up to 1.0 turns the display on fully.
253
262
//|
254
- STATIC mp_obj_t protomatter_protomatter_get_paused (mp_obj_t self_in ) {
263
+ STATIC mp_obj_t protomatter_protomatter_get_brightness (mp_obj_t self_in ) {
255
264
protomatter_protomatter_obj_t * self = (protomatter_protomatter_obj_t * )self_in ;
256
265
check_for_deinit (self );
257
- return mp_obj_new_bool (common_hal_protomatter_protomatter_get_paused (self ));
266
+ return mp_obj_new_float (common_hal_protomatter_protomatter_get_paused (self )? 0.0f : 1.0f );
258
267
}
259
- MP_DEFINE_CONST_FUN_OBJ_1 (protomatter_protomatter_get_paused_obj , protomatter_protomatter_get_paused );
268
+ MP_DEFINE_CONST_FUN_OBJ_1 (protomatter_protomatter_get_brightness_obj , protomatter_protomatter_get_brightness );
260
269
261
- STATIC mp_obj_t protomatter_protomatter_set_paused (mp_obj_t self_in , mp_obj_t value_in ) {
270
+ STATIC mp_obj_t protomatter_protomatter_set_brightness (mp_obj_t self_in , mp_obj_t value_in ) {
262
271
protomatter_protomatter_obj_t * self = (protomatter_protomatter_obj_t * )self_in ;
263
272
check_for_deinit (self );
264
- bool paused = mp_obj_is_true (value_in );
265
- common_hal_protomatter_protomatter_set_paused (self , paused );
273
+ mp_float_t brightness = mp_obj_get_float (value_in );
274
+ if (brightness < 0.0f || brightness > 1.0f ) {
275
+ mp_raise_ValueError (translate ("Brightness must be 0-1.0" ));
276
+ }
277
+ common_hal_protomatter_protomatter_set_paused (self_in , brightness <= 0 );
266
278
267
279
return mp_const_none ;
268
280
}
269
- MP_DEFINE_CONST_FUN_OBJ_2 (protomatter_protomatter_set_paused_obj , protomatter_protomatter_set_paused );
281
+ MP_DEFINE_CONST_FUN_OBJ_2 (protomatter_protomatter_set_brightness_obj , protomatter_protomatter_set_brightness );
270
282
271
- const mp_obj_property_t protomatter_protomatter_paused_obj = {
283
+ const mp_obj_property_t protomatter_protomatter_brightness_obj = {
272
284
.base .type = & mp_type_property ,
273
- .proxy = {(mp_obj_t )& protomatter_protomatter_get_paused_obj ,
274
- (mp_obj_t )& protomatter_protomatter_set_paused_obj ,
285
+ .proxy = {(mp_obj_t )& protomatter_protomatter_get_brightness_obj ,
286
+ (mp_obj_t )& protomatter_protomatter_set_brightness_obj ,
275
287
(mp_obj_t )& mp_const_none_obj },
276
288
};
277
289
278
- //| .. method:: swapbuffers()
279
- //|
280
- //| Transmits the color data in the buffer to the pixels so that they are shown.
290
+ //| .. method:: refresh()
281
291
//|
282
- //| The data in the buffer must be in "RGB565" format. This means
283
- //| that it is organized as a series of 16-bit numbers where the highest 5
284
- //| bits are interpreted as red, the next 6 as green, and the final 5 as
285
- //| blue. The object can be any buffer, but `array.array` and `ulab.array`
286
- //| objects are most often useful.
292
+ //| Transmits the color data in the buffer to the pixels so that
293
+ //| they are shown.
287
294
//|
288
- STATIC mp_obj_t protomatter_protomatter_swapbuffers (mp_obj_t self_in ) {
295
+ STATIC mp_obj_t protomatter_protomatter_refresh (mp_obj_t self_in ) {
289
296
protomatter_protomatter_obj_t * self = (protomatter_protomatter_obj_t * )self_in ;
290
297
check_for_deinit (self );
291
-
292
- _PM_convert_565 (& self -> core , self -> bufinfo .buf , self -> width );
293
- _PM_swapbuffer_maybe (& self -> core );
298
+ common_hal_protomatter_protomatter_refresh (self );
294
299
return mp_const_none ;
295
300
}
296
- MP_DEFINE_CONST_FUN_OBJ_1 (protomatter_protomatter_swapbuffers_obj , protomatter_protomatter_swapbuffers );
301
+ MP_DEFINE_CONST_FUN_OBJ_1 (protomatter_protomatter_refresh_obj , protomatter_protomatter_refresh );
297
302
298
303
STATIC const mp_rom_map_elem_t protomatter_protomatter_locals_dict_table [] = {
299
304
{ MP_ROM_QSTR (MP_QSTR_deinit ), MP_ROM_PTR (& protomatter_protomatter_deinit_obj ) },
300
- { MP_ROM_QSTR (MP_QSTR_paused ), MP_ROM_PTR (& protomatter_protomatter_paused_obj ) },
301
- { MP_ROM_QSTR (MP_QSTR_swapbuffers ), MP_ROM_PTR (& protomatter_protomatter_swapbuffers_obj ) },
305
+ { MP_ROM_QSTR (MP_QSTR_brightness ), MP_ROM_PTR (& protomatter_protomatter_brightness_obj ) },
306
+ { MP_ROM_QSTR (MP_QSTR_refresh ), MP_ROM_PTR (& protomatter_protomatter_refresh_obj ) },
302
307
};
303
308
STATIC MP_DEFINE_CONST_DICT (protomatter_protomatter_locals_dict , protomatter_protomatter_locals_dict_table );
304
309
305
310
STATIC void protomatter_protomatter_get_bufinfo (mp_obj_t self_in , mp_buffer_info_t * bufinfo ) {
306
311
protomatter_protomatter_obj_t * self = (protomatter_protomatter_obj_t * )self_in ;
307
312
check_for_deinit (self );
308
-
313
+
309
314
* bufinfo = self -> bufinfo ;
310
315
}
311
316
312
- // This version exists so that the return value of the function can be none, matching the protocol
313
- STATIC void protomatter_protomatter_swapbuffers_void (mp_obj_t self_in ) {
314
- protomatter_protomatter_swapbuffers (self_in );
317
+ // These version exists so that the prototype matches the protocol,
318
+ // avoiding a type cast that can hide errors
319
+ STATIC void protomatter_protomatter_swapbuffers (mp_obj_t self_in ) {
320
+ common_hal_protomatter_protomatter_refresh (self_in );
321
+ }
322
+
323
+ STATIC void protomatter_protomatter_deinit_proto (mp_obj_t self_in ) {
324
+ common_hal_protomatter_protomatter_deinit (self_in );
315
325
}
316
326
317
- // This version exists so that the return value of the function can be none, matching the protocol
318
- STATIC void protomatter_protomatter_deinit_void (mp_obj_t self_in ) {
319
- protomatter_protomatter_deinit (self_in );
327
+ STATIC float protomatter_protomatter_get_brightness_proto (mp_obj_t self_in ) {
328
+ return common_hal_protomatter_protomatter_get_paused (self_in ) ? 0.0f : 1.0f ;
320
329
}
321
330
322
- STATIC bool protomatter_protomatter_set_brightness (mp_obj_t self_in , mp_float_t value ) {
331
+ STATIC bool protomatter_protomatter_set_brightness_proto (mp_obj_t self_in , mp_float_t value ) {
323
332
common_hal_protomatter_protomatter_set_paused (self_in , value <= 0 );
324
333
return true;
325
334
}
326
335
327
336
STATIC const framebuffer_p_t protomatter_protomatter_proto = {
328
337
MP_PROTO_IMPLEMENT (MP_QSTR_protocol_framebuffer )
329
338
.get_bufinfo = protomatter_protomatter_get_bufinfo ,
330
- .set_brightness = protomatter_protomatter_set_brightness ,
331
- .swapbuffers = protomatter_protomatter_swapbuffers_void ,
332
- .deinit = protomatter_protomatter_deinit_void ,
339
+ .set_brightness = protomatter_protomatter_set_brightness_proto ,
340
+ .get_brightness = protomatter_protomatter_get_brightness_proto ,
341
+ .swapbuffers = protomatter_protomatter_swapbuffers ,
342
+ .deinit = protomatter_protomatter_deinit_proto ,
333
343
};
334
344
335
345
STATIC mp_int_t protomatter_protomatter_get_buffer (mp_obj_t self_in , mp_buffer_info_t * bufinfo , mp_uint_t flags ) {
0 commit comments