''' Created on 08.02.2012 @author: sth2mt #define SER_0 "/dev/ttyS0" #define SER_1 "/dev/ttyS1" #define SER_2 "/dev/ttyS2" //Drehzahlvorgabe fuer PT- Elektronik ''' import serial import time import threading import thread import fcntl import termios import array import struct as struct import FertigungsTest.Hardware.Typschild as Typschild import subprocess class Treiber(threading.Thread): ''' classdocs ''' # Achtung dies ist Pseudo Singleton -> variablen werden statisch verwendet. Aufgeraumt wird erst wenn alle instanzen weg sindwird nur einmal instaniiert !!!! ObjCount = 0 _Thread_name = "LtInterface" stout = False Motornenndrehzahl = 19995 Getriebeuntersetzung = 12.25 #default Abtriebuntersetzung = 1.0 SpindelNennDrehzahl = None s_port = "/dev/ttyS0" N_MOUSE = 2 s_PathLt = ["/proc/nexoctrl/dataselect","/proc/nexoctrl/enable","/proc/nexoctrl/speedref","/proc/nexoctrl/adcvalues/mainswitch"\ ,"/proc/nexoctrl/adcvalues/lrswitch","/proc/nexoctrl/adcvalues/battery","/proc/nexoctrl/leds/white"\ ,"/proc/nexoctrl/leds/rgb","/proc/nexoctrl/fwupdate/update","/proc/nexoctrl/fwupdate/control","/boot/NxLtFw.bin"] MAX_FILE_SIZE = 200000 INDEX_DATA_SELECT = 0 INDEX_ENABLE = 1 # Freigabe (Wert 0 = aus, anderer Wert = an) INDEX_SPEED_REF = 2 # Drehzahlvorgabe INDEX_MAIN_SWITCH = 3 INDEX_LR_SWITCH = 4 INDEX_BATTERY = 5 INDEX_LED = 6 INDEX_LED_RGB = 7 INDEX_FW_UPDATE = 8 INDEX_FW_CONTROL = 9 INDEX_LT_FW_FILEPATH = 10 CMD_KEEP_ALIVE_TRYS = 10 CMD_FW_CTRL_TRYS = 5 LT_FWCTRL_STARTKEEPALIVE = "startkeepalive" LT_FWCTRL_STOPKEEPALIVE = "stopkeepalive" LT_FWCTRL_DELETESECTORS = "deletesectors" LT_FWCTRL_GOTOBL = "gotobl" LT_FWCTRL_REQSYNC = "reqsync" LT_FWCTRL_KEEPALIVE = "keepalive" LT_FWCTRL_STARTFW = "startfw" f_LtFunction = [file,file,file,file,file,file,file,file,file,file,file] KeepAliveTime = 20 WatchdogActive = False iDrehzahl=0 O_SerLt = None O_LP3943 = None O_Typschild = None def __init__(self): ''' Constructor ''' Treiber.ObjCount += 1 self.printf("%i.Construktor %s" % (Treiber.ObjCount,Treiber._Thread_name)) threading.Thread.__init__(self) self._EventStop = threading.Event() self.MerkerDrehzahl = 0 self.LEDred = 0 self.LEDgreen = 0 self.LEDblue = 0 try: if Treiber.O_SerLt == None: if subprocess.call(["killall","AblaufStrg.elf"],shell=False)!=0: self.printf ("killall AblaufStrg.elf NOK\n") else: self.printf ("killall AblaufStrg.elf OK\n") # Ser0 zum schreiben und lesen oeffnen Versuche = 0 while Versuche < 20 : try: Treiber.O_SerLt= serial.Serial( port=Treiber.s_port, baudrate=230400, parity=serial.PARITY_EVEN, stopbits=serial.STOPBITS_ONE, bytesize=serial.EIGHTBITS, timeout = 2 ) # Abbruchbedingung setzen Versuche = 100 except IOError,e: self.printf ("%i.LtInterface.__init__() open %s %s" %(Versuche,Treiber.s_port, e)) time.sleep(1) Versuche+=1 if Versuche < 100: # Noch Einmal dann nie wieder, -> Exception werfen Treiber.O_SerLt= serial.Serial( port=Treiber.s_port, baudrate=230400, parity=serial.PARITY_EVEN, stopbits=serial.STOPBITS_ONE, bytesize=serial.EIGHTBITS, timeout = 2 ) # Ser0 oeffnen if not Treiber.O_SerLt.isOpen(): Treiber.O_SerLt.open() # Line Discipline setzen fd = Treiber.O_SerLt.fileno() self.printf ("LTInterface Init fd=0x%x )" % (fd)) buf= array.array('h',[Treiber.N_MOUSE]) fcntl.ioctl(Treiber.O_SerLt.fileno(), termios.TIOCSETD, buf) except IOError,e: self.printf( "LtInterface.__init__() open %s %s" %(Treiber.s_port, e)) return None #if Treiber.O_LP3943 == None: # # LP3943 fuer LT_Freigabe anlegen # Treiber.O_LP3943 = LP3943.Treiber() #Freigabe wegnehmen self.LTFreigabe(False) #Dataselect auf Drehzahlvorgabe einstellen self.SetDataSelect(False) if Treiber.O_Typschild == None: Treiber.O_Typschild = Typschild.Treiber() self.SetLED(0) self.SetLEDRGB(0,0,0) pass def __del__(self): ''' Destructor ''' self.printf("%i Destruktor %s" % (Treiber.ObjCount,Treiber._Thread_name)) if Treiber.ObjCount == 1: self.printf("Reste aufraumen") self.StopWatchdog() self.SetDrehzahl(0) self.LTFreigabe(0) self.SetLED(0) self.SetLEDRGB(0,0,0) for i in range (len(Treiber.f_LtFunction)): self.Close(i) if Treiber.O_SerLt != None: Treiber.O_SerLt.close() del(Treiber.O_Typschild) Treiber.O_Typschild=None del(Treiber.O_SerLt) Treiber.O_SerLt = None #del(Treiber.O_LP3943) #Treiber.O_LP3943 = None #print "AblaufStrg.elf wieder starten\n" p=subprocess.Popen(["/home/tool/bin/AblaufStrg.elf"],stderr=None,stdout=None,stdin=None,shell=False) #p=False if p._child_created==False: self.printf( "AblaufStrg.elf starten NOK\n") time.sleep(5) if Treiber.ObjCount > 0: Treiber.ObjCount -= 1 pass def readSpindleParams(self): ''' Spindelwerte bestimmen''' s_Brc_Typschild = Treiber.O_Typschild.ReadBrcStatParFromEeprom() Treiber.Getriebeuntersetzung = Treiber.O_Typschild.getStatValue(s_Brc_Typschild,"Getriebeuntersetzung") Treiber.Motornenndrehzahl = Treiber.O_Typschild.getStatValue(s_Brc_Typschild,"Motornenndrehzahl") Treiber.Abtriebuntersetzung = Treiber.O_Typschild.getStatValue(s_Brc_Typschild,"Abtriebuntersetzung") Treiber.SpindelNennDrehzahl = Treiber.Motornenndrehzahl / Treiber.Getriebeuntersetzung / Treiber.Abtriebuntersetzung self.printf("%s.__init__ Getriebeuntersetzung=%2.3f Motornenndrehzahl=%i Abtriebuntersetzung=%2.3f SpindelNennDrehzahl %3.0f" % (Treiber._Thread_name,Treiber.Getriebeuntersetzung,Treiber.Motornenndrehzahl,Treiber.Abtriebuntersetzung,Treiber.SpindelNennDrehzahl)) return True def GetPath(self,iLTInterface): s_Path = "" if (iLTInterface < Treiber.INDEX_DATA_SELECT) or (iLTInterface > Treiber.INDEX_LT_FW_FILEPATH): return s_Path s_Path=Treiber.s_PathLt[iLTInterface] #self.printf ("LtInterface.GetPath(%i) %s" %(iLTInterface,s_Path)) return s_Path def Open(self,iLTInterface,mode): try: if self.Closed(iLTInterface): Treiber.f_LtFunction[iLTInterface] = open(self.GetPath(iLTInterface),mode,0) # Bufferung = 0 -> keine Bufferung sonst wird nicht alles runtergeschickt #self.printf( "LtInterface.Open(%s,%s)" % (self.GetPath(iLTInterface),mode)) return True except IOError,e: self.printf( "LtInterface.Open((%i)->%s,""%s"") %s" %(iLTInterface,self.GetPath(iLTInterface),mode, e)) self.printf( Treiber.s_PathLt[iLTInterface]) return False pass def Close(self,iLTInterface): try: if self.Closed(iLTInterface): return True Treiber.f_LtFunction[iLTInterface].close() #self.printf( "LtInterface.close() %s" % self.GetPath(iLTInterface)) return True except IOError,e: self.printf( "LtInterface.close() %s %s" %(self.GetPath(iLTInterface), e)) return False pass def Read(self,iLTInterface,length=1): try: if self.Open(iLTInterface,"rb"): # Auf Fileanfangs setzen #Treiber.f_LtFunction[iLTInterface].seek(0,0) # Lesen s_value = Treiber.f_LtFunction[iLTInterface].read(length) else: self.printf( "LtInterface.Read(%s) open error length=%i len(s_value)=%i" % (self.GetPath(iLTInterface),length,0)) return "" if len(s_value) == 1: self.printf( "LtInterface.Read(%s) length=%i len(s_value)=%i = %i" % (self.GetPath(iLTInterface),length,len(s_value),ord(s_value))) else: self.printf( "LtInterface.Read(%s) length=%i len(s_value)=%i" % (self.GetPath(iLTInterface),length,len(s_value))) return s_value except IOError,e: print "LtInterface.Read() %s %s" %(self.GetPath(iLTInterface), e) return s_value pass def Closed(self,iLTInterface): return Treiber.f_LtFunction[iLTInterface].closed def Write(self,string,iLTInterface): try: if self.Open(iLTInterface,"wb"): Treiber.f_LtFunction[iLTInterface].seek(0,0) self.printf( "LtInterface.write(%s) c_charlength=%i" % (self.GetPath(iLTInterface),len(string))) Treiber.f_LtFunction[iLTInterface].write(string) returnwert = Treiber.f_LtFunction[iLTInterface].tell() if len(string)==1: if self.MerkerDrehzahl != string: self.printf( "LtInterface.write(0x%x,%s)" % (ord(string),self.GetPath(iLTInterface))) self.MerkerDrehzahl = string else: self.printf( "LtInterface.write(%s) length=%i" % (self.GetPath(iLTInterface),returnwert)) return returnwert else: self.printf( "LtInterface.Write(%s) open error" % self.GetPath(iLTInterface)) return 0 except IOError,e: returnwert = Treiber.f_LtFunction[iLTInterface].tell() self.Close(iLTInterface) if len(string)==1: self.printf( "LtInterface.write(0x%x,%s)" % (ord(string),self.GetPath(iLTInterface))) else: self.printf( "LtInterface.write(%s) length=%i" % (self.GetPath(iLTInterface),returnwert)) return returnwert pass def SetDataSelect(self,Zustand): if Zustand: s_string = chr(0x05) else: s_string = chr(0x00) self.printf("SetDataSelect 0x%x"%ord(s_string)) return self.Write(s_string, Treiber.INDEX_DATA_SELECT) pass def LTFreigabe(self,Zustand): if Zustand: s_string = chr(0x05) else: s_string = chr(0x00) self.printf("LTFreigabe 0x%x"%ord(s_string)) return self.Write(s_string, Treiber.INDEX_ENABLE) pass def SetDrehzahl(self,iDrehzahlNeu): if Treiber.iDrehzahl == iDrehzahlNeu: #nichts tun return False Treiber.iDrehzahl=iDrehzahlNeu self.printf("SetDrehzahl %i U/min" % Treiber.iDrehzahl) return True def GetSpindelNennDrehzahl(self): if Treiber.SpindelNennDrehzahl ==None: self.readSpindleParams() return Treiber.SpindelNennDrehzahl def writeDrehzahl(self): iMotordrehzahl = int( self.iDrehzahl * Treiber.Getriebeuntersetzung * Treiber.Abtriebuntersetzung) #self.printf("writeDrehzahl iMotordrehzahl=0x%02x" % iMotordrehzahl) s_Drehzahl = chr((+((iMotordrehzahl * 0x7F)/Treiber.Motornenndrehzahl)) & 0xFF) #self.printf("writeDrehzahl 0x%02x" % ord(s_Drehzahl)) self.Write(s_Drehzahl,Treiber.INDEX_SPEED_REF) pass def stop(self): # Thread normal beenden self.printf("stop") if self.isAlive(): self._EventStop.set() #print "stop Ende" pass def stopped(self): return self._EventStop.isSet() def run(self): # Ablauf starten self.printf("Ablauf starten") self.runMotor() self.printf("Nach Ablauf") pass def runMotor(self): if Treiber.SpindelNennDrehzahl ==None: self.readSpindleParams() self.StopWatchdog() Treiber.WatchdogActive=False # Kurz warten bis Watchdog beendet time.sleep(0.050) self.LTFreigabe(1) while (not self.stopped()): self.writeDrehzahl() time.sleep(0.002) self.SetDrehzahl(0) self.writeDrehzahl() self.LTFreigabe(0) self.StartWatchdog() pass def ResetWatchdog(self,KeepAliveTime): while ((not self.stopped())&(Treiber.WatchdogActive)): self.printf("LtInterface.ResetWatchdog") self.LTFreigabe(1) self.SetDrehzahl(36)#entspricht digital 10 von 255 self.writeDrehzahl() time.sleep(0.005) self.SetDrehzahl(0) self.writeDrehzahl() self.LTFreigabe(0) time.sleep(KeepAliveTime) def StartWatchdog(self): self.printf("LtInterface.StartWatchdog") if not Treiber.WatchdogActive: thread.start_new_thread(self.ResetWatchdog,(Treiber.KeepAliveTime,)) Treiber.WatchdogActive = True pass def StopWatchdog(self): self.printf("LtInterface.StopWatchdog") time.sleep(0.05) Treiber.WatchdogActive = False pass def UpdateLTFirmware(self): # FilenamePath checken # Filegroesse LtFw pruefen try: if self.Open(Treiber.INDEX_LT_FW_FILEPATH,"rb"): Treiber.f_LtFunction[Treiber.INDEX_LT_FW_FILEPATH].seek(0,2) l_size = Treiber.f_LtFunction[Treiber.INDEX_LT_FW_FILEPATH].tell() else: l_size = Treiber.MAX_FILE_SIZE + 4711 self.printf( "LtInterface.UpdateLTFirmware(%s) filesize=%i" % (self.GetPath(Treiber.INDEX_LT_FW_FILEPATH),l_size)) if (l_size >= Treiber.MAX_FILE_SIZE) or (l_size==0): self.printf ("LtInterface.UpdateLTFirmware()->Filesize(%s)->%i zu Gross Max=%i" %(self.GetPath(Treiber.INDEX_LT_FW_FILEPATH),l_size,Treiber.MAX_FILE_SIZE)) self.Close(Treiber.INDEX_LT_FW_FILEPATH) return False self.Close(Treiber.INDEX_LT_FW_FILEPATH) except IOError,e: self.Close(Treiber.INDEX_LT_FW_FILEPATH) self.printf( "LtInterface.UpdateLTFirmware()->Filesize %s %s" %(self.GetPath(Treiber.INDEX_LT_FW_FILEPATH), e)) return False # LT Freigabe wegnehmen self.LTFreigabe(0) #Fw einlesen try: s_LtFw = self.Read(Treiber.INDEX_LT_FW_FILEPATH,Treiber.MAX_FILE_SIZE) self.Close(Treiber.INDEX_LT_FW_FILEPATH) if l_size!=len(s_LtFw): self.printf( "LtInterface.UpdateLTFirmware()->read %s nur %i Bytes gelesen" %(self.GetPath(Treiber.INDEX_LT_FW_FILEPATH),len(s_LtFw))) return False else: self.printf("LtInterface.UpdateLTFirmware()->read %s %i Bytes gelesen" %(self.GetPath(Treiber.INDEX_LT_FW_FILEPATH),len(s_LtFw))) except IOError,e: self.printf( "LtInterface.UpdateLTFirmware()->read LtFw %s %s" %(self.GetPath(Treiber.INDEX_LT_FW_FILEPATH), e)) return False # Keepalive stoppen try: for attempt in range (1, Treiber.CMD_KEEP_ALIVE_TRYS , 1): laenge=self.Write(Treiber.LT_FWCTRL_STOPKEEPALIVE, Treiber.INDEX_FW_CONTROL) if laenge != len (Treiber.LT_FWCTRL_STOPKEEPALIVE): self.printf("f_UpdateLTFirmware Keepalive laesst sich nicht stoppen ... Next try " %(attempt)) time.sleep(2) else: self.printf("f_UpdateLTFirmware Keepalive gestoppt " %(attempt)) break self.printf("f_UpdateLTFirmware Keepalive " %(attempt)) if attempt == Treiber.CMD_KEEP_ALIVE_TRYS-1: self.printf("f_UpdateLTFirmware Keepalive laesst sich nicht stoppen") laenge=self.Write(Treiber.LT_FWCTRL_STARTKEEPALIVE, Treiber.INDEX_FW_CONTROL) if laenge != len (Treiber.LT_FWCTRL_STARTKEEPALIVE): self.printf("f_UpdateLTFirmware Keepalive starten %s" %(Treiber.LT_FWCTRL_STARTKEEPALIVE)) return False else: return True except IOError,e: self.printf( "LtInterface.UpdateLTFirmware()->write LT_FWCTRL_STOPKEEPALIVE LtFw %s %s" %(self.GetPath(Treiber.INDEX_FW_CONTROL), e)) return False # LT in Bootlader Modus schicken try: l_write=self.Write(Treiber.LT_FWCTRL_GOTOBL, Treiber.INDEX_FW_CONTROL) if l_write!=len(Treiber.LT_FWCTRL_GOTOBL): self.printf( "LtInterface.UpdateLTFirmware()->write %s nur %i Bytes geschrieben" %(Treiber.LT_FWCTRL_GOTOBL,l_write)) return False except IOError,e: self.printf( "LtInterface.UpdateLTFirmware()->write LT_FWCTRL_GOTOBL LtFw %s %s" %(self.GetPath(Treiber.INDEX_FW_CONTROL), e)) return False time.sleep(2) #BL Abfrage try: for attempt in range (0, Treiber.CMD_FW_CTRL_TRYS , 1): laenge=self.Write(Treiber.LT_FWCTRL_REQSYNC, Treiber.INDEX_FW_CONTROL) if laenge != len (Treiber.LT_FWCTRL_REQSYNC): self.printf("f_UpdateLTFirmware NxLt nicht im Bootloader ... Next try " %(attempt)) time.sleep(2) else: self.printf("f_UpdateLTFirmware NxLt ist im Bootloader " %(attempt)) break if attempt == Treiber.CMD_FW_CTRL_TRYS-1: self.printf("Keine Antwort vom Bootlader -> KeepAlive wieder starten!") laenge=self.Write(Treiber.LT_FWCTRL_STARTKEEPALIVE, Treiber.INDEX_FW_CONTROL) if laenge != len (Treiber.LT_FWCTRL_STARTKEEPALIVE): self.printf("f_UpdateLTFirmware BL Abfrage %s" %(Treiber.LT_FWCTRL_STARTKEEPALIVE)) return False else: return True except IOError,e: self.printf( "LtInterface.UpdateLTFirmware()->write LT_FWCTRL_REQSYNC LtFw %s %s" %(self.GetPath(Treiber.INDEX_FW_CONTROL), e)) return False time.sleep(1) #Sektoren loeschen try: l_write=self.Write(Treiber.LT_FWCTRL_DELETESECTORS, Treiber.INDEX_FW_CONTROL) if l_write!=len(Treiber.LT_FWCTRL_DELETESECTORS): self.printf( "LtInterface.UpdateLTFirmware()->write %s nur %i Bytes geschrieben" %(Treiber.LT_FWCTRL_DELETESECTORS,l_write)) return False except IOError,e: self.printf( "LtInterface.UpdateLTFirmware()->write LT_FWCTRL_DELETESECTORS LtFw %s %s" %(self.GetPath(Treiber.INDEX_FW_CONTROL), e)) return False time.sleep(1) # Friss oder stirb try: l_write=self.Write(s_LtFw, Treiber.INDEX_FW_UPDATE) if l_write!=len(s_LtFw): self.printf( "LtInterface.UpdateLTFirmware()->write %s nur %i Bytes geschrieben" %(self.GetPath(Treiber.INDEX_FW_UPDATE),l_write)) return False except IOError,e: self.printf( "LtInterface.UpdateLTFirmware()->write LT_FW %s %s" %(self.GetPath(Treiber.INDEX_FW_UPDATE), e)) return False time.sleep(1) # Wiederbelebung try: l_write=self.Write(Treiber.LT_FWCTRL_STARTFW, Treiber.INDEX_FW_CONTROL) if l_write!=len(Treiber.LT_FWCTRL_STARTFW): self.printf( "LtInterface.UpdateLTFirmware()->write %s nur %i Bytes geschrieben" %(Treiber.LT_FWCTRL_STARTFW,l_write)) return False except IOError,e: self.printf( "LtInterface.UpdateLTFirmware()->write LT_FW %s %s" %(self.GetPath(Treiber.INDEX_FW_CONTROL), e)) return False # Tod oder Lebendig return True pass def SetLEDRGB(self,red,green,blue): self.LEDred = self.ChkLEDHelligkeit(red) self.LEDgreen = self.ChkLEDHelligkeit(green) self.LEDblue = self.ChkLEDHelligkeit(blue) self.struct_RGB = struct.pack('BBB',self.LEDred,self.LEDgreen,self.LEDblue) self.Write(str(self.struct_RGB),Treiber.INDEX_LED_RGB) return True def SetLEDRed(self,Helligkeit): self.SetLEDRGB(Helligkeit,self.LEDgreen,self.LEDblue) return True def SetLEDGreen(self,Helligkeit): self.SetLEDRGB(self.LEDred,Helligkeit,self.LEDblue) return True def SetLEDBlue(self,Helligkeit): self.SetLEDRGB(self.LEDred,self.LEDgreen,Helligkeit) return True def ChkLEDHelligkeit(self,Helligkeit): if Helligkeit < 0: Helligkeit = 0 if Helligkeit > 255: Helligkeit = 255 return Helligkeit def SetLED(self,Helligkeit): self.Write(chr(self.ChkLEDHelligkeit(Helligkeit)),Treiber.INDEX_LED) return True def LEDSoftBlink(self,cycletime): #cycletime=float(cycletime) #print"cycletime %f"%(cycletime) multip=2.55/float(cycletime)*2 rest = (multip - int(multip))*0.005 multip=int(multip) #print"multip %i resttime=%f"%(multip,rest) for i in range (0,255,multip): self.SetLED(i) time.sleep(rest) time.sleep(rest) for i in range (255,0,-multip): self.SetLED(i) time.sleep(rest) self.SetLED(0) time.sleep(rest) return True def LEDRegenbogen(self): for z in range(100): for i in range (0,20,5): self.SetLEDRed(i) time.sleep(0.01) for i in range (20,256,15): self.SetLEDRed(i) time.sleep(0.01) time.sleep(0.400) for i in range (0,20,5): self.SetLEDGreen(i) time.sleep(0.01) for i in range (20,256,15): self.SetLEDGreen(i) time.sleep(0.01) time.sleep(0.400) for i in range (0,20,5): self.SetLEDBlue(i) time.sleep(0.01) for i in range (20,256,15): self.SetLEDBlue(i) time.sleep(0.01) time.sleep(0.400) for i in range (256,20,-15): self.SetLEDRed(i) time.sleep(0.01) for i in range (20,0,-5): self.SetLEDRed(i) time.sleep(0.01) self.SetLEDRed(0) time.sleep(0.100) for i in range (256,20,-15): self.SetLEDGreen(i) time.sleep(0.01) for i in range (20,0,-5): self.SetLEDGreen(i) time.sleep(0.01) self.SetLEDGreen(0) time.sleep(0.100) for i in range (256,20,-15): self.SetLEDBlue(i) time.sleep(0.01) for i in range (20,0,-5): self.SetLEDBlue(i) time.sleep(0.01) self.SetLEDBlue(0) time.sleep(0.100) return True def printf(self,string): if Treiber.stout: print string pass