Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 8 of 8

Thread: Reading multiple GPIO pins on the Teensy 4.0 "atomically"

  1. #1
    Junior Member
    Join Date
    Aug 2019
    Posts
    9

    Reading multiple GPIO pins on the Teensy 4.0 "atomically"

    I plan on using a 16 bit parallel ADC with the Teensy4.0. Currently, I only know how to read each of the 16 pins individually:

    //ADC bit 0 (LSB) //bit 1 //bit 2 //bit 3
    ADC_result = digitalRead(PIN_C2) + digitalRead(PIN_C3) <<1 + digitalRead(PIN_C4) <<2 + digitalRead(PIN_D2) <<3 ...etc.

    Is there a way to "group" GPIO pins together, so that I can read all of the 16 inputs "at the same time"?

  2. #2
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    5,755
    The short answer is no.

    The longer answer is probably not. At least not in a contiguous 16 IO pins associated with one IO port.

    If you look at the section of the Processor reference manual talking about GPIO (11.5)
    There are eight 32-bit GPIO registers. All registers are accessible from the IP interface.
    Only 32-bit access is supported.
    Again I have no idea of what your pins like PIN_C2, PIN_C3 are. But assuming you have some #defines for them some where.

    But if you look at the table of which Teensy pin is connected to which IMXRT pin. You can find that in several places including: https://forum.pjrc.com/threads/54711...l=1#post193716

    You could try to see if any of the GPIO objects have 16 actual IO pins that are brought out on the Teensy. If so you could configure all of these to be inputs and then use the DR register to read them. But I am guessing that there may not be any one GPIO register with 16 pins brought out. But I have not counted them up...

    But that would be where I would start looking.

  3. #3
    Senior Member vjmuzik's Avatar
    Join Date
    Apr 2017
    Location
    Florida
    Posts
    430
    There does happen to be one port with 16 IO pins available, pins 0-1 and pins 14-27 are all on GPIO6 so it could be possible. You will have to do some bit shuffling to get them in the right order for a 16 bit variable, but they are there if you want that to be an option.

  4. #4
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    578
    I wonder if the bit shuffling will be faster at the end as reading the pins sequentially. However, you should use digitalReadFast instead of digitalRead and it might be faster to OR the results together instead of adding.

    Code:
    uint16_t value =  (digitalReadFast(P1) << 0) | (digitalReadFast(P2) << 2) | (digitalReadFast(P3) << 3) ....
    As long as the pin numbers are compile time constants this should be very fast.
    Last edited by luni; 11-13-2019 at 09:18 PM.

  5. #5
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    578
    Just measured the speed of this snippet with an LA on pin 11 and get some 250ns on a T4@600MHz

    Code:
    digitalWriteFast(11, HIGH);
        
        volatile uint16_t value =
            digitalReadFast(2) << 0 |
            digitalReadFast(3) << 1 |
            digitalReadFast(5) << 2 |
            digitalReadFast(1) << 3 |
            digitalReadFast(7) << 4 |
            digitalReadFast(12) << 5 |
            digitalReadFast(15) << 6 |
            digitalReadFast(14) << 7 |
            digitalReadFast(4) << 8 |
            digitalReadFast(6) << 9 |
            digitalReadFast(9) << 10 |
            digitalReadFast(8) << 11 |
            digitalReadFast(7) << 12 |
            digitalReadFast(10) << 13 |
            digitalReadFast(16) << 14 |
            digitalReadFast(17) << 15;
    
    digitalWriteFast(11, LOW);

  6. #6
    Junior Member
    Join Date
    Aug 2019
    Posts
    9
    Thank you ALL - these code snippets and suggestions are a BIG help, I will try them shortly!

  7. #7
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    5,755
    Sorry, this one won't help: But on the IMXRT1062 there is an ability to read or write multiple pins at the same time using FlexIO subsystem.

    In particular you can configure it for 1 bit, 4, 8, 16, 32 bits, but there is a few rubs!

    They work on FlexIO pins and they have to be contiguous FlexIO pins on the same FlexIO controller. The problem is on the largest run of contiguous FlexIO pin on any of the three controllers is I believe 6 pins.

    And so far I have not tried this part of the FlexIO subsystem. I have thought about trying to drive some simple display to see how well it worked, but I have not seen many recent ones that allow 4 bit writes.

    The interesting thing will be to see which pins we bring out on the larger T4 (T4.1) And if there will be more contiguous pins. If so I will probably experiment then when the first betas come out.

    Again sorry I know that this probably won't help you with your current stuff, but thought I would mention it.

  8. #8
    16 bits at once is going to suck, no doubt about it. For two 8-bit buses on T4 I made it work by reading a 32 bit register (GPIO6_PSR and GPIO7_PSR) and then scrambling it with a macro I can drop into my code that reorders the pins I'm using into a normal byte. This would never be fast if you had 8 (or 16!!) bits scattered all over the place, but GPIO6 in particular does have something like 6 sequential bits brought out to pins on the T4, so you only need a couple bit shifts.

    I might do this in my code to read a byte:
    Code:
    read_byte=MACRO_INVTRANSPOSE_DATAWORD(DATA_BUS_INPUTREG);  // This is the actual read from GPIO bus.
    where DATA_BUS_INPUTREG has already been defined elsewhere (as GPIO6_PSR)

    That macro looks like this:
    Code:
    #define MACRO_INVTRANSPOSE_DATAWORD(orig32b) (byte)(orig32b>>22)<<2 | (orig32b&0b11000000000000000000)>>18
    I couldn't tell you if it's the MOST efficient way to do this, but it seems to do the trick.

    I'd pay $50 a piece no doubt about it for T4.1s that bring out two separate GPIO buses each with 8 or more sequential bits brought out to pins.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •