From 1721f67ec37d106e7edaa3b397ea3280d49c0a37 Mon Sep 17 00:00:00 2001 From: Evg33 <evg33@evg33.ru> Date: Fri, 6 Dec 2019 03:24:01 +0300 Subject: [PATCH] fr waveshare.com/1.44inch-lcd-hat --- pwnagotchi/defaults.yml | 2 +- pwnagotchi/ui/display.py | 3 + pwnagotchi/ui/hw/__init__.py | 4 + .../hw/libs/waveshare/lcdhat144/LCD_1in44.py | 319 ++++++++++++++++++ .../hw/libs/waveshare/lcdhat144/__init__.py | 0 .../ui/hw/libs/waveshare/lcdhat144/config.py | 73 ++++ .../ui/hw/libs/waveshare/lcdhat144/epd.py | 32 ++ pwnagotchi/ui/hw/waveshare144lcd.py | 46 +++ pwnagotchi/utils.py | 3 + 9 files changed, 481 insertions(+), 1 deletion(-) create mode 100644 pwnagotchi/ui/hw/libs/waveshare/lcdhat144/LCD_1in44.py create mode 100644 pwnagotchi/ui/hw/libs/waveshare/lcdhat144/__init__.py create mode 100644 pwnagotchi/ui/hw/libs/waveshare/lcdhat144/config.py create mode 100644 pwnagotchi/ui/hw/libs/waveshare/lcdhat144/epd.py create mode 100644 pwnagotchi/ui/hw/waveshare144lcd.py diff --git a/pwnagotchi/defaults.yml b/pwnagotchi/defaults.yml index 60be285..a41650d 100644 --- a/pwnagotchi/defaults.yml +++ b/pwnagotchi/defaults.yml @@ -260,7 +260,7 @@ ui: display: enabled: true rotation: 180 - # Possible options inkyphat/inky, papirus/papi, waveshare_1/ws_1 or waveshare_2/ws_2, oledhat, lcdhat, waveshare154inch, waveshare27inch, waveshare29inch, dfrobot/df + # Possible options inkyphat/inky, papirus/papi, waveshare_1/ws_1 or waveshare_2/ws_2, oledhat, lcdhat, waveshare154inch, waveshare27inch, waveshare29inch, dfrobot/df, waveshare144lcd/ws144inch type: 'waveshare_2' # Possible options red/yellow/black (black used for monocromatic displays) # Waveshare tri-color 2.13in display can be over-driven with color set as 'fastAndFurious' diff --git a/pwnagotchi/ui/display.py b/pwnagotchi/ui/display.py index a6789d5..9ef8774 100644 --- a/pwnagotchi/ui/display.py +++ b/pwnagotchi/ui/display.py @@ -52,6 +52,9 @@ class Display(View): def is_dfrobot(self): return self._implementation.name == 'dfrobot' + def is_waveshare144lcd(self): + return self._implementation.name == 'waveshare144lcd' + def is_waveshare154inch(self): return self._implementation.name == 'waveshare154inch' diff --git a/pwnagotchi/ui/hw/__init__.py b/pwnagotchi/ui/hw/__init__.py index 1bbb602..696a41f 100644 --- a/pwnagotchi/ui/hw/__init__.py +++ b/pwnagotchi/ui/hw/__init__.py @@ -7,6 +7,7 @@ from pwnagotchi.ui.hw.waveshare1 import WaveshareV1 from pwnagotchi.ui.hw.waveshare2 import WaveshareV2 from pwnagotchi.ui.hw.waveshare27inch import Waveshare27inch from pwnagotchi.ui.hw.waveshare29inch import Waveshare29inch +from pwnagotchi.ui.hw.waveshare144lcd import Waveshare144lcd from pwnagotchi.ui.hw.waveshare154inch import Waveshare154inch from pwnagotchi.ui.hw.waveshare213d import Waveshare213d from pwnagotchi.ui.hw.spotpear24inch import Spotpear24inch @@ -40,6 +41,9 @@ def display_for(config): elif config['ui']['display']['type'] == 'waveshare29inch': return Waveshare29inch(config) + elif config['ui']['display']['type'] == 'waveshare144lcd': + return Waveshare144lcd(config) + elif config['ui']['display']['type'] == 'waveshare154inch': return Waveshare154inch(config) diff --git a/pwnagotchi/ui/hw/libs/waveshare/lcdhat144/LCD_1in44.py b/pwnagotchi/ui/hw/libs/waveshare/lcdhat144/LCD_1in44.py new file mode 100644 index 0000000..26f4850 --- /dev/null +++ b/pwnagotchi/ui/hw/libs/waveshare/lcdhat144/LCD_1in44.py @@ -0,0 +1,319 @@ + # -*- coding:UTF-8 -*- + ## + # | file : LCD_1IN44.py + # | version : V2.0 + # | date : 2018-07-16 + # | function : On the ST7735S chip driver and clear screen, drawing lines, drawing, writing + # and other functions to achieve + # + # Permission is hereby granted, free of charge, to any person obtaining a copy + # of this software and associated documnetation files (the "Software"), to deal + # in the Software without restriction, including without limitation the rights + # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + # copies of the Software, and to permit persons to whom the Software is + # furished to do so, subject to the following conditions: + # + # The above copyright notice and this permission notice shall be included in + # all copies or substantial portions of the Software. + # + # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + # FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + # LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + # THE SOFTWARE. + # + + +import RPi.GPIO as GPIO +import time +import numpy as np +from . import config + +LCD_1IN44 = 1 +LCD_1IN8 = 0 +if LCD_1IN44 == 1: + LCD_WIDTH = 128 #LCD width + LCD_HEIGHT = 128 #LCD height + LCD_X = 2 + LCD_Y = 1 +if LCD_1IN8 == 1: + LCD_WIDTH = 160 + LCD_HEIGHT = 128 + LCD_X = 1 + LCD_Y = 2 + +LCD_X_MAXPIXEL = 132 #LCD width maximum memory +LCD_Y_MAXPIXEL = 162 #LCD height maximum memory + +#scanning method +L2R_U2D = 1 +L2R_D2U = 2 +R2L_U2D = 3 +R2L_D2U = 4 +U2D_L2R = 5 +U2D_R2L = 6 +D2U_L2R = 7 +D2U_R2L = 8 +SCAN_DIR_DFT = U2D_R2L + + +class LCD: + def __init__(self): + GPIO.setmode(GPIO.BCM) + self.width = LCD_WIDTH + self.height = LCD_HEIGHT + self.LCD_Scan_Dir = SCAN_DIR_DFT + self.LCD_X_Adjust = LCD_X + self.LCD_Y_Adjust = LCD_Y + + """ Hardware reset """ + def LCD_Reset(self): + GPIO.output(config.LCD_RST_PIN, GPIO.HIGH) + config.Driver_Delay_ms(100) + GPIO.output(config.LCD_RST_PIN, GPIO.LOW) + config.Driver_Delay_ms(100) + GPIO.output(config.LCD_RST_PIN, GPIO.HIGH) + config.Driver_Delay_ms(100) + + """ Write register address and data """ + def LCD_WriteReg(self, Reg): + GPIO.setmode(GPIO.BCM) + GPIO.setup(config.LCD_DC_PIN, GPIO.OUT) + GPIO.output(config.LCD_DC_PIN, GPIO.LOW) + config.SPI_Write_Byte([Reg]) + + def LCD_WriteData_8bit(self, Data): + GPIO.output(config.LCD_DC_PIN, GPIO.HIGH) + config.SPI_Write_Byte([Data]) + + def LCD_WriteData_NLen16Bit(self, Data, DataLen): + GPIO.output(config.LCD_DC_PIN, GPIO.HIGH) + for i in range(0, DataLen): + config.SPI_Write_Byte([Data >> 8]) + config.SPI_Write_Byte([Data & 0xff]) + + """ Common register initialization """ + def LCD_InitReg(self): + #ST7735R Frame Rate + self.LCD_WriteReg(0xB1) + self.LCD_WriteData_8bit(0x01) + self.LCD_WriteData_8bit(0x2C) + self.LCD_WriteData_8bit(0x2D) + + self.LCD_WriteReg(0xB2) + self.LCD_WriteData_8bit(0x01) + self.LCD_WriteData_8bit(0x2C) + self.LCD_WriteData_8bit(0x2D) + + self.LCD_WriteReg(0xB3) + self.LCD_WriteData_8bit(0x01) + self.LCD_WriteData_8bit(0x2C) + self.LCD_WriteData_8bit(0x2D) + self.LCD_WriteData_8bit(0x01) + self.LCD_WriteData_8bit(0x2C) + self.LCD_WriteData_8bit(0x2D) + + #Column inversion + self.LCD_WriteReg(0xB4) + self.LCD_WriteData_8bit(0x07) + + #ST7735R Power Sequence + self.LCD_WriteReg(0xC0) + self.LCD_WriteData_8bit(0xA2) + self.LCD_WriteData_8bit(0x02) + self.LCD_WriteData_8bit(0x84) + self.LCD_WriteReg(0xC1) + self.LCD_WriteData_8bit(0xC5) + + self.LCD_WriteReg(0xC2) + self.LCD_WriteData_8bit(0x0A) + self.LCD_WriteData_8bit(0x00) + + self.LCD_WriteReg(0xC3) + self.LCD_WriteData_8bit(0x8A) + self.LCD_WriteData_8bit(0x2A) + self.LCD_WriteReg(0xC4) + self.LCD_WriteData_8bit(0x8A) + self.LCD_WriteData_8bit(0xEE) + + self.LCD_WriteReg(0xC5)#VCOM + self.LCD_WriteData_8bit(0x0E) + + #ST7735R Gamma Sequence + self.LCD_WriteReg(0xe0) + self.LCD_WriteData_8bit(0x0f) + self.LCD_WriteData_8bit(0x1a) + self.LCD_WriteData_8bit(0x0f) + self.LCD_WriteData_8bit(0x18) + self.LCD_WriteData_8bit(0x2f) + self.LCD_WriteData_8bit(0x28) + self.LCD_WriteData_8bit(0x20) + self.LCD_WriteData_8bit(0x22) + self.LCD_WriteData_8bit(0x1f) + self.LCD_WriteData_8bit(0x1b) + self.LCD_WriteData_8bit(0x23) + self.LCD_WriteData_8bit(0x37) + self.LCD_WriteData_8bit(0x00) + self.LCD_WriteData_8bit(0x07) + self.LCD_WriteData_8bit(0x02) + self.LCD_WriteData_8bit(0x10) + + self.LCD_WriteReg(0xe1) + self.LCD_WriteData_8bit(0x0f) + self.LCD_WriteData_8bit(0x1b) + self.LCD_WriteData_8bit(0x0f) + self.LCD_WriteData_8bit(0x17) + self.LCD_WriteData_8bit(0x33) + self.LCD_WriteData_8bit(0x2c) + self.LCD_WriteData_8bit(0x29) + self.LCD_WriteData_8bit(0x2e) + self.LCD_WriteData_8bit(0x30) + self.LCD_WriteData_8bit(0x30) + self.LCD_WriteData_8bit(0x39) + self.LCD_WriteData_8bit(0x3f) + self.LCD_WriteData_8bit(0x00) + self.LCD_WriteData_8bit(0x07) + self.LCD_WriteData_8bit(0x03) + self.LCD_WriteData_8bit(0x10) + + #Enable test command + self.LCD_WriteReg(0xF0) + self.LCD_WriteData_8bit(0x01) + + #Disable ram power save mode + self.LCD_WriteReg(0xF6) + self.LCD_WriteData_8bit(0x00) + + #65k mode + self.LCD_WriteReg(0x3A) + self.LCD_WriteData_8bit(0x05) + + #******************************************************************************** + #function: Set the display scan and color transfer modes + #parameter: + # Scan_dir : Scan direction + # Colorchose : RGB or GBR color format + #******************************************************************************** + def LCD_SetGramScanWay(self, Scan_dir): + #Get the screen scan direction + self.LCD_Scan_Dir = Scan_dir + + #Get GRAM and LCD width and height + if (Scan_dir == L2R_U2D) or (Scan_dir == L2R_D2U) or (Scan_dir == R2L_U2D) or (Scan_dir == R2L_D2U) : + self.width = LCD_HEIGHT + self.height = LCD_WIDTH + if Scan_dir == L2R_U2D: + MemoryAccessReg_Data = 0X00 | 0x00 + elif Scan_dir == L2R_D2U: + MemoryAccessReg_Data = 0X00 | 0x80 + elif Scan_dir == R2L_U2D: + MemoryAccessReg_Data = 0x40 | 0x00 + else: #R2L_D2U: + MemoryAccessReg_Data = 0x40 | 0x80 + else: + self.width = LCD_WIDTH + self.height = LCD_HEIGHT + if Scan_dir == U2D_L2R: + MemoryAccessReg_Data = 0X00 | 0x00 | 0x20 + elif Scan_dir == U2D_R2L: + MemoryAccessReg_Data = 0X00 | 0x40 | 0x20 + elif Scan_dir == D2U_L2R: + MemoryAccessReg_Data = 0x80 | 0x00 | 0x20 + else: #R2L_D2U + MemoryAccessReg_Data = 0x40 | 0x80 | 0x20 + + #please set (MemoryAccessReg_Data & 0x10) != 1 + if (MemoryAccessReg_Data & 0x10) != 1: + self.LCD_X_Adjust = LCD_Y + self.LCD_Y_Adjust = LCD_X + else: + self.LCD_X_Adjust = LCD_X + self.LCD_Y_Adjust = LCD_Y + + # Set the read / write scan direction of the frame memory + self.LCD_WriteReg(0x36) #MX, MY, RGB mode + if LCD_1IN44 == 1: + self.LCD_WriteData_8bit( MemoryAccessReg_Data | 0x08) #0x08 set RGB + else: + self.LCD_WriteData_8bit( MemoryAccessReg_Data & 0xf7) #RGB color filter panel + + #/******************************************************************************** + #function: + # initialization + #********************************************************************************/ + def LCD_Init(self, Lcd_ScanDir): + if (config.GPIO_Init() != 0): + return -1 + + #Turn on the backlight + #GPIO.setup(config.LCD_BL_PIN, GPIO.OUT) + GPIO.output(config.LCD_BL_PIN,GPIO.HIGH) + + #Hardware reset + self.LCD_Reset() + + #Set the initialization register + self.LCD_InitReg() + + #Set the display scan and color transfer modes + self.LCD_SetGramScanWay(Lcd_ScanDir) + config.Driver_Delay_ms(200) + + #sleep out + self.LCD_WriteReg(0x11) + config.Driver_Delay_ms(120) + + #Turn on the LCD display + self.LCD_WriteReg(0x29) + + #/******************************************************************************** + #function: Sets the start position and size of the display area + #parameter: + # Xstart : X direction Start coordinates + # Ystart : Y direction Start coordinates + # Xend : X direction end coordinates + # Yend : Y direction end coordinates + #********************************************************************************/ + def LCD_SetWindows(self, Xstart, Ystart, Xend, Yend): + #set the X coordinates + self.LCD_WriteReg(0x2A) + self.LCD_WriteData_8bit(0x00) + self.LCD_WriteData_8bit((Xstart & 0xff) + self.LCD_X_Adjust) + self.LCD_WriteData_8bit(0x00) + self.LCD_WriteData_8bit(((Xend - 1) & 0xff) + self.LCD_X_Adjust) + + #set the Y coordinates + self.LCD_WriteReg (0x2B) + self.LCD_WriteData_8bit(0x00) + self.LCD_WriteData_8bit((Ystart & 0xff) + self.LCD_Y_Adjust) + self.LCD_WriteData_8bit(0x00) + self.LCD_WriteData_8bit(((Yend - 1) & 0xff )+ self.LCD_Y_Adjust) + + self.LCD_WriteReg(0x2C) + + def LCD_Clear(self): + #hello + _buffer = [0xff]*(self.width * self.height * 2) + self.LCD_SetWindows(0, 0, self.width, self.height) + GPIO.output(config.LCD_DC_PIN, GPIO.HIGH) + for i in range(0,len(_buffer),4096): + config.SPI_Write_Byte(_buffer[i:i+4096]) + + def LCD_ShowImage(self,Image,Xstart,Ystart): + if (Image == None): + return + imwidth, imheight = Image.size + if imwidth != self.width or imheight != self.height: + raise ValueError('Image must be same dimensions as display \ + ({0}x{1}).' .format(self.width, self.height)) + img = np.asarray(Image) + pix = np.zeros((self.width,self.height,2), dtype = np.uint8) + pix[...,[0]] = np.add(np.bitwise_and(img[...,[0]],0xF8),np.right_shift(img[...,[1]],5)) + pix[...,[1]] = np.add(np.bitwise_and(np.left_shift(img[...,[1]],3),0xE0),np.right_shift(img[...,[2]],3)) + pix = pix.flatten().tolist() + self.LCD_SetWindows(0, 0, self.width , self.height) + GPIO.output(config.LCD_DC_PIN, GPIO.HIGH) + for i in range(0,len(pix),4096): + config.SPI_Write_Byte(pix[i:i+4096]) diff --git a/pwnagotchi/ui/hw/libs/waveshare/lcdhat144/__init__.py b/pwnagotchi/ui/hw/libs/waveshare/lcdhat144/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/pwnagotchi/ui/hw/libs/waveshare/lcdhat144/config.py b/pwnagotchi/ui/hw/libs/waveshare/lcdhat144/config.py new file mode 100644 index 0000000..83a6d9c --- /dev/null +++ b/pwnagotchi/ui/hw/libs/waveshare/lcdhat144/config.py @@ -0,0 +1,73 @@ +# /***************************************************************************** +# * | File : config.py +# * | Author : +# * | Info : +# *---------------- +# * | This version: V1.0 +# * | Date : 2019-12-06 +# * | Info : +# ******************************************************************************/ +Device_SPI = 1 +Device_I2C = 0 +Device = Device_SPI +#spi = spidev.SpiDev(0, 0) + +## + # @filename : DEV_Config.py + # @brief : LCD hardware interface implements (GPIO, SPI) + # @author : Yehui from Waveshare + # + # Copyright (C) Waveshare July 10 2017 + # + # Permission is hereby granted, free of charge, to any person obtaining a copy + # of this software and associated documnetation files (the "Software"), to deal + # in the Software without restriction, including without limitation the rights + # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + # copies of the Software, and to permit persons to whom the Software is + # furished to do so, subject to the following conditions: + # + # The above copyright notice and this permission notice shall be included in + # all copies or substantial portions of the Software. + # + # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + # FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + # LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + # THE SOFTWARE. + # + +import spidev +import RPi.GPIO as GPIO +import time + +# Pin definition +LCD_RST_PIN = 27 +LCD_DC_PIN = 25 +LCD_CS_PIN = 8 +LCD_BL_PIN = 24 + +# SPI device, bus = 0, device = 0 +SPI = spidev.SpiDev(0, 0) + +def epd_digital_write(pin, value): + GPIO.output(pin, value) + +def Driver_Delay_ms(xms): + time.sleep(xms / 1000.0) + +def SPI_Write_Byte(data): + SPI.writebytes(data) + +def GPIO_Init(): + GPIO.setmode(GPIO.BCM) + GPIO.setwarnings(False) + GPIO.setup(LCD_RST_PIN, GPIO.OUT) + GPIO.setup(LCD_DC_PIN, GPIO.OUT) + GPIO.setup(LCD_CS_PIN, GPIO.OUT) + GPIO.setup(LCD_BL_PIN, GPIO.OUT) + SPI.max_speed_hz = 9000000 + SPI.mode = 0b00 + return 0; +### END OF FILE ### diff --git a/pwnagotchi/ui/hw/libs/waveshare/lcdhat144/epd.py b/pwnagotchi/ui/hw/libs/waveshare/lcdhat144/epd.py new file mode 100644 index 0000000..2f6fbfd --- /dev/null +++ b/pwnagotchi/ui/hw/libs/waveshare/lcdhat144/epd.py @@ -0,0 +1,32 @@ +# Waveshare 1.44inch LCD HAT +# https://www.waveshare.com/1.44inch-lcd-hat.htm +# https://www.waveshare.com/wiki/1.44inch_LCD_HAT +# Driver: ST7735S +# Interface: SPI +# Display color: RGB, 65K color +# Resolution: 128x128 +# Backlight: LED +# Operating voltage: 3.3V + +from . import config +from . import LCD_1in44 +from PIL import ImageOps + +class EPD(object): + def __init__(self): + self.width = 128 + self.height = 128 + self.LCD = LCD_1in44.LCD() + self.LCD.Lcd_ScanDir = LCD_1in44.SCAN_DIR_DFT #SCAN_DIR_DFT = D2U_L2R + self.LCD.LCD_Init(self.LCD.Lcd_ScanDir) + + def init(self): + pass + + def clear(self): + #self.LCD.LCD_Clear() + pass + + def display(self, image): + rgb_im = ImageOps.colorize(image.convert("L"), black ="green", white ="black") + self.LCD.LCD_ShowImage(rgb_im, 0, 0) diff --git a/pwnagotchi/ui/hw/waveshare144lcd.py b/pwnagotchi/ui/hw/waveshare144lcd.py new file mode 100644 index 0000000..fb58de2 --- /dev/null +++ b/pwnagotchi/ui/hw/waveshare144lcd.py @@ -0,0 +1,46 @@ +import logging + +import pwnagotchi.ui.fonts as fonts +from pwnagotchi.ui.hw.base import DisplayImpl + + +class Waveshare144lcd(DisplayImpl): + def __init__(self, config): + super(Waveshare144lcd, self).__init__(config, 'waveshare144lcd') + self._display = None + + def layout(self): + fonts.setup(10, 8, 10, 18) + self._layout['width'] = 128 + self._layout['height'] = 128 + self._layout['face'] = (0, 43) + self._layout['name'] = (0, 14) + self._layout['channel'] = (0, 0) + self._layout['aps'] = (30, 0) + self._layout['uptime'] = (0, 25) + self._layout['line1'] = [0, 12, 127, 12] + self._layout['line2'] = [0, 116, 127, 116] + self._layout['friend_face'] = (14, 78) + self._layout['friend_name'] = (1, 103) + self._layout['shakes'] = (26, 117) + self._layout['mode'] = (0, 117) + self._layout['status'] = { + 'pos': (65, 26), + 'font': fonts.Small, + 'max': 12 + } + return self._layout + + def initialize(self): + logging.info("initializing waveshare 1.44 inch lcd display") + from pwnagotchi.ui.hw.libs.waveshare.lcdhat144.epd import EPD + self._display = EPD() + self._display.init() + self._display.clear() + + def render(self, canvas): + self._display.display(canvas) + + def clear(self): + pass + #self._display.clear() diff --git a/pwnagotchi/utils.py b/pwnagotchi/utils.py index 4384dc8..4d0ba90 100644 --- a/pwnagotchi/utils.py +++ b/pwnagotchi/utils.py @@ -109,6 +109,9 @@ def load_config(args): elif config['ui']['display']['type'] in ('ws_154inch', 'ws154inch', 'waveshare_154inch', 'waveshare154inch'): config['ui']['display']['type'] = 'waveshare154inch' + elif config['ui']['display']['type'] in ('waveshare144lcd', 'ws_144inch', 'ws144inch', 'waveshare_144inch', 'waveshare144inch'): + config['ui']['display']['type'] = 'waveshare144lcd' + elif config['ui']['display']['type'] in ('ws_213d', 'ws213d', 'waveshare_213d', 'waveshare213d'): config['ui']['display']['type'] = 'waveshare213d'