5 Replies Latest reply on Mar 7, 2015 1:02 PM by MyDirtIsRed

    Python, MRAA, I2C, and non-standard Addressing

    MyDirtIsRed

      Hello,

       

      I've got a particular part hooked up over I2C to my Edison (through some level-shifters).  Python is generally my weapon of choice, and after reading some things, I initially decided that it suited my needs just fine.  However, I'm having a little bit of trouble understanding how the mraa library works, especially if the hardware on the bus uses 16 bit addresses.  I'm attaching an example of what I mean.  Here's some snippets from some code that I've put together:

       

      class Device(object):
        def __init__(  self,
                        parent=None,
                        i2c_bus=1,
                        i2c_addr=0x28):
            """
            Initialization function.
            """
            self.mraa_i2c = mraa.I2c(i2c_bus)
            self.mraa_i2c.address(i2c_addr)

       

      ...

       

        def smallRegisterDump(self):
            for addr in [self.ctrl, self.status, self.int_enable, self.int_flags, self.version_reg,self.id_reg]:
               self.mraa_i2c.write(bytearray(b'0xFF'+str(addr[0])))
               print addr[1]+" = "+str(self.mraa_i2c.readByte())

       

      ...and then the main code establishes an instance of the class and calls the smallRegisterDump function.  Of course, I now realize, after looking at more code examples on the web and looking at the I2C lines on the oscilloscope that this code doesn't do what I was intending.  Instead, the first line (self.mraa_i2c.write) actually requests a write (not what I intended), and the address to which it's trying to write is not what I was expecting either.  Any ideas as to how I can read from a 16-bit address with the mraa library, or is it, as I suspect, just not possible with that library?  If it's not possible with the mraa library, is there another library that I can use, or am I really going to have my 'roll my own' here?  I can code everything in C, but if there's a 'pythonic' alternative, I generally prefer that.

       

      I also have experience taking C code and turning it into a Python library if need be, but most C code that I've seen for the Edison that utilizes I2C makes use of the mraa library, which from what I can tell is what is ultimately limiting me.

       

      Thanks in advance!

        • 1. Re: Python, MRAA, I2C, and non-standard Addressing
          Intel_Peter

          Hello MyDirtIsRed,

           

          As an alternate to the MRAA library you could use I2Ctools, you can get it if you type the following on your Edison:

          opkg install http://repo.opkg.net/edison/repo/core2-32/i2c-tools_3.1.0-r0_core2-32.ipk
          

          Also you might find this thread useful:

          Re: I2C Help

          In it they suggest this git: edouardrosset/i2c-tools · GitHub, I believe it might also be helpful for you.

           

          Peter.

          • 2. Re: Python, MRAA, I2C, and non-standard Addressing
            MyDirtIsRed

            Hello Peter,

             

            I wound up pulling the source of i2c-tools from github and building it.  There were a couple of tweaks necessary to get it built and then to be able to import the library.  I will share them for posterity:

             

            -You must start by building i2c-tools before building the python module.  It states in the README that you should be able to run the command 'make EXTRA="py-smbus"', but this fails.  Instead, ran 'make' followed by 'make install', and then cd'ed into py-smbus and ran 'python setup.py build' and 'python setup.py install'.

            -Once the module built successfully, could not just import smbus (results in ImportError: libi2c.so.0: cannot open shared...).  I use bash as my shell, so in ~/.bashrc, include the line 'export LD_LIBRARY_PATH=/usr/local/lib'.  This fixes it.

             

            However, in looking through the code, it looks like everything is still hard-coded for a byte-wide command, as opposed to a 2-byte command.  Am I mistaken?  If not, it's easy enough to add code for longer command sequences.

             

            Thanks,

            Jake

            • 3. Re: Python, MRAA, I2C, and non-standard Addressing
              arfoll

              I'm not sure I understand your question, if you want to read a 16bit you can use readWordReg for example. AFAIK all command bytes are 8bit but sometimes people shortand them and want the next one, that's why we have the read(2) which will do a read of two commands one after the other. You have to give your address in 7bit format not 8bit, mraa will do the flipping read/write of the LSB for you.

              • 4. Re: Python, MRAA, I2C, and non-standard Addressing
                MyDirtIsRed

                Hello arfoll,

                 

                Thank you for responding.  In reading the mraa documentation, I don't think that readWordReg applies, unless I'm missing something.  The registers on the hardware that I'm trying to communicate with have commands that are 16 bits wide and data that is 8 bits wide.  If I'm reading the documentation for readWordReg correctly, it sounds like to me that the command space is 8 bits, and the data coming back is 16 bits wide.  Am I correct, or does readWordReg actually do what I'm looking for?

                 

                Thanks,

                Jake

                • 5. Re: Python, MRAA, I2C, and non-standard Addressing
                  MyDirtIsRed

                  Hello,

                   

                  Ok, I figured out what my problem was.  It wasn't with the mraa library, it was how I was using the Python bytearray function.  arfoll, you are correct in everything that you said.  For a device that uses a 16-bit command (like the one that I'm interfacing with), I'm able to treat it as if I'm writing a byte (the LSBs of the 16-bit command byte) to a command register (the MSBs of the 16-bit command byte).

                   

                  Thank you for your help!

                  Jake