32
32
#include "py/objproperty.h"
33
33
#include "py/runtime.h"
34
34
35
- // #include "common-hal/is31fl3741/Is31fl3741.h"
36
35
#include "shared-module/is31fl3741/allocator.h"
37
36
#include "shared-bindings/is31fl3741/is31fl3741.h"
38
37
#include "shared-bindings/microcontroller/Pin.h"
41
40
#include "shared-module/framebufferio/FramebufferDisplay.h"
42
41
#include "shared-bindings/busio/I2C.h"
43
42
44
- extern Protomatter_core * _PM_protoPtr ;
45
-
46
- uint8_t cur_page = 99 ;
47
-
48
- void send_unlock (busio_i2c_obj_t * i2c , uint8_t addr ) {
49
- uint8_t unlock [2 ] = { 0xFE , 0xC5 }; // unlock command
50
- common_hal_busio_i2c_write (i2c , addr , unlock , 2 , true);
51
- }
52
-
53
- void set_page (busio_i2c_obj_t * i2c , uint8_t addr , uint8_t p ) {
54
- if (p == cur_page ) {
55
- return ;
56
- }
57
-
58
- cur_page = p ;
59
- send_unlock (i2c , addr );
60
-
61
- uint8_t page [2 ] = { 0xFD , 0x00 }; // page command
62
- page [1 ] = p ;
63
- common_hal_busio_i2c_write (i2c , addr , page , 2 , true);
64
- }
65
-
66
- void send_enable (busio_i2c_obj_t * i2c , uint8_t addr ) {
67
- set_page (i2c , addr , 4 );
68
- uint8_t enable [2 ] = { 0x00 , 0x01 }; // enable command
69
- common_hal_busio_i2c_write (i2c , addr , enable , 2 , true);
70
- }
71
-
72
- void send_reset (busio_i2c_obj_t * i2c , uint8_t addr ) {
73
- set_page (i2c , addr , 4 );
74
- uint8_t rst [2 ] = { 0x3F , 0xAE }; // reset command
75
- common_hal_busio_i2c_write (i2c , addr , rst , 2 , true);
76
- }
77
-
78
- void set_current (busio_i2c_obj_t * i2c , uint8_t addr , uint8_t current ) {
79
- set_page (i2c , addr , 4 );
80
- uint8_t gcur [2 ] = { 0x01 , 0x00 }; // global current command
81
- gcur [1 ] = current ;
82
- common_hal_busio_i2c_write (i2c , addr , gcur , 2 , true);
83
- }
84
-
85
- uint8_t get_current (busio_i2c_obj_t * i2c , uint8_t addr ) {
86
- set_page (i2c , addr , 4 );
87
- uint8_t gcur = 0x01 ; // global current command
88
- common_hal_busio_i2c_write (i2c , addr , & gcur , 1 , true);
89
-
90
- uint8_t data = 0 ;
91
- common_hal_busio_i2c_read (i2c , addr , & data , 1 );
92
- return data ;
93
- }
94
-
95
-
96
- void set_led (busio_i2c_obj_t * i2c , uint8_t addr , uint16_t led , uint8_t level , uint8_t page ) {
97
- uint8_t cmd [2 ] = { 0x00 , 0x00 };
98
-
99
- if (led < 180 ) {
100
- set_page (i2c , addr , page );
101
- cmd [0 ] = (uint8_t )led ;
102
- } else {
103
- set_page (i2c , addr , page + 1 );
104
- cmd [0 ] = (uint8_t )(led - 180 );
105
- }
106
-
107
- cmd [1 ] = level ;
108
-
109
- common_hal_busio_i2c_write (i2c , addr , cmd , 2 , true);
110
- }
111
-
112
- void drawPixel (busio_i2c_obj_t * i2c , uint8_t addr , int16_t x , int16_t y , uint32_t color ) {
113
- uint8_t r = color >> 16 & 0xFF ;
114
- uint8_t g = color >> 8 & 0xFF ;
115
- uint8_t b = color & 0xFF ;
116
-
117
- int16_t x1 = (x * 5 + y ) * 3 ;
118
- uint16_t ridx = glassesmatrix_ledmap [x1 + 2 ];
119
- if (ridx != 65535 ) {
120
- uint16_t gidx = glassesmatrix_ledmap [x1 + 1 ];
121
- uint16_t bidx = glassesmatrix_ledmap [x1 + 0 ];
122
- set_led (i2c , addr , ridx , r , 0 );
123
- set_led (i2c , addr , gidx , g , 0 );
124
- set_led (i2c , addr , bidx , b , 0 );
125
- }
126
- }
127
-
128
43
void common_hal_is31fl3741_is31fl3741_construct (is31fl3741_is31fl3741_obj_t * self , int width , int height , mp_obj_t framebuffer , busio_i2c_obj_t * i2c , uint8_t addr ) {
129
44
self -> width = width ;
130
45
self -> height = height ;
131
46
132
- self -> bufsize = 4 * width * height ;
47
+ self -> bufsize = sizeof ( uint32_t ) * width * height ;
133
48
134
49
// Probe the bus to see if a device acknowledges the given address.
135
50
if (!common_hal_busio_i2c_probe (i2c , addr )) {
@@ -141,24 +56,6 @@ void common_hal_is31fl3741_is31fl3741_construct(is31fl3741_is31fl3741_obj_t *sel
141
56
self -> device_address = addr ;
142
57
143
58
common_hal_is31fl3741_is31fl3741_reconstruct (self , framebuffer );
144
-
145
- common_hal_displayio_is31fl3741_begin_transaction (self );
146
-
147
- uint8_t command = 0xFC ;
148
- common_hal_busio_i2c_write (i2c , addr , & command , 1 , false);
149
- uint8_t data = 0 ;
150
- common_hal_busio_i2c_read (i2c , addr , & data , 1 );
151
-
152
- send_reset (i2c , addr );
153
- send_enable (i2c , addr );
154
- set_current (i2c , addr , 0x08 );
155
-
156
- // set scale to max for all
157
- for (int i ; i < 351 ; i ++ ) {
158
- set_led (i2c , addr , i , 0xFF , 2 );
159
- }
160
-
161
- common_hal_displayio_is31fl3741_end_transaction (self );
162
59
}
163
60
164
61
void common_hal_is31fl3741_is31fl3741_reconstruct (is31fl3741_is31fl3741_obj_t * self , mp_obj_t framebuffer ) {
@@ -184,7 +81,23 @@ void common_hal_is31fl3741_is31fl3741_reconstruct(is31fl3741_is31fl3741_obj_t *s
184
81
self -> bufinfo .typecode = 'H' | MP_OBJ_ARRAY_TYPECODE_FLAG_RW ;
185
82
}
186
83
187
- // initialize LEDs here
84
+ common_hal_displayio_is31fl3741_begin_transaction (self );
85
+
86
+ uint8_t command = 0xFC ;
87
+ common_hal_busio_i2c_write (self -> i2c , self -> device_address , & command , 1 , false);
88
+ uint8_t data = 0 ;
89
+ common_hal_busio_i2c_read (self -> i2c , self -> device_address , & data , 1 );
90
+
91
+ is31fl3741_send_reset (self -> i2c , self -> device_address );
92
+ is31fl3741_send_enable (self -> i2c , self -> device_address );
93
+ is31fl3741_set_current (self -> i2c , self -> device_address , 0x08 );
94
+
95
+ // set scale to max for all
96
+ for (int i ; i < 351 ; i ++ ) {
97
+ is31fl3741_set_led (self -> i2c , self -> device_address , i , 0xFF , 2 );
98
+ }
99
+
100
+ common_hal_displayio_is31fl3741_end_transaction (self );
188
101
189
102
self -> paused = 0 ;
190
103
}
@@ -207,13 +120,13 @@ bool common_hal_is31fl3741_is31fl3741_get_paused(is31fl3741_is31fl3741_obj_t *se
207
120
208
121
void common_hal_is31fl3741_is31fl3741_set_global_current (is31fl3741_is31fl3741_obj_t * self , uint8_t current ) {
209
122
common_hal_displayio_is31fl3741_begin_transaction (self );
210
- set_current (self -> i2c , self -> device_address , current );
123
+ is31fl3741_set_current (self -> i2c , self -> device_address , current );
211
124
common_hal_displayio_is31fl3741_end_transaction (self );
212
125
}
213
126
214
127
uint8_t common_hal_is31fl3741_is31fl3741_get_global_current (is31fl3741_is31fl3741_obj_t * self ) {
215
128
common_hal_displayio_is31fl3741_begin_transaction (self );
216
- uint8_t current = get_current (self -> i2c , self -> device_address );
129
+ uint8_t current = is31fl3741_get_current (self -> i2c , self -> device_address );
217
130
common_hal_displayio_is31fl3741_end_transaction (self );
218
131
return current ;
219
132
}
@@ -230,9 +143,9 @@ void common_hal_is31fl3741_is31fl3741_refresh(is31fl3741_is31fl3741_obj_t *self,
230
143
if (self -> scale ) {
231
144
uint32_t * buffer = self -> bufinfo .buf ;
232
145
233
- for (int x = 0 ; x < 18 ; x ++ ) {
146
+ for (int x = 0 ; x < self -> scale_width ; x ++ ) {
234
147
uint32_t * ptr = & buffer [x * 3 ]; // Entry along top scan line w/x offset
235
- for (int y = 0 ; y < 5 ; y ++ ) {
148
+ for (int y = 0 ; y < self -> scale_height ; y ++ ) {
236
149
uint16_t rsum = 0 , gsum = 0 , bsum = 0 ;
237
150
// Inner x/y loops are row-major on purpose (less pointer math)
238
151
for (uint8_t yy = 0 ; yy < 3 ; yy ++ ) {
@@ -242,23 +155,37 @@ void common_hal_is31fl3741_is31fl3741_refresh(is31fl3741_is31fl3741_obj_t *self,
242
155
gsum += (rgb >> 8 ) & 0xFF ;
243
156
bsum += rgb & 0xFF ;
244
157
}
245
- ptr += 54 ; // canvas->width(); // Advance one scan line
158
+ ptr += self -> width ; // canvas->width(); // Advance one scan line
246
159
}
247
160
rsum = rsum / 9 ;
248
161
gsum = gsum / 9 ;
249
162
bsum = bsum / 9 ;
250
- uint32_t color = (IS31GammaTable [rsum ] << 16 ) +
251
- (IS31GammaTable [gsum ] << 8 ) +
252
- (IS31GammaTable [bsum ] / 9 );
253
- drawPixel (self -> i2c , self -> device_address , x , y , color );
163
+ uint32_t color = 0 ;
164
+ if (self -> auto_gamma ) {
165
+ color = (IS31GammaTable [rsum ] << 16 ) +
166
+ (IS31GammaTable [gsum ] << 8 ) +
167
+ IS31GammaTable [bsum ];
168
+ } else {
169
+ color = (rsum << 16 ) + (gsum << 8 ) + bsum ;
170
+ }
171
+ is31fl3741_draw_pixel (self -> i2c , self -> device_address , x , y , color );
254
172
}
255
173
}
256
174
} else {
257
175
uint32_t * buffer = self -> bufinfo .buf ;
258
176
for (int y = 0 ; y < self -> height ; y ++ ) {
259
177
if ((dirty_row_flags >> y ) & 0x1 ) {
178
+ uint32_t color = 0 ;
179
+ if (self -> auto_gamma ) {
180
+ color = IS31GammaTable [((* buffer ) >> 16 & 0xFF )] +
181
+ IS31GammaTable [((* buffer ) >> 8 & 0xFF )] +
182
+ IS31GammaTable [((* buffer ) & 0xFF )];
183
+ } else {
184
+ color = * buffer ;
185
+ }
186
+
260
187
for (int x = 0 ; x < self -> width ; x ++ ) {
261
- drawPixel (self -> i2c , self -> device_address , x , y , * buffer );
188
+ is31fl3741_draw_pixel (self -> i2c , self -> device_address , x , y , color );
262
189
buffer ++ ;
263
190
}
264
191
}
@@ -299,3 +226,84 @@ void common_hal_is31fl3741_free_impl(void *ptr_in) {
299
226
void is31fl3741_is31fl3741_collect_ptrs (is31fl3741_is31fl3741_obj_t * self ) {
300
227
gc_collect_ptr (self -> framebuffer );
301
228
}
229
+
230
+ uint8_t cur_page = 99 ; // set to invalid page to start
231
+
232
+ void is31fl3741_send_unlock (busio_i2c_obj_t * i2c , uint8_t addr ) {
233
+ uint8_t unlock [2 ] = { 0xFE , 0xC5 }; // unlock command
234
+ common_hal_busio_i2c_write (i2c , addr , unlock , 2 , true);
235
+ }
236
+
237
+ void is31fl3741_set_page (busio_i2c_obj_t * i2c , uint8_t addr , uint8_t p ) {
238
+ if (p == cur_page ) {
239
+ return ;
240
+ }
241
+
242
+ cur_page = p ;
243
+ is31fl3741_send_unlock (i2c , addr );
244
+
245
+ uint8_t page [2 ] = { 0xFD , 0x00 }; // page command
246
+ page [1 ] = p ;
247
+ common_hal_busio_i2c_write (i2c , addr , page , 2 , true);
248
+ }
249
+
250
+ void is31fl3741_send_enable (busio_i2c_obj_t * i2c , uint8_t addr ) {
251
+ is31fl3741_set_page (i2c , addr , 4 );
252
+ uint8_t enable [2 ] = { 0x00 , 0x01 }; // enable command
253
+ common_hal_busio_i2c_write (i2c , addr , enable , 2 , true);
254
+ }
255
+
256
+ void is31fl3741_send_reset (busio_i2c_obj_t * i2c , uint8_t addr ) {
257
+ is31fl3741_set_page (i2c , addr , 4 );
258
+ uint8_t rst [2 ] = { 0x3F , 0xAE }; // reset command
259
+ common_hal_busio_i2c_write (i2c , addr , rst , 2 , true);
260
+ }
261
+
262
+ void is31fl3741_set_current (busio_i2c_obj_t * i2c , uint8_t addr , uint8_t current ) {
263
+ is31fl3741_set_page (i2c , addr , 4 );
264
+ uint8_t gcur [2 ] = { 0x01 , 0x00 }; // global current command
265
+ gcur [1 ] = current ;
266
+ common_hal_busio_i2c_write (i2c , addr , gcur , 2 , true);
267
+ }
268
+
269
+ uint8_t is31fl3741_get_current (busio_i2c_obj_t * i2c , uint8_t addr ) {
270
+ is31fl3741_set_page (i2c , addr , 4 );
271
+ uint8_t gcur = 0x01 ; // global current command
272
+ common_hal_busio_i2c_write (i2c , addr , & gcur , 1 , true);
273
+
274
+ uint8_t data = 0 ;
275
+ common_hal_busio_i2c_read (i2c , addr , & data , 1 );
276
+ return data ;
277
+ }
278
+
279
+ void is31fl3741_set_led (busio_i2c_obj_t * i2c , uint8_t addr , uint16_t led , uint8_t level , uint8_t page ) {
280
+ uint8_t cmd [2 ] = { 0x00 , 0x00 };
281
+
282
+ if (led < 180 ) {
283
+ is31fl3741_set_page (i2c , addr , page );
284
+ cmd [0 ] = (uint8_t )led ;
285
+ } else {
286
+ is31fl3741_set_page (i2c , addr , page + 1 );
287
+ cmd [0 ] = (uint8_t )(led - 180 );
288
+ }
289
+
290
+ cmd [1 ] = level ;
291
+
292
+ common_hal_busio_i2c_write (i2c , addr , cmd , 2 , true);
293
+ }
294
+
295
+ void is31fl3741_draw_pixel (busio_i2c_obj_t * i2c , uint8_t addr , int16_t x , int16_t y , uint32_t color ) {
296
+ uint8_t r = color >> 16 & 0xFF ;
297
+ uint8_t g = color >> 8 & 0xFF ;
298
+ uint8_t b = color & 0xFF ;
299
+
300
+ int16_t x1 = (x * 5 + y ) * 3 ;
301
+ uint16_t ridx = glassesmatrix_ledmap [x1 + 2 ];
302
+ if (ridx != 65535 ) {
303
+ uint16_t gidx = glassesmatrix_ledmap [x1 + 1 ];
304
+ uint16_t bidx = glassesmatrix_ledmap [x1 + 0 ];
305
+ is31fl3741_set_led (i2c , addr , ridx , r , 0 );
306
+ is31fl3741_set_led (i2c , addr , gidx , g , 0 );
307
+ is31fl3741_set_led (i2c , addr , bidx , b , 0 );
308
+ }
309
+ }
0 commit comments