diff --git a/epicardium/epicardium.h b/epicardium/epicardium.h
index 9c4a770dd2ca448d94c011b76cc3801404e9194f..09151042219855ca510ed9e3f23c6ed6aa19d18b 100644
--- a/epicardium/epicardium.h
+++ b/epicardium/epicardium.h
@@ -48,6 +48,7 @@ typedef unsigned int size_t;
 #define API_DISP_RECT          0x16
 #define API_DISP_CIRC          0x17
 #define API_DISP_PIXEL         0x18
+#define API_DISP_FRAMEBUFFER   0x19
 
 #define API_FILE_OPEN          0x30
 #define API_FILE_CLOSE         0x31
@@ -288,7 +289,6 @@ API(API_DISP_CLOSE, int epic_disp_close());
  * to be shown on the display
  */
 API(API_DISP_UPDATE, int epic_disp_update());
-
 /**
  * Prints a string into the display framebuffer
  *
@@ -410,6 +410,13 @@ API(API_DISP_CIRC,
 	    uint16_t pixelsize)
     );
 
+/**
+ * Returns the back framebuffer (the display buffer that's currently inactive
+ * that will be shown after the next call to ``epic_disp_update``.
+ */
+API(API_DISP_FRAMEBUFFER, uint16_t *epic_disp_framebuffer());
+
+
 /**
  * Start continuous readout of the light sensor. Will read light level
  * at preconfigured interval and make it available via `epic_light_sensor_get()`.
diff --git a/epicardium/modules/display.c b/epicardium/modules/display.c
index 1786d80534ed630e405763c9a7efd77fddc9806c..2cabe397901796cdb99645be915509892d353173 100644
--- a/epicardium/modules/display.c
+++ b/epicardium/modules/display.c
@@ -125,6 +125,11 @@ int epic_disp_update()
 	}
 }
 
+uint16_t *epic_disp_framebuffer()
+{
+	return (uint16_t*) LCD_Framebuffer();
+}
+
 int epic_disp_open()
 {
 	TaskHandle_t task = xTaskGetCurrentTaskHandle();
diff --git a/lib/card10/display.c b/lib/card10/display.c
index e1d66276646f480cde27c063f162d7bd85dd6138..9db6e29e0bc8c86c4f3a1e05347bed18f4c8aedc 100644
--- a/lib/card10/display.c
+++ b/lib/card10/display.c
@@ -1,5 +1,6 @@
 #include "LCD/LCD_Driver.h"
 #include "GUI_DEV/GUI_Paint.h"
+#include "GUI_DEV/DEV_Config.h"
 
 #include "gpio.h"
 #include "tmr.h"
@@ -81,6 +82,8 @@ void display_set_reset_pin(uint8_t state)
 
 void display_init(void)
 {
+	lcd_irq_init();
+
 	if (!portexpander_detected()) {
 		// Open-drain
 		MAX77650_setDRV(false);
diff --git a/lib/gfx/GUI_DEV/DEV_Config.c b/lib/gfx/GUI_DEV/DEV_Config.c
index 5c1e4b22bb971126cc8ab0f6ce3599ab828c4a3f..7a09c400cd166fb976751ba43c81217552132407 100644
--- a/lib/gfx/GUI_DEV/DEV_Config.c
+++ b/lib/gfx/GUI_DEV/DEV_Config.c
@@ -39,7 +39,7 @@
 static spi_req_t req = {.rx_data = NULL, .bits=8, .width = SPI17Y_WIDTH_1, .ssel = 0, .deass = 1, .ssel_pol = SPI17Y_POL_LOW, .tx_num = 0, .rx_num = 0};
 
 /********************************************************************************/
-void lcd_write(uint8_t *data, int size, lcd_write_cb_t wr_callback)
+void lcd_write_async(uint8_t *data, int size, lcd_write_cb_t wr_callback)
 {
     req.tx_data = data;
     req.len = size;
@@ -47,3 +47,19 @@ void lcd_write(uint8_t *data, int size, lcd_write_cb_t wr_callback)
     SPI_MasterTransAsync(SPI, &req);
 }
 
