#!/usr/bin/python3 # # load some data into the Flash on the test board # # read in the command args from argparse import ArgumentParser import serial import string #import binascii import time from datetime import datetime parser = ArgumentParser() parser.add_argument("-f", "--file", dest="filename", help="write report to FILE", metavar="FILE") parser.add_argument("-p", "--port", dest="port", default="/dev/ttyACM0", help="serial port device") parser.add_argument("-t", "--test", action="store_true", dest="test", default=False, help="load a default page") args = parser.parse_args() print ("args:%s:%s" % (type(args),str(args))) page = bytearray(256) # https://stackoverflow.com/questions/69369408/calculating-crc16-in-python-for-modbus def modbusCrc(msg:str) -> int: crc = 0xFFFF for n in range(len(msg)) : crc ^= msg[n] for i in range(8) : if crc & 1 : crc >>= 1 crc ^= 0xA001 else : crc >>= 1 return crc def print_page (data) : ascii = "" print ("00 : ", end="") printable = string.ascii_letters + string.digits + string.punctuation + " " for b in range(256) : if b > 0 and b % 16 == 0 : print (": %s\n%02X : " % (ascii,b), end="") ascii = "" if chr(data[b]) in printable : ascii += chr(data[b]) else : ascii += "." print ("%02X " % (data[b]), end="") print (": %s" % (ascii)) def open_port () : port = serial.Serial (args.port, 115200, timeout=1, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE) time.sleep(1) text = "" print ("init.") while True : bytesToRead = port.inWaiting() if bytesToRead > 0 : print ("bytes =",bytesToRead) text += port.read(bytesToRead).decode() print ("text = %s = \"%s\"" % (type(text),text)) time.sleep(0.1) if "code.py" in text or "REPL" in text : print ("send ctrl") port.write( b'\x04' ); time.sleep (3) else : break return port def read_port (port, stop=False) : # get one line from the serial port text = "" cnt = 250 while True : # wait for something to arrive bytesToRead = port.inWaiting() if bytesToRead > 0 : break else : time.sleep(0.1) cnt -= 1 if cnt == 0 : return "" cnt = 5 while (cnt > 0) : # read the line bytesToRead = port.inWaiting() if bytesToRead > 0 : #print ("bytes =", bytesToRead, end=" ") ch = port.read(1).decode() if ch == "\r" or ch == "\n" : # we get both CR and LF if stop : break else : continue text += ch.upper() else : time.sleep (0.05) cnt -= 1 #print (f"read_port() text = \"{text}\"") return text def check_connection (port) : ok = False for tries in range(10) : print ("sending AT") port.write("AT\r".encode()) # what is writen gets echoed time.sleep(0.5) text = read_port (port) print (" ",text) ok = (text == "OK ATTENTION") if ok : break # stop trying when OK time.sleep(1) # one second between tries return ok def write_test_page () : port = open_port() ok = check_connection(port) print ("ok =",ok) if ok : port.write("WRITE\r".encode()) resp = read_port (port) print (f"WRITE = \"{resp}\"") ok = (resp == "OK") if ok : port.write ("ADDRESS:0\r".encode()) resp = read_port (port) print (f"ADDRESS = \"{resp}\"") ok = (resp == "OK") if ok : for x in range(16) : def my_hex (num) : return hex(num)[2:] # remove the '0x' text = ",".join(map(my_hex,page[(x * 16):(x * 16)+16])) text += "\r" port.write(text.encode()) resp = read_port (port) print (f"DATA = \"{resp}\"") ok = resp.startswith("OK") if not ok : break if ok : port.write (f"CRC:{hex(crc)}\r".encode()) resp = read_port (port) print (f"CRC = \"{resp}\"") ok = resp.startswith("OK") port.close() def read_page (page) : port = open_port() ok = check_connection(port) print ("ok =",ok) if ok : port.write ("READ\r".encode()) resp = read_port (port) print (f"READ = \"{resp}\"") ok = resp.startswith("OK") if ok : print (f"reading page {page}") port.write (f"ADDRESS:{page}\r".encode()) arr = [] while len(arr) < 256 : resp = read_port (port, stop=True) if len(resp) == 0 : continue arr += [int(h.strip(),16) for h in resp.split(",")] print_page (arr) def erase_chip () : port = open_port() ok = check_connection(port) print ("ok =",ok) if ok : port.write ("ERASE\r".encode()) resp = read_port (port) print (f"ERASE = \"{resp}\"") ok = resp.startswith("OK") if args.test : print ("testing") for x in range(256) : # a page of number from 0 -> 0xFF if x < 128 : page[x] = x; else : page[x] = 0xFF; now = datetime.now().strftime("%d/%m/%Y %H:%M:%S") for n in range(len(now)) : page[n + 0xA0] = ord(now[n]) print_page (page) crc = modbusCrc(page) # work out the crc for the page print ("crc = $%04X" % (crc)) print ("port =",args.port) erase = input("Do you want to erase chip [y/N] ?") if erase.upper() == "Y" : erase_chip() write = input("Do you want to write page zero [y/N] ?") if write.upper() == "Y" : write_test_page() read_page (0) else : print ("not testing")