Skip to content
TeensyUser edited this page Mar 21, 2020 · 12 revisions

The digital pins are shown with gray numbers on the pinout cards. (Additional info about the pinouts can be found here). They can be accessed using digitalWriteFast and digititalReadFast. Of course, you can also use the slower digitalRead and digitalWrite functions but other than compatibility to Arduino code there is no advantage.

Internally, digital input or output is handled by the GPIO (general purpose input / output) module which is not identical but very similar between the various boards.

Setting pin modes

To setup the pins for one of the various input or output modes you can use the pinMode(pin, mode) function which takes the pin number (as given in the pinout card) as first and the mode as second parameter. The following modes are available:

Mode Description
OUTPUT Low impedance output mode. Pin can be set or cleared using digitalWriteFast
OUTPUT_OPENDRAIN Operate the pin in open drain mode. Please note this Teensy specific quirk of open-drain mode.
INPUT High impedance input mode. Pin can be read with digitalReadFast. This mode is set per default. Reading an open pin gives undefined values.
INPUT_PULLUP Adds a pull up resistor (~10k?) to the pin. Open pin reads HIGH
INPUT_PULLDOWN Adds a pull down resistor (~10k?) to the pin. Open pin reads LOW
INPUT_DISABLE Disables the pin

Here an example demonstrating how to read and write digital pins. It also shows the effect of PULLUP and PULLDOWN input modes. (Code for this section can be found here)

constexpr int inputPin = 0;

void setup()
{
    while (!Serial && millis() < 1000) {}

    pinMode(LED_BUILTIN, OUTPUT);

    pinMode(inputPin, INPUT_PULLUP);
    Serial.println("Using INPUT_PULLUP:");
    printDigitalVal(inputPin, digitalReadFast(inputPin));

    pinMode(inputPin, INPUT_PULLDOWN);
    Serial.println("\nUsing INPUT_PULLDOWN:");
    printDigitalVal(inputPin, digitalReadFast(inputPin));
}

void loop()
{
    digitalWriteFast(LED_BUILTIN, !digitalReadFast(LED_BUILTIN)); // toggle pin
    delay(150);
}

// Helpers ----------------------------------------------------------

void printDigitalVal(int pin, int val)
{
    Serial.printf("Pin %d value: %s\n", pin, val == 0 ? "LOW" : "HIGH");
}

Pin interrupts

TBD

Low Level access

WIP: Shortly explain Registers

For accessing the GPIO registers directly it is necessary to know the mapping from GPIO registers and bits to the digital pins and vice versa. The following sketch prints out a table with these relations. The first column shows how the pins are mapped to the registers, the second column shows how the registers are mapped to the pins. The full code can be downloaded here

#include <algorithm>
#include "pin.h"

void setup()
{
    while (!Serial && millis() < 1000){}

    Pin *pins1[CORE_NUM_DIGITAL];
    Pin *pins2[CORE_NUM_DIGITAL];

    for (unsigned pinNr = 0; pinNr < CORE_NUM_DIGITAL; pinNr++)
    {
        Pin *p = new Pin(pinNr);
        pins1[pinNr] = p;
        pins2[pinNr] = p;
    }

    std::sort(pins1, pins1 + CORE_NUM_DIGITAL, [](Pin *a, Pin *b)  // Sort by pin number
    {
        return a->getPinNr() < b->getPinNr(); 
    }); 

    std::sort(pins2, pins2 + CORE_NUM_DIGITAL, [](Pin *a, Pin *b)   // Sort by GPIO and Bit
    {
        if (a->getGpioNr() < b->getGpioNr()) return true;
        if (a->getGpioNr() > b->getGpioNr()) return false;
        if (a->getBitNr() < b->getBitNr())   return true;
        return false;
    });

    // Print results in two columns--------------------------

    Serial.println("PIN   GPIOn-BITm  |  GPIOn-BITm    PIN");
    Serial.println("------------------|-------------------");
    for (unsigned i = 0; i < CORE_NUM_DIGITAL; i++)
    {
        unsigned pin1 = pins1[i]->getPinNr();
        unsigned pin2 = pins2[i]->getPinNr();
        unsigned gpio1 = pins1[i]->getGpioNr();
        unsigned gpio2 = pins2[i]->getGpioNr();
        unsigned bit1 = pins1[i]->getBitNr();
        unsigned bit2 = pins2[i]->getBitNr();
        Serial.printf("%02d  -> GPIO%u-%02u   |   GIPO%u-%02u  ->  %02d\n", pin1, gpio1, bit1, gpio2, bit2, pin2);
    }    
}

void loop()
{   
}

And here a part of the printout for a T-LC

PIN   GPIOn-BITm  |  GPIOn-BITm    PIN
------------------|-------------------
00  -> GPIO1-16   |   GIPO0-01  ->  03
01  -> GPIO1-17   |   GIPO0-02  ->  04
02  -> GPIO3-00   |   GIPO1-00  ->  16
03  -> GPIO0-01   |   GIPO1-01  ->  17
04  -> GPIO0-02   |   GIPO1-02  ->  19
05  -> GPIO3-07   |   GIPO1-03  ->  18
06  -> GPIO3-04   |   GIPO1-16  ->  00
07  -> GPIO3-02   |   GIPO1-17  ->  01
08  -> GPIO3-03   |   GIPO2-00  ->  15
09  -> GPIO2-03   |   GIPO2-01  ->  22
10  -> GPIO2-04   |   GIPO2-02  ->  23
11  -> GPIO2-06   |   GIPO2-03  ->  09
12  -> GPIO2-07   |   GIPO2-04  ->  10
13  -> GPIO2-05   |   GIPO2-05  ->  13
...

Clone this wiki locally