From 84f2fea262be15985c15eed63e47d6e02a548f47 Mon Sep 17 00:00:00 2001
From: fgross <florian.gross@snowflake.com>
Date: Fri, 23 Aug 2019 12:22:27 +0200
Subject: [PATCH] First working implementation of framebuffer rendering in
 Python

---
 pycardium/modules/qstrdefs.h    |  1 +
 pycardium/modules/sys_display.c | 31 +++++++++++++++++++++++++++++++
 pycardium/mpconfigport.h        |  1 +
 3 files changed, 33 insertions(+)

diff --git a/pycardium/modules/qstrdefs.h b/pycardium/modules/qstrdefs.h
index d789c8730..5efb50131 100644
--- a/pycardium/modules/qstrdefs.h
+++ b/pycardium/modules/qstrdefs.h
@@ -91,6 +91,7 @@ Q(line)
 Q(rect)
 Q(circ)
 Q(clear)
+Q(framebuffer)
 
 /* ambient */
 Q(light_sensor)
diff --git a/pycardium/modules/sys_display.c b/pycardium/modules/sys_display.c
index f5523d548..d009a788d 100644
--- a/pycardium/modules/sys_display.c
+++ b/pycardium/modules/sys_display.c
@@ -7,6 +7,16 @@
 
 #include <stdio.h>
 
+// TODO: Where does this belong? Needs to be in sync with extmod/modframebuf
+#define FRAMEBUF_RGB565   (1)
+typedef struct _mp_obj_framebuf_t {
+    mp_obj_base_t base;
+    mp_obj_t buf_obj; // need to store this to prevent GC from reclaiming buf
+    void *buf;
+    uint16_t width, height, stride;
+    uint8_t format;
+} mp_obj_framebuf_t;
+
 static uint16_t rgb888_to_rgb565(uint8_t *bytes)
 {
 	return ((bytes[0] & 0b11111000) << 8) | ((bytes[1] & 0b11111100) << 3) |
@@ -208,6 +218,26 @@ static mp_obj_t mp_display_update()
 }
 static MP_DEFINE_CONST_FUN_OBJ_0(display_update_obj, mp_display_update);
 
+static mp_obj_t mp_display_framebuffer(mp_obj_t fb_obj)
+{
+    mp_obj_framebuf_t *fb = MP_OBJ_TO_PTR(fb_obj);
+
+	if (fb->format != FRAMEBUF_RGB565)
+		mp_raise_ValueError("Framebuffer format has to be RGB565");
+
+	if (fb->width != 160 || fb->height != 80)
+		mp_raise_ValueError("Framebuffer size has to match native display size (160x80)");
+
+	void* dfb = fb->buf;
+	
+	int res = epic_disp_framebuffer((union disp_framebuffer*) dfb);
+	if (res < 0) {
+		mp_raise_OSError(-res);
+	}
+	return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(display_framebuffer_obj, mp_display_framebuffer);
+
 static mp_obj_t mp_display_open()
 {
 	int res = epic_disp_open();
@@ -241,6 +271,7 @@ static const mp_rom_map_elem_t display_module_globals_table[] = {
 	{ MP_ROM_QSTR(MP_QSTR_circ), MP_ROM_PTR(&display_circ_obj) },
 	{ MP_ROM_QSTR(MP_QSTR_clear), MP_ROM_PTR(&display_clear_obj) },
 	{ MP_ROM_QSTR(MP_QSTR_update), MP_ROM_PTR(&display_update_obj) },
+	{ MP_ROM_QSTR(MP_QSTR_framebuffer), MP_ROM_PTR(&display_framebuffer_obj) },
 };
 static MP_DEFINE_CONST_DICT(
 	display_module_globals, display_module_globals_table
diff --git a/pycardium/mpconfigport.h b/pycardium/mpconfigport.h
index 43f878706..ee7687a1d 100644
--- a/pycardium/mpconfigport.h
+++ b/pycardium/mpconfigport.h
@@ -43,6 +43,7 @@ int mp_hal_trng_read_int(void);
 #define MICROPY_PY_UTIME_MP_HAL             (1)
 #define MICROPY_PY_IO_FILEIO                (1)
 #define MICROPY_PY_UERRNO                   (1)
+#define MICROPY_PY_FRAMEBUF                 (1)
 
 /* Modules */
 #define MODULE_BHI160_ENABLED               (1)
-- 
GitLab