# cPy - USB echo server
# Copyright by Anthony Vogelaar, Perth Scotland
# rev 0.10  2026-07-09  initial release

import  subprocess;         subprocess.run('clear')
import	serial				# (venv) pip install pyserial
import	time

# documentation:
#    https://pyserial.readthedocs.io/en/latest/pyserial.html

# Windows: see uart_cross.png
# linux  : $ socat -d -d pty,rawer,echo=0 pty,rawer,echo=0
#            --> /dev/pts/1 and /dev/pts/2
#		   $ picocom -q /dev/pts/2

# Implemented:
# Serial(port)
#    Serial.writeLn(s_tx)
#    Serial.readLn()            -->  s | None

# ============================= Serial =============================

# Class for string serial UART / USB communication
class Serial:
    
    def __init__(self, port):
        self.comm = None
        self.comm = serial.Serial(port, baudrate=115200, timeout=0)
        self.rx_buff = b''
        
        
    # write <CR><LF> terminated s_tx as bytes
    def writeLn(self, s_tx):
        self.comm.write(f'{s_tx}\r\n'.encode())
        
        
    # return received <CR> or <LF> terminated string or None. Non blocking
    def readLn(self):
        while ch := self.comm.read(1):
            if ch in b'\n\r':
                if self.rx_buff:
                    s_rx, self.rx_buff = self.rx_buff.decode(), b''
                    return s_rx
            else: self.rx_buff += ch
        
# ======================== test UART communication ============================

def echoServer(port):
    print('Echo server running ...')
    try:
        comm = Serial(port)						# open serial port
        while True:
            if s_rx := comm.readLn():			# if a line received
                print('echo:  ', s_rx)			#   print it
                comm.writeLn(s_rx)				#   echo it
            time.sleep(0.1)
    except serial.serialutil.SerialException:
        print('Exception, unable to connect to:', port)
        

echoServer('/dev/pts/2')

# ================================== end =====================================
