7 Replies Latest reply on Jan 5, 2015 5:59 PM by KurtE

    intel edison mraa gpio output initial status

    lzyun

      I found that when I set the mraa_gpio_context(pin, MRAA_OUT)

      And the pin always get low at initial status,

      Is there any way to change the initial status?

        • 1. Re: intel edison mraa gpio output initial status
          Intel_Peter

          Hello Izyun,

           

          I can think of two possibilities, the first one, that I think you have already thought of and probably doesn't work for you, is to change all GPIO to high in the very beginning of your project (it probably doesn't work since they have to be initialized first).

          The second one is to create a script to change the GPIO to high and making sure it runs very early in the boot process.

          I hope this helps.

           

                      Peter.

          • 2. Re: intel edison mraa gpio output initial status
            arfoll

            What @Intel_Peter suggests is correct, the initial 'mode' of a pin is pretty undefined behaviour and the only way to be certain is to set it at boot. Setting it early in the boot process would be ok as long as you set owner to false otherwise you'll unexport it and probably will loose the initial state (though I haven't checked).

             

            Even if we gave you call that would give you a context and set the dir it wouldn't actually happen at the same time, it would still cause a transition :/

            • 3. Re: intel edison mraa gpio output initial status
              lzyun

              Actually, I apply the edison on the 1-Wire interface.

              In the interface, the pin status would switch direction while reading data.

              And the low status usually mean the trigger signal for the device.

              The pin always pulls up through the resistor to Vcc I provide.

              So I need the MRAA_GPIO_OUT init status to high.

               

              mraa_gpio_context gpio;

              gpio = mraa_gpio_init(pin);  

              mraa_gpio_use_mmaped(gpio, 1);

              mraa_gpio_dir(gpio, MRAA_GPIO_OUT);    ===> getting low here

              mraa_gpio_write(gpio, 1);                             ===> getting high here

              • 4. Re: intel edison mraa gpio output initial status
                KurtE

                lzyun  Some things that come to mind:

                My assumption is you tried the obvious, to see what what happen if you first did the calls in a different order: something like;

                mraa_gpio_write before the mraa_gpio_dir call.  Probably won't work, but...

                 

                arfoll Something I wonder about maybe handling in MRAA is that in the mraa_gpio_dir call for the MRAA pin associated with GPIO182 (mini board MRAA pin 0),

                In that call you open the file: /sys/class/gpio/gpio182/direction

                 

                and you either write in or out to this file to set the actual direction, but I have seen examples (actually in the arduino IDE), where instead of writing the value out, you

                write either high or low to the file, where internally it sets the direction to out and the value to either 1 or 0...

                 

                So wondering what would happen if you made a version of mraa that allowed you to pass in either an optional value or a new value to the call like:

                mraa_gpio_dir(gpio, MRAA_GPIO_OUT_HIGH);

                 

                Should not be hard to hack up a version that does something like that.

                 

                Kurt

                • 5. Re: intel edison mraa gpio output initial status
                  arfoll

                  lzyun sadly the defaul states for input/output can change because as you set the direction a mux is switched which means the pin connected is now 'different' physically so it can be in a different state. The behaviour you're seeing is just a result of how the IO works on the platform.

                   

                  KurtE Yes that's a shortcut in gpiolibs, though from what I understand it doesn't work on many platforms and would still cause a 'twiddle' in the stats as is being seen here. Definately worth a shot though and we can definately add support for it. I've filed an enhacament for it. Like you say it's very easy to do . Just filed issue #80 here - Add high & low to direction enum in mraa_gpio_dir · Issue #80 · intel-iot-devkit/mraa · GitHub.

                  1 of 1 people found this helpful
                  • 6. Re: intel edison mraa gpio output initial status
                    lzyun

                    arfoll I got some possibility in my origin problem. I think the output status transform in other MCU like MSP430 is fast enough that I can not find the difference between the input and output status.

                    And Edison changes status not fast enough even I use mraa_gpio_use_mmaped function, the transformation time from low to high may fit the trigger requirement of the sensor I use.

                    • 7. Re: intel edison mraa gpio output initial status
                      KurtE

                      FYI - I made a version of mraa that added some new values you can pass into gpio_dir, that allows you to set the value of the pin at hopefully the same time.

                      mraa_gpio_dir(gpio, MRAA_GPIO_OUT_HIGH)

                       

                      What it does is instead of doing the equivalent of doing something like:

                      echo out > /sys/class/gpio/gpio182/direction

                      echo 1 > /sys/class/gpio/gpio182/value

                      (or second part may be done by write to memory mapped location).

                      it instead does:

                      echo high > /sys/class/gpio/gpio182/direction

                       

                      which the underlying driver then sets the actual direction to out and value to 1...

                       

                      It is not yet pulled into the main mraa project, but if you wish to try it out, it is up in :

                      KurtE/mraa at gpio_in_out · GitHub

                       

                      I did a simple test case on my Edison Mini breakout, which could be a bit cleaner, but was copy/paste from other test.

                      #include <iostream>
                      #include "stdio.h"
                      #include "unistd.h"
                      #include <time.h>
                      #include <pthread.h>
                      
                      
                      //=========================================================================
                      #include <time.h>
                      #include "mraa.h"
                      #include <string>
                      #include "memory.h"
                      
                      #define GPIO_INDEX 14
                      
                      int main(int argc, char **argv)
                      {
                        using namespace std;
                        mraa_result_t rtv = mraa_init();
                        if (rtv != MRAA_SUCCESS && rtv != MRAA_ERROR_PLATFORM_ALREADY_INITIALISED)
                        {
                          cout << "MRAA Init Failed,Return Value is ";
                          cout << rtv << endl;
                          return 0;
                        }
                        fprintf(stdout, "MRAA Version: %s\nStarting Read\n",mraa_get_version());
                      
                        mraa_gpio_context gpio;
                        gpio = mraa_gpio_init(GPIO_INDEX);
                        mraa_gpio_use_mmaped(gpio, true);
                        if (gpio == NULL)
                        {
                          std::cout << "Init GPIO Out Failed" << endl;
                          return 0;
                        }
                        mraa_gpio_dir(gpio, MRAA_GPIO_IN); // Start off in input with PU going...
                      
                        usleep(250000);  // give time for the ping to settle...
                        mraa_gpio_dir(gpio, MRAA_GPIO_OUT);
                        mraa_gpio_write(gpio, 1);   // try to get it high again. 
                        usleep(250000);  // give time for the ping to settle...
                        for(int i=0; i< 5; i++) {
                          mraa_gpio_write(gpio, 0);   // try to get it high again. 
                          mraa_gpio_write(gpio, 1);   // try to get it high again. 
                         }
                        usleep(250000);  // give time for the ping to settle...
                        mraa_gpio_dir(gpio, MRAA_GPIO_IN); // Start off in input with PU going...
                        usleep(250000);  // give time for the ping to settle...
                        mraa_gpio_dir(gpio, MRAA_GPIO_OUT_HIGH); // Start off in input with PU going...
                        usleep(250000);  // give time for the ping to settle...
                      
                        for(int i=0; i< 5; i++) {
                          mraa_gpio_write(gpio, 0);   // try to get it high again. 
                          mraa_gpio_write(gpio, 1);   // try to get it high again. 
                         }
                      
                        mraa_gpio_close(gpio);
                      
                      
                        return 0;
                      }
                      

                      I then watched the IO line with my logic analyzer.  Could easily see how the current way to do this, where the IO pin went low in between the time that I set the direction and then set the value.  But with the one step way, I did not see any pulse like that.

                      Kurt