You could do this many possible ways, but these are probably the most likely, in order of increasing difficulty.
1: Edit the core library files for pinMode(), digitalWrite(), digitalRead()
2: Copy and rename the pinMode(), digitalWrite(), digitalRead(), and edit that copy... eg: myPinMode(), myDigitalWrite(), myDigitalRead().
3: Create your own code using the hardware registers.
The downside to #1 is the possibility your edits could be overwritten and lost if you update or reinstall Teensyduino. Backup copies are essential. Of course, everyone doing creative work should use backup software for all their original irreplaceable data, but in practice many people don't go to the trouble. Just know that it is particularly important if you edit the core library files, because updates or reinstalling may overwrite them.
The first step is to simply find where these files are located on your computer. It varies depending on whether you use Windows, MacOS or Linux, and if you use Arduino 1.8.x or Arduino 2.0.x. The files are also on github, so for the rest of this message I'm going to link to the github files, but know you need to find the copy on your computer and edit those. File search may help. They may be located in folders which are normally hidden. On MacOS with Arduino 1.8.x, they are inside the application bundle, so control-click Arduino and "Show Package Contents" to look inside.
As a very first step, when you first edit the file add an intentional syntax error and click Verify in Arduino to make sure you get the error, as a confirmation you are editing the file Arduino is actually using.
The main pin definition file is core_pins.h.
https://github.com/PaulStoffregen/cores/blob/master/teensy4/core_pins.h
This file is large. It has 3 separate copies of the pin defines, for Teensy 4.0, Teensy 4.1 and MicroMod Teensy. Make sure you are editing in the correct area. Again, adding an intentional syntax error is the quick way to confirm you're editing in the right place. Do this first, because it's possible to waste a lot of time without results if you end up editing lines which aren't actually used.
For each pin you add, you'll need to know the native name and also which GPIO port and bit it is. You already know the native names. Use Table 10-1 in the
reference manual. The native names to GPIO starts on page 300. The GPIO ports are 1-4. Teensy uses the fast version, which are 6-9, so you will need to add 5 to the number shown in Table 10-1.
For example, if you edit the defines for Teensy 4.0 which have pins 0 to 39, and you wish to add pin "B0_09" as pin 40, you would first look it up in Table 10-1.
You'll add 5, so for B0_09 the the GPIO is port 7, bit 9.
Then you'll edit the
core_pins.h defines. First add the bit 9 part:
Code:
#define CORE_PIN37_BIT 12
#define CORE_PIN38_BIT 17
#define CORE_PIN39_BIT 16
[COLOR=#FF0000]#define CORE_PIN40_BIT 9[/COLOR]
Then for each of the register defines, add GPIO7. For example:
Code:
#define CORE_PIN37_PORTREG GPIO8_DR
#define CORE_PIN38_PORTREG GPIO8_DR
#define CORE_PIN39_PORTREG GPIO8_DR
[COLOR=#FF0000]#define CORE_PIN40_PORTREG GPIO7_DR[/COLOR]
Code:
#define CORE_PIN37_PORTSET GPIO8_DR_SET
#define CORE_PIN38_PORTSET GPIO8_DR_SET
#define CORE_PIN39_PORTSET GPIO8_DR_SET
[COLOR=#FF0000]#define CORE_PIN40_PORTSET GPIO7_DR_SET[/COLOR]
Several registers exist. Add this to the list for all of them.
Finally, you'll find 2 final groups of defines. Here you will add to the list using the pin name convention. For example:
Code:
#define CORE_PIN37_CONFIG IOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B0_00
#define CORE_PIN38_CONFIG IOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B0_05
#define CORE_PIN39_CONFIG IOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B0_04
[COLOR=#FF0000]#define CORE_PIN40_CONFIG IOMUXC_SW_MUX_CTL_PAD_GPIO_B0_09[/COLOR]
You'll also need to edit the define for the number of pins, since you've increase from 40 to 41:
Code:
#define CORE_NUM_TOTAL_PINS [COLOR=#FF0000]41[/COLOR]
#define CORE_NUM_DIGITAL [COLOR=#FF0000]41[/COLOR]
#define CORE_NUM_INTERRUPT [COLOR=#FF0000]41[/COLOR]
#define CORE_NUM_ANALOG 14
#define CORE_NUM_PWM 27
There are also redundant defines for the number of pins in
pins_arduino.h. Edit those if your program or libraries you use need them.
Next you'll edit
digital.c. It has a table which uses all those defines.
Code:
{&CORE_PIN37_PORTREG, &CORE_PIN37_CONFIG, &CORE_PIN37_PADCONFIG, CORE_PIN37_BITMASK},
{&CORE_PIN38_PORTREG, &CORE_PIN38_CONFIG, &CORE_PIN38_PADCONFIG, CORE_PIN38_BITMASK},
{&CORE_PIN39_PORTREG, &CORE_PIN39_CONFIG, &CORE_PIN39_PADCONFIG, CORE_PIN39_BITMASK},
#if CORE_NUM_DIGITAL > 40
{&CORE_PIN40_PORTREG, &CORE_PIN40_CONFIG, &CORE_PIN40_PADCONFIG, CORE_PIN40_BITMASK},
{&CORE_PIN41_PORTREG, &CORE_PIN41_CONFIG, &CORE_PIN41_PADCONFIG, CORE_PIN41_BITMASK},
{&CORE_PIN42_PORTREG, &CORE_PIN42_CONFIG, &CORE_PIN42_PADCONFIG, CORE_PIN42_BITMASK},
{&CORE_PIN43_PORTREG, &CORE_PIN43_CONFIG, &CORE_PIN43_PADCONFIG, CORE_PIN43_BITMASK},
{&CORE_PIN44_PORTREG, &CORE_PIN44_CONFIG, &CORE_PIN44_PADCONFIG, CORE_PIN44_BITMASK},
{&CORE_PIN45_PORTREG, &CORE_PIN45_CONFIG, &CORE_PIN45_PADCONFIG, CORE_PIN45_BITMASK},
#endif
#if CORE_NUM_DIGITAL > 46
{&CORE_PIN46_PORTREG, &CORE_PIN46_CONFIG, &CORE_PIN46_PADCONFIG, CORE_PIN46_BITMASK},
{&CORE_PIN47_PORTREG, &CORE_PIN47_CONFIG, &CORE_PIN47_PADCONFIG, CORE_PIN47_BITMASK},
{&CORE_PIN48_PORTREG, &CORE_PIN48_CONFIG, &CORE_PIN48_PADCONFIG, CORE_PIN48_BITMASK},
{&CORE_PIN49_PORTREG, &CORE_PIN49_CONFIG, &CORE_PIN49_PADCONFIG, CORE_PIN49_BITMASK},
{&CORE_PIN50_PORTREG, &CORE_PIN50_CONFIG, &CORE_PIN50_PADCONFIG, CORE_PIN50_BITMASK},
{&CORE_PIN51_PORTREG, &CORE_PIN51_CONFIG, &CORE_PIN51_PADCONFIG, CORE_PIN51_BITMASK},
{&CORE_PIN52_PORTREG, &CORE_PIN52_CONFIG, &CORE_PIN52_PADCONFIG, CORE_PIN52_BITMASK},
{&CORE_PIN53_PORTREG, &CORE_PIN53_CONFIG, &CORE_PIN53_PADCONFIG, CORE_PIN53_BITMASK},
{&CORE_PIN54_PORTREG, &CORE_PIN54_CONFIG, &CORE_PIN54_PADCONFIG, CORE_PIN54_BITMASK},
#endif
};
For this example, pin 40 already is in the table. The #if checks just keep the table from using extra space needlessly, so you can just ignore those unless you care about saving a small amount of memory. For beyond pin 54, you'll need to add more lines. But the hard work is already done in core_pins.h, so just copy and increase the numbers from 54 to 55.
Likewise, if you want the digitalWriteFast() and digitalReadFast() to be able to use pins beyond 54, you'll need to add them to those functions, which are in
core_pins.h. For example:
Code:
} else if (pin == 45) {
CORE_PIN45_PORTSET = CORE_PIN45_BITMASK;
#endif
#if CORE_NUM_DIGITAL > 46
} else if (pin == 46) {
CORE_PIN46_PORTSET = CORE_PIN46_BITMASK;
} else if (pin == 47) {
CORE_PIN47_PORTSET = CORE_PIN47_BITMASK;
} else if (pin == 48) {
CORE_PIN48_PORTSET = CORE_PIN48_BITMASK;
} else if (pin == 49) {
CORE_PIN49_PORTSET = CORE_PIN49_BITMASK;
} else if (pin == 50) {
CORE_PIN50_PORTSET = CORE_PIN50_BITMASK;
} else if (pin == 51) {
CORE_PIN51_PORTSET = CORE_PIN51_BITMASK;
} else if (pin == 52) {
CORE_PIN52_PORTSET = CORE_PIN52_BITMASK;
} else if (pin == 53) {
CORE_PIN53_PORTSET = CORE_PIN53_BITMASK;
} else if (pin == 54) {
CORE_PIN54_PORTSET = CORE_PIN54_BITMASK;
[COLOR=#FF0000] } else if (pin == 55) {
CORE_PIN54_PORTSET = CORE_PIN54_BITMASK;[/COLOR]
#endif
}
} else {
if (pin == 0) {
CORE_PIN0_PORTCLEAR = CORE_PIN0_BITMASK;
} else if (pin == 1) {
CORE_PIN1_PORTCLEAR = CORE_PIN1_BITMASK;
Like the table in digital.c, the hard work was already done so just copy line and increment the number.
For approach #2, you would do basically the same thing, but copy the code into files in your own program and change the global scope names so they don't conflict with the core library code.
For approach #3, you could craft whatever code you like.... creativity required. But hopefully this at least gives you some ideas?