4242
4343extern Protomatter_core * _PM_protoPtr ;
4444
45+ STATIC void common_hal_rgbmatrix_rgbmatrix_construct1 (rgbmatrix_rgbmatrix_obj_t * self , mp_obj_t framebuffer );
46+
4547void common_hal_rgbmatrix_rgbmatrix_construct (rgbmatrix_rgbmatrix_obj_t * self , int width , int bit_depth , uint8_t rgb_count , uint8_t * rgb_pins , uint8_t addr_count , uint8_t * addr_pins , uint8_t clock_pin , uint8_t latch_pin , uint8_t oe_pin , bool doublebuffer , mp_obj_t framebuffer , int8_t tile , bool serpentine , void * timer ) {
4648 self -> width = width ;
4749 self -> bit_depth = bit_depth ;
@@ -64,15 +66,11 @@ void common_hal_rgbmatrix_rgbmatrix_construct(rgbmatrix_rgbmatrix_obj_t *self, i
6466 self -> width = width ;
6567 self -> bufsize = 2 * width * common_hal_rgbmatrix_rgbmatrix_get_height (self );
6668
67- common_hal_rgbmatrix_rgbmatrix_reconstruct (self , framebuffer );
69+ common_hal_rgbmatrix_rgbmatrix_construct1 (self , framebuffer );
6870}
6971
70- void common_hal_rgbmatrix_rgbmatrix_reconstruct (rgbmatrix_rgbmatrix_obj_t * self , mp_obj_t framebuffer ) {
71- self -> paused = 1 ;
72-
73- common_hal_rgbmatrix_timer_disable (self -> timer );
74- if (framebuffer ) {
75- self -> framebuffer = framebuffer ;
72+ STATIC void common_hal_rgbmatrix_rgbmatrix_construct1 (rgbmatrix_rgbmatrix_obj_t * self , mp_obj_t framebuffer ) {
73+ if (framebuffer != mp_const_none ) {
7674 mp_get_buffer_raise (self -> framebuffer , & self -> bufinfo , MP_BUFFER_READ );
7775 if (mp_get_buffer (self -> framebuffer , & self -> bufinfo , MP_BUFFER_RW )) {
7876 self -> bufinfo .typecode = 'H' | MP_OBJ_ARRAY_TYPECODE_FLAG_RW ;
@@ -82,16 +80,11 @@ void common_hal_rgbmatrix_rgbmatrix_reconstruct(rgbmatrix_rgbmatrix_obj_t *self,
8280 // verify that the matrix is big enough
8381 mp_get_index (mp_obj_get_type (self -> framebuffer ), self -> bufinfo .len , MP_OBJ_NEW_SMALL_INT (self -> bufsize - 1 ), false);
8482 } else {
85- common_hal_rgbmatrix_free_impl (self -> bufinfo .buf );
86- common_hal_rgbmatrix_free_impl (self -> protomatter .rgbPins );
87- common_hal_rgbmatrix_free_impl (self -> protomatter .addr );
88- common_hal_rgbmatrix_free_impl (self -> protomatter .screenData );
89-
90- self -> framebuffer = NULL ;
9183 self -> bufinfo .buf = common_hal_rgbmatrix_allocator_impl (self -> bufsize );
9284 self -> bufinfo .len = self -> bufsize ;
9385 self -> bufinfo .typecode = 'H' | MP_OBJ_ARRAY_TYPECODE_FLAG_RW ;
9486 }
87+ self -> framebuffer = framebuffer ;
9588
9689 memset (& self -> protomatter , 0 , sizeof (self -> protomatter ));
9790 ProtomatterStatus stat = _PM_init (& self -> protomatter ,
@@ -115,6 +108,9 @@ void common_hal_rgbmatrix_rgbmatrix_reconstruct(rgbmatrix_rgbmatrix_obj_t *self,
115108
116109 if (stat != PROTOMATTER_OK ) {
117110 common_hal_rgbmatrix_rgbmatrix_deinit (self );
111+ if (!gc_alloc_possible ()) {
112+ return ;
113+ }
118114 switch (stat ) {
119115 case PROTOMATTER_ERR_PINS :
120116 raise_ValueError_invalid_pin ();
@@ -148,35 +144,65 @@ STATIC void free_pin_seq(uint8_t *seq, int count) {
148144 }
149145}
150146
151- void common_hal_rgbmatrix_rgbmatrix_deinit (rgbmatrix_rgbmatrix_obj_t * self ) {
152- if (self -> timer ) {
153- common_hal_rgbmatrix_timer_free (self -> timer );
154- self -> timer = 0 ;
155- }
147+ extern int pm_row_count ;
148+ STATIC void common_hal_rgbmatrix_rgbmatrix_deinit1 (rgbmatrix_rgbmatrix_obj_t * self ) {
149+ common_hal_rgbmatrix_timer_disable (self -> timer );
156150
157151 if (_PM_protoPtr == & self -> protomatter ) {
158152 _PM_protoPtr = NULL ;
159153 }
160154
161- free_pin_seq (self -> rgb_pins , self -> rgb_count );
162- free_pin_seq (self -> addr_pins , self -> addr_count );
163- free_pin (& self -> clock_pin );
164- free_pin (& self -> latch_pin );
165- free_pin (& self -> oe_pin );
166-
167155 if (self -> protomatter .rgbPins ) {
168156 _PM_deallocate (& self -> protomatter );
169157 }
158+
170159 memset (& self -> protomatter , 0 , sizeof (self -> protomatter ));
171160
172161 // If it was supervisor-allocated, it is supervisor-freed and the pointer
173162 // is zeroed, otherwise the pointer is just zeroed
174- _PM_free (self -> bufinfo .buf );
175- self -> base .type = NULL ;
163+ if (self -> bufinfo .buf ) {
164+ common_hal_rgbmatrix_free_impl (self -> bufinfo .buf );
165+ self -> bufinfo .buf = NULL ;
166+ }
167+
176168
177- // If a framebuffer was passed in to the constructor, NULL the reference
169+ // If a framebuffer was passed in to the constructor, clear the reference
178170 // here so that it will become GC'able
179- self -> framebuffer = NULL ;
171+ self -> framebuffer = mp_const_none ;
172+ }
173+
174+ void common_hal_rgbmatrix_rgbmatrix_deinit (rgbmatrix_rgbmatrix_obj_t * self ) {
175+ common_hal_rgbmatrix_rgbmatrix_deinit1 (self );
176+ if (self -> timer ) {
177+ common_hal_rgbmatrix_timer_free (self -> timer );
178+ self -> timer = 0 ;
179+ }
180+
181+ free_pin_seq (self -> rgb_pins , self -> rgb_count );
182+ free_pin_seq (self -> addr_pins , self -> addr_count );
183+ free_pin (& self -> clock_pin );
184+ free_pin (& self -> latch_pin );
185+ free_pin (& self -> oe_pin );
186+
187+ self -> base .type = & mp_type_NoneType ;
188+ }
189+
190+ void common_hal_rgbmatrix_rgbmatrix_reconstruct (rgbmatrix_rgbmatrix_obj_t * self ) {
191+ if (self -> framebuffer != mp_const_none ) {
192+ memset (& self -> bufinfo , 0 , sizeof (self -> bufinfo ));
193+ }
194+ #if CIRCUITPY_RGBMATRIX_USES_SUPERVISOR_ALLOCATION
195+ common_hal_rgbmatrix_rgbmatrix_set_paused (self , true);
196+ common_hal_rgbmatrix_rgbmatrix_deinit1 (self );
197+ common_hal_rgbmatrix_rgbmatrix_construct1 (self , mp_const_none );
198+ #endif
199+ if (self -> bufinfo .buf == NULL ) {
200+ self -> bufinfo .buf = common_hal_rgbmatrix_allocator_impl (self -> bufsize );
201+ self -> bufinfo .len = self -> bufsize ;
202+ self -> bufinfo .typecode = 'H' | MP_OBJ_ARRAY_TYPECODE_FLAG_RW ;
203+ }
204+ memset (self -> bufinfo .buf , 0 , self -> bufinfo .len );
205+ common_hal_rgbmatrix_rgbmatrix_set_paused (self , false);
180206}
181207
182208void rgbmatrix_rgbmatrix_collect_ptrs (rgbmatrix_rgbmatrix_obj_t * self ) {
0 commit comments