micosootys,
Ref post #13
Thanks, I took your advice and changed my TC0 capture to run at 200MHz!
And it looks like the Adafruit Metro M4 Express only uses DLLP[0].
I did not have to mess with startup.c thankfully! And as you will see below
ADC0, ADC1 and the USB are setup to run at 48MHz and the DAC is set to run at 12MHz.
The CPU is set at 120MHz.
After a hard reset this is how the clocks and their paths stacks-up:
In setup() I generated some code to display all the registers I needed to see.
Which is where all this came from.
loop() was left empty.
DFPLL[0] is set for 120MHz and DFPLL[1] is set for 100MHz.
GCLK Peripheral CH1 and 2 use Generator 5 as its reference input.
GCLK Peripheral CH10, 40 and 41 use Generator 1 as its reference input.
GCLK Peripheral CH42 uses Generator 4 as its reference input.
The Peripheral channel mapping is as follows. See page 156
Ch1 output goes to -> Ref for FDPLL0.
Ch2 output goes to -> Ref for FDPLL1.
Ch10 output goes to -> USB.
Ch40 output goes to -> ADC0.
Ch41 output goes to -> ADC1.
Ch42 output goes to -> DAC.
Nothing else was set up.
Generic Clock Generator 0,1, 2, 3 are divide by 0 or no division.
Generic Clock Generator 4 is divided by 0x4 = 4.
Generic Clock Generator 5 is divided by 0x30 = 48.
Generator 0 uses DPLL[0] as its input source. ( This is used for the CPU CLOCK)
Generator 1 uses DFLL48 as its input source. (This is used for the USB, ADC0, ADC1)
Generator 2 uses DPLL[1] as its input source. (Not used)
Generator 3 uses XOSC32K as its input source.( Not used)
Generator 4 uses DFLL48 as its input source. (This is used for the DAC)
Generator 5 uses DFLL48 as its input source. (This is used for the CPU CLOCK)
Generators 6-11 are not setup.(Not used)
It looks like after a hard reset, DFLL48 is running in open loop mode at 48MHz.
Below is my connection chart or clock paths taken after a reset.
-
[DFLL(48MHz)]->[(/48)GEN5(1MHz)]->[CH1]->[(x120)FDPLL0(120MHz)]->
[(/1)GEN0(120MHz)->[GCLK_MAIN] which is the CPU clock.
-
[DFLL(48MHz)]->[(/48)GEN5(1MHz)]->[CH2]->[(x100)FDPLL1(100MHz)]->It is setup this far but not used.
-
[DFLL(48MHz)]->[(/1)GEN1(48MHz)]->[CH10(USB)],[CH41(ADC0)],[CH41(ADC1)].
-
[DFLL(48MHz)]->[(/4)GEN4(12MHz)]->[CH44(DAC)].
You read line 1 as follows:
DFLL at 48MHz feeds Generator 5 which divides the input by 48 giving a 1MHz output.
This feeds CH1 which feeds the FDPLL0 which multiplies the input freq. by 120 giving an output freq. of 120MHz. This then feeds Generator 0 dividing by 1 and sends the 120MHz to GCLK_MAIN which is the CPU clock.
Hope that makes sense?
OK, Wow!
Now to set my TC0 clock to 200MHz.
Here is the snippet of code I used to put TC0 onto DPLL[1] and run it at 200MHz
// change the speed of the FDPLL[1] from 100MHz to 200MHz Max freq
// change the speed
OSCCTRL->Dpll[1].DPLLCTRLA.bit.ENABLE=0; // disable DPLL[1]
while(OSCCTRL->Dpll[1].DPLLSYNCBUSY.bit.ENABLE); // wait for synchronization
OSCCTRL->Dpll[1].DPLLCTRLB.bit.LBYPASS=0; // Clear the LBYPASS bit
while(OSCCTRL->Dpll[1].DPLLSYNCBUSY.bit.ENABLE); // wait for synchronization
OSCCTRL->Dpll[1].DPLLCTRLB.bit.LTIME=0; // keep LTIME = 0
while(OSCCTRL->Dpll[1].DPLLSYNCBUSY.bit.ENABLE); // wait for synchronization
//OSCCTRL->Dpll[1].DPLLCTRLB.reg=0x000; // Clear the LBYPASS bit, keep LTIME = 0 all in one step
//while(OSCCTRL->Dpll[1].DPLLSYNCBUSY.bit.ENABLE); // wait for synchronization
OSCCTRL->Dpll[1].DPLLRATIO.reg=0xC7; // set the LDR to 0xC7 = 199 to give an output of 200MHz MAX speed!
while(OSCCTRL->Dpll[1].DPLLSYNCBUSY.bit.DPLLRATIO); // wait for synchronization
OSCCTRL->Dpll[1].DPLLCTRLA.bit.ENABLE=1; // enable DPLL[1]
while(OSCCTRL->Dpll[1].DPLLSYNCBUSY.bit.ENABLE); // wait for synchronization
// done
// FDPLL[1] using Generator 2
GCLK->PCHCTRL[TC0_GCLK_ID].reg = GCLK_PCHCTRL_CHEN | // Enable perhipheral channel (9=GCLK_TC0,GCLK_TC1)
GCLK_PCHCTRL_GEN_GCLK2; // Connect 200MHz generic clock (2) to TC0
There is probably a better way to do this but this did work!
If there is a cleaner way I would be happy to see it.
Also did I get my self into unknown trouble or leave something important out?
Let me know if you see something that does not look right?
My new connection chart for this is:
[DFLL(48MHz)]->[(/48)GEN5(1MHz)]->[CH2]->[(x200)DPLL1(200MHz)]->[(/1)GEN2(200MHz)]-> [CH9(TC0,TC1).
Since nothing but this code is using DPLL[1] nothing is being overclocked.
I left DFLL48 and DPLL[0] alone so as to not mess-up the CPU clock or other stuff.
So it all works and getting better accuracy at the 200MHz !
So thanks again for the suggestion! In this project I have learned a lot about coding for this ATSAMD51 processor!
Starting from scratch and getting here was only possible because the help from you and the others!
Thanks to all!
Now I just need to get more timers running! It never ends. Great fun!!!
Sorry it was so wordy.