+void lcd_write(uint8_t *data, int size)
+{
+    req.tx_data = data;
+    req.len = size;
+    SPI_MasterTrans(SPI, &req);
+}
+
+void lcd_irq_init(void)
+{
+    NVIC_EnableIRQ(SPI2_IRQn);
+}
+
+void SPI2_IRQHandler(void)
+{
+    SPI_Handler(SPI);
+}
diff --git a/lib/gfx/GUI_DEV/DEV_Config.h b/lib/gfx/GUI_DEV/DEV_Config.h
index 5e4ed5f7c4d0001852bc0a64d5c69745b7b71e9c..7308bf02b353322fc972888bcad850c6e4cbca26 100644
--- a/lib/gfx/GUI_DEV/DEV_Config.h
+++ b/lib/gfx/GUI_DEV/DEV_Config.h
@@ -59,9 +59,11 @@ extern const gpio_cfg_t DEV_DC_PIN;
 /**
  * SPI
 **/
-void lcd_write(uint8_t* data, int size, lcd_write_cb_t wr_callback);
+void lcd_write(uint8_t* data, int size);
+void lcd_write_async(uint8_t* data, int size, lcd_write_cb_t wr_callback);
 void display_set_reset_pin(uint8_t state);
-#define DEV_SPI_WRITE(_dat) lcd_write(&_dat, 1, NULL)
+void lcd_irq_init(void);
+#define DEV_SPI_WRITE(_dat) lcd_write(&_dat, 1)
 #define DEV_RESET_LOW() display_set_reset_pin(0)
 #define DEV_RESET_HIGH() display_set_reset_pin(1)
 /**
diff --git a/lib/gfx/LCD/LCD_Driver.c b/lib/gfx/LCD/LCD_Driver.c
index a75582d346e48e5e0eb3d41279fa2f26601fb873..a6c50e5a5e19639f1dc9721c37a3983bcf170057 100644
--- a/lib/gfx/LCD/LCD_Driver.c
+++ b/lib/gfx/LCD/LCD_Driver.c
@@ -29,11 +29,6 @@
 ******************************************************************************/
 #include "LCD_Driver.h"
 
-typedef union {
-    uint8_t fb[LCD_HEIGHT][LCD_WIDTH][2];
-    uint8_t raw[LCD_HEIGHT * LCD_WIDTH * 2];
-} frame_t;
-
 static frame_t frames[2];
 static uint8_t active_frame;
 static uint8_t update_in_progress;
@@ -328,7 +323,7 @@ static void LCD_Set(uint8_t *data, int len)
 	LCD_SetCursor(0, 0, 160 - 1, 80 - 1);
 	DEV_Digital_Write(DEV_DC_PIN, 1);
     update_in_progress = 1;
-    lcd_write(data, len, update_cb);
+    lcd_write_async(data, len, update_cb);
 }
 
 int LCD_Update(void)
@@ -341,3 +336,6 @@ int LCD_Update(void)
     return 0;
 }
 
+frame_t *LCD_Framebuffer(void) {
+	return frame();
+}
diff --git a/lib/gfx/LCD/LCD_Driver.h b/lib/gfx/LCD/LCD_Driver.h
index 6e4f3ed947f57c1ccbd4d8221b4c722947e50573..aff3b575291b6e5114da8317aedf8be764c96276 100644
--- a/lib/gfx/LCD/LCD_Driver.h
+++ b/lib/gfx/LCD/LCD_Driver.h
@@ -35,6 +35,10 @@
 #define LCD_WIDTH   160 //LCD width
 #define LCD_HEIGHT  80 //LCD height
 
+typedef union {
+    uint8_t fb[LCD_HEIGHT][LCD_WIDTH][2];
+    uint8_t raw[LCD_HEIGHT * LCD_WIDTH * 2];
+} frame_t;
 
 void LCD_WriteData_Byte(UBYTE da); 
 void LCD_WriteData_Word(UWORD da);
@@ -52,5 +56,6 @@ void LCD_ClearWindow(UWORD Xstart, UWORD Ystart, UWORD Xend, UWORD Yend, UWORD U
  *                1 - an update was already in progress
  */
 int LCD_Update(void);
+frame_t *LCD_Framebuffer(void);
 
 #endif