10 Replies Latest reply on Jul 10, 2015 10:00 AM by PeteB

    Edison/Neopixel, memory mapped gpio speed

    sam.baker

      I'm working on getting the neopixel displays working with Edison which requires very precise timing of data on a single GPIO pin according to these specs:

       

      https://learn.adafruit.com/adafruit-neopixel-uberguide/advanced-coding

       

      Can anyone confirm whether the memory-mapped gpio write execution speed is consistent, or even better let me know exactly how many clock cycles it takes?

       

      I have the lights working fairly well, but there are intermittent glitches due to the timing being off. I'm in the process of converting my entire update function for the neopixels to assembly language but before I spend too much more time on that, it would be helpful to know more about the critical instruction that writes to the gpio pin using:

       

          *(volatile uint32_t*) (mmap_reg + offset + valoff) =

              (uint32_t)(1 << (dev->pin % 32));

       

      in intel_edison_fab_c.c

       

      I've done various timings and it appears to take an average of ~0.24 microseconds to execute the write instruction to the single pin that I'm using (just the write, not the calculations of the address and pin mask). Is it reasonable to assume that the write speed is predictable and that if I add extra assembly instructions to fill the required time between toggling the pin state, that I'll be able to get precisely timed updates for 500+ consecutive bytes of data? This is what the Arduino neopixel library does, but I can see from their code that the memory mapped writes on arduino only use 2 CPU cycles, whereas Edison is taking significantly longer.

        • 1. Re: Edison/Neopixel, memory mapped gpio speed
          Intel_Peter

          Hello sam.baker,

           

          In Re: Fast GPIO Arduino board to logical IO pins on Breakout board?, we tested the IO toggling speed, it reached speeds up to 1.4MHz, but that was toggling from output to input. I will do some research to see if I can find out how many clock cycles it takes to execute the write command, if I'm able to find some info about this, I will post it here.

           

          Peter.

          • 2. Re: Edison/Neopixel, memory mapped gpio speed
            sam.baker

            Thanks Peter, I appreciate it. I was able to get a good estimate of the average speed (0.24 microseconds - 120 clock cycles?) by looping over thousands of writes but I wasn't able to test whether the first write after other CPU activity is any slower, or whether there's any variation between writes. Confirming consistency of timing for the initial write and all subsequent writes would be very helpful.

             

            Sam

            • 3. Re: Edison/Neopixel, memory mapped gpio speed
              Hank_Coffin

              You are not going to be able to get consistent timings if you are running on Linux.  The timing on those NeoPixels is very rigid, and Linux interrupts will wreak havoc.  Unless... could one reserve a core for Linux and reserve the other core for real-time?  Or, one of these days Intel is bound to open up that Quark Micro-controller on the Edison that is disabled and would be perfect for this.  (I've been waiting for that....)   Adafruit has a new line of programmable LED's, DotStar, which uses a simpler two-wire protocol which is not dependent on timing.

              • 4. Re: Edison/Neopixel, memory mapped gpio speed
                sam.baker

                Interesting, given that I have complete control of the system and only need to run one executable, I assumed there'd be a way to disable interrupts or request a dedicated CPU for the time it takes to update the LEDs. Maybe not but it's possible that running my app on a dedicated core could work:

                 

                http://stackoverflow.com/questions/13583146/whole-one-core-dedicated-to-single-process

                 

                That page refers to a long list of potential sources of interrupt though. I wish DotStar worked but they don't have the flexibility and density of Neopixel.

                 

                I'm sure there's a hack possible somewhere but it probably requires a custom kernel build.

                 

                My backup plan is to connect an Arduino to the Edison but it would be nice if none of these things were required. It is a shame that the Quark is unavailable.

                • 5. Re: Edison/Neopixel, memory mapped gpio speed
                  Hank_Coffin

                  Interesting.  If you're running Linux, you don't really have complete control.  Those potential sources listed look mostly like the low level ones.  Try running the app "top" (should be installed by default, 'q' to exit).  It will probably list 20-40 higher level processes.  You could have web server, ssh server, etc.

                   

                  I haven't been using my Edison much, waiting on the Quark.  Interesting that there is work on isolating cores.  One aspect of that though is that these OS capable cores are typically much more powerful than needed for a lot of microcontroller tasks. 

                  • 6. Re: Edison/Neopixel, memory mapped gpio speed
                    sam.baker

                    Given the time it'll take to solve this with just the Edison, I'm adding an arduino as an i2c slave instead, not ideal but much easier. My tiny edison keeps getting bigger, I'm now adding a sparkfun i2c board and one of these to control the neopixel: https://learn.adafruit.com/introducing-trinket/pinouts

                    • 7. Re: Edison/Neopixel, memory mapped gpio speed
                      Intel_Peter

                      Hello sam.baker,

                       

                      I'm sorry for the delay in my response (I know I'll be a little bit out of context), as Hank_Coffin said, you won't get consistent write times since clock cycles for any Arduino commands like write are non-deterministic. The reason is because the Arduino on Edison runs as a process within the Linux system, where execution is controlled by the kernel and also shared with other processes.

                       

                      Peter.

                      • 8. Re: Edison/Neopixel, memory mapped gpio speed
                        PeteB

                        Sorry to resurrect an old thread, but does anyone know enough about the Quark MCU yet to state whether FastLED or the Adafruit code could be ported to it? Then you could do CnC with the Edison, and actually driving the NeoPixels would be done by the Quark. Based on reading through the MCU docs, it should be possible, but there are challenges. Is it possible to control a signal on a GPIO with usecond resolution, or does the slow clock prevent this? I see PWM is possible, so it seems like it should be possible to control a signal on a GPIO for a set amount of time (say 300 usecs). but any feedback would be great on this. I'm going to give it a whirl anyway. Worst that can happen is it doesn't work.

                        • 10. Re: Edison/Neopixel, memory mapped gpio speed
                          PeteB

                          Close, but not quite. Those are the WS2801 LED's, which run a slightly dumbed down SPI. Which is nice, but the problem with the 2801 is the size, and since it runs SPI, you can only hook one connected unit to the controller. I want to be able to control 4 independent WS2812 strips at one time (mostly for wiring ease and to be able to power it more simply). So, that tutorial is great for another project, but I figured that would work already. Pry use the Beagle for that though, so I can control 2 strands at a time.

                           

                          I see the Quark has a delay limit of 1 micro second (using mcu_delay()). Is that going to stay? The CPU itself runs fast enough to provide deterministic nano second timings, but in the documentation, I can't find a way to toggle a gpio for some number of nanoseconds. See this link for some details on specific timings. Turns out it's not that complicated if you can get the specific signals right. They have a great library for the Beagle (LEDScape) which uses it's MCU, but the Beagle is bigger, and doesn't have built in WiFi which would allow me greater control without a lot of additional components.

                           

                          Basically, can someone tell me how to do nano second timing with the Quark MCU? If it's not possible yet, is that planned? I would figure it should be, the Quark should be at least as capable as any Arduino.