11 Replies Latest reply on Dec 29, 2014 2:04 PM by Intel_Peter

    Is there a way to toggle GPIO direction without signaling all pins?

    llatta

      I'm trying to drive an LCD display over an 8-bit data bus + 4 control lines. I have connected it to 12 pins on the Arduino Edison board (D0-11 right now).

       

      The 8 data lines (D0-7) need to switch IO direction between write and reads, eg I need to write an 8 bit command, then toggle to read mode, flag the "read" control pin and read out the 8-bit result.

       

      Whenever I call mraa_gpio_dir() on the 8 data pins to switch from out to in, all my pins that are high (even the control pins D8-11) toggle from high to low to high 8 times, which the LCD obviously treats as an intentional input, and therefore doesn't work (eg the above mentioned read-after-write can only read zeros).

       

      Inspired by KurtE's MRAA optimizations (in Ping Sensor - pinMode too slow?  (both Arduino and MRAA)), I did some hacking in MRAA and found that both the tristate flipping and the write to the "outputen" pin trigger the high-low-high transition on the other pins. By holding the tristate pin low once for all 8 data direction changes, I can reduce the undesired pin flips to only happen once instead of 8 times, but that is still not sufficient for correct functioning of the LCD.

       

      Is there any way to not have all pins flip when the tristate gets changed? Like if i were do to some kernel hacking could I get further on this or is this a general limitation of the hardware design? Or are there any pins that are isolated from the tristate that I could put my control pins on?

       

      Thanks for any help!

        • 1. Re: Is there a way to toggle GPIO direction without signaling all pins?
          Intel_Peter

          Hello llatta,

           

          Let me see what I can find out about it, I will get back to you as soon as I get some info.

           

          Regards,

                      Peter.

          • 2. Re: Is there a way to toggle GPIO direction without signaling all pins?
            KurtE

            I have not setup to watch the other IO pins yet when mucking with a few of them, but I have wondered about the effect of the tristate object.  My impression was that it might put all of the IO pins into a floating state... Will be interesting to hear what the answer is.

             

            Kurt

            • 3. Re: Is there a way to toggle GPIO direction without signaling all pins?
              Intel_Peter

              Hello llatta,

               

              Could you please attach your code?

               

              Regards,

                          Peter.

              • 4. Re: Is there a way to toggle GPIO direction without signaling all pins?
                KurtE

                Hi Peter and llatta

                 

                I did a quick hack on my Arduino board, where I ran a 2.2K resister from 3.3V to D8, 2.2K from Gnd to D7 left the rest floating.

                Hooked up LA (Channel 0 D8, 1 d7... 4 on d4)

                 

                Code:

                void setup() {
                  // put your setup code here, to run once:
                  pinMode(8, INPUT);
                  pinMode(7, INPUT);
                  pinMode(6, INPUT_PULLUP);
                  pinMode(5, INPUT/*_PULLDOWN*/);
                  pinMode(4, OUTPUT);
                
                }
                
                void loop() {
                  // put your main code here, to run repeatedly: 
                  digitalWrite(4, HIGH);
                  pinMode(3, INPUT);
                  digitalWrite(4, LOW);
                  pinMode(3, OUTPUT);
                  
                }
                

                Again not very fancy, But looking at LA output from it, you can see:

                Edison Pin changes during calls to pinMode.jpg

                Again the bottom line is showing my Setting and clearing of pin 4.  The line above it is the floating pin, which is changing reasonably often.  The one that was Init as INPUT_PULLUP does not change, nor does the one with 2.2K external PU  But the one with 2.2K Pull down does change some of the time.

                 

                Note: when I add the Analog capture which runs at lower speeds,  But you an see it sort of.

                Edison Pin changes with Analog.jpg

                The floating pin gets up to about 1v and the PD pin gets up to about .25v.

                 

                Again not sure if this is showing what you are seeing or not

                 

                Kurt

                • 5. Re: Is there a way to toggle GPIO direction without signaling all pins?
                  llatta

                  I've simplified a version of the app to repro this issue, and attached an archive exported from Eclipse. It should be possible to import it into the Eclipse examples workspace from the IOT Devkit.

                   

                  The code I'd like to get to work is in the tft.readID() function, but it always reads 0.

                  So to narrow it down to the problem with the GPIO direction toggle, I added test code. Put a breakpoint on line 100 in Adafruit_TFTLCD.cpp, to break just before the setWriteDir. When I start the logic analyzer then (hooked up to the 4 control pins and the first 4 data pins), I get this capture:

                   

                  mraaDirRepro.png

                  I can get the 8 high-low transitions to become just one, by enabling the OPTIMIZE_MRAA_DIR defined a little lower to 1, which will hold the tristate low once for all the 8 direction switches together, but that still doesnt solve my problem.

                   

                  My logic analyzer unfortunately cannot do analog captures, so I don't know what voltages occur during the toggles. Maybe I need to enable some pullup/down resistors? I'm a little unclear what those do in this context with a device attached to the pin (I'm a software engineer by trade with only limited EE experience...)

                  • 6. Re: Is there a way to toggle GPIO direction without signaling all pins?
                    KurtE

                    I will have to take a look at this at some point, which display are you using?

                     

                    Sometime I may have to do more work using Eclipse with break points...  Currently do most of my debugging the old way (traces, toggle IO pins...).

                     

                    I have not tried any 4 bit or 8 bit parallel devices yet on Edison, although I could at some point try with the Adafruit 2.8" TFT breakout board.  So far I have used SPI.  Might be interesting to see the performance of the 8 bit interface.  Especially if you can set all of the IO pins to fast memory mapped mode and potentially try to maybe play some games, like: know which IO pins map to which memory mapped addresses and instead of doing 8+ operations to the memory mapped locations, see if that can be reduced to a couple simple writes. 

                     

                    That is if you take the Edison pin number / 32, tells you which long word register you will modify.  Different register for Set versus clear.  So if all IO pins are in the same 32 bit range, you can set up two masks one for set one for clear and only have to do the two writes to the memory mapped area.... Not sure how much faster that might be, but...

                     

                    As for Logic Analyzer to show Analog info, you should maybe try out one of their new ones.

                    Saleae.jpg

                    You might be able to tell I sort of like their stuff.  The Red one is one of their new ones that can capture Analog info

                     

                    Kurt

                    • 7. Re: Is there a way to toggle GPIO direction without signaling all pins?
                      llatta

                      I'm using the Adafruit 2.8" TFT too. I got the SPI side working a few days ago, driving it with MRAA I get about 400 ms for a full screen refresh, ie about 2.5 frames per second. My goal is to see if I can get to 30 fps, maybe getting close to 8x out of the 8-bit interface, and 2x by going from 16-bit to 8-bit colors could get me there.

                      I have kind of low hopes that user space programming/MRAA can get fast enough, but I haven't tried the memmapped calls at all yet. Thanks for the pointers here! Looking at the mmap implementation in MRAA and moving the data bits to continuous Edison pins (looks like Arduino 10-17 map to Edison 40-47 - not in that order though) could allow me to update all 8 pins with two 32-bit writes.

                      If that's not enough, maybe I'll need to do some kernel hacking and write something like my own "display driver". I haven't done that before, but it sounds like an interesting challenge. I'm pretty fearless on the software side, just have a somewhat limited time.

                      • 8. Re: Is there a way to toggle GPIO direction without signaling all pins?
                        llatta

                        Are you able to repro the issue with my code, Intel_Peter?

                        • 9. Re: Is there a way to toggle GPIO direction without signaling all pins?
                          Intel_Peter

                          Hello llatta,

                           

                          I'm very sorry, I'm still working on it, I will reply back as soon as I can.

                           

                                      Peter.

                          • 10. Re: Is there a way to toggle GPIO direction without signaling all pins?
                            Intel_Peter

                            Hello llatta,

                             

                            We have replicated this issue and we got the same results, we will run some other tests to see how the Edison behaves. If we get updates on this matter, we will post them here.

                             

                                        Peter.

                            • 11. Re: Is there a way to toggle GPIO direction without signaling all pins?
                              Intel_Peter

                              Hello llatta,

                               

                              We have been performing some test on this and it seems that this behavior is a possible bug, we will submit it to the appropriate team so they can review it.

                               

                              Peter.