import serial import struct import os #--------------------------------------------------------------------- class TSP: def __init__(self): self.f_prog = "" self.f_fprec = "" self.f_aprec = 0 self.serial_port = None self.indi = 0 self.modo = "dec" self.buff = None self.lista_porte = self.analizza_porte() self.s_port = self.lista_porte[0] if self.lista_porte else "" #----------------------------------------------------------------- def erro(self, msg): print(msg) self.s_input("Premere invio per continuare...") #----------------------------------------------------------------- def carprog(self): self.erro("*** FUNZIONE NON DISPONIBILE ***") #----------------------------------------------------------------- def visufile(self): lista_files = os.listdir(".") lista_files.sort() s = [] i = 0 for fname in lista_files: s.append(fname.ljust(25)) i = (i + 1) % 3 if not i: print("".join(s)) s = [] if s: print("".join(s)) #----------------------------------------------------------------- def caricato(self, nome, indi): buff = open(nome, "rb").read() print("Caricamento " + nome + "(%s bytes)" % len(buff)) h_addr, l_addr = divmod(indi, 256) h_len, l_len = divmod(len(buff), 256) data = 32, l_addr, h_addr, l_len, h_len if not self.serial_open(): self.erro("*** Porta seriale non apribile ***") self.s_port = "" return False self.serial_port.write(struct.pack("B"*len(data), *data) + buff) self.serial_close() return True #----------------------------------------------------------------- def carica_singolo_file(self): print("CARICAMENTO SINGOLO FILE") if self.f_fprec: msg = "Ricaricare ultimo? (s=si, n=no, solo invio per annullare) " s = self.s_input(msg) if not s: return if s.lower() == "s": if self.caricato(self.f_fprec, self.f_aprec): self.indi = self.f_aprec return print("Lista files presenti in %s:" % os.getcwd()) self.visufile() nome = self.s_input("File: (Solo invio per annullare) ") if not nome: return if not os.path.isfile(nome): self.erro("Errore, nome file non valido") return s = self.s_input("Indirizzo: (Solo invio per annullare) ") if not s: return try: self.indi = int(s) % 65536 if self.indi < 0: raise ValueError except ValueError: self.erro("Errore, indirizzo non valido!") return if self.caricato(nome, self.indi): self.f_fprec = nome self.f_aprec = self.indi return #----------------------------------------------------------------- def esegui(self): s = self.s_input("Indirizzo: (Solo invio per annullare) ") if not s: return try: indi = int(s) % 65536 if self.indi < 0: raise ValueError except ValueError: self.erro("Errore, indirizzo non valido!") return h_addr, l_addr = divmod(indi, 256) if not self.serial_open(): self.erro("*** Porta seriale non apribile ***") self.s_port = "" return self.serial_port.write(struct.pack("BBB", 34, l_addr, h_addr)) self.serial_close() return #----------------------------------------------------------------- def serial_open(self): try: self.serial_port = serial.Serial(self.s_port, 9600, 8, "N", 2, timeout=1) return True except IOError: return False #----------------------------------------------------------------- def serial_close(self): try: self.serial_port.close() except IOError: pass #----------------------------------------------------------------- def visdump(self): filler = struct.pack("BBB", 0xe2, 0xac, 0xa5).decode("utf-8") addr = self.indi for i in range(0, len(self.buff), 16): chunk = self.buff[i:i+16] s = [] c = [] for v in chunk: s.append(" %3d"%v if self.modo=="dec" else " %02X"%v) c.append(chr(v) if 32<=v<=126 else filler) sa = "%5d:"%addr if self.modo=="dec" else "%04X:"%addr sb = ( "".join(s).ljust(48) if self.modo=="hex" else "".join(s).ljust(64)) sc = "".join(c) print((sa + sb + " " + sc) if self.modo=="hex" else (sa + sb)) addr = (addr + 16) % 65536 #----------------------------------------------------------------- def leggi_blocco(self): if not self.serial_open(): self.erro("*** Porta seriale non apribile ***") self.s_port = "" return () h_addr, l_addr = divmod(self.indi, 256) data = 33, l_addr, h_addr, 0, 1 self.serial_port.write(struct.pack("B"*len(data), *data)) received = [] for x in range(256): r = self.serial_port.read(1) if not r: self.erro("*** Errore di ricezione! ***") break received.extend(struct.unpack("B", r)) self.serial_close() return received #----------------------------------------------------------------- def avanti(self): self.indi = (self.indi + 256) % 65536 self.buff = self.leggi_blocco() #----------------------------------------------------------------- def imposta_indi(self): s = self.s_input("Indirizzo: (solo invio per annullare) ") if s: try: self.indi = int(s) % 65536 if self.indi < 0: raise ValueError self.buff = self.leggi_blocco() except ValueError: self.erro("Errore, indirizzo non valido!") #----------------------------------------------------------------- def cambia_modo(self): self.modo = "dec" if self.modo == "hex" else "hex" #----------------------------------------------------------------- def titolo(self, msg): print("\n+" + "-"*77 + "+") print("|" + msg.center(77) + "|") print("+" + "-"*77 + "+") #----------------------------------------------------------------- def menudump(self): self.titolo("DUMP MEMORIA") print(" 1)-Avanti 2)-Imposta indirizzo" " 3)-dec/hex x)-Ritorno (modo=%s)" % self.modo) #----------------------------------------------------------------- def dump_memoria(self): func = { "1": self.avanti, "2": self.imposta_indi, "3": self.cambia_modo, "x": None, "X": None } self.buff = None while True: self.menudump() if not self.buff: self.buff = self.leggi_blocco() if not self.buff: return self.visdump() scelta = self.choice("Scelta: ", func.keys()) if scelta.lower() == "x": break func[scelta]() #----------------------------------------------------------------- def immiss(self, indi): while True: h_addr, l_addr = divmod(indi, 256) data = 33, l_addr, h_addr, 1, 0 self.serial_port.write(struct.pack("B"*len(data), *data)) received = self.serial_port.read(1) if not received: self.erro("*** Errore ricezione dati! ***") return c = struct.unpack("B", received)[0] d = self.s_input("%5s - %02X . " % (indi, c)) if d.lower() == "x": break if d == "": indi = (indi + 1) % 65536 else: try: e = int(d, 16) % 256 data = 32, l_addr, h_addr, 1, 0, e self.serial_port.write(struct.pack("B"*len(data), *data)) indi = (indi + 1) % 65536 except ValueError: print("*** Dato non valido! ***") #----------------------------------------------------------------- def imman(self): self.titolo("IMMISSIONE MANUALE VALORI IN MEMORIA") print(" - Valori in esadecimale (2 digit)") print(" - x per finire") print(" - Solo invio per confermare") s = self.s_input("Indirizzo: (Solo invio per annullare) ") if not s: return try: indi = int(s) % 65536 if self.indi < 0: raise ValueError except ValueError: self.erro("Errore, indirizzo non valido!") return if not self.serial_open(): self.erro("*** Porta seriale non apribile ***") self.s_port = "" return self.immiss(indi) self.serial_close() #----------------------------------------------------------------- def scelta_porta_seriale(self): self.lista_porte = self.analizza_porte() print("Porte disponibili:") if not self.lista_porte: self.erro(" *** nessuna ***") self.s_port = "" return choices = [] for i, p in enumerate(self.lista_porte): print(" %d) - %s" % (i+1, p)) choices.append(str(i+1)) if len(self.lista_porte) == 1: self.s_port = self.lista_porte[0] return msg = "Scegliere la porta (x per annullare): " choices.extend(["x", "X"]) scelta = self.choice(msg, choices) if scelta.lower() != "x": self.s_port = self.lista_porte[int(scelta)-1] #----------------------------------------------------------------- def menuprinc(self): pr = self.f_prog if self.f_prog else "nessuno" fp = self.f_fprec if self.f_fprec else "nessuno" pa = self.s_port if self.s_port else "nessuna" self.titolo("MENU PRINCIPALE") print(" 1) - Carica progetto (ultimo: %s)" % pr) print(" 2) - Carica singolo file (ultimo: %s)" % fp) print(" 3) - Esegui da indirizzo N") print(" 4) - Dump memoria") print(" 5) - Enter manuale da indirizzo N") print(" 6) - Scelta porta seriale (attuale: %s)" % pa) print(" x) - Fine") #----------------------------------------------------------------- def analizza_porte(self): port_list = [] for prefix in ("com", "/dev/ttyS", "/dev/ttyUSB"): for number in range(48): port_name = prefix + str(number) try: serial.Serial(port_name).close() port_list.append(port_name) except IOError: pass return port_list #----------------------------------------------------------------- def s_input(self, msg): try: return raw_input(msg) # Py2 except NameError: return input(msg) # Py3 #----------------------------------------------------------------- def choice(self, msg, choices): while True: cho = self.s_input(msg) if cho in choices: return cho #----------------------------------------------------------------- def start(self): func = { "1": self.carprog, "2": self.carica_singolo_file, "3": self.esegui, "4": self.dump_memoria, "5": self.imman, "6": self.scelta_porta_seriale, "x": exit, "X": exit } print("\n\n") self.titolo("GESTIONE TSP - Versione 2.0 - By C.Fin 2012/2013") while True: self.menuprinc() func[self.choice("Scelta: ", func.keys())]() #--------------------------------------------------------------------- app = TSP() app.start()