view gdew0154t8.py @ 3:985940300069 draft default tip

Add text
author Radomir Dopieralski <sheep-devel@sheep.art.pl>
date Thu, 05 Apr 2018 20:45:06 +0200
parents 48c60546eb7f
children
line wrap: on
line source

_FONT = (
    b'LLLLLLLB\x13BLLGKLGKLz3z3zLb3f3vL/wP"/L|7!r$LLLGKLLLr3\rLLL\r3rLLfP'
    b'rPfLDDrDDLLL\xfc<LLDDDDDLLL,,LL,tPBOLr3\x053rLL\x0e33\x0cL>7\x15\x03*Ln/'
    b'\x053zLP\x12;5\x1cL{+\t1wLr3\t1vLO=1COLz3\x053zLB\x13\x1d3rLLzzLLLL\xfa:'
    b'LLLDPz/\rLXXXXXL\r/zPDLNO\x15CJLp2\x0e\x16PL23_32L33\x053zLr3\r/nL33\r3r'
    b'L33\x1d\r/L33]MOLr3\r76L33\\33LL\r33\rL}=\r3sL33D;/L33\x0c\x0c,L32P23L32'
    b'Ps3Lr3\r3rL33]SBLr3-\xb3\xf2L33]3"Lj#\x057~LMM33MMs3\x0c3sLKS4SKL3sTs3L/'
    b';P;/LKC44CK?5\x11\x03+LL33\r\rLOBPt,L\r\r33LLPBKBPL,,,,,LLNKBLLt0\x0800L'
    b'33\x080tLt0\x08 dLt0\x0833Lt0\x18\x10TL\\\xb2\xb3]NLP\xf0\xe8\xb0\x94L33'
    b'H04LLH11LLL\xc8\xb11LL33\\ \x08LMs3\x0clL00p04L00H04Lt0\x080tL\xb0\xb0'
    b'\x080tLt0\x08\xb0\xb0L00H@@L\x14\x10\x188|LHr3\x08LLp0\x0c00LPp\x0cpPLp0'
    b'|0pL  t  LP\xf0\xec\xb00L(80\x10\x00LLDf3;\rLL33LL\r;3fDLBOC@KL')

_LUT_FULL = (
    b'\x00\x08\x00\x00\x00\x02' b'\x60\x28\x28\x00\x00\x01'
    b'\x00\x14\x00\x00\x00\x01' b'\x00\x12\x12\x00\x00\x01'
    b'\x00\x00\x00\x00\x00\x00' b'\x00\x00\x00\x00\x00\x00'
    b'\x00\x00\x00\x00\x00\x00' b'\x00\x00',  # VCOM
    b'\x40\x08\x00\x00\x00\x02' b'\x90\x28\x28\x00\x00\x01'
    b'\x40\x14\x00\x00\x00\x01' b'\xA0\x12\x12\x00\x00\x01'
    b'\x00\x00\x00\x00\x00\x00' b'\x00\x00\x00\x00\x00\x00'
    b'\x00\x00\x00\x00\x00\x00',  # white to white
    b'\x40\x17\x00\x00\x00\x02' b'\x90\x0F\x0F\x00\x00\x03'
    b'\x40\x0A\x01\x00\x00\x01' b'\xA0\x0E\x0E\x00\x00\x02'
    b'\x00\x00\x00\x00\x00\x00' b'\x00\x00\x00\x00\x00\x00'
    b'\x00\x00\x00\x00\x00\x00',  # black to white
    b'\x80\x08\x00\x00\x00\x02' b'\x90\x28\x28\x00\x00\x01'
    b'\x80\x14\x00\x00\x00\x01' b'\x50\x12\x12\x00\x00\x01'
    b'\x00\x00\x00\x00\x00\x00' b'\x00\x00\x00\x00\x00\x00'
    b'\x00\x00\x00\x00\x00\x00',  # white to black
    b'\x80\x08\x00\x00\x00\x02' b'\x90\x28\x28\x00\x00\x01'
    b'\x80\x14\x00\x00\x00\x01' b'\x50\x12\x12\x00\x00\x01'
    b'\x00\x00\x00\x00\x00\x00' b'\x00\x00\x00\x00\x00\x00'
    b'\x00\x00\x00\x00\x00\x00')  # black to black

_LUT_FAST = (
    b'\x00\x19\x01\x00\x00\x01' b'0x00\x00\x00\x00\x00\x00'
    b'\x00\x00\x00\x00\x00\x00' b'0x00\x00\x00\x00\x00\x00'
    b'\x00\x00\x00\x00\x00\x00' b'0x00\x00\x00\x00\x00\x00'
    b'\x00\x00\x00\x00\x00\x00' b'\x00\x00',  # VCOM
    b'\x00\x19\x01\x00\x00\x01' b'0x00\x00\x00\x00\x00\x00'
    b'\x00\x00\x00\x00\x00\x00' b'0x00\x00\x00\x00\x00\x00'
    b'\x00\x00\x00\x00\x00\x00' b'0x00\x00\x00\x00\x00\x00'
    b'\x00\x00\x00\x00\x00\x00',  # white to white
    b'\x80\x19\x01\x00\x00\x01' b'0x00\x00\x00\x00\x00\x00'
    b'\x00\x00\x00\x00\x00\x00' b'0x00\x00\x00\x00\x00\x00'
    b'\x00\x00\x00\x00\x00\x00' b'0x00\x00\x00\x00\x00\x00'
    b'\x00\x00\x00\x00\x00\x00',  # black to white
    b'\x40\x19\x01\x00\x00\x01' b'0x00\x00\x00\x00\x00\x00'
    b'\x00\x00\x00\x00\x00\x00' b'0x00\x00\x00\x00\x00\x00'
    b'\x00\x00\x00\x00\x00\x00' b'0x00\x00\x00\x00\x00\x00'
    b'\x00\x00\x00\x00\x00\x00',  # white to black
    b'\x00\x19\x01\x00\x00\x01' b'0x00\x00\x00\x00\x00\x00'
    b'\x00\x00\x00\x00\x00\x00' b'0x00\x00\x00\x00\x00\x00'
    b'\x00\x00\x00\x00\x00\x00' b'0x00\x00\x00\x00\x00\x00'
    b'\x00\x00\x00\x00\x00\x00')  # black to black


