from machine import Pin
from utime import sleep,sleep_us,sleep_ms

class LCD:
    MODE_4BIT = 0x20
    MODE_8BIT = 0x30
    MODE_4BIT_WITH_2LINE = 0x28
    MODE_8BIT_WITH_2LINE = 0x38
    CLR_DISPLAY = 0x01
    RETURN_HOME = 0x02
    MOVE_CURSOR_RIGHT = 0x14
    DISPLAY_ON = 0xC
    CURSOR_ON = 0xE

    def __init__(self,RS=None,E=None,D4=None,D5=None,D6=None,D7=None,MODE=MODE_4BIT,CURSOR=False):
        self.rs_pin = Pin(RS,Pin.OUT)
        self.e_pin = Pin(E,Pin.OUT)
        self.d4_pin = Pin(D4,Pin.OUT)
        self.d5_pin = Pin(D5,Pin.OUT)
        self.d6_pin = Pin(D6,Pin.OUT)
        self.d7_pin = Pin(D7,Pin.OUT)
        self.mode = MODE
        self.cursor = CURSOR
        self.setMode()
        self.clearScr()
        self.setReturnToHome()
        self.setLcdOn()
        self.setCursorOn()

    def pulse_enable(self):
        self.e_pin.value(1)
        sleep_us(40)       
        self.e_pin.value(0)
        sleep_us(40)     

    def setMode(self):
        if self.mode == self.MODE_4BIT:
            self.writeCmd(self.MODE_4BIT)
            return
    
    def clearScr(self):
        self.writeCmd(self.CLR_DISPLAY)

    def setReturnToHome(self):
        self.writeCmd(self.RETURN_HOME)

    def moveCursorRight(self):
        self.writeCmd(self.MOVE_CURSOR_RIGHT)
    
    def setLcdOn(self):
        if not self.cursor:
            self.writeCmd(self.DISPLAY_ON)
       
    def setCursorOn(self):
        if self.cursor:
            self.writeCmd(self.CURSOR_ON)

    def write4bit(self,value):
        self.d7_pin.value((value & 0b00001000) >> 0x03)
        print('d7->',(value & 0b00001000) >> 3)
        self.d6_pin.value((value & 0b00000100) >> 0x02)
        print('d6->',(value & 0b00000100) >> 2)
        self.d5_pin.value((value & 0b00000010) >> 0x01)
        print('d5->',(value & 0b00000010) >> 1)
        self.d4_pin.value((value & 0b00000001) >> 0x00)
        print('d4->',(value & 0b00000001) >> 0)
        self.pulse_enable()
        print('--------------------------------')
        
    def writeCmd(self,cmd):
        self.rs_pin.value(0)
        if cmd == self.MODE_4BIT:
            print(cmd)
            self.write4bit(cmd >> 4)
        else:
            self.write4bit(cmd >> 4)
            self.write4bit(cmd)
        sleep_ms(5)
    
    def writeData(self,data):
        self.rs_pin.value(1)
        self.write4bit(data >> 4)
        self.write4bit(data)

    def setCursorPosition(self,line,pos):
        self.setReturnToHome()
        temp = 0
        if(line==1):
            temp = 0
        elif(line==2):
            temp = 40

        for i in range(temp+pos):
            self.moveCursorRight()

    def writeChar(self,value=None):
        if value:
            self.writeData(ord(value))
    
    def writeStr(self,value=None,line=0,pos=0):
        if value:
            self.setCursorPosition(line,pos)
            for i in value:
                print(i)
                self.writeChar(i)
        
BOOTSELLED1239USBRaspberryPiPico©2020RP2-8020/21P64M15.00TTT