Skip to content

Commit b472229

Browse files
authored
Merge pull request #208 from chca42/master
Added small, simple alternative GUI library (freedomgfx), which respects all four freedoms
2 parents f824562 + 34bf9ca commit b472229

File tree

12 files changed

+1339
-0
lines changed

12 files changed

+1339
-0
lines changed

esp32/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,8 @@ SRC_C = \
165165
modbpp.c \
166166
modbadge.c \
167167
modugfx.c \
168+
modfreedomgfx.c \
169+
modfreedomgfx_eink.c \
168170
moduhashlib.c \
169171
machine_rtc.c \
170172
machine_hw_spi.c \

esp32/modfreedomgfx.c

Lines changed: 266 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,266 @@
1+
/*
2+
* This file is part of the MicroPython project, http://micropython.org/
3+
*
4+
* SHA2017 Badge Firmware https://wiki.sha2017.org/w/Projects:Badge/MicroPython
5+
*
6+
* Based on work by EMF for their TiLDA MK3 badge
7+
* https://github.com/emfcamp/micropython/tree/tilda-master/stmhal
8+
*
9+
* The MIT License (MIT)
10+
*
11+
* Copyright (c) 2015 Paul Sokolovsky
12+
* Copyright (c) 2016 Damien P. George
13+
* Copyright (c) 2017 Anne Jan Brouwer
14+
* Copyright (c) 2017 Christian Carlowitz
15+
*
16+
* Permission is hereby granted, free of charge, to any person obtaining a copy
17+
* of this software and associated documentation files (the "Software"), to deal
18+
* in the Software without restriction, including without limitation the rights
19+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
20+
* copies of the Software, and to permit persons to whom the Software is
21+
* furnished to do so, subject to the following conditions:
22+
*
23+
* The above copyright notice and this permission notice shall be included in
24+
* all copies or substantial portions of the Software.
25+
*
26+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
29+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
30+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
31+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
32+
* THE SOFTWARE.
33+
*/
34+
35+
#include <stdbool.h>
36+
#include <stdio.h>
37+
#include <stdint.h>
38+
#include <stdbool.h>
39+
#include <string.h>
40+
41+
#include <badge_eink.h>
42+
#include <badge_button.h>
43+
#include <badge_input.h>
44+
45+
46+
#include "py/mperrno.h"
47+
#include "py/mphal.h"
48+
#include "py/runtime.h"
49+
50+
#include "py/nlr.h"
51+
#include "py/runtime.h"
52+
53+
#ifdef UNIX
54+
#include "modfreedomgfx_sdl.h"
55+
#else
56+
#include "modfreedomgfx_eink.h"
57+
#endif
58+
59+
#define imgSize (BADGE_EINK_WIDTH*BADGE_EINK_HEIGHT)
60+
static uint8_t* img = 0;
61+
62+
#define PX(x,y,v) \
63+
if( x>=0 && y>=0 && x < BADGE_EINK_WIDTH && y < BADGE_EINK_HEIGHT) \
64+
img[((x)+(y)*BADGE_EINK_WIDTH)] = (v)
65+
66+
#define ABS(x) (((x)<0)?-(x):(x))
67+
68+
static void gfx_input_poll(uint32_t btn);
69+
70+
STATIC mp_obj_t gfx_init(void) {
71+
img = freedomgfxInit();
72+
memset(img, 0xff, imgSize);
73+
freedomgfxDraw();
74+
return mp_const_none;
75+
}
76+
STATIC MP_DEFINE_CONST_FUN_OBJ_0(gfx_init_obj, gfx_init);
77+
78+
STATIC mp_obj_t gfx_deinit(void) {
79+
freedomgfxDeinit();
80+
return mp_const_none;
81+
}
82+
STATIC MP_DEFINE_CONST_FUN_OBJ_0(gfx_deinit_obj, gfx_deinit);
83+
84+
STATIC mp_obj_t gfx_poll(void) {
85+
uint32_t evt = freedomgfxPoll();
86+
gfx_input_poll(evt);
87+
return mp_const_none;
88+
}
89+
STATIC MP_DEFINE_CONST_FUN_OBJ_0(gfx_poll_obj, gfx_poll);
90+
91+
STATIC mp_obj_t gfx_line(mp_uint_t n_args, const mp_obj_t *args) {
92+
int x0 = mp_obj_get_int(args[0]);
93+
int y0 = mp_obj_get_int(args[1]);
94+
int x1 = mp_obj_get_int(args[2]);
95+
int y1 = mp_obj_get_int(args[3]);
96+
int col = mp_obj_get_int(args[4]);
97+
98+
PX(x0,y0,col);
99+
100+
// algorithm: https://de.wikipedia.org/wiki/Bresenham-Algorithmus
101+
int dx = ABS(x1-x0);
102+
int sx = x0<x1 ? 1 : -1;
103+
int dy = -ABS(y1-y0);
104+
int sy = y0<y1 ? 1 : -1;
105+
int err = dx+dy;
106+
int err2;
107+
108+
while(1){
109+
PX(x0,y0,col);
110+
if ((x0 == x1) && (y0 == y1))
111+
break;
112+
err2 = 2*err;
113+
if (err2 > dy)
114+
{
115+
err += dy;
116+
x0 += sx;
117+
}
118+
if (err2 < dx)
119+
{
120+
err += dx;
121+
y0 += sy;
122+
}
123+
}
124+
125+
return mp_const_none;
126+
}
127+
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(gfx_line_obj, 5, 5, gfx_line);
128+
129+
STATIC mp_obj_t gfx_area(mp_uint_t n_args, const mp_obj_t *args) {
130+
int x0 = mp_obj_get_int(args[0]);
131+
int y0 = mp_obj_get_int(args[1]);
132+
int a = mp_obj_get_int(args[2]);
133+
int b = mp_obj_get_int(args[3]);
134+
int col = mp_obj_get_int(args[4]);
135+
136+
for(int i = 0; i < a; i++)
137+
{
138+
for(int j = 0; j < b; j++)
139+
PX(x0+i,y0+j,col);
140+
}
141+
142+
return mp_const_none;
143+
}
144+
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(gfx_area_obj, 5, 5, gfx_area);
145+
146+
147+
static uint8_t tm12x6_font[] = {
148+
#include "../share/fonts/Lat2-Terminus12x6.inc"
149+
};
150+
151+
STATIC mp_obj_t gfx_string(mp_uint_t n_args, const mp_obj_t *args) {
152+
mp_uint_t len;
153+
const unsigned char *data = (const unsigned char*) mp_obj_str_get_data(args[2], &len);
154+
int x0 = mp_obj_get_int(args[0]);
155+
int y0 = mp_obj_get_int(args[1]);
156+
int col = mp_obj_get_int(args[4]);
157+
158+
uint8_t* font = tm12x6_font;
159+
int clen = ((int*)font)[5];
160+
int cheight = ((int*)font)[6];
161+
int cwidth = ((int*)font)[7];
162+
163+
int xoffs = 0;
164+
while(*data != 0)
165+
{
166+
for(int i = 0; i < cheight; i++)
167+
{
168+
for(int j = 0; j < cwidth; j++) // TODO: only works for single byte rows
169+
{
170+
if( font[4*8+(int)(*data)*clen+i] & (1<<(7-j)))
171+
PX(x0+j+xoffs,y0+i,col);
172+
}
173+
}
174+
data++;
175+
xoffs += cwidth;
176+
177+
if(*data == '\n')
178+
{
179+
xoffs = 0;
180+
y0 += cheight;
181+
data++;
182+
}
183+
}
184+
185+
return mp_const_none;
186+
}
187+
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(gfx_string_obj, 5, 5, gfx_string);
188+
189+
190+
STATIC mp_obj_t gfx_flush(mp_uint_t n_args, const mp_obj_t *args) {
191+
freedomgfxDraw();
192+
return mp_const_none;
193+
}
194+
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(gfx_flush_obj, 0, 1, gfx_flush);
195+
196+
197+
// callback system
198+
199+
STATIC bool button_init_done = false;
200+
STATIC mp_obj_t button_callbacks[1+BADGE_BUTTONS];
201+
202+
static void gfx_input_poll(uint32_t btn)
203+
{
204+
if(button_init_done && btn > 0 && btn <= BADGE_BUTTONS)
205+
{
206+
if(button_callbacks[btn] != mp_const_none)
207+
mp_sched_schedule(button_callbacks[btn], mp_obj_new_bool(0));
208+
}
209+
}
210+
211+
STATIC mp_obj_t gfx_input_init(mp_uint_t n_args, const mp_obj_t *args) {
212+
for(size_t i = 0; i <= BADGE_BUTTONS; i++){
213+
button_callbacks[i] = mp_const_none;
214+
}
215+
button_init_done = true;
216+
return mp_const_none;
217+
}
218+
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(gfx_input_init_obj, 0, 1, gfx_input_init);
219+
220+
STATIC mp_obj_t gfx_input_attach(mp_uint_t n_args, const mp_obj_t *args) {
221+
int button = mp_obj_get_int(args[0]);
222+
if(button > 0 && button <= BADGE_BUTTONS)
223+
button_callbacks[button] = args[1];
224+
return mp_const_none;
225+
}
226+
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(gfx_input_attach_obj, 2, 2, gfx_input_attach);
227+
228+
229+
// Module globals
230+
231+
STATIC const mp_rom_map_elem_t freedomgfx_module_globals_table[] = {
232+
{MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_freedomgfx)},
233+
234+
{MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&gfx_init_obj},
235+
{MP_OBJ_NEW_QSTR(MP_QSTR_deinit), (mp_obj_t)&gfx_deinit_obj},
236+
{MP_OBJ_NEW_QSTR(MP_QSTR_poll), (mp_obj_t)&gfx_poll_obj},
237+
238+
{MP_OBJ_NEW_QSTR(MP_QSTR_line), (mp_obj_t)&gfx_line_obj},
239+
{MP_OBJ_NEW_QSTR(MP_QSTR_area), (mp_obj_t)&gfx_area_obj},
240+
{MP_OBJ_NEW_QSTR(MP_QSTR_string), (mp_obj_t)&gfx_string_obj},
241+
{MP_OBJ_NEW_QSTR(MP_QSTR_flush), (mp_obj_t)&gfx_flush_obj},
242+
243+
{MP_OBJ_NEW_QSTR(MP_QSTR_input_init), (mp_obj_t)&gfx_input_init_obj},
244+
{MP_OBJ_NEW_QSTR(MP_QSTR_input_attach), (mp_obj_t)&gfx_input_attach_obj},
245+
246+
{MP_OBJ_NEW_QSTR(MP_QSTR_BLACK), MP_OBJ_NEW_SMALL_INT(0x00)},
247+
{MP_OBJ_NEW_QSTR(MP_QSTR_WHITE), MP_OBJ_NEW_SMALL_INT(0xff)},
248+
249+
{MP_OBJ_NEW_QSTR(MP_QSTR_JOY_UP), MP_OBJ_NEW_SMALL_INT(BADGE_BUTTON_UP)},
250+
{MP_OBJ_NEW_QSTR(MP_QSTR_JOY_DOWN), MP_OBJ_NEW_SMALL_INT(BADGE_BUTTON_DOWN)},
251+
{MP_OBJ_NEW_QSTR(MP_QSTR_JOY_LEFT), MP_OBJ_NEW_SMALL_INT(BADGE_BUTTON_LEFT)},
252+
{MP_OBJ_NEW_QSTR(MP_QSTR_JOY_RIGHT), MP_OBJ_NEW_SMALL_INT(BADGE_BUTTON_RIGHT)},
253+
{MP_OBJ_NEW_QSTR(MP_QSTR_BTN_A), MP_OBJ_NEW_SMALL_INT(BADGE_BUTTON_A)},
254+
{MP_OBJ_NEW_QSTR(MP_QSTR_BTN_B), MP_OBJ_NEW_SMALL_INT(BADGE_BUTTON_B)},
255+
{MP_OBJ_NEW_QSTR(MP_QSTR_BTN_SELECT), MP_OBJ_NEW_SMALL_INT(BADGE_BUTTON_SELECT)},
256+
{MP_OBJ_NEW_QSTR(MP_QSTR_BTN_START), MP_OBJ_NEW_SMALL_INT(BADGE_BUTTON_START)},
257+
{MP_OBJ_NEW_QSTR(MP_QSTR_BTN_FLASH), MP_OBJ_NEW_SMALL_INT(BADGE_BUTTON_FLASH)},
258+
259+
};
260+
261+
STATIC MP_DEFINE_CONST_DICT(freedomgfx_module_globals, freedomgfx_module_globals_table);
262+
263+
const mp_obj_module_t freedomgfx_module = {
264+
.base = {&mp_type_module}, .globals = (mp_obj_dict_t *)&freedomgfx_module_globals,
265+
};
266+

