1 2 Previous Next 21 Replies Latest reply on Nov 15, 2014 8:07 PM by KurtE

    digitalWrite and MRAA digitalWrite

    KurtE

      I am playing around some and trying to understand some of the speed issues with my Adafruit_ILI9341 driver both on Arduino side as well as linux version...

       

      One thing I was wondering about was the speed for updating the CS and DC pins as part of the interface.  So I first hacked up an MRAA version

      #include <stdio.h>

      #include <unistd.h>

      #include <errno.h>

      #include <signal.h>

      #include <stdlib.h>

       

      #include "mraa.h"

       

      #define DEFAULT_IOPIN 13

       

      int running = 0;

      static int iopin;

       

      void

      sig_handler(int signo)

      {

          if (signo == SIGINT) {

              printf("closing IO%d nicely\n", iopin);

              running = -1;

          }

      }

       

      int

      main(int argc, char **argv)

      {

          mraa_result_t r = MRAA_SUCCESS;

          iopin = DEFAULT_IOPIN;

       

          if (argc < 2) {

              printf("Provide an int arg if you want to flash on something other than %d\n", DEFAULT_IOPIN);

          } else {

              iopin = strtol(argv[1], NULL, 10);

          }

       

          mraa_init();

          fprintf(stdout, "MRAA Version: %s\nStarting Blinking on IO%d\n",

                  mraa_get_version(), iopin);

       

          mraa_gpio_context gpio;

          gpio = mraa_gpio_init(iopin);

          if (gpio == NULL) {

              fprintf(stderr, "Are you sure that pin%d you requested is valid on your platform?", iopin);

          exit(1);

          }

          printf("Initialised pin%d\n", iopin);

       

          // set direction to OUT

          r = mraa_gpio_dir(gpio, MRAA_GPIO_OUT);

          if (r != MRAA_SUCCESS) {

              mraa_result_print(r);

          }

       

          signal(SIGINT, sig_handler);

       

          while (running == 0) {

              r = mraa_gpio_write(gpio, 0);

              r = mraa_gpio_write(gpio, 1);

          }

          r = mraa_gpio_close(gpio);

          if (r != MRAA_SUCCESS) {

              mraa_result_print(r);

          }

       

          return r;

      }

       

       

      I ran the program and first off found that the IO speed was pretty slow.  Also looking at the Logic Analyzer I am getting other IO pins appearing to change as well... I have probes on IO pins 13-6 as you can see in the following output from Saleae...

      Edison MRAA pin 10.jpg

      As you can see it appears like pin 9 is sometimes getting a spike...

       

      So then I wondered what the timings would be for Arduino.  I am running the 1.0.4 build and I am running with the latest firmware (updated it yesterday).  Real simple program

      #define PIN 10

      void setup() {

        // put your setup code here, to run once:

        pinMode(PIN, OUTPUT);

      }

       

      void loop() {

        // put your main code here, to run repeatedly:

        while(1) {

          digitalWrite(PIN, 1);

          digitalWrite(PIN, 0);

        }

      }

       

      The speeds are much faster, but on pin 10 I get lots of other stuff going on:

      Edison Arduino digitalWrite 10.jpg

      As you can see pin 9 and 8 are also getting some changes going on...

       

      Note: If I tell the program to use pin 13 instead I only see changes on pin 13...

      Edison Arduino digitalWrite13.jpg

       

      Two part question:

      1) Is it my LA that is screwing up or is there an issue with some IO pins changing with other IO pins?

       

      2) How to speed up MRAA.

       

      This is with Edison an Arduino board.  Currently have XBee shield in place, but it only should touch IO0-1

        • 1. Re: digitalWrite and MRAA digitalWrite
          DiegoV_Intel

          Hi KurtE,

           

          This is a interest behavoir. Let me do some test about it and as soon as I have some results I will post them here.

           

          Regards,

          Diego.

          • 2. Re: digitalWrite and MRAA digitalWrite
            DiegoV_Intel

            Hi KurtE,

             

            I've done some tests and I got a similar behavior you described. I used the same Arduino code you posted using the pin 13 and I got the following:

            Pin 13 sin delay.png

             

            Note that for my test I don't only see changes in pin 13 as in your test (that is interesting). Then I modified the code adding delays between the transitions, and I got the following:

            Pin 13 con delay de 10.png

             

            Pin 13 con delay de 100.png

             

            For the first one I added delay(10); and for the second one delay(100); and for those tests I only saw changes on pin 13.

             

            Then, I returned to the first test, the one without any delays (I mean, the test with the same Arduino code you posted) and again I got the same behavior on pins 13 and 10. So I decided to plug a LED on each pin. Since the code is using the pin 13, the onboard LED on the Arduino Expansion Board was always ON because the transitions were so fast, so I though that if the pin 10 is changing almost in the same way as the pin 13 (according to the Logic Analyzer)  if I connect a LED in the pin 10 it will be always ON, just as the onboard LED. So I plugged it but the LED was always OFF. My conclusion is that the unusual behavior is caused by the Logic Analyzer, but I'm not 100% sure yet. I have the Saleae Logic 8. Unfortunately I don't have another device to measure the same tests and comparing them with each other.

             

            Regards,

            Diego.

            • 3. Re: digitalWrite and MRAA digitalWrite
              KurtE

              My guess is maybe the signals are floating with no load...  I may try again with same program and turn on try to trace the analog values of these pins.  Could also try with older Logic 16 to see if any difference.

              • 4. Re: digitalWrite and MRAA digitalWrite
                KurtE

                For the fun of it I did a quick Logic capture, this time also capturing the Analog values on pins 13 and 12 as you can see below:

                EdisonArduino digital Write 13.jpg

                As you can pin 12 is floating along in a range of about .86 and 1.32...

                • 5. Re: digitalWrite and MRAA digitalWrite
                  DiegoV_Intel

                  Hi KurtE,

                   

                  Just sharing more results, I did another test and I got the following outputs. I just added a line for each unused pin to set its value to LOW and avoid floating values and it worked.

                   

                  Test ATest B
                  Test with noise.pngTest without noise.png

                   

                  Regards,

                  Diego.

                  • 6. Re: digitalWrite and MRAA digitalWrite
                    KurtE

                    Thanks,  that is what I sort of figured as well.  The signal was just floating up high enough to sometimes register as a high...

                    Side note: I do like having the analog feature of the new Saleae logic analyzer... It's the third LA of theirs I have purchased (original, 16 and now logic 8)

                     

                    I know that the difference in speed between Arduino code and mraa, is that the Arduino is using memory mapped address to update the values and the MRAA is still going through file system for it.  I know they are looking into adding some form of memory mapped as well.

                    • 7. Re: digitalWrite and MRAA digitalWrite
                      DiegoV_Intel

                      Hi KurtE,

                       

                      I think I'm a little confused… Did you already answered your own mraa question, right?

                       

                      Regards,

                      Diego.

                      • 8. Re: digitalWrite and MRAA digitalWrite
                        David_J_Hunt

                        Kurt,

                         

                           The arduino IDE was written using direct hardware register access, and defaults to this "Fast" mode, hence the 2.5MHz

                        Mraa probably uses the slow(er) access through sysfs, hence the ~50KHz you're seeing.

                         

                        You can see examples of this register access in the Arduino code (path shown on a Mac)

                        Arduino.app/Contents/Resources/Java/hardware/arduino/edison/cores/arduino/fast_gpio_nc.c


                        Part 1 of your question: set unused pins to a valid state, i.e. input, with pullups enabled.

                        Part 2 of your question: mraa needs to be updated to use the gpio register as demonstrated in the Arduino code. Which I reckon would involve significant effort.

                         

                        Rgds,

                        Dave.

                        • 9. Re: digitalWrite and MRAA digitalWrite
                          KurtE

                          Hi,  I answered that I know what the issue is.  I raised the issue over in the MRAA: https://github.com/intel-iot-devkit/mraa/issues/27

                           

                          Some interesting comments in the issue, include:

                           

                           

                          The arduino code is afaik GPL and copyrighted emutex so we're avoiding it and going from the specs.

                           

                          To be honest having 'slow' gpio has never really been a concern of libmraa as myslef and tom both consider that bitbanging on non real time systems is just wrong. Out of curiosity what is your use case?

                           

                          They are working on it and created a new branch mem of the github project, that they hoped would have something in it sometime this week.  So I am hoping.  In the mean time I might do up my own version, such that I have the equivalent of the pinMode/DigitalWrite in my own library, which makes it easier for me to move code from Arduino environment to linux environment.

                          • 10. Re: digitalWrite and MRAA digitalWrite
                            KurtE

                            There is a WIP with MRAA, currently up on their github MEM branch.  They now support the memory map.  I did an update of a simple blink program that blinks two IO pins, one normal, one set to high speed.

                            ```// setup our fast one... probably not as cleanly
                            mraa_gpio_context gpioFast;
                            gpioFast = mraa_gpio_init(iopinFast);
                            mraa_gpio_dir(gpioFast, MRAA_GPIO_OUT);
                            mraa_gpio_use_mmaped(gpioFast, 1);

                             

                            Note the new call for use mmaped....

                            My main loop now looks like:

                             

                            while (running == 0) {
                                for(int i=0; i< 5; i++) {
                                    r = mraa_gpio_write(gpio, 0);
                                    r = mraa_gpio_write(gpio, 1);
                                }
                                for(int i=0; i< 5; i++) {
                                    r = mraa_gpio_write(gpioFast, 0);
                                    r = mraa_gpio_write(gpioFast, 1);
                                }
                            }

                            Sorry about formating, one of these days will figure out this forum editor for showing code.  But the main point is speed differences.

                            Edison MRAA fast and slow.jpg

                            Needless to say it is quite a bit faster.  I did not have enough room to show a full loop of the slow one and still show the measurements for the fast one...

                            • 11. Re: digitalWrite and MRAA digitalWrite
                              hk101

                              Hi KurtE,

                              Is the libmraa you are using version == v0.5.2-3-gb5a2739 ?

                               

                              I did similar experiment and do not see any difference between fast and slow GPIO = time is ~27 uS for code below.

                               

                              #include <stdio.h>

                              #include <string.h>

                              #include <unistd.h>

                              #include "mraa/gpio.h"

                              //#define SLOW 1

                              int

                              main(int argc, char **argv)

                              {

                                  char board_name[] = "Some weird devboard that isn't recognised...";

                                  int ledstate = 0;

                                  mraa_platform_t platform = mraa_get_platform_type();

                              #ifdef SLOW

                                  mraa_gpio_context gpio;

                                  gpio = mraa_gpio_init(31);

                                  mraa_gpio_dir(gpio, MRAA_GPIO_OUT);

                                  strcpy(board_name, "Intel Edison w minibreakout libmraa SLOW gpio");

                              #else  

                                  mraa_gpio_context gpioFast;

                                  gpioFast = mraa_gpio_init(31);

                                  mraa_gpio_dir(gpioFast, MRAA_GPIO_OUT);

                                  mraa_gpio_use_mmaped(gpioFast, 1);

                                  strcpy(board_name, "Intel Edison w minibreakout libmraa FAST gpio");

                              #endif  

                                  fprintf(stdout, "Welcome to libmraa\n Version: %s\n Running on %s\n",

                                      mraa_get_version(), board_name);

                                   for (;;) {

                              #ifdef SLOW

                                      mraa_gpio_write(gpio, ledstate);

                                      ledstate = !ledstate;

                              #else      

                                      mraa_gpio_write(gpioFast, 0);

                                      mraa_gpio_write(gpioFast, 1);

                              #endif

                                  }

                               

                               

                                  return 0;

                              }

                              • 12. Re: digitalWrite and MRAA digitalWrite
                                KurtE

                                The version I am using, I built from the current sources: https://github.com/intel-iot-devkit/mraa/tree/mem

                                Note: this is the mem branch.  I actually have their project forked, so I had to update my sources to match theirs...

                                 

                                I then downloaded the sources to my Edison (Arduino one) and built it.  Note: this requires cmake.  I downloaded a version of cmake off of the web...

                                Maybe should ask AlexT_Intel about adding this to the his OPKG repo...

                                 

                                I then followed their build instructions.  I used the option to install it in the top level... then after cmake is done, I ran make and then make installed.

                                 

                                Also note: my test app, I build and run on the Edison.  If you are using something like devkit and eclipse, I would imagine that you would need to update the headers and the like on the PC and you would need to update the run time library on the Edison.

                                 

                                My first attempts of running new MRAA stuff through Eclipse kept faulting until I remembered to updated the run time on the Edison.

                                • 13. Re: digitalWrite and MRAA digitalWrite
                                  arfoll

                                  You can already get the latest version of mraa & UPM on mraa-upm-repo/. When the mem branch gets merged to master you'll get the changes.

                                  • 14. Re: digitalWrite and MRAA digitalWrite
                                    hk101

                                    Hi arfoll,

                                     

                                    I updated and installed libmraa0 , and I can see that the lib version number went up on edison. However

                                    the GPIO timing remains unchanged : for one complete period of one (1) followed by zero (0) the time

                                    is approx 27 micro secs.

                                     

                                    Is there a way to put inline assembly code to make GPIO toggle in say 0.1 micro secs ?

                                    I understand that the microcontroller runs at 100MHz, which gives a clock time of 10 nano secs.

                                     

                                    making a tight loop of (psudocode -> ) "asm volatile ( outp 1, outp 0);" inline should be able to generate a

                                    clock on GPIO pin of approx 10 MHz or even 1 MHz ..

                                     

                                    Anyone tried this?

                                    1 2 Previous Next