# -*- coding: cp1252 -*- ''' Created on 11.10.2011 @author: sth2mt ''' I2C_DEV_1="/dev/i2c-1" I2C_DEV_2="/dev/i2c-2" I2C_DEV_3="/dev/i2c-3" ''' /dev/i2c-X ioctl commands. The ioctl's parameter is always an * unsigned long, except for: * - I2C_FUNCS, takes pointer to an unsigned long * - I2C_RDWR, takes pointer to struct i2c_rdwr_ioctl_data * - I2C_SMBUS, takes pointer to struct i2c_smbus_ioctl_data *''' I2C_RETRIES=0x0701 # number of times a device address should be polled when not acknowledging I2C_TIMEOUT=0x0702 # set timeout in jiffies - call with int ''' NOTE: Slave address is 7 or 10 bits, but 10-bit addresses * are NOT supported! (due to code brokenness) ''' I2C_SLAVE=0x0703 # Use this slave address I2C_SLAVE_FORCE=0x0706 # Use this slave address, even if it is already in use by a driver! */ I2C_TENBIT=0x0704 # 0 for 7 bit addrs, != 0 for 10 bit I2C_FUNCS=0x0705 # Get the adapter functionality mask I2C_RDWR=0x0707 # Combined R/W transfer (one STOP only) I2C_PEC=0x0708 # != 0 to use PEC with SMBus I2C_SMBUS=0x0720 #SMBus transfer I2C_M_RD=0x0001 #read Data from slave to master I2C_OFFSET_DAC101C081 = 0x0D #Drehzahl I2C_OFFSET_AD7991 = 0x29 #Startschalter, R/L-Schalter, VBat I2C_OFFSET_LP3943 = 0x64 import Gpio as Gpio import time import fcntl ioctl = fcntl.ioctl from ctypes import CDLL, c_char_p, c_ubyte, c_ushort, pointer,c_char, create_string_buffer class Treiber(object): ''' classdocs ''' # Achtung dies ist Pseudo Singleton -> variablen werden statisch verwendet. Aufgeraumt wird erst wenn alle instanzen weg sindwird nur einmal instaniiert !!!! ObjCount = [0,0,0,0] _Thread_name = "I2CDev" stout = False sI2Path = "/usr/lib/libi2c.so" i2clib=[CDLL(sI2Path),CDLL(sI2Path),CDLL(sI2Path),CDLL(sI2Path)] O_UI2c = None Token=False def __init__(self,i_I2C_Bus_Nr): ''' Constructor ''' self.I2C_BusNr = i_I2C_Bus_Nr self.printf("%i.Construktor %s Bus Nr %i" % (Treiber.ObjCount[self.I2C_BusNr]+1,Treiber._Thread_name,i_I2C_Bus_Nr)) self.i_I2cDevError = 0 self.i_I2C_Adress = None self.pw_Buf = create_string_buffer(b'0',2) self.pr_Buf = create_string_buffer(b'0',4096) if i_I2C_Bus_Nr < 4: self.s_I2C_Bus_Nr = "/dev/i2c-%d" % i_I2C_Bus_Nr else: self.s_I2C_Bus_Nr = None self.i_I2cDevError = -1 #Spannung fuer I2c und Epld einschalten if Treiber.O_UI2c == None: Treiber.O_UI2c = Gpio.Treiber(154,Gpio.GPIO_DIRECT_OUT,False) # invers if Treiber.ObjCount[self.I2C_BusNr] < 1: self.f_OpenI2cBus() Treiber.ObjCount[self.I2C_BusNr] +=1 pass def __del__(self): ''' Destructor ''' self.I2C_BusNr = 2 self.printf( "%i. Destruktor %s Bus Nr %i" % (Treiber.ObjCount[self.I2C_BusNr],Treiber._Thread_name,self.I2C_BusNr)) if Treiber.ObjCount[self.I2C_BusNr] == 1: self.printf("Reste aufraumen") self.f_CloseI2cBus() Treiber.O_UI2c.f_WritePin(False) # invers del(Treiber.O_UI2c) Treiber.O_UI2c = None if Treiber.ObjCount[self.I2C_BusNr] > 0: Treiber.ObjCount[self.I2C_BusNr] -= 1 pass def f_OpenI2cBus(self): try: if Treiber.i2clib[self.I2C_BusNr].i2c_open(c_char_p(self.s_I2C_Bus_Nr)) < 0: raise IOError("IOError") self.printf( "I2C.f_OpenI2cBus(%s) opened successfully" %self.s_I2C_Bus_Nr) self.i_I2cDevError = 0; return 0 except IOError,e: print "I2C.f_OpenI2cBus()", e self.i_I2cDevError = -1 return -1 pass def f_CloseI2cBus(self): try: if Treiber.i2clib[self.I2C_BusNr].i2c_close() < 0: raise IOError("IOError") except IOError,e: print "I2C.f_CloseI2cBus()", e self.i_I2cDevError = -1 return -1 pass def f_Write16(self,i_Adress,i_Offset,s_Daten,i_Anzahl): try: pw_Buf = create_string_buffer(b'0',i_Anzahl+2) self.i_I2C_Adress=i_Adress pw_Buf[1] = chr(i_Offset&0xFF) pw_Buf[0] = chr((i_Offset&0xFF00)>>8) self.printf( "I2C.f_Write16(0X%02X,0X%02X)Offset=0x%x Laenge %i" % (ord(pw_Buf[1]),ord(pw_Buf[0]),i_Offset,i_Anzahl)) #print "I2C.f_Write16(0X%02X,0X%02X)Offset=0x%x Laenge %i %s" % (ord(pw_Buf[1]),ord(pw_Buf[0]),i_Offset,i_Anzahl,s_Daten) for i in range (0,i_Anzahl,1): self.printf("0x%02X %c," % (ord(pw_Buf[i+2]),s_Daten[i])) pw_Buf[i+2] = chr(ord(s_Daten[i])) #print"0x%02X," % ord(pw_Buf[i+2]) # write all self.semTake() if Treiber.i2clib[self.I2C_BusNr].i2c_write(c_ubyte(self.i_I2C_Adress),pw_Buf,c_ushort(i_Anzahl+2))< 1: raise IOError("IOError") time.sleep(0.005*2)# Twrite I2C 5ms , doppelte Zeit nehmen self.semGive() return 0 except IOError,e: self.semGive() self.printf( "I2C.f_Write16(0X%02X,0X%02X)Offset=0x%x Laenge %i, %s" % (ord(pw_Buf[1]),ord(pw_Buf[0]),i_Offset,i_Anzahl,e)) return -3 pass def f_Write8(self,i_Adress,c_Offset,s_Daten,i_Anzahl): try: pw_Buf = create_string_buffer(b'0',i_Anzahl+1) self.i_I2C_Adress=i_Adress # chosse Adress 8Bit Offset + Daten # Adress Byte self.printf("I2C.f_Write8 0x%02X Offset %i " %(self.i_I2C_Adress, c_Offset)) pw_Buf[0] = chr(c_Offset) for i in range (0,i_Anzahl,1): pw_Buf[i+1] = s_Daten[i] self.printf("0x%02X," % ord(pw_Buf[i+1])) # write all self.semTake() if Treiber.i2clib[self.I2C_BusNr].i2c_write(c_ubyte(self.i_I2C_Adress),pw_Buf,c_ushort(i_Anzahl+1))< 1: raise IOError("IOError") self.semGive() return 0 except IOError,e: self.semGive() print "I2C.f_Write8(0x%02x,%d) Error" % (c_Offset, i_Anzahl) ,e return -3 pass def f_Read8(self,i_Adress,c_Offset,i_Anzahl): try: pw_Buf = create_string_buffer(b'0',1) pr_Buf = create_string_buffer(b'0',i_Anzahl) self.i_I2C_Adress=i_Adress pw_Buf[0] = chr(c_Offset) self.printf( "I2C.f_Read8(0x%02X) Laenge %i" % (ord(pw_Buf[0]),1)) # read all self.semTake() laenge=Treiber.i2clib[self.I2C_BusNr].i2c_readw(c_ubyte(self.i_I2C_Adress),pw_Buf,c_ushort(1),pr_Buf,c_ushort(i_Anzahl)) if laenge < 1: time.sleep(0.01) #nochmals versuchen manchmal gehts nich laenge=Treiber.i2clib[self.I2C_BusNr].i2c_readw(c_ubyte(self.i_I2C_Adress),pw_Buf,c_ushort(1),pr_Buf,c_ushort(i_Anzahl)) if laenge < 1: raise IOError("IOError") self.semGive() self.printf( "Laenge %i" % laenge) #for i in range(0,i_Anzahl,1): # self.printf( "0x%02X '%c'," % (ord(pr_Buf[i]),pr_Buf[i]) ) return pr_Buf.raw except IOError,e: self.semGive() print "I2C.f_Read8(0x%02x,%d) Error" % (c_Offset, i_Anzahl) ,e return pr_Buf.raw def f_Read16(self,i_Adress,i_Offset,i_Anzahl): try: pw_Buf = create_string_buffer(b'0',2) pr_Buf = create_string_buffer(b'0',i_Anzahl) self.i_I2C_Adress=i_Adress pw_Buf[1] = chr(i_Offset&0xFF) pw_Buf[0] = chr((i_Offset&0xFF00)>>8) self.printf( "I2C.f_Read16(Adr 0x%x,0x%02X,0x%02X) Laenge %i" % (i_Adress,ord(pw_Buf[1]),ord(pw_Buf[0]),i_Anzahl)) # read all self.semTake() laenge=Treiber.i2clib[self.I2C_BusNr].i2c_lltransfer(c_ubyte(self.i_I2C_Adress),pw_Buf,c_ushort(2),pr_Buf,c_ushort(i_Anzahl)) if laenge < 1: self.f_CloseI2cBus()# I2C Bus neu initialisieren time.sleep(0.1) self.f_OpenI2cBus() #nochmals versuchen manchmal gehts nich laenge=Treiber.i2clib[self.I2C_BusNr].i2c_lltransfer(c_ubyte(self.i_I2C_Adress),pw_Buf,c_ushort(2),pr_Buf,c_ushort(i_Anzahl)) if laenge < 1: raise IOError("IOError") self.semGive() self.printf( "Laenge %i" % laenge) #for i in range(0,i_Anzahl,1): # self.printf( "0x%02X '%c'," % (ord(pr_Buf[i]),pr_Buf[i]) ) return pr_Buf.raw except IOError,e: self.semGive() print "I2C.f_Read16(0X%02X,0X%02X) Laenge %i Error" % (ord(pw_Buf[1]),ord(pw_Buf[0]),laenge) ,e return pr_Buf.raw pass def f_Read(self,i_Adress,i_Anzahl): try: s_Buf=self.f_Read8(i_Adress,0,i_Anzahl) for i in range(0,i_Anzahl,1): self.printf( "0x%02X," % ord(s_Buf[i]) ) return s_Buf except IOError,e: print "I2C.f_Read(%d) Error" % ( i_Anzahl) ,e return -3 pass def semTake(self): while Treiber.Token: time.sleep(0.05) Treiber.Token = True def semGive(self): Treiber.Token = False def printf(self,string): if Treiber.stout: print string pass