Arduino M0 Port Manipulation

Hi,

My project is about signal processing with a Adafruit Trinket M0, which is very similar to an Arduino M0.
I was looking for information about speeding up port manipulation on a M0 board, in a similar way as using DDRB and PORTB on an Arduino UNO.
The Arduino UNO produces a blokwave of 210 kHz by using digitalWrite. But with this code:

void setup() {
DDRB = B00000100; //pin 10
while(true) {
PORTB = B00000100;
PORTB = B00000000;
}

void loop() {}

you can speed it up to 4 MHz. But how to do this on a M0 board?
In the Microchip manual for SAND21 microcontrollers I found that the word PORT was used, so I put the word PORT in my sketch and I got an error message referring to:
C:\Users\admin\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.16.17\cores\arduino\wiring_digital.c (This was on Windows 7 and it will be different on other systems.)
I opened the file in TextPad and there I got everything I was looking for. Here I would like to share with you what I was able to make with this information.

uint8_t pin = 4;

void setup() {
pinMode(pin, OUTPUT);
EPortType port = g_APinDescription[pin].ulPort;
uint32_t pinMask = (1ul << g_APinDescription[pin].ulPin);
while(true) {
PORT->Group[port].OUTSET.reg = pinMask;
PORT->Group[port].OUTCLR.reg = pinMask;
}
}

void loop() {}

Instead of 290 kHz by using digitalWrite I got 2,5 MHz on the M0 board. Less than the UNO but still a big improvement.
Although a M0 board has a higher clock rate than an UNO board, you can't speed it up as much because port manipulation is much more complicated. The next sketch shows how to read pins in a faster way than with digitalRead.

void setup() {
pinMode(0, INPUT);
pinMode(4, OUTPUT);
EPortType portIn = g_APinDescription[0].ulPort;
uint32_t pinIn = g_APinDescription[0].ulPin;
uint32_t pinMaskIn = (1ul << pinIn);
EPortType portOut = g_APinDescription[4].ulPort;
uint32_t pinOut = g_APinDescription[4].ulPin;
uint32_t pinMaskOut = (1ul << pinOut);
while(true) {
while((PORT->Group[portIn].IN.reg & pinMaskIn) != 0);
while((PORT->Group[portIn].IN.reg & pinMaskIn) == 0);
PORT->Group[portOut].OUTSET.reg = pinMaskOut;
PORT->Group[portOut].OUTCLR.reg = pinMaskOut;
}
}

void loop() {}

It reads a blockwave (that was created with a Arduino DUE) on pin 0 and gives a short pulse on pin 4 everytime the blockwave goes from 0 to 3V.
If you were looking for this information, I hope this helps.

Blockwave_with_M0.ino (296 Bytes)

Convert.ino (620 Bytes)

The OneWire library uses it: OneWire/OneWire_direct_gpio.h at master · PaulStoffregen/OneWire · GitHub

I still wonder where I can find de declarations of the type EPortType and the class PORT. I guess they must be somewhere in the SAMD core, but I couldn't find them.