esp32/modfreedomgfx_eink.c

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* This file is part of the SHA2017 Micro Python fork
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2017 Christian Carlowitz
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy
9+
* of this software and associated documentation files (the "Software"), to deal
10+
* in the Software without restriction, including without limitation the rights
11+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
* copies of the Software, and to permit persons to whom the Software is
13+
* furnished to do so, subject to the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be included in
16+
* all copies or substantial portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24+
* THE SOFTWARE.
25+
*/
26+
27+
#include <stdbool.h>
28+
29+
#include "modfreedomgfx_eink.h"
30+
#include <badge_eink.h>
31+
#include <badge_eink_fb.h>
32+
#include <badge_input.h>
33+
34+
extern bool ugfx_screen_flipped;
35+
36+
uint8_t* freedomgfxInit(void)
37+
{
38+
badge_eink_fb_init();
39+
return badge_eink_fb;
40+
}
41+
42+
void freedomgfxDeinit(void)
43+
{
44+
//
45+
}
46+
47+
uint32_t freedomgfxPoll(void)
48+
{
49+
uint32_t btn = badge_input_get_event(0);
50+
return btn;
51+
}
52+
53+
void freedomgfxDraw()
54+
{
55+
badge_eink_flags_t flags = DISPLAY_FLAG_FULL_UPDATE | DISPLAY_FLAG_8BITPIXEL;
56+
if(ugfx_screen_flipped)
57+
flags |= DISPLAY_FLAG_ROTATE_180;
58+
badge_eink_display(badge_eink_fb, flags);
59+
}

