Ejemplo n.º 1
0
    def init_gui_SDL(self):

        import SDL
        SDL.init()

        # Register SDL display driver.

        disp_buf1 = lv.disp_buf_t()
        buf1_1 = bytearray(480 * 10)
        lv.disp_buf_init(disp_buf1, buf1_1, None, len(buf1_1) // 4)
        disp_drv = lv.disp_drv_t()
        lv.disp_drv_init(disp_drv)
        disp_drv.buffer = disp_buf1
        disp_drv.flush_cb = SDL.monitor_flush
        disp_drv.hor_res = 480
        disp_drv.ver_res = 320
        lv.disp_drv_register(disp_drv)

        # Regsiter SDL mouse driver

        indev_drv = lv.indev_drv_t()
        lv.indev_drv_init(indev_drv)
        indev_drv.type = lv.INDEV_TYPE.POINTER
        indev_drv.read_cb = SDL.mouse_read
        lv.indev_drv_register(indev_drv)
Ejemplo n.º 2
0
    def init_gui_esp32(self):

        import lvesp32
        import ILI9341 as ili

        # Initialize ILI9341 display

        disp = ili.display(miso=5, mosi=18, clk=19, cs=13, dc=12, rst=4, backlight=2)
        disp.init()

        # Register display driver 

        disp_buf1 = lv.disp_buf_t()
        buf1_1 = bytearray(480*10)
        lv.disp_buf_init(disp_buf1,buf1_1, None, len(buf1_1)//4)
        disp_drv = lv.disp_drv_t()
        lv.disp_drv_init(disp_drv)
        disp_drv.buffer = disp_buf1
        disp_drv.flush_cb = disp.flush
        disp_drv.hor_res = 240
        disp_drv.ver_res = 320
        lv.disp_drv_register(disp_drv)

        # Register raw resistive touch driver

        import rtch
        touch = rtch.touch(xp = 32, yp = 33, xm = 25, ym = 26, touch_rail = 27, touch_sense = 33)
        touch.init()
        indev_drv = lv.indev_drv_t()
        lv.indev_drv_init(indev_drv) 
        indev_drv.type = lv.INDEV_TYPE.POINTER;
        indev_drv.read_cb = touch.read;
        lv.indev_drv_register(indev_drv);
Ejemplo n.º 3
0
    def init_gui_esp32(self):

        import lvesp32
        import ILI9341 as ili

        # Initialize ILI9341 display

        disp = ili.display(miso=5, mosi=18, clk=19, cs=13, dc=12, rst=4, backlight=2)
        disp.init()

        # Register display driver 

        disp_drv = lv.disp_drv_t()
        lv.disp_drv_init(disp_drv)
        disp_drv.disp_flush = disp.flush
        disp_drv.disp_fill = disp.fill
        lv.disp_drv_register(disp_drv)

        # Register raw resistive touch driver

        import rtch
        touch = rtch.touch(xp = 32, yp = 33, xm = 25, ym = 26, touch_rail = 27, touch_sense = 33)
        touch.init()
        indev_drv = lv.indev_drv_t()
        lv.indev_drv_init(indev_drv) 
        indev_drv.type = lv.INDEV_TYPE.POINTER;
        indev_drv.read = touch.read;
        lv.indev_drv_register(indev_drv);
Ejemplo n.º 4
0
    def init_gui_stm32(self):
        import rk043fn48h as lcd
        import lvstm32

        hres = 480
        vres = 272

        # Register display driver
        tick = lvstm32.lvstm32()
        lcd.init(w=hres, h=vres)
        disp_buf1 = lv.disp_buf_t()
        buf1_1 = lcd.framebuffer(1)
        buf1_2 = lcd.framebuffer(2)
        lv.disp_buf_init(disp_buf1, buf1_1, buf1_2, len(buf1_1) // lv.color_t.SIZE)
        disp_drv = lv.disp_drv_t()
        lv.disp_drv_init(disp_drv)
        disp_drv.buffer = disp_buf1
        disp_drv.flush_cb = lcd.flush
        disp_drv.gpu_blend_cb = lcd.gpu_blend
        disp_drv.gpu_fill_cb = lcd.gpu_fill
        disp_drv.hor_res = hres
        disp_drv.ver_res = vres
        lv.disp_drv_register(disp_drv)

        # Register touch sensor
        indev_drv = lv.indev_drv_t()
        lv.indev_drv_init(indev_drv)
        indev_drv.type = lv.INDEV_TYPE.POINTER
        indev_drv.read_cb = lcd.ts_read
        lv.indev_drv_register(indev_drv)
Ejemplo n.º 5
0
 def init_disp_drv(self, flush, hor_res, ver_res, buf_size = 0):
     disp_buf1 = lv.disp_buf_t()
     if not buf_size: buf_size = (hor_res*ver_res)//4
     buf1_1 = bytearray(buf_size)
     lv.disp_buf_init(disp_buf1,buf1_1, None, len(buf1_1)//4)
     disp_drv = lv.disp_drv_t()
     lv.disp_drv_init(disp_drv)
     disp_drv.buffer = disp_buf1
     disp_drv.flush_cb = flush
     disp_drv.hor_res = hor_res
     disp_drv.ver_res = ver_res
     lv.disp_drv_register(disp_drv)
Ejemplo n.º 6
0
    def __init__(self,
                 miso=5,
                 mosi=18,
                 clk=19,
                 cs=13,
                 dc=12,
                 rst=4,
                 backlight=2,
                 spihost=esp.enum.HSPI_HOST,
                 mhz=40,
                 factor=5):

        # Make sure Micropython was built such that color won't require processing before DMA

        if lv.color_t.SIZE != 2:
            raise RuntimeError(
                'ili9341 micropython driver requires defining LV_COLOR_DEPTH=16'
            )
        if not hasattr(lv.color_t().ch, 'green_l'):
            raise RuntimeError(
                'ili9341 micropython driver requires defining LV_COLOR_16_SWAP=1'
            )

        # Initializations

        self.miso = miso
        self.mosi = mosi
        self.clk = clk
        self.cs = cs
        self.dc = dc
        self.rst = rst
        self.backlight = backlight
        self.spihost = spihost
        self.mhz = mhz

        self.init()

        # Register display driver

        buf_size = (self.width * self.height * lv.color_t.SIZE) // factor

        lv.disp_buf_init(self.disp_buf, bytearray(buf_size),
                         bytearray(buf_size), buf_size // lv.color_t.SIZE)
        lv.disp_drv_init(self.disp_drv)

        self.disp_drv.buffer = self.disp_buf
        self.disp_drv.flush_cb = self.flush
        self.disp_drv.monitor_cb = self.monitor
        self.disp_drv.hor_res = self.width
        self.disp_drv.ver_res = self.height

        lv.disp_drv_register(self.disp_drv)
Ejemplo n.º 7
0
    def init_gui(self):
        import lvgl as lv
        import lvgl_helper as lv_h
        import lcd
        import time
        from machine import I2C

        config_touchscreen_support = True
        board_m1n = False

        i2c = I2C(I2C.I2C0, freq=400000, scl=30, sda=31)
        if not board_m1n:
            lcd.init()
        else:
            lcd.init(type=2, freq=20000000)
        if config_touchscreen_support:
            import touchscreen as ts
            ts.init(i2c)
        lv.init()

        disp_buf1 = lv.disp_buf_t()
        buf1_1 = bytearray(320 * 10)
        lv.disp_buf_init(disp_buf1, buf1_1, None, len(buf1_1) // 4)
        disp_drv = lv.disp_drv_t()
        lv.disp_drv_init(disp_drv)
        disp_drv.buffer = disp_buf1
        disp_drv.flush_cb = lv_h.flush
        if board_m1n:
            disp_drv.hor_res = 240
            disp_drv.ver_res = 240
        else:
            disp_drv.hor_res = 320
            disp_drv.ver_res = 240
        lv.disp_drv_register(disp_drv)

        if config_touchscreen_support:
            indev_drv = lv.indev_drv_t()
            lv.indev_drv_init(indev_drv)
            indev_drv.type = lv.INDEV_TYPE.POINTER
            indev_drv.read_cb = lv_h.read
            lv.indev_drv_register(indev_drv)

        # lv.log_register_print_cb(lv_h.log)
        lv.log_register_print_cb(lambda level, path, line, msg: print(
            '%s(%d): %s' % (path, line, msg)))

        # Create the main screen and load it.

        self.screen_main = Screen_Main(self)
        lv.scr_load(self.screen_main)
    def __init__(self, miso=5, mosi=18, clk=19, cs=13, dc=12, rst=4, backlight=2, spihost=esp.enum.HSPI_HOST, mhz=40, factor=4, hybrid=True):

        # Make sure Micropython was built such that color won't require processing before DMA

        if lv.color_t.SIZE != 2:
            raise RuntimeError('ili9341 micropython driver requires defining LV_COLOR_DEPTH=16')
        if not hasattr(lv.color_t().ch, 'green_l'):
            raise RuntimeError('ili9341 micropython driver requires defining LV_COLOR_16_SWAP=1')

        # Initializations

        self.miso = miso
        self.mosi = mosi
        self.clk = clk
        self.cs = cs
        self.dc = dc
        self.rst = rst
        self.backlight = backlight
        self.spihost = spihost
        self.mhz = mhz
        self.factor = factor
        self.hybrid = hybrid

        self.buf_size = (self.width * self.height * lv.color_t.SIZE) // factor

        self.init()

        # Register display driver 

        self.buf1 = esp.heap_caps_malloc(self.buf_size, esp.CAP.DMA)
        self.buf2 = esp.heap_caps_malloc(self.buf_size, esp.CAP.DMA)
        
        if self.buf1 and self.buf2:
            print("Double buffer")
        elif self.buf1:
            print("Single buffer")
        else:
            raise RuntimeError("Not enough DMA-able memory to allocate display buffer")

        lv.disp_buf_init(self.disp_buf, self.buf1, self.buf2, self.buf_size // lv.color_t.SIZE)
        lv.disp_drv_init(self.disp_drv)

        self.disp_drv.user_data = {'dc': self.dc, 'spi': self.spi}
        self.disp_drv.buffer = self.disp_buf
        self.disp_drv.flush_cb = esp.ili9341_flush if self.hybrid and hasattr(esp, 'ili9341_flush') else self.flush
        self.disp_drv.monitor_cb = self.monitor
        self.disp_drv.hor_res = self.width
        self.disp_drv.ver_res = self.height
        
        lv.disp_drv_register(self.disp_drv)
    async def run_display(self):
        # Initialize the ILI9341 driver
        # spihost:  1=HSPI 2=VSPI
        # Workaround note:  need to initialize the SPI bus before initializing LittlevGL
        # SPI bus init was taken out of LittlevGL for streetsense design...should fix this.  TODO
        # SPI bus initialization is done when the SD Card is initialized 
        # (must be called before display initialization) 
        
        disp = ili.display(spihost=1, miso=19, mosi=23, clk=18, cs=22, dc=21, mhz=25, share=ili.SHARED)
        disp.init()
        
        self.backlight_ctrl.value(0)  # note: init() turns on backlight

        # Register display driver to LittlevGL
        # ... Start boilerplate magic
        disp_buf1 = lv.disp_buf_t()
        buf1_1 = bytearray(320*10)
        lv.disp_buf_init(disp_buf1,buf1_1, None, len(buf1_1)//4)
        disp_drv = lv.disp_drv_t()
        lv.disp_drv_init(disp_drv)
        disp_drv.buffer = disp_buf1
        disp_drv.flush_cb = disp.flush
        disp_drv.hor_res = 320  
        disp_drv.ver_res = 240
        disp_drv.rotated = 0
        lv.disp_drv_register(disp_drv)  
        # ... End boilerplate magic   
                   
        await self.show_welcome_screens()
        
        # continually refresh the active screen
        # detect screen change coming from a button press
        # detect screen timeout
        while True:
            if (self.next_screen != self.active_screen):
                self.active_screen = self.next_screen
                self.screen_timeout = False
                if modes[operating_mode].display == 'timeout':
                    self.timeout_timer.init(period=Display.SCREEN_TIMEOUT_IN_S * 1000, 
                                            mode=Timer.ONE_SHOT, 
                                            callback=self.screen_timeout_callback)
                
            elif (self.screen_timeout == True):
                self.next_screen = len(self.screens) - 1
            
            # display the active screen    
            await self.screens[self.active_screen]()
            await asyncio.sleep(Display.SCREEN_REFRESH_IN_S)                    
 def _register_disp_drv(self):
     # Init buffer
     self._disp_buf = lv.disp_buf_t()
     self._buf_1 = bytearray(DISP_BUF_SIZE)
     self._buf_2 = bytearray(DISP_BUF_SIZE)
     self._disp_drv = lv.disp_drv_t()
     lv.disp_buf_init(self._disp_buf, self._buf_1, self._buf_2,
                      DISP_BUF_SIZE // 4)
     # Register display driver
     lv.disp_drv_init(self._disp_drv)
     self._disp_drv.buffer = self._disp_buf
     self._disp_drv.flush_cb = self._tft.flush
     self._disp_drv.hor_res = 480
     self._disp_drv.ver_res = 320
     self._disp = lv.disp_drv_register(self._disp_drv)
     return
Ejemplo n.º 11
0
 def __init__(self):
     disp_buf1 = lv.disp_buf_t()
     buf1_1 = bytearray(390 * 32)
     lv.disp_buf_init(disp_buf1, buf1_1, None, len(buf1_1) // 4)
     disp_drv = lv.disp_drv_t()
     lv.disp_drv_init(disp_drv)
     disp_drv.buffer = disp_buf1
     disp_drv.flush_cb = display.flush
     disp_drv.hor_res = 390
     disp_drv.ver_res = 390
     lv.disp_drv_register(disp_drv)
     touchscreen.init()
     indev_drv = lv.indev_drv_t()
     lv.indev_drv_init(indev_drv)
     indev_drv.type = lv.INDEV_TYPE.POINTER
     indev_drv.read_cb = touchscreen.touchscreen_read
     lv.indev_drv_register(indev_drv)
Ejemplo n.º 12
0
def init():
    """
    GUI initialization function. 
    Should be called once in the very beginning.
    """

    # init the gui library
    lv.init()
    # init the hardware library
    SDL.init()

    # Register SDL display driver
    disp_buf1 = lv.disp_buf_t()
    buf1_1 = bytearray(HOR_RES*10)
    lv.disp_buf_init(disp_buf1,buf1_1, None, len(buf1_1)//4)
    disp_drv = lv.disp_drv_t()
    lv.disp_drv_init(disp_drv)
    disp_drv.buffer = disp_buf1
    disp_drv.flush_cb = SDL.monitor_flush
    disp_drv.hor_res = HOR_RES
    disp_drv.ver_res = VER_RES
    lv.disp_drv_register(disp_drv)

    # Regsiter SDL mouse driver
    indev_drv = lv.indev_drv_t()
    lv.indev_drv_init(indev_drv) 
    indev_drv.type = lv.INDEV_TYPE.POINTER;
    indev_drv.read_cb = SDL.mouse_read;
    lv.indev_drv_register(indev_drv);

    # Set up material theme
    # First argument (210) is a hue - theme color shift,
    # Second - default font to use. Builtin: roboto_16, roboto_28
    th = lv.theme_material_init(210, lv.font_roboto_22)
    lv.theme_set_current(th)

    # Create a screen and load it
    # To access active screen use lv.scr_act()
    scr = lv.obj()
    lv.scr_load(scr)

    # Initialize the styles
    styles["title"] = lv.style_t()
    # Title style - just a default style with larger font
    lv.style_copy(styles["title"], lv.style_plain)
    styles["title"].text.font = lv.font_roboto_28
Ejemplo n.º 13
0
def screen_init():
    sda_pin = machine.Pin(23)
    scl_pin = machine.Pin(32)

    i2c = machine.I2C(id=1, scl=scl_pin, sda=sda_pin, speed=400000)
    ts.init(i2c)

    tft.init(tft.ST7789, width=240, invrot=3, rot=1, bgr=False, height=240, miso=2, mosi=19, clk=18, cs=5, dc=27,
             speed=40000000, color_bits=tft.COLOR_BITS16, backl_pin=12, backl_on=1)

    tft.clear(tft.RED)
    time.sleep(1)
    tft.clear(tft.GREEN)
    time.sleep(1)
    tft.clear(tft.BLUE)
    time.sleep(1)

    lv.init()
    disp_buf1 = lv.disp_buf_t()
    buf1_1 = bytes(240 * 10)
    lv.disp_buf_init(disp_buf1, buf1_1, None, len(buf1_1) // 4)
    disp_drv = lv.disp_drv_t()
    lv.disp_drv_init(disp_drv)
    disp_drv.buffer = disp_buf1
    disp_drv.flush_cb = lv_h.flush
    disp_drv.hor_res = 240
    disp_drv.ver_res = 240
    lv.disp_drv_register(disp_drv)

    indev_drv = lv.indev_drv_t()
    lv.indev_drv_init(indev_drv)
    indev_drv.type = lv.INDEV_TYPE.POINTER
    indev_drv.read_cb = lv_h.read
    lv.indev_drv_register(indev_drv)

    scr = lv.obj()
    btn = lv.btn(scr)
    btn.align(lv.scr_act(), lv.ALIGN.CENTER, 0, 0)
    label = lv.label(btn)
    label.set_text("Button")
    lv.scr_load(scr)
Ejemplo n.º 14
0
    def init_gui_SDL(self):

        import SDL
        SDL.init()

        # Register SDL display driver.

        disp_drv = lv.disp_drv_t()
        lv.disp_drv_init(disp_drv)
        disp_drv.disp_flush = SDL.monitor_flush
        disp_drv.disp_fill = SDL.monitor_fill
        disp_drv.disp_map = SDL.monitor_map
        lv.disp_drv_register(disp_drv)

        # Regsiter SDL mouse driver

        indev_drv = lv.indev_drv_t()
        lv.indev_drv_init(indev_drv) 
        indev_drv.type = lv.INDEV_TYPE.POINTER;
        indev_drv.read = SDL.mouse_read;
        lv.indev_drv_register(indev_drv);
Ejemplo n.º 15
0
def init(autoupdate=True):
    import lvgl as lv
    import SDL

    HOR_RES = 480
    VER_RES = 800
    """
    GUI initialization function. 
    Should be called once in the very beginning.
    """

    # init the gui library
    lv.init()
    # init the hardware library
    SDL.init()

    # Register SDL display driver
    disp_buf1 = lv.disp_buf_t()
    buf1_1 = bytearray(HOR_RES * 10)
    lv.disp_buf_init(disp_buf1, buf1_1, None, len(buf1_1) // 4)
    disp_drv = lv.disp_drv_t()
    lv.disp_drv_init(disp_drv)
    disp_drv.buffer = disp_buf1
    disp_drv.flush_cb = SDL.monitor_flush
    disp_drv.hor_res = HOR_RES
    disp_drv.ver_res = VER_RES
    lv.disp_drv_register(disp_drv)

    # Regsiter SDL mouse driver
    indev_drv = lv.indev_drv_t()
    lv.indev_drv_init(indev_drv)
    indev_drv.type = lv.INDEV_TYPE.POINTER
    indev_drv.read_cb = SDL.mouse_read
    lv.indev_drv_register(indev_drv)

    scr = lv.obj()
    lv.scr_load(scr)
    if autoupdate:
        import SDL
        SDL.enable_autoupdate()
Ejemplo n.º 16
0
    return False

if config_touchscreen_support:
    i2c = I2C(I2C.I2C0, freq=1000*1000, scl=24, sda=27)  # 24 27)
    devices = i2c.scan()
    print("devs", devices)  # devs 0 [16, 38, 52, 56]
    TouchLow.config(i2c)
    TOUCH = Touch(480, 320, 200)

lv.init()

disp_buf1 = lv.disp_buf_t()
buf1_1 = bytearray(320*10)
lv.disp_buf_init(disp_buf1,buf1_1, None, len(buf1_1)//4)
disp_drv = lv.disp_drv_t()
lv.disp_drv_init(disp_drv)
disp_drv.buffer = disp_buf1

disp_drv.flush_cb = lv_h.flush
if board_m1n:
    disp_drv.hor_res = 240
    disp_drv.ver_res = 240
else:
    disp_drv.hor_res = 480
    disp_drv.ver_res = 320
lv.disp_drv_register(disp_drv)

if config_touchscreen_support:
    indev_drv = lv.indev_drv_t()
    lv.indev_drv_init(indev_drv)
    indev_drv.type = lv.INDEV_TYPE.POINTER
Ejemplo n.º 17
0
    def __init__(self,
                 miso=5,
                 mosi=18,
                 clk=19,
                 cs=13,
                 dc=12,
                 rst=4,
                 power=14,
                 backlight=15,
                 backlight_on=0,
                 power_on=0,
                 spihost=esp.HSPI_HOST,
                 mhz=40,
                 factor=4,
                 hybrid=True,
                 width=240,
                 height=320,
                 colormode=COLOR_MODE_BGR,
                 rot=PORTRAIT,
                 invert=False,
                 double_buffer=True):

        # Make sure Micropython was built such that color won't require processing before DMA

        if lv.color_t.SIZE != 2:
            raise RuntimeError(
                'ili9341 micropython driver requires defining LV_COLOR_DEPTH=16'
            )
        if colormode == COLOR_MODE_BGR and not hasattr(lv.color_t().ch,
                                                       'green_l'):
            raise RuntimeError(
                'ili9341 BGR color mode requires defining LV_COLOR_16_SWAP=1')

        # Initializations

        self.width = width
        self.height = height

        self.miso = miso
        self.mosi = mosi
        self.clk = clk
        self.cs = cs
        self.dc = dc
        self.rst = rst
        self.power = power
        self.backlight = backlight
        self.backlight_on = backlight_on
        self.power_on = power_on
        self.spihost = spihost
        self.mhz = mhz
        self.factor = factor
        self.hybrid = hybrid

        self.buf_size = (self.width * self.height * lv.color_t.SIZE) // factor

        self.init_cmds = [
            {
                'cmd': 0xCF,
                'data': bytes([0x00, 0x83, 0X30])
            },
            {
                'cmd': 0xED,
                'data': bytes([0x64, 0x03, 0X12, 0X81])
            },
            {
                'cmd': 0xE8,
                'data': bytes([0x85, 0x01, 0x79])
            },
            {
                'cmd': 0xCB,
                'data': bytes([0x39, 0x2C, 0x00, 0x34, 0x02])
            },
            {
                'cmd': 0xF7,
                'data': bytes([0x20])
            },
            {
                'cmd': 0xEA,
                'data': bytes([0x00, 0x00])
            },
            {
                'cmd': 0xC0,
                'data': bytes([0x26])
            },  # Power control
            {
                'cmd': 0xC1,
                'data': bytes([0x11])
            },  # Power control
            {
                'cmd': 0xC5,
                'data': bytes([0x35, 0x3E])
            },  # VCOM control
            {
                'cmd': 0xC7,
                'data': bytes([0xBE])
            },  # VCOM control
            {
                'cmd': 0x36,
                'data': bytes([rot | colormode])
            },  # Memory Access Control
            {
                'cmd': 0x3A,
                'data': bytes([0x55])
            },  # Pixel Format Set
            {
                'cmd': 0xB1,
                'data': bytes([0x00, 0x1B])
            },
            {
                'cmd': 0xF2,
                'data': bytes([0x08])
            },
            {
                'cmd': 0x26,
                'data': bytes([0x01])
            },
            {
                'cmd':
                0xE0,
                'data':
                bytes([
                    0x1F, 0x1A, 0x18, 0x0A, 0x0F, 0x06, 0x45, 0X87, 0x32, 0x0A,
                    0x07, 0x02, 0x07, 0x05, 0x00
                ])
            },
            {
                'cmd':
                0XE1,
                'data':
                bytes([
                    0x00, 0x25, 0x27, 0x05, 0x10, 0x09, 0x3A, 0x78, 0x4D, 0x05,
                    0x18, 0x0D, 0x38, 0x3A, 0x1F
                ])
            },
            {
                'cmd': 0x2A,
                'data': bytes([0x00, 0x00, 0x00, 0xEF])
            },
            {
                'cmd': 0x2B,
                'data': bytes([0x00, 0x00, 0x01, 0x3f])
            },
            {
                'cmd': 0x2C,
                'data': bytes([0])
            },
            {
                'cmd': 0xB7,
                'data': bytes([0x07])
            },
            {
                'cmd': 0xB6,
                'data': bytes([0x0A, 0x82, 0x27, 0x00])
            },
            {
                'cmd': 0x11,
                'data': bytes([0]),
                'delay': 100
            },
            {
                'cmd': 0x29,
                'data': bytes([0]),
                'delay': 100
            }
        ]

        if invert:
            self.init_cmds.append({'cmd': 0x21})

        self.init()

        # Register display driver

        self.buf1 = esp.heap_caps_malloc(self.buf_size, esp.MALLOC_CAP.DMA)
        self.buf2 = esp.heap_caps_malloc(
            self.buf_size, esp.MALLOC_CAP.DMA) if double_buffer else None

        if self.buf1 and self.buf2:
            print("Double buffer")
        elif self.buf1:
            print("Single buffer")
        else:
            raise RuntimeError(
                "Not enough DMA-able memory to allocate display buffer")

        self.disp_buf = lv.disp_buf_t()
        self.disp_drv = lv.disp_drv_t()

        lv.disp_buf_init(self.disp_buf, self.buf1, self.buf2,
                         self.buf_size // lv.color_t.SIZE)
        lv.disp_drv_init(self.disp_drv)

        self.disp_drv.user_data = {'dc': self.dc, 'spi': self.spi}
        self.disp_drv.buffer = self.disp_buf
        self.disp_drv.flush_cb = esp.ili9341_flush if self.hybrid and hasattr(
            esp, 'ili9341_flush') else self.flush
        self.disp_drv.monitor_cb = self.monitor
        self.disp_drv.hor_res = self.width
        self.disp_drv.ver_res = self.height

        lv.disp_drv_register(self.disp_drv)