14 Replies Latest reply on Dec 30, 2020 5:37 PM by Jan Cumps

    I2C Slave?

    benett

      Hi

      I need to communicate with a I2C master with a BeagleBone black rev3 (Debian) as a slave.

      I have search over the internet but not find anything. I'm new with BeagleBone.

      I find a lot of example for master but not for the slave.

      Can somebody please help me?

       

      Regards Stefan

        • Re: I2C Slave?
          clem57

          @benett

          May I ask what would the master be? Will there be any other I2C in the design on the same interface? How will the BBB respond to the clock from the master? One way could be to have a forever running service. Another would be to sense interrupt and respond(a bit more difficult). How much coding do you want to do or are you looking for already done code? A hardware hookup picture can help me to suggest some coding...

           

          Clem

            • Re: I2C Slave?
              benett

              Hi

              There will only be one master and one slave. I have no control over the master, it sends a "ping" and listen to a answer from the slave with right address.

              After that normal I2C operation.

              I found this code for the Arduino and that is what I need for BeagleBone, a library. http://arduino.cc/en/Tutorial/MasterWriter

              If someone know what I can find it, I will be happy.

              // Wire Slave Receiver
              // by Nicholas Zambetti <http://www.zambetti.com>
              
              // Demonstrates use of the Wire library
              // Receives data as an I2C/TWI slave device
              // Refer to the "Wire Master Writer" example for use with this
              
              // Created 29 March 2006
              
              // This example code is in the public domain.
              
              
              #include <Wire.h>
              
              void setup()
              {
                Wire.begin(4); // join i2c bus with address #4
                Wire.onReceive(receiveEvent); // register event
                Serial.begin(9600); // start serial for output
              }
              
              void loop()
              {
                delay(100);
              }
              
              // function that executes whenever data is received from master
              // this function is registered as an event, see setup()
              void receiveEvent(int howMany)
              {
                while(1 < Wire.available()) // loop through all but the last
                {
                char c = Wire.read(); // receive byte as a character
                Serial.print(c); // print the character
                }
                int x = Wire.read(); // receive byte as an integer
                Serial.println(x); // print the integer
              }
              
            • Re: I2C Slave?
              gstro

              I'd also like to know this!

               

              For my project, I'd like to have the BBB rev C receive I2C (TWI) messages from up to about 25 different AVR microcontrollers on the bus. I just assumed that the BBB was capable of I2C slave mode because it said it "supports I2C" but now I'm not sure -- I can't find any examples or documentation.

               

              For my application, they could all be masters in a multi-master layout, or they could switch modes -- BBB(slave) listen to all others (multi-master) then switch to the traditional I2C BBB(master) speak to all others (slaves).

               

              Let me know what you find!

              • Re: I2C Slave?
                gdstew

                The I2C hardware on the AM3358/59 SoC  on the BeagleBone Black is perfectly capable of operating in slave mode. The real question is do any of the Linux I2C drivers support it ?

                If they do all you need to do is figure out how to open the I2C interface in slave mode. If they do not the only recourse is to either write your own I2C driver or find someone that will

                do it for you.

                 

                I would be surprised if there were no support for a slave mode in the drivers. While it is fairly unusual for I2C to be used this way on a SBC, it is not unheard of. There is another

                forum member, shabaz, that has done a lot of experimenting with the BeagleBone Black so you might try to contact him to see if he knows anything about this.

                  • Re: I2C Slave?
                    shabaz

                    I must admit I've never used a microcontroller/processor in slave mode, this is quite unusual. Multi-master mode is supported, but this is something I'm not familiar with either.

                    The details are in the AM3359 tech docs of course, but as you say I don't know if the standard I2C drivers support it. It may need some custom driver. An easier option would be to use

                    a different interface, i.e. change the AVR code.

                    Or you could bit-bang (easier than writing a driver but will still take you some effort if you're new to it. If you want to try this, search for PRU examples).

                    I once wrote a single-wire interface which allowed chaining of multiple devices in/out (much like the WS2811 or 'neopixel' style LEDs do) for PIC devices, but I don't have the code for that

                    any more.

                    So sorry Greg, but this is unusual enough that I don't have an answer. What exactly are you trying to do? (End use-case). Are these 25 devices over some distance?

                      • Re: I2C Slave?
                        gstro

                        Thanks for the responses, Gary and shabaz! I had already done some surface level searches for Linux I2C drivers that also do slave-mode but didn't come up with anything conclusive. And I had almost forgot about the PRU since purchasing the BBB, but my project isn't necessarily time-sensitive enough to justify the extra effort. Both are good to keep in mind for later optimizations.

                         

                        My project: I'm trying to have the BBB act as the main intelligence to a connected grid of 2-3 inch "blocks" controlled by AVRs. The blocks could be ordered in different ways, say, 5x5 or 3x8 or even mixed-length rows, but the likely max distance should be less than 3 feet or so which shouldn't be too long (I hope). The idea was I could hard-code an I2C address for the BBB into each AVR block. Once connected, the microcontroller could then take control (become master) of the shared I2C bus and address the BBB (as slave) to pass along its own I2C address, effectively allowing the BBB to collect the addresses of all the blocks present. Once the BBB (now as master) has all the block addresses, it can address each AVR (now switched to slave) individually over the shared I2C to send commands, read other values, etc.

                         

                        Not all blocks are required and they will be disconnected and reconnected while the full system is running. Also, order matters - so I wanted each AVR address to dynamically reflect its "location" so I didn't want to just assign unique IDs to each AVR manually. (I've worked out dynamic location separately from the I2C stuff). Nor did I want to try to keep track of the IDs of 25+ nearly-identical blocks. I really liked the idea of each block "introducing" itself once connected and I thought the 2-way multi-master I2C common bus was a good and easy solution.

                         

                        What I might do for now, at least to get a first working prototype started, is fairly regularly poll all 127 or so possible I2C addresses from the BBB and see who responds. This means the protocol is the more traditional 1-master, several-slaves I2C and should at least get me started. It's not as cleanly interrupt-driven like the "introductions" would have been, but it'll get me to the next development stage quicker.

                         

                        Thanks again for the responses! I really appreciate the feedback.

                          • Re: I2C Slave?
                            clem57

                            Now it is clear! The switching of master slave in the relationship is not necessary if you let the master "broadcast" a welcome message to see who responds with an address. The broadcast would happen at say 5 second intervals. Reserve address 127 as special for only this purpose. Then a slave needs two address to know: itself and the special 127 address. This is how routing occurs.

                              • Re: I2C Slave?
                                gdstew

                                "if you let the master "broadcast" a welcome message to see who responds with an address"

                                 

                                The address used for this in the I2C specification is the general call address. I think your are correct that this is what Greg is looking for and will simplify

                                what he is trying to do.

                                 

                                Greg, if you haven't already I suggest you Google UM10204 which is the document number for the NXP Semiconductors pdf of the official I2C specification.

                                The current version is revision 6, earlier versions are also available. NXP Semiconductor used to to be Phillips and they were the originators of the I2C bus.

                        • Re: I2C Slave?
                          ravi.prasad

                          @benett

                          Linux 3.19 provides I2C slave mode kernel driver. 

                            • Re: I2C Slave?
                              troyholt

                              Well, I know this is a 5 year old post, but I was looking for a BBB i2c-slave driver and examples of how to use it.  Can anyone point me to such a thing or at least where to go look to find such information?  I have been running Debian 9.3 since it has LXQT and enough space to put gedit on a 8 GB uSD Card.

                                • Re: I2C Slave?
                                  shabaz

                                  Hi Troy,

                                   

                                  I don't know the answer to your question, hopefully someone else can answer if they know, but just in case it helps, here is how I would go about working around such an issue.

                                  1. Determine if I2C slave is really the right thing - it's usually not for a processor. Usually the processor is the master. It's unusual enough to want to question the actual aim of this.

                                  2. If I2C slave really was essential, and I could not find a driver, then as a workaround I would write some code to bit-bang it, since I2C can run at speeds slow enough for this, and it doesn't need critical timing between bits/bytes for it to be successfully decoded by the remote device. Depending on the type of I/O that was available, it might need some external hardware (BJT or MOSFETs).

                                  To bit-bang it, the I2C specification could be used.

                                    • Re: I2C Slave?
                                      Jan Cumps

                                      shabaz  wrote:

                                       

                                      ...

                                      To bit-bang it, the I2C specification could be used.

                                      The though thing with i2c is that it's way more complex to implement (bitbang) the slave state machine than a master.

                                      The master is not easy, but you can do that without too much hard timing and state criterea.