esp32/modfreedomgfx_eink.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* This file is part of the SHA2017 Micro Python fork
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2017 Christian Carlowitz
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy
9+
* of this software and associated documentation files (the "Software"), to deal
10+
* in the Software without restriction, including without limitation the rights
11+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
* copies of the Software, and to permit persons to whom the Software is
13+
* furnished to do so, subject to the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be included in
16+
* all copies or substantial portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24+
* THE SOFTWARE.
25+
*/
26+
27+
#ifndef UNIX_MODFREEDOMGFX_SDL_H_
28+
#define UNIX_MODFREEDOMGFX_SDL_H_
29+
30+
#include <inttypes.h>
31+
32+
uint8_t* freedomgfxInit(void); // returns buffer to draw to
33+
void freedomgfxDeinit(void);
34+
uint32_t freedomgfxPoll(void);
35+
void freedomgfxDraw();
36+
37+
#endif /* UNIX_MODFREEDOMGFX_SDL_H_ */

esp32/mpconfigport.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ extern const struct _mp_obj_module_t mp_module_network;
178178
extern const struct _mp_obj_module_t badge_module;
179179
extern const struct _mp_obj_module_t bpp_module;
180180
extern const struct _mp_obj_module_t ugfx_module;
181+
extern const struct _mp_obj_module_t freedomgfx_module;
181182
extern const struct _mp_obj_module_t mp_module_onewire;
182183

183184
#define MICROPY_PORT_BUILTIN_MODULES \
@@ -190,6 +191,7 @@ extern const struct _mp_obj_module_t mp_module_onewire;
190191
{ MP_OBJ_NEW_QSTR(MP_QSTR_badge), (mp_obj_t)&badge_module }, \
191192
{ MP_OBJ_NEW_QSTR(MP_QSTR_bpp), (mp_obj_t)&bpp_module }, \
192193
{ MP_OBJ_NEW_QSTR(MP_QSTR_ugfx), (mp_obj_t)&ugfx_module }, \
194+
{ MP_OBJ_NEW_QSTR(MP_QSTR_freedomgfx), (mp_obj_t)&freedomgfx_module }, \
193195
{ MP_OBJ_NEW_QSTR(MP_QSTR__onewire), (mp_obj_t)&mp_module_onewire }, \
194196

195197
#define MICROPY_PORT_BUILTIN_MODULE_WEAK_LINKS \

0 commit comments

Comments
 (0)