import os
import utime
from machine import UART, Pin

#print("unfixed ERROR thinks msg is fully received at 1500 (sees a ']' at 35th byte")

# all functions and subroutines are at top of program

#  1. bChar  converts 4 char byte into 1 char
#  2. serTx_pico()   transmits a full serial text message
#  3. serRx_pico()   receives  a full serial text message
#  4. txParse()      parses the outgoing text message and cals txChar
#  5. txChar()       transmitts 1 char

def bChar(strB):
    #  given a string like b'z' this returns the "z"
    # tested by D@CC on 2021FJun15
    
    #strB=input("eg b'h' :")
    b=strB[2:]
    #print("b:"+b)
    c=b[0]
    #c="zz"
    #print("bChar("+'"'+strB+ '"):'+c)
    return c
#end def


def serTx_pico(uartObject,bps, txtToBeSent="[UUUUUUUU]",rxtxEndChar="]"):
    t5c=50/bps
    t10c=100/bps
    t1000c=10000/bps
    # requires a uart object (below) to be created before this function is called
    #uart = machine.UART(1,600, parity=None, stop=1, bits=8, tx=Pin(txPin), rx=Pin(rxPin))
    print("entering serTx_pico.py")
    #print("rOrT:"+rOrT)
    if rxtxEndChar=="]":
        som = "["
        emo = "]"
    
    msgOut = """
    S +
    M +
    E +
    X"""

    
    
    where
    S is SOM
    M is Message text to be sent
    E is EOM
    X is t10c  (ten character time delay: "roman numeral X")
    
        
    Most messages will have   msgOut = "A" "SMEX"
 
    Between messages the transmitter will send "0" every minute indicating that its alive but
    has no message to send.
    Before sending each message the transmitter will send a single "A" which is 0x41 indicating
    that the following message will be in packets of 16 characters.  In the future when the
    packet size.
    changes to 32 characters, the transmitter will precede each message with a single "B"
    indicating the each packet will contain 32 characters.  This will allow future packet sizes
    at least as big as 16x16x4 = 1024 characters and total message lengths of around 32768 without
    using any control characters in the "ascii" preamble.
 
    Future versions will have msgOut = "DDDSNKMX"
    with packets having the format:
        "A" SNKPV SMPV SMPV etc SMPEX
    The optional packet of 16 x D permits synchronization
    
    where
    D  is the Delete character
    P is the 
    N is the 2-character packet Number
    K is the 2-character message character "Kount"
    V is t5c


    When a receiver starts up (and between messages) it should start by expecting packets of single
    characters.  It will read a single character expecting it to be a "0" meaning an idle transmitter.
    If it is not a "0", it will read another single character expecting it to be an "A".  If it is not an
    "A",the character will be discarded, but the receiver will presume that it is reading a character
    stream that is mid-message.  It will read single characters searching for a "]" which will indicate
    that it this the last packet of the message. It will keep reading and discarding all the "]".
    After the last "]" the
    next character should be a "0" or an "A".  The receiver should keep reading and discarding the "0"
    characters.  When an "A" is received (while reading single characters), the receiver knows that
    this means subsequent packets will be packets of 16 characters.  The receiver is now fully
    synchonized with the transmitter.  If something other than an "A" is received, the receiver should
    begin looking for a "]" ()meaning "end of message" again.  If the state of "being in mid-message
    continues 10 times, the operator should be informed the This ERROR is occuring.
    #send the message
    def txParse(uartObject, bps, msgOut, t5cIn=-1, packetSize=16,  eom="]",som="["):
#
#    uartObject is the uart being used
#    bps is the baud rate (bits/sec)
#    msgOut is the text message to be sent (It should not contain (EOM="]") they will become "?"
#    t5c indicates time interval of 5 characters.  The transmitter will follow each packet with
#       this time delay
#    packetSize defaults to 16
#    rxtxEndChar is the definition of the 'EOM" character (usually "]")
    if t5cIn==-1:
       t5c=50/bps
       t10c=100/bps
       t1000c=10000/bps
    else:
        t5c=t5cIn
        t10c=t5cIn*2
        t1000c=t5cIn*200
    #end if
    
#    in 2021 msgOut="SMEX"
    for msgPart in msgOut:
        if msgPart=="S":
            # send SOF
            txChar(som)
        if msgPart=="X":
            utime.sleep(t10c)
        of msgPart=="M"
            
    return
#end def
    
    # the above is the current format of the rxtx protocol
    # The som,eom,t10c and are 1-character special codes
    #    each must be converted into outgoing text or actions or both
    #    all normal text does not need to be converted before transmission
    #
    # The txParse routine analyses the msgOut and separates it into
    # special codes (text and actions).  Each special code is sent to the serTx
    # routine to be processed. Each character of text is sent to the
    # serTx routine to be processed.
    #
    # The serTx routine is used to
    #   transmit a special code of text ("S" and "M")
    #   cause a time delay (V is "t5c X is "t10c  " and M is "t1000c")
    #   transmit a single character (must not be "]" which is replaced by "?" )
    #
    # Note that the "E" also inserts "--" and at least 1 "]" character and
    #   enough extra "]" characters (or none) to make a message with a exact multiple
    #   of 16 characters.  This is because there are always 16 characters per
    #   packet. Each packet is followed by a time delay of t5c.
    #   The last packet is always followed by a time delay of t10c.
    #   These time delays permit the receiver to resync with the transmitter.
    #   These time delays are never included in the character count of the
    #   message
    
    
    
             
    The txSend function continues
    
    if rOrT=="T":
        isValidRorT=True
        txtOut=txtToBeSent
        #print("A transmitting:"+txtOut+":")
        if txtOut=="":
            txtOut="[HelloThere]"
        #end if
        print("B1 transmitting:"+txtOut+":")
        uartObject.write(txtOut)
        utime.sleep(0.1)
        print("transmission complete")
        return
    #end if
    if rOrT=="X":
        isValidRorT=True
        txtIn=""
        while uartObject.any():
            txtIn=uartObject.read(1)
        #end while
        if txtIn=="":
            pass
        else:
            print(txtIn)
        #end if
    #end if
    m=0

#end def
    
################################################################################################
progName="test serTxRxA_pico.py"
print("progName:"+progName)
bps=600
t5c=50/bps
t10c=100/bps
t1000c=10000/bps
rxtxEndChar="]"
txPin=4
rxPin=5
print("Jumper GP"+str(rxPin)+" to GP"+str(txPin))
#print sys info
print(os.uname())

#indicate program started visually
led_onboard = machine.Pin(25, machine.Pin.OUT)
led_onboard.value(0)     # onboard LED OFF for 0.5 sec
utime.sleep(0.5)
led_onboard.value(1)

#create uart object sample code
if False :
    #self.uart = UART(1, 115200, parity=None, stop=1, bits=8, rx=Pin(rxPin), tx=Pin(txPin))
    pass
#end if

create actual uart object
uart = machine.UART(1,bps, parity=None, stop=1, bits=8, tx=Pin(txPin), rx=Pin(rxPin))
#print uart info
#uart = machine.UART(1)
print(uart)

#initialization is complete