python i2c ioctl

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • luca

    #1

    python i2c ioctl


    Hi,
    I was trying to make to work directly l i2c with python with the
    calls ioctl. But I have of the problems and I do not succeed to go
    ahead.

    this and l error

    [root@axis-00408c000001 /usr/local/wrap]129# python pcf8591_ioctl.p y
    Reading from 4 ch 8 bit A/D converter PCF8591
    Traceback (most recent call last):
    File "pcf8591_ioctl. py", line 269, in ?
    main()
    File "pcf8591_ioctl. py", line 229, in main
    if i2c_open () < 0:
    File "pcf8591_ioctl. py", line 168, in i2c_open
    fcntl.ioctl(i2c _fd, _IO(ETRAXGPIO_I OCTYPE, IO_SETGET_OUTPU T), 0,
    iomask)
    TypeError: ioctl requires a file or file descriptor, an integer and
    optionally a integer or buffer argument

    the code

    import fcntl
    import os
    ############### ############### #####
    #etrax.h
    ETRAXGPIO_IOCTY PE = 43
    GPIO_MINOR_A = 0
    GPIO_MINOR_B = 1
    GPIO_MINOR_LEDS = 2
    GPIO_MINOR_G = 3
    GPIO_MINOR_LAST = 3
    IO_READBITS = 0x1
    IO_SETBITS = 0x2
    IO_CLRBITS = 0x3
    IO_HIGHALARM = 0x4
    IO_LOWALARM = 0x5
    IO_CLRALARM = 0x6
    IO_LEDACTIVE_SE T = 0x7
    IO_READDIR = 0x8
    IO_SETINPUT = 0x9
    IO_SETOUTPUT = 0xA
    IO_LED_SETBIT = 0xB
    IO_LED_CLRBIT = 0xC
    IO_SHUTDOWN = 0xD
    IO_GET_PWR_BT = 0xE
    IO_CFG_WRITE_MO DE = 0xF

    def IO_CFG_WRITE_MO DE_VALUE(msb, data_mask, clk_mask):
    ( (((msb)&1) << 16) | (((data_mask) &0xFF) << 8) | ((clk_mask) &
    0xFF) )
    def IO_CFG_WRITE_MO DE_VALUE(msb, data_mask, clk_mask):
    ( (((msb)&1) << 16) | (((data_mask) &0xFF) << 8) | ((clk_mask) &
    0xFF) )

    IO_READ_INBITS = 0x10
    IO_READ_OUTBITS = 0x11
    IO_SETGET_INPUT = 0x12
    IO_SETGET_OUTPU T = 0x13
    ############### ############### #########
    ############### ############### #########
    #ioctl.h

    _IOC_NRBITS = 8
    _IOC_TYPEBITS= 8
    _IOC_SIZEBITS =14
    _IOC_DIRBITS = 2
    _IOC_NRMASK = ((1 << _IOC_NRBITS)-1)
    _IOC_TYPEMASK = ((1 << _IOC_TYPEBITS)-1)
    _IOC_SIZEMASK =((1 << _IOC_SIZEBITS)-1)
    _IOC_DIRMASK =((1 << _IOC_DIRBITS)-1)
    _IOC_NRSHIFT =0
    _IOC_TYPESHIFT =(_IOC_NRSHIFT+ _IOC_NRBITS)
    _IOC_SIZESHIFT =(_IOC_TYPESHIF T+_IOC_TYPEBITS )
    _IOC_DIRSHIFT =(_IOC_SIZESHIF T+_IOC_SIZEBITS )
    _IOC_NONE=0
    _IOC_WRITE=1
    _IOC_READ=2
    def _IOC(dir,type,n r,size):
    (((dir) << _IOC_DIRSHIFT) |
    ((type) << _IOC_TYPESHIFT) |
    ((nr) << _IOC_NRSHIFT) |
    ((size) << _IOC_SIZESHIFT) )

    def _IO(type,nr):
    _IOC(_IOC_NONE, (type),(nr),0)

    def _IOR(type,nr,si ze):
    _IOC(_IOC_READ, (type),(nr),siz eof(size))

    def _IOW(type,nr,si ze):
    _IOC(_IOC_WRITE ,(type),(nr),si zeof(size))

    def _IOWR(type,nr,s ize):
    _IOC(_IOC_READ| _IOC_WRITE,(typ e),(nr),sizeof( size))

    def _IOC_DIR(nr):
    (((nr) >_IOC_DIRSHIF T) & _IOC_DIRMASK)
    def _IOC_TYPE(nr):
    (((nr) >_IOC_TYPESHIFT ) & _IOC_TYPEMASK)
    def _IOC_NR(nr):
    (((nr) >_IOC_NRSHIFT ) & _IOC_NRMASK)
    def _IOC_SIZE(nr):
    (((nr) >_IOC_SIZESHIFT ) & _IOC_SIZEMASK)
    def IOC_IN():
    (_IOC_WRITE << _IOC_DIRSHIFT)

    def IOC_OUT():
    (_IOC_READ << _IOC_DIRSHIFT)
    def IOC_INOUT():
    ((_IOC_WRITE|_I OC_READ) << _IOC_DIRSHIFT)
    def IOCSIZE_MASK():
    (_IOC_SIZEMASK << _IOC_SIZESHIFT)
    def IOCSIZE_SHIFT() :
    (_IOC_SIZESHIFT )
    ############### ############### ########
    ############### ############### ########
    ############### ############### ########



    I2C_DATA_LINE = 1<<24
    I2C_CLOCK_LINE = 1<<25


    #Get the SDA line state
    def i2c_getbit():
    value=fcntl.ioc tl(i2c_fd, _IO(ETRAXGPIO_I OCTYPE, IO_READBITS))
    if ((value&(I2C_DA TA_LINE))==0):
    return 0
    else:
    return 1

    #Set the SDA line as output
    def i2c_dir_out():
    iomask = I2C_DATA_LINE
    fcntl.ioctl(i2c _fd, _IO(ETRAXGPIO_I OCTYPE, IO_SETGET_OUTPU T), iomask)

    #Set the SDA line as input
    def i2c_dir_in():
    iomask = I2C_DATA_LINE
    fcntl.ioctl(i2c _fd, _IO(ETRAXGPIO_I OCTYPE, IO_SETGET_INPUT ), iomask)

    #Set the SDA line state
    def i2c_data(state) :
    if (state==1):
    i2c_dir_in()
    else:
    i2c_dir_out()
    fcntl.ioctl(i2c _fd, _IO(ETRAXGPIO_I OCTYPE, IO_CLRBITS),
    I2C_DATA_LINE)
    #Set the SCL line state
    def i2c_clk(state):
    if (state==1):
    ioctl(i2c_fd, _IO(ETRAXGPIO_I OCTYPE, IO_SETBITS), I2C_CLOCK_LINE)
    else:
    ioctl(i2c_fd, _IO(ETRAXGPIO_I OCTYPE, IO_CLRBITS), I2C_CLOCK_LINE)

    #Read a byte from I2C bus and send the ack sequence
    #Put islast = 1 is this is the last byte to receive from the slave

    def i2c_inbyte(isla st):
    value = 0

    #Read data byte

    i2c_clk(0)
    i2c_dir_in()
    for i in range (0,5):
    i2c_clk(1)
    bitvalue = i2c_getbit()
    value |= bitvalue
    if (i<7):
    value = 1
    i2c_clk(0)

    if (islast==0):
    #Send Ack if is not the last byte to read
    i2c_dir_out()
    i2c_data(0)
    i2c_clk(1)
    i2c_clk(0)
    i2c_dir_in()
    else:
    #Doesn't send Ack if is the last byte to read
    i2c_dir_in()
    i2c_clk(1)
    i2c_clk(0)
    return value

    #Open the GPIOB dev
    def i2c_open():
    i2c_fd = os.open("/dev/gpiog", os.O_RDWR)
    iomask = I2C_CLOCK_LINE
    fcntl.ioctl(i2c _fd, _IO(ETRAXGPIO_I OCTYPE, IO_SETGET_OUTPU T), iomask)
    iomask = I2C_DATA_LINE
    fcntl.ioctl(i2c _fd, _IO(ETRAXGPIO_I OCTYPE, IO_SETGET_INPUT ), iomask)
    fcntl.ioctl(i2c _fd, _IO(ETRAXGPIO_I OCTYPE, IO_SETBITS),
    I2C_DATA_LINE)
    i2c_dir_in()
    i2c_clk(1)
    return i2c_fd


    #Close the GPIOB dev
    def i2c_close():
    i2c_dir_in()
    i2c_fd.close()


    #Send a start sequence to I2C bus

    def i2c_start():
    i2c_clk(0)
    i2c_data(1)
    i2c_clk(1)
    i2c_data(0)

    #Send a stop sequence to I2C bus
    def i2c_stop():
    i2c_clk(0)
    i2c_data(0)
    i2c_clk(1)
    i2c_data(1)

    #Send a byte to the I2C bus and return the ack sequence from slave rtc
    #0 = Nack, 1=Ack

    def i2c_outbyte():
    i2c_clk(0)
    for i in range (0,8):
    if (x & 0x80):
    i2c_data(1)
    else:
    i2c_data(0)
    i2c_clk(1)
    i2c_clk(0)
    x <<= 1
    i2c_dir_in()
    i2c_clk(1)
    ack=i2c_getbit( )
    i2c_clk(0)
    if (ack==0):
    return 1
    else:
    return 0

    #PCF8591 address scheme
    #| 1 | 0 | 0 | 1 | A2 | A1 | A0 | R/W |
    #| i2c_fixed | i2c_addr | 1/0 |
    def main ():
    i2c_fixed = 0x09
    i2c_addr = 0x01

    print "Reading from 4 ch 8 bit A/D converter PCF8591"

    if i2c_open () < 0:
    print "i2c open error"
    return 1

    ch = 0

    while "azz":
    i2c_start ()

    if i2c_outbyte ((i2c_fixed<<4) |(i2c_addr<<1)| 0) == 0:
    print "NACK received"
    i2c_stop ()
    continue

    if i2c_outbyte (ch) == 0:
    print "NACK received"
    i2c_stop ()
    continue

    i2c_stop ()
    i2c_start ()

    if i2c_outbyte((i2 c_fixed<<4)|(i2 c_addr<<1)|1) == 0:
    print "NACK received"
    i2c_stop ()
    continue

    i2c_inbyte (0)
    value = i2c_inbyte (1)
    i2c_stop ()

    print "CH%d = %.4fv (%.4f hex/n)" %
    (ch,value*0.012 941,value)

    ch += 1

    if ch == 4:
    break;

    i2c_close ()
    return 0
    main()


    tnx all

  • Tim Roberts

    #2
    Re: python i2c ioctl

    luca <sanluca78@gmai l.comwrote:
    >
    I was trying to make to work directly l i2c with python with the
    >calls ioctl. But I have of the problems and I do not succeed to go
    >ahead.
    >
    >[root@axis-00408c000001 /usr/local/wrap]129# python pcf8591_ioctl.p y
    >Reading from 4 ch 8 bit A/D converter PCF8591
    >Traceback (most recent call last):
    File "pcf8591_ioctl. py", line 269, in ?
    main()
    File "pcf8591_ioctl. py", line 229, in main
    if i2c_open () < 0:
    File "pcf8591_ioctl. py", line 168, in i2c_open
    fcntl.ioctl(i2c _fd, _IO(ETRAXGPIO_I OCTYPE, IO_SETGET_OUTPU T), 0,
    >iomask)
    >TypeError: ioctl requires a file or file descriptor, an integer and
    >optionally a integer or buffer argument
    The error message pretty much tells you the problem. One of the parameters
    is not correct. Notice this:
    >def IO_CFG_WRITE_MO DE_VALUE(msb, data_mask, clk_mask):
    > ( (((msb)&1) << 16) | (((data_mask) &0xFF) << 8) | ((clk_mask) &
    >0xFF) )
    >def IO_CFG_WRITE_MO DE_VALUE(msb, data_mask, clk_mask):
    > ( (((msb)&1) << 16) | (((data_mask) &0xFF) << 8) | ((clk_mask) &
    >0xFF) )
    Key question: what do these functions return?

    Answer: nothing. You compute a value and then throw it away. Thus:
    print IO_CFG_WRITE_MO DE_VALUE( 15, 0xfff, 0x0f0 )
    This will print "None". Add a "return" before the expression.

    The same thing is true of all of these functions. You are thinking that a
    Python "def" is like a C "#define". It's not. It's like a C function.
    Nothing is returned unless you return it.
    >def _IOC(dir,type,n r,size):
    > (((dir) << _IOC_DIRSHIFT) |
    > ((type) << _IOC_TYPESHIFT) |
    > ((nr) << _IOC_NRSHIFT) |
    > ((size) << _IOC_SIZESHIFT) )
    >
    >def _IO(type,nr):
    > _IOC(_IOC_NONE, (type),(nr),0)
    >
    >def _IOR(type,nr,si ze):
    > _IOC(_IOC_READ, (type),(nr),siz eof(size))
    >
    >def _IOW(type,nr,si ze):
    > _IOC(_IOC_WRITE ,(type),(nr),si zeof(size))
    >
    >def _IOWR(type,nr,s ize):
    > _IOC(_IOC_READ| _IOC_WRITE,(typ e),(nr),sizeof( size))
    >
    >def _IOC_DIR(nr):
    > (((nr) >_IOC_DIRSHIF T) & _IOC_DIRMASK)
    >def _IOC_TYPE(nr):
    > (((nr) >_IOC_TYPESHIFT ) & _IOC_TYPEMASK)
    >def _IOC_NR(nr):
    > (((nr) >_IOC_NRSHIFT ) & _IOC_NRMASK)
    >def _IOC_SIZE(nr):
    > (((nr) >_IOC_SIZESHIFT ) & _IOC_SIZEMASK)
    >def IOC_IN():
    > (_IOC_WRITE << _IOC_DIRSHIFT)
    >
    >def IOC_OUT():
    > (_IOC_READ << _IOC_DIRSHIFT)
    >def IOC_INOUT():
    > ((_IOC_WRITE|_I OC_READ) << _IOC_DIRSHIFT)
    >def IOCSIZE_MASK():
    > (_IOC_SIZEMASK << _IOC_SIZESHIFT)
    >def IOCSIZE_SHIFT() :
    > (_IOC_SIZESHIFT )
    However, there are more problems with this script. Example:
    >#Get the SDA line state
    >def i2c_getbit():
    > value=fcntl.ioc tl(i2c_fd, _IO(ETRAXGPIO_I OCTYPE, IO_READBITS))
    > if ((value&(I2C_DA TA_LINE))==0):
    > return 0
    > else:
    > return 1
    This will produce a runtime error, because the name "i2c_fd" is not
    defined. Notice this:
    >#Open the GPIOB dev
    >def i2c_open():
    > i2c_fd = os.open("/dev/gpiog", os.O_RDWR)
    > iomask = I2C_CLOCK_LINE
    > fcntl.ioctl(i2c _fd, _IO(ETRAXGPIO_I OCTYPE, IO_SETGET_OUTPU T), iomask)
    > iomask = I2C_DATA_LINE
    > fcntl.ioctl(i2c _fd, _IO(ETRAXGPIO_I OCTYPE, IO_SETGET_INPUT ), iomask)
    > fcntl.ioctl(i2c _fd, _IO(ETRAXGPIO_I OCTYPE, IO_SETBITS),
    >I2C_DATA_LIN E)
    > i2c_dir_in()
    > i2c_clk(1)
    > return i2c_fd
    The result of the open is bound in a LOCAL variable called "i2c_fd". As
    soon as the function returns, that variable goes away. You do RETURN the
    value, but you don't store it anywhere:
    >#PCF8591 address scheme
    >#| 1 | 0 | 0 | 1 | A2 | A1 | A0 | R/W |
    >#| i2c_fixed | i2c_addr | 1/0 |
    >def main ():
    i2c_fixed = 0x09
    i2c_addr = 0x01
    >
    print "Reading from 4 ch 8 bit A/D converter PCF8591"
    >
    if i2c_open () < 0:
    print "i2c open error"
    return 1
    You should probably make this:

    i2c_fd = i2c_open()
    if i2c_fd < 0:
    print "i2c open error"
    return 1

    But, of course, that's not enough either; i2c_fd is a local variable in
    THIS function as well. You should change ALL of the functions so that they
    accept an fd as the first parameter, and then pass i2c_fd into the
    functions here.

    Alternatively, you could create a wrapper class to hold the fd and make the
    function methods on that class.
    while "azz":
    i2c_start ()
    I'm curious. What do you think "while" statement is doing? The answer is
    that it is an infinite loop; the string "azz" will always be true, so the
    while statement will always loop. I can't guess what you really wanted
    here.
    --
    Tim Roberts, timr@probo.com
    Providenza & Boekelheide, Inc.

    Comment

    Working...