6 Replies Latest reply on Feb 21, 2017 12:37 PM by Intel Corporation

    "open drain" with mraa on Edison

    Electrumpet

      Dear all,

       

      I am trying to get the mgc3130 development board working (through I2C) with the Intel Edison using MRAA. I got it working with a teensy in the past but the hassle is the 'open drain' TS_line required in this particular case. Is there a way to define a GPIO (or other) pin as 'open drain'? And can this be done in combination with a level convertor?

       

      From the MGC3130 gestuc kubrart

       

      The TS line is used to check whether the I2C data is valid and can be sent from MGC3X30 to the host controller.

       

      The MGC3X30 (I2C Slave) uses this line to inform the host controller (I2C Master) that there is data available to be transferred. The host controller uses the TS line to indicate that data is being transferred and prevents MGC3X30 from updating its data buffer.

       

      MGC3X30 can update the I2C buffer only when TS is released by both chips, and a data transfer can only be started when MGC3X30 pulls TS low. 

       

      This procedure secures that:

           • the host is always informed when new sensor data is available

           • buffer updates in MGC3X30 are always completed before data is sent to the I2C bus

       

       

      Table 2-1 shows how the TS line is used in the different states of communication.This is required:

       

      MGC3X30 Host ControllerTS LineStatus
      Released (H)Released (H)HighHost finished reading data (Transfer end). No more data to be transferred to the host. MGC3X30 is allowed to update the data buffer.
      Asserted (L)Released (H)LowData from MGC3X30 is available to be sent, but the host has not yet started reading. If the host is busy and did not start reading before the next data update (5 ms), the MGC3X30 will assert the TS line high while updating the data buffer.c
      Asserted (L)Asserted (L)LowData from MGC3X30 is available to be sent, but the host has not yet started reading. If the host is busy and did not start reading before the next data update (5 ms), the MGC3X30 will assert the TS line high while updating the data buffer.
      Released (H)Asserted (L)LowMGC3X30 is ready to update the data buffer, but the host is still reading the previous data. MGC3X30 is allowed to update the data only when the host releases the TS high.
        • 1. Re: "open drain" with mraa on Edison
          Intel_Peter

          Hello Electrumpet,

           

          Thanks for reaching out!

           

          As you can see in the module's hardware guide (http://www.intel.com/content/www/us/en/support/boards-and-kits/000005808.html) in section 4.2, the I2C interface found on Edison is open collector. In regards to I2C, open collector and open drain are the same thing (as you can see in https://www.i2c-bus.org/i2c-primer/how-i2c-hardware-works/), so, you shouldn't have issues with that.

           

          Regarding a level translator, you shouldn't have trouble using one as long as this device is capable of "translating" I2C signals.

           

          There is no way to set GPIOs that are not on the I2C interface as open collector as this feature is hardware dependent.

           

          I hope this information helps you,

          Peter.

          • 2. Re: "open drain" with mraa on Edison
            Electrumpet

            Hi Peter,

             

            Yes if you talk about the I2C lines (the clock and the data line) then you are correct. But it is indeed about the other pins. I found though that when I look in the Linux system that open drain is actually present as a configuration possibility. I was already busy changing different configuration files. It needs some testing but then I intended to post it here. For now if I look here within the linux file on the Edison:

             

            /sys/kernel/debug/gpio_debug/gpio44#

             

            I can see all the configurations of the pin. I can write within these files as well and I can see that if I write another value in current_value that I can change those values.

             

            I am already writing a c function to be able to change a number of pin values through this Linux pin configuration work around. I see open drain as one of the possibilities. Why would that not be possible? I still have to test it but your answer came first:

             

            Below what I see in Linux:

             

             

            /sys/kernel/debug/gpio_debug/gpio44# ls

            available_debounce           current_direction

            available_direction          current_irqtype

            available_irqtype            current_opendrain

            available_opendrain          current_override_indir

            available_override_indir     current_override_inval

            available_override_inval     current_override_outdir

            available_override_outdir    current_override_outval

            available_override_outval    current_pinmux

            available_pinmux             current_pullmode

            available_pullmode           current_pullstrength

            available_pullstrength       current_standby_indir

            available_standby_indir      current_standby_inval

            available_standby_inval      current_standby_opendrain

            available_standby_opendrain  current_standby_outdir

            available_standby_outdir     current_standby_outval

            available_standby_outval     current_standby_pullmode

            available_standby_pullmode   current_standby_trigger

            available_standby_trigger    current_value

            available_value              irq_count

            conf_reg                     register_info

            current_debounce

            /sys/kernel/debug/gpio_debug/gpio44# cat available_opendrain

            disable enable

            /sys/kernel/debug/gpio_debug/gpio44# cat current_opendrain

            disable

            /sys/kernel/debug/gpio_debug/gpio44#

             

            Best, Hans.

            • 3. Re: "open drain" with mraa on Edison
              Electrumpet

              Just tested the open drain option mentioned above. It seems that it is not working indeed. Strange that these modes are there in the GPIO files available for change but not all of them seem to work.

               

              On the other hand I tried by hand if a trick could be used to emulate an 'open drain'. And as far as I know this should do the trick (it worked when I tested it in the terminal although I don't know about the timing yet).

               

              I do the following sequence on gpio44. Since I don't have to listen while the GPIO is a low output this should do the trick:

               

               

              /sys/kernel/debug/gpio_debug/gpio44# echo "low" > current_value // prepare the output value for asserting the line low (I only have to do this once)

              "wait till the MGC3130 frees the line by letting it float (high)"

              /sys/kernel/debug/gpio_debug/gpio44# echo "out" > current_direction // asserting the line (low) and do the things that have to be done

              /sys/kernel/debug/gpio_debug/gpio44# echo "nopull" > current_pullmode // prepare for freeing the line (by changing the direction to "out" the pull mode

                                                                                         automatically goes to pulldown although it seems that the internal pulldown

                                                                                         resistor itself is not used (different strengths don't result in different

                                                                                         pull strengths for output, only for input)

              /sys/kernel/debug/gpio_debug/gpio44# echo "in" > current_direction // free the line and start listening

               

              /sys/kernel/debug/gpio_debug/gpio44# echo "out" > current_direction

              /sys/kernel/debug/gpio_debug/gpio44# echo "nopull" > current_pullmode

              /sys/kernel/debug/gpio_debug/gpio44# echo "in" > current_direction

               

              /sys/kernel/debug/gpio_debug/gpio44# echo "out" > current_direction

              /sys/kernel/debug/gpio_debug/gpio44# echo "nopull" > current_pullmode

              /sys/kernel/debug/gpio_debug/gpio44# echo "in" > current_direction

              etcetera

               

              I will work this out in c and get back to you soon unless somebody has some useful comments.

               

              Best, Hans.

              • 4. Re: "open drain" with mraa on Edison
                Electrumpet

                Dear all,

                 

                This should be it then. I am not a professional programmer so let me know if this is plain stupid or a workable solution. If you have something more compact and elegant please let me know ;-). At least I should be able to use this with the sensor.

                 

                /*

                * Author: Hans Leeuw <hans@electrumpet.nl>

                *

                * Permission is hereby granted, free of charge, to any person obtaining

                * a copy of this software and associated documentation files (the

                * "Software"), to deal in the Software without restriction, including

                * without limitation the rights to use, copy, modify, merge, publish,

                * distribute, sublicense, and/or sell copies of the Software, and to

                * permit persons to whom the Software is furnished to do so, subject to

                * the following conditions:

                *

                * The above copyright notice and this permission notice shall be

                * included in all copies or substantial portions of the Software.

                *

                * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,

                * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF

                * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND

                * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE

                * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION

                * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION

                * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

                */

                 

                 

                #include <mraa.h>

                #include <string.h>

                #include <stdio.h>

                #include <unistd.h>

                 

                 

                 

                 

                void configureTSpin(char *TSpin,char *action);

                void changePinFile(char *file, char *value);

                 

                int main()

                {

                  char *TSpin = "gpio44";

                 

                  configureTSpin(TSpin, "initialisePin"); // make the pin low for output mode.

                  for(;;) {

                  configureTSpin(TSpin, "assertionLow"); // output mode force the line low to be able to write to the sensor.

                  sleep(5);

                  configureTSpin(TSpin, "freeLine"); // Release the line so it can be taken over by the sensor and change the pin to input to know when data is available.

                  sleep(10);

                }

                 

                  return 0;

                }

                 

                 

                 

                 

                void configureTSpin(char *TSpin,char *action)

                {

                  const char *pinConfigureParameters[3]; // Ending of the paths towards the files that are to be changed.

                  pinConfigureParameters[0] = "/current_direction";

                  pinConfigureParameters[1] = "/current_pullmode";

                  pinConfigureParameters[2] = "/current_value";

                  char *fileStart = "/sys/kernel/debug/gpio_debug/"; // Beginning of the paths towards the files that are to be changed.

                 

                  char TSpinDirectory[36];

                  strcpy(TSpinDirectory, fileStart);

                  strcat(TSpinDirectory, TSpin); // path to the configuration directory of the TSpin within the linux file system.

                 

                  char file[60];

                 

                 

                int initial = strcmp(action, "initialisePin");

                if (initial == 0)

                  {

                  strcpy(file, TSpinDirectory);

                  strcat(file, pinConfigureParameters[2]); // Specific file within the directory: Value of the pin (low or high)

                  char *value = "low";

                  changePinFile(file, value);

                  }

                 

                 

                int freeLine = strcmp(action, "freeLine");

                if (freeLine == 0)

                  {

                  strcpy(file, TSpinDirectory);

                  strcat(file, pinConfigureParameters[1]); // Specific file within the directory: pullup of the pin (pullup, pulldown or nopull)

                  char *value = "nopull";

                  changePinFile(file, value);

                 

                  strcpy(file, TSpinDirectory);

                  strcat(file, pinConfigureParameters[0]);// Specific file within the directory: pindirection (input or output)

                  char *value2 = "in";

                  changePinFile(file, value2);

                  }

                 

                 

                int assertion = strcmp(action, "assertionLow");

                if (assertion == 0)

                  {

                  strcpy(file, TSpinDirectory);

                  strcat(file, pinConfigureParameters[0]);// Specific file within the directory: pindirection (input or output)

                  char *value = "out";

                  changePinFile(file, value);

                  }

                }

                 

                 

                 

                 

                void changePinFile(char *file, char *value) // standard routine for writing in a file

                {

                    FILE *xfin;

                    // open the file

                    xfin = fopen(file,"w");

                    if (xfin == NULL) {

                        perror(file);

                        exit(1);

                    }

                    fprintf(xfin, "%s \n", value);

                    fclose(xfin);

                }

                 

                Best, Hans.

                • 5. Re: "open drain" with mraa on Edison
                  Electrumpet

                  Sorry, forgot to mention that I use the mini breakout board for what it is worth.

                   

                  Best, Hans.

                  • 6. Re: "open drain" with mraa on Edison
                    Intel Corporation
                    This message was posted on behalf of Intel Corporation

                    Hi Electrumpet,

                    I'm glad to hear that you were able to find a solution for this. I'm also not a programmer, so, I also tend to do these "no so elegant" solutions. However, as long as it’s functional I'm happy. 

                    Thank you for sharing your solution with the community. It will be of much help for other users that have similar doubts.

                    If you ever have any other doubts or questions, please don't hesitate to come back to the community. We'll do our best to help you.

                    Peter.