... but how do I do this, and where do you get the information? I noticed in your earlier code the "non Arduino" Port defines syntax, where did you get this information?
The CMSIS register definitions for the SAMD51 are buried (on my Windows machine) at:
C:\Users\Computer\AppData\Local\Arduino15\packages\arduino\tools\CMSIS-Atmel\1.2.0\CMSIS\Device\ATMEL\samd51\include...
Here you'll find the directories "component", "instance" and "pio".
The component directory contains the register definitions and bitfields for each peripheral type, for example adc.h, tc.h, tcc.h, etc...
These definitions can be used to specify the entire register (in the "tcc.h" file):
TCC0->CTRLA.reg |= TCC_CTRLA_ENABLE; // Enable the TCC0 timer
Or alternatively a bit or bitfield in the register:
TCC0->CTRLA.bit.ENABLE = TCC_CTRLA_ENABLE_Pos; // Enable the TCC0 timer
or alternatively:
TCC0->CTRLA.bit.ENABLE = 1; // Enable the TCC0 timer
These "component" definitions are usually the preferred method of specifying registers.
An alternative notation is specified in the "instance" directory, which contains an instance of each periperal, for example tc0.h, tc1.h, tc2.h, tcc0.h, tcc1.h etc...
These defintions can also be used to specify an entire register (in the "tcc0.h" file):
REG_TCC0_CTRLA |= TCC_CTRLA_ENABLE; // Enable the TCC0 timer
However, this notation is less commonly used.
The "pio" register is used for GPIO definitions. Personally, I rarely use it.
Also, why are the ports different between the Metro M4 and Grand Central M4? according to the Atmel datasheets although they are different IC packages, the ports should still be the same (where available) - is there some software define which is redefining these ports / pins?
There are three sets of pin numbers: the IC pin numbers (1, 2, 3, etc..), the port pin numbers (PA00, PA01, PA02, etc...) and the Arduino pin numbers (D0, D1, D2, etc...).
As you mention, the SAMD51 microcontrollers themselves maintain port pin continuity across the different size chip variants. However, unlike on their SAMD21 (M0) boards, Adafruit doesn't mantain port pin to Arduino pin continuity on their SAMD51 (M4) series: the Metro M4, Feather M4, Itsy Bitsy M4 and Metro M4 Grand Central port pins do not go to the same Arduino board pins. This means for example that port pin PB13 on the Metro M4 is connected to D4, while the same port pin on the Grand Central is connected to UART RX1.
This means that it's possible to write register code for the Adafruit Metro M0 and have it work on the same Arduino pins on the Feather M0, the same is sadly not true for the Metro M4 and Feather M4.
I have an Arduino Due - did you have to modify the your earlier software for this board (over the Metro M4 version)?
The code I used for the Arduino Due, that generates a 28MHz PWM pulse on D9 is as follows, I just connected the grounds between the boards and plugged D9 output on the Due into the D4 input on my Metro M4:
// Output a 28MHz PWM waveform on pin D9 (PWML4)
void setup() {
PMC->PMC_PCER1 |= PMC_PCER1_PID36; // Enable the PWM Controller
PIOC->PIO_ABSR |= PIO_ABSR_P21; // Set PWM pin perhipheral type A or B, in this case B
PIOC->PIO_PDR |= PIO_PDR_P21; // Set PWM pin to an output
PWM->PWM_CLK = PWM_CLK_PREA(0) | PWM_CLK_DIVA(1); // Set the PWM clock rate to 84MHz (84MHz/1=84MHz)
PWM->PWM_CH_NUM[4].PWM_CMR = PWM_CMR_CPRE_CLKA; // Enable single slope PWM and set the clock source as CLKA
PWM->PWM_CH_NUM[4].PWM_CPRD = 3; // Set the PWM frequency 84MHz/28MHz = 3
PWM->PWM_CH_NUM[4].PWM_CDTY = 2; // Set the PWM duty cycle
PWM->PWM_ENA = PWM_ENA_CHID4; // Enable the PWM channel 4
}
void loop() {}