class Display:
    width = 152
    height = 152

    def __init__(self, spi, dc, cs, busy):
        self._spi = spi
        self._cs = cs
        self._dc = dc
        self._busy = busy
        self._stride = self.height // 8
        self.buffer = memoryview(bytearray(self.width * self._stride))
        self.reset()
        self._fast = False

    def _wait(self):
        while not self._busy.value:
            pass

    def _command(self, command, data=None):
        self._dc.value = 0
        self._cs.value = 0
        self._spi.write(command)
        self._dc.value = 1
        if data:
            self._spi.write(data)
        self._cs.value = 1

    def _lut(self, lut):
        for command, data in zip('\x20\x21\x22\x23\x24', lut):
            self._command(command, data)

    def reset(self):
        self._wait()
        self._command(b'\x00', b'\x00')  # reset
        self._command(b'\x01', b'\x03\x00\x2b\x2b\x03')  # power settings
        self._command(b'\x06', b'\x17\x17\x17')  # booster soft start
        self._command(b'\x04')  # power on
        self._wait()
        #self._command(b'\x00', b'\x33\x0d')  # panel setting for BW
        self._command(b'\x00', b'\x23\x0d')  # panel setting for BWR/BWY
        self._command(b'\x61', b'\x98\x00\x98')  # resolution 152x152
        self._command(b'\x82', b'\x28')  # VCOM value
        self._command(b'\x50', b'\x97')  # VCOM and data interval
        self._command(b'\x30', b'\x3c')  # PLL control 50Hz
        self._lut(_LUT_FULL)

    def sleep(self):
        self._command(b'\x50', b'\x17')  # frame floating
        self._command(b'\x82', b'\x00')  # VCOM value 0.1V
        self._command(b'\x01', b'\x00\x00\x00\x00\x00')  # power 0V
        self._command(b'\x02')  # power off
        self._wait()
        self._command(b'\x07\xa5')  # deep sleep

    def clean(self):
        #self._command(b'\x00', b'\x13\x0d')  # panel setting for BW
        self._command(b'\x00', b'\x03\x0d')  # panel setting for BWR/BWY
        self._command(b'\x12')  # refresh
        #self._command(b'\x00', b'\x33\x0d')  # panel setting for BW
        self._command(b'\x00', b'\x23\x0d')  # panel setting for BWR/BWY

    def update(self, block=True, fast=False):
        self._wait()
        self._command(b'\x10', self.buffer)  # old data
        self._command(b'\x11')  # data stop
        self._command(b'\x13', self.buffer)  # new data
        self._command(b'\x11')  # data stop
        if fast != self._fast:
            self._fast = fast
            if fast:
                self._lut(_LUT_FAST)
                self._command(b'\x82', b'\x08')  # VCOM value
                self._command(b'\x50', b'\x47')  # VCOM interval
            else:
                self._lut(_LUT_FULL)
                self._command(b'\x82', b'\x28')  # VCOM value
                self._command(b'\x50', b'\x97')  # VCOM interval
        self._command(b'\x12')  # refresh
        if block:
            self._wait()

    def pixel(self, x, y, color=None):
        if not 0 <= x < self.width or not 0 <= y < self.height:
            return
        page = x // 8
        mask = 1 << (x % 8)
        if color is None:
            return bool(self.buffer[page + y * self._stride] & mask)
        elif color:
            self.buffer[page + y * self._stride] |= mask
        else:
            self.buffer[page + y * self._stride] &= ~mask

    def char(self, x, y, c, width=1, height=1, inverse=False):
        x *= 6
        if x >= self.width or y >= self._stride:
            return
        c = ord(c)
        inverse = 0xff if c & 0x80 or inverse else 0x00
        index = ((c & 0x7f) - 32) * 6
        if not (0 <= index < len(_FONT)):
            index = 0
        for scan in range(index, index + 6):
            byte = _FONT[scan] ^ 0xb3
            if height > 1:
                out = 0x00
                for bit in range(8):
                    if byte & (1 << bit):
                        out |= (2 ** height - 1) << (bit * height)
            else:
                out = byte
            for row in range(y, y + height):
                if not 0 <= row < self._stride:
                    break
                for col in range(x, x + width):
                    if not 0 <= col < 152:
                        break
                    self.buffer[(col + 1) * self._stride - 1 - row] = (
                        out & 0xff) ^ inverse
                out >>= 8
            x += width

    def text(self, text, row=0, col=0, width=1, height=1, inverse=False):
        x = col
        y = row
        for c in text:
            if c == '\n':
                x = col
                y += height
                continue
            self.char(x, y, c, width, height, inverse)
            x += width
            if x >= self.width // 6 - width:
                x = col
                y += height