Skip to content

Commit 3424746

Browse files
encukoudpgeorge
authored andcommitted
extmod/modframebuf: Add 2-bit color format (GS2_HMSB).
This format is used in 2-color LED matrices and in e-ink displays like SSD1606.
1 parent 36f7952 commit 3424746

4 files changed

Lines changed: 153 additions & 0 deletions

File tree

‎docs/library/framebuf.rst‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,10 @@ Constants
148148

149149
Red Green Blue (16-bit, 5+6+5) color format
150150

151+
.. data:: framebuf.GS2_HMSB
152+
153+
Grayscale (2-bit) color format
154+
151155
.. data:: framebuf.GS4_HMSB
152156

153157
Grayscale (4-bit) color format

‎extmod/modframebuf.c‎

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ typedef struct _mp_framebuf_p_t {
5454
// constants for formats
5555
#define FRAMEBUF_MVLSB (0)
5656
#define FRAMEBUF_RGB565 (1)
57+
#define FRAMEBUF_GS2_HMSB (5)
5758
#define FRAMEBUF_GS4_HMSB (2)
5859
#define FRAMEBUF_MHLSB (3)
5960
#define FRAMEBUF_MHMSB (4)
@@ -130,6 +131,30 @@ STATIC void rgb565_fill_rect(const mp_obj_framebuf_t *fb, int x, int y, int w, i
130131
}
131132
}
132133

134+
// Functions for GS2_HMSB format
135+
136+
STATIC void gs2_hmsb_setpixel(const mp_obj_framebuf_t *fb, int x, int y, uint32_t col) {
137+
uint8_t *pixel = &((uint8_t*)fb->buf)[(x + y * fb->stride) >> 2];
138+
uint8_t shift = (x & 0x3) << 1;
139+
uint8_t mask = 0x3 << shift;
140+
uint8_t color = (col & 0x3) << shift;
141+
*pixel = color | (*pixel & (~mask));
142+
}
143+
144+
STATIC uint32_t gs2_hmsb_getpixel(const mp_obj_framebuf_t *fb, int x, int y) {
145+
uint8_t pixel = ((uint8_t*)fb->buf)[(x + y * fb->stride) >> 2];
146+
uint8_t shift = (x & 0x3) << 1;
147+
return (pixel >> shift) & 0x3;
148+
}
149+
150+
STATIC void gs2_hmsb_fill_rect(const mp_obj_framebuf_t *fb, int x, int y, int w, int h, uint32_t col) {
151+
for (int xx=x; xx < x+w; xx++) {
152+
for (int yy=y; yy < y+h; yy++) {
153+
gs2_hmsb_setpixel(fb, xx, yy, col);
154+
}
155+
}
156+
}
157+
133158
// Functions for GS4_HMSB format
134159

