@@ -177,17 +177,18 @@ STATIC void preflight_pins_or_throw(uint8_t clock_pin, uint8_t *rgb_pins, uint8_
177177
178178STATIC 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 ) {
179179 enum { ARG_width , ARG_bit_depth , ARG_rgb_list , ARG_addr_list ,
180- ARG_clock_pin , ARG_latch_pin , ARG_output_enable_pin , ARG_doublebuffer , ARG_framebuffer };
180+ ARG_clock_pin , ARG_latch_pin , ARG_output_enable_pin , ARG_doublebuffer , ARG_framebuffer , ARG_height };
181181 static const mp_arg_t allowed_args [] = {
182- { MP_QSTR_width , MP_ARG_INT | MP_ARG_REQUIRED },
183- { MP_QSTR_bit_depth , MP_ARG_INT | MP_ARG_REQUIRED },
184- { MP_QSTR_rgb_pins , MP_ARG_OBJ | MP_ARG_REQUIRED },
185- { MP_QSTR_addr_pins , MP_ARG_OBJ | MP_ARG_REQUIRED },
186- { MP_QSTR_clock_pin , MP_ARG_OBJ | MP_ARG_REQUIRED },
187- { MP_QSTR_latch_pin , MP_ARG_OBJ | MP_ARG_REQUIRED },
188- { MP_QSTR_output_enable_pin , MP_ARG_OBJ | MP_ARG_REQUIRED },
189- { MP_QSTR_doublebuffer , MP_ARG_BOOL , { .u_bool = true } },
190- { MP_QSTR_framebuffer , MP_ARG_OBJ , { .u_obj = mp_const_none } },
182+ { MP_QSTR_width , MP_ARG_INT | MP_ARG_REQUIRED | MP_ARG_KW_ONLY },
183+ { MP_QSTR_bit_depth , MP_ARG_INT | MP_ARG_REQUIRED | MP_ARG_KW_ONLY },
184+ { MP_QSTR_rgb_pins , MP_ARG_OBJ | MP_ARG_REQUIRED | MP_ARG_KW_ONLY },
185+ { MP_QSTR_addr_pins , MP_ARG_OBJ | MP_ARG_REQUIRED | MP_ARG_KW_ONLY },
186+ { MP_QSTR_clock_pin , MP_ARG_OBJ | MP_ARG_REQUIRED | MP_ARG_KW_ONLY },
187+ { MP_QSTR_latch_pin , MP_ARG_OBJ | MP_ARG_REQUIRED | MP_ARG_KW_ONLY },
188+ { MP_QSTR_output_enable_pin , MP_ARG_OBJ | MP_ARG_REQUIRED | MP_ARG_KW_ONLY },
189+ { MP_QSTR_doublebuffer , MP_ARG_BOOL | MP_ARG_KW_ONLY , { .u_bool = true } },
190+ { MP_QSTR_framebuffer , MP_ARG_OBJ | MP_ARG_KW_ONLY , { .u_obj = mp_const_none } },
191+ { MP_QSTR_height , MP_ARG_INT | MP_ARG_KW_ONLY , { .u_int = 0 } },
191192 };
192193 mp_arg_val_t args [MP_ARRAY_SIZE (allowed_args )];
193194 mp_arg_parse_all (n_args , pos_args , kw_args , MP_ARRAY_SIZE (allowed_args ), allowed_args , args );
@@ -208,6 +209,19 @@ STATIC mp_obj_t protomatter_protomatter_make_new(const mp_obj_type_t *type, size
208209 validate_pins (MP_QSTR_rgb_pins , rgb_pins , MP_ARRAY_SIZE (self -> rgb_pins ), args [ARG_rgb_list ].u_obj , & rgb_count );
209210 validate_pins (MP_QSTR_addr_pins , addr_pins , MP_ARRAY_SIZE (self -> addr_pins ), args [ARG_addr_list ].u_obj , & addr_count );
210211
212+ if (rgb_count % 6 ) {
213+ mp_raise_ValueError_varg (translate ("Must use a multiple of 6 rgb pins, not %d" ), rgb_count );
214+ }
215+
216+ // TODO(@jepler) Use fewer than all rows of pixels if height < computed_height
217+ if (args [ARG_height ].u_int != 0 ) {
218+ int computed_height = (rgb_count / 3 ) << (addr_count );
219+ if (computed_height != args [ARG_height ].u_int ) {
220+ mp_raise_ValueError_varg (
221+ translate ("%d address pins and %d rgb pins indicate a height of %d, not %d" ), addr_count , rgb_count , computed_height , args [ARG_height ].u_int );
222+ }
223+ }
224+
211225 preflight_pins_or_throw (clock_pin , rgb_pins , rgb_count , true);
212226
213227 mp_obj_t framebuffer = args [ARG_framebuffer ].u_obj ;
0 commit comments