from machine import Pin
from rp2 import PIO, StateMachine, asm_pio


## ASM
@asm_pio(autopush=True, push_thresh=8, in_shiftdir=PIO.SHIFT_RIGHT, fifo_join=PIO.JOIN_RX)
def uart_rx_mini():
    wait(0, pin, 0)
    set(x, 7)                 [10]
    label("bitloop")
    in_(pins, 1)
    jmp(x_dec, "bitloop")     [6]


@asm_pio(sideset_init=PIO.OUT_HIGH, out_init=PIO.OUT_HIGH, out_shiftdir=PIO.SHIFT_RIGHT)
def uart_tx():
    pull()
    set(x, 7)  .side(0)       [7]
    label("bitloop")
    out(pins, 1)              [6]
    jmp(x_dec, "bitloop")
    nop()      .side(1)       [6]
        


class UART:

    def __init__(self, rx, tx, baudrate, id):
        self.UART_BAUD = baudrate
        self.PIO_RX_PIN = Pin(rx, Pin.IN, Pin.PULL_UP)
        self.PIO_TX_PIN = Pin(tx, Pin.OUT, value=1)
        self.smrx = StateMachine(id, uart_rx_mini, freq=8*self.UART_BAUD, in_base=self.PIO_RX_PIN, jmp_pin=self.PIO_RX_PIN)
        self.smrx.active(1)
        self.smtx = StateMachine(id + 1, uart_tx, freq=8*self.UART_BAUD, sideset_base=self.PIO_TX_PIN, out_base=self.PIO_TX_PIN)
        self.smtx.active(1)
        
    def deinit(self):
        self.smrx.active(0)
        self.smtx.active(0)
        
    def write(self,s):
        #self.smtx.put(bytes(s))
        self.smtx.put(s)
        return len(s)

    def read(self):
        z = []

        for i in range(100):
            buflen = self.smrx.rx_fifo()

            if buflen:
                for c in range(buflen): 
                    z.append(self.smrx.get() >> 24)

        return bytes(z)