135160
STATIC void gs4_hmsb_setpixel(const mp_obj_framebuf_t *fb, int x, int y, uint32_t col) {
@@ -184,6 +209,7 @@ STATIC void gs4_hmsb_fill_rect(const mp_obj_framebuf_t *fb, int x, int y, int w,
184209
STATIC mp_framebuf_p_t formats[] = {
185210
[FRAMEBUF_MVLSB] = {mvlsb_setpixel, mvlsb_getpixel, mvlsb_fill_rect},
186211
[FRAMEBUF_RGB565] = {rgb565_setpixel, rgb565_getpixel, rgb565_fill_rect},
212+
[FRAMEBUF_GS2_HMSB] = {gs2_hmsb_setpixel, gs2_hmsb_getpixel, gs2_hmsb_fill_rect},
187213
[FRAMEBUF_GS4_HMSB] = {gs4_hmsb_setpixel, gs4_hmsb_getpixel, gs4_hmsb_fill_rect},
188214
[FRAMEBUF_MHLSB] = {mono_horiz_setpixel, mono_horiz_getpixel, mono_horiz_fill_rect},
189215
[FRAMEBUF_MHMSB] = {mono_horiz_setpixel, mono_horiz_getpixel, mono_horiz_fill_rect},
@@ -240,6 +266,9 @@ STATIC mp_obj_t framebuf_make_new(const mp_obj_type_t *type, size_t n_args, size
240266
case FRAMEBUF_MHMSB:
241267
o->stride = (o->stride + 7) & ~7;
242268
break;
269+
case FRAMEBUF_GS2_HMSB:
270+
o->stride = (o->stride + 3) & ~3;
271+
break;
243272
case FRAMEBUF_GS4_HMSB:
244273
o->stride = (o->stride + 1) & ~1;
245274
break;
@@ -579,6 +608,7 @@ STATIC const mp_rom_map_elem_t framebuf_module_globals_table[] = {
579608
{ MP_ROM_QSTR(MP_QSTR_MVLSB), MP_ROM_INT(FRAMEBUF_MVLSB) },
580609
{ MP_ROM_QSTR(MP_QSTR_MONO_VLSB), MP_ROM_INT(FRAMEBUF_MVLSB) },
581610
{ MP_ROM_QSTR(MP_QSTR_RGB565), MP_ROM_INT(FRAMEBUF_RGB565) },
611+
{ MP_ROM_QSTR(MP_QSTR_GS2_HMSB), MP_ROM_INT(FRAMEBUF_GS2_HMSB) },
582612
{ MP_ROM_QSTR(MP_QSTR_GS4_HMSB), MP_ROM_INT(FRAMEBUF_GS4_HMSB) },
583613
{ MP_ROM_QSTR(MP_QSTR_MONO_HLSB), MP_ROM_INT(FRAMEBUF_MHLSB) },
584614
{ MP_ROM_QSTR(MP_QSTR_MONO_HMSB), MP_ROM_INT(FRAMEBUF_MHMSB) },

‎tests/extmod/framebuf2.py‎

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
try:
2+
import framebuf
3+
except ImportError:
4+
print("SKIP")
5+
raise SystemExit
6+
7+
def printbuf():
8+
print("--8<--")
9+
for y in range(h):
10+
for x in range(w):
11+
print('%u' % ((buf[(x + y * w) // 4] >> ((x & 3) << 1)) & 3), end='')
12+
print()
13+
print("-->8--")
14+
15+
w = 8
16+
h = 5
17+
buf = bytearray(w * h // 4)
18+
fbuf = framebuf.FrameBuffer(buf, w, h, framebuf.GS2_HMSB)
19+
20+
# fill
21+
fbuf.fill(3)
22+
printbuf()
23+
fbuf.fill(0)
24+
printbuf()
25+
26+
# put pixel
27+
fbuf.pixel(0, 0, 1)
28+
fbuf.pixel(3, 0, 2)
29+
fbuf.pixel(0, 4, 3)
30+
fbuf.pixel(3, 4, 2)
31+
printbuf()
32+
33+
# get pixel
34+
print(fbuf.pixel(0, 4), fbuf.pixel(1, 1))
35+
36+
# scroll
37+
fbuf.fill(0)
38+
fbuf.pixel(2, 2, 3)
39+
printbuf()
40+
fbuf.scroll(0, 1)
41+
printbuf()
42+
fbuf.scroll(1, 0)
43+
printbuf()
44+
fbuf.scroll(-1, -2)
45+
printbuf()
46+
47+
w2 = 2
48+
h2 = 3
49+
buf2 = bytearray(w2 * h2 // 4)
50+
fbuf2 = framebuf.FrameBuffer(buf2, w2, h2, framebuf.GS2_HMSB)
51+
52+
# blit
53+
fbuf2.fill(0)
54+
fbuf2.pixel(0, 0, 1)
55+
fbuf2.pixel(0, 2, 2)
56+
fbuf2.pixel(1, 0, 1)
57+
fbuf2.pixel(1, 2, 2)
58+
fbuf.fill(3)
59+
fbuf.blit(fbuf2, 3, 3, 0)
60+
fbuf.blit(fbuf2, -1, -1, 0)
61+
fbuf.blit(fbuf2, 16, 16, 0)
62+
printbuf()

‎tests/extmod/framebuf2.py.exp‎

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
--8<--
2+
33333333
3+
33333333
4+
33333333
5+
33333333
6+
33333333
7+
-->8--
8+
--8<--
9+
00000000
10+
00000000
11+
00000000
12+
00000000
13+
00000000
14+
-->8--
15+
--8<--
16+
10020000
17+
00000000
18+
00000000
19+
00000000
20+
30020000
21+
-->8--
22+
3 0
23+
--8<--
24+
00000000
25+
00000000
26+
00300000
27+
00000000
28+
00000000
29+
-->8--
30+
--8<--
31+
00000000
32+
00000000
33+
00000000
34+
00300000
35+
00000000
36+
-->8--
37+
--8<--
38+
00000000
39+
00000000
40+
00000000
41+
00030000
42+
00000000
43+
-->8--
44+
--8<--
45+
00000000
46+
00300000
47+
00000000
48+
00030000
49+
00000000
50+
-->8--
51+
--8<--
52+
33333333
53+
23333333
54+
33333333
55+
33311333
56+
33333333
57+
-->8--

0 commit comments

Comments
 (0)